Add define for Kirk Smith's USR Courier driver. Change default baud
[unix-history] / usr / src / usr.bin / window / scanner.c
index 7d79ce3..b289fd1 100644 (file)
@@ -1,7 +1,13 @@
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)scanner.c   3.2 83/11/22";
+static char sccsid[] = "@(#)scanner.c  3.8 %G%";
 #endif
 
 #endif
 
+/*
+ * Copyright (c) 1983 Regents of the University of California,
+ * All rights reserved.  Redistribution permitted subject to
+ * the terms of the Berkeley Software License Agreement.
+ */
+
 #include <stdio.h>
 #include "value.h"
 #include "token.h"
 #include <stdio.h>
 #include "value.h"
 #include "token.h"
@@ -54,26 +60,22 @@ s_gettok()
        register char *p = buf;
        register c;
        register state = 0;
        register char *p = buf;
        register c;
        register state = 0;
-       char quote = 0;
 
 loop:
        c = s_getc();
        switch (state) {
 
 loop:
        c = s_getc();
        switch (state) {
-       case 0:                         /* blank skipping */
-               if (c != ' ' && c != '\t') {
-                       (void) s_ungetc(c);
-                       state = 1;
-               }
-               break;
-       case 1:                         /* beginning of token */
+       case 0:
                switch (c) {
                switch (c) {
+               case ' ':
+               case '\t':
+                       break;
                case '\n':
                case ';':
                        cx.x_token = T_EOL;
                        state = -1;
                        break;
                case '#':
                case '\n':
                case ';':
                        cx.x_token = T_EOL;
                        state = -1;
                        break;
                case '#':
-                       state = 7;
+                       state = 1;
                        break;
                case EOF:
                        cx.x_token = T_EOF;
                        break;
                case EOF:
                        cx.x_token = T_EOF;
@@ -91,18 +93,28 @@ loop:
                case 'P': case 'Q': case 'R': case 'S': case 'T':
                case 'U': case 'V': case 'W': case 'X': case 'Y':
                case 'Z':
                case 'P': case 'Q': case 'R': case 'S': case 'T':
                case 'U': case 'V': case 'W': case 'X': case 'Y':
                case 'Z':
-               case '_':
+               case '_': case '.':
                        *p++ = c;
                        state = 2;
                        break;
                case '"':
                        *p++ = c;
                        state = 2;
                        break;
                case '"':
-               case '\'':
-                       quote = c;
                        state = 3;
                        break;
                        state = 3;
                        break;
-               case '\\':
+               case '\'':
                        state = 4;
                        break;
                        state = 4;
                        break;
+               case '\\':
+                       switch (c = s_gettok1()) {
+                       case -1:
+                               break;
+                       case -2:
+                               state = 0;
+                               break;
+                       default:
+                               *p++ = c;
+                               state = 2;
+                       }
+                       break;
                case '0':
                        cx.x_val.v_num = 0;
                        state = 10;
                case '0':
                        cx.x_val.v_num = 0;
                        state = 10;
@@ -130,6 +142,9 @@ loop:
                case '|':
                        state = 25;
                        break;
                case '|':
                        state = 25;
                        break;
+               case '$':
+                       state = 26;
+                       break;
                case '~':
                        cx.x_token = T_COMP;
                        state = -1;
                case '~':
                        cx.x_token = T_COMP;
                        state = -1;
@@ -166,10 +181,6 @@ loop:
                        cx.x_token = T_RP;
                        state = -1;
                        break;
                        cx.x_token = T_RP;
                        state = -1;
                        break;
-               case '$':
-                       cx.x_token = T_DOLLAR;
-                       state = -1;
-                       break;
                case ',':
                        cx.x_token = T_COMMA;
                        state = -1;
                case ',':
                        cx.x_token = T_COMMA;
                        state = -1;
@@ -189,6 +200,12 @@ loop:
                        break;
                }
                break;
                        break;
                }
                break;
+       case 1:                         /* got # */
+               if (c == '\n' || c == EOF) {
+                       (void) s_ungetc(c);
+                       state = 0;
+               }
+               break;
        case 2:                         /* unquoted string */
                switch (c) {
                case 'a': case 'b': case 'c': case 'd': case 'e':
        case 2:                         /* unquoted string */
                switch (c) {
                case 'a': case 'b': case 'c': case 'd': case 'e':
@@ -203,20 +220,29 @@ loop:
                case 'P': case 'Q': case 'R': case 'S': case 'T':
                case 'U': case 'V': case 'W': case 'X': case 'Y':
                case 'Z':
                case 'P': case 'Q': case 'R': case 'S': case 'T':
                case 'U': case 'V': case 'W': case 'X': case 'Y':
                case 'Z':
-               case '_':
+               case '_': case '.':
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
                        if (p < buf + sizeof buf - 1)
                                *p++ = c;
                        break;
                case '"':
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
                        if (p < buf + sizeof buf - 1)
                                *p++ = c;
                        break;
                case '"':
-               case '\'':
-                       quote = c;
                        state = 3;
                        break;
                        state = 3;
                        break;
-               case '\\':
+               case '\'':
                        state = 4;
                        break;
                        state = 4;
                        break;
+               case '\\':
+                       switch (c = s_gettok1()) {
+                       case -2:
+                               (void) s_ungetc(' ');
+                       case -1:
+                               break;
+                       default:
+                               if (p < buf + sizeof buf - 1)
+                                       *p++ = c;
+                       }
+                       break;
                default:
                        (void) s_ungetc(c);
                case EOF:
                default:
                        (void) s_ungetc(c);
                case EOF:
@@ -228,107 +254,78 @@ loop:
                                        cx.x_token = T_IF;
                                break;
                        case 't':
                                        cx.x_token = T_IF;
                                break;
                        case 't':
-                               if (strcmp(buf, "then") == 0)
+                               if (buf[1] == 'h' && buf[2] == 'e'
+                                   && buf[3] == 'n' && buf[4] == 0)
                                        cx.x_token = T_THEN;
                                break;
                        case 'e':
                                        cx.x_token = T_THEN;
                                break;
                        case 'e':
-                               switch (buf[1]) {
-                               case 'n':
-                                       if (strcmp(buf, "endif") == 0)
-                                               cx.x_token = T_ENDIF;
-                                       break;
-                               case 'l':
-                                       if (strcmp(buf, "else") == 0)
-                                               cx.x_token = T_ELSE;
-                                       if (strcmp(buf, "elsif") == 0)
+                               if (buf[1] == 'n' && buf[2] == 'd'
+                                   && buf[3] == 'i' && buf[4] == 'f'
+                                   && buf[5] == 0)
+                                       cx.x_token = T_ENDIF;
+                               else if (buf[1] == 'l' && buf[2] == 's')
+                                       if (buf[3] == 'i' && buf[4] == 'f'
+                                           && buf[5] == 0)
                                                cx.x_token = T_ELSIF;
                                                cx.x_token = T_ELSIF;
-                                       break;
-                               }
+                                       else if (buf[3] == 'e' && buf[4] == 0)
+                                               cx.x_token = T_ELSE;
                                break;
                        }
                                break;
                        }
-                       if (cx.x_token == T_STR)
-                               if ((cx.x_val.v_str = str_cpy(buf)) == 0) {
-                                       p_memerror();
-                                       cx.x_token = T_EOF;
-                               }
+                       if (cx.x_token == T_STR
+                           && (cx.x_val.v_str = str_cpy(buf)) == 0) {
+                               p_memerror();
+                               cx.x_token = T_EOF;
+                       }
                        state = -1;
                        break;
                }
                break;
                        state = -1;
                        break;
                }
                break;
