etc/protocols - sync with NetBSD-8
[minix.git] / tests / lib / libc / regex / debug.c
blobc1528b9e8c9540ba4b227e92cbdf5232a8a20a87
1 /* $NetBSD: debug.c,v 1.2 2011/10/10 04:32:41 christos Exp $ */
3 /*-
4 * Copyright (c) 1993 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 #include <ctype.h>
30 #include <limits.h>
31 #include <regex.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
36 #include <sys/types.h>
38 /* Don't sort these! */
39 #include "utils.h"
40 #include "regex2.h"
42 #include "test_regex.h"
44 static void s_print(struct re_guts *, FILE *);
45 static char *regchar(int);
48 * regprint - print a regexp for debugging
50 void
51 regprint(regex_t *r, FILE *d)
53 struct re_guts *g = r->re_g;
54 int c;
55 int last;
56 int nincat[NC];
58 fprintf(d, "%ld states, %zu categories", (long)g->nstates,
59 g->ncategories);
60 fprintf(d, ", first %ld last %ld", (long)g->firststate,
61 (long)g->laststate);
62 if (g->iflags&USEBOL)
63 fprintf(d, ", USEBOL");
64 if (g->iflags&USEEOL)
65 fprintf(d, ", USEEOL");
66 if (g->iflags&BAD)
67 fprintf(d, ", BAD");
68 if (g->nsub > 0)
69 fprintf(d, ", nsub=%ld", (long)g->nsub);
70 if (g->must != NULL)
71 fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
72 g->must);
73 if (g->backrefs)
74 fprintf(d, ", backrefs");
75 if (g->nplus > 0)
76 fprintf(d, ", nplus %ld", (long)g->nplus);
77 fprintf(d, "\n");
78 s_print(g, d);
79 for (size_t i = 0; i < g->ncategories; i++) {
80 nincat[i] = 0;
81 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
82 if (g->categories[c] == i)
83 nincat[i]++;
85 fprintf(d, "cc0#%d", nincat[0]);
86 for (size_t i = 1; i < g->ncategories; i++)
87 if (nincat[i] == 1) {
88 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
89 if (g->categories[c] == i)
90 break;
91 fprintf(d, ", %zu=%s", i, regchar(c));
93 fprintf(d, "\n");
94 for (size_t i = 1; i < g->ncategories; i++)
95 if (nincat[i] != 1) {
96 fprintf(d, "cc%zu\t", i);
97 last = -1;
98 for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */
99 if (c <= CHAR_MAX && g->categories[c] == i) {
100 if (last < 0) {
101 fprintf(d, "%s", regchar(c));
102 last = c;
104 } else {
105 if (last >= 0) {
106 if (last != c-1)
107 fprintf(d, "-%s",
108 regchar(c-1));
109 last = -1;
112 fprintf(d, "\n");
117 * s_print - print the strip for debugging
119 static void
120 s_print(struct re_guts *g, FILE *d)
122 sop *s;
123 cset *cs;
124 int done = 0;
125 sop opnd;
126 int col = 0;
127 ssize_t last;
128 sopno offset = 2;
129 # define GAP() { if (offset % 5 == 0) { \
130 if (col > 40) { \
131 fprintf(d, "\n\t"); \
132 col = 0; \
133 } else { \
134 fprintf(d, " "); \
135 col++; \
137 } else \
138 col++; \
139 offset++; \
142 if (OP(g->strip[0]) != OEND)
143 fprintf(d, "missing initial OEND!\n");
144 for (s = &g->strip[1]; !done; s++) {
145 opnd = OPND(*s);
146 switch (OP(*s)) {
147 case OEND:
148 fprintf(d, "\n");
149 done = 1;
150 break;
151 case OCHAR:
152 if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
153 fprintf(d, "\\%c", (char)opnd);
154 else
155 fprintf(d, "%s", regchar((char)opnd));
156 break;
157 case OBOL:
158 fprintf(d, "^");
159 break;
160 case OEOL:
161 fprintf(d, "$");
162 break;
163 case OBOW:
164 fprintf(d, "\\{");
165 break;
166 case OEOW:
167 fprintf(d, "\\}");
168 break;
169 case OANY:
170 fprintf(d, ".");
171 break;
172 case OANYOF:
173 fprintf(d, "[(%ld)", (long)opnd);
174 cs = &g->sets[opnd];
175 last = -1;
176 for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */
177 if (CHIN(cs, i) && i < g->csetsize) {
178 if (last < 0) {
179 fprintf(d, "%s", regchar(i));
180 last = i;
182 } else {
183 if (last >= 0) {
184 if (last != (ssize_t)i - 1)
185 fprintf(d, "-%s",
186 regchar(i - 1));
187 last = -1;
190 fprintf(d, "]");
191 break;
192 case OBACK_:
193 fprintf(d, "(\\<%ld>", (long)opnd);
194 break;
195 case O_BACK:
196 fprintf(d, "<%ld>\\)", (long)opnd);
197 break;
198 case OPLUS_:
199 fprintf(d, "(+");
200 if (OP(*(s+opnd)) != O_PLUS)
201 fprintf(d, "<%ld>", (long)opnd);
202 break;
203 case O_PLUS:
204 if (OP(*(s-opnd)) != OPLUS_)
205 fprintf(d, "<%ld>", (long)opnd);
206 fprintf(d, "+)");
207 break;
208 case OQUEST_:
209 fprintf(d, "(?");
210 if (OP(*(s+opnd)) != O_QUEST)
211 fprintf(d, "<%ld>", (long)opnd);
212 break;
213 case O_QUEST:
214 if (OP(*(s-opnd)) != OQUEST_)
215 fprintf(d, "<%ld>", (long)opnd);
216 fprintf(d, "?)");
217 break;
218 case OLPAREN:
219 fprintf(d, "((<%ld>", (long)opnd);
220 break;
221 case ORPAREN:
222 fprintf(d, "<%ld>))", (long)opnd);
223 break;
224 case OCH_:
225 fprintf(d, "<");
226 if (OP(*(s+opnd)) != OOR2)
227 fprintf(d, "<%ld>", (long)opnd);
228 break;
229 case OOR1:
230 if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
231 fprintf(d, "<%ld>", (long)opnd);
232 fprintf(d, "|");
233 break;
234 case OOR2:
235 fprintf(d, "|");
236 if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
237 fprintf(d, "<%ld>", (long)opnd);
238 break;
239 case O_CH:
240 if (OP(*(s-opnd)) != OOR1)
241 fprintf(d, "<%ld>", (long)opnd);
242 fprintf(d, ">");
243 break;
244 default:
245 fprintf(d, "!%d(%d)!", OP(*s), opnd);
246 break;
248 if (!done)
249 GAP();
254 * regchar - make a character printable
256 static char * /* -> representation */
257 regchar(int ch)
259 static char buf[10];
261 if (isprint(ch) || ch == ' ')
262 sprintf(buf, "%c", ch);
263 else
264 sprintf(buf, "\\%o", ch);
265 return(buf);