xref: /freebsd/lib/libc/regex/grot/debug.c (revision 624e87b673064ae228b79cde11b82f1ad7502bc3)
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, "!%ld(%ld)!", OP(*s), (long)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