526 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			526 lines
		
	
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "f2c.h"
 | 
						|
#include "fio.h"
 | 
						|
#include "fmt.h"
 | 
						|
#include "lio.h"
 | 
						|
#include "ctype.h"
 | 
						|
#include "fp.h"
 | 
						|
 | 
						|
extern char *fmtbuf;
 | 
						|
extern char *malloc(), *realloc();
 | 
						|
int (*lioproc)(), (*l_getc)(), (*l_ungetc)();
 | 
						|
int l_eof;
 | 
						|
 | 
						|
#define isblnk(x) (ltab[x+1]&B)
 | 
						|
#define issep(x) (ltab[x+1]&SX)
 | 
						|
#define isapos(x) (ltab[x+1]&AX)
 | 
						|
#define isexp(x) (ltab[x+1]&EX)
 | 
						|
#define issign(x) (ltab[x+1]&SG)
 | 
						|
#define iswhit(x) (ltab[x+1]&WH)
 | 
						|
#define SX 1
 | 
						|
#define B 2
 | 
						|
#define AX 4
 | 
						|
#define EX 8
 | 
						|
#define SG 16
 | 
						|
#define WH 32
 | 
						|
char ltab[128+1] = {	/* offset one for EOF */
 | 
						|
	0,
 | 
						|
	0,0,AX,0,0,0,0,0,0,WH|B,SX|WH,0,0,0,0,0,
 | 
						|
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
						|
	SX|B|WH,0,AX,0,0,0,0,AX,0,0,0,SG,SX,SG,0,SX,
 | 
						|
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
						|
	0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,
 | 
						|
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 | 
						|
	AX,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,
 | 
						|
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 | 
						|
};
 | 
						|
 | 
						|
t_getc()
 | 
						|
{	int ch;
 | 
						|
	if(curunit->uend) return(EOF);
 | 
						|
	if((ch=getc(cf))!=EOF) return(ch);
 | 
						|
	if(feof(cf))
 | 
						|
		l_eof = curunit->uend = 1;
 | 
						|
	return(EOF);
 | 
						|
}
 | 
						|
integer e_rsle()
 | 
						|
{
 | 
						|
	int ch;
 | 
						|
	if(curunit->uend) return(0);
 | 
						|
	while((ch=t_getc())!='\n' && ch!=EOF);
 | 
						|
	return(0);
 | 
						|
}
 | 
						|
 | 
						|
flag lquit;
 | 
						|
int lcount,ltype;
 | 
						|
char *lchar;
 | 
						|
double lx,ly;
 | 
						|
#define ERR(x) if(n=(x)) return(n)
 | 
						|
#define GETC(x) (x=(*l_getc)())
 | 
						|
#define Ungetc(x,y) (*l_ungetc)(x,y)
 | 
						|
 | 
						|
