Annotation of embedaddon/sudo/compat/regress/glob/globtest.c, revision 1.1.1.1

1.1       misho       1: /*     $OpenBSD: globtest.c,v 1.1 2008/10/01 23:04:36 millert Exp $    */
                      2: 
                      3: /*
                      4:  * Public domain, 2008, Todd C. Miller <Todd.Miller@courtesan.com>
                      5:  */
                      6: 
                      7: #include <config.h>
                      8: 
                      9: #include <stdio.h>
                     10: #include <stdlib.h>
                     11: #ifdef HAVE_STRING_H
                     12: # include <string.h>
                     13: #endif /* HAVE_STRING_H */
                     14: #ifdef HAVE_STRINGS_H
                     15: # include <strings.h>
                     16: #endif /* HAVE_STRINGS_H */
                     17: #ifdef HAVE_EXTENDED_GLOB
                     18: # include <glob.h>
                     19: #else
                     20: # include "compat/glob.h"
                     21: #endif
                     22: #include <errno.h>
                     23: 
                     24: #include "missing.h"
                     25: 
                     26: #define MAX_RESULTS    256
                     27: 
                     28: struct gl_entry {
                     29:        int flags;
                     30:        int nresults;
                     31:        char pattern[1024];
                     32:        char *results[MAX_RESULTS];
                     33: };
                     34: 
                     35: int test_glob(struct gl_entry *);
                     36: 
                     37: int
                     38: main(int argc, char **argv)
                     39: {
                     40:        FILE *fp = stdin;
                     41:        char buf[2048], *cp, *ep;
                     42:        int errors = 0, tests = 0, lineno;
                     43:        struct gl_entry entry;
                     44:        size_t len;
                     45: 
                     46:        if (argc > 1) {
                     47:                if ((fp = fopen(argv[1], "r")) == NULL) {
                     48:                        perror(argv[1]);
                     49:                        exit(1);
                     50:                }
                     51:        }
                     52: 
                     53:        /*
                     54:         * Read in test file, which is formatted thusly:
                     55:         *
                     56:         * [pattern] <flags>
                     57:         * result1
                     58:         * result2
                     59:         * result3
                     60:         * ...
                     61:         *
                     62:         */
                     63:        lineno = 0;
                     64:        memset(&entry, 0, sizeof(entry));
                     65:        while (fgets(buf, sizeof(buf), fp) != NULL) {
                     66:                lineno++;
                     67:                len = strlen(buf);
                     68:                if (len > 0) {
                     69:                        if (buf[len - 1] != '\n') {
                     70:                                fprintf(stderr,
                     71:                                    "globtest: missing newline at EOF\n");
                     72:                                exit(1);
                     73:                        }
                     74:                        buf[--len] = '\0';
                     75:                }
                     76:                if (len == 0)
                     77:                        continue; /* blank line */
                     78: 
                     79:                if (buf[0] == '[') {
                     80:                        /* check previous pattern */
                     81:                        if (entry.pattern[0]) {
                     82:                                errors += test_glob(&entry);
                     83:                                tests++;
                     84:                        }
                     85: 
                     86:                        /* start new entry */
                     87:                        if ((cp = strrchr(buf + 1, ']')) == NULL) {
                     88:                                fprintf(stderr,
                     89:                                    "globtest: invalid entry on line %d\n",
                     90:                                    lineno);
                     91:                                exit(1);
                     92:                        }
                     93:                        len = cp - buf - 1;
                     94:                        if (len >= sizeof(entry.pattern)) {
                     95:                                fprintf(stderr,
                     96:                                    "globtest: pattern too big on line %d\n",
                     97:                                    lineno);
                     98:                                exit(1);
                     99:                        }
                    100:                        memcpy(entry.pattern, buf + 1, len);
                    101:                        entry.pattern[len] = '\0';
                    102: 
                    103:                        cp += 2;
                    104:                        if (*cp++ != '<') {
                    105:                                fprintf(stderr,
                    106:                                    "globtest: invalid entry on line %d\n",
                    107:                                    lineno);
                    108:                                exit(1);
                    109:                        }
                    110:                        ep = strchr(cp, '>');
                    111:                        if (ep == NULL) {
                    112:                                fprintf(stderr,
                    113:                                    "globtest: invalid entry on line %d\n",
                    114:                                    lineno);
                    115:                                exit(1);
                    116:                        }
                    117:                        *ep = '\0';
                    118:                        entry.flags = 0;
                    119:                        for ((cp = strtok(cp, "|")); cp != NULL; (cp = strtok(NULL, "|"))) {
                    120:                                if (strcmp(cp, "GLOB_APPEND") == 0)
                    121:                                        entry.flags |= GLOB_APPEND;
                    122:                                else if (strcmp(cp, "GLOB_DOOFFS") == 0)
                    123:                                        entry.flags |= GLOB_DOOFFS;
                    124:                                else if (strcmp(cp, "GLOB_ERR") == 0)
                    125:                                        entry.flags |= GLOB_ERR;
                    126:                                else if (strcmp(cp, "GLOB_MARK") == 0)
                    127:                                        entry.flags |= GLOB_MARK;
                    128:                                else if (strcmp(cp, "GLOB_NOCHECK") == 0)
                    129:                                        entry.flags |= GLOB_NOCHECK;
                    130:                                else if (strcmp(cp, "GLOB_NOSORT") == 0)
                    131:                                        entry.flags |= GLOB_NOSORT;
                    132:                                else if (strcmp(cp, "GLOB_NOESCAPE") == 0)
                    133:                                        entry.flags |= GLOB_NOESCAPE;
                    134:                                else if (strcmp(cp, "GLOB_BRACE") == 0)
                    135:                                        entry.flags |= GLOB_BRACE;
                    136:                                else if (strcmp(cp, "GLOB_TILDE") == 0)
                    137:                                        entry.flags |= GLOB_TILDE;
                    138:                                else if (strcmp(cp, "NONE") != 0) {
                    139:                                        fprintf(stderr,
                    140:                                            "globtest: invalid flags on line %d\n",
                    141:                                            lineno);
                    142:                                        exit(1);
                    143:                                }
                    144:                        }
                    145:                        entry.nresults = 0;
                    146:                        continue;
                    147:                }
                    148:                if (!entry.pattern[0]) {
                    149:                        fprintf(stderr, "globtest: missing entry on line %d\n",
                    150:                            lineno);
                    151:                        exit(1);
                    152:                }
                    153: 
                    154:                if (entry.nresults + 1 > MAX_RESULTS) {
                    155:                        fprintf(stderr,
                    156:                            "globtest: too many results for %s, max %d\n",
                    157:                            entry.pattern, MAX_RESULTS);
                    158:                        exit(1);
                    159:                }
                    160:                entry.results[entry.nresults++] = strdup(buf);
                    161:        }
                    162:        if (entry.pattern[0]) {
                    163:                errors += test_glob(&entry); /* test last pattern */
                    164:                tests++;
                    165:        }
                    166:         if (tests != 0) {
                    167:                printf("glob: %d test%s run, %d errors, %d%% success rate\n",
                    168:                    tests, tests == 1 ? "" : "s", errors,
                    169:                    (tests - errors) * 100 / tests);
                    170:         }
                    171:        exit(errors);
                    172: }
                    173: 
                    174: int test_glob(struct gl_entry *entry)
                    175: {
                    176:        glob_t gl;
                    177:        char **ap;
                    178:        int nmatches = 0, i = 0;
                    179: 
                    180:        if (glob(entry->pattern, entry->flags, NULL, &gl) != 0) {
                    181:                fprintf(stderr, "glob failed: %s: %s\n", entry->pattern,
                    182:                    strerror(errno));
                    183:                exit(1);
                    184:        }
                    185: 
                    186:        for (ap = gl.gl_pathv; *ap != NULL; ap++)
                    187:                nmatches++;
                    188: 
                    189:        if (nmatches != entry->nresults)
                    190:                goto mismatch;
                    191: 
                    192:        for (i = 0; i < entry->nresults; i++) {
                    193:                if (strcmp(gl.gl_pathv[i], entry->results[i]) != 0)
                    194:                        goto mismatch;
                    195:                free(entry->results[i]);
                    196:        }
                    197:        return 0;
                    198:  mismatch:
                    199:        if (nmatches != entry->nresults) {
                    200:                fprintf(stderr,
                    201:                    "globtest: mismatch in number of results (found %d, expected %d) for pattern %s\n",
                    202:                    nmatches, entry->nresults, entry->pattern);
                    203:        } else {
                    204:                fprintf(stderr, "globtest: mismatch for pattern %s, flags 0x%x "
                    205:                    "(found \"%s\", expected \"%s\")\n", entry->pattern, entry->flags,
                    206:                    gl.gl_pathv[i], entry->results[i]);
                    207:                while (i < entry->nresults)
                    208:                        free(entry->results[i++]);
                    209:        }
                    210:        return 1;
                    211: }

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