12496Sdlw /* 2*23079Skre * Copyright (c) 1980 Regents of the University of California. 3*23079Skre * All rights reserved. The Berkeley software License Agreement 4*23079Skre * specifies the terms and conditions for redistribution. 52496Sdlw * 6*23079Skre * @(#)lread.c 5.1 06/07/85 7*23079Skre */ 8*23079Skre 9*23079Skre /* 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; 532496Sdlw if(n=c_le(a,READ)) return(n); 542496Sdlw l_first = YES; 552496Sdlw lquit = NO; 562496Sdlw lioproc = l_read; 572496Sdlw getn = t_getc; 582496Sdlw ungetn = ungetc; 592496Sdlw leof = curunit->uend; 602496Sdlw lcount = 0; 6112244Sdlw ltype = NULL; 624117Sdlw if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, lrd) 632496Sdlw return(OK); 642496Sdlw } 652496Sdlw 6620984Slibs LOCAL 672496Sdlw t_getc() 682496Sdlw { int ch; 692496Sdlw if(curunit->uend) return(EOF); 702496Sdlw if((ch=getc(cf))!=EOF) return(ch); 712496Sdlw if(feof(cf)) 722496Sdlw { curunit->uend = YES; 732496Sdlw leof = EOF; 742496Sdlw } 752496Sdlw else clearerr(cf); 762496Sdlw return(EOF); 772496Sdlw } 782496Sdlw 792496Sdlw e_rsle() 802496Sdlw { 812496Sdlw int ch; 8217671Sdlw if(curunit->uend) return(EOF); 8312368Sdlw while(GETC(ch) != '\n' && ch != EOF); 8417671Sdlw return(ch==EOF?EOF:OK); 852496Sdlw } 862496Sdlw 872496Sdlw l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len; 882496Sdlw { int i,n,ch; 892496Sdlw double *yy; 902496Sdlw float *xx; 912496Sdlw for(i=0;i<*number;i++) 922496Sdlw { 932496Sdlw if(leof) err(endflag, EOF, lrd) 942496Sdlw if(l_first) 952496Sdlw { l_first = NO; 962496Sdlw while(isblnk(GETC(ch))); /* skip blanks */ 972496Sdlw (*ungetn)(ch,cf); 982496Sdlw } 992496Sdlw else if(lcount==0) /* repeat count == 0 ? */ 1002496Sdlw { ERR(t_sep()); /* look for non-blank, allow 1 comma */ 1012496Sdlw if(lquit) return(OK); /* slash found */ 1022496Sdlw } 1032496Sdlw switch((int)type) 1042496Sdlw { 1052496Sdlw case TYSHORT: 1062496Sdlw case TYLONG: 1072496Sdlw case TYREAL: 1082496Sdlw case TYDREAL: 1092496Sdlw ERR(l_R(1)); 1102496Sdlw break; 1112496Sdlw case TYCOMPLEX: 1122496Sdlw case TYDCOMPLEX: 1132496Sdlw ERR(l_C()); 1142496Sdlw break; 1152496Sdlw case TYLOGICAL: 1162496Sdlw ERR(l_L()); 1172496Sdlw break; 1182496Sdlw case TYCHAR: 1192496Sdlw ERR(l_CHAR()); 1202496Sdlw break; 1212496Sdlw } 12219986Slibs 12319986Slibs /* peek at next character; it should be separator or new line */ 12419986Slibs GETC(ch); (*ungetn)(ch,cf); 12519986Slibs if(!issep(ch) && !endlinp(ch)) { 12619986Slibs while(GETC(ch)!= '\n' && ch != EOF); 12719986Slibs err(errflag,F_ERLIO,lrd); 12819986Slibs } 12919986Slibs 1302496Sdlw if(lquit) return(OK); 1312496Sdlw if(leof) err(endflag,EOF,lrd) 1322496Sdlw else if(external && ferror(cf)) err(errflag,errno,lrd) 1332496Sdlw if(ltype) switch((int)type) 1342496Sdlw { 1352496Sdlw case TYSHORT: 1362496Sdlw ptr->flshort=lx; 1372496Sdlw break; 1382496Sdlw case TYLOGICAL: 13918532Sralph if(len == sizeof(short)) 14018532Sralph ptr->flshort = lx; 14118532Sralph else 14218532Sralph ptr->flint = lx; 14318532Sralph break; 1442496Sdlw case TYLONG: 1452496Sdlw ptr->flint=lx; 1462496Sdlw break; 1472496Sdlw case TYREAL: 1482496Sdlw ptr->flreal=lx; 1492496Sdlw break; 1502496Sdlw case TYDREAL: 1512496Sdlw ptr->fldouble=lx; 1522496Sdlw break; 1532496Sdlw case TYCOMPLEX: 1542496Sdlw xx=(float *)ptr; 1552496Sdlw *xx++ = ly; 1562496Sdlw *xx = lx; 1572496Sdlw break; 1582496Sdlw case TYDCOMPLEX: 1592496Sdlw yy=(double *)ptr; 1602496Sdlw *yy++ = ly; 1612496Sdlw *yy = lx; 1622496Sdlw break; 1632496Sdlw case TYCHAR: 1642496Sdlw b_char(lchar,(char *)ptr,len); 1652496Sdlw break; 1662496Sdlw } 1672496Sdlw if(lcount>0) lcount--; 16812244Sdlw ptr = (flex *)((char *)ptr + len); 1692496Sdlw } 1702496Sdlw return(OK); 1712496Sdlw } 1722496Sdlw 17320984Slibs LOCAL 1742496Sdlw lr_comm() 1752496Sdlw { int ch; 1762496Sdlw if(lcount) return(lcount); 1772496Sdlw ltype=NULL; 1782496Sdlw while(isblnk(GETC(ch))); 1794727Sdlw (*ungetn)(ch,cf); 1802496Sdlw if(ch==',') 1812496Sdlw { lcount=1; 1822496Sdlw return(lcount); 1832496Sdlw } 1842496Sdlw if(ch=='/') 1852496Sdlw { lquit = YES; 1862496Sdlw return(lquit); 1872496Sdlw } 1882496Sdlw else 1892496Sdlw return(OK); 1902496Sdlw } 1912496Sdlw 19220984Slibs LOCAL 1932496Sdlw get_repet() 1942496Sdlw { char ch; 1952496Sdlw double lc; 1962496Sdlw if(isdigit(GETC(ch))) 1972496Sdlw { (*ungetn)(ch,cf); 1982496Sdlw rd_int(&lc); 1992496Sdlw lcount = (int)lc; 2002496Sdlw if(GETC(ch)!='*') 2012496Sdlw if(leof) return(EOF); 2022595Sdlw else return(F_ERREPT); 2032496Sdlw } 2042496Sdlw else 2052496Sdlw { lcount = 1; 2062496Sdlw (*ungetn)(ch,cf); 2072496Sdlw } 2082496Sdlw return(OK); 2092496Sdlw } 2102496Sdlw 21120984Slibs LOCAL 2122496Sdlw l_R(flg) int flg; 2132496Sdlw { double a,b,c,d; 2142496Sdlw int da,db,dc,dd; 2152496Sdlw int i,ch,sign=0; 2162496Sdlw a=b=c=d=0; 2172496Sdlw da=db=dc=dd=0; 21821012Slibs 21921012Slibs if( flg ) /* real */ 2202496Sdlw { 22121012Slibs if(lr_comm()) return(OK); 22221012Slibs da=rd_int(&a); /* repeat count ? */ 22321012Slibs if(GETC(ch)=='*') 22421012Slibs { 22521012Slibs if (a <= 0.) return(F_ERNREP); 22621012Slibs lcount=(int)a; 22721012Slibs if (nullfld()) return(OK); /* could be R* */ 22821012Slibs db=rd_int(&b); /* whole part of number */ 22921012Slibs } 23021012Slibs else 23121012Slibs { (*ungetn)(ch,cf); 23221012Slibs db=da; 23321012Slibs b=a; 23421012Slibs lcount=1; 23521012Slibs } 2362496Sdlw } 23721012Slibs else /* complex */ 23821012Slibs { 23921012Slibs db=rd_int(&b); 2402496Sdlw } 24121012Slibs 2422496Sdlw if(GETC(ch)=='.' && isdigit(GETC(ch))) 2432496Sdlw { (*ungetn)(ch,cf); 2442496Sdlw dc=rd_int(&c); /* fractional part of number */ 2452496Sdlw } 2462496Sdlw else 2472496Sdlw { (*ungetn)(ch,cf); 2482496Sdlw dc=0; 2492496Sdlw c=0.; 2502496Sdlw } 2512496Sdlw if(isexp(GETC(ch))) 2522496Sdlw dd=rd_int(&d); /* exponent */ 2532496Sdlw else if (ch == '+' || ch == '-') 2542496Sdlw { (*ungetn)(ch,cf); 2552496Sdlw dd=rd_int(&d); 2562496Sdlw } 2572496Sdlw else 2582496Sdlw { (*ungetn)(ch,cf); 2592496Sdlw dd=0; 2602496Sdlw } 2612496Sdlw if(db<0 || b<0) 2622496Sdlw { sign=1; 2632496Sdlw b = -b; 2642496Sdlw } 2652496Sdlw for(i=0;i<dc;i++) c/=10.; 2662496Sdlw b=b+c; 2672496Sdlw if (dd > 0) 2682496Sdlw { for(i=0;i<d;i++) b *= 10.; 2692496Sdlw for(i=0;i< -d;i++) b /= 10.; 2702496Sdlw } 2712496Sdlw lx=sign?-b:b; 2722496Sdlw ltype=TYLONG; 2732496Sdlw return(OK); 2742496Sdlw } 2752496Sdlw 27620984Slibs LOCAL 2772496Sdlw rd_int(x) double *x; 2782496Sdlw { int ch,sign=0,i=0; 2792496Sdlw double y=0.0; 2802496Sdlw if(GETC(ch)=='-') sign = -1; 2812496Sdlw else if(ch=='+') sign=0; 2822496Sdlw else (*ungetn)(ch,cf); 2832496Sdlw while(isdigit(GETC(ch))) 2842496Sdlw { i++; 2852496Sdlw y=10*y + ch-'0'; 2862496Sdlw } 2872496Sdlw (*ungetn)(ch,cf); 2882496Sdlw if(sign) y = -y; 2892496Sdlw *x = y; 2902496Sdlw return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */ 2912496Sdlw } 2922496Sdlw 29320984Slibs LOCAL 2942496Sdlw l_C() 2952496Sdlw { int ch,n; 2962496Sdlw if(lr_comm()) return(OK); 2972496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 29812244Sdlw if (nullfld()) return(OK); /* could be R* */ 2992595Sdlw if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (") 3002496Sdlw while(isblnk(GETC(ch))); 3012496Sdlw (*ungetn)(ch,cf); 3022496Sdlw l_R(0); /* get real part */ 3032496Sdlw ly = lx; 3042496Sdlw if(t_sep()) return(EOF); 3052496Sdlw l_R(0); /* get imag part */ 3062496Sdlw while(isblnk(GETC(ch))); 3072595Sdlw if(ch!=')') err(errflag,F_ERLIO,"no )") 3082496Sdlw ltype = TYCOMPLEX; 3092496Sdlw return(OK); 3102496Sdlw } 3112496Sdlw 31220984Slibs LOCAL 3132496Sdlw l_L() 3142496Sdlw { 3152496Sdlw int ch,n; 3162496Sdlw if(lr_comm()) return(OK); 3172496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 31812244Sdlw if (nullfld()) return(OK); /* could be R* */ 3192496Sdlw if(GETC(ch)=='.') GETC(ch); 3202496Sdlw switch(ch) 3212496Sdlw { 3222496Sdlw case 't': 3232496Sdlw case 'T': 3242496Sdlw lx=1; 3252496Sdlw break; 3262496Sdlw case 'f': 3272496Sdlw case 'F': 3282496Sdlw lx=0; 3292496Sdlw break; 3302496Sdlw default: 33121012Slibs if(issep(ch)) 3322496Sdlw { (*ungetn)(ch,cf); 3332496Sdlw lx=0; 3342496Sdlw return(OK); 3352496Sdlw } 3362496Sdlw else if(ch==EOF) return(EOF); 3372595Sdlw else err(errflag,F_ERLIO,"logical not T or F"); 3382496Sdlw } 3392496Sdlw ltype=TYLOGICAL; 34021012Slibs while(!issep(GETC(ch)) && !endlinp(ch)); 34112041Sdlw (*ungetn)(ch,cf); 3422496Sdlw return(OK); 3432496Sdlw } 3442496Sdlw 3452496Sdlw #define BUFSIZE 128 34620984Slibs LOCAL 3472496Sdlw l_CHAR() 3482496Sdlw { int ch,size,i,n; 3492496Sdlw char quote,*p; 3502496Sdlw if(lr_comm()) return(OK); 3512496Sdlw if(n=get_repet()) return(n); /* get repeat count */ 35212244Sdlw if (nullfld()) return(OK); /* could be R* */ 3532496Sdlw if(isapos(GETC(ch))) quote=ch; 35421012Slibs else if(issep(ch) || ch==EOF || ch=='\n') 3552496Sdlw { if(ch==EOF) return(EOF); 3562496Sdlw (*ungetn)(ch,cf); 3572496Sdlw return(OK); 3582496Sdlw } 3592496Sdlw else 3602496Sdlw { quote = '\0'; /* to allow single word non-quoted */ 3612496Sdlw (*ungetn)(ch,cf); 3622496Sdlw } 3632496Sdlw ltype=TYCHAR; 3642496Sdlw if(lchar!=NULL) free(lchar); 3652496Sdlw size=BUFSIZE-1; 3662496Sdlw p=lchar=(char *)malloc(BUFSIZE); 3672595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3682496Sdlw for(i=0;;) 3692496Sdlw { while( ( (quote && GETC(ch)!=quote) || 37021012Slibs (!quote && !issep(GETC(ch)) && !endlinp(ch)) ) 3712496Sdlw && ch!='\n' && ch!=EOF && ++i<size ) 3722496Sdlw *p++ = ch; 3732496Sdlw if(i==size) 3742496Sdlw { 3752496Sdlw newone: 3762496Sdlw size += BUFSIZE; 3772496Sdlw lchar=(char *)realloc(lchar, size+1); 3782595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd) 3792496Sdlw p=lchar+i-1; 3802496Sdlw *p++ = ch; 3812496Sdlw } 3822496Sdlw else if(ch==EOF) return(EOF); 3832496Sdlw else if(ch=='\n') 3842496Sdlw { if(*(p-1) == '\\') *(p-1) = ch; 3852496Sdlw else if(!quote) 3862496Sdlw { *p = '\0'; 3872496Sdlw (*ungetn)(ch,cf); 3882496Sdlw return(OK); 3892496Sdlw } 3902496Sdlw } 3912496Sdlw else if(quote && GETC(ch)==quote) 3922496Sdlw { if(++i<size) *p++ = ch; 3932496Sdlw else goto newone; 3942496Sdlw } 3952496Sdlw else 3962496Sdlw { (*ungetn)(ch,cf); 3972496Sdlw *p = '\0'; 3982496Sdlw return(OK); 3992496Sdlw } 4002496Sdlw } 4012496Sdlw } 4022496Sdlw 40320984Slibs LOCAL 4042496Sdlw t_sep() 4052496Sdlw { 4062496Sdlw int ch; 4072496Sdlw while(isblnk(GETC(ch))); 4082496Sdlw if(leof) return(EOF); 4092496Sdlw if(ch=='/') 4102496Sdlw { lquit = YES; 4112496Sdlw (*ungetn)(ch,cf); 4122496Sdlw return(OK); 4132496Sdlw } 4142496Sdlw if(issep(ch)) while(isblnk(GETC(ch))); 4152496Sdlw if(leof) return(EOF); 4162496Sdlw (*ungetn)(ch,cf); 4172496Sdlw return(OK); 4182496Sdlw } 41912244Sdlw 42020984Slibs LOCAL 42112244Sdlw nullfld() /* look for null field following a repeat count */ 42212244Sdlw { 42312244Sdlw int ch; 42412244Sdlw 42521012Slibs GETC(ch); 42612244Sdlw (*ungetn)(ch,cf); 42712244Sdlw if (issep(ch) || endlinp(ch)) 42812244Sdlw return(YES); 42912244Sdlw return(NO); 43012244Sdlw } 431