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
, "\"");