home *** CD-ROM | disk | FTP | other *** search
- #include "f2c.h"
- #include "fio.h"
- #include "fmt.h"
- #define skip(s) while(*s==' ') s++
- #ifdef interdata
- #define SYLMX 300
- #endif
- #ifdef pdp11
- #define SYLMX 300
- #endif
- #ifdef vax
- #define SYLMX 300
- #endif
- #ifndef SYLMX
- #define SYLMX 300
- #endif
- #define GLITCH '\2'
- /* special quote character for stu */
- extern int cursor,scale;
- extern flag cblank,cplus; /*blanks in I and compulsory plus*/
- struct syl syl[SYLMX];
- int parenlvl,pc,revloc;
-
- char *f_s(),*f_list(),*i_tem(),*gt_num();
-
- pars_f(s) char *s;
- {
- parenlvl=revloc=pc=0;
- if(f_s(s,0) == NULL)
- {
- return(-1);
- }
- return(0);
- }
- char *f_s(s,curloc) char *s;
- {
- skip(s);
- if(*s++!='(')
- {
- return(NULL);
- }
- if(parenlvl++ ==1) revloc=curloc;
- if(op_gen(RET,curloc,0,0)<0 ||
- (s=f_list(s))==NULL)
- {
- return(NULL);
- }
- skip(s);
- return(s);
- }
- char *f_list(s) char *s;
- {
- for(;*s!=0;)
- { skip(s);
- if((s=i_tem(s))==NULL) return(NULL);
- skip(s);
- if(*s==',') s++;
- else if(*s==')')
- { if(--parenlvl==0)
- {
- (void) op_gen(REVERT,revloc,0,0);
- return(++s);
- }
- (void) op_gen(GOTO,0,0,0);
- return(++s);
- }
- }
- return(NULL);
- }
- char *i_tem(s) char *s;
- { char *t;
- int n,curloc;
- if(*s==')') return(s);
- if(ne_d(s,&t)) return(t);
- if(e_d(s,&t)) return(t);
- s=gt_num(s,&n);
- if((curloc=op_gen(STACK,n,0,0))<0) return(NULL);
- return(f_s(s,curloc));
- }
- ne_d(s,p) char *s,**p;
- { int n,x,sign=0;
- char *ap_end();
- struct syl *sp;
- switch(*s)
- {
- default:
- return(0);
- case ':': (void) op_gen(COLON,0,0,0); break;
- case '$':
- (void) op_gen(NONL, 0, 0, 0); break;
- case 'B':
- case 'b':
- if(*++s=='z' || *s == 'Z') (void) op_gen(BZ,0,0,0);
- else (void) op_gen(BN,0,0,0);
- break;
- case 'S':
- case 's':
- if(*(s+1)=='s' || *(s+1) == 'S')
- { x=SS;
- s++;
- }
- else if(*(s+1)=='p' || *(s+1) == 'P')
- { x=SP;
- s++;
- }
- else x=S;
- (void) op_gen(x,0,0,0);
- break;
- case '/': (void) op_gen(SLASH,0,0,0); break;
- case '-': sign=1;
- case '+': s++; /*OUTRAGEOUS CODING TRICK*/
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- s=gt_num(s,&n);
- switch(*s)
- {
- default:
- return(0);
- case 'P':
- case 'p': if(sign) n= -n; (void) op_gen(P,n,0,0); break;
- case 'X':
- case 'x': (void) op_gen(X,n,0,0); break;
- case 'H':
- case 'h':
- sp = &syl[op_gen(H,n,0,0)];
- *(char **)&sp->p2 = s + 1;
- s+=n;
- break;
- }
- break;
- case GLITCH:
- case '"':
- case '\'':
- sp = &syl[op_gen(APOS,0,0,0)];
- *(char **)&sp->p2 = s;
- if((*p = ap_end(s)) == NULL)
- return(0);
- return(1);
- case 'T':
- case 't':
- if(*(s+1)=='l' || *(s+1) == 'L')
- { x=TL;
- s++;
- }
- else if(*(s+1)=='r'|| *(s+1) == 'R')
- { x=TR;
- s++;
- }
- else x=T;
- s=gt_num(s+1,&n);
- s--;
- (void) op_gen(x,n,0,0);
- break;
- case 'X':
- case 'x': (void) op_gen(X,1,0,0); break;
- case 'P':
- case 'p': (void) op_gen(P,1,0,0); break;
- }
- s++;
- *p=s;
- return(1);
- }
- e_d(s,p) char *s,**p;
- { int n,w,d,e,found=0,x=0;
- char *sv=s;
- s=gt_num(s,&n);
- (void) op_gen(STACK,n,0,0);
- switch(*s++)
- {
- default: break;
- case 'E':
- case 'e': x=1;
- case 'G':
- case 'g':
- found=1;
- s=gt_num(s,&w);
- if(w==0) break;
- if(*s=='.')
- { s++;
- s=gt_num(s,&d);
- }
- else d=0;
- if(*s!='E' && *s != 'e')
- (void) op_gen(x==1?E:G,w,d,0); /* default is Ew.dE2 */
- else
- { s++;
- s=gt_num(s,&e);
- (void) op_gen(x==1?EE:GE,w,d,e);
- }
- break;
- case 'O':
- case 'o':
- found = 1;
- s = gt_num(s, &w);
- if(w==0) break;
- (void) op_gen(O, w, 0, 0);
- break;
- case 'L':
- case 'l':
- found=1;
- s=gt_num(s,&w);
- if(w==0) break;
- (void) op_gen(L,w,0,0);
- break;
- case 'A':
- case 'a':
- found=1;
- skip(s);
- if(*s>='0' && *s<='9')
- { s=gt_num(s,&w);
- if(w==0) break;
- (void) op_gen(AW,w,0,0);
- break;
- }
- (void) op_gen(A,0,0,0);
- break;
- case 'F':
- case 'f':
- found=1;
- s=gt_num(s,&w);
- if(w==0) break;
- if(*s=='.')
- { s++;
- s=gt_num(s,&d);
- }
- else d=0;
- (void) op_gen(F,w,d,0);
- break;
- case 'D':
- case 'd':
- found=1;
- s=gt_num(s,&w);
- if(w==0) break;
- if(*s=='.')
- { s++;
- s=gt_num(s,&d);
- }
- else d=0;
- (void) op_gen(D,w,d,0);
- break;
- case 'I':
- case 'i':
- found=1;
- s=gt_num(s,&w);
- if(w==0) break;
- if(*s!='.')
- { (void) op_gen(I,w,0,0);
- break;
- }
- s++;
- s=gt_num(s,&d);
- (void) op_gen(IM,w,d,0);
- break;
- }
- if(found==0)
- { pc--; /*unSTACK*/
- *p=sv;
- return(0);
- }
- *p=s;
- return(1);
- }
- op_gen(a,b,c,d)
- { struct syl *p= &syl[pc];
- if(pc>=SYLMX)
- { fprintf(stderr,"format too complicated:\n");
- sig_die(fmtbuf, 1);
- }
- p->op=a;
- p->p1=b;
- p->p2=c;
- p->p3=d;
- return(pc++);
- }
- char *gt_num(s,n) char *s; int *n;
- { int m=0,cnt=0;
- char c;
- for(c= *s;;c = *s)
- { if(c==' ')
- { s++;
- continue;
- }
- if(c>'9' || c<'0') break;
- m=10*m+c-'0';
- cnt++;
- s++;
- }
- if(cnt==0) *n=1;
- else *n=m;
- return(s);
- }
- #define STKSZ 10
- int cnt[STKSZ],ret[STKSZ],cp,rp;
- flag workdone, nonl;
-
- integer do_fio(number,ptr,len) ftnint *number; ftnlen len; char *ptr;
- { struct syl *p;
- int n,i;
- for(i=0;i<*number;i++,ptr+=len)
- {
- loop: switch(type_f((p= &syl[pc])->op))
- {
- default:
- fprintf(stderr,"unknown code in do_fio: %d\n%s\n",
- p->op,fmtbuf);
- err(elist->cierr,100,"do_fio");
- case NED:
- if((*doned)(p))
- { pc++;
- goto loop;
- }
- pc++;
- continue;
- case ED:
- if(cnt[cp]<=0)
- { cp--;
- pc++;
- goto loop;
- }
- if(ptr==NULL)
- return((*doend)());
- cnt[cp]--;
- workdone=1;
- if((n=(*doed)(p,ptr,len))>0) err(elist->cierr,errno,"fmt");
- if(n<0) err(elist->ciend,(EOF),"fmt");
- continue;
- case STACK:
- cnt[++cp]=p->p1;
- pc++;
- goto loop;
- case RET:
- ret[++rp]=p->p1;
- pc++;
- goto loop;
- case GOTO:
- if(--cnt[cp]<=0)
- { cp--;
- rp--;
- pc++;
- goto loop;
- }
- pc=1+ret[rp--];
- goto loop;
- case REVERT:
- rp=cp=0;
- pc = p->p1;
- if(ptr==NULL)
- return((*doend)());
- if(!workdone) return(0);
- if((n=(*dorevert)()) != 0) return(n);
- goto loop;
- case COLON:
- if(ptr==NULL)
- return((*doend)());
- pc++;
- goto loop;
- case NONL:
- nonl = 1;
- pc++;
- goto loop;
- case S:
- case SS:
- cplus=0;
- pc++;
- goto loop;
- case SP:
- cplus = 1;
- pc++;
- goto loop;
- case P: scale=p->p1;
- pc++;
- goto loop;
- case BN:
- cblank=0;
- pc++;
- goto loop;
- case BZ:
- cblank=1;
- pc++;
- goto loop;
- }
- }
- return(0);
- }
- en_fio()
- { ftnint one=1;
- return(do_fio(&one,(char *)NULL,(ftnint)0));
- }
- fmt_bg()
- {
- workdone=cp=rp=pc=cursor=0;
- cnt[0]=ret[0]=0;
- }
- type_f(n)
- {
- switch(n)
- {
- default:
- return(n);
- case RET:
- return(RET);
- case REVERT: return(REVERT);
- case GOTO: return(GOTO);
- case STACK: return(STACK);
- case X:
- case SLASH:
- case APOS: case H:
- case T: case TL: case TR:
- return(NED);
- case F:
- case I:
- case IM:
- case A: case AW:
- case O:
- case L:
- case E: case EE: case D:
- case G: case GE:
- return(ED);
- }
- }
- char *ap_end(s) char *s;
- { char quote;
- quote= *s++;
- for(;*s;s++)
- { if(*s!=quote) continue;
- if(*++s!=quote) return(s);
- }
- if(elist->cierr) {
- errno = 100;
- return(NULL);
- }
- fatal(100, "bad string");
- /*NOTREACHED*/ return 0;
- }
-