must add one to the extra_data size to transfer the 0 string terminator.
[Samba/gebeck_regimport.git] / source3 / popt / poptparse.c
blob8f00769be9fec7343cd317b9f579e5b7bbd34e93
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 */
5 #include "system.h"
7 #define POPT_ARGV_ARRAY_GROW_DELTA 5
9 int poptDupArgv(int argc, const char **argv,
10 int * argcPtr, const char *** argvPtr)
12 size_t nb = (argc + 1) * sizeof(*argv);
13 const char ** argv2;
14 char * dst;
15 int i;
17 for (i = 0; i < argc; i++) {
18 if (argv[i] == NULL)
19 return POPT_ERROR_NOARG;
20 nb += strlen(argv[i]) + 1;
23 dst = malloc(nb);
24 argv2 = (void *) dst;
25 dst += (argc + 1) * sizeof(*argv);
27 for (i = 0; i < argc; i++) {
28 argv2[i] = dst;
29 dst += strlen(strcpy(dst, argv[i])) + 1;
31 argv2[argc] = NULL;
33 *argvPtr = argv2;
34 *argcPtr = argc;
35 return 0;
38 int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
40 const char * src;
41 char quote = '\0';
42 int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
43 const char ** argv = malloc(sizeof(*argv) * argvAlloced);
44 int argc = 0;
45 int buflen = strlen(s) + 1;
46 char *buf0 = calloc(buflen, 1);
47 char *buf = buf0;
49 argv[argc] = buf;
51 for (src = s; *src; src++) {
52 if (quote == *src) {
53 quote = '\0';
54 } else if (quote) {
55 if (*src == '\\') {
56 src++;
57 if (!*src) {
58 free(argv);
59 free(buf0);
60 return POPT_ERROR_BADQUOTE;
62 if (*src != quote) *buf++ = '\\';
64 *buf++ = *src;
65 } else if (isspace(*src)) {
66 if (*argv[argc]) {
67 buf++, argc++;
68 if (argc == argvAlloced) {
69 argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
70 argv = realloc(argv, sizeof(*argv) * argvAlloced);
72 argv[argc] = buf;
74 } else switch (*src) {
75 case '"':
76 case '\'':
77 quote = *src;
78 break;
79 case '\\':
80 src++;
81 if (!*src) {
82 free(argv);
83 free(buf0);
84 return POPT_ERROR_BADQUOTE;
86 /*@fallthrough@*/
87 default:
88 *buf++ = *src;
89 break;
93 if (strlen(argv[argc])) {
94 argc++, buf++;
97 (void) poptDupArgv(argc, argv, argcPtr, argvPtr);
99 free(argv);
100 free(buf0);
101 return 0;