1*47943Sbostic /*-
2*47943Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*47943Sbostic * All rights reserved.
42504Sdlw *
5*47943Sbostic * %sccs.include.proprietary.c%
623094Skre */
723094Skre
8*47943Sbostic #ifndef lint
9*47943Sbostic static char sccsid[] = "@(#)wrtfmt.c 5.2 (Berkeley) 04/12/91";
10*47943Sbostic #endif /* not lint */
11*47943Sbostic
1223094Skre /*
132504Sdlw * formatted write routines
142504Sdlw */
152504Sdlw
162504Sdlw #include "fio.h"
172603Sdlw #include "format.h"
182504Sdlw
192504Sdlw extern char *icvt();
2017969Slibs extern char *s_init;
212504Sdlw
222504Sdlw #define abs(x) (x<0?-x:x)
232504Sdlw
w_ed(p,ptr,len)242504Sdlw w_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len;
252504Sdlw { int n;
262504Sdlw if(cursor && (n=wr_mvcur())) return(n);
272504Sdlw switch(p->op)
282504Sdlw {
292504Sdlw case I:
302504Sdlw case IM:
312504Sdlw return(wrt_IM(ptr,p->p1,p->p2,len));
322504Sdlw case L:
3319985Slibs return(wrt_L(ptr,p->p1,len));
342504Sdlw case A:
3517969Slibs return(wrt_AW(ptr,len,len));
362504Sdlw case AW:
372504Sdlw return(wrt_AW(ptr,p->p1,len));
382504Sdlw case D:
3917969Slibs return(wrt_E(ptr,p->p1,p->p2,2,len,'d'));
402504Sdlw case DE:
4117969Slibs return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'d'));
422504Sdlw case E:
4317969Slibs return(wrt_E(ptr,p->p1,p->p2,2,len,'e'));
442504Sdlw case EE:
4517969Slibs return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'e'));
462504Sdlw case G:
4717969Slibs return(wrt_G(ptr,p->p1,p->p2,2,len));
482504Sdlw case GE:
4917969Slibs return(wrt_G(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len));
502504Sdlw case F:
512504Sdlw return(wrt_F(ptr,p->p1,p->p2,len));
522504Sdlw default:
532603Sdlw return(errno=F_ERFMT);
542504Sdlw }
552504Sdlw }
562504Sdlw
w_ned(p,ptr)572504Sdlw w_ned(p,ptr) char *ptr; struct syl *p;
582504Sdlw {
592504Sdlw switch(p->op)
602504Sdlw {
612504Sdlw case SLASH:
622504Sdlw return((*donewrec)());
632504Sdlw case T:
642504Sdlw if(p->p1) cursor = p->p1 - recpos - 1;
652504Sdlw #ifndef KOSHER
662504Sdlw else cursor = 8*p->p2 - recpos%8; /* NOT STANDARD FORT */
672504Sdlw #endif
682504Sdlw tab = YES;
692504Sdlw return(OK);
702504Sdlw case TL:
712504Sdlw cursor -= p->p1;
7212371Sdlw if ((recpos + cursor) < 0) cursor = -recpos; /* ANSI req'd */
732504Sdlw tab = YES;
742504Sdlw return(OK);
752504Sdlw case TR:
762504Sdlw case X:
772504Sdlw cursor += p->p1;
7812371Sdlw /* tab = (p->op == TR); this would implement destructive X */
7912371Sdlw tab = YES;
802504Sdlw return(OK);
812504Sdlw case APOS:
8217969Slibs return(wrt_AP(&s_init[p->p1]));
832504Sdlw case H:
8417969Slibs return(wrt_H(p->p1,&s_init[p->p2]));
852504Sdlw default:
862603Sdlw return(errno=F_ERFMT);
872504Sdlw }
882504Sdlw }
892504Sdlw
9020984Slibs LOCAL
wr_mvcur()912504Sdlw wr_mvcur()
922504Sdlw { int n;
932504Sdlw if(tab) return((*dotab)());
9412466Sdlw if (cursor < 0) return(errno=F_ERSEEK);
952504Sdlw while(cursor--) PUT(' ')
962504Sdlw return(cursor=0);
972504Sdlw }
982504Sdlw
9920984Slibs LOCAL
wrt_IM(ui,w,m,len)1002504Sdlw wrt_IM(ui,w,m,len) uint *ui; ftnlen len;
1012504Sdlw { int ndigit,sign,spare,i,xsign,n;
1022504Sdlw long x;
1032504Sdlw char *ans;
1042504Sdlw if(sizeof(short)==len) x=ui->is;
1052504Sdlw /* else if(len == sizeof(char)) x = ui->ic; */
1062504Sdlw else x=ui->il;
1072504Sdlw if(x==0 && m==0)
1082504Sdlw { for(i=0;i<w;i++) PUT(' ')
1092504Sdlw return(OK);
1102504Sdlw }
1112504Sdlw ans=icvt(x,&ndigit,&sign);
1122504Sdlw if(sign || cplus) xsign=1;
1132504Sdlw else xsign=0;
1142504Sdlw if(ndigit+xsign>w || m+xsign>w)
1152504Sdlw { for(i=0;i<w;i++) PUT('*')
1162504Sdlw return(OK);
1172504Sdlw }
1182504Sdlw if(ndigit>=m)
1192504Sdlw spare=w-ndigit-xsign;
1202504Sdlw else
1212504Sdlw spare=w-m-xsign;
1222504Sdlw for(i=0;i<spare;i++) PUT(' ')
1232504Sdlw if(sign) PUT('-')
1242504Sdlw else if(cplus) PUT('+')
1252504Sdlw for(i=0;i<m-ndigit;i++) PUT('0')
1262504Sdlw for(i=0;i<ndigit;i++) PUT(*ans++)
1272504Sdlw return(OK);
1282504Sdlw }
1292504Sdlw
13020984Slibs LOCAL
wrt_AP(p)1312504Sdlw wrt_AP(p)
1322504Sdlw { char *s,quote;
1332504Sdlw int n;
1342504Sdlw if(cursor && (n=wr_mvcur())) return(n);
1352504Sdlw s=(char *)p;
1362504Sdlw quote = *s++;
1372504Sdlw for(; *s; s++)
1382504Sdlw { if(*s!=quote) PUT(*s)
1392504Sdlw else if(*++s==quote) PUT(*s)
1402504Sdlw else return(OK);
1412504Sdlw }
1422504Sdlw return(OK);
1432504Sdlw }
1442504Sdlw
14520984Slibs LOCAL
wrt_H(a,b)1462504Sdlw wrt_H(a,b)
1472504Sdlw { char *s=(char *)b;
1482504Sdlw int n;
1492504Sdlw if(cursor && (n=wr_mvcur())) return(n);
1502504Sdlw while(a--) PUT(*s++)
1512504Sdlw return(OK);
1522504Sdlw }
1532504Sdlw
wrt_L(l,width,len)15419985Slibs wrt_L(l,width,len) uint *l; ftnlen len;
1552504Sdlw { int i,n;
15619985Slibs for(i=0;i<width-1;i++) PUT(' ')
15719985Slibs if(len == sizeof (short))
15819985Slibs i = l->is;
15919985Slibs else
16019985Slibs i = l->il;
16119985Slibs if(i) PUT('t')
1622504Sdlw else PUT('f')
1632504Sdlw return(OK);
1642504Sdlw }
1652504Sdlw
16620984Slibs LOCAL
wrt_AW(p,w,len)1672504Sdlw wrt_AW(p,w,len) char * p; ftnlen len;
1682504Sdlw { int n;
1692504Sdlw while(w>len)
1702504Sdlw { w--;
1712504Sdlw PUT(' ')
1722504Sdlw }
1732504Sdlw while(w-- > 0)
1742504Sdlw PUT(*p++)
1752504Sdlw return(OK);
1762504Sdlw }
1772504Sdlw
wrt_E(p,w,d,e,len,expch)17812039Sdlw wrt_E(p,w,d,e,len,expch) ufloat *p; ftnlen len; char expch;
17912039Sdlw { char *s,ex[4];
1802504Sdlw int dd,dp,sign,i,delta,pad,n;
1812504Sdlw char *ecvt();
18212039Sdlw
1832504Sdlw if((len==sizeof(float)?p->pf:p->pd)==0.0)
1842504Sdlw {
18517229Sdlw n = cblank;
18617229Sdlw cblank = 1; /* force '0' fill */
1872504Sdlw wrt_F(p,w-(e+2),d,len);
18817229Sdlw cblank = n;
1892504Sdlw PUT(expch)
1902504Sdlw PUT('+')
1912504Sdlw /* for(i=0;i<(e-1);i++)PUT(' ')
1922504Sdlw deleted PUT('0')
1932504Sdlw */
1942504Sdlw /* added */ for(i=0;i<e;i++) PUT('0')
1952504Sdlw return(OK);
1962504Sdlw }
19712371Sdlw if (scale > 0) { /* insane ANSI requirement */
19812371Sdlw dd = d + 1;
19912371Sdlw d = dd - scale;
20012371Sdlw } else
20112371Sdlw dd = d + scale;
20212371Sdlw if (dd <= 0 || d < 0) goto E_badfield;
2032504Sdlw s=ecvt( (len==sizeof(float)?(double)p->pf:p->pd) ,dd,&dp,&sign);
2042504Sdlw delta = 3+e;
2052504Sdlw if(sign||cplus) delta++;
2062504Sdlw pad=w-(delta+d)-(scale>0? scale:0);
20712371Sdlw if(pad<0) {
20812371Sdlw E_badfield:
20912371Sdlw for(i=0;i<w;i++) PUT('*')
2102504Sdlw return(OK);
2112504Sdlw }
2122504Sdlw for(i=0;i<(pad-(scale<=0?1:0));i++) PUT(' ')
2132504Sdlw if(sign) PUT('-')
2142504Sdlw else if(cplus) PUT('+')
2152504Sdlw if(scale<=0 && pad) PUT('0')
2162504Sdlw if(scale<0 && scale > -d)
2172504Sdlw {
2182504Sdlw PUT('.')
2192504Sdlw for(i=0;i<-scale;i++)
2202504Sdlw PUT('0')
2212504Sdlw for(i=0;i<d+scale;i++)
2222504Sdlw PUT(*s++)
2232504Sdlw }
2242504Sdlw else
2252504Sdlw {
2262504Sdlw if(scale>0)
2272504Sdlw for(i=0;i<scale;i++)
2282504Sdlw PUT(*s++)
2292504Sdlw PUT('.')
2302504Sdlw for(i=0;i<d;i++)
2312504Sdlw PUT(*s++)
2322504Sdlw }
2332504Sdlw dp -= scale;
2342504Sdlw sprintf(ex,"%d",abs(dp));
2352504Sdlw if((pad=strlen(ex))>e)
2362504Sdlw { if(pad>(++e))
2372504Sdlw { PUT(expch)
2382504Sdlw for(i=0;i<e;i++) PUT('*')
2392504Sdlw return(OK);
2402504Sdlw }
2412504Sdlw }
2422504Sdlw else PUT(expch)
2432504Sdlw PUT(dp<0?'-':'+')
2442504Sdlw for(i=0;i<(e-pad);i++) PUT('0') /* was ' ' */
2452504Sdlw s= &ex[0];
2462504Sdlw while(*s) PUT(*s++)
2472504Sdlw return(OK);
2482504Sdlw }
2492504Sdlw
25020984Slibs LOCAL
wrt_G(p,w,d,e,len)2512504Sdlw wrt_G(p,w,d,e,len) ufloat *p; ftnlen len;
2522504Sdlw { double uplim = 1.0, x;
2532504Sdlw int i,oldscale,n,j,ne;
2542504Sdlw x=(len==sizeof(float)?(double)p->pf:p->pd);
2552504Sdlw i=d;
2562504Sdlw if(x==0.0) goto zero;
2572504Sdlw x = abs(x);
2582504Sdlw if(x>=0.1)
2592504Sdlw {
2602504Sdlw for(i=0; i<=d; i++, uplim*=10.0)
2617456Sdlw { if(x>=uplim) continue;
2622504Sdlw zero: oldscale=scale;
2632504Sdlw scale=0;
2642504Sdlw ne = e+2;
2652504Sdlw if(n = wrt_F(p,w-ne,d-i,len)) return(n);
2662504Sdlw for(j=0; j<ne; j++) PUT(' ')
2672504Sdlw scale=oldscale;
2682504Sdlw return(OK);
2692504Sdlw }
2702504Sdlw /* falling off the bottom implies E format */
2712504Sdlw }
27212039Sdlw return(wrt_E(p,w,d,e,len,'e'));
2732504Sdlw }
2742504Sdlw
wrt_F(p,w,d,len)2752504Sdlw wrt_F(p,w,d,len) ufloat *p; ftnlen len;
2762504Sdlw { int i,delta,dp,sign,n,nf;
2772504Sdlw double x;
2782504Sdlw char *s,*fcvt();
2792504Sdlw x= (len==sizeof(float)?(double)p->pf:p->pd);
2802504Sdlw if(scale && x!=0.0)
2812504Sdlw { if(scale>0)
2822504Sdlw for(i=0;i<scale;i++) x*=10;
2832504Sdlw else for(i=0;i<-scale;i++) x/=10;
2842504Sdlw }
2852504Sdlw s=fcvt(x,d,&dp,&sign);
2862504Sdlw /* if(-dp>=d) sign=0; ?? */
2872504Sdlw delta=1;
2882504Sdlw if(sign || cplus) delta++;
2892504Sdlw nf = w - (d + delta + (dp>0?dp:0));
2902504Sdlw if(nf<0)
2912504Sdlw {
2922504Sdlw for(i=0;i<w;i++) PUT('*')
2932504Sdlw return(OK);
2942504Sdlw }
2952504Sdlw if(nf>0) for(i=0; i<(nf-(dp<=0?1:0)); i++) PUT(' ')
2962504Sdlw if(sign) PUT('-')
2972504Sdlw else if(cplus) PUT('+')
2982504Sdlw if(dp>0) for(i=0;i<dp;i++) PUT(*s++)
2992504Sdlw else if(nf>0) PUT('0')
3002504Sdlw PUT('.')
3012504Sdlw for(i=0; i< -dp && i<d; i++) PUT('0')
3022504Sdlw for(;i<d;i++)
3033561Sdlw { if(x==0.0 && !cblank) PUT(' ') /* exactly zero */
3042504Sdlw else if(*s) PUT(*s++)
3052504Sdlw else PUT('0')
3062504Sdlw }
3072504Sdlw return(OK);
3082504Sdlw }
309