1cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes/* $NetBSD: engine.c,v 1.24 2012/03/13 21:13:42 christos Exp $ */ 24fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 34fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/*- 44fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * Copyright (c) 1992, 1993, 1994 54fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * The Regents of the University of California. All rights reserved. 64fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 74fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * This code is derived from software contributed to Berkeley by 84fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * Henry Spencer. 94fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * Redistribution and use in source and binary forms, with or without 114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * modification, are permitted provided that the following conditions 124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * are met: 134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 1. Redistributions of source code must retain the above copyright 144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * notice, this list of conditions and the following disclaimer. 154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 2. Redistributions in binary form must reproduce the above copyright 164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * notice, this list of conditions and the following disclaimer in the 174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * documentation and/or other materials provided with the distribution. 184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 3. Neither the name of the University nor the names of its contributors 194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * may be used to endorse or promote products derived from this software 204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * without specific prior written permission. 214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * SUCH DAMAGE. 334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * @(#)engine.c 8.5 (Berkeley) 3/20/94 354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 37cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes/*- 38cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * Copyright (c) 1992, 1993, 1994 Henry Spencer. 39cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 40cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * This code is derived from software contributed to Berkeley by 41cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * Henry Spencer. 42cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 43cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * Redistribution and use in source and binary forms, with or without 44cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * modification, are permitted provided that the following conditions 45cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * are met: 46cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 1. Redistributions of source code must retain the above copyright 47cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * notice, this list of conditions and the following disclaimer. 48cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright 49cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * notice, this list of conditions and the following disclaimer in the 50cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * documentation and/or other materials provided with the distribution. 51cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 3. All advertising materials mentioning features or use of this software 52cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * must display the following acknowledgement: 53cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * This product includes software developed by the University of 54cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * California, Berkeley and its contributors. 55cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 4. Neither the name of the University nor the names of its contributors 56cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * may be used to endorse or promote products derived from this software 57cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * without specific prior written permission. 58cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 59cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * SUCH DAMAGE. 70cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * 71cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes * @(#)engine.c 8.5 (Berkeley) 3/20/94 72cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes */ 73cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 754fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * The matching engine and friends. This file is #included by regexec.c 764fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * after suitable #defines of a variety of macros used herein, so that 774fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * different state representations can be used without duplicating masses 784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * of code. 794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifdef SNAMES 824fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define matcher smatcher 834fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define fast sfast 844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define slow sslow 854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define dissect sdissect 864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define backref sbackref 874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define step sstep 884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define print sprint 894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define at sat 904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define match smat 914fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define nope snope 924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifdef LNAMES 944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define matcher lmatcher 954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define fast lfast 964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define slow lslow 974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define dissect ldissect 984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define backref lbackref 994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define step lstep 1004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define print lprint 1014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define at lat 1024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define match lmat 1034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define nope lnope 1044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 1054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 1064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* another structure passed up and down to avoid zillions of parameters */ 1074fa7b105644222d9b35347c9d226ca8e011072ebColin Crossstruct match { 1084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross struct re_guts *g; 1094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int eflags; 1104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ 111cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *offp; /* offsets work from here */ 112cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *beginp; /* start of string -- virtual NUL precedes */ 113cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *endp; /* end of string -- virtual NUL here */ 114cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *coldp; /* can be no match starting before here */ 115cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char **lastpos; /* [nplus+1] */ 1164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross STATEVARS; 1174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states st; /* current states */ 1184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states fresh; /* states for a fresh start */ 1194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states tmp; /* temporary */ 1204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states empty; /* empty set of states */ 1214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross}; 1224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 123cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes/* ========= begin header generated by ./mkh ========= */ 124cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#ifdef __cplusplus 125cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesextern "C" { 126cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#endif 127cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 128cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes/* === engine.c === */ 129cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic int matcher(struct re_guts *g, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); 130cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char *dissect(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); 131cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char *backref(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst, sopno lev); 132cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char *fast(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); 133cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char *slow(struct match *m, const char *start, const char *stop, sopno startst, sopno stopst); 134cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic states step(struct re_guts *g, sopno start, sopno stop, states bef, int ch, states aft); 1354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define BOL (OUT+1) 1364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define EOL (BOL+1) 1374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define BOLEOL (BOL+2) 1384fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define NOTHING (BOL+3) 1394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define BOW (BOL+4) 1404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define EOW (BOL+5) 1414fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define CODEMAX (BOL+5) /* highest code used */ 1424fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define NONCHAR(c) ((c) > CHAR_MAX) 1434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define NNONCHAR (CODEMAX-CHAR_MAX) 1444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifdef REDEBUG 145cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic void print(struct match *m, char *caption, states st, int ch, FILE *d); 1464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 1474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifdef REDEBUG 148cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic void at(struct match *m, char *title, char *start, char *stop, sopno startst, sopno stopst); 1494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 1504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifdef REDEBUG 151cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic char *pchar(int ch); 152cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#endif 153cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 154cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#ifdef __cplusplus 155cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes} 1564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 157cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes/* ========= end header generated by ./mkh ========= */ 1584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 1594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifdef REDEBUG 1604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define SP(t, s, c) print(m, t, s, c, stdout) 1614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) 162cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } 1634fa7b105644222d9b35347c9d226ca8e011072ebColin Crossstatic int nope = 0; 1644fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#else 1654fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define SP(t, s, c) /* nothing */ 1664fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define AT(t, p1, p2, s1, s2) /* nothing */ 1674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define NOTE(s) /* nothing */ 1684fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 1694fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 1704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 1714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - matcher - the actual matching engine 172cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static int matcher(struct re_guts *g, char *string, \ 173cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == size_t nmatch, regmatch_t pmatch[], int eflags); 1744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 1754fa7b105644222d9b35347c9d226ca8e011072ebColin Crossstatic int /* 0 success, REG_NOMATCH failure */ 176cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesmatcher( 177cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct re_guts *g, 178cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *string, 179cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes size_t nmatch, 180cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes regmatch_t pmatch[], 1814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int eflags) 1824fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 183cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *endp; 184cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes size_t i; 1854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross struct match mv; 1864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross struct match *m = &mv; 187cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *dp; 1884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross const sopno gf = g->firststate+1; /* +1 for OEND */ 1894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross const sopno gl = g->laststate; 190cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *start; 191cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *stop; 192cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes int error = 0; 193cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 194cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(g != NULL); 195cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(string != NULL); 196cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes /* pmatch checked below */ 1974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 1984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* simplify the situation where possible */ 1994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (g->cflags®_NOSUB) 2004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross nmatch = 0; 2014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (eflags®_STARTEND) { 202cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(pmatch != NULL); 203cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes start = string + (size_t)pmatch[0].rm_so; 204cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes stop = string + (size_t)pmatch[0].rm_eo; 2054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } else { 2064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross start = string; 2074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross stop = start + strlen(start); 2084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 2094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (stop < start) 2104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(REG_INVARG); 2114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 2124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* prescreening; this does wonders for this rather slow code */ 2134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (g->must != NULL) { 2144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (dp = start; dp < stop; dp++) 215cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes if (*dp == g->must[0] && (size_t)(stop - dp) >= g->mlen && 216cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes memcmp(dp, g->must, g->mlen) == 0) 2174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 2184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp == stop) /* we didn't find g->must */ 2194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(REG_NOMATCH); 2204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 2214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 2224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* match struct setup */ 2234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->g = g; 2244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->eflags = eflags; 2254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch = NULL; 2264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->lastpos = NULL; 2274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->offp = string; 2284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->beginp = start; 2294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->endp = stop; 2304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross STATESETUP(m, 4); 2314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SETUP(m->st); 2324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SETUP(m->fresh); 2334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SETUP(m->tmp); 2344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SETUP(m->empty); 2354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross CLEAR(m->empty); 2364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 2374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* this loop does only one repetition except for backrefs */ 2384fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 2394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross endp = fast(m, start, stop, gf, gl); 2404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (endp == NULL) { /* a miss */ 241cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes error = REG_NOMATCH; 242cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes goto done; 2434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 2444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (nmatch == 0 && !g->backrefs) 2454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* no further info needed */ 2464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 2474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* where? */ 2484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(m->coldp != NULL); 2494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 2504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross NOTE("finding start"); 2514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross endp = slow(m, m->coldp, stop, gf, gl); 2524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (endp != NULL) 2534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 2544fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(m->coldp < m->endp); 2554fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->coldp++; 2564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 2574fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (nmatch == 1 && !g->backrefs) 2584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* no further info needed */ 2594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 2604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* oh my, he wants the subexpressions... */ 2614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (m->pmatch == NULL) 2624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) * 2634fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sizeof(regmatch_t)); 2644fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (m->pmatch == NULL) { 265cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes error = REG_ESPACE; 266cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes goto done; 2674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 268cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes for (i = 1; i <= m->g->nsub; i++) 269cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes m->pmatch[i].rm_so = m->pmatch[i].rm_eo = (regoff_t)-1; 2704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (!g->backrefs && !(m->eflags®_BACKR)) { 2714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross NOTE("dissecting"); 2724fa7b105644222d9b35347c9d226ca8e011072ebColin Cross dp = dissect(m, m->coldp, endp, gf, gl); 2734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } else { 2744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (g->nplus > 0 && m->lastpos == NULL) 275cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes m->lastpos = malloc((g->nplus+1) * 276cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sizeof(const char *)); 2774fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (g->nplus > 0 && m->lastpos == NULL) { 278cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes error = REG_ESPACE; 279cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes goto done; 2804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 2814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross NOTE("backref dissect"); 282cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); 2834fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 2844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp != NULL) 2854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 2864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 2874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* uh-oh... we couldn't find a subexpression-level match */ 2884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(g->backrefs); /* must be back references doing it */ 2894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(g->nplus == 0 || m->lastpos != NULL); 2904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 2914fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp != NULL || endp <= m->coldp) 2924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* defeat */ 2934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross NOTE("backoff"); 2944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross endp = slow(m, m->coldp, endp-1, gf, gl); 2954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (endp == NULL) 2964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* defeat */ 2974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* try it on a shorter possibility */ 2984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifndef NDEBUG 2994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (i = 1; i <= m->g->nsub; i++) { 300cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes assert(m->pmatch[i].rm_so == (regoff_t)-1); 301cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes assert(m->pmatch[i].rm_eo == (regoff_t)-1); 3024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 3034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 3044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross NOTE("backoff dissect"); 305cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, m->coldp, endp, gf, gl, (sopno)0); 3064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 3074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(dp == NULL || dp == endp); 3084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp != NULL) /* found a shorter one */ 3094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 3104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 3114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* despite initial appearances, there is no match here */ 3124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross NOTE("false alarm"); 3134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross start = m->coldp + 1; /* recycle starting later */ 314cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes assert(start <= stop); 3154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 3164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 3174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* fill in the details if requested */ 3184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (nmatch > 0) { 319cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(pmatch != NULL); 3204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross pmatch[0].rm_so = m->coldp - m->offp; 3214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross pmatch[0].rm_eo = endp - m->offp; 3224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 3234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (nmatch > 1) { 3244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(m->pmatch != NULL); 325cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes for (i = 1; i < nmatch; i++) 326cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes if (i <= m->g->nsub) 3274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross pmatch[i] = m->pmatch[i]; 3284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else { 329cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes pmatch[i].rm_so = (regoff_t)-1; 330cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes pmatch[i].rm_eo = (regoff_t)-1; 3314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 3324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 3334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 334cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesdone: 335cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes if (m->pmatch != NULL) { 336cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes free(m->pmatch); 337cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes m->pmatch = NULL; 338cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes } 339cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes if (m->lastpos != NULL) { 340cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes free(m->lastpos); 341cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes m->lastpos = NULL; 342cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes } 3434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross STATETEARDOWN(m); 344cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes return error; 3454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 3464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 3474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 3484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - dissect - figure out what matched what, no back references 349cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static const char *dissect(struct match *m, const char *start, \ 350cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == const char *stop, sopno startst, sopno stopst); 3514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 352cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char * /* == stop (success) always */ 353cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesdissect( 354cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct match *m, 355cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *start, 356cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *stop, 357cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno startst, 358cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno stopst) 3594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 3604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int i; 3614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno ss; /* start sop of current subRE */ 3624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno es; /* end sop of current subRE */ 363cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *sp; /* start of string matched by it */ 364cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *stp; /* string matched by it cannot pass here */ 365cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *rest; /* start of rest of string */ 366cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *tail; /* string unmatched by rest of RE */ 3674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno ssub; /* start sop of subsubRE */ 3684fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno esub; /* end sop of subsubRE */ 369cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *ssp; /* start of string matched by subsubRE */ 370cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *sep; /* end of string matched by subsubRE */ 371cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *oldssp; /* previous ssp */ 372cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#ifndef NDEBUG 373cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *dp; 374cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#endif 375cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 376cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(m != NULL); 377cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(start != NULL); 378cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(stop != NULL); 3794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 3804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross AT("diss", start, stop, startst, stopst); 3814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp = start; 3824fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (ss = startst; ss < stopst; ss = es) { 3834fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* identify end of subRE */ 3844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross es = ss; 3854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross switch (OP(m->g->strip[es])) { 3864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OPLUS_: 3874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OQUEST_: 3884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross es += OPND(m->g->strip[es]); 3894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 3904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OCH_: 3914fa7b105644222d9b35347c9d226ca8e011072ebColin Cross while (OP(m->g->strip[es]) != O_CH) 3924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross es += OPND(m->g->strip[es]); 3934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 3944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 3954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross es++; 3964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 3974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* figure out what it matched */ 3984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross switch (OP(m->g->strip[ss])) { 3994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEND: 4004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(nope); 4014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 4024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OCHAR: 4034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp++; 4044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 4054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBOL: 4064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEOL: 4074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBOW: 4084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEOW: 4094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 4104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OANY: 4114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OANYOF: 4124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp++; 4134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 4144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBACK_: 4154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_BACK: 4164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(nope); 4174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 4184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* cases where length of match is hard to find */ 4194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OQUEST_: 4204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross stp = stop; 4214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 4224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* how long could this one be? */ 4234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross rest = slow(m, sp, stp, ss, es); 4244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(rest != NULL); /* it did match */ 4254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* could the rest match the rest? */ 4264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross tail = slow(m, rest, stop, es, stopst); 4274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (tail == stop) 4284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* yes! */ 4294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* no -- try a shorter match for this one */ 4304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross stp = rest - 1; 4314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(stp >= sp); /* it did work */ 4324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 4334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssub = ss + 1; 4344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub = es - 1; 4354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* did innards match? */ 4364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (slow(m, sp, rest, ssub, esub) != NULL) { 437cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#ifdef NDEBUG 438cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes (void) 439cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#else 440cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = 441cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#endif 442cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dissect(m, sp, rest, ssub, esub); 4434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(dp == rest); 4444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } else /* no */ 4454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(sp == rest); 4464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp = rest; 4474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 4484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OPLUS_: 4494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross stp = stop; 4504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 4514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* how long could this one be? */ 4524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross rest = slow(m, sp, stp, ss, es); 4534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(rest != NULL); /* it did match */ 4544fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* could the rest match the rest? */ 4554fa7b105644222d9b35347c9d226ca8e011072ebColin Cross tail = slow(m, rest, stop, es, stopst); 4564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (tail == stop) 4574fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* yes! */ 4584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* no -- try a shorter match for this one */ 4594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross stp = rest - 1; 4604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(stp >= sp); /* it did work */ 4614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 4624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssub = ss + 1; 4634fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub = es - 1; 4644fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssp = sp; 4654fa7b105644222d9b35347c9d226ca8e011072ebColin Cross oldssp = ssp; 4664fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { /* find last match of innards */ 4674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sep = slow(m, ssp, rest, ssub, esub); 4684fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sep == NULL || sep == ssp) 4694fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* failed or matched null */ 4704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross oldssp = ssp; /* on to next try */ 4714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssp = sep; 4724fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 4734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sep == NULL) { 4744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* last successful match */ 4754fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sep = ssp; 4764fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssp = oldssp; 4774fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 4784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(sep == rest); /* must exhaust substring */ 4794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(slow(m, ssp, sep, ssub, esub) == rest); 480cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#ifdef NDEBUG 481cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes (void) 482cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#else 483cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = 484cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#endif 485cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dissect(m, ssp, sep, ssub, esub); 4864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(dp == sep); 4874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp = rest; 4884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 4894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OCH_: 4904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross stp = stop; 4914fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 4924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* how long could this one be? */ 4934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross rest = slow(m, sp, stp, ss, es); 4944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(rest != NULL); /* it did match */ 4954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* could the rest match the rest? */ 4964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross tail = slow(m, rest, stop, es, stopst); 4974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (tail == stop) 4984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* yes! */ 4994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* no -- try a shorter match for this one */ 5004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross stp = rest - 1; 5014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(stp >= sp); /* it did work */ 5024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 5034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssub = ss + 1; 5044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub = ss + OPND(m->g->strip[ss]) - 1; 5054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(m->g->strip[esub]) == OOR1); 5064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { /* find first matching branch */ 5074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (slow(m, sp, rest, ssub, esub) == rest) 5084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* it matched all of it */ 5094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* that one missed, try next one */ 5104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(m->g->strip[esub]) == OOR1); 5114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub++; 5124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(m->g->strip[esub]) == OOR2); 5134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssub = esub + 1; 5144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub += OPND(m->g->strip[esub]); 5154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (OP(m->g->strip[esub]) == OOR2) 5164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub--; 5174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 5184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(m->g->strip[esub]) == O_CH); 5194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 520cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#ifdef NDEBUG 521cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes (void) 522cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#else 523cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = 524cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes#endif 525cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dissect(m, sp, rest, ssub, esub); 5264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(dp == rest); 5274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp = rest; 5284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 5294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_PLUS: 5304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_QUEST: 5314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OOR1: 5324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OOR2: 5334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_CH: 5344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(nope); 5354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 5364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OLPAREN: 5374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = OPND(m->g->strip[ss]); 5384fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(0 < i && i <= m->g->nsub); 5394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch[i].rm_so = sp - m->offp; 5404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 5414fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case ORPAREN: 5424fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = OPND(m->g->strip[ss]); 5434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(0 < i && i <= m->g->nsub); 5444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch[i].rm_eo = sp - m->offp; 5454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 5464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross default: /* uh oh */ 5474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(nope); 5484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 5494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 5504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 5514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 5524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(sp == stop); 5534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(sp); 5544fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 5554fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 5564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 5574fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - backref - figure out what matched what, figuring in back references 558cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static const char *backref(struct match *m, const char *start, \ 559cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == const char *stop, sopno startst, sopno stopst, sopno lev); 5604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 561cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char * /* == stop (success) or NULL (failure) */ 562cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesbackref( 563cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct match *m, 564cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *start, 565cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *stop, 566cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno startst, 567cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno stopst, 568cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno lev) /* PLUS nesting level */ 5694fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 5704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int i; 5714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno ss; /* start sop of current subRE */ 572cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *sp; /* start of string matched by it */ 5734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno ssub; /* start sop of subsubRE */ 5744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno esub; /* end sop of subsubRE */ 575cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *ssp; /* start of string matched by subsubRE */ 576cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *dp; 5774fa7b105644222d9b35347c9d226ca8e011072ebColin Cross size_t len; 5784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int hard; 5794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sop s; 5804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross regoff_t offsave; 5814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross cset *cs; 5824fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 583cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(m != NULL); 584cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(start != NULL); 585cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(stop != NULL); 586cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 5874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross AT("back", start, stop, startst, stopst); 5884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp = start; 5894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 5904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* get as far as we can with easy stuff */ 5914fa7b105644222d9b35347c9d226ca8e011072ebColin Cross hard = 0; 5924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (ss = startst; !hard && ss < stopst; ss++) 5934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross switch (OP(s = m->g->strip[ss])) { 5944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OCHAR: 5954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sp == stop || *sp++ != (char)OPND(s)) 5964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 5974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 5984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OANY: 5994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sp == stop) 6004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sp++; 6024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OANYOF: 6044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross cs = &m->g->sets[OPND(s)]; 6054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sp == stop || !CHIN(cs, *sp++)) 6064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBOL: 6094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) || 6104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp < m->endp && *(sp-1) == '\n' && 6114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (m->g->cflags®_NEWLINE)) ) 6124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross { /* yes */ } 6134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 6144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEOL: 6174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (sp == m->endp && !(m->eflags®_NOTEOL)) || 6184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp < m->endp && *sp == '\n' && 6194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (m->g->cflags®_NEWLINE)) ) 6204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross { /* yes */ } 6214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 6224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBOW: 6254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) || 6264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp < m->endp && *(sp-1) == '\n' && 6274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (m->g->cflags®_NEWLINE)) || 6284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp > m->beginp && 6294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross !ISWORD(*(sp-1))) ) && 6304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp < m->endp && ISWORD(*sp)) ) 6314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross { /* yes */ } 6324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 6334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEOW: 6364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (( (sp == m->endp && !(m->eflags®_NOTEOL)) || 6374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp < m->endp && *sp == '\n' && 6384fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (m->g->cflags®_NEWLINE)) || 6394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp < m->endp && !ISWORD(*sp)) ) && 6404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (sp > m->beginp && ISWORD(*(sp-1))) ) 6414fa7b105644222d9b35347c9d226ca8e011072ebColin Cross { /* yes */ } 6424fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 6434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_QUEST: 6464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OOR1: /* matches null but needs to skip */ 6484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ss++; 6494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross s = m->g->strip[ss]; 6504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross do { 6514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(s) == OOR2); 6524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ss += OPND(s); 6534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } while (OP(s = m->g->strip[ss]) != O_CH); 6544fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* note that the ss++ gets us past the O_CH */ 6554fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross default: /* have to make a choice */ 6574fa7b105644222d9b35347c9d226ca8e011072ebColin Cross hard = 1; 6584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 6594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 6604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (!hard) { /* that was it! */ 6614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sp != stop) 6624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6634fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(sp); 6644fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 6654fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ss--; /* adjust for the for's final increment */ 6664fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 6674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* the hard stuff */ 6684fa7b105644222d9b35347c9d226ca8e011072ebColin Cross AT("hard", sp, stop, ss, stopst); 6694fa7b105644222d9b35347c9d226ca8e011072ebColin Cross s = m->g->strip[ss]; 6704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross switch (OP(s)) { 6714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBACK_: /* the vilest depths */ 6724fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = OPND(s); 6734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(0 < i && i <= m->g->nsub); 674cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes if (m->pmatch[i].rm_eo == (regoff_t)-1) 6754fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 676cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes assert(m->pmatch[i].rm_so != (regoff_t)-1); 677cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes len = (size_t)(m->pmatch[i].rm_eo - m->pmatch[i].rm_so); 678cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes if (len == 0) 6794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(stop - m->beginp >= len); 6814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sp > stop - len) 6824fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); /* not enough left to match */ 683cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes ssp = m->offp + (size_t)m->pmatch[i].rm_so; 6844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (memcmp(sp, ssp, len) != 0) 6854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 6864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross while (m->g->strip[ss] != SOP(O_BACK, i)) 6874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ss++; 688cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes return(backref(m, sp+len, stop, ss+1, stopst, lev)); 689cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 6904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OQUEST_: /* to null or not */ 691cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, sp, stop, ss+1, stopst, lev); 6924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp != NULL) 6934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(dp); /* not */ 694cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev)); 695cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 6964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OPLUS_: 6974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(m->lastpos != NULL); 6984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(lev+1 <= m->g->nplus); 6994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->lastpos[lev+1] = sp; 700cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes return(backref(m, sp, stop, ss+1, stopst, lev+1)); 701cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 7024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_PLUS: 7034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (sp == m->lastpos[lev]) /* last pass matched null */ 704cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes return(backref(m, sp, stop, ss+1, stopst, lev-1)); 7054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* try another pass */ 7064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->lastpos[lev] = sp; 707cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev); 7084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp == NULL) 709cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, sp, stop, ss+1, stopst, lev-1); 710cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes return(dp); 711cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 7124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OCH_: /* find the right one, if any */ 7134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssub = ss + 1; 7144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub = ss + OPND(s) - 1; 7154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(m->g->strip[esub]) == OOR1); 7164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { /* find first matching branch */ 717cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, sp, stop, ssub, esub, lev); 7184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp != NULL) 7194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(dp); 7204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* that one missed, try next one */ 7214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (OP(m->g->strip[esub]) == O_CH) 7224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); /* there is none */ 7234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub++; 7244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(m->g->strip[esub]) == OOR2); 7254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ssub = esub + 1; 7264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub += OPND(m->g->strip[esub]); 7274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (OP(m->g->strip[esub]) == OOR2) 7284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross esub--; 7294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 7304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(m->g->strip[esub]) == O_CH); 7314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 732cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 7334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OLPAREN: /* must undo assignment if rest fails */ 7344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = OPND(s); 7354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(0 < i && i <= m->g->nsub); 7364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross offsave = m->pmatch[i].rm_so; 7374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch[i].rm_so = sp - m->offp; 738cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, sp, stop, ss+1, stopst, lev); 7394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp != NULL) 7404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(dp); 7414fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch[i].rm_so = offsave; 7424fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 743cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 7444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case ORPAREN: /* must undo assignment if rest fails */ 7454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = OPND(s); 7464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(0 < i && i <= m->g->nsub); 7474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross offsave = m->pmatch[i].rm_eo; 7484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch[i].rm_eo = sp - m->offp; 749cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes dp = backref(m, sp, stop, ss+1, stopst, lev); 7504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (dp != NULL) 7514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(dp); 7524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->pmatch[i].rm_eo = offsave; 7534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 754cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 7554fa7b105644222d9b35347c9d226ca8e011072ebColin Cross default: /* uh oh */ 7564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(nope); 7574fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 7584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 7594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 7604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* "can't happen" */ 7614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(nope); 7624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* NOTREACHED */ 763cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes return NULL; 7644fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 7654fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 7664fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 7674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - fast - step through the string at top speed 768cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static const char *fast(struct match *m, const char *start, \ 769cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == const char *stop, sopno startst, sopno stopst); 7704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 771cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char * /* where tentative match ended, or NULL */ 772cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesfast( 773cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct match *m, 774cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *start, 775cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *stop, 776cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno startst, 777cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno stopst) 7784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 7794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states st = m->st; 7804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states fresh = m->fresh; 7814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states tmp = m->tmp; 782cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *p = start; 7834fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int c = (start == m->beginp) ? OUT : *(start-1); 7844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int lastc; /* previous c */ 7854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int flagch; 786cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes size_t i; 787cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *coldp; /* last p after which no match was underway */ 788cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 789cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(m != NULL); 790cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(start != NULL); 791cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(stop != NULL); 7924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 7934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross CLEAR(st); 7944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SET1(st, startst); 7954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, st, NOTHING, st); 7964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ASSIGN(fresh, st); 7974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("start", st, *p); 7984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross coldp = NULL; 7994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 8004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* next character */ 8014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross lastc = c; 8024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross c = (p == m->endp) ? OUT : *p; 8034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (EQ(st, fresh)) 8044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross coldp = p; 8054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* is there an EOL and/or BOL between lastc and c? */ 8074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = '\0'; 8084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = 0; 8094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || 8104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (lastc == OUT && !(m->eflags®_NOTBOL)) ) { 8114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = BOL; 8124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = m->g->nbol; 8134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 8144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (c == '\n' && m->g->cflags®_NEWLINE) || 8154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (c == OUT && !(m->eflags®_NOTEOL)) ) { 8164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = (flagch == BOL) ? BOLEOL : EOL; 8174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i += m->g->neol; 8184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 8194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (i != 0) { 8204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (; i > 0; i--) 8214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, st, flagch, st); 8224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("boleol", st, c); 8234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 8244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* how about a word boundary? */ 8264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && 8274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (c != OUT && ISWORD(c)) ) { 8284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = BOW; 8294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 8304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (lastc != OUT && ISWORD(lastc)) && 8314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (flagch == EOL || (c != OUT && !ISWORD(c))) ) { 8324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = EOW; 8334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 8344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (flagch == BOW || flagch == EOW) { 8354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, st, flagch, st); 8364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("boweow", st, c); 8374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 8384fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* are we done? */ 8404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ISSET(st, stopst) || p == stop) 8414fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* NOTE BREAK OUT */ 8424fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* no, we must deal with this character */ 8444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ASSIGN(tmp, st); 8454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ASSIGN(st, fresh); 8464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(c != OUT); 8474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, tmp, c, st); 8484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("aft", st, c); 8494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); 8504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross p++; 8514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 8524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(coldp != NULL); 8544fa7b105644222d9b35347c9d226ca8e011072ebColin Cross m->coldp = coldp; 8554fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ISSET(st, stopst)) 8564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(p+1); 8574fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 8584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(NULL); 8594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 8604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 8624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - slow - step through the string more deliberately 863cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static const char *slow(struct match *m, const char *start, \ 864cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == const char *stop, sopno startst, sopno stopst); 8654fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 866cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstatic const char * /* where it ended */ 867cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesslow( 868cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct match *m, 869cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *start, 870cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *stop, 871cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno startst, 872cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno stopst) 8734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 8744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states st = m->st; 8754fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states empty = m->empty; 8764fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states tmp = m->tmp; 877cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *p = start; 8784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int c = (start == m->beginp) ? OUT : *(start-1); 8794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int lastc; /* previous c */ 8804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int flagch; 881cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes size_t i; 882cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes const char *matchp; /* last p at which a match ended */ 883cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 884cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(m != NULL); 885cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(start != NULL); 886cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(stop != NULL); 8874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross AT("slow", start, stop, startst, stopst); 8894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross CLEAR(st); 8904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SET1(st, startst); 8914fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("sstart", st, *p); 8924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, st, NOTHING, st); 8934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross matchp = NULL; 8944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (;;) { 8954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* next character */ 8964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross lastc = c; 8974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross c = (p == m->endp) ? OUT : *p; 8984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 8994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* is there an EOL and/or BOL between lastc and c? */ 9004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = '\0'; 9014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = 0; 9024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || 9034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (lastc == OUT && !(m->eflags®_NOTBOL)) ) { 9044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = BOL; 9054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = m->g->nbol; 9064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 9074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (c == '\n' && m->g->cflags®_NEWLINE) || 9084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (c == OUT && !(m->eflags®_NOTEOL)) ) { 9094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = (flagch == BOL) ? BOLEOL : EOL; 9104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i += m->g->neol; 9114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 9124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (i != 0) { 9134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (; i > 0; i--) 9144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, st, flagch, st); 9154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("sboleol", st, c); 9164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 9174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 9184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* how about a word boundary? */ 9194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && 9204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (c != OUT && ISWORD(c)) ) { 9214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = BOW; 9224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 9234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if ( (lastc != OUT && ISWORD(lastc)) && 9244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (flagch == EOL || (c != OUT && !ISWORD(c))) ) { 9254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross flagch = EOW; 9264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 9274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (flagch == BOW || flagch == EOW) { 9284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, st, flagch, st); 9294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("sboweow", st, c); 9304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 9314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 9324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* are we done? */ 9334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ISSET(st, stopst)) 9344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross matchp = p; 9354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (EQ(st, empty) || p == stop) 9364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; /* NOTE BREAK OUT */ 9374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 9384fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* no, we must deal with this character */ 9394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ASSIGN(tmp, st); 9404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross ASSIGN(st, empty); 9414fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(c != OUT); 9424fa7b105644222d9b35347c9d226ca8e011072ebColin Cross st = step(m->g, startst, stopst, tmp, c, st); 9434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross SP("saft", st, c); 9444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); 9454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross p++; 9464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 9474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 9484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(matchp); 9494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 9504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 9514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 9524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 9534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - step - map set of states reachable before char to set reachable after 954cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static states step(struct re_guts *g, sopno start, sopno stop, \ 955cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == states bef, int ch, states aft); 956cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define BOL (OUT+1) 957cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define EOL (BOL+1) 958cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define BOLEOL (BOL+2) 959cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define NOTHING (BOL+3) 960cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define BOW (BOL+4) 961cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define EOW (BOL+5) 962cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define CODEMAX (BOL+5) // highest code used 963cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define NONCHAR(c) ((c) > CHAR_MAX) 964cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #define NNONCHAR (CODEMAX-CHAR_MAX) 9654fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 9664fa7b105644222d9b35347c9d226ca8e011072ebColin Crossstatic states 967cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesstep( 968cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct re_guts *g, 9694fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno start, /* start state within strip */ 9704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno stop, /* state after stop state within strip */ 9714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states bef, /* states reachable before */ 9724fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int ch, /* character or NONCHAR code */ 9734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross states aft) /* states already known reachable after */ 9744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 9754fa7b105644222d9b35347c9d226ca8e011072ebColin Cross cset *cs; 9764fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sop s; 9774fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno pc; 9784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross onestate here; /* note, macros know this name */ 9794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno look; 9804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int i; 9814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 982cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(g != NULL); 983cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 9844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { 9854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross s = g->strip[pc]; 9864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross switch (OP(s)) { 9874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEND: 9884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(pc == stop-1); 9894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 9904fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OCHAR: 9914fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* only characters can match */ 9924fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(!NONCHAR(ch) || ch != (char)OPND(s)); 9934fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ch == (char)OPND(s)) 9944fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, bef, 1); 9954fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 9964fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBOL: 9974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ch == BOL || ch == BOLEOL) 9984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, bef, 1); 9994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEOL: 10014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ch == EOL || ch == BOLEOL) 10024fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, bef, 1); 10034fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10044fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBOW: 10054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ch == BOW) 10064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, bef, 1); 10074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10084fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OEOW: 10094fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ch == EOW) 10104fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, bef, 1); 10114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10124fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OANY: 10134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (!NONCHAR(ch)) 10144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, bef, 1); 10154fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OANYOF: 10174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross cs = &g->sets[OPND(s)]; 10184fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (!NONCHAR(ch) && CHIN(cs, ch)) 10194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, bef, 1); 10204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OBACK_: /* ignored here */ 10224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_BACK: 10234fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10244fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10254fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OPLUS_: /* forward, this is just an empty */ 10264fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10284fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_PLUS: /* both forward and back */ 10294fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10304fa7b105644222d9b35347c9d226ca8e011072ebColin Cross i = ISSETBACK(aft, OPND(s)); 10314fa7b105644222d9b35347c9d226ca8e011072ebColin Cross BACK(aft, aft, OPND(s)); 10324fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (!i && ISSETBACK(aft, OPND(s))) { 10334fa7b105644222d9b35347c9d226ca8e011072ebColin Cross /* oho, must reconsider loop body */ 10344fa7b105644222d9b35347c9d226ca8e011072ebColin Cross pc -= OPND(s) + 1; 10354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross INIT(here, pc); 10364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 10374fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10384fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OQUEST_: /* two branches, both forward */ 10394fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10404fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, OPND(s)); 10414fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10424fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_QUEST: /* just an empty */ 10434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OLPAREN: /* not significant here */ 10464fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case ORPAREN: 10474fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10484fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OCH_: /* mark the first two branches */ 10504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(g->strip[pc+OPND(s)]) == OOR2); 10524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, OPND(s)); 10534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10544fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OOR1: /* done a branch, find the O_CH */ 10554fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ISSTATEIN(aft, here)) { 10564fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (look = 1; 10574fa7b105644222d9b35347c9d226ca8e011072ebColin Cross OP(s = g->strip[pc+look]) != O_CH; 10584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross look += OPND(s)) 10594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(s) == OOR2); 10604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, look); 10614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 10624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10634fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case OOR2: /* propagate OCH_'s marking */ 10644fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10654fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (OP(g->strip[pc+OPND(s)]) != O_CH) { 10664fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(OP(g->strip[pc+OPND(s)]) == OOR2); 10674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, OPND(s)); 10684fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 10694fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross case O_CH: /* just empty */ 10714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross FWD(aft, aft, 1); 10724fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross default: /* ooooops... */ 10744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross assert(nope); 10754fa7b105644222d9b35347c9d226ca8e011072ebColin Cross break; 10764fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 10774fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 10784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 10794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(aft); 10804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 10814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 10824fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifdef REDEBUG 10834fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 10844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - print - print a set of states 1085cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #ifdef REDEBUG 1086cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static void print(struct match *m, char *caption, states st, \ 1087cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == int ch, FILE *d); 1088cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #endif 10894fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 10904fa7b105644222d9b35347c9d226ca8e011072ebColin Crossstatic void 1091cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesprint( 1092cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct match *m, 1093cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes char *caption, 1094cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes states st, 1095cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes int ch, 1096cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes FILE *d) 10974fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 10984fa7b105644222d9b35347c9d226ca8e011072ebColin Cross struct re_guts *g = m->g; 10994fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int i; 11004fa7b105644222d9b35347c9d226ca8e011072ebColin Cross int first = 1; 11014fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 1102cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(m != NULL); 1103cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(caption != NULL); 1104cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 11054fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (!(m->eflags®_TRACE)) 11064fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return; 11074fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 1108cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(d != NULL); 1109cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 1110cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes fprintf(d, "%s", caption); 11114fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ch != '\0') 1112cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes fprintf(d, " %s", pchar(ch)); 11134fa7b105644222d9b35347c9d226ca8e011072ebColin Cross for (i = 0; i < g->nstates; i++) 11144fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (ISSET(st, i)) { 1115cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes fprintf(d, "%s%d", (first) ? "\t" : ", ", i); 11164fa7b105644222d9b35347c9d226ca8e011072ebColin Cross first = 0; 11174fa7b105644222d9b35347c9d226ca8e011072ebColin Cross } 1118cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes fprintf(d, "\n"); 11194fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 11204fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 11214fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 11224fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - at - print current situation 1123cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #ifdef REDEBUG 1124cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static void at(struct match *m, char *title, char *start, char *stop, \ 1125cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == sopno startst, sopno stopst); 1126cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #endif 11274fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 11284fa7b105644222d9b35347c9d226ca8e011072ebColin Crossstatic void 1129cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughesat( 1130cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes struct match *m, 1131cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes char *title, 1132cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes char *start, 1133cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes char *stop, 1134cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes sopno startst, 11354fa7b105644222d9b35347c9d226ca8e011072ebColin Cross sopno stopst) 11364fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 1137cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 1138cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(m != NULL); 1139cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(title != NULL); 1140cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(start != NULL); 1141cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes _DIAGASSERT(stop != NULL); 1142cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes 11434fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (!(m->eflags®_TRACE)) 11444fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return; 11454fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 1146cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes printf("%s %s-", title, pchar(*start)); 1147cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes printf("%s ", pchar(*stop)); 1148cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes printf("%ld-%ld\n", (long)startst, (long)stopst); 11494fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 11504fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 11514fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#ifndef PCHARDONE 11524fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#define PCHARDONE /* never again */ 11534fa7b105644222d9b35347c9d226ca8e011072ebColin Cross/* 11544fa7b105644222d9b35347c9d226ca8e011072ebColin Cross - pchar - make a character printable 1155cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #ifdef REDEBUG 1156cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == static char *pchar(int ch); 1157cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes == #endif 11584fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * 11594fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * Is this identical to regchar() over in debug.c? Well, yes. But a 11604fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * duplicate here avoids having a debugging-capable regexec.o tied to 11614fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * a matching debug.o, and this is convenient. It all disappears in 11624fa7b105644222d9b35347c9d226ca8e011072ebColin Cross * the non-debug compilation anyway, so it doesn't matter much. 11634fa7b105644222d9b35347c9d226ca8e011072ebColin Cross */ 11644fa7b105644222d9b35347c9d226ca8e011072ebColin Crossstatic char * /* -> representation */ 1165cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughespchar( 1166cc213f871bf4c5329eb5eb7a80a0ce9d4a880af8Elliott Hughes int ch) 11674fa7b105644222d9b35347c9d226ca8e011072ebColin Cross{ 11684fa7b105644222d9b35347c9d226ca8e011072ebColin Cross static char pbuf[10]; 11694fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 11704fa7b105644222d9b35347c9d226ca8e011072ebColin Cross if (isprint(ch) || ch == ' ') 11714fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (void)snprintf(pbuf, sizeof pbuf, "%c", ch); 11724fa7b105644222d9b35347c9d226ca8e011072ebColin Cross else 11734fa7b105644222d9b35347c9d226ca8e011072ebColin Cross (void)snprintf(pbuf, sizeof pbuf, "\\%o", ch); 11744fa7b105644222d9b35347c9d226ca8e011072ebColin Cross return(pbuf); 11754fa7b105644222d9b35347c9d226ca8e011072ebColin Cross} 11764fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 11774fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#endif 11784fa7b105644222d9b35347c9d226ca8e011072ebColin Cross 11794fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef matcher 11804fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef fast 11814fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef slow 11824fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef dissect 11834fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef backref 11844fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef step 11854fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef print 11864fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef at 11874fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef match 11884fa7b105644222d9b35347c9d226ca8e011072ebColin Cross#undef nope 1189