Upgrade from popt 1.2 to a cut-down 1.5
[rsync/rsync.git] / popt / poptparse.c
CommitLineData
62402cb1
MP
1/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
2 file accompanying popt source distributions, available from
3 ftp://ftp.redhat.com/pub/code/popt */
4
b348deae 5#include "system.h"
62402cb1 6
b348deae 7#define POPT_ARGV_ARRAY_GROW_DELTA 5
62402cb1 8
b348deae
MP
9int poptDupArgv(int argc, const char **argv,
10 int * argcPtr, const char *** argvPtr)
11{
12 size_t nb = (argc + 1) * sizeof(*argv);
13 const char ** argv2;
14 char * dst;
15 int i;
16
17 for (i = 0; i < argc; i++) {
18 if (argv[i] == NULL)
19 return POPT_ERROR_NOARG;
20 nb += strlen(argv[i]) + 1;
21 }
22
23 dst = malloc(nb);
24 argv2 = (void *) dst;
25 dst += (argc + 1) * sizeof(*argv);
26
27 for (i = 0; i < argc; i++) {
28 argv2[i] = dst;
29 dst += strlen(strcpy(dst, argv[i])) + 1;
30 }
31 argv2[argc] = NULL;
32
33 *argvPtr = argv2;
34 *argcPtr = argc;
35 return 0;
36}
62402cb1 37
b348deae
MP
38int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
39{
40 const char * src;
62402cb1 41 char quote = '\0';
b348deae
MP
42 int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
43 const char ** argv = malloc(sizeof(*argv) * argvAlloced);
62402cb1 44 int argc = 0;
b348deae
MP
45 int buflen = strlen(s) + 1;
46 char * buf = memset(alloca(buflen), 0, buflen);
62402cb1 47
62402cb1
MP
48 argv[argc] = buf;
49
b348deae 50 for (src = s; *src; src++) {
62402cb1
MP
51 if (quote == *src) {
52 quote = '\0';
53 } else if (quote) {
54 if (*src == '\\') {
55 src++;
56 if (!*src) {
57 free(argv);
58 return POPT_ERROR_BADQUOTE;
59 }
60 if (*src != quote) *buf++ = '\\';
61 }
62 *buf++ = *src;
63 } else if (isspace(*src)) {
64 if (*argv[argc]) {
65 buf++, argc++;
66 if (argc == argvAlloced) {
b348deae 67 argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
62402cb1
MP
68 argv = realloc(argv, sizeof(*argv) * argvAlloced);
69 }
70 argv[argc] = buf;
71 }
72 } else switch (*src) {
73 case '"':
74 case '\'':
75 quote = *src;
76 break;
77 case '\\':
78 src++;
79 if (!*src) {
80 free(argv);
81 return POPT_ERROR_BADQUOTE;
82 }
b348deae 83 /*@fallthrough@*/
62402cb1
MP
84 default:
85 *buf++ = *src;
b348deae 86 break;
62402cb1 87 }
62402cb1
MP
88 }
89
90 if (strlen(argv[argc])) {
91 argc++, buf++;
92 }
93
b348deae 94 (void) poptDupArgv(argc, argv, argcPtr, argvPtr);
62402cb1
MP
95
96 free(argv);
97
62402cb1
MP
98 return 0;
99}