12508Sdlw /* 2*12231Sdlw char id_fmt[] = "@(#)fmt.c 1.4"; 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 262508Sdlw struct syl syl[SYLMX]; 272508Sdlw int parenlvl,pc,revloc; 282508Sdlw char *f_s(), *f_list(), *i_tem(), *gt_num(), *ap_end(); 292508Sdlw 302508Sdlw pars_f(s) char *s; 312508Sdlw { 322508Sdlw parenlvl=revloc=pc=0; 332508Sdlw return((f_s(s,0)==FMTERR)? ERROR : OK); 342508Sdlw } 352508Sdlw 362508Sdlw char *f_s(s,curloc) char *s; 372508Sdlw { 382508Sdlw skip(s); 392508Sdlw if(*s++!='(') 402508Sdlw { 412508Sdlw fmtptr = s; 422508Sdlw return(FMTERR); 432508Sdlw } 442508Sdlw if(parenlvl++ ==1) revloc=curloc; 452508Sdlw op_gen(RET,curloc,0,0,s); 462508Sdlw if((s=f_list(s))==FMTERR) 472508Sdlw { 482508Sdlw return(FMTERR); 492508Sdlw } 502508Sdlw skip(s); 512508Sdlw return(s); 522508Sdlw } 532508Sdlw 542508Sdlw char *f_list(s) char *s; 552508Sdlw { 562508Sdlw while (*s) 572508Sdlw { skip(s); 582508Sdlw if((s=i_tem(s))==FMTERR) return(FMTERR); 592508Sdlw skip(s); 602508Sdlw if(*s==',') s++; 612508Sdlw else if(*s==')') 622508Sdlw { if(--parenlvl==0) 632508Sdlw { 642508Sdlw op_gen(REVERT,revloc,0,0,s); 652508Sdlw } 662508Sdlw else op_gen(GOTO,0,0,0,s); 672508Sdlw return(++s); 682508Sdlw } 692508Sdlw } 702508Sdlw fmtptr = s; 712508Sdlw return(FMTERR); 722508Sdlw } 732508Sdlw 742508Sdlw char *i_tem(s) char *s; 752508Sdlw { char *t; 762508Sdlw int n,curloc; 772508Sdlw if(*s==')') return(s); 782508Sdlw if(ne_d(s,&t)) return(t); 792508Sdlw if(e_d(s,&t)) return(t); 802508Sdlw s=gt_num(s,&n); 812508Sdlw curloc = op_gen(STACK,n,0,0,s); 822508Sdlw return(f_s(s,curloc)); 832508Sdlw } 842508Sdlw 852508Sdlw ne_d(s,p) char *s,**p; 862508Sdlw { int n,x,sign=0,pp1,pp2; 872508Sdlw switch(lcase(*s)) 882508Sdlw { 892508Sdlw case ':': op_gen(COLON,(int)('\n'),0,0,s); break; 902508Sdlw #ifndef KOSHER 912508Sdlw case '$': op_gen(DOLAR,(int)('\0'),0,0,s); break; /*** NOT STANDARD FORTRAN ***/ 922508Sdlw #endif 932508Sdlw case 'b': 942508Sdlw switch(lcase(*(s+1))) 952508Sdlw { 9612132Sdlw case '\0': op_gen(BN,cblank,0,0,s); break; 972508Sdlw case 'z': s++; op_gen(BZ,1,0,0,s); break; 982508Sdlw case 'n': s++; 992508Sdlw default: op_gen(BN,0,0,0,s); break; 1002508Sdlw } 1012508Sdlw break; 1022508Sdlw case 's': 1032508Sdlw switch(lcase(*(s+1))) 1042508Sdlw { 1052508Sdlw case 'p': s++; x=SP; pp1=1; pp2=1; break; 1062508Sdlw #ifndef KOSHER 1072508Sdlw case 'u': s++; x=SU; pp1=0; pp2=0; break; /*** NOT STANDARD FORTRAN ***/ 1082508Sdlw #endif 1092508Sdlw case 's': s++; x=SS; pp1=0; pp2=1; break; 1102508Sdlw default: x=S; pp1=0; pp2=1; break; 1112508Sdlw } 1122508Sdlw op_gen(x,pp1,pp2,0,s); 1132508Sdlw break; 1142508Sdlw case '/': op_gen(SLASH,0,0,0,s); break; 115*12231Sdlw 116*12231Sdlw case '-': sign=1; /* OUTRAGEOUS CODING */ 117*12231Sdlw case '+': s++; /* OUTRAGEOUS CODING */ 1182508Sdlw case '0': case '1': case '2': case '3': case '4': 1192508Sdlw case '5': case '6': case '7': case '8': case '9': 1202508Sdlw s=gt_num(s,&n); 1212508Sdlw switch(lcase(*s)) 1222508Sdlw { 1232508Sdlw case 'p': if(sign) n= -n; op_gen(P,n,0,0,s); break; 1242508Sdlw #ifndef KOSHER 1252508Sdlw case 'r': if(n<=1) /*** NOT STANDARD FORTRAN ***/ 1262508Sdlw { fmtptr = s; return(FMTERR); } 1272508Sdlw op_gen(R,n,0,0,s); break; 1282508Sdlw case 't': op_gen(T,0,n,0,s); break; /* NOT STANDARD FORT */ 1292508Sdlw #endif 1302508Sdlw case 'x': op_gen(X,n,0,0,s); break; 1312508Sdlw case 'h': op_gen(H,n,(int)(s+1),0,s); 1322508Sdlw s+=n; 1332508Sdlw break; 1342508Sdlw default: fmtptr = s; return(0); 1352508Sdlw } 1362508Sdlw break; 1372508Sdlw case GLITCH: 1382508Sdlw case '"': 1392508Sdlw case '\'': op_gen(APOS,(int)s,0,0,s); 1402508Sdlw *p = ap_end(s); 1412508Sdlw return(FMTOK); 1422508Sdlw case 't': 1432508Sdlw switch(lcase(*(s+1))) 1442508Sdlw { 1452508Sdlw case 'l': s++; x=TL; break; 1462508Sdlw case 'r': s++; x=TR; break; 1472508Sdlw default: x=T; break; 1482508Sdlw } 1492508Sdlw if(isdigit(*(s+1))) {s=gt_num(s+1,&n); s--;} 1502508Sdlw #ifndef KOSHER 1512508Sdlw else n = 0; /* NOT STANDARD FORTRAN, should be error */ 1522508Sdlw #endif 1532508Sdlw #ifdef KOSHER 1542508Sdlw fmtptr = s; return(FMTERR); 1552508Sdlw #endif 1562508Sdlw op_gen(x,n,1,0,s); 1572508Sdlw break; 1582508Sdlw case 'x': op_gen(X,1,0,0,s); break; 1592508Sdlw case 'p': op_gen(P,0,0,0,s); break; 1602508Sdlw #ifndef KOSHER 1612508Sdlw case 'r': op_gen(R,10,1,0,s); break; /*** NOT STANDARD FORTRAN ***/ 1622508Sdlw #endif 1632508Sdlw 1642508Sdlw default: fmtptr = s; return(0); 1652508Sdlw } 1662508Sdlw s++; 1672508Sdlw *p=s; 1682508Sdlw return(FMTOK); 1692508Sdlw } 1702508Sdlw 1712508Sdlw e_d(s,p) char *s,**p; 1722508Sdlw { int n,w,d,e,x=0; 1732508Sdlw char *sv=s; 1742508Sdlw char c; 1752508Sdlw s=gt_num(s,&n); 1762508Sdlw op_gen(STACK,n,0,0,s); 1772508Sdlw c = lcase(*s); s++; 1782508Sdlw switch(c) 1792508Sdlw { 1802508Sdlw case 'd': 1812508Sdlw case 'e': 1822508Sdlw case 'g': 1832508Sdlw s = gt_num(s, &w); 1842508Sdlw if (w==0) break; 1852508Sdlw if(*s=='.') 1862508Sdlw { s++; 1872508Sdlw s=gt_num(s,&d); 1882508Sdlw } 1892508Sdlw else d=0; 1902508Sdlw if(lcase(*s) == 'e' 1912508Sdlw #ifndef KOSHER 1922508Sdlw || *s == '.' /*** '.' is NOT STANDARD FORTRAN ***/ 1932508Sdlw #endif 1942508Sdlw ) 1952508Sdlw { s++; 1962508Sdlw s=gt_num(s,&e); 1972508Sdlw if(c=='e') n=EE; else if(c=='d') n=DE; else n=GE; 1982508Sdlw } 1992508Sdlw else 2002508Sdlw { e=2; 2012508Sdlw if(c=='e') n=E; else if(c=='d') n=D; else n=G; 2022508Sdlw } 2032508Sdlw op_gen(n,w,d,e,s); 2042508Sdlw break; 2052508Sdlw case 'l': 2062508Sdlw s = gt_num(s, &w); 2072508Sdlw if (w==0) break; 2082508Sdlw op_gen(L,w,0,0,s); 2092508Sdlw break; 2102508Sdlw case 'a': 2112508Sdlw skip(s); 2122508Sdlw if(*s>='0' && *s<='9') 2132508Sdlw { s=gt_num(s,&w); 2142508Sdlw if(w==0) break; 2152508Sdlw op_gen(AW,w,0,0,s); 2162508Sdlw break; 2172508Sdlw } 2182508Sdlw op_gen(A,0,0,0,s); 2192508Sdlw break; 2202508Sdlw case 'f': 2212508Sdlw s = gt_num(s, &w); 2222508Sdlw if (w==0) break; 2232508Sdlw if(*s=='.') 2242508Sdlw { s++; 2252508Sdlw s=gt_num(s,&d); 2262508Sdlw } 2272508Sdlw else d=0; 2282508Sdlw op_gen(F,w,d,0,s); 2292508Sdlw break; 2302508Sdlw case 'i': 2312508Sdlw s = gt_num(s, &w); 2322508Sdlw if (w==0) break; 2332508Sdlw if(*s =='.') 2342508Sdlw { 2352508Sdlw s++; 2362508Sdlw s=gt_num(s,&d); 2372508Sdlw x = IM; 2382508Sdlw } 2392508Sdlw else 2402508Sdlw { d = 1; 2412508Sdlw x = I; 2422508Sdlw } 2432508Sdlw op_gen(x,w,d,0,s); 2442508Sdlw break; 2452508Sdlw default: 2462508Sdlw pc--; /* unSTACK */ 2472508Sdlw *p = sv; 2482508Sdlw fmtptr = s; 2492508Sdlw return(FMTERR); 2502508Sdlw } 2512508Sdlw *p = s; 2522508Sdlw return(FMTOK); 2532508Sdlw } 2542508Sdlw 2552508Sdlw op_gen(a,b,c,d,s) char *s; 2562508Sdlw { struct syl *p= &syl[pc]; 2572508Sdlw if(pc>=SYLMX) 2582508Sdlw { fmtptr = s; 2592591Sdlw fatal(F_ERFMT,"format too complex"); 2602508Sdlw } 2612508Sdlw #ifdef DEBUG 2622508Sdlw fprintf(stderr,"%3d opgen: %d %d %d %d %c\n", 2632508Sdlw pc,a,b,c,d,*s==GLITCH?'"':*s); /* for debug */ 2642508Sdlw #endif 2652508Sdlw p->op=a; 2662508Sdlw p->p1=b; 2672508Sdlw p->p2=c; 2682508Sdlw p->p3=d; 2692508Sdlw return(pc++); 2702508Sdlw } 2712508Sdlw 2722508Sdlw char *gt_num(s,n) char *s; int *n; 2732508Sdlw { int m=0,a_digit=NO; 2742508Sdlw skip(s); 2752508Sdlw while(isdigit(*s) || isspace(*s)) 2762508Sdlw { 2772508Sdlw if (isdigit(*s)) 2782508Sdlw { 2792508Sdlw m = 10*m + (*s)-'0'; 2802508Sdlw a_digit = YES; 2812508Sdlw } 2822508Sdlw s++; 2832508Sdlw } 2842508Sdlw if(a_digit) *n=m; 2852508Sdlw else *n=1; 2862508Sdlw return(s); 2872508Sdlw } 2882508Sdlw 2892508Sdlw char *ap_end(s) char *s; 2902508Sdlw { 2912508Sdlw char quote; 2922508Sdlw quote = *s++; 2932508Sdlw for(;*s;s++) 2942508Sdlw { 2952508Sdlw if(*s==quote && *++s!=quote) return(s); 2962508Sdlw } 2972508Sdlw fmtptr = s; 2982591Sdlw fatal(F_ERFMT,"bad string"); 2992508Sdlw } 300