1*63d1fd59SEnji Cooper /* $NetBSD: debug.c,v 1.3 2017/01/14 00:50:56 christos Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /*- 457718be8SEnji Cooper * Copyright (c) 1993 The NetBSD Foundation, Inc. 557718be8SEnji Cooper * All rights reserved. 657718be8SEnji Cooper * 757718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 857718be8SEnji Cooper * modification, are permitted provided that the following conditions 957718be8SEnji Cooper * are met: 1057718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 1157718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 1257718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1357718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 1457718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 1557718be8SEnji Cooper * 1657718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1757718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1857718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1957718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2057718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2157718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2257718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2357718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2457718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2557718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2657718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 2757718be8SEnji Cooper */ 2857718be8SEnji Cooper 29*63d1fd59SEnji Cooper #include <sys/types.h> 3057718be8SEnji Cooper #include <ctype.h> 3157718be8SEnji Cooper #include <limits.h> 3257718be8SEnji Cooper #include <regex.h> 3357718be8SEnji Cooper #include <stdio.h> 3457718be8SEnji Cooper #include <stdlib.h> 3557718be8SEnji Cooper #include <string.h> 3640187119SEnji Cooper #include <wchar.h> 3740187119SEnji Cooper #include <wctype.h> 3857718be8SEnji Cooper 3957718be8SEnji Cooper /* Don't sort these! */ 4057718be8SEnji Cooper #include "utils.h" 4157718be8SEnji Cooper #include "regex2.h" 4257718be8SEnji Cooper 4357718be8SEnji Cooper #include "test_regex.h" 4457718be8SEnji Cooper 45c519c0a1SEnji Cooper #ifdef __NetBSD__ 4657718be8SEnji Cooper static void s_print(struct re_guts *, FILE *); 4757718be8SEnji Cooper static char *regchar(int); 4857718be8SEnji Cooper 4957718be8SEnji Cooper /* 5057718be8SEnji Cooper * regprint - print a regexp for debugging 5157718be8SEnji Cooper */ 5257718be8SEnji Cooper void 5357718be8SEnji Cooper regprint(regex_t *r, FILE *d) 5457718be8SEnji Cooper { 5557718be8SEnji Cooper struct re_guts *g = r->re_g; 5657718be8SEnji Cooper int c; 5757718be8SEnji Cooper int last; 5857718be8SEnji Cooper int nincat[NC]; 5957718be8SEnji Cooper 6057718be8SEnji Cooper fprintf(d, "%ld states, %zu categories", (long)g->nstates, 6157718be8SEnji Cooper g->ncategories); 6257718be8SEnji Cooper fprintf(d, ", first %ld last %ld", (long)g->firststate, 6357718be8SEnji Cooper (long)g->laststate); 6457718be8SEnji Cooper if (g->iflags&USEBOL) 6557718be8SEnji Cooper fprintf(d, ", USEBOL"); 6657718be8SEnji Cooper if (g->iflags&USEEOL) 6757718be8SEnji Cooper fprintf(d, ", USEEOL"); 6857718be8SEnji Cooper if (g->iflags&BAD) 6957718be8SEnji Cooper fprintf(d, ", BAD"); 7057718be8SEnji Cooper if (g->nsub > 0) 7157718be8SEnji Cooper fprintf(d, ", nsub=%ld", (long)g->nsub); 7257718be8SEnji Cooper if (g->must != NULL) 7357718be8SEnji Cooper fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen, 7457718be8SEnji Cooper g->must); 7557718be8SEnji Cooper if (g->backrefs) 7657718be8SEnji Cooper fprintf(d, ", backrefs"); 7757718be8SEnji Cooper if (g->nplus > 0) 7857718be8SEnji Cooper fprintf(d, ", nplus %ld", (long)g->nplus); 7957718be8SEnji Cooper fprintf(d, "\n"); 8057718be8SEnji Cooper s_print(g, d); 8157718be8SEnji Cooper for (size_t i = 0; i < g->ncategories; i++) { 8257718be8SEnji Cooper nincat[i] = 0; 8357718be8SEnji Cooper for (c = CHAR_MIN; c <= CHAR_MAX; c++) 8457718be8SEnji Cooper if (g->categories[c] == i) 8557718be8SEnji Cooper nincat[i]++; 8657718be8SEnji Cooper } 8757718be8SEnji Cooper fprintf(d, "cc0#%d", nincat[0]); 8857718be8SEnji Cooper for (size_t i = 1; i < g->ncategories; i++) 8957718be8SEnji Cooper if (nincat[i] == 1) { 9057718be8SEnji Cooper for (c = CHAR_MIN; c <= CHAR_MAX; c++) 9157718be8SEnji Cooper if (g->categories[c] == i) 9257718be8SEnji Cooper break; 9357718be8SEnji Cooper fprintf(d, ", %zu=%s", i, regchar(c)); 9457718be8SEnji Cooper } 9557718be8SEnji Cooper fprintf(d, "\n"); 9657718be8SEnji Cooper for (size_t i = 1; i < g->ncategories; i++) 9757718be8SEnji Cooper if (nincat[i] != 1) { 9857718be8SEnji Cooper fprintf(d, "cc%zu\t", i); 9957718be8SEnji Cooper last = -1; 10057718be8SEnji Cooper for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */ 10157718be8SEnji Cooper if (c <= CHAR_MAX && g->categories[c] == i) { 10257718be8SEnji Cooper if (last < 0) { 10357718be8SEnji Cooper fprintf(d, "%s", regchar(c)); 10457718be8SEnji Cooper last = c; 10557718be8SEnji Cooper } 10657718be8SEnji Cooper } else { 10757718be8SEnji Cooper if (last >= 0) { 10857718be8SEnji Cooper if (last != c-1) 10957718be8SEnji Cooper fprintf(d, "-%s", 11057718be8SEnji Cooper regchar(c-1)); 11157718be8SEnji Cooper last = -1; 11257718be8SEnji Cooper } 11357718be8SEnji Cooper } 11457718be8SEnji Cooper fprintf(d, "\n"); 11557718be8SEnji Cooper } 11657718be8SEnji Cooper } 11757718be8SEnji Cooper 11857718be8SEnji Cooper /* 11957718be8SEnji Cooper * s_print - print the strip for debugging 12057718be8SEnji Cooper */ 12157718be8SEnji Cooper static void 12257718be8SEnji Cooper s_print(struct re_guts *g, FILE *d) 12357718be8SEnji Cooper { 12457718be8SEnji Cooper sop *s; 12557718be8SEnji Cooper cset *cs; 12657718be8SEnji Cooper int done = 0; 12757718be8SEnji Cooper sop opnd; 12857718be8SEnji Cooper int col = 0; 12957718be8SEnji Cooper ssize_t last; 13057718be8SEnji Cooper sopno offset = 2; 13157718be8SEnji Cooper # define GAP() { if (offset % 5 == 0) { \ 13257718be8SEnji Cooper if (col > 40) { \ 13357718be8SEnji Cooper fprintf(d, "\n\t"); \ 13457718be8SEnji Cooper col = 0; \ 13557718be8SEnji Cooper } else { \ 13657718be8SEnji Cooper fprintf(d, " "); \ 13757718be8SEnji Cooper col++; \ 13857718be8SEnji Cooper } \ 13957718be8SEnji Cooper } else \ 14057718be8SEnji Cooper col++; \ 14157718be8SEnji Cooper offset++; \ 14257718be8SEnji Cooper } 14357718be8SEnji Cooper 14457718be8SEnji Cooper if (OP(g->strip[0]) != OEND) 14557718be8SEnji Cooper fprintf(d, "missing initial OEND!\n"); 14657718be8SEnji Cooper for (s = &g->strip[1]; !done; s++) { 14757718be8SEnji Cooper opnd = OPND(*s); 14857718be8SEnji Cooper switch (OP(*s)) { 14957718be8SEnji Cooper case OEND: 15057718be8SEnji Cooper fprintf(d, "\n"); 15157718be8SEnji Cooper done = 1; 15257718be8SEnji Cooper break; 15357718be8SEnji Cooper case OCHAR: 15457718be8SEnji Cooper if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) 15557718be8SEnji Cooper fprintf(d, "\\%c", (char)opnd); 15657718be8SEnji Cooper else 15757718be8SEnji Cooper fprintf(d, "%s", regchar((char)opnd)); 15857718be8SEnji Cooper break; 15957718be8SEnji Cooper case OBOL: 16057718be8SEnji Cooper fprintf(d, "^"); 16157718be8SEnji Cooper break; 16257718be8SEnji Cooper case OEOL: 16357718be8SEnji Cooper fprintf(d, "$"); 16457718be8SEnji Cooper break; 16557718be8SEnji Cooper case OBOW: 16657718be8SEnji Cooper fprintf(d, "\\{"); 16757718be8SEnji Cooper break; 16857718be8SEnji Cooper case OEOW: 16957718be8SEnji Cooper fprintf(d, "\\}"); 17057718be8SEnji Cooper break; 17157718be8SEnji Cooper case OANY: 17257718be8SEnji Cooper fprintf(d, "."); 17357718be8SEnji Cooper break; 17457718be8SEnji Cooper case OANYOF: 17557718be8SEnji Cooper fprintf(d, "[(%ld)", (long)opnd); 17657718be8SEnji Cooper cs = &g->sets[opnd]; 17757718be8SEnji Cooper last = -1; 17857718be8SEnji Cooper for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */ 17957718be8SEnji Cooper if (CHIN(cs, i) && i < g->csetsize) { 18057718be8SEnji Cooper if (last < 0) { 18157718be8SEnji Cooper fprintf(d, "%s", regchar(i)); 18257718be8SEnji Cooper last = i; 18357718be8SEnji Cooper } 18457718be8SEnji Cooper } else { 18557718be8SEnji Cooper if (last >= 0) { 18657718be8SEnji Cooper if (last != (ssize_t)i - 1) 18757718be8SEnji Cooper fprintf(d, "-%s", 18857718be8SEnji Cooper regchar(i - 1)); 18957718be8SEnji Cooper last = -1; 19057718be8SEnji Cooper } 19157718be8SEnji Cooper } 19257718be8SEnji Cooper fprintf(d, "]"); 19357718be8SEnji Cooper break; 19457718be8SEnji Cooper case OBACK_: 19557718be8SEnji Cooper fprintf(d, "(\\<%ld>", (long)opnd); 19657718be8SEnji Cooper break; 19757718be8SEnji Cooper case O_BACK: 19857718be8SEnji Cooper fprintf(d, "<%ld>\\)", (long)opnd); 19957718be8SEnji Cooper break; 20057718be8SEnji Cooper case OPLUS_: 20157718be8SEnji Cooper fprintf(d, "(+"); 20257718be8SEnji Cooper if (OP(*(s+opnd)) != O_PLUS) 20357718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 20457718be8SEnji Cooper break; 20557718be8SEnji Cooper case O_PLUS: 20657718be8SEnji Cooper if (OP(*(s-opnd)) != OPLUS_) 20757718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 20857718be8SEnji Cooper fprintf(d, "+)"); 20957718be8SEnji Cooper break; 21057718be8SEnji Cooper case OQUEST_: 21157718be8SEnji Cooper fprintf(d, "(?"); 21257718be8SEnji Cooper if (OP(*(s+opnd)) != O_QUEST) 21357718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 21457718be8SEnji Cooper break; 21557718be8SEnji Cooper case O_QUEST: 21657718be8SEnji Cooper if (OP(*(s-opnd)) != OQUEST_) 21757718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 21857718be8SEnji Cooper fprintf(d, "?)"); 21957718be8SEnji Cooper break; 22057718be8SEnji Cooper case OLPAREN: 22157718be8SEnji Cooper fprintf(d, "((<%ld>", (long)opnd); 22257718be8SEnji Cooper break; 22357718be8SEnji Cooper case ORPAREN: 22457718be8SEnji Cooper fprintf(d, "<%ld>))", (long)opnd); 22557718be8SEnji Cooper break; 22657718be8SEnji Cooper case OCH_: 22757718be8SEnji Cooper fprintf(d, "<"); 22857718be8SEnji Cooper if (OP(*(s+opnd)) != OOR2) 22957718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 23057718be8SEnji Cooper break; 23157718be8SEnji Cooper case OOR1: 23257718be8SEnji Cooper if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) 23357718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 23457718be8SEnji Cooper fprintf(d, "|"); 23557718be8SEnji Cooper break; 23657718be8SEnji Cooper case OOR2: 23757718be8SEnji Cooper fprintf(d, "|"); 23857718be8SEnji Cooper if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) 23957718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 24057718be8SEnji Cooper break; 24157718be8SEnji Cooper case O_CH: 24257718be8SEnji Cooper if (OP(*(s-opnd)) != OOR1) 24357718be8SEnji Cooper fprintf(d, "<%ld>", (long)opnd); 24457718be8SEnji Cooper fprintf(d, ">"); 24557718be8SEnji Cooper break; 24657718be8SEnji Cooper default: 24757718be8SEnji Cooper fprintf(d, "!%d(%d)!", OP(*s), opnd); 24857718be8SEnji Cooper break; 24957718be8SEnji Cooper } 25057718be8SEnji Cooper if (!done) 25157718be8SEnji Cooper GAP(); 25257718be8SEnji Cooper } 25357718be8SEnji Cooper } 25457718be8SEnji Cooper 25557718be8SEnji Cooper /* 25657718be8SEnji Cooper * regchar - make a character printable 25757718be8SEnji Cooper */ 25857718be8SEnji Cooper static char * /* -> representation */ 25957718be8SEnji Cooper regchar(int ch) 26057718be8SEnji Cooper { 26157718be8SEnji Cooper static char buf[10]; 26257718be8SEnji Cooper 26357718be8SEnji Cooper if (isprint(ch) || ch == ' ') 26457718be8SEnji Cooper sprintf(buf, "%c", ch); 26557718be8SEnji Cooper else 26657718be8SEnji Cooper sprintf(buf, "\\%o", ch); 26757718be8SEnji Cooper return(buf); 26857718be8SEnji Cooper } 269c519c0a1SEnji Cooper #else 270c519c0a1SEnji Cooper void 271c519c0a1SEnji Cooper regprint(regex_t *r, FILE *d) 272c519c0a1SEnji Cooper { 273c519c0a1SEnji Cooper 274c519c0a1SEnji Cooper } 275c519c0a1SEnji Cooper #endif 276