source: trunk/third/popt/poptparse.c @ 15550

Revision 15550, 2.0 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15549, which included commits to RCS files with non-trunk default branches.
Line 
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
5#include "system.h"
6
7#define POPT_ARGV_ARRAY_GROW_DELTA 5
8
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}
37
38int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
39{
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 * buf = memset(alloca(buflen), 0, buflen);
47
48    argv[argc] = buf;
49
50    for (src = s; *src; src++) {
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) {
67                    argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
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            }
83            /*@fallthrough@*/
84          default:
85            *buf++ = *src;
86            break;
87        }
88    }
89
90    if (strlen(argv[argc])) {
91        argc++, buf++;
92    }
93
94    (void) poptDupArgv(argc, argv, argcPtr, argvPtr);
95
96    free(argv);
97
98    return 0;
99}
Note: See TracBrowser for help on using the repository browser.