regcomp.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:58k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * re_*comp and friends - compile REs
  3.  * This file #includes several others (see the bottom).
  4.  *
  5.  * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
  6.  * 
  7.  * Development of this software was funded, in part, by Cray Research Inc.,
  8.  * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
  9.  * Corporation, none of whom are responsible for the results.  The author
  10.  * thanks all of them. 
  11.  * 
  12.  * Redistribution and use in source and binary forms -- with or without
  13.  * modification -- are permitted for any purpose, provided that
  14.  * redistributions in source form retain this entire copyright notice and
  15.  * indicate the origin and nature of any modifications.
  16.  * 
  17.  * I'd appreciate being given credit for this package in the documentation
  18.  * of software which uses it, but that is not a requirement.
  19.  * 
  20.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  21.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  22.  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
  23.  * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  26.  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  27.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29.  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  *
  31.  */
  32. #include "regguts.h"
  33. /*
  34.  * forward declarations, up here so forward datatypes etc. are defined early
  35.  */
  36. /* =====^!^===== begin forwards =====^!^===== */
  37. /* automatically gathered by fwd; do not hand-edit */
  38. /* === regcomp.c === */
  39. int compile _ANSI_ARGS_((regex_t *, CONST chr *, size_t, int));
  40. static VOID moresubs _ANSI_ARGS_((struct vars *, int));
  41. static int freev _ANSI_ARGS_((struct vars *, int));
  42. static VOID makesearch _ANSI_ARGS_((struct vars *, struct nfa *));
  43. static struct subre *parse _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
  44. static struct subre *parsebranch _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, int));
  45. static VOID parseqatom _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, struct subre *));
  46. static VOID nonword _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
  47. static VOID word _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
  48. static int scannum _ANSI_ARGS_((struct vars *));
  49. static VOID repeat _ANSI_ARGS_((struct vars *, struct state *, struct state *, int, int));
  50. static VOID bracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
  51. static VOID cbracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
  52. static VOID brackpart _ANSI_ARGS_((struct vars *, struct state *, struct state *));
  53. static chr *scanplain _ANSI_ARGS_((struct vars *));
  54. static VOID leaders _ANSI_ARGS_((struct vars *, struct cvec *));
  55. static VOID onechr _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
  56. static VOID dovec _ANSI_ARGS_((struct vars *, struct cvec *, struct state *, struct state *));
  57. static celt nextleader _ANSI_ARGS_((struct vars *, pchr, pchr));
  58. static VOID wordchrs _ANSI_ARGS_((struct vars *));
  59. static struct subre *subre _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
  60. static VOID freesubre _ANSI_ARGS_((struct vars *, struct subre *));
  61. static VOID freesrnode _ANSI_ARGS_((struct vars *, struct subre *));
  62. static VOID optst _ANSI_ARGS_((struct vars *, struct subre *));
  63. static int numst _ANSI_ARGS_((struct subre *, int));
  64. static VOID markst _ANSI_ARGS_((struct subre *));
  65. static VOID cleanst _ANSI_ARGS_((struct vars *));
  66. static long nfatree _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
  67. static long nfanode _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
  68. static int newlacon _ANSI_ARGS_((struct vars *, struct state *, struct state *, int));
  69. static VOID freelacons _ANSI_ARGS_((struct subre *, int));
  70. static VOID rfree _ANSI_ARGS_((regex_t *));
  71. static VOID dump _ANSI_ARGS_((regex_t *, FILE *));
  72. static VOID dumpst _ANSI_ARGS_((struct subre *, FILE *, int));
  73. static VOID stdump _ANSI_ARGS_((struct subre *, FILE *, int));
  74. static char *stid _ANSI_ARGS_((struct subre *, char *, size_t));
  75. /* === regc_lex.c === */
  76. static VOID lexstart _ANSI_ARGS_((struct vars *));
  77. static VOID prefixes _ANSI_ARGS_((struct vars *));
  78. static VOID lexnest _ANSI_ARGS_((struct vars *, chr *, chr *));
  79. static VOID lexword _ANSI_ARGS_((struct vars *));
  80. static int next _ANSI_ARGS_((struct vars *));
  81. static int lexescape _ANSI_ARGS_((struct vars *));
  82. static chr lexdigits _ANSI_ARGS_((struct vars *, int, int, int));
  83. static int brenext _ANSI_ARGS_((struct vars *, pchr));
  84. static VOID skip _ANSI_ARGS_((struct vars *));
  85. static chr newline _ANSI_ARGS_((NOPARMS));
  86. #ifdef REG_DEBUG
  87. static chr *ch _ANSI_ARGS_((NOPARMS));
  88. #endif
  89. static chr chrnamed _ANSI_ARGS_((struct vars *, chr *, chr *, pchr));
  90. /* === regc_color.c === */
  91. static VOID initcm _ANSI_ARGS_((struct vars *, struct colormap *));
  92. static VOID freecm _ANSI_ARGS_((struct colormap *));
  93. static VOID cmtreefree _ANSI_ARGS_((struct colormap *, union tree *, int));
  94. static color setcolor _ANSI_ARGS_((struct colormap *, pchr, pcolor));
  95. static color maxcolor _ANSI_ARGS_((struct colormap *));
  96. static color newcolor _ANSI_ARGS_((struct colormap *));
  97. static VOID freecolor _ANSI_ARGS_((struct colormap *, pcolor));
  98. static color pseudocolor _ANSI_ARGS_((struct colormap *));
  99. static color subcolor _ANSI_ARGS_((struct colormap *, pchr c));
  100. static color newsub _ANSI_ARGS_((struct colormap *, pcolor));
  101. static VOID subrange _ANSI_ARGS_((struct vars *, pchr, pchr, struct state *, struct state *));
  102. static VOID subblock _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
  103. static VOID okcolors _ANSI_ARGS_((struct nfa *, struct colormap *));
  104. static VOID colorchain _ANSI_ARGS_((struct colormap *, struct arc *));
  105. static VOID uncolorchain _ANSI_ARGS_((struct colormap *, struct arc *));
  106. static int singleton _ANSI_ARGS_((struct colormap *, pchr c));
  107. static VOID rainbow _ANSI_ARGS_((struct nfa *, struct colormap *, int, pcolor, struct state *, struct state *));
  108. static VOID colorcomplement _ANSI_ARGS_((struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *));
  109. #ifdef REG_DEBUG
  110. static VOID dumpcolors _ANSI_ARGS_((struct colormap *, FILE *));
  111. static VOID fillcheck _ANSI_ARGS_((struct colormap *, union tree *, int, FILE *));
  112. static VOID dumpchr _ANSI_ARGS_((pchr, FILE *));
  113. #endif
  114. /* === regc_nfa.c === */
  115. static struct nfa *newnfa _ANSI_ARGS_((struct vars *, struct colormap *, struct nfa *));
  116. static VOID freenfa _ANSI_ARGS_((struct nfa *));
  117. static struct state *newstate _ANSI_ARGS_((struct nfa *));
  118. static struct state *newfstate _ANSI_ARGS_((struct nfa *, int flag));
  119. static VOID dropstate _ANSI_ARGS_((struct nfa *, struct state *));
  120. static VOID freestate _ANSI_ARGS_((struct nfa *, struct state *));
  121. static VOID destroystate _ANSI_ARGS_((struct nfa *, struct state *));
  122. static VOID newarc _ANSI_ARGS_((struct nfa *, int, pcolor, struct state *, struct state *));
  123. static struct arc *allocarc _ANSI_ARGS_((struct nfa *, struct state *));
  124. static VOID freearc _ANSI_ARGS_((struct nfa *, struct arc *));
  125. static struct arc *findarc _ANSI_ARGS_((struct state *, int, pcolor));
  126. static VOID cparc _ANSI_ARGS_((struct nfa *, struct arc *, struct state *, struct state *));
  127. static VOID moveins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
  128. static VOID copyins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
  129. static VOID moveouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
  130. static VOID copyouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
  131. static VOID cloneouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, int));
  132. static VOID delsub _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
  133. static VOID deltraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
  134. static VOID dupnfa _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, struct state *));
  135. static VOID duptraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
  136. static VOID cleartraverse _ANSI_ARGS_((struct nfa *, struct state *));
  137. static VOID specialcolors _ANSI_ARGS_((struct nfa *));
  138. static long optimize _ANSI_ARGS_((struct nfa *, FILE *));
  139. static VOID pullback _ANSI_ARGS_((struct nfa *, FILE *));
  140. static int pull _ANSI_ARGS_((struct nfa *, struct arc *));
  141. static VOID pushfwd _ANSI_ARGS_((struct nfa *, FILE *));
  142. static int push _ANSI_ARGS_((struct nfa *, struct arc *));
  143. #define INCOMPATIBLE 1 /* destroys arc */
  144. #define SATISFIED 2 /* constraint satisfied */
  145. #define COMPATIBLE 3 /* compatible but not satisfied yet */
  146. static int combine _ANSI_ARGS_((struct arc *, struct arc *));
  147. static VOID fixempties _ANSI_ARGS_((struct nfa *, FILE *));
  148. static int unempty _ANSI_ARGS_((struct nfa *, struct arc *));
  149. static VOID cleanup _ANSI_ARGS_((struct nfa *));
  150. static VOID markreachable _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
  151. static VOID markcanreach _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
  152. static long analyze _ANSI_ARGS_((struct nfa *));
  153. static VOID compact _ANSI_ARGS_((struct nfa *, struct cnfa *));
  154. static VOID carcsort _ANSI_ARGS_((struct carc *, struct carc *));
  155. static VOID freecnfa _ANSI_ARGS_((struct cnfa *));
  156. static VOID dumpnfa _ANSI_ARGS_((struct nfa *, FILE *));
  157. #ifdef REG_DEBUG
  158. static VOID dumpstate _ANSI_ARGS_((struct state *, FILE *));
  159. static VOID dumparcs _ANSI_ARGS_((struct state *, FILE *));
  160. static int dumprarcs _ANSI_ARGS_((struct arc *, struct state *, FILE *, int));
  161. static VOID dumparc _ANSI_ARGS_((struct arc *, struct state *, FILE *));
  162. #endif
  163. static VOID dumpcnfa _ANSI_ARGS_((struct cnfa *, FILE *));
  164. #ifdef REG_DEBUG
  165. static VOID dumpcstate _ANSI_ARGS_((int, struct carc *, struct cnfa *, FILE *));
  166. #endif
  167. /* === regc_cvec.c === */
  168. static struct cvec *newcvec _ANSI_ARGS_((int, int, int));
  169. static struct cvec *clearcvec _ANSI_ARGS_((struct cvec *));
  170. static VOID addchr _ANSI_ARGS_((struct cvec *, pchr));
  171. static VOID addrange _ANSI_ARGS_((struct cvec *, pchr, pchr));
  172. static VOID addmcce _ANSI_ARGS_((struct cvec *, chr *, chr *));
  173. static int haschr _ANSI_ARGS_((struct cvec *, pchr));
  174. static struct cvec *getcvec _ANSI_ARGS_((struct vars *, int, int, int));
  175. static VOID freecvec _ANSI_ARGS_((struct cvec *));
  176. /* === regc_locale.c === */
  177. static int nmcces _ANSI_ARGS_((struct vars *));
  178. static int nleaders _ANSI_ARGS_((struct vars *));
  179. static struct cvec *allmcces _ANSI_ARGS_((struct vars *, struct cvec *));
  180. static celt element _ANSI_ARGS_((struct vars *, chr *, chr *));
  181. static struct cvec *range _ANSI_ARGS_((struct vars *, celt, celt, int));
  182. static int before _ANSI_ARGS_((celt, celt));
  183. static struct cvec *eclass _ANSI_ARGS_((struct vars *, celt, int));
  184. static struct cvec *cclass _ANSI_ARGS_((struct vars *, chr *, chr *, int));
  185. static struct cvec *allcases _ANSI_ARGS_((struct vars *, pchr));
  186. static int cmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
  187. static int casecmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
  188. /* automatically gathered by fwd; do not hand-edit */
  189. /* =====^!^===== end forwards =====^!^===== */
  190. /* internal variables, bundled for easy passing around */
  191. struct vars {
  192. regex_t *re;
  193. chr *now; /* scan pointer into string */
  194. chr *stop; /* end of string */
  195. chr *savenow; /* saved now and stop for "subroutine call" */
  196. chr *savestop;
  197. int err; /* error code (0 if none) */
  198. int cflags; /* copy of compile flags */
  199. int lasttype; /* type of previous token */
  200. int nexttype; /* type of next token */
  201. chr nextvalue; /* value (if any) of next token */
  202. int lexcon; /* lexical context type (see lex.c) */
  203. int nsubexp; /* subexpression count */
  204. struct subre **subs; /* subRE pointer vector */
  205. size_t nsubs; /* length of vector */
  206. struct subre *sub10[10]; /* initial vector, enough for most */
  207. struct nfa *nfa; /* the NFA */
  208. struct colormap *cm; /* character color map */
  209. color nlcolor; /* color of newline */
  210. struct state *wordchrs; /* state in nfa holding word-char outarcs */
  211. struct subre *tree; /* subexpression tree */
  212. struct subre *treechain; /* all tree nodes allocated */
  213. struct subre *treefree; /* any free tree nodes */
  214. int ntree; /* number of tree nodes */
  215. struct cvec *cv; /* interface cvec */
  216. struct cvec *cv2; /* utility cvec */
  217. struct cvec *mcces; /* collating-element information */
  218. # define ISCELEADER(v,c) (v->mcces != NULL && haschr(v->mcces, (c)))
  219. struct state *mccepbegin; /* in nfa, start of MCCE prototypes */
  220. struct state *mccepend; /* in nfa, end of MCCE prototypes */
  221. struct subre *lacons; /* lookahead-constraint vector */
  222. int nlacons; /* size of lacons */
  223. };
  224. /* parsing macros; most know that `v' is the struct vars pointer */
  225. #define NEXT() (next(v)) /* advance by one token */
  226. #define SEE(t) (v->nexttype == (t)) /* is next token this? */
  227. #define EAT(t) (SEE(t) && next(v)) /* if next is this, swallow it */
  228. #define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
  229. #define ISERR() VISERR(v)
  230. #define VERR(vv,e) ((vv)->nexttype = EOS, ((vv)->err) ? (vv)->err :
  231. ((vv)->err = (e)))
  232. #define ERR(e) VERR(v, e) /* record an error */
  233. #define NOERR() {if (ISERR()) return;} /* if error seen, return */
  234. #define NOERRN() {if (ISERR()) return NULL;} /* NOERR with retval */
  235. #define NOERRZ() {if (ISERR()) return 0;} /* NOERR with retval */
  236. #define INSIST(c, e) ((c) ? 0 : ERR(e)) /* if condition false, error */
  237. #define NOTE(b) (v->re->re_info |= (b)) /* note visible condition */
  238. #define EMPTYARC(x, y) newarc(v->nfa, EMPTY, 0, x, y)
  239. /* token type codes, some also used as NFA arc types */
  240. #define EMPTY 'n' /* no token present */
  241. #define EOS 'e' /* end of string */
  242. #define PLAIN 'p' /* ordinary character */
  243. #define DIGIT 'd' /* digit (in bound) */
  244. #define BACKREF 'b' /* back reference */
  245. #define COLLEL 'I' /* start of [. */
  246. #define ECLASS 'E' /* start of [= */
  247. #define CCLASS 'C' /* start of [: */
  248. #define END 'X' /* end of [. [= [: */
  249. #define RANGE 'R' /* - within [] which might be range delim. */
  250. #define LACON 'L' /* lookahead constraint subRE */
  251. #define AHEAD 'a' /* color-lookahead arc */
  252. #define BEHIND 'r' /* color-lookbehind arc */
  253. #define WBDRY 'w' /* word boundary constraint */
  254. #define NWBDRY 'W' /* non-word-boundary constraint */
  255. #define SBEGIN 'A' /* beginning of string (even if not BOL) */
  256. #define SEND 'Z' /* end of string (even if not EOL) */
  257. #define PREFER 'P' /* length preference */
  258. /* is an arc colored, and hence on a color chain? */
  259. #define COLORED(a) ((a)->type == PLAIN || (a)->type == AHEAD || 
  260. (a)->type == BEHIND)
  261. /* static function list */
  262. static struct fns functions = {
  263. rfree, /* regfree insides */
  264. };
  265. /*
  266.  - compile - compile regular expression
  267.  ^ int compile(regex_t *, CONST chr *, size_t, int);
  268.  */
  269. int
  270. compile(re, string, len, flags)
  271. regex_t *re;
  272. CONST chr *string;
  273. size_t len;
  274. int flags;
  275. {
  276. struct vars var;
  277. struct vars *v = &var;
  278. struct guts *g;
  279. int i;
  280. size_t j;
  281. FILE *debug = (flags&REG_PROGRESS) ? stdout : (FILE *)NULL;
  282. # define CNOERR() { if (ISERR()) return freev(v, v->err); }
  283. /* sanity checks */
  284. if (re == NULL || string == NULL)
  285. return REG_INVARG;
  286. if ((flags&REG_QUOTE) &&
  287. (flags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)))
  288. return REG_INVARG;
  289. if (!(flags&REG_EXTENDED) && (flags&REG_ADVF))
  290. return REG_INVARG;
  291. /* initial setup (after which freev() is callable) */
  292. v->re = re;
  293. v->now = (chr *)string;
  294. v->stop = v->now + len;
  295. v->savenow = v->savestop = NULL;
  296. v->err = 0;
  297. v->cflags = flags;
  298. v->nsubexp = 0;
  299. v->subs = v->sub10;
  300. v->nsubs = 10;
  301. for (j = 0; j < v->nsubs; j++)
  302. v->subs[j] = NULL;
  303. v->nfa = NULL;
  304. v->cm = NULL;
  305. v->nlcolor = COLORLESS;
  306. v->wordchrs = NULL;
  307. v->tree = NULL;
  308. v->treechain = NULL;
  309. v->treefree = NULL;
  310. v->cv = NULL;
  311. v->cv2 = NULL;
  312. v->mcces = NULL;
  313. v->lacons = NULL;
  314. v->nlacons = 0;
  315. re->re_magic = REMAGIC;
  316. re->re_info = 0; /* bits get set during parse */
  317. re->re_csize = sizeof(chr);
  318. re->re_guts = NULL;
  319. re->re_fns = VS(&functions);
  320. /* more complex setup, malloced things */
  321. re->re_guts = VS(MALLOC(sizeof(struct guts)));
  322. if (re->re_guts == NULL)
  323. return freev(v, REG_ESPACE);
  324. g = (struct guts *)re->re_guts;
  325. g->tree = NULL;
  326. initcm(v, &g->cmap);
  327. v->cm = &g->cmap;
  328. g->lacons = NULL;
  329. g->nlacons = 0;
  330. ZAPCNFA(g->search);
  331. v->nfa = newnfa(v, v->cm, (struct nfa *)NULL);
  332. CNOERR();
  333. v->cv = newcvec(100, 20, 10);
  334. if (v->cv == NULL)
  335. return freev(v, REG_ESPACE);
  336. i = nmcces(v);
  337. if (i > 0) {
  338. v->mcces = newcvec(nleaders(v), 0, i);
  339. CNOERR();
  340. v->mcces = allmcces(v, v->mcces);
  341. leaders(v, v->mcces);
  342. addmcce(v->mcces, (chr *)NULL, (chr *)NULL); /* dummy */
  343. }
  344. CNOERR();
  345. /* parsing */
  346. lexstart(v); /* also handles prefixes */
  347. if ((v->cflags&REG_NLSTOP) || (v->cflags&REG_NLANCH)) {
  348. /* assign newline a unique color */
  349. v->nlcolor = subcolor(v->cm, newline());
  350. okcolors(v->nfa, v->cm);
  351. }
  352. CNOERR();
  353. v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
  354. assert(SEE(EOS)); /* even if error; ISERR() => SEE(EOS) */
  355. CNOERR();
  356. assert(v->tree != NULL);
  357. /* finish setup of nfa and its subre tree */
  358. specialcolors(v->nfa);
  359. CNOERR();
  360. if (debug != NULL) {
  361. fprintf(debug, "nnn========= RAW ==========n");
  362. dumpnfa(v->nfa, debug);
  363. dumpst(v->tree, debug, 1);
  364. }
  365. optst(v, v->tree);
  366. v->ntree = numst(v->tree, 1);
  367. markst(v->tree);
  368. cleanst(v);
  369. if (debug != NULL) {
  370. fprintf(debug, "nnn========= TREE FIXED ==========n");
  371. dumpst(v->tree, debug, 1);
  372. }
  373. /* build compacted NFAs for tree and lacons */
  374. re->re_info |= nfatree(v, v->tree, debug);
  375. CNOERR();
  376. assert(v->nlacons == 0 || v->lacons != NULL);
  377. for (i = 1; i < v->nlacons; i++) {
  378. if (debug != NULL)
  379. fprintf(debug, "nnn========= LA%d ==========n", i);
  380. nfanode(v, &v->lacons[i], debug);
  381. }
  382. CNOERR();
  383. if (v->tree->flags&SHORTER)
  384. NOTE(REG_USHORTEST);
  385. /* build compacted NFAs for tree, lacons, fast search */
  386. if (debug != NULL)
  387. fprintf(debug, "nnn========= SEARCH ==========n");
  388. /* can sacrifice main NFA now, so use it as work area */
  389. (DISCARD)optimize(v->nfa, debug);
  390. CNOERR();
  391. makesearch(v, v->nfa);
  392. CNOERR();
  393. compact(v->nfa, &g->search);
  394. CNOERR();
  395. /* looks okay, package it up */
  396. re->re_nsub = v->nsubexp;
  397. v->re = NULL; /* freev no longer frees re */
  398. g->magic = GUTSMAGIC;
  399. g->cflags = v->cflags;
  400. g->info = re->re_info;
  401. g->nsub = re->re_nsub;
  402. g->tree = v->tree;
  403. v->tree = NULL;
  404. g->ntree = v->ntree;
  405. g->compare = (v->cflags&REG_ICASE) ? casecmp : cmp;
  406. g->lacons = v->lacons;
  407. v->lacons = NULL;
  408. g->nlacons = v->nlacons;
  409. if (flags&REG_DUMP)
  410. dump(re, stdout);
  411. assert(v->err == 0);
  412. return freev(v, 0);
  413. }
  414. /*
  415.  - moresubs - enlarge subRE vector
  416.  ^ static VOID moresubs(struct vars *, int);
  417.  */
  418. static VOID
  419. moresubs(v, wanted)
  420. struct vars *v;
  421. int wanted; /* want enough room for this one */
  422. {
  423. struct subre **p;
  424. size_t n;
  425. assert(wanted > 0 && (size_t)wanted >= v->nsubs);
  426. n = (size_t)wanted * 3 / 2 + 1;
  427. if (v->subs == v->sub10) {
  428. p = (struct subre **)MALLOC(n * sizeof(struct subre *));
  429. if (p != NULL)
  430. memcpy(VS(p), VS(v->subs),
  431. v->nsubs * sizeof(struct subre *));
  432. } else
  433. p = (struct subre **)REALLOC(v->subs, n*sizeof(struct subre *));
  434. if (p == NULL) {
  435. ERR(REG_ESPACE);
  436. return;
  437. }
  438. v->subs = p;
  439. for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++)
  440. *p = NULL;
  441. assert(v->nsubs == n);
  442. assert((size_t)wanted < v->nsubs);
  443. }
  444. /*
  445.  - freev - free vars struct's substructures where necessary
  446.  * Optionally does error-number setting, and always returns error code
  447.  * (if any), to make error-handling code terser.
  448.  ^ static int freev(struct vars *, int);
  449.  */
  450. static int
  451. freev(v, err)
  452. struct vars *v;
  453. int err;
  454. {
  455. if (v->re != NULL)
  456. rfree(v->re);
  457. if (v->subs != v->sub10)
  458. FREE(v->subs);
  459. if (v->nfa != NULL)
  460. freenfa(v->nfa);
  461. if (v->tree != NULL)
  462. freesubre(v, v->tree);
  463. if (v->treechain != NULL)
  464. cleanst(v);
  465. if (v->cv != NULL)
  466. freecvec(v->cv);
  467. if (v->cv2 != NULL)
  468. freecvec(v->cv2);
  469. if (v->mcces != NULL)
  470. freecvec(v->mcces);
  471. if (v->lacons != NULL)
  472. freelacons(v->lacons, v->nlacons);
  473. ERR(err); /* nop if err==0 */
  474. return v->err;
  475. }
  476. /*
  477.  - makesearch - turn an NFA into a search NFA (implicit prepend of .*?)
  478.  * NFA must have been optimize()d already.
  479.  ^ static VOID makesearch(struct vars *, struct nfa *);
  480.  */
  481. static VOID
  482. makesearch(v, nfa)
  483. struct vars *v;
  484. struct nfa *nfa;
  485. {
  486. struct arc *a;
  487. struct arc *b;
  488. struct state *pre = nfa->pre;
  489. struct state *s;
  490. struct state *s2;
  491. struct state *slist;
  492. /* no loops are needed if it's anchored */
  493. for (a = pre->outs; a != NULL; a = a->outchain) {
  494. assert(a->type == PLAIN);
  495. if (a->co != nfa->bos[0] && a->co != nfa->bos[1])
  496. break;
  497. }
  498. if (a != NULL) {
  499. /* add implicit .* in front */
  500. rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);
  501. /* and ^* and A* too -- not always necessary, but harmless */
  502. newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
  503. newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
  504. }
  505. /*
  506.  * Now here's the subtle part.  Because many REs have no lookback
  507.  * constraints, often knowing when you were in the pre state tells
  508.  * you little; it's the next state(s) that are informative.  But
  509.  * some of them may have other inarcs, i.e. it may be possible to
  510.  * make actual progress and then return to one of them.  We must
  511.  * de-optimize such cases, splitting each such state into progress
  512.  * and no-progress states.
  513.  */
  514. /* first, make a list of the states */
  515. slist = NULL;
  516. for (a = pre->outs; a != NULL; a = a->outchain) {
  517. s = a->to;
  518. for (b = s->ins; b != NULL; b = b->inchain)
  519. if (b->from != pre)
  520. break;
  521. if (b != NULL) { /* must be split */
  522. if (s->tmp == NULL) {  /* if not already in the list */
  523.                        /* (fixes bugs 505048, 230589, */
  524.                        /* 840258, 504785) */
  525. s->tmp = slist;
  526. slist = s;
  527. }
  528. }
  529. }
  530. /* do the splits */
  531. for (s = slist; s != NULL; s = s2) {
  532. s2 = newstate(nfa);
  533. copyouts(nfa, s, s2);
  534. for (a = s->ins; a != NULL; a = b) {
  535. b = a->inchain;
  536. if (a->from != pre) {
  537. cparc(nfa, a, a->from, s2);
  538. freearc(nfa, a);
  539. }
  540. }
  541. s2 = s->tmp;
  542. s->tmp = NULL; /* clean up while we're at it */
  543. }
  544. }
  545. /*
  546.  - parse - parse an RE
  547.  * This is actually just the top level, which parses a bunch of branches
  548.  * tied together with '|'.  They appear in the tree as the left children
  549.  * of a chain of '|' subres.
  550.  ^ static struct subre *parse(struct vars *, int, int, struct state *,
  551.  ^  struct state *);
  552.  */
  553. static struct subre *
  554. parse(v, stopper, type, init, final)
  555. struct vars *v;
  556. int stopper; /* EOS or ')' */
  557. int type; /* LACON (lookahead subRE) or PLAIN */
  558. struct state *init; /* initial state */
  559. struct state *final; /* final state */
  560. {
  561. struct state *left; /* scaffolding for branch */
  562. struct state *right;
  563. struct subre *branches; /* top level */
  564. struct subre *branch; /* current branch */
  565. struct subre *t; /* temporary */
  566. int firstbranch; /* is this the first branch? */
  567. assert(stopper == ')' || stopper == EOS);
  568. branches = subre(v, '|', LONGER, init, final);
  569. NOERRN();
  570. branch = branches;
  571. firstbranch = 1;
  572. do { /* a branch */
  573. if (!firstbranch) {
  574. /* need a place to hang it */
  575. branch->right = subre(v, '|', LONGER, init, final);
  576. NOERRN();
  577. branch = branch->right;
  578. }
  579. firstbranch = 0;
  580. left = newstate(v->nfa);
  581. right = newstate(v->nfa);
  582. NOERRN();
  583. EMPTYARC(init, left);
  584. EMPTYARC(right, final);
  585. NOERRN();
  586. branch->left = parsebranch(v, stopper, type, left, right, 0);
  587. NOERRN();
  588. branch->flags |= UP(branch->flags | branch->left->flags);
  589. if ((branch->flags &~ branches->flags) != 0) /* new flags */
  590. for (t = branches; t != branch; t = t->right)
  591. t->flags |= branch->flags;
  592. } while (EAT('|'));
  593. assert(SEE(stopper) || SEE(EOS));
  594. if (!SEE(stopper)) {
  595. assert(stopper == ')' && SEE(EOS));
  596. ERR(REG_EPAREN);
  597. }
  598. /* optimize out simple cases */
  599. if (branch == branches) { /* only one branch */
  600. assert(branch->right == NULL);
  601. t = branch->left;
  602. branch->left = NULL;
  603. freesubre(v, branches);
  604. branches = t;
  605. } else if (!MESSY(branches->flags)) { /* no interesting innards */
  606. freesubre(v, branches->left);
  607. branches->left = NULL;
  608. freesubre(v, branches->right);
  609. branches->right = NULL;
  610. branches->op = '=';
  611. }
  612. return branches;
  613. }
  614. /*
  615.  - parsebranch - parse one branch of an RE
  616.  * This mostly manages concatenation, working closely with parseqatom().
  617.  * Concatenated things are bundled up as much as possible, with separate
  618.  * ',' nodes introduced only when necessary due to substructure.
  619.  ^ static struct subre *parsebranch(struct vars *, int, int, struct state *,
  620.  ^  struct state *, int);
  621.  */
  622. static struct subre *
  623. parsebranch(v, stopper, type, left, right, partial)
  624. struct vars *v;
  625. int stopper; /* EOS or ')' */
  626. int type; /* LACON (lookahead subRE) or PLAIN */
  627. struct state *left; /* leftmost state */
  628. struct state *right; /* rightmost state */
  629. int partial; /* is this only part of a branch? */
  630. {
  631. struct state *lp; /* left end of current construct */
  632. int seencontent; /* is there anything in this branch yet? */
  633. struct subre *t;
  634. lp = left;
  635. seencontent = 0;
  636. t = subre(v, '=', 0, left, right); /* op '=' is tentative */
  637. NOERRN();
  638. while (!SEE('|') && !SEE(stopper) && !SEE(EOS)) {
  639. if (seencontent) { /* implicit concat operator */
  640. lp = newstate(v->nfa);
  641. NOERRN();
  642. moveins(v->nfa, right, lp);
  643. }
  644. seencontent = 1;
  645. /* NB, recursion in parseqatom() may swallow rest of branch */
  646. parseqatom(v, stopper, type, lp, right, t);
  647. }
  648. if (!seencontent) { /* empty branch */
  649. if (!partial)
  650. NOTE(REG_UUNSPEC);
  651. assert(lp == left);
  652. EMPTYARC(left, right);
  653. }
  654. return t;
  655. }
  656. /*
  657.  - parseqatom - parse one quantified atom or constraint of an RE
  658.  * The bookkeeping near the end cooperates very closely with parsebranch();
  659.  * in particular, it contains a recursion that can involve parsing the rest
  660.  * of the branch, making this function's name somewhat inaccurate.
  661.  ^ static VOID parseqatom(struct vars *, int, int, struct state *,
  662.  ^  struct state *, struct subre *);
  663.  */
  664. static VOID
  665. parseqatom(v, stopper, type, lp, rp, top)
  666. struct vars *v;
  667. int stopper; /* EOS or ')' */
  668. int type; /* LACON (lookahead subRE) or PLAIN */
  669. struct state *lp; /* left state to hang it on */
  670. struct state *rp; /* right state to hang it on */
  671. struct subre *top; /* subtree top */
  672. {
  673. struct state *s; /* temporaries for new states */
  674. struct state *s2;
  675. # define ARCV(t, val) newarc(v->nfa, t, val, lp, rp)
  676. int m, n;
  677. struct subre *atom; /* atom's subtree */
  678. struct subre *t;
  679. int cap; /* capturing parens? */
  680. int pos; /* positive lookahead? */
  681. int subno; /* capturing-parens or backref number */
  682. int atomtype;
  683. int qprefer; /* quantifier short/long preference */
  684. int f;
  685. struct subre **atomp; /* where the pointer to atom is */
  686. /* initial bookkeeping */
  687. atom = NULL;
  688. assert(lp->nouts == 0); /* must string new code */
  689. assert(rp->nins == 0); /*  between lp and rp */
  690. subno = 0; /* just to shut lint up */
  691. /* an atom or constraint... */
  692. atomtype = v->nexttype;
  693. switch (atomtype) {
  694. /* first, constraints, which end by returning */
  695. case '^':
  696. ARCV('^', 1);
  697. if (v->cflags&REG_NLANCH)
  698. ARCV(BEHIND, v->nlcolor);
  699. NEXT();
  700. return;
  701. break;
  702. case '$':
  703. ARCV('$', 1);
  704. if (v->cflags&REG_NLANCH)
  705. ARCV(AHEAD, v->nlcolor);
  706. NEXT();
  707. return;
  708. break;
  709. case SBEGIN:
  710. ARCV('^', 1); /* BOL */
  711. ARCV('^', 0); /* or BOS */
  712. NEXT();
  713. return;
  714. break;
  715. case SEND:
  716. ARCV('$', 1); /* EOL */
  717. ARCV('$', 0); /* or EOS */
  718. NEXT();
  719. return;
  720. break;
  721. case '<':
  722. wordchrs(v); /* does NEXT() */
  723. s = newstate(v->nfa);
  724. NOERR();
  725. nonword(v, BEHIND, lp, s);
  726. word(v, AHEAD, s, rp);
  727. return;
  728. break;
  729. case '>':
  730. wordchrs(v); /* does NEXT() */
  731. s = newstate(v->nfa);
  732. NOERR();
  733. word(v, BEHIND, lp, s);
  734. nonword(v, AHEAD, s, rp);
  735. return;
  736. break;
  737. case WBDRY:
  738. wordchrs(v); /* does NEXT() */
  739. s = newstate(v->nfa);
  740. NOERR();
  741. nonword(v, BEHIND, lp, s);
  742. word(v, AHEAD, s, rp);
  743. s = newstate(v->nfa);
  744. NOERR();
  745. word(v, BEHIND, lp, s);
  746. nonword(v, AHEAD, s, rp);
  747. return;
  748. break;
  749. case NWBDRY:
  750. wordchrs(v); /* does NEXT() */
  751. s = newstate(v->nfa);
  752. NOERR();
  753. word(v, BEHIND, lp, s);
  754. word(v, AHEAD, s, rp);
  755. s = newstate(v->nfa);
  756. NOERR();
  757. nonword(v, BEHIND, lp, s);
  758. nonword(v, AHEAD, s, rp);
  759. return;
  760. break;
  761. case LACON: /* lookahead constraint */
  762. pos = v->nextvalue;
  763. NEXT();
  764. s = newstate(v->nfa);
  765. s2 = newstate(v->nfa);
  766. NOERR();
  767. t = parse(v, ')', LACON, s, s2);
  768. freesubre(v, t); /* internal structure irrelevant */
  769. assert(SEE(')') || ISERR());
  770. NEXT();
  771. n = newlacon(v, s, s2, pos);
  772. NOERR();
  773. ARCV(LACON, n);
  774. return;
  775. break;
  776. /* then errors, to get them out of the way */
  777. case '*':
  778. case '+':
  779. case '?':
  780. case '{':
  781. ERR(REG_BADRPT);
  782. return;
  783. break;
  784. default:
  785. ERR(REG_ASSERT);
  786. return;
  787. break;
  788. /* then plain characters, and minor variants on that theme */
  789. case ')': /* unbalanced paren */
  790. if ((v->cflags&REG_ADVANCED) != REG_EXTENDED) {
  791. ERR(REG_EPAREN);
  792. return;
  793. }
  794. /* legal in EREs due to specification botch */
  795. NOTE(REG_UPBOTCH);
  796. /* fallthrough into case PLAIN */
  797. case PLAIN:
  798. onechr(v, v->nextvalue, lp, rp);
  799. okcolors(v->nfa, v->cm);
  800. NOERR();
  801. NEXT();
  802. break;
  803. case '[':
  804. if (v->nextvalue == 1)
  805. bracket(v, lp, rp);
  806. else
  807. cbracket(v, lp, rp);
  808. assert(SEE(']') || ISERR());
  809. NEXT();
  810. break;
  811. case '.':
  812. rainbow(v->nfa, v->cm, PLAIN,
  813. (v->cflags&REG_NLSTOP) ? v->nlcolor : COLORLESS,
  814. lp, rp);
  815. NEXT();
  816. break;
  817. /* and finally the ugly stuff */
  818. case '(': /* value flags as capturing or non */
  819. cap = (type == LACON) ? 0 : v->nextvalue;
  820. if (cap) {
  821. v->nsubexp++;
  822. subno = v->nsubexp;
  823. if ((size_t)subno >= v->nsubs)
  824. moresubs(v, subno);
  825. assert((size_t)subno < v->nsubs);
  826. } else
  827. atomtype = PLAIN; /* something that's not '(' */
  828. NEXT();
  829. /* need new endpoints because tree will contain pointers */
  830. s = newstate(v->nfa);
  831. s2 = newstate(v->nfa);
  832. NOERR();
  833. EMPTYARC(lp, s);
  834. EMPTYARC(s2, rp);
  835. NOERR();
  836. atom = parse(v, ')', PLAIN, s, s2);
  837. assert(SEE(')') || ISERR());
  838. NEXT();
  839. NOERR();
  840. if (cap) {
  841. v->subs[subno] = atom;
  842. t = subre(v, '(', atom->flags|CAP, lp, rp);
  843. NOERR();
  844. t->subno = subno;
  845. t->left = atom;
  846. atom = t;
  847. }
  848. /* postpone everything else pending possible {0} */
  849. break;
  850. case BACKREF: /* the Feature From The Black Lagoon */
  851. INSIST(type != LACON, REG_ESUBREG);
  852. INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
  853. INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
  854. NOERR();
  855. assert(v->nextvalue > 0);
  856. atom = subre(v, 'b', BACKR, lp, rp);
  857. subno = v->nextvalue;
  858. atom->subno = subno;
  859. EMPTYARC(lp, rp); /* temporarily, so there's something */
  860. NEXT();
  861. break;
  862. }
  863. /* ...and an atom may be followed by a quantifier */
  864. switch (v->nexttype) {
  865. case '*':
  866. m = 0;
  867. n = INFINITY;
  868. qprefer = (v->nextvalue) ? LONGER : SHORTER;
  869. NEXT();
  870. break;
  871. case '+':
  872. m = 1;
  873. n = INFINITY;
  874. qprefer = (v->nextvalue) ? LONGER : SHORTER;
  875. NEXT();
  876. break;
  877. case '?':
  878. m = 0;
  879. n = 1;
  880. qprefer = (v->nextvalue) ? LONGER : SHORTER;
  881. NEXT();
  882. break;
  883. case '{':
  884. NEXT();
  885. m = scannum(v);
  886. if (EAT(',')) {
  887. if (SEE(DIGIT))
  888. n = scannum(v);
  889. else
  890. n = INFINITY;
  891. if (m > n) {
  892. ERR(REG_BADBR);
  893. return;
  894. }
  895. /* {m,n} exercises preference, even if it's {m,m} */
  896. qprefer = (v->nextvalue) ? LONGER : SHORTER;
  897. } else {
  898. n = m;
  899. /* {m} passes operand's preference through */
  900. qprefer = 0;
  901. }
  902. if (!SEE('}')) { /* catches errors too */
  903. ERR(REG_BADBR);
  904. return;
  905. }
  906. NEXT();
  907. break;
  908. default: /* no quantifier */
  909. m = n = 1;
  910. qprefer = 0;
  911. break;
  912. }
  913. /* annoying special case:  {0} or {0,0} cancels everything */
  914. if (m == 0 && n == 0) {
  915. if (atom != NULL)
  916. freesubre(v, atom);
  917. if (atomtype == '(')
  918. v->subs[subno] = NULL;
  919. delsub(v->nfa, lp, rp);
  920. EMPTYARC(lp, rp);
  921. return;
  922. }
  923. /* if not a messy case, avoid hard part */
  924. assert(!MESSY(top->flags));
  925. f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
  926. if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f))) {
  927. if (!(m == 1 && n == 1))
  928. repeat(v, lp, rp, m, n);
  929. if (atom != NULL)
  930. freesubre(v, atom);
  931. top->flags = f;
  932. return;
  933. }
  934. /*
  935.  * hard part:  something messy
  936.  * That is, capturing parens, back reference, short/long clash, or
  937.  * an atom with substructure containing one of those.
  938.  */
  939. /* now we'll need a subre for the contents even if they're boring */
  940. if (atom == NULL) {
  941. atom = subre(v, '=', 0, lp, rp);
  942. NOERR();
  943. }
  944. /*
  945.  * prepare a general-purpose state skeleton
  946.  *
  947.  *    ---> [s] ---prefix---> [begin] ---atom---> [end] ----rest---> [rp]
  948.  *   /                                            /
  949.  * [lp] ----> [s2] ----bypass---------------------
  950.  *
  951.  * where bypass is an empty, and prefix is some repetitions of atom
  952.  */
  953. s = newstate(v->nfa); /* first, new endpoints for the atom */
  954. s2 = newstate(v->nfa);
  955. NOERR();
  956. moveouts(v->nfa, lp, s);
  957. moveins(v->nfa, rp, s2);
  958. NOERR();
  959. atom->begin = s;
  960. atom->end = s2;
  961. s = newstate(v->nfa); /* and spots for prefix and bypass */
  962. s2 = newstate(v->nfa);
  963. NOERR();
  964. EMPTYARC(lp, s);
  965. EMPTYARC(lp, s2);
  966. NOERR();
  967. /* break remaining subRE into x{...} and what follows */
  968. t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
  969. t->left = atom;
  970. atomp = &t->left;
  971. /* here we should recurse... but we must postpone that to the end */
  972. /* split top into prefix and remaining */
  973. assert(top->op == '=' && top->left == NULL && top->right == NULL);
  974. top->left = subre(v, '=', top->flags, top->begin, lp);
  975. top->op = '.';
  976. top->right = t;
  977. /* if it's a backref, now is the time to replicate the subNFA */
  978. if (atomtype == BACKREF) {
  979. assert(atom->begin->nouts == 1); /* just the EMPTY */
  980. delsub(v->nfa, atom->begin, atom->end);
  981. assert(v->subs[subno] != NULL);
  982. /* and here's why the recursion got postponed:  it must */
  983. /* wait until the skeleton is filled in, because it may */
  984. /* hit a backref that wants to copy the filled-in skeleton */
  985. dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
  986. atom->begin, atom->end);
  987. NOERR();
  988. }
  989. /* it's quantifier time; first, turn x{0,...} into x{1,...}|empty */
  990. if (m == 0) {
  991. EMPTYARC(s2, atom->end); /* the bypass */
  992. assert(PREF(qprefer) != 0);
  993. f = COMBINE(qprefer, atom->flags);
  994. t = subre(v, '|', f, lp, atom->end);
  995. NOERR();
  996. t->left = atom;
  997. t->right = subre(v, '|', PREF(f), s2, atom->end);
  998. NOERR();
  999. t->right->left = subre(v, '=', 0, s2, atom->end);
  1000. NOERR();
  1001. *atomp = t;
  1002. atomp = &t->left;
  1003. m = 1;
  1004. }
  1005. /* deal with the rest of the quantifier */
  1006. if (atomtype == BACKREF) {
  1007. /* special case:  backrefs have internal quantifiers */
  1008. EMPTYARC(s, atom->begin); /* empty prefix */
  1009. /* just stuff everything into atom */
  1010. repeat(v, atom->begin, atom->end, m, n);
  1011. atom->min = (short)m;
  1012. atom->max = (short)n;
  1013. atom->flags |= COMBINE(qprefer, atom->flags);
  1014. } else if (m == 1 && n == 1) {
  1015. /* no/vacuous quantifier:  done */
  1016. EMPTYARC(s, atom->begin); /* empty prefix */
  1017. } else {
  1018. /* turn x{m,n} into x{m-1,n-1}x, with capturing */
  1019. /*  parens in only second x */
  1020. dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
  1021. assert(m >= 1 && m != INFINITY && n >= 1);
  1022. repeat(v, s, atom->begin, m-1, (n == INFINITY) ? n : n-1);
  1023. f = COMBINE(qprefer, atom->flags);
  1024. t = subre(v, '.', f, s, atom->end); /* prefix and atom */
  1025. NOERR();
  1026. t->left = subre(v, '=', PREF(f), s, atom->begin);
  1027. NOERR();
  1028. t->right = atom;
  1029. *atomp = t;
  1030. }
  1031. /* and finally, look after that postponed recursion */
  1032. t = top->right;
  1033. if (!(SEE('|') || SEE(stopper) || SEE(EOS)))
  1034. t->right = parsebranch(v, stopper, type, atom->end, rp, 1);
  1035. else {
  1036. EMPTYARC(atom->end, rp);
  1037. t->right = subre(v, '=', 0, atom->end, rp);
  1038. }
  1039. assert(SEE('|') || SEE(stopper) || SEE(EOS));
  1040. t->flags |= COMBINE(t->flags, t->right->flags);
  1041. top->flags |= COMBINE(top->flags, t->flags);
  1042. }
  1043. /*
  1044.  - nonword - generate arcs for non-word-character ahead or behind
  1045.  ^ static VOID nonword(struct vars *, int, struct state *, struct state *);
  1046.  */
  1047. static VOID
  1048. nonword(v, dir, lp, rp)
  1049. struct vars *v;
  1050. int dir; /* AHEAD or BEHIND */
  1051. struct state *lp;
  1052. struct state *rp;
  1053. {
  1054. int anchor = (dir == AHEAD) ? '$' : '^';
  1055. assert(dir == AHEAD || dir == BEHIND);
  1056. newarc(v->nfa, anchor, 1, lp, rp);
  1057. newarc(v->nfa, anchor, 0, lp, rp);
  1058. colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
  1059. /* (no need for special attention to n) */
  1060. }
  1061. /*
  1062.  - word - generate arcs for word character ahead or behind
  1063.  ^ static VOID word(struct vars *, int, struct state *, struct state *);
  1064.  */
  1065. static VOID
  1066. word(v, dir, lp, rp)
  1067. struct vars *v;
  1068. int dir; /* AHEAD or BEHIND */
  1069. struct state *lp;
  1070. struct state *rp;
  1071. {
  1072. assert(dir == AHEAD || dir == BEHIND);
  1073. cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
  1074. /* (no need for special attention to n) */
  1075. }
  1076. /*
  1077.  - scannum - scan a number
  1078.  ^ static int scannum(struct vars *);
  1079.  */
  1080. static int /* value, <= DUPMAX */
  1081. scannum(v)
  1082. struct vars *v;
  1083. {
  1084. int n = 0;
  1085. while (SEE(DIGIT) && n < DUPMAX) {
  1086. n = n*10 + v->nextvalue;
  1087. NEXT();
  1088. }
  1089. if (SEE(DIGIT) || n > DUPMAX) {
  1090. ERR(REG_BADBR);
  1091. return 0;
  1092. }
  1093. return n;
  1094. }
  1095. /*
  1096.  - repeat - replicate subNFA for quantifiers
  1097.  * The duplication sequences used here are chosen carefully so that any
  1098.  * pointers starting out pointing into the subexpression end up pointing into
  1099.  * the last occurrence.  (Note that it may not be strung between the same
  1100.  * left and right end states, however!)  This used to be important for the
  1101.  * subRE tree, although the important bits are now handled by the in-line
  1102.  * code in parse(), and when this is called, it doesn't matter any more.
  1103.  ^ static VOID repeat(struct vars *, struct state *, struct state *, int, int);
  1104.  */
  1105. static VOID
  1106. repeat(v, lp, rp, m, n)
  1107. struct vars *v;
  1108. struct state *lp;
  1109. struct state *rp;
  1110. int m;
  1111. int n;
  1112. {
  1113. # define SOME 2
  1114. # define INF 3
  1115. # define PAIR(x, y) ((x)*4 + (y))
  1116. # define REDUCE(x) ( ((x) == INFINITY) ? INF : (((x) > 1) ? SOME : (x)) )
  1117. CONST int rm = REDUCE(m);
  1118. CONST int rn = REDUCE(n);
  1119. struct state *s;
  1120. struct state *s2;
  1121. switch (PAIR(rm, rn)) {
  1122. case PAIR(0, 0): /* empty string */
  1123. delsub(v->nfa, lp, rp);
  1124. EMPTYARC(lp, rp);
  1125. break;
  1126. case PAIR(0, 1): /* do as x| */
  1127. EMPTYARC(lp, rp);
  1128. break;
  1129. case PAIR(0, SOME): /* do as x{1,n}| */
  1130. repeat(v, lp, rp, 1, n);
  1131. NOERR();
  1132. EMPTYARC(lp, rp);
  1133. break;
  1134. case PAIR(0, INF): /* loop x around */
  1135. s = newstate(v->nfa);
  1136. NOERR();
  1137. moveouts(v->nfa, lp, s);
  1138. moveins(v->nfa, rp, s);
  1139. EMPTYARC(lp, s);
  1140. EMPTYARC(s, rp);
  1141. break;
  1142. case PAIR(1, 1): /* no action required */
  1143. break;
  1144. case PAIR(1, SOME): /* do as x{0,n-1}x = (x{1,n-1}|)x */
  1145. s = newstate(v->nfa);
  1146. NOERR();
  1147. moveouts(v->nfa, lp, s);
  1148. dupnfa(v->nfa, s, rp, lp, s);
  1149. NOERR();
  1150. repeat(v, lp, s, 1, n-1);
  1151. NOERR();
  1152. EMPTYARC(lp, s);
  1153. break;
  1154. case PAIR(1, INF): /* add loopback arc */
  1155. s = newstate(v->nfa);
  1156. s2 = newstate(v->nfa);
  1157. NOERR();
  1158. moveouts(v->nfa, lp, s);
  1159. moveins(v->nfa, rp, s2);
  1160. EMPTYARC(lp, s);
  1161. EMPTYARC(s2, rp);
  1162. EMPTYARC(s2, s);
  1163. break;
  1164. case PAIR(SOME, SOME): /* do as x{m-1,n-1}x */
  1165. s = newstate(v->nfa);
  1166. NOERR();
  1167. moveouts(v->nfa, lp, s);
  1168. dupnfa(v->nfa, s, rp, lp, s);
  1169. NOERR();
  1170. repeat(v, lp, s, m-1, n-1);
  1171. break;
  1172. case PAIR(SOME, INF): /* do as x{m-1,}x */
  1173. s = newstate(v->nfa);
  1174. NOERR();
  1175. moveouts(v->nfa, lp, s);
  1176. dupnfa(v->nfa, s, rp, lp, s);
  1177. NOERR();
  1178. repeat(v, lp, s, m-1, n);
  1179. break;
  1180. default:
  1181. ERR(REG_ASSERT);
  1182. break;
  1183. }
  1184. }
  1185. /*
  1186.  - bracket - handle non-complemented bracket expression
  1187.  * Also called from cbracket for complemented bracket expressions.
  1188.  ^ static VOID bracket(struct vars *, struct state *, struct state *);
  1189.  */
  1190. static VOID
  1191. bracket(v, lp, rp)
  1192. struct vars *v;
  1193. struct state *lp;
  1194. struct state *rp;
  1195. {
  1196. assert(SEE('['));
  1197. NEXT();
  1198. while (!SEE(']') && !SEE(EOS))
  1199. brackpart(v, lp, rp);
  1200. assert(SEE(']') || ISERR());
  1201. okcolors(v->nfa, v->cm);
  1202. }
  1203. /*
  1204.  - cbracket - handle complemented bracket expression
  1205.  * We do it by calling bracket() with dummy endpoints, and then complementing
  1206.  * the result.  The alternative would be to invoke rainbow(), and then delete
  1207.  * arcs as the b.e. is seen... but that gets messy.
  1208.  ^ static VOID cbracket(struct vars *, struct state *, struct state *);
  1209.  */
  1210. static VOID
  1211. cbracket(v, lp, rp)
  1212. struct vars *v;
  1213. struct state *lp;
  1214. struct state *rp;
  1215. {
  1216. struct state *left = newstate(v->nfa);
  1217. struct state *right = newstate(v->nfa);
  1218. struct state *s;
  1219. struct arc *a; /* arc from lp */
  1220. struct arc *ba; /* arc from left, from bracket() */
  1221. struct arc *pa; /* MCCE-prototype arc */
  1222. color co;
  1223. chr *p;
  1224. int i;
  1225. NOERR();
  1226. bracket(v, left, right);
  1227. if (v->cflags&REG_NLSTOP)
  1228. newarc(v->nfa, PLAIN, v->nlcolor, left, right);
  1229. NOERR();
  1230. assert(lp->nouts == 0); /* all outarcs will be ours */
  1231. /* easy part of complementing */
  1232. colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
  1233. NOERR();
  1234. if (v->mcces == NULL) { /* no MCCEs -- we're done */
  1235. dropstate(v->nfa, left);
  1236. assert(right->nins == 0);
  1237. freestate(v->nfa, right);
  1238. return;
  1239. }
  1240. /* but complementing gets messy in the presence of MCCEs... */
  1241. NOTE(REG_ULOCALE);
  1242. for (p = v->mcces->chrs, i = v->mcces->nchrs; i > 0; p++, i--) {
  1243. co = GETCOLOR(v->cm, *p);
  1244. a = findarc(lp, PLAIN, co);
  1245. ba = findarc(left, PLAIN, co);
  1246. if (ba == NULL) {
  1247. assert(a != NULL);
  1248. freearc(v->nfa, a);
  1249. } else {
  1250. assert(a == NULL);
  1251. }
  1252. s = newstate(v->nfa);
  1253. NOERR();
  1254. newarc(v->nfa, PLAIN, co, lp, s);
  1255. NOERR();
  1256. pa = findarc(v->mccepbegin, PLAIN, co);
  1257. assert(pa != NULL);
  1258. if (ba == NULL) { /* easy case, need all of them */
  1259. cloneouts(v->nfa, pa->to, s, rp, PLAIN);
  1260. newarc(v->nfa, '$', 1, s, rp);
  1261. newarc(v->nfa, '$', 0, s, rp);
  1262. colorcomplement(v->nfa, v->cm, AHEAD, pa->to, s, rp);
  1263. } else { /* must be selective */
  1264. if (findarc(ba->to, '$', 1) == NULL) {
  1265. newarc(v->nfa, '$', 1, s, rp);
  1266. newarc(v->nfa, '$', 0, s, rp);
  1267. colorcomplement(v->nfa, v->cm, AHEAD, pa->to,
  1268.  s, rp);
  1269. }
  1270. for (pa = pa->to->outs; pa != NULL; pa = pa->outchain)
  1271. if (findarc(ba->to, PLAIN, pa->co) == NULL)
  1272. newarc(v->nfa, PLAIN, pa->co, s, rp);
  1273. if (s->nouts == 0) /* limit of selectivity: none */
  1274. dropstate(v->nfa, s); /* frees arc too */
  1275. }
  1276. NOERR();
  1277. }
  1278. delsub(v->nfa, left, right);
  1279. assert(left->nouts == 0);
  1280. freestate(v->nfa, left);
  1281. assert(right->nins == 0);
  1282. freestate(v->nfa, right);
  1283. }
  1284. /*
  1285.  - brackpart - handle one item (or range) within a bracket expression
  1286.  ^ static VOID brackpart(struct vars *, struct state *, struct state *);
  1287.  */
  1288. static VOID
  1289. brackpart(v, lp, rp)
  1290. struct vars *v;
  1291. struct state *lp;
  1292. struct state *rp;
  1293. {
  1294. celt startc;
  1295. celt endc;
  1296. struct cvec *cv;
  1297. chr *startp;
  1298. chr *endp;
  1299. chr c[1];
  1300. /* parse something, get rid of special cases, take shortcuts */
  1301. switch (v->nexttype) {
  1302. case RANGE: /* a-b-c or other botch */
  1303. ERR(REG_ERANGE);
  1304. return;
  1305. break;
  1306. case PLAIN:
  1307. c[0] = v->nextvalue;
  1308. NEXT();
  1309. /* shortcut for ordinary chr (not range, not MCCE leader) */
  1310. if (!SEE(RANGE) && !ISCELEADER(v, c[0])) {
  1311. onechr(v, c[0], lp, rp);
  1312. return;
  1313. }
  1314. startc = element(v, c, c+1);
  1315. NOERR();
  1316. break;
  1317. case COLLEL:
  1318. startp = v->now;
  1319. endp = scanplain(v);
  1320. INSIST(startp < endp, REG_ECOLLATE);
  1321. NOERR();
  1322. startc = element(v, startp, endp);
  1323. NOERR();
  1324. break;
  1325. case ECLASS:
  1326. startp = v->now;
  1327. endp = scanplain(v);
  1328. INSIST(startp < endp, REG_ECOLLATE);
  1329. NOERR();
  1330. startc = element(v, startp, endp);
  1331. NOERR();
  1332. cv = eclass(v, startc, (v->cflags&REG_ICASE));
  1333. NOERR();
  1334. dovec(v, cv, lp, rp);
  1335. return;
  1336. break;
  1337. case CCLASS:
  1338. startp = v->now;
  1339. endp = scanplain(v);
  1340. INSIST(startp < endp, REG_ECTYPE);
  1341. NOERR();
  1342. cv = cclass(v, startp, endp, (v->cflags&REG_ICASE));
  1343. NOERR();
  1344. dovec(v, cv, lp, rp);
  1345. return;
  1346. break;
  1347. default:
  1348. ERR(REG_ASSERT);
  1349. return;
  1350. break;
  1351. }
  1352. if (SEE(RANGE)) {
  1353. NEXT();
  1354. switch (v->nexttype) {
  1355. case PLAIN:
  1356. case RANGE:
  1357. c[0] = v->nextvalue;
  1358. NEXT();
  1359. endc = element(v, c, c+1);
  1360. NOERR();
  1361. break;
  1362. case COLLEL:
  1363. startp = v->now;
  1364. endp = scanplain(v);
  1365. INSIST(startp < endp, REG_ECOLLATE);
  1366. NOERR();
  1367. endc = element(v, startp, endp);
  1368. NOERR();
  1369. break;
  1370. default:
  1371. ERR(REG_ERANGE);
  1372. return;
  1373. break;
  1374. }
  1375. } else
  1376. endc = startc;
  1377. /*
  1378.  * Ranges are unportable.  Actually, standard C does
  1379.  * guarantee that digits are contiguous, but making
  1380.  * that an exception is just too complicated.
  1381.  */
  1382. if (startc != endc)
  1383. NOTE(REG_UUNPORT);
  1384. cv = range(v, startc, endc, (v->cflags&REG_ICASE));
  1385. NOERR();
  1386. dovec(v, cv, lp, rp);
  1387. }
  1388. /*
  1389.  - scanplain - scan PLAIN contents of [. etc.
  1390.  * Certain bits of trickery in lex.c know that this code does not try
  1391.  * to look past the final bracket of the [. etc.
  1392.  ^ static chr *scanplain(struct vars *);
  1393.  */
  1394. static chr * /* just after end of sequence */
  1395. scanplain(v)
  1396. struct vars *v;
  1397. {
  1398. chr *endp;
  1399. assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
  1400. NEXT();
  1401. endp = v->now;
  1402. while (SEE(PLAIN)) {
  1403. endp = v->now;
  1404. NEXT();
  1405. }
  1406. assert(SEE(END) || ISERR());
  1407. NEXT();
  1408. return endp;
  1409. }
  1410. /*
  1411.  - leaders - process a cvec of collating elements to also include leaders
  1412.  * Also gives all characters involved their own colors, which is almost
  1413.  * certainly necessary, and sets up little disconnected subNFA.
  1414.  ^ static VOID leaders(struct vars *, struct cvec *);
  1415.  */
  1416. static VOID
  1417. leaders(v, cv)
  1418. struct vars *v;
  1419. struct cvec *cv;
  1420. {
  1421. int mcce;
  1422. chr *p;
  1423. chr leader;
  1424. struct state *s;
  1425. struct arc *a;
  1426. v->mccepbegin = newstate(v->nfa);
  1427. v->mccepend = newstate(v->nfa);
  1428. NOERR();
  1429. for (mcce = 0; mcce < cv->nmcces; mcce++) {
  1430. p = cv->mcces[mcce];
  1431. leader = *p;
  1432. if (!haschr(cv, leader)) {
  1433. addchr(cv, leader);
  1434. s = newstate(v->nfa);
  1435. newarc(v->nfa, PLAIN, subcolor(v->cm, leader),
  1436. v->mccepbegin, s);
  1437. okcolors(v->nfa, v->cm);
  1438. } else {
  1439. a = findarc(v->mccepbegin, PLAIN,
  1440. GETCOLOR(v->cm, leader));
  1441. assert(a != NULL);
  1442. s = a->to;
  1443. assert(s != v->mccepend);
  1444. }
  1445. p++;
  1446. assert(*p != 0 && *(p+1) == 0); /* only 2-char MCCEs for now */
  1447. newarc(v->nfa, PLAIN, subcolor(v->cm, *p), s, v->mccepend);
  1448. okcolors(v->nfa, v->cm);
  1449. }
  1450. }
  1451. /*
  1452.  - onechr - fill in arcs for a plain character, and possible case complements
  1453.  * This is mostly a shortcut for efficient handling of the common case.
  1454.  ^ static VOID onechr(struct vars *, pchr, struct state *, struct state *);
  1455.  */
  1456. static VOID
  1457. onechr(v, c, lp, rp)
  1458. struct vars *v;
  1459. pchr c;
  1460. struct state *lp;
  1461. struct state *rp;
  1462. {
  1463. if (!(v->cflags&REG_ICASE)) {
  1464. newarc(v->nfa, PLAIN, subcolor(v->cm, c), lp, rp);
  1465. return;
  1466. }
  1467. /* rats, need general case anyway... */
  1468. dovec(v, allcases(v, c), lp, rp);
  1469. }
  1470. /*
  1471.  - dovec - fill in arcs for each element of a cvec
  1472.  * This one has to handle the messy cases, like MCCEs and MCCE leaders.
  1473.  ^ static VOID dovec(struct vars *, struct cvec *, struct state *,
  1474.  ^  struct state *);
  1475.  */
  1476. static VOID
  1477. dovec(v, cv, lp, rp)
  1478. struct vars *v;
  1479. struct cvec *cv;
  1480. struct state *lp;
  1481. struct state *rp;
  1482. {
  1483. chr ch, from, to;
  1484. celt ce;
  1485. chr *p;
  1486. int i;
  1487. color co;
  1488. struct cvec *leads;
  1489. struct arc *a;
  1490. struct arc *pa; /* arc in prototype */
  1491. struct state *s;
  1492. struct state *ps; /* state in prototype */
  1493. /* need a place to store leaders, if any */
  1494. if (nmcces(v) > 0) {
  1495. assert(v->mcces != NULL);
  1496. if (v->cv2 == NULL || v->cv2->nchrs < v->mcces->nchrs) {
  1497. if (v->cv2 != NULL)
  1498. free(v->cv2);
  1499. v->cv2 = newcvec(v->mcces->nchrs, 0, v->mcces->nmcces);
  1500. NOERR();
  1501. leads = v->cv2;
  1502. } else
  1503. leads = clearcvec(v->cv2);
  1504. } else
  1505. leads = NULL;
  1506. /* first, get the ordinary characters out of the way */
  1507. for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
  1508. ch = *p;
  1509. if (!ISCELEADER(v, ch))
  1510. newarc(v->nfa, PLAIN, subcolor(v->cm, ch), lp, rp);
  1511. else {
  1512. assert(singleton(v->cm, ch));
  1513. assert(leads != NULL);
  1514. if (!haschr(leads, ch))
  1515. addchr(leads, ch);
  1516. }
  1517. }
  1518. /* and the ranges */
  1519. for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
  1520. from = *p;
  1521. to = *(p+1);
  1522. while (from <= to && (ce = nextleader(v, from, to)) != NOCELT) {
  1523. if (from < ce)
  1524. subrange(v, from, ce - 1, lp, rp);
  1525. assert(singleton(v->cm, ce));
  1526. assert(leads != NULL);
  1527. if (!haschr(leads, ce))
  1528. addchr(leads, ce);
  1529. from = ce + 1;
  1530. }
  1531. if (from <= to)
  1532. subrange(v, from, to, lp, rp);
  1533. }
  1534. if ((leads == NULL || leads->nchrs == 0) && cv->nmcces == 0)
  1535. return;
  1536. /* deal with the MCCE leaders */
  1537. NOTE(REG_ULOCALE);
  1538. for (p = leads->chrs, i = leads->nchrs; i > 0; p++, i--) {
  1539. co = GETCOLOR(v->cm, *p);
  1540. a = findarc(lp, PLAIN, co);
  1541. if (a != NULL)
  1542. s = a->to;
  1543. else {
  1544. s = newstate(v->nfa);
  1545. NOERR();
  1546. newarc(v->nfa, PLAIN, co, lp, s);
  1547. NOERR();
  1548. }
  1549. pa = findarc(v->mccepbegin, PLAIN, co);
  1550. assert(pa != NULL);
  1551. ps = pa->to;
  1552. newarc(v->nfa, '$', 1, s, rp);
  1553. newarc(v->nfa, '$', 0, s, rp);
  1554. colorcomplement(v->nfa, v->cm, AHEAD, ps, s, rp);
  1555. NOERR();
  1556. }
  1557. /* and the MCCEs */
  1558. for (i = 0; i < cv->nmcces; i++) {
  1559. p = cv->mcces[i];
  1560. assert(singleton(v->cm, *p));
  1561. if (!singleton(v->cm, *p)) {
  1562. ERR(REG_ASSERT);
  1563. return;
  1564. }
  1565. ch = *p++;
  1566. co = GETCOLOR(v->cm, ch);
  1567. a = findarc(lp, PLAIN, co);
  1568. if (a != NULL)
  1569. s = a->to;
  1570. else {
  1571. s = newstate(v->nfa);
  1572. NOERR();
  1573. newarc(v->nfa, PLAIN, co, lp, s);
  1574. NOERR();
  1575. }
  1576. assert(*p != 0); /* at least two chars */
  1577. assert(singleton(v->cm, *p));
  1578. ch = *p++;
  1579. co = GETCOLOR(v->cm, ch);
  1580. assert(*p == 0); /* and only two, for now */
  1581. newarc(v->nfa, PLAIN, co, s, rp);
  1582. NOERR();
  1583. }
  1584. }
  1585. /*
  1586.  - nextleader - find next MCCE leader within range
  1587.  ^ static celt nextleader(struct vars *, pchr, pchr);
  1588.  */
  1589. static celt /* NOCELT means none */
  1590. nextleader(v, from, to)
  1591. struct vars *v;
  1592. pchr from;
  1593. pchr to;
  1594. {
  1595. int i;
  1596. chr *p;
  1597. chr ch;
  1598. celt it = NOCELT;
  1599. if (v->mcces == NULL)
  1600. return it;
  1601. for (i = v->mcces->nchrs, p = v->mcces->chrs; i > 0; i--, p++) {
  1602. ch = *p;
  1603. if (from <= ch && ch <= to)
  1604. if (it == NOCELT || ch < it)
  1605. it = ch;
  1606. }
  1607. return it;
  1608. }
  1609. /*
  1610.  - wordchrs - set up word-chr list for word-boundary stuff, if needed
  1611.  * The list is kept as a bunch of arcs between two dummy states; it's
  1612.  * disposed of by the unreachable-states sweep in NFA optimization.
  1613.  * Does NEXT().  Must not be called from any unusual lexical context.
  1614.  * This should be reconciled with the w etc. handling in lex.c, and
  1615.  * should be cleaned up to reduce dependencies on input scanning.
  1616.  ^ static VOID wordchrs(struct vars *);
  1617.  */
  1618. static VOID
  1619. wordchrs(v)
  1620. struct vars *v;
  1621. {
  1622. struct state *left;
  1623. struct state *right;
  1624. if (v->wordchrs != NULL) {
  1625. NEXT(); /* for consistency */
  1626. return;
  1627. }
  1628. left = newstate(v->nfa);
  1629. right = newstate(v->nfa);
  1630. NOERR();
  1631. /* fine point:  implemented with [::], and lexer will set REG_ULOCALE */
  1632. lexword(v);
  1633. NEXT();
  1634. assert(v->savenow != NULL && SEE('['));
  1635. bracket(v, left, right);
  1636. assert((v->savenow != NULL && SEE(']')) || ISERR());
  1637. NEXT();
  1638. NOERR();
  1639. v->wordchrs = left;
  1640. }
  1641. /*
  1642.  - subre - allocate a subre
  1643.  ^ static struct subre *subre(struct vars *, int, int, struct state *,
  1644.  ^ struct state *);
  1645.  */
  1646. static struct subre *
  1647. subre(v, op, flags, begin, end)
  1648. struct vars *v;
  1649. int op;
  1650. int flags;
  1651. struct state *begin;
  1652. struct state *end;
  1653. {
  1654. struct subre *ret;
  1655. ret = v->treefree;
  1656. if (ret != NULL)
  1657. v->treefree = ret->left;
  1658. else {
  1659. ret = (struct subre *)MALLOC(sizeof(struct subre));
  1660. if (ret == NULL) {
  1661. ERR(REG_ESPACE);
  1662. return NULL;
  1663. }
  1664. ret->chain = v->treechain;
  1665. v->treechain = ret;
  1666. }
  1667. assert(strchr("|.b(=", op) != NULL);
  1668. ret->op = op;
  1669. ret->flags = flags;
  1670. ret->retry = 0;
  1671. ret->subno = 0;
  1672. ret->min = ret->max = 1;
  1673. ret->left = NULL;
  1674. ret->right = NULL;
  1675. ret->begin = begin;
  1676. ret->end = end;
  1677. ZAPCNFA(ret->cnfa);
  1678. return ret;
  1679. }
  1680. /*
  1681.  - freesubre - free a subRE subtree
  1682.  ^ static VOID freesubre(struct vars *, struct subre *);
  1683.  */
  1684. static VOID
  1685. freesubre(v, sr)
  1686. struct vars *v; /* might be NULL */
  1687. struct subre *sr;
  1688. {
  1689. if (sr == NULL)
  1690. return;
  1691. if (sr->left != NULL)
  1692. freesubre(v, sr->left);
  1693. if (sr->right != NULL)
  1694. freesubre(v, sr->right);
  1695. freesrnode(v, sr);
  1696. }
  1697. /*
  1698.  - freesrnode - free one node in a subRE subtree
  1699.  ^ static VOID freesrnode(struct vars *, struct subre *);
  1700.  */
  1701. static VOID
  1702. freesrnode(v, sr)
  1703. struct vars *v; /* might be NULL */
  1704. struct subre *sr;
  1705. {
  1706. if (sr == NULL)
  1707. return;
  1708. if (!NULLCNFA(sr->cnfa))
  1709. freecnfa(&sr->cnfa);
  1710. sr->flags = 0;
  1711. if (v != NULL) {
  1712. sr->left = v->treefree;
  1713. v->treefree = sr;
  1714. } else
  1715. FREE(sr);
  1716. }
  1717. /*
  1718.  - optst - optimize a subRE subtree
  1719.  ^ static VOID optst(struct vars *, struct subre *);
  1720.  */
  1721. static VOID
  1722. optst(v, t)
  1723. struct vars *v;
  1724. struct subre *t;
  1725. {
  1726.     /*
  1727.      * DGP (2007-11-13): I assume it was the programmer's intent to eventually
  1728.      * come back and add code to optimize subRE trees, but the routine coded
  1729.      * just spent effort traversing the tree and doing nothing. We can do
  1730.      * nothing with less effort.
  1731.      */
  1732.     return;
  1733. }
  1734. /*
  1735.  - numst - number tree nodes (assigning retry indexes)
  1736.  ^ static int numst(struct subre *, int);
  1737.  */
  1738. static int /* next number */
  1739. numst(t, start)
  1740. struct subre *t;
  1741. int start; /* starting point for subtree numbers */
  1742. {
  1743. int i;
  1744. assert(t != NULL);
  1745. i = start;
  1746. t->retry = (short)i++;
  1747. if (t->left != NULL)
  1748. i = numst(t->left, i);
  1749. if (t->right != NULL)
  1750. i = numst(t->right, i);
  1751. return i;
  1752. }
  1753. /*
  1754.  - markst - mark tree nodes as INUSE
  1755.  ^ static VOID markst(struct subre *);
  1756.  */
  1757. static VOID
  1758. markst(t)
  1759. struct subre *t;
  1760. {
  1761. assert(t != NULL);
  1762. t->flags |= INUSE;
  1763. if (t->left != NULL)
  1764. markst(t->left);
  1765. if (t->right != NULL)
  1766. markst(t->right);
  1767. }
  1768. /*
  1769.  - cleanst - free any tree nodes not marked INUSE
  1770.  ^ static VOID cleanst(struct vars *);
  1771.  */
  1772. static VOID
  1773. cleanst(v)
  1774. struct vars *v;
  1775. {
  1776. struct subre *t;
  1777. struct subre *next;
  1778. for (t = v->treechain; t != NULL; t = next) {
  1779. next = t->chain;
  1780. if (!(t->flags&INUSE))
  1781. FREE(t);
  1782. }
  1783. v->treechain = NULL;
  1784. v->treefree = NULL; /* just on general principles */
  1785. }
  1786. /*
  1787.  - nfatree - turn a subRE subtree into a tree of compacted NFAs
  1788.  ^ static long nfatree(struct vars *, struct subre *, FILE *);
  1789.  */
  1790. static long /* optimize results from top node */
  1791. nfatree(v, t, f)
  1792. struct vars *v;
  1793. struct subre *t;
  1794. FILE *f; /* for debug output */
  1795. {
  1796. assert(t != NULL && t->begin != NULL);
  1797. if (t->left != NULL)
  1798. (DISCARD)nfatree(v, t->left, f);
  1799. if (t->right != NULL)
  1800. (DISCARD)nfatree(v, t->right, f);
  1801. return nfanode(v, t, f);
  1802. }
  1803. /*
  1804.  - nfanode - do one NFA for nfatree
  1805.  ^ static long nfanode(struct vars *, struct subre *, FILE *);
  1806.  */
  1807. static long /* optimize results */
  1808. nfanode(v, t, f)
  1809. struct vars *v;
  1810. struct subre *t;
  1811. FILE *f; /* for debug output */
  1812. {
  1813. struct nfa *nfa;
  1814. long ret = 0;
  1815. char idbuf[50];
  1816. assert(t->begin != NULL);
  1817. if (f != NULL)
  1818. fprintf(f, "nnn========= TREE NODE %s ==========n",
  1819. stid(t, idbuf, sizeof(idbuf)));
  1820. nfa = newnfa(v, v->cm, v->nfa);
  1821. NOERRZ();
  1822. dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
  1823. if (!ISERR()) {
  1824. specialcolors(nfa);
  1825. ret = optimize(nfa, f);
  1826. }
  1827. if (!ISERR())
  1828. compact(nfa, &t->cnfa);
  1829. freenfa(nfa);
  1830. return ret;
  1831. }
  1832. /*
  1833.  - newlacon - allocate a lookahead-constraint subRE
  1834.  ^ static int newlacon(struct vars *, struct state *, struct state *, int);
  1835.  */
  1836. static int /* lacon number */
  1837. newlacon(v, begin, end, pos)
  1838. struct vars *v;
  1839. struct state *begin;
  1840. struct state *end;
  1841. int pos;
  1842. {
  1843. int n;
  1844. struct subre *sub;
  1845. if (v->nlacons == 0) {
  1846. v->lacons = (struct subre *)MALLOC(2 * sizeof(struct subre));
  1847. n = 1; /* skip 0th */
  1848. v->nlacons = 2;
  1849. } else {
  1850. v->lacons = (struct subre *)REALLOC(v->lacons,
  1851. (v->nlacons+1)*sizeof(struct subre));
  1852. n = v->nlacons++;
  1853. }
  1854. if (v->lacons == NULL) {
  1855. ERR(REG_ESPACE);
  1856. return 0;
  1857. }
  1858. sub = &v->lacons[n];
  1859. sub->begin = begin;
  1860. sub->end = end;
  1861. sub->subno = pos;
  1862. ZAPCNFA(sub->cnfa);
  1863. return n;
  1864. }
  1865. /*
  1866.  - freelacons - free lookahead-constraint subRE vector
  1867.  ^ static VOID freelacons(struct subre *, int);
  1868.  */
  1869. static VOID
  1870. freelacons(subs, n)
  1871. struct subre *subs;
  1872. int n;
  1873. {
  1874. struct subre *sub;
  1875. int i;
  1876. assert(n > 0);
  1877. for (sub = subs + 1, i = n - 1; i > 0; sub++, i--) /* no 0th */
  1878. if (!NULLCNFA(sub->cnfa))
  1879. freecnfa(&sub->cnfa);
  1880. FREE(subs);
  1881. }
  1882. /*
  1883.  - rfree - free a whole RE (insides of regfree)
  1884.  ^ static VOID rfree(regex_t *);
  1885.  */
  1886. static VOID
  1887. rfree(re)
  1888. regex_t *re;
  1889. {
  1890. struct guts *g;
  1891. if (re == NULL || re->re_magic != REMAGIC)
  1892. return;
  1893. re->re_magic = 0; /* invalidate RE */
  1894. g = (struct guts *)re->re_guts;
  1895. re->re_guts = NULL;
  1896. re->re_fns = NULL;
  1897. g->magic = 0;
  1898. freecm(&g->cmap);
  1899. if (g->tree != NULL)
  1900. freesubre((struct vars *)NULL, g->tree);
  1901. if (g->lacons != NULL)
  1902. freelacons(g->lacons, g->nlacons);
  1903. if (!NULLCNFA(g->search))
  1904. freecnfa(&g->search);
  1905. FREE(g);
  1906. }
  1907. /*
  1908.  - dump - dump an RE in human-readable form
  1909.  ^ static VOID dump(regex_t *, FILE *);
  1910.  */
  1911. static VOID
  1912. dump(re, f)
  1913. regex_t *re;
  1914. FILE *f;
  1915. {
  1916. #ifdef REG_DEBUG
  1917. struct guts *g;
  1918. int i;
  1919. if (re->re_magic != REMAGIC)
  1920. fprintf(f, "bad magic number (0x%x not 0x%x)n", re->re_magic,
  1921. REMAGIC);
  1922. if (re->re_guts == NULL) {
  1923. fprintf(f, "NULL guts!!!n");
  1924. return;
  1925. }
  1926. g = (struct guts *)re->re_guts;
  1927. if (g->magic != GUTSMAGIC)
  1928. fprintf(f, "bad guts magic number (0x%x not 0x%x)n", g->magic,
  1929. GUTSMAGIC);
  1930. fprintf(f, "nnn========= DUMP ==========n");
  1931. fprintf(f, "nsub %d, info 0%lo, csize %d, ntree %dn", 
  1932. re->re_nsub, re->re_info, re->re_csize, g->ntree);
  1933. dumpcolors(&g->cmap, f);
  1934. if (!NULLCNFA(g->search)) {
  1935. printf("nsearch:n");
  1936. dumpcnfa(&g->search, f);
  1937. }
  1938. for (i = 1; i < g->nlacons; i++) {
  1939. fprintf(f, "nla%d (%s):n", i,
  1940. (g->lacons[i].subno) ? "positive" : "negative");
  1941. dumpcnfa(&g->lacons[i].cnfa, f);
  1942. }
  1943. fprintf(f, "n");
  1944. dumpst(g->tree, f, 0);
  1945. #endif
  1946. }
  1947. /*
  1948.  - dumpst - dump a subRE tree
  1949.  ^ static VOID dumpst(struct subre *, FILE *, int);
  1950.  */
  1951. static VOID
  1952. dumpst(t, f, nfapresent)
  1953. struct subre *t;
  1954. FILE *f;
  1955. int nfapresent; /* is the original NFA still around? */
  1956. {
  1957. if (t == NULL)
  1958. fprintf(f, "null treen");
  1959. else
  1960. stdump(t, f, nfapresent);
  1961. fflush(f);
  1962. }
  1963. /*
  1964.  - stdump - recursive guts of dumpst
  1965.  ^ static VOID stdump(struct subre *, FILE *, int);
  1966.  */
  1967. static VOID
  1968. stdump(t, f, nfapresent)
  1969. struct subre *t;
  1970. FILE *f;
  1971. int nfapresent; /* is the original NFA still around? */
  1972. {
  1973. char idbuf[50];
  1974. fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op);
  1975. if (t->flags&LONGER)
  1976. fprintf(f, " longest");
  1977. if (t->flags&SHORTER)
  1978. fprintf(f, " shortest");
  1979. if (t->flags&MIXED)
  1980. fprintf(f, " hasmixed");
  1981. if (t->flags&CAP)
  1982. fprintf(f, " hascapture");
  1983. if (t->flags&BACKR)
  1984. fprintf(f, " hasbackref");
  1985. if (!(t->flags&INUSE))
  1986. fprintf(f, " UNUSED");
  1987. if (t->subno != 0)
  1988. fprintf(f, " (#%d)", t->subno);
  1989. if (t->min != 1 || t->max != 1) {
  1990. fprintf(f, " {%d,", t->min);
  1991. if (t->max != INFINITY)
  1992. fprintf(f, "%d", t->max);
  1993. fprintf(f, "}");
  1994. }
  1995. if (nfapresent)
  1996. fprintf(f, " %ld-%ld", (long)t->begin->no, (long)t->end->no);
  1997. if (t->left != NULL)
  1998. fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf)));
  1999. if (t->right != NULL)
  2000. fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf)));
  2001. if (!NULLCNFA(t->cnfa)) {
  2002. fprintf(f, "n");
  2003. dumpcnfa(&t->cnfa, f);
  2004. }
  2005. fprintf(f, "n");
  2006. if (t->left != NULL)
  2007. stdump(t->left, f, nfapresent);
  2008. if (t->right != NULL)
  2009. stdump(t->right, f, nfapresent);
  2010. }
  2011. /*
  2012.  - stid - identify a subtree node for dumping
  2013.  ^ static char *stid(struct subre *, char *, size_t);
  2014.  */
  2015. static char * /* points to buf or constant string */
  2016. stid(t, buf, bufsize)
  2017. struct subre *t;
  2018. char *buf;
  2019. size_t bufsize;
  2020. {
  2021. /* big enough for hex int or decimal t->retry? */
  2022. if (bufsize < sizeof(void*)*2 + 3 || bufsize < sizeof(t->retry)*3 + 1)
  2023. return "unable";
  2024. if (t->retry != 0)
  2025. sprintf(buf, "%d", t->retry);
  2026. else
  2027. sprintf(buf, "%p", t);
  2028. return buf;
  2029. }
  2030. #include "regc_lex.c"
  2031. #include "regc_color.c"
  2032. #include "regc_nfa.c"
  2033. #include "regc_cvec.c"
  2034. #include "regc_locale.c"