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 */
22void
23regprint(r, d)
24regex_t *r;
25FILE *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 */
58static void
59s_print(g, d)
60struct re_guts *g;
61FILE *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 */
201static char *			/* -> representation */
202regchar(ch)
203int 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