=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/sed/process.c,v retrieving revision 1.16 retrieving revision 1.17 diff -c -r1.16 -r1.17 *** src/usr.bin/sed/process.c 2011/07/24 13:59:15 1.16 --- src/usr.bin/sed/process.c 2011/07/26 08:47:07 1.17 *************** *** 1,4 **** ! /* $OpenBSD: process.c,v 1.16 2011/07/24 13:59:15 schwarze Exp $ */ /*- * Copyright (c) 1992 Diomidis Spinellis. --- 1,4 ---- ! /* $OpenBSD: process.c,v 1.17 2011/07/26 08:47:07 schwarze Exp $ */ /*- * Copyright (c) 1992 Diomidis Spinellis. *************** *** 312,318 **** { SPACE tspace; regex_t *re; ! regoff_t slen; int n, lastempty; char *s; --- 312,318 ---- { SPACE tspace; regex_t *re; ! size_t re_off, slen; int n, lastempty; char *s; *************** *** 333,386 **** n = cp->u.s->n; lastempty = 1; ! do { ! /* Copy the leading retained string. */ ! if (n <= 1 && match[0].rm_so) ! cspace(&SS, s, match[0].rm_so, APPEND); ! ! /* Skip zero-length matches right after other matches. */ ! if (lastempty || match[0].rm_so || ! match[0].rm_so != match[0].rm_eo) { ! if (n <= 1) { ! /* Want this match: append replacement. */ regsub(&SS, s, cp->u.s->new); ! if (n == 1) ! n = -1; } else { ! /* Want a later match: append original. */ ! if (match[0].rm_eo) ! cspace(&SS, s, match[0].rm_eo, APPEND); ! n--; } } ! ! /* Move past this match. */ s += 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 == '\n') - slen = -1; - else - slen--; - 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); /* * Swap the substitute space and the pattern space, and make sure --- 333,392 ---- n = cp->u.s->n; lastempty = 1; ! switch (n) { ! case 0: /* Global */ ! do { ! if (lastempty || match[0].rm_so != match[0].rm_eo) { ! /* 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. */ ! if (match[0].rm_so != match[0].rm_eo) { ! s += match[0].rm_eo; ! slen -= match[0].rm_eo; ! lastempty = 0; } else { ! if (match[0].rm_so == 0) ! cspace(&SS, s, match[0].rm_so + 1, ! APPEND); ! else ! cspace(&SS, s + match[0].rm_so, 1, ! APPEND); ! s += match[0].rm_so + 1; ! 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) { + s += match[0].rm_eo; + slen -= match[0].rm_eo; + if (!regexec_e(re, s, REG_NOTBOL, 0, slen)) + return (0); } ! /* FALLTHROUGH */ ! case 1: /* 1st occurrence */ ! /* 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; slen -= match[0].rm_eo; cspace(&SS, s, slen, APPEND); + break; + } /* * Swap the substitute space and the pattern space, and make sure