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