12499Sdlw /* 2*23085Skre * Copyright (c) 1980 Regents of the University of California. 3*23085Skre * All rights reserved. The Berkeley software License Agreement 4*23085Skre * specifies the terms and conditions for redistribution. 52499Sdlw * 6*23085Skre * @(#)rdfmt.c 5.1 06/07/85 7*23085Skre */ 8*23085Skre 9*23085Skre /* 102499Sdlw * formatted read routines 112499Sdlw */ 122499Sdlw 132499Sdlw #include "fio.h" 142598Sdlw #include "format.h" 152499Sdlw 1617968Slibs extern char *s_init; 1718016Slibs extern int low_case[256]; 1818014Slibs extern int used_data; 1917968Slibs 202499Sdlw rd_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len; 212499Sdlw { int n; 222499Sdlw if(cursor && (n=rd_mvcur())) return(n); 232499Sdlw switch(p->op) 242499Sdlw { 252499Sdlw case I: 262499Sdlw case IM: 272499Sdlw n = (rd_I(ptr,p->p1,len)); 282499Sdlw break; 292499Sdlw case L: 3019984Slibs n = (rd_L(ptr,p->p1,len)); 312499Sdlw break; 322499Sdlw case A: 3317968Slibs n = (rd_AW(ptr,len,len)); 3417968Slibs break; 352499Sdlw case AW: 362499Sdlw n = (rd_AW(ptr,p->p1,len)); 372499Sdlw break; 382499Sdlw case E: 392499Sdlw case EE: 402499Sdlw case D: 412499Sdlw case DE: 422499Sdlw case G: 432499Sdlw case GE: 442499Sdlw case F: 452499Sdlw n = (rd_F(ptr,p->p1,p->p2,len)); 462499Sdlw break; 472499Sdlw default: 482598Sdlw return(errno=F_ERFMT); 492499Sdlw } 502499Sdlw if (n < 0) 512499Sdlw { 522499Sdlw if(feof(cf)) return(EOF); 532499Sdlw n = errno; 542499Sdlw clearerr(cf); 552499Sdlw } 562499Sdlw return(n); 572499Sdlw } 582499Sdlw 592499Sdlw rd_ned(p,ptr) char *ptr; struct syl *p; 602499Sdlw { 612499Sdlw switch(p->op) 622499Sdlw { 633632Sdlw #ifndef KOSHER 643632Sdlw case APOS: /* NOT STANDARD F77 */ 6517968Slibs return(rd_POS(&s_init[p->p1])); 663632Sdlw case H: /* NOT STANDARD F77 */ 6717968Slibs return(rd_H(p->p1,&s_init[p->p2])); 683632Sdlw #endif 692499Sdlw case SLASH: 702499Sdlw return((*donewrec)()); 712499Sdlw case TR: 722499Sdlw case X: 732499Sdlw cursor += p->p1; 7412465Sdlw /* tab = (p->op==TR); This voids '..,tl6,1x,..' sequences */ 7512465Sdlw tab = YES; 762499Sdlw return(OK); 772499Sdlw case T: 782499Sdlw if(p->p1) cursor = p->p1 - recpos - 1; 792499Sdlw #ifndef KOSHER 802499Sdlw else cursor = 8*p->p2 - recpos%8; /* NOT STANDARD FORT */ 812499Sdlw #endif 822499Sdlw tab = YES; 832499Sdlw return(OK); 842499Sdlw case TL: 852499Sdlw cursor -= p->p1; 8612370Sdlw if ((recpos + cursor) < 0) cursor = -recpos; /* ANSI req'd */ 872499Sdlw tab = YES; 882499Sdlw return(OK); 892499Sdlw default: 902598Sdlw return(errno=F_ERFMT); 912499Sdlw } 922499Sdlw } 932499Sdlw 9420984Slibs LOCAL 952499Sdlw rd_mvcur() 962499Sdlw { int n; 972499Sdlw if(tab) return((*dotab)()); 9812465Sdlw if (cursor < 0) return(errno=F_ERSEEK); 992499Sdlw while(cursor--) if((n=(*getn)()) < 0) return(n); 1002499Sdlw return(cursor=0); 1012499Sdlw } 1022499Sdlw 10320984Slibs LOCAL 1042499Sdlw rd_I(n,w,len) ftnlen len; uint *n; 1052499Sdlw { long x=0; 10618016Slibs int i,sign=0,ch,c,sign_ok=YES; 1072499Sdlw for(i=0;i<w;i++) 1082499Sdlw { 1092499Sdlw if((ch=(*getn)())<0) return(ch); 11018016Slibs switch(ch) 1112499Sdlw { 1122499Sdlw case ',': goto done; 11318016Slibs case '-': sign=1; /* and fall thru */ 11418016Slibs case '+': if(sign_ok == NO) return(errno=F_ERRICHR); 11518016Slibs sign_ok = NO; 11618016Slibs break; 1172499Sdlw case ' ': 1182499Sdlw if(cblank) x *= radix; 1192499Sdlw break; 12018016Slibs case '\n': if(cblank) { 12118016Slibs x *= radix; 12218016Slibs break; 12318016Slibs } else { 12418016Slibs goto done; 12518016Slibs } 1262499Sdlw default: 12718016Slibs sign_ok = NO; 12818016Slibs if( (c = ch-'0')>=0 && c<radix ) 12918016Slibs { x = (x * radix) + c; 13018016Slibs break; 1312499Sdlw } 13218016Slibs else if( (c = low_case[ch]-'a'+10)>=0 && c<radix ) 13318016Slibs { x = (x * radix) + c; 13418016Slibs break; 1352499Sdlw } 13617973Slibs return(errno=F_ERRICHR); 1372499Sdlw } 1382499Sdlw } 1392499Sdlw done: 1402499Sdlw if(sign) x = -x; 1412499Sdlw if(len==sizeof(short)) n->is=x; 1422499Sdlw else n->il=x; 1432499Sdlw return(OK); 1442499Sdlw } 1452499Sdlw 14620984Slibs LOCAL 14719984Slibs rd_L(n,w,len) uint *n; ftnlen len; 14822026Slibs { int ch,i,v = -1, period=0; 1492499Sdlw for(i=0;i<w;i++) 1502499Sdlw { if((ch=(*getn)()) < 0) return(ch); 15118016Slibs if((ch=low_case[ch])=='t' && v==-1) v=1; 1522499Sdlw else if(ch=='f' && v==-1) v=0; 15322026Slibs else if(ch=='.' && !period) period++; 15422026Slibs else if(ch==' ' || ch=='\t') ; 1552499Sdlw else if(ch==',') break; 15622026Slibs else if(v==-1) return(errno=F_ERLOGIF); 1572499Sdlw } 1582598Sdlw if(v==-1) return(errno=F_ERLOGIF); 15919984Slibs if(len==sizeof(short)) n->is=v; 16019984Slibs else n->il=v; 1612499Sdlw return(OK); 1622499Sdlw } 1632499Sdlw 16420984Slibs LOCAL 1652499Sdlw rd_F(p,w,d,len) ftnlen len; ufloat *p; 1662499Sdlw { double x,y; 16718016Slibs int i,sx,sz,ch,dot,ny,z,sawz,mode, sign_ok=YES; 1682499Sdlw x=y=0; 1692499Sdlw sawz=z=ny=dot=sx=sz=0; 17018016Slibs /* modes: 0 in initial blanks, 17118016Slibs 2 blanks plus sign 17218016Slibs 3 found a digit 17318016Slibs */ 17418016Slibs mode = 0; 17518016Slibs 1762499Sdlw for(i=0;i<w;) 1772499Sdlw { i++; 1782499Sdlw if((ch=(*getn)())<0) return(ch); 17918016Slibs 18018016Slibs if(ch==' ') { /* blank */ 18118016Slibs if(cblank && (mode==2)) x *= 10; 18218016Slibs } else if(ch<='9' && ch>='0') { /* digit */ 18318016Slibs mode = 2; 1842499Sdlw x=10*x+ch-'0'; 18518016Slibs } else if(ch=='.') { 1862499Sdlw break; 18718016Slibs } else if(ch=='e' || ch=='d' || ch=='E' || ch=='D') { 18818016Slibs goto exponent; 18918016Slibs } else if(ch=='+' || ch=='-') { 19018016Slibs if(mode==0) { /* sign before digits */ 19118016Slibs if(ch=='-') sx=1; 19218016Slibs mode = 1; 19318016Slibs } else if(mode==1) { /* two signs before digits */ 19418016Slibs return(errno=F_ERRFCHR); 19518016Slibs } else { /* sign after digits, weird but standard! 19618016Slibs means exponent without 'e' or 'd' */ 19718016Slibs goto exponent; 19818016Slibs } 19918016Slibs } else if(ch==',') { 20018016Slibs goto done; 20118016Slibs } else if(ch=='\n') { 20218016Slibs if(cblank && (mode==2)) x *= 10; 20318016Slibs } else { 20418016Slibs return(errno=F_ERRFCHR); 2052499Sdlw } 2062499Sdlw } 20718016Slibs /* get here if out of characters to scan or found a period */ 2082499Sdlw if(ch=='.') dot=1; 20918016Slibs while(i<w) 2102499Sdlw { i++; 2112499Sdlw if((ch=(*getn)())<0) return(ch); 21218016Slibs 21318016Slibs if(ch<='9' && ch>='0') { 2142499Sdlw y=10*y+ch-'0'; 21518016Slibs ny++; 21618016Slibs } else if(ch==' ' || ch=='\n') { 21718016Slibs if(cblank) { 21818016Slibs y*= 10; 21918016Slibs ny++; 22018016Slibs } 22118016Slibs } else if(ch==',') { 22218016Slibs goto done; 22318016Slibs } else if(ch=='d' || ch=='e' || ch=='+' || ch=='-' || ch=='D' || ch=='E') { 22418016Slibs break; 22518016Slibs } else { 22618016Slibs return(errno=F_ERRFCHR); 22718016Slibs } 2282499Sdlw } 22918016Slibs /* now for the exponent. 23018016Slibs * mode=3 means seen digit or sign of exponent. 23118016Slibs * either out of characters to scan or 23218016Slibs * ch is '+', '-', 'd', or 'e'. 23318016Slibs */ 23418016Slibs exponent: 23518016Slibs if(ch=='-' || ch=='+') { 23618016Slibs if(ch=='-') sz=1; 23718016Slibs mode = 3; 23818016Slibs } else { 23918016Slibs mode = 2; 24018016Slibs } 24118016Slibs 2422499Sdlw while(i<w) 2432499Sdlw { i++; 2442499Sdlw sawz=1; 2452499Sdlw if((ch=(*getn)())<0) return(ch); 24618016Slibs 24718016Slibs if(ch<='9' && ch>='0') { 24818016Slibs mode = 3; 2492499Sdlw z=10*z+ch-'0'; 25018016Slibs } else if(ch=='+' || ch=='-') { 25118016Slibs if(mode==3 ) return(errno=F_ERRFCHR); 25218016Slibs mode = 3; 25318016Slibs if(ch=='-') sz=1; 25418016Slibs } else if(ch == ' ' || ch=='\n') { 25518016Slibs if(cblank) z *=10; 25618016Slibs } else if(ch==',') { 25718016Slibs break; 25818016Slibs } else { 25918016Slibs return(errno=F_ERRFCHR); 26018016Slibs } 2612499Sdlw } 26218016Slibs done: 2632499Sdlw if(!dot) 2642499Sdlw for(i=0;i<d;i++) x /= 10; 2652499Sdlw for(i=0;i<ny;i++) y /= 10; 2662499Sdlw x=x+y; 2672499Sdlw if(sz) 2682499Sdlw for(i=0;i<z;i++) x /=10; 2692499Sdlw else for(i=0;i<z;i++) x *= 10; 2702499Sdlw if(sx) x = -x; 2712499Sdlw if(!sawz) 2722499Sdlw { 2732499Sdlw for(i=scale;i>0;i--) x /= 10; 2742499Sdlw for(i=scale;i<0;i++) x *= 10; 2752499Sdlw } 2762499Sdlw if(len==sizeof(float)) p->pf=x; 2772499Sdlw else p->pd=x; 2782499Sdlw return(OK); 2792499Sdlw } 2802499Sdlw 28120984Slibs LOCAL 2822499Sdlw rd_AW(p,w,len) char *p; ftnlen len; 2832499Sdlw { int i,ch; 2842499Sdlw if(w >= len) 2852499Sdlw { 2862499Sdlw for(i=0;i<w-len;i++) GET(ch); 2872499Sdlw for(i=0;i<len;i++) 2882499Sdlw { GET(ch); 2892499Sdlw *p++=VAL(ch); 2902499Sdlw } 2912499Sdlw } 2922499Sdlw else 2932499Sdlw { 2942499Sdlw for(i=0;i<w;i++) 2952499Sdlw { GET(ch); 2962499Sdlw *p++=VAL(ch); 2972499Sdlw } 2982499Sdlw for(i=0;i<len-w;i++) *p++=' '; 2992499Sdlw } 3002499Sdlw return(OK); 3012499Sdlw } 3022499Sdlw 3032499Sdlw /* THIS IS NOT ALLOWED IN THE NEW STANDARD 'CAUSE IT'S WEIRD */ 30420984Slibs LOCAL 3053632Sdlw rd_H(n,s) char *s; 3063632Sdlw { int i,ch = 0; 30718014Slibs 30818014Slibs used_data = YES; 3093632Sdlw for(i=0;i<n;i++) 3103632Sdlw { if (ch != '\n') 3113632Sdlw GET(ch); 3123632Sdlw if (ch == '\n') 3133632Sdlw *s++ = ' '; 3143632Sdlw else 3153632Sdlw *s++ = ch; 3163632Sdlw } 3173632Sdlw return(OK); 3183632Sdlw } 3193632Sdlw 32020984Slibs LOCAL 3213632Sdlw rd_POS(s) char *s; 3223632Sdlw { char quote; 3233632Sdlw int ch = 0; 32418014Slibs 32518014Slibs used_data = YES; 3263632Sdlw quote = *s++; 3273632Sdlw while(*s) 3283632Sdlw { if(*s==quote && *(s+1)!=quote) 3293632Sdlw break; 3303632Sdlw if (ch != '\n') 3313632Sdlw GET(ch); 3323632Sdlw if (ch == '\n') 3333632Sdlw *s++ = ' '; 3343632Sdlw else 3353632Sdlw *s++ = ch; 3363632Sdlw } 3373632Sdlw return(OK); 3383632Sdlw } 339