Imported Upstream version 2.5.1
[debian/amanda] / regex-src / debug.c
1 #include "amanda.h"
2 #include <regex.h>
3
4 #include "utils.h"
5 #include "regex2.h"
6 #include "debug.ih"
7
8 /*
9  - regprint - print a regexp for debugging
10  == void regprint(regex_t *r, FILE *d);
11  */
12 void
13 regprint(r, d)
14 regex_t *r;
15 FILE *d;
16 {
17         register struct re_guts *g = r->re_g;
18         register int i;
19         register int c;
20         register int last;
21         int nincat[NC];
22
23         fprintf(d, "%ld states, %d categories", (long)g->nstates,
24                                                         g->ncategories);
25         fprintf(d, ", first %ld last %ld", (long)g->firststate,
26                                                 (long)g->laststate);
27         if (g->iflags&USEBOL)
28                 fprintf(d, ", USEBOL");
29         if (g->iflags&USEEOL)
30                 fprintf(d, ", USEEOL");
31         if (g->iflags&BAD)
32                 fprintf(d, ", BAD");
33         if (g->nsub > 0)
34                 fprintf(d, ", nsub=%ld", (long)g->nsub);
35         if (g->must != NULL)
36                 fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
37                                                                 g->must);
38         if (g->backrefs)
39                 fprintf(d, ", backrefs");
40         if (g->nplus > 0)
41                 fprintf(d, ", nplus %ld", (long)g->nplus);
42         fprintf(d, "\n");
43         s_print(g, d);
44         for (i = 0; i < g->ncategories; i++) {
45                 nincat[i] = 0;
46                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
47                         if (g->categories[c] == i)
48                                 nincat[i]++;
49         }
50         fprintf(d, "cc0#%d", nincat[0]);
51         for (i = 1; i < g->ncategories; i++)
52                 if (nincat[i] == 1) {
53                         for (c = CHAR_MIN; c <= CHAR_MAX; c++)
54                                 if (g->categories[c] == i)
55                                         break;
56                         fprintf(d, ", %d=%s", i, regchar(c));
57                 }
58         fprintf(d, "\n");
59         for (i = 1; i < g->ncategories; i++)
60                 if (nincat[i] != 1) {
61                         fprintf(d, "cc%d\t", i);
62                         last = -1;
63                         for (c = CHAR_MIN; c <= CHAR_MAX+1; c++)        /* +1 does flush */
64                                 if (c <= CHAR_MAX && g->categories[c] == i) {
65                                         if (last < 0) {
66                                                 fprintf(d, "%s", regchar(c));
67                                                 last = c;
68                                         }
69                                 } else {
70                                         if (last >= 0) {
71                                                 if (last != c-1)
72                                                         fprintf(d, "-%s",
73                                                                 regchar(c-1));
74                                                 last = -1;
75                                         }
76                                 }
77                         fprintf(d, "\n");
78                 }
79 }
80
81 /*
82  - s_print - print the strip for debugging
83  == static void s_print(register struct re_guts *g, FILE *d);
84  */
85 static void
86 s_print(g, d)
87 register struct re_guts *g;
88 FILE *d;
89 {
90         register sop *s;
91         register cset *cs;
92         register int i;
93         register int done = 0;
94         register sop opnd;
95         register int col = 0;
96         register int last;
97         register 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, "[(%ld)", (long)opnd);
143                         cs = &g->sets[opnd];
144                         last = -1;
145                         for (i = 0; i < g->csetsize+1; i++)     /* +1 flushes */
146                                 if (CHIN(cs, i) && i < g->csetsize) {
147                                         if (last < 0) {
148                                                 fprintf(d, "%s", regchar(i));
149                                                 last = i;
150                                         }
151                                 } else {
152                                         if (last >= 0) {
153                                                 if (last != i-1)
154                                                         fprintf(d, "-%s",
155                                                                 regchar(i-1));
156                                                 last = -1;
157                                         }
158                                 }
159                         fprintf(d, "]");
160                         break;
161                 case OBACK_:
162                         fprintf(d, "(\\<%ld>", (long)opnd);
163                         break;
164                 case O_BACK:
165                         fprintf(d, "<%ld>\\)", (long)opnd);
166                         break;
167                 case OPLUS_:
168                         fprintf(d, "(+");
169                         if (OP(*(s+opnd)) != O_PLUS)
170                                 fprintf(d, "<%ld>", (long)opnd);
171                         break;
172                 case O_PLUS:
173                         if (OP(*(s-opnd)) != OPLUS_)
174                                 fprintf(d, "<%ld>", (long)opnd);
175                         fprintf(d, "+)");
176                         break;
177                 case OQUEST_:
178                         fprintf(d, "(?");
179                         if (OP(*(s+opnd)) != O_QUEST)
180                                 fprintf(d, "<%ld>", (long)opnd);
181                         break;
182                 case O_QUEST:
183                         if (OP(*(s-opnd)) != OQUEST_)
184                                 fprintf(d, "<%ld>", (long)opnd);
185                         fprintf(d, "?)");
186                         break;
187                 case OLPAREN:
188                         fprintf(d, "((<%ld>", (long)opnd);
189                         break;
190                 case ORPAREN:
191                         fprintf(d, "<%ld>))", (long)opnd);
192                         break;
193                 case OCH_:
194                         fprintf(d, "<");
195                         if (OP(*(s+opnd)) != OOR2)
196                                 fprintf(d, "<%ld>", (long)opnd);
197                         break;
198                 case OOR1:
199                         if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
200                                 fprintf(d, "<%ld>", (long)opnd);
201                         fprintf(d, "|");
202                         break;
203                 case OOR2:
204                         fprintf(d, "|");
205                         if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
206                                 fprintf(d, "<%ld>", (long)opnd);
207                         break;
208                 case O_CH:
209                         if (OP(*(s-opnd)) != OOR1)
210                                 fprintf(d, "<%ld>", (long)opnd);
211                         fprintf(d, ">");
212                         break;
213                 default:
214                         fprintf(d, "!%d(%d)!", OP(*s), opnd);
215                         break;
216                 }
217                 if (!done)
218                         GAP();
219         }
220 }
221
222 /*
223  - regchar - make a character printable
224  == static char *regchar(int ch);
225  */
226 static char *                   /* -> representation */
227 regchar(ch)
228 int ch;
229 {
230         static char buf[10];
231
232         if (isprint(ch) || ch == ' ')
233                 snprintf(buf, SIZEOF(buf), "%c", ch);
234         else
235                 snprintf(buf, SIZEOF(buf), "\\%o", ch);
236         return(buf);
237 }