12508Sdlw /* 2*17967Slibs char id_fmt[] = "@(#)fmt.c 1.7"; 32508Sdlw * 42508Sdlw * fortran format parser 52508Sdlw */ 62508Sdlw 72508Sdlw #include "fio.h" 82591Sdlw #include "format.h" 92508Sdlw 102508Sdlw #define isdigit(x) (x>='0' && x<='9') 112508Sdlw #define isspace(s) (s==' ') 122508Sdlw #define skip(s) while(isspace(*s)) s++ 132508Sdlw 142508Sdlw #ifdef interdata 152508Sdlw #define SYLMX 300 162508Sdlw #endif 172508Sdlw 182508Sdlw #ifdef pdp11 192508Sdlw #define SYLMX 300 202508Sdlw #endif 212508Sdlw 222508Sdlw #ifdef vax 232508Sdlw #define SYLMX 300 242508Sdlw #endif 252508Sdlw 26*17967Slibs struct syl syl_vec[SYLMX]; 27*17967Slibs struct syl *syl_ptr; 28*17967Slibs int parenlvl,revloc; 29*17967Slibs short pc; 302508Sdlw char *f_s(), *f_list(), *i_tem(), *gt_num(), *ap_end(); 31*17967Slibs char *s_init; 322508Sdlw 33*17967Slibs pars_f() 342508Sdlw { 35*17967Slibs short *s_ptr; 36*17967Slibs long *l_ptr; 37*17967Slibs 382508Sdlw parenlvl=revloc=pc=0; 39*17967Slibs s_ptr = (short *) fmtbuf; 40*17967Slibs if( *s_ptr == FMT_COMP ) { 41*17967Slibs /* already compiled - copy value of pc */ 42*17967Slibs pc = *(s_ptr+1); 43*17967Slibs /* get address of the format */ 44*17967Slibs l_ptr = (long *) fmtbuf; 45*17967Slibs fmtbuf = s_init = (char *) *(l_ptr+1); 46*17967Slibs /* point syl_ptr to the compiled format */ 47*17967Slibs syl_ptr = (struct syl *) (l_ptr + 2); 48*17967Slibs return(OK); 49*17967Slibs } else { 50*17967Slibs syl_ptr = syl_vec; 51*17967Slibs s_init = fmtbuf; 52*17967Slibs return((f_s(fmtbuf,0)==FMTERR)? ERROR : OK); 53*17967Slibs } 542508Sdlw } 552508Sdlw 562508Sdlw char *f_s(s,curloc) char *s; 572508Sdlw { 582508Sdlw skip(s); 592508Sdlw if(*s++!='(') 602508Sdlw { 612508Sdlw fmtptr = s; 622508Sdlw return(FMTERR); 632508Sdlw } 642508Sdlw if(parenlvl++ ==1) revloc=curloc; 652508Sdlw op_gen(RET,curloc,0,0,s); 662508Sdlw if((s=f_list(s))==FMTERR) 672508Sdlw { 682508Sdlw return(FMTERR); 692508Sdlw } 702508Sdlw skip(s); 712508Sdlw return(s); 722508Sdlw } 732508Sdlw 742508Sdlw char *f_list(s) char *s; 752508Sdlw { 762508Sdlw while (*s) 772508Sdlw { skip(s); 782508Sdlw if((s=i_tem(s))==FMTERR) return(FMTERR); 792508Sdlw skip(s); 802508Sdlw if(*s==',') s++; 812508Sdlw else if(*s==')') 822508Sdlw { if(--parenlvl==0) 832508Sdlw op_gen(REVERT,revloc,0,0,s); 8416597Sralph else 8516597Sralph op_gen(GOTO,0,0,0,s); 862508Sdlw return(++s); 872508Sdlw } 882508Sdlw } 892508Sdlw fmtptr = s; 902508Sdlw return(FMTERR); 912508Sdlw } 922508Sdlw 932508Sdlw char *i_tem(s) char *s; 942508Sdlw { char *t; 952508Sdlw int n,curloc; 962508Sdlw if(*s==')') return(s); 9716597Sralph if ((n=ne_d(s,&t))==FMTOK) 9816597Sralph return(t); 9916597Sralph else if (n==FMTERR) 10016597Sralph return(FMTERR); 10116597Sralph if ((n=e_d(s,&t))==FMTOK) 10216597Sralph return(t); 10316597Sralph else if (n==FMTERR) 10416597Sralph return(FMTERR); 1052508Sdlw s=gt_num(s,&n); 10616597Sralph if (n == 0) { fmtptr = s; return(FMTERR); } 1072508Sdlw curloc = op_gen(STACK,n,0,0,s); 1082508Sdlw return(f_s(s,curloc)); 1092508Sdlw } 1102508Sdlw 1112508Sdlw ne_d(s,p) char *s,**p; 1122508Sdlw { int n,x,sign=0,pp1,pp2; 1132508Sdlw switch(lcase(*s)) 1142508Sdlw { 1152508Sdlw case ':': op_gen(COLON,(int)('\n'),0,0,s); break; 1162508Sdlw #ifndef KOSHER 1172508Sdlw case '$': op_gen(DOLAR,(int)('\0'),0,0,s); break; /*** NOT STANDARD FORTRAN ***/ 1182508Sdlw #endif 1192508Sdlw case 'b': 1202508Sdlw switch(lcase(*(s+1))) 1212508Sdlw { 12217876Sdlw case 'n': s++; op_gen(BNZ,0,0,0,s); break; 12317876Sdlw case 'z': s++; op_gen(BNZ,1,0,0,s); break; 12417876Sdlw #ifndef KOSHER 12517876Sdlw default: op_gen(B,0,0,0,s); break; /*** NOT STANDARD FORTRAN ***/ 12617876Sdlw #else 12717876Sdlw default: fmtptr = s; return(FMTUNKN); 12817876Sdlw #endif 1292508Sdlw } 1302508Sdlw break; 1312508Sdlw case 's': 1322508Sdlw switch(lcase(*(s+1))) 1332508Sdlw { 1342508Sdlw case 'p': s++; x=SP; pp1=1; pp2=1; break; 1352508Sdlw #ifndef KOSHER 1362508Sdlw case 'u': s++; x=SU; pp1=0; pp2=0; break; /*** NOT STANDARD FORTRAN ***/ 1372508Sdlw #endif 1382508Sdlw case 's': s++; x=SS; pp1=0; pp2=1; break; 1392508Sdlw default: x=S; pp1=0; pp2=1; break; 1402508Sdlw } 1412508Sdlw op_gen(x,pp1,pp2,0,s); 1422508Sdlw break; 1432508Sdlw case '/': op_gen(SLASH,0,0,0,s); break; 14412231Sdlw 14512231Sdlw case '-': sign=1; /* OUTRAGEOUS CODING */ 14612231Sdlw case '+': s++; /* OUTRAGEOUS CODING */ 1472508Sdlw case '0': case '1': case '2': case '3': case '4': 1482508Sdlw case '5': case '6': case '7': case '8': case '9': 1492508Sdlw s=gt_num(s,&n); 1502508Sdlw switch(lcase(*s)) 1512508Sdlw { 1522508Sdlw case 'p': if(sign) n= -n; op_gen(P,n,0,0,s); break; 1532508Sdlw #ifndef KOSHER 1542508Sdlw case 'r': if(n<=1) /*** NOT STANDARD FORTRAN ***/ 15516597Sralph { fmtptr = --s; return(FMTERR); } 1562508Sdlw op_gen(R,n,0,0,s); break; 1572508Sdlw case 't': op_gen(T,0,n,0,s); break; /* NOT STANDARD FORT */ 1582508Sdlw #endif 1592508Sdlw case 'x': op_gen(X,n,0,0,s); break; 160*17967Slibs case 'h': op_gen(H,n,(s+1)-s_init,0,s); 1612508Sdlw s+=n; 1622508Sdlw break; 16316597Sralph default: fmtptr = s; return(FMTUNKN); 1642508Sdlw } 1652508Sdlw break; 1662508Sdlw case GLITCH: 1672508Sdlw case '"': 168*17967Slibs case '\'': op_gen(APOS,s-s_init,0,0,s); 1692508Sdlw *p = ap_end(s); 1702508Sdlw return(FMTOK); 1712508Sdlw case 't': 1722508Sdlw switch(lcase(*(s+1))) 1732508Sdlw { 1742508Sdlw case 'l': s++; x=TL; break; 1752508Sdlw case 'r': s++; x=TR; break; 1762508Sdlw default: x=T; break; 1772508Sdlw } 1782508Sdlw if(isdigit(*(s+1))) {s=gt_num(s+1,&n); s--;} 17916597Sralph #ifdef KOSHER 18016597Sralph else { fmtptr = s; return(FMTERR); } 18116597Sralph #else 1822508Sdlw else n = 0; /* NOT STANDARD FORTRAN, should be error */ 1832508Sdlw #endif 1842508Sdlw op_gen(x,n,1,0,s); 1852508Sdlw break; 1862508Sdlw case 'x': op_gen(X,1,0,0,s); break; 1872508Sdlw case 'p': op_gen(P,0,0,0,s); break; 1882508Sdlw #ifndef KOSHER 1892508Sdlw case 'r': op_gen(R,10,1,0,s); break; /*** NOT STANDARD FORTRAN ***/ 1902508Sdlw #endif 1912508Sdlw 19216597Sralph default: fmtptr = s; return(FMTUNKN); 1932508Sdlw } 1942508Sdlw s++; 1952508Sdlw *p=s; 1962508Sdlw return(FMTOK); 1972508Sdlw } 1982508Sdlw 1992508Sdlw e_d(s,p) char *s,**p; 200*17967Slibs { int n,w,d,e,x=0, rep_count; 2012508Sdlw char *sv=s; 2022508Sdlw char c; 203*17967Slibs s=gt_num(s,&rep_count); 204*17967Slibs if (rep_count == 0) goto ed_err; 2052508Sdlw c = lcase(*s); s++; 2062508Sdlw switch(c) 2072508Sdlw { 2082508Sdlw case 'd': 2092508Sdlw case 'e': 2102508Sdlw case 'g': 2112508Sdlw s = gt_num(s, &w); 21216597Sralph if (w==0) goto ed_err; 2132508Sdlw if(*s=='.') 2142508Sdlw { s++; 2152508Sdlw s=gt_num(s,&d); 2162508Sdlw } 2172508Sdlw else d=0; 2182508Sdlw if(lcase(*s) == 'e' 2192508Sdlw #ifndef KOSHER 2202508Sdlw || *s == '.' /*** '.' is NOT STANDARD FORTRAN ***/ 2212508Sdlw #endif 2222508Sdlw ) 2232508Sdlw { s++; 2242508Sdlw s=gt_num(s,&e); 225*17967Slibs if (e==0 || e>127 || d>127 ) goto ed_err; 2262508Sdlw if(c=='e') n=EE; else if(c=='d') n=DE; else n=GE; 227*17967Slibs op_gen(n,w,d + (e<<8),rep_count,s); 2282508Sdlw } 2292508Sdlw else 230*17967Slibs { 2312508Sdlw if(c=='e') n=E; else if(c=='d') n=D; else n=G; 232*17967Slibs op_gen(n,w,d,rep_count,s); 2332508Sdlw } 2342508Sdlw break; 2352508Sdlw case 'l': 2362508Sdlw s = gt_num(s, &w); 23716597Sralph if (w==0) goto ed_err; 238*17967Slibs op_gen(L,w,0,rep_count,s); 2392508Sdlw break; 2402508Sdlw case 'a': 2412508Sdlw skip(s); 24216597Sralph if(isdigit(*s)) 2432508Sdlw { s=gt_num(s,&w); 24416597Sralph #ifdef KOSHER 24516597Sralph if (w==0) goto ed_err; 24616597Sralph #else 247*17967Slibs if (w==0) op_gen(A,0,0,rep_count,s); 24816597Sralph else 24916597Sralph #endif 250*17967Slibs op_gen(AW,w,0,rep_count,s); 2512508Sdlw break; 2522508Sdlw } 253*17967Slibs op_gen(A,0,0,rep_count,s); 2542508Sdlw break; 2552508Sdlw case 'f': 2562508Sdlw s = gt_num(s, &w); 25716597Sralph if (w==0) goto ed_err; 2582508Sdlw if(*s=='.') 2592508Sdlw { s++; 2602508Sdlw s=gt_num(s,&d); 2612508Sdlw } 2622508Sdlw else d=0; 263*17967Slibs op_gen(F,w,d,rep_count,s); 2642508Sdlw break; 26516597Sralph #ifndef KOSHER 26616597Sralph case 'o': /*** octal format - NOT STANDARD FORTRAN ***/ 26716597Sralph case 'z': /*** hex format - NOT STANDARD FORTRAN ***/ 26816597Sralph #endif 2692508Sdlw case 'i': 2702508Sdlw s = gt_num(s, &w); 27116597Sralph if (w==0) goto ed_err; 2722508Sdlw if(*s =='.') 2732508Sdlw { 2742508Sdlw s++; 2752508Sdlw s=gt_num(s,&d); 2762508Sdlw x = IM; 2772508Sdlw } 2782508Sdlw else 2792508Sdlw { d = 1; 2802508Sdlw x = I; 2812508Sdlw } 28216597Sralph #ifndef KOSHER 28316597Sralph if (c == 'o') 284*17967Slibs op_gen(R,8,1,rep_count,s); 28516597Sralph else if (c == 'z') 286*17967Slibs op_gen(R,16,1,rep_count,s); 28716597Sralph #endif 288*17967Slibs op_gen(x,w,d,rep_count,s); 28916597Sralph #ifndef KOSHER 29016597Sralph if (c == 'o' || c == 'z') 291*17967Slibs op_gen(R,10,1,rep_count,s); 29216597Sralph #endif 2932508Sdlw break; 2942508Sdlw default: 2952508Sdlw *p = sv; 2962508Sdlw fmtptr = s; 29716597Sralph return(FMTUNKN); 2982508Sdlw } 2992508Sdlw *p = s; 3002508Sdlw return(FMTOK); 30116597Sralph ed_err: 30216597Sralph fmtptr = --s; 30316597Sralph return(FMTERR); 3042508Sdlw } 3052508Sdlw 306*17967Slibs op_gen(a,b,c,rep,s) char *s; 307*17967Slibs { struct syl *p= &syl_ptr[pc]; 3082508Sdlw if(pc>=SYLMX) 3092508Sdlw { fmtptr = s; 3102591Sdlw fatal(F_ERFMT,"format too complex"); 3112508Sdlw } 312*17967Slibs if( b>32767 || c>32767 || rep>32767 ) 313*17967Slibs { fmtptr = s; 314*17967Slibs fatal("field width or repeat count too large"); 315*17967Slibs } 3162508Sdlw #ifdef DEBUG 3172508Sdlw fprintf(stderr,"%3d opgen: %d %d %d %d %c\n", 318*17967Slibs pc,a,b,c,rep,*s==GLITCH?'"':*s); /* for debug */ 3192508Sdlw #endif 3202508Sdlw p->op=a; 3212508Sdlw p->p1=b; 3222508Sdlw p->p2=c; 323*17967Slibs p->rpcnt=rep; 3242508Sdlw return(pc++); 3252508Sdlw } 3262508Sdlw 3272508Sdlw char *gt_num(s,n) char *s; int *n; 3282508Sdlw { int m=0,a_digit=NO; 3292508Sdlw skip(s); 3302508Sdlw while(isdigit(*s) || isspace(*s)) 3312508Sdlw { 3322508Sdlw if (isdigit(*s)) 3332508Sdlw { 3342508Sdlw m = 10*m + (*s)-'0'; 3352508Sdlw a_digit = YES; 3362508Sdlw } 3372508Sdlw s++; 3382508Sdlw } 3392508Sdlw if(a_digit) *n=m; 3402508Sdlw else *n=1; 3412508Sdlw return(s); 3422508Sdlw } 3432508Sdlw 3442508Sdlw char *ap_end(s) char *s; 3452508Sdlw { 3462508Sdlw char quote; 3472508Sdlw quote = *s++; 3482508Sdlw for(;*s;s++) 3492508Sdlw { 3502508Sdlw if(*s==quote && *++s!=quote) return(s); 3512508Sdlw } 3522508Sdlw fmtptr = s; 3532591Sdlw fatal(F_ERFMT,"bad string"); 3542508Sdlw } 355