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