Add copyright
[unix-history] / usr / src / usr.bin / f77 / libI77 / rdfmt.c
index 6217c3a..4f79b75 100644 (file)
@@ -1,16 +1,20 @@
 /*
 /*
-char id_rdfmt[] = "@(#)rdfmt.c 1.8";
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
  *
  *
+ *     @(#)rdfmt.c     5.1     %G%
+ */
+
+/*
  * formatted read routines
  */
 
 #include "fio.h"
 #include "format.h"
 
  * formatted read routines
  */
 
 #include "fio.h"
 #include "format.h"
 
-#define isdigit(c)     (c>='0' && c<='9')
-#define isalpha(c)     (c>='a' && c<='z')
-
 extern char *s_init;
 extern char *s_init;
+extern int low_case[256];
 extern int used_data;
 
 rd_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len;
 extern int used_data;
 
 rd_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len;
@@ -23,7 +27,7 @@ rd_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len;
                n = (rd_I(ptr,p->p1,len));
                break;
        case L:
                n = (rd_I(ptr,p->p1,len));
                break;
        case L:
-               n = (rd_L(ptr,p->p1));
+               n = (rd_L(ptr,p->p1,len));
                break;
        case A:
                n = (rd_AW(ptr,len,len));
                break;
        case A:
                n = (rd_AW(ptr,len,len));
@@ -87,6 +91,7 @@ rd_ned(p,ptr) char *ptr; struct syl *p;
        }
 }
 
        }
 }
 
+LOCAL
 rd_mvcur()
 {      int n;
        if(tab) return((*dotab)());
 rd_mvcur()
 {      int n;
        if(tab) return((*dotab)());
@@ -95,35 +100,38 @@ rd_mvcur()
        return(cursor=0);
 }
 
        return(cursor=0);
 }
 
