192986Sobrien#include <sys/cdefs.h>
292986Sobrien__FBSDID("$FreeBSD$");
392986Sobrien
462856Sdcs#include <stdio.h>
562856Sdcs#include <string.h>
662856Sdcs#include <ctype.h>
762856Sdcs#include <limits.h>
862856Sdcs#include <stdlib.h>
962856Sdcs#include <sys/types.h>
1062856Sdcs#include <regex.h>
11132388Stjr#include <wchar.h>
12132388Stjr#include <wctype.h>
1362856Sdcs
1462856Sdcs#include "utils.h"
1562856Sdcs#include "regex2.h"
1662856Sdcs#include "debug.ih"
1762856Sdcs
1862856Sdcs/*
1962856Sdcs - regprint - print a regexp for debugging
2062856Sdcs == void regprint(regex_t *r, FILE *d);
2162856Sdcs */
2262856Sdcsvoid
2362856Sdcsregprint(r, d)
2462856Sdcsregex_t *r;
2562856SdcsFILE *d;
2662856Sdcs{
2792889Sobrien	struct re_guts *g = r->re_g;
2892889Sobrien	int i;
2992889Sobrien	int c;
3092889Sobrien	int last;
3162856Sdcs
32132388Stjr	fprintf(d, "%ld states", (long)g->nstates);
3362856Sdcs	fprintf(d, ", first %ld last %ld", (long)g->firststate,
3462856Sdcs						(long)g->laststate);
3562856Sdcs	if (g->iflags&USEBOL)
3662856Sdcs		fprintf(d, ", USEBOL");
3762856Sdcs	if (g->iflags&USEEOL)
3862856Sdcs		fprintf(d, ", USEEOL");
3962856Sdcs	if (g->iflags&BAD)
4062856Sdcs		fprintf(d, ", BAD");
4162856Sdcs	if (g->nsub > 0)
4262856Sdcs		fprintf(d, ", nsub=%ld", (long)g->nsub);
4362856Sdcs	if (g->must != NULL)
4462856Sdcs		fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
4562856Sdcs								g->must);
4662856Sdcs	if (g->backrefs)
4762856Sdcs		fprintf(d, ", backrefs");
4862856Sdcs	if (g->nplus > 0)
4962856Sdcs		fprintf(d, ", nplus %ld", (long)g->nplus);
5062856Sdcs	fprintf(d, "\n");
5162856Sdcs	s_print(g, d);
5262856Sdcs}
5362856Sdcs
5462856Sdcs/*
5562856Sdcs - s_print - print the strip for debugging
5692889Sobrien == static void s_print(struct re_guts *g, FILE *d);
5762856Sdcs */
5862856Sdcsstatic void
5962856Sdcss_print(g, d)
6092889Sobrienstruct re_guts *g;
6162856SdcsFILE *d;
6262856Sdcs{
6392889Sobrien	sop *s;
6492889Sobrien	cset *cs;
6592889Sobrien	int i;
6692889Sobrien	int done = 0;
6792889Sobrien	sop opnd;
6892889Sobrien	int col = 0;
6992889Sobrien	int last;
7092889Sobrien	sopno offset = 2;
7162856Sdcs#	define	GAP()	{	if (offset % 5 == 0) { \
7262856Sdcs					if (col > 40) { \
7362856Sdcs						fprintf(d, "\n\t"); \
7462856Sdcs						col = 0; \
7562856Sdcs					} else { \
7662856Sdcs						fprintf(d, " "); \
7762856Sdcs						col++; \
7862856Sdcs					} \
7962856Sdcs				} else \
8062856Sdcs					col++; \
8162856Sdcs				offset++; \
8262856Sdcs			}
8362856Sdcs
8462856Sdcs	if (OP(g->strip[0]) != OEND)
8562856Sdcs		fprintf(d, "missing initial OEND!\n");
8662856Sdcs	for (s = &g->strip[1]; !done; s++) {
8762856Sdcs		opnd = OPND(*s);
8862856Sdcs		switch (OP(*s)) {
8962856Sdcs		case OEND:
9062856Sdcs			fprintf(d, "\n");
9162856Sdcs			done = 1;
9262856Sdcs			break;
9362856Sdcs		case OCHAR:
9462856Sdcs			if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
9562856Sdcs				fprintf(d, "\\%c", (char)opnd);
9662856Sdcs			else
9762856Sdcs				fprintf(d, "%s", regchar((char)opnd));
9862856Sdcs			break;
9962856Sdcs		case OBOL:
10062856Sdcs			fprintf(d, "^");
10162856Sdcs			break;
10262856Sdcs		case OEOL:
10362856Sdcs			fprintf(d, "$");
10462856Sdcs			break;
10562856Sdcs		case OBOW:
10662856Sdcs			fprintf(d, "\\{");
10762856Sdcs			break;
10862856Sdcs		case OEOW:
10962856Sdcs			fprintf(d, "\\}");
11062856Sdcs			break;
11162856Sdcs		case OANY:
11262856Sdcs			fprintf(d, ".");
11362856Sdcs			break;
11462856Sdcs		case OANYOF:
11562856Sdcs			fprintf(d, "[(%ld)", (long)opnd);
116132388Stjr#if 0
11762856Sdcs			cs = &g->sets[opnd];
11862856Sdcs			last = -1;
11962856Sdcs			for (i = 0; i < g->csetsize+1; i++)	/* +1 flushes */
12062856Sdcs				if (CHIN(cs, i) && i < g->csetsize) {
12162856Sdcs					if (last < 0) {
12262856Sdcs						fprintf(d, "%s", regchar(i));
12362856Sdcs						last = i;
12462856Sdcs					}
12562856Sdcs				} else {
12662856Sdcs					if (last >= 0) {
12762856Sdcs						if (last != i-1)
12862856Sdcs							fprintf(d, "-%s",
12962856Sdcs								regchar(i-1));
13062856Sdcs						last = -1;
13162856Sdcs					}
13262856Sdcs				}
133132388Stjr#endif
13462856Sdcs			fprintf(d, "]");
13562856Sdcs			break;
13662856Sdcs		case OBACK_:
13762856Sdcs			fprintf(d, "(\\<%ld>", (long)opnd);
13862856Sdcs			break;
13962856Sdcs		case O_BACK:
14062856Sdcs			fprintf(d, "<%ld>\\)", (long)opnd);
14162856Sdcs			break;
14262856Sdcs		case OPLUS_:
14362856Sdcs			fprintf(d, "(+");
14462856Sdcs			if (OP(*(s+opnd)) != O_PLUS)
14562856Sdcs				fprintf(d, "<%ld>", (long)opnd);
14662856Sdcs			break;
14762856Sdcs		case O_PLUS:
14862856Sdcs			if (OP(*(s-opnd)) != OPLUS_)
14962856Sdcs				fprintf(d, "<%ld>", (long)opnd);
15062856Sdcs			fprintf(d, "+)");
15162856Sdcs			break;
15262856Sdcs		case OQUEST_:
15362856Sdcs			fprintf(d, "(?");
15462856Sdcs			if (OP(*(s+opnd)) != O_QUEST)
15562856Sdcs				fprintf(d, "<%ld>", (long)opnd);
15662856Sdcs			break;
15762856Sdcs		case O_QUEST:
15862856Sdcs			if (OP(*(s-opnd)) != OQUEST_)
15962856Sdcs				fprintf(d, "<%ld>", (long)opnd);
16062856Sdcs			fprintf(d, "?)");
16162856Sdcs			break;
16262856Sdcs		case OLPAREN:
16362856Sdcs			fprintf(d, "((<%ld>", (long)opnd);
16462856Sdcs			break;
16562856Sdcs		case ORPAREN:
16662856Sdcs			fprintf(d, "<%ld>))", (long)opnd);
16762856Sdcs			break;
16862856Sdcs		case OCH_:
16962856Sdcs			fprintf(d, "<");
17062856Sdcs			if (OP(*(s+opnd)) != OOR2)
17162856Sdcs				fprintf(d, "<%ld>", (long)opnd);
17262856Sdcs			break;
17362856Sdcs		case OOR1:
17462856Sdcs			if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
17562856Sdcs				fprintf(d, "<%ld>", (long)opnd);
17662856Sdcs			fprintf(d, "|");
17762856Sdcs			break;
17862856Sdcs		case OOR2:
17962856Sdcs			fprintf(d, "|");
18062856Sdcs			if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
18162856Sdcs				fprintf(d, "<%ld>", (long)opnd);
18262856Sdcs			break;
18362856Sdcs		case O_CH:
18462856Sdcs			if (OP(*(s-opnd)) != OOR1)
18562856Sdcs				fprintf(d, "<%ld>", (long)opnd);
18662856Sdcs			fprintf(d, ">");
18762856Sdcs			break;
18862856Sdcs		default:
189291832Sngie			fprintf(d, "!%ld(%ld)!", OP(*s), (long)opnd);
19062856Sdcs			break;
19162856Sdcs		}
19262856Sdcs		if (!done)
19362856Sdcs			GAP();
19462856Sdcs	}
19562856Sdcs}
19662856Sdcs
19762856Sdcs/*
19862856Sdcs - regchar - make a character printable
19962856Sdcs == static char *regchar(int ch);
20062856Sdcs */
20162856Sdcsstatic char *			/* -> representation */
20262856Sdcsregchar(ch)
20362856Sdcsint ch;
20462856Sdcs{
20562856Sdcs	static char buf[10];
20662856Sdcs
20762856Sdcs	if (isprint(ch) || ch == ' ')
20862856Sdcs		sprintf(buf, "%c", ch);
20962856Sdcs	else
21062856Sdcs		sprintf(buf, "\\%o", ch);
21162856Sdcs	return(buf);
21262856Sdcs}
213