date and time created 88/07/22 16:08:01 by bostic
[unix-history] / usr / src / old / as.vax / asscan2.c
index 906feff..ae470fc 100644 (file)
 /*
 /*
- *     Copyright (c) 1982 Regents of the University of California
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
  */
  */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)asscan2.c 4.2 %G%";
+static char sccsid[] = "@(#)asscan2.c  5.1 (Berkeley) %G%";
 #endif not lint
 
 #include "asscanl.h"
 #endif not lint
 
 #include "asscanl.h"
-static inttoktype      oval = NL;
 
 
-#define        NINBUFFERS      2
-#define        INBUFLG         NINBUFFERS*BUFSIZ + 2
-       /*
-        *      We have two input buffers; the first one is reserved
-        *      for catching the tail of a line split across a buffer
-        *      boundary; the other one are used for snarfing a buffer
-        *      worth of .s source.
-        */
-static char    inbuffer[INBUFLG];
-static char    *InBufPtr = 0;
-
-/*
- *     fill the inbuffer from the standard input.
- *     Assert: there are always n COMPLETE! lines in the buffer area.
- *     Assert: there is always a \n terminating the last line
- *             in the buffer area.
- *     Assert: after the \n, there is an EOFCHAR (hard end of file)
- *             or a NEEDCHAR (end of buffer)
- *     Assert: fgets always null pads the string it reads.
- *     Assert: no ungetc's are done at the end of a line or at the
- *             beginning of a line.
- *     
- *     We read a complete buffer of characters in one single read.
- *     We then back scan within this buffer to find the end of the
- *     last complete line, and force the assertions, and save a pointer
- *     to the incomplete line.
- *     The next call to fillinbuffer will move the unread characters
- *     to the end of the first buffer, and then read another two buffers,
- *     completing the cycle.
- */
+static inttoktype      oval = NL;
+#define        ASINBUFSIZ      4096
+char   inbufunget[8];
+char   inbuffer[ASINBUFSIZ];
+char   *Ginbufptr = inbuffer;
+int    Ginbufcnt = 0;
+int    scannerhadeof;
 
 
-static char    p_swapped = '\0';                       
-static char    *p_start = &inbuffer[NINBUFFERS * BUFSIZ];
-static char    *p_stop = &inbuffer[NINBUFFERS * BUFSIZ];
-char *fillinbuffer()
+fillinbuffer()
 {
 {
-       register        char    *to;
-       register        char    *from;
-                       char    *inbufptr;
-       int             nread;
-
-       *p_start = p_swapped;
-       inbufptr = &inbuffer[1*BUFSIZ] - (p_stop - p_start);
+               int     nread;
+               int     goal;
+               int     got;
 
 
-       for (to = inbufptr, from = p_start; from < p_stop;)
-               *to++ = *from++;
+       nread = 0;
+       if (scannerhadeof == 0){
+               goal = sizeof(inbuffer);
+               do {
+                       got = read(stdin->_file, inbuffer + nread, goal);
+                       if (got == 0)
+                               scannerhadeof = 1;
+                       if (got <= 0)
+                               break;
+                       nread += got;
+                       goal -= got;
+               } while (goal);
+       } else {
+               scannerhadeof = 0;
+       }
        /*
        /*
-        *      Now, go read two full buffers (hopefully)
+        *      getchar assumes that Ginbufcnt and Ginbufptr
+        *      are adjusted as if one character has been removed
+        *      from the input.
         */
         */
-       nread = read(stdin->_file, &inbuffer[1*BUFSIZ], (NINBUFFERS - 1)*BUFSIZ);
-       if (nread == 0)
-               return(0);
-       p_stop = from = &inbuffer[1*BUFSIZ + nread];
-       *from = '\0';
-       while (*--from != '\n')         /* back over the partial line */
-               continue;
-       from++;                         /* first char of partial line */
-       p_start = from;
-       p_swapped = *p_start;
-       *p_start = NEEDCHAR;            /* force assertion */
-       return(inbufptr);
+       if (nread == 0){
+               inbuffer[0] = EOFCHAR;
+               nread = 1;
+       }
+       Ginbufcnt = nread - 1;
+       Ginbufptr = inbuffer + 1;
 }
 
 scan_dot_s(bufferbox)
        struct tokbufdesc *bufferbox;
 {
 }
 
 scan_dot_s(bufferbox)
        struct tokbufdesc *bufferbox;
 {
+       reg     char    *inbufptr;
+       reg     int     inbufcnt;
        reg     int     ryylval;        /* local copy of lexical value */
        extern  int     yylval;         /* global copy of lexical value */
        reg     int     val;            /* the value returned */
                int     i;              /* simple counter */
        reg     char    *rcp;   
        reg     int     ryylval;        /* local copy of lexical value */
        extern  int     yylval;         /* global copy of lexical value */
        reg     int     val;            /* the value returned */
                int     i;              /* simple counter */
        reg     char    *rcp;   
-               char    *cp;            /* can have address taken */
-       reg     int     ch;             /* treated as a character */
+               int     ch;             /* treated as a character */
                int     ch1;            /* shadow value */
                int     ch1;            /* shadow value */
-       reg     char    *inbufptr;
                struct  symtab  *op;
                struct  symtab  *op;
-
-       reg     ptrall  bufptr;         /* where to stuff tokens */
                ptrall  lgbackpatch;    /* where to stuff a string length */
                ptrall  lgbackpatch;    /* where to stuff a string length */
+       reg     ptrall  bufptr;         /* where to stuff tokens */
                ptrall  bufub;          /* where not to stuff tokens */
                ptrall  bufub;          /* where not to stuff tokens */
-               int     maxstrlg;       /* how long a string can be */
                long    intval;         /* value of int */
                int     linescrossed;   /* when doing strings and comments */
                struct  Opcode          opstruct;
                long    intval;         /* value of int */
                int     linescrossed;   /* when doing strings and comments */
                struct  Opcode          opstruct;
+       reg     int     strlg;          /* the length of a string */
 
        (bytetoktype *)bufptr = (bytetoktype *) & (bufferbox->toks[0]); 
        (bytetoktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
 
 
        (bytetoktype *)bufptr = (bytetoktype *) & (bufferbox->toks[0]); 
        (bytetoktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
 
-       inbufptr = InBufPtr;
-       if (inbufptr == 0){
-               inbufptr = fillinbuffer();
-               if (inbufptr == 0){     /*end of file*/
-                 endoffile:
-                       inbufptr = 0;
-                       ptoken(bufptr, PARSEEOF);
-                       goto done;
-               }
-       }
-
+       MEMTOREGBUF;
        if (newfflag){
        if (newfflag){
+               newfflag = 0;
+               ryylval = (int)savestr(newfname, strlen(newfname)+1, STR_BOTH);
+
                ptoken(bufptr, IFILE);
                ptoken(bufptr, STRING);
                ptoken(bufptr, IFILE);
                ptoken(bufptr, STRING);
-               val = strlen(newfname) + 1;
-               movestr( (char *)&( ( (lgtype *)bufptr)[1]), newfname, val);
-               bstrlg(bufptr, val);
+               pptr(bufptr, ryylval);
 
                ptoken(bufptr, ILINENO);
                ptoken(bufptr, INT);
                pint(bufptr,  1);
 
                ptoken(bufptr, ILINENO);
                ptoken(bufptr, INT);
                pint(bufptr,  1);
-               newfflag = 0;
        }
 
        while (bufptr < bufub){
    loop:
        }
 
        while (bufptr < bufub){
    loop:
-        switch(ryylval = (type+2)[ch = getchar()]) {
+        switch(ryylval = (type+1)[ch = getchar()]) {
        case SCANEOF:
        case SCANEOF:
+       endoffile: ;
                inbufptr = 0;
                inbufptr = 0;
-               goto endoffile;
-
-       case NEEDSBUF:
-               inbufptr = fillinbuffer();
-               if (inbufptr == 0)
-                       goto endoffile;
-               goto loop;
+               ptoken(bufptr, PARSEEOF);
+               goto done;
 
        case DIV:               /*process C style comments*/
                if ( (ch = getchar()) == '*') {  /*comment prelude*/
 
        case DIV:               /*process C style comments*/
                if ( (ch = getchar()) == '*') {  /*comment prelude*/
@@ -152,13 +118,6 @@ scan_dot_s(bufferbox)
                                        break;
                                case EOFCHAR:
                                        goto endoffile;
                                        break;
                                case EOFCHAR:
                                        goto endoffile;
-                               case NEEDCHAR:
-                                       inbufptr = fillinbuffer();
-                                       if (inbufptr == 0)
-                                               goto endoffile;
-                                       lineno++;
-                                       ch = getchar();
-                                       break;
                                default:
                                        ch = getchar();
                                        break;
                                default:
                                        ch = getchar();
                                        break;
@@ -277,7 +236,7 @@ scan_dot_s(bufferbox)
                }
                rcp = yytext;
                do {
                }
                rcp = yytext;
                do {
-                       if (rcp < &yytext[NCPS])
+                       if (rcp < &yytext[NCPName])
                                *rcp++ = ch;
                } while (INCHARSET ( (ch = getchar()), ALPHA | DIGIT));
                *rcp = '\0';
                                *rcp++ = ch;
                } while (INCHARSET ( (ch = getchar()), ALPHA | DIGIT));
                *rcp = '\0';
@@ -289,7 +248,7 @@ scan_dot_s(bufferbox)
                case 0:
                case LABELID:
                        /*
                case 0:
                case LABELID:
                        /*
-                        *      Its a name... (Labels are subsets ofname)
+                        *      Its a name... (Labels are subsets of name)
                         */
                        ryylval = (int)op;
                        val = NAME;
                         */
                        ryylval = (int)op;
                        val = NAME;
@@ -310,17 +269,17 @@ scan_dot_s(bufferbox)
 
        case DIG:
                /*
 
        case DIG:
                /*
-                *      Implement call by reference on a reg variable
+                *      restore local inbufptr and inbufcnt
                 */
                 */
-               cp = inbufptr;
-               val = number(ch, &cp);
+               REGTOMEMBUF;
+               val = number(ch);
+               MEMTOREGBUF;
                /*
                 *      yylval or yybignum has been stuffed as a side
                 *      effect to number(); get the global yylval
                 *      into our fast local copy in case it was an INT.
                 */
                ryylval = yylval;
                /*
                 *      yylval or yybignum has been stuffed as a side
                 *      effect to number(); get the global yylval
                 *      into our fast local copy in case it was an INT.
                 */
                ryylval = yylval;
-               inbufptr = cp;
                goto ret;
 
        case LSH:
                goto ret;
 
        case LSH:
@@ -352,58 +311,32 @@ scan_dot_s(bufferbox)
        case DQ:
           eatstr:
                linescrossed = 0;
        case DQ:
           eatstr:
                linescrossed = 0;
-               maxstrlg = (char *)bufub - (char *)bufptr;
-
-               if (maxstrlg < MAXSTRLG) {
-                       ungetc('"');
-                       *(bytetoktype *)bufptr = VOID ;
-                       bufub = bufptr;
-                       goto done;
-               }
-               if (maxstrlg > MAXSTRLG)
-                       maxstrlg = MAXSTRLG;
-               
-               ptoken(bufptr, STRING);
-               lgbackpatch = bufptr;   /*this is where the size goes*/
-               bufptr += sizeof(lgtype);
-               /*
-                *      bufptr is now set to
-                *      be stuffed with characters from
-                *      the input
-                */
-
-               while (   (maxstrlg > 0)
-                      && !(INCHARSET( (ch = getchar()), STRESCAPE))
-                     ){
-                       stuff:
-                               maxstrlg-= 1;
-                               pchar(bufptr, ch);
-                       }
-               if (maxstrlg <= 0){     /*enough characters to fill a string buffer*/
-                       ungetc('"');            /*will read it next*/
-               }
-               else if (ch == '"');            /*done*/
-               else if (ch == '\n'){
-                       yywarning("New line embedded in a string constant.");
+               for (strlg = 0; /*VOID*/; strlg++){
+                   switch(ch = getchar()){
+                   case '"':
+                       goto tailDQ;
+                   default:
+                   stuff:
+                       putc(ch, strfile);
+                       break;
+                   case '\n':
+                       yywarning("New line in a string constant");
                        scanlineno++;
                        linescrossed++;
                        ch = getchar();
                        scanlineno++;
                        linescrossed++;
                        ch = getchar();
-                       if (ch == EOFCHAR){
-                         do_eof:
-                               pchar(bufptr, '\n');
+                       switch(ch){
+                       case EOFCHAR:
+                               putc('\n', strfile);
                                ungetc(EOFCHAR);
                                ungetc(EOFCHAR);
-                       } else
-                       if (ch == NEEDCHAR){
-                               if ( (inbufptr = fillinbuffer()) == 0)
-                                       goto do_eof;
-                               ch = '\n';
-                               goto stuff;
-                       } else {        /* simple case */
+                               goto tailDQ;
+                       default:
                                ungetc(ch);
                                ch = '\n';
                                goto stuff;
                        }
                                ungetc(ch);
                                ch = '\n';
                                goto stuff;
                        }
-               } else {
+                       break;
+
+                   case '\\':
                        ch = getchar();         /*skip the '\\'*/
                        if ( INCHARSET(ch, BSESCAPE)){
                                switch (ch){
                        ch = getchar();         /*skip the '\\'*/
                        if ( INCHARSET(ch, BSESCAPE)){
                                switch (ch){
@@ -414,27 +347,40 @@ scan_dot_s(bufferbox)
                                  case 't':  ch = '\t'; goto stuff;
                                }
                        }
                                  case 't':  ch = '\t'; goto stuff;
                                }
                        }
-                       if ( !(INCHARSET(ch,OCTDIGIT)) )  goto stuff;
+                       if ( !(INCHARSET(ch, OCTDIGIT)) ) 
+                               goto stuff;
                        i = 0;
                        intval = 0;
                        while ( (i < 3) && (INCHARSET(ch, OCTDIGIT))){
                        i = 0;
                        intval = 0;
                        while ( (i < 3) && (INCHARSET(ch, OCTDIGIT))){
-                               i++;intval <<= 3;intval += ch - '0';
+                               i++;
+                               intval <<= 3;
+                               intval += ch - '0';
                                ch = getchar();
                        }
                        ungetc(ch);
                                ch = getchar();
                        }
                        ungetc(ch);
-                       val = (char)intval;
+                       ch = (char)intval;
                        goto stuff;
                        goto stuff;
+                   }
                }
                }
+       tailDQ: ;
                /*
                /*
-                *      bufptr now points at the next free slot
+                *      account for any lines that were crossed
                 */
                 */
-               bstrfromto(lgbackpatch, bufptr);
                if (linescrossed){
                if (linescrossed){
-                       val = ILINESKIP;
-                       ryylval = linescrossed;
-                       goto ret;
-               } else
-                       goto builtval;
+                       ptoken(bufptr, ILINESKIP);
+                       pint(bufptr, linescrossed);
+               }
+               /*
+                *      Cheat: append a trailing null to the string
+                *      and then adjust the string length to ignore
+                *      the trailing null.  If any STRING client requires
+                *      the trailing null, the client can just change STRLEN
+                */
+               putc(0, strfile);
+               ryylval = (int)savestr((char *)0, strlg + 1, STR_FILE);
+               val = STRING;
+               ((struct strdesc *)ryylval)->sd_strlen -= 1;
+               goto ret;
 
        case BADCHAR:
                linescrossed = lineno;
 
        case BADCHAR:
                linescrossed = lineno;
@@ -468,6 +414,8 @@ scan_dot_s(bufferbox)
                                break;
                case    BIGNUM: pnumber(bufptr, yybignum);
                                break;
                                break;
                case    BIGNUM: pnumber(bufptr, yybignum);
                                break;
+               case    STRING: pptr(bufptr, (int)(char *)ryylval);
+                               break;
                case    NAME:   pptr(bufptr, (int)(struct symtab *)ryylval);
                                break;
                case    REG:    pchar(bufptr, ryylval);
                case    NAME:   pptr(bufptr, (int)(struct symtab *)ryylval);
                                break;
                case    REG:    pchar(bufptr, ryylval);
@@ -495,7 +443,6 @@ scan_dot_s(bufferbox)
    }                   /*end of the while to stuff the buffer*/
    done:
        bufferbox->tok_count = (bytetoktype *)bufptr - &(bufferbox->toks[0]);
    }                   /*end of the while to stuff the buffer*/
    done:
        bufferbox->tok_count = (bytetoktype *)bufptr - &(bufferbox->toks[0]);
-
        /*
         *      This is a real kludge:
         *
        /*
         *      This is a real kludge:
         *
@@ -514,5 +461,5 @@ scan_dot_s(bufferbox)
         *      fail.
         */
        ptoken(bufptr, MINUS);
         *      fail.
         */
        ptoken(bufptr, MINUS);
-       InBufPtr = inbufptr;            /*copy this back*/
+       REGTOMEMBUF;
 }
 }