#include #include #include #include "cl_chop.h" #ifdef DMALLOC #include #endif #define ARGS_MAN_GROW_BY 30 args_man_t * freecell_solver_args_man_alloc(void) { args_man_t * ret; ret = malloc(sizeof(args_man_t)); ret->argc = 0; ret->max_num_argv = ARGS_MAN_GROW_BY; ret->argv = malloc(sizeof(ret->argv[0]) * ret->max_num_argv); return ret; } void freecell_solver_args_man_free(args_man_t * manager) { int a; for(a=0;aargc;a++) { free(manager->argv[a]); } free(manager->argv); free(manager); } #define skip_ws() { while((*s == ' ') || (*s == '\t')) { s++; } } #define skip_non_ws() { while((*s != ' ') && (*s != '\t') && (*s)) { s++; }} #define add_to_last_arg(c) \ { \ *(last_arg_ptr++) = (c); \ if (last_arg_ptr == last_arg_end) \ { \ new_last_arg = realloc(last_arg, (size_t)(last_arg_end-last_arg+1024)); \ last_arg_ptr += new_last_arg - last_arg; \ last_arg_end += new_last_arg - last_arg + 1024; \ last_arg = new_last_arg; \ } \ } #define push_args_last_arg() { \ new_arg = malloc((size_t)(last_arg_ptr-last_arg+1)); \ strncpy(new_arg, last_arg, (size_t)(last_arg_ptr-last_arg)); \ new_arg[last_arg_ptr-last_arg] = '\0'; \ manager->argv[manager->argc] = new_arg; \ manager->argc++; \ if (manager->argc == manager->max_num_argv) \ { \ manager->max_num_argv += ARGS_MAN_GROW_BY; \ manager->argv = realloc(manager->argv, sizeof(manager->argv[0]) * manager->max_num_argv); \ } \ \ /* Reset last_arg_ptr so we will have an entirely new argument */ \ last_arg_ptr = last_arg; \ } #define is_whitespace(c) \ (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r')) int freecell_solver_args_man_chop(args_man_t * manager, char * string) { char * s = string; char * new_arg; char * last_arg, * last_arg_ptr, * last_arg_end, * new_last_arg; char next_char; int in_arg; last_arg_ptr = last_arg = malloc(1024); last_arg_end = last_arg + 1023; while (*s != '\0') { LOOP_START: in_arg = 0; while (is_whitespace(*s)) { s++; } if (*s == '\0') { break; } if (*s == '#') { in_arg = 0; /* Skip to the next line */ while((*s != '\0') && (*s != '\n')) { s++; } continue; } AFTER_WS: while ((*s != ' ') && (*s != '\t') && (*s != '\n') && (*s != '\r') && (*s != '\\') && (*s != '\"') && (*s != '\0') && (*s != '#')) { in_arg = 1; add_to_last_arg(*s); s++; } if ((*s == ' ') || (*s == '\t') || (*s == '\n') || (*s == '\0') || (*s == '\r')) { NEXT_ARG: push_args_last_arg(); in_arg = 0; if (*s == '\0') { break; } } else if (*s == '\\') { char next_char = *(++s); s++; if (next_char == '\0') { s--; goto NEXT_ARG; } else if ((next_char == '\n') || (next_char == '\r')) { if (in_arg) { goto AFTER_WS; } else { goto LOOP_START; } } else { add_to_last_arg(next_char); } } else if (*s == '\"') { s++; in_arg = 1; while ((*s != '\"') && (*s != '\0')) { if (*s == '\\') { next_char = *(++s); if (next_char == '\0') { push_args_last_arg(); goto END_OF_LOOP; } else if ((next_char == '\n') || (next_char == '\r')) { /* Do nothing */ } else if ((next_char == '\\') || (next_char == '\"')) { add_to_last_arg(next_char); } else { add_to_last_arg('\\'); add_to_last_arg(next_char); } } else { add_to_last_arg(*s); } s++; } s++; goto AFTER_WS; } else if (*s == '#') { in_arg = 0; /* Skip to the next line */ while((*s != '\0') && (*s != '\n')) { s++; } goto NEXT_ARG; } } END_OF_LOOP: free(last_arg); return 0; } #ifdef CMD_LINE_CHOP_WITH_MAIN int main(int argc, char * * argv) { args_man_t * args_man; char * string; #if 0 string = argv[1]; #else { FILE * f; f = fopen(argv[1],"rb"); string = calloc(4096,1); fread(string, 4095, 1, f); fclose(f); } #endif /* Initialize an arg man */ args_man = args_man_alloc(); /* Call it on string */ args_man_chop(args_man, string); /* Now use args_man->argc and args_man->argv */ { int a; for(a=0;aargc;a++) { printf("argv[%i] = \"%s\"\n", a, args_man->argv[a]); } } /* Free the allocated memory */ args_man_free(args_man); free(string); return 0; } #endif