1 /*
2  * Simple test program for regexp(3) stuff.  Knows about debugging hooks.
3  *
4  *	Copyright (c) 1986 by University of Toronto.
5  *	Written by Henry Spencer.  Not derived from licensed software.
6  *
7  *	Permission is granted to anyone to use this software for any
8  *	purpose on any computer system, and to redistribute it freely,
9  *	subject to the following restrictions:
10  *
11  *	1. The author is not responsible for the consequences of use of
12  *		this software, no matter how awful, even if they arise
13  *		from defects in it.
14  *
15  *	2. The origin of this software must not be misrepresented, either
16  *		by explicit claim or by omission.
17  *
18  *	3. Altered versions must be plainly marked as such, and must not
19  *		be misrepresented as being the original software.
20  *
21  * Usage: try re [string [output [-]]]
22  * The re is compiled and dumped, regexeced against the string, the result
23  * is applied to output using regsub().  The - triggers a running narrative
24  * from regexec().  Dumping and narrative don't happen unless DEBUG.
25  *
26  * If there are no arguments, stdin is assumed to be a stream of lines with
27  * five fields:  a r.e., a string to match it against, a result code, a
28  * source string for regsub, and the proper result.  Result codes are 'c'
29  * for compile failure, 'y' for match success, 'n' for match failure.
30  * Field separator is tab.
31  */
32 #include <stdio.h>
33 #include <regexp.h>
34 
35 #ifdef ERRAVAIL
36 char *progname;
37 extern char *mkprogname();
38 #endif
39 
40 #ifdef DEBUG
41 extern int regnarrate;
42 #endif
43 
44 char buf[BUFSIZ];
45 
46 int errreport = 0;		/* Report errors via errseen? */
47 char *errseen = NULL;		/* Error message. */
48 int status = 0;			/* Exit status. */
49 
50 /* ARGSUSED */
main(argc,argv)51 main(argc, argv)
52 int argc;
53 char *argv[];
54 {
55 	regexp *r;
56 	int i;
57 
58 #ifdef ERRAVAIL
59 	progname = mkprogname(argv[0]);
60 #endif
61 
62 	if (argc == 1) {
63 		multiple();
64 		exit(status);
65 	}
66 
67 	r = regcomp(argv[1]);
68 	if (r == NULL)
69 		error("regcomp failure", "");
70 #ifdef DEBUG
71 	regdump(r);
72 	if (argc > 4)
73 		regnarrate++;
74 #endif
75 	if (argc > 2) {
76 		i = regexec(r, argv[2]);
77 		printf("%d", i);
78 		for (i = 1; i < NSUBEXP; i++)
79 			if (r->startp[i] != NULL && r->endp[i] != NULL)
80 				printf(" \\%d", i);
81 		printf("\n");
82 	}
83 	if (argc > 3) {
84 		regsub(r, argv[3], buf);
85 		printf("%s\n", buf);
86 	}
87 	exit(status);
88 }
89 
90 void
regerror(s)91 regerror(s)
92 char *s;
93 {
94 	if (errreport)
95 		errseen = s;
96 	else
97 		error(s, "");
98 }
99 
100 #ifndef ERRAVAIL
error(s1,s2)101 error(s1, s2)
102 char *s1;
103 char *s2;
104 {
105 	fprintf(stderr, "regexp: ");
106 	fprintf(stderr, s1, s2);
107 	fprintf(stderr, "\n");
108 	exit(1);
109 }
110 #endif
111 
112 int lineno;
113 
114 regexp badregexp;		/* Implicit init to 0. */
115 
multiple()116 multiple()
117 {
118 	char rbuf[BUFSIZ];
119 	char *field[5];
120 	char *scan;
121 	int i;
122 	regexp *r;
123 	extern char *strchr();
124 
125 	errreport = 1;
126 	lineno = 0;
127 	while (fgets(rbuf, sizeof(rbuf), stdin) != NULL) {
128 		rbuf[strlen(rbuf)-1] = '\0';	/* Dispense with \n. */
129 		lineno++;
130 		scan = rbuf;
131 		for (i = 0; i < 5; i++) {
132 			field[i] = scan;
133 			if (field[i] == NULL) {
134 				complain("bad testfile format", "");
135 				exit(1);
136 			}
137 			scan = strchr(scan, '\t');
138 			if (scan != NULL)
139 				*scan++ = '\0';
140 		}
141 		try(field);
142 	}
143 
144 	/* And finish up with some internal testing... */
145 	lineno = 9990;
146 	errseen = NULL;
147 	if (regcomp((char *)NULL) != NULL || errseen == NULL)
148 		complain("regcomp(NULL) doesn't complain", "");
149 	lineno = 9991;
150 	errseen = NULL;
151 	if (regexec((regexp *)NULL, "foo") || errseen == NULL)
152 		complain("regexec(NULL, ...) doesn't complain", "");
153 	lineno = 9992;
154 	r = regcomp("foo");
155 	if (r == NULL) {
156 		complain("regcomp(\"foo\") fails", "");
157 		return;
158 	}
159 	lineno = 9993;
160 	errseen = NULL;
161 	if (regexec(r, (char *)NULL) || errseen == NULL)
162 		complain("regexec(..., NULL) doesn't complain", "");
163 	lineno = 9994;
164 	errseen = NULL;
165 	regsub((regexp *)NULL, "foo", rbuf);
166 	if (errseen == NULL)
167 		complain("regsub(NULL, ..., ...) doesn't complain", "");
168 	lineno = 9995;
169 	errseen = NULL;
170 	regsub(r, (char *)NULL, rbuf);
171 	if (errseen == NULL)
172 		complain("regsub(..., NULL, ...) doesn't complain", "");
173 	lineno = 9996;
174 	errseen = NULL;
175 	regsub(r, "foo", (char *)NULL);
176 	if (errseen == NULL)
177 		complain("regsub(..., ..., NULL) doesn't complain", "");
178 	lineno = 9997;
179 	errseen = NULL;
180 	if (regexec(&badregexp, "foo") || errseen == NULL)
181 		complain("regexec(nonsense, ...) doesn't complain", "");
182 	lineno = 9998;
183 	errseen = NULL;
184 	regsub(&badregexp, "foo", rbuf);
185 	if (errseen == NULL)
186 		complain("regsub(nonsense, ..., ...) doesn't complain", "");
187 }
188 
try(fields)189 try(fields)
190 char **fields;
191 {
192 	regexp *r;
193 	char dbuf[BUFSIZ];
194 
195 	errseen = NULL;
196 	r = regcomp(fields[0]);
197 	if (r == NULL) {
198 		if (*fields[2] != 'c')
199 			complain("regcomp failure in `%s'", fields[0]);
200 		return;
201 	}
202 	if (*fields[2] == 'c') {
203 		complain("unexpected regcomp success in `%s'", fields[0]);
204 		free((char *)r);
205 		return;
206 	}
207 	if (!regexec(r, fields[1])) {
208 		if (*fields[2] != 'n')
209 			complain("regexec failure in `%s'", "");
210 		free((char *)r);
211 		return;
212 	}
213 	if (*fields[2] == 'n') {
214 		complain("unexpected regexec success", "");
215 		free((char *)r);
216 		return;
217 	}
218 	errseen = NULL;
219 	regsub(r, fields[3], dbuf);
220 	if (errseen != NULL) {
221 		complain("regsub complaint", "");
222 		free((char *)r);
223 		return;
224 	}
225 	if (strcmp(dbuf, fields[4]) != 0)
226 		complain("regsub result `%s' wrong", dbuf);
227 	free((char *)r);
228 }
229 
complain(s1,s2)230 complain(s1, s2)
231 char *s1;
232 char *s2;
233 {
234 	fprintf(stderr, "try: %d: ", lineno);
235 	fprintf(stderr, s1, s2);
236 	fprintf(stderr, " (%s)\n", (errseen != NULL) ? errseen : "");
237 	status = 1;
238 }
239