Ejemplo n.º 1
0
static void my_iter_handler(void *const user_instance,
    const fcs_int_limit_t iter_num, const int depth, void *const ptr_state,
    const fcs_int_limit_t parent_iter_num, void *const context)
{
    const fc_solve_display_information_context_t *const display_context =
        (const fc_solve_display_information_context_t *const)context;
    my_iter_handler_base(
        iter_num, depth, user_instance, display_context, parent_iter_num);
    if (display_context->debug_iter_state_output)
    {
        char state_string[1000];
        freecell_solver_user_iter_state_stringify(user_instance, state_string,
            ptr_state FC_SOLVE__PASS_PARSABLE(TRUE),
            FALSE FC_SOLVE__PASS_T(TRUE));
        printf("%s\n---------------\n\n\n", state_string);
        /* Now pass it to a secondary user_instance prune it. */
        {
            void *const pruner = freecell_solver_user_alloc();

            freecell_solver_user_set_num_freecells(pruner, 2);
#ifdef FCS_WITH_ERROR_STRS
            char *error_string;
#endif
            freecell_solver_user_set_tests_order(
                pruner, "01ABCDE" FCS__PASS_ERR_STR(&error_string));
#ifdef FCS_WITH_ERROR_STRS
            free(error_string);
#endif
            freecell_solver_user_limit_iterations_long(pruner, 128 * 1024);

            const int ret =
                freecell_solver_user_solve_board(pruner, state_string);
            switch (ret)
            {
            case FCS_STATE_SUSPEND_PROCESS:
                printf("\n\nVerdict: INDETERMINATE\n\n");
                break;

            case FCS_STATE_WAS_SOLVED:
                printf("\n\nVerdict: SOLVED\n\nYay! We found a solution from "
                       "this one.");
                exit(0);
                break;

            case FCS_STATE_IS_NOT_SOLVEABLE:
                printf("\n\nVerdict: PRUNED\n\n");
                break;

            default:
                printf("\n\nVerdict: unknown ret code: %d\n\n", ret);
                exit(-1);
                break;
            }
            freecell_solver_user_free(pruner);
        }
    }
}
Ejemplo n.º 2
0
int freecell_solver_user_cmd_line_parse_args_with_file_nesting_count(
    void * instance,
    int argc,
    char * argv[],
    int start_arg,
    char * * known_parameters,
    freecell_solver_user_cmd_line_known_commands_callback_t callback,
    void * callback_context,
    char * * error_string,
    int * last_arg,
    int file_nesting_count,
    char * opened_files_dir
    )
{
    char * * arg, * * arg_argc;
    char * * known_param;
    int num_to_skip;
    int callback_ret;
    int ret;
    int opt;
    const char * p;

    *error_string = NULL;

    arg_argc = &(argv[argc]);

    for(arg=&(argv[start_arg]);arg<arg_argc;arg++)
    {
        /* First check for the parameters that the user recognizes */
        known_param = known_parameters;
        while((*known_param) && strcmp(*known_param, (*arg)))
        {
            known_param++;
        }
        if ((*known_param) != NULL )
        {
            callback_ret = callback(instance, argc, argv, arg-&(argv[0]), &num_to_skip, &ret, callback_context);
            if (callback_ret == FCS_CMD_LINE_SKIP)
            {
                arg += num_to_skip-1;
                continue;
            }
            else if (callback_ret == FCS_CMD_LINE_STOP)
            {
                *last_arg = arg-&(argv[0]);
                return ret;
            }
        }

        /* OPT-PARSE-START */
p = (*arg);
opt = FCS_OPT_UNRECOGNIZED;

{
if (*(p++) == '-')
{
{ switch(*(p++)) { 
case '-':
{ switch(*(p++)) { 
case 'a':
{
if (!strncmp(p, "-star-weights", 13)) {
p += 13;
opt = FCS_OPT_A_STAR_WEIGHTS;

}
}

break;

case 'c':
{
if (!strncmp(p, "alc-real-depth", 14)) {
p += 14;
opt = FCS_OPT_CALC_REAL_DEPTH;

}
}

break;

case 'd':
{
if (!strncmp(p, "ecks-num", 8)) {
p += 8;
opt = FCS_OPT_DECKS_NUM;

}
}

break;

case 'e':
{
if (!strncmp(p, "mpty-stacks-filled-by", 21)) {
p += 21;
opt = FCS_OPT_EMPTY_STACKS_FILLED_BY;

}
}

break;

case 'f':
{
if (!strncmp(p, "reecells-num", 12)) {
p += 12;
opt = FCS_OPT_FREECELLS_NUM;

}
}

break;

case 'g':
{
if (!strncmp(p, "ame", 3)) {
p += 3;
opt = FCS_OPT_GAME;

}
}

break;

case 'l':
{
if (!strncmp(p, "oad-config", 10)) {
p += 10;
opt = FCS_OPT_LOAD_CONFIG;

}
}

break;

case 'm':
{ switch(*(p++)) { 
case 'a':
{
if (!strncmp(p, "x-", 2)) {
p += 2;
{ switch(*(p++)) { 
case 'd':
{
if (!strncmp(p, "epth", 4)) {
p += 4;
opt = FCS_OPT_MAX_DEPTH;

}
}

break;

case 'i':
{
if (!strncmp(p, "ters", 4)) {
p += 4;
opt = FCS_OPT_MAX_ITERS;

}
}

break;

case 's':
{
if (!strncmp(p, "tored-states", 12)) {
p += 12;
opt = FCS_OPT_MAX_STORED_STATES;

}
}

break;

}
}

}
}

break;

case 'e':
{
if (!strncmp(p, "thod", 4)) {
p += 4;
opt = FCS_OPT_METHOD;

}
}

break;

}
}

break;

case 'n':
{
if (!strncmp(p, "ext-", 4)) {
p += 4;
{ switch(*(p++)) { 
case 'h':
{
if (!strncmp(p, "ard-thread", 10)) {
p += 10;
opt = FCS_OPT_NEXT_HARD_THREAD;

}
}

break;

case 's':
{
if (!strncmp(p, "oft-thread", 10)) {
p += 10;
opt = FCS_OPT_NEXT_SOFT_THREAD;

}
}

break;

}
}

}
}

break;

case 'o':
{
if (!strncmp(p, "ptimiz", 6)) {
p += 6;
{ switch(*(p++)) { 
case 'a':
{
if (!strncmp(p, "tion-tests-order", 16)) {
p += 16;
opt = FCS_OPT_OPTIMIZATION_TESTS_ORDER;

}
}

break;

case 'e':
{
if (!strncmp(p, "-solution", 9)) {
p += 9;
opt = FCS_OPT_OPTIMIZE_SOLUTION;

}
}

break;

}
}

}
}

break;

case 'p':
{
if (!strncmp(p, "re", 2)) {
p += 2;
{ switch(*(p++)) { 
case 'l':
{
if (!strncmp(p, "ude", 3)) {
p += 3;
opt = FCS_OPT_PRELUDE;

}
}

break;

case 's':
{
if (!strncmp(p, "et", 2)) {
p += 2;
opt = FCS_OPT_GAME;

}
}

break;

}
}

}
}

break;

case 'r':

{
if (*(p++) == 'e')
{
{ switch(*(p++)) { 
case 'a':
{
if (!strncmp(p, "d-from-file", 11)) {
p += 11;
opt = FCS_OPT_READ_FROM_FILE;

}
}

break;

case 'p':
{
if (!strncmp(p, "arent-states", 12)) {
p += 12;
opt = FCS_OPT_REPARENT_STATES;

}
}

break;

case 's':
{
if (!strncmp(p, "et", 2)) {
p += 2;
opt = FCS_OPT_RESET;

}
}

break;

}
}

}

}

break;

case 's':
{ switch(*(p++)) { 
case 'c':
{
if (!strncmp(p, "ans-synergy", 11)) {
p += 11;
opt = FCS_OPT_SCANS_SYNERGY;

}
}

break;

case 'e':
{
if (!strncmp(p, "quence", 6)) {
p += 6;
{ switch(*(p++)) { 
case '-':
{
if (!strncmp(p, "move", 4)) {
p += 4;
opt = FCS_OPT_SEQUENCE_MOVE;

}
}

break;

case 's':
{
if (!strncmp(p, "-are-built-by", 13)) {
p += 13;
opt = FCS_OPT_SEQUENCES_ARE_BUILT_BY;

}
}

break;

}
}

}
}

break;

case 'o':
{
if (!strncmp(p, "ft-thread-step", 14)) {
p += 14;
opt = FCS_OPT_SOFT_THREAD_STEP;

}
}

break;

case 't':
{ switch(*(p++)) { 
case '-':
{
if (!strncmp(p, "name", 4)) {
p += 4;
opt = FCS_OPT_ST_NAME;

}
}

break;

case 'a':
{
if (!strncmp(p, "cks-num", 7)) {
p += 7;
opt = FCS_OPT_STACKS_NUM;

}
}

break;

}
}

break;

}
}

break;

case 't':
{
if (!strncmp(p, "ests-order", 10)) {
p += 10;
opt = FCS_OPT_TESTS_ORDER;

}
}

break;

}
}

break;

case 'a':
{
if (!strncmp(p, "sw", 2)) {
p += 2;
opt = FCS_OPT_A_STAR_WEIGHTS;

}
}

break;

case 'g':

{
if (*p == '\0')
{

opt = FCS_OPT_GAME;
}
}

break;

case 'l':

{
if (*p == '\0')
{

opt = FCS_OPT_LOAD_CONFIG;
}
}

break;

case 'm':
{ switch(*(p++)) { 
case 'd':

{
if (*p == '\0')
{

opt = FCS_OPT_MAX_DEPTH;
}
}

break;

case 'e':

{
if (*p == '\0')
{

opt = FCS_OPT_METHOD;
}
}

break;

case 'i':

{
if (*p == '\0')
{

opt = FCS_OPT_MAX_ITERS;
}
}

break;

case 's':
{
if (!strncmp(p, "s", 1)) {
p += 1;
opt = FCS_OPT_MAX_STORED_STATES;

}
}

break;

}
}

break;

case 'n':
{ switch(*(p++)) { 
case 'h':
{
if (!strncmp(p, "t", 1)) {
p += 1;
opt = FCS_OPT_NEXT_HARD_THREAD;

}
}

break;

case 's':
{
if (!strncmp(p, "t", 1)) {
p += 1;
opt = FCS_OPT_NEXT_SOFT_THREAD;

}
}

break;

}
}

break;

case 'o':
{
if (!strncmp(p, "pt", 2)) {
p += 2;
{ switch(*(p++)) { 
case '\0':
{
opt = FCS_OPT_OPTIMIZE_SOLUTION;
}

break;

case '-':
{
if (!strncmp(p, "to", 2)) {
p += 2;
opt = FCS_OPT_OPTIMIZATION_TESTS_ORDER;

}
}

break;

}
}

}
}

break;

case 's':
{ switch(*(p++)) { 
case 'e':
{
if (!strncmp(p, "ed", 2)) {
p += 2;
opt = FCS_OPT_SEED;

}
}

break;

case 't':
{
if (!strncmp(p, "ep", 2)) {
p += 2;
opt = FCS_OPT_SOFT_THREAD_STEP;

}
}

break;

}
}

break;

case 't':
{
if (!strncmp(p, "o", 1)) {
p += 1;
opt = FCS_OPT_TESTS_ORDER;

}
}

break;

}
}

}

}
        switch (opt)
        {
        case FCS_OPT_UNRECOGNIZED:
        {
            *last_arg = arg-&(argv[0]);
            return FCS_CMD_LINE_UNRECOGNIZED_OPTION;
        }
        break;

#define PROCESS_OPT_ARG() \
        { \
            arg++; \
            if (arg == arg_argc) \
            { \
                *last_arg = arg-&(argv[0]); \
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG; \
            } \
        }

#define RET_ERROR_IN_ARG() \
        *last_arg = arg-&(argv[0]); \
        return FCS_CMD_LINE_ERROR_IN_ARG;

        case FCS_OPT_MAX_DEPTH: /* STRINGS=-md|--max-depth; */
        {
            PROCESS_OPT_ARG() ;
            freecell_solver_user_limit_depth(instance, atoi((*arg)));
        }
        break;

        case FCS_OPT_MAX_ITERS: /* STRINGS=-mi|--max-iters; */
        {
            PROCESS_OPT_ARG() ;

            freecell_solver_user_limit_current_instance_iterations(instance, atoi((*arg)));
        }
        break;

        case FCS_OPT_TESTS_ORDER: /* STRINGS=-to|--tests-order; */
        {
            char * fcs_user_errstr;

            PROCESS_OPT_ARG() ;

            ret = freecell_solver_user_set_tests_order(instance, (*arg), &fcs_user_errstr);
            if (ret != 0)
            {
                char * errstr = malloc(strlen(fcs_user_errstr)+500);
                sprintf(
                    errstr,
                    "Error in tests' order!\n%s\n",
                    fcs_user_errstr
                    );
                free(fcs_user_errstr);

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
        }
        break;

        case FCS_OPT_FREECELLS_NUM: /* STRINGS=--freecells-num; */
        {
            PROCESS_OPT_ARG() ;
            if (freecell_solver_user_set_num_freecells(instance, atoi((*arg))) != 0)
            {
                char * errstr;

                errstr = malloc(500);
                sprintf(errstr,
                    "Error! The freecells\' number "
                    "exceeds the maximum of %i.\n"
                    "Recompile the program if you wish to have more.\n",
                    freecell_solver_user_get_max_num_freecells()
                    );

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
        }
        break;

        case FCS_OPT_STACKS_NUM: /* STRINGS=--stacks-num; */
        {
            PROCESS_OPT_ARG() ;
            if (freecell_solver_user_set_num_stacks(instance, atoi((*arg))) != 0)
            {
                char * errstr;

                errstr = malloc(500);
                sprintf(errstr,
                    "Error! The stacks\' number "
                    "exceeds the maximum of %i.\n"
                    "Recompile the program if you wish to have more.\n",
                    freecell_solver_user_get_max_num_stacks()
                    );

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
        }
        break;

        case FCS_OPT_DECKS_NUM: /* STRINGS=--decks-num; */
        {
            PROCESS_OPT_ARG() ;
            if (freecell_solver_user_set_num_decks(instance, atoi((*arg))) != 0)
            {
                char * errstr;

                errstr = malloc(500);
                sprintf(errstr,
                    "Error! The decks\' number "
                    "exceeds the maximum of %i.\n"
                    "Recopmile the program if you wish to have more.\n",
                    freecell_solver_user_get_max_num_decks()
                    );

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
        }
        break;

        case FCS_OPT_SEQUENCES_ARE_BUILT_BY: /* STRINGS=--sequences-are-built-by; */
        {
            int sbb;

            PROCESS_OPT_ARG() ;

            if (!strcmp((*arg), "suit"))
            {
                sbb = FCS_SEQ_BUILT_BY_SUIT;
            }
            else if (!strcmp((*arg), "rank"))
            {
                sbb = FCS_SEQ_BUILT_BY_RANK;
            }
            else
            {
                sbb = FCS_SEQ_BUILT_BY_ALTERNATE_COLOR;
            }
            freecell_solver_user_set_sequences_are_built_by_type(instance, sbb);
        }
        break;

        case FCS_OPT_SEQUENCE_MOVE: /* STRINGS=--sequence-move; */
        {
            int unlimited;

            PROCESS_OPT_ARG() ;

            if (!strcmp((*arg), "unlimited"))
            {
                unlimited = 1;
            }
            else
            {
                unlimited = 0;
            }
            freecell_solver_user_set_sequence_move(instance, unlimited);
        }
        break;

        case FCS_OPT_EMPTY_STACKS_FILLED_BY: /* STRINGS=--empty-stacks-filled-by; */
        {
            int es_fill;

            PROCESS_OPT_ARG() ;

            if (!strcmp((*arg), "kings"))
            {
                es_fill = FCS_ES_FILLED_BY_KINGS_ONLY;
            }
            else if (!strcmp((*arg), "none"))
            {
                es_fill = FCS_ES_FILLED_BY_NONE;
            }
            else
            {
                es_fill = FCS_ES_FILLED_BY_ANY_CARD;
            }
            freecell_solver_user_set_empty_stacks_filled_by(
                instance,
                es_fill
                );
        }
        break;

        case FCS_OPT_GAME: /* STRINGS=--game|--preset|-g; */
        {
            PROCESS_OPT_ARG() ;

            ret = freecell_solver_user_apply_preset(instance, (*arg));
            if (ret == FCS_PRESET_CODE_NOT_FOUND)
            {
                char * errstr;

                errstr = malloc(strlen((*arg))+500);

                sprintf(errstr, "Unknown game \"%s\"!\n\n", (*arg));
                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
            else if (ret == FCS_PRESET_CODE_FREECELLS_EXCEED_MAX)
            {
                char * errstr;

                errstr = malloc(strlen((*arg))+500);
                sprintf(errstr, "The game \"%s\" exceeds the maximal number "
                        "of freecells in the program.\n"
                        "Modify the file \"config.h\" and recompile, "
                        "if you wish to solve one of its boards.\n",
                        (*arg)
                        );

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
            else if (ret == FCS_PRESET_CODE_STACKS_EXCEED_MAX)
            {
                char * errstr;

                errstr = malloc(strlen((*arg))+500);

                sprintf(errstr, "The game \"%s\" exceeds the maximal number "
                        "of stacks in the program.\n"
                        "Modify the file \"config.h\" and recompile, "
                        "if you wish to solve one of its boards.\n",
                        (*arg)
                        );

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
            else if (ret != FCS_PRESET_CODE_OK)
            {
                char * errstr;

                errstr = malloc(strlen((*arg))+500);

                sprintf(errstr,
                    "The game \"%s\" exceeds the limits of the program.\n"
                    "Modify the file \"config.h\" and recompile, if you wish to solve one of its boards.\n",
                    (*arg)
                );

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
        }
        break;

        case FCS_OPT_METHOD: /* STRINGS=-me|--method; */
        {
            int method;

            PROCESS_OPT_ARG() ;

            if (!strcmp((*arg), "dfs"))
            {
                method = FCS_METHOD_HARD_DFS;
            }
            else if (!strcmp((*arg), "soft-dfs"))
            {
                method = FCS_METHOD_SOFT_DFS;
            }
            else if (!strcmp((*arg), "bfs"))
            {
                method = FCS_METHOD_BFS;
            }
            else if (!strcmp((*arg), "a-star"))
            {
                method = FCS_METHOD_A_STAR;
            }
            else if (!strcmp((*arg), "random-dfs"))
            {
                method = FCS_METHOD_RANDOM_DFS;
            }
            else
            {
                char * errstr;

                errstr = malloc(strlen((*arg))+500);

                sprintf(
                    errstr,
                    "Unknown solving method \"%s\".\n",
                    (*arg)
                    );

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }

            freecell_solver_user_set_solving_method(instance, method);
        }
        break;

        case FCS_OPT_A_STAR_WEIGHTS: /* STRINGS=-asw|--a-star-weights; */
        {
            PROCESS_OPT_ARG() ;

            {
                int a;
                char * start_num;
                char * end_num;
                char save;
                start_num = (*arg);
                for(a=0;a<5;a++)
                {
                    while ((*start_num > '9') && (*start_num < '0') && (*start_num != '\0'))
                    {
                        start_num++;
                    }
                    if (*start_num == '\0')
                    {
                        break;
                    }
                    end_num = start_num+1;
                    while ((((*end_num >= '0') && (*end_num <= '9')) || (*end_num == '.')) && (*end_num != '\0'))
                    {
                        end_num++;
                    }
                    save = *end_num;
                    *end_num = '\0';
                    freecell_solver_user_set_a_star_weight(
                        instance,
                        a,
                        atof(start_num)
                        );
                    *end_num = save;
                    start_num=end_num+1;
                }
            }
        }
        break;

        case FCS_OPT_OPTIMIZE_SOLUTION: /* STRINGS=-opt|--optimize-solution; */
        {
            freecell_solver_user_set_solution_optimization(instance, 1);
        }
        break;

        case FCS_OPT_SEED: /* STRINGS=-seed; */
        {
            PROCESS_OPT_ARG() ;

            freecell_solver_user_set_random_seed(instance, atoi((*arg)));
        }
        break;

        case FCS_OPT_MAX_STORED_STATES: /* STRINGS=-mss|--max-stored-states; */
        {
            PROCESS_OPT_ARG() ;

            freecell_solver_user_limit_num_states_in_collection(
                instance,
                atoi((*arg))
            );
        }
        break;

        case FCS_OPT_NEXT_SOFT_THREAD: /* STRINGS=-nst|--next-soft-thread; */
        case FCS_OPT_NEXT_HARD_THREAD: /* STRINGS=-nht|--next-hard-thread; */
        {
            int ret;

            ret =
                (opt == FCS_OPT_NEXT_SOFT_THREAD)
                    ? freecell_solver_user_next_soft_thread(instance)
                    : freecell_solver_user_next_hard_thread(instance)
                    ;

            if (ret)
            {
                char * errstr;

                errstr = strdup("The maximal number of soft threads has been exceeded\n");

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
        }
        break;

        case FCS_OPT_SOFT_THREAD_STEP: /* STRINGS=-step|--soft-thread-step; */
        {
            PROCESS_OPT_ARG() ;

            freecell_solver_user_set_soft_thread_step(
                instance,
                atoi((*arg))
            );
        }
        break;

        case FCS_OPT_REPARENT_STATES: /* STRINGS=--reparent-states; */
        {
            freecell_solver_user_set_reparent_states(
                instance,
                1
                );
        }
        break;

        case FCS_OPT_CALC_REAL_DEPTH: /* STRINGS=--calc-real-depth; */
        {
            freecell_solver_user_set_calc_real_depth(
                instance,
                1);
        }
        break;

        case FCS_OPT_ST_NAME: /* STRINGS=--st-name; */
        {
            PROCESS_OPT_ARG() ;

            freecell_solver_user_set_soft_thread_name(instance, (*arg));
        }
        break;

        case FCS_OPT_PRELUDE: /* STRINGS=--prelude; */
        {
            PROCESS_OPT_ARG() ;

            freecell_solver_user_set_hard_thread_prelude(instance, (*arg));
        }
        break;

        case FCS_OPT_OPTIMIZATION_TESTS_ORDER: /* STRINGS=-opt-to|--optimization-tests-order; */
        {
            char * fcs_user_errstr;
            
            PROCESS_OPT_ARG() ;

            ret = freecell_solver_user_set_optimization_scan_tests_order(
                    instance,
                    (*arg),
                    &fcs_user_errstr
                    );

            if (ret != 0)
            {
                char * errstr = malloc(strlen(fcs_user_errstr)+500);
                sprintf(
                    errstr,
                    "Error in the optimization scan's tests' order!\n%s\n",
                    fcs_user_errstr
                    );
                free(fcs_user_errstr);

                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }
        }
        break;

        case FCS_OPT_SCANS_SYNERGY: /* STRINGS=--scans-synergy; */
        {
            int value;

            PROCESS_OPT_ARG() ;

            if (!strcmp((*arg), "none"))
            {
                value = 0;
            }
            else if (!strcmp((*arg), "dead-end-marks"))
            {
                value = 1;
            }
            else
            {
                char * errstr;

                errstr = malloc(strlen((*arg))+500);

                sprintf(errstr, "Unknown scans' synergy type \"%s\"!\n", (*arg));
                *error_string = errstr;

                RET_ERROR_IN_ARG() ;
            }

            freecell_solver_user_set_scans_synergy(
                instance,
                value
                );
        }
        break;

        case FCS_OPT_RESET: /* STRINGS=--reset; */
        {
            freecell_solver_user_reset(instance);
        }
        break;

        case FCS_OPT_READ_FROM_FILE: /* STRINGS=--read-from-file; */
        {
            PROCESS_OPT_ARG() ;

            if (file_nesting_count == 0)
            {
                /* do nothing */
            }
            else
            {
                int num_to_skip = 0;
                char * s, * buffer;
                FILE * f;
                long file_len;
                int ret;
                size_t num_read;
                args_man_t * args_man;

                s = (*arg);
                while(isdigit(*s))
                {
                    s++;
                }
                if (*s == ',')
                {
                    num_to_skip = atoi((*arg));
                    s++;
                }

                if (opened_files_dir)
                {
                    char * complete_path;

                    complete_path = malloc(strlen(opened_files_dir)+strlen(s)+1);
                    sprintf(complete_path, "%s%s", opened_files_dir, s);
                    f = fopen(complete_path, "rt");
                    free(complete_path);
                }
                else
                {
                    /* 
                     * Initialize f to NULL so it will be initialized
                     * */
                    f = NULL;
                }

                /* Try to open from the local path */                
                if (f == NULL)
                {
                    f = fopen(s, "rt");
                }
                
                /* If we still could not open it return an error */
                if (f == NULL)
                {
                    char * err_str;

                    err_str = malloc(strlen(s)+100);
                    sprintf(err_str,
                            "Could not open file \"%s\"!\nQuitting.\n",
                            s);

                    *error_string = err_str;

                    RET_ERROR_IN_ARG() ;
                }
                fseek(f, 0, SEEK_END);
                file_len = ftell(f);
                buffer=malloc(file_len+1);
                if (buffer == NULL)
                {
                    *error_string = strdup("Could not allocate enough memory to parse the file. Quitting.\n");
                    fclose(f);

                    RET_ERROR_IN_ARG() ;
                }
                fseek(f,0,SEEK_SET);
                num_read = fread(buffer, 1, file_len, f);
                fclose(f);
                buffer[num_read] = '\0';

                args_man = fc_solve_args_man_alloc();
                ret = fc_solve_args_man_chop(args_man, buffer);
                free(buffer);
                if (ret != 0)
                {
                    *error_string =
                        strdup("Could not parse the file. Quitting\n");
                    fc_solve_args_man_free(args_man);

                    RET_ERROR_IN_ARG() ;
                }

                if (num_to_skip >= args_man->argc)
                {
                    /* Do nothing */
                }
                else
                {
                    ret = freecell_solver_user_cmd_line_parse_args_with_file_nesting_count(
                        instance,
                        args_man->argc - num_to_skip,
                        args_man->argv + num_to_skip,
                        0,
                        known_parameters,
                        callback,
                        callback_context,
                        error_string,
                        last_arg,
                        ((file_nesting_count < 0) ? file_nesting_count : (file_nesting_count-1)),
                        opened_files_dir
                        );

                    if (ret == FCS_CMD_LINE_UNRECOGNIZED_OPTION)
                    {
                        /* Do nothing - continue */
                    }
                    else if (ret != FCS_CMD_LINE_OK)
                    {
                        fc_solve_args_man_free(args_man);
                        return ret;
                    }
                }
                fc_solve_args_man_free(args_man);
            }
        }
        break;

        case FCS_OPT_LOAD_CONFIG: /* STRINGS=-l|--load-config; */
        {
            PROCESS_OPT_ARG() ;

            {
                int status;
                args_man_t * preset_args;
                char * dir = NULL;

                status = read_preset((*arg), &preset_args, &dir, NULL);
                if (status != 0)
                {
                    char * err_str;
                    err_str = malloc(strlen((*arg)) + 100);
                    sprintf(err_str, "Unable to load the \"%s\" configuration!\n", (*arg));
                    *error_string = err_str;

                    RET_ERROR_IN_ARG() ;
                }
                else
                {
                    ret = freecell_solver_user_cmd_line_parse_args_with_file_nesting_count(
                        instance,
                        preset_args->argc,
                        preset_args->argv,
                        0,
                        known_parameters,
                        callback,
                        callback_context,
                        error_string,
                        last_arg,
                        ((file_nesting_count < 0) ? file_nesting_count : (file_nesting_count-1)),
                        dir ? dir : opened_files_dir
                        );

                    if (dir)
                    {
                        free(dir);
                    }
                    fc_solve_args_man_free(preset_args);

                    if (ret == FCS_CMD_LINE_UNRECOGNIZED_OPTION)
                    {
                        /* Do nothing - continue */
                    }
                    else if (ret != FCS_CMD_LINE_OK)
                    {
                        return ret;
                    }
                }
            }
        }
        break;


        }
        /* OPT-PARSE-END */
    }

    *last_arg = arg-&(argv[0]);
    return FCS_CMD_LINE_OK;
}
Ejemplo n.º 3
0
int freecell_solver_user_cmd_line_parse_args(
    void * instance,
    int argc,
    char * argv[],
    int start_arg,
    char * * known_parameters,
    freecell_solver_user_cmd_line_known_commands_callback_t callback,
    void * callback_context,
    char * * error_string,
    int * last_arg
    )
{
    int arg;
    char * * known_param;
    int num_to_skip;
    int callback_ret;
    int ret;

    *error_string = NULL;

    for(arg=start_arg;arg<argc;arg++)
    {
        /* First check for the parameters that the user recognizes */
        known_param = known_parameters;
        while((*known_param) && strcmp(*known_param, argv[arg]))
        {
            known_param++;
        }
        if ((*known_param) != NULL )
        {
            callback_ret = callback(instance, argc, argv, arg, &num_to_skip, &ret, callback_context);
            if (callback_ret == FCS_CMD_LINE_SKIP)
            {
                arg += num_to_skip-1;
                continue;
            }
            else if (callback_ret == FCS_CMD_LINE_STOP)
            {
                *last_arg = arg;
                return ret;
            }
        }

        if (0)
        {
        }
        else if ((!strcmp(argv[arg], "-md")) || (!strcmp(argv[arg], "--max-depth")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }
            freecell_solver_user_limit_depth(instance, atoi(argv[arg]));
        }
        else if ((!strcmp(argv[arg], "-mi")) || (!strcmp(argv[arg], "--max-iters")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            freecell_solver_user_limit_iterations(instance, atoi(argv[arg]));
        }
        else if ((!strcmp(argv[arg], "-to")) || (!strcmp(argv[arg], "--tests-order")))
        {
            char * fcs_user_errstr;
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }
            ret = freecell_solver_user_set_tests_order(instance, argv[arg], &fcs_user_errstr);
            if (ret != 0)
            {
                char * errstr = malloc(strlen(fcs_user_errstr)+500);
                sprintf(
                    errstr,
                    "Error in tests' order!\n%s\n",
                    fcs_user_errstr
                    );
                free(fcs_user_errstr);

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
        }
        else if ((!strcmp(argv[arg], "--freecells-num")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }
            if (freecell_solver_user_set_num_freecells(instance, atoi(argv[arg])) != 0)
            {
                char * errstr;

                errstr = malloc(500);
                sprintf(errstr,
                    "Error! The freecells\' number "
                    "exceeds the maximum of %i.\n"
                    "Recompile the program if you wish to have more.\n",
                    freecell_solver_user_get_max_num_freecells()
                    );

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
        }
        else if ((!strcmp(argv[arg], "--stacks-num")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }
            if (freecell_solver_user_set_num_stacks(instance, atoi(argv[arg])) != 0)
            {
                char * errstr;

                errstr = malloc(500);
                sprintf(errstr,
                    "Error! The stacks\' number "
                    "exceeds the maximum of %i.\n"
                    "Recompile the program if you wish to have more.\n",
                    freecell_solver_user_get_max_num_stacks()
                    );

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
        }
        else if ((!strcmp(argv[arg], "--decks-num")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }
            if (freecell_solver_user_set_num_decks(instance, atoi(argv[arg])) != 0)
            {
                char * errstr;

                errstr = malloc(500);
                sprintf(errstr,
                    "Error! The decks\' number "
                    "exceeds the maximum of %i.\n"
                    "Recopmile the program if you wish to have more.\n",
                    freecell_solver_user_get_max_num_decks()
                    );

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
        }
        else if ((!strcmp(argv[arg], "--sequences-are-built-by")))
        {
            int sbb;

            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            if (!strcmp(argv[arg], "suit"))
            {
                sbb = FCS_SEQ_BUILT_BY_SUIT;
            }
            else if (!strcmp(argv[arg], "rank"))
            {
                sbb = FCS_SEQ_BUILT_BY_RANK;
            }
            else
            {
                sbb = FCS_SEQ_BUILT_BY_ALTERNATE_COLOR;
            }
            freecell_solver_user_set_sequences_are_built_by_type(instance, sbb);
        }
        else if ((!strcmp(argv[arg], "--sequence-move")))
        {
            int unlimited;

            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            if (!strcmp(argv[arg], "unlimited"))
            {
                unlimited = 1;
            }
            else
            {
                unlimited = 0;
            }
            freecell_solver_user_set_sequence_move(instance, unlimited);
        }
        else if (!strcmp(argv[arg], "--empty-stacks-filled-by"))
        {
            int es_fill;

            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            if (!strcmp(argv[arg], "kings"))
            {
                es_fill = FCS_ES_FILLED_BY_KINGS_ONLY;
            }
            else if (!strcmp(argv[arg], "none"))
            {
                es_fill = FCS_ES_FILLED_BY_NONE;
            }
            else
            {
                es_fill = FCS_ES_FILLED_BY_ANY_CARD;
            }
            freecell_solver_user_set_empty_stacks_filled_by(
                instance,
                es_fill
                );
        }
        else if (
            (!strcmp(argv[arg], "--game")) ||
            (!strcmp(argv[arg], "--preset")) ||
            (!strcmp(argv[arg], "-g"))
            )
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            ret = freecell_solver_user_apply_preset(instance, argv[arg]);
            if (ret == FCS_PRESET_CODE_NOT_FOUND)
            {
                char * errstr;

                errstr = malloc(strlen(argv[arg])+500);

                sprintf(errstr, "Unknown game \"%s\"!\n\n", argv[arg]);
                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
            else if (ret == FCS_PRESET_CODE_FREECELLS_EXCEED_MAX)
            {
                char * errstr;

                errstr = malloc(strlen(argv[arg])+500);
                sprintf(errstr, "The game \"%s\" exceeds the maximal number "
                        "of freecells in the program.\n"
                        "Modify the file \"config.h\" and recompile, "
                        "if you wish to solve one of its boards.\n",
                        argv[arg]
                        );

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
            else if (ret == FCS_PRESET_CODE_STACKS_EXCEED_MAX)
            {
                char * errstr;

                errstr = malloc(strlen(argv[arg])+500);

                sprintf(errstr, "The game \"%s\" exceeds the maximal number "
                        "of stacks in the program.\n"
                        "Modify the file \"config.h\" and recompile, "
                        "if you wish to solve one of its boards.\n",
                        argv[arg]
                        );

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
            else if (ret != FCS_PRESET_CODE_OK)
            {
                char * errstr;

                errstr = malloc(strlen(argv[arg])+500);

                sprintf(errstr,
                    "The game \"%s\" exceeds the limits of the program.\n"
                    "Modify the file \"config.h\" and recompile, if you wish to solve one of its boards.\n",
                    argv[arg]
                );

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
        }
        else if ((!strcmp(argv[arg], "-me")) || (!strcmp(argv[arg], "--method")))
        {
            int method;

            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }
            if (!strcmp(argv[arg], "dfs"))
            {
                method = FCS_METHOD_HARD_DFS;
            }
            else if (!strcmp(argv[arg], "soft-dfs"))
            {
                method = FCS_METHOD_SOFT_DFS;
            }
            else if (!strcmp(argv[arg], "bfs"))
            {
                method = FCS_METHOD_BFS;
            }
            else if (!strcmp(argv[arg], "a-star"))
            {
                method = FCS_METHOD_A_STAR;
            }
            else if (!strcmp(argv[arg], "random-dfs"))
            {
                method = FCS_METHOD_RANDOM_DFS;
            }
            else
            {
                char * errstr;

                errstr = malloc(strlen(argv[arg])+500);

                sprintf(
                    errstr,
                    "Unknown solving method \"%s\".\n",
                    argv[arg]
                    );

                *error_string = errstr;

                *last_arg = arg;
                return FCS_CMD_LINE_ERROR_IN_ARG;
            }

            freecell_solver_user_set_solving_method(instance, method);
        }
        else if ((!strcmp(argv[arg], "-asw")) || (!strcmp(argv[arg], "--a-star-weights")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }
            {
                int a;
                char * start_num;
                char * end_num;
                char save;
                start_num = argv[arg];
                for(a=0;a<5;a++)
                {
                    while ((*start_num > '9') && (*start_num < '0') && (*start_num != '\0'))
                    {
                        start_num++;
                    }
                    if (*start_num == '\0')
                    {
                        break;
                    }
                    end_num = start_num+1;
                    while ((((*end_num >= '0') && (*end_num <= '9')) || (*end_num == '.')) && (*end_num != '\0'))
                    {
                        end_num++;
                    }
                    save = *end_num;
                    *end_num = '\0';
                    freecell_solver_user_set_a_star_weight(
                        instance,
                        a,
                        atof(start_num)
                        );
                    *end_num = save;
                    start_num=end_num+1;
                }
            }
        }
        else if ((!strcmp(argv[arg], "-opt")) || (!strcmp(argv[arg], "--optimize-solution")))
        {
            freecell_solver_user_set_solution_optimization(instance, 1);
        }
        else if ((!strcmp(argv[arg], "-seed")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            freecell_solver_user_set_random_seed(instance, atoi(argv[arg]));
        }
        else if ((!strcmp(argv[arg], "-mss")) || (!strcmp(argv[arg], "--max-stored-states")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            freecell_solver_user_limit_num_states_in_collection(
                instance,
                atoi(argv[arg])
            );
        }
        else if (
            (!strcmp(argv[arg], "-nst")) ||
            (!strcmp(argv[arg], "--next-soft-thread")) ||
            (!strcmp(argv[arg], "-nht")) ||
            (!strcmp(argv[arg], "--next-hard-thread"))
        )
        {
            int ret;
            int is_st = ((!strcmp(argv[arg], "-nst")) || (!strcmp(argv[arg], "--next-soft-thread")));

            ret =
                is_st ?
                    freecell_solver_user_next_soft_thread(instance) :
                    freecell_solver_user_next_hard_thread(instance)
                    ;

            if (ret)
            {
                char * errstr;

                errstr = strdup("The maximal number of soft threads has been exceeded\n");

                *error_string = errstr;

                *last_arg = arg;

                return FCS_CMD_LINE_ERROR_IN_ARG;
            }
        }
        else if ((!strcmp(argv[arg], "-step")) || (!strcmp(argv[arg], "--soft-thread-step")))
        {
            arg++;
            if (arg == argc)
            {
                *last_arg = arg;
                return FCS_CMD_LINE_PARAM_WITH_NO_ARG;
            }

            freecell_solver_user_set_soft_thread_step(
                instance,
                atoi(argv[arg])
            );
        }
        else
        {
            *last_arg = arg;
            return FCS_CMD_LINE_UNRECOGNIZED_OPTION;
        }
    }

    *last_arg = arg;
    return FCS_CMD_LINE_OK;
}