BSD 4_4_Lite1 release
[unix-history] / usr / src / usr.bin / sed / process.c
index 1f6d678..2ec8aac 100644 (file)
@@ -1,16 +1,42 @@
 /*-
  * Copyright (c) 1992 Diomidis Spinellis.
 /*-
  * Copyright (c) 1992 Diomidis Spinellis.
- * Copyright (c) 1992, 1993
+ * Copyright (c) 1992, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Diomidis Spinellis of Imperial College, University of London.
  *
  *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Diomidis Spinellis of Imperial College, University of London.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)process.c  8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)process.c  8.6 (Berkeley) 4/20/94";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -64,7 +90,6 @@ process()
        struct s_command *cp;
        SPACE tspace;
        size_t len;
        struct s_command *cp;
        SPACE tspace;
        size_t len;
-       int r;
        char oldc, *p;
 
        for (linenum = 0; mf_fgets(&PS, REPLACE);) {
        char oldc, *p;
 
        for (linenum = 0; mf_fgets(&PS, REPLACE);) {
@@ -108,7 +133,7 @@ redirect:
                                if ((p = memchr(ps, '\n', psl)) == NULL)
                                        pd = 1;
                                else {
                                if ((p = memchr(ps, '\n', psl)) == NULL)
                                        pd = 1;
                                else {
-                                       psl -= (p - ps) - 1;
+                                       psl -= (p - ps) + 1;
                                        memmove(ps, p + 1, psl);
                                }
                                goto new;
                                        memmove(ps, p + 1, psl);
                                }
                                goto new;
@@ -134,11 +159,8 @@ redirect:
                                if (!nflag && !pd)
                                        OUT(ps)
                                flush_appends();
                                if (!nflag && !pd)
                                        OUT(ps)
                                flush_appends();
-                               r = mf_fgets(&PS, REPLACE);
-#ifdef HISTORIC_PRACTICE
-                               if (!r)
+                               if (!mf_fgets(&PS, REPLACE))
                                        exit(0);
                                        exit(0);
-#endif
                                pd = 0;
                                break;
                        case 'N':
                                pd = 0;
                                break;
                        case 'N':
@@ -291,7 +313,7 @@ substitute(cp)
        SPACE tspace;
        regex_t *re;
        size_t re_off, slen;
        SPACE tspace;
        regex_t *re;
        size_t re_off, slen;
-       int n;
+       int lastempty, n;
        char *s;
 
        s = ps;
        char *s;
 
        s = ps;
@@ -306,25 +328,44 @@ substitute(cp)
        if (!regexec_e(re, s, 0, 0, psl))
                return (0);
 
        if (!regexec_e(re, s, 0, 0, psl))
                return (0);
 
-       SS.len = 0;                             /* Clean substitute space. */
-       slen = psl;
-       n = cp->u.s->n;
-       switch (n) {
-       case 0:                                 /* Global */
-               do {
-                       /* 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. */
-                       s += match[0].rm_eo;
-                       slen -= match[0].rm_eo;
-               } while(regexec_e(re, s, REG_NOTBOL, 0, slen));
+       SS.len = 0;                             /* Clean substitute space. */
+       slen = psl;
+       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. */
                /* Copy trailing retained string. */
-               cspace(&SS, s, slen, APPEND);
-               break;
+               if (slen > 0)
+                       cspace(&SS, s, slen, APPEND);
+               break;
        default:                                /* Nth occurrence */
                while (--n) {
                        s += match[0].rm_eo;
        default:                                /* Nth occurrence */
                while (--n) {
                        s += match[0].rm_eo;