12504Sdlw /* 2*20984Slibs char id_wrtfmt[] = "@(#)wrtfmt.c 1.11"; 32504Sdlw * 42504Sdlw * formatted write routines 52504Sdlw */ 62504Sdlw 72504Sdlw #include "fio.h" 82603Sdlw #include "format.h" 92504Sdlw 102504Sdlw extern char *icvt(); 1117969Slibs extern char *s_init; 122504Sdlw 132504Sdlw #define abs(x) (x<0?-x:x) 142504Sdlw 152504Sdlw w_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len; 162504Sdlw { int n; 172504Sdlw if(cursor && (n=wr_mvcur())) return(n); 182504Sdlw switch(p->op) 192504Sdlw { 202504Sdlw case I: 212504Sdlw case IM: 222504Sdlw return(wrt_IM(ptr,p->p1,p->p2,len)); 232504Sdlw case L: 2419985Slibs return(wrt_L(ptr,p->p1,len)); 252504Sdlw case A: 2617969Slibs return(wrt_AW(ptr,len,len)); 272504Sdlw case AW: 282504Sdlw return(wrt_AW(ptr,p->p1,len)); 292504Sdlw case D: 3017969Slibs return(wrt_E(ptr,p->p1,p->p2,2,len,'d')); 312504Sdlw case DE: 3217969Slibs return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'d')); 332504Sdlw case E: 3417969Slibs return(wrt_E(ptr,p->p1,p->p2,2,len,'e')); 352504Sdlw case EE: 3617969Slibs return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'e')); 372504Sdlw case G: 3817969Slibs return(wrt_G(ptr,p->p1,p->p2,2,len)); 392504Sdlw case GE: 4017969Slibs return(wrt_G(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len)); 412504Sdlw case F: 422504Sdlw return(wrt_F(ptr,p->p1,p->p2,len)); 432504Sdlw default: 442603Sdlw return(errno=F_ERFMT); 452504Sdlw } 462504Sdlw } 472504Sdlw 482504Sdlw w_ned(p,ptr) char *ptr; struct syl *p; 492504Sdlw { 502504Sdlw switch(p->op) 512504Sdlw { 522504Sdlw case SLASH: 532504Sdlw return((*donewrec)()); 542504Sdlw case T: 552504Sdlw if(p->p1) cursor = p->p1 - recpos - 1; 562504Sdlw #ifndef KOSHER 572504Sdlw else cursor = 8*p->p2 - recpos%8; /* NOT STANDARD FORT */ 582504Sdlw #endif 592504Sdlw tab = YES; 602504Sdlw return(OK); 612504Sdlw case TL: 622504Sdlw cursor -= p->p1; 6312371Sdlw if ((recpos + cursor) < 0) cursor = -recpos; /* ANSI req'd */ 642504Sdlw tab = YES; 652504Sdlw return(OK); 662504Sdlw case TR: 672504Sdlw case X: 682504Sdlw cursor += p->p1; 6912371Sdlw /* tab = (p->op == TR); this would implement destructive X */ 7012371Sdlw tab = YES; 712504Sdlw return(OK); 722504Sdlw case APOS: 7317969Slibs return(wrt_AP(&s_init[p->p1])); 742504Sdlw case H: 7517969Slibs return(wrt_H(p->p1,&s_init[p->p2])); 762504Sdlw default: 772603Sdlw return(errno=F_ERFMT); 782504Sdlw } 792504Sdlw } 802504Sdlw 81*20984Slibs LOCAL 822504Sdlw wr_mvcur() 832504Sdlw { int n; 842504Sdlw if(tab) return((*dotab)()); 8512466Sdlw if (cursor < 0) return(errno=F_ERSEEK); 862504Sdlw while(cursor--) PUT(' ') 872504Sdlw return(cursor=0); 882504Sdlw } 892504Sdlw 90*20984Slibs LOCAL 912504Sdlw wrt_IM(ui,w,m,len) uint *ui; ftnlen len; 922504Sdlw { int ndigit,sign,spare,i,xsign,n; 932504Sdlw long x; 942504Sdlw char *ans; 952504Sdlw if(sizeof(short)==len) x=ui->is; 962504Sdlw /* else if(len == sizeof(char)) x = ui->ic; */ 972504Sdlw else x=ui->il; 982504Sdlw if(x==0 && m==0) 992504Sdlw { for(i=0;i<w;i++) PUT(' ') 1002504Sdlw return(OK); 1012504Sdlw } 1022504Sdlw ans=icvt(x,&ndigit,&sign); 1032504Sdlw if(sign || cplus) xsign=1; 1042504Sdlw else xsign=0; 1052504Sdlw if(ndigit+xsign>w || m+xsign>w) 1062504Sdlw { for(i=0;i<w;i++) PUT('*') 1072504Sdlw return(OK); 1082504Sdlw } 1092504Sdlw if(ndigit>=m) 1102504Sdlw spare=w-ndigit-xsign; 1112504Sdlw else 1122504Sdlw spare=w-m-xsign; 1132504Sdlw for(i=0;i<spare;i++) PUT(' ') 1142504Sdlw if(sign) PUT('-') 1152504Sdlw else if(cplus) PUT('+') 1162504Sdlw for(i=0;i<m-ndigit;i++) PUT('0') 1172504Sdlw for(i=0;i<ndigit;i++) PUT(*ans++) 1182504Sdlw return(OK); 1192504Sdlw } 1202504Sdlw 121*20984Slibs LOCAL 1222504Sdlw wrt_AP(p) 1232504Sdlw { char *s,quote; 1242504Sdlw int n; 1252504Sdlw if(cursor && (n=wr_mvcur())) return(n); 1262504Sdlw s=(char *)p; 1272504Sdlw quote = *s++; 1282504Sdlw for(; *s; s++) 1292504Sdlw { if(*s!=quote) PUT(*s) 1302504Sdlw else if(*++s==quote) PUT(*s) 1312504Sdlw else return(OK); 1322504Sdlw } 1332504Sdlw return(OK); 1342504Sdlw } 1352504Sdlw 136*20984Slibs LOCAL 1372504Sdlw wrt_H(a,b) 1382504Sdlw { char *s=(char *)b; 1392504Sdlw int n; 1402504Sdlw if(cursor && (n=wr_mvcur())) return(n); 1412504Sdlw while(a--) PUT(*s++) 1422504Sdlw return(OK); 1432504Sdlw } 1442504Sdlw 14519985Slibs wrt_L(l,width,len) uint *l; ftnlen len; 1462504Sdlw { int i,n; 14719985Slibs for(i=0;i<width-1;i++) PUT(' ') 14819985Slibs if(len == sizeof (short)) 14919985Slibs i = l->is; 15019985Slibs else 15119985Slibs i = l->il; 15219985Slibs if(i) PUT('t') 1532504Sdlw else PUT('f') 1542504Sdlw return(OK); 1552504Sdlw } 1562504Sdlw 157*20984Slibs LOCAL 1582504Sdlw wrt_AW(p,w,len) char * p; ftnlen len; 1592504Sdlw { int n; 1602504Sdlw while(w>len) 1612504Sdlw { w--; 1622504Sdlw PUT(' ') 1632504Sdlw } 1642504Sdlw while(w-- > 0) 1652504Sdlw PUT(*p++) 1662504Sdlw return(OK); 1672504Sdlw } 1682504Sdlw 16912039Sdlw wrt_E(p,w,d,e,len,expch) ufloat *p; ftnlen len; char expch; 17012039Sdlw { char *s,ex[4]; 1712504Sdlw int dd,dp,sign,i,delta,pad,n; 1722504Sdlw char *ecvt(); 17312039Sdlw 1742504Sdlw if((len==sizeof(float)?p->pf:p->pd)==0.0) 1752504Sdlw { 17617229Sdlw n = cblank; 17717229Sdlw cblank = 1; /* force '0' fill */ 1782504Sdlw wrt_F(p,w-(e+2),d,len); 17917229Sdlw cblank = n; 1802504Sdlw PUT(expch) 1812504Sdlw PUT('+') 1822504Sdlw /* for(i=0;i<(e-1);i++)PUT(' ') 1832504Sdlw deleted PUT('0') 1842504Sdlw */ 1852504Sdlw /* added */ for(i=0;i<e;i++) PUT('0') 1862504Sdlw return(OK); 1872504Sdlw } 18812371Sdlw if (scale > 0) { /* insane ANSI requirement */ 18912371Sdlw dd = d + 1; 19012371Sdlw d = dd - scale; 19112371Sdlw } else 19212371Sdlw dd = d + scale; 19312371Sdlw if (dd <= 0 || d < 0) goto E_badfield; 1942504Sdlw s=ecvt( (len==sizeof(float)?(double)p->pf:p->pd) ,dd,&dp,&sign); 1952504Sdlw delta = 3+e; 1962504Sdlw if(sign||cplus) delta++; 1972504Sdlw pad=w-(delta+d)-(scale>0? scale:0); 19812371Sdlw if(pad<0) { 19912371Sdlw E_badfield: 20012371Sdlw for(i=0;i<w;i++) PUT('*') 2012504Sdlw return(OK); 2022504Sdlw } 2032504Sdlw for(i=0;i<(pad-(scale<=0?1:0));i++) PUT(' ') 2042504Sdlw if(sign) PUT('-') 2052504Sdlw else if(cplus) PUT('+') 2062504Sdlw if(scale<=0 && pad) PUT('0') 2072504Sdlw if(scale<0 && scale > -d) 2082504Sdlw { 2092504Sdlw PUT('.') 2102504Sdlw for(i=0;i<-scale;i++) 2112504Sdlw PUT('0') 2122504Sdlw for(i=0;i<d+scale;i++) 2132504Sdlw PUT(*s++) 2142504Sdlw } 2152504Sdlw else 2162504Sdlw { 2172504Sdlw if(scale>0) 2182504Sdlw for(i=0;i<scale;i++) 2192504Sdlw PUT(*s++) 2202504Sdlw PUT('.') 2212504Sdlw for(i=0;i<d;i++) 2222504Sdlw PUT(*s++) 2232504Sdlw } 2242504Sdlw dp -= scale; 2252504Sdlw sprintf(ex,"%d",abs(dp)); 2262504Sdlw if((pad=strlen(ex))>e) 2272504Sdlw { if(pad>(++e)) 2282504Sdlw { PUT(expch) 2292504Sdlw for(i=0;i<e;i++) PUT('*') 2302504Sdlw return(OK); 2312504Sdlw } 2322504Sdlw } 2332504Sdlw else PUT(expch) 2342504Sdlw PUT(dp<0?'-':'+') 2352504Sdlw for(i=0;i<(e-pad);i++) PUT('0') /* was ' ' */ 2362504Sdlw s= &ex[0]; 2372504Sdlw while(*s) PUT(*s++) 2382504Sdlw return(OK); 2392504Sdlw } 2402504Sdlw 241*20984Slibs LOCAL 2422504Sdlw wrt_G(p,w,d,e,len) ufloat *p; ftnlen len; 2432504Sdlw { double uplim = 1.0, x; 2442504Sdlw int i,oldscale,n,j,ne; 2452504Sdlw x=(len==sizeof(float)?(double)p->pf:p->pd); 2462504Sdlw i=d; 2472504Sdlw if(x==0.0) goto zero; 2482504Sdlw x = abs(x); 2492504Sdlw if(x>=0.1) 2502504Sdlw { 2512504Sdlw for(i=0; i<=d; i++, uplim*=10.0) 2527456Sdlw { if(x>=uplim) continue; 2532504Sdlw zero: oldscale=scale; 2542504Sdlw scale=0; 2552504Sdlw ne = e+2; 2562504Sdlw if(n = wrt_F(p,w-ne,d-i,len)) return(n); 2572504Sdlw for(j=0; j<ne; j++) PUT(' ') 2582504Sdlw scale=oldscale; 2592504Sdlw return(OK); 2602504Sdlw } 2612504Sdlw /* falling off the bottom implies E format */ 2622504Sdlw } 26312039Sdlw return(wrt_E(p,w,d,e,len,'e')); 2642504Sdlw } 2652504Sdlw 2662504Sdlw wrt_F(p,w,d,len) ufloat *p; ftnlen len; 2672504Sdlw { int i,delta,dp,sign,n,nf; 2682504Sdlw double x; 2692504Sdlw char *s,*fcvt(); 2702504Sdlw x= (len==sizeof(float)?(double)p->pf:p->pd); 2712504Sdlw if(scale && x!=0.0) 2722504Sdlw { if(scale>0) 2732504Sdlw for(i=0;i<scale;i++) x*=10; 2742504Sdlw else for(i=0;i<-scale;i++) x/=10; 2752504Sdlw } 2762504Sdlw s=fcvt(x,d,&dp,&sign); 2772504Sdlw /* if(-dp>=d) sign=0; ?? */ 2782504Sdlw delta=1; 2792504Sdlw if(sign || cplus) delta++; 2802504Sdlw nf = w - (d + delta + (dp>0?dp:0)); 2812504Sdlw if(nf<0) 2822504Sdlw { 2832504Sdlw for(i=0;i<w;i++) PUT('*') 2842504Sdlw return(OK); 2852504Sdlw } 2862504Sdlw if(nf>0) for(i=0; i<(nf-(dp<=0?1:0)); i++) PUT(' ') 2872504Sdlw if(sign) PUT('-') 2882504Sdlw else if(cplus) PUT('+') 2892504Sdlw if(dp>0) for(i=0;i<dp;i++) PUT(*s++) 2902504Sdlw else if(nf>0) PUT('0') 2912504Sdlw PUT('.') 2922504Sdlw for(i=0; i< -dp && i<d; i++) PUT('0') 2932504Sdlw for(;i<d;i++) 2943561Sdlw { if(x==0.0 && !cblank) PUT(' ') /* exactly zero */ 2952504Sdlw else if(*s) PUT(*s++) 2962504Sdlw else PUT('0') 2972504Sdlw } 2982504Sdlw return(OK); 2992504Sdlw } 300