xref: /csrg-svn/usr.bin/f77/libI77/rsnmle.c (revision 24099)
1*24099Sjerry /*
2*24099Sjerry  * Copyright (c) 1980 Regents of the University of California.
3*24099Sjerry  * All rights reserved.  The Berkeley software License Agreement
4*24099Sjerry  * specifies the terms and conditions for redistribution.
5*24099Sjerry  *
6*24099Sjerry  *	@(#)rsnmle.c	1.1	07/30/85
7*24099Sjerry  */
8*24099Sjerry 
9*24099Sjerry /*
10*24099Sjerry  *		name-list read
11*24099Sjerry  */
12*24099Sjerry 
13*24099Sjerry #include "fio.h"
14*24099Sjerry #include "lio.h"
15*24099Sjerry #include "nmlio.h"
16*24099Sjerry #include <ctype.h>
17*24099Sjerry 
18*24099Sjerry LOCAL char nml_rd[] = "namelist read";
19*24099Sjerry 
20*24099Sjerry static int ch;
21*24099Sjerry 
22*24099Sjerry #define SP 1
23*24099Sjerry #define B  2
24*24099Sjerry #define AP 4
25*24099Sjerry #define EX 8
26*24099Sjerry #define isblnk(x)	(ltab[x+1]&B)	/* space, tab, newline */
27*24099Sjerry #define issep(x)	(ltab[x+1]&SP)	/* space, tab, newline, comma */
28*24099Sjerry #define isapos(x)	(ltab[x+1]&AP)	/* apost., quote mark */
29*24099Sjerry #define isexp(x)	(ltab[x+1]&EX)	/* d, e, D, E */
30*24099Sjerry 
31*24099Sjerry #define GETC(x) (x=t_getc())
32*24099Sjerry #define UNGETC() ungetc(ch,cf)
33*24099Sjerry 
34*24099Sjerry LOCAL char *lchar;
35*24099Sjerry LOCAL double lx,ly;
36*24099Sjerry LOCAL int ltype;
37*24099Sjerry int t_getc(), ungetc();
38*24099Sjerry 
39*24099Sjerry LOCAL char ltab[128+1] =
40*24099Sjerry {			0, 		/* offset one for EOF */
41*24099Sjerry /*   0- 15 */	0,0,0,0,0,0,0,0,0,SP|B,SP|B,0,0,0,0,0, /* TAB,NEWLINE */
42*24099Sjerry /*  16- 31 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
43*24099Sjerry /*  32- 47 */	SP|B,0,AP,0,0,0,0,AP,0,0,0,0,SP,0,0,0, /* space,",',comma */
44*24099Sjerry /*  48- 63 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
45*24099Sjerry /*  64- 79 */	0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,	/* D,E */
46*24099Sjerry /*  80- 95 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
47*24099Sjerry /*  96-111 */	0,0,0,0,EX,EX,0,0,0,0,0,0,0,0,0,0,	/* d,e */
48*24099Sjerry /* 112-127 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
49*24099Sjerry };
50*24099Sjerry 
51*24099Sjerry s_rsne(a) namelist_arglist *a;
52*24099Sjerry {
53*24099Sjerry 	int n, first;
54*24099Sjerry 	struct namelistentry *entry;
55*24099Sjerry 	int nelem, vlen, vtype;
56*24099Sjerry 	char *nmlist_nm, *addr;
57*24099Sjerry 	char var_name[VL+1];
58*24099Sjerry 
59*24099Sjerry 	reading = YES;
60*24099Sjerry 	formatted = NAMELIST;
61*24099Sjerry 	fmtbuf = "ext namelist io";
62*24099Sjerry 	if(n=c_le(a,READ)) return(n);
63*24099Sjerry 	l_first = YES;
64*24099Sjerry 	getn = t_getc;
65*24099Sjerry 	ungetn = ungetc;
66*24099Sjerry 	leof = curunit->uend;
67*24099Sjerry 	lcount = 0;
68*24099Sjerry 	ltype = NULL;
69*24099Sjerry 	if(curunit->uwrt && ! nowreading(curunit)) err(errflag, errno, nml_rd)
70*24099Sjerry 
71*24099Sjerry 	/* look for " &namelistname " */
72*24099Sjerry 	nmlist_nm = a->namelist->namelistname;
73*24099Sjerry 	while(isblnk(GETC(ch))) ;
74*24099Sjerry 	/* check for "&end" (like IBM) or "$end" (like DEC) */
75*24099Sjerry 	if(ch != '&' && ch != '$') goto rderr;
76*24099Sjerry 	/* save it - write out using the same character as used on input */
77*24099Sjerry 	namelistkey_ = ch;
78*24099Sjerry 	while( *nmlist_nm )
79*24099Sjerry 		if( GETC(ch) != *nmlist_nm++ ) goto rderr;
80*24099Sjerry 	if(!isblnk(GETC(ch))) goto rderr;
81*24099Sjerry 	while(isblnk(GETC(ch))) ;
82*24099Sjerry 	if(leof) goto rderr;
83*24099Sjerry 	UNGETC();
84*24099Sjerry 
85*24099Sjerry 	while( GETC(ch) != namelistkey_ )
86*24099Sjerry 	{
87*24099Sjerry 	    /* get variable name */
88*24099Sjerry 	    if(rd_name(var_name)) goto rderr;
89*24099Sjerry 	    entry = a->namelist->names;
90*24099Sjerry 	    /* loop through namelist entries looking for this variable name */
91*24099Sjerry 	    while( entry->varname[0] != 0 )
92*24099Sjerry 	    {
93*24099Sjerry 		if( strcmp(entry->varname, var_name) == 0 ) goto got_name;
94*24099Sjerry 		entry++;
95*24099Sjerry 	    }
96*24099Sjerry 	    goto rderr;
97*24099Sjerry got_name:
98*24099Sjerry 	    if( n= get_pars( entry, &addr, &nelem, &vlen, &vtype ))
99*24099Sjerry 							goto rderr_n;
100*24099Sjerry 		/*debug*/printf("var=%s, nelem=%x,vlen=%x,vtype=%x\n",
101*24099Sjerry 		/*debug*/	var_name, nelem, vlen, vtype);
102*24099Sjerry 	    while(isblnk(GETC(ch))) ;
103*24099Sjerry 	    if(ch != '=') goto rderr;
104*24099Sjerry 	    if(n = l_read( nelem, addr, vlen, vtype ))
105*24099Sjerry 		{
106*24099Sjerry rderr_n:
107*24099Sjerry 			err(n<0?endflag:errflag,n,nml_rd)
108*24099Sjerry 		}
109*24099Sjerry 	    while(isblnk(GETC(ch)));
110*24099Sjerry 	    if(ch == ',') while(isblnk(GETC(ch)));
111*24099Sjerry 	    UNGETC();
112*24099Sjerry 	    if(leof) goto rderr;
113*24099Sjerry 	}
114*24099Sjerry 	printf("at end record looking for 'end'\n");
115*24099Sjerry 	/* check for 'end' after '&' or '$'*/
116*24099Sjerry 	if(GETC(ch)!='e' || GETC(ch)!='n' || GETC(ch)!='d' )
117*24099Sjerry 		goto rderr;
118*24099Sjerry 	/* flush to next input record */
119*24099Sjerry flush:
120*24099Sjerry 	while(GETC(ch) != '\n' && ch != EOF);
121*24099Sjerry 	return(ch == EOF ? EOF : OK);
122*24099Sjerry 
123*24099Sjerry rderr:
124*24099Sjerry 	if(leof)
125*24099Sjerry 		err(endflag,EOF,nml_rd)
126*24099Sjerry 	else
127*24099Sjerry 		err(errflag,F_ERNMLIST,nml_rd)
128*24099Sjerry 	goto flush;
129*24099Sjerry }
130*24099Sjerry 
131*24099Sjerry #define MAXSUBS 7
132*24099Sjerry 
133*24099Sjerry LOCAL
134*24099Sjerry get_pars( entry, addr, nelem, vlen, vtype )
135*24099Sjerry struct namelistentry *entry;
136*24099Sjerry char	**addr;		/* beginning address to read into */
137*24099Sjerry int	*nelem,		/* number of elements to read */
138*24099Sjerry 	*vlen,		/* length of elements */
139*24099Sjerry 	*vtype;		/* type of elements */
140*24099Sjerry {
141*24099Sjerry 	int	offset, i, n,
142*24099Sjerry 		*dimptr,	/* points to dimensioning info */
143*24099Sjerry 		ndim,		/* number of dimensions */
144*24099Sjerry 		baseoffset,	/* offset of corner element */
145*24099Sjerry 		*span,		/* subscript span for each dimension */
146*24099Sjerry 		subs[MAXSUBS],	/* actual subscripts */
147*24099Sjerry 		subcnt = -1;	/* number of actual subscripts */
148*24099Sjerry 
149*24099Sjerry 
150*24099Sjerry 	/* get element size and base address */
151*24099Sjerry 	*vlen = entry->typelen;
152*24099Sjerry 	*addr = entry->varaddr;
153*24099Sjerry 
154*24099Sjerry 	/* get type */
155*24099Sjerry 	switch ( *vtype = entry->type ) {
156*24099Sjerry 		case TYSHORT:
157*24099Sjerry 		case TYLONG:
158*24099Sjerry 		case TYREAL:
159*24099Sjerry 		case TYDREAL:
160*24099Sjerry 		case TYCOMPLEX:
161*24099Sjerry 		case TYDCOMPLEX:
162*24099Sjerry 		case TYLOGICAL:
163*24099Sjerry 		case TYCHAR:
164*24099Sjerry 			break;
165*24099Sjerry 		default:
166*24099Sjerry 		    fatal(F_ERSYS,"unknown type in wsnmle");
167*24099Sjerry 	}
168*24099Sjerry 
169*24099Sjerry 	/* get number of elements */
170*24099Sjerry 	dimptr = entry->dimp;
171*24099Sjerry 	if( dimptr==NULL )
172*24099Sjerry 	{		/* scalar */
173*24099Sjerry 		*nelem = 1;
174*24099Sjerry 		return(OK);
175*24099Sjerry 	}
176*24099Sjerry 
177*24099Sjerry 	if( GETC(ch) != '(' )
178*24099Sjerry 	{		/* entire array */
179*24099Sjerry 		*nelem = dimptr[1];
180*24099Sjerry 		UNGETC();
181*24099Sjerry 		return(OK);
182*24099Sjerry 	}
183*24099Sjerry 
184*24099Sjerry 	/* get element length, number of dimensions, base, span vector */
185*24099Sjerry 	ndim = dimptr[0];
186*24099Sjerry 	if(ndim<=0 || ndim>MAXSUBS) fatal(F_ERSYS,"illegal dimensions");
187*24099Sjerry 	baseoffset = dimptr[2];
188*24099Sjerry 	span = dimptr+3;
189*24099Sjerry 
190*24099Sjerry 	/* get subscripts from input data */
191*24099Sjerry 	while(ch!=')') {
192*24099Sjerry 		if( ++subcnt > MAXSUBS-1 ) return F_ERNMLIST;
193*24099Sjerry 		if(n=get_int(&subs[subcnt])) return n;
194*24099Sjerry 		GETC(ch);
195*24099Sjerry 		if(leof) return EOF;
196*24099Sjerry 		if(ch != ',' && ch != ')') return F_ERNMLIST;
197*24099Sjerry 	}
198*24099Sjerry 	if( ++subcnt != ndim ) return F_ERNMLIST;
199*24099Sjerry 
200*24099Sjerry 	offset = subs[ndim-1];
201*24099Sjerry 	for( i = ndim-2; i>=0; i-- )
202*24099Sjerry 		offset = subs[i] + span[i]*offset;
203*24099Sjerry 	offset -= baseoffset;
204*24099Sjerry 	*nelem = dimptr[1] - offset;
205*24099Sjerry 	printf("get_par: *nelem, dimptr[1], offset, baseoffset = %d %d %d %d\n",
206*24099Sjerry 			*nelem, dimptr[1], offset, baseoffset );
207*24099Sjerry 	if( offset < 0 || offset >= dimptr[1] )
208*24099Sjerry 		return F_ERNMLIST;
209*24099Sjerry 	*addr = *addr + (*vlen)*offset;
210*24099Sjerry 	return OK;
211*24099Sjerry }
212*24099Sjerry 
213*24099Sjerry LOCAL
214*24099Sjerry get_int(subval)
215*24099Sjerry int *subval;
216*24099Sjerry {
217*24099Sjerry 	int sign=0, value=0, cnt=0;
218*24099Sjerry 
219*24099Sjerry 	/* look for sign */
220*24099Sjerry 	if(GETC(ch) == '-') sign = -1;
221*24099Sjerry 	else if(ch == '+') ;
222*24099Sjerry 	else UNGETC();
223*24099Sjerry 	if(ch == EOF) return(EOF);
224*24099Sjerry 
225*24099Sjerry 	while(isdigit(GETC(ch)))
226*24099Sjerry 	{
227*24099Sjerry 		value = 10*value + ch-'0';
228*24099Sjerry 		cnt++;
229*24099Sjerry 	}
230*24099Sjerry 	UNGETC();
231*24099Sjerry 	if(ch == 'EOF') return EOF;
232*24099Sjerry 	if(cnt == 0 ) return F_ERNMLIST;
233*24099Sjerry 	if(sign== -1) value = -value;
234*24099Sjerry 	*subval = value;
235*24099Sjerry 	return OK;
236*24099Sjerry }
237*24099Sjerry 
238*24099Sjerry LOCAL
239*24099Sjerry rd_name(ptr)
240*24099Sjerry char *ptr;
241*24099Sjerry {
242*24099Sjerry 	/* read a variable name from the input stream */
243*24099Sjerry 	char *init = ptr-1;
244*24099Sjerry 
245*24099Sjerry 	if(!isalpha(ch)) {
246*24099Sjerry 		UNGETC();
247*24099Sjerry 		return(ERROR);
248*24099Sjerry 	}
249*24099Sjerry 	*ptr++ = ch;
250*24099Sjerry 	while(isalnum(GETC(ch)))
251*24099Sjerry 	{
252*24099Sjerry 		if(ptr-init > VL ) return(ERROR);
253*24099Sjerry 		*ptr++ = ch;
254*24099Sjerry 	}
255*24099Sjerry 	*ptr = '\0';
256*24099Sjerry 	UNGETC();
257*24099Sjerry 	return(OK);
258*24099Sjerry }
259*24099Sjerry 
260*24099Sjerry LOCAL
261*24099Sjerry t_getc()
262*24099Sjerry {	int ch;
263*24099Sjerry 	static newline = YES;
264*24099Sjerry rd:
265*24099Sjerry 	if(curunit->uend) {
266*24099Sjerry 		leof = EOF;
267*24099Sjerry 		return(EOF);
268*24099Sjerry 	}
269*24099Sjerry 	if((ch=getc(cf))!=EOF)
270*24099Sjerry 	{
271*24099Sjerry 		if(ch == '\n') newline = YES;
272*24099Sjerry 		else if(newline==YES)
273*24099Sjerry 		{	/* skip first character on each line for namelist */
274*24099Sjerry 			newline = NO;
275*24099Sjerry 			goto rd;
276*24099Sjerry 		}
277*24099Sjerry 		return(ch);
278*24099Sjerry 	}
279*24099Sjerry 	if(feof(cf))
280*24099Sjerry 	{	curunit->uend = YES;
281*24099Sjerry 		leof = EOF;
282*24099Sjerry 	}
283*24099Sjerry 	else clearerr(cf);
284*24099Sjerry 	return(EOF);
285*24099Sjerry }
286*24099Sjerry 
287*24099Sjerry LOCAL
288*24099Sjerry l_read(number,ptr,len,type) ftnint number,type; flex *ptr; ftnlen len;
289*24099Sjerry {	int i,n;
290*24099Sjerry 	double *yy;
291*24099Sjerry 	float *xx;
292*24099Sjerry 	for(i=0;i<number;i++)
293*24099Sjerry 	{
294*24099Sjerry 		if(leof) return EOF;
295*24099Sjerry 		if(l_first)
296*24099Sjerry 		{	l_first = NO;
297*24099Sjerry 			while(isblnk(GETC(ch)));	/* skip blanks */
298*24099Sjerry 			UNGETC();
299*24099Sjerry 		}
300*24099Sjerry 		else if(lcount==0)		/* repeat count == 0 ? */
301*24099Sjerry 		{	ERRNM(t_sep());  /* look for non-blank, allow 1 comma */
302*24099Sjerry 		}
303*24099Sjerry 		if(!lr_comm())
304*24099Sjerry 		{
305*24099Sjerry 			while(isblnk(GETC(ch)));
306*24099Sjerry 			UNGETC();
307*24099Sjerry 			if(ch == namelistkey_ ) return(OK);
308*24099Sjerry 
309*24099Sjerry 			switch((int)type)
310*24099Sjerry 			{
311*24099Sjerry 			case TYSHORT:
312*24099Sjerry 			case TYLONG:
313*24099Sjerry 			case TYREAL:
314*24099Sjerry 			case TYDREAL:
315*24099Sjerry 				ERRNM(l_R(1));
316*24099Sjerry 				break;
317*24099Sjerry 			case TYCOMPLEX:
318*24099Sjerry 			case TYDCOMPLEX:
319*24099Sjerry 				ERRNM(l_C());
320*24099Sjerry 				break;
321*24099Sjerry 			case TYLOGICAL:
322*24099Sjerry 				ERRNM(l_L());
323*24099Sjerry 				break;
324*24099Sjerry 			case TYCHAR:
325*24099Sjerry 				ERRNM(l_CHAR());
326*24099Sjerry 				break;
327*24099Sjerry 			}
328*24099Sjerry 		}
329*24099Sjerry 
330*24099Sjerry  		/* peek at next character;should be separator or namelistkey_ */
331*24099Sjerry  		GETC(ch); UNGETC();
332*24099Sjerry 		printf("l_read: peek at %c %x\n", ch, ch);
333*24099Sjerry 		if(!issep(ch) && (ch != namelistkey_))
334*24099Sjerry 			return( leof?EOF:F_ERNMLIST );
335*24099Sjerry 
336*24099Sjerry 		if(ltype) switch((int)type)
337*24099Sjerry 		{
338*24099Sjerry 		case TYSHORT:
339*24099Sjerry 			ptr->flshort=lx;
340*24099Sjerry 			break;
341*24099Sjerry 		case TYLOGICAL:
342*24099Sjerry 			if(len == sizeof(short))
343*24099Sjerry 				ptr->flshort = lx;
344*24099Sjerry 			else
345*24099Sjerry 				ptr->flint = lx;
346*24099Sjerry 			break;
347*24099Sjerry 		case TYLONG:
348*24099Sjerry 			ptr->flint=lx;
349*24099Sjerry 			break;
350*24099Sjerry 		case TYREAL:
351*24099Sjerry 			ptr->flreal=lx;
352*24099Sjerry 			break;
353*24099Sjerry 		case TYDREAL:
354*24099Sjerry 			ptr->fldouble=lx;
355*24099Sjerry 			break;
356*24099Sjerry 		case TYCOMPLEX:
357*24099Sjerry 			xx=(float *)ptr;
358*24099Sjerry 			*xx++ = ly;
359*24099Sjerry 			*xx = lx;
360*24099Sjerry 			break;
361*24099Sjerry 		case TYDCOMPLEX:
362*24099Sjerry 			yy=(double *)ptr;
363*24099Sjerry 			*yy++ = ly;
364*24099Sjerry 			*yy = lx;
365*24099Sjerry 			break;
366*24099Sjerry 		case TYCHAR:
367*24099Sjerry 			b_char(lchar,(char *)ptr,len);
368*24099Sjerry 			break;
369*24099Sjerry 		}
370*24099Sjerry 		if(lcount>0) lcount--;
371*24099Sjerry 		ptr = (flex *)((char *)ptr + len);
372*24099Sjerry 	}
373*24099Sjerry 	if(lcount>0) return F_ERNMLIST;
374*24099Sjerry 	return(OK);
375*24099Sjerry }
376*24099Sjerry 
377*24099Sjerry LOCAL
378*24099Sjerry lr_comm()
379*24099Sjerry {	int ch;
380*24099Sjerry 	if(lcount) return(lcount);
381*24099Sjerry 	ltype=NULL;
382*24099Sjerry 	while(isblnk(GETC(ch)));
383*24099Sjerry 	UNGETC();
384*24099Sjerry 	if(ch==',')
385*24099Sjerry 	{	lcount=1;
386*24099Sjerry 		return(lcount);
387*24099Sjerry 	}
388*24099Sjerry 	return(OK);
389*24099Sjerry }
390*24099Sjerry 
391*24099Sjerry LOCAL
392*24099Sjerry get_repet()
393*24099Sjerry {	char ch;
394*24099Sjerry 	double lc;
395*24099Sjerry 	if(isdigit(GETC(ch)))
396*24099Sjerry 	{	UNGETC();
397*24099Sjerry 		rd_int(&lc);
398*24099Sjerry 		lcount = (int)lc;
399*24099Sjerry 		if(GETC(ch)!='*')
400*24099Sjerry 			if(leof) return(EOF);
401*24099Sjerry 			else return(F_ERREPT);
402*24099Sjerry 	}
403*24099Sjerry 	else
404*24099Sjerry 	{	lcount = 1;
405*24099Sjerry 		UNGETC();
406*24099Sjerry 	}
407*24099Sjerry 	return(OK);
408*24099Sjerry }
409*24099Sjerry 
410*24099Sjerry LOCAL
411*24099Sjerry l_R(flg) int flg;
412*24099Sjerry {	double a,b,c,d;
413*24099Sjerry 	int da,db,dc,dd;
414*24099Sjerry 	int i,ch,sign=0;
415*24099Sjerry 	a=b=c=d=0;
416*24099Sjerry 	da=db=dc=dd=0;
417*24099Sjerry 
418*24099Sjerry 	if( flg )		/* real */
419*24099Sjerry 	{
420*24099Sjerry 		da=rd_int(&a);	/* repeat count ? */
421*24099Sjerry 		if(GETC(ch)=='*')
422*24099Sjerry 		{
423*24099Sjerry 			if (a <= 0.) return(F_ERNREP);
424*24099Sjerry 			lcount=(int)a;
425*24099Sjerry 			db=rd_int(&b);	/* whole part of number */
426*24099Sjerry 		}
427*24099Sjerry 		else
428*24099Sjerry 		{	UNGETC();
429*24099Sjerry 			db=da;
430*24099Sjerry 			b=a;
431*24099Sjerry 			lcount=1;
432*24099Sjerry 		}
433*24099Sjerry 	}
434*24099Sjerry 	else		   /* complex */
435*24099Sjerry 	{
436*24099Sjerry 		db=rd_int(&b);
437*24099Sjerry 	}
438*24099Sjerry 
439*24099Sjerry 	if(GETC(ch)=='.' && isdigit(GETC(ch)))
440*24099Sjerry 	{	UNGETC();
441*24099Sjerry 		dc=rd_int(&c);	/* fractional part of number */
442*24099Sjerry 	}
443*24099Sjerry 	else
444*24099Sjerry 	{	UNGETC();
445*24099Sjerry 		dc=0;
446*24099Sjerry 		c=0.;
447*24099Sjerry 	}
448*24099Sjerry 	if(isexp(GETC(ch)))
449*24099Sjerry 		dd=rd_int(&d);	/* exponent */
450*24099Sjerry 	else if (ch == '+' || ch == '-')
451*24099Sjerry 	{	UNGETC();
452*24099Sjerry 		dd=rd_int(&d);
453*24099Sjerry 	}
454*24099Sjerry 	else
455*24099Sjerry 	{	UNGETC();
456*24099Sjerry 		dd=0;
457*24099Sjerry 	}
458*24099Sjerry 	if(db<0 || b<0)
459*24099Sjerry 	{	sign=1;
460*24099Sjerry 		b = -b;
461*24099Sjerry 	}
462*24099Sjerry 	for(i=0;i<dc;i++) c/=10.;
463*24099Sjerry 	b=b+c;
464*24099Sjerry 	if (dd > 0)
465*24099Sjerry 	{	for(i=0;i<d;i++) b *= 10.;
466*24099Sjerry 		for(i=0;i< -d;i++) b /= 10.;
467*24099Sjerry 	}
468*24099Sjerry 	lx=sign?-b:b;
469*24099Sjerry 	ltype=TYLONG;
470*24099Sjerry 	return(OK);
471*24099Sjerry }
472*24099Sjerry 
473*24099Sjerry LOCAL
474*24099Sjerry rd_int(x) double *x;
475*24099Sjerry {	int ch,sign=0,i=0;
476*24099Sjerry 	double y=0.0;
477*24099Sjerry 	if(GETC(ch)=='-') sign = -1;
478*24099Sjerry 	else if(ch=='+') sign=0;
479*24099Sjerry 	else UNGETC();
480*24099Sjerry 	while(isdigit(GETC(ch)))
481*24099Sjerry 	{	i++;
482*24099Sjerry 		y=10*y + ch-'0';
483*24099Sjerry 	}
484*24099Sjerry 	UNGETC();
485*24099Sjerry 	if(sign) y = -y;
486*24099Sjerry 	*x = y;
487*24099Sjerry 	return(y==0.0?sign:i); /* 0:[+]&&y==0, -1:-&&y==0, >0:#digits&&y!=0 */
488*24099Sjerry }
489*24099Sjerry 
490*24099Sjerry LOCAL
491*24099Sjerry l_C()
492*24099Sjerry {	int ch,n;
493*24099Sjerry 	if(n=get_repet()) return(n);		/* get repeat count */
494*24099Sjerry 	if(GETC(ch)!='(') err(errflag,F_ERNMLIST,"no (")
495*24099Sjerry 	while(isblnk(GETC(ch)));
496*24099Sjerry 	UNGETC();
497*24099Sjerry 	l_R(0);		/* get real part */
498*24099Sjerry 	ly = lx;
499*24099Sjerry 	if(t_sep()) return(EOF);
500*24099Sjerry 	l_R(0);		/* get imag part */
501*24099Sjerry 	while(isblnk(GETC(ch)));
502*24099Sjerry 	if(ch!=')') err(errflag,F_ERNMLIST,"no )")
503*24099Sjerry 	ltype = TYCOMPLEX;
504*24099Sjerry 	return(OK);
505*24099Sjerry }
506*24099Sjerry 
507*24099Sjerry LOCAL
508*24099Sjerry l_L()
509*24099Sjerry {
510*24099Sjerry 	int ch,n;
511*24099Sjerry 	if(n=get_repet()) return(n);		/* get repeat count */
512*24099Sjerry 	if(GETC(ch)=='.') GETC(ch);
513*24099Sjerry 	switch(ch)
514*24099Sjerry 	{
515*24099Sjerry 	case 't':
516*24099Sjerry 	case 'T':
517*24099Sjerry 		lx=1;
518*24099Sjerry 		break;
519*24099Sjerry 	case 'f':
520*24099Sjerry 	case 'F':
521*24099Sjerry 		lx=0;
522*24099Sjerry 		break;
523*24099Sjerry 	default:
524*24099Sjerry 		if(issep(ch))
525*24099Sjerry 		{	UNGETC();
526*24099Sjerry 			lx=0;
527*24099Sjerry 			return(OK);
528*24099Sjerry 		}
529*24099Sjerry 		else if(ch==EOF) return(EOF);
530*24099Sjerry 		else	err(errflag,F_ERNMLIST,"logical not T or F");
531*24099Sjerry 	}
532*24099Sjerry 	ltype=TYLOGICAL;
533*24099Sjerry 	while(!issep(GETC(ch)) && ch!=EOF) ;
534*24099Sjerry 	UNGETC();
535*24099Sjerry 	if(ch == EOF ) return(EOF);
536*24099Sjerry 	return(OK);
537*24099Sjerry }
538*24099Sjerry 
539*24099Sjerry #define BUFSIZE	128
540*24099Sjerry LOCAL
541*24099Sjerry l_CHAR()
542*24099Sjerry {	int ch,size,i,n;
543*24099Sjerry 	char quote,*p;
544*24099Sjerry 	if(n=get_repet()) return(n);		/* get repeat count */
545*24099Sjerry 	if(isapos(GETC(ch))) quote=ch;
546*24099Sjerry 	else if(ch == EOF) return EOF;
547*24099Sjerry 	else return F_ERNMLIST;
548*24099Sjerry 	ltype=TYCHAR;
549*24099Sjerry 	if(lchar!=NULL) free(lchar);
550*24099Sjerry 	size=BUFSIZE-1;
551*24099Sjerry 	p=lchar=(char *)malloc(BUFSIZE);
552*24099Sjerry 	if(lchar==NULL) return (F_ERSPACE);
553*24099Sjerry 	for(i=0;;)
554*24099Sjerry 	{	while( GETC(ch)!=quote && ch!='\n' && ch!=EOF && ++i<size )
555*24099Sjerry 				*p++ = ch;
556*24099Sjerry 		if(i==size)
557*24099Sjerry 		{
558*24099Sjerry 		newone:
559*24099Sjerry 			size += BUFSIZE;
560*24099Sjerry 			lchar=(char *)realloc(lchar, size+1);
561*24099Sjerry 			if(lchar==NULL) return( F_ERSPACE );
562*24099Sjerry 			p=lchar+i-1;
563*24099Sjerry 			*p++ = ch;
564*24099Sjerry 		}
565*24099Sjerry 		else if(ch==EOF) return(EOF);
566*24099Sjerry 		else if(ch=='\n')
567*24099Sjerry 		{	if(*(p-1) == '\\') *(p-1) = ch;
568*24099Sjerry 		}
569*24099Sjerry 		else if(GETC(ch)==quote)
570*24099Sjerry 		{	if(++i<size) *p++ = ch;
571*24099Sjerry 			else goto newone;
572*24099Sjerry 		}
573*24099Sjerry 		else
574*24099Sjerry 		{	UNGETC();
575*24099Sjerry 			*p = '\0';
576*24099Sjerry 			return(OK);
577*24099Sjerry 		}
578*24099Sjerry 	}
579*24099Sjerry }
580*24099Sjerry 
581*24099Sjerry LOCAL
582*24099Sjerry t_sep()
583*24099Sjerry {
584*24099Sjerry 	int ch;
585*24099Sjerry 	while(isblnk(GETC(ch)));
586*24099Sjerry 	if(leof) return(EOF);
587*24099Sjerry 	if(issep(ch)) while(isblnk(GETC(ch)));
588*24099Sjerry 	if(leof) return(EOF);
589*24099Sjerry 	UNGETC();
590*24099Sjerry 	return(OK);
591*24099Sjerry }
592