BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.bin / sed / compile.c
index 79cac81..8ad1b2d 100644 (file)
@@ -6,11 +6,37 @@
  * This code is derived from software contributed to Berkeley by
  * Diomidis Spinellis of Imperial College, University of London.
  *
  * 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[] = "@(#)compile.c  8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)compile.c  8.2 (Berkeley) 4/28/95";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -149,7 +175,6 @@ semicolon:  EATSPACE();
                cmd->nonsel = cmd->inrange = 0;
                /* First parse the addresses */
                naddr = 0;
                cmd->nonsel = cmd->inrange = 0;
                /* First parse the addresses */
                naddr = 0;
-               cmd->a1 = cmd->a2 = NULL;
 
 /* Valid characters to start an address */
 #define        addrchar(c)     (strchr("0123456789/\\$", (c)))
 
 /* Valid characters to start an address */
 #define        addrchar(c)     (strchr("0123456789/\\$", (c)))
@@ -159,16 +184,18 @@ semicolon:        EATSPACE();
                        p = compile_addr(p, cmd->a1);
                        EATSPACE();                             /* EXTENSION */
                        if (*p == ',') {
                        p = compile_addr(p, cmd->a1);
                        EATSPACE();                             /* EXTENSION */
                        if (*p == ',') {
-                               naddr++;
                                p++;
                                EATSPACE();                     /* EXTENSION */
                                p++;
                                EATSPACE();                     /* EXTENSION */
+                               naddr++;
                                cmd->a2 = xmalloc(sizeof(struct s_addr));
                                p = compile_addr(p, cmd->a2);
                                cmd->a2 = xmalloc(sizeof(struct s_addr));
                                p = compile_addr(p, cmd->a2);
-                       }
-               }
+                               EATSPACE();
+                       } else
+                               cmd->a2 = 0;
+               } else
+                       cmd->a1 = cmd->a2 = 0;
 
 nonsel:                /* Now parse the command */
 
 nonsel:                /* Now parse the command */
-               EATSPACE();
                if (!*p)
                        err(COMPILE, "command expected");
                cmd->code = *p;
                if (!*p)
                        err(COMPILE, "command expected");
                cmd->code = *p;
@@ -182,8 +209,9 @@ nonsel:             /* Now parse the command */
 "command %c expects up to %d address(es), found %d", *p, fp->naddr, naddr);
                switch (fp->args) {
                case NONSEL:                    /* ! */
 "command %c expects up to %d address(es), found %d", *p, fp->naddr, naddr);
                switch (fp->args) {
                case NONSEL:                    /* ! */
-                       cmd->nonsel = ! cmd->nonsel;
                        p++;
                        p++;
+                       EATSPACE();
+                       cmd->nonsel = ! cmd->nonsel;
                        goto nonsel;
                case GROUP:                     /* { */
                        p++;
                        goto nonsel;
                case GROUP:                     /* { */
                        p++;
@@ -195,6 +223,12 @@ nonsel:            /* Now parse the command */
                        *compile_stream("}", &cmd->u.c, p) = cmd2;
                        cmd->next = cmd2;
                        link = &cmd2->next;
                        *compile_stream("}", &cmd->u.c, p) = cmd2;
                        cmd->next = cmd2;
                        link = &cmd2->next;
+                       /*
+                        * Short-circuit command processing, since end of
+                        * group is really just a noop.
+                        */
+                       cmd2->nonsel = 1;
+                       cmd2->a1 = cmd2->a2 = 0;
                        break;
                case EMPTY:             /* d D g G h H l n N p P q x = \0 */
                        p++;
                        break;
                case EMPTY:             /* d D g G h H l n N p P q x = \0 */
                        p++;