debug.c revision 92986
1#include <sys/cdefs.h>
2__FBSDID("$FreeBSD: head/lib/libc/regex/grot/debug.c 92986 2002-03-22 21:53:29Z obrien $");
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
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 */
20void
21regprint(r, d)
22regex_t *r;
23FILE *d;
24{
25	struct re_guts *g = r->re_g;
26	int i;
27	int c;
28	int last;
29	int nincat[NC];
30
31	fprintf(d, "%ld states, %d categories", (long)g->nstates,
32							g->ncategories);
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	for (i = 0; i < g->ncategories; i++) {
53		nincat[i] = 0;
54		for (c = CHAR_MIN; c <= CHAR_MAX; c++)
55			if (g->categories[c] == i)
56				nincat[i]++;
57	}
58	fprintf(d, "cc0#%d", nincat[0]);
59	for (i = 1; i < g->ncategories; i++)
60		if (nincat[i] == 1) {
61			for (c = CHAR_MIN; c <= CHAR_MAX; c++)
62				if (g->categories[c] == i)
63					break;
64			fprintf(d, ", %d=%s", i, regchar(c));
65		}
66	fprintf(d, "\n");
67	for (i = 1; i < g->ncategories; i++)
68		if (nincat[i] != 1) {
69			fprintf(d, "cc%d\t", i);
70			last = -1;
71			for (c = CHAR_MIN; c <= CHAR_MAX+1; c++)	/* +1 does flush */
72				if (c <= CHAR_MAX && g->categories[c] == i) {
73					if (last < 0) {
74						fprintf(d, "%s", regchar(c));
75						last = c;
76					}
77				} else {
78					if (last >= 0) {
79						if (last != c-1)
80							fprintf(d, "-%s",
81								regchar(c-1));
82						last = -1;
83					}
84				}
85			fprintf(d, "\n");
86		}
87}
88
89/*
90 - s_print - print the strip for debugging
91 == static void s_print(struct re_guts *g, FILE *d);
92 */
93static void
94s_print(g, d)
95struct re_guts *g;
96FILE *d;
97{
98	sop *s;
99	cset *cs;
100	int i;
101	int done = 0;
102	sop opnd;
103	int col = 0;
104	int last;
105	sopno offset = 2;
106#	define	GAP()	{	if (offset % 5 == 0) { \
107					if (col > 40) { \
108						fprintf(d, "\n\t"); \
109						col = 0; \
110					} else { \
111						fprintf(d, " "); \
112						col++; \
113					} \
114				} else \
115					col++; \
116				offset++; \
117			}
118
119	if (OP(g->strip[0]) != OEND)
120		fprintf(d, "missing initial OEND!\n");
121	for (s = &g->strip[1]; !done; s++) {
122		opnd = OPND(*s);
123		switch (OP(*s)) {
124		case OEND:
125			fprintf(d, "\n");
126			done = 1;
127			break;
128		case OCHAR:
129			if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
130				fprintf(d, "\\%c", (char)opnd);
131			else
132				fprintf(d, "%s", regchar((char)opnd));
133			break;
134		case OBOL:
135			fprintf(d, "^");
136			break;
137		case OEOL:
138			fprintf(d, "$");
139			break;
140		case OBOW:
141			fprintf(d, "\\{");
142			break;
143		case OEOW:
144			fprintf(d, "\\}");
145			break;
146		case OANY:
147			fprintf(d, ".");
148			break;
149		case OANYOF:
150			fprintf(d, "[(%ld)", (long)opnd);
151			cs = &g->sets[opnd];
152			last = -1;
153			for (i = 0; i < g->csetsize+1; i++)	/* +1 flushes */
154				if (CHIN(cs, i) && i < g->csetsize) {
155					if (last < 0) {
156						fprintf(d, "%s", regchar(i));
157						last = i;
158					}
159				} else {
160					if (last >= 0) {
161						if (last != i-1)
162							fprintf(d, "-%s",
163								regchar(i-1));
164						last = -1;
165					}
166				}
167			fprintf(d, "]");
168			break;
169		case OBACK_:
170			fprintf(d, "(\\<%ld>", (long)opnd);
171			break;
172		case O_BACK:
173			fprintf(d, "<%ld>\\)", (long)opnd);
174			break;
175		case OPLUS_:
176			fprintf(d, "(+");
177			if (OP(*(s+opnd)) != O_PLUS)
178				fprintf(d, "<%ld>", (long)opnd);
179			break;
180		case O_PLUS:
181			if (OP(*(s-opnd)) != OPLUS_)
182				fprintf(d, "<%ld>", (long)opnd);
183			fprintf(d, "+)");
184			break;
185		case OQUEST_:
186			fprintf(d, "(?");
187			if (OP(*(s+opnd)) != O_QUEST)
188				fprintf(d, "<%ld>", (long)opnd);
189			break;
190		case O_QUEST:
191			if (OP(*(s-opnd)) != OQUEST_)
192				fprintf(d, "<%ld>", (long)opnd);
193			fprintf(d, "?)");
194			break;
195		case OLPAREN:
196			fprintf(d, "((<%ld>", (long)opnd);
197			break;
198		case ORPAREN:
199			fprintf(d, "<%ld>))", (long)opnd);
200			break;
201		case OCH_:
202			fprintf(d, "<");
203			if (OP(*(s+opnd)) != OOR2)
204				fprintf(d, "<%ld>", (long)opnd);
205			break;
206		case OOR1:
207			if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
208				fprintf(d, "<%ld>", (long)opnd);
209			fprintf(d, "|");
210			break;
211		case OOR2:
212			fprintf(d, "|");
213			if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
214				fprintf(d, "<%ld>", (long)opnd);
215			break;
216		case O_CH:
217			if (OP(*(s-opnd)) != OOR1)
218				fprintf(d, "<%ld>", (long)opnd);
219			fprintf(d, ">");
220			break;
221		default:
222			fprintf(d, "!%d(%d)!", OP(*s), opnd);
223			break;
224		}
225		if (!done)
226			GAP();
227	}
228}
229
230/*
231 - regchar - make a character printable
232 == static char *regchar(int ch);
233 */
234static char *			/* -> representation */
235regchar(ch)
236int ch;
237{
238	static char buf[10];
239
240	if (isprint(ch) || ch == ' ')
241		sprintf(buf, "%c", ch);
242	else
243		sprintf(buf, "\\%o", ch);
244	return(buf);
245}
246