summaryrefslogtreecommitdiffstats
path: root/kpat/freecell-solver/cl_chop.c
diff options
context:
space:
mode:
Diffstat (limited to 'kpat/freecell-solver/cl_chop.c')
-rw-r--r--kpat/freecell-solver/cl_chop.c245
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