/* * cutup: cut up a command line */ #include #include #include #include /* for definition of strdup() */ #include "args.h" /* * newargs() initializes an arg_t structure * (c++ would do this with a arg_t class. Finally a good reason to use * c++, and not a compiler in sight) */ newargs(args) struct arg_t *args; { args->argc = 0; args->argv = malloc(1); } /* newargs */ /* * disposeargs() throws away an arg_t structure */ disposeargs(args) struct arg_t *args; { register i; for (i=args->argc; i-- > 0; ) free(args->argv[i]); free(args->argv); args->argc = args->argv = 0; } /* disposeargs */ /* * addarg() adds an argument to an arg_t structure. using c++, you could * just overload + to do this :-( */ addarg(item, list) char *item; struct arg_t *list; { if (list->argv = realloc(list->argv, (1+list->argc)*sizeof list->argv[0])) list->argv[list->argc++] = strdup(item); else { newargs(list); no_more_core(); } return list->argc; } /* addarg */ /* * isesc() is the given character one that needs to be escaped? */ isesc(c) { switch (c) { case '"': case '\'': case '`': case '\\': case ';': case '|': case '&': case '*': case ' ': case '\t': case '\n': case '?': case '<': case '>': case '=': return 1; } return 0; } cutup(text, args, io) register char *text; struct arg_t *args, *io; { register char c; register i=0; register ioarg=0; char buf[512]; newargs(args); newargs(io); while (c = *text++) { if (isspace(c)) { if (i>0) { buf[i] = 0; i=0; addarg(buf, ioarg ? io : args); ioarg=0; } } else if (c == '\\' && isesc(*text)) buf[i++] = *text++; else if (c == '"' || c == '\'' || c == '`') { while (*text && *text != c) { if (*text == '\\' && isesc(text[1])) { buf[i++] = *++text; ++text; } else buf[i++] = *text++; } if (*text) text++; } else { if (c == '<' || c == '>') ioarg=1; buf[i++] = c; } } if (i>0) { buf[i] = 0; i=0; addarg(buf, ioarg ? io : args); } } /* cutup */