l_read(number,ptr,len,type) ftnint *number,type; char *ptr; ftnlen len;
 | 
						|
{
 | 
						|
#define Ptr ((flex *)ptr)
 | 
						|
	int i,n,ch;
 | 
						|
	doublereal *yy;
 | 
						|
	real *xx;
 | 
						|
	for(i=0;i<*number;i++)
 | 
						|
	{
 | 
						|
		if(lquit) return(0);
 | 
						|
		if(l_eof)
 | 
						|
			err(elist->ciend, EOF, "list in")
 | 
						|
		if(lcount == 0) {
 | 
						|
			ltype = 0;
 | 
						|
			for(;;)  {
 | 
						|
				GETC(ch);
 | 
						|
				switch(ch) {
 | 
						|
				case EOF:
 | 
						|
					goto loopend;
 | 
						|
				case ' ':
 | 
						|
				case '\t':
 | 
						|
				case '\n':
 | 
						|
					continue;
 | 
						|
				case '/':
 | 
						|
					lquit = 1;
 | 
						|
					goto loopend;
 | 
						|
				case ',':
 | 
						|
					lcount = 1;
 | 
						|
					goto loopend;
 | 
						|
				default:
 | 
						|
					(void) Ungetc(ch, cf);
 | 
						|
					goto rddata;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	rddata:
 | 
						|
		switch((int)type)
 | 
						|
		{
 | 
						|
		case TYSHORT:
 | 
						|
		case TYLONG:
 | 
						|
		case TYREAL:
 | 
						|
		case TYDREAL:
 | 
						|
			ERR(l_R(0));
 | 
						|
			break;
 | 
						|
		case TYCOMPLEX:
 | 
						|
		case TYDCOMPLEX:
 | 
						|
			ERR(l_C());
 | 
						|
			break;
 | 
						|
		case TYLOGICAL:
 | 
						|
			ERR(l_L());
 | 
						|
			break;
 | 
						|
		case TYCHAR:
 | 
						|
			ERR(l_CHAR());
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	while (GETC(ch) == ' ' || ch == '\t');
 | 
						|
	if (ch != ',')
 | 
						|
		Ungetc(ch,cf);
 | 
						|
	loopend:
 | 
						|
		if(lquit) return(0);
 | 
						|
		if(cf) {
 | 
						|
			if (feof(cf))
 | 
						|
				err(elist->ciend,(EOF),"list in")
 | 
						|
			else if(ferror(cf)) {
 | 
						|
				clearerr(cf);
 | 
						|
				err(elist->cierr,errno,"list in")
 | 
						|
				}
 | 
						|
			}
 | 
						|
		if(ltype==0) goto bump;
 | 
						|
		switch((int)type)
 | 
						|
		{
 | 
						|
		case TYSHORT:
 | 
						|
			Ptr->flshort=lx;
 | 
						|
			break;
 | 
						|
		case TYLOGICAL:
 | 
						|
		case TYLONG:
 | 
						|
			Ptr->flint=lx;
 | 
						|
			break;
 | 
						|
		case TYREAL:
 | 
						|
			Ptr->flreal=lx;
 | 
						|
			break;
 | 
						|
		case TYDREAL:
 | 
						|
			Ptr->fldouble=lx;
 | 
						|
			break;
 | 
						|
		case TYCOMPLEX:
 | 
						|
			xx=(real *)ptr;
 | 
						|
			*xx++ = lx;
 | 
						|
			*xx = ly;
 | 
						|
			break;
 | 
						|
		case TYDCOMPLEX:
 | 
						|
			yy=(doublereal *)ptr;
 | 
						|
			*yy++ = lx;
 | 
						|
			*yy = ly;
 | 
						|
			break;
 | 
						|
		case TYCHAR:
 | 
						|
			b_char(lchar,ptr,len);
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	bump:
 | 
						|
		if(lcount>0) lcount--;
 | 
						|
		ptr += len;
 | 
						|
	}
 | 
						|
	return(0);
 | 
						|
#undef Ptr
 | 
						|
}
 | 
						|
l_R(poststar)
 | 
						|
 int poststar;
 | 
						|
{
 | 
						|
	char s[FMAX+EXPMAXDIGS+4];
 | 
						|
	register int ch;
 | 
						|
	register char *sp, *spe, *sp1;
 | 
						|
	long e, exp;
 | 
						|
	double atof();
 | 
						|
	int havenum, se;
 | 
						|
 | 
						|
	if (!poststar) {
 | 
						|
		if (lcount > 0)
 | 
						|
			return(0);
 | 
						|
		lcount = 1;
 | 
						|
		}
 | 
						|
	ltype = 0;
 | 
						|
	exp = 0;
 | 
						|
retry:
 | 
						|
	sp1 = sp = s;
 | 
						|
	spe = sp + FMAX;
 | 
						|
	havenum = 0;
 | 
						|
 | 
						|
	switch(GETC(ch)) {
 | 
						|
		case '-': *sp++ = ch; sp1++; spe++;
 | 
						|
		case '+':
 | 
						|
			GETC(ch);
 | 
						|
		}
 | 
						|
	while(ch == '0') {
 | 
						|
		++havenum;
 | 
						|
		GETC(ch);
 | 
						|
		}
 | 
						|
	while(isdigit(ch)) {
 | 
						|
		if (sp < spe) *sp++ = ch;
 | 
						|
		else ++exp;
 | 
						|
		GETC(ch);
 | 
						|
		}
 | 
						|
	if (ch == '*' && !poststar) {
 | 
						|
		if (sp == sp1 || exp || *s == '-') {
 | 
						|
			err(elist->cierr,112,"bad repetition count")
 | 
						|
			}
 | 
						|
		poststar = 1;
 | 
						|
		*sp = 0;
 | 
						|
		lcount = atoi(s);
 | 
						|
		goto retry;
 | 
						|
		}
 | 
						|
	if (ch == '.') {
 | 
						|
		GETC(ch);
 | 
						|
		if (sp == sp1)
 | 
						|
			while(ch == '0') {
 | 
						|
				++havenum;
 | 
						|
				--exp;
 | 
						|
				GETC(ch);
 | 
						|
				}
 | 
						|
		while(isdigit(ch)) {
 | 
						|
			if (sp < spe)
 | 
						|
				{ *sp++ = ch; --exp; }
 | 
						|
			GETC(ch);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	se = 0;
 | 
						|
	if (issign(ch))
 | 
						|
		goto signonly;
 | 
						|
	if (isexp(ch)) {
 | 
						|
		GETC(ch);
 | 
						|
		if (issign(ch)) {
 | 
						|
signonly:
 | 
						|
			if (ch == '-') se = 1;
 | 
						|
			GETC(ch);
 | 
						|
			}
 | 
						|
		if (!isdigit(ch)) {
 | 
						|
bad:
 | 
						|
			err(elist->cierr,112,"exponent field")
 | 
						|
			}
 | 
						|
 | 
						|
		e = ch - '0';
 | 
						|
		while(isdigit(GETC(ch))) {
 | 
						|
			e = 10*e + ch - '0';
 | 
						|
			if (e > EXPMAX)
 | 
						|
				goto bad;
 | 
						|
			}
 | 
						|
		if (se)
 | 
						|
			exp -= e;
 | 
						|
		else
 | 
						|
			exp += e;
 | 
						|
		}
 | 
						|
	(void) Ungetc(ch, cf);
 | 
						|
	if (sp > sp1) {
 | 
						|
		++havenum;
 | 
						|
		while(*--sp == '0')
 | 
						|
			++exp;
 | 
						|
		if (exp)
 | 
						|
			sprintf(sp+1, "e%ld", exp);
 | 
						|
		else
 | 
						|
			sp[1] = 0;
 | 
						|
		lx = atof(s);
 | 
						|
		}
 | 
						|
	else
 | 
						|
		lx = 0.;
 | 
						|
	if (havenum)
 | 
						|
		ltype = TYLONG;
 | 
						|
	else
 | 
						|
		switch(ch) {
 | 
						|
			case ',':
 | 
						|
			case '/':
 | 
						|
				break;
 | 
						|
			default:
 | 
						|
				err(elist->cierr,112,"invalid number")
 | 
						|
			}
 | 
						|
	return 0;
 | 
						|
	}
 | 
						|
 | 
						|
 static int
 | 
						|
rd_count(ch)
 | 
						|
 register int ch;
 | 
						|
{
 | 
						|
	if (ch < '0' || ch > '9')
 | 
						|
		return 1;
 | 
						|
	lcount = ch - '0';
 | 
						|
	while(GETC(ch) >= '0' && ch <= '9')
 | 
						|
		lcount = 10*lcount + ch - '0';
 | 
						|
	Ungetc(ch,cf);
 | 
						|
	return 0;
 | 
						|
	}
 | 
						|
 | 
						|
l_C()
 | 
						|
{	int ch;
 | 
						|
	double lz;
 | 
						|
	if(lcount>0) return(0);
 | 
						|
	ltype=0;
 | 
						|
	GETC(ch);
 | 
						|
	if(ch!='(')
 | 
						|
	{
 | 
						|
		if (rd_count(ch))
 | 
						|
			if(!cf || !feof(cf))
 | 
						|
				err(elist->cierr,112,"complex format")
 | 
						|
			else
 | 
						|
				err(elist->cierr,(EOF),"lread");
 | 
						|
		if(GETC(ch)!='*')
 | 
						|
		{
 | 
						|
			if(!cf || !feof(cf))
 | 
						|
				err(elist->cierr,112,"no star")
 | 
						|
			else
 | 
						|
				err(elist->cierr,(EOF),"lread");
 | 
						|
		}
 | 
						|
		if(GETC(ch)!='(')
 | 
						|
		{	(void) Ungetc(ch,cf);
 | 
						|
			return(0);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
		lcount = 1;
 | 
						|
	while(iswhit(GETC(ch)));
 | 
						|
	(void) Ungetc(ch,cf);
 | 
						|
	if (ch = l_R(1))
 | 
						|
		return ch;
 | 
						|
	if (!ltype)
 | 
						|
		err(elist->cierr,112,"no real part");
 | 
						|
	lz = lx;
 | 
						|
	while(iswhit(GETC(ch)));
 | 
						|
	if(ch!=',')
 | 
						|
	{	(void) Ungetc(ch,cf);
 | 
						|
		err(elist->cierr,112,"no comma");
 | 
						|
	}
 | 
						|
	while(iswhit(GETC(ch)));
 | 
						|
	(void) Ungetc(ch,cf);
 | 
						|
	if (ch = l_R(1))
 | 
						|
		return ch;
 | 
						|
	if (!ltype)
 | 
						|
		err(elist->cierr,112,"no imaginary part");
 | 
						|
	while(iswhit(GETC(ch)));
 | 
						|
	if(ch!=')') err(elist->cierr,112,"no )");
 | 
						|
	ly = lx;
 | 
						|
	lx = lz;
 | 
						|
	return(0);
 | 
						|
}
 | 
						|
l_L()
 | 
						|
{
 | 
						|
	int ch;
 | 
						|
	if(lcount>0) return(0);
 | 
						|
	ltype=0;
 | 
						|
	GETC(ch);
 | 
						|
	if(isdigit(ch))
 | 
						|
	{
 | 
						|
		rd_count(ch);
 | 
						|
		if(GETC(ch)!='*')
 | 
						|
			if(!cf || !feof(cf))
 | 
						|
				err(elist->cierr,112,"no star")
 | 
						|
			else
 | 
						|
				err(elist->cierr,(EOF),"lread");
 | 
						|
		GETC(ch);
 | 
						|
	}
 | 
						|
	if(ch == '.') GETC(ch);
 | 
						|
	switch(ch)
 | 
						|
	{
 | 
						|
	case 't':
 | 
						|
	case 'T':
 | 
						|
		lx=1;
 | 
						|
		break;
 | 
						|
	case 'f':
 | 
						|
	case 'F':
 | 
						|
		lx=0;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		if(isblnk(ch) || issep(ch) || ch==EOF)
 | 
						|
		{	(void) Ungetc(ch,cf);
 | 
						|
			return(0);
 | 
						|
		}
 | 
						|
		else	err(elist->cierr,112,"logical");
 | 
						|
	}
 | 
						|
	ltype=TYLONG;
 | 
						|
	lcount = 1;
 | 
						|
	while(!issep(GETC(ch)) && ch!=EOF);
 | 
						|
	(void) Ungetc(ch, cf);
 | 
						|
	return(0);
 | 
						|
}
 | 
						|
#define BUFSIZE	128
 | 
						|
l_CHAR()
 | 
						|
{	int ch,size,i;
 | 
						|
	char quote,*p;
 | 
						|
	if(lcount>0) return(0);
 | 
						|
	ltype=0;
 | 
						|
	if(lchar!=NULL) free(lchar);
 | 
						|
	size=BUFSIZE;
 | 
						|
	p=lchar=malloc((unsigned int)size);
 | 
						|
	if(lchar==NULL) err(elist->cierr,113,"no space");
 | 
						|
 | 
						|
	GETC(ch);
 | 
						|
	if(isdigit(ch)) {
 | 
						|
		/* allow Fortran 8x-style unquoted string...	*/
 | 
						|
		/* either find a repetition count or the string	*/
 | 
						|
		lcount = ch - '0';
 | 
						|
		*p++ = ch;
 | 
						|
		for(i = 1;;) {
 | 
						|
			switch(GETC(ch)) {
 | 
						|
				case '*':
 | 
						|
					if (lcount == 0) {
 | 
						|
						lcount = 1;
 | 
						|
						goto noquote;
 | 
						|
						}
 | 
						|
					p = lchar;
 | 
						|
					goto have_lcount;
 | 
						|
				case ',':
 | 
						|
				case ' ':
 | 
						|
				case '\t':
 | 
						|
				case '\n':
 | 
						|
				case '/':
 | 
						|
					Ungetc(ch,cf);
 | 
						|
					/* no break */
 | 
						|
				case EOF:
 | 
						|
					lcount = 1;
 | 
						|
					ltype = TYCHAR;
 | 
						|
					return *p = 0;
 | 
						|
				}
 | 
						|
			if (!isdigit(ch)) {
 | 
						|
				lcount = 1;
 | 
						|
				goto noquote;
 | 
						|
				}
 | 
						|
			*p++ = ch;
 | 
						|
			lcount = 10*lcount + ch - '0';
 | 
						|
			if (++i == size) {
 | 
						|
				lchar = realloc(lchar,
 | 
						|
					(unsigned int)(size += BUFSIZE));
 | 
						|
				p = lchar + i;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	else	(void) Ungetc(ch,cf);
 | 
						|
 have_lcount:
 | 
						|
	if(GETC(ch)=='\'' || ch=='"') quote=ch;
 | 
						|
	else if(isblnk(ch) || (issep(ch) && ch != '\n') || ch==EOF)
 | 
						|
	{	(void) Ungetc(ch,cf);
 | 
						|
		return(0);
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		/* Fortran 8x-style unquoted string */
 | 
						|
		*p++ = ch;
 | 
						|
		for(i = 1;;) {
 | 
						|
			switch(GETC(ch)) {
 | 
						|
				case ',':
 | 
						|
				case ' ':
 | 
						|
				case '\t':
 | 
						|
				case '\n':
 | 
						|
				case '/':
 | 
						|
					Ungetc(ch,cf);
 | 
						|
					/* no break */
 | 
						|
				case EOF:
 | 
						|
					ltype = TYCHAR;
 | 
						|
					return *p = 0;
 | 
						|
				}
 | 
						|
 noquote:
 | 
						|
			*p++ = ch;
 | 
						|
			if (++i == size) {
 | 
						|
				lchar = realloc(lchar,
 | 
						|
					(unsigned int)(size += BUFSIZE));
 | 
						|
				p = lchar + i;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	ltype=TYCHAR;
 | 
						|
	for(i=0;;)
 | 
						|
	{	while(GETC(ch)!=quote && ch!='\n'
 | 
						|
			&& ch!=EOF && ++i<size) *p++ = ch;
 | 
						|
		if(i==size)
 | 
						|
		{
 | 
						|
		newone:
 | 
						|
			lchar= realloc(lchar, (unsigned int)(size += BUFSIZE));
 | 
						|
			p=lchar+i-1;
 | 
						|
			*p++ = ch;
 | 
						|
		}
 | 
						|
		else if(ch==EOF) return(EOF);
 | 
						|
		else if(ch=='\n')
 | 
						|
		{	if(*(p-1) != '\\') continue;
 | 
						|
			i--;
 | 
						|
			p--;
 | 
						|
			if(++i<size) *p++ = ch;
 | 
						|
			else goto newone;
 | 
						|
		}
 | 
						|
		else if(GETC(ch)==quote)
 | 
						|
		{	if(++i<size) *p++ = ch;
 | 
						|
			else goto newone;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{	(void) Ungetc(ch,cf);
 | 
						|
			*p = 0;
 | 
						|
			return(0);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
integer s_rsle(a) cilist *a;
 | 
						|
{
 | 
						|
	int n;
 | 
						|
	extern int ungetc();
 | 
						|
 | 
						|
	if(!init) f_init();
 | 
						|
	if(n=c_le(a)) return(n);
 | 
						|
	reading=1;
 | 
						|
	external=1;
 | 
						|
	formatted=1;
 | 
						|
	lioproc = l_read;
 | 
						|
	lquit = 0;
 | 
						|
	lcount = 0;
 | 
						|
	l_eof = 0;
 | 
						|
	if(curunit->uwrt && nowreading(curunit))
 | 
						|
		err(a->cierr,errno,"read start");
 | 
						|
	l_getc = t_getc;
 | 
						|
	l_ungetc = ungetc;
 | 
						|
	return(0);
 | 
						|
}
 | 
						|
c_le(a) cilist *a;
 | 
						|
{
 | 
						|
	fmtbuf="list io";
 | 
						|
	if(a->ciunit>=MXUNIT || a->ciunit<0)
 | 
						|
		err(a->cierr,101,"stler");
 | 
						|
	scale=recpos=0;
 | 
						|
	elist=a;
 | 
						|
	curunit = &units[a->ciunit];
 | 
						|
	if(curunit->ufd==NULL && fk_open(SEQ,FMT,a->ciunit))
 | 
						|
		err(a->cierr,102,"lio");
 | 
						|
	cf=curunit->ufd;
 | 
						|
	if(!curunit->ufmt) err(a->cierr,103,"lio")
 | 
						|
	return(0);
 | 
						|
}
 |