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. */
13 #define POPT_ARGV_ARRAY_GROW_DELTA 5
16 int poptDupArgv(int argc
, const char **argv
,
17 int * argcPtr
, const char *** argvPtr
)
19 size_t nb
= (argc
+ 1) * sizeof(*argv
);
24 if (argc
<= 0 || argv
== NULL
) /* XXX can't happen */
25 return POPT_ERROR_NOARG
;
26 for (i
= 0; i
< argc
; i
++) {
28 return POPT_ERROR_NOARG
;
29 nb
+= strlen(argv
[i
]) + 1;
33 if (dst
== NULL
) /* XXX can't happen */
34 return POPT_ERROR_MALLOC
;
36 dst
+= (argc
+ 1) * sizeof(*argv
);
39 for (i
= 0; i
< argc
; i
++) {
41 dst
+= strlcpy(dst
, argv
[i
], nb
) + 1;
59 int poptParseArgvString(const char * s
, int * argcPtr
, const char *** argvPtr
)
63 int argvAlloced
= POPT_ARGV_ARRAY_GROW_DELTA
;
64 const char ** argv
= malloc(sizeof(*argv
) * argvAlloced
);
66 int buflen
= strlen(s
) + 1;
67 char * buf
= memset(alloca(buflen
), 0, buflen
);
68 int rc
= POPT_ERROR_MALLOC
;
70 if (argv
== NULL
) return rc
;
73 for (src
= s
; *src
!= '\0'; src
++) {
76 } else if (quote
!= '\0') {
80 rc
= POPT_ERROR_BADQUOTE
;
83 if (*src
!= quote
) *buf
++ = '\\';
86 } else if (isSpace(src
)) {
87 if (*argv
[argc
] != '\0') {
89 if (argc
== argvAlloced
) {
90 argvAlloced
+= POPT_ARGV_ARRAY_GROW_DELTA
;
91 argv
= realloc(argv
, sizeof(*argv
) * argvAlloced
);
92 if (argv
== NULL
) goto exit
;
96 } else switch (*src
) {
100 /*@switchbreak@*/ break;
104 rc
= POPT_ERROR_BADQUOTE
;
110 /*@switchbreak@*/ break;
114 if (strlen(argv
[argc
])) {
118 rc
= poptDupArgv(argc
, argv
, argcPtr
, argvPtr
);
121 if (argv
) free(argv
);
126 /* still in the dev stage.
127 * return values, perhaps 1== file erro
131 int poptConfigFileToString(FILE *fp
, char ** argstrp
, /*@unused@*/ UNUSED(int flags
))
140 size_t maxlinelen
= sizeof(line
);
142 int maxargvlen
= 480;
147 /* | this_is = our_line
152 return POPT_ERROR_NULLARG
;
154 argstr
= calloc(maxargvlen
, sizeof(*argstr
));
155 if (argstr
== NULL
) return POPT_ERROR_MALLOC
;
157 while (fgets(line
, (int)maxlinelen
, fp
) != NULL
) {
161 /* loop until first non-space char or EOL */
162 while( *p
!= '\0' && isSpace(p
) )
166 if (linelen
>= maxlinelen
-1) {
168 return POPT_ERROR_OVERFLOW
; /* XXX line too long */
171 if (*p
== '\0' || *p
== '\n') continue; /* line is empty */
172 if (*p
== '#') continue; /* comment line */
176 while (*q
!= '\0' && (!isSpace(q
)) && *q
!= '=')
180 /* a space after the name, find next non space */
182 while( *q
!= '\0' && isSpace(q
) ) q
++;
185 /* single command line option (ie, no name=val, just name) */
186 q
[-1] = '\0'; /* kill off newline from fgets() call */
187 argvlen
+= (t
= q
- p
) + (sizeof(" --")-1);
188 if (argvlen
>= maxargvlen
) {
189 maxargvlen
= (t
> maxargvlen
) ? t
*2 : maxargvlen
*2;
190 argstr
= realloc(argstr
, maxargvlen
);
191 if (argstr
== NULL
) return POPT_ERROR_MALLOC
;
193 strlcat(argstr
, " --", maxargvlen
);
194 strlcat(argstr
, p
, maxargvlen
);
198 continue; /* XXX for now, silently ignore bogus line */
200 /* *q is an equal sign. */
203 /* find next non-space letter of value */
204 while (*q
!= '\0' && isSpace(q
))
207 continue; /* XXX silently ignore missing value */
209 /* now, loop and strip all ending whitespace */
212 *x
= 0; /* null out last char if space (including fgets() NL) */
214 /* rest of line accept */
216 argvlen
+= t
+ (sizeof("' --='")-1);
217 if (argvlen
>= maxargvlen
) {
218 maxargvlen
= (t
> maxargvlen
) ? t
*2 : maxargvlen
*2;
219 argstr
= realloc(argstr
, maxargvlen
);
220 if (argstr
== NULL
) return POPT_ERROR_MALLOC
;
222 strlcat(argstr
, " --", maxargvlen
);
223 strlcat(argstr
, p
, maxargvlen
);
224 strlcat(argstr
, "=\"", maxargvlen
);
225 strlcat(argstr
, q
, maxargvlen
);
226 strlcat(argstr
, "\"", maxargvlen
);