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 <err.h> 8 #include <glob.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #define MAX_RESULTS 256 14 15 struct gl_entry { 16 int flags; 17 int nresults; 18 char pattern[1024]; 19 char *results[MAX_RESULTS]; 20 }; 21 22 int test_glob(struct gl_entry *); 23 24 int 25 main(int argc, char **argv) 26 { 27 FILE *fp = stdin; 28 char *buf, *cp, *want, *got, *last; 29 const char *errstr; 30 int errors = 0, i, lineno; 31 struct gl_entry entry; 32 size_t len; 33 34 if (argc > 1) { 35 if ((fp = fopen(argv[1], "r")) == NULL) 36 err(1, "%s", argv[1]); 37 } 38 39 /* 40 * Read in test file, which is formatted thusly: 41 * 42 * [pattern] <flags> 43 * result1 44 * result2 45 * result3 46 * ... 47 * 48 */ 49 lineno = 0; 50 memset(&entry, 0, sizeof(entry)); 51 while ((buf = fgetln(fp, &len)) != NULL) { 52 lineno++; 53 if (buf[len - 1] != '\n') 54 errx(1, "missing newline at EOF"); 55 buf[--len] = '\0'; 56 if (len == 0) 57 continue; /* blank line */ 58 59 if (buf[0] == '[') { 60 /* check previous pattern */ 61 if (entry.pattern[0]) 62 errors += test_glob(&entry); 63 64 /* start new entry */ 65 if ((cp = strrchr(buf + 1, ']')) == NULL) 66 errx(1, "invalid entry on line %d", lineno); 67 len = cp - buf - 1; 68 if (len >= sizeof(entry.pattern)) 69 errx(1, "pattern too big on line %d", lineno); 70 memcpy(entry.pattern, buf + 1, len); 71 entry.pattern[len] = '\0'; 72 73 buf = cp + 2; 74 if (*buf++ != '<') 75 errx(1, "invalid entry on line %d", lineno); 76 if ((cp = strchr(buf, '>')) == NULL) 77 errx(1, "invalid entry on line %d", lineno); 78 entry.flags = (int)strtol(buf, &cp, 0); 79 if (*cp != '>' || entry.flags < 0 || entry.flags > 0x2000) 80 errx(1, "invalid flags: %s", buf); 81 entry.nresults = 0; 82 continue; 83 } 84 if (!entry.pattern[0]) 85 errx(1, "missing entry on line %d", lineno); 86 87 if (entry.nresults + 1 > MAX_RESULTS) { 88 errx(1, "too many results for %s, max %d", 89 entry.pattern, MAX_RESULTS); 90 } 91 entry.results[entry.nresults++] = strdup(buf); 92 } 93 if (entry.pattern[0]) 94 errors += test_glob(&entry); /* test last pattern */ 95 exit(errors); 96 } 97 98 int test_glob(struct gl_entry *entry) 99 { 100 glob_t gl; 101 int i; 102 103 if (glob(entry->pattern, entry->flags, NULL, &gl) != 0) 104 errx(1, "glob failed: %s", entry->pattern); 105 106 if (gl.gl_matchc != entry->nresults) 107 goto mismatch; 108 109 for (i = 0; i < gl.gl_matchc; i++) { 110 if (strcmp(gl.gl_pathv[i], entry->results[i]) != 0) 111 goto mismatch; 112 free(entry->results[i]); 113 } 114 return (0); 115 mismatch: 116 warnx("mismatch for pattern %s, flags 0x%x", entry->pattern, 117 entry->flags); 118 while (i < gl.gl_matchc) { 119 free(entry->results[i++]); 120 } 121 return (0); 122 return (1); 123 } 124