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