xref: /csrg-svn/usr.bin/f77/libI77/rdfmt.c (revision 18016)
12499Sdlw /*
2*18016Slibs char id_rdfmt[] = "@(#)rdfmt.c	1.9";
32499Sdlw  *
42499Sdlw  * formatted read routines
52499Sdlw  */
62499Sdlw 
72499Sdlw #include "fio.h"
82598Sdlw #include "format.h"
92499Sdlw 
1017968Slibs extern char *s_init;
11*18016Slibs extern int low_case[256];
1218014Slibs extern int used_data;
1317968Slibs 
142499Sdlw rd_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len;
152499Sdlw {	int n;
162499Sdlw 	if(cursor && (n=rd_mvcur())) return(n);
172499Sdlw 	switch(p->op)
182499Sdlw 	{
192499Sdlw 	case I:
202499Sdlw 	case IM:
212499Sdlw 		n = (rd_I(ptr,p->p1,len));
222499Sdlw 		break;
232499Sdlw 	case L:
242499Sdlw 		n = (rd_L(ptr,p->p1));
252499Sdlw 		break;
262499Sdlw 	case A:
2717968Slibs 		n = (rd_AW(ptr,len,len));
2817968Slibs 		break;
292499Sdlw 	case AW:
302499Sdlw 		n = (rd_AW(ptr,p->p1,len));
312499Sdlw 		break;
322499Sdlw 	case E:
332499Sdlw 	case EE:
342499Sdlw 	case D:
352499Sdlw 	case DE:
362499Sdlw 	case G:
372499Sdlw 	case GE:
382499Sdlw 	case F:
392499Sdlw 		n = (rd_F(ptr,p->p1,p->p2,len));
402499Sdlw 		break;
412499Sdlw 	default:
422598Sdlw 		return(errno=F_ERFMT);
432499Sdlw 	}
442499Sdlw 	if (n < 0)
452499Sdlw 	{
462499Sdlw 		if(feof(cf)) return(EOF);
472499Sdlw 		n = errno;
482499Sdlw 		clearerr(cf);
492499Sdlw 	}
502499Sdlw 	return(n);
512499Sdlw }
522499Sdlw 
532499Sdlw rd_ned(p,ptr) char *ptr; struct syl *p;
542499Sdlw {
552499Sdlw 	switch(p->op)
562499Sdlw 	{
573632Sdlw #ifndef	KOSHER
583632Sdlw 	case APOS:					/* NOT STANDARD F77 */
5917968Slibs 		return(rd_POS(&s_init[p->p1]));
603632Sdlw 	case H:						/* NOT STANDARD F77 */
6117968Slibs 		return(rd_H(p->p1,&s_init[p->p2]));
623632Sdlw #endif
632499Sdlw 	case SLASH:
642499Sdlw 		return((*donewrec)());
652499Sdlw 	case TR:
662499Sdlw 	case X:
672499Sdlw 		cursor += p->p1;
6812465Sdlw 		/* tab = (p->op==TR); This voids '..,tl6,1x,..' sequences */
6912465Sdlw 		tab = YES;
702499Sdlw 		return(OK);
712499Sdlw 	case T:
722499Sdlw 		if(p->p1) cursor = p->p1 - recpos - 1;
732499Sdlw #ifndef KOSHER
742499Sdlw 		else cursor = 8*p->p2 - recpos%8;	/* NOT STANDARD FORT */
752499Sdlw #endif
762499Sdlw 		tab = YES;
772499Sdlw 		return(OK);
782499Sdlw 	case TL:
792499Sdlw 		cursor -= p->p1;
8012370Sdlw 		if ((recpos + cursor) < 0) cursor = -recpos;	/* ANSI req'd */
812499Sdlw 		tab = YES;
822499Sdlw 		return(OK);
832499Sdlw 	default:
842598Sdlw 		return(errno=F_ERFMT);
852499Sdlw 	}
862499Sdlw }
872499Sdlw 
882499Sdlw rd_mvcur()
892499Sdlw {	int n;
902499Sdlw 	if(tab) return((*dotab)());
9112465Sdlw 	if (cursor < 0) return(errno=F_ERSEEK);
922499Sdlw 	while(cursor--) if((n=(*getn)()) < 0) return(n);
932499Sdlw 	return(cursor=0);
942499Sdlw }
952499Sdlw 
962499Sdlw rd_I(n,w,len) ftnlen len; uint *n;
972499Sdlw {	long x=0;
98*18016Slibs 	int i,sign=0,ch,c,sign_ok=YES;
992499Sdlw 	for(i=0;i<w;i++)
1002499Sdlw 	{
1012499Sdlw 		if((ch=(*getn)())<0) return(ch);
102*18016Slibs 		switch(ch)
1032499Sdlw 		{
1042499Sdlw 		case ',': goto done;
105*18016Slibs 		case '-': sign=1;		/* and fall thru */
106*18016Slibs 		case '+': if(sign_ok == NO) return(errno=F_ERRICHR);
107*18016Slibs 			  sign_ok = NO;
108*18016Slibs 			  break;
1092499Sdlw 		case ' ':
1102499Sdlw 			if(cblank) x *= radix;
1112499Sdlw 			break;
112*18016Slibs 		case '\n':  if(cblank) {
113*18016Slibs 				x *= radix;
114*18016Slibs 				break;
115*18016Slibs 			    } else {
116*18016Slibs 				goto done;
117*18016Slibs 			    }
1182499Sdlw 		default:
119*18016Slibs 			sign_ok = NO;
120*18016Slibs 			if( (c = ch-'0')>=0 && c<radix )
121*18016Slibs 			{	x = (x * radix) + c;
122*18016Slibs 				break;
1232499Sdlw 			}
124*18016Slibs 			else if( (c = low_case[ch]-'a'+10)>=0 && c<radix )
125*18016Slibs 			{	x = (x * radix) + c;
126*18016Slibs 				break;
1272499Sdlw 			}
12817973Slibs 			return(errno=F_ERRICHR);
1292499Sdlw 		}
1302499Sdlw 	}
1312499Sdlw done:
1322499Sdlw 	if(sign) x = -x;
1332499Sdlw 	if(len==sizeof(short)) n->is=x;
1342499Sdlw 	else n->il=x;
1352499Sdlw 	return(OK);
1362499Sdlw }
1372499Sdlw 
1382499Sdlw rd_L(n,w) ftnint *n;
1392499Sdlw {	int ch,i,v = -1;
1402499Sdlw 	for(i=0;i<w;i++)
1412499Sdlw 	{	if((ch=(*getn)()) < 0) return(ch);
142*18016Slibs 		if((ch=low_case[ch])=='t' && v==-1) v=1;
1432499Sdlw 		else if(ch=='f' && v==-1) v=0;
1442499Sdlw 		else if(ch==',') break;
1452499Sdlw 	}
1462598Sdlw 	if(v==-1) return(errno=F_ERLOGIF);
1472499Sdlw 	*n=v;
1482499Sdlw 	return(OK);
1492499Sdlw }
1502499Sdlw 
1512499Sdlw rd_F(p,w,d,len) ftnlen len; ufloat *p;
1522499Sdlw {	double x,y;
153*18016Slibs 	int i,sx,sz,ch,dot,ny,z,sawz,mode, sign_ok=YES;
1542499Sdlw 	x=y=0;
1552499Sdlw 	sawz=z=ny=dot=sx=sz=0;
156*18016Slibs 	/* modes:	0 in initial blanks,
157*18016Slibs 			2 blanks plus sign
158*18016Slibs 			3 found a digit
159*18016Slibs 	 */
160*18016Slibs 	mode = 0;
161*18016Slibs 
1622499Sdlw 	for(i=0;i<w;)
1632499Sdlw 	{	i++;
1642499Sdlw 		if((ch=(*getn)())<0) return(ch);
165*18016Slibs 
166*18016Slibs 		if(ch==' ') {	/* blank */
167*18016Slibs 			if(cblank && (mode==2)) x *= 10;
168*18016Slibs 		} else if(ch<='9' && ch>='0') { /* digit */
169*18016Slibs 			mode = 2;
1702499Sdlw 			x=10*x+ch-'0';
171*18016Slibs 		} else if(ch=='.') {
1722499Sdlw 			break;
173*18016Slibs 		} else if(ch=='e' || ch=='d' || ch=='E' || ch=='D') {
174*18016Slibs 			goto exponent;
175*18016Slibs 		} else if(ch=='+' || ch=='-') {
176*18016Slibs 			if(mode==0) {  /* sign before digits */
177*18016Slibs 				if(ch=='-') sx=1;
178*18016Slibs 				mode = 1;
179*18016Slibs 			} else if(mode==1) {  /* two signs before digits */
180*18016Slibs 				return(errno=F_ERRFCHR);
181*18016Slibs 			} else { /* sign after digits, weird but standard!
182*18016Slibs 				    	means exponent without 'e' or 'd' */
183*18016Slibs 				    goto exponent;
184*18016Slibs 			}
185*18016Slibs 		} else if(ch==',') {
186*18016Slibs 			goto done;
187*18016Slibs 		} else if(ch=='\n') {
188*18016Slibs 			if(cblank && (mode==2)) x *= 10;
189*18016Slibs 		} else {
190*18016Slibs 			return(errno=F_ERRFCHR);
1912499Sdlw 		}
1922499Sdlw 	}
193*18016Slibs 	/* get here if out of characters to scan or found a period */
1942499Sdlw 	if(ch=='.') dot=1;
195*18016Slibs 	while(i<w)
1962499Sdlw 	{	i++;
1972499Sdlw 		if((ch=(*getn)())<0) return(ch);
198*18016Slibs 
199*18016Slibs 		if(ch<='9' && ch>='0') {
2002499Sdlw 			y=10*y+ch-'0';
201*18016Slibs 			ny++;
202*18016Slibs 		} else if(ch==' ' || ch=='\n') {
203*18016Slibs 			if(cblank) {
204*18016Slibs 				y*= 10;
205*18016Slibs 				ny++;
206*18016Slibs 			}
207*18016Slibs 		} else if(ch==',') {
208*18016Slibs 			goto done;
209*18016Slibs 		} else if(ch=='d' || ch=='e' || ch=='+' || ch=='-' || ch=='D' || ch=='E') {
210*18016Slibs 			break;
211*18016Slibs 		} else {
212*18016Slibs 			return(errno=F_ERRFCHR);
213*18016Slibs 		}
2142499Sdlw 	}
215*18016Slibs 	/*	now for the exponent.
216*18016Slibs 	 *	mode=3 means seen digit or sign of exponent.
217*18016Slibs 	 *	either out of characters to scan or
218*18016Slibs 	 *		ch is '+', '-', 'd', or 'e'.
219*18016Slibs 	 */
220*18016Slibs exponent:
221*18016Slibs 	if(ch=='-' || ch=='+') {
222*18016Slibs 		if(ch=='-') sz=1;
223*18016Slibs 		mode = 3;
224*18016Slibs 	} else {
225*18016Slibs 		mode = 2;
226*18016Slibs 	}
227*18016Slibs 
2282499Sdlw 	while(i<w)
2292499Sdlw 	{	i++;
2302499Sdlw 		sawz=1;
2312499Sdlw 		if((ch=(*getn)())<0) return(ch);
232*18016Slibs 
233*18016Slibs 		if(ch<='9' && ch>='0') {
234*18016Slibs 			mode = 3;
2352499Sdlw 			z=10*z+ch-'0';
236*18016Slibs 		} else if(ch=='+' || ch=='-') {
237*18016Slibs 			if(mode==3 ) return(errno=F_ERRFCHR);
238*18016Slibs 			mode = 3;
239*18016Slibs 			if(ch=='-') sz=1;
240*18016Slibs 		} else if(ch == ' ' || ch=='\n') {
241*18016Slibs 			if(cblank) z *=10;
242*18016Slibs 		} else if(ch==',') {
243*18016Slibs 			break;
244*18016Slibs 		} else {
245*18016Slibs 			return(errno=F_ERRFCHR);
246*18016Slibs 		}
2472499Sdlw 	}
248*18016Slibs done:
2492499Sdlw 	if(!dot)
2502499Sdlw 		for(i=0;i<d;i++) x /= 10;
2512499Sdlw 	for(i=0;i<ny;i++) y /= 10;
2522499Sdlw 	x=x+y;
2532499Sdlw 	if(sz)
2542499Sdlw 		for(i=0;i<z;i++) x /=10;
2552499Sdlw 	else	for(i=0;i<z;i++) x *= 10;
2562499Sdlw 	if(sx) x = -x;
2572499Sdlw 	if(!sawz)
2582499Sdlw 	{
2592499Sdlw 		for(i=scale;i>0;i--) x /= 10;
2602499Sdlw 		for(i=scale;i<0;i++) x *= 10;
2612499Sdlw 	}
2622499Sdlw 	if(len==sizeof(float)) p->pf=x;
2632499Sdlw 	else p->pd=x;
2642499Sdlw 	return(OK);
2652499Sdlw }
2662499Sdlw 
2672499Sdlw rd_AW(p,w,len) char *p; ftnlen len;
2682499Sdlw {	int i,ch;
2692499Sdlw 	if(w >= len)
2702499Sdlw 	{
2712499Sdlw 		for(i=0;i<w-len;i++) GET(ch);
2722499Sdlw 		for(i=0;i<len;i++)
2732499Sdlw 		{	GET(ch);
2742499Sdlw 			*p++=VAL(ch);
2752499Sdlw 		}
2762499Sdlw 	}
2772499Sdlw 	else
2782499Sdlw 	{
2792499Sdlw 		for(i=0;i<w;i++)
2802499Sdlw 		{	GET(ch);
2812499Sdlw 			*p++=VAL(ch);
2822499Sdlw 		}
2832499Sdlw 		for(i=0;i<len-w;i++) *p++=' ';
2842499Sdlw 	}
2852499Sdlw 	return(OK);
2862499Sdlw }
2872499Sdlw 
2882499Sdlw /* THIS IS NOT ALLOWED IN THE NEW STANDARD 'CAUSE IT'S WEIRD */
2893632Sdlw rd_H(n,s) char *s;
2903632Sdlw {	int i,ch = 0;
29118014Slibs 
29218014Slibs 	used_data = YES;
2933632Sdlw 	for(i=0;i<n;i++)
2943632Sdlw 	{	if (ch != '\n')
2953632Sdlw 			GET(ch);
2963632Sdlw 		if (ch == '\n')
2973632Sdlw 			*s++ = ' ';
2983632Sdlw 		else
2993632Sdlw 			*s++ = ch;
3003632Sdlw 	}
3013632Sdlw 	return(OK);
3023632Sdlw }
3033632Sdlw 
3043632Sdlw rd_POS(s) char *s;
3053632Sdlw {	char quote;
3063632Sdlw 	int ch = 0;
30718014Slibs 
30818014Slibs 	used_data = YES;
3093632Sdlw 	quote = *s++;
3103632Sdlw 	while(*s)
3113632Sdlw 	{	if(*s==quote && *(s+1)!=quote)
3123632Sdlw 			break;
3133632Sdlw 		if (ch != '\n')
3143632Sdlw 			GET(ch);
3153632Sdlw 		if (ch == '\n')
3163632Sdlw 			*s++ = ' ';
3173632Sdlw 		else
3183632Sdlw 			*s++ = ch;
3193632Sdlw 	}
3203632Sdlw 	return(OK);
3213632Sdlw }
322