xref: /csrg-svn/usr.bin/f77/libI77/lread.c (revision 24101)
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