Upgrade from popt 1.2 to a cut-down 1.5
[rsync/rsync.git] / popt / poptparse.c
similarity index 52%
rename from popt-1.2/poptparse.c
rename to popt/poptparse.c
index cd97ec6..7c9f06b 100644 (file)
@@ -2,34 +2,52 @@
    file accompanying popt source distributions, available from 
    ftp://ftp.redhat.com/pub/code/popt */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "system.h"
 
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
+#define POPT_ARGV_ARRAY_GROW_DELTA 5
 
-#include "popt.h"
+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(char * s, int * argcPtr, char *** argvPtr) {
-    char * buf = strcpy(alloca(strlen(s) + 1), s);
-    char * bufStart = buf;
-    char * src, * dst;
+int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
+{
+    const char * src;
     char quote = '\0';
-    int argvAlloced = 5;
-    char ** argv = malloc(sizeof(*argv) * argvAlloced);
-    char ** argv2;
+    int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
+    const char ** argv = malloc(sizeof(*argv) * argvAlloced);
     int argc = 0;
-    int i;
+    int buflen = strlen(s) + 1;
+    char * buf = memset(alloca(buflen), 0, buflen);
 
-    src = s;
-    dst = buf;
     argv[argc] = buf;
 
-    memset(buf, '\0', strlen(s) + 1);
-
-    while (*src) {
+    for (src = s; *src; src++) {
        if (quote == *src) {
            quote = '\0';
        } else if (quote) {
@@ -46,7 +64,7 @@ int poptParseArgvString(char * s, int * argcPtr, char *** argvPtr) {
            if (*argv[argc]) {
                buf++, argc++;
                if (argc == argvAlloced) {
-                   argvAlloced += 5;
+                   argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
                    argv = realloc(argv, sizeof(*argv) * argvAlloced);
                }
                argv[argc] = buf;
@@ -62,32 +80,20 @@ int poptParseArgvString(char * s, int * argcPtr, char *** argvPtr) {
                free(argv);
                return POPT_ERROR_BADQUOTE;
            }
-           /* fallthrough */
+           /*@fallthrough@*/
          default:
            *buf++ = *src;
+           break;
        }
-
-       src++;
     }
 
     if (strlen(argv[argc])) {
        argc++, buf++;
     }
 
-    dst = malloc(argc * sizeof(*argv) + (buf - bufStart));
-    argv2 = (void *) dst;
-    dst += argc * sizeof(*argv);
-    memcpy(argv2, argv, argc * sizeof(*argv));
-    memcpy(dst, bufStart, buf - bufStart);
-
-    for (i = 0; i < argc; i++) {
-       argv2[i] = dst + (argv[i] - bufStart);
-    }
+    (void) poptDupArgv(argc, argv, argcPtr, argvPtr);
 
     free(argv);
 
-    *argvPtr = argv2;
-    *argcPtr = argc;
-
     return 0;
 }