home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume44 / vim / part11 < prev    next >
Encoding:
Internet Message Format  |  1994-08-16  |  68.2 KB

  1. From: mool@oce.nl (Bram Moolenaar)
  2. Newsgroups: comp.sources.misc
  3. Subject: v44i030:  vim - Vi IMproved editor, v3.0, Part11/26
  4. Date: 16 Aug 1994 21:18:18 -0500
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <32rs1a$keg@sparky.sterling.com>
  9. X-Md4-Signature: 1d36337d58b209ff5cc0f9e9bdd3a745
  10.  
  11. Submitted-by: mool@oce.nl (Bram Moolenaar)
  12. Posting-number: Volume 44, Issue 30
  13. Archive-name: vim/part11
  14. Environment: UNIX, AMIGA, MS-DOS, Windows NT
  15. Supersedes: vim: Volume 41, Issue 50-75
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  vim/src/regexp.c vim/src/undo.c
  22. # Wrapped by kent@sparky on Mon Aug 15 21:44:05 1994
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 11 (of 26)."'
  26. if test -f 'vim/src/regexp.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'vim/src/regexp.c'\"
  28. else
  29.   echo shar: Extracting \"'vim/src/regexp.c'\" \(40070 characters\)
  30.   sed "s/^X//" >'vim/src/regexp.c' <<'END_OF_FILE'
  31. X/* vi:ts=4:sw=4
  32. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  33. X *
  34. X * This is NOT the original regular expression code as written by
  35. X * Henry Spencer. This code has been modified specifically for use
  36. X * with the VIM editor, and should not be used apart from compiling
  37. X * VIM. If you want a good regular expression library, get the
  38. X * original code. The copyright notice that follows is from the
  39. X * original.
  40. X *
  41. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  42. X *
  43. X *
  44. X * regcomp and regexec -- regsub and regerror are elsewhere
  45. X *
  46. X *        Copyright (c) 1986 by University of Toronto.
  47. X *        Written by Henry Spencer.  Not derived from licensed software.
  48. X *
  49. X *        Permission is granted to anyone to use this software for any
  50. X *        purpose on any computer system, and to redistribute it freely,
  51. X *        subject to the following restrictions:
  52. X *
  53. X *        1. The author is not responsible for the consequences of use of
  54. X *                this software, no matter how awful, even if they arise
  55. X *                from defects in it.
  56. X *
  57. X *        2. The origin of this software must not be misrepresented, either
  58. X *                by explicit claim or by omission.
  59. X *
  60. X *        3. Altered versions must be plainly marked as such, and must not
  61. X *                be misrepresented as being the original software.
  62. X *
  63. X * Beware that some of this code is subtly aware of the way operator
  64. X * precedence is structured in regular expressions.  Serious changes in
  65. X * regular-expression syntax might require a total rethink.
  66. X *
  67. X * $Log:        regexp.c,v $
  68. X * Revision 1.2  88/04/28  08:09:45  tony
  69. X * First modification of the regexp library. Added an external variable
  70. X * 'reg_ic' which can be set to indicate that case should be ignored.
  71. X * Added a new parameter to regexec() to indicate that the given string
  72. X * comes from the beginning of a line and is thus eligible to match
  73. X * 'beginning-of-line'.
  74. X *
  75. X * Revisions by Olaf 'Rhialto' Seibert, rhialto@cs.kun.nl:
  76. X * Changes for vi: (the semantics of several things were rather different)
  77. X * - Added lexical analyzer, because in vi magicness of characters
  78. X *   is rather difficult, and may change over time.
  79. X * - Added support for \< \> \1-\9 and ~
  80. X * - Left some magic stuff in, but only backslashed: \| \+
  81. X * - * and \+ still work after \) even though they shouldn't.
  82. X */
  83. X#include "vim.h"
  84. X#include "globals.h"
  85. X#include "proto.h"
  86. X#undef DEBUG
  87. X
  88. X#include <stdio.h>
  89. X#include "regexp.h"
  90. X#include "regmagic.h"
  91. X#include "param.h"
  92. X
  93. X/*
  94. X * The "internal use only" fields in regexp.h are present to pass info from
  95. X * compile to execute that permits the execute phase to run lots faster on
  96. X * simple cases.  They are:
  97. X *
  98. X * regstart     char that must begin a match; '\0' if none obvious
  99. X * reganch        is the match anchored (at beginning-of-line only)?
  100. X * regmust        string (pointer into program) that match must include, or NULL
  101. X * regmlen        length of regmust string
  102. X *
  103. X * Regstart and reganch permit very fast decisions on suitable starting points
  104. X * for a match, cutting down the work a lot.  Regmust permits fast rejection
  105. X * of lines that cannot possibly match.  The regmust tests are costly enough
  106. X * that regcomp() supplies a regmust only if the r.e. contains something
  107. X * potentially expensive (at present, the only such thing detected is * or +
  108. X * at the start of the r.e., which can involve a lot of backup).  Regmlen is
  109. X * supplied because the test in regexec() needs it and regcomp() is computing
  110. X * it anyway.
  111. X */
  112. X
  113. X/*
  114. X * Structure for regexp "program".    This is essentially a linear encoding
  115. X * of a nondeterministic finite-state machine (aka syntax charts or
  116. X * "railroad normal form" in parsing technology).  Each node is an opcode
  117. X * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
  118. X * all nodes except BRANCH implement concatenation; a "next" pointer with
  119. X * a BRANCH on both ends of it is connecting two alternatives.    (Here we
  120. X * have one of the subtle syntax dependencies:    an individual BRANCH (as
  121. X * opposed to a collection of them) is never concatenated with anything
  122. X * because of operator precedence.)  The operand of some types of node is
  123. X * a literal string; for others, it is a node leading into a sub-FSM.  In
  124. X * particular, the operand of a BRANCH node is the first node of the branch.
  125. X * (NB this is *not* a tree structure:    the tail of the branch connects
  126. X * to the thing following the set of BRANCHes.)  The opcodes are:
  127. X */
  128. X
  129. X/* definition    number               opnd?    meaning */
  130. X#define END     0                /* no    End of program. */
  131. X#define BOL     1                /* no    Match "" at beginning of line. */
  132. X#define EOL     2                /* no    Match "" at end of line. */
  133. X#define ANY     3                /* no    Match any one character. */
  134. X#define ANYOF    4                /* str    Match any character in this string. */
  135. X#define ANYBUT    5                /* str    Match any character not in this
  136. X                                 *        string. */
  137. X#define BRANCH    6                /* node Match this alternative, or the
  138. X                                 *        next... */
  139. X#define BACK    7                /* no    Match "", "next" ptr points backward. */
  140. X#define EXACTLY 8                /* str    Match this string. */
  141. X#define NOTHING 9                /* no    Match empty string. */
  142. X#define STAR    10                /* node Match this (simple) thing 0 or more
  143. X                                 *        times. */
  144. X#define PLUS    11                /* node Match this (simple) thing 1 or more
  145. X                                 *        times. */
  146. X#define BOW        12                /* no    Match "" after [^a-zA-Z0-9_] */
  147. X#define EOW        13                /* no    Match "" at    [^a-zA-Z0-9_] */
  148. X#define MOPEN    20                /* no    Mark this point in input as start of
  149. X                                 *        #n. */
  150. X /* MOPEN+1 is number 1, etc. */
  151. X#define MCLOSE    30                /* no    Analogous to MOPEN. */
  152. X#define BACKREF    40                /* node Match same string again \1-\9 */
  153. X
  154. X#define Magic(x)    ((x)|('\\'<<8))
  155. X
  156. X/*
  157. X * Opcode notes:
  158. X *
  159. X * BRANCH        The set of branches constituting a single choice are hooked
  160. X *                together with their "next" pointers, since precedence prevents
  161. X *                anything being concatenated to any individual branch.  The
  162. X *                "next" pointer of the last BRANCH in a choice points to the
  163. X *                thing following the whole choice.  This is also where the
  164. X *                final "next" pointer of each individual branch points; each
  165. X *                branch starts with the operand node of a BRANCH node.
  166. X *
  167. X * BACK         Normal "next" pointers all implicitly point forward; BACK
  168. X *                exists to make loop structures possible.
  169. X *
  170. X * STAR,PLUS    '=', and complex '*' and '+', are implemented as circular
  171. X *                BRANCH structures using BACK.  Simple cases (one character
  172. X *                per match) are implemented with STAR and PLUS for speed
  173. X *                and to minimize recursive plunges.
  174. X *
  175. X * MOPEN,MCLOSE    ...are numbered at compile time.
  176. X */
  177. X
  178. X/*
  179. X * A node is one char of opcode followed by two chars of "next" pointer.
  180. X * "Next" pointers are stored as two 8-bit pieces, high order first.  The
  181. X * value is a positive offset from the opcode of the node containing it.
  182. X * An operand, if any, simply follows the node.  (Note that much of the
  183. X * code generation knows about this implicit relationship.)
  184. X *
  185. X * Using two bytes for the "next" pointer is vast overkill for most things,
  186. X * but allows patterns to get big without disasters.
  187. X */
  188. X#define OP(p)    (*(p))
  189. X#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
  190. X#define OPERAND(p)        ((p) + 3)
  191. X
  192. X/*
  193. X * See regmagic.h for one further detail of program structure.
  194. X */
  195. X
  196. X
  197. X/*
  198. X * Utility definitions.
  199. X */
  200. X#ifndef CHARBITS
  201. X#define UCHARAT(p)        ((int)*(unsigned char *)(p))
  202. X#else
  203. X#define UCHARAT(p)        ((int)*(p)&CHARBITS)
  204. X#endif
  205. X
  206. X#define EMSG_RETURN(m) { emsg(m); return NULL; }
  207. X
  208. Xstatic int ismult __ARGS((int));
  209. X
  210. X    static int
  211. Xismult(c)
  212. X    int c;
  213. X{
  214. X    return (c == Magic('*') || c == Magic('+') || c == Magic('='));
  215. X}
  216. X
  217. X/*
  218. X * Flags to be passed up and down.
  219. X */
  220. X#define HASWIDTH        01        /* Known never to match null string. */
  221. X#define SIMPLE            02        /* Simple enough to be STAR/PLUS operand. */
  222. X#define SPSTART         04        /* Starts with * or +. */
  223. X#define WORST            0        /* Worst case. */
  224. X
  225. X/*
  226. X * The following allows empty REs, meaning "the same as the previous RE".
  227. X * per the ed(1) manual.
  228. X */
  229. X/* #define EMPTY_RE */            /* this is done outside of regexp */
  230. X#ifdef EMPTY_RE
  231. Xchar_u           *reg_prev_re;
  232. X#endif
  233. X
  234. X#define TILDE
  235. X#ifdef TILDE
  236. Xchar_u           *reg_prev_sub;
  237. X#endif
  238. X
  239. X/*
  240. X * This if for vi's "magic" mode. If magic is false, only ^$\ are magic.
  241. X */
  242. X
  243. Xint                reg_magic = 1;
  244. X
  245. X/*
  246. X * Global work variables for regcomp().
  247. X */
  248. X
  249. Xstatic char_u    *regparse;    /* Input-scan pointer. */
  250. Xstatic int        regnpar;        /* () count. */
  251. Xstatic char_u     regdummy;
  252. Xstatic char_u   *regcode;        /* Code-emit pointer; ®dummy = don't. */
  253. Xstatic long     regsize;        /* Code size. */
  254. Xstatic char_u   **regendp;        /* Ditto for endp. */
  255. X
  256. X/*
  257. X * META contains all characters that may be magic, except '^' and '$'.
  258. X * This depends on the configuration options TILDE, BACKREF.
  259. X * (could be done simpler for compilers that know string concatenation)
  260. X */
  261. X
  262. X#ifdef TILDE
  263. X# ifdef BACKREF
  264. X       static char_u META[] = ".[()|=+*<>~123456789";
  265. X# else
  266. X       static char_u META[] = ".[()|=+*<>~";
  267. X# endif
  268. X#else
  269. X# ifdef BACKREF
  270. X       static char_u META[] = ".[()|=+*<>123456789";
  271. X# else
  272. X       static char_u META[] = ".[()|=+*<>";
  273. X# endif
  274. X#endif
  275. X
  276. X/*
  277. X * Forward declarations for regcomp()'s friends.
  278. X */
  279. Xstatic void        initchr __ARGS((char_u *));
  280. Xstatic int        getchr __ARGS((void));
  281. Xstatic int        peekchr __ARGS((void));
  282. X#define PeekChr() curchr    /* shortcut only when last action was peekchr() */
  283. Xstatic int         curchr;
  284. Xstatic void        skipchr __ARGS((void));
  285. Xstatic void        ungetchr __ARGS((void));
  286. Xstatic char_u    *reg __ARGS((int, int *));
  287. Xstatic char_u    *regbranch __ARGS((int *));
  288. Xstatic char_u    *regpiece __ARGS((int *));
  289. Xstatic char_u    *regatom __ARGS((int *));
  290. Xstatic char_u    *regnode __ARGS((int));
  291. Xstatic char_u    *regnext __ARGS((char_u *));
  292. Xstatic void     regc __ARGS((int));
  293. Xstatic void     unregc __ARGS((void));
  294. Xstatic void     reginsert __ARGS((int, char_u *));
  295. Xstatic void     regtail __ARGS((char_u *, char_u *));
  296. Xstatic void     regoptail __ARGS((char_u *, char_u *));
  297. X
  298. X#undef STRCSPN
  299. X#ifdef STRCSPN
  300. Xstatic int        strcspn __ARGS((const char_u *, const char_u *));
  301. X#endif
  302. X
  303. X/*
  304. X * skip past regular expression
  305. X * stop at end of 'p' of where 'dirc' is found ('/', '?', etc)
  306. X * take care of characters with a backslash in front of it
  307. X * skip strings inside [ and ].
  308. X */
  309. X    char_u *
  310. Xskip_regexp(p, dirc)
  311. X    char_u    *p;
  312. X    int        dirc;
  313. X{
  314. X    int        in_range = FALSE;
  315. X
  316. X    for (; p[0] != NUL; ++p)
  317. X    {
  318. X        if (p[0] == dirc && !in_range)        /* found end of regexp */
  319. X            break;
  320. X        if ((p[0] == '[' && p_magic) || (p[0] == '\\' && p[1] == '[' && !p_magic))
  321. X        {
  322. X            in_range = TRUE;
  323. X            if (p[0] == '\\')
  324. X                ++p;
  325. X                                /* "[^]" and "[]" are not the end of a range */
  326. X            if (p[1] == '^')
  327. X                ++p;
  328. X            if (p[1] == ']')
  329. X                ++p;
  330. X        }
  331. X        else if (p[0] == '\\' && p[1] != NUL)
  332. X            ++p;    /* skip next character */
  333. X        else if (p[0] == ']')
  334. X            in_range = FALSE;
  335. X    }
  336. X    return p;
  337. X}
  338. X
  339. X/*
  340. X - regcomp - compile a regular expression into internal code
  341. X *
  342. X * We can't allocate space until we know how big the compiled form will be,
  343. X * but we can't compile it (and thus know how big it is) until we've got a
  344. X * place to put the code.  So we cheat:  we compile it twice, once with code
  345. X * generation turned off and size counting turned on, and once "for real".
  346. X * This also means that we don't allocate space until we are sure that the
  347. X * thing really will compile successfully, and we never have to move the
  348. X * code and thus invalidate pointers into it.  (Note that it has to be in
  349. X * one piece because free() must be able to free it all.)
  350. X *
  351. X * Beware that the optimization-preparation code in here knows about some
  352. X * of the structure of the compiled regexp.
  353. X */
  354. X    regexp           *
  355. Xregcomp(exp)
  356. X    char_u           *exp;
  357. X{
  358. X    register regexp *r;
  359. X    register char_u  *scan;
  360. X    register char_u  *longest;
  361. X    register int    len;
  362. X    int             flags;
  363. X/*    extern char    *malloc();*/
  364. X
  365. X    if (exp == NULL) {
  366. X        EMSG_RETURN(e_null);
  367. X    }
  368. X
  369. X#ifdef EMPTY_RE            /* this is done outside of regexp */
  370. X    if (*exp == '\0') {
  371. X        if (reg_prev_re) {
  372. X            exp = reg_prev_re;
  373. X        } else {
  374. X            EMSG_RETURN(e_noprevre);
  375. X        }
  376. X    }
  377. X#endif
  378. X
  379. X    /* First pass: determine size, legality. */
  380. X    initchr((char_u *)exp);
  381. X    regnpar = 1;
  382. X    regsize = 0L;
  383. X    regcode = ®dummy;
  384. X    regendp = NULL;
  385. X    regc(MAGIC);
  386. X    if (reg(0, &flags) == NULL)
  387. X        return NULL;
  388. X
  389. X    /* Small enough for pointer-storage convention? */
  390. X    if (regsize >= 32767L)        /* Probably could be 65535L. */
  391. X        EMSG_RETURN(e_toolong);
  392. X
  393. X    /* Allocate space. */
  394. X/*    r = (regexp *) malloc((unsigned) (sizeof(regexp) + regsize));*/
  395. X    r = (regexp *) alloc((unsigned) (sizeof(regexp) + regsize));
  396. X    if (r == NULL)
  397. X        EMSG_RETURN(e_outofmem);
  398. X
  399. X#ifdef EMPTY_RE            /* this is done outside of regexp */
  400. X    if (exp != reg_prev_re) {
  401. X        free(reg_prev_re);
  402. X        if (reg_prev_re = alloc(STRLEN(exp) + 1))
  403. X            STRCPY(reg_prev_re, exp);
  404. X    }
  405. X#endif
  406. X
  407. X    /* Second pass: emit code. */
  408. X    initchr((char_u *)exp);
  409. X    regnpar = 1;
  410. X    regcode = r->program;
  411. X    regendp = r->endp;
  412. X    regc(MAGIC);
  413. X    if (reg(0, &flags) == NULL) {
  414. X        free(r);
  415. X        return NULL;
  416. X    }
  417. X
  418. X    /* Dig out information for optimizations. */
  419. X    r->regstart = '\0';         /* Worst-case defaults. */
  420. X    r->reganch = 0;
  421. X    r->regmust = NULL;
  422. X    r->regmlen = 0;
  423. X    scan = r->program + 1;        /* First BRANCH. */
  424. X    if (OP(regnext(scan)) == END) {     /* Only one top-level choice. */
  425. X        scan = OPERAND(scan);
  426. X
  427. X        /* Starting-point info. */
  428. X        if (OP(scan) == EXACTLY)
  429. X            r->regstart = *OPERAND(scan);
  430. X        else if (OP(scan) == BOL)
  431. X            r->reganch++;
  432. X
  433. X        /*
  434. X         * If there's something expensive in the r.e., find the longest
  435. X         * literal string that must appear and make it the regmust.  Resolve
  436. X         * ties in favor of later strings, since the regstart check works
  437. X         * with the beginning of the r.e. and avoiding duplication
  438. X         * strengthens checking.  Not a strong reason, but sufficient in the
  439. X         * absence of others.
  440. X         */
  441. X        /*
  442. X         * When the r.e. starts with BOW, it is faster to look for a regmust
  443. X         * first. Used a lot for "#" and "*" commands. (Added by mool).
  444. X         */
  445. X        if (flags & SPSTART || OP(scan) == BOW) {
  446. X            longest = NULL;
  447. X            len = 0;
  448. X            for (; scan != NULL; scan = regnext(scan))
  449. X                if (OP(scan) == EXACTLY && STRLEN(OPERAND(scan)) >= (size_t)len) {
  450. X                    longest = OPERAND(scan);
  451. X                    len = STRLEN(OPERAND(scan));
  452. X                }
  453. X            r->regmust = longest;
  454. X            r->regmlen = len;
  455. X        }
  456. X    }
  457. X#ifdef DEBUG
  458. X    regdump(r);
  459. X#endif
  460. X    return r;
  461. X}
  462. X
  463. X/*
  464. X - reg - regular expression, i.e. main body or parenthesized thing
  465. X *
  466. X * Caller must absorb opening parenthesis.
  467. X *
  468. X * Combining parenthesis handling with the base level of regular expression
  469. X * is a trifle forced, but the need to tie the tails of the branches to what
  470. X * follows makes it hard to avoid.
  471. X */
  472. X    static char_u *
  473. Xreg(paren, flagp)
  474. X    int             paren;        /* Parenthesized? */
  475. X    int            *flagp;
  476. X{
  477. X    register char_u  *ret;
  478. X    register char_u  *br;
  479. X    register char_u  *ender;
  480. X    register int    parno = 0;
  481. X    int             flags;
  482. X
  483. X    *flagp = HASWIDTH;            /* Tentatively. */
  484. X
  485. X    /* Make an MOPEN node, if parenthesized. */
  486. X    if (paren) {
  487. X        if (regnpar >= NSUBEXP)
  488. X            EMSG_RETURN(e_toombra);
  489. X        parno = regnpar;
  490. X        regnpar++;
  491. X        ret = regnode(MOPEN + parno);
  492. X        if (regendp)
  493. X            regendp[parno] = NULL;    /* haven't seen the close paren yet */
  494. X    } else
  495. X        ret = NULL;
  496. X
  497. X    /* Pick up the branches, linking them together. */
  498. X    br = regbranch(&flags);
  499. X    if (br == NULL)
  500. X        return NULL;
  501. X    if (ret != NULL)
  502. X        regtail(ret, br);        /* MOPEN -> first. */
  503. X    else
  504. X        ret = br;
  505. X    if (!(flags & HASWIDTH))
  506. X        *flagp &= ~HASWIDTH;
  507. X    *flagp |= flags & SPSTART;
  508. X    while (peekchr() == Magic('|')) {
  509. X        skipchr();
  510. X        br = regbranch(&flags);
  511. X        if (br == NULL)
  512. X            return NULL;
  513. X        regtail(ret, br);        /* BRANCH -> BRANCH. */
  514. X        if (!(flags & HASWIDTH))
  515. X            *flagp &= ~HASWIDTH;
  516. X        *flagp |= flags & SPSTART;
  517. X    }
  518. X
  519. X    /* Make a closing node, and hook it on the end. */
  520. X    ender = regnode((paren) ? MCLOSE + parno : END);
  521. X    regtail(ret, ender);
  522. X
  523. X    /* Hook the tails of the branches to the closing node. */
  524. X    for (br = ret; br != NULL; br = regnext(br))
  525. X        regoptail(br, ender);
  526. X
  527. X    /* Check for proper termination. */
  528. X    if (paren && getchr() != Magic(')')) {
  529. X        EMSG_RETURN(e_toombra);
  530. X    } else if (!paren && peekchr() != '\0') {
  531. X        if (PeekChr() == Magic(')')) {
  532. X            EMSG_RETURN(e_toomket);
  533. X        } else
  534. X            EMSG_RETURN(e_trailing);/* "Can't happen". */
  535. X        /* NOTREACHED */
  536. X    }
  537. X    /*
  538. X     * Here we set the flag allowing back references to this set of
  539. X     * parentheses.
  540. X     */
  541. X    if (paren && regendp)
  542. X        regendp[parno] = ender;    /* have seen the close paren */
  543. X    return ret;
  544. X}
  545. X
  546. X/*
  547. X - regbranch - one alternative of an | operator
  548. X *
  549. X * Implements the concatenation operator.
  550. X */
  551. X    static char_u    *
  552. Xregbranch(flagp)
  553. X    int            *flagp;
  554. X{
  555. X    register char_u  *ret;
  556. X    register char_u  *chain;
  557. X    register char_u  *latest;
  558. X    int             flags;
  559. X
  560. X    *flagp = WORST;             /* Tentatively. */
  561. X
  562. X    ret = regnode(BRANCH);
  563. X    chain = NULL;
  564. X    while (peekchr() != '\0' && PeekChr() != Magic('|') && PeekChr() != Magic(')')) {
  565. X        latest = regpiece(&flags);
  566. X        if (latest == NULL)
  567. X            return NULL;
  568. X        *flagp |= flags & HASWIDTH;
  569. X        if (chain == NULL)        /* First piece. */
  570. X            *flagp |= flags & SPSTART;
  571. X        else
  572. X            regtail(chain, latest);
  573. X        chain = latest;
  574. X    }
  575. X    if (chain == NULL)            /* Loop ran zero times. */
  576. X        (void) regnode(NOTHING);
  577. X
  578. X    return ret;
  579. X}
  580. X
  581. X/*
  582. X - regpiece - something followed by possible [*+=]
  583. X *
  584. X * Note that the branching code sequences used for = and the general cases
  585. X * of * and + are somewhat optimized:  they use the same NOTHING node as
  586. X * both the endmarker for their branch list and the body of the last branch.
  587. X * It might seem that this node could be dispensed with entirely, but the
  588. X * endmarker role is not redundant.
  589. X */
  590. Xstatic char_u    *
  591. Xregpiece(flagp)
  592. X    int            *flagp;
  593. X{
  594. X    register char_u  *ret;
  595. X    register int    op;
  596. X    register char_u  *next;
  597. X    int             flags;
  598. X
  599. X    ret = regatom(&flags);
  600. X    if (ret == NULL)
  601. X        return NULL;
  602. X
  603. X    op = peekchr();
  604. X    if (!ismult(op)) {
  605. X        *flagp = flags;
  606. X        return ret;
  607. X    }
  608. X    if (!(flags & HASWIDTH) && op != Magic('='))
  609. X        EMSG_RETURN((char_u *)"*+ operand could be empty");
  610. X    *flagp = (op != Magic('+')) ? (WORST | SPSTART) : (WORST | HASWIDTH);
  611. X
  612. X    if (op == Magic('*') && (flags & SIMPLE))
  613. X        reginsert(STAR, ret);
  614. X    else if (op == Magic('*')) {
  615. X        /* Emit x* as (x&|), where & means "self". */
  616. X        reginsert(BRANCH, ret); /* Either x */
  617. X        regoptail(ret, regnode(BACK));    /* and loop */
  618. X        regoptail(ret, ret);    /* back */
  619. X        regtail(ret, regnode(BRANCH));    /* or */
  620. X        regtail(ret, regnode(NOTHING)); /* null. */
  621. X    } else if (op == Magic('+') && (flags & SIMPLE))
  622. X        reginsert(PLUS, ret);
  623. X    else if (op == Magic('+')) {
  624. X        /* Emit x+ as x(&|), where & means "self". */
  625. X        next = regnode(BRANCH); /* Either */
  626. X        regtail(ret, next);
  627. X        regtail(regnode(BACK), ret);    /* loop back */
  628. X        regtail(next, regnode(BRANCH)); /* or */
  629. X        regtail(ret, regnode(NOTHING)); /* null. */
  630. X    } else if (op == Magic('=')) {
  631. X        /* Emit x= as (x|) */
  632. X        reginsert(BRANCH, ret); /* Either x */
  633. X        regtail(ret, regnode(BRANCH));    /* or */
  634. X        next = regnode(NOTHING);/* null. */
  635. X        regtail(ret, next);
  636. X        regoptail(ret, next);
  637. X    }
  638. X    skipchr();
  639. X    if (ismult(peekchr()))
  640. X        EMSG_RETURN((char_u *)"Nested *=+");
  641. X
  642. X    return ret;
  643. X}
  644. X
  645. X/*
  646. X - regatom - the lowest level
  647. X *
  648. X * Optimization:  gobbles an entire sequence of ordinary characters so that
  649. X * it can turn them into a single node, which is smaller to store and
  650. X * faster to run.
  651. X */
  652. Xstatic char_u    *
  653. Xregatom(flagp)
  654. X    int            *flagp;
  655. X{
  656. X    register char_u  *ret;
  657. X    int             flags;
  658. X
  659. X    *flagp = WORST;             /* Tentatively. */
  660. X
  661. X    switch (getchr()) {
  662. X      case Magic('^'):
  663. X        ret = regnode(BOL);
  664. X        break;
  665. X      case Magic('$'):
  666. X        ret = regnode(EOL);
  667. X        break;
  668. X      case Magic('<'):
  669. X        ret = regnode(BOW);
  670. X        break;
  671. X      case Magic('>'):
  672. X        ret = regnode(EOW);
  673. X        break;
  674. X      case Magic('.'):
  675. X        ret = regnode(ANY);
  676. X        *flagp |= HASWIDTH | SIMPLE;
  677. X        break;
  678. X      case Magic('['):{
  679. X            /*
  680. X             * In a character class, different parsing rules apply.
  681. X             * Not even \ is special anymore, nothing is.
  682. X             */
  683. X            if (*regparse == '^') {     /* Complement of range. */
  684. X                ret = regnode(ANYBUT);
  685. X                regparse++;
  686. X            } else
  687. X                ret = regnode(ANYOF);
  688. X            if (*regparse == ']' || *regparse == '-')
  689. X                regc(*regparse++);
  690. X            while (*regparse != '\0' && *regparse != ']') {
  691. X                if (*regparse == '-') {
  692. X                    regparse++;
  693. X                    if (*regparse == ']' || *regparse == '\0')
  694. X                        regc('-');
  695. X                    else {
  696. X                        register int    class;
  697. X                        register int    classend;
  698. X
  699. X                        class = UCHARAT(regparse - 2) + 1;
  700. X                        classend = UCHARAT(regparse);
  701. X                        if (class > classend + 1)
  702. X                            EMSG_RETURN(e_invrange);
  703. X                        for (; class <= classend; class++)
  704. X                            regc(class);
  705. X                        regparse++;
  706. X                    }
  707. X                } else if (*regparse == '\\' && regparse[1]) {
  708. X                    regparse++;
  709. X                    regc(*regparse++);
  710. X                } else
  711. X                    regc(*regparse++);
  712. X            }
  713. X            regc('\0');
  714. X            if (*regparse != ']')
  715. X                EMSG_RETURN(e_toomsbra);
  716. X            skipchr();            /* let's be friends with the lexer again */
  717. X            *flagp |= HASWIDTH | SIMPLE;
  718. X        }
  719. X        break;
  720. X      case Magic('('):
  721. X        ret = reg(1, &flags);
  722. X        if (ret == NULL)
  723. X            return NULL;
  724. X        *flagp |= flags & (HASWIDTH | SPSTART);
  725. X        break;
  726. X      case '\0':
  727. X      case Magic('|'):
  728. X      case Magic(')'):
  729. X        EMSG_RETURN(e_internal);    /* Supposed to be caught earlier. */
  730. X        /* break; Not Reached */
  731. X      case Magic('='):
  732. X      case Magic('+'):
  733. X      case Magic('*'):
  734. X        EMSG_RETURN((char_u *)"=+* follows nothing");
  735. X        /* break; Not Reached */
  736. X#ifdef TILDE
  737. X      case Magic('~'):            /* previous substitute pattern */
  738. X            if (reg_prev_sub) {
  739. X                register char_u *p;
  740. X
  741. X                ret = regnode(EXACTLY);
  742. X                p = reg_prev_sub;
  743. X                while (*p) {
  744. X                    regc(*p++);
  745. X                }
  746. X                regc('\0');
  747. X                if (p - reg_prev_sub) {
  748. X                    *flagp |= HASWIDTH;
  749. X                    if ((p - reg_prev_sub) == 1)
  750. X                        *flagp |= SIMPLE;
  751. X                }
  752. X              } else
  753. X                EMSG_RETURN(e_nopresub);
  754. X            break;
  755. X#endif
  756. X#ifdef BACKREF
  757. X      case Magic('1'):
  758. X      case Magic('2'):
  759. X      case Magic('3'):
  760. X      case Magic('4'):
  761. X      case Magic('5'):
  762. X      case Magic('6'):
  763. X      case Magic('7'):
  764. X      case Magic('8'):
  765. X      case Magic('9'): {
  766. X            int                refnum;
  767. X
  768. X            ungetchr();
  769. X            refnum = getchr() - Magic('0');
  770. X            /*
  771. X             * Check if the back reference is legal. We use the parentheses
  772. X             * pointers to mark encountered close parentheses, but this
  773. X             * is only available in the second pass. Checking opens is
  774. X             * always possible.
  775. X             * Should also check that we don't refer to something that
  776. X             * is repeated (+*=): what instance of the repetition should
  777. X             * we match? TODO.
  778. X             */
  779. X            if (refnum < regnpar &&
  780. X                (regendp == NULL || regendp[refnum] != NULL))
  781. X                ret = regnode(BACKREF + refnum);
  782. X            else
  783. X                EMSG_RETURN((char_u *)"Illegal back reference");
  784. X        }
  785. X        break;
  786. X#endif
  787. X      default:{
  788. X            register int    len;
  789. X            int                chr;
  790. X
  791. X            ungetchr();
  792. X            len = 0;
  793. X            ret = regnode(EXACTLY);
  794. X            while ((chr = peekchr()) != '\0' && (chr < Magic(0)))
  795. X            {
  796. X                regc(chr);
  797. X                skipchr();
  798. X                len++;
  799. X            }
  800. X#ifdef DEBUG
  801. X            if (len == 0)
  802. X                 EMSG_RETURN((char_u *)"Unexpected magic character; check META.");
  803. X#endif
  804. X            /*
  805. X             * If there is a following *, \+ or \= we need the character
  806. X             * in front of it as a single character operand
  807. X             */
  808. X            if (len > 1 && ismult(chr))
  809. X            {
  810. X                unregc();            /* Back off of *+= operand */
  811. X                ungetchr();            /* and put it back for next time */
  812. X                --len;
  813. X            }
  814. X            regc('\0');
  815. X            *flagp |= HASWIDTH;
  816. X            if (len == 1)
  817. X                *flagp |= SIMPLE;
  818. X        }
  819. X        break;
  820. X    }
  821. X
  822. X    return ret;
  823. X}
  824. X
  825. X/*
  826. X - regnode - emit a node
  827. X */
  828. Xstatic char_u    *                /* Location. */
  829. Xregnode(op)
  830. X    int            op;
  831. X{
  832. X    register char_u  *ret;
  833. X    register char_u  *ptr;
  834. X
  835. X    ret = regcode;
  836. X    if (ret == ®dummy) {
  837. X        regsize += 3;
  838. X        return ret;
  839. X    }
  840. X    ptr = ret;
  841. X    *ptr++ = op;
  842. X    *ptr++ = '\0';                /* Null "next" pointer. */
  843. X    *ptr++ = '\0';
  844. X    regcode = ptr;
  845. X
  846. X    return ret;
  847. X}
  848. X
  849. X/*
  850. X - regc - emit (if appropriate) a byte of code
  851. X */
  852. Xstatic void
  853. Xregc(b)
  854. X    int            b;
  855. X{
  856. X    if (regcode != ®dummy)
  857. X        *regcode++ = b;
  858. X    else
  859. X        regsize++;
  860. X}
  861. X
  862. X/*
  863. X - unregc - take back (if appropriate) a byte of code
  864. X */
  865. Xstatic void
  866. Xunregc()
  867. X{
  868. X    if (regcode != ®dummy)
  869. X        regcode--;
  870. X    else
  871. X        regsize--;
  872. X}
  873. X
  874. X/*
  875. X - reginsert - insert an operator in front of already-emitted operand
  876. X *
  877. X * Means relocating the operand.
  878. X */
  879. Xstatic void
  880. Xreginsert(op, opnd)
  881. X    int            op;
  882. X    char_u           *opnd;
  883. X{
  884. X    register char_u  *src;
  885. X    register char_u  *dst;
  886. X    register char_u  *place;
  887. X
  888. X    if (regcode == ®dummy) {
  889. X        regsize += 3;
  890. X        return;
  891. X    }
  892. X    src = regcode;
  893. X    regcode += 3;
  894. X    dst = regcode;
  895. X    while (src > opnd)
  896. X        *--dst = *--src;
  897. X
  898. X    place = opnd;                /* Op node, where operand used to be. */
  899. X    *place++ = op;
  900. X    *place++ = '\0';
  901. X    *place = '\0';
  902. X}
  903. X
  904. X/*
  905. X - regtail - set the next-pointer at the end of a node chain
  906. X */
  907. Xstatic void
  908. Xregtail(p, val)
  909. X    char_u           *p;
  910. X    char_u           *val;
  911. X{
  912. X    register char_u  *scan;
  913. X    register char_u  *temp;
  914. X    register int    offset;
  915. X
  916. X    if (p == ®dummy)
  917. X        return;
  918. X
  919. X    /* Find last node. */
  920. X    scan = p;
  921. X    for (;;) {
  922. X        temp = regnext(scan);
  923. X        if (temp == NULL)
  924. X            break;
  925. X        scan = temp;
  926. X    }
  927. X
  928. X    if (OP(scan) == BACK)
  929. X        offset = (int)(scan - val);
  930. X    else
  931. X        offset = (int)(val - scan);
  932. X    *(scan + 1) = (char_u) ((offset >> 8) & 0377);
  933. X    *(scan + 2) = (char_u) (offset & 0377);
  934. X}
  935. X
  936. X/*
  937. X - regoptail - regtail on operand of first argument; nop if operandless
  938. X */
  939. Xstatic void
  940. Xregoptail(p, val)
  941. X    char_u           *p;
  942. X    char_u           *val;
  943. X{
  944. X    /* "Operandless" and "op != BRANCH" are synonymous in practice. */
  945. X    if (p == NULL || p == ®dummy || OP(p) != BRANCH)
  946. X        return;
  947. X    regtail(OPERAND(p), val);
  948. X}
  949. X
  950. X/*
  951. X - getchr() - get the next character from the pattern. We know about
  952. X * magic and such, so therefore we need a lexical analyzer.
  953. X */
  954. X
  955. X/* static int        curchr; */
  956. Xstatic int        prevchr;
  957. Xstatic int        nextchr;    /* used for ungetchr() */
  958. X
  959. Xstatic void
  960. Xinitchr(str)
  961. Xchar_u *str;
  962. X{
  963. X    regparse = str;
  964. X    curchr = prevchr = nextchr = -1;
  965. X}
  966. X
  967. Xstatic int
  968. Xpeekchr()
  969. X{
  970. X    if (curchr < 0) {
  971. X        switch (curchr = regparse[0]) {
  972. X        case '.':
  973. X        case '*':
  974. X    /*    case '+':*/
  975. X    /*    case '=':*/
  976. X        case '[':
  977. X        case '~':
  978. X            if (reg_magic)
  979. X                curchr = Magic(curchr);
  980. X            break;
  981. X        case '^':
  982. X            /* ^ is only magic as the very first character */
  983. X            if (prevchr < 0)
  984. X                curchr = Magic('^');
  985. X            break;
  986. X        case '$':
  987. X            /* $ is only magic as the very last character and in front of '\|' */
  988. X            if (regparse[1] == NUL || (regparse[1] == '\\' && regparse[2] == '|'))
  989. X                curchr = Magic('$');
  990. X            break;
  991. X        case '\\':
  992. X            regparse++;
  993. X            if (regparse[0] == NUL)
  994. X                curchr = '\\';    /* trailing '\' */
  995. X            else if (STRCHR(META, regparse[0]))
  996. X            {
  997. X                /*
  998. X                 * META contains everything that may be magic sometimes, except
  999. X                 * ^ and $ ("\^" and "\$" are never magic).
  1000. X                 * We now fetch the next character and toggle its magicness.
  1001. X                 * Therefore, \ is so meta-magic that it is not in META.
  1002. X                 */
  1003. X                curchr = -1;
  1004. X                peekchr();
  1005. X                curchr ^= Magic(0);
  1006. X            }
  1007. X            else
  1008. X            {
  1009. X                /*
  1010. X                 * Next character can never be (made) magic?
  1011. X                 * Then backslashing it won't do anything.
  1012. X                 */
  1013. X                curchr = regparse[0];
  1014. X            }
  1015. X            break;
  1016. X        }
  1017. X    }
  1018. X
  1019. X    return curchr;
  1020. X}
  1021. X
  1022. Xstatic void
  1023. Xskipchr()
  1024. X{
  1025. X    regparse++;
  1026. X    prevchr = curchr;
  1027. X    curchr = nextchr;        /* use previously unget char, or -1 */
  1028. X    nextchr = -1;
  1029. X}
  1030. X
  1031. Xstatic int
  1032. Xgetchr()
  1033. X{
  1034. X    int chr;
  1035. X
  1036. X    chr = peekchr();
  1037. X    skipchr();
  1038. X
  1039. X    return chr;
  1040. X}
  1041. X
  1042. X/*
  1043. X * put character back. Works only once!
  1044. X */
  1045. Xstatic void
  1046. Xungetchr()
  1047. X{
  1048. X    nextchr = curchr;
  1049. X    curchr = prevchr;
  1050. X    /*
  1051. X     * Backup regparse as well; not because we will use what it points at,
  1052. X     * but because skipchr() will bump it again.
  1053. X     */
  1054. X    regparse--;
  1055. X}
  1056. X
  1057. X/*
  1058. X * regexec and friends
  1059. X */
  1060. X
  1061. X/*
  1062. X * Global work variables for regexec().
  1063. X */
  1064. Xstatic char_u    *reginput;        /* String-input pointer. */
  1065. Xstatic char_u    *regbol;         /* Beginning of input, for ^ check. */
  1066. Xstatic char_u   **regstartp;        /* Pointer to startp array. */
  1067. X/* static char_u   **regendp;    */    /* Ditto for endp. */
  1068. X
  1069. X/*
  1070. X * Forwards.
  1071. X */
  1072. Xstatic int        regtry __ARGS((regexp *, char_u *));
  1073. Xstatic int        regmatch __ARGS((char_u *));
  1074. Xstatic int        regrepeat __ARGS((char_u *));
  1075. X
  1076. X#ifdef DEBUG
  1077. Xint             regnarrate = 1;
  1078. Xvoid            regdump __ARGS((regexp *));
  1079. Xstatic char_u    *regprop __ARGS((char_u *));
  1080. X#endif
  1081. X
  1082. X/*
  1083. X - regexec - match a regexp against a string
  1084. X */
  1085. Xint
  1086. Xregexec(prog, string, at_bol)
  1087. X    register regexp *prog;
  1088. X    register char_u  *string;
  1089. X    int             at_bol;
  1090. X{
  1091. X    register char_u  *s;
  1092. X
  1093. X    /* Be paranoid... */
  1094. X    if (prog == NULL || string == NULL) {
  1095. X        emsg(e_null);
  1096. X        return 0;
  1097. X    }
  1098. X    /* Check validity of program. */
  1099. X    if (UCHARAT(prog->program) != MAGIC) {
  1100. X        emsg(e_re_corr);
  1101. X        return 0;
  1102. X    }
  1103. X    /* If there is a "must appear" string, look for it. */
  1104. X    if (prog->regmust != NULL) {
  1105. X        s = string;
  1106. X        while ((s = cstrchr(s, prog->regmust[0])) != NULL) {
  1107. X            if (cstrncmp(s, prog->regmust, prog->regmlen) == 0)
  1108. X                break;            /* Found it. */
  1109. X            s++;
  1110. X        }
  1111. X        if (s == NULL)            /* Not present. */
  1112. X            return 0;
  1113. X    }
  1114. X    /* Mark beginning of line for ^ . */
  1115. X    if (at_bol)
  1116. X        regbol = string;        /* is possible to match bol */
  1117. X    else
  1118. X        regbol = NULL;            /* we aren't there, so don't match it */
  1119. X
  1120. X    /* Simplest case:  anchored match need be tried only once. */
  1121. X    if (prog->reganch)
  1122. X        return regtry(prog, string);
  1123. X
  1124. X    /* Messy cases:  unanchored match. */
  1125. X    s = string;
  1126. X    if (prog->regstart != '\0')
  1127. X        /* We know what char it must start with. */
  1128. X        while ((s = cstrchr(s, prog->regstart)) != NULL) {
  1129. X            if (regtry(prog, s))
  1130. X                return 1;
  1131. X            s++;
  1132. X        }
  1133. X    else
  1134. X        /* We don't -- general case. */
  1135. X        do {
  1136. X            if (regtry(prog, s))
  1137. X                return 1;
  1138. X        } while (*s++ != '\0');
  1139. X
  1140. X    /* Failure. */
  1141. X    return 0;
  1142. X}
  1143. X
  1144. X/*
  1145. X - regtry - try match at specific point
  1146. X */
  1147. Xstatic int                        /* 0 failure, 1 success */
  1148. Xregtry(prog, string)
  1149. X    regexp           *prog;
  1150. X    char_u           *string;
  1151. X{
  1152. X    register int    i;
  1153. X    register char_u **sp;
  1154. X    register char_u **ep;
  1155. X
  1156. X    reginput = string;
  1157. X    regstartp = prog->startp;
  1158. X    regendp = prog->endp;
  1159. X
  1160. X    sp = prog->startp;
  1161. X    ep = prog->endp;
  1162. X    for (i = NSUBEXP; i > 0; i--) {
  1163. X        *sp++ = NULL;
  1164. X        *ep++ = NULL;
  1165. X    }
  1166. X    if (regmatch(prog->program + 1)) {
  1167. X        prog->startp[0] = string;
  1168. X        prog->endp[0] = reginput;
  1169. X        return 1;
  1170. X    } else
  1171. X        return 0;
  1172. X}
  1173. X
  1174. X/*
  1175. X - regmatch - main matching routine
  1176. X *
  1177. X * Conceptually the strategy is simple:  check to see whether the current
  1178. X * node matches, call self recursively to see whether the rest matches,
  1179. X * and then act accordingly.  In practice we make some effort to avoid
  1180. X * recursion, in particular by going through "ordinary" nodes (that don't
  1181. X * need to know whether the rest of the match failed) by a loop instead of
  1182. X * by recursion.
  1183. X */
  1184. Xstatic int                        /* 0 failure, 1 success */
  1185. Xregmatch(prog)
  1186. X    char_u           *prog;
  1187. X{
  1188. X    register char_u  *scan;        /* Current node. */
  1189. X    char_u           *next;        /* Next node. */
  1190. X
  1191. X    scan = prog;
  1192. X#ifdef DEBUG
  1193. X    if (scan != NULL && regnarrate)
  1194. X        fprintf(stderr, "%s(\n", regprop(scan));
  1195. X#endif
  1196. X    while (scan != NULL) {
  1197. X#ifdef DEBUG
  1198. X        if (regnarrate) {
  1199. X            fprintf(stderr, "%s...\n", regprop(scan));
  1200. X        }
  1201. X#endif
  1202. X        next = regnext(scan);
  1203. X        switch (OP(scan)) {
  1204. X          case BOL:
  1205. X            if (reginput != regbol)
  1206. X                return 0;
  1207. X            break;
  1208. X          case EOL:
  1209. X            if (*reginput != '\0')
  1210. X                return 0;
  1211. X            break;
  1212. X          case BOW:        /* \<word; reginput points to w */
  1213. X#define isidchar(x)    (isalnum(x) || ((x) == '_'))
  1214. X              if (reginput != regbol && isidchar(reginput[-1]))
  1215. X                return 0;
  1216. X              if (!reginput[0] || !isidchar(reginput[0]))
  1217. X                return 0;
  1218. X            break;
  1219. X          case EOW:        /* word\>; reginput points after d */
  1220. X              if (reginput == regbol || !isidchar(reginput[-1]))
  1221. X                return 0;
  1222. X              if (reginput[0] && isidchar(reginput[0]))
  1223. X                return 0;
  1224. X            break;
  1225. X          case ANY:
  1226. X            if (*reginput == '\0')
  1227. X                return 0;
  1228. X            reginput++;
  1229. X            break;
  1230. X          case EXACTLY:{
  1231. X                register int    len;
  1232. X                register char_u  *opnd;
  1233. X
  1234. X                opnd = OPERAND(scan);
  1235. X                /* Inline the first character, for speed. */
  1236. X                if (*opnd != *reginput && (!reg_ic || TO_UPPER(*opnd) != TO_UPPER(*reginput)))
  1237. X                    return 0;
  1238. X                len = STRLEN(opnd);
  1239. X                if (len > 1 && cstrncmp(opnd, reginput, len) != 0)
  1240. X                    return 0;
  1241. X                reginput += len;
  1242. X            }
  1243. X            break;
  1244. X          case ANYOF:
  1245. X            if (*reginput == '\0' || cstrchr(OPERAND(scan), *reginput) == NULL)
  1246. X                return 0;
  1247. X            reginput++;
  1248. X            break;
  1249. X          case ANYBUT:
  1250. X            if (*reginput == '\0' || cstrchr(OPERAND(scan), *reginput) != NULL)
  1251. X                return 0;
  1252. X            reginput++;
  1253. X            break;
  1254. X          case NOTHING:
  1255. X            break;
  1256. X          case BACK:
  1257. X            break;
  1258. X          case MOPEN + 1:
  1259. X          case MOPEN + 2:
  1260. X          case MOPEN + 3:
  1261. X          case MOPEN + 4:
  1262. X          case MOPEN + 5:
  1263. X          case MOPEN + 6:
  1264. X          case MOPEN + 7:
  1265. X          case MOPEN + 8:
  1266. X          case MOPEN + 9:{
  1267. X                register int    no;
  1268. X                register char_u  *save;
  1269. X
  1270. X                no = OP(scan) - MOPEN;
  1271. X                save = regstartp[no];
  1272. X                regstartp[no] = reginput; /* Tentatively */
  1273. X#ifdef DEBUG
  1274. X                printf("MOPEN  %d pre  @'%s' ('%s' )'%s'\n",
  1275. X                    no, save,
  1276. X                    regstartp[no] ? regstartp[no] : "NULL",
  1277. X                    regendp[no] ? regendp[no] : "NULL");
  1278. X#endif
  1279. X
  1280. X                if (regmatch(next)) {
  1281. X#ifdef DEBUG
  1282. X                printf("MOPEN  %d post @'%s' ('%s' )'%s'\n",
  1283. X                    no, save,
  1284. X                    regstartp[no] ? regstartp[no] : "NULL",
  1285. X                    regendp[no] ? regendp[no] : "NULL");
  1286. X#endif
  1287. X                    return 1;
  1288. X                }
  1289. X                regstartp[no] = save;        /* We were wrong... */
  1290. X                return 0;
  1291. X            }
  1292. X            /* break; Not Reached */
  1293. X          case MCLOSE + 1:
  1294. X          case MCLOSE + 2:
  1295. X          case MCLOSE + 3:
  1296. X          case MCLOSE + 4:
  1297. X          case MCLOSE + 5:
  1298. X          case MCLOSE + 6:
  1299. X          case MCLOSE + 7:
  1300. X          case MCLOSE + 8:
  1301. X          case MCLOSE + 9:{
  1302. X                register int    no;
  1303. X                register char_u  *save;
  1304. X
  1305. X                no = OP(scan) - MCLOSE;
  1306. X                save = regendp[no];
  1307. X                regendp[no] = reginput; /* Tentatively */
  1308. X#ifdef DEBUG
  1309. X                printf("MCLOSE %d pre  @'%s' ('%s' )'%s'\n",
  1310. X                    no, save,
  1311. X                    regstartp[no] ? regstartp[no] : "NULL",
  1312. X                    regendp[no] ? regendp[no] : "NULL");
  1313. X#endif
  1314. X
  1315. X                if (regmatch(next)) {
  1316. X#ifdef DEBUG
  1317. X                printf("MCLOSE %d post @'%s' ('%s' )'%s'\n",
  1318. X                    no, save,
  1319. X                    regstartp[no] ? regstartp[no] : "NULL",
  1320. X                    regendp[no] ? regendp[no] : "NULL");
  1321. X#endif
  1322. X                    return 1;
  1323. X                }
  1324. X                regendp[no] = save;        /* We were wrong... */
  1325. X                return 0;
  1326. X            }
  1327. X            /* break; Not Reached */
  1328. X#ifdef BACKREF
  1329. X          case BACKREF + 1:
  1330. X          case BACKREF + 2:
  1331. X          case BACKREF + 3:
  1332. X          case BACKREF + 4:
  1333. X          case BACKREF + 5:
  1334. X          case BACKREF + 6:
  1335. X          case BACKREF + 7:
  1336. X          case BACKREF + 8:
  1337. X          case BACKREF + 9:{
  1338. X                register int    no;
  1339. X                int                len;
  1340. X
  1341. X                no = OP(scan) - BACKREF;
  1342. X                if (regendp[no] != NULL) {
  1343. X                    len = (int)(regendp[no] - regstartp[no]);
  1344. X                    if (cstrncmp(regstartp[no], reginput, len) != 0)
  1345. X                        return 0;
  1346. X                    reginput += len;
  1347. X                } else {
  1348. X                    /*emsg("backref to 0-repeat");*/
  1349. X                    /*return 0;*/
  1350. X                }
  1351. X              }
  1352. X            break;
  1353. X#endif
  1354. X          case BRANCH:{
  1355. X                register char_u  *save;
  1356. X
  1357. X                if (OP(next) != BRANCH) /* No choice. */
  1358. X                    next = OPERAND(scan);        /* Avoid recursion. */
  1359. X                else {
  1360. X                    do {
  1361. X                        save = reginput;
  1362. X                        if (regmatch(OPERAND(scan)))
  1363. X                            return 1;
  1364. X                        reginput = save;
  1365. X                        scan = regnext(scan);
  1366. X                    } while (scan != NULL && OP(scan) == BRANCH);
  1367. X                    return 0;
  1368. X                    /* NOTREACHED */
  1369. X                }
  1370. X            }
  1371. X            break;
  1372. X          case STAR:
  1373. X          case PLUS:{
  1374. X                register int    nextch;
  1375. X                register int    no;
  1376. X                register char_u  *save;
  1377. X                register int    min;
  1378. X
  1379. X                /*
  1380. X                 * Lookahead to avoid useless match attempts when we know
  1381. X                 * what character comes next.
  1382. X                 */
  1383. X                nextch = '\0';
  1384. X                if (OP(next) == EXACTLY)
  1385. X                {
  1386. X                    nextch = *OPERAND(next);
  1387. X                    if (reg_ic)
  1388. X                        nextch = TO_UPPER(nextch);
  1389. X                }
  1390. X                min = (OP(scan) == STAR) ? 0 : 1;
  1391. X                save = reginput;
  1392. X                no = regrepeat(OPERAND(scan));
  1393. X                while (no >= min)
  1394. X                {
  1395. X                    /* If it could work, try it. */
  1396. X                    if (nextch == '\0' || (*reginput == nextch ||
  1397. X                                    (reg_ic && TO_UPPER(*reginput) == nextch)))
  1398. X                        if (regmatch(next))
  1399. X                            return 1;
  1400. X                    /* Couldn't or didn't -- back up. */
  1401. X                    no--;
  1402. X                    reginput = save + no;
  1403. X                }
  1404. X                return 0;
  1405. X            }
  1406. X            /* break; Not Reached */
  1407. X          case END:
  1408. X            return 1;         /* Success! */
  1409. X            /* break; Not Reached */
  1410. X          default:
  1411. X            emsg(e_re_corr);
  1412. X            return 0;
  1413. X            /* break; Not Reached */
  1414. X        }
  1415. X
  1416. X        scan = next;
  1417. X    }
  1418. X
  1419. X    /*
  1420. X     * We get here only if there's trouble -- normally "case END" is the
  1421. X     * terminating point.
  1422. X     */
  1423. X    emsg(e_re_corr);
  1424. X    return 0;
  1425. X}
  1426. X
  1427. X/*
  1428. X - regrepeat - repeatedly match something simple, report how many
  1429. X */
  1430. Xstatic int
  1431. Xregrepeat(p)
  1432. X    char_u           *p;
  1433. X{
  1434. X    register int    count = 0;
  1435. X    register char_u  *scan;
  1436. X    register char_u  *opnd;
  1437. X
  1438. X    scan = reginput;
  1439. X    opnd = OPERAND(p);
  1440. X    switch (OP(p)) {
  1441. X      case ANY:
  1442. X        count = STRLEN(scan);
  1443. X        scan += count;
  1444. X        break;
  1445. X      case EXACTLY:
  1446. X        while (*opnd == *scan || (reg_ic && TO_UPPER(*opnd) == TO_UPPER(*scan)))
  1447. X        {
  1448. X            count++;
  1449. X            scan++;
  1450. X        }
  1451. X        break;
  1452. X      case ANYOF:
  1453. X        while (*scan != '\0' && cstrchr(opnd, *scan) != NULL)
  1454. X        {
  1455. X            count++;
  1456. X            scan++;
  1457. X        }
  1458. X        break;
  1459. X      case ANYBUT:
  1460. X        while (*scan != '\0' && cstrchr(opnd, *scan) == NULL) {
  1461. X            count++;
  1462. X            scan++;
  1463. X        }
  1464. X        break;
  1465. X      default:                    /* Oh dear.  Called inappropriately. */
  1466. X        emsg(e_re_corr);
  1467. X        count = 0;                /* Best compromise. */
  1468. X        break;
  1469. X    }
  1470. X    reginput = scan;
  1471. X
  1472. X    return count;
  1473. X}
  1474. X
  1475. X/*
  1476. X - regnext - dig the "next" pointer out of a node
  1477. X */
  1478. Xstatic char_u    *
  1479. Xregnext(p)
  1480. X    register char_u  *p;
  1481. X{
  1482. X    register int    offset;
  1483. X
  1484. X    if (p == ®dummy)
  1485. X        return NULL;
  1486. X
  1487. X    offset = NEXT(p);
  1488. X    if (offset == 0)
  1489. X        return NULL;
  1490. X
  1491. X    if (OP(p) == BACK)
  1492. X        return p - offset;
  1493. X    else
  1494. X        return p + offset;
  1495. X}
  1496. X
  1497. X#ifdef DEBUG
  1498. X
  1499. X/*
  1500. X - regdump - dump a regexp onto stdout in vaguely comprehensible form
  1501. X */
  1502. Xvoid
  1503. Xregdump(r)
  1504. X    regexp           *r;
  1505. X{
  1506. X    register char_u  *s;
  1507. X    register int    op = EXACTLY;        /* Arbitrary non-END op. */
  1508. X    register char_u  *next;
  1509. X    /*extern char_u    *strchr();*/
  1510. X
  1511. X
  1512. X    s = r->program + 1;
  1513. X    while (op != END) {         /* While that wasn't END last time... */
  1514. X        op = OP(s);
  1515. X        printf("%2d%s", s - r->program, regprop(s));    /* Where, what. */
  1516. X        next = regnext(s);
  1517. X        if (next == NULL)        /* Next ptr. */
  1518. X            printf("(0)");
  1519. X        else
  1520. X            printf("(%d)", (s - r->program) + (next - s));
  1521. X        s += 3;
  1522. X        if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
  1523. X            /* Literal string, where present. */
  1524. X            while (*s != '\0') {
  1525. X                putchar(*s);
  1526. X                s++;
  1527. X            }
  1528. X            s++;
  1529. X        }
  1530. X        putchar('\n');
  1531. X    }
  1532. X
  1533. X    /* Header fields of interest. */
  1534. X    if (r->regstart != '\0')
  1535. X        printf("start `%c' ", r->regstart);
  1536. X    if (r->reganch)
  1537. X        printf("anchored ");
  1538. X    if (r->regmust != NULL)
  1539. X        printf("must have \"%s\"", r->regmust);
  1540. X    printf("\n");
  1541. X}
  1542. X
  1543. X/*
  1544. X - regprop - printable representation of opcode
  1545. X */
  1546. Xstatic char_u    *
  1547. Xregprop(op)
  1548. X    char_u           *op;
  1549. X{
  1550. X    register char_u  *p;
  1551. X    static char_u     buf[50];
  1552. X
  1553. X    (void) strcpy(buf, ":");
  1554. X
  1555. X    switch (OP(op)) {
  1556. X      case BOL:
  1557. X        p = "BOL";
  1558. X        break;
  1559. X      case EOL:
  1560. X        p = "EOL";
  1561. X        break;
  1562. X      case ANY:
  1563. X        p = "ANY";
  1564. X        break;
  1565. X      case ANYOF:
  1566. X        p = "ANYOF";
  1567. X        break;
  1568. X      case ANYBUT:
  1569. X        p = "ANYBUT";
  1570. X        break;
  1571. X      case BRANCH:
  1572. X        p = "BRANCH";
  1573. X        break;
  1574. X      case EXACTLY:
  1575. X        p = "EXACTLY";
  1576. X        break;
  1577. X      case NOTHING:
  1578. X        p = "NOTHING";
  1579. X        break;
  1580. X      case BACK:
  1581. X        p = "BACK";
  1582. X        break;
  1583. X      case END:
  1584. X        p = "END";
  1585. X        break;
  1586. X      case MOPEN + 1:
  1587. X      case MOPEN + 2:
  1588. X      case MOPEN + 3:
  1589. X      case MOPEN + 4:
  1590. X      case MOPEN + 5:
  1591. X      case MOPEN + 6:
  1592. X      case MOPEN + 7:
  1593. X      case MOPEN + 8:
  1594. X      case MOPEN + 9:
  1595. X        sprintf(buf + STRLEN(buf), "MOPEN%d", OP(op) - MOPEN);
  1596. X        p = NULL;
  1597. X        break;
  1598. X      case MCLOSE + 1:
  1599. X      case MCLOSE + 2:
  1600. X      case MCLOSE + 3:
  1601. X      case MCLOSE + 4:
  1602. X      case MCLOSE + 5:
  1603. X      case MCLOSE + 6:
  1604. X      case MCLOSE + 7:
  1605. X      case MCLOSE + 8:
  1606. X      case MCLOSE + 9:
  1607. X        sprintf(buf + STRLEN(buf), "MCLOSE%d", OP(op) - MCLOSE);
  1608. X        p = NULL;
  1609. X        break;
  1610. X      case BACKREF + 1:
  1611. X      case BACKREF + 2:
  1612. X      case BACKREF + 3:
  1613. X      case BACKREF + 4:
  1614. X      case BACKREF + 5:
  1615. X      case BACKREF + 6:
  1616. X      case BACKREF + 7:
  1617. X      case BACKREF + 8:
  1618. X      case BACKREF + 9:
  1619. X        sprintf(buf + STRLEN(buf), "BACKREF%d", OP(op) - BACKREF);
  1620. X        p = NULL;
  1621. X        break;
  1622. X      case STAR:
  1623. X        p = "STAR";
  1624. X        break;
  1625. X      case PLUS:
  1626. X        p = "PLUS";
  1627. X        break;
  1628. X      default:
  1629. X        sprintf(buf + STRLEN(buf), "corrupt %d", OP(op));
  1630. X        p = NULL;
  1631. X        break;
  1632. X    }
  1633. X    if (p != NULL)
  1634. X        (void) strcat(buf, p);
  1635. X    return buf;
  1636. X}
  1637. X#endif
  1638. X
  1639. X/*
  1640. X * The following is provided for those people who do not have strcspn() in
  1641. X * their C libraries.  They should get off their butts and do something
  1642. X * about it; at least one public-domain implementation of those (highly
  1643. X * useful) string routines has been published on Usenet.
  1644. X */
  1645. X#ifdef STRCSPN
  1646. X/*
  1647. X * strcspn - find length of initial segment of s1 consisting entirely
  1648. X * of characters not from s2
  1649. X */
  1650. X
  1651. Xstatic int
  1652. Xstrcspn(s1, s2)
  1653. X    const char_u           *s1;
  1654. X    const char_u           *s2;
  1655. X{
  1656. X    register char_u  *scan1;
  1657. X    register char_u  *scan2;
  1658. X    register int    count;
  1659. X
  1660. X    count = 0;
  1661. X    for (scan1 = s1; *scan1 != '\0'; scan1++) {
  1662. X        for (scan2 = s2; *scan2 != '\0';)        /* ++ moved down. */
  1663. X            if (*scan1 == *scan2++)
  1664. X                return count;
  1665. X        count++;
  1666. X    }
  1667. X    return count;
  1668. X}
  1669. X#endif
  1670. X
  1671. X/*
  1672. X * Compare two strings, ignore case if reg_ic set.
  1673. X * Return 0 if strings match, non-zero otherwise.
  1674. X */
  1675. X    int
  1676. Xcstrncmp(s1, s2, n)
  1677. X    char_u           *s1, *s2;
  1678. X    int             n;
  1679. X{
  1680. X    if (!reg_ic)
  1681. X        return STRNCMP(s1, s2, (size_t)n);
  1682. X
  1683. X    return vim_strnicmp(s1, s2, (size_t)n);
  1684. X}
  1685. X
  1686. X/*
  1687. X * cstrchr: This function is used a lot for simple searches, keep it fast!
  1688. X */
  1689. X    char_u *
  1690. Xcstrchr(s, c)
  1691. X    char_u           *s;
  1692. X    register int    c;
  1693. X{
  1694. X    register char_u           *p;
  1695. X
  1696. X    if (!reg_ic)
  1697. X        return STRCHR(s, c);
  1698. X
  1699. X    c = TO_UPPER(c);
  1700. X
  1701. X    for (p = s; *p; p++)
  1702. X    {
  1703. X        if (TO_UPPER(*p) == c)
  1704. X            return p;
  1705. X    }
  1706. X    return NULL;
  1707. X}
  1708. END_OF_FILE
  1709.   if test 40070 -ne `wc -c <'vim/src/regexp.c'`; then
  1710.     echo shar: \"'vim/src/regexp.c'\" unpacked with wrong size!
  1711.   fi
  1712.   # end of 'vim/src/regexp.c'
  1713. fi
  1714. if test -f 'vim/src/undo.c' -a "${1}" != "-c" ; then 
  1715.   echo shar: Will not clobber existing file \"'vim/src/undo.c'\"
  1716. else
  1717.   echo shar: Extracting \"'vim/src/undo.c'\" \(24811 characters\)
  1718.   sed "s/^X//" >'vim/src/undo.c' <<'END_OF_FILE'
  1719. X/* vi:ts=4:sw=4
  1720. X *
  1721. X * VIM - Vi IMproved        by Bram Moolenaar
  1722. X *
  1723. X * Read the file "credits.txt" for a list of people who contributed.
  1724. X * Read the file "uganda.txt" for copying and usage conditions.
  1725. X */
  1726. X
  1727. X/*
  1728. X * undo.c: multi level undo facility
  1729. X *
  1730. X * The saved lines are stored in a list of lists (one for each buffer):
  1731. X *
  1732. X * b_u_oldhead------------------------------------------------+
  1733. X *                                                            |
  1734. X *                                                            V
  1735. X *                +--------------+    +--------------+    +--------------+
  1736. X * b_u_newhead--->| u_header     |    | u_header     |    | u_header     |
  1737. X *                |     uh_next------>|     uh_next------>|     uh_next---->NULL
  1738. X *         NULL<--------uh_prev  |<---------uh_prev  |<---------uh_prev  |
  1739. X *                |     uh_entry |    |     uh_entry |    |     uh_entry |
  1740. X *                +--------|-----+    +--------|-----+    +--------|-----+
  1741. X *                         |                   |                   |
  1742. X *                         V                   V                   V
  1743. X *                +--------------+    +--------------+    +--------------+
  1744. X *                | u_entry      |    | u_entry      |    | u_entry      |
  1745. X *                |     ue_next  |    |     ue_next  |    |     ue_next  |
  1746. X *                +--------|-----+    +--------|-----+    +--------|-----+
  1747. X *                         |                   |                   |
  1748. X *                         V                   V                   V
  1749. X *                +--------------+            NULL                NULL
  1750. X *                | u_entry      |
  1751. X *                |     ue_next  |
  1752. X *                +--------|-----+
  1753. X *                         |
  1754. X *                         V
  1755. X *                        etc.
  1756. X *
  1757. X * Each u_entry list contains the information for one undo or redo.
  1758. X * curbuf->b_u_curhead points to the header of the last undo (the next redo), or is
  1759. X * NULL if nothing has been undone.
  1760. X *
  1761. X * All data is allocated with u_alloc_line(), thus it will be freed as soon as
  1762. X * we switch files!
  1763. X */
  1764. X
  1765. X#include "vim.h"
  1766. X#include "globals.h"
  1767. X#include "proto.h"
  1768. X#include "param.h"
  1769. X
  1770. Xstatic void u_getbot __ARGS((void));
  1771. Xstatic int u_savecommon __ARGS((linenr_t, linenr_t, linenr_t));
  1772. Xstatic void u_undoredo __ARGS((void));
  1773. Xstatic void u_undo_end __ARGS((void));
  1774. Xstatic void u_freelist __ARGS((struct u_header *));
  1775. Xstatic void u_freeentry __ARGS((struct u_entry *, long));
  1776. X
  1777. Xstatic char_u *u_blockalloc __ARGS((long_u));
  1778. Xstatic void u_free_line __ARGS((char_u *));
  1779. Xstatic char_u *u_alloc_line __ARGS((unsigned));
  1780. Xstatic char_u *u_save_line __ARGS((linenr_t));
  1781. X
  1782. Xstatic long        u_newcount, u_oldcount;
  1783. X
  1784. X/*
  1785. X * save the current line for both the "u" and "U" command
  1786. X */
  1787. X    int
  1788. Xu_save_cursor()
  1789. X{
  1790. X    return (u_save((linenr_t)(curwin->w_cursor.lnum - 1), (linenr_t)(curwin->w_cursor.lnum + 1)));
  1791. X}
  1792. X
  1793. X/*
  1794. X * Save the lines between "top" and "bot" for both the "u" and "U" command.
  1795. X * "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1.
  1796. X * Returns FALSE when lines could not be saved.
  1797. X */
  1798. X    int
  1799. Xu_save(top, bot)
  1800. X    linenr_t top, bot;
  1801. X{
  1802. X    if (top > curbuf->b_ml.ml_line_count || top >= bot || bot > curbuf->b_ml.ml_line_count + 1)
  1803. X        return FALSE;    /* rely on caller to do error messages */
  1804. X
  1805. X    if (top + 2 == bot)
  1806. X        u_saveline((linenr_t)(top + 1));
  1807. X
  1808. X    return (u_savecommon(top, bot, (linenr_t)0));
  1809. X}
  1810. X
  1811. X/*
  1812. X * save the line "lnum" (used by :s command)
  1813. X * The line is replaced, so the new bottom line is lnum + 1.
  1814. X */
  1815. X    int
  1816. Xu_savesub(lnum)
  1817. X    linenr_t    lnum;
  1818. X{
  1819. X    return (u_savecommon(lnum - 1, lnum + 1, lnum + 1));
  1820. X}
  1821. X
  1822. X/*
  1823. X * a new line is inserted before line "lnum" (used by :s command)
  1824. X * The line is inserted, so the new bottom line is lnum + 1.
  1825. X */
  1826. X     int
  1827. Xu_inssub(lnum)
  1828. X    linenr_t    lnum;
  1829. X{
  1830. X    return (u_savecommon(lnum - 1, lnum, lnum + 1));
  1831. X}
  1832. X
  1833. X/*
  1834. X * save the lines "lnum" - "lnum" + nlines (used by delete command)
  1835. X * The lines are deleted, so the new bottom line is lnum.
  1836. X */
  1837. X    int
  1838. Xu_savedel(lnum, nlines)
  1839. X    linenr_t    lnum;
  1840. X    long        nlines;
  1841. X{
  1842. X    return (u_savecommon(lnum - 1, lnum + nlines, lnum));
  1843. X}
  1844. X
  1845. X    static int 
  1846. Xu_savecommon(top, bot, newbot)
  1847. X    linenr_t top, bot;
  1848. X    linenr_t newbot;
  1849. X{
  1850. X    linenr_t        lnum;
  1851. X    long            i;
  1852. X    struct u_header *uhp;
  1853. X    struct u_entry    *uep;
  1854. X    long            size;
  1855. X
  1856. X    /*
  1857. X     * if curbuf->b_u_synced == TRUE make a new header
  1858. X     */
  1859. X    if (curbuf->b_u_synced)
  1860. X    {
  1861. X        /*
  1862. X         * if we undid more than we redid, free the entry lists before and
  1863. X         * including curbuf->b_u_curhead
  1864. X         */
  1865. X        while (curbuf->b_u_curhead != NULL)
  1866. X            u_freelist(curbuf->b_u_newhead);
  1867. X
  1868. X        /*
  1869. X         * free headers to keep the size right
  1870. X         */
  1871. X        while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
  1872. X            u_freelist(curbuf->b_u_oldhead);
  1873. X
  1874. X        if (p_ul < 0)            /* no undo at all */
  1875. X            return TRUE;
  1876. X
  1877. X        /*
  1878. X         * make a new header entry
  1879. X         */
  1880. X        uhp = (struct u_header *)u_alloc_line((unsigned)sizeof(struct u_header));
  1881. X        if (uhp == NULL)
  1882. X            goto nomem;
  1883. X        uhp->uh_prev = NULL;
  1884. X        uhp->uh_next = curbuf->b_u_newhead;
  1885. X        if (curbuf->b_u_newhead != NULL)
  1886. X            curbuf->b_u_newhead->uh_prev = uhp;
  1887. X        uhp->uh_entry = NULL;
  1888. X        uhp->uh_cursor = curwin->w_cursor;        /* save cursor position for undo */
  1889. X        uhp->uh_changed = curbuf->b_changed;    /* save changed flag for undo */
  1890. X                                                /* save named marks for undo */
  1891. X        memmove((char *)uhp->uh_namedm, (char *)curbuf->b_namedm, sizeof(FPOS) * NMARKS); 
  1892. X        curbuf->b_u_newhead = uhp;
  1893. X        if (curbuf->b_u_oldhead == NULL)
  1894. X            curbuf->b_u_oldhead = uhp;
  1895. X        ++curbuf->b_u_numhead;
  1896. X    }
  1897. X    else    /* find line number for ue_bot for previous u_save() */
  1898. X        u_getbot();
  1899. X
  1900. X    size = bot - top - 1;
  1901. X#ifndef UNIX
  1902. X        /*
  1903. X         * With Amiga and MSDOS we can't handle big undo's, because then
  1904. X         * u_alloc_line would have to allocate a block larger than 32K
  1905. X         */
  1906. X    if (size >= 8000)
  1907. X        goto nomem;
  1908. X#endif
  1909. X
  1910. X    /*
  1911. X     * add lines in front of entry list
  1912. X     */
  1913. X    uep = (struct u_entry *)u_alloc_line((unsigned)sizeof(struct u_entry));
  1914. X    if (uep == NULL)
  1915. X        goto nomem;
  1916. X
  1917. X    uep->ue_size = size;
  1918. X    uep->ue_top = top;
  1919. X    uep->ue_lcount = 0;
  1920. X    if (newbot)
  1921. X        uep->ue_bot = newbot;
  1922. X        /*
  1923. X         * use 0 for ue_bot if bot is below last line or if the buffer is empty, in
  1924. X         * which case the last line may be replaced (e.g. with 'O' command).
  1925. X         */
  1926. X    else if (bot > curbuf->b_ml.ml_line_count || bufempty())
  1927. X        uep->ue_bot = 0;
  1928. X    else
  1929. X        uep->ue_lcount = curbuf->b_ml.ml_line_count;    /* we have to compute ue_bot later */
  1930. X
  1931. X    if (size)
  1932. X    {
  1933. X        if ((uep->ue_array = (char_u **)u_alloc_line((unsigned)(sizeof(char_u *) * size))) == NULL)
  1934. X        {
  1935. X            u_freeentry(uep, 0L);
  1936. X            goto nomem;
  1937. X        }
  1938. X        for (i = 0, lnum = top + 1; i < size; ++i)
  1939. X        {
  1940. X            if ((uep->ue_array[i] = u_save_line(lnum++)) == NULL)
  1941. X            {
  1942. X                u_freeentry(uep, i);
  1943. X                goto nomem;
  1944. X            }
  1945. X        }
  1946. X    }
  1947. X    uep->ue_next = curbuf->b_u_newhead->uh_entry;
  1948. X    curbuf->b_u_newhead->uh_entry = uep;
  1949. X    curbuf->b_u_synced = FALSE;
  1950. X    return TRUE;
  1951. X
  1952. Xnomem:
  1953. X    if (ask_yesno((char_u *)"no undo possible; continue anyway") == 'y')
  1954. X        return TRUE;
  1955. X    return FALSE;
  1956. X}
  1957. X
  1958. X    void
  1959. Xu_undo(count)
  1960. X    int count;
  1961. X{
  1962. X    /*
  1963. X     * If we get an undo command while executing a macro, we behave like the 
  1964. X     * original vi. If this happens twice in one macro the result will not
  1965. X     * be compatible.
  1966. X     */
  1967. X    if (curbuf->b_u_synced == FALSE)
  1968. X    {
  1969. X        u_sync();
  1970. X        count = 1;
  1971. X    }
  1972. X
  1973. X    curbuf->b_startop.lnum = 0;            /* unset '[ mark */
  1974. X    curbuf->b_endop.lnum = 0;                /* unset '] mark */
  1975. X    u_newcount = 0;
  1976. X    u_oldcount = 0;
  1977. X    while (count--)
  1978. X    {
  1979. X        if (curbuf->b_u_curhead == NULL)                        /* first undo */
  1980. X            curbuf->b_u_curhead = curbuf->b_u_newhead;
  1981. X        else if (p_ul > 0)                            /* multi level undo */
  1982. X            curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next;            /* get next undo */
  1983. X
  1984. X        if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL)    /* nothing to undo */
  1985. X        {
  1986. X            curbuf->b_u_curhead = curbuf->b_u_oldhead;                    /* stick curbuf->b_u_curhead at end */
  1987. X            beep();
  1988. X            break;
  1989. X        }
  1990. X
  1991. X        u_undoredo();
  1992. X    }
  1993. X    u_undo_end();
  1994. X}
  1995. X
  1996. X    void
  1997. Xu_redo(count)
  1998. X    int count;
  1999. X{
  2000. X    u_newcount = 0;
  2001. X    u_oldcount = 0;
  2002. X    while (count--)
  2003. X    {
  2004. X        if (curbuf->b_u_curhead == NULL || p_ul <= 0)        /* nothing to redo */
  2005. X        {
  2006. X            beep();
  2007. X            break;
  2008. X        }
  2009. X
  2010. X        u_undoredo();
  2011. X
  2012. X        curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev;            /* advance for next redo */
  2013. X    }
  2014. X    u_undo_end();
  2015. X}
  2016. X
  2017. X/*
  2018. X * u_undoredo: common code for undo and redo
  2019. X *
  2020. X * The lines in the file are replaced by the lines in the entry list at curbuf->b_u_curhead.
  2021. X * The replaced lines in the file are saved in the entry list for the next undo/redo.
  2022. X */
  2023. X    static void
  2024. Xu_undoredo()
  2025. X{
  2026. X    char_u        **newarray = NULL;
  2027. X    linenr_t    oldsize;
  2028. X    linenr_t    newsize;
  2029. X    linenr_t    top, bot;
  2030. X    linenr_t    lnum;
  2031. X    linenr_t    newlnum = MAXLNUM;
  2032. X    long        i;
  2033. X    struct u_entry *uep, *nuep;
  2034. X    struct u_entry *newlist = NULL;
  2035. X    int            changed = curbuf->b_changed;
  2036. X    FPOS        namedm[NMARKS];
  2037. X
  2038. X    if (curbuf->b_u_curhead->uh_changed)
  2039. X        CHANGED;
  2040. X    else
  2041. X        UNCHANGED(curbuf);
  2042. X    /*
  2043. X     * save marks before undo/redo
  2044. X     */
  2045. X    memmove((char *)namedm, (char *)curbuf->b_namedm, sizeof(FPOS) * NMARKS); 
  2046. X
  2047. X    for (uep = curbuf->b_u_curhead->uh_entry; uep != NULL; uep = nuep)
  2048. X    {
  2049. X        top = uep->ue_top;
  2050. X        bot = uep->ue_bot;
  2051. X        if (bot == 0)
  2052. X            bot = curbuf->b_ml.ml_line_count + 1;
  2053. X        if (top > curbuf->b_ml.ml_line_count || top >= bot || bot > curbuf->b_ml.ml_line_count + 1)
  2054. X        {
  2055. X            EMSG("u_undo: line numbers wrong");
  2056. X            CHANGED;        /* don't want UNCHANGED now */
  2057. X            return;
  2058. X        }
  2059. X
  2060. X        if (top < newlnum)
  2061. X        {
  2062. X            newlnum = top;
  2063. X            curwin->w_cursor.lnum = top + 1;
  2064. X        }
  2065. X        oldsize = bot - top - 1;    /* number of lines before undo */
  2066. X
  2067. X        newsize = uep->ue_size;        /* number of lines after undo */
  2068. X
  2069. X        /* delete the lines between top and bot and save them in newarray */
  2070. X        if (oldsize)
  2071. X        {
  2072. X            if ((newarray = (char_u **)u_alloc_line((unsigned)(sizeof(char_u *) * oldsize))) == NULL)
  2073. X            {
  2074. X                /*
  2075. X                 * We have messed up the entry list, repair is impossible.
  2076. X                 * we have to free the rest of the list.
  2077. X                 */
  2078. X                while (uep != NULL)
  2079. X                {
  2080. X                    nuep = uep->ue_next;
  2081. X                    u_freeentry(uep, uep->ue_size);
  2082. X                    uep = nuep;
  2083. X                }
  2084. X                break;
  2085. X            }
  2086. X            /* delete backwards, it goes faster in most cases */
  2087. X            for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum)
  2088. X            {
  2089. X                newarray[i] = u_save_line(lnum);
  2090. X                ml_delete(lnum);
  2091. X            }
  2092. X        }
  2093. X
  2094. X        /* insert the lines in u_array between top and bot */
  2095. X        if (newsize)
  2096. X        {
  2097. X            for (lnum = top, i = 0; i < newsize; ++i, ++lnum)
  2098. X            {
  2099. X                ml_append(lnum, uep->ue_array[i], (colnr_t)0, FALSE);
  2100. X                u_free_line(uep->ue_array[i]);
  2101. X            }
  2102. X            u_free_line((char_u *)uep->ue_array);
  2103. X        }
  2104. X
  2105. X        /* adjust marks */
  2106. X        if (oldsize != newsize)
  2107. X        {
  2108. X            mark_adjust(top, top + oldsize - 1, MAXLNUM);
  2109. X            mark_adjust(top + oldsize, MAXLNUM, (long)newsize - (long)oldsize);
  2110. X        }
  2111. X
  2112. X        u_newcount += newsize;
  2113. X        u_oldcount += oldsize;
  2114. X        uep->ue_size = oldsize;
  2115. X        uep->ue_array = newarray;
  2116. X        uep->ue_bot = top + newsize + 1;
  2117. X
  2118. X        /*
  2119. X         * insert this entry in front of the new entry list
  2120. X         */
  2121. X        nuep = uep->ue_next;
  2122. X        uep->ue_next = newlist;
  2123. X        newlist = uep;
  2124. X    }
  2125. X
  2126. X    curbuf->b_u_curhead->uh_entry = newlist;
  2127. X    curbuf->b_u_curhead->uh_changed = changed;
  2128. X
  2129. X    /*
  2130. X     * restore marks from before undo/redo
  2131. X     */
  2132. X    for (i = 0; i < NMARKS; ++i)
  2133. X        if (curbuf->b_u_curhead->uh_namedm[i].lnum)
  2134. X        {
  2135. X            curbuf->b_namedm[i] = curbuf->b_u_curhead->uh_namedm[i];
  2136. X            curbuf->b_u_curhead->uh_namedm[i] = namedm[i];
  2137. X        }
  2138. X
  2139. X    if (curbuf->b_u_curhead->uh_cursor.lnum == curwin->w_cursor.lnum)
  2140. X        curwin->w_cursor.col = curbuf->b_u_curhead->uh_cursor.col;
  2141. X    else
  2142. X        curwin->w_cursor.col = 0;
  2143. X}
  2144. X
  2145. X/*
  2146. X * If we deleted or added lines, report the number of less/more lines.
  2147. X * Otherwise, report the number of changes (this may be incorrect
  2148. X * in some cases, but it's better than nothing).
  2149. X */
  2150. X    static void
  2151. Xu_undo_end()
  2152. X{
  2153. X    if ((u_oldcount -= u_newcount) != 0)
  2154. X        msgmore(-u_oldcount);
  2155. X    else if (u_newcount > p_report)
  2156. X        smsg((char_u *)"%ld change%s", u_newcount, plural(u_newcount));
  2157. X
  2158. X    updateScreen(CURSUPD);
  2159. X}
  2160. X
  2161. X/*
  2162. X * u_sync: stop adding to the current entry list
  2163. X */
  2164. X    void
  2165. Xu_sync()
  2166. X{
  2167. X    if (curbuf->b_u_synced)
  2168. X        return;                /* already synced */
  2169. X    u_getbot();                /* compute ue_bot of previous u_save */
  2170. X    curbuf->b_u_curhead = NULL;
  2171. X}
  2172. X
  2173. X/*
  2174. X * Called after writing the file and setting b_changed to FALSE.
  2175. X * Now an undo means that the buffer is modified.
  2176. X */
  2177. X    void
  2178. Xu_unchanged(buf)
  2179. X    BUF        *buf;
  2180. X{
  2181. X    register struct u_header *uh;
  2182. X
  2183. X    for (uh = buf->b_u_newhead; uh; uh = uh->uh_next)
  2184. X        uh->uh_changed = 1;
  2185. X    buf->b_did_warn = FALSE;
  2186. X}
  2187. X
  2188. X/*
  2189. X * u_getbot(): compute the line number of the previous u_save
  2190. X *                 It is called only when b_u_synced is FALSE.
  2191. X */
  2192. X    static void
  2193. Xu_getbot()
  2194. X{
  2195. X    register struct u_entry *uep;
  2196. X
  2197. X    if (curbuf->b_u_newhead == NULL || (uep = curbuf->b_u_newhead->uh_entry) == NULL)
  2198. X    {
  2199. X        EMSG("undo list corrupt");
  2200. X        return;
  2201. X    }
  2202. X
  2203. X    if (uep->ue_lcount != 0)
  2204. X    {
  2205. X        /*
  2206. X         * the new ue_bot is computed from the number of lines that has been
  2207. X         * inserted (0 - deleted) since calling u_save. This is equal to the old
  2208. X         * line count subtracted from the current line count.
  2209. X         */
  2210. X        uep->ue_bot = uep->ue_top + uep->ue_size + 1 + (curbuf->b_ml.ml_line_count - uep->ue_lcount);
  2211. X        if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count)
  2212. X        {
  2213. X            EMSG("undo line missing");
  2214. X            uep->ue_bot = uep->ue_top + 1;    /* assume all lines deleted, will get
  2215. X                                             * all the old lines back without
  2216. X                                             * deleting the current ones */
  2217. X        }
  2218. X        uep->ue_lcount = 0;
  2219. X    }
  2220. X
  2221. X    curbuf->b_u_synced = TRUE;
  2222. X}
  2223. X
  2224. X/*
  2225. X * u_freelist: free one entry list and adjust the pointers
  2226. X */
  2227. X    static void
  2228. Xu_freelist(uhp)
  2229. X    struct u_header *uhp;
  2230. X{
  2231. X    register struct u_entry *uep, *nuep;
  2232. X
  2233. X    for (uep = uhp->uh_entry; uep != NULL; uep = nuep)
  2234. X    {
  2235. X        nuep = uep->ue_next;
  2236. X        u_freeentry(uep, uep->ue_size);
  2237. X    }
  2238. X
  2239. X    if (curbuf->b_u_curhead == uhp)
  2240. X        curbuf->b_u_curhead = NULL;
  2241. X
  2242. X    if (uhp->uh_next == NULL)
  2243. X        curbuf->b_u_oldhead = uhp->uh_prev;
  2244. X    else
  2245. X        uhp->uh_next->uh_prev = uhp->uh_prev;
  2246. X
  2247. X    if (uhp->uh_prev == NULL)
  2248. X        curbuf->b_u_newhead = uhp->uh_next;
  2249. X    else
  2250. X        uhp->uh_prev->uh_next = uhp->uh_next;
  2251. X
  2252. X    u_free_line((char_u *)uhp);
  2253. X    --curbuf->b_u_numhead;
  2254. X}
  2255. X
  2256. X/*
  2257. X * free entry 'uep' and 'n' lines in uep->ue_array[]
  2258. X */
  2259. X    static void
  2260. Xu_freeentry(uep, n)
  2261. X    struct u_entry *uep;
  2262. X    register long n;
  2263. X{
  2264. X    while (n)
  2265. X        u_free_line(uep->ue_array[--n]);
  2266. X    u_free_line((char_u *)uep);
  2267. X}
  2268. X
  2269. X/*
  2270. X * invalidate the undo buffer; called when storage has already been released
  2271. X */
  2272. X    void
  2273. Xu_clearall(buf)
  2274. X    BUF        *buf;
  2275. X{
  2276. X    buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL;
  2277. X    buf->b_u_synced = TRUE;
  2278. X    buf->b_u_numhead = 0;
  2279. X    buf->b_u_line_ptr = NULL;
  2280. X    buf->b_u_line_lnum = 0;
  2281. X}
  2282. X
  2283. X/*
  2284. X * save the line "lnum" for the "U" command
  2285. X */
  2286. X    void
  2287. Xu_saveline(lnum)
  2288. X    linenr_t lnum;
  2289. X{
  2290. X    if (lnum == curbuf->b_u_line_lnum)        /* line is already saved */
  2291. X        return;
  2292. X    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)    /* should never happen */
  2293. X        return;
  2294. X    u_clearline();
  2295. X    curbuf->b_u_line_lnum = lnum;
  2296. X    if (curwin->w_cursor.lnum == lnum)
  2297. X        curbuf->b_u_line_colnr = curwin->w_cursor.col;
  2298. X    else
  2299. X        curbuf->b_u_line_colnr = 0;
  2300. X    curbuf->b_u_line_ptr = u_save_line(lnum);    /* when out of mem alloc() will give a warning */
  2301. X}
  2302. X
  2303. X/*
  2304. X * clear the line saved for the "U" command
  2305. X * (this is used externally for crossing a line while in insert mode)
  2306. X */
  2307. X    void
  2308. Xu_clearline()
  2309. X{
  2310. X    if (curbuf->b_u_line_ptr != NULL)
  2311. X    {
  2312. X        u_free_line(curbuf->b_u_line_ptr);
  2313. X        curbuf->b_u_line_ptr = NULL;
  2314. X        curbuf->b_u_line_lnum = 0;
  2315. X    }
  2316. X}
  2317. X
  2318. X/*
  2319. X * Implementation of the "U" command.
  2320. X * Differentiation from vi: "U" can be undone with the next "U".
  2321. X * We also allow the cursor to be in another line.
  2322. X */
  2323. X    void
  2324. Xu_undoline()
  2325. X{
  2326. X    colnr_t t;
  2327. X    char_u    *old;
  2328. X
  2329. X    if (curbuf->b_u_line_ptr == NULL || curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
  2330. X    {
  2331. X        beep();
  2332. X        return;
  2333. X    }
  2334. X        /* first save the line for the 'u' command */
  2335. X    u_savecommon(curbuf->b_u_line_lnum - 1, curbuf->b_u_line_lnum + 1, (linenr_t)0);
  2336. X    old = u_save_line(curbuf->b_u_line_lnum);
  2337. X    if (old == NULL)
  2338. X        return;
  2339. X    ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
  2340. X    u_free_line(curbuf->b_u_line_ptr);
  2341. X    curbuf->b_u_line_ptr = old;
  2342. X
  2343. X    t = curbuf->b_u_line_colnr;
  2344. X    if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum)
  2345. X        curbuf->b_u_line_colnr = curwin->w_cursor.col;
  2346. X    curwin->w_cursor.col = t;
  2347. X    curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
  2348. X    cursupdate();
  2349. X    updateScreen(VALID_TO_CURSCHAR);
  2350. X}
  2351. X
  2352. X/*
  2353. X * storage allocation for the undo lines and blocks of the current file
  2354. X */
  2355. X
  2356. X/*
  2357. X * Memory is allocated in relatively large blocks. These blocks are linked
  2358. X * in the allocated block list, headed by curbuf->b_block_head. They are all freed
  2359. X * when abandoning a file, so we don't have to free every single line. The
  2360. X * list is kept sorted on memory address.
  2361. X * block_alloc() allocates a block.
  2362. X * m_blockfree() frees all blocks.
  2363. X *
  2364. X * The available chunks of memory are kept in free chunk lists. There is
  2365. X * one free list for each block of allocated memory. The list is kept sorted
  2366. X * on memory address.
  2367. X * u_alloc_line() gets a chunk from the free lists.
  2368. X * u_free_line() returns a chunk to the free lists.
  2369. X * curbuf->b_m_search points to the chunk before the chunk that was
  2370. X * freed/allocated the last time.
  2371. X * curbuf->b_mb_current points to the b_head where curbuf->b_m_search
  2372. X * points into the free list.
  2373. X *
  2374. X *
  2375. X *  b_block_head     /---> block #1     /---> block #2
  2376. X *       mb_next ---/       mb_next ---/       mb_next ---> NULL
  2377. X *       mb_info            mb_info            mb_info
  2378. X *          |                  |                  |
  2379. X *          V                  V                  V
  2380. X *        NULL          free chunk #1.1      free chunk #2.1
  2381. X *                             |                  |
  2382. X *                             V                  V
  2383. X *                      free chunk #1.2          NULL
  2384. X *                             |
  2385. X *                             V
  2386. X *                            NULL
  2387. X *
  2388. X * When a single free chunk list would have been used, it could take a lot
  2389. X * of time in u_free_line() to find the correct place to insert a chunk in the
  2390. X * free list. The single free list would become very long when many lines are
  2391. X * changed (e.g. with :%s/^M$//).
  2392. X */
  2393. X
  2394. X    /*
  2395. X     * this blocksize is used when allocating new lines
  2396. X     */
  2397. X#define MEMBLOCKSIZE 2044
  2398. X
  2399. X/*
  2400. X * The size field contains the size of the chunk, including the size field itself.
  2401. X *
  2402. X * When the chunk is not in-use it is preceded with the m_info structure.
  2403. X * The m_next field links it in one of the free chunk lists.
  2404. X *
  2405. X * On most unix systems structures have to be longword (32 or 64 bit) aligned.
  2406. X * On most other systems they are short (16 bit) aligned.
  2407. X */
  2408. X
  2409. X/* the structure definitions are now in structs.h */
  2410. X
  2411. X#ifdef ALIGN_LONG
  2412. X    /* size of m_size */
  2413. X# define M_OFFSET (sizeof(long_u))
  2414. X#else
  2415. X    /* size of m_size */
  2416. X# define M_OFFSET (sizeof(short_u))
  2417. X#endif
  2418. X
  2419. X/*
  2420. X * Allocate a block of memory and link it in the allocated block list.
  2421. X */
  2422. X    static char_u *
  2423. Xu_blockalloc(size)
  2424. X    long_u    size;
  2425. X{
  2426. X    struct m_block *p;
  2427. X    struct m_block *mp, *next;
  2428. X
  2429. X    p = (struct m_block *)lalloc(size + sizeof(struct m_block), TRUE);
  2430. X    if (p != NULL)
  2431. X    {
  2432. X         /* Insert the block into the allocated block list, keeping it
  2433. X                     sorted on address. */
  2434. X        for (mp = &curbuf->b_block_head; (next = mp->mb_next) != NULL && next < p; mp = next)
  2435. X            ;
  2436. X        p->mb_next = next;                /* link in block list */
  2437. X        mp->mb_next = p;
  2438. X        p->mb_info.m_next = NULL;        /* clear free list */
  2439. X        p->mb_info.m_size = 0;
  2440. X        curbuf->b_mb_current = p;        /* remember current block */
  2441. X        curbuf->b_m_search = NULL;
  2442. X        p++;                            /* return usable memory */
  2443. X    }
  2444. X    return (char_u *)p;
  2445. X}
  2446. X
  2447. X/*
  2448. X * free all allocated memory blocks for the buffer 'buf'
  2449. X */
  2450. X    void
  2451. Xu_blockfree(buf)
  2452. X    BUF        *buf;
  2453. X{
  2454. X    struct m_block    *p, *np;
  2455. X
  2456. X    for (p = buf->b_block_head.mb_next; p != NULL; p = np)
  2457. X    {
  2458. X        np = p->mb_next;
  2459. X        free(p);
  2460. X    }
  2461. X    buf->b_block_head.mb_next = NULL;
  2462. X    buf->b_m_search = NULL;
  2463. X    buf->b_mb_current = NULL;
  2464. X}
  2465. X
  2466. X/*
  2467. X * Free a chunk of memory.
  2468. X * Insert the chunk into the correct free list, keeping it sorted on address.
  2469. X */
  2470. X    static void
  2471. Xu_free_line(ptr)
  2472. X    char_u *ptr;
  2473. X{
  2474. X    register info_t        *next;
  2475. X    register info_t        *prev, *curr;
  2476. X    register info_t        *mp;
  2477. X    struct m_block        *nextb;
  2478. X
  2479. X    if (ptr == NULL || ptr == IObuff)
  2480. X        return;    /* illegal address can happen in out-of-memory situations */
  2481. X
  2482. X    mp = (info_t *)(ptr - M_OFFSET);
  2483. X
  2484. X        /* find block where chunk could be a part off */
  2485. X        /* if we change curbuf->b_mb_current, curbuf->b_m_search is set to NULL */
  2486. X    if (curbuf->b_mb_current == NULL || mp < (info_t *)curbuf->b_mb_current)
  2487. X    {
  2488. X        curbuf->b_mb_current = curbuf->b_block_head.mb_next;
  2489. X        curbuf->b_m_search = NULL;
  2490. X    }
  2491. X    if ((nextb = curbuf->b_mb_current->mb_next) != NULL && (info_t *)nextb < mp)
  2492. X    {
  2493. X        curbuf->b_mb_current = nextb;
  2494. X        curbuf->b_m_search = NULL;
  2495. X    }
  2496. X    while ((nextb = curbuf->b_mb_current->mb_next) != NULL && (info_t *)nextb < mp)
  2497. X        curbuf->b_mb_current = nextb;
  2498. X
  2499. X    curr = NULL;
  2500. X    /*
  2501. X     * If mp is smaller than curbuf->b_m_search->m_next go to the start of
  2502. X     * the free list
  2503. X     */
  2504. X    if (curbuf->b_m_search == NULL || mp < (curbuf->b_m_search->m_next))
  2505. X        next = &(curbuf->b_mb_current->mb_info);
  2506. X    else
  2507. X        next = curbuf->b_m_search;
  2508. X    /*
  2509. X     * The following loop is executed very often.
  2510. X     * Therefore it has been optimized at the cost of readability.
  2511. X     * Keep it fast!
  2512. X     */
  2513. X#ifdef SLOW_BUT_EASY_TO_READ
  2514. X    do
  2515. X    {
  2516. X        prev = curr;
  2517. X        curr = next;
  2518. X        next = next->m_next;
  2519. X    }
  2520. X    while (mp > next && next != NULL);
  2521. X#else
  2522. X    do                                        /* first, middle, last */
  2523. X    {
  2524. X        prev = next->m_next;                /* curr, next, prev */
  2525. X        if (prev == NULL || mp <= prev)
  2526. X        {
  2527. X            prev = curr;
  2528. X            curr = next;
  2529. X            next = next->m_next;
  2530. X            break;
  2531. X        }
  2532. X        curr = prev->m_next;                /* next, prev, curr */
  2533. X        if (curr == NULL || mp <= curr)
  2534. X        {
  2535. X            prev = next;
  2536. X            curr = prev->m_next;
  2537. X            next = curr->m_next;
  2538. X            break;
  2539. X        }
  2540. X        next = curr->m_next;                /* prev, curr, next */
  2541. X    }
  2542. X    while (mp > next && next != NULL);
  2543. X#endif
  2544. X
  2545. X/* if *mp and *next are concatenated, join them into one chunk */
  2546. X    if ((char_u *)mp + mp->m_size == (char_u *)next)
  2547. X    {
  2548. X        mp->m_size += next->m_size;
  2549. X        mp->m_next = next->m_next;
  2550. X    }
  2551. X    else
  2552. X        mp->m_next = next;
  2553. X
  2554. X/* if *curr and *mp are concatenated, join them */
  2555. X    if (prev != NULL && (char_u *)curr + curr->m_size == (char_u *)mp)
  2556. X    {
  2557. X        curr->m_size += mp->m_size;
  2558. X        curr->m_next = mp->m_next;
  2559. X        curbuf->b_m_search = prev;
  2560. X    }
  2561. X    else
  2562. X    {
  2563. X        curr->m_next = mp;
  2564. X        curbuf->b_m_search = curr;    /* put curbuf->b_m_search before freed chunk */
  2565. X    }
  2566. X}
  2567. X
  2568. X/*
  2569. X * Allocate and initialize a new line structure with room for at least
  2570. X * 'size' characters plus a terminating NUL.
  2571. X */
  2572. X    static char_u *
  2573. Xu_alloc_line(size)
  2574. X    register unsigned size;
  2575. X{
  2576. X    register info_t *mp, *mprev, *mp2;
  2577. X    struct m_block    *mbp;
  2578. X    int                 size_align;
  2579. X
  2580. X/*
  2581. X * Add room for size field and trailing NUL byte.
  2582. X * Adjust for minimal size (must be able to store info_t
  2583. X * plus a trailing NUL, so the chunk can be released again)
  2584. X */
  2585. X    size += M_OFFSET + 1;
  2586. X    if (size < sizeof(info_t) + 1)
  2587. X      size = sizeof(info_t) + 1;
  2588. X
  2589. X/*
  2590. X * round size up for alignment
  2591. X */
  2592. X    size_align = (size + ALIGN_MASK) & ~ALIGN_MASK;
  2593. X
  2594. X/*
  2595. X * If curbuf->b_m_search is NULL (uninitialized free list) start at
  2596. X * curbuf->b_block_head
  2597. X */
  2598. X    if (curbuf->b_mb_current == NULL || curbuf->b_m_search == NULL)
  2599. X    {
  2600. X        curbuf->b_mb_current = &curbuf->b_block_head;
  2601. X        curbuf->b_m_search = &(curbuf->b_block_head.mb_info);
  2602. X    }
  2603. X
  2604. X/* search for space in free list */
  2605. X    mprev = curbuf->b_m_search;
  2606. X    mbp = curbuf->b_mb_current;
  2607. X    mp = curbuf->b_m_search->m_next;
  2608. X    if (mp == NULL)
  2609. X    {
  2610. X        if (mbp->mb_next)
  2611. X            mbp = mbp->mb_next;
  2612. X        else
  2613. X            mbp = &curbuf->b_block_head;
  2614. X        mp = curbuf->b_m_search = &(mbp->mb_info);
  2615. X    }
  2616. X    while (mp->m_size < size)
  2617. X    {
  2618. X        if (mp == curbuf->b_m_search)        /* back where we started in free chunk list */
  2619. X        {
  2620. X            if (mbp->mb_next)
  2621. X                mbp = mbp->mb_next;
  2622. X            else
  2623. X                mbp = &curbuf->b_block_head;
  2624. X            mp = curbuf->b_m_search = &(mbp->mb_info);
  2625. X            if (mbp == curbuf->b_mb_current)    /* back where we started in block list */
  2626. X            {
  2627. X                int        n = (size_align > (MEMBLOCKSIZE / 4) ? size_align : MEMBLOCKSIZE);
  2628. X
  2629. X                mp = (info_t *)u_blockalloc((long_u)n);
  2630. X                if (mp == NULL)
  2631. X                    return (NULL);
  2632. X                mp->m_size = n;
  2633. X                u_free_line((char_u *)mp + M_OFFSET);
  2634. X                mp = curbuf->b_m_search;
  2635. X                mbp = curbuf->b_mb_current;
  2636. X            }
  2637. X        }
  2638. X        mprev = mp;
  2639. X        if ((mp = mp->m_next) == NULL)        /* at end of the list */
  2640. X            mp = &(mbp->mb_info);            /* wrap around to begin */
  2641. X    }
  2642. X
  2643. X/* if the chunk we found is large enough, split it up in two */
  2644. X    if ((long)mp->m_size - size_align >= (long)(sizeof(info_t) + 1))
  2645. X    {
  2646. X        mp2 = (info_t *)((char_u *)mp + size_align);
  2647. X        mp2->m_size = mp->m_size - size_align;
  2648. X        mp2->m_next = mp->m_next;
  2649. X        mprev->m_next = mp2;
  2650. X        mp->m_size = size_align;
  2651. X    }
  2652. X    else                    /* remove *mp from the free list */
  2653. X    {
  2654. X        mprev->m_next = mp->m_next;
  2655. X    }
  2656. X    curbuf->b_m_search = mprev;
  2657. X    curbuf->b_mb_current = mbp;
  2658. X
  2659. X    mp = (info_t *)((char_u *)mp + M_OFFSET);
  2660. X    *(char_u *)mp = NUL;                    /* set the first byte to NUL */
  2661. X
  2662. X    return ((char_u *)mp);
  2663. X}
  2664. X
  2665. X/*
  2666. X * u_save_line(): allocate memory with u_alloc_line() and copy line 'lnum' into it.
  2667. X */
  2668. X    static char_u *
  2669. Xu_save_line(lnum)
  2670. X    linenr_t    lnum;
  2671. X{
  2672. X    register char_u *src;
  2673. X    register char_u *dst;
  2674. X    register unsigned len;
  2675. X
  2676. X    src = ml_get(lnum);
  2677. X    len = STRLEN(src);
  2678. X    if ((dst = u_alloc_line(len)) != NULL)
  2679. X        memmove((char *)dst, (char *)src, (size_t)(len + 1));
  2680. X    return (dst);
  2681. X}
  2682. END_OF_FILE
  2683.   if test 24811 -ne `wc -c <'vim/src/undo.c'`; then
  2684.     echo shar: \"'vim/src/undo.c'\" unpacked with wrong size!
  2685.   fi
  2686.   # end of 'vim/src/undo.c'
  2687. fi
  2688. echo shar: End of archive 11 \(of 26\).
  2689. cp /dev/null ark11isdone
  2690. MISSING=""
  2691. 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 24 25 26 ; do
  2692.     if test ! -f ark${I}isdone ; then
  2693.     MISSING="${MISSING} ${I}"
  2694.     fi
  2695. done
  2696. if test "${MISSING}" = "" ; then
  2697.     echo You have unpacked all 26 archives.
  2698.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2699. else
  2700.     echo You still must unpack the following archives:
  2701.     echo "        " ${MISSING}
  2702. fi
  2703. exit 0
  2704. exit 0 # Just in case...
  2705.