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