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