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 */ 17void 18regprint(r, d) 19regex_t *r; 20FILE *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 */ 90static void 91s_print(g, d) 92register struct re_guts *g; 93FILE *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 */ 231static char * /* -> representation */ 232regchar(ch) 233int ch; 234{ 235 static char buf[10]; 236 237 if (isprint(ch) || ch == ' ') 238 sprintf(buf, "%c", ch); 239 else 240 sprintf(buf, "\\%o", ch); 241 return(buf); 242} 243