1*47943Sbostic /*-
2*47943Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*47943Sbostic * All rights reserved.
42496Sdlw *
5*47943Sbostic * %sccs.include.proprietary.c%
623079Skre */
723079Skre
8*47943Sbostic #ifndef lint
9*47943Sbostic static char sccsid[] = "@(#)lread.c 5.3 (Berkeley) 04/12/91";
10*47943Sbostic #endif /* not lint */
11*47943Sbostic
1223079Skre /*
132496Sdlw * list directed read
142496Sdlw */
152496Sdlw
162496Sdlw #include "fio.h"
172496Sdlw #include "lio.h"
182496Sdlw
192496Sdlw #define SP 1
202496Sdlw #define B 2
212496Sdlw #define AP 4
222496Sdlw #define EX 8
232496Sdlw #define D 16
242496Sdlw #define EIN 32
2521012Slibs #define isblnk(x) (ltab[x+1]&B) /* space, tab, newline */
2621012Slibs #define issep(x) (ltab[x+1]&SP) /* space, tab, newline, comma */
2721012Slibs #define isapos(x) (ltab[x+1]&AP) /* apost., quote mark, \02 */
2821012Slibs #define isexp(x) (ltab[x+1]&EX) /* d, e, D, E */
292496Sdlw #define isdigit(x) (ltab[x+1]&D)
3021012Slibs #define endlinp(x) (ltab[x+1]&EIN) /* EOF, newline, / */
312496Sdlw
322496Sdlw #define GETC(x) (x=(*getn)())
332496Sdlw
3420984Slibs LOCAL char lrd[] = "list read";
3520984Slibs LOCAL char *lchar;
3620984Slibs LOCAL double lx,ly;
3720984Slibs LOCAL int ltype;
382496Sdlw int l_read(),t_getc(),ungetc();
392496Sdlw
4020984Slibs LOCAL char ltab[128+1] =
4121012Slibs { EIN, /* offset one for EOF */
4221012Slibs /* 0- 15 */ 0,0,AP,0,0,0,0,0,0,SP|B,SP|B|EIN,0,0,0,0,0, /* ^B,TAB,NEWLINE */
432496Sdlw /* 16- 31 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
442496Sdlw /* 32- 47 */ SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,EIN, /* space,",',comma,/ */
452496Sdlw /* 48- 63 */ D,D,D,D,D,D,D,D,D,D,0,0,0,0,0,0, /* digits 0-9 */
462496Sdlw /* 64- 79 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* D,E */
472496Sdlw /* 80- 95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
482496Sdlw /* 96-111 */ 0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0, /* d,e */
492496Sdlw /* 112-127 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
502496Sdlw };
512496Sdlw
s_rsle(a)522496Sdlw s_rsle(a) cilist *a; /* start read sequential list external */
532496Sdlw {
542496Sdlw int n;
552496Sdlw reading = YES;
5624101Sjerry formatted = LISTDIRECTED;
5724101Sjerry fmtbuf = "ext list io";
582496Sdlw if(n=c_le(a,READ)) return(n);
592496Sdlw l_first = YES;
602496Sdlw lquit = NO;
612496Sdlw lioproc = l_read;
622496Sdlw getn = t_getc;
632496Sdlw ungetn = ungetc;
642496Sdlw leof = curunit->uend;
652496Sdlw lcount = 0;
6612244Sdlw ltype = NULL;
674117Sdlw if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, lrd)
682496Sdlw return(OK);
692496Sdlw }
702496Sdlw
7120984Slibs LOCAL
t_getc()722496Sdlw t_getc()
732496Sdlw { int ch;
742496Sdlw if(curunit->uend) return(EOF);
752496Sdlw if((ch=getc(cf))!=EOF) return(ch);
762496Sdlw if(feof(cf))
772496Sdlw { curunit->uend = YES;
782496Sdlw leof = EOF;
792496Sdlw }
802496Sdlw else clearerr(cf);
812496Sdlw return(EOF);
822496Sdlw }
832496Sdlw
e_rsle()842496Sdlw e_rsle()
852496Sdlw {
862496Sdlw int ch;
8717671Sdlw if(curunit->uend) return(EOF);
8812368Sdlw while(GETC(ch) != '\n' && ch != EOF);
8917671Sdlw return(ch==EOF?EOF:OK);
902496Sdlw }
912496Sdlw
l_read(number,ptr,len,type)922496Sdlw l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len;
932496Sdlw { int i,n,ch;
942496Sdlw double *yy;
952496Sdlw float *xx;
962496Sdlw for(i=0;i<*number;i++)
972496Sdlw {
982496Sdlw if(leof) err(endflag, EOF, lrd)
992496Sdlw if(l_first)
1002496Sdlw { l_first = NO;
1012496Sdlw while(isblnk(GETC(ch))); /* skip blanks */
1022496Sdlw (*ungetn)(ch,cf);
1032496Sdlw }
1042496Sdlw else if(lcount==0) /* repeat count == 0 ? */
1052496Sdlw { ERR(t_sep()); /* look for non-blank, allow 1 comma */
1062496Sdlw if(lquit) return(OK); /* slash found */
1072496Sdlw }
1082496Sdlw switch((int)type)
1092496Sdlw {
1102496Sdlw case TYSHORT:
1112496Sdlw case TYLONG:
1122496Sdlw case TYREAL:
1132496Sdlw case TYDREAL:
1142496Sdlw ERR(l_R(1));
1152496Sdlw break;
1162496Sdlw case TYCOMPLEX:
1172496Sdlw case TYDCOMPLEX:
1182496Sdlw ERR(l_C());
1192496Sdlw break;
1202496Sdlw case TYLOGICAL:
1212496Sdlw ERR(l_L());
1222496Sdlw break;
1232496Sdlw case TYCHAR:
1242496Sdlw ERR(l_CHAR());
1252496Sdlw break;
1262496Sdlw }
12719986Slibs
12819986Slibs /* peek at next character; it should be separator or new line */
12919986Slibs GETC(ch); (*ungetn)(ch,cf);
13019986Slibs if(!issep(ch) && !endlinp(ch)) {
13119986Slibs while(GETC(ch)!= '\n' && ch != EOF);
13219986Slibs err(errflag,F_ERLIO,lrd);
13319986Slibs }
13419986Slibs
1352496Sdlw if(lquit) return(OK);
1362496Sdlw if(leof) err(endflag,EOF,lrd)
1372496Sdlw else if(external && ferror(cf)) err(errflag,errno,lrd)
1382496Sdlw if(ltype) switch((int)type)
1392496Sdlw {
1402496Sdlw case TYSHORT:
1412496Sdlw ptr->flshort=lx;
1422496Sdlw break;
1432496Sdlw case TYLOGICAL:
14418532Sralph if(len == sizeof(short))
14518532Sralph ptr->flshort = lx;
14618532Sralph else
14718532Sralph ptr->flint = lx;
14818532Sralph break;
1492496Sdlw case TYLONG:
1502496Sdlw ptr->flint=lx;
1512496Sdlw break;
1522496Sdlw case TYREAL:
1532496Sdlw ptr->flreal=lx;
1542496Sdlw break;
1552496Sdlw case TYDREAL:
1562496Sdlw ptr->fldouble=lx;
1572496Sdlw break;
1582496Sdlw case TYCOMPLEX:
1592496Sdlw xx=(float *)ptr;
1602496Sdlw *xx++ = ly;
1612496Sdlw *xx = lx;
1622496Sdlw break;
1632496Sdlw case TYDCOMPLEX:
1642496Sdlw yy=(double *)ptr;
1652496Sdlw *yy++ = ly;
1662496Sdlw *yy = lx;
1672496Sdlw break;
1682496Sdlw case TYCHAR:
1692496Sdlw b_char(lchar,(char *)ptr,len);
1702496Sdlw break;
1712496Sdlw }
1722496Sdlw if(lcount>0) lcount--;
17312244Sdlw ptr = (flex *)((char *)ptr + len);
1742496Sdlw }
1752496Sdlw return(OK);
1762496Sdlw }
1772496Sdlw
17820984Slibs LOCAL
lr_comm()1792496Sdlw lr_comm()
1802496Sdlw { int ch;
1812496Sdlw if(lcount) return(lcount);
1822496Sdlw ltype=NULL;
1832496Sdlw while(isblnk(GETC(ch)));
1844727Sdlw (*ungetn)(ch,cf);
1852496Sdlw if(ch==',')
1862496Sdlw { lcount=1;
1872496Sdlw return(lcount);
1882496Sdlw }
1892496Sdlw if(ch=='/')
1902496Sdlw { lquit = YES;
1912496Sdlw return(lquit);
1922496Sdlw }
1932496Sdlw else
1942496Sdlw return(OK);
1952496Sdlw }
1962496Sdlw
19720984Slibs LOCAL
get_repet()1982496Sdlw get_repet()
1992496Sdlw { char ch;
2002496Sdlw double lc;
2012496Sdlw if(isdigit(GETC(ch)))
2022496Sdlw { (*ungetn)(ch,cf);
2032496Sdlw rd_int(&lc);
2042496Sdlw lcount = (int)lc;
2052496Sdlw if(GETC(ch)!='*')
2062496Sdlw if(leof) return(EOF);
2072595Sdlw else return(F_ERREPT);
2082496Sdlw }
2092496Sdlw else
2102496Sdlw { lcount = 1;
2112496Sdlw (*ungetn)(ch,cf);
2122496Sdlw }
2132496Sdlw return(OK);
2142496Sdlw }
2152496Sdlw
21620984Slibs LOCAL
l_R(flg)2172496Sdlw l_R(flg) int flg;
2182496Sdlw { double a,b,c,d;
2192496Sdlw int da,db,dc,dd;
2202496Sdlw int i,ch,sign=0;
2212496Sdlw a=b=c=d=0;
2222496Sdlw da=db=dc=dd=0;
22321012Slibs
22421012Slibs if( flg ) /* real */
2252496Sdlw {
22621012Slibs if(lr_comm()) return(OK);
22721012Slibs da=rd_int(&a); /* repeat count ? */
22821012Slibs if(GETC(ch)=='*')
22921012Slibs {
23021012Slibs if (a <= 0.) return(F_ERNREP);
23121012Slibs lcount=(int)a;
23221012Slibs if (nullfld()) return(OK); /* could be R* */
23321012Slibs db=rd_int(&b); /* whole part of number */
23421012Slibs }
23521012Slibs else
23621012Slibs { (*ungetn)(ch,cf);
23721012Slibs db=da;
23821012Slibs b=a;
23921012Slibs lcount=1;
24021012Slibs }
2412496Sdlw }
24221012Slibs else /* complex */
24321012Slibs {
24421012Slibs db=rd_int(&b);
2452496Sdlw }
24621012Slibs
2472496Sdlw if(GETC(ch)=='.' && isdigit(GETC(ch)))
2482496Sdlw { (*ungetn)(ch,cf);
2492496Sdlw dc=rd_int(&c); /* fractional part of number */
2502496Sdlw }
2512496Sdlw else
2522496Sdlw { (*ungetn)(ch,cf);
2532496Sdlw dc=0;
2542496Sdlw c=0.;
2552496Sdlw }
2562496Sdlw if(isexp(GETC(ch)))
2572496Sdlw dd=rd_int(&d); /* exponent */
2582496Sdlw else if (ch == '+' || ch == '-')
2592496Sdlw { (*ungetn)(ch,cf);
2602496Sdlw dd=rd_int(&d);
2612496Sdlw }
2622496Sdlw else
2632496Sdlw { (*ungetn)(ch,cf);
2642496Sdlw dd=0;
2652496Sdlw }
2662496Sdlw if(db<0 || b<0)
2672496Sdlw { sign=1;
2682496Sdlw b = -b;
2692496Sdlw }
2702496Sdlw for(i=0;i<dc;i++) c/=10.;
2712496Sdlw b=b+c;
2722496Sdlw if (dd > 0)
2732496Sdlw { for(i=0;i<d;i++) b *= 10.;
2742496Sdlw for(i=0;i< -d;i++) b /= 10.;
2752496Sdlw }
2762496Sdlw lx=sign?-b:b;
2772496Sdlw ltype=TYLONG;
2782496Sdlw return(OK);
2792496Sdlw }
2802496Sdlw
28120984Slibs LOCAL
rd_int(x)2822496Sdlw rd_int(x) double *x;
2832496Sdlw { int ch,sign=0,i=0;
2842496Sdlw double y=0.0;
2852496Sdlw if(GETC(ch)=='-') sign = -1;
2862496Sdlw else if(ch=='+') sign=0;
2872496Sdlw else (*ungetn)(ch,cf);
2882496Sdlw while(isdigit(GETC(ch)))
2892496Sdlw { i++;
2902496Sdlw y=10*y + ch-'0';
2912496Sdlw }
2922496Sdlw (*ungetn)(ch,cf);
2932496Sdlw if(sign) y = -y;
2942496Sdlw *x = y;
2952496Sdlw return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */
2962496Sdlw }
2972496Sdlw
29820984Slibs LOCAL
l_C()2992496Sdlw l_C()
3002496Sdlw { int ch,n;
3012496Sdlw if(lr_comm()) return(OK);
3022496Sdlw if(n=get_repet()) return(n); /* get repeat count */
30312244Sdlw if (nullfld()) return(OK); /* could be R* */
3042595Sdlw if(GETC(ch)!='(') err(errflag,F_ERLIO,"no (")
3052496Sdlw while(isblnk(GETC(ch)));
3062496Sdlw (*ungetn)(ch,cf);
3072496Sdlw l_R(0); /* get real part */
3082496Sdlw ly = lx;
3092496Sdlw if(t_sep()) return(EOF);
3102496Sdlw l_R(0); /* get imag part */
3112496Sdlw while(isblnk(GETC(ch)));
3122595Sdlw if(ch!=')') err(errflag,F_ERLIO,"no )")
3132496Sdlw ltype = TYCOMPLEX;
3142496Sdlw return(OK);
3152496Sdlw }
3162496Sdlw
31720984Slibs LOCAL
l_L()3182496Sdlw l_L()
3192496Sdlw {
3202496Sdlw int ch,n;
3212496Sdlw if(lr_comm()) return(OK);
3222496Sdlw if(n=get_repet()) return(n); /* get repeat count */
32312244Sdlw if (nullfld()) return(OK); /* could be R* */
3242496Sdlw if(GETC(ch)=='.') GETC(ch);
3252496Sdlw switch(ch)
3262496Sdlw {
3272496Sdlw case 't':
3282496Sdlw case 'T':
3292496Sdlw lx=1;
3302496Sdlw break;
3312496Sdlw case 'f':
3322496Sdlw case 'F':
3332496Sdlw lx=0;
3342496Sdlw break;
3352496Sdlw default:
33621012Slibs if(issep(ch))
3372496Sdlw { (*ungetn)(ch,cf);
3382496Sdlw lx=0;
3392496Sdlw return(OK);
3402496Sdlw }
3412496Sdlw else if(ch==EOF) return(EOF);
3422595Sdlw else err(errflag,F_ERLIO,"logical not T or F");
3432496Sdlw }
3442496Sdlw ltype=TYLOGICAL;
34521012Slibs while(!issep(GETC(ch)) && !endlinp(ch));
34612041Sdlw (*ungetn)(ch,cf);
3472496Sdlw return(OK);
3482496Sdlw }
3492496Sdlw
3502496Sdlw #define BUFSIZE 128
35120984Slibs LOCAL
l_CHAR()3522496Sdlw l_CHAR()
3532496Sdlw { int ch,size,i,n;
3542496Sdlw char quote,*p;
3552496Sdlw if(lr_comm()) return(OK);
3562496Sdlw if(n=get_repet()) return(n); /* get repeat count */
35712244Sdlw if (nullfld()) return(OK); /* could be R* */
3582496Sdlw if(isapos(GETC(ch))) quote=ch;
35921012Slibs else if(issep(ch) || ch==EOF || ch=='\n')
3602496Sdlw { if(ch==EOF) return(EOF);
3612496Sdlw (*ungetn)(ch,cf);
3622496Sdlw return(OK);
3632496Sdlw }
3642496Sdlw else
3652496Sdlw { quote = '\0'; /* to allow single word non-quoted */
3662496Sdlw (*ungetn)(ch,cf);
3672496Sdlw }
3682496Sdlw ltype=TYCHAR;
3692496Sdlw if(lchar!=NULL) free(lchar);
3702496Sdlw size=BUFSIZE-1;
3712496Sdlw p=lchar=(char *)malloc(BUFSIZE);
3722595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd)
3732496Sdlw for(i=0;;)
3742496Sdlw { while( ( (quote && GETC(ch)!=quote) ||
37521012Slibs (!quote && !issep(GETC(ch)) && !endlinp(ch)) )
3762496Sdlw && ch!='\n' && ch!=EOF && ++i<size )
3772496Sdlw *p++ = ch;
3782496Sdlw if(i==size)
3792496Sdlw {
3802496Sdlw newone:
3812496Sdlw size += BUFSIZE;
3822496Sdlw lchar=(char *)realloc(lchar, size+1);
3832595Sdlw if(lchar==NULL) err(errflag,F_ERSPACE,lrd)
3842496Sdlw p=lchar+i-1;
3852496Sdlw *p++ = ch;
3862496Sdlw }
3872496Sdlw else if(ch==EOF) return(EOF);
3882496Sdlw else if(ch=='\n')
3892496Sdlw { if(*(p-1) == '\\') *(p-1) = ch;
3902496Sdlw else if(!quote)
3912496Sdlw { *p = '\0';
3922496Sdlw (*ungetn)(ch,cf);
3932496Sdlw return(OK);
3942496Sdlw }
3952496Sdlw }
3962496Sdlw else if(quote && GETC(ch)==quote)
3972496Sdlw { if(++i<size) *p++ = ch;
3982496Sdlw else goto newone;
3992496Sdlw }
4002496Sdlw else
4012496Sdlw { (*ungetn)(ch,cf);
4022496Sdlw *p = '\0';
4032496Sdlw return(OK);
4042496Sdlw }
4052496Sdlw }
4062496Sdlw }
4072496Sdlw
40820984Slibs LOCAL
t_sep()4092496Sdlw t_sep()
4102496Sdlw {
4112496Sdlw int ch;
4122496Sdlw while(isblnk(GETC(ch)));
4132496Sdlw if(leof) return(EOF);
4142496Sdlw if(ch=='/')
4152496Sdlw { lquit = YES;
4162496Sdlw (*ungetn)(ch,cf);
4172496Sdlw return(OK);
4182496Sdlw }
4192496Sdlw if(issep(ch)) while(isblnk(GETC(ch)));
4202496Sdlw if(leof) return(EOF);
4212496Sdlw (*ungetn)(ch,cf);
4222496Sdlw return(OK);
4232496Sdlw }
42412244Sdlw
42520984Slibs LOCAL
nullfld()42612244Sdlw nullfld() /* look for null field following a repeat count */
42712244Sdlw {
42812244Sdlw int ch;
42912244Sdlw
43021012Slibs GETC(ch);
43112244Sdlw (*ungetn)(ch,cf);
43212244Sdlw if (issep(ch) || endlinp(ch))
43312244Sdlw return(YES);
43412244Sdlw return(NO);
43512244Sdlw }
436