Increase the testrun timeout for slow compilefarm systems.
[rsync/rsync.git] / popt / poptparse.c
CommitLineData
cc248aae
WD
1/** \ingroup popt
2 * \file popt/poptparse.c
3 */
4
bc93ee84 5/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
62402cb1 6 file accompanying popt source distributions, available from
cc248aae 7 ftp://ftp.rpm.org/pub/rpm/dist. */
62402cb1 8
b348deae 9#include "system.h"
62402cb1 10
a8facdc0
WD
11#include "poptint.h"
12
b348deae 13#define POPT_ARGV_ARRAY_GROW_DELTA 5
62402cb1 14
bc93ee84 15/*@-boundswrite@*/
b348deae
MP
16int poptDupArgv(int argc, const char **argv,
17 int * argcPtr, const char *** argvPtr)
18{
19 size_t nb = (argc + 1) * sizeof(*argv);
20 const char ** argv2;
21 char * dst;
22 int i;
23
cc248aae
WD
24 if (argc <= 0 || argv == NULL) /* XXX can't happen */
25 return POPT_ERROR_NOARG;
b348deae
MP
26 for (i = 0; i < argc; i++) {
27 if (argv[i] == NULL)
28 return POPT_ERROR_NOARG;
29 nb += strlen(argv[i]) + 1;
30 }
31
32 dst = malloc(nb);
cc248aae
WD
33 if (dst == NULL) /* XXX can't happen */
34 return POPT_ERROR_MALLOC;
b348deae
MP
35 argv2 = (void *) dst;
36 dst += (argc + 1) * sizeof(*argv);
37
cc248aae 38 /*@-branchstate@*/
b348deae
MP
39 for (i = 0; i < argc; i++) {
40 argv2[i] = dst;
bc93ee84 41 dst += strlcpy(dst, argv[i], nb) + 1;
b348deae 42 }
cc248aae 43 /*@=branchstate@*/
b348deae
MP
44 argv2[argc] = NULL;
45
cc248aae
WD
46 if (argvPtr) {
47 *argvPtr = argv2;
48 } else {
49 free(argv2);
50 argv2 = NULL;
51 }
52 if (argcPtr)
53 *argcPtr = argc;
b348deae
MP
54 return 0;
55}
bc93ee84 56/*@=boundswrite@*/
62402cb1 57
bc93ee84
WD
58/*@-bounds@*/
59int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
b348deae 60{
bc93ee84
WD
61 const char * src;
62 char quote = '\0';
b348deae
MP
63 int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
64 const char ** argv = malloc(sizeof(*argv) * argvAlloced);
62402cb1 65 int argc = 0;
b348deae 66 int buflen = strlen(s) + 1;
cc248aae
WD
67 char * buf = memset(alloca(buflen), 0, buflen);
68 int rc = POPT_ERROR_MALLOC;
62402cb1 69
cc248aae 70 if (argv == NULL) return rc;
62402cb1
MP
71 argv[argc] = buf;
72
cc248aae 73 for (src = s; *src != '\0'; src++) {
62402cb1
MP
74 if (quote == *src) {
75 quote = '\0';
cc248aae 76 } else if (quote != '\0') {
62402cb1
MP
77 if (*src == '\\') {
78 src++;
79 if (!*src) {
cc248aae
WD
80 rc = POPT_ERROR_BADQUOTE;
81 goto exit;
62402cb1
MP
82 }
83 if (*src != quote) *buf++ = '\\';
84 }
85 *buf++ = *src;
a8facdc0 86 } else if (isSpace(src)) {
cc248aae 87 if (*argv[argc] != '\0') {
62402cb1
MP
88 buf++, argc++;
89 if (argc == argvAlloced) {
b348deae 90 argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
62402cb1 91 argv = realloc(argv, sizeof(*argv) * argvAlloced);
cc248aae 92 if (argv == NULL) goto exit;
62402cb1
MP
93 }
94 argv[argc] = buf;
95 }
96 } else switch (*src) {
97 case '"':
98 case '\'':
99 quote = *src;
cc248aae 100 /*@switchbreak@*/ break;
62402cb1
MP
101 case '\\':
102 src++;
103 if (!*src) {
cc248aae
WD
104 rc = POPT_ERROR_BADQUOTE;
105 goto exit;
62402cb1 106 }
b348deae 107 /*@fallthrough@*/
62402cb1
MP
108 default:
109 *buf++ = *src;
cc248aae 110 /*@switchbreak@*/ break;
62402cb1 111 }
62402cb1
MP
112 }
113
114 if (strlen(argv[argc])) {
115 argc++, buf++;
116 }
117
cc248aae 118 rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
62402cb1 119
cc248aae
WD
120exit:
121 if (argv) free(argv);
122 return rc;
62402cb1 123}
bc93ee84
WD
124/*@=bounds@*/
125
126/* still in the dev stage.
127 * return values, perhaps 1== file erro
128 * 2== line to long
129 * 3== umm.... more?
130 */
131int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ UNUSED(int flags))
132{
133 char line[999];
134 char * argstr;
135 char * p;
136 char * q;
137 char * x;
138 int t;
139 int argvlen = 0;
140 size_t maxlinelen = sizeof(line);
141 size_t linelen;
142 int maxargvlen = 480;
143 int linenum = 0;
144
145 *argstrp = NULL;
146
147 /* | this_is = our_line
148 * p q x
149 */
150
151 if (fp == NULL)
152 return POPT_ERROR_NULLARG;
153
154 argstr = calloc(maxargvlen, sizeof(*argstr));
155 if (argstr == NULL) return POPT_ERROR_MALLOC;
156
157 while (fgets(line, (int)maxlinelen, fp) != NULL) {
158 linenum++;
159 p = line;
160
161 /* loop until first non-space char or EOL */
a8facdc0 162 while( *p != '\0' && isSpace(p) )
bc93ee84
WD
163 p++;
164
165 linelen = strlen(p);
894e6299
WD
166 if (linelen >= maxlinelen-1) {
167 free(argstr);
bc93ee84 168 return POPT_ERROR_OVERFLOW; /* XXX line too long */
894e6299 169 }
bc93ee84
WD
170
171 if (*p == '\0' || *p == '\n') continue; /* line is empty */
172 if (*p == '#') continue; /* comment line */
173
174 q = p;
175
a8facdc0 176 while (*q != '\0' && (!isSpace(q)) && *q != '=')
bc93ee84
WD
177 q++;
178
a8facdc0 179 if (isSpace(q)) {
bc93ee84
WD
180 /* a space after the name, find next non space */
181 *q++='\0';
a8facdc0 182 while( *q != '\0' && isSpace(q) ) q++;
bc93ee84
WD
183 }
184 if (*q == '\0') {
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;
192 }
a19d285a
WD
193 strlcat(argstr, " --", maxargvlen);
194 strlcat(argstr, p, maxargvlen);
bc93ee84
WD
195 continue;
196 }
197 if (*q != '=')
198 continue; /* XXX for now, silently ignore bogus line */
199
200 /* *q is an equal sign. */
201 *q++ = '\0';
202
203 /* find next non-space letter of value */
a8facdc0 204 while (*q != '\0' && isSpace(q))
bc93ee84
WD
205 q++;
206 if (*q == '\0')
207 continue; /* XXX silently ignore missing value */
208
209 /* now, loop and strip all ending whitespace */
210 x = p + linelen;
a8facdc0 211 while (isSpace(--x))
bc93ee84
WD
212 *x = 0; /* null out last char if space (including fgets() NL) */
213
214 /* rest of line accept */
215 t = x - p;
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;
221 }
a19d285a
WD
222 strlcat(argstr, " --", maxargvlen);
223 strlcat(argstr, p, maxargvlen);
224 strlcat(argstr, "=\"", maxargvlen);
225 strlcat(argstr, q, maxargvlen);
226 strlcat(argstr, "\"", maxargvlen);
bc93ee84
WD
227 }
228
229 *argstrp = argstr;
230 return 0;
231}