xref: /csrg-svn/usr.bin/f77/libI77/lread.c (revision 2496)
1*2496Sdlw /*
2*2496Sdlw char id_lread[] = "@(#)lread.c	1.1";
3*2496Sdlw  *
4*2496Sdlw  * list directed read
5*2496Sdlw  */
6*2496Sdlw 
7*2496Sdlw #include "fio.h"
8*2496Sdlw #include "lio.h"
9*2496Sdlw 
10*2496Sdlw #define SP 1
11*2496Sdlw #define B  2
12*2496Sdlw #define AP 4
13*2496Sdlw #define EX 8
14*2496Sdlw #define D 16
15*2496Sdlw #define EIN 32
16*2496Sdlw #define isblnk(x)	(ltab[x+1]&B)
17*2496Sdlw #define issep(x)	(ltab[x+1]&SP)
18*2496Sdlw #define isapos(x)	(ltab[x+1]&AP)
19*2496Sdlw #define isexp(x)	(ltab[x+1]&EX)
20*2496Sdlw #define isdigit(x)	(ltab[x+1]&D)
21*2496Sdlw #define endlinp(x)	(ltab[x+1]&EIN)
22*2496Sdlw 
23*2496Sdlw #define GETC(x) (x=(*getn)())
24*2496Sdlw 
25*2496Sdlw char *lrd = "list read";
26*2496Sdlw char *lchar;
27*2496Sdlw double lx,ly;
28*2496Sdlw int ltype;
29*2496Sdlw int l_read(),t_getc(),ungetc();
30*2496Sdlw 
31*2496Sdlw char ltab[128+1] =
32*2496Sdlw {		EIN, /* offset one for EOF */
33*2496Sdlw /*   0- 15 */	0,0,AP,0,0,0,0,0,0,B,SP|B|EIN,0,0,0,0,0, /* ^B,TAB,NEWLINE */
34*2496Sdlw /*  16- 31 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
35*2496Sdlw /*  32- 47 */	SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,EIN, /* space,",',comma,/ */
36*2496Sdlw /*  48- 63 */	D,D,D,D,D,D,D,D,D,D,0,0,0,0,0,0,	/* digits 0-9 */
37*2496Sdlw /*  64- 79 */	0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,	/* D,E */
38*2496Sdlw /*  80- 95 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
39*2496Sdlw /*  96-111 */	0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,	/* d,e */
40*2496Sdlw /* 112-127 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
41*2496Sdlw };
42*2496Sdlw 
43*2496Sdlw s_rsle(a) cilist *a;	/* start read sequential list external */
44*2496Sdlw {
45*2496Sdlw 	int n;
46*2496Sdlw 	reading = YES;
47*2496Sdlw 	if(n=c_le(a,READ)) return(n);
48*2496Sdlw 	l_first = YES;
49*2496Sdlw 	lquit = NO;
50*2496Sdlw 	lioproc = l_read;
51*2496Sdlw 	getn = t_getc;
52*2496Sdlw 	ungetn = ungetc;
53*2496Sdlw 	leof = curunit->uend;
54*2496Sdlw 	lcount = 0;
55*2496Sdlw 	if(curunit->uwrt) nowreading(curunit);
56*2496Sdlw 	return(OK);
57*2496Sdlw }
58*2496Sdlw 
59*2496Sdlw t_getc()
60*2496Sdlw {	int ch;
61*2496Sdlw 	if(curunit->uend) return(EOF);
62*2496Sdlw 	if((ch=getc(cf))!=EOF) return(ch);
63*2496Sdlw 	if(feof(cf))
64*2496Sdlw 	{	curunit->uend = YES;
65*2496Sdlw 		leof = EOF;
66*2496Sdlw 	}
67*2496Sdlw 	else clearerr(cf);
68*2496Sdlw 	return(EOF);
69*2496Sdlw }
70*2496Sdlw 
71*2496Sdlw e_rsle()
72*2496Sdlw {
73*2496Sdlw 	int ch;
74*2496Sdlw 	if(curunit->uend) return(OK);
75*2496Sdlw 	while(!endlinp(GETC(ch)));
76*2496Sdlw 	return(OK);
77*2496Sdlw }
78*2496Sdlw 
79*2496Sdlw l_read(number,ptr,len,type) ftnint *number,type; flex *ptr; ftnlen len;
80*2496Sdlw {	int i,n,ch;
81*2496Sdlw 	double *yy;
82*2496Sdlw 	float *xx;
83*2496Sdlw 	for(i=0;i<*number;i++)
84*2496Sdlw 	{
85*2496Sdlw 		if(leof) err(endflag, EOF, lrd)
86*2496Sdlw 		if(l_first)
87*2496Sdlw 		{	l_first = NO;
88*2496Sdlw 			while(isblnk(GETC(ch)));	/* skip blanks */
89*2496Sdlw 			(*ungetn)(ch,cf);
90*2496Sdlw 		}
91*2496Sdlw 		else if(lcount==0)		/* repeat count == 0 ? */
92*2496Sdlw 		{	ERR(t_sep());  /* look for non-blank, allow 1 comma */
93*2496Sdlw 			if(lquit) return(OK);	/* slash found */
94*2496Sdlw 		}
95*2496Sdlw 		switch((int)type)
96*2496Sdlw 		{
97*2496Sdlw 		case TYSHORT:
98*2496Sdlw 		case TYLONG:
99*2496Sdlw 		case TYREAL:
100*2496Sdlw 		case TYDREAL:
101*2496Sdlw 			ERR(l_R(1));
102*2496Sdlw 			break;
103*2496Sdlw 		case TYCOMPLEX:
104*2496Sdlw 		case TYDCOMPLEX:
105*2496Sdlw 			ERR(l_C());
106*2496Sdlw 			break;
107*2496Sdlw 		case TYLOGICAL:
108*2496Sdlw 			ERR(l_L());
109*2496Sdlw 			break;
110*2496Sdlw 		case TYCHAR:
111*2496Sdlw 			ERR(l_CHAR());
112*2496Sdlw 			break;
113*2496Sdlw 		}
114*2496Sdlw 		if(lquit) return(OK);
115*2496Sdlw 		if(leof) err(endflag,EOF,lrd)
116*2496Sdlw 		else if(external && ferror(cf)) err(errflag,errno,lrd)
117*2496Sdlw 		if(ltype) switch((int)type)
118*2496Sdlw 		{
119*2496Sdlw 		case TYSHORT:
120*2496Sdlw 			ptr->flshort=lx;
121*2496Sdlw 			break;
122*2496Sdlw 		case TYLOGICAL:
123*2496Sdlw 		case TYLONG:
124*2496Sdlw 			ptr->flint=lx;
125*2496Sdlw 			break;
126*2496Sdlw 		case TYREAL:
127*2496Sdlw 			ptr->flreal=lx;
128*2496Sdlw 			break;
129*2496Sdlw 		case TYDREAL:
130*2496Sdlw 			ptr->fldouble=lx;
131*2496Sdlw 			break;
132*2496Sdlw 		case TYCOMPLEX:
133*2496Sdlw 			xx=(float *)ptr;
134*2496Sdlw 			*xx++ = ly;
135*2496Sdlw 			*xx = lx;
136*2496Sdlw 			break;
137*2496Sdlw 		case TYDCOMPLEX:
138*2496Sdlw 			yy=(double *)ptr;
139*2496Sdlw 			*yy++ = ly;
140*2496Sdlw 			*yy = lx;
141*2496Sdlw 			break;
142*2496Sdlw 		case TYCHAR:
143*2496Sdlw 			b_char(lchar,(char *)ptr,len);
144*2496Sdlw 			break;
145*2496Sdlw 		}
146*2496Sdlw 		if(lcount>0) lcount--;
147*2496Sdlw 		ptr = (char *)ptr + len;
148*2496Sdlw 	}
149*2496Sdlw 	return(OK);
150*2496Sdlw }
151*2496Sdlw 
152*2496Sdlw lr_comm()
153*2496Sdlw {	int ch;
154*2496Sdlw 	if(lcount) return(lcount);
155*2496Sdlw 	ltype=NULL;
156*2496Sdlw 	while(isblnk(GETC(ch)));
157*2496Sdlw 	if(ch==',')
158*2496Sdlw 	{	lcount=1;
159*2496Sdlw 		return(lcount);
160*2496Sdlw 	}
161*2496Sdlw 	(*ungetn)(ch,cf);
162*2496Sdlw 	if(ch=='/')
163*2496Sdlw 	{	lquit = YES;
164*2496Sdlw 		return(lquit);
165*2496Sdlw 	}
166*2496Sdlw 	else
167*2496Sdlw 		return(OK);
168*2496Sdlw }
169*2496Sdlw 
170*2496Sdlw get_repet()
171*2496Sdlw {	char ch;
172*2496Sdlw 	double lc;
173*2496Sdlw 	if(isdigit(GETC(ch)))
174*2496Sdlw 	{	(*ungetn)(ch,cf);
175*2496Sdlw 		rd_int(&lc);
176*2496Sdlw 		lcount = (int)lc;
177*2496Sdlw 		if(GETC(ch)!='*')
178*2496Sdlw 			if(leof) return(EOF);
179*2496Sdlw 			else return(109);
180*2496Sdlw 	}
181*2496Sdlw 	else
182*2496Sdlw 	{	lcount = 1;
183*2496Sdlw 		(*ungetn)(ch,cf);
184*2496Sdlw 	}
185*2496Sdlw 	return(OK);
186*2496Sdlw }
187*2496Sdlw 
188*2496Sdlw l_R(flg) int flg;
189*2496Sdlw {	double a,b,c,d;
190*2496Sdlw 	int da,db,dc,dd;
191*2496Sdlw 	int i,ch,sign=0;
192*2496Sdlw 	a=b=c=d=0;
193*2496Sdlw 	da=db=dc=dd=0;
194*2496Sdlw 	if(flg && lr_comm()) return(OK);
195*2496Sdlw 	da=rd_int(&a);	/* repeat count ? */
196*2496Sdlw 	if(GETC(ch)=='*')
197*2496Sdlw 	{
198*2496Sdlw 		if (a <= 0.) return(122);
199*2496Sdlw 		lcount=(int)a;
200*2496Sdlw 		db=rd_int(&b);	/* whole part of number */
201*2496Sdlw 	}
202*2496Sdlw 	else
203*2496Sdlw 	{	(*ungetn)(ch,cf);
204*2496Sdlw 		db=da;
205*2496Sdlw 		b=a;
206*2496Sdlw 		lcount=1;
207*2496Sdlw 	}
208*2496Sdlw 	if(GETC(ch)=='.' && isdigit(GETC(ch)))
209*2496Sdlw 	{	(*ungetn)(ch,cf);
210*2496Sdlw 		dc=rd_int(&c);	/* fractional part of number */
211*2496Sdlw 	}
212*2496Sdlw 	else
213*2496Sdlw 	{	(*ungetn)(ch,cf);
214*2496Sdlw 		dc=0;
215*2496Sdlw 		c=0.;
216*2496Sdlw 	}
217*2496Sdlw 	if(isexp(GETC(ch)))
218*2496Sdlw 		dd=rd_int(&d);	/* exponent */
219*2496Sdlw 	else if (ch == '+' || ch == '-')
220*2496Sdlw 	{	(*ungetn)(ch,cf);
221*2496Sdlw 		dd=rd_int(&d);
222*2496Sdlw 	}
223*2496Sdlw 	else
224*2496Sdlw 	{	(*ungetn)(ch,cf);
225*2496Sdlw 		dd=0;
226*2496Sdlw 	}
227*2496Sdlw 	if(db<0 || b<0)
228*2496Sdlw 	{	sign=1;
229*2496Sdlw 		b = -b;
230*2496Sdlw 	}
231*2496Sdlw 	for(i=0;i<dc;i++) c/=10.;
232*2496Sdlw 	b=b+c;
233*2496Sdlw 	if (dd > 0)
234*2496Sdlw 	{	for(i=0;i<d;i++) b *= 10.;
235*2496Sdlw 		for(i=0;i< -d;i++) b /= 10.;
236*2496Sdlw 	}
237*2496Sdlw 	lx=sign?-b:b;
238*2496Sdlw 	ltype=TYLONG;
239*2496Sdlw 	return(OK);
240*2496Sdlw }
241*2496Sdlw 
242*2496Sdlw rd_int(x) double *x;
243*2496Sdlw {	int ch,sign=0,i=0;
244*2496Sdlw 	double y=0.0;
245*2496Sdlw 	if(GETC(ch)=='-') sign = -1;
246*2496Sdlw 	else if(ch=='+') sign=0;
247*2496Sdlw 	else (*ungetn)(ch,cf);
248*2496Sdlw 	while(isdigit(GETC(ch)))
249*2496Sdlw 	{	i++;
250*2496Sdlw 		y=10*y + ch-'0';
251*2496Sdlw 	}
252*2496Sdlw 	(*ungetn)(ch,cf);
253*2496Sdlw 	if(sign) y = -y;
254*2496Sdlw 	*x = y;
255*2496Sdlw 	return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */
256*2496Sdlw }
257*2496Sdlw 
258*2496Sdlw l_C()
259*2496Sdlw {	int ch,n;
260*2496Sdlw 	if(lr_comm()) return(OK);
261*2496Sdlw 	if(n=get_repet()) return(n);		/* get repeat count */
262*2496Sdlw 	if(GETC(ch)!='(') err(errflag,112,"no (")
263*2496Sdlw 	while(isblnk(GETC(ch)));
264*2496Sdlw 	(*ungetn)(ch,cf);
265*2496Sdlw 	l_R(0);		/* get real part */
266*2496Sdlw 	ly = lx;
267*2496Sdlw 	if(t_sep()) return(EOF);
268*2496Sdlw 	l_R(0);		/* get imag part */
269*2496Sdlw 	while(isblnk(GETC(ch)));
270*2496Sdlw 	if(ch!=')') err(errflag,112,"no )")
271*2496Sdlw 	ltype = TYCOMPLEX;
272*2496Sdlw 	return(OK);
273*2496Sdlw }
274*2496Sdlw 
275*2496Sdlw l_L()
276*2496Sdlw {
277*2496Sdlw 	int ch,n;
278*2496Sdlw 	if(lr_comm()) return(OK);
279*2496Sdlw 	if(n=get_repet()) return(n);		/* get repeat count */
280*2496Sdlw 	if(GETC(ch)=='.') GETC(ch);
281*2496Sdlw 	switch(ch)
282*2496Sdlw 	{
283*2496Sdlw 	case 't':
284*2496Sdlw 	case 'T':
285*2496Sdlw 		lx=1;
286*2496Sdlw 		break;
287*2496Sdlw 	case 'f':
288*2496Sdlw 	case 'F':
289*2496Sdlw 		lx=0;
290*2496Sdlw 		break;
291*2496Sdlw 	default:
292*2496Sdlw 		if(isblnk(ch) || issep(ch))
293*2496Sdlw 		{	(*ungetn)(ch,cf);
294*2496Sdlw 			lx=0;
295*2496Sdlw 			return(OK);
296*2496Sdlw 		}
297*2496Sdlw 		else if(ch==EOF) return(EOF);
298*2496Sdlw 		else	err(errflag,112,"logical not T or F");
299*2496Sdlw 	}
300*2496Sdlw 	ltype=TYLOGICAL;
301*2496Sdlw 	while(!issep(GETC(ch)) && !isblnk(ch) && ch!='\n' && ch!=EOF);
302*2496Sdlw 	return(OK);
303*2496Sdlw }
304*2496Sdlw 
305*2496Sdlw #define BUFSIZE	128
306*2496Sdlw l_CHAR()
307*2496Sdlw {	int ch,size,i,n;
308*2496Sdlw 	char quote,*p;
309*2496Sdlw 	if(lr_comm()) return(OK);
310*2496Sdlw 	if(n=get_repet()) return(n);		/* get repeat count */
311*2496Sdlw 	if(isapos(GETC(ch))) quote=ch;
312*2496Sdlw 	else if(isblnk(ch) || issep(ch) || ch==EOF || ch=='\n')
313*2496Sdlw 	{	if(ch==EOF) return(EOF);
314*2496Sdlw 		(*ungetn)(ch,cf);
315*2496Sdlw 		return(OK);
316*2496Sdlw 	}
317*2496Sdlw 	else
318*2496Sdlw 	{	quote = '\0';	/* to allow single word non-quoted */
319*2496Sdlw 		(*ungetn)(ch,cf);
320*2496Sdlw 	}
321*2496Sdlw 	ltype=TYCHAR;
322*2496Sdlw 	if(lchar!=NULL) free(lchar);
323*2496Sdlw 	size=BUFSIZE-1;
324*2496Sdlw 	p=lchar=(char *)malloc(BUFSIZE);
325*2496Sdlw 	if(lchar==NULL) err(errflag,113,lrd)
326*2496Sdlw 	for(i=0;;)
327*2496Sdlw 	{	while( ( (quote && GETC(ch)!=quote) ||
328*2496Sdlw 			(!quote && !issep(GETC(ch)) && !isblnk(ch) ) )
329*2496Sdlw 			&& ch!='\n' && ch!=EOF && ++i<size )
330*2496Sdlw 				*p++ = ch;
331*2496Sdlw 		if(i==size)
332*2496Sdlw 		{
333*2496Sdlw 		newone:
334*2496Sdlw 			size += BUFSIZE;
335*2496Sdlw 			lchar=(char *)realloc(lchar, size+1);
336*2496Sdlw 			if(lchar==NULL) err(errflag,113,lrd)
337*2496Sdlw 			p=lchar+i-1;
338*2496Sdlw 			*p++ = ch;
339*2496Sdlw 		}
340*2496Sdlw 		else if(ch==EOF) return(EOF);
341*2496Sdlw 		else if(ch=='\n')
342*2496Sdlw 		{	if(*(p-1) == '\\') *(p-1) = ch;
343*2496Sdlw 			else if(!quote)
344*2496Sdlw 			{	*p = '\0';
345*2496Sdlw 				(*ungetn)(ch,cf);
346*2496Sdlw 				return(OK);
347*2496Sdlw 			}
348*2496Sdlw 		}
349*2496Sdlw 		else if(quote && GETC(ch)==quote)
350*2496Sdlw 		{	if(++i<size) *p++ = ch;
351*2496Sdlw 			else goto newone;
352*2496Sdlw 		}
353*2496Sdlw 		else
354*2496Sdlw 		{	(*ungetn)(ch,cf);
355*2496Sdlw 			*p = '\0';
356*2496Sdlw 			return(OK);
357*2496Sdlw 		}
358*2496Sdlw 	}
359*2496Sdlw }
360*2496Sdlw 
361*2496Sdlw t_sep()
362*2496Sdlw {
363*2496Sdlw 	int ch;
364*2496Sdlw 	while(isblnk(GETC(ch)));
365*2496Sdlw 	if(leof) return(EOF);
366*2496Sdlw 	if(ch=='/')
367*2496Sdlw 	{	lquit = YES;
368*2496Sdlw 		(*ungetn)(ch,cf);
369*2496Sdlw 		return(OK);
370*2496Sdlw 	}
371*2496Sdlw 	if(issep(ch)) while(isblnk(GETC(ch)));
372*2496Sdlw 	if(leof) return(EOF);
373*2496Sdlw 	(*ungetn)(ch,cf);
374*2496Sdlw 	return(OK);
375*2496Sdlw }
376