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