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
13 int poptDupArgv(int argc
, const char **argv
,
14 int * argcPtr
, const char *** argvPtr
)
16 size_t nb
= (argc
+ 1) * sizeof(*argv
);
21 if (argc
<= 0 || argv
== NULL
) /* XXX can't happen */
22 return POPT_ERROR_NOARG
;
23 for (i
= 0; i
< argc
; i
++) {
25 return POPT_ERROR_NOARG
;
26 nb
+= strlen(argv
[i
]) + 1;
30 if (dst
== NULL
) /* XXX can't happen */
31 return POPT_ERROR_MALLOC
;
33 dst
+= (argc
+ 1) * sizeof(*argv
);
36 for (i
= 0; i
< argc
; i
++) {
38 dst
= stpcpy(dst
, argv
[i
]);
39 dst
++; /* trailing NUL */
54 int poptParseArgvString(const char * s
, int * argcPtr
, const char *** argvPtr
)
58 int argvAlloced
= POPT_ARGV_ARRAY_GROW_DELTA
;
59 const char ** argv
= malloc(sizeof(*argv
) * argvAlloced
);
60 const char ** argv_tmp
;
62 size_t buflen
= strlen(s
) + 1;
63 char * buf
, * bufOrig
= NULL
;
64 int rc
= POPT_ERROR_MALLOC
;
66 if (argv
== NULL
) return rc
;
67 buf
= bufOrig
= calloc((size_t)1, buflen
);
74 for (src
= s
; *src
!= '\0'; src
++) {
77 } else if (quote
!= '\0') {
81 rc
= POPT_ERROR_BADQUOTE
;
84 if (*src
!= quote
) *buf
++ = '\\';
87 } else if (_isspaceptr(src
)) {
88 if (*argv
[argc
] != '\0') {
90 if (argc
== argvAlloced
) {
91 argvAlloced
+= POPT_ARGV_ARRAY_GROW_DELTA
;
92 argv_tmp
= realloc(argv
, sizeof(*argv
) * argvAlloced
);
93 if (argv_tmp
== NULL
) goto exit
;
98 } else switch (*src
) {
106 rc
= POPT_ERROR_BADQUOTE
;
116 if (strlen(argv
[argc
])) {
120 rc
= poptDupArgv(argc
, argv
, argcPtr
, argvPtr
);
123 if (bufOrig
) free(bufOrig
);
124 if (argv
) free(argv
);
128 /* still in the dev stage.
129 * return values, perhaps 1== file error
133 int poptConfigFileToString(FILE *fp
, char ** argstrp
,
144 size_t maxlinelen
= sizeof(line
);
146 size_t maxargvlen
= (size_t)480;
150 /* | this_is = our_line
155 return POPT_ERROR_NULLARG
;
157 argstr
= calloc(maxargvlen
, sizeof(*argstr
));
158 if (argstr
== NULL
) return POPT_ERROR_MALLOC
;
160 while (fgets(line
, (int)maxlinelen
, fp
) != NULL
) {
163 /* loop until first non-space char or EOL */
164 while( *p
!= '\0' && _isspaceptr(p
) )
168 if (linelen
>= maxlinelen
-1) {
170 return POPT_ERROR_OVERFLOW
; /* XXX line too long */
173 if (*p
== '\0' || *p
== '\n') continue; /* line is empty */
174 if (*p
== '#') continue; /* comment line */
178 while (*q
!= '\0' && (!_isspaceptr(q
)) && *q
!= '=')
181 if (_isspaceptr(q
)) {
182 /* a space after the name, find next non space */
184 while( *q
!= '\0' && _isspaceptr(q
) ) q
++;
187 /* single command line option (ie, no name=val, just name) */
188 q
[-1] = '\0'; /* kill off newline from fgets() call */
189 argvlen
+= (t
= (size_t)(q
- p
)) + (sizeof(" --")-1);
190 if (argvlen
>= maxargvlen
) {
191 maxargvlen
= (t
> maxargvlen
) ? t
*2 : maxargvlen
*2;
192 argstr_tmp
= realloc(argstr
, maxargvlen
);
193 if (argstr_tmp
== NULL
) {
195 return POPT_ERROR_MALLOC
;
199 strcat(argstr
, " --");
204 continue; /* XXX for now, silently ignore bogus line */
206 /* *q is an equal sign. */
209 /* find next non-space letter of value */
210 while (*q
!= '\0' && _isspaceptr(q
))
213 continue; /* XXX silently ignore missing value */
215 /* now, loop and strip all ending whitespace */
217 while (_isspaceptr(--x
))
218 *x
= '\0'; /* null out last char if space (including fgets() NL) */
220 /* rest of line accept */
222 argvlen
+= t
+ (sizeof("' --='")-1);
223 if (argvlen
>= maxargvlen
) {
224 maxargvlen
= (t
> maxargvlen
) ? t
*2 : maxargvlen
*2;
225 argstr_tmp
= realloc(argstr
, maxargvlen
);
226 if (argstr_tmp
== NULL
) {
228 return POPT_ERROR_MALLOC
;
232 strcat(argstr
, " --");
234 strcat(argstr
, "=\"");
236 strcat(argstr
, "\"");