From owner-svn-src-all@freebsd.org Tue May 24 03:08:33 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4C11BB4859B; Tue, 24 May 2016 03:08:33 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 288E310C2; Tue, 24 May 2016 03:08:33 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4O38WGV098665; Tue, 24 May 2016 03:08:32 GMT (envelope-from pfg@FreeBSD.org) Received: (from pfg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4O38WWQ098664; Tue, 24 May 2016 03:08:32 GMT (envelope-from pfg@FreeBSD.org) Message-Id: <201605240308.u4O38WWQ098664@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: pfg set sender to pfg@FreeBSD.org using -f From: "Pedro F. Giffuni" Date: Tue, 24 May 2016 03:08:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r300555 - stable/10/usr.bin/sed X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 May 2016 03:08:33 -0000 Author: pfg Date: Tue May 24 03:08:32 2016 New Revision: 300555 URL: https://svnweb.freebsd.org/changeset/base/300555 Log: 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) Modified: stable/10/usr.bin/sed/process.c Directory Properties: stable/10/ (props changed) Modified: stable/10/usr.bin/sed/process.c ============================================================================== --- stable/10/usr.bin/sed/process.c Tue May 24 03:00:24 2016 (r300554) +++ stable/10/usr.bin/sed/process.c Tue May 24 03:08:32 2016 (r300555) @@ -369,7 +369,7 @@ substitute(struct s_command *cp) { SPACE tspace; regex_t *re; - regoff_t re_off, slen; + regoff_t slen; int lastempty, n; char *s; @@ -390,61 +390,55 @@ substitute(struct s_command *cp) 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. */ + 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); - } - - /* 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; + if (n == 1) + n = -1; } else { - if (match[0].rm_so < slen) - cspace(&SS, s + match[0].rm_so, 1, - APPEND); - s += match[0].rm_so + 1; - slen -= match[0].rm_so + 1; - lastempty = 1; + /* Want a later match: append original. */ + if (match[0].rm_eo) + cspace(&SS, s, match[0].rm_eo, APPEND); + n--; } - } 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 */ - /* 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. */ + + /* 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 == '\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); - break; - } /* * Swap the substitute space and the pattern space, and make sure