* add p cc
[mascara-docs.git] / compilers / pcc / pcc-libs-1.0.0 / libI77 / wrtfmt.c
blob6c032025062390bda85ea946ad73ac6b4e6dea23
1 /* $Id: wrtfmt.c,v 1.3 2008/03/01 13:42:02 ragge Exp $ */
2 /*
3 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * Redistributions of source code and documentation must retain the above
10 * copyright notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditionsand the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed or owned by Caldera
17 * International, Inc.
18 * Neither the name of Caldera International, Inc. nor the names of other
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
22 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
35 #include <stdio.h>
36 #include <stdlib.h>
38 #include "fio.h"
39 #include "fmt.h"
41 int wrt_I(unint *n,int w,ftnlen len);
42 int wrt_IM(unint *n,int w,int m,ftnlen len);
43 int wrt_AP(int n);
44 int wrt_A(char *p,ftnlen len);
45 int wrt_AW(char *p, int w,ftnlen len);
46 int wrt_G(ufloat *p,int w,int d,int e,ftnlen len);
47 int wrt_H(int a,int b);
49 extern int cursor;
50 static int
51 mv_cur(void)
52 { /*buggy, could move off front of record*/
53 for(;cursor>0;cursor--) (*putn)(' ');
54 if(cursor<0)
56 if(cursor+recpos<0) err(elist->cierr,110,"left off");
57 if(curunit->useek) fseek(cf,(long)cursor,1);
58 else err(elist->cierr,106,"fmt");
59 cursor=0;
61 return(0);
64 int
65 w_ed(struct syl *p, void *ptr, ftnlen len)
67 if(mv_cur()) return(mv_cur());
68 switch(p->op)
70 default:
71 fprintf(stderr,"w_ed, unexpected code: %d\n%s\n",
72 p->op,fmtbuf);
73 abort();
74 case I: return(wrt_I(ptr,p->p1,len));
75 case IM:
76 return(wrt_IM(ptr,p->p1,p->p2,len));
77 case L: return(wrt_L(ptr,p->p1));
78 case A: return(wrt_A(ptr,len));
79 case AW:
80 return(wrt_AW(ptr,p->p1,len));
81 case D:
82 case E:
83 case EE:
84 return(wrt_E(ptr,p->p1,p->p2,p->p3,len));
85 case G:
86 case GE:
87 return(wrt_G(ptr,p->p1,p->p2,p->p3,len));
88 case F: return(wrt_F(ptr,p->p1,p->p2,len));
92 int
93 w_ned(struct syl *p, char *ptr)
95 switch(p->op)
97 default: fprintf(stderr,"w_ned, unexpected code: %d\n%s\n",
98 p->op,fmtbuf);
99 abort();
100 case SLASH:
101 return((*donewrec)());
102 case T: cursor = p->p1-recpos;
103 return(1);
104 case TL: cursor -= p->p1;
105 return(1);
106 case TR:
107 case X:
108 cursor += p->p1;
109 return(1);
110 case APOS:
111 return(wrt_AP(p->p1));
112 case H:
113 return(wrt_H(p->p1,p->p2));
118 wrt_I(unint *n,int w,ftnlen len)
119 { int ndigit,sign,spare,i;
120 long x;
121 char *ans;
122 if(len==sizeof(short)) x=n->is;
123 else if(len == sizeof(char)) x = n->ic;
124 else x=n->il;
125 ans=icvt(x,&ndigit,&sign);
126 spare=w-ndigit;
127 if(sign || cplus) spare--;
128 if(spare<0)
129 for(i=0;i<len;i++) (*putn)('*');
130 else
131 { for(i=0;i<spare;i++) (*putn)(' ');
132 if(sign) (*putn)('-');
133 else if(cplus) (*putn)('+');
134 for(i=0;i<ndigit;i++) (*putn)(*ans++);
136 return(0);
140 wrt_IM(unint *n,int w,int m,ftnlen len)
141 { int ndigit,sign,spare,i,xsign;
142 long x;
143 char *ans;
144 if(sizeof(short)==len) x=n->is;
145 else if(len == sizeof(char)) x = n->ic;
146 else x=n->il;
147 ans=icvt(x,&ndigit,&sign);
148 if(sign || cplus) xsign=1;
149 else xsign=0;
150 if(ndigit+xsign>w || m+xsign>w)
151 { for(i=0;i<w;i++) (*putn)('*');
152 return(0);
154 if(x==0 && m==0)
155 { for(i=0;i<w;i++) (*putn)(' ');
156 return(0);
158 if(ndigit>=m)
159 spare=w-ndigit-xsign;
160 else
161 spare=w-m-xsign;
162 for(i=0;i<spare;i++) (*putn)(' ');
163 if(sign) (*putn)('-');
164 else if(cplus) (*putn)('+');
165 for(i=0;i<m-ndigit;i++) (*putn)('0');
166 for(i=0;i<ndigit;i++) (*putn)(*ans++);
167 return(0);
171 wrt_AP(int n)
172 { char *s,quote;
173 if(mv_cur()) return(mv_cur());
174 s=(char *)n;
175 quote = *s++;
176 for(;*s;s++)
177 { if(*s!=quote) (*putn)(*s);
178 else if(*++s==quote) (*putn)(*s);
179 else return(1);
181 return(1);
185 wrt_H(int a,int b)
186 { char *s=(char *)b;
187 if(mv_cur()) return(mv_cur());
188 while(a--) (*putn)(*s++);
189 return(1);
193 wrt_L(ftnint *n, int len)
194 { int i;
195 for(i=0;i<len-1;i++)
196 (*putn)(' ');
197 if(*n) (*putn)('t');
198 else (*putn)('f');
199 return(0);
203 wrt_A(char *p,ftnlen len)
205 while(len-- > 0) (*putn)(*p++);
206 return(0);
210 wrt_AW(char *p, int w,ftnlen len)
212 while(w>len)
213 { w--;
214 (*putn)(' ');
216 while(w-- > 0)
217 (*putn)(*p++);
218 return(0);
221 #define MXSTR 80
222 char nr[MXSTR];
225 * Trivial ecvt implementation.
227 static char *
228 Xecvt(double value, int ndigit, int *decpt, int *sign)
230 char fmt[10];
231 char *w = nr;
233 if (ndigit > 70)
234 ndigit = 70;
236 snprintf(fmt, 10, "%%# .%de", ndigit-1);
237 snprintf(nr, MXSTR, fmt, value);
238 *sign = (*w == '-' ? 1 : 0);
239 w[2] = w[1];
240 *decpt = atoi(&nr[ndigit+3]) + 1;
241 nr[ndigit+2] = 0;
242 return &nr[2];
247 wrt_E(ufloat *p,int w,int d,int e, ftnlen len)
248 { char *s;
249 int dp,sign,i,delta;
251 if(scale>0) d++;
252 s=Xecvt( (len==sizeof(float)?p->pf:p->pd) ,d,&dp,&sign);
253 if(sign || cplus) delta=6;
254 else delta=5;
255 if(w<delta+d)
256 { for(i=0;i<w;i++) (*putn)('*');
257 return(0);
259 for(i=0;i<w-(delta+d);i++) (*putn)(' ');
260 if(sign) (*putn)('-');
261 else if(cplus) (*putn)('+');
262 if(scale<0 && scale > -d)
264 (*putn)('.');
265 for(i=0;i<-scale;i++)
266 (*putn)('0');
267 for(i=0;i<d+scale;i++)
268 (*putn)(*s++);
270 else if(scale>0 && scale<d+2)
271 { for(i=0;i<scale;i++)
272 (*putn)(*s++);
273 (*putn)('.');
274 for(i=0;i<d-scale;i++)
275 (*putn)(*s++);
277 else
278 { (*putn)('.');
279 for(i=0;i<d;i++) (*putn)(*s++);
281 if(p->pf != 0) dp -= scale;
282 else dp = 0;
283 if(dp < 100 && dp > -100) (*putn)('e');
284 if(dp<0)
285 { (*putn)('-');
286 dp = -dp;
288 else (*putn)('+');
289 if(e>=3 || dp >= 100)
290 { (*putn)(dp/100 + '0');
291 dp = dp % 100;
293 if(e!=1) (*putn)(dp/10+'0');
294 (*putn)(dp%10+'0');
295 return(0);
299 wrt_G(ufloat *p,int w,int d,int e,ftnlen len)
300 { double up = 1,x;
301 int i,oldscale=scale,n,j;
302 x= len==sizeof(float)?p->pf:p->pd;
303 if(x < 0 ) x = -x;
304 if(x<.1) return(wrt_E(p,w,d,e,len));
305 for(i=0;i<=d;i++,up*=10)
306 { if(x>up) continue;
307 scale=0;
308 if(e==0) n=4;
309 else n=e+2;
310 i=wrt_F(p,w-n,d-i,len);
311 for(j=0;j<n;j++) (*putn)(' ');
312 scale=oldscale;
313 return(i);
315 return(wrt_E(p,w,d,e,len));
319 * Simple fcvt() implementation.
321 static char *
322 Xfcvt(double value, int ndigit, int *decpt, int *sign)
324 char fmt[10];
325 char *w = nr;
327 if (ndigit > 70)
328 ndigit = 70;
330 snprintf(fmt, 10, "%%# .%df", ndigit);
331 snprintf(nr, MXSTR, fmt, value);
332 *sign = (*w == '-' ? 1 : 0);
333 if (w[1] == '0') {
334 *decpt = 0;
335 w+= 3;
336 } else {
337 for (w+= 1; *w && *w != '.'; w++)
339 *decpt = w - nr - 1;
340 while (*w)
341 *w = w[1], w++;
342 w = &nr[1];
344 return w;
349 wrt_F(ufloat *p, int w,int d, ftnlen len)
350 { int i,delta,dp,sign,n;
351 double x;
352 char *s;
354 x= (len==sizeof(float)?p->pf:p->pd);
355 if(scale)
356 { if(scale>0)
357 for(i=0;i<scale;i++) x*=10;
358 else for(i=0;i<-scale;i++) x/=10;
360 s=Xfcvt(x,d,&dp,&sign);
361 if(-dp>=d) sign=0;
362 if(sign || cplus) delta=2;
363 else delta=1;
364 n= w - (d+delta+(dp>0?dp:0));
365 if(n<0)
367 for(i=0;i<w;i++) PUT('*');
368 return(0);
370 for(i=0;i<n;i++) PUT(' ');
371 if(sign) PUT('-');
372 else if(cplus) PUT('+');
373 for(i=0;i<dp;i++) PUT(*s++);
374 PUT('.');
375 for(i=0;i< -dp && i<d;i++) PUT('0');
376 for(;i<d;i++)
377 { if(*s) PUT(*s++);
378 else PUT('0');
380 return(0);