/* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * @(#)lread.c 5.2 7/30/85 */ /* * list directed read */ #include "fio.h" #include "lio.h" #define SP 1 #define B 2 #define AP 4 #define EX 8 #define D 16 #define EIN 32 #define isblnk(x) (ltab[x+1]&B) /* space, tab, newline */ #define issep(x) (ltab[x+1]&SP) /* space, tab, newline, comma */ #define isapos(x) (ltab[x+1]&AP) /* apost., quote mark, \02 */ #define isexp(x) (ltab[x+1]&EX) /* d, e, D, E */ #define isdigit(x) (ltab[x+1]&D) #define endlinp(x) (ltab[x+1]&EIN) /* EOF, newline, / */ #define GETC(x) (x=(*getn)()) LOCAL char lrd[] = "list read"; LOCAL char *lchar; LOCAL double lx,ly; LOCAL int ltype; int l_read(),t_getc(),ungetc(); LOCAL char ltab[128+1] = { EIN, /* offset one for EOF */ /* 0- 15 */ 0,0,AP,0,0,0,0,0,0,SP|B,SP|B|EIN,0,0,0,0,0, /* ^B,TAB,NEWLINE */ /* 16- 31 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 32- 47 */ SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,EIN, /* space,",',comma,/ */ /* 48- 63 */ D,D,D,D,D,D,D,D,D,D,0,0,0,0,0,0, /* digits 0-9 */ /* 64- 79 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* D,E */ /* 80- 95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 96-111 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* d,e */ /* 112-127 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; s_rsle(a) cilist *a; /* start read sequential list external */ { int n; reading = YES; formatted = LISTDIRECTED; fmtbuf = "ext list io"; if(n=c_le(a,READ)) return(n); l_first = YES; lquit = NO; lioproc = l_read; getn = t_getc; ungetn = ungetc; leof = curunit->uend; lcount = 0; ltype = NULL; if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, lrd) return(OK); } LOCAL t_getc() { int ch; if(curunit->uend) return(EOF); if((ch=getc(cf))!=EOF) return(ch); if(feof(cf)) { curunit->uend = YES; leof = EOF; } else clearerr(cf); return(EOF); } e_rsle() { int ch; if(curunit->uend) return(EOF); while(GETC(ch) != '\n' && ch != EOF); return(ch==EOF?EOF:OK); } l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len; { int i,n,ch; double *yy; float *xx; for(i=0;i<*number;i++) { if(leof) err(endflag, EOF, lrd) if(l_first) { l_first = NO; while(isblnk(GETC(ch))); /* skip blanks */ (*ungetn)(ch,cf); } else if(lcount==0) /* repeat count == 0 ? */ { ERR(t_sep()); /* look for non-blank, allow 1 comma */ if(lquit) return(OK); /* slash found */ } switch((int)type) { case TYSHORT: case TYLONG: case TYREAL: case TYDREAL: ERR(l_R(1)); break; case TYCOMPLEX: case TYDCOMPLEX: ERR(l_C()); break; case TYLOGICAL: ERR(l_L()); break; case TYCHAR: ERR(l_CHAR()); break; } /* peek at next character; it should be separator or new line */ GETC(ch); (*ungetn)(ch,cf); if(!issep(ch) && !endlinp(ch)) { while(GETC(ch)!= '\n' && ch != EOF); err(errflag,F_ERLIO,lrd); } if(lquit) return(OK); if(leof) err(endflag,EOF,lrd) else if(external && ferror(cf)) err(errflag,errno,lrd) if(ltype) switch((int)type) { case TYSHORT: ptr->flshort=lx; break; case TYLOGICAL: if(len == sizeof(short)) ptr->flshort = lx; else ptr->flint = lx; break; case TYLONG: ptr->flint=lx; break; case TYREAL: ptr->flreal=lx; break; case TYDREAL: ptr->fldouble=lx; break; case TYCOMPLEX: xx=(float *)ptr; *xx++ = ly; *xx = lx; break; case TYDCOMPLEX: yy=(double *)ptr; *yy++ = ly; *yy = lx; break; case TYCHAR: b_char(lchar,(char *)ptr,len); break; } if(lcount>0) lcount--; ptr = (flex *)((char *)ptr + len); } return(OK); } LOCAL lr_comm() { int ch; if(lcount) return(lcount); ltype=NULL; while(isblnk(GETC(ch))); (*ungetn)(ch,cf); if(ch==',') { lcount=1; return(lcount); } if(ch=='/') { lquit = YES; return(lquit); } else return(OK); } LOCAL get_repet() { char ch; double lc; if(isdigit(GETC(ch))) { (*ungetn)(ch,cf); rd_int(&lc); lcount = (int)lc; if(GETC(ch)!='*') if(leof) return(EOF); else return(F_ERREPT); } else { lcount = 1; (*ungetn)(ch,cf); } return(OK); } LOCAL l_R(flg) int flg; { double a,b,c,d; int da,db,dc,dd; int i,ch,sign=0; a=b=c=d=0; da=db=dc=dd=0; if( flg ) /* real */ { if(lr_comm()) return(OK); da=rd_int(&a); /* repeat count ? */ if(GETC(ch)=='*') { if (a <= 0.) return(F_ERNREP); lcount=(int)a; if (nullfld()) return(OK); /* could be R* */ db=rd_int(&b); /* whole part of number */ } else { (*ungetn)(ch,cf); db=da; b=a; lcount=1; } } else /* complex */ { db=rd_int(&b); } if(GETC(ch)=='.' && isdigit(GETC(ch))) { (*ungetn)(ch,cf); dc=rd_int(&c); /* fractional part of number */ } else { (*ungetn)(ch,cf); dc=0; c=0.; } if(isexp(GETC(ch))) dd=rd_int(&d); /* exponent */ else if (ch == '+' || ch == '-') { (*ungetn)(ch,cf); dd=rd_int(&d); } else { (*ungetn)(ch,cf); dd=0; } if(db<0 || b<0) { sign=1; b = -b; } for(i=0;i 0) { for(i=0;i0:#digits&&y!=0 */ } LOCAL l_C() { int ch,n; if(lr_comm()) return(OK); if(n=get_repet()) return(n); /* get repeat count */ if (nullfld()) return(OK); /* could be R* */ if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (") while(isblnk(GETC(ch))); (*ungetn)(ch,cf); l_R(0); /* get real part */ ly = lx; if(t_sep()) return(EOF); l_R(0); /* get imag part */ while(isblnk(GETC(ch))); if(ch!=')') err(errflag,F_ERLIO,"no )") ltype = TYCOMPLEX; return(OK); } LOCAL l_L() { int ch,n; if(lr_comm()) return(OK); if(n=get_repet()) return(n); /* get repeat count */ if (nullfld()) return(OK); /* could be R* */ if(GETC(ch)=='.') GETC(ch); switch(ch) { case 't': case 'T': lx=1; break; case 'f': case 'F': lx=0; break; default: if(issep(ch)) { (*ungetn)(ch,cf); lx=0; return(OK); } else if(ch==EOF) return(EOF); else err(errflag,F_ERLIO,"logical not T or F"); } ltype=TYLOGICAL; while(!issep(GETC(ch)) && !endlinp(ch)); (*ungetn)(ch,cf); return(OK); } #define BUFSIZE 128 LOCAL l_CHAR() { int ch,size,i,n; char quote,*p; if(lr_comm()) return(OK); if(n=get_repet()) return(n); /* get repeat count */ if (nullfld()) return(OK); /* could be R* */ if(isapos(GETC(ch))) quote=ch; else if(issep(ch) || ch==EOF || ch=='\n') { if(ch==EOF) return(EOF); (*ungetn)(ch,cf); return(OK); } else { quote = '\0'; /* to allow single word non-quoted */ (*ungetn)(ch,cf); } ltype=TYCHAR; if(lchar!=NULL) free(lchar); size=BUFSIZE-1; p=lchar=(char *)malloc(BUFSIZE); if(lchar==NULL) err(errflag,F_ERSPACE,lrd) for(i=0;;) { while( ( (quote && GETC(ch)!=quote) || (!quote && !issep(GETC(ch)) && !endlinp(ch)) ) && ch!='\n' && ch!=EOF && ++i