version 1.11, 1999/01/20 12:58:21 |
version 1.23.2.1, 2012/04/17 00:05:22 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/*- |
/*- |
* Copyright (c) 1992, 1993, 1994 Henry Spencer. |
|
* Copyright (c) 1992, 1993, 1994 |
* Copyright (c) 1992, 1993, 1994 |
* The Regents of the University of California. All rights reserved. |
* The Regents of the University of California. All rights reserved. |
* |
* |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
|
* 3. Neither the name of the University nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
* SUCH DAMAGE. |
|
* |
|
* @(#)engine.c 8.5 (Berkeley) 3/20/94 |
|
*/ |
|
|
|
/*- |
|
* Copyright (c) 1992, 1993, 1994 Henry Spencer. |
|
* |
|
* This code is derived from software contributed to Berkeley by |
|
* Henry Spencer. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* This product includes software developed by the University of |
|
|
#define print sprint |
#define print sprint |
#define at sat |
#define at sat |
#define match smat |
#define match smat |
|
#define nope snope |
#endif |
#endif |
#ifdef LNAMES |
#ifdef LNAMES |
#define matcher lmatcher |
#define matcher lmatcher |
|
|
#define print lprint |
#define print lprint |
#define at lat |
#define at lat |
#define match lmat |
#define match lmat |
|
#define nope lnope |
#endif |
#endif |
|
|
/* another structure passed up and down to avoid zillions of parameters */ |
/* another structure passed up and down to avoid zillions of parameters */ |
|
|
struct re_guts *g; |
struct re_guts *g; |
int eflags; |
int eflags; |
regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ |
regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ |
char *offp; /* offsets work from here */ |
const char *offp; /* offsets work from here */ |
char *beginp; /* start of string -- virtual NUL precedes */ |
const char *beginp; /* start of string -- virtual NUL precedes */ |
char *endp; /* end of string -- virtual NUL here */ |
const char *endp; /* end of string -- virtual NUL here */ |
char *coldp; /* can be no match starting before here */ |
const char *coldp; /* can be no match starting before here */ |
char **lastpos; /* [nplus+1] */ |
const char **lastpos; /* [nplus+1] */ |
STATEVARS; |
STATEVARS; |
states st; /* current states */ |
states st; /* current states */ |
states fresh; /* states for a fresh start */ |
states fresh; /* states for a fresh start */ |
|
|
#endif |
#endif |
|
|
/* === engine.c === */ |
/* === engine.c === */ |
static int matcher __P((struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags)); |
static int matcher(struct re_guts *g, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); |
static char *dissect __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst)); |
static const char *dissect(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); |
static char *backref __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev)); |
static const char *backref(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst, sopno lev); |
static char *fast __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst)); |
static const char *fast(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); |
static char *slow __P((struct match *m, char *start, char *stop, sopno startst, sopno stopst)); |
static const char *slow(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); |
static states step __P((struct re_guts *g, sopno start, sopno stop, states bef, int ch, states aft)); |
static states step(struct re_guts *g, sopno start, sopno stop, states bef, int ch, states aft); |
#define BOL (OUT+1) |
#define BOL (OUT+1) |
#define EOL (BOL+1) |
#define EOL (BOL+1) |
#define BOLEOL (BOL+2) |
#define BOLEOL (BOL+2) |
Line 108 static states step __P((struct re_guts * |
|
Line 142 static states step __P((struct re_guts * |
|
#define NONCHAR(c) ((c) > CHAR_MAX) |
#define NONCHAR(c) ((c) > CHAR_MAX) |
#define NNONCHAR (CODEMAX-CHAR_MAX) |
#define NNONCHAR (CODEMAX-CHAR_MAX) |
#ifdef REDEBUG |
#ifdef REDEBUG |
static void print __P((struct match *m, char *caption, states st, int ch, FILE *d)); |
static void print(struct match *m, char *caption, states st, int ch, FILE *d); |
#endif |
#endif |
#ifdef REDEBUG |
#ifdef REDEBUG |
static void at __P((struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst)); |
static void at(struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst); |
#endif |
#endif |
#ifdef REDEBUG |
#ifdef REDEBUG |
static char *pchar __P((int ch)); |
static char *pchar(int ch); |
#endif |
#endif |
|
|
#ifdef __cplusplus |
#ifdef __cplusplus |
Line 126 static char *pchar __P((int ch)); |
|
Line 160 static char *pchar __P((int ch)); |
|
#define SP(t, s, c) print(m, t, s, c, stdout) |
#define SP(t, s, c) print(m, t, s, c, stdout) |
#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) |
#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) |
#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } |
#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } |
|
static int nope = 0; |
#else |
#else |
#define SP(t, s, c) /* nothing */ |
#define SP(t, s, c) /* nothing */ |
#define AT(t, p1, p2, s1, s2) /* nothing */ |
#define AT(t, p1, p2, s1, s2) /* nothing */ |
Line 138 static char *pchar __P((int ch)); |
|
Line 173 static char *pchar __P((int ch)); |
|
== size_t nmatch, regmatch_t pmatch[], int eflags); |
== size_t nmatch, regmatch_t pmatch[], int eflags); |
*/ |
*/ |
static int /* 0 success, REG_NOMATCH failure */ |
static int /* 0 success, REG_NOMATCH failure */ |
matcher(g, string, nmatch, pmatch, eflags) |
matcher( |
struct re_guts *g; |
struct re_guts *g, |
char *string; |
const char *string, |
size_t nmatch; |
size_t nmatch, |
regmatch_t pmatch[]; |
regmatch_t pmatch[], |
int eflags; |
int eflags) |
{ |
{ |
char *endp; |
const char *endp; |
int i; |
size_t i; |
struct match mv; |
struct match mv; |
struct match *m = &mv; |
struct match *m = &mv; |
char *dp; |
const char *dp; |
const sopno gf = g->firststate+1; /* +1 for OEND */ |
const sopno gf = g->firststate+1; /* +1 for OEND */ |
const sopno gl = g->laststate; |
const sopno gl = g->laststate; |
char *start; |
const char *start; |
char *stop; |
const char *stop; |
|
int error = 0; |
|
|
|
_DIAGASSERT(g != NULL); |
|
_DIAGASSERT(string != NULL); |
|
/* pmatch checked below */ |
|
|
/* simplify the situation where possible */ |
/* simplify the situation where possible */ |
if (g->cflags®_NOSUB) |
if (g->cflags®_NOSUB) |
nmatch = 0; |
nmatch = 0; |
if (eflags®_STARTEND) { |
if (eflags®_STARTEND) { |
|
_DIAGASSERT(pmatch != NULL); |
start = string + (size_t)pmatch[0].rm_so; |
start = string + (size_t)pmatch[0].rm_so; |
stop = string + (size_t)pmatch[0].rm_eo; |
stop = string + (size_t)pmatch[0].rm_eo; |
} else { |
} else { |
|
|
/* prescreening; this does wonders for this rather slow code */ |
/* prescreening; this does wonders for this rather slow code */ |
if (g->must != NULL) { |
if (g->must != NULL) { |
for (dp = start; dp < stop; dp++) |
for (dp = start; dp < stop; dp++) |
if (*dp == g->must[0] && stop - dp >= g->mlen && |
if (*dp == g->must[0] && (size_t)(stop - dp) >= g->mlen && |
memcmp(dp, g->must, (size_t)g->mlen) == 0) |
memcmp(dp, g->must, g->mlen) == 0) |
break; |
break; |
if (dp == stop) /* we didn't find g->must */ |
if (dp == stop) /* we didn't find g->must */ |
return(REG_NOMATCH); |
return(REG_NOMATCH); |
|
|
for (;;) { |
for (;;) { |
endp = fast(m, start, stop, gf, gl); |
endp = fast(m, start, stop, gf, gl); |
if (endp == NULL) { /* a miss */ |
if (endp == NULL) { /* a miss */ |
STATETEARDOWN(m); |
error = REG_NOMATCH; |
return(REG_NOMATCH); |
goto done; |
} |
} |
if (nmatch == 0 && !g->backrefs) |
if (nmatch == 0 && !g->backrefs) |
break; /* no further info needed */ |
break; /* no further info needed */ |
|
|
m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * |
m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * |
sizeof(regmatch_t)); |
sizeof(regmatch_t)); |
if (m->pmatch == NULL) { |
if (m->pmatch == NULL) { |
STATETEARDOWN(m); |
error = REG_ESPACE; |
return(REG_ESPACE); |
goto done; |
} |
} |
for (i = 1; i <= m->g->nsub; i++) |
for (i = 1; i <= m->g->nsub; i++) |
m->pmatch[i].rm_so = m->pmatch[i].rm_eo = (regoff_t)-1; |
m->pmatch[i].rm_so = m->pmatch[i].rm_eo = (regoff_t)-1; |
|
|
dp = dissect(m, m->coldp, endp, gf, gl); |
dp = dissect(m, m->coldp, endp, gf, gl); |
} else { |
} else { |
if (g->nplus > 0 && m->lastpos == NULL) |
if (g->nplus > 0 && m->lastpos == NULL) |
m->lastpos = (char **)malloc((g->nplus+1) * |
m->lastpos = malloc((g->nplus+1) * |
sizeof(char *)); |
sizeof(const char *)); |
if (g->nplus > 0 && m->lastpos == NULL) { |
if (g->nplus > 0 && m->lastpos == NULL) { |
free(m->pmatch); |
error = REG_ESPACE; |
STATETEARDOWN(m); |
goto done; |
return(REG_ESPACE); |
|
} |
} |
NOTE("backref dissect"); |
NOTE("backref dissect"); |
dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); |
dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); |
|
|
|
|
/* fill in the details if requested */ |
/* fill in the details if requested */ |
if (nmatch > 0) { |
if (nmatch > 0) { |
|
_DIAGASSERT(pmatch != NULL); |
pmatch[0].rm_so = m->coldp - m->offp; |
pmatch[0].rm_so = m->coldp - m->offp; |
pmatch[0].rm_eo = endp - m->offp; |
pmatch[0].rm_eo = endp - m->offp; |
} |
} |
|
|
} |
} |
} |
} |
|
|
if (m->pmatch != NULL) |
done: |
|
if (m->pmatch != NULL) { |
free(m->pmatch); |
free(m->pmatch); |
if (m->lastpos != NULL) |
m->pmatch = NULL; |
|
} |
|
if (m->lastpos != NULL) { |
free(m->lastpos); |
free(m->lastpos); |
|
m->lastpos = NULL; |
|
} |
STATETEARDOWN(m); |
STATETEARDOWN(m); |
return(0); |
return error; |
} |
} |
|
|
/* |
/* |
- dissect - figure out what matched what, no back references |
- dissect - figure out what matched what, no back references |
== static char *dissect(struct match *m, char *start, \ |
== static const char *dissect(struct match *m, const char *start, \ |
== char *stop, sopno startst, sopno stopst); |
== const char *stop, sopno startst, sopno stopst); |
*/ |
*/ |
static char * /* == stop (success) always */ |
static const char * /* == stop (success) always */ |
dissect(m, start, stop, startst, stopst) |
dissect( |
struct match *m; |
struct match *m, |
char *start; |
const char *start, |
char *stop; |
const char *stop, |
sopno startst; |
sopno startst, |
sopno stopst; |
sopno stopst) |
{ |
{ |
int i; |
int i; |
sopno ss; /* start sop of current subRE */ |
sopno ss; /* start sop of current subRE */ |
sopno es; /* end sop of current subRE */ |
sopno es; /* end sop of current subRE */ |
char *sp; /* start of string matched by it */ |
const char *sp; /* start of string matched by it */ |
char *stp; /* string matched by it cannot pass here */ |
const char *stp; /* string matched by it cannot pass here */ |
char *rest; /* start of rest of string */ |
const char *rest; /* start of rest of string */ |
char *tail; /* string unmatched by rest of RE */ |
const char *tail; /* string unmatched by rest of RE */ |
sopno ssub; /* start sop of subsubRE */ |
sopno ssub; /* start sop of subsubRE */ |
sopno esub; /* end sop of subsubRE */ |
sopno esub; /* end sop of subsubRE */ |
char *ssp; /* start of string matched by subsubRE */ |
const char *ssp; /* start of string matched by subsubRE */ |
char *sep; /* end of string matched by subsubRE */ |
const char *sep; /* end of string matched by subsubRE */ |
char *oldssp; /* previous ssp */ |
const char *oldssp; /* previous ssp */ |
#ifndef NDEBUG |
#ifndef NDEBUG |
char *dp; |
const char *dp; |
#endif |
#endif |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
AT("diss", start, stop, startst, stopst); |
AT("diss", start, stop, startst, stopst); |
sp = start; |
sp = start; |
for (ss = startst; ss < stopst; ss = es) { |
for (ss = startst; ss < stopst; ss = es) { |
|
|
|
|
/* |
/* |
- backref - figure out what matched what, figuring in back references |
- backref - figure out what matched what, figuring in back references |
== static char *backref(struct match *m, char *start, \ |
== static const char *backref(struct match *m, const char *start, \ |
== char *stop, sopno startst, sopno stopst, sopno lev); |
== const char *stop, sopno startst, sopno stopst, sopno lev); |
*/ |
*/ |
static char * /* == stop (success) or NULL (failure) */ |
static const char * /* == stop (success) or NULL (failure) */ |
backref(m, start, stop, startst, stopst, lev) |
backref( |
struct match *m; |
struct match *m, |
char *start; |
const char *start, |
char *stop; |
const char *stop, |
sopno startst; |
sopno startst, |
sopno stopst; |
sopno stopst, |
sopno lev; /* PLUS nesting level */ |
sopno lev) /* PLUS nesting level */ |
{ |
{ |
int i; |
int i; |
sopno ss; /* start sop of current subRE */ |
sopno ss; /* start sop of current subRE */ |
char *sp; /* start of string matched by it */ |
const char *sp; /* start of string matched by it */ |
sopno ssub; /* start sop of subsubRE */ |
sopno ssub; /* start sop of subsubRE */ |
sopno esub; /* end sop of subsubRE */ |
sopno esub; /* end sop of subsubRE */ |
char *ssp; /* start of string matched by subsubRE */ |
const char *ssp; /* start of string matched by subsubRE */ |
char *dp; |
const char *dp; |
size_t len; |
size_t len; |
int hard; |
int hard; |
sop s; |
sop s; |
regoff_t offsave; |
regoff_t offsave; |
cset *cs; |
cset *cs; |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
AT("back", start, stop, startst, stopst); |
AT("back", start, stop, startst, stopst); |
sp = start; |
sp = start; |
|
|
Line 621 sopno lev; /* PLUS nesting level */ |
|
Line 675 sopno lev; /* PLUS nesting level */ |
|
return(NULL); |
return(NULL); |
assert(m->pmatch[i].rm_so != (regoff_t)-1); |
assert(m->pmatch[i].rm_so != (regoff_t)-1); |
len = (size_t)(m->pmatch[i].rm_eo - m->pmatch[i].rm_so); |
len = (size_t)(m->pmatch[i].rm_eo - m->pmatch[i].rm_so); |
|
if (len == 0) |
|
return(NULL); |
assert(stop - m->beginp >= len); |
assert(stop - m->beginp >= len); |
if (sp > stop - len) |
if (sp > stop - len) |
return(NULL); /* not enough left to match */ |
return(NULL); /* not enough left to match */ |
Line 709 sopno lev; /* PLUS nesting level */ |
|
Line 765 sopno lev; /* PLUS nesting level */ |
|
|
|
/* |
/* |
- fast - step through the string at top speed |
- fast - step through the string at top speed |
== static char *fast(struct match *m, char *start, \ |
== static const char *fast(struct match *m, const char *start, \ |
== char *stop, sopno startst, sopno stopst); |
== const char *stop, sopno startst, sopno stopst); |
*/ |
*/ |
static char * /* where tentative match ended, or NULL */ |
static const char * /* where tentative match ended, or NULL */ |
fast(m, start, stop, startst, stopst) |
fast( |
struct match *m; |
struct match *m, |
char *start; |
const char *start, |
char *stop; |
const char *stop, |
sopno startst; |
sopno startst, |
sopno stopst; |
sopno stopst) |
{ |
{ |
states st = m->st; |
states st = m->st; |
states fresh = m->fresh; |
states fresh = m->fresh; |
states tmp = m->tmp; |
states tmp = m->tmp; |
char *p = start; |
const char *p = start; |
int c = (start == m->beginp) ? OUT : *(start-1); |
int c = (start == m->beginp) ? OUT : *(start-1); |
int lastc; /* previous c */ |
int lastc; /* previous c */ |
int flagch; |
int flagch; |
int i; |
size_t i; |
char *coldp; /* last p after which no match was underway */ |
const char *coldp; /* last p after which no match was underway */ |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
CLEAR(st); |
CLEAR(st); |
SET1(st, startst); |
SET1(st, startst); |
|
|
|
|
/* |
/* |
- slow - step through the string more deliberately |
- slow - step through the string more deliberately |
== static char *slow(struct match *m, char *start, \ |
== static const char *slow(struct match *m, const char *start, \ |
== char *stop, sopno startst, sopno stopst); |
== const char *stop, sopno startst, sopno stopst); |
*/ |
*/ |
static char * /* where it ended */ |
static const char * /* where it ended */ |
slow(m, start, stop, startst, stopst) |
slow( |
struct match *m; |
struct match *m, |
char *start; |
const char *start, |
char *stop; |
const char *stop, |
sopno startst; |
sopno startst, |
sopno stopst; |
sopno stopst) |
{ |
{ |
states st = m->st; |
states st = m->st; |
states empty = m->empty; |
states empty = m->empty; |
states tmp = m->tmp; |
states tmp = m->tmp; |
char *p = start; |
const char *p = start; |
int c = (start == m->beginp) ? OUT : *(start-1); |
int c = (start == m->beginp) ? OUT : *(start-1); |
int lastc; /* previous c */ |
int lastc; /* previous c */ |
int flagch; |
int flagch; |
int i; |
size_t i; |
char *matchp; /* last p at which a match ended */ |
const char *matchp; /* last p at which a match ended */ |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
AT("slow", start, stop, startst, stopst); |
AT("slow", start, stop, startst, stopst); |
CLEAR(st); |
CLEAR(st); |
|
|
== #define NNONCHAR (CODEMAX-CHAR_MAX) |
== #define NNONCHAR (CODEMAX-CHAR_MAX) |
*/ |
*/ |
static states |
static states |
step(g, start, stop, bef, ch, aft) |
step( |
struct re_guts *g; |
struct re_guts *g, |
sopno start; /* start state within strip */ |
sopno start, /* start state within strip */ |
sopno stop; /* state after stop state within strip */ |
sopno stop, /* state after stop state within strip */ |
states bef; /* states reachable before */ |
states bef, /* states reachable before */ |
int ch; /* character or NONCHAR code */ |
int ch, /* character or NONCHAR code */ |
states aft; /* states already known reachable after */ |
states aft) /* states already known reachable after */ |
{ |
{ |
cset *cs; |
cset *cs; |
sop s; |
sop s; |
Line 915 states aft; /* states already known rea |
|
Line 979 states aft; /* states already known rea |
|
sopno look; |
sopno look; |
int i; |
int i; |
|
|
|
_DIAGASSERT(g != NULL); |
|
|
for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { |
for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { |
s = g->strip[pc]; |
s = g->strip[pc]; |
switch (OP(s)) { |
switch (OP(s)) { |
Line 1022 states aft; /* states already known rea |
|
Line 1088 states aft; /* states already known rea |
|
== #endif |
== #endif |
*/ |
*/ |
static void |
static void |
print(m, caption, st, ch, d) |
print( |
struct match *m; |
struct match *m, |
char *caption; |
char *caption, |
states st; |
states st, |
int ch; |
int ch, |
FILE *d; |
FILE *d) |
{ |
{ |
struct re_guts *g = m->g; |
struct re_guts *g = m->g; |
int i; |
int i; |
int first = 1; |
int first = 1; |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(caption != NULL); |
|
|
if (!(m->eflags®_TRACE)) |
if (!(m->eflags®_TRACE)) |
return; |
return; |
|
|
|
_DIAGASSERT(d != NULL); |
|
|
fprintf(d, "%s", caption); |
fprintf(d, "%s", caption); |
if (ch != '\0') |
if (ch != '\0') |
fprintf(d, " %s", pchar(ch)); |
fprintf(d, " %s", pchar(ch)); |
|
|
== #endif |
== #endif |
*/ |
*/ |
static void |
static void |
at(m, title, start, stop, startst, stopst) |
at( |
struct match *m; |
struct match *m, |
char *title; |
char *title, |
char *start; |
char *start, |
char *stop; |
char *stop, |
sopno startst; |
sopno startst, |
sopno stopst; |
sopno stopst) |
{ |
{ |
|
|
|
_DIAGASSERT(m != NULL); |
|
_DIAGASSERT(title != NULL); |
|
_DIAGASSERT(start != NULL); |
|
_DIAGASSERT(stop != NULL); |
|
|
if (!(m->eflags®_TRACE)) |
if (!(m->eflags®_TRACE)) |
return; |
return; |
|
|
|
|
* the non-debug compilation anyway, so it doesn't matter much. |
* the non-debug compilation anyway, so it doesn't matter much. |
*/ |
*/ |
static char * /* -> representation */ |
static char * /* -> representation */ |
pchar(ch) |
pchar( |
int ch; |
int ch) |
{ |
{ |
static char pbuf[10]; |
static char pbuf[10]; |
|
|
|
|
#undef print |
#undef print |
#undef at |
#undef at |
#undef match |
#undef match |
|
#undef nope |