]>
Commit | Line | Data |
---|---|---|
5a419892 VZ |
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> | |
770dba7a | 7 | #include "regex.h" |
5a419892 VZ |
8 | |
9 | #include "utils.h" | |
10 | #include "regex2.h" | |
11 | #include "debug.ih" | |
12 | ||
13 | /* | |
14 | - regprint - print a regexp for debugging | |
15 | == void regprint(regex_t *r, FILE *d); | |
16 | */ | |
17 | void | |
18 | regprint(r, d) | |
19 | regex_t *r; | |
20 | FILE *d; | |
21 | { | |
22 | register struct re_guts *g = r->re_g; | |
23 | register int i; | |
24 | register int c; | |
25 | register int last; | |
26 | int nincat[NC]; | |
27 | ||
28 | fprintf(d, "%ld states, %d categories", (long)g->nstates, | |
29 | g->ncategories); | |
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 | for (i = 0; i < g->ncategories; i++) { | |
50 | nincat[i] = 0; | |
51 | for (c = CHAR_MIN; c <= CHAR_MAX; c++) | |
52 | if (g->categories[c] == i) | |
53 | nincat[i]++; | |
54 | } | |
55 | fprintf(d, "cc0#%d", nincat[0]); | |
56 | for (i = 1; i < g->ncategories; i++) | |
57 | if (nincat[i] == 1) { | |
58 | for (c = CHAR_MIN; c <= CHAR_MAX; c++) | |
59 | if (g->categories[c] == i) | |
60 | break; | |
61 | fprintf(d, ", %d=%s", i, regchar(c)); | |
62 | } | |
63 | fprintf(d, "\n"); | |
64 | for (i = 1; i < g->ncategories; i++) | |
65 | if (nincat[i] != 1) { | |
66 | fprintf(d, "cc%d\t", i); | |
67 | last = -1; | |
68 | for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */ | |
69 | if (c <= CHAR_MAX && g->categories[c] == i) { | |
70 | if (last < 0) { | |
71 | fprintf(d, "%s", regchar(c)); | |
72 | last = c; | |
73 | } | |
74 | } else { | |
75 | if (last >= 0) { | |
76 | if (last != c-1) | |
77 | fprintf(d, "-%s", | |
78 | regchar(c-1)); | |
79 | last = -1; | |
80 | } | |
81 | } | |
82 | fprintf(d, "\n"); | |
83 | } | |
84 | } | |
85 | ||
86 | /* | |
87 | - s_print - print the strip for debugging | |
88 | == static void s_print(register struct re_guts *g, FILE *d); | |
89 | */ | |
90 | static void | |
91 | s_print(g, d) | |
92 | register struct re_guts *g; | |
93 | FILE *d; | |
94 | { | |
95 | register sop *s; | |
96 | register cset *cs; | |
97 | register int i; | |
98 | register int done = 0; | |
99 | register sop opnd; | |
100 | register int col = 0; | |
101 | register int last; | |
102 | register sopno offset = 2; | |
103 | # define GAP() { if (offset % 5 == 0) { \ | |
104 | if (col > 40) { \ | |
105 | fprintf(d, "\n\t"); \ | |
106 | col = 0; \ | |
107 | } else { \ | |
108 | fprintf(d, " "); \ | |
109 | col++; \ | |
110 | } \ | |
111 | } else \ | |
112 | col++; \ | |
113 | offset++; \ | |
114 | } | |
115 | ||
116 | if (OP(g->strip[0]) != OEND) | |
117 | fprintf(d, "missing initial OEND!\n"); | |
118 | for (s = &g->strip[1]; !done; s++) { | |
119 | opnd = OPND(*s); | |
120 | switch (OP(*s)) { | |
121 | case OEND: | |
122 | fprintf(d, "\n"); | |
123 | done = 1; | |
124 | break; | |
125 | case OCHAR: | |
126 | if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) | |
127 | fprintf(d, "\\%c", (char)opnd); | |
128 | else | |
129 | fprintf(d, "%s", regchar((char)opnd)); | |
130 | break; | |
131 | case OBOL: | |
132 | fprintf(d, "^"); | |
133 | break; | |
134 | case OEOL: | |
135 | fprintf(d, "$"); | |
136 | break; | |
137 | case OBOW: | |
138 | fprintf(d, "\\{"); | |
139 | break; | |
140 | case OEOW: | |
141 | fprintf(d, "\\}"); | |
142 | break; | |
143 | case OANY: | |
144 | fprintf(d, "."); | |
145 | break; | |
146 | case OANYOF: | |
147 | fprintf(d, "[(%ld)", (long)opnd); | |
148 | cs = &g->sets[opnd]; | |
149 | last = -1; | |
150 | for (i = 0; i < g->csetsize+1; i++) /* +1 flushes */ | |
151 | if (CHIN(cs, i) && i < g->csetsize) { | |
152 | if (last < 0) { | |
153 | fprintf(d, "%s", regchar(i)); | |
154 | last = i; | |
155 | } | |
156 | } else { | |
157 | if (last >= 0) { | |
158 | if (last != i-1) | |
159 | fprintf(d, "-%s", | |
160 | regchar(i-1)); | |
161 | last = -1; | |
162 | } | |
163 | } | |
164 | fprintf(d, "]"); | |
165 | break; | |
166 | case OBACK_: | |
167 | fprintf(d, "(\\<%ld>", (long)opnd); | |
168 | break; | |
169 | case O_BACK: | |
170 | fprintf(d, "<%ld>\\)", (long)opnd); | |
171 | break; | |
172 | case OPLUS_: | |
173 | fprintf(d, "(+"); | |
174 | if (OP(*(s+opnd)) != O_PLUS) | |
175 | fprintf(d, "<%ld>", (long)opnd); | |
176 | break; | |
177 | case O_PLUS: | |
178 | if (OP(*(s-opnd)) != OPLUS_) | |
179 | fprintf(d, "<%ld>", (long)opnd); | |
180 | fprintf(d, "+)"); | |
181 | break; | |
182 | case OQUEST_: | |
183 | fprintf(d, "(?"); | |
184 | if (OP(*(s+opnd)) != O_QUEST) | |
185 | fprintf(d, "<%ld>", (long)opnd); | |
186 | break; | |
187 | case O_QUEST: | |
188 | if (OP(*(s-opnd)) != OQUEST_) | |
189 | fprintf(d, "<%ld>", (long)opnd); | |
190 | fprintf(d, "?)"); | |
191 | break; | |
192 | case OLPAREN: | |
193 | fprintf(d, "((<%ld>", (long)opnd); | |
194 | break; | |
195 | case ORPAREN: | |
196 | fprintf(d, "<%ld>))", (long)opnd); | |
197 | break; | |
198 | case OCH_: | |
199 | fprintf(d, "<"); | |
200 | if (OP(*(s+opnd)) != OOR2) | |
201 | fprintf(d, "<%ld>", (long)opnd); | |
202 | break; | |
203 | case OOR1: | |
204 | if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) | |
205 | fprintf(d, "<%ld>", (long)opnd); | |
206 | fprintf(d, "|"); | |
207 | break; | |
208 | case OOR2: | |
209 | fprintf(d, "|"); | |
210 | if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) | |
211 | fprintf(d, "<%ld>", (long)opnd); | |
212 | break; | |
213 | case O_CH: | |
214 | if (OP(*(s-opnd)) != OOR1) | |
215 | fprintf(d, "<%ld>", (long)opnd); | |
216 | fprintf(d, ">"); | |
217 | break; | |
218 | default: | |
219 | fprintf(d, "!%d(%d)!", OP(*s), opnd); | |
220 | break; | |
221 | } | |
222 | if (!done) | |
223 | GAP(); | |
224 | } | |
225 | } | |
226 | ||
227 | /* | |
228 | - regchar - make a character printable | |
229 | == static char *regchar(int ch); | |
230 | */ | |
231 | static char * /* -> representation */ | |
232 | regchar(ch) | |
233 | int ch; | |
234 | { | |
235 | static char buf[10]; | |
236 | ||
237 | if (isprint(ch) || ch == ' ') | |
238 | sprintf(buf, "%c", ch); | |
239 | else | |
240 | sprintf(buf, "\\%o", ch); | |
241 | return(buf); | |
242 | } |