1 /* 2 This file contains a function, build_argv(), which will take an input 3 string and chop it into individual words. The return value is an 4 argv style array (i.e. like what main() receives). 5 6 THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED 7 OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR 8 NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED. 9 10 FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com). 11 12 Dominic Giampaolo 13 dbg@be.com 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <ctype.h> 19 #include <string.h> 20 21 #include "argv.h" 22 23 #define DOUBLE_QUOTE '"' 24 #define SINGLE_QUOTE '\'' 25 #define BACK_SLASH '\\' 26 27 char ** 28 build_argv(char *str, int *argc) 29 { 30 int table_size = 16, _argc; 31 char **argv; 32 33 if (argc == NULL) 34 argc = &_argc; 35 36 *argc = 0; 37 argv = (char **)calloc(table_size, sizeof(char *)); 38 39 if (argv == NULL) 40 return NULL; 41 42 while(*str) { 43 /* skip intervening white space */ 44 while(*str != '\0' && (*str == ' ' || *str == '\t' || *str == '\n')) 45 str++; 46 47 if (*str == '\0') 48 break; 49 50 if (*str == DOUBLE_QUOTE) { 51 argv[*argc] = ++str; 52 while(*str && *str != DOUBLE_QUOTE) { 53 if (*str == BACK_SLASH) 54 strcpy(str, str+1); /* copy everything down */ 55 str++; 56 } 57 } else if (*str == SINGLE_QUOTE) { 58 argv[*argc] = ++str; 59 while(*str && *str != SINGLE_QUOTE) { 60 if (*str == BACK_SLASH) 61 strcpy(str, str+1); /* copy everything down */ 62 str++; 63 } 64 } else { 65 argv[*argc] = str; 66 while(*str && *str != ' ' && *str != '\t' && *str != '\n') { 67 if (*str == BACK_SLASH) 68 strcpy(str, str+1); /* copy everything down */ 69 str++; 70 } 71 } 72 73 if (*str != '\0') 74 *str++ = '\0'; /* chop the string */ 75 76 *argc = *argc + 1; 77 if (*argc >= table_size-1) { 78 char **nargv; 79 80 table_size = table_size * 2; 81 nargv = (char **)calloc(table_size, sizeof(char *)); 82 83 if (nargv == NULL) { /* drats! failure. */ 84 free(argv); 85 return NULL; 86 } 87 88 memcpy(nargv, argv, (*argc) * sizeof(char *)); 89 free(argv); 90 argv = nargv; 91 } 92 } 93 94 return argv; 95 } 96