Use seteuid() (if available) when using setuid().
[rsync.git] / wildtest.c
index 3c40e4ae5504c9fb6313e64d48f507d7a78c2349..bd1f4cc27a6101d4f605719480d4b60a57ce2f3b 100644 (file)
@@ -1,13 +1,28 @@
 /*
-**  wildmatch test suite.
-*/
+ * Test suite for the wildmatch code.
+ *
+ * Copyright (C) 2003-2009 Wayne Davison
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, visit the http://fsf.org website.
+ */
 
 /*#define COMPARE_WITH_FNMATCH*/
 
 #define WILD_TEST_ITERATIONS
 #include "lib/wildmatch.c"
 
-#include "popt.h"
+#include <popt.h>
 
 #ifdef COMPARE_WITH_FNMATCH
 #include <fnmatch.h>
@@ -19,14 +34,17 @@ int wildmatch_errors = 0;
 
 typedef char bool;
 
-#define false 0
-#define true 1
-
 int output_iterations = 0;
+int explode_mod = 0;
+int empties_mod = 0;
+int empty_at_start = 0;
+int empty_at_end = 0;
 
 static struct poptOption long_options[] = {
   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
   {"iterations",     'i', POPT_ARG_NONE,   &output_iterations, 0, 0, 0},
+  {"empties",        'e', POPT_ARG_STRING, 0, 'e', 0, 0},
+  {"explode",        'x', POPT_ARG_INT,    &explode_mod, 0, 0, 0},
   {0,0,0,0, 0, 0, 0}
 };
 
@@ -43,7 +61,28 @@ run_test(int line, bool matches, bool same_as_fnmatch,
     same_as_fnmatch = 0; /* Get rid of unused-variable compiler warning. */
 #endif
 
-    matched = wildmatch(pattern, text);
+    if (explode_mod) {
+       char buf[MAXPATHLEN*2], *texts[MAXPATHLEN];
+       int pos = 0, cnt = 0, ndx = 0, len = strlen(text);
+
+       if (empty_at_start)
+           texts[ndx++] = "";
+       /* An empty string must turn into at least one empty array item. */
+       while (1) {
+           texts[ndx] = buf + ndx * (explode_mod + 1);
+           strlcpy(texts[ndx++], text + pos, explode_mod + 1);
+           if (pos + explode_mod >= len)
+               break;
+           pos += explode_mod;
+           if (!(++cnt % empties_mod))
+               texts[ndx++] = "";
+       }
+       if (empty_at_end)
+           texts[ndx++] = "";
+       texts[ndx] = NULL;
+       matched = wildmatch_array(pattern, (const char**)texts, 0);
+    } else
+       matched = wildmatch(pattern, text);
 #ifdef COMPARE_WITH_FNMATCH
     fn_matched = !fnmatch(pattern, text, flags);
 #endif
@@ -69,6 +108,7 @@ int
 main(int argc, char **argv)
 {
     char buf[2048], *s, *string[2], *end[2];
+    const char *arg;
     FILE *fp;
     int opt, line, i, flag[2];
     poptContext pc = poptGetContext("wildtest", argc, (const char**)argv,
@@ -76,6 +116,16 @@ main(int argc, char **argv)
 
     while ((opt = poptGetNextOpt(pc)) != -1) {
        switch (opt) {
+         case 'e':
+           arg = poptGetOptArg(pc);
+           empties_mod = atoi(arg);
+           if (strchr(arg, 's'))
+               empty_at_start = 1;
+           if (strchr(arg, 'e'))
+               empty_at_end = 1;
+           if (!explode_mod)
+               explode_mod = 1024;
+           break;
          default:
            fprintf(stderr, "%s: %s\n",
                    poptBadOption(pc, POPT_BADOPTION_NOALIAS),
@@ -84,8 +134,17 @@ main(int argc, char **argv)
        }
     }
 
-    if ((fp = fopen("wildtest.txt", "r")) == NULL) {
-       fprintf(stderr, "Unable to open wildtest.txt.\n");
+    if (explode_mod && !empties_mod)
+       empties_mod = 1024;
+
+    argv = (char**)poptGetArgs(pc);
+    if (!argv || argv[1]) {
+       fprintf(stderr, "Usage: wildtest [OPTIONS] TESTFILE\n");
+       exit(1);
+    }
+
+    if ((fp = fopen(*argv, "r")) == NULL) {
+       fprintf(stderr, "Unable to open %s\n", *argv);
        exit(1);
     }
 
@@ -104,8 +163,8 @@ main(int argc, char **argv)
            if (*++s != ' ' && *s != '\t')
                flag[i] = -1;
            if (flag[i] < 0) {
-               fprintf(stderr, "Invalid flag syntax on line %d of wildtest.txt:%s\n",
-                       line, buf);
+               fprintf(stderr, "Invalid flag syntax on line %d of %s:\n%s",
+                       line, *argv, buf);
                exit(1);
            }
            while (*++s == ' ' || *s == '\t') {}
@@ -116,16 +175,16 @@ main(int argc, char **argv)
                string[i] = s;
                while (*s && *s != quote) s++;
                if (!*s) {
-                   fprintf(stderr, "Unmatched quote on line %d of wildtest.txt:%s\n",
-                           line, buf);
+                   fprintf(stderr, "Unmatched quote on line %d of %s:\n%s",
+                           line, *argv, buf);
                    exit(1);
                }
                end[i] = s;
            }
            else {
                if (!*s || *s == '\n') {
-                   fprintf(stderr, "Not enough strings on line %d of wildtest.txt:%s\n",
-                           line, buf);
+                   fprintf(stderr, "Not enough strings on line %d of %s:\n%s",
+                           line, *argv, buf);
                    exit(1);
                }
                string[i] = s;
@@ -139,15 +198,17 @@ main(int argc, char **argv)
     }
 
     if (!wildmatch_errors)
-       printf("No wildmatch errors found.\n");
+       fputs("No", stdout);
     else
-       printf("Found %d wildmatch errors.\n", wildmatch_errors);
+       printf("%d", wildmatch_errors);
+    printf(" wildmatch error%s found.\n", wildmatch_errors == 1? "" : "s");
 
 #ifdef COMPARE_WITH_FNMATCH
     if (!fnmatch_errors)
-       printf("No fnmatch errors found.\n");
+       fputs("No", stdout);
     else
-       printf("Found %d fnmatch errors.\n", fnmatch_errors);
+       printf("%d", fnmatch_errors);
+    printf(" fnmatch error%s found.\n", fnmatch_errors == 1? "" : "s");
 
 #endif