diff options
Diffstat (limited to 'src/commands.c')
| -rw-r--r-- | src/commands.c | 322 |
1 files changed, 61 insertions, 261 deletions
diff --git a/src/commands.c b/src/commands.c index a91fb4f..7f58ef5 100644 --- a/src/commands.c +++ b/src/commands.c | |||
| @@ -1,187 +1,11 @@ | |||
| 1 | #include "commands.h" | 1 | #define COMMANDS_C |
| 2 | |||
| 3 | /* Arg parsing functions *****************************************************/ | ||
| 4 | |||
| 5 | CommandArgs * gen_parse_args(int c, char **v); | ||
| 6 | CommandArgs * help_parse_args(int c, char **v); | ||
| 7 | CommandArgs * parse_only_scramble(int c, char **v); | ||
| 8 | CommandArgs * parse_no_arg(int c, char **v); | ||
| 9 | CommandArgs * solve_parse_args(int c, char **v); | ||
| 10 | CommandArgs * scramble_parse_args(int c, char **v); | ||
| 11 | |||
| 12 | /* Exec functions ************************************************************/ | ||
| 13 | 2 | ||
| 14 | static void gen_exec(CommandArgs *args); | 3 | #include "commands.h" |
| 15 | static void cleanup_exec(CommandArgs *args); | ||
| 16 | static void invert_exec(CommandArgs *args); | ||
| 17 | static void solve_exec(CommandArgs *args); | ||
| 18 | static void scramble_exec(CommandArgs *args); | ||
| 19 | static void steps_exec(CommandArgs *args); | ||
| 20 | static void commands_exec(CommandArgs *args); | ||
| 21 | static void freemem_exec(CommandArgs *args); | ||
| 22 | static void print_exec(CommandArgs *args); | ||
| 23 | static void twophase_exec(CommandArgs *args); | ||
| 24 | static void help_exec(CommandArgs *args); | ||
| 25 | static void quit_exec(CommandArgs *args); | ||
| 26 | static void unniss_exec(CommandArgs *args); | ||
| 27 | static void version_exec(CommandArgs *args); | ||
| 28 | |||
| 29 | /* Local functions ***********************************************************/ | ||
| 30 | 4 | ||
| 31 | static bool read_step(CommandArgs *args, char *str); | 5 | static bool read_step(CommandArgs *args, char *str); |
| 32 | static bool read_scrtype(CommandArgs *args, char *str); | 6 | static bool read_scrtype(CommandArgs *args, char *str); |
| 33 | static bool read_scramble(int c, char **v, CommandArgs *args); | 7 | static bool read_scramble(int c, char **v, CommandArgs *args); |
| 34 | 8 | ||
| 35 | /* Commands ******************************************************************/ | ||
| 36 | |||
| 37 | Command | ||
| 38 | solve_cmd = { | ||
| 39 | .name = "solve", | ||
| 40 | .usage = "solve STEP [OPTIONS] SCRAMBLE", | ||
| 41 | .description = "Solve a step; see command steps for a list of steps", | ||
| 42 | .parse_args = solve_parse_args, | ||
| 43 | .exec = solve_exec | ||
| 44 | }; | ||
| 45 | |||
| 46 | Command | ||
| 47 | scramble_cmd = { | ||
| 48 | .name = "scramble", | ||
| 49 | .usage = "scramble [TYPE] [-n N]", | ||
| 50 | .description = "Get a random-position scramble", | ||
| 51 | .parse_args = scramble_parse_args, | ||
| 52 | .exec = scramble_exec, | ||
| 53 | }; | ||
| 54 | |||
| 55 | Command | ||
| 56 | gen_cmd = { | ||
| 57 | .name = "gen", | ||
| 58 | .usage = "gen [-t N]", | ||
| 59 | .description = "Generate all tables [using N threads]", | ||
| 60 | .parse_args = gen_parse_args, | ||
| 61 | .exec = gen_exec | ||
| 62 | }; | ||
| 63 | |||
| 64 | Command | ||
| 65 | invert_cmd = { | ||
| 66 | .name = "invert", | ||
| 67 | .usage = "invert SCRAMBLE]", | ||
| 68 | .description = "Invert a scramble", | ||
| 69 | .parse_args = parse_only_scramble, | ||
| 70 | .exec = invert_exec, | ||
| 71 | }; | ||
| 72 | |||
| 73 | Command | ||
| 74 | steps_cmd = { | ||
| 75 | .name = "steps", | ||
| 76 | .usage = "steps", | ||
| 77 | .description = "List available steps", | ||
| 78 | .parse_args = parse_no_arg, | ||
| 79 | .exec = steps_exec | ||
| 80 | }; | ||
| 81 | |||
| 82 | Command | ||
| 83 | commands_cmd = { | ||
| 84 | .name = "commands", | ||
| 85 | .usage = "commands", | ||
| 86 | .description = "List available commands", | ||
| 87 | .parse_args = parse_no_arg, | ||
| 88 | .exec = commands_exec | ||
| 89 | }; | ||
| 90 | |||
| 91 | Command | ||
| 92 | freemem_cmd = { | ||
| 93 | .name = "freemem", | ||
| 94 | .usage = "freemem", | ||
| 95 | .description = "free large tables from RAM", | ||
| 96 | .parse_args = parse_no_arg, | ||
| 97 | .exec = freemem_exec, | ||
| 98 | }; | ||
| 99 | |||
| 100 | Command | ||
| 101 | print_cmd = { | ||
| 102 | .name = "print", | ||
| 103 | .usage = "print SCRAMBLE", | ||
| 104 | .description = "Print written description of the cube", | ||
| 105 | .parse_args = parse_only_scramble, | ||
| 106 | .exec = print_exec, | ||
| 107 | }; | ||
| 108 | |||
| 109 | Command | ||
| 110 | help_cmd = { | ||
| 111 | .name = "help", | ||
| 112 | .usage = "help [COMMAND]", | ||
| 113 | .description = "Display nissy manual page or help on specific command", | ||
| 114 | .parse_args = help_parse_args, | ||
| 115 | .exec = help_exec, | ||
| 116 | }; | ||
| 117 | |||
| 118 | Command | ||
| 119 | twophase_cmd = { | ||
| 120 | .name = "twophase", | ||
| 121 | .usage = "twophase", | ||
| 122 | .description = "Find a solution quickly using a 2-phase method", | ||
| 123 | .parse_args = parse_only_scramble, | ||
| 124 | .exec = twophase_exec, | ||
| 125 | }; | ||
| 126 | |||
| 127 | Command | ||
| 128 | quit_cmd = { | ||
| 129 | .name = "quit", | ||
| 130 | .usage = "quit", | ||
| 131 | .description = "Quit nissy", | ||
| 132 | .parse_args = parse_no_arg, | ||
| 133 | .exec = quit_exec, | ||
| 134 | }; | ||
| 135 | |||
| 136 | Command | ||
| 137 | cleanup_cmd = { | ||
| 138 | .name = "cleanup", | ||
| 139 | .usage = "cleanup SCRAMBLE", | ||
| 140 | .description = "Rewrite a scramble using only standard moves (HTM)", | ||
| 141 | .parse_args = parse_only_scramble, | ||
| 142 | .exec = cleanup_exec, | ||
| 143 | }; | ||
| 144 | |||
| 145 | Command | ||
| 146 | unniss_cmd = { | ||
| 147 | .name = "unniss", | ||
| 148 | .usage = "unniss SCRAMBLE", | ||
| 149 | .description = "Rewrite a scramble without NISS", | ||
| 150 | .parse_args = parse_only_scramble, | ||
| 151 | .exec = unniss_exec, | ||
| 152 | }; | ||
| 153 | |||
| 154 | Command | ||
| 155 | version_cmd = { | ||
| 156 | .name = "version", | ||
| 157 | .usage = "version", | ||
| 158 | .description = "print nissy version", | ||
| 159 | .parse_args = parse_no_arg, | ||
| 160 | .exec = version_exec, | ||
| 161 | }; | ||
| 162 | |||
| 163 | Command *commands[] = { | ||
| 164 | &commands_cmd, | ||
| 165 | &freemem_cmd, | ||
| 166 | &gen_cmd, | ||
| 167 | &help_cmd, | ||
| 168 | &invert_cmd, | ||
| 169 | &print_cmd, | ||
| 170 | &quit_cmd, | ||
| 171 | &solve_cmd, | ||
| 172 | &scramble_cmd, | ||
| 173 | &steps_cmd, | ||
| 174 | &twophase_cmd, | ||
| 175 | &cleanup_cmd, | ||
| 176 | &unniss_cmd, | ||
| 177 | &version_cmd, | ||
| 178 | NULL | ||
| 179 | }; | ||
| 180 | |||
| 181 | /* Other constants ***********************************************************/ | ||
| 182 | |||
| 183 | char *scrtypes[20] = { "eo", "corners", "edges", "fmc", "dr", "htr", NULL }; | ||
| 184 | |||
| 185 | /* Arg parsing functions implementation **************************************/ | 9 | /* Arg parsing functions implementation **************************************/ |
| 186 | 10 | ||
| 187 | CommandArgs * | 11 | CommandArgs * |
| @@ -386,17 +210,15 @@ parse_no_arg(int c, char **v) | |||
| 386 | 210 | ||
| 387 | /* Exec functions implementation *********************************************/ | 211 | /* Exec functions implementation *********************************************/ |
| 388 | 212 | ||
| 389 | static void | 213 | void |
| 390 | solve_exec(CommandArgs *args) | 214 | solve_exec(CommandArgs *args) |
| 391 | { | 215 | { |
| 392 | Cube c; | 216 | Cube c; |
| 393 | AlgList *sols; | 217 | AlgList *sols; |
| 394 | 218 | ||
| 395 | init_all_movesets(); | 219 | make_solved(&c); |
| 396 | init_symcoord(); | 220 | apply_alg(args->scramble, &c); |
| 397 | 221 | sols = solve(&c, args->step, args->opts); | |
| 398 | c = apply_alg(args->scramble, (Cube){0}); | ||
| 399 | sols = solve(c, args->step, args->opts); | ||
| 400 | 222 | ||
| 401 | if (args->opts->count_only) | 223 | if (args->opts->count_only) |
| 402 | printf("%d\n", sols->len); | 224 | printf("%d\n", sols->len); |
| @@ -406,85 +228,64 @@ solve_exec(CommandArgs *args) | |||
| 406 | free_alglist(sols); | 228 | free_alglist(sols); |
| 407 | } | 229 | } |
| 408 | 230 | ||
| 409 | static void | 231 | void |
| 410 | scramble_exec(CommandArgs *args) | 232 | scramble_exec(CommandArgs *args) |
| 411 | { | 233 | { |
| 412 | Cube cube; | 234 | Cube cube; |
| 413 | CubeArray *arr; | ||
| 414 | Alg *scr, *ruf, *aux; | 235 | Alg *scr, *ruf, *aux; |
| 415 | int i, j, eo, ep, co, cp, a[12]; | 236 | int i, j, eo, ep, co, cp; |
| 416 | int eparr[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 }; | ||
| 417 | uint64_t ui, uj, uk; | 237 | uint64_t ui, uj, uk; |
| 418 | 238 | ||
| 419 | init_all_movesets(); | ||
| 420 | init_symcoord(); | ||
| 421 | |||
| 422 | srand(time(NULL)); | 239 | srand(time(NULL)); |
| 423 | 240 | ||
| 424 | for (i = 0; i < args->n; i++) { | 241 | for (i = 0; i < args->n; i++) { |
| 425 | 242 | ||
| 426 | if (!strcmp(args->scrtype, "dr")) { | 243 | if (!strcmp(args->scrtype, "dr")) { |
| 427 | /* Warning: cube is inconsistent because of side CO * | 244 | ui = rand() % FACTORIAL8; |
| 428 | * and EO on U/D. But solve_2phase only solves drfin * | 245 | uj = rand() % FACTORIAL8; |
| 429 | * in this case, so it should be ok. * | 246 | uk = rand() % FACTORIAL4; |
| 430 | * TODO: check this properly * | ||
| 431 | * Moreover we again need to fix parity after * | ||
| 432 | * generating epose manually */ | ||
| 433 | do { | ||
| 434 | ui = rand() % FACTORIAL8; | ||
| 435 | uj = rand() % FACTORIAL8; | ||
| 436 | uk = rand() % FACTORIAL4; | ||
| 437 | |||
| 438 | index_to_perm(ui, 12, a); | ||
| 439 | arr = malloc(sizeof(CubeArray)); | ||
| 440 | arr->ep = eparr; | ||
| 441 | cube = arrays_to_cube(arr, pf_ep); | ||
| 442 | free(arr); | ||
| 443 | 247 | ||
| 444 | cube.cp = uj; | 248 | make_solved(&cube); |
| 445 | cube.epose += uk; | 249 | index_to_perm(ui, 8, cube.cp); |
| 446 | } while (!is_admissible(cube)); | 250 | index_to_perm(uj, 8, cube.ep); |
| 251 | index_to_perm(uk, 4, cube.ep + 8); | ||
| 252 | for (j = 8; j < 12; j++) | ||
| 253 | cube.ep[j] += 8; | ||
| 447 | } else if (!strcmp(args->scrtype, "htr")) { | 254 | } else if (!strcmp(args->scrtype, "htr")) { |
| 448 | /* antindex_htrfin() returns a consistent * | 255 | make_solved(&cube); |
| 449 | * cube, except possibly for parity */ | 256 | /* TODO */ |
| 450 | do { | ||
| 451 | ui = rand() % (24*24/6); | ||
| 452 | cube = (Cube){0}; | ||
| 453 | cube.cp = cornershtrfin_ant[ui]; | ||
| 454 | cube.epose = rand() % 24; | ||
| 455 | cube.eposs = rand() % 24; | ||
| 456 | cube.eposm = rand() % 24; | ||
| 457 | } while (!is_admissible(cube)); | ||
| 458 | } else { | 257 | } else { |
| 459 | eo = rand() % POW2TO11; | ||
| 460 | ep = rand() % FACTORIAL12; | 258 | ep = rand() % FACTORIAL12; |
| 461 | co = rand() % POW3TO7; | ||
| 462 | cp = rand() % FACTORIAL8; | 259 | cp = rand() % FACTORIAL8; |
| 260 | eo = rand() % POW2TO11; | ||
| 261 | co = rand() % POW3TO7; | ||
| 463 | 262 | ||
| 464 | if (!strcmp(args->scrtype, "eo")) { | 263 | if (!strcmp(args->scrtype, "eo")) { |
| 465 | eo = 0; | 264 | eo = 0; |
| 466 | } else if (!strcmp(args->scrtype, "corners")) { | 265 | } else if (!strcmp(args->scrtype, "corners")) { |
| 467 | eo = 0; | 266 | eo = 0; |
| 468 | ep = 0; | 267 | ep = 0; |
| 469 | index_to_perm(cp, 8, a); | ||
| 470 | if (perm_sign(a, 8) == 1) { | ||
| 471 | swap(&a[0], &a[1]); | ||
| 472 | cp = perm_to_index(a, 8); | ||
| 473 | } | ||
| 474 | } else if (!strcmp(args->scrtype, "edges")) { | 268 | } else if (!strcmp(args->scrtype, "edges")) { |
| 475 | co = 0; | 269 | co = 0; |
| 476 | cp = 0; | 270 | cp = 0; |
| 477 | index_to_perm(ep, 12, a); | ||
| 478 | if (perm_sign(a, 12) == 1) { | ||
| 479 | swap(&a[0], &a[1]); | ||
| 480 | ep = perm_to_index(a, 12); | ||
| 481 | } | ||
| 482 | } | 271 | } |
| 483 | cube = fourval_to_cube(eo, ep, co, cp); | 272 | |
| 273 | make_solved(&cube); | ||
| 274 | index_to_perm(ep, 12, cube.ep); | ||
| 275 | index_to_perm(cp, 8, cube.cp); | ||
| 276 | int_to_sum_zero_array(eo, 2, 12, cube.eo); | ||
| 277 | int_to_sum_zero_array(co, 3, 8, cube.co); | ||
| 278 | } | ||
| 279 | |||
| 280 | if (!is_admissible(&cube)) { | ||
| 281 | if (!strcmp(args->scrtype, "corners")) | ||
| 282 | swap(&cube.cp[UFR], &cube.cp[UFL]); | ||
| 283 | else | ||
| 284 | swap(&cube.ep[UF], &cube.ep[UB]); | ||
| 484 | } | 285 | } |
| 485 | 286 | ||
| 486 | /* TODO: can be optimized for htr and dr using htrfin, drfin */ | 287 | /* TODO: can be optimized for htr and dr using htrfin, drfin */ |
| 487 | scr = solve_2phase(cube, 1); | 288 | scr = solve_2phase(&cube, 1); |
| 488 | 289 | ||
| 489 | if (!strcmp(args->scrtype, "fmc")) { | 290 | if (!strcmp(args->scrtype, "fmc")) { |
| 490 | aux = new_alg(""); | 291 | aux = new_alg(""); |
| @@ -513,23 +314,22 @@ scramble_exec(CommandArgs *args) | |||
| 513 | } | 314 | } |
| 514 | } | 315 | } |
| 515 | 316 | ||
| 516 | static void | 317 | void |
| 517 | gen_exec(CommandArgs *args) | 318 | gen_exec(CommandArgs *args) |
| 518 | { | 319 | { |
| 320 | /* TODO: | ||
| 519 | int i; | 321 | int i; |
| 520 | 322 | ||
| 521 | fprintf(stderr, "Generating coordinates...\n"); | 323 | fprintf(stderr, "Generating coordinates...\n"); |
| 522 | init_all_movesets(); | ||
| 523 | init_symcoord(); | ||
| 524 | |||
| 525 | fprintf(stderr, "Generating pruning tables...\n"); | 324 | fprintf(stderr, "Generating pruning tables...\n"); |
| 526 | for (i = 0; all_pd[i] != NULL; i++) | 325 | for (i = 0; all_pd[i] != NULL; i++) |
| 527 | genptable(all_pd[i], args->opts->nthreads); | 326 | genptable(all_pd[i], args->opts->nthreads); |
| 327 | */ | ||
| 528 | 328 | ||
| 529 | fprintf(stderr, "Done!\n"); | 329 | fprintf(stderr, "Done!\n"); |
| 530 | } | 330 | } |
| 531 | 331 | ||
| 532 | static void | 332 | void |
| 533 | invert_exec(CommandArgs *args) | 333 | invert_exec(CommandArgs *args) |
| 534 | { | 334 | { |
| 535 | Alg *inv; | 335 | Alg *inv; |
| @@ -540,7 +340,7 @@ invert_exec(CommandArgs *args) | |||
| 540 | free_alg(inv); | 340 | free_alg(inv); |
| 541 | } | 341 | } |
| 542 | 342 | ||
| 543 | static void | 343 | void |
| 544 | steps_exec(CommandArgs *args) | 344 | steps_exec(CommandArgs *args) |
| 545 | { | 345 | { |
| 546 | int i; | 346 | int i; |
| @@ -549,7 +349,7 @@ steps_exec(CommandArgs *args) | |||
| 549 | printf("%-15s %s\n", steps[i]->shortname, steps[i]->name); | 349 | printf("%-15s %s\n", steps[i]->shortname, steps[i]->name); |
| 550 | } | 350 | } |
| 551 | 351 | ||
| 552 | static void | 352 | void |
| 553 | commands_exec(CommandArgs *args) | 353 | commands_exec(CommandArgs *args) |
| 554 | { | 354 | { |
| 555 | int i; | 355 | int i; |
| @@ -559,9 +359,10 @@ commands_exec(CommandArgs *args) | |||
| 559 | 359 | ||
| 560 | } | 360 | } |
| 561 | 361 | ||
| 562 | static void | 362 | void |
| 563 | freemem_exec(CommandArgs *args) | 363 | freemem_exec(CommandArgs *args) |
| 564 | { | 364 | { |
| 365 | /* TODO: | ||
| 565 | int i; | 366 | int i; |
| 566 | 367 | ||
| 567 | for (i = 0; all_pd[i] != NULL; i++) | 368 | for (i = 0; all_pd[i] != NULL; i++) |
| @@ -569,35 +370,34 @@ freemem_exec(CommandArgs *args) | |||
| 569 | 370 | ||
| 570 | for (i = 0; all_sd[i] != NULL; i++) | 371 | for (i = 0; all_sd[i] != NULL; i++) |
| 571 | free_sd(all_sd[i]); | 372 | free_sd(all_sd[i]); |
| 572 | 373 | */ | |
| 573 | /* TODO: invtables are also large, but for now they are * | ||
| 574 | * statically allocated. Consider releasing those too. */ | ||
| 575 | } | 374 | } |
| 576 | 375 | ||
| 577 | static void | 376 | void |
| 578 | print_exec(CommandArgs *args) | 377 | print_exec(CommandArgs *args) |
| 579 | { | 378 | { |
| 580 | init_moves(); | 379 | Cube c; |
| 581 | print_cube(apply_alg(args->scramble, (Cube){0})); | 380 | |
| 381 | make_solved(&c); | ||
| 382 | apply_alg(args->scramble, &c); | ||
| 383 | print_cube(&c); | ||
| 582 | } | 384 | } |
| 583 | 385 | ||
| 584 | static void | 386 | void |
| 585 | twophase_exec(CommandArgs *args) | 387 | twophase_exec(CommandArgs *args) |
| 586 | { | 388 | { |
| 587 | Cube c; | 389 | Cube c; |
| 588 | Alg *sol; | 390 | Alg *sol; |
| 589 | 391 | ||
| 590 | init_all_movesets(); | 392 | make_solved(&c); |
| 591 | init_symcoord(); | 393 | apply_alg(args->scramble, &c); |
| 592 | 394 | sol = solve_2phase(&c, 1); | |
| 593 | c = apply_alg(args->scramble, (Cube){0}); | ||
| 594 | sol = solve_2phase(c, 1); | ||
| 595 | 395 | ||
| 596 | print_alg(sol, false); | 396 | print_alg(sol, false); |
| 597 | free_alg(sol); | 397 | free_alg(sol); |
| 598 | } | 398 | } |
| 599 | 399 | ||
| 600 | static void | 400 | void |
| 601 | help_exec(CommandArgs *args) | 401 | help_exec(CommandArgs *args) |
| 602 | { | 402 | { |
| 603 | if (args->command == NULL) { | 403 | if (args->command == NULL) { |
| @@ -619,26 +419,24 @@ help_exec(CommandArgs *args) | |||
| 619 | } | 419 | } |
| 620 | } | 420 | } |
| 621 | 421 | ||
| 622 | static void | 422 | void |
| 623 | quit_exec(CommandArgs *args) | 423 | quit_exec(CommandArgs *args) |
| 624 | { | 424 | { |
| 625 | exit(0); | 425 | exit(0); |
| 626 | } | 426 | } |
| 627 | 427 | ||
| 628 | static void | 428 | void |
| 629 | cleanup_exec(CommandArgs *args) | 429 | cleanup_exec(CommandArgs *args) |
| 630 | { | 430 | { |
| 631 | Alg *alg; | 431 | Alg *alg; |
| 632 | 432 | ||
| 633 | init_moves(); | ||
| 634 | |||
| 635 | alg = cleanup(args->scramble); | 433 | alg = cleanup(args->scramble); |
| 636 | print_alg(alg, false); | 434 | print_alg(alg, false); |
| 637 | 435 | ||
| 638 | free_alg(alg); | 436 | free_alg(alg); |
| 639 | } | 437 | } |
| 640 | 438 | ||
| 641 | static void | 439 | void |
| 642 | unniss_exec(CommandArgs *args) | 440 | unniss_exec(CommandArgs *args) |
| 643 | { | 441 | { |
| 644 | Alg *aux; | 442 | Alg *aux; |
| @@ -648,7 +446,7 @@ unniss_exec(CommandArgs *args) | |||
| 648 | free(aux); | 446 | free(aux); |
| 649 | } | 447 | } |
| 650 | 448 | ||
| 651 | static void | 449 | void |
| 652 | version_exec(CommandArgs *args) | 450 | version_exec(CommandArgs *args) |
| 653 | { | 451 | { |
| 654 | printf(VERSION"\n"); | 452 | printf(VERSION"\n"); |
| @@ -691,6 +489,8 @@ static bool | |||
| 691 | read_scrtype(CommandArgs *args, char *str) | 489 | read_scrtype(CommandArgs *args, char *str) |
| 692 | { | 490 | { |
| 693 | int i; | 491 | int i; |
| 492 | static char *scrtypes[20] = | ||
| 493 | { "eo", "corners", "edges", "fmc", "dr", "htr", NULL }; | ||
| 694 | 494 | ||
| 695 | for (i = 0; scrtypes[i] != NULL; i++) { | 495 | for (i = 0; scrtypes[i] != NULL; i++) { |
| 696 | if (!strcmp(scrtypes[i], str)) { | 496 | if (!strcmp(scrtypes[i], str)) { |
