1 /* $OpenBSD: debug.c,v 1.5 2020/12/31 17:20:19 millert Exp $ */ 2 /* $NetBSD: debug.c,v 1.2 1995/04/20 22:39:42 cgd Exp $ */ 3 4 #include <stdio.h> 5 #include <string.h> 6 #include <ctype.h> 7 #include <limits.h> 8 #include <stdlib.h> 9 #include <sys/types.h> 10 #include <regex.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 register struct re_guts *g = r->re_g; 26 register int i; 27 register int c; 28 register 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(register struct re_guts *g, FILE *d); 55 */ 56 static void 57 s_print(g, d) 58 register struct re_guts *g; 59 FILE *d; 60 { 61 register sop *s; 62 register cset *cs; 63 register int i; 64 register int done = 0; 65 register sop opnd; 66 register int col = 0; 67 register int last; 68 register 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 cs = &g->sets[opnd]; 115 last = -1; 116 for (i = 0; i < g->csetsize+1; i++) /* +1 flushes */ 117 if (CHIN(cs, i) && i < g->csetsize) { 118 if (last < 0) { 119 fprintf(d, "%s", regchar(i)); 120 last = i; 121 } 122 } else { 123 if (last >= 0) { 124 if (last != i-1) 125 fprintf(d, "-%s", 126 regchar(i-1)); 127 last = -1; 128 } 129 } 130 fprintf(d, "]"); 131 break; 132 case OBACK_: 133 fprintf(d, "(\\<%ld>", (long)opnd); 134 break; 135 case O_BACK: 136 fprintf(d, "<%ld>\\)", (long)opnd); 137 break; 138 case OPLUS_: 139 fprintf(d, "(+"); 140 if (OP(*(s+opnd)) != O_PLUS) 141 fprintf(d, "<%ld>", (long)opnd); 142 break; 143 case O_PLUS: 144 if (OP(*(s-opnd)) != OPLUS_) 145 fprintf(d, "<%ld>", (long)opnd); 146 fprintf(d, "+)"); 147 break; 148 case OQUEST_: 149 fprintf(d, "(?"); 150 if (OP(*(s+opnd)) != O_QUEST) 151 fprintf(d, "<%ld>", (long)opnd); 152 break; 153 case O_QUEST: 154 if (OP(*(s-opnd)) != OQUEST_) 155 fprintf(d, "<%ld>", (long)opnd); 156 fprintf(d, "?)"); 157 break; 158 case OLPAREN: 159 fprintf(d, "((<%ld>", (long)opnd); 160 break; 161 case ORPAREN: 162 fprintf(d, "<%ld>))", (long)opnd); 163 break; 164 case OCH_: 165 fprintf(d, "<"); 166 if (OP(*(s+opnd)) != OOR2) 167 fprintf(d, "<%ld>", (long)opnd); 168 break; 169 case OOR1: 170 if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) 171 fprintf(d, "<%ld>", (long)opnd); 172 fprintf(d, "|"); 173 break; 174 case OOR2: 175 fprintf(d, "|"); 176 if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) 177 fprintf(d, "<%ld>", (long)opnd); 178 break; 179 case O_CH: 180 if (OP(*(s-opnd)) != OOR1) 181 fprintf(d, "<%ld>", (long)opnd); 182 fprintf(d, ">"); 183 break; 184 default: 185 fprintf(d, "!%ld(%ld)!", (long)OP(*s), (long)opnd); 186 break; 187 } 188 if (!done) 189 GAP(); 190 } 191 } 192 193 /* 194 - regchar - make a character printable 195 == static char *regchar(int ch); 196 */ 197 static char * /* -> representation */ 198 regchar(ch) 199 int ch; 200 { 201 static char buf[10]; 202 203 if (isprint(ch) || ch == ' ') 204 snprintf(buf, sizeof buf, "%c", ch); 205 else 206 snprintf(buf, sizeof buf, "\\%o", ch); 207 return(buf); 208 } 209