xref: /csrg-svn/usr.bin/f77/libI77/rdfmt.c (revision 23085)
12499Sdlw /*
2*23085Skre  * Copyright (c) 1980 Regents of the University of California.
3*23085Skre  * All rights reserved.  The Berkeley software License Agreement
4*23085Skre  * specifies the terms and conditions for redistribution.
52499Sdlw  *
6*23085Skre  *	@(#)rdfmt.c	5.1	06/07/85
7*23085Skre  */
8*23085Skre 
9*23085Skre /*
102499Sdlw  * formatted read routines
112499Sdlw  */
122499Sdlw 
132499Sdlw #include "fio.h"
142598Sdlw #include "format.h"
152499Sdlw 
1617968Slibs extern char *s_init;
1718016Slibs extern int low_case[256];
1818014Slibs extern int used_data;
1917968Slibs 
202499Sdlw rd_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len;
212499Sdlw {	int n;
222499Sdlw 	if(cursor && (n=rd_mvcur())) return(n);
232499Sdlw 	switch(p->op)
242499Sdlw 	{
252499Sdlw 	case I:
262499Sdlw 	case IM:
272499Sdlw 		n = (rd_I(ptr,p->p1,len));
282499Sdlw 		break;
292499Sdlw 	case L:
3019984Slibs 		n = (rd_L(ptr,p->p1,len));
312499Sdlw 		break;
322499Sdlw 	case A:
3317968Slibs 		n = (rd_AW(ptr,len,len));
3417968Slibs 		break;
352499Sdlw 	case AW:
362499Sdlw 		n = (rd_AW(ptr,p->p1,len));
372499Sdlw 		break;
382499Sdlw 	case E:
392499Sdlw 	case EE:
402499Sdlw 	case D:
412499Sdlw 	case DE:
422499Sdlw 	case G:
432499Sdlw 	case GE:
442499Sdlw 	case F:
452499Sdlw 		n = (rd_F(ptr,p->p1,p->p2,len));
462499Sdlw 		break;
472499Sdlw 	default:
482598Sdlw 		return(errno=F_ERFMT);
492499Sdlw 	}
502499Sdlw 	if (n < 0)
512499Sdlw 	{
522499Sdlw 		if(feof(cf)) return(EOF);
532499Sdlw 		n = errno;
542499Sdlw 		clearerr(cf);
552499Sdlw 	}
562499Sdlw 	return(n);
572499Sdlw }
582499Sdlw 
592499Sdlw rd_ned(p,ptr) char *ptr; struct syl *p;
602499Sdlw {
612499Sdlw 	switch(p->op)
622499Sdlw 	{
633632Sdlw #ifndef	KOSHER
643632Sdlw 	case APOS:					/* NOT STANDARD F77 */
6517968Slibs 		return(rd_POS(&s_init[p->p1]));
663632Sdlw 	case H:						/* NOT STANDARD F77 */
6717968Slibs 		return(rd_H(p->p1,&s_init[p->p2]));
683632Sdlw #endif
692499Sdlw 	case SLASH:
702499Sdlw 		return((*donewrec)());
712499Sdlw 	case TR:
722499Sdlw 	case X:
732499Sdlw 		cursor += p->p1;
7412465Sdlw 		/* tab = (p->op==TR); This voids '..,tl6,1x,..' sequences */
7512465Sdlw 		tab = YES;
762499Sdlw 		return(OK);
772499Sdlw 	case T:
782499Sdlw 		if(p->p1) cursor = p->p1 - recpos - 1;
792499Sdlw #ifndef KOSHER
802499Sdlw 		else cursor = 8*p->p2 - recpos%8;	/* NOT STANDARD FORT */
812499Sdlw #endif
822499Sdlw 		tab = YES;
832499Sdlw 		return(OK);
842499Sdlw 	case TL:
852499Sdlw 		cursor -= p->p1;
8612370Sdlw 		if ((recpos + cursor) < 0) cursor = -recpos;	/* ANSI req'd */
872499Sdlw 		tab = YES;
882499Sdlw 		return(OK);
892499Sdlw 	default:
902598Sdlw 		return(errno=F_ERFMT);
912499Sdlw 	}
922499Sdlw }
932499Sdlw 
9420984Slibs LOCAL
952499Sdlw rd_mvcur()
962499Sdlw {	int n;
972499Sdlw 	if(tab) return((*dotab)());
9812465Sdlw 	if (cursor < 0) return(errno=F_ERSEEK);
992499Sdlw 	while(cursor--) if((n=(*getn)()) < 0) return(n);
1002499Sdlw 	return(cursor=0);
1012499Sdlw }
1022499Sdlw 
10320984Slibs LOCAL
1042499Sdlw rd_I(n,w,len) ftnlen len; uint *n;
1052499Sdlw {	long x=0;
10618016Slibs 	int i,sign=0,ch,c,sign_ok=YES;
1072499Sdlw 	for(i=0;i<w;i++)
1082499Sdlw 	{
1092499Sdlw 		if((ch=(*getn)())<0) return(ch);
11018016Slibs 		switch(ch)
1112499Sdlw 		{
1122499Sdlw 		case ',': goto done;
11318016Slibs 		case '-': sign=1;		/* and fall thru */
11418016Slibs 		case '+': if(sign_ok == NO) return(errno=F_ERRICHR);
11518016Slibs 			  sign_ok = NO;
11618016Slibs 			  break;
1172499Sdlw 		case ' ':
1182499Sdlw 			if(cblank) x *= radix;
1192499Sdlw 			break;
12018016Slibs 		case '\n':  if(cblank) {
12118016Slibs 				x *= radix;
12218016Slibs 				break;
12318016Slibs 			    } else {
12418016Slibs 				goto done;
12518016Slibs 			    }
1262499Sdlw 		default:
12718016Slibs 			sign_ok = NO;
12818016Slibs 			if( (c = ch-'0')>=0 && c<radix )
12918016Slibs 			{	x = (x * radix) + c;
13018016Slibs 				break;
1312499Sdlw 			}
13218016Slibs 			else if( (c = low_case[ch]-'a'+10)>=0 && c<radix )
13318016Slibs 			{	x = (x * radix) + c;
13418016Slibs 				break;
1352499Sdlw 			}
13617973Slibs 			return(errno=F_ERRICHR);
1372499Sdlw 		}
1382499Sdlw 	}
1392499Sdlw done:
1402499Sdlw 	if(sign) x = -x;
1412499Sdlw 	if(len==sizeof(short)) n->is=x;
1422499Sdlw 	else n->il=x;
1432499Sdlw 	return(OK);
1442499Sdlw }
1452499Sdlw 
14620984Slibs LOCAL
14719984Slibs rd_L(n,w,len) uint *n; ftnlen len;
14822026Slibs {	int ch,i,v = -1, period=0;
1492499Sdlw 	for(i=0;i<w;i++)
1502499Sdlw 	{	if((ch=(*getn)()) < 0) return(ch);
15118016Slibs 		if((ch=low_case[ch])=='t' && v==-1) v=1;
1522499Sdlw 		else if(ch=='f' && v==-1) v=0;
15322026Slibs 		else if(ch=='.' && !period) period++;
15422026Slibs 		else if(ch==' ' || ch=='\t') ;
1552499Sdlw 		else if(ch==',') break;
15622026Slibs 		else if(v==-1) return(errno=F_ERLOGIF);
1572499Sdlw 	}
1582598Sdlw 	if(v==-1) return(errno=F_ERLOGIF);
15919984Slibs 	if(len==sizeof(short)) n->is=v;
16019984Slibs 	else n->il=v;
1612499Sdlw 	return(OK);
1622499Sdlw }
1632499Sdlw 
16420984Slibs LOCAL
1652499Sdlw rd_F(p,w,d,len) ftnlen len; ufloat *p;
1662499Sdlw {	double x,y;
16718016Slibs 	int i,sx,sz,ch,dot,ny,z,sawz,mode, sign_ok=YES;
1682499Sdlw 	x=y=0;
1692499Sdlw 	sawz=z=ny=dot=sx=sz=0;
17018016Slibs 	/* modes:	0 in initial blanks,
17118016Slibs 			2 blanks plus sign
17218016Slibs 			3 found a digit
17318016Slibs 	 */
17418016Slibs 	mode = 0;
17518016Slibs 
1762499Sdlw 	for(i=0;i<w;)
1772499Sdlw 	{	i++;
1782499Sdlw 		if((ch=(*getn)())<0) return(ch);
17918016Slibs 
18018016Slibs 		if(ch==' ') {	/* blank */
18118016Slibs 			if(cblank && (mode==2)) x *= 10;
18218016Slibs 		} else if(ch<='9' && ch>='0') { /* digit */
18318016Slibs 			mode = 2;
1842499Sdlw 			x=10*x+ch-'0';
18518016Slibs 		} else if(ch=='.') {
1862499Sdlw 			break;
18718016Slibs 		} else if(ch=='e' || ch=='d' || ch=='E' || ch=='D') {
18818016Slibs 			goto exponent;
18918016Slibs 		} else if(ch=='+' || ch=='-') {
19018016Slibs 			if(mode==0) {  /* sign before digits */
19118016Slibs 				if(ch=='-') sx=1;
19218016Slibs 				mode = 1;
19318016Slibs 			} else if(mode==1) {  /* two signs before digits */
19418016Slibs 				return(errno=F_ERRFCHR);
19518016Slibs 			} else { /* sign after digits, weird but standard!
19618016Slibs 				    	means exponent without 'e' or 'd' */
19718016Slibs 				    goto exponent;
19818016Slibs 			}
19918016Slibs 		} else if(ch==',') {
20018016Slibs 			goto done;
20118016Slibs 		} else if(ch=='\n') {
20218016Slibs 			if(cblank && (mode==2)) x *= 10;
20318016Slibs 		} else {
20418016Slibs 			return(errno=F_ERRFCHR);
2052499Sdlw 		}
2062499Sdlw 	}
20718016Slibs 	/* get here if out of characters to scan or found a period */
2082499Sdlw 	if(ch=='.') dot=1;
20918016Slibs 	while(i<w)
2102499Sdlw 	{	i++;
2112499Sdlw 		if((ch=(*getn)())<0) return(ch);
21218016Slibs 
21318016Slibs 		if(ch<='9' && ch>='0') {
2142499Sdlw 			y=10*y+ch-'0';
21518016Slibs 			ny++;
21618016Slibs 		} else if(ch==' ' || ch=='\n') {
21718016Slibs 			if(cblank) {
21818016Slibs 				y*= 10;
21918016Slibs 				ny++;
22018016Slibs 			}
22118016Slibs 		} else if(ch==',') {
22218016Slibs 			goto done;
22318016Slibs 		} else if(ch=='d' || ch=='e' || ch=='+' || ch=='-' || ch=='D' || ch=='E') {
22418016Slibs 			break;
22518016Slibs 		} else {
22618016Slibs 			return(errno=F_ERRFCHR);
22718016Slibs 		}
2282499Sdlw 	}
22918016Slibs 	/*	now for the exponent.
23018016Slibs 	 *	mode=3 means seen digit or sign of exponent.
23118016Slibs 	 *	either out of characters to scan or
23218016Slibs 	 *		ch is '+', '-', 'd', or 'e'.
23318016Slibs 	 */
23418016Slibs exponent:
23518016Slibs 	if(ch=='-' || ch=='+') {
23618016Slibs 		if(ch=='-') sz=1;
23718016Slibs 		mode = 3;
23818016Slibs 	} else {
23918016Slibs 		mode = 2;
24018016Slibs 	}
24118016Slibs 
2422499Sdlw 	while(i<w)
2432499Sdlw 	{	i++;
2442499Sdlw 		sawz=1;
2452499Sdlw 		if((ch=(*getn)())<0) return(ch);
24618016Slibs 
24718016Slibs 		if(ch<='9' && ch>='0') {
24818016Slibs 			mode = 3;
2492499Sdlw 			z=10*z+ch-'0';
25018016Slibs 		} else if(ch=='+' || ch=='-') {
25118016Slibs 			if(mode==3 ) return(errno=F_ERRFCHR);
25218016Slibs 			mode = 3;
25318016Slibs 			if(ch=='-') sz=1;
25418016Slibs 		} else if(ch == ' ' || ch=='\n') {
25518016Slibs 			if(cblank) z *=10;
25618016Slibs 		} else if(ch==',') {
25718016Slibs 			break;
25818016Slibs 		} else {
25918016Slibs 			return(errno=F_ERRFCHR);
26018016Slibs 		}
2612499Sdlw 	}
26218016Slibs done:
2632499Sdlw 	if(!dot)
2642499Sdlw 		for(i=0;i<d;i++) x /= 10;
2652499Sdlw 	for(i=0;i<ny;i++) y /= 10;
2662499Sdlw 	x=x+y;
2672499Sdlw 	if(sz)
2682499Sdlw 		for(i=0;i<z;i++) x /=10;
2692499Sdlw 	else	for(i=0;i<z;i++) x *= 10;
2702499Sdlw 	if(sx) x = -x;
2712499Sdlw 	if(!sawz)
2722499Sdlw 	{
2732499Sdlw 		for(i=scale;i>0;i--) x /= 10;
2742499Sdlw 		for(i=scale;i<0;i++) x *= 10;
2752499Sdlw 	}
2762499Sdlw 	if(len==sizeof(float)) p->pf=x;
2772499Sdlw 	else p->pd=x;
2782499Sdlw 	return(OK);
2792499Sdlw }
2802499Sdlw 
28120984Slibs LOCAL
2822499Sdlw rd_AW(p,w,len) char *p; ftnlen len;
2832499Sdlw {	int i,ch;
2842499Sdlw 	if(w >= len)
2852499Sdlw 	{
2862499Sdlw 		for(i=0;i<w-len;i++) GET(ch);
2872499Sdlw 		for(i=0;i<len;i++)
2882499Sdlw 		{	GET(ch);
2892499Sdlw 			*p++=VAL(ch);
2902499Sdlw 		}
2912499Sdlw 	}
2922499Sdlw 	else
2932499Sdlw 	{
2942499Sdlw 		for(i=0;i<w;i++)
2952499Sdlw 		{	GET(ch);
2962499Sdlw 			*p++=VAL(ch);
2972499Sdlw 		}
2982499Sdlw 		for(i=0;i<len-w;i++) *p++=' ';
2992499Sdlw 	}
3002499Sdlw 	return(OK);
3012499Sdlw }
3022499Sdlw 
3032499Sdlw /* THIS IS NOT ALLOWED IN THE NEW STANDARD 'CAUSE IT'S WEIRD */
30420984Slibs LOCAL
3053632Sdlw rd_H(n,s) char *s;
3063632Sdlw {	int i,ch = 0;
30718014Slibs 
30818014Slibs 	used_data = YES;
3093632Sdlw 	for(i=0;i<n;i++)
3103632Sdlw 	{	if (ch != '\n')
3113632Sdlw 			GET(ch);
3123632Sdlw 		if (ch == '\n')
3133632Sdlw 			*s++ = ' ';
3143632Sdlw 		else
3153632Sdlw 			*s++ = ch;
3163632Sdlw 	}
3173632Sdlw 	return(OK);
3183632Sdlw }
3193632Sdlw 
32020984Slibs LOCAL
3213632Sdlw rd_POS(s) char *s;
3223632Sdlw {	char quote;
3233632Sdlw 	int ch = 0;
32418014Slibs 
32518014Slibs 	used_data = YES;
3263632Sdlw 	quote = *s++;
3273632Sdlw 	while(*s)
3283632Sdlw 	{	if(*s==quote && *(s+1)!=quote)
3293632Sdlw 			break;
3303632Sdlw 		if (ch != '\n')
3313632Sdlw 			GET(ch);
3323632Sdlw 		if (ch == '\n')
3333632Sdlw 			*s++ = ' ';
3343632Sdlw 		else
3353632Sdlw 			*s++ = ch;
3363632Sdlw 	}
3373632Sdlw 	return(OK);
3383632Sdlw }
339