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