-       case 3:                         /* quoted string */
+       case 3:                         /* quoted string */
                switch (c) {
                case '\n':
                        (void) s_ungetc(c);
                case EOF:
                switch (c) {
                case '\n':
                        (void) s_ungetc(c);
                case EOF:
+               case '"':
                        state = 2;
                        break;
                case '\\':
                        state = 2;
                        break;
                case '\\':
-                       state = 4;
+                       switch (c = s_gettok1()) {
+                       case -1:
+                       case -2:        /* newlines are invisible */
+                               break;
+                       default:
+                               if (p < buf + sizeof buf - 1)
+                                       *p++ = c;
+                       }
                        break;
                default:
                        break;
                default:
-                       if (c == quote) {
-                               quote = 0;
-                               state = 2;
-                       } else if (p < buf + sizeof buf - 1)
+                       if (p < buf + sizeof buf - 1)
                                *p++ = c;
                        break;
                }
                break;
                                *p++ = c;
                        break;
                }
                break;
-       case 4:                         /* got \ */
+       case 4:                         /* ' quoted string */
                switch (c) {
                switch (c) {
+               case '\n':
+                       (void) s_ungetc(c);
                case EOF:
                case EOF:
+               case '\'':
                        state = 2;
                        break;
                        state = 2;
                        break;
-               case '0': case '1': case '2': case '3': case '4':
-               case '5': case '6': case '7':
-                       if (p < buf + sizeof buf - 1)
-                               *p = c - '0';
-                       state = 5;
-                       break;
-               case 'b':
-                       c = '\b';
-                       goto foo;
-               case 'f':
-                       c = '\f';
-                       goto foo;
-               case 'n':
-                       c = '\n';
-                       goto foo;
-               case 'r':
-                       c = '\r';
-                       goto foo;
-               case 't':
-                       c = '\t';
-               foo:
+               case '\\':
+                       switch (c = s_gettok1()) {
+                       case -1:
+                       case -2:        /* newlines are invisible */
+                               break;
+                       default:
+                               if (p < buf + sizeof buf - 1)
+                                       *p++ = c;
+                       }
+                       break;
                default:
                        if (p < buf + sizeof buf - 1)
                                *p++ = c;
                default:
                        if (p < buf + sizeof buf - 1)
                                *p++ = c;
-               case '\n':              /* swallow the \n */
-                       state = quote == 0 ? 2 : 3;
-               }
-               break;
-       case 5:                         /* got \[0-7] */
-               if (c >= '0' && c <= '7') {
-                       *p = *p * 8 + c - '0';
-                       state = 6;
-               } else {
-                       (void) s_ungetc(c);
-                       p++;
-                       state = quote == 0 ? 2 : 3;
-               }
-               break;
-       case 6:                         /* got \[0-7][0-7] */
-               if (c >= '0' && c <= '7')
-                       *p = *p * 8 + c - '0';
-               else
-                       (void) s_ungetc(c);
-               p++;
-               state = quote == 0 ? 2 : 3;
-               break;
-       case 7:                         /* got # */
-               if (c == '\n' || c == EOF) {
-                       (void) s_ungetc(c);
-                       state = 1;
+                       break;
                }
                break;
        case 10:                        /* got 0 */
                }
                break;
        case 10:                        /* got 0 */
