xref: /csrg-svn/usr.bin/f77/libI77/wrtfmt.c (revision 23094)
12504Sdlw /*
2*23094Skre  * Copyright (c) 1980 Regents of the University of California.
3*23094Skre  * All rights reserved.  The Berkeley software License Agreement
4*23094Skre  * specifies the terms and conditions for redistribution.
52504Sdlw  *
6*23094Skre  *	@(#)wrtfmt.c	5.1	06/07/85
7*23094Skre  */
8*23094Skre 
9*23094Skre /*
102504Sdlw  * formatted write routines
112504Sdlw  */
122504Sdlw 
132504Sdlw #include "fio.h"
142603Sdlw #include "format.h"
152504Sdlw 
162504Sdlw extern char *icvt();
1717969Slibs extern char *s_init;
182504Sdlw 
192504Sdlw #define abs(x) (x<0?-x:x)
202504Sdlw 
212504Sdlw w_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len;
222504Sdlw {	int n;
232504Sdlw 	if(cursor && (n=wr_mvcur())) return(n);
242504Sdlw 	switch(p->op)
252504Sdlw 	{
262504Sdlw 	case I:
272504Sdlw 	case IM:
282504Sdlw 		return(wrt_IM(ptr,p->p1,p->p2,len));
292504Sdlw 	case L:
3019985Slibs 		return(wrt_L(ptr,p->p1,len));
312504Sdlw 	case A:
3217969Slibs 		return(wrt_AW(ptr,len,len));
332504Sdlw 	case AW:
342504Sdlw 		return(wrt_AW(ptr,p->p1,len));
352504Sdlw 	case D:
3617969Slibs 		return(wrt_E(ptr,p->p1,p->p2,2,len,'d'));
372504Sdlw 	case DE:
3817969Slibs 		return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'d'));
392504Sdlw 	case E:
4017969Slibs 		return(wrt_E(ptr,p->p1,p->p2,2,len,'e'));
412504Sdlw 	case EE:
4217969Slibs 		return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'e'));
432504Sdlw 	case G:
4417969Slibs 		return(wrt_G(ptr,p->p1,p->p2,2,len));
452504Sdlw 	case GE:
4617969Slibs 		return(wrt_G(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len));
472504Sdlw 	case F:
482504Sdlw 		return(wrt_F(ptr,p->p1,p->p2,len));
492504Sdlw 	default:
502603Sdlw 		return(errno=F_ERFMT);
512504Sdlw 	}
522504Sdlw }
532504Sdlw 
542504Sdlw w_ned(p,ptr) char *ptr; struct syl *p;
552504Sdlw {
562504Sdlw 	switch(p->op)
572504Sdlw 	{
582504Sdlw 	case SLASH:
592504Sdlw 		return((*donewrec)());
602504Sdlw 	case T:
612504Sdlw 		if(p->p1) cursor = p->p1 - recpos - 1;
622504Sdlw #ifndef KOSHER
632504Sdlw 		else cursor = 8*p->p2 - recpos%8;	/* NOT STANDARD FORT */
642504Sdlw #endif
652504Sdlw 		tab = YES;
662504Sdlw 		return(OK);
672504Sdlw 	case TL:
682504Sdlw 		cursor -= p->p1;
6912371Sdlw 		if ((recpos + cursor) < 0) cursor = -recpos;	/* ANSI req'd */
702504Sdlw 		tab = YES;
712504Sdlw 		return(OK);
722504Sdlw 	case TR:
732504Sdlw 	case X:
742504Sdlw 		cursor += p->p1;
7512371Sdlw 		/* tab = (p->op == TR); this would implement destructive X */
7612371Sdlw 		tab = YES;
772504Sdlw 		return(OK);
782504Sdlw 	case APOS:
7917969Slibs 		return(wrt_AP(&s_init[p->p1]));
802504Sdlw 	case H:
8117969Slibs 		return(wrt_H(p->p1,&s_init[p->p2]));
822504Sdlw 	default:
832603Sdlw 		return(errno=F_ERFMT);
842504Sdlw 	}
852504Sdlw }
862504Sdlw 
8720984Slibs LOCAL
882504Sdlw wr_mvcur()
892504Sdlw {	int n;
902504Sdlw 	if(tab) return((*dotab)());
9112466Sdlw 	if (cursor < 0) return(errno=F_ERSEEK);
922504Sdlw 	while(cursor--) PUT(' ')
932504Sdlw 	return(cursor=0);
942504Sdlw }
952504Sdlw 
9620984Slibs LOCAL
972504Sdlw wrt_IM(ui,w,m,len) uint *ui; ftnlen len;
982504Sdlw {	int ndigit,sign,spare,i,xsign,n;
992504Sdlw 	long x;
1002504Sdlw 	char *ans;
1012504Sdlw 	if(sizeof(short)==len) x=ui->is;
1022504Sdlw /*	else if(len == sizeof(char)) x = ui->ic; */
1032504Sdlw 	else x=ui->il;
1042504Sdlw 	if(x==0 && m==0)
1052504Sdlw 	{	for(i=0;i<w;i++) PUT(' ')
1062504Sdlw 		return(OK);
1072504Sdlw 	}
1082504Sdlw 	ans=icvt(x,&ndigit,&sign);
1092504Sdlw 	if(sign || cplus) xsign=1;
1102504Sdlw 	else xsign=0;
1112504Sdlw 	if(ndigit+xsign>w || m+xsign>w)
1122504Sdlw 	{	for(i=0;i<w;i++) PUT('*')
1132504Sdlw 		return(OK);
1142504Sdlw 	}
1152504Sdlw 	if(ndigit>=m)
1162504Sdlw 		spare=w-ndigit-xsign;
1172504Sdlw 	else
1182504Sdlw 		spare=w-m-xsign;
1192504Sdlw 	for(i=0;i<spare;i++) PUT(' ')
1202504Sdlw 	if(sign) PUT('-')
1212504Sdlw 	else if(cplus) PUT('+')
1222504Sdlw 	for(i=0;i<m-ndigit;i++) PUT('0')
1232504Sdlw 	for(i=0;i<ndigit;i++) PUT(*ans++)
1242504Sdlw 	return(OK);
1252504Sdlw }
1262504Sdlw 
12720984Slibs LOCAL
1282504Sdlw wrt_AP(p)
1292504Sdlw {	char *s,quote;
1302504Sdlw 	int n;
1312504Sdlw 	if(cursor && (n=wr_mvcur())) return(n);
1322504Sdlw 	s=(char *)p;
1332504Sdlw 	quote = *s++;
1342504Sdlw 	for(; *s; s++)
1352504Sdlw 	{	if(*s!=quote) PUT(*s)
1362504Sdlw 		else if(*++s==quote) PUT(*s)
1372504Sdlw 		else return(OK);
1382504Sdlw 	}
1392504Sdlw 	return(OK);
1402504Sdlw }
1412504Sdlw 
14220984Slibs LOCAL
1432504Sdlw wrt_H(a,b)
1442504Sdlw {	char *s=(char *)b;
1452504Sdlw 	int n;
1462504Sdlw 	if(cursor && (n=wr_mvcur())) return(n);
1472504Sdlw 	while(a--) PUT(*s++)
1482504Sdlw 	return(OK);
1492504Sdlw }
1502504Sdlw 
15119985Slibs wrt_L(l,width,len) uint *l; ftnlen len;
1522504Sdlw {	int i,n;
15319985Slibs 	for(i=0;i<width-1;i++) PUT(' ')
15419985Slibs 	if(len == sizeof (short))
15519985Slibs 		i = l->is;
15619985Slibs 	else
15719985Slibs 		i = l->il;
15819985Slibs 	if(i) PUT('t')
1592504Sdlw 	else PUT('f')
1602504Sdlw 	return(OK);
1612504Sdlw }
1622504Sdlw 
16320984Slibs LOCAL
1642504Sdlw wrt_AW(p,w,len) char * p; ftnlen len;
1652504Sdlw {	int n;
1662504Sdlw 	while(w>len)
1672504Sdlw 	{	w--;
1682504Sdlw 		PUT(' ')
1692504Sdlw 	}
1702504Sdlw 	while(w-- > 0)
1712504Sdlw 		PUT(*p++)
1722504Sdlw 	return(OK);
1732504Sdlw }
1742504Sdlw 
17512039Sdlw wrt_E(p,w,d,e,len,expch) ufloat *p; ftnlen len; char expch;
17612039Sdlw {	char *s,ex[4];
1772504Sdlw 	int dd,dp,sign,i,delta,pad,n;
1782504Sdlw 	char *ecvt();
17912039Sdlw 
1802504Sdlw 	if((len==sizeof(float)?p->pf:p->pd)==0.0)
1812504Sdlw 	{
18217229Sdlw 		n = cblank;
18317229Sdlw 		cblank = 1;	/* force '0' fill */
1842504Sdlw 		wrt_F(p,w-(e+2),d,len);
18517229Sdlw 		cblank = n;
1862504Sdlw 		PUT(expch)
1872504Sdlw 		PUT('+')
1882504Sdlw /*		for(i=0;i<(e-1);i++)PUT(' ')
1892504Sdlw deleted		PUT('0')
1902504Sdlw  */
1912504Sdlw /* added */	for(i=0;i<e;i++) PUT('0')
1922504Sdlw 		return(OK);
1932504Sdlw 	}
19412371Sdlw 	if (scale > 0) {	/* insane ANSI requirement */
19512371Sdlw 		dd = d + 1;
19612371Sdlw 		d = dd - scale;
19712371Sdlw 	} else
19812371Sdlw 		dd = d + scale;
19912371Sdlw 	if (dd <= 0 || d < 0) goto E_badfield;
2002504Sdlw 	s=ecvt( (len==sizeof(float)?(double)p->pf:p->pd) ,dd,&dp,&sign);
2012504Sdlw 	delta = 3+e;
2022504Sdlw 	if(sign||cplus) delta++;
2032504Sdlw 	pad=w-(delta+d)-(scale>0? scale:0);
20412371Sdlw 	if(pad<0) {
20512371Sdlw E_badfield:
20612371Sdlw 		for(i=0;i<w;i++) PUT('*')
2072504Sdlw 		return(OK);
2082504Sdlw 	}
2092504Sdlw 	for(i=0;i<(pad-(scale<=0?1:0));i++) PUT(' ')
2102504Sdlw 	if(sign) PUT('-')
2112504Sdlw 	else if(cplus) PUT('+')
2122504Sdlw 	if(scale<=0 && pad) PUT('0')
2132504Sdlw 	if(scale<0 && scale > -d)
2142504Sdlw 	{
2152504Sdlw 		PUT('.')
2162504Sdlw 		for(i=0;i<-scale;i++)
2172504Sdlw 			PUT('0')
2182504Sdlw 		for(i=0;i<d+scale;i++)
2192504Sdlw 			PUT(*s++)
2202504Sdlw 	}
2212504Sdlw 	else
2222504Sdlw 	{
2232504Sdlw 		if(scale>0)
2242504Sdlw 			for(i=0;i<scale;i++)
2252504Sdlw 				PUT(*s++)
2262504Sdlw 		PUT('.')
2272504Sdlw 		for(i=0;i<d;i++)
2282504Sdlw 			PUT(*s++)
2292504Sdlw 	}
2302504Sdlw 	dp -= scale;
2312504Sdlw 	sprintf(ex,"%d",abs(dp));
2322504Sdlw 	if((pad=strlen(ex))>e)
2332504Sdlw 	{	if(pad>(++e))
2342504Sdlw 		{	PUT(expch)
2352504Sdlw 			for(i=0;i<e;i++) PUT('*')
2362504Sdlw 			return(OK);
2372504Sdlw 		}
2382504Sdlw 	}
2392504Sdlw 	else PUT(expch)
2402504Sdlw 	PUT(dp<0?'-':'+')
2412504Sdlw 	for(i=0;i<(e-pad);i++) PUT('0')  /* was ' ' */
2422504Sdlw 	s= &ex[0];
2432504Sdlw 	while(*s) PUT(*s++)
2442504Sdlw 	return(OK);
2452504Sdlw }
2462504Sdlw 
24720984Slibs LOCAL
2482504Sdlw wrt_G(p,w,d,e,len) ufloat *p; ftnlen len;
2492504Sdlw {	double uplim = 1.0, x;
2502504Sdlw 	int i,oldscale,n,j,ne;
2512504Sdlw 	x=(len==sizeof(float)?(double)p->pf:p->pd);
2522504Sdlw 	i=d;
2532504Sdlw 	if(x==0.0) goto zero;
2542504Sdlw 	x = abs(x);
2552504Sdlw 	if(x>=0.1)
2562504Sdlw 	{
2572504Sdlw 		for(i=0; i<=d; i++, uplim*=10.0)
2587456Sdlw 		{	if(x>=uplim) continue;
2592504Sdlw zero:			oldscale=scale;
2602504Sdlw 			scale=0;
2612504Sdlw 			ne = e+2;
2622504Sdlw 			if(n = wrt_F(p,w-ne,d-i,len)) return(n);
2632504Sdlw 			for(j=0; j<ne; j++) PUT(' ')
2642504Sdlw 			scale=oldscale;
2652504Sdlw 			return(OK);
2662504Sdlw 		}
2672504Sdlw 		/* falling off the bottom implies E format */
2682504Sdlw 	}
26912039Sdlw 	return(wrt_E(p,w,d,e,len,'e'));
2702504Sdlw }
2712504Sdlw 
2722504Sdlw wrt_F(p,w,d,len) ufloat *p; ftnlen len;
2732504Sdlw {	int i,delta,dp,sign,n,nf;
2742504Sdlw 	double x;
2752504Sdlw 	char *s,*fcvt();
2762504Sdlw 	x= (len==sizeof(float)?(double)p->pf:p->pd);
2772504Sdlw 	if(scale && x!=0.0)
2782504Sdlw 	{	if(scale>0)
2792504Sdlw 			for(i=0;i<scale;i++) x*=10;
2802504Sdlw 		else	for(i=0;i<-scale;i++) x/=10;
2812504Sdlw 	}
2822504Sdlw 	s=fcvt(x,d,&dp,&sign);
2832504Sdlw /*	if(-dp>=d) sign=0; ?? */
2842504Sdlw 	delta=1;
2852504Sdlw 	if(sign || cplus) delta++;
2862504Sdlw 	nf = w - (d + delta + (dp>0?dp:0));
2872504Sdlw 	if(nf<0)
2882504Sdlw 	{
2892504Sdlw 		for(i=0;i<w;i++) PUT('*')
2902504Sdlw 		return(OK);
2912504Sdlw 	}
2922504Sdlw 	if(nf>0) for(i=0; i<(nf-(dp<=0?1:0)); i++) PUT(' ')
2932504Sdlw 	if(sign) PUT('-')
2942504Sdlw 	else if(cplus) PUT('+')
2952504Sdlw 	if(dp>0) for(i=0;i<dp;i++) PUT(*s++)
2962504Sdlw 	else if(nf>0) PUT('0')
2972504Sdlw 	PUT('.')
2982504Sdlw 	for(i=0; i< -dp && i<d; i++) PUT('0')
2992504Sdlw 	for(;i<d;i++)
3003561Sdlw 	{	if(x==0.0 && !cblank) PUT(' ')	/* exactly zero */
3012504Sdlw 		else if(*s) PUT(*s++)
3022504Sdlw 		else PUT('0')
3032504Sdlw 	}
3042504Sdlw 	return(OK);
3052504Sdlw }
306