xref: /openbsd-src/regress/lib/libc/regex/debug.c (revision a2944cb5a4ff13fc12aa4ee37f0a8f9375025a65)
1*a2944cb5Smillert /*	$OpenBSD: debug.c,v 1.5 2020/12/31 17:20:19 millert Exp $	*/
2df930be7Sderaadt /*	$NetBSD: debug.c,v 1.2 1995/04/20 22:39:42 cgd Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt #include <stdio.h>
5df930be7Sderaadt #include <string.h>
6df930be7Sderaadt #include <ctype.h>
7df930be7Sderaadt #include <limits.h>
8df930be7Sderaadt #include <stdlib.h>
9df930be7Sderaadt #include <sys/types.h>
10df930be7Sderaadt #include <regex.h>
11df930be7Sderaadt 
12df930be7Sderaadt #include "utils.h"
13df930be7Sderaadt #include "regex2.h"
14df930be7Sderaadt #include "debug.ih"
15df930be7Sderaadt 
16df930be7Sderaadt /*
17df930be7Sderaadt  - regprint - print a regexp for debugging
18df930be7Sderaadt  == void regprint(regex_t *r, FILE *d);
19df930be7Sderaadt  */
20df930be7Sderaadt void
regprint(r,d)21df930be7Sderaadt regprint(r, d)
22df930be7Sderaadt regex_t *r;
23df930be7Sderaadt FILE *d;
24df930be7Sderaadt {
25df930be7Sderaadt 	register struct re_guts *g = r->re_g;
26df930be7Sderaadt 	register int i;
27df930be7Sderaadt 	register int c;
28df930be7Sderaadt 	register int last;
29df930be7Sderaadt 
30*a2944cb5Smillert 	fprintf(d, "%ld states", (long)g->nstates);
31df930be7Sderaadt 	fprintf(d, ", first %ld last %ld", (long)g->firststate,
32df930be7Sderaadt 						(long)g->laststate);
33df930be7Sderaadt 	if (g->iflags&USEBOL)
34df930be7Sderaadt 		fprintf(d, ", USEBOL");
35df930be7Sderaadt 	if (g->iflags&USEEOL)
36df930be7Sderaadt 		fprintf(d, ", USEEOL");
37df930be7Sderaadt 	if (g->iflags&BAD)
38df930be7Sderaadt 		fprintf(d, ", BAD");
39df930be7Sderaadt 	if (g->nsub > 0)
40df930be7Sderaadt 		fprintf(d, ", nsub=%ld", (long)g->nsub);
41df930be7Sderaadt 	if (g->must != NULL)
42df930be7Sderaadt 		fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
43df930be7Sderaadt 								g->must);
44df930be7Sderaadt 	if (g->backrefs)
45df930be7Sderaadt 		fprintf(d, ", backrefs");
46df930be7Sderaadt 	if (g->nplus > 0)
47df930be7Sderaadt 		fprintf(d, ", nplus %ld", (long)g->nplus);
48df930be7Sderaadt 	fprintf(d, "\n");
49df930be7Sderaadt 	s_print(g, d);
50df930be7Sderaadt }
51df930be7Sderaadt 
52df930be7Sderaadt /*
53df930be7Sderaadt  - s_print - print the strip for debugging
54df930be7Sderaadt  == static void s_print(register struct re_guts *g, FILE *d);
55df930be7Sderaadt  */
56df930be7Sderaadt static void
s_print(g,d)57df930be7Sderaadt s_print(g, d)
58df930be7Sderaadt register struct re_guts *g;
59df930be7Sderaadt FILE *d;
60df930be7Sderaadt {
61df930be7Sderaadt 	register sop *s;
62df930be7Sderaadt 	register cset *cs;
63df930be7Sderaadt 	register int i;
64df930be7Sderaadt 	register int done = 0;
65df930be7Sderaadt 	register sop opnd;
66df930be7Sderaadt 	register int col = 0;
67df930be7Sderaadt 	register int last;
68df930be7Sderaadt 	register sopno offset = 2;
69df930be7Sderaadt #	define	GAP()	{	if (offset % 5 == 0) { \
70df930be7Sderaadt 					if (col > 40) { \
71df930be7Sderaadt 						fprintf(d, "\n\t"); \
72df930be7Sderaadt 						col = 0; \
73df930be7Sderaadt 					} else { \
74df930be7Sderaadt 						fprintf(d, " "); \
75df930be7Sderaadt 						col++; \
76df930be7Sderaadt 					} \
77df930be7Sderaadt 				} else \
78df930be7Sderaadt 					col++; \
79df930be7Sderaadt 				offset++; \
80df930be7Sderaadt 			}
81df930be7Sderaadt 
82df930be7Sderaadt 	if (OP(g->strip[0]) != OEND)
83df930be7Sderaadt 		fprintf(d, "missing initial OEND!\n");
84df930be7Sderaadt 	for (s = &g->strip[1]; !done; s++) {
85df930be7Sderaadt 		opnd = OPND(*s);
86df930be7Sderaadt 		switch (OP(*s)) {
87df930be7Sderaadt 		case OEND:
88df930be7Sderaadt 			fprintf(d, "\n");
89df930be7Sderaadt 			done = 1;
90df930be7Sderaadt 			break;
91df930be7Sderaadt 		case OCHAR:
92df930be7Sderaadt 			if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
93df930be7Sderaadt 				fprintf(d, "\\%c", (char)opnd);
94df930be7Sderaadt 			else
95df930be7Sderaadt 				fprintf(d, "%s", regchar((char)opnd));
96df930be7Sderaadt 			break;
97df930be7Sderaadt 		case OBOL:
98df930be7Sderaadt 			fprintf(d, "^");
99df930be7Sderaadt 			break;
100df930be7Sderaadt 		case OEOL:
101df930be7Sderaadt 			fprintf(d, "$");
102df930be7Sderaadt 			break;
103df930be7Sderaadt 		case OBOW:
104df930be7Sderaadt 			fprintf(d, "\\{");
105df930be7Sderaadt 			break;
106df930be7Sderaadt 		case OEOW:
107df930be7Sderaadt 			fprintf(d, "\\}");
108df930be7Sderaadt 			break;
109df930be7Sderaadt 		case OANY:
110df930be7Sderaadt 			fprintf(d, ".");
111df930be7Sderaadt 			break;
112df930be7Sderaadt 		case OANYOF:
113df930be7Sderaadt 			fprintf(d, "[(%ld)", (long)opnd);
114df930be7Sderaadt 			cs = &g->sets[opnd];
115df930be7Sderaadt 			last = -1;
116df930be7Sderaadt 			for (i = 0; i < g->csetsize+1; i++)	/* +1 flushes */
117df930be7Sderaadt 				if (CHIN(cs, i) && i < g->csetsize) {
118df930be7Sderaadt 					if (last < 0) {
119df930be7Sderaadt 						fprintf(d, "%s", regchar(i));
120df930be7Sderaadt 						last = i;
121df930be7Sderaadt 					}
122df930be7Sderaadt 				} else {
123df930be7Sderaadt 					if (last >= 0) {
124df930be7Sderaadt 						if (last != i-1)
125df930be7Sderaadt 							fprintf(d, "-%s",
126df930be7Sderaadt 								regchar(i-1));
127df930be7Sderaadt 						last = -1;
128df930be7Sderaadt 					}
129df930be7Sderaadt 				}
130df930be7Sderaadt 			fprintf(d, "]");
131df930be7Sderaadt 			break;
132df930be7Sderaadt 		case OBACK_:
133df930be7Sderaadt 			fprintf(d, "(\\<%ld>", (long)opnd);
134df930be7Sderaadt 			break;
135df930be7Sderaadt 		case O_BACK:
136df930be7Sderaadt 			fprintf(d, "<%ld>\\)", (long)opnd);
137df930be7Sderaadt 			break;
138df930be7Sderaadt 		case OPLUS_:
139df930be7Sderaadt 			fprintf(d, "(+");
140df930be7Sderaadt 			if (OP(*(s+opnd)) != O_PLUS)
141df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
142df930be7Sderaadt 			break;
143df930be7Sderaadt 		case O_PLUS:
144df930be7Sderaadt 			if (OP(*(s-opnd)) != OPLUS_)
145df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
146df930be7Sderaadt 			fprintf(d, "+)");
147df930be7Sderaadt 			break;
148df930be7Sderaadt 		case OQUEST_:
149df930be7Sderaadt 			fprintf(d, "(?");
150df930be7Sderaadt 			if (OP(*(s+opnd)) != O_QUEST)
151df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
152df930be7Sderaadt 			break;
153df930be7Sderaadt 		case O_QUEST:
154df930be7Sderaadt 			if (OP(*(s-opnd)) != OQUEST_)
155df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
156df930be7Sderaadt 			fprintf(d, "?)");
157df930be7Sderaadt 			break;
158df930be7Sderaadt 		case OLPAREN:
159df930be7Sderaadt 			fprintf(d, "((<%ld>", (long)opnd);
160df930be7Sderaadt 			break;
161df930be7Sderaadt 		case ORPAREN:
162df930be7Sderaadt 			fprintf(d, "<%ld>))", (long)opnd);
163df930be7Sderaadt 			break;
164df930be7Sderaadt 		case OCH_:
165df930be7Sderaadt 			fprintf(d, "<");
166df930be7Sderaadt 			if (OP(*(s+opnd)) != OOR2)
167df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
168df930be7Sderaadt 			break;
169df930be7Sderaadt 		case OOR1:
170df930be7Sderaadt 			if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
171df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
172df930be7Sderaadt 			fprintf(d, "|");
173df930be7Sderaadt 			break;
174df930be7Sderaadt 		case OOR2:
175df930be7Sderaadt 			fprintf(d, "|");
176df930be7Sderaadt 			if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
177df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
178df930be7Sderaadt 			break;
179df930be7Sderaadt 		case O_CH:
180df930be7Sderaadt 			if (OP(*(s-opnd)) != OOR1)
181df930be7Sderaadt 				fprintf(d, "<%ld>", (long)opnd);
182df930be7Sderaadt 			fprintf(d, ">");
183df930be7Sderaadt 			break;
184df930be7Sderaadt 		default:
18507ea8d15Smillert 			fprintf(d, "!%ld(%ld)!", (long)OP(*s), (long)opnd);
186df930be7Sderaadt 			break;
187df930be7Sderaadt 		}
188df930be7Sderaadt 		if (!done)
189df930be7Sderaadt 			GAP();
190df930be7Sderaadt 	}
191df930be7Sderaadt }
192df930be7Sderaadt 
193df930be7Sderaadt /*
194df930be7Sderaadt  - regchar - make a character printable
195df930be7Sderaadt  == static char *regchar(int ch);
196df930be7Sderaadt  */
197df930be7Sderaadt static char *			/* -> representation */
regchar(ch)198df930be7Sderaadt regchar(ch)
199df930be7Sderaadt int ch;
200df930be7Sderaadt {
201df930be7Sderaadt 	static char buf[10];
202df930be7Sderaadt 
203df930be7Sderaadt 	if (isprint(ch) || ch == ' ')
204db3296cfSderaadt 		snprintf(buf, sizeof buf, "%c", ch);
205df930be7Sderaadt 	else
206db3296cfSderaadt 		snprintf(buf, sizeof buf, "\\%o", ch);
207df930be7Sderaadt 	return(buf);
208df930be7Sderaadt }
209