|
|
1.1 root 1: /* @(#)fmt.c 1.3 */
2: /* 3.0 SID # 1.2 */
3: #include "fio.h"
4: #include "fmt.h"
5: #define skip(s) while(*s==' ') s++
6: #ifdef interdata
7: #define SYLMX 300
8: #endif
9: #ifdef pdp11
10: #define SYLMX 300
11: #endif
12: #ifdef vax
13: #define SYLMX 300
14: #endif
15: #ifndef SYLMX
16: #define SYLMX 300
17: #endif
18: #define GLITCH '\2'
19: /* special quote character for stu */
20: extern int cursor,scale;
21: extern flag cblank,cplus; /*blanks in I and compulsory plus*/
22: struct syl syl[SYLMX];
23: int parenlvl,pc,revloc;
24: char *f_s(),*f_list(),*i_tem(),*gt_num();
25: pars_f(s) char *s;
26: {
27: parenlvl=revloc=pc=0;
28: if((s=f_s(s,0))==NULL)
29: {
30: return(-1);
31: }
32: return(0);
33: }
34: char *f_s(s,curloc) char *s;
35: {
36: skip(s);
37: if(*s++!='(')
38: {
39: return(NULL);
40: }
41: if(parenlvl++ ==1) revloc=curloc;
42: if(op_gen(RET,curloc,0,0)<0 ||
43: (s=f_list(s))==NULL)
44: {
45: return(NULL);
46: }
47: skip(s);
48: return(s);
49: }
50: char *f_list(s) char *s;
51: {
52: for(;*s!=0;)
53: { skip(s);
54: if((s=i_tem(s))==NULL) return(NULL);
55: skip(s);
56: if(*s==',') s++;
57: else if(*s==')')
58: { if(--parenlvl==0)
59: {
60: (void) op_gen(REVERT,revloc,0,0);
61: return(++s);
62: }
63: (void) op_gen(GOTO,0,0,0);
64: return(++s);
65: }
66: }
67: return(NULL);
68: }
69: char *i_tem(s) char *s;
70: { char *t;
71: int n,curloc;
72: if(*s==')') return(s);
73: if(ne_d(s,&t)) return(t);
74: if(e_d(s,&t)) return(t);
75: s=gt_num(s,&n);
76: if((curloc=op_gen(STACK,n,0,0))<0) return(NULL);
77: return(f_s(s,curloc));
78: }
79: ne_d(s,p) char *s,**p;
80: { int n,x,sign=0;
81: char *ap_end();
82: switch(*s)
83: {
84: default:
85: return(0);
86: case ':': (void) op_gen(COLON,0,0,0); break;
87: case '$':
88: (void) op_gen(NONL, 0, 0, 0); break;
89: case 'B':
90: case 'b':
91: if(*++s=='z' || *s == 'Z') (void) op_gen(BZ,0,0,0);
92: else (void) op_gen(BN,0,0,0);
93: break;
94: case 'S':
95: case 's':
96: if(*(s+1)=='s' || *(s+1) == 'S')
97: { x=SS;
98: s++;
99: }
100: else if(*(s+1)=='p' || *(s+1) == 'P')
101: { x=SP;
102: s++;
103: }
104: else x=S;
105: (void) op_gen(x,0,0,0);
106: break;
107: case '/': (void) op_gen(SLASH,0,0,0); break;
108: case '-': sign=1;
109: case '+': s++; /*OUTRAGEOUS CODING TRICK*/
110: case '0': case '1': case '2': case '3': case '4':
111: case '5': case '6': case '7': case '8': case '9':
112: s=gt_num(s,&n);
113: switch(*s)
114: {
115: default:
116: return(0);
117: case 'P':
118: case 'p': if(sign) n= -n; (void) op_gen(P,n,0,0); break;
119: case 'X':
120: case 'x': (void) op_gen(X,n,0,0); break;
121: case 'H':
122: case 'h': (void) op_gen(H,n,(int)(s+1),0);
123: s+=n;
124: break;
125: }
126: break;
127: case GLITCH:
128: case '"':
129: case '\'': (void) op_gen(APOS,(int)s,0,0);
130: if((*p = ap_end(s)) == NULL)
131: return(0);
132: return(1);
133: case 'T':
134: case 't':
135: if(*(s+1)=='l' || *(s+1) == 'L')
136: { x=TL;
137: s++;
138: }
139: else if(*(s+1)=='r'|| *(s+1) == 'R')
140: { x=TR;
141: s++;
142: }
143: else x=T;
144: s=gt_num(s+1,&n);
145: s--;
146: (void) op_gen(x,n,0,0);
147: break;
148: case 'X':
149: case 'x': (void) op_gen(X,1,0,0); break;
150: case 'P':
151: case 'p': (void) op_gen(P,1,0,0); break;
152: }
153: s++;
154: *p=s;
155: return(1);
156: }
157: e_d(s,p) char *s,**p;
158: { int n,w,d,e,found=0,x=0;
159: char *sv=s;
160: s=gt_num(s,&n);
161: (void) op_gen(STACK,n,0,0);
162: switch(*s++)
163: {
164: default: break;
165: case 'E':
166: case 'e': x=1;
167: case 'G':
168: case 'g':
169: found=1;
170: s=gt_num(s,&w);
171: if(w==0) break;
172: if(*s=='.')
173: { s++;
174: s=gt_num(s,&d);
175: }
176: else d=0;
177: if(*s!='E' && *s != 'e')
178: (void) op_gen(x==1?E:G,w,d,2); /* default is Ew.dE2 */
179: else
180: { s++;
181: s=gt_num(s,&e);
182: (void) op_gen(x==1?EE:GE,w,d,e);
183: }
184: break;
185: case 'O':
186: case 'o':
187: found = 1;
188: s = gt_num(s, &w);
189: if(w==0) break;
190: (void) op_gen(O, w, 0, 0);
191: break;
192: case 'L':
193: case 'l':
194: found=1;
195: s=gt_num(s,&w);
196: if(w==0) break;
197: (void) op_gen(L,w,0,0);
198: break;
199: case 'A':
200: case 'a':
201: found=1;
202: skip(s);
203: if(*s>='0' && *s<='9')
204: { s=gt_num(s,&w);
205: if(w==0) break;
206: (void) op_gen(AW,w,0,0);
207: break;
208: }
209: (void) op_gen(A,0,0,0);
210: break;
211: case 'F':
212: case 'f':
213: found=1;
214: s=gt_num(s,&w);
215: if(w==0) break;
216: if(*s=='.')
217: { s++;
218: s=gt_num(s,&d);
219: }
220: else d=0;
221: (void) op_gen(F,w,d,0);
222: break;
223: case 'D':
224: case 'd':
225: found=1;
226: s=gt_num(s,&w);
227: if(w==0) break;
228: if(*s=='.')
229: { s++;
230: s=gt_num(s,&d);
231: }
232: else d=0;
233: (void) op_gen(D,w,d,0);
234: break;
235: case 'I':
236: case 'i':
237: found=1;
238: s=gt_num(s,&w);
239: if(w==0) break;
240: if(*s!='.')
241: { (void) op_gen(I,w,0,0);
242: break;
243: }
244: s++;
245: s=gt_num(s,&d);
246: (void) op_gen(IM,w,d,0);
247: break;
248: }
249: if(found==0)
250: { pc--; /*unSTACK*/
251: *p=sv;
252: return(0);
253: }
254: *p=s;
255: return(1);
256: }
257: op_gen(a,b,c,d)
258: { struct syl *p= &syl[pc];
259: if(pc>=SYLMX)
260: { fprintf(stderr,"format too complicated:\n%s\n",
261: fmtbuf);
262: abort();
263: }
264: p->op=a;
265: p->p1=b;
266: p->p2=c;
267: p->p3=d;
268: return(pc++);
269: }
270: char *gt_num(s,n) char *s; int *n;
271: { int m=0,cnt=0;
272: char c;
273: for(c= *s;;c = *s)
274: { if(c==' ')
275: { s++;
276: continue;
277: }
278: if(c>'9' || c<'0') break;
279: m=10*m+c-'0';
280: cnt++;
281: s++;
282: }
283: if(cnt==0) *n=1;
284: else *n=m;
285: return(s);
286: }
287: #define STKSZ 10
288: int cnt[STKSZ],ret[STKSZ],cp,rp;
289: flag workdone, nonl;
290: en_fio()
291: { ftnint one=1;
292: return(do_fio(&one,(char *)NULL,0l));
293: }
294: do_fio(number,ptr,len) ftnint *number; ftnlen len; char *ptr;
295: { struct syl *p;
296: int n,i;
297: for(i=0;i<*number;i++,ptr+=len)
298: {
299: loop: switch(type_f((p= &syl[pc])->op))
300: {
301: default:
302: fprintf(stderr,"unknown code in do_fio: %d\n%s\n",
303: p->op,fmtbuf);
304: err(elist->cierr,100,"do_fio");
305: case NED:
306: if((*doned)(p))
307: { pc++;
308: goto loop;
309: }
310: pc++;
311: continue;
312: case ED:
313: if(cnt[cp]<=0)
314: { cp--;
315: pc++;
316: goto loop;
317: }
318: if(ptr==NULL)
319: return((*doend)());
320: cnt[cp]--;
321: workdone=1;
322: if((n=(*doed)(p,ptr,len))>0) err(elist->cierr,errno,"fmt");
323: if(n<0) err(elist->ciend,(EOF),"fmt");
324: continue;
325: case STACK:
326: cnt[++cp]=p->p1;
327: pc++;
328: goto loop;
329: case RET:
330: ret[++rp]=p->p1;
331: pc++;
332: goto loop;
333: case GOTO:
334: if(--cnt[cp]<=0)
335: { cp--;
336: rp--;
337: pc++;
338: goto loop;
339: }
340: pc=1+ret[rp--];
341: goto loop;
342: case REVERT:
343: rp=cp=0;
344: pc = p->p1;
345: if(ptr==NULL)
346: return((*doend)());
347: if(!workdone) return(0);
348: if((n=(*dorevert)()) != 0) return(n);
349: goto loop;
350: case COLON:
351: if(ptr==NULL)
352: return((*doend)());
353: pc++;
354: goto loop;
355: case NONL:
356: nonl = 1;
357: pc++;
358: goto loop;
359: case S:
360: case SS:
361: cplus=0;
362: pc++;
363: goto loop;
364: case SP:
365: cplus = 1;
366: pc++;
367: goto loop;
368: case P: scale=p->p1;
369: pc++;
370: goto loop;
371: case BN:
372: cblank=0;
373: pc++;
374: goto loop;
375: case BZ:
376: cblank=1;
377: pc++;
378: goto loop;
379: }
380: }
381: return(0);
382: }
383: fmt_bg()
384: {
385: workdone=cp=rp=pc=cursor=0;
386: cnt[0]=ret[0]=0;
387: }
388: type_f(n)
389: {
390: switch(n)
391: {
392: default:
393: return(n);
394: case RET:
395: return(RET);
396: case REVERT: return(REVERT);
397: case GOTO: return(GOTO);
398: case STACK: return(STACK);
399: case X:
400: case SLASH:
401: case APOS: case H:
402: case T: case TL: case TR:
403: return(NED);
404: case F:
405: case I:
406: case IM:
407: case A: case AW:
408: case O:
409: case L:
410: case E: case EE: case D:
411: case G: case GE:
412: return(ED);
413: }
414: }
415: char *ap_end(s) char *s;
416: { char quote;
417: quote= *s++;
418: for(;*s;s++)
419: { if(*s!=quote) continue;
420: if(*++s!=quote) return(s);
421: }
422: if(elist->cierr) {
423: errno = 100;
424: return(NULL);
425: }
426: fatal(100, "bad string");
427: /*NOTREACHED*/
428: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.