@@ -451,7 +448,7 @@ loop:
                        state = -1;
                }
                break;
                        state = -1;
                }
                break;
-       case 24:                        /* and & */
+       case 24:                        /* got & */
                switch (c) {
                case '&':
                        cx.x_token = T_ANDAND;
                switch (c) {
                case '&':
                        cx.x_token = T_ANDAND;
@@ -463,7 +460,7 @@ loop:
                        state = -1;
                }
                break;
                        state = -1;
                }
                break;
-       case 25:                        /* and | */
+       case 25:                        /* got | */
                switch (c) {
                case '|':
                        cx.x_token = T_OROR;
                switch (c) {
                case '|':
                        cx.x_token = T_OROR;
@@ -475,6 +472,18 @@ loop:
                        state = -1;
                }
                break;
                        state = -1;
                }
                break;
+       case 26:                        /* got $ */
+               switch (c) {
+               case '?':
+                       cx.x_token = T_DQ;
+                       state = -1;
+                       break;
+               default:
+                       (void) s_ungetc(c);
+                       cx.x_token = T_DOLLAR;
+                       state = -1;
+               }
+               break;
        default:
                abort();
        }
        default:
                abort();
        }
@@ -482,3 +491,45 @@ loop:
                goto loop;
        return cx.x_token;
 }
                goto loop;
        return cx.x_token;
 }
+
+s_gettok1()
+{
+       register c;
+       register n;
+
+       c = s_getc();                   /* got \ */
+       switch (c) {
+       case EOF:
+               return -1;
+       case '\n':
+               return -2;
+       case 'b':
+               return '\b';
+       case 'f':
+               return '\f';
+       case 'n':
+               return '\n';
+       case 'r':
+               return '\r';
+       case 't':
+               return '\t';
+       default:
+               return c;
+       case '0': case '1': case '2': case '3': case '4':
+       case '5': case '6': case '7':
+               break;
+       }
+       n = c - '0';
+       c = s_getc();                   /* got \[0-7] */
+       if (c < '0' || c > '7') {
+               (void) s_ungetc(c);
+               return n;
+       }
+       n = n * 8 + c - '0';
+       c = s_getc();                   /* got \[0-7][0-7] */
+       if (c < '0' || c > '7') {
+               (void) s_ungetc(c);
+               return n;
+       }
+       return n * 8 + c - '0';
+}