You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/kpat/freecell-solver/cl_chop.c

246 lines
5.9 KiB

#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