Merge from vendor branch LESS:
[dragonfly.git] / contrib / nvi / ex / ex_subst.c
1 /*-
2  * Copyright (c) 1992, 1993, 1994
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1992, 1993, 1994, 1995, 1996
5  *      Keith Bostic.  All rights reserved.
6  *
7  * See the LICENSE file for redistribution information.
8  */
9
10 #include "config.h"
11
12 #ifndef lint
13 static const char sccsid[] = "@(#)ex_subst.c    10.37 (Berkeley) 9/15/96";
14 #endif /* not lint */
15
16 #include <sys/types.h>
17 #include <sys/queue.h>
18 #include <sys/time.h>
19
20 #include <bitstring.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28
29 #include "../common/common.h"
30 #include "../vi/vi.h"
31
32 #define SUB_FIRST       0x01            /* The 'r' flag isn't reasonable. */
33 #define SUB_MUSTSETR    0x02            /* The 'r' flag is required. */
34
35 static int re_conv __P((SCR *, char **, size_t *, int *));
36 static int re_cscope_conv __P((SCR *, char **, size_t *, int *));
37 static int re_sub __P((SCR *,
38                 char *, char **, size_t *, size_t *, regmatch_t [10]));
39 static int re_tag_conv __P((SCR *, char **, size_t *, int *));
40 static int s __P((SCR *, EXCMD *, char *, regex_t *, u_int));
41
42 /*
43  * ex_s --
44  *      [line [,line]] s[ubstitute] [[/;]pat[/;]/repl[/;] [cgr] [count] [#lp]]
45  *
46  *      Substitute on lines matching a pattern.
47  *
48  * PUBLIC: int ex_s __P((SCR *, EXCMD *));
49  */
50 int
51 ex_s(sp, cmdp)
52         SCR *sp;
53         EXCMD *cmdp;
54 {
55         regex_t *re;
56         size_t blen, len;
57         u_int flags;
58         int delim;
59         char *bp, *ptrn, *rep, *p, *t;
60
61         /*
62          * Skip leading white space.
63          *
64          * !!!
65          * Historic vi allowed any non-alphanumeric to serve as the
66          * substitution command delimiter.
67          *
68          * !!!
69          * If the arguments are empty, it's the same as &, i.e. we
70          * repeat the last substitution.
71          */
72         if (cmdp->argc == 0)
73                 goto subagain;
74         for (p = cmdp->argv[0]->bp,
75             len = cmdp->argv[0]->len; len > 0; --len, ++p) {
76                 if (!isblank(*p))
77                         break;
78         }
79         if (len == 0)
80 subagain:       return (ex_subagain(sp, cmdp));
81
82         delim = *p++;
83         if (isalnum(delim) || delim == '\\')
84                 return (s(sp, cmdp, p, &sp->subre_c, SUB_MUSTSETR));
85
86         /*
87          * !!!
88          * The full-blown substitute command reset the remembered
89          * state of the 'c' and 'g' suffices.
90          */
91         sp->c_suffix = sp->g_suffix = 0;
92
93         /*
94          * Get the pattern string, toss escaping characters.
95          *
96          * !!!
97          * Historic vi accepted any of the following forms:
98          *
99          *      :s/abc/def/             change "abc" to "def"
100          *      :s/abc/def              change "abc" to "def"
101          *      :s/abc/                 delete "abc"
102          *      :s/abc                  delete "abc"
103          *
104          * QUOTING NOTE:
105          *
106          * Only toss an escaping character if it escapes a delimiter.
107          * This means that "s/A/\\\\f" replaces "A" with "\\f".  It
108          * would be nice to be more regular, i.e. for each layer of
109          * escaping a single escaping character is removed, but that's
110          * not how the historic vi worked.
111          */
112         for (ptrn = t = p;;) {
113                 if (p[0] == '\0' || p[0] == delim) {
114                         if (p[0] == delim)
115                                 ++p;
116                         /*
117                          * !!!
118                          * Nul terminate the pattern string -- it's passed
119                          * to regcomp which doesn't understand anything else.
120                          */
121                         *t = '\0';
122                         break;
123                 }
124                 if (p[0] == '\\')
125                         if (p[1] == delim)
126                                 ++p;
127                         else if (p[1] == '\\')
128                                 *t++ = *p++;
129                 *t++ = *p++;
130         }
131
132         /*
133          * If the pattern string is empty, use the last RE (not just the
134          * last substitution RE).
135          */
136         if (*ptrn == '\0') {
137                 if (sp->re == NULL) {
138                         ex_emsg(sp, NULL, EXM_NOPREVRE);
139                         return (1);
140                 }
141
142                 /* Re-compile the RE if necessary. */
143                 if (!F_ISSET(sp, SC_RE_SEARCH) && re_compile(sp,
144                     sp->re, sp->re_len, NULL, NULL, &sp->re_c, RE_C_SEARCH))
145                         return (1);
146                 flags = 0;
147         } else {
148                 /*
149                  * !!!
150                  * Compile the RE.  Historic practice is that substitutes set
151                  * the search direction as well as both substitute and search
152                  * RE's.  We compile the RE twice, as we don't want to bother
153                  * ref counting the pattern string and (opaque) structure.
154                  */
155                 if (re_compile(sp, ptrn, t - ptrn,
156                     &sp->re, &sp->re_len, &sp->re_c, RE_C_SEARCH))
157                         return (1);
158                 if (re_compile(sp, ptrn, t - ptrn,
159                     &sp->subre, &sp->subre_len, &sp->subre_c, RE_C_SUBST))
160                         return (1);
161                 
162                 flags = SUB_FIRST;
163                 sp->searchdir = FORWARD;
164         }
165         re = &sp->re_c;
166
167         /*
168          * Get the replacement string.
169          *
170          * The special character & (\& if O_MAGIC not set) matches the
171          * entire RE.  No handling of & is required here, it's done by
172          * re_sub().
173          *
174          * The special character ~ (\~ if O_MAGIC not set) inserts the
175          * previous replacement string into this replacement string.
176          * Count ~'s to figure out how much space we need.  We could
177          * special case nonexistent last patterns or whether or not
178          * O_MAGIC is set, but it's probably not worth the effort.
179          *
180          * QUOTING NOTE:
181          *
182          * Only toss an escaping character if it escapes a delimiter or
183          * if O_MAGIC is set and it escapes a tilde.
184          *
185          * !!!
186          * If the entire replacement pattern is "%", then use the last
187          * replacement pattern.  This semantic was added to vi in System
188          * V and then percolated elsewhere, presumably around the time
189          * that it was added to their version of ed(1).
190          */
191         if (p[0] == '\0' || p[0] == delim) {
192                 if (p[0] == delim)
193                         ++p;
194                 if (sp->repl != NULL)
195                         free(sp->repl);
196                 sp->repl = NULL;
197                 sp->repl_len = 0;
198         } else if (p[0] == '%' && (p[1] == '\0' || p[1] == delim))
199                 p += p[1] == delim ? 2 : 1;
200         else {
201                 for (rep = p, len = 0;
202                     p[0] != '\0' && p[0] != delim; ++p, ++len)
203                         if (p[0] == '~')
204                                 len += sp->repl_len;
205                 GET_SPACE_RET(sp, bp, blen, len);
206                 for (t = bp, len = 0, p = rep;;) {
207                         if (p[0] == '\0' || p[0] == delim) {
208                                 if (p[0] == delim)
209                                         ++p;
210                                 break;
211                         }
212                         if (p[0] == '\\') {
213                                 if (p[1] == delim)
214                                         ++p;
215                                 else if (p[1] == '\\') {
216                                         *t++ = *p++;
217                                         ++len;
218                                 } else if (p[1] == '~') {
219                                         ++p;
220                                         if (!O_ISSET(sp, O_MAGIC))
221                                                 goto tilde;
222                                 }
223                         } else if (p[0] == '~' && O_ISSET(sp, O_MAGIC)) {
224 tilde:                          ++p;
225                                 memcpy(t, sp->repl, sp->repl_len);
226                                 t += sp->repl_len;
227                                 len += sp->repl_len;
228                                 continue;
229                         }
230                         *t++ = *p++;
231                         ++len;
232                 }
233                 if ((sp->repl_len = len) != 0) {
234                         if (sp->repl != NULL)
235                                 free(sp->repl);
236                         if ((sp->repl = malloc(len)) == NULL) {
237                                 msgq(sp, M_SYSERR, NULL);
238                                 FREE_SPACE(sp, bp, blen);
239                                 return (1);
240                         }
241                         memcpy(sp->repl, bp, len);
242                 }
243                 FREE_SPACE(sp, bp, blen);
244         }
245         return (s(sp, cmdp, p, re, flags));
246 }
247
248 /*
249  * ex_subagain --
250  *      [line [,line]] & [cgr] [count] [#lp]]
251  *
252  *      Substitute using the last substitute RE and replacement pattern.
253  *
254  * PUBLIC: int ex_subagain __P((SCR *, EXCMD *));
255  */
256 int
257 ex_subagain(sp, cmdp)
258         SCR *sp;
259         EXCMD *cmdp;
260 {
261         if (sp->subre == NULL) {
262                 ex_emsg(sp, NULL, EXM_NOPREVRE);
263                 return (1);
264         }
265         if (!F_ISSET(sp, SC_RE_SUBST) && re_compile(sp,
266             sp->subre, sp->subre_len, NULL, NULL, &sp->subre_c, RE_C_SUBST))
267                 return (1);
268         return (s(sp,
269             cmdp, cmdp->argc ? cmdp->argv[0]->bp : NULL, &sp->subre_c, 0));
270 }
271
272 /*
273  * ex_subtilde --
274  *      [line [,line]] ~ [cgr] [count] [#lp]]
275  *
276  *      Substitute using the last RE and last substitute replacement pattern.
277  *
278  * PUBLIC: int ex_subtilde __P((SCR *, EXCMD *));
279  */
280 int
281 ex_subtilde(sp, cmdp)
282         SCR *sp;
283         EXCMD *cmdp;
284 {
285         if (sp->re == NULL) {
286                 ex_emsg(sp, NULL, EXM_NOPREVRE);
287                 return (1);
288         }
289         if (!F_ISSET(sp, SC_RE_SEARCH) && re_compile(sp,
290             sp->re, sp->re_len, NULL, NULL, &sp->re_c, RE_C_SEARCH))
291                 return (1);
292         return (s(sp,
293             cmdp, cmdp->argc ? cmdp->argv[0]->bp : NULL, &sp->re_c, 0));
294 }
295
296 /*
297  * s --
298  * Do the substitution.  This stuff is *really* tricky.  There are lots of
299  * special cases, and general nastiness.  Don't mess with it unless you're
300  * pretty confident.
301  * 
302  * The nasty part of the substitution is what happens when the replacement
303  * string contains newlines.  It's a bit tricky -- consider the information
304  * that has to be retained for "s/f\(o\)o/^M\1^M\1/".  The solution here is
305  * to build a set of newline offsets which we use to break the line up later,
306  * when the replacement is done.  Don't change it unless you're *damned*
307  * confident.
308  */
309 #define NEEDNEWLINE(sp) {                                               \
310         if (sp->newl_len == sp->newl_cnt) {                             \
311                 sp->newl_len += 25;                                     \
312                 REALLOC(sp, sp->newl, size_t *,                         \
313                     sp->newl_len * sizeof(size_t));                     \
314                 if (sp->newl == NULL) {                                 \
315                         sp->newl_len = 0;                               \
316                         return (1);                                     \
317                 }                                                       \
318         }                                                               \
319 }
320
321 #define BUILD(sp, l, len) {                                             \
322         if (lbclen + (len) > lblen) {                                   \
323                 lblen += MAX(lbclen + (len), 256);                      \
324                 REALLOC(sp, lb, char *, lblen);                         \
325                 if (lb == NULL) {                                       \
326                         lbclen = 0;                                     \
327                         return (1);                                     \
328                 }                                                       \
329         }                                                               \
330         memcpy(lb + lbclen, l, len);                                    \
331         lbclen += len;                                                  \
332 }
333
334 #define NEEDSP(sp, len, pnt) {                                          \
335         if (lbclen + (len) > lblen) {                                   \
336                 lblen += MAX(lbclen + (len), 256);                      \
337                 REALLOC(sp, lb, char *, lblen);                         \
338                 if (lb == NULL) {                                       \
339                         lbclen = 0;                                     \
340                         return (1);                                     \
341                 }                                                       \
342                 pnt = lb + lbclen;                                      \
343         }                                                               \
344 }
345
346 static int
347 s(sp, cmdp, s, re, flags)
348         SCR *sp;
349         EXCMD *cmdp;
350         char *s;
351         regex_t *re;
352         u_int flags;
353 {
354         EVENT ev;
355         MARK from, to;
356         TEXTH tiq;
357         recno_t elno, lno, slno;
358         regmatch_t match[10];
359         size_t blen, cnt, last, lbclen, lblen, len, llen;
360         size_t offset, saved_offset, scno;
361         int cflag, lflag, nflag, pflag, rflag;
362         int didsub, do_eol_match, eflags, empty_ok, eval;
363         int linechanged, matched, quit, rval;
364         char *bp, *lb;
365
366         NEEDFILE(sp, cmdp);
367
368         slno = sp->lno;
369         scno = sp->cno;
370
371         /*
372          * !!!
373          * Historically, the 'g' and 'c' suffices were always toggled as flags,
374          * so ":s/A/B/" was the same as ":s/A/B/ccgg".  If O_EDCOMPATIBLE was
375          * not set, they were initialized to 0 for all substitute commands.  If
376          * O_EDCOMPATIBLE was set, they were initialized to 0 only if the user
377          * specified substitute/replacement patterns (see ex_s()).
378          */
379         if (!O_ISSET(sp, O_EDCOMPATIBLE))
380                 sp->c_suffix = sp->g_suffix = 0;
381
382         /*
383          * Historic vi permitted the '#', 'l' and 'p' options in vi mode, but
384          * it only displayed the last change.  I'd disallow them, but they are
385          * useful in combination with the [v]global commands.  In the current
386          * model the problem is combining them with the 'c' flag -- the screen
387          * would have to flip back and forth between the confirm screen and the
388          * ex print screen, which would be pretty awful.  We do display all
389          * changes, though, for what that's worth.
390          *
391          * !!!
392          * Historic vi was fairly strict about the order of "options", the
393          * count, and "flags".  I'm somewhat fuzzy on the difference between
394          * options and flags, anyway, so this is a simpler approach, and we
395          * just take it them in whatever order the user gives them.  (The ex
396          * usage statement doesn't reflect this.)
397          */
398         cflag = lflag = nflag = pflag = rflag = 0;
399         if (s == NULL)
400                 goto noargs;
401         for (lno = OOBLNO; *s != '\0'; ++s)
402                 switch (*s) {
403                 case ' ':
404                 case '\t':
405                         continue;
406                 case '+':
407                         ++cmdp->flagoff;
408                         break;
409                 case '-':
410                         --cmdp->flagoff;
411                         break;
412                 case '0': case '1': case '2': case '3': case '4':
413                 case '5': case '6': case '7': case '8': case '9':
414                         if (lno != OOBLNO)
415                                 goto usage;
416                         errno = 0;
417                         lno = strtoul(s, &s, 10);
418                         if (*s == '\0')         /* Loop increment correction. */
419                                 --s;
420                         if (errno == ERANGE) {
421                                 if (lno == LONG_MAX)
422                                         msgq(sp, M_ERR, "153|Count overflow");
423                                 else if (lno == LONG_MIN)
424                                         msgq(sp, M_ERR, "154|Count underflow");
425                                 else
426                                         msgq(sp, M_SYSERR, NULL);
427                                 return (1);
428                         }
429                         /*
430                          * In historic vi, the count was inclusive from the
431                          * second address.
432                          */
433                         cmdp->addr1.lno = cmdp->addr2.lno;
434                         cmdp->addr2.lno += lno - 1;
435                         if (!db_exist(sp, cmdp->addr2.lno) &&
436                             db_last(sp, &cmdp->addr2.lno))
437                                 return (1);
438                         break;
439                 case '#':
440                         nflag = 1;
441                         break;
442                 case 'c':
443                         sp->c_suffix = !sp->c_suffix;
444
445                         /* Ex text structure initialization. */
446                         if (F_ISSET(sp, SC_EX)) {
447                                 memset(&tiq, 0, sizeof(TEXTH));
448                                 CIRCLEQ_INIT(&tiq);
449                         }
450                         break;
451                 case 'g':
452                         sp->g_suffix = !sp->g_suffix;
453                         break;
454                 case 'l':
455                         lflag = 1;
456                         break;
457                 case 'p':
458                         pflag = 1;
459                         break;
460                 case 'r':
461                         if (LF_ISSET(SUB_FIRST)) {
462                                 msgq(sp, M_ERR,
463                     "155|Regular expression specified; r flag meaningless");
464                                 return (1);
465                         }
466                         if (!F_ISSET(sp, SC_RE_SEARCH)) {
467                                 ex_emsg(sp, NULL, EXM_NOPREVRE);
468                                 return (1);
469                         }
470                         rflag = 1;
471                         re = &sp->re_c;
472                         break;
473                 default:
474                         goto usage;
475                 }
476
477         if (*s != '\0' || !rflag && LF_ISSET(SUB_MUSTSETR)) {
478 usage:          ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE);
479                 return (1);
480         }
481
482 noargs: if (F_ISSET(sp, SC_VI) && sp->c_suffix && (lflag || nflag || pflag)) {
483                 msgq(sp, M_ERR,
484 "156|The #, l and p flags may not be combined with the c flag in vi mode");
485                 return (1);
486         }
487
488         /*
489          * bp:          if interactive, line cache
490          * blen:        if interactive, line cache length
491          * lb:          build buffer pointer.
492          * lbclen:      current length of built buffer.
493          * lblen;       length of build buffer.
494          */
495         bp = lb = NULL;
496         blen = lbclen = lblen = 0;
497
498         /* For each line... */
499         for (matched = quit = 0, lno = cmdp->addr1.lno,
500             elno = cmdp->addr2.lno; !quit && lno <= elno; ++lno) {
501
502                 /* Someone's unhappy, time to stop. */
503                 if (INTERRUPTED(sp))
504                         break;
505
506                 /* Get the line. */
507                 if (db_get(sp, lno, DBG_FATAL, &s, &llen))
508                         goto err;
509
510                 /*
511                  * Make a local copy if doing confirmation -- when calling
512                  * the confirm routine we're likely to lose the cached copy.
513                  */
514                 if (sp->c_suffix) {
515                         if (bp == NULL) {
516                                 GET_SPACE_RET(sp, bp, blen, llen);
517                         } else
518                                 ADD_SPACE_RET(sp, bp, blen, llen);
519                         memcpy(bp, s, llen);
520                         s = bp;
521                 }
522
523                 /* Start searching from the beginning. */
524                 offset = 0;
525                 len = llen;
526
527                 /* Reset the build buffer offset. */
528                 lbclen = 0;
529
530                 /* Reset empty match flag. */
531                 empty_ok = 1;
532
533                 /*
534                  * We don't want to have to do a setline if the line didn't
535                  * change -- keep track of whether or not this line changed.
536                  * If doing confirmations, don't want to keep setting the
537                  * line if change is refused -- keep track of substitutions.
538                  */
539                 didsub = linechanged = 0;
540
541                 /* New line, do an EOL match. */
542                 do_eol_match = 1;
543
544                 /* It's not nul terminated, but we pretend it is. */
545                 eflags = REG_STARTEND;
546
547                 /*
548                  * The search area is from s + offset to the EOL.
549                  *
550                  * Generally, match[0].rm_so is the offset of the start
551                  * of the match from the start of the search, and offset
552                  * is the offset of the start of the last search.
553                  */
554 nextmatch:      match[0].rm_so = 0;
555                 match[0].rm_eo = len;
556
557                 /* Get the next match. */
558                 eval = regexec(re, (char *)s + offset, 10, match, eflags);
559
560                 /*
561                  * There wasn't a match or if there was an error, deal with
562                  * it.  If there was a previous match in this line, resolve
563                  * the changes into the database.  Otherwise, just move on.
564                  */
565                 if (eval == REG_NOMATCH)
566                         goto endmatch;
567                 if (eval != 0) {
568                         re_error(sp, eval, re);
569                         goto err;
570                 }
571                 matched = 1;
572
573                 /* Only the first search can match an anchored expression. */
574                 eflags |= REG_NOTBOL;
575
576                 /*
577                  * !!!
578                  * It's possible to match 0-length strings -- for example, the
579                  * command s;a*;X;, when matched against the string "aabb" will
580                  * result in "XbXbX", i.e. the matches are "aa", the space
581                  * between the b's and the space between the b's and the end of
582                  * the string.  There is a similar space between the beginning
583                  * of the string and the a's.  The rule that we use (because vi
584                  * historically used it) is that any 0-length match, occurring
585                  * immediately after a match, is ignored.  Otherwise, the above
586                  * example would have resulted in "XXbXbX".  Another example is
587                  * incorrectly using " *" to replace groups of spaces with one
588                  * space.
589                  *
590                  * The way we do this is that if we just had a successful match,
591                  * the starting offset does not skip characters, and the match
592                  * is empty, ignore the match and move forward.  If there's no
593                  * more characters in the string, we were attempting to match
594                  * after the last character, so quit.
595                  */
596                 if (!empty_ok && match[0].rm_so == 0 && match[0].rm_eo == 0) {
597                         empty_ok = 1;
598                         if (len == 0)
599                                 goto endmatch;
600                         BUILD(sp, s + offset, 1)
601                         ++offset;
602                         --len;
603                         goto nextmatch;
604                 }
605
606                 /* Confirm change. */
607                 if (sp->c_suffix) {
608                         /*
609                          * Set the cursor position for confirmation.  Note,
610                          * if we matched on a '$', the cursor may be past
611                          * the end of line.
612                          */
613                         from.lno = to.lno = lno;
614                         from.cno = match[0].rm_so + offset;
615                         to.cno = match[0].rm_eo + offset;
616                         /*
617                          * Both ex and vi have to correct for a change before
618                          * the first character in the line.
619                          */
620                         if (llen == 0)
621                                 from.cno = to.cno = 0;
622                         if (F_ISSET(sp, SC_VI)) {
623                                 /*
624                                  * Only vi has to correct for a change after
625                                  * the last character in the line.
626                                  *
627                                  * XXX
628                                  * It would be nice to change the vi code so
629                                  * that we could display a cursor past EOL.
630                                  */
631                                 if (to.cno >= llen)
632                                         to.cno = llen - 1;
633                                 if (from.cno >= llen)
634                                         from.cno = llen - 1;
635
636                                 sp->lno = from.lno;
637                                 sp->cno = from.cno;
638                                 if (vs_refresh(sp, 1))
639                                         goto err;
640
641                                 vs_update(sp, msg_cat(sp,
642                                     "169|Confirm change? [n]", NULL), NULL);
643
644                                 if (v_event_get(sp, &ev, 0, 0))
645                                         goto err;
646                                 switch (ev.e_event) {
647                                 case E_CHARACTER:
648                                         break;
649                                 case E_EOF:
650                                 case E_ERR:
651                                 case E_INTERRUPT:
652                                         goto lquit;
653                                 default:
654                                         v_event_err(sp, &ev);
655                                         goto lquit;
656                                 }
657                         } else {
658                                 if (ex_print(sp, cmdp, &from, &to, 0) ||
659                                     ex_scprint(sp, &from, &to))
660                                         goto lquit;
661                                 if (ex_txt(sp, &tiq, 0, TXT_CR))
662                                         goto err;
663                                 ev.e_c = tiq.cqh_first->lb[0];
664                         }
665
666                         switch (ev.e_c) {
667                         case CH_YES:
668                                 break;
669                         default:
670                         case CH_NO:
671                                 didsub = 0;
672                                 BUILD(sp, s +offset, match[0].rm_eo);
673                                 goto skip;
674                         case CH_QUIT:
675                                 /* Set the quit/interrupted flags. */
676 lquit:                          quit = 1;
677                                 F_SET(sp->gp, G_INTERRUPTED);
678
679                                 /*
680                                  * Resolve any changes, then return to (and
681                                  * exit from) the main loop.
682                                  */
683                                 goto endmatch;
684                         }
685                 }
686
687                 /*
688                  * Set the cursor to the last position changed, converting
689                  * from 1-based to 0-based.
690                  */
691                 sp->lno = lno;
692                 sp->cno = match[0].rm_so;
693
694                 /* Copy the bytes before the match into the build buffer. */
695                 BUILD(sp, s + offset, match[0].rm_so);
696
697                 /* Substitute the matching bytes. */
698                 didsub = 1;
699                 if (re_sub(sp, s + offset, &lb, &lbclen, &lblen, match))
700                         goto err;
701
702                 /* Set the change flag so we know this line was modified. */
703                 linechanged = 1;
704
705                 /* Move past the matched bytes. */
706 skip:           offset += match[0].rm_eo;
707                 len -= match[0].rm_eo;
708
709                 /* A match cannot be followed by an empty pattern. */
710                 empty_ok = 0;
711
712                 /*
713                  * If doing a global change with confirmation, we have to
714                  * update the screen.  The basic idea is to store the line
715                  * so the screen update routines can find it, and restart.
716                  */
717                 if (didsub && sp->c_suffix && sp->g_suffix) {
718                         /*
719                          * The new search offset will be the end of the
720                          * modified line.
721                          */
722                         saved_offset = lbclen;
723
724                         /* Copy the rest of the line. */
725                         if (len)
726                                 BUILD(sp, s + offset, len)
727
728                         /* Set the new offset. */
729                         offset = saved_offset;
730
731                         /* Store inserted lines, adjusting the build buffer. */
732                         last = 0;
733                         if (sp->newl_cnt) {
734                                 for (cnt = 0;
735                                     cnt < sp->newl_cnt; ++cnt, ++lno, ++elno) {
736                                         if (db_insert(sp, lno,
737                                             lb + last, sp->newl[cnt] - last))
738                                                 goto err;
739                                         last = sp->newl[cnt] + 1;
740                                         ++sp->rptlines[L_ADDED];
741                                 }
742                                 lbclen -= last;
743                                 offset -= last;
744                                 sp->newl_cnt = 0;
745                         }
746
747                         /* Store and retrieve the line. */
748                         if (db_set(sp, lno, lb + last, lbclen))
749                                 goto err;
750                         if (db_get(sp, lno, DBG_FATAL, &s, &llen))
751                                 goto err;
752                         ADD_SPACE_RET(sp, bp, blen, llen)
753                         memcpy(bp, s, llen);
754                         s = bp;
755                         len = llen - offset;
756
757                         /* Restart the build. */
758                         lbclen = 0;
759                         BUILD(sp, s, offset);
760
761                         /*
762                          * If we haven't already done the after-the-string
763                          * match, do one.  Set REG_NOTEOL so the '$' pattern
764                          * only matches once.
765                          */
766                         if (!do_eol_match)
767                                 goto endmatch;
768                         if (offset == len) {
769                                 do_eol_match = 0;
770                                 eflags |= REG_NOTEOL;
771                         }
772                         goto nextmatch;
773                 }
774
775                 /*
776                  * If it's a global:
777                  *
778                  * If at the end of the string, do a test for the after
779                  * the string match.  Set REG_NOTEOL so the '$' pattern
780                  * only matches once.
781                  */
782                 if (sp->g_suffix && do_eol_match) {
783                         if (len == 0) {
784                                 do_eol_match = 0;
785                                 eflags |= REG_NOTEOL;
786                         }
787                         goto nextmatch;
788                 }
789
790 endmatch:       if (!linechanged)
791                         continue;
792
793                 /* Copy any remaining bytes into the build buffer. */
794                 if (len)
795                         BUILD(sp, s + offset, len)
796
797                 /* Store inserted lines, adjusting the build buffer. */
798                 last = 0;
799                 if (sp->newl_cnt) {
800                         for (cnt = 0;
801                             cnt < sp->newl_cnt; ++cnt, ++lno, ++elno) {
802                                 if (db_insert(sp,
803                                     lno, lb + last, sp->newl[cnt] - last))
804                                         goto err;
805                                 last = sp->newl[cnt] + 1;
806                                 ++sp->rptlines[L_ADDED];
807                         }
808                         lbclen -= last;
809                         sp->newl_cnt = 0;
810                 }
811
812                 /* Store the changed line. */
813                 if (db_set(sp, lno, lb + last, lbclen))
814                         goto err;
815
816                 /* Update changed line counter. */
817                 if (sp->rptlchange != lno) {
818                         sp->rptlchange = lno;
819                         ++sp->rptlines[L_CHANGED];
820                 }
821
822                 /*
823                  * !!!
824                  * Display as necessary.  Historic practice is to only
825                  * display the last line of a line split into multiple
826                  * lines.
827                  */
828                 if (lflag || nflag || pflag) {
829                         from.lno = to.lno = lno;
830                         from.cno = to.cno = 0;
831                         if (lflag)
832                                 (void)ex_print(sp, cmdp, &from, &to, E_C_LIST);
833                         if (nflag)
834                                 (void)ex_print(sp, cmdp, &from, &to, E_C_HASH);
835                         if (pflag)
836                                 (void)ex_print(sp, cmdp, &from, &to, E_C_PRINT);
837                 }
838         }
839
840         /*
841          * !!!
842          * Historically, vi attempted to leave the cursor at the same place if
843          * the substitution was done at the current cursor position.  Otherwise
844          * it moved it to the first non-blank of the last line changed.  There
845          * were some problems: for example, :s/$/foo/ with the cursor on the
846          * last character of the line left the cursor on the last character, or
847          * the & command with multiple occurrences of the matching string in the
848          * line usually left the cursor in a fairly random position.
849          *
850          * We try to do the same thing, with the exception that if the user is
851          * doing substitution with confirmation, we move to the last line about
852          * which the user was consulted, as opposed to the last line that they
853          * actually changed.  This prevents a screen flash if the user doesn't
854          * change many of the possible lines.
855          */
856         if (!sp->c_suffix && (sp->lno != slno || sp->cno != scno)) {
857                 sp->cno = 0;
858                 (void)nonblank(sp, sp->lno, &sp->cno);
859         }
860
861         /*
862          * If not in a global command, and nothing matched, say so.
863          * Else, if none of the lines displayed, put something up.
864          */
865         rval = 0;
866         if (!matched) {
867                 if (!F_ISSET(sp, SC_EX_GLOBAL)) {
868                         msgq(sp, M_ERR, "157|No match found");
869                         goto err;
870                 }
871         } else if (!lflag && !nflag && !pflag)
872                 F_SET(cmdp, E_AUTOPRINT);
873
874         if (0) {
875 err:            rval = 1;
876         }
877
878         if (bp != NULL)
879                 FREE_SPACE(sp, bp, blen);
880         if (lb != NULL)
881                 free(lb);
882         return (rval);
883 }
884
885 /*
886  * re_compile --
887  *      Compile the RE.
888  *
889  * PUBLIC: int re_compile __P((SCR *,
890  * PUBLIC:     char *, size_t, char **, size_t *, regex_t *, u_int));
891  */
892 int
893 re_compile(sp, ptrn, plen, ptrnp, lenp, rep, flags)
894         SCR *sp;
895         char *ptrn, **ptrnp;
896         size_t plen, *lenp;
897         regex_t *rep;
898         u_int flags;
899 {
900         size_t len;
901         int reflags, replaced, rval;
902         char *p;
903
904         /* Set RE flags. */
905         reflags = 0;
906         if (!LF_ISSET(RE_C_CSCOPE | RE_C_TAG)) {
907                 if (O_ISSET(sp, O_EXTENDED))
908                         reflags |= REG_EXTENDED;
909                 if (O_ISSET(sp, O_IGNORECASE))
910                         reflags |= REG_ICASE;
911                 if (O_ISSET(sp, O_ICLOWER)) {
912                         for (p = ptrn, len = plen; len > 0; ++p, --len)
913                                 if (isupper(*p))
914                                         break;
915                         if (len == 0)
916                                 reflags |= REG_ICASE;
917                 }
918         }
919
920         /* If we're replacing a saved value, clear the old one. */
921         if (LF_ISSET(RE_C_SEARCH) && F_ISSET(sp, SC_RE_SEARCH)) {
922                 regfree(&sp->re_c);
923                 F_CLR(sp, SC_RE_SEARCH);
924         }
925         if (LF_ISSET(RE_C_SUBST) && F_ISSET(sp, SC_RE_SUBST)) {
926                 regfree(&sp->subre_c);
927                 F_CLR(sp, SC_RE_SUBST);
928         }
929
930         /*
931          * If we're saving the string, it's a pattern we haven't seen before,
932          * so convert the vi-style RE's to POSIX 1003.2 RE's.  Save a copy for
933          * later recompilation.   Free any previously saved value.
934          */
935         if (ptrnp != NULL) {
936                 if (LF_ISSET(RE_C_CSCOPE)) {
937                         if (re_cscope_conv(sp, &ptrn, &plen, &replaced))
938                                 return (1);
939                         /*
940                          * XXX
941                          * Currently, the match-any-<blank> expression used in
942                          * re_cscope_conv() requires extended RE's.  This may
943                          * not be right or safe.
944                          */
945                         reflags |= REG_EXTENDED;
946                 } else if (LF_ISSET(RE_C_TAG)) {
947                         if (re_tag_conv(sp, &ptrn, &plen, &replaced))
948                                 return (1);
949                 } else
950                         if (re_conv(sp, &ptrn, &plen, &replaced))
951                                 return (1);
952
953                 /* Discard previous pattern. */
954                 if (*ptrnp != NULL) {
955                         free(*ptrnp);
956                         *ptrnp = NULL;
957                 }
958                 if (lenp != NULL)
959                         *lenp = plen;
960
961                 /*
962                  * Copy the string into allocated memory.
963                  *
964                  * XXX
965                  * Regcomp isn't 8-bit clean, so the pattern is nul-terminated
966                  * for now.  There's just no other solution.  
967                  */
968                 MALLOC(sp, *ptrnp, char *, plen + 1);
969                 if (*ptrnp != NULL) {
970                         memcpy(*ptrnp, ptrn, plen);
971                         (*ptrnp)[plen] = '\0';
972                 }
973
974                 /* Free up conversion-routine-allocated memory. */
975                 if (replaced)
976                         FREE_SPACE(sp, ptrn, 0);
977
978                 if (*ptrnp == NULL)
979                         return (1);
980
981                 ptrn = *ptrnp;
982         }
983
984         /*
985          * XXX
986          * Regcomp isn't 8-bit clean, so we just lost if the pattern
987          * contained a nul.  Bummer!
988          */
989         if ((rval = regcomp(rep, ptrn, /* plen, */ reflags)) != 0) {
990                 if (!LF_ISSET(RE_C_SILENT))
991                         re_error(sp, rval, rep); 
992                 return (1);
993         }
994
995         if (LF_ISSET(RE_C_SEARCH))
996                 F_SET(sp, SC_RE_SEARCH);
997         if (LF_ISSET(RE_C_SUBST))
998                 F_SET(sp, SC_RE_SUBST);
999
1000         return (0);
1001 }
1002
1003 /*
1004  * re_conv --
1005  *      Convert vi's regular expressions into something that the
1006  *      the POSIX 1003.2 RE functions can handle.
1007  *
1008  * There are three conversions we make to make vi's RE's (specifically
1009  * the global, search, and substitute patterns) work with POSIX RE's.
1010  *
1011  * 1: If O_MAGIC is not set, strip backslashes from the magic character
1012  *    set (.[*~) that have them, and add them to the ones that don't.
1013  * 2: If O_MAGIC is not set, the string "\~" is replaced with the text
1014  *    from the last substitute command's replacement string.  If O_MAGIC
1015  *    is set, it's the string "~".
1016  * 3: The pattern \<ptrn\> does "word" searches, convert it to use the
1017  *    new RE escapes.
1018  *
1019  * !!!/XXX
1020  * This doesn't exactly match the historic behavior of vi because we do
1021  * the ~ substitution before calling the RE engine, so magic characters
1022  * in the replacement string will be expanded by the RE engine, and they
1023  * weren't historically.  It's a bug.
1024  */
1025 static int
1026 re_conv(sp, ptrnp, plenp, replacedp)
1027         SCR *sp;
1028         char **ptrnp;
1029         size_t *plenp;
1030         int *replacedp;
1031 {
1032         size_t blen, len, needlen;
1033         int magic;
1034         char *bp, *p, *t;
1035
1036         /*
1037          * First pass through, we figure out how much space we'll need.
1038          * We do it in two passes, on the grounds that most of the time
1039          * the user is doing a search and won't have magic characters.
1040          * That way we can skip most of the memory allocation and copies.
1041          */
1042         magic = 0;
1043         for (p = *ptrnp, len = *plenp, needlen = 0; len > 0; ++p, --len)
1044                 switch (*p) {
1045                 case '\\':
1046                         if (len > 1) {
1047                                 --len;
1048                                 switch (*++p) {
1049                                 case '<':
1050                                         magic = 1;
1051                                         needlen += sizeof(RE_WSTART);
1052                                         break;
1053                                 case '>':
1054                                         magic = 1;
1055                                         needlen += sizeof(RE_WSTOP);
1056                                         break;
1057                                 case '~':
1058                                         if (!O_ISSET(sp, O_MAGIC)) {
1059                                                 magic = 1;
1060                                                 needlen += sp->repl_len;
1061                                         }
1062                                         break;
1063                                 case '.':
1064                                 case '[':
1065                                 case '*':
1066                                         if (!O_ISSET(sp, O_MAGIC)) {
1067                                                 magic = 1;
1068                                                 needlen += 1;
1069                                         }
1070                                         break;
1071                                 default:
1072                                         needlen += 2;
1073                                 }
1074                         } else
1075                                 needlen += 1;
1076                         break;
1077                 case '~':
1078                         if (O_ISSET(sp, O_MAGIC)) {
1079                                 magic = 1;
1080                                 needlen += sp->repl_len;
1081                         }
1082                         break;
1083                 case '.':
1084                 case '[':
1085                 case '*':
1086                         if (!O_ISSET(sp, O_MAGIC)) {
1087                                 magic = 1;
1088                                 needlen += 2;
1089                         }
1090                         break;
1091                 default:
1092                         needlen += 1;
1093                         break;
1094                 }
1095
1096         if (!magic) {
1097                 *replacedp = 0;
1098                 return (0);
1099         }
1100
1101         /* Get enough memory to hold the final pattern. */
1102         *replacedp = 1;
1103         GET_SPACE_RET(sp, bp, blen, needlen);
1104
1105         for (p = *ptrnp, len = *plenp, t = bp; len > 0; ++p, --len)
1106                 switch (*p) {
1107                 case '\\':
1108                         if (len > 1) {
1109                                 --len;
1110                                 switch (*++p) {
1111                                 case '<':
1112                                         memcpy(t,
1113                                             RE_WSTART, sizeof(RE_WSTART) - 1);
1114                                         t += sizeof(RE_WSTART) - 1;
1115                                         break;
1116                                 case '>':
1117                                         memcpy(t,
1118                                             RE_WSTOP, sizeof(RE_WSTOP) - 1);
1119                                         t += sizeof(RE_WSTOP) - 1;
1120                                         break;
1121                                 case '~':
1122                                         if (O_ISSET(sp, O_MAGIC))
1123                                                 *t++ = '~';
1124                                         else {
1125                                                 memcpy(t,
1126                                                     sp->repl, sp->repl_len);
1127                                                 t += sp->repl_len;
1128                                         }
1129                                         break;
1130                                 case '.':
1131                                 case '[':
1132                                 case '*':
1133                                         if (O_ISSET(sp, O_MAGIC))
1134                                                 *t++ = '\\';
1135                                         *t++ = *p;
1136                                         break;
1137                                 default:
1138                                         *t++ = '\\';
1139                                         *t++ = *p;
1140                                 }
1141                         } else
1142                                 *t++ = '\\';
1143                         break;
1144                 case '~':
1145                         if (O_ISSET(sp, O_MAGIC)) {
1146                                 memcpy(t, sp->repl, sp->repl_len);
1147                                 t += sp->repl_len;
1148                         } else
1149                                 *t++ = '~';
1150                         break;
1151                 case '.':
1152                 case '[':
1153                 case '*':
1154                         if (!O_ISSET(sp, O_MAGIC))
1155                                 *t++ = '\\';
1156                         *t++ = *p;
1157                         break;
1158                 default:
1159                         *t++ = *p;
1160                         break;
1161                 }
1162
1163         *ptrnp = bp;
1164         *plenp = t - bp;
1165         return (0);
1166 }
1167
1168 /*
1169  * re_tag_conv --
1170  *      Convert a tags search path into something that the POSIX
1171  *      1003.2 RE functions can handle.
1172  */
1173 static int
1174 re_tag_conv(sp, ptrnp, plenp, replacedp)
1175         SCR *sp;
1176         char **ptrnp;
1177         size_t *plenp;
1178         int *replacedp;
1179 {
1180         size_t blen, len;
1181         int lastdollar;
1182         char *bp, *p, *t;
1183
1184         len = *plenp;
1185
1186         /* Max memory usage is 2 times the length of the string. */
1187         *replacedp = 1;
1188         GET_SPACE_RET(sp, bp, blen, len * 2);
1189
1190         p = *ptrnp;
1191         t = bp;
1192
1193         /* If the last character is a '/' or '?', we just strip it. */
1194         if (len > 0 && (p[len - 1] == '/' || p[len - 1] == '?'))
1195                 --len;
1196
1197         /* If the next-to-last or last character is a '$', it's magic. */
1198         if (len > 0 && p[len - 1] == '$') {
1199                 --len;
1200                 lastdollar = 1;
1201         } else
1202                 lastdollar = 0;
1203
1204         /* If the first character is a '/' or '?', we just strip it. */
1205         if (len > 0 && (p[0] == '/' || p[0] == '?')) {
1206                 ++p;
1207                 --len;
1208         }
1209
1210         /* If the first or second character is a '^', it's magic. */
1211         if (p[0] == '^') {
1212                 *t++ = *p++;
1213                 --len;
1214         }
1215
1216         /*
1217          * Escape every other magic character we can find, meanwhile stripping
1218          * the backslashes ctags inserts when escaping the search delimiter
1219          * characters.
1220          */
1221         for (; len > 0; --len) {
1222                 if (p[0] == '\\' && (p[1] == '/' || p[1] == '?')) {
1223                         ++p;
1224                         --len;
1225                 } else if (strchr("^.[]$*", p[0]))
1226                         *t++ = '\\';
1227                 *t++ = *p++;
1228         }
1229         if (lastdollar)
1230                 *t++ = '$';
1231
1232         *ptrnp = bp;
1233         *plenp = t - bp;
1234         return (0);
1235 }
1236
1237 /*
1238  * re_cscope_conv --
1239  *       Convert a cscope search path into something that the POSIX
1240  *      1003.2 RE functions can handle.
1241  */
1242 static int
1243 re_cscope_conv(sp, ptrnp, plenp, replacedp)
1244         SCR *sp;
1245         char **ptrnp;
1246         size_t *plenp;
1247         int *replacedp;
1248 {
1249         size_t blen, len, nspaces;
1250         char *bp, *p, *t;
1251
1252         /*
1253          * Each space in the source line printed by cscope represents an
1254          * arbitrary sequence of spaces, tabs, and comments.
1255          */
1256 #define CSCOPE_RE_SPACE         "([ \t]|/\\*([^*]|\\*/)*\\*/)*"
1257         for (nspaces = 0, p = *ptrnp, len = *plenp; len > 0; ++p, --len)
1258                 if (*p == ' ')
1259                         ++nspaces;
1260
1261         /*
1262          * Allocate plenty of space:
1263          *      the string, plus potential escaping characters;
1264          *      nspaces + 2 copies of CSCOPE_RE_SPACE;
1265          *      ^, $, nul terminator characters.
1266          */
1267         *replacedp = 1;
1268         len = (p - *ptrnp) * 2 + (nspaces + 2) * sizeof(CSCOPE_RE_SPACE) + 3;
1269         GET_SPACE_RET(sp, bp, blen, len);
1270
1271         p = *ptrnp;
1272         t = bp;
1273
1274         *t++ = '^';
1275         memcpy(t, CSCOPE_RE_SPACE, sizeof(CSCOPE_RE_SPACE) - 1);
1276         t += sizeof(CSCOPE_RE_SPACE) - 1;
1277
1278         for (len = *plenp; len > 0; ++p, --len)
1279                 if (*p == ' ') {
1280                         memcpy(t, CSCOPE_RE_SPACE, sizeof(CSCOPE_RE_SPACE) - 1);
1281                         t += sizeof(CSCOPE_RE_SPACE) - 1;
1282                 } else {
1283                         if (strchr("\\^.[]$*+?()|{}", *p))
1284                                 *t++ = '\\';
1285                         *t++ = *p;
1286                 }
1287
1288         memcpy(t, CSCOPE_RE_SPACE, sizeof(CSCOPE_RE_SPACE) - 1);
1289         t += sizeof(CSCOPE_RE_SPACE) - 1;
1290         *t++ = '$';
1291
1292         *ptrnp = bp;
1293         *plenp = t - bp;
1294         return (0);
1295 }
1296
1297 /*
1298  * re_error --
1299  *      Report a regular expression error.
1300  *
1301  * PUBLIC: void re_error __P((SCR *, int, regex_t *));
1302  */
1303 void
1304 re_error(sp, errcode, preg)
1305         SCR *sp;
1306         int errcode;
1307         regex_t *preg;
1308 {
1309         size_t s;
1310         char *oe;
1311
1312         s = regerror(errcode, preg, "", 0);
1313         if ((oe = malloc(s)) == NULL)
1314                 msgq(sp, M_SYSERR, NULL);
1315         else {
1316                 (void)regerror(errcode, preg, oe, s);
1317                 msgq(sp, M_ERR, "RE error: %s", oe);
1318                 free(oe);
1319         }
1320 }
1321
1322 /*
1323  * re_sub --
1324  *      Do the substitution for a regular expression.
1325  */
1326 static int
1327 re_sub(sp, ip, lbp, lbclenp, lblenp, match)
1328         SCR *sp;
1329         char *ip;                       /* Input line. */
1330         char **lbp;
1331         size_t *lbclenp, *lblenp;
1332         regmatch_t match[10];
1333 {
1334         enum { C_NOTSET, C_LOWER, C_ONELOWER, C_ONEUPPER, C_UPPER } conv;
1335         size_t lbclen, lblen;           /* Local copies. */
1336         size_t mlen;                    /* Match length. */
1337         size_t rpl;                     /* Remaining replacement length. */
1338         char *rp;                       /* Replacement pointer. */
1339         int ch;
1340         int no;                         /* Match replacement offset. */
1341         char *p, *t;                    /* Buffer pointers. */
1342         char *lb;                       /* Local copies. */
1343
1344         lb = *lbp;                      /* Get local copies. */
1345         lbclen = *lbclenp;
1346         lblen = *lblenp;
1347
1348         /*
1349          * QUOTING NOTE:
1350          *
1351          * There are some special sequences that vi provides in the
1352          * replacement patterns.
1353          *       & string the RE matched (\& if nomagic set)
1354          *      \# n-th regular subexpression
1355          *      \E end \U, \L conversion
1356          *      \e end \U, \L conversion
1357          *      \l convert the next character to lower-case
1358          *      \L convert to lower-case, until \E, \e, or end of replacement
1359          *      \u convert the next character to upper-case
1360          *      \U convert to upper-case, until \E, \e, or end of replacement
1361          *
1362          * Otherwise, since this is the lowest level of replacement, discard
1363          * all escaping characters.  This (hopefully) matches historic practice.
1364          */
1365 #define OUTCH(ch, nltrans) {                                            \
1366         CHAR_T __ch = (ch);                                             \
1367         u_int __value = KEY_VAL(sp, __ch);                              \
1368         if (nltrans && (__value == K_CR || __value == K_NL)) {          \
1369                 NEEDNEWLINE(sp);                                        \
1370                 sp->newl[sp->newl_cnt++] = lbclen;                      \
1371         } else if (conv != C_NOTSET) {                                  \
1372                 switch (conv) {                                         \
1373                 case C_ONELOWER:                                        \
1374                         conv = C_NOTSET;                                \
1375                         /* FALLTHROUGH */                               \
1376                 case C_LOWER:                                           \
1377                         if (isupper(__ch))                              \
1378                                 __ch = tolower(__ch);                   \
1379                         break;                                          \
1380                 case C_ONEUPPER:                                        \
1381                         conv = C_NOTSET;                                \
1382                         /* FALLTHROUGH */                               \
1383                 case C_UPPER:                                           \
1384                         if (islower(__ch))                              \
1385                                 __ch = toupper(__ch);                   \
1386                         break;                                          \
1387                 default:                                                \
1388                         abort();                                        \
1389                 }                                                       \
1390         }                                                               \
1391         NEEDSP(sp, 1, p);                                               \
1392         *p++ = __ch;                                                    \
1393         ++lbclen;                                                       \
1394 }
1395         conv = C_NOTSET;
1396         for (rp = sp->repl, rpl = sp->repl_len, p = lb + lbclen; rpl--;) {
1397                 switch (ch = *rp++) {
1398                 case '&':
1399                         if (O_ISSET(sp, O_MAGIC)) {
1400                                 no = 0;
1401                                 goto subzero;
1402                         }
1403                         break;
1404                 case '\\':
1405                         if (rpl == 0)
1406                                 break;
1407                         --rpl;
1408                         switch (ch = *rp) {
1409                         case '&':
1410                                 ++rp;
1411                                 if (!O_ISSET(sp, O_MAGIC)) {
1412                                         no = 0;
1413                                         goto subzero;
1414                                 }
1415                                 break;
1416                         case '0': case '1': case '2': case '3': case '4':
1417                         case '5': case '6': case '7': case '8': case '9':
1418                                 no = *rp++ - '0';
1419 subzero:                        if (match[no].rm_so == -1 ||
1420                                     match[no].rm_eo == -1)
1421                                         break;
1422                                 mlen = match[no].rm_eo - match[no].rm_so;
1423                                 for (t = ip + match[no].rm_so; mlen--; ++t)
1424                                         OUTCH(*t, 0);
1425                                 continue;
1426                         case 'e':
1427                         case 'E':
1428                                 ++rp;
1429                                 conv = C_NOTSET;
1430                                 continue;
1431                         case 'l':
1432                                 ++rp;
1433                                 conv = C_ONELOWER;
1434                                 continue;
1435                         case 'L':
1436                                 ++rp;
1437                                 conv = C_LOWER;
1438                                 continue;
1439                         case 'u':
1440                                 ++rp;
1441                                 conv = C_ONEUPPER;
1442                                 continue;
1443                         case 'U':
1444                                 ++rp;
1445                                 conv = C_UPPER;
1446                                 continue;
1447                         default:
1448                                 ++rp;
1449                                 break;
1450                         }
1451                 }
1452                 OUTCH(ch, 1);
1453         }
1454
1455         *lbp = lb;                      /* Update caller's information. */
1456         *lbclenp = lbclen;
1457         *lblenp = lblen;
1458         return (0);
1459 }