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