関数 | |
int | poptDupArgv (int argc, const char **argv, int *argcPtr, const char ***argvPtr) |
Duplicate an argument array. | |
int | poptParseArgvString (const char *s, int *argcPtr, const char ***argvPtr) |
Parse a string into an argument array. | |
int | poptConfigFileToString (FILE *fp, char **argstrp, int flags) |
Parses an input configuration file and returns an string that is a command line. |
poptparse.c で定義されています。
int poptDupArgv | ( | int | argc, | |
const char ** | argv, | |||
int * | argcPtr, | |||
const char *** | argvPtr | |||
) |
Duplicate an argument array.
argc | no. of arguments | |
argv | argument array |
argcPtr | address of returned no. of arguments | |
argvPtr | address of returned argument array |
poptparse.c の 14 行で定義されています。
参照元 handleAlias()・poptParseArgvString()・poptStuffArgs().
00016 { 00017 size_t nb = (argc + 1) * sizeof(*argv); 00018 const char ** argv2; 00019 char * dst; 00020 int i; 00021 00022 if (argc <= 0 || argv == NULL) /* XXX can't happen */ 00023 return POPT_ERROR_NOARG; 00024 for (i = 0; i < argc; i++) { 00025 if (argv[i] == NULL) 00026 return POPT_ERROR_NOARG; 00027 nb += strlen(argv[i]) + 1; 00028 } 00029 00030 dst = malloc(nb); 00031 if (dst == NULL) /* XXX can't happen */ 00032 return POPT_ERROR_MALLOC; 00033 argv2 = (void *) dst; 00034 dst += (argc + 1) * sizeof(*argv); 00035 00036 /*@-branchstate@*/ 00037 for (i = 0; i < argc; i++) { 00038 argv2[i] = dst; 00039 dst += strlen(strcpy(dst, argv[i])) + 1; 00040 } 00041 /*@=branchstate@*/ 00042 argv2[argc] = NULL; 00043 00044 if (argvPtr) { 00045 *argvPtr = argv2; 00046 } else { 00047 free(argv2); 00048 argv2 = NULL; 00049 } 00050 if (argcPtr) 00051 *argcPtr = argc; 00052 return 0; 00053 }
int poptParseArgvString | ( | const char * | s, | |
int * | argcPtr, | |||
const char *** | argvPtr | |||
) |
Parse a string into an argument array.
The parse allows ', ", and \ quoting, but ' is treated the same as " and both may include \ quotes.
s | string to parse |
argcPtr | address of returned no. of arguments | |
argvPtr | address of returned argument array |
poptparse.c の 57 行で定義されています。
参照先 alloca()・buf・poptDupArgv().
参照元 configLine()・net_rpc_shell()・process_cmd().
00058 { 00059 const char * src; 00060 char quote = '\0'; 00061 int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; 00062 const char ** argv = malloc(sizeof(*argv) * argvAlloced); 00063 int argc = 0; 00064 int buflen = strlen(s) + 1; 00065 char * buf = memset(alloca(buflen), 0, buflen); 00066 int rc = POPT_ERROR_MALLOC; 00067 00068 if (argv == NULL) return rc; 00069 argv[argc] = buf; 00070 00071 for (src = s; *src != '\0'; src++) { 00072 if (quote == *src) { 00073 quote = '\0'; 00074 } else if (quote != '\0') { 00075 if (*src == '\\') { 00076 src++; 00077 if (!*src) { 00078 rc = POPT_ERROR_BADQUOTE; 00079 goto exit; 00080 } 00081 if (*src != quote) *buf++ = '\\'; 00082 } 00083 *buf++ = *src; 00084 } else if (isspace(*src)) { 00085 if (*argv[argc] != '\0') { 00086 buf++, argc++; 00087 if (argc == argvAlloced) { 00088 argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; 00089 argv = realloc(argv, sizeof(*argv) * argvAlloced); 00090 if (argv == NULL) goto exit; 00091 } 00092 argv[argc] = buf; 00093 } 00094 } else switch (*src) { 00095 case '"': 00096 case '\'': 00097 quote = *src; 00098 /*@switchbreak@*/ break; 00099 case '\\': 00100 src++; 00101 if (!*src) { 00102 rc = POPT_ERROR_BADQUOTE; 00103 goto exit; 00104 } 00105 /*@fallthrough@*/ 00106 default: 00107 *buf++ = *src; 00108 /*@switchbreak@*/ break; 00109 } 00110 } 00111 00112 if (strlen(argv[argc])) { 00113 argc++, buf++; 00114 } 00115 00116 rc = poptDupArgv(argc, argv, argcPtr, argvPtr); 00117 00118 exit: 00119 if (argv) free(argv); 00120 return rc; 00121 }
int poptConfigFileToString | ( | FILE * | fp, | |
char ** | argstrp, | |||
int | flags | |||
) |
Parses an input configuration file and returns an string that is a command line.
For use with popt. You must free the return value when done.
Given the file:
# this line is ignored # this one too aaa bbb ccc bla=bla this_is = fdsafdas bad_line= reall bad line reall bad line = again 5555= 55555 test = with lots of spaces
The result is:
--aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces"
Passing this to poptParseArgvString() yields an argv of:
'--aaa' '--bbb' '--ccc' '--bla=bla' '--this_is=fdsafdas' '--5555=55555' '--test=with lots of spaces'
Silently ignores invalid lines.
fp | file handle to read | |
*argstrp | return string of options (malloc'd) | |
flags | unused |
poptparse.c の 129 行で定義されています。
00130 { 00131 char line[999]; 00132 char * argstr; 00133 char * p; 00134 char * q; 00135 char * x; 00136 int t; 00137 int argvlen = 0; 00138 size_t maxlinelen = sizeof(line); 00139 size_t linelen; 00140 int maxargvlen = 480; 00141 int linenum = 0; 00142 00143 *argstrp = NULL; 00144 00145 /* | this_is = our_line 00146 * p q x 00147 */ 00148 00149 if (fp == NULL) 00150 return POPT_ERROR_NULLARG; 00151 00152 argstr = calloc(maxargvlen, sizeof(*argstr)); 00153 if (argstr == NULL) return POPT_ERROR_MALLOC; 00154 00155 while (fgets(line, (int)maxlinelen, fp) != NULL) { 00156 linenum++; 00157 p = line; 00158 00159 /* loop until first non-space char or EOL */ 00160 while( *p != '\0' && isspace(*p) ) 00161 p++; 00162 00163 linelen = strlen(p); 00164 if (linelen >= maxlinelen-1) 00165 return POPT_ERROR_OVERFLOW; /* XXX line too long */ 00166 00167 if (*p == '\0' || *p == '\n') continue; /* line is empty */ 00168 if (*p == '#') continue; /* comment line */ 00169 00170 q = p; 00171 00172 while (*q != '\0' && (!isspace(*q)) && *q != '=') 00173 q++; 00174 00175 if (isspace(*q)) { 00176 /* a space after the name, find next non space */ 00177 *q++='\0'; 00178 while( *q != '\0' && isspace((int)*q) ) q++; 00179 } 00180 if (*q == '\0') { 00181 /* single command line option (ie, no name=val, just name) */ 00182 q[-1] = '\0'; /* kill off newline from fgets() call */ 00183 argvlen += (t = q - p) + (sizeof(" --")-1); 00184 if (argvlen >= maxargvlen) { 00185 maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; 00186 argstr = realloc(argstr, maxargvlen); 00187 if (argstr == NULL) return POPT_ERROR_MALLOC; 00188 } 00189 strcat(argstr, " --"); 00190 strcat(argstr, p); 00191 continue; 00192 } 00193 if (*q != '=') 00194 continue; /* XXX for now, silently ignore bogus line */ 00195 00196 /* *q is an equal sign. */ 00197 *q++ = '\0'; 00198 00199 /* find next non-space letter of value */ 00200 while (*q != '\0' && isspace(*q)) 00201 q++; 00202 if (*q == '\0') 00203 continue; /* XXX silently ignore missing value */ 00204 00205 /* now, loop and strip all ending whitespace */ 00206 x = p + linelen; 00207 while (isspace(*--x)) 00208 *x = 0; /* null out last char if space (including fgets() NL) */ 00209 00210 /* rest of line accept */ 00211 t = x - p; 00212 argvlen += t + (sizeof("' --='")-1); 00213 if (argvlen >= maxargvlen) { 00214 maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; 00215 argstr = realloc(argstr, maxargvlen); 00216 if (argstr == NULL) return POPT_ERROR_MALLOC; 00217 } 00218 strcat(argstr, " --"); 00219 strcat(argstr, p); 00220 strcat(argstr, "=\""); 00221 strcat(argstr, q); 00222 strcat(argstr, "\""); 00223 } 00224 00225 *argstrp = argstr; 00226 return 0; 00227 }