Annotation of embedaddon/rsync/wildtest.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:  * Test suite for the wildmatch code.
                      3:  *
1.1.1.3 ! misho       4:  * Copyright (C) 2003-2015 Wayne Davison
1.1       misho       5:  *
                      6:  * This program is free software; you can redistribute it and/or modify
                      7:  * it under the terms of the GNU General Public License as published by
                      8:  * the Free Software Foundation; either version 3 of the License, or
                      9:  * (at your option) any later version.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:  * GNU General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License along
                     17:  * with this program; if not, visit the http://fsf.org website.
                     18:  */
                     19: 
                     20: /*#define COMPARE_WITH_FNMATCH*/
                     21: 
                     22: #define WILD_TEST_ITERATIONS
                     23: #include "lib/wildmatch.c"
                     24: 
                     25: #include <popt.h>
                     26: 
                     27: #ifdef COMPARE_WITH_FNMATCH
                     28: #include <fnmatch.h>
                     29: 
                     30: int fnmatch_errors = 0;
                     31: #endif
                     32: 
                     33: int wildmatch_errors = 0;
                     34: 
                     35: typedef char bool;
                     36: 
                     37: int output_iterations = 0;
                     38: int explode_mod = 0;
                     39: int empties_mod = 0;
                     40: int empty_at_start = 0;
                     41: int empty_at_end = 0;
                     42: 
                     43: static struct poptOption long_options[] = {
                     44:   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
                     45:   {"iterations",     'i', POPT_ARG_NONE,   &output_iterations, 0, 0, 0},
                     46:   {"empties",        'e', POPT_ARG_STRING, 0, 'e', 0, 0},
                     47:   {"explode",        'x', POPT_ARG_INT,    &explode_mod, 0, 0, 0},
                     48:   {0,0,0,0, 0, 0, 0}
                     49: };
                     50: 
                     51: /* match just at the start of string (anchored tests) */
                     52: static void
                     53: run_test(int line, bool matches,
                     54: #ifdef COMPARE_WITH_FNMATCH
                     55:         bool same_as_fnmatch,
                     56: #endif
                     57:         const char *text, const char *pattern)
                     58: {
                     59:     bool matched;
                     60: #ifdef COMPARE_WITH_FNMATCH
                     61:     bool fn_matched;
                     62:     int flags = strstr(pattern, "**")? 0 : FNM_PATHNAME;
                     63: #endif
                     64: 
                     65:     if (explode_mod) {
                     66:        char buf[MAXPATHLEN*2], *texts[MAXPATHLEN];
                     67:        int pos = 0, cnt = 0, ndx = 0, len = strlen(text);
                     68: 
                     69:        if (empty_at_start)
                     70:            texts[ndx++] = "";
                     71:        /* An empty string must turn into at least one empty array item. */
                     72:        while (1) {
                     73:            texts[ndx] = buf + ndx * (explode_mod + 1);
                     74:            strlcpy(texts[ndx++], text + pos, explode_mod + 1);
                     75:            if (pos + explode_mod >= len)
                     76:                break;
                     77:            pos += explode_mod;
                     78:            if (!(++cnt % empties_mod))
                     79:                texts[ndx++] = "";
                     80:        }
                     81:        if (empty_at_end)
                     82:            texts[ndx++] = "";
                     83:        texts[ndx] = NULL;
                     84:        matched = wildmatch_array(pattern, (const char**)texts, 0);
                     85:     } else
                     86:        matched = wildmatch(pattern, text);
                     87: #ifdef COMPARE_WITH_FNMATCH
                     88:     fn_matched = !fnmatch(pattern, text, flags);
                     89: #endif
                     90:     if (matched != matches) {
                     91:        printf("wildmatch failure on line %d:\n  %s\n  %s\n  expected %s match\n",
                     92:               line, text, pattern, matches? "a" : "NO");
                     93:        wildmatch_errors++;
                     94:     }
                     95: #ifdef COMPARE_WITH_FNMATCH
                     96:     if (fn_matched != (matches ^ !same_as_fnmatch)) {
                     97:        printf("fnmatch disagreement on line %d:\n  %s\n  %s\n  expected %s match\n",
                     98:               line, text, pattern, matches ^ !same_as_fnmatch? "a" : "NO");
                     99:        fnmatch_errors++;
                    100:     }
                    101: #endif
                    102:     if (output_iterations) {
                    103:        printf("%d: \"%s\" iterations = %d\n", line, pattern,
                    104:               wildmatch_iteration_count);
                    105:     }
                    106: }
                    107: 
                    108: int
                    109: main(int argc, char **argv)
                    110: {
                    111:     char buf[2048], *s, *string[2], *end[2];
                    112:     const char *arg;
                    113:     FILE *fp;
                    114:     int opt, line, i, flag[2];
                    115:     poptContext pc = poptGetContext("wildtest", argc, (const char**)argv,
                    116:                                    long_options, 0);
                    117: 
                    118:     while ((opt = poptGetNextOpt(pc)) != -1) {
                    119:        switch (opt) {
                    120:          case 'e':
                    121:            arg = poptGetOptArg(pc);
                    122:            empties_mod = atoi(arg);
                    123:            if (strchr(arg, 's'))
                    124:                empty_at_start = 1;
                    125:            if (strchr(arg, 'e'))
                    126:                empty_at_end = 1;
                    127:            if (!explode_mod)
                    128:                explode_mod = 1024;
                    129:            break;
                    130:          default:
                    131:            fprintf(stderr, "%s: %s\n",
                    132:                    poptBadOption(pc, POPT_BADOPTION_NOALIAS),
                    133:                    poptStrerror(opt));
                    134:            exit(1);
                    135:        }
                    136:     }
                    137: 
                    138:     if (explode_mod && !empties_mod)
                    139:        empties_mod = 1024;
                    140: 
                    141:     argv = (char**)poptGetArgs(pc);
                    142:     if (!argv || argv[1]) {
                    143:        fprintf(stderr, "Usage: wildtest [OPTIONS] TESTFILE\n");
                    144:        exit(1);
                    145:     }
                    146: 
                    147:     if ((fp = fopen(*argv, "r")) == NULL) {
                    148:        fprintf(stderr, "Unable to open %s\n", *argv);
                    149:        exit(1);
                    150:     }
                    151: 
                    152:     line = 0;
                    153:     while (fgets(buf, sizeof buf, fp)) {
                    154:        line++;
                    155:        if (*buf == '#' || *buf == '\n')
                    156:            continue;
                    157:        for (s = buf, i = 0; i <= 1; i++) {
                    158:            if (*s == '1')
                    159:                flag[i] = 1;
                    160:            else if (*s == '0')
                    161:                flag[i] = 0;
                    162:            else
                    163:                flag[i] = -1;
                    164:            if (*++s != ' ' && *s != '\t')
                    165:                flag[i] = -1;
                    166:            if (flag[i] < 0) {
                    167:                fprintf(stderr, "Invalid flag syntax on line %d of %s:\n%s",
                    168:                        line, *argv, buf);
                    169:                exit(1);
                    170:            }
                    171:            while (*++s == ' ' || *s == '\t') {}
                    172:        }
                    173:        for (i = 0; i <= 1; i++) {
                    174:            if (*s == '\'' || *s == '"' || *s == '`') {
                    175:                char quote = *s++;
                    176:                string[i] = s;
                    177:                while (*s && *s != quote) s++;
                    178:                if (!*s) {
                    179:                    fprintf(stderr, "Unmatched quote on line %d of %s:\n%s",
                    180:                            line, *argv, buf);
                    181:                    exit(1);
                    182:                }
                    183:                end[i] = s;
                    184:            }
                    185:            else {
                    186:                if (!*s || *s == '\n') {
                    187:                    fprintf(stderr, "Not enough strings on line %d of %s:\n%s",
                    188:                            line, *argv, buf);
                    189:                    exit(1);
                    190:                }
                    191:                string[i] = s;
                    192:                while (*++s && *s != ' ' && *s != '\t' && *s != '\n') {}
                    193:                end[i] = s;
                    194:            }
                    195:            while (*++s == ' ' || *s == '\t') {}
                    196:        }
                    197:        *end[0] = *end[1] = '\0';
                    198:        run_test(line, flag[0],
                    199: #ifdef COMPARE_WITH_FNMATCH
                    200:                 flag[1],
                    201: #endif
                    202:                 string[0], string[1]);
                    203:     }
                    204: 
                    205:     if (!wildmatch_errors)
                    206:        fputs("No", stdout);
                    207:     else
                    208:        printf("%d", wildmatch_errors);
                    209:     printf(" wildmatch error%s found.\n", wildmatch_errors == 1? "" : "s");
                    210: 
                    211: #ifdef COMPARE_WITH_FNMATCH
                    212:     if (!fnmatch_errors)
                    213:        fputs("No", stdout);
                    214:     else
                    215:        printf("%d", fnmatch_errors);
                    216:     printf(" fnmatch error%s found.\n", fnmatch_errors == 1? "" : "s");
                    217: 
                    218: #endif
                    219: 
                    220:     return 0;
                    221: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>