12504Sdlw /* 2*17229Sdlw char id_wrtfmt[] = "@(#)wrtfmt.c 1.8"; 32504Sdlw * 42504Sdlw * formatted write routines 52504Sdlw */ 62504Sdlw 72504Sdlw #include "fio.h" 82603Sdlw #include "format.h" 92504Sdlw 102504Sdlw extern char *icvt(); 112504Sdlw 122504Sdlw #define abs(x) (x<0?-x:x) 132504Sdlw 142504Sdlw w_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len; 152504Sdlw { int n; 162504Sdlw if(cursor && (n=wr_mvcur())) return(n); 172504Sdlw switch(p->op) 182504Sdlw { 192504Sdlw case I: 202504Sdlw case IM: 212504Sdlw return(wrt_IM(ptr,p->p1,p->p2,len)); 222504Sdlw case L: 232504Sdlw return(wrt_L(ptr,p->p1)); 242504Sdlw case A: 252504Sdlw p->p1 = len; /* cheap trick */ 262504Sdlw case AW: 272504Sdlw return(wrt_AW(ptr,p->p1,len)); 282504Sdlw case D: 292504Sdlw case DE: 3012039Sdlw return(wrt_E(ptr,p->p1,p->p2,p->p3,len,'d')); 312504Sdlw case E: 322504Sdlw case EE: 3312039Sdlw return(wrt_E(ptr,p->p1,p->p2,p->p3,len,'e')); 342504Sdlw case G: 352504Sdlw case GE: 362504Sdlw return(wrt_G(ptr,p->p1,p->p2,p->p3,len)); 372504Sdlw case F: 382504Sdlw return(wrt_F(ptr,p->p1,p->p2,len)); 392504Sdlw default: 402603Sdlw return(errno=F_ERFMT); 412504Sdlw } 422504Sdlw } 432504Sdlw 442504Sdlw w_ned(p,ptr) char *ptr; struct syl *p; 452504Sdlw { 462504Sdlw switch(p->op) 472504Sdlw { 482504Sdlw case SLASH: 492504Sdlw return((*donewrec)()); 502504Sdlw case T: 512504Sdlw if(p->p1) cursor = p->p1 - recpos - 1; 522504Sdlw #ifndef KOSHER 532504Sdlw else cursor = 8*p->p2 - recpos%8; /* NOT STANDARD FORT */ 542504Sdlw #endif 552504Sdlw tab = YES; 562504Sdlw return(OK); 572504Sdlw case TL: 582504Sdlw cursor -= p->p1; 5912371Sdlw if ((recpos + cursor) < 0) cursor = -recpos; /* ANSI req'd */ 602504Sdlw tab = YES; 612504Sdlw return(OK); 622504Sdlw case TR: 632504Sdlw case X: 642504Sdlw cursor += p->p1; 6512371Sdlw /* tab = (p->op == TR); this would implement destructive X */ 6612371Sdlw tab = YES; 672504Sdlw return(OK); 682504Sdlw case APOS: 692504Sdlw return(wrt_AP(p->p1)); 702504Sdlw case H: 712504Sdlw return(wrt_H(p->p1,p->p2)); 722504Sdlw default: 732603Sdlw return(errno=F_ERFMT); 742504Sdlw } 752504Sdlw } 762504Sdlw 772504Sdlw wr_mvcur() 782504Sdlw { int n; 792504Sdlw if(tab) return((*dotab)()); 8012466Sdlw if (cursor < 0) return(errno=F_ERSEEK); 812504Sdlw while(cursor--) PUT(' ') 822504Sdlw return(cursor=0); 832504Sdlw } 842504Sdlw 852504Sdlw wrt_IM(ui,w,m,len) uint *ui; ftnlen len; 862504Sdlw { int ndigit,sign,spare,i,xsign,n; 872504Sdlw long x; 882504Sdlw char *ans; 892504Sdlw if(sizeof(short)==len) x=ui->is; 902504Sdlw /* else if(len == sizeof(char)) x = ui->ic; */ 912504Sdlw else x=ui->il; 922504Sdlw if(x==0 && m==0) 932504Sdlw { for(i=0;i<w;i++) PUT(' ') 942504Sdlw return(OK); 952504Sdlw } 962504Sdlw ans=icvt(x,&ndigit,&sign); 972504Sdlw if(sign || cplus) xsign=1; 982504Sdlw else xsign=0; 992504Sdlw if(ndigit+xsign>w || m+xsign>w) 1002504Sdlw { for(i=0;i<w;i++) PUT('*') 1012504Sdlw return(OK); 1022504Sdlw } 1032504Sdlw if(ndigit>=m) 1042504Sdlw spare=w-ndigit-xsign; 1052504Sdlw else 1062504Sdlw spare=w-m-xsign; 1072504Sdlw for(i=0;i<spare;i++) PUT(' ') 1082504Sdlw if(sign) PUT('-') 1092504Sdlw else if(cplus) PUT('+') 1102504Sdlw for(i=0;i<m-ndigit;i++) PUT('0') 1112504Sdlw for(i=0;i<ndigit;i++) PUT(*ans++) 1122504Sdlw return(OK); 1132504Sdlw } 1142504Sdlw 1152504Sdlw wrt_AP(p) 1162504Sdlw { char *s,quote; 1172504Sdlw int n; 1182504Sdlw if(cursor && (n=wr_mvcur())) return(n); 1192504Sdlw s=(char *)p; 1202504Sdlw quote = *s++; 1212504Sdlw for(; *s; s++) 1222504Sdlw { if(*s!=quote) PUT(*s) 1232504Sdlw else if(*++s==quote) PUT(*s) 1242504Sdlw else return(OK); 1252504Sdlw } 1262504Sdlw return(OK); 1272504Sdlw } 1282504Sdlw 1292504Sdlw wrt_H(a,b) 1302504Sdlw { char *s=(char *)b; 1312504Sdlw int n; 1322504Sdlw if(cursor && (n=wr_mvcur())) return(n); 1332504Sdlw while(a--) PUT(*s++) 1342504Sdlw return(OK); 1352504Sdlw } 1362504Sdlw 1372504Sdlw wrt_L(l,len) ftnint *l; 1382504Sdlw { int i,n; 1392504Sdlw for(i=0;i<len-1;i++) PUT(' ') 1402504Sdlw if(*l) PUT('t') 1412504Sdlw else PUT('f') 1422504Sdlw return(OK); 1432504Sdlw } 1442504Sdlw 1452504Sdlw wrt_AW(p,w,len) char * p; ftnlen len; 1462504Sdlw { int n; 1472504Sdlw while(w>len) 1482504Sdlw { w--; 1492504Sdlw PUT(' ') 1502504Sdlw } 1512504Sdlw while(w-- > 0) 1522504Sdlw PUT(*p++) 1532504Sdlw return(OK); 1542504Sdlw } 1552504Sdlw 15612039Sdlw wrt_E(p,w,d,e,len,expch) ufloat *p; ftnlen len; char expch; 15712039Sdlw { char *s,ex[4]; 1582504Sdlw int dd,dp,sign,i,delta,pad,n; 1592504Sdlw char *ecvt(); 16012039Sdlw 1612504Sdlw if((len==sizeof(float)?p->pf:p->pd)==0.0) 1622504Sdlw { 163*17229Sdlw n = cblank; 164*17229Sdlw cblank = 1; /* force '0' fill */ 1652504Sdlw wrt_F(p,w-(e+2),d,len); 166*17229Sdlw cblank = n; 1672504Sdlw PUT(expch) 1682504Sdlw PUT('+') 1692504Sdlw /* for(i=0;i<(e-1);i++)PUT(' ') 1702504Sdlw deleted PUT('0') 1712504Sdlw */ 1722504Sdlw /* added */ for(i=0;i<e;i++) PUT('0') 1732504Sdlw return(OK); 1742504Sdlw } 17512371Sdlw if (scale > 0) { /* insane ANSI requirement */ 17612371Sdlw dd = d + 1; 17712371Sdlw d = dd - scale; 17812371Sdlw } else 17912371Sdlw dd = d + scale; 18012371Sdlw if (dd <= 0 || d < 0) goto E_badfield; 1812504Sdlw s=ecvt( (len==sizeof(float)?(double)p->pf:p->pd) ,dd,&dp,&sign); 1822504Sdlw delta = 3+e; 1832504Sdlw if(sign||cplus) delta++; 1842504Sdlw pad=w-(delta+d)-(scale>0? scale:0); 18512371Sdlw if(pad<0) { 18612371Sdlw E_badfield: 18712371Sdlw for(i=0;i<w;i++) PUT('*') 1882504Sdlw return(OK); 1892504Sdlw } 1902504Sdlw for(i=0;i<(pad-(scale<=0?1:0));i++) PUT(' ') 1912504Sdlw if(sign) PUT('-') 1922504Sdlw else if(cplus) PUT('+') 1932504Sdlw if(scale<=0 && pad) PUT('0') 1942504Sdlw if(scale<0 && scale > -d) 1952504Sdlw { 1962504Sdlw PUT('.') 1972504Sdlw for(i=0;i<-scale;i++) 1982504Sdlw PUT('0') 1992504Sdlw for(i=0;i<d+scale;i++) 2002504Sdlw PUT(*s++) 2012504Sdlw } 2022504Sdlw else 2032504Sdlw { 2042504Sdlw if(scale>0) 2052504Sdlw for(i=0;i<scale;i++) 2062504Sdlw PUT(*s++) 2072504Sdlw PUT('.') 2082504Sdlw for(i=0;i<d;i++) 2092504Sdlw PUT(*s++) 2102504Sdlw } 2112504Sdlw dp -= scale; 2122504Sdlw sprintf(ex,"%d",abs(dp)); 2132504Sdlw if((pad=strlen(ex))>e) 2142504Sdlw { if(pad>(++e)) 2152504Sdlw { PUT(expch) 2162504Sdlw for(i=0;i<e;i++) PUT('*') 2172504Sdlw return(OK); 2182504Sdlw } 2192504Sdlw } 2202504Sdlw else PUT(expch) 2212504Sdlw PUT(dp<0?'-':'+') 2222504Sdlw for(i=0;i<(e-pad);i++) PUT('0') /* was ' ' */ 2232504Sdlw s= &ex[0]; 2242504Sdlw while(*s) PUT(*s++) 2252504Sdlw return(OK); 2262504Sdlw } 2272504Sdlw 2282504Sdlw wrt_G(p,w,d,e,len) ufloat *p; ftnlen len; 2292504Sdlw { double uplim = 1.0, x; 2302504Sdlw int i,oldscale,n,j,ne; 2312504Sdlw x=(len==sizeof(float)?(double)p->pf:p->pd); 2322504Sdlw i=d; 2332504Sdlw if(x==0.0) goto zero; 2342504Sdlw x = abs(x); 2352504Sdlw if(x>=0.1) 2362504Sdlw { 2372504Sdlw for(i=0; i<=d; i++, uplim*=10.0) 2387456Sdlw { if(x>=uplim) continue; 2392504Sdlw zero: oldscale=scale; 2402504Sdlw scale=0; 2412504Sdlw ne = e+2; 2422504Sdlw if(n = wrt_F(p,w-ne,d-i,len)) return(n); 2432504Sdlw for(j=0; j<ne; j++) PUT(' ') 2442504Sdlw scale=oldscale; 2452504Sdlw return(OK); 2462504Sdlw } 2472504Sdlw /* falling off the bottom implies E format */ 2482504Sdlw } 24912039Sdlw return(wrt_E(p,w,d,e,len,'e')); 2502504Sdlw } 2512504Sdlw 2522504Sdlw wrt_F(p,w,d,len) ufloat *p; ftnlen len; 2532504Sdlw { int i,delta,dp,sign,n,nf; 2542504Sdlw double x; 2552504Sdlw char *s,*fcvt(); 2562504Sdlw x= (len==sizeof(float)?(double)p->pf:p->pd); 2572504Sdlw if(scale && x!=0.0) 2582504Sdlw { if(scale>0) 2592504Sdlw for(i=0;i<scale;i++) x*=10; 2602504Sdlw else for(i=0;i<-scale;i++) x/=10; 2612504Sdlw } 2622504Sdlw s=fcvt(x,d,&dp,&sign); 2632504Sdlw /* if(-dp>=d) sign=0; ?? */ 2642504Sdlw delta=1; 2652504Sdlw if(sign || cplus) delta++; 2662504Sdlw nf = w - (d + delta + (dp>0?dp:0)); 2672504Sdlw if(nf<0) 2682504Sdlw { 2692504Sdlw for(i=0;i<w;i++) PUT('*') 2702504Sdlw return(OK); 2712504Sdlw } 2722504Sdlw if(nf>0) for(i=0; i<(nf-(dp<=0?1:0)); i++) PUT(' ') 2732504Sdlw if(sign) PUT('-') 2742504Sdlw else if(cplus) PUT('+') 2752504Sdlw if(dp>0) for(i=0;i<dp;i++) PUT(*s++) 2762504Sdlw else if(nf>0) PUT('0') 2772504Sdlw PUT('.') 2782504Sdlw for(i=0; i< -dp && i<d; i++) PUT('0') 2792504Sdlw for(;i<d;i++) 2803561Sdlw { if(x==0.0 && !cblank) PUT(' ') /* exactly zero */ 2812504Sdlw else if(*s) PUT(*s++) 2822504Sdlw else PUT('0') 2832504Sdlw } 2842504Sdlw return(OK); 2852504Sdlw } 286