]> git.cworth.org Git - vogl/blob - src/voglcore/regex/debug.c
Initial vogl checkin
[vogl] / src / voglcore / regex / debug.c
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 #ifndef D_FILE_OFFSET_BITS
28 #define _FILE_OFFSET_BITS 64
29 #endif
30 #ifndef _LARGEFILE64_SOURCE
31 #define _LARGEFILE64_SOURCE 1
32 #endif
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <limits.h>
38 #include <stdlib.h>
39 #include <sys/types.h>
40
41 #include "regex.h"
42 #include "utils.h"
43 #include "regex2.h"
44 #include "debug.ih"
45
46 /*
47  - regprint - print a regexp for debugging
48  == void regprint(regex_t *r, FILE *d);
49  */
50 void
51 vogl_regprint(r, d)
52     regex_t *r;
53 FILE *d;
54 {
55     register struct re_guts *g = r->re_g;
56     register int i;
57     register int c;
58     register int last;
59     int nincat[NC];
60
61     fprintf(d, "%ld states, %d categories", (long)g->nstates,
62             g->ncategories);
63     fprintf(d, ", first %ld last %ld", (long)g->firststate,
64             (long)g->laststate);
65     if (g->iflags & USEBOL)
66         fprintf(d, ", USEBOL");
67     if (g->iflags & USEEOL)
68         fprintf(d, ", USEEOL");
69     if (g->iflags & BAD)
70         fprintf(d, ", BAD");
71     if (g->nsub > 0)
72         fprintf(d, ", nsub=%ld", (long)g->nsub);
73     if (g->must != NULL)
74         fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
75                 g->must);
76     if (g->backrefs)
77         fprintf(d, ", backrefs");
78     if (g->nplus > 0)
79         fprintf(d, ", nplus %ld", (long)g->nplus);
80     fprintf(d, "\n");
81     vogl_s_print(g, d);
82     for (i = 0; i < g->ncategories; i++)
83     {
84         nincat[i] = 0;
85         for (c = CHAR_MIN; c <= CHAR_MAX; c++)
86             if (g->categories[c] == i)
87                 nincat[i]++;
88     }
89     fprintf(d, "cc0#%d", nincat[0]);
90     for (i = 1; i < g->ncategories; i++)
91         if (nincat[i] == 1)
92         {
93             for (c = CHAR_MIN; c <= CHAR_MAX; c++)
94                 if (g->categories[c] == i)
95                     break;
96             fprintf(d, ", %d=%s", i, vogl_regchar(c));
97         }
98     fprintf(d, "\n");
99     for (i = 1; i < g->ncategories; i++)
100         if (nincat[i] != 1)
101         {
102             fprintf(d, "cc%d\t", i);
103             last = -1;
104             for (c = CHAR_MIN; c <= CHAR_MAX + 1; c++) /* +1 does flush */
105                 if (c <= CHAR_MAX && g->categories[c] == i)
106                 {
107                     if (last < 0)
108                     {
109                         fprintf(d, "%s", vogl_regchar(c));
110                         last = c;
111                     }
112                 }
113                 else
114                 {
115                     if (last >= 0)
116                     {
117                         if (last != c - 1)
118                             fprintf(d, "-%s",
119                                     vogl_regchar(c - 1));
120                         last = -1;
121                     }
122                 }
123             fprintf(d, "\n");
124         }
125 }
126
127 /*
128  - vogl_s_print - print the strip for debugging
129  == static void s_print(register struct re_guts *g, FILE *d);
130  */
131 static void
132 vogl_s_print(g, d) register struct re_guts *g;
133 FILE *d;
134 {
135     register sop *s;
136     register cset *cs;
137     register int i;
138     register int done = 0;
139     register sop opnd;
140     register int col = 0;
141     register int last;
142     register sopno offset = 2;
143 #define GAP()                       \
144     {                               \
145         if (offset % 5 == 0)        \
146         {                           \
147             if (col > 40)           \
148             {                       \
149                 fprintf(d, "\n\t"); \
150                 col = 0;            \
151             }                       \
152             else                    \
153             {                       \
154                 fprintf(d, " ");    \
155                 col++;              \
156             }                       \
157         }                           \
158         else                        \
159             col++;                  \
160         offset++;                   \
161     }
162
163     if (OP(g->strip[0]) != OEND)
164         fprintf(d, "missing initial OEND!\n");
165     for (s = &g->strip[1]; !done; s++)
166     {
167         opnd = OPND(*s);
168         switch (OP(*s))
169         {
170             case OEND:
171                 fprintf(d, "\n");
172                 done = 1;
173                 break;
174             case OCHAR:
175                 if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
176                     fprintf(d, "\\%c", (char)opnd);
177                 else
178                     fprintf(d, "%s", vogl_regchar((char)opnd));
179                 break;
180             case OBOL:
181                 fprintf(d, "^");
182                 break;
183             case OEOL:
184                 fprintf(d, "$");
185                 break;
186             case OBOW:
187                 fprintf(d, "\\{");
188                 break;
189             case OEOW:
190                 fprintf(d, "\\}");
191                 break;
192             case OANY:
193                 fprintf(d, ".");
194                 break;
195             case OANYOF:
196                 fprintf(d, "[(%ld)", (long)opnd);
197                 cs = &g->sets[opnd];
198                 last = -1;
199                 for (i = 0; i < g->csetsize + 1; i++) /* +1 flushes */
200                     if (CHIN(cs, i) && i < g->csetsize)
201                     {
202                         if (last < 0)
203                         {
204                             fprintf(d, "%s", vogl_regchar(i));
205                             last = i;
206                         }
207                     }
208                     else
209                     {
210                         if (last >= 0)
211                         {
212                             if (last != i - 1)
213                                 fprintf(d, "-%s",
214                                         vogl_regchar(i - 1));
215                             last = -1;
216                         }
217                     }
218                 fprintf(d, "]");
219                 break;
220             case OBACK_:
221                 fprintf(d, "(\\<%ld>", (long)opnd);
222                 break;
223             case O_BACK:
224                 fprintf(d, "<%ld>\\)", (long)opnd);
225                 break;
226             case OPLUS_:
227                 fprintf(d, "(+");
228                 if (OP(*(s + opnd)) != O_PLUS)
229                     fprintf(d, "<%ld>", (long)opnd);
230                 break;
231             case O_PLUS:
232                 if (OP(*(s - opnd)) != OPLUS_)
233                     fprintf(d, "<%ld>", (long)opnd);
234                 fprintf(d, "+)");
235                 break;
236             case OQUEST_:
237                 fprintf(d, "(?");
238                 if (OP(*(s + opnd)) != O_QUEST)
239                     fprintf(d, "<%ld>", (long)opnd);
240                 break;
241             case O_QUEST:
242                 if (OP(*(s - opnd)) != OQUEST_)
243                     fprintf(d, "<%ld>", (long)opnd);
244                 fprintf(d, "?)");
245                 break;
246             case OLPAREN:
247                 fprintf(d, "((<%ld>", (long)opnd);
248                 break;
249             case ORPAREN:
250                 fprintf(d, "<%ld>))", (long)opnd);
251                 break;
252             case OCH_:
253                 fprintf(d, "<");
254                 if (OP(*(s + opnd)) != OOR2)
255                     fprintf(d, "<%ld>", (long)opnd);
256                 break;
257             case OOR1:
258                 if (OP(*(s - opnd)) != OOR1 && OP(*(s - opnd)) != OCH_)
259                     fprintf(d, "<%ld>", (long)opnd);
260                 fprintf(d, "|");
261                 break;
262             case OOR2:
263                 fprintf(d, "|");
264                 if (OP(*(s + opnd)) != OOR2 && OP(*(s + opnd)) != O_CH)
265                     fprintf(d, "<%ld>", (long)opnd);
266                 break;
267             case O_CH:
268                 if (OP(*(s - opnd)) != OOR1)
269                     fprintf(d, "<%ld>", (long)opnd);
270                 fprintf(d, ">");
271                 break;
272             default:
273                 fprintf(d, "!%d(%d)!", (int)OP(*s), (int)opnd);
274                 break;
275         }
276         if (!done)
277             GAP();
278     }
279 }
280
281 /*
282  - vogl_regchar - make a character printable
283  == static char *vogl_regchar(int ch);
284  */
285 static char * /* -> representation */
286     vogl_regchar(ch) int ch;
287 {
288     static char buf[10];
289
290     if (isprint(ch) || ch == ' ')
291         sprintf(buf, "%c", ch);
292     else
293         sprintf(buf, "\\%o", ch);
294     return (buf);
295 }