Commit | Line | Data |
---|---|---|
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 |
9 | int 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 |
38 | int 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 | 45 | int buflen = strlen(s) + 1; |
6afe7f23 AT |
46 | char *buf0 = calloc(buflen, 1); |
47 | char *buf = buf0; | |
62402cb1 | 48 | |
62402cb1 MP |
49 | argv[argc] = buf; |
50 | ||
b348deae | 51 | for (src = s; *src; src++) { |
62402cb1 MP |
52 | if (quote == *src) { |
53 | quote = '\0'; | |
54 | } else if (quote) { | |
55 | if (*src == '\\') { | |
56 | src++; | |
57 | if (!*src) { | |
58 | free(argv); | |
6afe7f23 | 59 | free(buf0); |
62402cb1 MP |
60 | return POPT_ERROR_BADQUOTE; |
61 | } | |
62 | if (*src != quote) *buf++ = '\\'; | |
63 | } | |
64 | *buf++ = *src; | |
65 | } else if (isspace(*src)) { | |
66 | if (*argv[argc]) { | |
67 | buf++, argc++; | |
68 | if (argc == argvAlloced) { | |
b348deae | 69 | argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; |
62402cb1 MP |
70 | argv = realloc(argv, sizeof(*argv) * argvAlloced); |
71 | } | |
72 | argv[argc] = buf; | |
73 | } | |
74 | } else switch (*src) { | |
75 | case '"': | |
76 | case '\'': | |
77 | quote = *src; | |
78 | break; | |
79 | case '\\': | |
80 | src++; | |
81 | if (!*src) { | |
82 | free(argv); | |
6afe7f23 | 83 | free(buf0); |
62402cb1 MP |
84 | return POPT_ERROR_BADQUOTE; |
85 | } | |
b348deae | 86 | /*@fallthrough@*/ |
62402cb1 MP |
87 | default: |
88 | *buf++ = *src; | |
b348deae | 89 | break; |
62402cb1 | 90 | } |
62402cb1 MP |
91 | } |
92 | ||
93 | if (strlen(argv[argc])) { | |
94 | argc++, buf++; | |
95 | } | |
96 | ||
b348deae | 97 | (void) poptDupArgv(argc, argv, argcPtr, argvPtr); |
62402cb1 MP |
98 | |
99 | free(argv); | |
6afe7f23 | 100 | free(buf0); |
62402cb1 MP |
101 | return 0; |
102 | } |