/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#include "utils.h"
#include "regex2.h"
#include "debug.ih"
/*
- regprint - print a regexp for debugging
== void regprint(regex_t *r, FILE *d);
*/
void
regprint(r, d)
regex_t *r;
FILE *d;
{
register struct re_guts *g = r->re_g;
register int i;
register int c;
register int last;
int nincat[NC];
fprintf(d
, "%ld states, %d categories", (long)g
->nstates
,
g->ncategories);
fprintf(d
, ", first %ld last %ld", (long)g
->firststate
,
(long)g->laststate);
if (g->iflags&USEBOL)
if (g->iflags&USEEOL)
if (g->iflags&BAD)
if (g->nsub > 0)
fprintf(d
, ", nsub=%ld", (long)g
->nsub
);
if (g->must != NULL)
fprintf(d
, ", must(%ld) `%*s'", (long)g
->mlen
, (int)g
->mlen
,
g->must);
if (g->backrefs)
if (g->nplus > 0)
fprintf(d
, ", nplus %ld", (long)g
->nplus
);
s_print(g, d);
for (i = 0; i < g->ncategories; i++) {
nincat[i] = 0;
for (c = CHAR_MIN; c <= CHAR_MAX; c++)
if (g->categories[c] == i)
nincat[i]++;
}
for (i = 1; i < g->ncategories; i++)
if (nincat[i] == 1) {
for (c = CHAR_MIN; c <= CHAR_MAX; c++)
if (g->categories[c] == i)
break;
fprintf(d
, ", %d=%s", i
, regchar
(c
));
}
for (i = 1; i < g->ncategories; i++)
if (nincat[i] != 1) {
last = -1;
for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */
if (c <= CHAR_MAX && g->categories[c] == i) {
if (last < 0) {
last = c;
}
} else {
if (last >= 0) {
if (last != c-1)
regchar(c-1));
last = -1;
}
}
}
}
/*
- s_print - print the strip for debugging
== static void s_print(register struct re_guts *g, FILE *d);
*/
static void
s_print(g, d)
register struct re_guts *g;
FILE *d;
{
register sop *s;
register cset *cs;
register int i;
register int done = 0;
register sop opnd;
register int col = 0;
register int last;
register sopno offset = 2;
# define GAP() { if (offset % 5 == 0) { \
if (col > 40) { \
fprintf(d, "\n\t"); \
col = 0; \
} else { \
fprintf(d, " "); \
col++; \
} \
} else \
col++; \
offset++; \
}
if (OP(g->strip[0]) != OEND)
fprintf(d
, "missing initial OEND!\n");
for (s = &g->strip[1]; !done; s++) {
opnd = OPND(*s);
switch (OP(*s)) {
case OEND:
done = 1;
break;
case OCHAR:
if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd
) != NULL
)
else
fprintf(d
, "%s", regchar
((char)opnd
));
break;
case OBOL:
break;
case OEOL:
break;
case OBOW:
break;
case OEOW:
break;
case OANY:
break;
case OANYOF:
cs = &g->sets[opnd];
last = -1;
for (i = 0; i < g->csetsize+1; i++) /* +1 flushes */
if (CHIN(cs, i) && i < g->csetsize) {
if (last < 0) {
last = i;
}
} else {
if (last >= 0) {
if (last != i-1)
regchar(i-1));
last = -1;
}
}
break;
case OBACK_:
fprintf(d
, "(\\<%ld>", (long)opnd
);
break;
case O_BACK:
fprintf(d
, "<%ld>\\)", (long)opnd
);
break;
case OPLUS_:
if (OP(*(s+opnd)) != O_PLUS)
break;
case O_PLUS:
if (OP(*(s-opnd)) != OPLUS_)
break;
case OQUEST_:
if (OP(*(s+opnd)) != O_QUEST)
break;
case O_QUEST:
if (OP(*(s-opnd)) != OQUEST_)
break;
case OLPAREN:
break;
case ORPAREN:
break;
case OCH_:
if (OP(*(s+opnd)) != OOR2)
break;
case OOR1:
if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
break;
case OOR2:
if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
break;
case O_CH:
if (OP(*(s-opnd)) != OOR1)
break;
default:
fprintf(d
, "!%d(%d)!", OP
(*s
), opnd
);
break;
}
if (!done)
GAP();
}
}
/*
- regchar - make a character printable
== static char *regchar(int ch);
*/
static char * /* -> representation */
regchar(ch)
int ch;
{
static char buf[10];
else
return(buf);
}