/* argv.c - turns a string into an argc,argv list */ /* PUBLIC DOMAIN 2001 - Jon Mayo */ /* TODO: * - make sure argv is NULL terminated * - eliminate argc from argv_free (NULL terminated) * - add shell style quoting */ /* DONE: * - support null terminated or length terminated */ #include #include #include #include "argv.h" /* what argv_create() considers to be a delimiter */ #define IS_SPACETAB(x) ((x)=='\t'||(x)==' ') /*! * description: turns string into an argc,argv * parameters: * command - input string * command_len - length of input string * argc - pointer to count of arguments. can be NULL not to use. * argv - pointer to a list of strings * line - pointer to everything after the first argument (index into command). * can be NULL not to use. only null terminated if command is null terminated! * returns: * count of arguments in argv (same as what is stored in argc pointer) */ int argv_create(const ARGV_TYPE *command, int command_len, int *argc, ARGV_TYPE ***argv, const ARGV_TYPE **line) { int argc_guess; int argc_real; ARGV_TYPE **argv_tmp; const ARGV_TYPE *ic; const ARGV_TYPE *cmdstart, *cmdend; int len; if(command_len<0) command_len=INT_MAX; /* roughly figure out argc */ for(ic=command,argc_guess=1;*ic;ic++) { if(IS_SPACETAB(*ic)) { /* is space,tab,newline,... */ argc_guess++; } } /* here's the list */ argv_tmp=malloc(sizeof *argv_tmp * argc_guess); argc_real=0; /* count as we go */ if(line) *line=NULL; /* intialize it */ while(command_len>0 && *command) { for(;command_len>0 && IS_SPACETAB(*command);command++, command_len--) ; cmdstart=command; for(;command_len>0 && !IS_SPACETAB(*command) && *command;command++, command_len--) ; cmdend=command; len=cmdend-cmdstart; argv_tmp[argc_real]=malloc(len+1); memcpy(argv_tmp[argc_real],cmdstart,len); argv_tmp[argc_real][len]=0; if(argc_real==1 && line) { /* line is after the command */ *line=cmdstart; } argc_real++; for(;command_len>0 && IS_SPACETAB(*command);command++, command_len--) ; } if(argc) *argc=argc_real; *argv=argv_tmp; return argc_real; } void argv_free(int argc, ARGV_TYPE **argv) { int i; for(i=0;i /* test routine */ void test(const char *str, int len) { char **argv; int argc; const char *line; int i; printf("str = \"%s\"\n", str); printf("argc = %d\n", argv_create(str, len, &argc, &argv, &line) ); printf("line = \"%s\"\n", line); for(i=0;i