2 * \file popt/poptparse.c
5 /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
6 file accompanying popt source distributions, available from
7 ftp://ftp.rpm.org/pub/rpm/dist. */
11 #define POPT_ARGV_ARRAY_GROW_DELTA 5
14 int poptDupArgv(int argc, const char **argv,
15 int * argcPtr, const char *** argvPtr)
17 size_t nb = (argc + 1) * sizeof(*argv);
22 if (argc <= 0 || argv == NULL) /* XXX can't happen */
23 return POPT_ERROR_NOARG;
24 for (i = 0; i < argc; i++) {
26 return POPT_ERROR_NOARG;
27 nb += strlen(argv[i]) + 1;
30 dst = (char *)malloc(nb);
31 if (dst == NULL) /* XXX can't happen */
32 return POPT_ERROR_MALLOC;
33 argv2 = (const char **) dst;
34 dst += (argc + 1) * sizeof(*argv);
37 for (i = 0; i < argc; i++) {
39 dst += strlen(strcpy(dst, argv[i])) + 1;
57 int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
61 int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
62 const char ** argv = (const char **)malloc(sizeof(*argv) * argvAlloced);
64 int buflen = strlen(s) + 1;
65 char * buf = (char*)memset(alloca(buflen), 0, buflen);
66 int rc = POPT_ERROR_MALLOC;
68 if (argv == NULL) return rc;
71 for (src = s; *src != '\0'; src++) {
74 } else if (quote != '\0') {
78 rc = POPT_ERROR_BADQUOTE;
81 if (*src != quote) *buf++ = '\\';
84 } else if (isspace(*src)) {
85 if (*argv[argc] != '\0') {
87 if (argc == argvAlloced) {
88 argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
89 argv = (const char **)realloc(argv, sizeof(*argv) * argvAlloced);
90 if (argv == NULL) goto exit;
94 } else switch (*src) {
98 /*@switchbreak@*/ break;
102 rc = POPT_ERROR_BADQUOTE;
108 /*@switchbreak@*/ break;
112 if (strlen(argv[argc])) {
116 rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
119 if (argv) free(argv);
124 /* still in the dev stage.
125 * return values, perhaps 1== file erro
129 int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags)
138 size_t maxlinelen = sizeof(line);
140 int maxargvlen = 480;
145 /* | this_is = our_line
150 return POPT_ERROR_NULLARG;
152 argstr = (char *)calloc(maxargvlen, sizeof(*argstr));
153 if (argstr == NULL) return POPT_ERROR_MALLOC;
155 while (fgets(line, (int)maxlinelen, fp) != NULL) {
159 /* loop until first non-space char or EOL */
160 while( *p != '\0' && isspace(*p) )
164 if (linelen >= maxlinelen-1)
165 return POPT_ERROR_OVERFLOW; /* XXX line too long */
167 if (*p == '\0' || *p == '\n') continue; /* line is empty */
168 if (*p == '#') continue; /* comment line */
172 while (*q != '\0' && (!isspace(*q)) && *q != '=')
176 /* a space after the name, find next non space */
178 while( *q != '\0' && isspace((int)*q) ) q++;
181 /* single command line option (ie, no name=val, just name) */
182 q[-1] = '\0'; /* kill off newline from fgets() call */
183 argvlen += (t = q - p) + (sizeof(" --")-1);
184 if (argvlen >= maxargvlen) {
185 maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
186 argstr = (char *)realloc(argstr, maxargvlen);
187 if (argstr == NULL) return POPT_ERROR_MALLOC;
189 strcat(argstr, " --");
194 continue; /* XXX for now, silently ignore bogus line */
196 /* *q is an equal sign. */
199 /* find next non-space letter of value */
200 while (*q != '\0' && isspace(*q))
203 continue; /* XXX silently ignore missing value */
205 /* now, loop and strip all ending whitespace */
207 while (isspace(*--x))
208 *x = 0; /* null out last char if space (including fgets() NL) */
210 /* rest of line accept */
212 argvlen += t + (sizeof("' --='")-1);
213 if (argvlen >= maxargvlen) {
214 maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
215 argstr = (char *)realloc(argstr, maxargvlen);
216 if (argstr == NULL) return POPT_ERROR_MALLOC;
218 strcat(argstr, " --");
220 strcat(argstr, "=\"");
222 strcat(argstr, "\"");