summaryrefslogtreecommitdiff
path: root/source4/popt/poptparse.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-08-13 01:53:07 +0000
committerAndrew Tridgell <tridge@samba.org>2003-08-13 01:53:07 +0000
commitcc3a6ea9920f30925a678c566b4af417da6d455b (patch)
tree60015a1a5f4b47ac3d133bdbbe32b75815595d4d /source4/popt/poptparse.c
parent4d1f9d1def5bf5fea64722626028d94da49c654c (diff)
parentef2e26c91b80556af033d3335e55f5dfa6fff31d (diff)
downloadsamba-cc3a6ea9920f30925a678c566b4af417da6d455b.tar.gz
samba-cc3a6ea9920f30925a678c566b4af417da6d455b.tar.bz2
samba-cc3a6ea9920f30925a678c566b4af417da6d455b.zip
This commit was generated by cvs2svn to compensate for changes in r30,
which included commits to RCS files with non-trunk default branches. (This used to be commit 3a69cffb062d4f1238b8cae10481c1f2ea4d3d8b)
Diffstat (limited to 'source4/popt/poptparse.c')
-rw-r--r--source4/popt/poptparse.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/source4/popt/poptparse.c b/source4/popt/poptparse.c
new file mode 100644
index 0000000000..8f00769be9
--- /dev/null
+++ b/source4/popt/poptparse.c
@@ -0,0 +1,102 @@
+/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
+ file accompanying popt source distributions, available from
+ ftp://ftp.redhat.com/pub/code/popt */
+
+#include "system.h"
+
+#define POPT_ARGV_ARRAY_GROW_DELTA 5
+
+int poptDupArgv(int argc, const char **argv,
+ int * argcPtr, const char *** argvPtr)
+{
+ size_t nb = (argc + 1) * sizeof(*argv);
+ const char ** argv2;
+ char * dst;
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ if (argv[i] == NULL)
+ return POPT_ERROR_NOARG;
+ nb += strlen(argv[i]) + 1;
+ }
+
+ dst = malloc(nb);
+ argv2 = (void *) dst;
+ dst += (argc + 1) * sizeof(*argv);
+
+ for (i = 0; i < argc; i++) {
+ argv2[i] = dst;
+ dst += strlen(strcpy(dst, argv[i])) + 1;
+ }
+ argv2[argc] = NULL;
+
+ *argvPtr = argv2;
+ *argcPtr = argc;
+ return 0;
+}
+
+int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
+{
+ const char * src;
+ char quote = '\0';
+ int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
+ const char ** argv = malloc(sizeof(*argv) * argvAlloced);
+ int argc = 0;
+ int buflen = strlen(s) + 1;
+ char *buf0 = calloc(buflen, 1);
+ char *buf = buf0;
+
+ argv[argc] = buf;
+
+ for (src = s; *src; src++) {
+ if (quote == *src) {
+ quote = '\0';
+ } else if (quote) {
+ if (*src == '\\') {
+ src++;
+ if (!*src) {
+ free(argv);
+ free(buf0);
+ return POPT_ERROR_BADQUOTE;
+ }
+ if (*src != quote) *buf++ = '\\';
+ }
+ *buf++ = *src;
+ } else if (isspace(*src)) {
+ if (*argv[argc]) {
+ buf++, argc++;
+ if (argc == argvAlloced) {
+ argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
+ argv = realloc(argv, sizeof(*argv) * argvAlloced);
+ }
+ argv[argc] = buf;
+ }
+ } else switch (*src) {
+ case '"':
+ case '\'':
+ quote = *src;
+ break;
+ case '\\':
+ src++;
+ if (!*src) {
+ free(argv);
+ free(buf0);
+ return POPT_ERROR_BADQUOTE;
+ }
+ /*@fallthrough@*/
+ default:
+ *buf++ = *src;
+ break;
+ }
+ }
+
+ if (strlen(argv[argc])) {
+ argc++, buf++;
+ }
+
+ (void) poptDupArgv(argc, argv, argcPtr, argvPtr);
+
+ free(argv);
+ free(buf0);
+ return 0;
+}