|
|
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.