Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / pcc / dist / pcc-libs / libI77 / fmt.c
blob0405aa0e38f53f70b1780c6b40a90166f1c22057
1 /* $Id: fmt.c,v 1.1.1.1 2008/08/24 05:34:47 gmcgarry 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 <stdlib.h>
37 #include "fio.h"
38 #include "fmt.h"
40 static int type_f(int);
41 static int ne_d(char *s,char **p);
42 static int e_d(char *s,char **p);
43 static int op_gen(int a,int b,int c,int d);
44 static char *ap_end(char *s);
46 #define skip(s) while(*s==' ') s++
47 #define SYLMX 300
48 #define GLITCH '\2'
49 /* special quote character for stu */
50 extern int cursor,scale;
51 extern flag cblank,cplus; /*blanks in I and compulsory plus*/
52 struct syl syl[SYLMX];
53 int parenlvl,pc,revloc;
54 static char *f_s(char *s, int curloc),*f_list(char *),
55 *i_tem(char *),*gt_num(char *s, int *n);
56 int
57 pars_f(s) char *s;
59 parenlvl=revloc=pc=0;
60 if((s=f_s(s,0))==NULL)
62 return(-1);
64 return(0);
67 char *
68 f_s(char *s, int curloc)
70 skip(s);
71 if(*s++!='(')
73 return(NULL);
75 if(parenlvl++ ==1) revloc=curloc;
76 if(op_gen(RET,curloc,0,0)<0 ||
77 (s=f_list(s))==NULL)
79 return(NULL);
81 skip(s);
82 return(s);
84 char *
85 f_list(char *s)
87 for(;*s!=0;)
88 { skip(s);
89 if((s=i_tem(s))==NULL) return(NULL);
90 skip(s);
91 if(*s==',') s++;
92 else if(*s==')')
93 { if(--parenlvl==0)
95 op_gen(REVERT,revloc,0,0);
96 return(++s);
98 op_gen(GOTO,0,0,0);
99 return(++s);
102 return(NULL);
104 char *
105 i_tem(char *s)
106 { char *t;
107 int n,curloc;
108 if(*s==')') return(s);
109 if(ne_d(s,&t)) return(t);
110 if(e_d(s,&t)) return(t);
111 s=gt_num(s,&n);
112 if((curloc=op_gen(STACK,n,0,0))<0) return(NULL);
113 return(f_s(s,curloc));
117 ne_d(char *s,char **p)
118 { int n,x,sign=0;
119 switch(*s)
121 default: return(0);
122 case ':': op_gen(COLON,0,0,0); break;
123 case 'b':
124 if(*++s=='z') op_gen(BZ,0,0,0);
125 else op_gen(BN,0,0,0);
126 break;
127 case 's':
128 if(*(s+1)=='s')
129 { x=SS;
130 s++;
132 else if(*(s+1)=='p')
133 { x=SP;
134 s++;
136 else x=S;
137 op_gen(x,0,0,0);
138 break;
139 case '/': op_gen(SLASH,0,0,0); break;
140 case '-': sign=1; s++; /*OUTRAGEOUS CODING TRICK*/
141 case '0': case '1': case '2': case '3': case '4':
142 case '5': case '6': case '7': case '8': case '9':
143 s=gt_num(s,&n);
144 switch(*s)
146 default: return(0);
147 case 'p': if(sign) n= -n; op_gen(P,n,0,0); break;
148 case 'x': op_gen(X,n,0,0); break;
149 case 'H':
150 case 'h': op_gen(H,n,(int)(s+1),0);
151 s+=n;
152 break;
154 break;
155 case GLITCH:
156 case '"':
157 case '\'': op_gen(APOS,(int)s,0,0);
158 *p=ap_end(s);
159 return(1);
160 case 't':
161 if(*(s+1)=='l')
162 { x=TL;
163 s++;
165 else if(*(s+1)=='r')
166 { x=TR;
167 s++;
169 else x=T;
170 s=gt_num(s+1,&n);
171 op_gen(x,n,0,0);
172 break;
173 case 'x': op_gen(X,1,0,0); break;
174 case 'p': op_gen(P,1,0,0); break;
176 s++;
177 *p=s;
178 return(1);
182 e_d(char *s,char **p)
183 { int n,w,d,e,found=0,x=0;
184 char *sv=s;
185 s=gt_num(s,&n);
186 op_gen(STACK,n,0,0);
187 switch(*s++)
189 default: break;
190 case 'e': x=1;
191 case 'g':
192 found=1;
193 s=gt_num(s,&w);
194 if(w==0) break;
195 if(*s=='.')
196 { s++;
197 s=gt_num(s,&d);
199 else d=0;
200 if(*s!='E')
201 op_gen(x==1?E:G,w,d,0);
202 else
203 { s++;
204 s=gt_num(s,&e);
205 op_gen(x==1?EE:GE,w,d,e);
207 break;
208 case 'l':
209 found=1;
210 s=gt_num(s,&w);
211 if(w==0) break;
212 op_gen(L,w,0,0);
213 break;
214 case 'a':
215 found=1;
216 skip(s);
217 if(*s>='0' && *s<='9')
218 { s=gt_num(s,&w);
219 if(w==0) break;
220 op_gen(AW,w,0,0);
221 break;
223 op_gen(A,0,0,0);
224 break;
225 case 'f':
226 found=1;
227 s=gt_num(s,&w);
228 if(w==0) break;
229 if(*s=='.')
230 { s++;
231 s=gt_num(s,&d);
233 else d=0;
234 op_gen(F,w,d,0);
235 break;
236 case 'd':
237 found=1;
238 s=gt_num(s,&w);
239 if(w==0) break;
240 if(*s=='.')
241 { s++;
242 s=gt_num(s,&d);
244 else d=0;
245 op_gen(D,w,d,0);
246 break;
247 case 'i':
248 found=1;
249 s=gt_num(s,&w);
250 if(w==0) break;
251 if(*s!='.')
252 { op_gen(I,w,0,0);
253 break;
255 s++;
256 s=gt_num(s,&d);
257 op_gen(IM,w,d,0);
258 break;
260 if(found==0)
261 { pc--; /*unSTACK*/
262 *p=sv;
263 return(0);
265 *p=s;
266 return(1);
270 op_gen(int a,int b,int c,int d)
271 { struct syl *p= &syl[pc];
272 if(pc>=SYLMX)
273 { fprintf(stderr,"format too complicated:\n%s\n",
274 fmtbuf);
275 abort();
277 p->op=a;
278 p->p1=b;
279 p->p2=c;
280 p->p3=d;
281 return(pc++);
283 char *
284 gt_num(char *s, int *n)
285 { int m=0,cnt=0;
286 char c;
287 for(c= *s;;c = *s)
288 { if(c==' ')
289 { s++;
290 continue;
292 if(c>'9' || c<'0') break;
293 m=10*m+c-'0';
294 cnt++;
295 s++;
297 if(cnt==0) *n=1;
298 else *n=m;
299 return(s);
301 #define STKSZ 10
302 int cnt[STKSZ],ret[STKSZ],cp,rp;
303 flag workdone;
306 en_fio()
307 { ftnint one=1;
308 return(do_fio(&one,NULL,0l));
312 do_fio(ftnint *number, char *ptr, ftnlen len)
314 struct syl *p;
315 int n,i;
316 for(i=0;i<*number;i++,ptr+=len)
318 loop: switch(type_f((p= &syl[pc])->op))
320 default:
321 fprintf(stderr,"unknown code in do_fio: %d\n%s\n",
322 p->op,fmtbuf);
323 err(elist->cierr,100,"do_fio");
324 case NED:
325 if((*doned)(p,ptr))
326 { pc++;
327 goto loop;
329 pc++;
330 continue;
331 case ED:
332 if(cnt[cp]<=0)
333 { cp--;
334 pc++;
335 goto loop;
337 if(ptr==NULL)
338 return((*doend)());
339 cnt[cp]--;
340 workdone=1;
341 if((n=(*doed)(p,ptr,len))>0) err(elist->cierr,errno,"fmt");
342 if(n<0) err(elist->ciend,(EOF),"fmt");
343 continue;
344 case STACK:
345 cnt[++cp]=p->p1;
346 pc++;
347 goto loop;
348 case RET:
349 ret[++rp]=p->p1;
350 pc++;
351 goto loop;
352 case GOTO:
353 if(--cnt[cp]<=0)
354 { cp--;
355 rp--;
356 pc++;
357 goto loop;
359 pc=1+ret[rp--];
360 goto loop;
361 case REVERT:
362 rp=cp=0;
363 pc = p->p1;
364 if(ptr==NULL)
365 return((*doend)());
366 if(!workdone) return(0);
367 if((n=(*dorevert)()) != 0) return(n);
368 goto loop;
369 case COLON:
370 if(ptr==NULL)
371 return((*doend)());
372 pc++;
373 goto loop;
374 case S:
375 case SS:
376 cplus=0;
377 pc++;
378 goto loop;
379 case SP:
380 cplus = 1;
381 pc++;
382 goto loop;
383 case P: scale=p->p1;
384 pc++;
385 goto loop;
386 case BN:
387 cblank=0;
388 pc++;
389 goto loop;
390 case BZ:
391 cblank=1;
392 pc++;
393 goto loop;
396 return(0);
399 void
400 fmt_bg()
402 workdone=cp=rp=pc=cursor=0;
403 cnt[0]=ret[0]=0;
407 type_f(n)
409 switch(n)
411 default:
412 return(n);
413 case RET:
414 return(RET);
415 case REVERT: return(REVERT);
416 case GOTO: return(GOTO);
417 case STACK: return(STACK);
418 case X:
419 case SLASH:
420 case APOS: case H:
421 case T: case TL: case TR:
422 return(NED);
423 case F:
424 case I:
425 case IM:
426 case A: case AW:
427 case L:
428 case E: case EE: case D:
429 case G: case GE:
430 return(ED);
433 char *
434 ap_end(char *s)
435 { char quote;
436 quote= *s++;
437 for(;*s;s++)
438 { if(*s!=quote) continue;
439 if(*++s!=quote) return(s);
441 if(elist->cierr)
442 errno= 100;
443 else
444 fatal(100,"bad string");
445 return s;