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.
246 lines
5.9 KiB
246 lines
5.9 KiB
15 years ago
|
#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
|