debug.c revision 272343
1272343Sngie/* $NetBSD: debug.c,v 1.2 2011/10/10 04:32:41 christos Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 1993 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * Redistribution and use in source and binary forms, with or without 8272343Sngie * modification, are permitted provided that the following conditions 9272343Sngie * are met: 10272343Sngie * 1. Redistributions of source code must retain the above copyright 11272343Sngie * notice, this list of conditions and the following disclaimer. 12272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 13272343Sngie * notice, this list of conditions and the following disclaimer in the 14272343Sngie * documentation and/or other materials provided with the distribution. 15272343Sngie * 16272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26272343Sngie * POSSIBILITY OF SUCH DAMAGE. 27272343Sngie */ 28272343Sngie 29272343Sngie#include <ctype.h> 30272343Sngie#include <limits.h> 31272343Sngie#include <regex.h> 32272343Sngie#include <stdio.h> 33272343Sngie#include <stdlib.h> 34272343Sngie#include <string.h> 35272343Sngie 36272343Sngie#include <sys/types.h> 37272343Sngie 38272343Sngie/* Don't sort these! */ 39272343Sngie#include "utils.h" 40272343Sngie#include "regex2.h" 41272343Sngie 42272343Sngie#include "test_regex.h" 43272343Sngie 44272343Sngiestatic void s_print(struct re_guts *, FILE *); 45272343Sngiestatic char *regchar(int); 46272343Sngie 47272343Sngie/* 48272343Sngie * regprint - print a regexp for debugging 49272343Sngie */ 50272343Sngievoid 51272343Sngieregprint(regex_t *r, FILE *d) 52272343Sngie{ 53272343Sngie struct re_guts *g = r->re_g; 54272343Sngie int c; 55272343Sngie int last; 56272343Sngie int nincat[NC]; 57272343Sngie 58272343Sngie fprintf(d, "%ld states, %zu categories", (long)g->nstates, 59272343Sngie g->ncategories); 60272343Sngie fprintf(d, ", first %ld last %ld", (long)g->firststate, 61272343Sngie (long)g->laststate); 62272343Sngie if (g->iflags&USEBOL) 63272343Sngie fprintf(d, ", USEBOL"); 64272343Sngie if (g->iflags&USEEOL) 65272343Sngie fprintf(d, ", USEEOL"); 66272343Sngie if (g->iflags&BAD) 67272343Sngie fprintf(d, ", BAD"); 68272343Sngie if (g->nsub > 0) 69272343Sngie fprintf(d, ", nsub=%ld", (long)g->nsub); 70272343Sngie if (g->must != NULL) 71272343Sngie fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen, 72272343Sngie g->must); 73272343Sngie if (g->backrefs) 74272343Sngie fprintf(d, ", backrefs"); 75272343Sngie if (g->nplus > 0) 76272343Sngie fprintf(d, ", nplus %ld", (long)g->nplus); 77272343Sngie fprintf(d, "\n"); 78272343Sngie s_print(g, d); 79272343Sngie for (size_t i = 0; i < g->ncategories; i++) { 80272343Sngie nincat[i] = 0; 81272343Sngie for (c = CHAR_MIN; c <= CHAR_MAX; c++) 82272343Sngie if (g->categories[c] == i) 83272343Sngie nincat[i]++; 84272343Sngie } 85272343Sngie fprintf(d, "cc0#%d", nincat[0]); 86272343Sngie for (size_t i = 1; i < g->ncategories; i++) 87272343Sngie if (nincat[i] == 1) { 88272343Sngie for (c = CHAR_MIN; c <= CHAR_MAX; c++) 89272343Sngie if (g->categories[c] == i) 90272343Sngie break; 91272343Sngie fprintf(d, ", %zu=%s", i, regchar(c)); 92272343Sngie } 93272343Sngie fprintf(d, "\n"); 94272343Sngie for (size_t i = 1; i < g->ncategories; i++) 95272343Sngie if (nincat[i] != 1) { 96272343Sngie fprintf(d, "cc%zu\t", i); 97272343Sngie last = -1; 98272343Sngie for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */ 99272343Sngie if (c <= CHAR_MAX && g->categories[c] == i) { 100272343Sngie if (last < 0) { 101272343Sngie fprintf(d, "%s", regchar(c)); 102272343Sngie last = c; 103272343Sngie } 104272343Sngie } else { 105272343Sngie if (last >= 0) { 106272343Sngie if (last != c-1) 107272343Sngie fprintf(d, "-%s", 108272343Sngie regchar(c-1)); 109272343Sngie last = -1; 110272343Sngie } 111272343Sngie } 112272343Sngie fprintf(d, "\n"); 113272343Sngie } 114272343Sngie} 115272343Sngie 116272343Sngie/* 117272343Sngie * s_print - print the strip for debugging 118272343Sngie */ 119272343Sngiestatic void 120272343Sngies_print(struct re_guts *g, FILE *d) 121272343Sngie{ 122272343Sngie sop *s; 123272343Sngie cset *cs; 124272343Sngie int done = 0; 125272343Sngie sop opnd; 126272343Sngie int col = 0; 127272343Sngie ssize_t last; 128272343Sngie sopno offset = 2; 129272343Sngie# define GAP() { if (offset % 5 == 0) { \ 130272343Sngie if (col > 40) { \ 131272343Sngie fprintf(d, "\n\t"); \ 132272343Sngie col = 0; \ 133272343Sngie } else { \ 134272343Sngie fprintf(d, " "); \ 135272343Sngie col++; \ 136272343Sngie } \ 137272343Sngie } else \ 138272343Sngie col++; \ 139272343Sngie offset++; \ 140272343Sngie } 141272343Sngie 142272343Sngie if (OP(g->strip[0]) != OEND) 143272343Sngie fprintf(d, "missing initial OEND!\n"); 144272343Sngie for (s = &g->strip[1]; !done; s++) { 145272343Sngie opnd = OPND(*s); 146272343Sngie switch (OP(*s)) { 147272343Sngie case OEND: 148272343Sngie fprintf(d, "\n"); 149272343Sngie done = 1; 150272343Sngie break; 151272343Sngie case OCHAR: 152272343Sngie if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) 153272343Sngie fprintf(d, "\\%c", (char)opnd); 154272343Sngie else 155272343Sngie fprintf(d, "%s", regchar((char)opnd)); 156272343Sngie break; 157272343Sngie case OBOL: 158272343Sngie fprintf(d, "^"); 159272343Sngie break; 160272343Sngie case OEOL: 161272343Sngie fprintf(d, "$"); 162272343Sngie break; 163272343Sngie case OBOW: 164272343Sngie fprintf(d, "\\{"); 165272343Sngie break; 166272343Sngie case OEOW: 167272343Sngie fprintf(d, "\\}"); 168272343Sngie break; 169272343Sngie case OANY: 170272343Sngie fprintf(d, "."); 171272343Sngie break; 172272343Sngie case OANYOF: 173272343Sngie fprintf(d, "[(%ld)", (long)opnd); 174272343Sngie cs = &g->sets[opnd]; 175272343Sngie last = -1; 176272343Sngie for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */ 177272343Sngie if (CHIN(cs, i) && i < g->csetsize) { 178272343Sngie if (last < 0) { 179272343Sngie fprintf(d, "%s", regchar(i)); 180272343Sngie last = i; 181272343Sngie } 182272343Sngie } else { 183272343Sngie if (last >= 0) { 184272343Sngie if (last != (ssize_t)i - 1) 185272343Sngie fprintf(d, "-%s", 186272343Sngie regchar(i - 1)); 187272343Sngie last = -1; 188272343Sngie } 189272343Sngie } 190272343Sngie fprintf(d, "]"); 191272343Sngie break; 192272343Sngie case OBACK_: 193272343Sngie fprintf(d, "(\\<%ld>", (long)opnd); 194272343Sngie break; 195272343Sngie case O_BACK: 196272343Sngie fprintf(d, "<%ld>\\)", (long)opnd); 197272343Sngie break; 198272343Sngie case OPLUS_: 199272343Sngie fprintf(d, "(+"); 200272343Sngie if (OP(*(s+opnd)) != O_PLUS) 201272343Sngie fprintf(d, "<%ld>", (long)opnd); 202272343Sngie break; 203272343Sngie case O_PLUS: 204272343Sngie if (OP(*(s-opnd)) != OPLUS_) 205272343Sngie fprintf(d, "<%ld>", (long)opnd); 206272343Sngie fprintf(d, "+)"); 207272343Sngie break; 208272343Sngie case OQUEST_: 209272343Sngie fprintf(d, "(?"); 210272343Sngie if (OP(*(s+opnd)) != O_QUEST) 211272343Sngie fprintf(d, "<%ld>", (long)opnd); 212272343Sngie break; 213272343Sngie case O_QUEST: 214272343Sngie if (OP(*(s-opnd)) != OQUEST_) 215272343Sngie fprintf(d, "<%ld>", (long)opnd); 216272343Sngie fprintf(d, "?)"); 217272343Sngie break; 218272343Sngie case OLPAREN: 219272343Sngie fprintf(d, "((<%ld>", (long)opnd); 220272343Sngie break; 221272343Sngie case ORPAREN: 222272343Sngie fprintf(d, "<%ld>))", (long)opnd); 223272343Sngie break; 224272343Sngie case OCH_: 225272343Sngie fprintf(d, "<"); 226272343Sngie if (OP(*(s+opnd)) != OOR2) 227272343Sngie fprintf(d, "<%ld>", (long)opnd); 228272343Sngie break; 229272343Sngie case OOR1: 230272343Sngie if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) 231272343Sngie fprintf(d, "<%ld>", (long)opnd); 232272343Sngie fprintf(d, "|"); 233272343Sngie break; 234272343Sngie case OOR2: 235272343Sngie fprintf(d, "|"); 236272343Sngie if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) 237272343Sngie fprintf(d, "<%ld>", (long)opnd); 238272343Sngie break; 239272343Sngie case O_CH: 240272343Sngie if (OP(*(s-opnd)) != OOR1) 241272343Sngie fprintf(d, "<%ld>", (long)opnd); 242272343Sngie fprintf(d, ">"); 243272343Sngie break; 244272343Sngie default: 245272343Sngie fprintf(d, "!%d(%d)!", OP(*s), opnd); 246272343Sngie break; 247272343Sngie } 248272343Sngie if (!done) 249272343Sngie GAP(); 250272343Sngie } 251272343Sngie} 252272343Sngie 253272343Sngie/* 254272343Sngie * regchar - make a character printable 255272343Sngie */ 256272343Sngiestatic char * /* -> representation */ 257272343Sngieregchar(int ch) 258272343Sngie{ 259272343Sngie static char buf[10]; 260272343Sngie 261272343Sngie if (isprint(ch) || ch == ' ') 262272343Sngie sprintf(buf, "%c", ch); 263272343Sngie else 264272343Sngie sprintf(buf, "\\%o", ch); 265272343Sngie return(buf); 266272343Sngie} 267