1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)wrtfmt.c 5.1 06/07/85 7 */ 8 9 /* 10 * formatted write routines 11 */ 12 13 #include "fio.h" 14 #include "format.h" 15 16 extern char *icvt(); 17 extern char *s_init; 18 19 #define abs(x) (x<0?-x:x) 20 21 w_ed(p,ptr,len) char *ptr; struct syl *p; ftnlen len; 22 { int n; 23 if(cursor && (n=wr_mvcur())) return(n); 24 switch(p->op) 25 { 26 case I: 27 case IM: 28 return(wrt_IM(ptr,p->p1,p->p2,len)); 29 case L: 30 return(wrt_L(ptr,p->p1,len)); 31 case A: 32 return(wrt_AW(ptr,len,len)); 33 case AW: 34 return(wrt_AW(ptr,p->p1,len)); 35 case D: 36 return(wrt_E(ptr,p->p1,p->p2,2,len,'d')); 37 case DE: 38 return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'d')); 39 case E: 40 return(wrt_E(ptr,p->p1,p->p2,2,len,'e')); 41 case EE: 42 return(wrt_E(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len,'e')); 43 case G: 44 return(wrt_G(ptr,p->p1,p->p2,2,len)); 45 case GE: 46 return(wrt_G(ptr,p->p1,(p->p2)&0xff,((p->p2)>>8)&0xff,len)); 47 case F: 48 return(wrt_F(ptr,p->p1,p->p2,len)); 49 default: 50 return(errno=F_ERFMT); 51 } 52 } 53 54 w_ned(p,ptr) char *ptr; struct syl *p; 55 { 56 switch(p->op) 57 { 58 case SLASH: 59 return((*donewrec)()); 60 case T: 61 if(p->p1) cursor = p->p1 - recpos - 1; 62 #ifndef KOSHER 63 else cursor = 8*p->p2 - recpos%8; /* NOT STANDARD FORT */ 64 #endif 65 tab = YES; 66 return(OK); 67 case TL: 68 cursor -= p->p1; 69 if ((recpos + cursor) < 0) cursor = -recpos; /* ANSI req'd */ 70 tab = YES; 71 return(OK); 72 case TR: 73 case X: 74 cursor += p->p1; 75 /* tab = (p->op == TR); this would implement destructive X */ 76 tab = YES; 77 return(OK); 78 case APOS: 79 return(wrt_AP(&s_init[p->p1])); 80 case H: 81 return(wrt_H(p->p1,&s_init[p->p2])); 82 default: 83 return(errno=F_ERFMT); 84 } 85 } 86 87 LOCAL 88 wr_mvcur() 89 { int n; 90 if(tab) return((*dotab)()); 91 if (cursor < 0) return(errno=F_ERSEEK); 92 while(cursor--) PUT(' ') 93 return(cursor=0); 94 } 95 96 LOCAL 97 wrt_IM(ui,w,m,len) uint *ui; ftnlen len; 98 { int ndigit,sign,spare,i,xsign,n; 99 long x; 100 char *ans; 101 if(sizeof(short)==len) x=ui->is; 102 /* else if(len == sizeof(char)) x = ui->ic; */ 103 else x=ui->il; 104 if(x==0 && m==0) 105 { for(i=0;i<w;i++) PUT(' ') 106 return(OK); 107 } 108 ans=icvt(x,&ndigit,&sign); 109 if(sign || cplus) xsign=1; 110 else xsign=0; 111 if(ndigit+xsign>w || m+xsign>w) 112 { for(i=0;i<w;i++) PUT('*') 113 return(OK); 114 } 115 if(ndigit>=m) 116 spare=w-ndigit-xsign; 117 else 118 spare=w-m-xsign; 119 for(i=0;i<spare;i++) PUT(' ') 120 if(sign) PUT('-') 121 else if(cplus) PUT('+') 122 for(i=0;i<m-ndigit;i++) PUT('0') 123 for(i=0;i<ndigit;i++) PUT(*ans++) 124 return(OK); 125 } 126 127 LOCAL 128 wrt_AP(p) 129 { char *s,quote; 130 int n; 131 if(cursor && (n=wr_mvcur())) return(n); 132 s=(char *)p; 133 quote = *s++; 134 for(; *s; s++) 135 { if(*s!=quote) PUT(*s) 136 else if(*++s==quote) PUT(*s) 137 else return(OK); 138 } 139 return(OK); 140 } 141 142 LOCAL 143 wrt_H(a,b) 144 { char *s=(char *)b; 145 int n; 146 if(cursor && (n=wr_mvcur())) return(n); 147 while(a--) PUT(*s++) 148 return(OK); 149 } 150 151 wrt_L(l,width,len) uint *l; ftnlen len; 152 { int i,n; 153 for(i=0;i<width-1;i++) PUT(' ') 154 if(len == sizeof (short)) 155 i = l->is; 156 else 157 i = l->il; 158 if(i) PUT('t') 159 else PUT('f') 160 return(OK); 161 } 162 163 LOCAL 164 wrt_AW(p,w,len) char * p; ftnlen len; 165 { int n; 166 while(w>len) 167 { w--; 168 PUT(' ') 169 } 170 while(w-- > 0) 171 PUT(*p++) 172 return(OK); 173 } 174 175 wrt_E(p,w,d,e,len,expch) ufloat *p; ftnlen len; char expch; 176 { char *s,ex[4]; 177 int dd,dp,sign,i,delta,pad,n; 178 char *ecvt(); 179 180 if((len==sizeof(float)?p->pf:p->pd)==0.0) 181 { 182 n = cblank; 183 cblank = 1; /* force '0' fill */ 184 wrt_F(p,w-(e+2),d,len); 185 cblank = n; 186 PUT(expch) 187 PUT('+') 188 /* for(i=0;i<(e-1);i++)PUT(' ') 189 deleted PUT('0') 190 */ 191 /* added */ for(i=0;i<e;i++) PUT('0') 192 return(OK); 193 } 194 if (scale > 0) { /* insane ANSI requirement */ 195 dd = d + 1; 196 d = dd - scale; 197 } else 198 dd = d + scale; 199 if (dd <= 0 || d < 0) goto E_badfield; 200 s=ecvt( (len==sizeof(float)?(double)p->pf:p->pd) ,dd,&dp,&sign); 201 delta = 3+e; 202 if(sign||cplus) delta++; 203 pad=w-(delta+d)-(scale>0? scale:0); 204 if(pad<0) { 205 E_badfield: 206 for(i=0;i<w;i++) PUT('*') 207 return(OK); 208 } 209 for(i=0;i<(pad-(scale<=0?1:0));i++) PUT(' ') 210 if(sign) PUT('-') 211 else if(cplus) PUT('+') 212 if(scale<=0 && pad) PUT('0') 213 if(scale<0 && scale > -d) 214 { 215 PUT('.') 216 for(i=0;i<-scale;i++) 217 PUT('0') 218 for(i=0;i<d+scale;i++) 219 PUT(*s++) 220 } 221 else 222 { 223 if(scale>0) 224 for(i=0;i<scale;i++) 225 PUT(*s++) 226 PUT('.') 227 for(i=0;i<d;i++) 228 PUT(*s++) 229 } 230 dp -= scale; 231 sprintf(ex,"%d",abs(dp)); 232 if((pad=strlen(ex))>e) 233 { if(pad>(++e)) 234 { PUT(expch) 235 for(i=0;i<e;i++) PUT('*') 236 return(OK); 237 } 238 } 239 else PUT(expch) 240 PUT(dp<0?'-':'+') 241 for(i=0;i<(e-pad);i++) PUT('0') /* was ' ' */ 242 s= &ex[0]; 243 while(*s) PUT(*s++) 244 return(OK); 245 } 246 247 LOCAL 248 wrt_G(p,w,d,e,len) ufloat *p; ftnlen len; 249 { double uplim = 1.0, x; 250 int i,oldscale,n,j,ne; 251 x=(len==sizeof(float)?(double)p->pf:p->pd); 252 i=d; 253 if(x==0.0) goto zero; 254 x = abs(x); 255 if(x>=0.1) 256 { 257 for(i=0; i<=d; i++, uplim*=10.0) 258 { if(x>=uplim) continue; 259 zero: oldscale=scale; 260 scale=0; 261 ne = e+2; 262 if(n = wrt_F(p,w-ne,d-i,len)) return(n); 263 for(j=0; j<ne; j++) PUT(' ') 264 scale=oldscale; 265 return(OK); 266 } 267 /* falling off the bottom implies E format */ 268 } 269 return(wrt_E(p,w,d,e,len,'e')); 270 } 271 272 wrt_F(p,w,d,len) ufloat *p; ftnlen len; 273 { int i,delta,dp,sign,n,nf; 274 double x; 275 char *s,*fcvt(); 276 x= (len==sizeof(float)?(double)p->pf:p->pd); 277 if(scale && x!=0.0) 278 { if(scale>0) 279 for(i=0;i<scale;i++) x*=10; 280 else for(i=0;i<-scale;i++) x/=10; 281 } 282 s=fcvt(x,d,&dp,&sign); 283 /* if(-dp>=d) sign=0; ?? */ 284 delta=1; 285 if(sign || cplus) delta++; 286 nf = w - (d + delta + (dp>0?dp:0)); 287 if(nf<0) 288 { 289 for(i=0;i<w;i++) PUT('*') 290 return(OK); 291 } 292 if(nf>0) for(i=0; i<(nf-(dp<=0?1:0)); i++) PUT(' ') 293 if(sign) PUT('-') 294 else if(cplus) PUT('+') 295 if(dp>0) for(i=0;i<dp;i++) PUT(*s++) 296 else if(nf>0) PUT('0') 297 PUT('.') 298 for(i=0; i< -dp && i<d; i++) PUT('0') 299 for(;i<d;i++) 300 { if(x==0.0 && !cblank) PUT(' ') /* exactly zero */ 301 else if(*s) PUT(*s++) 302 else PUT('0') 303 } 304 return(OK); 305 } 306