debug.c revision 62856
162856Sdcs/* $FreeBSD: head/lib/libc/regex/grot/debug.c 62856 2000-07-09 18:13:35Z dcs $
262856Sdcs */
362856Sdcs#include <stdio.h>
462856Sdcs#include <string.h>
562856Sdcs#include <ctype.h>
662856Sdcs#include <limits.h>
762856Sdcs#include <stdlib.h>
862856Sdcs#include <sys/types.h>
962856Sdcs#include <regex.h>
1062856Sdcs
1162856Sdcs#include "utils.h"
1262856Sdcs#include "regex2.h"
1362856Sdcs#include "debug.ih"
1462856Sdcs
1562856Sdcs/*
1662856Sdcs - regprint - print a regexp for debugging
1762856Sdcs == void regprint(regex_t *r, FILE *d);
1862856Sdcs */
1962856Sdcsvoid
2062856Sdcsregprint(r, d)
2162856Sdcsregex_t *r;
2262856SdcsFILE *d;
2362856Sdcs{
2462856Sdcs	register struct re_guts *g = r->re_g;
2562856Sdcs	register int i;
2662856Sdcs	register int c;
2762856Sdcs	register int last;
2862856Sdcs	int nincat[NC];
2962856Sdcs
3062856Sdcs	fprintf(d, "%ld states, %d categories", (long)g->nstates,
3162856Sdcs							g->ncategories);
3262856Sdcs	fprintf(d, ", first %ld last %ld", (long)g->firststate,
3362856Sdcs						(long)g->laststate);
3462856Sdcs	if (g->iflags&USEBOL)
3562856Sdcs		fprintf(d, ", USEBOL");
3662856Sdcs	if (g->iflags&USEEOL)
3762856Sdcs		fprintf(d, ", USEEOL");
3862856Sdcs	if (g->iflags&BAD)
3962856Sdcs		fprintf(d, ", BAD");
4062856Sdcs	if (g->nsub > 0)
4162856Sdcs		fprintf(d, ", nsub=%ld", (long)g->nsub);
4262856Sdcs	if (g->must != NULL)
4362856Sdcs		fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
4462856Sdcs								g->must);
4562856Sdcs	if (g->backrefs)
4662856Sdcs		fprintf(d, ", backrefs");
4762856Sdcs	if (g->nplus > 0)
4862856Sdcs		fprintf(d, ", nplus %ld", (long)g->nplus);
4962856Sdcs	fprintf(d, "\n");
5062856Sdcs	s_print(g, d);
5162856Sdcs	for (i = 0; i < g->ncategories; i++) {
5262856Sdcs		nincat[i] = 0;
5362856Sdcs		for (c = CHAR_MIN; c <= CHAR_MAX; c++)
5462856Sdcs			if (g->categories[c] == i)
5562856Sdcs				nincat[i]++;
5662856Sdcs	}
5762856Sdcs	fprintf(d, "cc0#%d", nincat[0]);
5862856Sdcs	for (i = 1; i < g->ncategories; i++)
5962856Sdcs		if (nincat[i] == 1) {
6062856Sdcs			for (c = CHAR_MIN; c <= CHAR_MAX; c++)
6162856Sdcs				if (g->categories[c] == i)
6262856Sdcs					break;
6362856Sdcs			fprintf(d, ", %d=%s", i, regchar(c));
6462856Sdcs		}
6562856Sdcs	fprintf(d, "\n");
6662856Sdcs	for (i = 1; i < g->ncategories; i++)
6762856Sdcs		if (nincat[i] != 1) {
6862856Sdcs			fprintf(d, "cc%d\t", i);
6962856Sdcs			last = -1;
7062856Sdcs			for (c = CHAR_MIN; c <= CHAR_MAX+1; c++)	/* +1 does flush */
7162856Sdcs				if (c <= CHAR_MAX && g->categories[c] == i) {
7262856Sdcs					if (last < 0) {
7362856Sdcs						fprintf(d, "%s", regchar(c));
7462856Sdcs						last = c;
7562856Sdcs					}
7662856Sdcs				} else {
7762856Sdcs					if (last >= 0) {
7862856Sdcs						if (last != c-1)
7962856Sdcs							fprintf(d, "-%s",
8062856Sdcs								regchar(c-1));
8162856Sdcs						last = -1;
8262856Sdcs					}
8362856Sdcs				}
8462856Sdcs			fprintf(d, "\n");
8562856Sdcs		}
8662856Sdcs}
8762856Sdcs
8862856Sdcs/*
8962856Sdcs - s_print - print the strip for debugging
9062856Sdcs == static void s_print(register struct re_guts *g, FILE *d);
9162856Sdcs */
9262856Sdcsstatic void
9362856Sdcss_print(g, d)
9462856Sdcsregister struct re_guts *g;
9562856SdcsFILE *d;
9662856Sdcs{
9762856Sdcs	register sop *s;
9862856Sdcs	register cset *cs;
9962856Sdcs	register int i;
10062856Sdcs	register int done = 0;
10162856Sdcs	register sop opnd;
10262856Sdcs	register int col = 0;
10362856Sdcs	register int last;
10462856Sdcs	register sopno offset = 2;
10562856Sdcs#	define	GAP()	{	if (offset % 5 == 0) { \
10662856Sdcs					if (col > 40) { \
10762856Sdcs						fprintf(d, "\n\t"); \
10862856Sdcs						col = 0; \
10962856Sdcs					} else { \
11062856Sdcs						fprintf(d, " "); \
11162856Sdcs						col++; \
11262856Sdcs					} \
11362856Sdcs				} else \
11462856Sdcs					col++; \
11562856Sdcs				offset++; \
11662856Sdcs			}
11762856Sdcs
11862856Sdcs	if (OP(g->strip[0]) != OEND)
11962856Sdcs		fprintf(d, "missing initial OEND!\n");
12062856Sdcs	for (s = &g->strip[1]; !done; s++) {
12162856Sdcs		opnd = OPND(*s);
12262856Sdcs		switch (OP(*s)) {
12362856Sdcs		case OEND:
12462856Sdcs			fprintf(d, "\n");
12562856Sdcs			done = 1;
12662856Sdcs			break;
12762856Sdcs		case OCHAR:
12862856Sdcs			if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
12962856Sdcs				fprintf(d, "\\%c", (char)opnd);
13062856Sdcs			else
13162856Sdcs				fprintf(d, "%s", regchar((char)opnd));
13262856Sdcs			break;
13362856Sdcs		case OBOL:
13462856Sdcs			fprintf(d, "^");
13562856Sdcs			break;
13662856Sdcs		case OEOL:
13762856Sdcs			fprintf(d, "$");
13862856Sdcs			break;
13962856Sdcs		case OBOW:
14062856Sdcs			fprintf(d, "\\{");
14162856Sdcs			break;
14262856Sdcs		case OEOW:
14362856Sdcs			fprintf(d, "\\}");
14462856Sdcs			break;
14562856Sdcs		case OANY:
14662856Sdcs			fprintf(d, ".");
14762856Sdcs			break;
14862856Sdcs		case OANYOF:
14962856Sdcs			fprintf(d, "[(%ld)", (long)opnd);
15062856Sdcs			cs = &g->sets[opnd];
15162856Sdcs			last = -1;
15262856Sdcs			for (i = 0; i < g->csetsize+1; i++)	/* +1 flushes */
15362856Sdcs				if (CHIN(cs, i) && i < g->csetsize) {
15462856Sdcs					if (last < 0) {
15562856Sdcs						fprintf(d, "%s", regchar(i));
15662856Sdcs						last = i;
15762856Sdcs					}
15862856Sdcs				} else {
15962856Sdcs					if (last >= 0) {
16062856Sdcs						if (last != i-1)
16162856Sdcs							fprintf(d, "-%s",
16262856Sdcs								regchar(i-1));
16362856Sdcs						last = -1;
16462856Sdcs					}
16562856Sdcs				}
16662856Sdcs			fprintf(d, "]");
16762856Sdcs			break;
16862856Sdcs		case OBACK_:
16962856Sdcs			fprintf(d, "(\\<%ld>", (long)opnd);
17062856Sdcs			break;
17162856Sdcs		case O_BACK:
17262856Sdcs			fprintf(d, "<%ld>\\)", (long)opnd);
17362856Sdcs			break;
17462856Sdcs		case OPLUS_:
17562856Sdcs			fprintf(d, "(+");
17662856Sdcs			if (OP(*(s+opnd)) != O_PLUS)
17762856Sdcs				fprintf(d, "<%ld>", (long)opnd);
17862856Sdcs			break;
17962856Sdcs		case O_PLUS:
18062856Sdcs			if (OP(*(s-opnd)) != OPLUS_)
18162856Sdcs				fprintf(d, "<%ld>", (long)opnd);
18262856Sdcs			fprintf(d, "+)");
18362856Sdcs			break;
18462856Sdcs		case OQUEST_:
18562856Sdcs			fprintf(d, "(?");
18662856Sdcs			if (OP(*(s+opnd)) != O_QUEST)
18762856Sdcs				fprintf(d, "<%ld>", (long)opnd);
18862856Sdcs			break;
18962856Sdcs		case O_QUEST:
19062856Sdcs			if (OP(*(s-opnd)) != OQUEST_)
19162856Sdcs				fprintf(d, "<%ld>", (long)opnd);
19262856Sdcs			fprintf(d, "?)");
19362856Sdcs			break;
19462856Sdcs		case OLPAREN:
19562856Sdcs			fprintf(d, "((<%ld>", (long)opnd);
19662856Sdcs			break;
19762856Sdcs		case ORPAREN:
19862856Sdcs			fprintf(d, "<%ld>))", (long)opnd);
19962856Sdcs			break;
20062856Sdcs		case OCH_:
20162856Sdcs			fprintf(d, "<");
20262856Sdcs			if (OP(*(s+opnd)) != OOR2)
20362856Sdcs				fprintf(d, "<%ld>", (long)opnd);
20462856Sdcs			break;
20562856Sdcs		case OOR1:
20662856Sdcs			if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
20762856Sdcs				fprintf(d, "<%ld>", (long)opnd);
20862856Sdcs			fprintf(d, "|");
20962856Sdcs			break;
21062856Sdcs		case OOR2:
21162856Sdcs			fprintf(d, "|");
21262856Sdcs			if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
21362856Sdcs				fprintf(d, "<%ld>", (long)opnd);
21462856Sdcs			break;
21562856Sdcs		case O_CH:
21662856Sdcs			if (OP(*(s-opnd)) != OOR1)
21762856Sdcs				fprintf(d, "<%ld>", (long)opnd);
21862856Sdcs			fprintf(d, ">");
21962856Sdcs			break;
22062856Sdcs		default:
22162856Sdcs			fprintf(d, "!%d(%d)!", OP(*s), opnd);
22262856Sdcs			break;
22362856Sdcs		}
22462856Sdcs		if (!done)
22562856Sdcs			GAP();
22662856Sdcs	}
22762856Sdcs}
22862856Sdcs
22962856Sdcs/*
23062856Sdcs - regchar - make a character printable
23162856Sdcs == static char *regchar(int ch);
23262856Sdcs */
23362856Sdcsstatic char *			/* -> representation */
23462856Sdcsregchar(ch)
23562856Sdcsint ch;
23662856Sdcs{
23762856Sdcs	static char buf[10];
23862856Sdcs
23962856Sdcs	if (isprint(ch) || ch == ' ')
24062856Sdcs		sprintf(buf, "%c", ch);
24162856Sdcs	else
24262856Sdcs		sprintf(buf, "\\%o", ch);
24362856Sdcs	return(buf);
24462856Sdcs}
245