xref: /openbsd-src/regress/lib/libc/glob/globtest.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
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