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