sed: rewrite the main loop.
Rewrite the main loop of the "sed s/..." command, shortening it by ten lines and simplifying it by removing the switch statement implementing /g, /1, and /2 separately and repetitively. This will be needed to bring a fix from OpenBSD later. Obtained from: OpenBSD (schwarze CVS Rev. 1.18) MFC after: 3 weeks
This commit is contained in:
parent
dc9643853d
commit
b6f5aa5715
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299211
@ -379,7 +379,7 @@ substitute(struct s_command *cp)
|
|||||||
{
|
{
|
||||||
SPACE tspace;
|
SPACE tspace;
|
||||||
regex_t *re;
|
regex_t *re;
|
||||||
regoff_t re_off, slen;
|
regoff_t slen;
|
||||||
int lastempty, n;
|
int lastempty, n;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
@ -400,61 +400,55 @@ substitute(struct s_command *cp)
|
|||||||
n = cp->u.s->n;
|
n = cp->u.s->n;
|
||||||
lastempty = 1;
|
lastempty = 1;
|
||||||
|
|
||||||
switch (n) {
|
do {
|
||||||
case 0: /* Global */
|
/* Copy the leading retained string. */
|
||||||
do {
|
if (n <= 1 && match[0].rm_so)
|
||||||
if (lastempty || match[0].rm_so != match[0].rm_eo) {
|
cspace(&SS, s, match[0].rm_so, APPEND);
|
||||||
/* Locate start of replaced string. */
|
|
||||||
re_off = match[0].rm_so;
|
|
||||||
/* Copy leading retained string. */
|
|
||||||
cspace(&SS, s, re_off, APPEND);
|
|
||||||
/* Add in regular expression. */
|
|
||||||
regsub(&SS, s, cp->u.s->new);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move past this match. */
|
/* Skip zero-length matches right after other matches. */
|
||||||
if (match[0].rm_so != match[0].rm_eo) {
|
if (lastempty || match[0].rm_so ||
|
||||||
s += match[0].rm_eo;
|
match[0].rm_so != match[0].rm_eo) {
|
||||||
slen -= match[0].rm_eo;
|
if (n <= 1) {
|
||||||
lastempty = 0;
|
/* Want this match: append replacement. */
|
||||||
|
regsub(&SS, s, cp->u.s->new);
|
||||||
|
if (n == 1)
|
||||||
|
n = -1;
|
||||||
} else {
|
} else {
|
||||||
if (match[0].rm_so < slen)
|
/* Want a later match: append original. */
|
||||||
cspace(&SS, s + match[0].rm_so, 1,
|
if (match[0].rm_eo)
|
||||||
APPEND);
|
cspace(&SS, s, match[0].rm_eo, APPEND);
|
||||||
s += match[0].rm_so + 1;
|
n--;
|
||||||
slen -= match[0].rm_so + 1;
|
|
||||||
lastempty = 1;
|
|
||||||
}
|
}
|
||||||
} while (slen >= 0 && regexec_e(re, s, REG_NOTBOL, 0, slen));
|
|
||||||
/* Copy trailing retained string. */
|
|
||||||
if (slen > 0)
|
|
||||||
cspace(&SS, s, slen, APPEND);
|
|
||||||
break;
|
|
||||||
default: /* Nth occurrence */
|
|
||||||
while (--n) {
|
|
||||||
if (match[0].rm_eo == match[0].rm_so)
|
|
||||||
match[0].rm_eo = match[0].rm_so + 1;
|
|
||||||
s += match[0].rm_eo;
|
|
||||||
slen -= match[0].rm_eo;
|
|
||||||
if (slen < 0)
|
|
||||||
return (0);
|
|
||||||
if (!regexec_e(re, s, REG_NOTBOL, 0, slen))
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 1: /* 1st occurrence */
|
/* Move past this match. */
|
||||||
/* Locate start of replaced string. */
|
|
||||||
re_off = match[0].rm_so + (s - ps);
|
|
||||||
/* Copy leading retained string. */
|
|
||||||
cspace(&SS, ps, re_off, APPEND);
|
|
||||||
/* Add in regular expression. */
|
|
||||||
regsub(&SS, s, cp->u.s->new);
|
|
||||||
/* Copy trailing retained string. */
|
|
||||||
s += match[0].rm_eo;
|
s += match[0].rm_eo;
|
||||||
slen -= match[0].rm_eo;
|
slen -= match[0].rm_eo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After a zero-length match, advance one byte,
|
||||||
|
* and at the end of the line, terminate.
|
||||||
|
*/
|
||||||
|
if (match[0].rm_so == match[0].rm_eo) {
|
||||||
|
if (*s == '\0' || *s == '\n')
|
||||||
|
slen = -1;
|
||||||
|
else
|
||||||
|
slen--;
|
||||||
|
if (*s != '\0')
|
||||||
|
cspace(&SS, s++, 1, APPEND);
|
||||||
|
lastempty = 1;
|
||||||
|
} else
|
||||||
|
lastempty = 0;
|
||||||
|
|
||||||
|
} while (n >= 0 && slen >= 0 && regexec_e(re, s, REG_NOTBOL, 0, slen));
|
||||||
|
|
||||||
|
/* Did not find the requested number of matches. */
|
||||||
|
if (n > 1)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Copy the trailing retained string. */
|
||||||
|
if (slen > 0)
|
||||||
cspace(&SS, s, slen, APPEND);
|
cspace(&SS, s, slen, APPEND);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Swap the substitute space and the pattern space, and make sure
|
* Swap the substitute space and the pattern space, and make sure
|
||||||
|
Loading…
Reference in New Issue
Block a user