Annotation of embedaddon/rsync/popt/poptparse.c, revision 1.1.1.1
1.1 misho 1: /** \ingroup popt
2: * \file popt/poptparse.c
3: */
4:
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. */
8:
9: #include "system.h"
10:
11: #include "poptint.h"
12:
13: #define POPT_ARGV_ARRAY_GROW_DELTA 5
14:
15: /*@-boundswrite@*/
16: int 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:
24: if (argc <= 0 || argv == NULL) /* XXX can't happen */
25: return POPT_ERROR_NOARG;
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);
33: if (dst == NULL) /* XXX can't happen */
34: return POPT_ERROR_MALLOC;
35: argv2 = (void *) dst;
36: dst += (argc + 1) * sizeof(*argv);
37:
38: /*@-branchstate@*/
39: for (i = 0; i < argc; i++) {
40: argv2[i] = dst;
41: dst += strlcpy(dst, argv[i], nb) + 1;
42: }
43: /*@=branchstate@*/
44: argv2[argc] = NULL;
45:
46: if (argvPtr) {
47: *argvPtr = argv2;
48: } else {
49: free(argv2);
50: argv2 = NULL;
51: }
52: if (argcPtr)
53: *argcPtr = argc;
54: return 0;
55: }
56: /*@=boundswrite@*/
57:
58: /*@-bounds@*/
59: int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
60: {
61: const char * src;
62: char quote = '\0';
63: int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
64: const char ** argv = malloc(sizeof(*argv) * argvAlloced);
65: int argc = 0;
66: int buflen = strlen(s) + 1;
67: char * buf = memset(alloca(buflen), 0, buflen);
68: int rc = POPT_ERROR_MALLOC;
69:
70: if (argv == NULL) return rc;
71: argv[argc] = buf;
72:
73: for (src = s; *src != '\0'; src++) {
74: if (quote == *src) {
75: quote = '\0';
76: } else if (quote != '\0') {
77: if (*src == '\\') {
78: src++;
79: if (!*src) {
80: rc = POPT_ERROR_BADQUOTE;
81: goto exit;
82: }
83: if (*src != quote) *buf++ = '\\';
84: }
85: *buf++ = *src;
86: } else if (isSpace(src)) {
87: if (*argv[argc] != '\0') {
88: buf++, argc++;
89: if (argc == argvAlloced) {
90: argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
91: argv = realloc(argv, sizeof(*argv) * argvAlloced);
92: if (argv == NULL) goto exit;
93: }
94: argv[argc] = buf;
95: }
96: } else switch (*src) {
97: case '"':
98: case '\'':
99: quote = *src;
100: /*@switchbreak@*/ break;
101: case '\\':
102: src++;
103: if (!*src) {
104: rc = POPT_ERROR_BADQUOTE;
105: goto exit;
106: }
107: /*@fallthrough@*/
108: default:
109: *buf++ = *src;
110: /*@switchbreak@*/ break;
111: }
112: }
113:
114: if (strlen(argv[argc])) {
115: argc++, buf++;
116: }
117:
118: rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
119:
120: exit:
121: if (argv) free(argv);
122: return rc;
123: }
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: */
131: int 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 */
162: while( *p != '\0' && isSpace(p) )
163: p++;
164:
165: linelen = strlen(p);
166: if (linelen >= maxlinelen-1) {
167: free(argstr);
168: return POPT_ERROR_OVERFLOW; /* XXX line too long */
169: }
170:
171: if (*p == '\0' || *p == '\n') continue; /* line is empty */
172: if (*p == '#') continue; /* comment line */
173:
174: q = p;
175:
176: while (*q != '\0' && (!isSpace(q)) && *q != '=')
177: q++;
178:
179: if (isSpace(q)) {
180: /* a space after the name, find next non space */
181: *q++='\0';
182: while( *q != '\0' && isSpace(q) ) q++;
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: }
193: strlcat(argstr, " --", maxargvlen);
194: strlcat(argstr, p, maxargvlen);
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 */
204: while (*q != '\0' && isSpace(q))
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;
211: while (isSpace(--x))
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: }
222: strlcat(argstr, " --", maxargvlen);
223: strlcat(argstr, p, maxargvlen);
224: strlcat(argstr, "=\"", maxargvlen);
225: strlcat(argstr, q, maxargvlen);
226: strlcat(argstr, "\"", maxargvlen);
227: }
228:
229: *argstrp = argstr;
230: return 0;
231: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>