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

1.1       misho       1: /*
                      2:  * Test suite for the wildmatch code.
                      3:  *
1.1.1.4 ! misho       4:  * Copyright (C) 2003-2019 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: 
1.1.1.4 ! misho      33: int ignore_case = 0;
1.1       misho      34: int wildmatch_errors = 0;
                     35: 
                     36: typedef char bool;
                     37: 
                     38: int output_iterations = 0;
                     39: int explode_mod = 0;
                     40: int empties_mod = 0;
                     41: int empty_at_start = 0;
                     42: int empty_at_end = 0;
                     43: 
                     44: static struct poptOption long_options[] = {
                     45:   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
                     46:   {"iterations",     'i', POPT_ARG_NONE,   &output_iterations, 0, 0, 0},
                     47:   {"empties",        'e', POPT_ARG_STRING, 0, 'e', 0, 0},
                     48:   {"explode",        'x', POPT_ARG_INT,    &explode_mod, 0, 0, 0},
                     49:   {0,0,0,0, 0, 0, 0}
                     50: };
                     51: 
                     52: /* match just at the start of string (anchored tests) */
                     53: static void
                     54: run_test(int line, bool matches,
                     55: #ifdef COMPARE_WITH_FNMATCH
                     56:         bool same_as_fnmatch,
                     57: #endif
                     58:         const char *text, const char *pattern)
                     59: {
                     60:     bool matched;
                     61: #ifdef COMPARE_WITH_FNMATCH
                     62:     bool fn_matched;
                     63:     int flags = strstr(pattern, "**")? 0 : FNM_PATHNAME;
                     64: #endif
                     65: 
                     66:     if (explode_mod) {
                     67:        char buf[MAXPATHLEN*2], *texts[MAXPATHLEN];
                     68:        int pos = 0, cnt = 0, ndx = 0, len = strlen(text);
                     69: 
                     70:        if (empty_at_start)
                     71:            texts[ndx++] = "";
                     72:        /* An empty string must turn into at least one empty array item. */
                     73:        while (1) {
                     74:            texts[ndx] = buf + ndx * (explode_mod + 1);
                     75:            strlcpy(texts[ndx++], text + pos, explode_mod + 1);
                     76:            if (pos + explode_mod >= len)
                     77:                break;
                     78:            pos += explode_mod;
                     79:            if (!(++cnt % empties_mod))
                     80:                texts[ndx++] = "";
                     81:        }
                     82:        if (empty_at_end)
                     83:            texts[ndx++] = "";
                     84:        texts[ndx] = NULL;
                     85:        matched = wildmatch_array(pattern, (const char**)texts, 0);
                     86:     } else
                     87:        matched = wildmatch(pattern, text);
                     88: #ifdef COMPARE_WITH_FNMATCH
                     89:     fn_matched = !fnmatch(pattern, text, flags);
                     90: #endif
                     91:     if (matched != matches) {
                     92:        printf("wildmatch failure on line %d:\n  %s\n  %s\n  expected %s match\n",
                     93:               line, text, pattern, matches? "a" : "NO");
                     94:        wildmatch_errors++;
                     95:     }
                     96: #ifdef COMPARE_WITH_FNMATCH
                     97:     if (fn_matched != (matches ^ !same_as_fnmatch)) {
                     98:        printf("fnmatch disagreement on line %d:\n  %s\n  %s\n  expected %s match\n",
                     99:               line, text, pattern, matches ^ !same_as_fnmatch? "a" : "NO");
                    100:        fnmatch_errors++;
                    101:     }
                    102: #endif
                    103:     if (output_iterations) {
                    104:        printf("%d: \"%s\" iterations = %d\n", line, pattern,
                    105:               wildmatch_iteration_count);
                    106:     }
                    107: }
                    108: 
                    109: int
                    110: main(int argc, char **argv)
                    111: {
                    112:     char buf[2048], *s, *string[2], *end[2];
                    113:     const char *arg;
                    114:     FILE *fp;
                    115:     int opt, line, i, flag[2];
                    116:     poptContext pc = poptGetContext("wildtest", argc, (const char**)argv,
                    117:                                    long_options, 0);
                    118: 
                    119:     while ((opt = poptGetNextOpt(pc)) != -1) {
                    120:        switch (opt) {
                    121:          case 'e':
                    122:            arg = poptGetOptArg(pc);
                    123:            empties_mod = atoi(arg);
                    124:            if (strchr(arg, 's'))
                    125:                empty_at_start = 1;
                    126:            if (strchr(arg, 'e'))
                    127:                empty_at_end = 1;
                    128:            if (!explode_mod)
                    129:                explode_mod = 1024;
                    130:            break;
                    131:          default:
                    132:            fprintf(stderr, "%s: %s\n",
                    133:                    poptBadOption(pc, POPT_BADOPTION_NOALIAS),
                    134:                    poptStrerror(opt));
                    135:            exit(1);
                    136:        }
                    137:     }
                    138: 
                    139:     if (explode_mod && !empties_mod)
                    140:        empties_mod = 1024;
                    141: 
                    142:     argv = (char**)poptGetArgs(pc);
                    143:     if (!argv || argv[1]) {
                    144:        fprintf(stderr, "Usage: wildtest [OPTIONS] TESTFILE\n");
                    145:        exit(1);
                    146:     }
                    147: 
                    148:     if ((fp = fopen(*argv, "r")) == NULL) {
                    149:        fprintf(stderr, "Unable to open %s\n", *argv);
                    150:        exit(1);
                    151:     }
                    152: 
                    153:     line = 0;
                    154:     while (fgets(buf, sizeof buf, fp)) {
                    155:        line++;
                    156:        if (*buf == '#' || *buf == '\n')
                    157:            continue;
                    158:        for (s = buf, i = 0; i <= 1; i++) {
                    159:            if (*s == '1')
                    160:                flag[i] = 1;
                    161:            else if (*s == '0')
                    162:                flag[i] = 0;
                    163:            else
                    164:                flag[i] = -1;
                    165:            if (*++s != ' ' && *s != '\t')
                    166:                flag[i] = -1;
                    167:            if (flag[i] < 0) {
                    168:                fprintf(stderr, "Invalid flag syntax on line %d of %s:\n%s",
                    169:                        line, *argv, buf);
                    170:                exit(1);
                    171:            }
                    172:            while (*++s == ' ' || *s == '\t') {}
                    173:        }
                    174:        for (i = 0; i <= 1; i++) {
                    175:            if (*s == '\'' || *s == '"' || *s == '`') {
                    176:                char quote = *s++;
                    177:                string[i] = s;
                    178:                while (*s && *s != quote) s++;
                    179:                if (!*s) {
                    180:                    fprintf(stderr, "Unmatched quote on line %d of %s:\n%s",
                    181:                            line, *argv, buf);
                    182:                    exit(1);
                    183:                }
                    184:                end[i] = s;
                    185:            }
                    186:            else {
                    187:                if (!*s || *s == '\n') {
                    188:                    fprintf(stderr, "Not enough strings on line %d of %s:\n%s",
                    189:                            line, *argv, buf);
                    190:                    exit(1);
                    191:                }
                    192:                string[i] = s;
                    193:                while (*++s && *s != ' ' && *s != '\t' && *s != '\n') {}
                    194:                end[i] = s;
                    195:            }
                    196:            while (*++s == ' ' || *s == '\t') {}
                    197:        }
                    198:        *end[0] = *end[1] = '\0';
                    199:        run_test(line, flag[0],
                    200: #ifdef COMPARE_WITH_FNMATCH
                    201:                 flag[1],
                    202: #endif
                    203:                 string[0], string[1]);
                    204:     }
                    205: 
                    206:     if (!wildmatch_errors)
                    207:        fputs("No", stdout);
                    208:     else
                    209:        printf("%d", wildmatch_errors);
                    210:     printf(" wildmatch error%s found.\n", wildmatch_errors == 1? "" : "s");
                    211: 
                    212: #ifdef COMPARE_WITH_FNMATCH
                    213:     if (!fnmatch_errors)
                    214:        fputs("No", stdout);
                    215:     else
                    216:        printf("%d", fnmatch_errors);
                    217:     printf(" fnmatch error%s found.\n", fnmatch_errors == 1? "" : "s");
                    218: 
                    219: #endif
                    220: 
                    221:     return 0;
                    222: }

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