12496Sdlw /* 2*19986Slibs char id_lread[] = "@(#)lread.c 1.10"; 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 162496Sdlw #define isblnk(x) (ltab[x+1]&B) 172496Sdlw #define issep(x) (ltab[x+1]&SP) 182496Sdlw #define isapos(x) (ltab[x+1]&AP) 192496Sdlw #define isexp(x) (ltab[x+1]&EX) 202496Sdlw #define isdigit(x) (ltab[x+1]&D) 212496Sdlw #define endlinp(x) (ltab[x+1]&EIN) 222496Sdlw 232496Sdlw #define GETC(x) (x=(*getn)()) 242496Sdlw 254117Sdlw char lrd[] = "list read"; 262496Sdlw char *lchar; 272496Sdlw double lx,ly; 282496Sdlw int ltype; 292496Sdlw int l_read(),t_getc(),ungetc(); 302496Sdlw 312496Sdlw char ltab[128+1] = 322496Sdlw { EIN, /* offset one for EOF */ 332496Sdlw /* 0- 15 */ 0,0,AP,0,0,0,0,0,0,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 602496Sdlw t_getc() 612496Sdlw { int ch; 622496Sdlw if(curunit->uend) return(EOF); 632496Sdlw if((ch=getc(cf))!=EOF) return(ch); 642496Sdlw if(feof(cf)) 652496Sdlw { curunit->uend = YES; 662496Sdlw leof = EOF; 672496Sdlw } 682496Sdlw else clearerr(cf); 692496Sdlw return(EOF); 702496Sdlw } 712496Sdlw 722496Sdlw e_rsle() 732496Sdlw { 742496Sdlw int ch; 7517671Sdlw if(curunit->uend) return(EOF); 7612368Sdlw while(GETC(ch) != '\n' && ch != EOF); 7717671Sdlw return(ch==EOF?EOF:OK); 782496Sdlw } 792496Sdlw 802496Sdlw l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len; 812496Sdlw { int i,n,ch; 822496Sdlw double *yy; 832496Sdlw float *xx; 842496Sdlw for(i=0;i<*number;i++) 852496Sdlw { 862496Sdlw if(leof) err(endflag, EOF, lrd) 872496Sdlw if(l_first) 882496Sdlw { l_first = NO; 892496Sdlw while(isblnk(GETC(ch))); /* skip blanks */ 902496Sdlw (*ungetn)(ch,cf); 912496Sdlw } 922496Sdlw else if(lcount==0) /* repeat count == 0 ? */ 932496Sdlw { ERR(t_sep()); /* look for non-blank, allow 1 comma */ 942496Sdlw if(lquit) return(OK); /* slash found */ 952496Sdlw } 962496Sdlw switch((int)type) 972496Sdlw { 982496Sdlw case TYSHORT: 992496Sdlw case TYLONG: 1002496Sdlw case TYREAL: 1012496Sdlw case TYDREAL: 1022496Sdlw ERR(l_R(1)); 1032496Sdlw break; 1042496Sdlw case TYCOMPLEX: 1052496Sdlw case TYDCOMPLEX: 1062496Sdlw ERR(l_C()); 1072496Sdlw break; 1082496Sdlw case TYLOGICAL: 1092496Sdlw ERR(l_L()); 1102496Sdlw break; 1112496Sdlw case TYCHAR: 1122496Sdlw ERR(l_CHAR()); 1132496Sdlw break; 1142496Sdlw } 115*19986Slibs 116*19986Slibs /* peek at next character; it should be separator or new line */ 117*19986Slibs GETC(ch); (*ungetn)(ch,cf); 118*19986Slibs if(!issep(ch) && !endlinp(ch)) { 119*19986Slibs while(GETC(ch)!= '\n' && ch != EOF); 120*19986Slibs err(errflag,F_ERLIO,lrd); 121*19986Slibs } 122*19986Slibs 1232496Sdlw if(lquit) return(OK); 1242496Sdlw if(leof) err(endflag,EOF,lrd) 1252496Sdlw else if(external && ferror(cf)) err(errflag,errno,lrd) 1262496Sdlw if(ltype) switch((int)type) 1272496Sdlw { 1282496Sdlw case TYSHORT: 1292496Sdlw ptr->flshort=lx; 1302496Sdlw break; 1312496Sdlw case TYLOGICAL: 13218532Sralph if(len == sizeof(short)) 13318532Sralph ptr->flshort = lx; 13418532Sralph else 13518532Sralph ptr->flint = lx; 13618532Sralph break; 1372496Sdlw case TYLONG: 1382496Sdlw ptr->flint=lx; 1392496Sdlw break; 1402496Sdlw case TYREAL: 1412496Sdlw ptr->flreal=lx; 1422496Sdlw break; 1432496Sdlw case TYDREAL: 1442496Sdlw ptr->fldouble=lx; 1452496Sdlw break; 1462496Sdlw case TYCOMPLEX: 1472496Sdlw xx=(float *)ptr; 1482496Sdlw *xx++ = ly; 1492496Sdlw *xx = lx; 1502496Sdlw break; 1512496Sdlw case TYDCOMPLEX: 1522496Sdlw yy=(double *)ptr; 1532496Sdlw *yy++ = ly; 1542496Sdlw *yy = lx; 1552496Sdlw break; 1562496Sdlw case TYCHAR: 1572496Sdlw b_char(lchar,(char *)ptr,len); 1582496Sdlw break; 1592496Sdlw } 1602496Sdlw if(lcount>0) lcount--; 16112244Sdlw ptr = (flex *)((char *)ptr + len); 1622496Sdlw } 1632496Sdlw return(OK); 1642496Sdlw } 1652496Sdlw 1662496Sdlw lr_comm() 1672496Sdlw { int ch; 1682496Sdlw if(lcount) return(lcount); 1692496Sdlw ltype=NULL; 1702496Sdlw while(isblnk(GETC(ch))); 1714727Sdlw (*ungetn)(ch,cf); 1722496Sdlw if(ch==',') 1732496Sdlw { lcount=1; 1742496Sdlw return(lcount); 1752496Sdlw } 1762496Sdlw if(ch=='/') 1772496Sdlw { lquit = YES; 1782496Sdlw return(lquit); 1792496Sdlw } 1802496Sdlw else 1812496Sdlw return(OK); 1822496Sdlw } 1832496Sdlw 1842496Sdlw get_repet() 1852496Sdlw { char ch; 1862496Sdlw double lc; 1872496Sdlw if(isdigit(GETC(ch))) 1882496Sdlw { (*ungetn)(ch,cf); 1892496Sdlw rd_int(&lc); 1902496Sdlw lcount = (int)lc; 1912496Sdlw if(GETC(ch)!='*') 1922496Sdlw if(leof) return(EOF); 1932595Sdlw else return(F_ERREPT); 1942496Sdlw } 1952496Sdlw else 1962496Sdlw { lcount = 1; 1972496Sdlw (*ungetn)(ch,cf); 1982496Sdlw } 1992496Sdlw return(OK); 2002496Sdlw } 2012496Sdlw 2022496Sdlw l_R(flg) int flg; 2032496Sdlw { double a,b,c,d; 2042496Sdlw int da,db,dc,dd; 2052496Sdlw int i,ch,sign=0; 2062496Sdlw a=b=c=d=0; 2072496Sdlw da=db=dc=dd=0; 2082496Sdlw if(flg && lr_comm()) return(OK); 2092496Sdlw da=rd_int(&a); /* repeat count ? */ 2102496Sdlw if(GETC(ch)=='*') 2112496Sdlw { 2122595Sdlw if (a <= 0.) return(F_ERNREP); 2132496Sdlw lcount=(int)a; 21412244Sdlw if (nullfld()) return(OK); /* could be R* */ 2152496Sdlw db=rd_int(&b); /* whole part of number */ 2162496Sdlw } 2172496Sdlw else 2182496Sdlw { (*ungetn)(ch,cf); 2192496Sdlw db=da; 2202496Sdlw b=a; 2212496Sdlw lcount=1; 2222496Sdlw } 2232496Sdlw if(GETC(ch)=='.' && isdigit(GETC(ch))) 2242496Sdlw { (*ungetn)(ch,cf); 2252496Sdlw dc=rd_int(&c); /* fractional part of number */ 2262496Sdlw } 2272496Sdlw else 2282496Sdlw { (*ungetn)(ch,cf); 2292496Sdlw dc=0; 2302496Sdlw c=0.; 2312496Sdlw } 2322496Sdlw if(isexp(GETC(ch))) 2332496Sdlw dd=rd_int(&d); /* exponent */ 2342496Sdlw else if (ch == '+' || ch == '-') 2352496Sdlw { (*ungetn)(ch,cf); 2362496Sdlw dd=rd_int(&d); 2372496Sdlw } 2382496Sdlw else 2392496Sdlw { (*ungetn)(ch,cf); 2402496Sdlw dd=0; 2412496Sdlw } 2422496Sdlw if(db<0 || b<0) 2432496Sdlw { sign=1; 2442496Sdlw b = -b; 2452496Sdlw } 2462496Sdlw for(i=0;i<dc;i++) c/=10.; 2472496Sdlw b=b+c; 2482496Sdlw if (dd > 0) 2492496Sdlw { for(i=0;i<d;i++) b *= 10.; 2502496Sdlw for(i=0;i< -d;i++) b /= 10.; 2512496Sdlw } 2522496Sdlw lx=sign?-b:b; 2532496Sdlw ltype=TYLONG; 2542496Sdlw return(OK); 2552496Sdlw } 2562496Sdlw 2572496Sdlw rd_int(x) double *x; 2582496Sdlw { int ch,sign=0,i=0; 2592496Sdlw double y=0.0; 2602496Sdlw if(GETC(ch)=='-') sign = -1; 2612496Sdlw else if(ch=='+') sign=0; 2622496Sdlw else (*ungetn)(ch,cf); 2632496Sdlw while(isdigit(GETC(ch))) 2642496Sdlw { i++; 2652496Sdlw y=10*y + ch-'0'; 2662496Sdlw } 2672496Sdlw (*ungetn)(ch,cf); 2682496Sdlw if(sign) y = -y; 2692496Sdlw *x = y; 2702496Sdlw return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */ 2712496Sdlw } 2722496Sdlw 2732496Sdlw l_C() 2742496Sdlw { int ch,n; 2752496Sdlw if(lr_comm()) return(OK); 2762496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 27712244Sdlw if (nullfld()) return(OK); /* could be R* */ 2782595Sdlw if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (") 2792496Sdlw while(isblnk(GETC(ch))); 2802496Sdlw (*ungetn)(ch,cf); 2812496Sdlw l_R(0); /* get real part */ 2822496Sdlw ly = lx; 2832496Sdlw if(t_sep()) return(EOF); 2842496Sdlw l_R(0); /* get imag part */ 2852496Sdlw while(isblnk(GETC(ch))); 2862595Sdlw if(ch!=')') err(errflag,F_ERLIO,"no )") 2872496Sdlw ltype = TYCOMPLEX; 2882496Sdlw return(OK); 2892496Sdlw } 2902496Sdlw 2912496Sdlw l_L() 2922496Sdlw { 2932496Sdlw int ch,n; 2942496Sdlw if(lr_comm()) return(OK); 2952496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 29612244Sdlw if (nullfld()) return(OK); /* could be R* */ 2972496Sdlw if(GETC(ch)=='.') GETC(ch); 2982496Sdlw switch(ch) 2992496Sdlw { 3002496Sdlw case 't': 3012496Sdlw case 'T': 3022496Sdlw lx=1; 3032496Sdlw break; 3042496Sdlw case 'f': 3052496Sdlw case 'F': 3062496Sdlw lx=0; 3072496Sdlw break; 3082496Sdlw default: 3092496Sdlw if(isblnk(ch) || issep(ch)) 3102496Sdlw { (*ungetn)(ch,cf); 3112496Sdlw lx=0; 3122496Sdlw return(OK); 3132496Sdlw } 3142496Sdlw else if(ch==EOF) return(EOF); 3152595Sdlw else err(errflag,F_ERLIO,"logical not T or F"); 3162496Sdlw } 3172496Sdlw ltype=TYLOGICAL; 31812368Sdlw while(!issep(GETC(ch)) && !isblnk(ch) && !endlinp(ch)); 31912041Sdlw (*ungetn)(ch,cf); 3202496Sdlw return(OK); 3212496Sdlw } 3222496Sdlw 3232496Sdlw #define BUFSIZE 128 3242496Sdlw l_CHAR() 3252496Sdlw { int ch,size,i,n; 3262496Sdlw char quote,*p; 3272496Sdlw if(lr_comm()) return(OK); 3282496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 32912244Sdlw if (nullfld()) return(OK); /* could be R* */ 3302496Sdlw if(isapos(GETC(ch))) quote=ch; 3312496Sdlw else if(isblnk(ch) || issep(ch) || ch==EOF || ch=='\n') 3322496Sdlw { if(ch==EOF) return(EOF); 3332496Sdlw (*ungetn)(ch,cf); 3342496Sdlw return(OK); 3352496Sdlw } 3362496Sdlw else 3372496Sdlw { quote = '\0'; /* to allow single word non-quoted */ 3382496Sdlw (*ungetn)(ch,cf); 3392496Sdlw } 3402496Sdlw ltype=TYCHAR; 3412496Sdlw if(lchar!=NULL) free(lchar); 3422496Sdlw size=BUFSIZE-1; 3432496Sdlw p=lchar=(char *)malloc(BUFSIZE); 3442595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3452496Sdlw for(i=0;;) 3462496Sdlw { while( ( (quote && GETC(ch)!=quote) || 34712368Sdlw (!quote && !issep(GETC(ch)) && !isblnk(ch) && !endlinp(ch)) ) 3482496Sdlw && ch!='\n' && ch!=EOF && ++i<size ) 3492496Sdlw *p++ = ch; 3502496Sdlw if(i==size) 3512496Sdlw { 3522496Sdlw newone: 3532496Sdlw size += BUFSIZE; 3542496Sdlw lchar=(char *)realloc(lchar, size+1); 3552595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3562496Sdlw p=lchar+i-1; 3572496Sdlw *p++ = ch; 3582496Sdlw } 3592496Sdlw else if(ch==EOF) return(EOF); 3602496Sdlw else if(ch=='\n') 3612496Sdlw { if(*(p-1) == '\\') *(p-1) = ch; 3622496Sdlw else if(!quote) 3632496Sdlw { *p = '\0'; 3642496Sdlw (*ungetn)(ch,cf); 3652496Sdlw return(OK); 3662496Sdlw } 3672496Sdlw } 3682496Sdlw else if(quote && GETC(ch)==quote) 3692496Sdlw { if(++i<size) *p++ = ch; 3702496Sdlw else goto newone; 3712496Sdlw } 3722496Sdlw else 3732496Sdlw { (*ungetn)(ch,cf); 3742496Sdlw *p = '\0'; 3752496Sdlw return(OK); 3762496Sdlw } 3772496Sdlw } 3782496Sdlw } 3792496Sdlw 3802496Sdlw t_sep() 3812496Sdlw { 3822496Sdlw int ch; 3832496Sdlw while(isblnk(GETC(ch))); 3842496Sdlw if(leof) return(EOF); 3852496Sdlw if(ch=='/') 3862496Sdlw { lquit = YES; 3872496Sdlw (*ungetn)(ch,cf); 3882496Sdlw return(OK); 3892496Sdlw } 3902496Sdlw if(issep(ch)) while(isblnk(GETC(ch))); 3912496Sdlw if(leof) return(EOF); 3922496Sdlw (*ungetn)(ch,cf); 3932496Sdlw return(OK); 3942496Sdlw } 39512244Sdlw 39612244Sdlw nullfld() /* look for null field following a repeat count */ 39712244Sdlw { 39812244Sdlw int ch; 39912244Sdlw 40012244Sdlw while(isblnk(GETC(ch))); 40112244Sdlw (*ungetn)(ch,cf); 40212244Sdlw if (issep(ch) || endlinp(ch)) 40312244Sdlw return(YES); 40412244Sdlw return(NO); 40512244Sdlw } 406