12496Sdlw /* 2*21012Slibs char id_lread[] = "@(#)lread.c 1.12"; 32496Sdlw * 42496Sdlw * list directed read 52496Sdlw */ 62496Sdlw 72496Sdlw #include "fio.h" 82496Sdlw #include "lio.h" 92496Sdlw 102496Sdlw #define SP 1 112496Sdlw #define B 2 122496Sdlw #define AP 4 132496Sdlw #define EX 8 142496Sdlw #define D 16 152496Sdlw #define EIN 32 16*21012Slibs #define isblnk(x) (ltab[x+1]&B) /* space, tab, newline */ 17*21012Slibs #define issep(x) (ltab[x+1]&SP) /* space, tab, newline, comma */ 18*21012Slibs #define isapos(x) (ltab[x+1]&AP) /* apost., quote mark, \02 */ 19*21012Slibs #define isexp(x) (ltab[x+1]&EX) /* d, e, D, E */ 202496Sdlw #define isdigit(x) (ltab[x+1]&D) 21*21012Slibs #define endlinp(x) (ltab[x+1]&EIN) /* EOF, newline, / */ 222496Sdlw 232496Sdlw #define GETC(x) (x=(*getn)()) 242496Sdlw 2520984Slibs LOCAL char lrd[] = "list read"; 2620984Slibs LOCAL char *lchar; 2720984Slibs LOCAL double lx,ly; 2820984Slibs LOCAL int ltype; 292496Sdlw int l_read(),t_getc(),ungetc(); 302496Sdlw 3120984Slibs LOCAL char ltab[128+1] = 32*21012Slibs { EIN, /* offset one for EOF */ 33*21012Slibs /* 0- 15 */ 0,0,AP,0,0,0,0,0,0,SP|B,SP|B|EIN,0,0,0,0,0, /* ^B,TAB,NEWLINE */ 342496Sdlw /* 16- 31 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 352496Sdlw /* 32- 47 */ SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,EIN, /* space,",',comma,/ */ 362496Sdlw /* 48- 63 */ D,D,D,D,D,D,D,D,D,D,0,0,0,0,0,0, /* digits 0-9 */ 372496Sdlw /* 64- 79 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* D,E */ 382496Sdlw /* 80- 95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 392496Sdlw /* 96-111 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* d,e */ 402496Sdlw /* 112-127 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 412496Sdlw }; 422496Sdlw 432496Sdlw s_rsle(a) cilist *a; /* start read sequential list external */ 442496Sdlw { 452496Sdlw int n; 462496Sdlw reading = YES; 472496Sdlw if(n=c_le(a,READ)) return(n); 482496Sdlw l_first = YES; 492496Sdlw lquit = NO; 502496Sdlw lioproc = l_read; 512496Sdlw getn = t_getc; 522496Sdlw ungetn = ungetc; 532496Sdlw leof = curunit->uend; 542496Sdlw lcount = 0; 5512244Sdlw ltype = NULL; 564117Sdlw if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, lrd) 572496Sdlw return(OK); 582496Sdlw } 592496Sdlw 6020984Slibs LOCAL 612496Sdlw t_getc() 622496Sdlw { int ch; 632496Sdlw if(curunit->uend) return(EOF); 642496Sdlw if((ch=getc(cf))!=EOF) return(ch); 652496Sdlw if(feof(cf)) 662496Sdlw { curunit->uend = YES; 672496Sdlw leof = EOF; 682496Sdlw } 692496Sdlw else clearerr(cf); 702496Sdlw return(EOF); 712496Sdlw } 722496Sdlw 732496Sdlw e_rsle() 742496Sdlw { 752496Sdlw int ch; 7617671Sdlw if(curunit->uend) return(EOF); 7712368Sdlw while(GETC(ch) != '\n' && ch != EOF); 7817671Sdlw return(ch==EOF?EOF:OK); 792496Sdlw } 802496Sdlw 812496Sdlw l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len; 822496Sdlw { int i,n,ch; 832496Sdlw double *yy; 842496Sdlw float *xx; 852496Sdlw for(i=0;i<*number;i++) 862496Sdlw { 872496Sdlw if(leof) err(endflag, EOF, lrd) 882496Sdlw if(l_first) 892496Sdlw { l_first = NO; 902496Sdlw while(isblnk(GETC(ch))); /* skip blanks */ 912496Sdlw (*ungetn)(ch,cf); 922496Sdlw } 932496Sdlw else if(lcount==0) /* repeat count == 0 ? */ 942496Sdlw { ERR(t_sep()); /* look for non-blank, allow 1 comma */ 952496Sdlw if(lquit) return(OK); /* slash found */ 962496Sdlw } 972496Sdlw switch((int)type) 982496Sdlw { 992496Sdlw case TYSHORT: 1002496Sdlw case TYLONG: 1012496Sdlw case TYREAL: 1022496Sdlw case TYDREAL: 1032496Sdlw ERR(l_R(1)); 1042496Sdlw break; 1052496Sdlw case TYCOMPLEX: 1062496Sdlw case TYDCOMPLEX: 1072496Sdlw ERR(l_C()); 1082496Sdlw break; 1092496Sdlw case TYLOGICAL: 1102496Sdlw ERR(l_L()); 1112496Sdlw break; 1122496Sdlw case TYCHAR: 1132496Sdlw ERR(l_CHAR()); 1142496Sdlw break; 1152496Sdlw } 11619986Slibs 11719986Slibs /* peek at next character; it should be separator or new line */ 11819986Slibs GETC(ch); (*ungetn)(ch,cf); 11919986Slibs if(!issep(ch) && !endlinp(ch)) { 12019986Slibs while(GETC(ch)!= '\n' && ch != EOF); 12119986Slibs err(errflag,F_ERLIO,lrd); 12219986Slibs } 12319986Slibs 1242496Sdlw if(lquit) return(OK); 1252496Sdlw if(leof) err(endflag,EOF,lrd) 1262496Sdlw else if(external && ferror(cf)) err(errflag,errno,lrd) 1272496Sdlw if(ltype) switch((int)type) 1282496Sdlw { 1292496Sdlw case TYSHORT: 1302496Sdlw ptr->flshort=lx; 1312496Sdlw break; 1322496Sdlw case TYLOGICAL: 13318532Sralph if(len == sizeof(short)) 13418532Sralph ptr->flshort = lx; 13518532Sralph else 13618532Sralph ptr->flint = lx; 13718532Sralph break; 1382496Sdlw case TYLONG: 1392496Sdlw ptr->flint=lx; 1402496Sdlw break; 1412496Sdlw case TYREAL: 1422496Sdlw ptr->flreal=lx; 1432496Sdlw break; 1442496Sdlw case TYDREAL: 1452496Sdlw ptr->fldouble=lx; 1462496Sdlw break; 1472496Sdlw case TYCOMPLEX: 1482496Sdlw xx=(float *)ptr; 1492496Sdlw *xx++ = ly; 1502496Sdlw *xx = lx; 1512496Sdlw break; 1522496Sdlw case TYDCOMPLEX: 1532496Sdlw yy=(double *)ptr; 1542496Sdlw *yy++ = ly; 1552496Sdlw *yy = lx; 1562496Sdlw break; 1572496Sdlw case TYCHAR: 1582496Sdlw b_char(lchar,(char *)ptr,len); 1592496Sdlw break; 1602496Sdlw } 1612496Sdlw if(lcount>0) lcount--; 16212244Sdlw ptr = (flex *)((char *)ptr + len); 1632496Sdlw } 1642496Sdlw return(OK); 1652496Sdlw } 1662496Sdlw 16720984Slibs LOCAL 1682496Sdlw lr_comm() 1692496Sdlw { int ch; 1702496Sdlw if(lcount) return(lcount); 1712496Sdlw ltype=NULL; 1722496Sdlw while(isblnk(GETC(ch))); 1734727Sdlw (*ungetn)(ch,cf); 1742496Sdlw if(ch==',') 1752496Sdlw { lcount=1; 1762496Sdlw return(lcount); 1772496Sdlw } 1782496Sdlw if(ch=='/') 1792496Sdlw { lquit = YES; 1802496Sdlw return(lquit); 1812496Sdlw } 1822496Sdlw else 1832496Sdlw return(OK); 1842496Sdlw } 1852496Sdlw 18620984Slibs LOCAL 1872496Sdlw get_repet() 1882496Sdlw { char ch; 1892496Sdlw double lc; 1902496Sdlw if(isdigit(GETC(ch))) 1912496Sdlw { (*ungetn)(ch,cf); 1922496Sdlw rd_int(&lc); 1932496Sdlw lcount = (int)lc; 1942496Sdlw if(GETC(ch)!='*') 1952496Sdlw if(leof) return(EOF); 1962595Sdlw else return(F_ERREPT); 1972496Sdlw } 1982496Sdlw else 1992496Sdlw { lcount = 1; 2002496Sdlw (*ungetn)(ch,cf); 2012496Sdlw } 2022496Sdlw return(OK); 2032496Sdlw } 2042496Sdlw 20520984Slibs LOCAL 2062496Sdlw l_R(flg) int flg; 2072496Sdlw { double a,b,c,d; 2082496Sdlw int da,db,dc,dd; 2092496Sdlw int i,ch,sign=0; 2102496Sdlw a=b=c=d=0; 2112496Sdlw da=db=dc=dd=0; 212*21012Slibs 213*21012Slibs if( flg ) /* real */ 2142496Sdlw { 215*21012Slibs if(lr_comm()) return(OK); 216*21012Slibs da=rd_int(&a); /* repeat count ? */ 217*21012Slibs if(GETC(ch)=='*') 218*21012Slibs { 219*21012Slibs if (a <= 0.) return(F_ERNREP); 220*21012Slibs lcount=(int)a; 221*21012Slibs if (nullfld()) return(OK); /* could be R* */ 222*21012Slibs db=rd_int(&b); /* whole part of number */ 223*21012Slibs } 224*21012Slibs else 225*21012Slibs { (*ungetn)(ch,cf); 226*21012Slibs db=da; 227*21012Slibs b=a; 228*21012Slibs lcount=1; 229*21012Slibs } 2302496Sdlw } 231*21012Slibs else /* complex */ 232*21012Slibs { 233*21012Slibs db=rd_int(&b); 2342496Sdlw } 235*21012Slibs 2362496Sdlw if(GETC(ch)=='.' && isdigit(GETC(ch))) 2372496Sdlw { (*ungetn)(ch,cf); 2382496Sdlw dc=rd_int(&c); /* fractional part of number */ 2392496Sdlw } 2402496Sdlw else 2412496Sdlw { (*ungetn)(ch,cf); 2422496Sdlw dc=0; 2432496Sdlw c=0.; 2442496Sdlw } 2452496Sdlw if(isexp(GETC(ch))) 2462496Sdlw dd=rd_int(&d); /* exponent */ 2472496Sdlw else if (ch == '+' || ch == '-') 2482496Sdlw { (*ungetn)(ch,cf); 2492496Sdlw dd=rd_int(&d); 2502496Sdlw } 2512496Sdlw else 2522496Sdlw { (*ungetn)(ch,cf); 2532496Sdlw dd=0; 2542496Sdlw } 2552496Sdlw if(db<0 || b<0) 2562496Sdlw { sign=1; 2572496Sdlw b = -b; 2582496Sdlw } 2592496Sdlw for(i=0;i<dc;i++) c/=10.; 2602496Sdlw b=b+c; 2612496Sdlw if (dd > 0) 2622496Sdlw { for(i=0;i<d;i++) b *= 10.; 2632496Sdlw for(i=0;i< -d;i++) b /= 10.; 2642496Sdlw } 2652496Sdlw lx=sign?-b:b; 2662496Sdlw ltype=TYLONG; 2672496Sdlw return(OK); 2682496Sdlw } 2692496Sdlw 27020984Slibs LOCAL 2712496Sdlw rd_int(x) double *x; 2722496Sdlw { int ch,sign=0,i=0; 2732496Sdlw double y=0.0; 2742496Sdlw if(GETC(ch)=='-') sign = -1; 2752496Sdlw else if(ch=='+') sign=0; 2762496Sdlw else (*ungetn)(ch,cf); 2772496Sdlw while(isdigit(GETC(ch))) 2782496Sdlw { i++; 2792496Sdlw y=10*y + ch-'0'; 2802496Sdlw } 2812496Sdlw (*ungetn)(ch,cf); 2822496Sdlw if(sign) y = -y; 2832496Sdlw *x = y; 2842496Sdlw return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */ 2852496Sdlw } 2862496Sdlw 28720984Slibs LOCAL 2882496Sdlw l_C() 2892496Sdlw { int ch,n; 2902496Sdlw if(lr_comm()) return(OK); 2912496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 29212244Sdlw if (nullfld()) return(OK); /* could be R* */ 2932595Sdlw if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (") 2942496Sdlw while(isblnk(GETC(ch))); 2952496Sdlw (*ungetn)(ch,cf); 2962496Sdlw l_R(0); /* get real part */ 2972496Sdlw ly = lx; 2982496Sdlw if(t_sep()) return(EOF); 2992496Sdlw l_R(0); /* get imag part */ 3002496Sdlw while(isblnk(GETC(ch))); 3012595Sdlw if(ch!=')') err(errflag,F_ERLIO,"no )") 3022496Sdlw ltype = TYCOMPLEX; 3032496Sdlw return(OK); 3042496Sdlw } 3052496Sdlw 30620984Slibs LOCAL 3072496Sdlw l_L() 3082496Sdlw { 3092496Sdlw int ch,n; 3102496Sdlw if(lr_comm()) return(OK); 3112496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 31212244Sdlw if (nullfld()) return(OK); /* could be R* */ 3132496Sdlw if(GETC(ch)=='.') GETC(ch); 3142496Sdlw switch(ch) 3152496Sdlw { 3162496Sdlw case 't': 3172496Sdlw case 'T': 3182496Sdlw lx=1; 3192496Sdlw break; 3202496Sdlw case 'f': 3212496Sdlw case 'F': 3222496Sdlw lx=0; 3232496Sdlw break; 3242496Sdlw default: 325*21012Slibs if(issep(ch)) 3262496Sdlw { (*ungetn)(ch,cf); 3272496Sdlw lx=0; 3282496Sdlw return(OK); 3292496Sdlw } 3302496Sdlw else if(ch==EOF) return(EOF); 3312595Sdlw else err(errflag,F_ERLIO,"logical not T or F"); 3322496Sdlw } 3332496Sdlw ltype=TYLOGICAL; 334*21012Slibs while(!issep(GETC(ch)) && !endlinp(ch)); 33512041Sdlw (*ungetn)(ch,cf); 3362496Sdlw return(OK); 3372496Sdlw } 3382496Sdlw 3392496Sdlw #define BUFSIZE 128 34020984Slibs LOCAL 3412496Sdlw l_CHAR() 3422496Sdlw { int ch,size,i,n; 3432496Sdlw char quote,*p; 3442496Sdlw if(lr_comm()) return(OK); 3452496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 34612244Sdlw if (nullfld()) return(OK); /* could be R* */ 3472496Sdlw if(isapos(GETC(ch))) quote=ch; 348*21012Slibs else if(issep(ch) || ch==EOF || ch=='\n') 3492496Sdlw { if(ch==EOF) return(EOF); 3502496Sdlw (*ungetn)(ch,cf); 3512496Sdlw return(OK); 3522496Sdlw } 3532496Sdlw else 3542496Sdlw { quote = '\0'; /* to allow single word non-quoted */ 3552496Sdlw (*ungetn)(ch,cf); 3562496Sdlw } 3572496Sdlw ltype=TYCHAR; 3582496Sdlw if(lchar!=NULL) free(lchar); 3592496Sdlw size=BUFSIZE-1; 3602496Sdlw p=lchar=(char *)malloc(BUFSIZE); 3612595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3622496Sdlw for(i=0;;) 3632496Sdlw { while( ( (quote && GETC(ch)!=quote) || 364*21012Slibs (!quote && !issep(GETC(ch)) && !endlinp(ch)) ) 3652496Sdlw && ch!='\n' && ch!=EOF && ++i<size ) 3662496Sdlw *p++ = ch; 3672496Sdlw if(i==size) 3682496Sdlw { 3692496Sdlw newone: 3702496Sdlw size += BUFSIZE; 3712496Sdlw lchar=(char *)realloc(lchar, size+1); 3722595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3732496Sdlw p=lchar+i-1; 3742496Sdlw *p++ = ch; 3752496Sdlw } 3762496Sdlw else if(ch==EOF) return(EOF); 3772496Sdlw else if(ch=='\n') 3782496Sdlw { if(*(p-1) == '\\') *(p-1) = ch; 3792496Sdlw else if(!quote) 3802496Sdlw { *p = '\0'; 3812496Sdlw (*ungetn)(ch,cf); 3822496Sdlw return(OK); 3832496Sdlw } 3842496Sdlw } 3852496Sdlw else if(quote && GETC(ch)==quote) 3862496Sdlw { if(++i<size) *p++ = ch; 3872496Sdlw else goto newone; 3882496Sdlw } 3892496Sdlw else 3902496Sdlw { (*ungetn)(ch,cf); 3912496Sdlw *p = '\0'; 3922496Sdlw return(OK); 3932496Sdlw } 3942496Sdlw } 3952496Sdlw } 3962496Sdlw 39720984Slibs LOCAL 3982496Sdlw t_sep() 3992496Sdlw { 4002496Sdlw int ch; 4012496Sdlw while(isblnk(GETC(ch))); 4022496Sdlw if(leof) return(EOF); 4032496Sdlw if(ch=='/') 4042496Sdlw { lquit = YES; 4052496Sdlw (*ungetn)(ch,cf); 4062496Sdlw return(OK); 4072496Sdlw } 4082496Sdlw if(issep(ch)) while(isblnk(GETC(ch))); 4092496Sdlw if(leof) return(EOF); 4102496Sdlw (*ungetn)(ch,cf); 4112496Sdlw return(OK); 4122496Sdlw } 41312244Sdlw 41420984Slibs LOCAL 41512244Sdlw nullfld() /* look for null field following a repeat count */ 41612244Sdlw { 41712244Sdlw int ch; 41812244Sdlw 419*21012Slibs GETC(ch); 42012244Sdlw (*ungetn)(ch,cf); 42112244Sdlw if (issep(ch) || endlinp(ch)) 42212244Sdlw return(YES); 42312244Sdlw return(NO); 42412244Sdlw } 425