diff options
Diffstat (limited to 'kpat/freecell-solver/cl_chop.c')
-rw-r--r-- | kpat/freecell-solver/cl_chop.c | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/kpat/freecell-solver/cl_chop.c b/kpat/freecell-solver/cl_chop.c new file mode 100644 index 00000000..4bb82aab --- /dev/null +++ b/kpat/freecell-solver/cl_chop.c @@ -0,0 +1,245 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "cl_chop.h" + +#ifdef DMALLOC +#include <dmalloc.h> +#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;a<manager->argc;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;a<args_man->argc;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 |