638bf5ac913d76d719b7403ba7a1cc5db28b0619
[debian/amanda] / regex-src / debug.c
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>
7 #include <regex.h>
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                 snprintf(buf, sizeof(buf), "%c", ch);
239         else
240                 snprintf(buf, sizeof(buf), "\\%o", ch);
241         return(buf);
242 }