1 /* $NetBSD: debug.c,v 1.7 2021/02/25 22:37:36 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1993 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/types.h> 30 #include <ctype.h> 31 #include <limits.h> 32 #include <regex.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 37 #ifndef __linux__ 38 /* Don't sort these! */ 39 #include "utils.h" 40 #include "regex2.h" 41 #else 42 #define REGEX_NODEBUG 43 #endif 44 45 #ifdef REGEX_TRE 46 #define REGEX_NODEBUG 47 #endif 48 49 #include "test_regex.h" 50 51 #ifndef REGEX_NODEBUG 52 static void s_print(struct re_guts *, FILE *); 53 static char *regchar(int); 54 #endif 55 56 /* 57 * regprint - print a regexp for debugging 58 */ 59 void 60 regprint(regex_t *r, FILE *d) 61 { 62 #ifndef REGEX_NODEBUG 63 struct re_guts *g = r->re_g; 64 65 fprintf(d, ", first %u last %u", g->firststate, g->laststate); 66 if (g->iflags&USEBOL) 67 fprintf(d, ", USEBOL"); 68 if (g->iflags&USEEOL) 69 fprintf(d, ", USEEOL"); 70 if (g->iflags&BAD) 71 fprintf(d, ", BAD"); 72 if (g->nsub > 0) 73 fprintf(d, ", nsub=%zu", g->nsub); 74 if (g->must != NULL) 75 fprintf(d, ", must(%zu) `%*s'", g->mlen, (int)g->mlen, g->must); 76 if (g->backrefs) 77 fprintf(d, ", backrefs"); 78 if (g->nplus > 0) 79 fprintf(d, ", nplus %u", g->nplus); 80 fprintf(d, "\n"); 81 s_print(g, d); 82 fprintf(d, "\n"); 83 #endif 84 } 85 86 #ifndef REGEX_NODEBUG 87 /* 88 * s_print - print the strip for debugging 89 */ 90 static void 91 s_print(struct re_guts *g, FILE *d) 92 { 93 sop *s; 94 int done = 0; 95 sop opnd; 96 int col = 0; 97 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, "[(%u)", opnd); 143 fprintf(d, "]"); 144 break; 145 case OBACK_: 146 fprintf(d, "(\\<%u>", opnd); 147 break; 148 case O_BACK: 149 fprintf(d, "<%u>\\)", opnd); 150 break; 151 case OPLUS_: 152 fprintf(d, "(+"); 153 if (OP(*(s+opnd)) != O_PLUS) 154 fprintf(d, "<%u>", opnd); 155 break; 156 case O_PLUS: 157 if (OP(*(s-opnd)) != OPLUS_) 158 fprintf(d, "<%u>", opnd); 159 fprintf(d, "+)"); 160 break; 161 case OQUEST_: 162 fprintf(d, "(?"); 163 if (OP(*(s+opnd)) != O_QUEST) 164 fprintf(d, "<%u>", opnd); 165 break; 166 case O_QUEST: 167 if (OP(*(s-opnd)) != OQUEST_) 168 fprintf(d, "<%u>", opnd); 169 fprintf(d, "?)"); 170 break; 171 case OLPAREN: 172 fprintf(d, "((<%u>", opnd); 173 break; 174 case ORPAREN: 175 fprintf(d, "<%u>))", opnd); 176 break; 177 case OCH_: 178 fprintf(d, "<"); 179 if (OP(*(s+opnd)) != OOR2) 180 fprintf(d, "<%u>", opnd); 181 break; 182 case OOR1: 183 if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) 184 fprintf(d, "<%u>", opnd); 185 fprintf(d, "|"); 186 break; 187 case OOR2: 188 fprintf(d, "|"); 189 if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) 190 fprintf(d, "<%u>", opnd); 191 break; 192 case O_CH: 193 if (OP(*(s-opnd)) != OOR1) 194 fprintf(d, "<%u>", opnd); 195 fprintf(d, ">"); 196 break; 197 default: 198 fprintf(d, "!%u(%u)!", OP(*s), opnd); 199 break; 200 } 201 if (!done) 202 GAP(); 203 } 204 } 205 206 /* 207 * regchar - make a character printable 208 */ 209 static char * /* -> representation */ 210 regchar(int ch) 211 { 212 static char buf[10]; 213 214 if (isprint(ch) || ch == ' ') 215 sprintf(buf, "%c", ch); 216 else 217 sprintf(buf, "\\%o", ch); 218 return(buf); 219 } 220 #endif 221