+LOCAL
 rd_I(n,w,len) ftnlen len; uint *n;
 {      long x=0;
 rd_I(n,w,len) ftnlen len; uint *n;
 {      long x=0;
-       int i,sign=0,ch,c;
+       int i,sign=0,ch,c,sign_ok=YES;
        for(i=0;i<w;i++)
        {
                if((ch=(*getn)())<0) return(ch);
        for(i=0;i<w;i++)
        {
                if((ch=(*getn)())<0) return(ch);
-               switch(ch=lcase(ch))
+               switch(ch)
                {
                case ',': goto done;
                {
                case ',': goto done;
-               case '+': break;
-               case '-':
-                       sign=1;
-                       break;
+               case '-': sign=1;               /* and fall thru */
+               case '+': if(sign_ok == NO) return(errno=F_ERRICHR);
+                         sign_ok = NO;
+                         break;
                case ' ':
                        if(cblank) x *= radix;
                        break;
                case ' ':
                        if(cblank) x *= radix;
                        break;
-               case '\n':  goto done;
+               case '\n':  if(cblank) {
+                               x *= radix;
+                               break;
+                           } else {
+                               goto done;
+                           }
                default:
                default:
-                       if(isdigit(ch))
-                       {       if ((c=(ch-'0')) < radix)
-                               {       x = (x * radix) + c;
-                                       break;
-                               }
+                       sign_ok = NO;
+                       if( (c = ch-'0')>=0 && c<radix )
+                       {       x = (x * radix) + c;
+                               break;
                        }
                        }
-                       else if(isalpha(ch))
-                       {       if ((c=(ch-'a'+10)) < radix)
-                               {       x = (x * radix) + c;
-                                       break;
-                               }
+                       else if( (c = low_case[ch]-'a'+10)>=0 && c<radix )
+                       {       x = (x * radix) + c;
+                               break;
                        }
                        return(errno=F_ERRICHR);
                }
                        }
                        return(errno=F_ERRICHR);
                }
@@ -135,71 +143,123 @@ done:
        return(OK);
 }
 
        return(OK);
 }
 
-rd_L(n,w) ftnint *n;
-{      int ch,i,v = -1;
+LOCAL
+rd_L(n,w,len) uint *n; ftnlen len;
+{      int ch,i,v = -1, period=0;
        for(i=0;i<w;i++)
        {       if((ch=(*getn)()) < 0) return(ch);
        for(i=0;i<w;i++)
        {       if((ch=(*getn)()) < 0) return(ch);
-               if((ch=lcase(ch))=='t' && v==-1) v=1;
+               if((ch=low_case[ch])=='t' && v==-1) v=1;
                else if(ch=='f' && v==-1) v=0;
                else if(ch=='f' && v==-1) v=0;
+               else if(ch=='.' && !period) period++;
+               else if(ch==' ' || ch=='\t') ;
                else if(ch==',') break;
                else if(ch==',') break;
+               else if(v==-1) return(errno=F_ERLOGIF);
        }
        if(v==-1) return(errno=F_ERLOGIF);
        }
        if(v==-1) return(errno=F_ERLOGIF);
-       *n=v;
+       if(len==sizeof(short)) n->is=v;
+       else n->il=v;
        return(OK);
 }
 
        return(OK);
 }
 
+LOCAL
 rd_F(p,w,d,len) ftnlen len; ufloat *p;
 {      double x,y;
 rd_F(p,w,d,len) ftnlen len; ufloat *p;
 {      double x,y;
-       int i,sx,sz,ch,dot,ny,z,sawz;
+       int i,sx,sz,ch,dot,ny,z,sawz,mode, sign_ok=YES;
        x=y=0;
        sawz=z=ny=dot=sx=sz=0;
        x=y=0;
        sawz=z=ny=dot=sx=sz=0;
+       /* modes:       0 in initial blanks,
+                       2 blanks plus sign
+                       3 found a digit
+        */
+       mode = 0;
+
        for(i=0;i<w;)
        {       i++;
                if((ch=(*getn)())<0) return(ch);
        for(i=0;i<w;)
        {       i++;
                if((ch=(*getn)())<0) return(ch);
-               ch=lcase(ch);
-               if(ch==' ' && !cblank || ch=='+') continue;
-               else if(ch=='-') sx=1;
-               else if(ch<='9' && ch>='0')
+
+               if(ch==' ') {   /* blank */
+                       if(cblank && (mode==2)) x *= 10;
+               } else if(ch<='9' && ch>='0') { /* digit */
+                       mode = 2;
                        x=10*x+ch-'0';
                        x=10*x+ch-'0';
-               else if(ch=='e' || ch=='d' || ch=='.')
-                       break;
-               else if(cblank && ch==' ') x*=10;
-               else if(ch==',')
-               {       i=w;
+               } else if(ch=='.') {
                        break;
                        break;
+               } else if(ch=='e' || ch=='d' || ch=='E' || ch=='D') {
+                       goto exponent;
+               } else if(ch=='+' || ch=='-') {
+                       if(mode==0) {  /* sign before digits */
+                               if(ch=='-') sx=1;
+                               mode = 1;
+                       } else if(mode==1) {  /* two signs before digits */
+                               return(errno=F_ERRFCHR);
+                       } else { /* sign after digits, weird but standard!
+                                       means exponent without 'e' or 'd' */
+                                   goto exponent;
+                       }
+               } else if(ch==',') {
+                       goto done;
+               } else if(ch=='\n') {
+                       if(cblank && (mode==2)) x *= 10;
+               } else {
+                       return(errno=F_ERRFCHR);
                }
                }
-               else if(ch!='\n') return(errno=F_ERRFCHR);
        }
        }
+       /* get here if out of characters to scan or found a period */
        if(ch=='.') dot=1;
        if(ch=='.') dot=1;
-       while(i<w && ch!='e' && ch!='d' && ch!='+' && ch!='-')
+       while(i<w)
        {       i++;
                if((ch=(*getn)())<0) return(ch);
        {       i++;
                if((ch=(*getn)())<0) return(ch);
-               ch = lcase(ch);
-               if(ch<='9' && ch>='0')
+
+               if(ch<='9' && ch>='0') {
                        y=10*y+ch-'0';
                        y=10*y+ch-'0';
-               else if(cblank && ch==' ')
-                       y *= 10;
-               else if(ch==',') {i=w; break;}
-               else if(ch==' ') continue;
-               else continue;
-               ny++;
+                       ny++;
+               } else if(ch==' ' || ch=='\n') {
+                       if(cblank) {
+                               y*= 10;
+                               ny++;
+                       }
+               } else if(ch==',') {
+                       goto done;
+               } else if(ch=='d' || ch=='e' || ch=='+' || ch=='-' || ch=='D' || ch=='E') {
+                       break;
+               } else {
+                       return(errno=F_ERRFCHR);
+               }
+       }
+       /*      now for the exponent.
+        *      mode=3 means seen digit or sign of exponent.
+        *      either out of characters to scan or 
+        *              ch is '+', '-', 'd', or 'e'.
+        */
+exponent:
+       if(ch=='-' || ch=='+') {
+               if(ch=='-') sz=1;
+               mode = 3;
+       } else {
+               mode = 2;
        }
        }
-       if(ch=='-') sz=1;
+
        while(i<w)
        {       i++;
                sawz=1;
                if((ch=(*getn)())<0) return(ch);
        while(i<w)
        {       i++;
                sawz=1;
                if((ch=(*getn)())<0) return(ch);
-               ch = lcase(ch);
-               if(ch=='-') sz=1;
-               else if(ch<='9' && ch>='0')
+
+               if(ch<='9' && ch>='0') {
+                       mode = 3;
                        z=10*z+ch-'0';
                        z=10*z+ch-'0';
-               else if(cblank && ch==' ')
-                       z *= 10;
-               else if(ch==',') break;
-               else if(ch==' ') continue;
-               else if(ch=='+') continue;
-               else if(ch!='\n') return(errno=F_ERRFCHR);
+               } else if(ch=='+' || ch=='-') {
+                       if(mode==3 ) return(errno=F_ERRFCHR);
+                       mode = 3;
+                       if(ch=='-') sz=1;
+               } else if(ch == ' ' || ch=='\n') {
+                       if(cblank) z *=10;
+               } else if(ch==',') {
+                       break;
+               } else {
+                       return(errno=F_ERRFCHR);
+               }
        }
        }
+done:
        if(!dot)
                for(i=0;i<d;i++) x /= 10;
        for(i=0;i<ny;i++) y /= 10;
        if(!dot)
                for(i=0;i<d;i++) x /= 10;
        for(i=0;i<ny;i++) y /= 10;
@@ -218,6 +278,7 @@ rd_F(p,w,d,len) ftnlen len; ufloat *p;
        return(OK);
 }
 
        return(OK);
 }
 
+LOCAL
 rd_AW(p,w,len) char *p; ftnlen len;
 {      int i,ch;
        if(w >= len)
 rd_AW(p,w,len) char *p; ftnlen len;
 {      int i,ch;
        if(w >= len)
@@ -240,6 +301,7 @@ rd_AW(p,w,len) char *p; ftnlen len;
 }
 
 /* THIS IS NOT ALLOWED IN THE NEW STANDARD 'CAUSE IT'S WEIRD */
 }
 
 /* THIS IS NOT ALLOWED IN THE NEW STANDARD 'CAUSE IT'S WEIRD */
+LOCAL
 rd_H(n,s) char *s;
 {      int i,ch = 0;
 
 rd_H(n,s) char *s;
 {      int i,ch = 0;
 
@@ -255,6 +317,7 @@ rd_H(n,s) char *s;
        return(OK);
 }
 
        return(OK);
 }
 
+LOCAL
 rd_POS(s) char *s;
 {      char quote;
        int ch = 0;
 rd_POS(s) char *s;
 {      char quote;
        int ch = 0;