home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / vim / part18 < prev    next >
Encoding:
Text File  |  1993-04-23  |  42.3 KB  |  1,728 lines

  1. Newsgroups: comp.sources.misc
  2. From: mool@oce.nl (Bram Moolenaar)
  3. Subject: v37i018:  vim - Vi IMitation editor v1.27, Part18/24
  4. Message-ID: <1993Apr25.013639.22856@sparky.imd.sterling.com>
  5. X-Md4-Signature: 2a12ed451ab909fd6aeb8a60fff1fbd3
  6. Date: Sun, 25 Apr 1993 01:36:39 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: mool@oce.nl (Bram Moolenaar)
  10. Posting-number: Volume 37, Issue 18
  11. Archive-name: vim/part18
  12. Environment: UNIX, AMIGA, MS-DOS
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 18 (of 23)."
  21. # Contents:  vim/src/regexp.c
  22. # Wrapped by mool@oce-rd2 on Mon Apr 19 15:50:12 1993
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'vim/src/regexp.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'vim/src/regexp.c'\"
  26. else
  27. echo shar: Extracting \"'vim/src/regexp.c'\" \(39338 characters\)
  28. sed "s/^X//" >'vim/src/regexp.c' <<'END_OF_FILE'
  29. X/* vi:ts=4:sw=4
  30. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  31. X *
  32. X * This is NOT the original regular expression code as written by
  33. X * Henry Spencer. This code has been modified specifically for use
  34. X * with the VIM editor, and should not be used apart from compiling
  35. X * VIM. If you want a good regular expression library, get the
  36. X * original code. The copyright notice that follows is from the
  37. X * original.
  38. X *
  39. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  40. X *
  41. X *
  42. X * regcomp and regexec -- regsub and regerror are elsewhere
  43. X *
  44. X *        Copyright (c) 1986 by University of Toronto.
  45. X *        Written by Henry Spencer.  Not derived from licensed software.
  46. X *
  47. X *        Permission is granted to anyone to use this software for any
  48. X *        purpose on any computer system, and to redistribute it freely,
  49. X *        subject to the following restrictions:
  50. X *
  51. X *        1. The author is not responsible for the consequences of use of
  52. X *                this software, no matter how awful, even if they arise
  53. X *                from defects in it.
  54. X *
  55. X *        2. The origin of this software must not be misrepresented, either
  56. X *                by explicit claim or by omission.
  57. X *
  58. X *        3. Altered versions must be plainly marked as such, and must not
  59. X *                be misrepresented as being the original software.
  60. X *
  61. X * Beware that some of this code is subtly aware of the way operator
  62. X * precedence is structured in regular expressions.  Serious changes in
  63. X * regular-expression syntax might require a total rethink.
  64. X *
  65. X * $Log:        regexp.c,v $
  66. X * Revision 1.2  88/04/28  08:09:45  tony
  67. X * First modification of the regexp library. Added an external variable
  68. X * 'reg_ic' which can be set to indicate that case should be ignored.
  69. X * Added a new parameter to regexec() to indicate that the given string
  70. X * comes from the beginning of a line and is thus eligible to match
  71. X * 'beginning-of-line'.
  72. X *
  73. X * Revisions by Olaf 'Rhialto' Seibert, rhialto@cs.kun.nl:
  74. X * Changes for vi: (the semantics of several things were rather different)
  75. X * - Added lexical analyzer, because in vi magicness of characters
  76. X *   is rather difficult, and may change over time.
  77. X * - Added support for \< \> \1-\9 and ~
  78. X * - Left some magic stuff in, but only backslashed: \| \+
  79. X * - * and \+ still work after \) even though they shouldn't.
  80. X */
  81. X#include "vim.h"
  82. X#include "globals.h"
  83. X#include "proto.h"
  84. X#undef DEBUG
  85. X
  86. X#include <stdio.h>
  87. X#include "regexp.h"
  88. X#include "regmagic.h"
  89. X
  90. X/*
  91. X * The "internal use only" fields in regexp.h are present to pass info from
  92. X * compile to execute that permits the execute phase to run lots faster on
  93. X * simple cases.  They are:
  94. X *
  95. X * regstart     char that must begin a match; '\0' if none obvious
  96. X * reganch        is the match anchored (at beginning-of-line only)?
  97. X * regmust        string (pointer into program) that match must include, or NULL
  98. X * regmlen        length of regmust string
  99. X *
  100. X * Regstart and reganch permit very fast decisions on suitable starting points
  101. X * for a match, cutting down the work a lot.  Regmust permits fast rejection
  102. X * of lines that cannot possibly match.  The regmust tests are costly enough
  103. X * that regcomp() supplies a regmust only if the r.e. contains something
  104. X * potentially expensive (at present, the only such thing detected is * or +
  105. X * at the start of the r.e., which can involve a lot of backup).  Regmlen is
  106. X * supplied because the test in regexec() needs it and regcomp() is computing
  107. X * it anyway.
  108. X */
  109. X
  110. X/*
  111. X * Structure for regexp "program".    This is essentially a linear encoding
  112. X * of a nondeterministic finite-state machine (aka syntax charts or
  113. X * "railroad normal form" in parsing technology).  Each node is an opcode
  114. X * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
  115. X * all nodes except BRANCH implement concatenation; a "next" pointer with
  116. X * a BRANCH on both ends of it is connecting two alternatives.    (Here we
  117. X * have one of the subtle syntax dependencies:    an individual BRANCH (as
  118. X * opposed to a collection of them) is never concatenated with anything
  119. X * because of operator precedence.)  The operand of some types of node is
  120. X * a literal string; for others, it is a node leading into a sub-FSM.  In
  121. X * particular, the operand of a BRANCH node is the first node of the branch.
  122. X * (NB this is *not* a tree structure:    the tail of the branch connects
  123. X * to the thing following the set of BRANCHes.)  The opcodes are:
  124. X */
  125. X
  126. X/* definition    number               opnd?    meaning */
  127. X#define END     0                /* no    End of program. */
  128. X#define BOL     1                /* no    Match "" at beginning of line. */
  129. X#define EOL     2                /* no    Match "" at end of line. */
  130. X#define ANY     3                /* no    Match any one character. */
  131. X#define ANYOF    4                /* str    Match any character in this string. */
  132. X#define ANYBUT    5                /* str    Match any character not in this
  133. X                                 *        string. */
  134. X#define BRANCH    6                /* node Match this alternative, or the
  135. X                                 *        next... */
  136. X#define BACK    7                /* no    Match "", "next" ptr points backward. */
  137. X#define EXACTLY 8                /* str    Match this string. */
  138. X#define NOTHING 9                /* no    Match empty string. */
  139. X#define STAR    10                /* node Match this (simple) thing 0 or more
  140. X                                 *        times. */
  141. X#define PLUS    11                /* node Match this (simple) thing 1 or more
  142. X                                 *        times. */
  143. X#define BOW        12                /* no    Match "" after [^a-zA-Z0-9_] */
  144. X#define EOW        13                /* no    Match "" at    [^a-zA-Z0-9_] */
  145. X#define MOPEN    20                /* no    Mark this point in input as start of
  146. X                                 *        #n. */
  147. X /* MOPEN+1 is number 1, etc. */
  148. X#define MCLOSE    30                /* no    Analogous to MOPEN. */
  149. X#define BACKREF    40                /* node Match same string again \1-\9 */
  150. X
  151. X#define Magic(x)    ((x)|('\\'<<8))
  152. X
  153. X/*
  154. X * Opcode notes:
  155. X *
  156. X * BRANCH        The set of branches constituting a single choice are hooked
  157. X *                together with their "next" pointers, since precedence prevents
  158. X *                anything being concatenated to any individual branch.  The
  159. X *                "next" pointer of the last BRANCH in a choice points to the
  160. X *                thing following the whole choice.  This is also where the
  161. X *                final "next" pointer of each individual branch points; each
  162. X *                branch starts with the operand node of a BRANCH node.
  163. X *
  164. X * BACK         Normal "next" pointers all implicitly point forward; BACK
  165. X *                exists to make loop structures possible.
  166. X *
  167. X * STAR,PLUS    '?', and complex '*' and '+', are implemented as circular
  168. X *                BRANCH structures using BACK.  Simple cases (one character
  169. X *                per match) are implemented with STAR and PLUS for speed
  170. X *                and to minimize recursive plunges.
  171. X *
  172. X * MOPEN,MCLOSE    ...are numbered at compile time.
  173. X */
  174. X
  175. X/*
  176. X * A node is one char of opcode followed by two chars of "next" pointer.
  177. X * "Next" pointers are stored as two 8-bit pieces, high order first.  The
  178. X * value is a positive offset from the opcode of the node containing it.
  179. X * An operand, if any, simply follows the node.  (Note that much of the
  180. X * code generation knows about this implicit relationship.)
  181. X *
  182. X * Using two bytes for the "next" pointer is vast overkill for most things,
  183. X * but allows patterns to get big without disasters.
  184. X */
  185. X#define OP(p)    (*(p))
  186. X#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
  187. X#define OPERAND(p)        ((p) + 3)
  188. X
  189. X/*
  190. X * See regmagic.h for one further detail of program structure.
  191. X */
  192. X
  193. X
  194. X/*
  195. X * Utility definitions.
  196. X */
  197. X#ifndef CHARBITS
  198. X#define UCHARAT(p)        ((int)*(unsigned char *)(p))
  199. X#else
  200. X#define UCHARAT(p)        ((int)*(p)&CHARBITS)
  201. X#endif
  202. X
  203. X#define FAIL(m) { emsg(m); return NULL; }
  204. X
  205. Xstatic int ismult __ARGS((int));
  206. X
  207. X    static int
  208. Xismult(c)
  209. X    int c;
  210. X{
  211. X    return (c == Magic('*') || c == Magic('+') || c == Magic('?'));
  212. X}
  213. X
  214. X/*
  215. X * Flags to be passed up and down.
  216. X */
  217. X#define HASWIDTH        01        /* Known never to match null string. */
  218. X#define SIMPLE            02        /* Simple enough to be STAR/PLUS operand. */
  219. X#define SPSTART         04        /* Starts with * or +. */
  220. X#define WORST            0        /* Worst case. */
  221. X
  222. X/*
  223. X * The following supports the ability to ignore case in searches.
  224. X */
  225. X
  226. X#include <ctype.h>
  227. X
  228. Xint             reg_ic = 0;     /* set by callers to ignore case */
  229. X
  230. X/*
  231. X * mkup - convert to upper case IF we're doing caseless compares
  232. X */
  233. X#ifdef __STDC__
  234. X#define mkup(c)         (reg_ic ? toupper(c) : (c))
  235. X#else
  236. X#define mkup(c)         ((reg_ic && islower(c)) ? toupper(c) : (c))
  237. X#endif
  238. X
  239. X/*
  240. X * The following allows empty REs, meaning "the same as the previous RE".
  241. X * per the ed(1) manual.
  242. X */
  243. X/* #define EMPTY_RE */            /* this is done outside of regexp */
  244. X#ifdef EMTY_RE
  245. Xchar           *reg_prev_re;
  246. X#endif
  247. X
  248. X#define TILDE
  249. X#ifdef TILDE
  250. Xchar           *reg_prev_sub;
  251. X#endif
  252. X
  253. X/*
  254. X * This if for vi's "magic" mode. If magic is false, only ^$\ are magic.
  255. X */
  256. X
  257. Xint                reg_magic = 1;
  258. X
  259. X/*
  260. X * Global work variables for regcomp().
  261. X */
  262. X
  263. Xstatic unsigned char    *regparse;    /* Input-scan pointer. */
  264. Xstatic int        regnpar;        /* () count. */
  265. Xstatic char     regdummy;
  266. Xstatic char    *regcode;        /* Code-emit pointer; ®dummy = don't. */
  267. Xstatic long     regsize;        /* Code size. */
  268. Xstatic char   **regendp;        /* Ditto for endp. */
  269. X
  270. X/*
  271. X * META contains all characters that may be magic, except '^' and '$'.
  272. X * This depends on the configuration options TILDE, BACKREF.
  273. X * (could be done simpler for compilers that know string concatenation)
  274. X */
  275. X
  276. X#ifdef TILDE
  277. X# ifdef BACKREF
  278. X       static char META[] = ".[()|?+*<>~123456789";
  279. X# else
  280. X       static char META[] = ".[()|?+*<>~";
  281. X# endif
  282. X#else
  283. X# ifdef BACKREF
  284. X       static char META[] = ".[()|?+*<>123456789";
  285. X# else
  286. X       static char META[] = ".[()|?+*<>";
  287. X# endif
  288. X#endif
  289. X
  290. X/*
  291. X * Forward declarations for regcomp()'s friends.
  292. X */
  293. Xstatic void        initchr __ARGS((unsigned char *));
  294. Xstatic int        getchr __ARGS((void));
  295. Xstatic int        peekchr __ARGS((void));
  296. Xstatic int        peekpeekchr __ARGS((void));
  297. X#define PeekChr() curchr    /* shortcut only when last action was peekchr() */
  298. Xstatic int         curchr;
  299. Xstatic void        skipchr __ARGS((void));
  300. Xstatic void        ungetchr __ARGS((void));
  301. Xstatic char    *reg __ARGS((int, int *));
  302. Xstatic char    *regbranch __ARGS((int *));
  303. Xstatic char    *regpiece __ARGS((int *));
  304. Xstatic char    *regatom __ARGS((int *));
  305. Xstatic char    *regnode __ARGS((int));
  306. Xstatic char    *regnext __ARGS((char *));
  307. Xstatic void     regc __ARGS((int));
  308. Xstatic void     unregc __ARGS((void));
  309. Xstatic void     reginsert __ARGS((int, char *));
  310. Xstatic void     regtail __ARGS((char *, char *));
  311. Xstatic void     regoptail __ARGS((char *, char *));
  312. X
  313. X#undef STRCSPN
  314. X#ifdef STRCSPN
  315. Xstatic int        strcspn __ARGS((const char *, const char *));
  316. X#endif
  317. Xstatic int        cstrncmp __ARGS((char *, char *, int));
  318. X
  319. X/*
  320. X - regcomp - compile a regular expression into internal code
  321. X *
  322. X * We can't allocate space until we know how big the compiled form will be,
  323. X * but we can't compile it (and thus know how big it is) until we've got a
  324. X * place to put the code.  So we cheat:  we compile it twice, once with code
  325. X * generation turned off and size counting turned on, and once "for real".
  326. X * This also means that we don't allocate space until we are sure that the
  327. X * thing really will compile successfully, and we never have to move the
  328. X * code and thus invalidate pointers into it.  (Note that it has to be in
  329. X * one piece because free() must be able to free it all.)
  330. X *
  331. X * Beware that the optimization-preparation code in here knows about some
  332. X * of the structure of the compiled regexp.
  333. X */
  334. X    regexp           *
  335. Xregcomp(exp)
  336. X    char           *exp;
  337. X{
  338. X    register regexp *r;
  339. X    register char  *scan;
  340. X    register char  *longest;
  341. X    register int    len;
  342. X    int             flags;
  343. X/*    extern char    *malloc();*/
  344. X
  345. X    if (exp == NULL) {
  346. X        FAIL(e_null);
  347. X    }
  348. X
  349. X#ifdef EMPTY_RE            /* this is done outside of regexp */
  350. X    if (*exp == '\0') {
  351. X        if (reg_prev_re) {
  352. X            exp = reg_prev_re;
  353. X        } else {
  354. X            FAIL(e_noprevre);
  355. X        }
  356. X    }
  357. X#endif
  358. X
  359. X    /* First pass: determine size, legality. */
  360. X    initchr((unsigned char *)exp);
  361. X    regnpar = 1;
  362. X    regsize = 0L;
  363. X    regcode = ®dummy;
  364. X    regendp = NULL;
  365. X    regc(MAGIC);
  366. X    if (reg(0, &flags) == NULL)
  367. X        return NULL;
  368. X
  369. X    /* Small enough for pointer-storage convention? */
  370. X    if (regsize >= 32767L)        /* Probably could be 65535L. */
  371. X        FAIL(e_toolong);
  372. X
  373. X    /* Allocate space. */
  374. X/*    r = (regexp *) malloc((unsigned) (sizeof(regexp) + regsize));*/
  375. X    r = (regexp *) alloc((unsigned) (sizeof(regexp) + regsize));
  376. X    if (r == NULL)
  377. X        FAIL(e_outofmem);
  378. X
  379. X#ifdef EMPTY_RE            /* this is done outside of regexp */
  380. X    if (exp != reg_prev_re) {
  381. X        free(reg_prev_re);
  382. X        if (reg_prev_re = alloc(strlen(exp) + 1))
  383. X            strcpy(reg_prev_re, exp);
  384. X    }
  385. X#endif
  386. X
  387. X    /* Second pass: emit code. */
  388. X    initchr((unsigned char *)exp);
  389. X    regnpar = 1;
  390. X    regcode = r->program;
  391. X    regendp = r->endp;
  392. X    regc(MAGIC);
  393. X    if (reg(0, &flags) == NULL) {
  394. X        free(r);
  395. X        return NULL;
  396. X    }
  397. X
  398. X    /* Dig out information for optimizations. */
  399. X    r->regstart = '\0';         /* Worst-case defaults. */
  400. X    r->reganch = 0;
  401. X    r->regmust = NULL;
  402. X    r->regmlen = 0;
  403. X    scan = r->program + 1;        /* First BRANCH. */
  404. X    if (OP(regnext(scan)) == END) {     /* Only one top-level choice. */
  405. X        scan = OPERAND(scan);
  406. X
  407. X        /* Starting-point info. */
  408. X        if (OP(scan) == EXACTLY)
  409. X            r->regstart = *OPERAND(scan);
  410. X        else if (OP(scan) == BOL)
  411. X            r->reganch++;
  412. X
  413. X        /*
  414. X         * If there's something expensive in the r.e., find the longest
  415. X         * literal string that must appear and make it the regmust.  Resolve
  416. X         * ties in favor of later strings, since the regstart check works
  417. X         * with the beginning of the r.e. and avoiding duplication
  418. X         * strengthens checking.  Not a strong reason, but sufficient in the
  419. X         * absence of others.
  420. X         */
  421. X        if (flags & SPSTART) {
  422. X            longest = NULL;
  423. X            len = 0;
  424. X            for (; scan != NULL; scan = regnext(scan))
  425. X                if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= (size_t)len) {
  426. X                    longest = OPERAND(scan);
  427. X                    len = strlen(OPERAND(scan));
  428. X                }
  429. X            r->regmust = longest;
  430. X            r->regmlen = len;
  431. X        }
  432. X    }
  433. X#ifdef DEBUG
  434. X    regdump(r);
  435. X#endif
  436. X    return r;
  437. X}
  438. X
  439. X/*
  440. X - reg - regular expression, i.e. main body or parenthesized thing
  441. X *
  442. X * Caller must absorb opening parenthesis.
  443. X *
  444. X * Combining parenthesis handling with the base level of regular expression
  445. X * is a trifle forced, but the need to tie the tails of the branches to what
  446. X * follows makes it hard to avoid.
  447. X */
  448. X    static char *
  449. Xreg(paren, flagp)
  450. X    int             paren;        /* Parenthesized? */
  451. X    int            *flagp;
  452. X{
  453. X    register char  *ret;
  454. X    register char  *br;
  455. X    register char  *ender;
  456. X    register int    parno = 0;
  457. X    int             flags;
  458. X
  459. X    *flagp = HASWIDTH;            /* Tentatively. */
  460. X
  461. X    /* Make an MOPEN node, if parenthesized. */
  462. X    if (paren) {
  463. X        if (regnpar >= NSUBEXP)
  464. X            FAIL(e_toombra);
  465. X        parno = regnpar;
  466. X        regnpar++;
  467. X        ret = regnode((char)(MOPEN + parno));
  468. X        if (regendp)
  469. X            regendp[parno] = NULL;    /* haven't seen the close paren yet */
  470. X    } else
  471. X        ret = NULL;
  472. X
  473. X    /* Pick up the branches, linking them together. */
  474. X    br = regbranch(&flags);
  475. X    if (br == NULL)
  476. X        return NULL;
  477. X    if (ret != NULL)
  478. X        regtail(ret, br);        /* MOPEN -> first. */
  479. X    else
  480. X        ret = br;
  481. X    if (!(flags & HASWIDTH))
  482. X        *flagp &= ~HASWIDTH;
  483. X    *flagp |= flags & SPSTART;
  484. X    while (peekchr() == Magic('|')) {
  485. X        skipchr();
  486. X        br = regbranch(&flags);
  487. X        if (br == NULL)
  488. X            return NULL;
  489. X        regtail(ret, br);        /* BRANCH -> BRANCH. */
  490. X        if (!(flags & HASWIDTH))
  491. X            *flagp &= ~HASWIDTH;
  492. X        *flagp |= flags & SPSTART;
  493. X    }
  494. X
  495. X    /* Make a closing node, and hook it on the end. */
  496. X    ender = regnode((char)((paren) ? MCLOSE + parno : END));
  497. X    regtail(ret, ender);
  498. X
  499. X    /* Hook the tails of the branches to the closing node. */
  500. X    for (br = ret; br != NULL; br = regnext(br))
  501. X        regoptail(br, ender);
  502. X
  503. X    /* Check for proper termination. */
  504. X    if (paren && getchr() != Magic(')')) {
  505. X        FAIL(e_toombra);
  506. X    } else if (!paren && peekchr() != '\0') {
  507. X        if (PeekChr() == Magic(')')) {
  508. X            FAIL(e_toomket);
  509. X        } else
  510. X            FAIL(e_trailing);/* "Can't happen". */
  511. X        /* NOTREACHED */
  512. X    }
  513. X    /*
  514. X     * Here we set the flag allowing back references to this set of
  515. X     * parentheses.
  516. X     */
  517. X    if (paren && regendp)
  518. X        regendp[parno] = ender;    /* have seen the close paren */
  519. X    return ret;
  520. X}
  521. X
  522. X/*
  523. X - regbranch - one alternative of an | operator
  524. X *
  525. X * Implements the concatenation operator.
  526. X */
  527. X    static char    *
  528. Xregbranch(flagp)
  529. X    int            *flagp;
  530. X{
  531. X    register char  *ret;
  532. X    register char  *chain;
  533. X    register char  *latest;
  534. X    int             flags;
  535. X
  536. X    *flagp = WORST;             /* Tentatively. */
  537. X
  538. X    ret = regnode(BRANCH);
  539. X    chain = NULL;
  540. X    while (peekchr() != '\0' && PeekChr() != Magic('|') && PeekChr() != Magic(')')) {
  541. X        latest = regpiece(&flags);
  542. X        if (latest == NULL)
  543. X            return NULL;
  544. X        *flagp |= flags & HASWIDTH;
  545. X        if (chain == NULL)        /* First piece. */
  546. X            *flagp |= flags & SPSTART;
  547. X        else
  548. X            regtail(chain, latest);
  549. X        chain = latest;
  550. X    }
  551. X    if (chain == NULL)            /* Loop ran zero times. */
  552. X        (void) regnode(NOTHING);
  553. X
  554. X    return ret;
  555. X}
  556. X
  557. X/*
  558. X - regpiece - something followed by possible [*+?]
  559. X *
  560. X * Note that the branching code sequences used for ? and the general cases
  561. X * of * and + are somewhat optimized:  they use the same NOTHING node as
  562. X * both the endmarker for their branch list and the body of the last branch.
  563. X * It might seem that this node could be dispensed with entirely, but the
  564. X * endmarker role is not redundant.
  565. X */
  566. Xstatic char    *
  567. Xregpiece(flagp)
  568. X    int            *flagp;
  569. X{
  570. X    register char  *ret;
  571. X    register int    op;
  572. X    register char  *next;
  573. X    int             flags;
  574. X
  575. X    ret = regatom(&flags);
  576. X    if (ret == NULL)
  577. X        return NULL;
  578. X
  579. X    op = peekchr();
  580. X    if (!ismult(op)) {
  581. X        *flagp = flags;
  582. X        return ret;
  583. X    }
  584. X    if (!(flags & HASWIDTH) && op != Magic('?'))
  585. X        FAIL("*+ operand could be empty");
  586. X    *flagp = (op != Magic('+')) ? (WORST | SPSTART) : (WORST | HASWIDTH);
  587. X
  588. X    if (op == Magic('*') && (flags & SIMPLE))
  589. X        reginsert(STAR, ret);
  590. X    else if (op == Magic('*')) {
  591. X        /* Emit x* as (x&|), where & means "self". */
  592. X        reginsert(BRANCH, ret); /* Either x */
  593. X        regoptail(ret, regnode(BACK));    /* and loop */
  594. X        regoptail(ret, ret);    /* back */
  595. X        regtail(ret, regnode(BRANCH));    /* or */
  596. X        regtail(ret, regnode(NOTHING)); /* null. */
  597. X    } else if (op == Magic('+') && (flags & SIMPLE))
  598. X        reginsert(PLUS, ret);
  599. X    else if (op == Magic('+')) {
  600. X        /* Emit x+ as x(&|), where & means "self". */
  601. X        next = regnode(BRANCH); /* Either */
  602. X        regtail(ret, next);
  603. X        regtail(regnode(BACK), ret);    /* loop back */
  604. X        regtail(next, regnode(BRANCH)); /* or */
  605. X        regtail(ret, regnode(NOTHING)); /* null. */
  606. X    } else if (op == Magic('?')) {
  607. X        /* Emit x? as (x|) */
  608. X        reginsert(BRANCH, ret); /* Either x */
  609. X        regtail(ret, regnode(BRANCH));    /* or */
  610. X        next = regnode(NOTHING);/* null. */
  611. X        regtail(ret, next);
  612. X        regoptail(ret, next);
  613. X    }
  614. X    skipchr();
  615. X    if (ismult(peekchr()))
  616. X        FAIL("Nested *?+");
  617. X
  618. X    return ret;
  619. X}
  620. X
  621. X/*
  622. X - regatom - the lowest level
  623. X *
  624. X * Optimization:  gobbles an entire sequence of ordinary characters so that
  625. X * it can turn them into a single node, which is smaller to store and
  626. X * faster to run.  Backslashed characters are exceptions, each becoming a
  627. X * separate node; the code is simpler that way and it's not worth fixing.
  628. X */
  629. Xstatic char    *
  630. Xregatom(flagp)
  631. X    int            *flagp;
  632. X{
  633. X    register char  *ret;
  634. X    int             flags;
  635. X
  636. X    *flagp = WORST;             /* Tentatively. */
  637. X
  638. X    switch (getchr()) {
  639. X      case Magic('^'):
  640. X        ret = regnode(BOL);
  641. X        break;
  642. X      case Magic('$'):
  643. X        ret = regnode(EOL);
  644. X        break;
  645. X      case Magic('<'):
  646. X        ret = regnode(BOW);
  647. X        break;
  648. X      case Magic('>'):
  649. X        ret = regnode(EOW);
  650. X        break;
  651. X      case Magic('.'):
  652. X        ret = regnode(ANY);
  653. X        *flagp |= HASWIDTH | SIMPLE;
  654. X        break;
  655. X      case Magic('['):{
  656. X            /*
  657. X             * In a character class, different parsing rules apply.
  658. X             * Not even \ is special anymore, nothing is.
  659. X             */
  660. X            if (*regparse == '^') {     /* Complement of range. */
  661. X                ret = regnode(ANYBUT);
  662. X                regparse++;
  663. X            } else
  664. X                ret = regnode(ANYOF);
  665. X            if (*regparse == ']' || *regparse == '-')
  666. X                regc(*regparse++);
  667. X            while (*regparse != '\0' && *regparse != ']') {
  668. X                if (*regparse == '-') {
  669. X                    regparse++;
  670. X                    if (*regparse == ']' || *regparse == '\0')
  671. X                        regc('-');
  672. X                    else {
  673. X                        register int    class;
  674. X                        register int    classend;
  675. X
  676. X                        class = UCHARAT(regparse - 2) + 1;
  677. X                        classend = UCHARAT(regparse);
  678. X                        if (class > classend + 1)
  679. X                            FAIL(e_invrange);
  680. X                        for (; class <= classend; class++)
  681. X                            regc((char)class);
  682. X                        regparse++;
  683. X                    }
  684. X                } else if (*regparse == '\\' && regparse[1]) {
  685. X                    regparse++;
  686. X                    regc(*regparse++);
  687. X                } else
  688. X                    regc(*regparse++);
  689. X            }
  690. X            regc('\0');
  691. X            if (*regparse != ']')
  692. X                FAIL(e_toomsbra);
  693. X            skipchr();            /* let's be friends with the lexer again */
  694. X            *flagp |= HASWIDTH | SIMPLE;
  695. X        }
  696. X        break;
  697. X      case Magic('('):
  698. X        ret = reg(1, &flags);
  699. X        if (ret == NULL)
  700. X            return NULL;
  701. X        *flagp |= flags & (HASWIDTH | SPSTART);
  702. X        break;
  703. X      case '\0':
  704. X      case Magic('|'):
  705. X      case Magic(')'):
  706. X        FAIL(e_internal);    /* Supposed to be caught earlier. */
  707. X        /* break; Not Reached */
  708. X      case Magic('?'):
  709. X      case Magic('+'):
  710. X      case Magic('*'):
  711. X        FAIL("?+* follows nothing");
  712. X        /* break; Not Reached */
  713. X#ifdef TILDE
  714. X      case Magic('~'):            /* previous substitute pattern */
  715. X            if (reg_prev_sub) {
  716. X                register char *p;
  717. X
  718. X                ret = regnode(EXACTLY);
  719. X                p = reg_prev_sub;
  720. X                while (*p) {
  721. X                    regc(*p++);
  722. X                }
  723. X                regc('\0');
  724. X                if (p - reg_prev_sub) {
  725. X                    *flagp |= HASWIDTH;
  726. X                    if ((p - reg_prev_sub) == 1)
  727. X                        *flagp |= SIMPLE;
  728. X                }
  729. X              } else
  730. X                FAIL(e_nopresub);
  731. X            break;
  732. X#endif
  733. X#ifdef BACKREF
  734. X      case Magic('1'):
  735. X      case Magic('2'):
  736. X      case Magic('3'):
  737. X      case Magic('4'):
  738. X      case Magic('5'):
  739. X      case Magic('6'):
  740. X      case Magic('7'):
  741. X      case Magic('8'):
  742. X      case Magic('9'): {
  743. X            int                refnum;
  744. X
  745. X            ungetchr();
  746. X            refnum = getchr() - Magic('0');
  747. X            /*
  748. X             * Check if the back reference is legal. We use the parentheses
  749. X             * pointers to mark encountered close parentheses, but this
  750. X             * is only available in the second pass. Checking opens is
  751. X             * always possible.
  752. X             * Should also check that we don't refer to something that
  753. X             * is repeated (+*?): what instance of the repetition should
  754. X             * we match? TODO.
  755. X             */
  756. X            if (refnum < regnpar &&
  757. X                (regendp == NULL || regendp[refnum] != NULL))
  758. X                ret = regnode(BACKREF + refnum);
  759. X            else
  760. X                FAIL("Illegal back reference");
  761. X        }
  762. X        break;
  763. X#endif
  764. X      default:{
  765. X            register int    len;
  766. X            int                chr;
  767. X
  768. X            ungetchr();
  769. X            len = 0;
  770. X            ret = regnode(EXACTLY);
  771. X            while ((chr = peekchr()) != '\0' && (chr < Magic(0))) {
  772. X        /*
  773. X         * We have to check for a following '*', '+' or '?'.
  774. X         * In those cases we must have a node with a single character
  775. X         * (added by mool)
  776. X         */
  777. X                if (len != 0 && peekpeekchr())
  778. X                    break;
  779. X                regc(chr);
  780. X                skipchr();
  781. X                len++;
  782. X            }
  783. X#ifdef DEBUG
  784. X            if (len == 0)
  785. X                 FAIL("Unexpected magic character; check META.");
  786. X#endif
  787. X            if (len > 1 && ismult(chr))
  788. X                unregc();            /* Back off of *+? operand */
  789. X            regc('\0');
  790. X            *flagp |= HASWIDTH;
  791. X            if (len == 1)
  792. X                *flagp |= SIMPLE;
  793. X        }
  794. X        break;
  795. X    }
  796. X
  797. X    return ret;
  798. X}
  799. X
  800. X/*
  801. X - regnode - emit a node
  802. X */
  803. Xstatic char    *                /* Location. */
  804. Xregnode(op)
  805. X    int            op;
  806. X{
  807. X    register char  *ret;
  808. X    register char  *ptr;
  809. X
  810. X    ret = regcode;
  811. X    if (ret == ®dummy) {
  812. X        regsize += 3;
  813. X        return ret;
  814. X    }
  815. X    ptr = ret;
  816. X    *ptr++ = op;
  817. X    *ptr++ = '\0';                /* Null "next" pointer. */
  818. X    *ptr++ = '\0';
  819. X    regcode = ptr;
  820. X
  821. X    return ret;
  822. X}
  823. X
  824. X/*
  825. X - regc - emit (if appropriate) a byte of code
  826. X */
  827. Xstatic void
  828. Xregc(b)
  829. X    int            b;
  830. X{
  831. X    if (regcode != ®dummy)
  832. X        *(u_char *)regcode++ = b;
  833. X    else
  834. X        regsize++;
  835. X}
  836. X
  837. X/*
  838. X - unregc - take back (if appropriate) a byte of code
  839. X */
  840. Xstatic void
  841. Xunregc()
  842. X{
  843. X    if (regcode != ®dummy)
  844. X        regcode--;
  845. X    else
  846. X        regsize--;
  847. X}
  848. X
  849. X/*
  850. X - reginsert - insert an operator in front of already-emitted operand
  851. X *
  852. X * Means relocating the operand.
  853. X */
  854. Xstatic void
  855. Xreginsert(op, opnd)
  856. X    int            op;
  857. X    char           *opnd;
  858. X{
  859. X    register char  *src;
  860. X    register char  *dst;
  861. X    register char  *place;
  862. X
  863. X    if (regcode == ®dummy) {
  864. X        regsize += 3;
  865. X        return;
  866. X    }
  867. X    src = regcode;
  868. X    regcode += 3;
  869. X    dst = regcode;
  870. X    while (src > opnd)
  871. X        *--dst = *--src;
  872. X
  873. X    place = opnd;                /* Op node, where operand used to be. */
  874. X    *place++ = op;
  875. X    *place++ = '\0';
  876. X    *place = '\0';
  877. X}
  878. X
  879. X/*
  880. X - regtail - set the next-pointer at the end of a node chain
  881. X */
  882. Xstatic void
  883. Xregtail(p, val)
  884. X    char           *p;
  885. X    char           *val;
  886. X{
  887. X    register char  *scan;
  888. X    register char  *temp;
  889. X    register int    offset;
  890. X
  891. X    if (p == ®dummy)
  892. X        return;
  893. X
  894. X    /* Find last node. */
  895. X    scan = p;
  896. X    for (;;) {
  897. X        temp = regnext(scan);
  898. X        if (temp == NULL)
  899. X            break;
  900. X        scan = temp;
  901. X    }
  902. X
  903. X    if (OP(scan) == BACK)
  904. X        offset = scan - val;
  905. X    else
  906. X        offset = val - scan;
  907. X    *(scan + 1) = (char) ((offset >> 8) & 0377);
  908. X    *(scan + 2) = (char) (offset & 0377);
  909. X}
  910. X
  911. X/*
  912. X - regoptail - regtail on operand of first argument; nop if operandless
  913. X */
  914. Xstatic void
  915. Xregoptail(p, val)
  916. X    char           *p;
  917. X    char           *val;
  918. X{
  919. X    /* "Operandless" and "op != BRANCH" are synonymous in practice. */
  920. X    if (p == NULL || p == ®dummy || OP(p) != BRANCH)
  921. X        return;
  922. X    regtail(OPERAND(p), val);
  923. X}
  924. X
  925. X/*
  926. X - getchr() - get the next character from the pattern. We know about
  927. X * magic and such, so therefore we need a lexical analyzer.
  928. X */
  929. X
  930. X/* static int        curchr; */
  931. Xstatic int        prevchr;
  932. X
  933. Xstatic void
  934. Xinitchr(str)
  935. Xunsigned char *str;
  936. X{
  937. X    regparse = str;
  938. X    curchr = prevchr = -1;
  939. X}
  940. X
  941. Xstatic int
  942. Xpeekchr()
  943. X{
  944. X    if (curchr < 0) {
  945. X        switch (curchr = regparse[0]) {
  946. X        case '.':
  947. X        case '*':
  948. X    /*    case '+':*/
  949. X    /*    case '?':*/
  950. X        case '[':
  951. X        case '~':
  952. X            if (reg_magic)
  953. X                curchr = Magic(curchr);
  954. X            break;
  955. X        case '^':
  956. X            /* ^ is only magic as the very first character */
  957. X            if (prevchr < 0)
  958. X                curchr = Magic('^');
  959. X            break;
  960. X        case '$':
  961. X            /* $ is only magic as the very last character */
  962. X            if (!regparse[1])
  963. X                curchr = Magic('$');
  964. X            break;
  965. X        case '\\':
  966. X            regparse++;
  967. X            if (regparse[0] == NUL)
  968. X                curchr = '\\';    /* trailing '\' */
  969. X            else if (strchr(META, regparse[0]))
  970. X            {
  971. X                /*
  972. X                 * META contains everything that may be magic sometimes, except
  973. X                 * ^ and $ ("\^" and "\$" are never magic).
  974. X                 * We now fetch the next character and toggle its magicness.
  975. X                 * Therefore, \ is so meta-magic that it is not in META.
  976. X                 */
  977. X                curchr = -1;
  978. X                peekchr();
  979. X                curchr ^= Magic(0);
  980. X            }
  981. X            else
  982. X            {
  983. X                /*
  984. X                 * Next character can never be (made) magic?
  985. X                 * Then backslashing it won't do anything.
  986. X                 */
  987. X                curchr = regparse[0];
  988. X            }
  989. X            break;
  990. X        }
  991. X    }
  992. X
  993. X    return curchr;
  994. X}
  995. X
  996. X/*
  997. X * return 1 if the character returned by peekchr() is followed by a '*', '+' or '?'
  998. X */
  999. Xstatic int
  1000. Xpeekpeekchr()
  1001. X{
  1002. X    if (regparse[1] == '\\')
  1003. X    {
  1004. X        if ((!reg_magic && regparse[2] == '*') || regparse[2] == '+' || regparse[2] == '?')
  1005. X            return 1;
  1006. X    }
  1007. X    else if (reg_magic && regparse[1] == '*')
  1008. X        return 1;
  1009. X    return 0;
  1010. X}
  1011. X
  1012. Xstatic void
  1013. Xskipchr()
  1014. X{
  1015. X    regparse++;
  1016. X    prevchr = curchr;
  1017. X    curchr = -1;
  1018. X}
  1019. X
  1020. Xstatic int
  1021. Xgetchr()
  1022. X{
  1023. X    int chr;
  1024. X
  1025. X    chr = peekchr();
  1026. X    skipchr();
  1027. X
  1028. X    return chr;
  1029. X}
  1030. X
  1031. Xstatic void
  1032. Xungetchr()
  1033. X{
  1034. X    curchr = prevchr;
  1035. X    /*
  1036. X     * Backup regparse as well; not because we will use what it points at,
  1037. X     * but because skipchr() will bump it again.
  1038. X     */
  1039. X    regparse--;
  1040. X}
  1041. X
  1042. X/*
  1043. X * regexec and friends
  1044. X */
  1045. X
  1046. X/*
  1047. X * Global work variables for regexec().
  1048. X */
  1049. Xstatic char    *reginput;        /* String-input pointer. */
  1050. Xstatic char    *regbol;         /* Beginning of input, for ^ check. */
  1051. Xstatic char   **regstartp;        /* Pointer to startp array. */
  1052. X/* static char   **regendp;    */    /* Ditto for endp. */
  1053. X
  1054. X/*
  1055. X * Forwards.
  1056. X */
  1057. Xstatic int        regtry __ARGS((regexp *, char *));
  1058. Xstatic int        regmatch __ARGS((char *));
  1059. Xstatic int        regrepeat __ARGS((char *));
  1060. X
  1061. X#ifdef DEBUG
  1062. Xint             regnarrate = 1;
  1063. Xvoid            regdump __ARGS((regexp *));
  1064. Xstatic char    *regprop __ARGS((char *));
  1065. X#endif
  1066. X
  1067. X/*
  1068. X - regexec - match a regexp against a string
  1069. X */
  1070. Xint
  1071. Xregexec(prog, string, at_bol)
  1072. X    register regexp *prog;
  1073. X    register char  *string;
  1074. X    int             at_bol;
  1075. X{
  1076. X    register char  *s;
  1077. X
  1078. X    /* Be paranoid... */
  1079. X    if (prog == NULL || string == NULL) {
  1080. X        emsg(e_null);
  1081. X        return 0;
  1082. X    }
  1083. X    /* Check validity of program. */
  1084. X    if (UCHARAT(prog->program) != MAGIC) {
  1085. X        emsg(e_re_corr);
  1086. X        return 0;
  1087. X    }
  1088. X    /* If there is a "must appear" string, look for it. */
  1089. X    if (prog->regmust != NULL) {
  1090. X        s = string;
  1091. X        while ((s = cstrchr(s, prog->regmust[0])) != NULL) {
  1092. X            if (cstrncmp(s, prog->regmust, prog->regmlen) == 0)
  1093. X                break;            /* Found it. */
  1094. X            s++;
  1095. X        }
  1096. X        if (s == NULL)            /* Not present. */
  1097. X            return 0;
  1098. X    }
  1099. X    /* Mark beginning of line for ^ . */
  1100. X    if (at_bol)
  1101. X        regbol = string;        /* is possible to match bol */
  1102. X    else
  1103. X        regbol = NULL;            /* we aren't there, so don't match it */
  1104. X
  1105. X    /* Simplest case:  anchored match need be tried only once. */
  1106. X    if (prog->reganch)
  1107. X        return regtry(prog, string);
  1108. X
  1109. X    /* Messy cases:  unanchored match. */
  1110. X    s = string;
  1111. X    if (prog->regstart != '\0')
  1112. X        /* We know what char it must start with. */
  1113. X        while ((s = cstrchr(s, prog->regstart)) != NULL) {
  1114. X            if (regtry(prog, s))
  1115. X                return 1;
  1116. X            s++;
  1117. X        }
  1118. X    else
  1119. X        /* We don't -- general case. */
  1120. X        do {
  1121. X            if (regtry(prog, s))
  1122. X                return 1;
  1123. X        } while (*s++ != '\0');
  1124. X
  1125. X    /* Failure. */
  1126. X    return 0;
  1127. X}
  1128. X
  1129. X/*
  1130. X - regtry - try match at specific point
  1131. X */
  1132. Xstatic int                        /* 0 failure, 1 success */
  1133. Xregtry(prog, string)
  1134. X    regexp           *prog;
  1135. X    char           *string;
  1136. X{
  1137. X    register int    i;
  1138. X    register char **sp;
  1139. X    register char **ep;
  1140. X
  1141. X    reginput = string;
  1142. X    regstartp = prog->startp;
  1143. X    regendp = prog->endp;
  1144. X
  1145. X    sp = prog->startp;
  1146. X    ep = prog->endp;
  1147. X    for (i = NSUBEXP; i > 0; i--) {
  1148. X        *sp++ = NULL;
  1149. X        *ep++ = NULL;
  1150. X    }
  1151. X    if (regmatch(prog->program + 1)) {
  1152. X        prog->startp[0] = string;
  1153. X        prog->endp[0] = reginput;
  1154. X        return 1;
  1155. X    } else
  1156. X        return 0;
  1157. X}
  1158. X
  1159. X/*
  1160. X - regmatch - main matching routine
  1161. X *
  1162. X * Conceptually the strategy is simple:  check to see whether the current
  1163. X * node matches, call self recursively to see whether the rest matches,
  1164. X * and then act accordingly.  In practice we make some effort to avoid
  1165. X * recursion, in particular by going through "ordinary" nodes (that don't
  1166. X * need to know whether the rest of the match failed) by a loop instead of
  1167. X * by recursion.
  1168. X */
  1169. Xstatic int                        /* 0 failure, 1 success */
  1170. Xregmatch(prog)
  1171. X    char           *prog;
  1172. X{
  1173. X    register char  *scan;        /* Current node. */
  1174. X    char           *next;        /* Next node. */
  1175. X
  1176. X    scan = prog;
  1177. X#ifdef DEBUG
  1178. X    if (scan != NULL && regnarrate)
  1179. X        fprintf(stderr, "%s(\n", regprop(scan));
  1180. X#endif
  1181. X    while (scan != NULL) {
  1182. X#ifdef DEBUG
  1183. X        if (regnarrate) {
  1184. X            fprintf(stderr, "%s...\n", regprop(scan));
  1185. X        }
  1186. X#endif
  1187. X        next = regnext(scan);
  1188. X        switch (OP(scan)) {
  1189. X          case BOL:
  1190. X            if (reginput != regbol)
  1191. X                return 0;
  1192. X            break;
  1193. X          case EOL:
  1194. X            if (*reginput != '\0')
  1195. X                return 0;
  1196. X            break;
  1197. X          case BOW:        /* \<word; reginput points to w */
  1198. X#define isidchar(x)    (isalnum(x) || ((x) == '_'))
  1199. X              if (reginput != regbol && isidchar(reginput[-1]))
  1200. X                return 0;
  1201. X              if (!reginput[0] || !isidchar(reginput[0]))
  1202. X                return 0;
  1203. X            break;
  1204. X          case EOW:        /* word\>; reginput points after d */
  1205. X              if (reginput == regbol || !isidchar(reginput[-1]))
  1206. X                return 0;
  1207. X              if (reginput[0] && isidchar(reginput[0]))
  1208. X                return 0;
  1209. X            break;
  1210. X          case ANY:
  1211. X            if (*reginput == '\0')
  1212. X                return 0;
  1213. X            reginput++;
  1214. X            break;
  1215. X          case EXACTLY:{
  1216. X                register int    len;
  1217. X                register char  *opnd;
  1218. X
  1219. X                opnd = OPERAND(scan);
  1220. X                /* Inline the first character, for speed. */
  1221. X                if (mkup(*opnd) != mkup(*reginput))
  1222. X                    return 0;
  1223. X                len = strlen(opnd);
  1224. X                if (len > 1 && cstrncmp(opnd, reginput, len) != 0)
  1225. X                    return 0;
  1226. X                reginput += len;
  1227. X            }
  1228. X            break;
  1229. X          case ANYOF:
  1230. X            if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
  1231. X                return 0;
  1232. X            reginput++;
  1233. X            break;
  1234. X          case ANYBUT:
  1235. X            if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
  1236. X                return 0;
  1237. X            reginput++;
  1238. X            break;
  1239. X          case NOTHING:
  1240. X            break;
  1241. X          case BACK:
  1242. X            break;
  1243. X          case MOPEN + 1:
  1244. X          case MOPEN + 2:
  1245. X          case MOPEN + 3:
  1246. X          case MOPEN + 4:
  1247. X          case MOPEN + 5:
  1248. X          case MOPEN + 6:
  1249. X          case MOPEN + 7:
  1250. X          case MOPEN + 8:
  1251. X          case MOPEN + 9:{
  1252. X                register int    no;
  1253. X                register char  *save;
  1254. X
  1255. X                no = OP(scan) - MOPEN;
  1256. X                save = regstartp[no];
  1257. X                regstartp[no] = reginput; /* Tentatively */
  1258. X#ifdef DEBUG
  1259. X                printf("MOPEN  %d pre  @'%s' ('%s' )'%s'\n",
  1260. X                    no, save,
  1261. X                    regstartp[no]? regstartp[no] : "NULL",
  1262. X                    regendp[no]? regendp[no] : "NULL");
  1263. X#endif
  1264. X
  1265. X                if (regmatch(next)) {
  1266. X#ifdef DEBUG
  1267. X                printf("MOPEN  %d post @'%s' ('%s' )'%s'\n",
  1268. X                    no, save,
  1269. X                    regstartp[no]? regstartp[no] : "NULL",
  1270. X                    regendp[no]? regendp[no] : "NULL");
  1271. X#endif
  1272. X                    return 1;
  1273. X                }
  1274. X                regstartp[no] = save;        /* We were wrong... */
  1275. X                return 0;
  1276. X            }
  1277. X            /* break; Not Reached */
  1278. X          case MCLOSE + 1:
  1279. X          case MCLOSE + 2:
  1280. X          case MCLOSE + 3:
  1281. X          case MCLOSE + 4:
  1282. X          case MCLOSE + 5:
  1283. X          case MCLOSE + 6:
  1284. X          case MCLOSE + 7:
  1285. X          case MCLOSE + 8:
  1286. X          case MCLOSE + 9:{
  1287. X                register int    no;
  1288. X                register char  *save;
  1289. X
  1290. X                no = OP(scan) - MCLOSE;
  1291. X                save = regendp[no];
  1292. X                regendp[no] = reginput; /* Tentatively */
  1293. X#ifdef DEBUG
  1294. X                printf("MCLOSE %d pre  @'%s' ('%s' )'%s'\n",
  1295. X                    no, save,
  1296. X                    regstartp[no]? regstartp[no] : "NULL",
  1297. X                    regendp[no]? regendp[no] : "NULL");
  1298. X#endif
  1299. X
  1300. X                if (regmatch(next)) {
  1301. X#ifdef DEBUG
  1302. X                printf("MCLOSE %d post @'%s' ('%s' )'%s'\n",
  1303. X                    no, save,
  1304. X                    regstartp[no]? regstartp[no] : "NULL",
  1305. X                    regendp[no]? regendp[no] : "NULL");
  1306. X#endif
  1307. X                    return 1;
  1308. X                }
  1309. X                regendp[no] = save;        /* We were wrong... */
  1310. X                return 0;
  1311. X            }
  1312. X            /* break; Not Reached */
  1313. X#ifdef BACKREF
  1314. X          case BACKREF + 1:
  1315. X          case BACKREF + 2:
  1316. X          case BACKREF + 3:
  1317. X          case BACKREF + 4:
  1318. X          case BACKREF + 5:
  1319. X          case BACKREF + 6:
  1320. X          case BACKREF + 7:
  1321. X          case BACKREF + 8:
  1322. X          case BACKREF + 9:{
  1323. X                register int    no;
  1324. X                int                len;
  1325. X
  1326. X                no = OP(scan) - BACKREF;
  1327. X                if (regendp[no] != NULL) {
  1328. X                    len = regendp[no] - regstartp[no];
  1329. X                    if (cstrncmp(regstartp[no], reginput, len) != 0)
  1330. X                        return 0;
  1331. X                    reginput += len;
  1332. X                } else {
  1333. X                    /*emsg("backref to 0-repeat");*/
  1334. X                    /*return 0;*/
  1335. X                }
  1336. X              }
  1337. X            break;
  1338. X#endif
  1339. X          case BRANCH:{
  1340. X                register char  *save;
  1341. X
  1342. X                if (OP(next) != BRANCH) /* No choice. */
  1343. X                    next = OPERAND(scan);        /* Avoid recursion. */
  1344. X                else {
  1345. X                    do {
  1346. X                        save = reginput;
  1347. X                        if (regmatch(OPERAND(scan)))
  1348. X                            return 1;
  1349. X                        reginput = save;
  1350. X                        scan = regnext(scan);
  1351. X                    } while (scan != NULL && OP(scan) == BRANCH);
  1352. X                    return 0;
  1353. X                    /* NOTREACHED */
  1354. X                }
  1355. X            }
  1356. X            break;
  1357. X          case STAR:
  1358. X          case PLUS:{
  1359. X                register char    nextch;
  1360. X                register int    no;
  1361. X                register char  *save;
  1362. X                register int    min;
  1363. X
  1364. X                /*
  1365. X                 * Lookahead to avoid useless match attempts when we know
  1366. X                 * what character comes next.
  1367. X                 */
  1368. X                nextch = '\0';
  1369. X                if (OP(next) == EXACTLY)
  1370. X                    nextch = *OPERAND(next);
  1371. X                min = (OP(scan) == STAR) ? 0 : 1;
  1372. X                save = reginput;
  1373. X                no = regrepeat(OPERAND(scan));
  1374. X                while (no >= min) {
  1375. X                    /* If it could work, try it. */
  1376. X                    if (nextch == '\0' || *reginput == nextch)
  1377. X                        if (regmatch(next))
  1378. X                            return 1;
  1379. X                    /* Couldn't or didn't -- back up. */
  1380. X                    no--;
  1381. X                    reginput = save + no;
  1382. X                }
  1383. X                return 0;
  1384. X            }
  1385. X            /* break; Not Reached */
  1386. X          case END:
  1387. X            return 1;         /* Success! */
  1388. X            /* break; Not Reached */
  1389. X          default:
  1390. X            emsg(e_re_corr);
  1391. X            return 0;
  1392. X            /* break; Not Reached */
  1393. X        }
  1394. X
  1395. X        scan = next;
  1396. X    }
  1397. X
  1398. X    /*
  1399. X     * We get here only if there's trouble -- normally "case END" is the
  1400. X     * terminating point.
  1401. X     */
  1402. X    emsg(e_re_corr);
  1403. X    return 0;
  1404. X}
  1405. X
  1406. X/*
  1407. X - regrepeat - repeatedly match something simple, report how many
  1408. X */
  1409. Xstatic int
  1410. Xregrepeat(p)
  1411. X    char           *p;
  1412. X{
  1413. X    register int    count = 0;
  1414. X    register char  *scan;
  1415. X    register char  *opnd;
  1416. X
  1417. X    scan = reginput;
  1418. X    opnd = OPERAND(p);
  1419. X    switch (OP(p)) {
  1420. X      case ANY:
  1421. X        count = strlen(scan);
  1422. X        scan += count;
  1423. X        break;
  1424. X      case EXACTLY:
  1425. X        while (mkup(*opnd) == mkup(*scan)) {
  1426. X            count++;
  1427. X            scan++;
  1428. X        }
  1429. X        break;
  1430. X      case ANYOF:
  1431. X        while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
  1432. X            count++;
  1433. X            scan++;
  1434. X        }
  1435. X        break;
  1436. X      case ANYBUT:
  1437. X        while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
  1438. X            count++;
  1439. X            scan++;
  1440. X        }
  1441. X        break;
  1442. X      default:                    /* Oh dear.  Called inappropriately. */
  1443. X        emsg(e_re_corr);
  1444. X        count = 0;                /* Best compromise. */
  1445. X        break;
  1446. X    }
  1447. X    reginput = scan;
  1448. X
  1449. X    return count;
  1450. X}
  1451. X
  1452. X/*
  1453. X - regnext - dig the "next" pointer out of a node
  1454. X */
  1455. Xstatic char    *
  1456. Xregnext(p)
  1457. X    register char  *p;
  1458. X{
  1459. X    register int    offset;
  1460. X
  1461. X    if (p == ®dummy)
  1462. X        return NULL;
  1463. X
  1464. X    offset = NEXT(p);
  1465. X    if (offset == 0)
  1466. X        return NULL;
  1467. X
  1468. X    if (OP(p) == BACK)
  1469. X        return p - offset;
  1470. X    else
  1471. X        return p + offset;
  1472. X}
  1473. X
  1474. X#ifdef DEBUG
  1475. X
  1476. X/*
  1477. X - regdump - dump a regexp onto stdout in vaguely comprehensible form
  1478. X */
  1479. Xvoid
  1480. Xregdump(r)
  1481. X    regexp           *r;
  1482. X{
  1483. X    register char  *s;
  1484. X    register char    op = EXACTLY;        /* Arbitrary non-END op. */
  1485. X    register char  *next;
  1486. X    /*extern char    *strchr();*/
  1487. X
  1488. X
  1489. X    s = r->program + 1;
  1490. X    while (op != END) {         /* While that wasn't END last time... */
  1491. X        op = OP(s);
  1492. X        printf("%2d%s", s - r->program, regprop(s));    /* Where, what. */
  1493. X        next = regnext(s);
  1494. X        if (next == NULL)        /* Next ptr. */
  1495. X            printf("(0)");
  1496. X        else
  1497. X            printf("(%d)", (s - r->program) + (next - s));
  1498. X        s += 3;
  1499. X        if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
  1500. X            /* Literal string, where present. */
  1501. X            while (*s != '\0') {
  1502. X                putchar(*s);
  1503. X                s++;
  1504. X            }
  1505. X            s++;
  1506. X        }
  1507. X        putchar('\n');
  1508. X    }
  1509. X
  1510. X    /* Header fields of interest. */
  1511. X    if (r->regstart != '\0')
  1512. X        printf("start `%c' ", r->regstart);
  1513. X    if (r->reganch)
  1514. X        printf("anchored ");
  1515. X    if (r->regmust != NULL)
  1516. X        printf("must have \"%s\"", r->regmust);
  1517. X    printf("\n");
  1518. X}
  1519. X
  1520. X/*
  1521. X - regprop - printable representation of opcode
  1522. X */
  1523. Xstatic char    *
  1524. Xregprop(op)
  1525. X    char           *op;
  1526. X{
  1527. X    register char  *p;
  1528. X    static char     buf[50];
  1529. X
  1530. X    (void) strcpy(buf, ":");
  1531. X
  1532. X    switch (OP(op)) {
  1533. X      case BOL:
  1534. X        p = "BOL";
  1535. X        break;
  1536. X      case EOL:
  1537. X        p = "EOL";
  1538. X        break;
  1539. X      case ANY:
  1540. X        p = "ANY";
  1541. X        break;
  1542. X      case ANYOF:
  1543. X        p = "ANYOF";
  1544. X        break;
  1545. X      case ANYBUT:
  1546. X        p = "ANYBUT";
  1547. X        break;
  1548. X      case BRANCH:
  1549. X        p = "BRANCH";
  1550. X        break;
  1551. X      case EXACTLY:
  1552. X        p = "EXACTLY";
  1553. X        break;
  1554. X      case NOTHING:
  1555. X        p = "NOTHING";
  1556. X        break;
  1557. X      case BACK:
  1558. X        p = "BACK";
  1559. X        break;
  1560. X      case END:
  1561. X        p = "END";
  1562. X        break;
  1563. X      case MOPEN + 1:
  1564. X      case MOPEN + 2:
  1565. X      case MOPEN + 3:
  1566. X      case MOPEN + 4:
  1567. X      case MOPEN + 5:
  1568. X      case MOPEN + 6:
  1569. X      case MOPEN + 7:
  1570. X      case MOPEN + 8:
  1571. X      case MOPEN + 9:
  1572. X        sprintf(buf + strlen(buf), "MOPEN%d", OP(op) - MOPEN);
  1573. X        p = NULL;
  1574. X        break;
  1575. X      case MCLOSE + 1:
  1576. X      case MCLOSE + 2:
  1577. X      case MCLOSE + 3:
  1578. X      case MCLOSE + 4:
  1579. X      case MCLOSE + 5:
  1580. X      case MCLOSE + 6:
  1581. X      case MCLOSE + 7:
  1582. X      case MCLOSE + 8:
  1583. X      case MCLOSE + 9:
  1584. X        sprintf(buf + strlen(buf), "MCLOSE%d", OP(op) - MCLOSE);
  1585. X        p = NULL;
  1586. X        break;
  1587. X      case BACKREF + 1:
  1588. X      case BACKREF + 2:
  1589. X      case BACKREF + 3:
  1590. X      case BACKREF + 4:
  1591. X      case BACKREF + 5:
  1592. X      case BACKREF + 6:
  1593. X      case BACKREF + 7:
  1594. X      case BACKREF + 8:
  1595. X      case BACKREF + 9:
  1596. X        sprintf(buf + strlen(buf), "BACKREF%d", OP(op) - BACKREF);
  1597. X        p = NULL;
  1598. X        break;
  1599. X      case STAR:
  1600. X        p = "STAR";
  1601. X        break;
  1602. X      case PLUS:
  1603. X        p = "PLUS";
  1604. X        break;
  1605. X      default:
  1606. X        sprintf(buf + strlen(buf), "corrupt %d", OP(op));
  1607. X        p = NULL;
  1608. X        break;
  1609. X    }
  1610. X    if (p != NULL)
  1611. X        (void) strcat(buf, p);
  1612. X    return buf;
  1613. X}
  1614. X#endif
  1615. X
  1616. X/*
  1617. X * The following is provided for those people who do not have strcspn() in
  1618. X * their C libraries.  They should get off their butts and do something
  1619. X * about it; at least one public-domain implementation of those (highly
  1620. X * useful) string routines has been published on Usenet.
  1621. X */
  1622. X#ifdef STRCSPN
  1623. X/*
  1624. X * strcspn - find length of initial segment of s1 consisting entirely
  1625. X * of characters not from s2
  1626. X */
  1627. X
  1628. Xstatic int
  1629. Xstrcspn(s1, s2)
  1630. X    const char           *s1;
  1631. X    const char           *s2;
  1632. X{
  1633. X    register char  *scan1;
  1634. X    register char  *scan2;
  1635. X    register int    count;
  1636. X
  1637. X    count = 0;
  1638. X    for (scan1 = s1; *scan1 != '\0'; scan1++) {
  1639. X        for (scan2 = s2; *scan2 != '\0';)        /* ++ moved down. */
  1640. X            if (*scan1 == *scan2++)
  1641. X                return count;
  1642. X        count++;
  1643. X    }
  1644. X    return count;
  1645. X}
  1646. X#endif
  1647. X
  1648. X/*
  1649. X * Compare two strings, ignore case if reg_ic set.
  1650. X * Return 0 if strings match, non-zero otherwise.
  1651. X */
  1652. X    static int
  1653. Xcstrncmp(s1, s2, n)
  1654. X    char           *s1, *s2;
  1655. X    int             n;
  1656. X{
  1657. X    if (!reg_ic)
  1658. X        return strncmp(s1, s2, (size_t)n);
  1659. X
  1660. X#ifndef UNIX
  1661. X    return strnicmp(s1, s2, (size_t)n);
  1662. X#else
  1663. X# ifdef STRNCASECMP
  1664. X    return strncasecmp(s1, s2, (size_t)n);
  1665. X# else
  1666. X    while (n && *s1 && *s2)
  1667. X    {
  1668. X        if (mkup(*s1) != mkup(*s2))
  1669. X            return 1;
  1670. X        s1++;
  1671. X        s2++;
  1672. X        n--;
  1673. X    }
  1674. X    if (n)
  1675. X        return 1;
  1676. X    return 0;
  1677. X# endif    /* STRNCASECMP */
  1678. X#endif    /* UNIX */
  1679. X}
  1680. X
  1681. X    char *
  1682. Xcstrchr(s, c)
  1683. X    char           *s;
  1684. X    int                c;
  1685. X{
  1686. X    char           *p;
  1687. X
  1688. X    c = mkup(c);
  1689. X
  1690. X    for (p = s; *p; p++)
  1691. X    {
  1692. X        if (mkup(*p) == c)
  1693. X            return p;
  1694. X    }
  1695. X    return NULL;
  1696. X}
  1697. END_OF_FILE
  1698. if test 39338 -ne `wc -c <'vim/src/regexp.c'`; then
  1699.     echo shar: \"'vim/src/regexp.c'\" unpacked with wrong size!
  1700. fi
  1701. # end of 'vim/src/regexp.c'
  1702. fi
  1703. echo shar: End of archive 18 \(of 23\).
  1704. cp /dev/null ark18isdone
  1705. MISSING=""
  1706. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
  1707.     if test ! -f ark${I}isdone ; then
  1708.     MISSING="${MISSING} ${I}"
  1709.     fi
  1710. done
  1711. if test "${MISSING}" = "" ; then
  1712.     echo You have unpacked all 23 archives.
  1713.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1714. else
  1715.     echo You still need to unpack the following archives:
  1716.     echo "        " ${MISSING}
  1717. fi
  1718. ##  End of shell archive.
  1719. exit 0
  1720. -------------8<----------------8<----------------8<---------------8<--------
  1721. Bram Moolenaar                             | DISCLAIMER:  This  note  does  not
  1722. Oce Nederland B.V., Research & Development | necessarily represent the position
  1723. p.o. box 101, 5900 MA  Venlo               | of  Oce-Nederland  B.V.  Therefore
  1724. The Netherlands        phone +31 77 594077 | no liability or responsibility for
  1725. UUCP: mool@oce.nl        fax +31 77 595450 | whatever will be accepted.
  1726.  
  1727. exit 0 # Just in case...
  1728.