commands.c (6843B)
1 #define COMMANDS_C 2 3 #include "commands.h" 4 5 static bool read_scramble(int c, char **v, CommandArgs *args); 6 7 /* Arg parsing functions implementation **************************************/ 8 9 CommandArgs * 10 solve_parse_args(int c, char **v) 11 { 12 int i; 13 bool infinitesols, fixedmsols; 14 long val; 15 16 CommandArgs *a = new_args(); 17 18 a->opts->min_moves = 0; 19 a->opts->max_moves = 20; 20 a->opts->max_solutions = 1; 21 a->opts->nthreads = 1; 22 a->opts->optimal = -1; 23 a->opts->can_niss = false; 24 a->opts->verbose = false; 25 a->opts->all = false; 26 a->opts->print_number = true; 27 a->opts->count_only = false; 28 29 fixedmsols = false; 30 infinitesols = false; 31 32 for (i = 0; i < c; i++) { 33 if (!strcmp(v[i], "-m") && i+1 < c) { 34 val = strtol(v[++i], NULL, 10); 35 if (val < 0 || val > 100) { 36 fprintf(stderr, 37 "Invalid min number of moves" 38 "(0 <= N <= 100).\n"); 39 return a; 40 } 41 a->opts->min_moves = val; 42 } else if (!strcmp(v[i], "-M") && i+1 < c) { 43 val = strtol(v[++i], NULL, 10); 44 if (val < 0 || val > 100) { 45 fprintf(stderr, 46 "Invalid max number of moves" 47 "(0 <= N <= 100).\n"); 48 return a; 49 } 50 a->opts->max_moves = val; 51 infinitesols = true; 52 } else if (!strcmp(v[i], "-t") && i+1 < c) { 53 val = strtol(v[++i], NULL, 10); 54 if (val < 1 || val > 64) { 55 fprintf(stderr, 56 "Invalid number of threads." 57 "1 <= t <= 64\n"); 58 return a; 59 } 60 a->opts->nthreads = val; 61 } else if (!strcmp(v[i], "-n") && i+1 < c) { 62 val = strtol(v[++i], NULL, 10); 63 if (val < 1 || val > 1000000) { 64 fprintf(stderr, 65 "Invalid number of solutions.\n"); 66 return a; 67 } 68 a->opts->max_solutions = val; 69 fixedmsols = true; 70 } else if (!strcmp(v[i], "-o")) { 71 a->opts->optimal = 0; 72 infinitesols = true; 73 } else if (!strcmp(v[i], "-O") && i+1 < c) { 74 val = strtol(v[++i], NULL, 10); 75 if (val < 0 || val > 100 || 76 (val == 0 && strcmp("0", v[i]))) { 77 fprintf(stderr, 78 "Invalid max number of moves" 79 " (0 <= N <= 100).\n"); 80 return a; 81 } 82 a->opts->optimal = val; 83 infinitesols = true; 84 } else if (!strcmp(v[i], "-i")) { 85 a->scrstdin = true; 86 } else if (!strcmp(v[i], "-v")) { 87 a->opts->verbose = true; 88 } else if (!strcmp(v[i], "-a")) { 89 a->opts->all = true; 90 } else if (!strcmp(v[i], "-p")) { 91 a->opts->print_number = false; 92 } else if (!strcmp(v[i], "-c")) { 93 a->opts->count_only = true; 94 } 95 } 96 97 if (infinitesols && !fixedmsols) 98 a->opts->max_solutions = 1000000; /* 1M = +infty */ 99 100 a->success = (a->scrstdin && i == c) || read_scramble(c-i, &v[i], a); 101 return a; 102 } 103 104 CommandArgs * 105 gen_parse_args(int c, char **v) 106 { 107 int val; 108 CommandArgs *a = new_args(); 109 110 a->opts->nthreads = 64; 111 a->success = false; 112 113 if (c == 0) { 114 a->success = true; 115 } else { 116 if (!strcmp(v[0], "-t") && c > 1) { 117 val = strtol(v[1], NULL, 10); 118 if (val < 1 || val > 64) { 119 fprintf(stderr, 120 "Invalid number of threads." 121 "1 <= t <= 64\n"); 122 return a; 123 } 124 a->opts->nthreads = val; 125 a->success = true; 126 } 127 } 128 129 return a; 130 } 131 132 CommandArgs * 133 help_parse_args(int c, char **v) 134 { 135 int i; 136 CommandArgs *a = new_args(); 137 138 if (c == 1) { 139 for (i = 0; commands[i] != NULL; i++) 140 if (!strcmp(v[0], commands[i]->name)) 141 a->command = commands[i]; 142 if (a->command == NULL) 143 fprintf(stderr, "%s: command not found\n", v[0]); 144 } 145 146 a->success = c == 0 || (c == 1 && a->command != NULL); 147 return a; 148 } 149 150 CommandArgs * 151 parse_only_scramble(int c, char **v) 152 { 153 CommandArgs *a = new_args(); 154 155 if (!strcmp(v[0], "-i")) { 156 a->scrstdin = true; 157 a->success = c == 1; 158 } else { 159 a->success = read_scramble(c, v, a); 160 } 161 162 return a; 163 } 164 165 CommandArgs * 166 parse_no_arg(int c, char **v) 167 { 168 CommandArgs *a = new_args(); 169 170 a->success = true; 171 172 return a; 173 } 174 175 /* Exec functions implementation *********************************************/ 176 177 void 178 solve_exec(CommandArgs *args) 179 { 180 Cube c; 181 AlgList *sols; 182 Solver *solver[99]; 183 Threader *threader; 184 185 make_solved(&c); 186 apply_alg(args->scramble, &c); 187 /* TODO: adjust */ 188 threader = &threader_single; 189 /* threader = &threader_eager;*/ 190 191 /* TODO: adjust */ 192 /* This was to solve steps 193 int i; 194 for (i = 0; args->cs->step[i] != NULL; i++) 195 solver[i] = new_stepsolver_lazy(args->cs->step[i]); 196 solver[i] = NULL; 197 */ 198 199 prepare_solver_nxopt31(); 200 solver[0] = &solver_nxopt31; 201 solver[1] = NULL; 202 sols = solve(&c, args->opts, solver, threader); 203 204 if (args->opts->count_only) 205 printf("%d\n", sols->len); 206 else 207 print_alglist(sols, args->opts->print_number); 208 209 free_alglist(sols); 210 } 211 212 void 213 gen_exec(CommandArgs *args) 214 { 215 /* TODO: 216 int i; 217 218 fprintf(stderr, "Generating coordinates...\n"); 219 fprintf(stderr, "Generating pruning tables...\n"); 220 for (i = 0; all_pd[i] != NULL; i++) 221 genptable(all_pd[i], args->opts->nthreads); 222 */ 223 224 fprintf(stderr, "Done!\n"); 225 } 226 227 void 228 help_exec(CommandArgs *args) 229 { 230 if (args->command == NULL) { 231 printf( 232 "Use the nissy command \"help COMMAND\" for a short " 233 "description of a specific command.\n" 234 "Use the nissy command \"commands\" for a list of " 235 "available commands.\n" 236 "See the manual page for more details. The manual" 237 " page is available with \"man nissy\" on a UNIX" 238 " system (such as Linux or MacOS) or in pdf and html" 239 " format in the docs folder.\n" 240 "Nissy is available for free at " 241 "https://nissy.tronto.net\n" 242 ); 243 } else { 244 printf("Command %s: %s\nusage: %s\n", args->command->name, 245 args->command->description, args->command->usage); 246 } 247 } 248 249 void 250 quit_exec(CommandArgs *args) 251 { 252 exit(0); 253 } 254 255 /* Local functions implementation ********************************************/ 256 257 static bool 258 read_scramble(int c, char **v, CommandArgs *args) 259 { 260 int i, k, n; 261 unsigned int j; 262 char *algstr; 263 264 if (c < 1) { 265 fprintf(stderr, "Error: no scramble given?\n"); 266 return false; 267 } 268 269 for(n = 0, i = 0; i < c; i++) 270 n += strlen(v[i]); 271 272 algstr = malloc((n + 1) * sizeof(char)); 273 k = 0; 274 for (i = 0; i < c; i++) 275 for (j = 0; j < strlen(v[i]); j++) 276 algstr[k++] = v[i][j]; 277 algstr[k] = 0; 278 279 args->scramble = new_alg(algstr); 280 free(algstr); 281 282 if (args->scramble->len == 0) 283 fprintf(stderr, "Error reading scramble\n"); 284 285 return args->scramble->len > 0; 286 } 287 288 /* Public functions implementation *******************************************/ 289 290 void 291 free_args(CommandArgs *args) 292 { 293 if (args == NULL) 294 return; 295 296 if (args->scramble != NULL) 297 free_alg(args->scramble); 298 if (args->opts != NULL) 299 free(args->opts); 300 301 /* step and command must not be freed, they are static! */ 302 303 free(args); 304 } 305 306 CommandArgs * 307 new_args() 308 { 309 CommandArgs *args = malloc(sizeof(CommandArgs)); 310 311 args->success = false; 312 args->scrstdin = false; 313 args->scramble = NULL; /* initialized in read_scramble */ 314 args->opts = malloc(sizeof(SolveOptions)); 315 316 args->cs = NULL; 317 args->command = NULL; 318 319 return args; 320 }