/* * 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 6/7/85 */ /* * formatted read routines */ #include "fio.h" #include "format.h" 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; { int n; if(cursor && (n=rd_mvcur())) return(n); switch(p->op) { case I: case IM: n = (rd_I(ptr,p->p1,len)); break; case L: n = (rd_L(ptr,p->p1,len)); break; case A: n = (rd_AW(ptr,(int)len,len)); break; case AW: n = (rd_AW(ptr,p->p1,len)); break; case E: case EE: case D: case DE: case G: case GE: case F: n = (rd_F(ptr,p->p1,p->p2,len)); break; default: return(errno=F_ERFMT); } if (n < 0) { if(feof(cf)) return(EOF); n = errno; clearerr(cf); } return(n); } rd_ned(p,ptr) char *ptr; struct syl *p; { switch(p->op) { #ifndef KOSHER case APOS: /* NOT STANDARD F77 */ return(rd_POS(&s_init[p->p1])); case H: /* NOT STANDARD F77 */ return(rd_H(p->p1,&s_init[p->p2])); #endif case SLASH: return((*donewrec)()); case TR: case X: cursor += p->p1; /* tab = (p->op==TR); This voids '..,tl6,1x,..' sequences */ tab = YES; return(OK); case T: if(p->p1) cursor = p->p1 - recpos - 1; #ifndef KOSHER else cursor = 8*p->p2 - recpos%8; /* NOT STANDARD FORT */ #endif tab = YES; return(OK); case TL: cursor -= p->p1; if ((recpos + cursor) < 0) cursor = -recpos; /* ANSI req'd */ tab = YES; return(OK); default: return(errno=F_ERFMT); } } LOCAL rd_mvcur() { int n; if(tab) return((*dotab)()); if (cursor < 0) return(errno=F_ERSEEK); while(cursor--) if((n=(*getn)()) < 0) return(n); return(cursor=0); } LOCAL rd_I(n,w,len) ftnlen len; uint *n; { long x=0; int i,sign=0,ch,c,sign_ok=YES; for(i=0;i=0 && c=0 && cis=x; else n->il=x; return(OK); } LOCAL rd_L(n,w,len) uint *n; ftnlen len; { int ch,i,v = -1, period=0; for(i=0;iis=v; else n->il=v; return(OK); } LOCAL rd_F(p,w,d,len) ftnlen len; ufloat *p; { double x,y; int i,sx,sz,ch,dot,ny,z,sawz,mode, sign_ok=YES; 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='0') { /* digit */ mode = 2; x=10*x+ch-'0'; } else if(ch=='.') { 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); } } /* get here if out of characters to scan or found a period */ if(ch=='.') dot=1; while(i='0') { y=10*y+ch-'0'; 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; } while(i='0') { mode = 3; z=10*z+ch-'0'; } 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;i0;i--) x /= 10; for(i=scale;i<0;i++) x *= 10; } if(len==sizeof(float)) p->pf=x; else p->pd=x; return(OK); } LOCAL rd_AW(p,w,len) char *p; ftnlen len; { int i,ch; if(w >= len) { for(i=0;i