12496Sdlw /* 223079Skre * Copyright (c) 1980 Regents of the University of California. 323079Skre * All rights reserved. The Berkeley software License Agreement 423079Skre * specifies the terms and conditions for redistribution. 52496Sdlw * 6*24101Sjerry * @(#)lread.c 5.2 07/30/85 723079Skre */ 823079Skre 923079Skre /* 102496Sdlw * list directed read 112496Sdlw */ 122496Sdlw 132496Sdlw #include "fio.h" 142496Sdlw #include "lio.h" 152496Sdlw 162496Sdlw #define SP 1 172496Sdlw #define B 2 182496Sdlw #define AP 4 192496Sdlw #define EX 8 202496Sdlw #define D 16 212496Sdlw #define EIN 32 2221012Slibs #define isblnk(x) (ltab[x+1]&B) /* space, tab, newline */ 2321012Slibs #define issep(x) (ltab[x+1]&SP) /* space, tab, newline, comma */ 2421012Slibs #define isapos(x) (ltab[x+1]&AP) /* apost., quote mark, \02 */ 2521012Slibs #define isexp(x) (ltab[x+1]&EX) /* d, e, D, E */ 262496Sdlw #define isdigit(x) (ltab[x+1]&D) 2721012Slibs #define endlinp(x) (ltab[x+1]&EIN) /* EOF, newline, / */ 282496Sdlw 292496Sdlw #define GETC(x) (x=(*getn)()) 302496Sdlw 3120984Slibs LOCAL char lrd[] = "list read"; 3220984Slibs LOCAL char *lchar; 3320984Slibs LOCAL double lx,ly; 3420984Slibs LOCAL int ltype; 352496Sdlw int l_read(),t_getc(),ungetc(); 362496Sdlw 3720984Slibs LOCAL char ltab[128+1] = 3821012Slibs { EIN, /* offset one for EOF */ 3921012Slibs /* 0- 15 */ 0,0,AP,0,0,0,0,0,0,SP|B,SP|B|EIN,0,0,0,0,0, /* ^B,TAB,NEWLINE */ 402496Sdlw /* 16- 31 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 412496Sdlw /* 32- 47 */ SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,EIN, /* space,",',comma,/ */ 422496Sdlw /* 48- 63 */ D,D,D,D,D,D,D,D,D,D,0,0,0,0,0,0, /* digits 0-9 */ 432496Sdlw /* 64- 79 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* D,E */ 442496Sdlw /* 80- 95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 452496Sdlw /* 96-111 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* d,e */ 462496Sdlw /* 112-127 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 472496Sdlw }; 482496Sdlw 492496Sdlw s_rsle(a) cilist *a; /* start read sequential list external */ 502496Sdlw { 512496Sdlw int n; 522496Sdlw reading = YES; 53*24101Sjerry formatted = LISTDIRECTED; 54*24101Sjerry fmtbuf = "ext list io"; 552496Sdlw if(n=c_le(a,READ)) return(n); 562496Sdlw l_first = YES; 572496Sdlw lquit = NO; 582496Sdlw lioproc = l_read; 592496Sdlw getn = t_getc; 602496Sdlw ungetn = ungetc; 612496Sdlw leof = curunit->uend; 622496Sdlw lcount = 0; 6312244Sdlw ltype = NULL; 644117Sdlw if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, lrd) 652496Sdlw return(OK); 662496Sdlw } 672496Sdlw 6820984Slibs LOCAL 692496Sdlw t_getc() 702496Sdlw { int ch; 712496Sdlw if(curunit->uend) return(EOF); 722496Sdlw if((ch=getc(cf))!=EOF) return(ch); 732496Sdlw if(feof(cf)) 742496Sdlw { curunit->uend = YES; 752496Sdlw leof = EOF; 762496Sdlw } 772496Sdlw else clearerr(cf); 782496Sdlw return(EOF); 792496Sdlw } 802496Sdlw 812496Sdlw e_rsle() 822496Sdlw { 832496Sdlw int ch; 8417671Sdlw if(curunit->uend) return(EOF); 8512368Sdlw while(GETC(ch) != '\n' && ch != EOF); 8617671Sdlw return(ch==EOF?EOF:OK); 872496Sdlw } 882496Sdlw 892496Sdlw l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len; 902496Sdlw { int i,n,ch; 912496Sdlw double *yy; 922496Sdlw float *xx; 932496Sdlw for(i=0;i<*number;i++) 942496Sdlw { 952496Sdlw if(leof) err(endflag, EOF, lrd) 962496Sdlw if(l_first) 972496Sdlw { l_first = NO; 982496Sdlw while(isblnk(GETC(ch))); /* skip blanks */ 992496Sdlw (*ungetn)(ch,cf); 1002496Sdlw } 1012496Sdlw else if(lcount==0) /* repeat count == 0 ? */ 1022496Sdlw { ERR(t_sep()); /* look for non-blank, allow 1 comma */ 1032496Sdlw if(lquit) return(OK); /* slash found */ 1042496Sdlw } 1052496Sdlw switch((int)type) 1062496Sdlw { 1072496Sdlw case TYSHORT: 1082496Sdlw case TYLONG: 1092496Sdlw case TYREAL: 1102496Sdlw case TYDREAL: 1112496Sdlw ERR(l_R(1)); 1122496Sdlw break; 1132496Sdlw case TYCOMPLEX: 1142496Sdlw case TYDCOMPLEX: 1152496Sdlw ERR(l_C()); 1162496Sdlw break; 1172496Sdlw case TYLOGICAL: 1182496Sdlw ERR(l_L()); 1192496Sdlw break; 1202496Sdlw case TYCHAR: 1212496Sdlw ERR(l_CHAR()); 1222496Sdlw break; 1232496Sdlw } 12419986Slibs 12519986Slibs /* peek at next character; it should be separator or new line */ 12619986Slibs GETC(ch); (*ungetn)(ch,cf); 12719986Slibs if(!issep(ch) && !endlinp(ch)) { 12819986Slibs while(GETC(ch)!= '\n' && ch != EOF); 12919986Slibs err(errflag,F_ERLIO,lrd); 13019986Slibs } 13119986Slibs 1322496Sdlw if(lquit) return(OK); 1332496Sdlw if(leof) err(endflag,EOF,lrd) 1342496Sdlw else if(external && ferror(cf)) err(errflag,errno,lrd) 1352496Sdlw if(ltype) switch((int)type) 1362496Sdlw { 1372496Sdlw case TYSHORT: 1382496Sdlw ptr->flshort=lx; 1392496Sdlw break; 1402496Sdlw case TYLOGICAL: 14118532Sralph if(len == sizeof(short)) 14218532Sralph ptr->flshort = lx; 14318532Sralph else 14418532Sralph ptr->flint = lx; 14518532Sralph break; 1462496Sdlw case TYLONG: 1472496Sdlw ptr->flint=lx; 1482496Sdlw break; 1492496Sdlw case TYREAL: 1502496Sdlw ptr->flreal=lx; 1512496Sdlw break; 1522496Sdlw case TYDREAL: 1532496Sdlw ptr->fldouble=lx; 1542496Sdlw break; 1552496Sdlw case TYCOMPLEX: 1562496Sdlw xx=(float *)ptr; 1572496Sdlw *xx++ = ly; 1582496Sdlw *xx = lx; 1592496Sdlw break; 1602496Sdlw case TYDCOMPLEX: 1612496Sdlw yy=(double *)ptr; 1622496Sdlw *yy++ = ly; 1632496Sdlw *yy = lx; 1642496Sdlw break; 1652496Sdlw case TYCHAR: 1662496Sdlw b_char(lchar,(char *)ptr,len); 1672496Sdlw break; 1682496Sdlw } 1692496Sdlw if(lcount>0) lcount--; 17012244Sdlw ptr = (flex *)((char *)ptr + len); 1712496Sdlw } 1722496Sdlw return(OK); 1732496Sdlw } 1742496Sdlw 17520984Slibs LOCAL 1762496Sdlw lr_comm() 1772496Sdlw { int ch; 1782496Sdlw if(lcount) return(lcount); 1792496Sdlw ltype=NULL; 1802496Sdlw while(isblnk(GETC(ch))); 1814727Sdlw (*ungetn)(ch,cf); 1822496Sdlw if(ch==',') 1832496Sdlw { lcount=1; 1842496Sdlw return(lcount); 1852496Sdlw } 1862496Sdlw if(ch=='/') 1872496Sdlw { lquit = YES; 1882496Sdlw return(lquit); 1892496Sdlw } 1902496Sdlw else 1912496Sdlw return(OK); 1922496Sdlw } 1932496Sdlw 19420984Slibs LOCAL 1952496Sdlw get_repet() 1962496Sdlw { char ch; 1972496Sdlw double lc; 1982496Sdlw if(isdigit(GETC(ch))) 1992496Sdlw { (*ungetn)(ch,cf); 2002496Sdlw rd_int(&lc); 2012496Sdlw lcount = (int)lc; 2022496Sdlw if(GETC(ch)!='*') 2032496Sdlw if(leof) return(EOF); 2042595Sdlw else return(F_ERREPT); 2052496Sdlw } 2062496Sdlw else 2072496Sdlw { lcount = 1; 2082496Sdlw (*ungetn)(ch,cf); 2092496Sdlw } 2102496Sdlw return(OK); 2112496Sdlw } 2122496Sdlw 21320984Slibs LOCAL 2142496Sdlw l_R(flg) int flg; 2152496Sdlw { double a,b,c,d; 2162496Sdlw int da,db,dc,dd; 2172496Sdlw int i,ch,sign=0; 2182496Sdlw a=b=c=d=0; 2192496Sdlw da=db=dc=dd=0; 22021012Slibs 22121012Slibs if( flg ) /* real */ 2222496Sdlw { 22321012Slibs if(lr_comm()) return(OK); 22421012Slibs da=rd_int(&a); /* repeat count ? */ 22521012Slibs if(GETC(ch)=='*') 22621012Slibs { 22721012Slibs if (a <= 0.) return(F_ERNREP); 22821012Slibs lcount=(int)a; 22921012Slibs if (nullfld()) return(OK); /* could be R* */ 23021012Slibs db=rd_int(&b); /* whole part of number */ 23121012Slibs } 23221012Slibs else 23321012Slibs { (*ungetn)(ch,cf); 23421012Slibs db=da; 23521012Slibs b=a; 23621012Slibs lcount=1; 23721012Slibs } 2382496Sdlw } 23921012Slibs else /* complex */ 24021012Slibs { 24121012Slibs db=rd_int(&b); 2422496Sdlw } 24321012Slibs 2442496Sdlw if(GETC(ch)=='.' && isdigit(GETC(ch))) 2452496Sdlw { (*ungetn)(ch,cf); 2462496Sdlw dc=rd_int(&c); /* fractional part of number */ 2472496Sdlw } 2482496Sdlw else 2492496Sdlw { (*ungetn)(ch,cf); 2502496Sdlw dc=0; 2512496Sdlw c=0.; 2522496Sdlw } 2532496Sdlw if(isexp(GETC(ch))) 2542496Sdlw dd=rd_int(&d); /* exponent */ 2552496Sdlw else if (ch == '+' || ch == '-') 2562496Sdlw { (*ungetn)(ch,cf); 2572496Sdlw dd=rd_int(&d); 2582496Sdlw } 2592496Sdlw else 2602496Sdlw { (*ungetn)(ch,cf); 2612496Sdlw dd=0; 2622496Sdlw } 2632496Sdlw if(db<0 || b<0) 2642496Sdlw { sign=1; 2652496Sdlw b = -b; 2662496Sdlw } 2672496Sdlw for(i=0;i<dc;i++) c/=10.; 2682496Sdlw b=b+c; 2692496Sdlw if (dd > 0) 2702496Sdlw { for(i=0;i<d;i++) b *= 10.; 2712496Sdlw for(i=0;i< -d;i++) b /= 10.; 2722496Sdlw } 2732496Sdlw lx=sign?-b:b; 2742496Sdlw ltype=TYLONG; 2752496Sdlw return(OK); 2762496Sdlw } 2772496Sdlw 27820984Slibs LOCAL 2792496Sdlw rd_int(x) double *x; 2802496Sdlw { int ch,sign=0,i=0; 2812496Sdlw double y=0.0; 2822496Sdlw if(GETC(ch)=='-') sign = -1; 2832496Sdlw else if(ch=='+') sign=0; 2842496Sdlw else (*ungetn)(ch,cf); 2852496Sdlw while(isdigit(GETC(ch))) 2862496Sdlw { i++; 2872496Sdlw y=10*y + ch-'0'; 2882496Sdlw } 2892496Sdlw (*ungetn)(ch,cf); 2902496Sdlw if(sign) y = -y; 2912496Sdlw *x = y; 2922496Sdlw return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */ 2932496Sdlw } 2942496Sdlw 29520984Slibs LOCAL 2962496Sdlw l_C() 2972496Sdlw { int ch,n; 2982496Sdlw if(lr_comm()) return(OK); 2992496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 30012244Sdlw if (nullfld()) return(OK); /* could be R* */ 3012595Sdlw if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (") 3022496Sdlw while(isblnk(GETC(ch))); 3032496Sdlw (*ungetn)(ch,cf); 3042496Sdlw l_R(0); /* get real part */ 3052496Sdlw ly = lx; 3062496Sdlw if(t_sep()) return(EOF); 3072496Sdlw l_R(0); /* get imag part */ 3082496Sdlw while(isblnk(GETC(ch))); 3092595Sdlw if(ch!=')') err(errflag,F_ERLIO,"no )") 3102496Sdlw ltype = TYCOMPLEX; 3112496Sdlw return(OK); 3122496Sdlw } 3132496Sdlw 31420984Slibs LOCAL 3152496Sdlw l_L() 3162496Sdlw { 3172496Sdlw int ch,n; 3182496Sdlw if(lr_comm()) return(OK); 3192496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 32012244Sdlw if (nullfld()) return(OK); /* could be R* */ 3212496Sdlw if(GETC(ch)=='.') GETC(ch); 3222496Sdlw switch(ch) 3232496Sdlw { 3242496Sdlw case 't': 3252496Sdlw case 'T': 3262496Sdlw lx=1; 3272496Sdlw break; 3282496Sdlw case 'f': 3292496Sdlw case 'F': 3302496Sdlw lx=0; 3312496Sdlw break; 3322496Sdlw default: 33321012Slibs if(issep(ch)) 3342496Sdlw { (*ungetn)(ch,cf); 3352496Sdlw lx=0; 3362496Sdlw return(OK); 3372496Sdlw } 3382496Sdlw else if(ch==EOF) return(EOF); 3392595Sdlw else err(errflag,F_ERLIO,"logical not T or F"); 3402496Sdlw } 3412496Sdlw ltype=TYLOGICAL; 34221012Slibs while(!issep(GETC(ch)) && !endlinp(ch)); 34312041Sdlw (*ungetn)(ch,cf); 3442496Sdlw return(OK); 3452496Sdlw } 3462496Sdlw 3472496Sdlw #define BUFSIZE 128 34820984Slibs LOCAL 3492496Sdlw l_CHAR() 3502496Sdlw { int ch,size,i,n; 3512496Sdlw char quote,*p; 3522496Sdlw if(lr_comm()) return(OK); 3532496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 35412244Sdlw if (nullfld()) return(OK); /* could be R* */ 3552496Sdlw if(isapos(GETC(ch))) quote=ch; 35621012Slibs else if(issep(ch) || ch==EOF || ch=='\n') 3572496Sdlw { if(ch==EOF) return(EOF); 3582496Sdlw (*ungetn)(ch,cf); 3592496Sdlw return(OK); 3602496Sdlw } 3612496Sdlw else 3622496Sdlw { quote = '\0'; /* to allow single word non-quoted */ 3632496Sdlw (*ungetn)(ch,cf); 3642496Sdlw } 3652496Sdlw ltype=TYCHAR; 3662496Sdlw if(lchar!=NULL) free(lchar); 3672496Sdlw size=BUFSIZE-1; 3682496Sdlw p=lchar=(char *)malloc(BUFSIZE); 3692595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3702496Sdlw for(i=0;;) 3712496Sdlw { while( ( (quote && GETC(ch)!=quote) || 37221012Slibs (!quote && !issep(GETC(ch)) && !endlinp(ch)) ) 3732496Sdlw && ch!='\n' && ch!=EOF && ++i<size ) 3742496Sdlw *p++ = ch; 3752496Sdlw if(i==size) 3762496Sdlw { 3772496Sdlw newone: 3782496Sdlw size += BUFSIZE; 3792496Sdlw lchar=(char *)realloc(lchar, size+1); 3802595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3812496Sdlw p=lchar+i-1; 3822496Sdlw *p++ = ch; 3832496Sdlw } 3842496Sdlw else if(ch==EOF) return(EOF); 3852496Sdlw else if(ch=='\n') 3862496Sdlw { if(*(p-1) == '\\') *(p-1) = ch; 3872496Sdlw else if(!quote) 3882496Sdlw { *p = '\0'; 3892496Sdlw (*ungetn)(ch,cf); 3902496Sdlw return(OK); 3912496Sdlw } 3922496Sdlw } 3932496Sdlw else if(quote && GETC(ch)==quote) 3942496Sdlw { if(++i<size) *p++ = ch; 3952496Sdlw else goto newone; 3962496Sdlw } 3972496Sdlw else 3982496Sdlw { (*ungetn)(ch,cf); 3992496Sdlw *p = '\0'; 4002496Sdlw return(OK); 4012496Sdlw } 4022496Sdlw } 4032496Sdlw } 4042496Sdlw 40520984Slibs LOCAL 4062496Sdlw t_sep() 4072496Sdlw { 4082496Sdlw int ch; 4092496Sdlw while(isblnk(GETC(ch))); 4102496Sdlw if(leof) return(EOF); 4112496Sdlw if(ch=='/') 4122496Sdlw { lquit = YES; 4132496Sdlw (*ungetn)(ch,cf); 4142496Sdlw return(OK); 4152496Sdlw } 4162496Sdlw if(issep(ch)) while(isblnk(GETC(ch))); 4172496Sdlw if(leof) return(EOF); 4182496Sdlw (*ungetn)(ch,cf); 4192496Sdlw return(OK); 4202496Sdlw } 42112244Sdlw 42220984Slibs LOCAL 42312244Sdlw nullfld() /* look for null field following a repeat count */ 42412244Sdlw { 42512244Sdlw int ch; 42612244Sdlw 42721012Slibs GETC(ch); 42812244Sdlw (*ungetn)(ch,cf); 42912244Sdlw if (issep(ch) || endlinp(ch)) 43012244Sdlw return(YES); 43112244Sdlw return(NO); 43212244Sdlw } 433