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