1*43209Sbostic /* 2*43209Sbostic * Copyright (c) 1980 Regents of the University of California. 3*43209Sbostic * All rights reserved. The Berkeley software License Agreement 4*43209Sbostic * specifies the terms and conditions for redistribution. 5*43209Sbostic */ 6*43209Sbostic 7*43209Sbostic #ifndef lint 8*43209Sbostic static char sccsid[] = "@(#)fmt.c 5.1 (Berkeley) 6/7/85"; 9*43209Sbostic #endif not lint 10*43209Sbostic 11*43209Sbostic /* 12*43209Sbostic * 13*43209Sbostic * fortran format parser 14*43209Sbostic * corresponds to fmt.c in /usr/lib/libI77 15*43209Sbostic */ 16*43209Sbostic 17*43209Sbostic /* define ERROR, OK, GLITCH, NO, YES 18*43209Sbostic * from /usr/src/usr.lib/libI77/fiodefs.h 19*43209Sbostic */ 20*43209Sbostic 21*43209Sbostic #define GLITCH '\2' /* special quote for Stu, generated in f77pass1 */ 22*43209Sbostic #define ERROR 1 23*43209Sbostic #define OK 0 24*43209Sbostic #define YES 1 25*43209Sbostic #define NO 0 26*43209Sbostic 27*43209Sbostic /* define struct syl[] and lots of defines for format terms */ 28*43209Sbostic #include "format.h" 29*43209Sbostic 30*43209Sbostic #define isdigit(x) (x>='0' && x<='9') 31*43209Sbostic #define isspace(s) (s==' ') 32*43209Sbostic #define skip(s) while(isspace(*s)) s++ 33*43209Sbostic 34*43209Sbostic #ifdef interdata 35*43209Sbostic #define SYLMX 300 36*43209Sbostic #endif 37*43209Sbostic 38*43209Sbostic #ifdef pdp11 39*43209Sbostic #define SYLMX 300 40*43209Sbostic #endif 41*43209Sbostic 42*43209Sbostic #ifdef tahoe 43*43209Sbostic #define SYLMX 300 44*43209Sbostic #endif 45*43209Sbostic 46*43209Sbostic struct syl syl[SYLMX]; 47*43209Sbostic int parenlvl,revloc, low_case[256]; 48*43209Sbostic short pc; 49*43209Sbostic char *f_s(), *f_list(), *i_tem(), *gt_num(), *ap_end(); 50*43209Sbostic char *s_init, *fmtptr; 51*43209Sbostic int fmt_strings; /* tells if have hollerith or string in format*/ 52*43209Sbostic 53*43209Sbostic pars_f(s) char *s; 54*43209Sbostic { 55*43209Sbostic int i; 56*43209Sbostic 57*43209Sbostic /* first time, initialize low_case[] */ 58*43209Sbostic if( low_case[1] == 0 ) { 59*43209Sbostic for(i = 0; i<256; i++) low_case[i]=i; 60*43209Sbostic for(i = 'A'; i<='Z'; i++) low_case[i]=i-'A'+'a'; 61*43209Sbostic } 62*43209Sbostic 63*43209Sbostic fmt_strings = 0; 64*43209Sbostic parenlvl=revloc=pc=0; 65*43209Sbostic s_init = s; /* save beginning location of format */ 66*43209Sbostic return((f_s(s,0)==FMTERR)? ERROR : OK); 67*43209Sbostic } 68*43209Sbostic 69*43209Sbostic char *f_s(s,curloc) char *s; 70*43209Sbostic { 71*43209Sbostic skip(s); 72*43209Sbostic if(*s++!='(') 73*43209Sbostic { 74*43209Sbostic fmtptr = s; 75*43209Sbostic return(FMTERR); 76*43209Sbostic } 77*43209Sbostic if(parenlvl++ ==1) revloc=curloc; 78*43209Sbostic op_gen(RET,curloc,0,0,s); 79*43209Sbostic if((s=f_list(s))==FMTERR) 80*43209Sbostic { 81*43209Sbostic return(FMTERR); 82*43209Sbostic } 83*43209Sbostic skip(s); 84*43209Sbostic return(s); 85*43209Sbostic } 86*43209Sbostic 87*43209Sbostic char *f_list(s) char *s; 88*43209Sbostic { 89*43209Sbostic while (*s) 90*43209Sbostic { skip(s); 91*43209Sbostic if((s=i_tem(s))==FMTERR) return(FMTERR); 92*43209Sbostic skip(s); 93*43209Sbostic if(*s==',') s++; 94*43209Sbostic else if(*s==')') 95*43209Sbostic { if(--parenlvl==0) 96*43209Sbostic op_gen(REVERT,revloc,0,0,s); 97*43209Sbostic else 98*43209Sbostic op_gen(GOTO,0,0,0,s); 99*43209Sbostic return(++s); 100*43209Sbostic } 101*43209Sbostic } 102*43209Sbostic fmtptr = s; 103*43209Sbostic return(FMTERR); 104*43209Sbostic } 105*43209Sbostic 106*43209Sbostic char *i_tem(s) char *s; 107*43209Sbostic { char *t; 108*43209Sbostic int n,curloc; 109*43209Sbostic if(*s==')') return(s); 110*43209Sbostic if ((n=ne_d(s,&t))==FMTOK) 111*43209Sbostic return(t); 112*43209Sbostic else if (n==FMTERR) 113*43209Sbostic return(FMTERR); 114*43209Sbostic if ((n=e_d(s,&t))==FMTOK) 115*43209Sbostic return(t); 116*43209Sbostic else if (n==FMTERR) 117*43209Sbostic return(FMTERR); 118*43209Sbostic s=gt_num(s,&n); 119*43209Sbostic if (n == 0) { fmtptr = s; return(FMTERR); } 120*43209Sbostic curloc = op_gen(STACK,n,0,0,s); 121*43209Sbostic return(f_s(s,curloc)); 122*43209Sbostic } 123*43209Sbostic 124*43209Sbostic ne_d(s,p) char *s,**p; 125*43209Sbostic { int n,x,sign=0,pp1,pp2; 126*43209Sbostic switch(low_case[*s]) 127*43209Sbostic { 128*43209Sbostic case ':': op_gen(COLON,(int)('\n'),0,0,s); break; 129*43209Sbostic #ifndef KOSHER 130*43209Sbostic case '$': op_gen(DOLAR,(int)('\0'),0,0,s); break; /*** NOT STANDARD FORTRAN ***/ 131*43209Sbostic #endif 132*43209Sbostic case 'b': 133*43209Sbostic switch(low_case[*(s+1)]) 134*43209Sbostic { 135*43209Sbostic case 'n': s++; op_gen(BNZ,0,0,0,s); break; 136*43209Sbostic case 'z': s++; op_gen(BNZ,1,0,0,s); break; 137*43209Sbostic #ifndef KOSHER 138*43209Sbostic default: op_gen(B,0,0,0,s); break; /*** NOT STANDARD FORTRAN ***/ 139*43209Sbostic #else 140*43209Sbostic default: fmtptr = s; return(FMTUNKN); 141*43209Sbostic #endif 142*43209Sbostic } 143*43209Sbostic break; 144*43209Sbostic case 's': 145*43209Sbostic switch(low_case[*(s+1)]) 146*43209Sbostic { 147*43209Sbostic case 'p': s++; x=SP; pp1=1; pp2=1; break; 148*43209Sbostic #ifndef KOSHER 149*43209Sbostic case 'u': s++; x=SU; pp1=0; pp2=0; break; /*** NOT STANDARD FORTRAN ***/ 150*43209Sbostic #endif 151*43209Sbostic case 's': s++; x=SS; pp1=0; pp2=1; break; 152*43209Sbostic default: x=S; pp1=0; pp2=1; break; 153*43209Sbostic } 154*43209Sbostic op_gen(x,pp1,pp2,0,s); 155*43209Sbostic break; 156*43209Sbostic case '/': op_gen(SLASH,0,0,0,s); break; 157*43209Sbostic 158*43209Sbostic case '-': sign=1; /* OUTRAGEOUS CODING */ 159*43209Sbostic case '+': s++; /* OUTRAGEOUS CODING */ 160*43209Sbostic case '0': case '1': case '2': case '3': case '4': 161*43209Sbostic case '5': case '6': case '7': case '8': case '9': 162*43209Sbostic s=gt_num(s,&n); 163*43209Sbostic switch(low_case[*s]) 164*43209Sbostic { 165*43209Sbostic case 'p': if(sign) n= -n; op_gen(P,n,0,0,s); break; 166*43209Sbostic #ifndef KOSHER 167*43209Sbostic case 'r': if(n<=1) /*** NOT STANDARD FORTRAN ***/ 168*43209Sbostic { fmtptr = --s; return(FMTERR); } 169*43209Sbostic op_gen(R,n,0,0,s); break; 170*43209Sbostic case 't': op_gen(T,0,n,0,s); break; /* NOT STANDARD FORT */ 171*43209Sbostic #endif 172*43209Sbostic case 'x': op_gen(X,n,0,0,s); break; 173*43209Sbostic case 'h': op_gen(H,n,(s+1)-s_init,0,s); 174*43209Sbostic s+=n; 175*43209Sbostic fmt_strings = 1; 176*43209Sbostic break; 177*43209Sbostic default: fmtptr = s; return(FMTUNKN); 178*43209Sbostic } 179*43209Sbostic break; 180*43209Sbostic case GLITCH: 181*43209Sbostic case '"': 182*43209Sbostic case '\'': op_gen(APOS,s-s_init,0,0,s); 183*43209Sbostic *p = ap_end(s); 184*43209Sbostic fmt_strings = 1; 185*43209Sbostic return(FMTOK); 186*43209Sbostic case 't': 187*43209Sbostic switch(low_case[*(s+1)]) 188*43209Sbostic { 189*43209Sbostic case 'l': s++; x=TL; break; 190*43209Sbostic case 'r': s++; x=TR; break; 191*43209Sbostic default: x=T; break; 192*43209Sbostic } 193*43209Sbostic if(isdigit(*(s+1))) {s=gt_num(s+1,&n); s--;} 194*43209Sbostic #ifdef KOSHER 195*43209Sbostic else { fmtptr = s; return(FMTERR); } 196*43209Sbostic #else 197*43209Sbostic else n = 0; /* NOT STANDARD FORTRAN, should be error */ 198*43209Sbostic #endif 199*43209Sbostic op_gen(x,n,1,0,s); 200*43209Sbostic break; 201*43209Sbostic case 'x': op_gen(X,1,0,0,s); break; 202*43209Sbostic case 'p': op_gen(P,0,0,0,s); break; 203*43209Sbostic #ifndef KOSHER 204*43209Sbostic case 'r': op_gen(R,10,1,0,s); break; /*** NOT STANDARD FORTRAN ***/ 205*43209Sbostic #endif 206*43209Sbostic 207*43209Sbostic default: fmtptr = s; return(FMTUNKN); 208*43209Sbostic } 209*43209Sbostic s++; 210*43209Sbostic *p=s; 211*43209Sbostic return(FMTOK); 212*43209Sbostic } 213*43209Sbostic 214*43209Sbostic e_d(s,p) char *s,**p; 215*43209Sbostic { int n,w,d,e,x=0, rep_count; 216*43209Sbostic char *sv=s; 217*43209Sbostic char c; 218*43209Sbostic s=gt_num(s,&rep_count); 219*43209Sbostic if (rep_count == 0) goto ed_err; 220*43209Sbostic c = low_case[*s]; s++; 221*43209Sbostic switch(c) 222*43209Sbostic { 223*43209Sbostic case 'd': 224*43209Sbostic case 'e': 225*43209Sbostic case 'g': 226*43209Sbostic s = gt_num(s, &w); 227*43209Sbostic if (w==0) goto ed_err; 228*43209Sbostic if(*s=='.') 229*43209Sbostic { s++; 230*43209Sbostic s=gt_num(s,&d); 231*43209Sbostic } 232*43209Sbostic else d=0; 233*43209Sbostic if(low_case[*s] == 'e' 234*43209Sbostic #ifndef KOSHER 235*43209Sbostic || *s == '.' /*** '.' is NOT STANDARD FORTRAN ***/ 236*43209Sbostic #endif 237*43209Sbostic ) 238*43209Sbostic { s++; 239*43209Sbostic s=gt_num(s,&e); 240*43209Sbostic if (e==0 || e>127 || d>127 ) goto ed_err; 241*43209Sbostic if(c=='e') n=EE; else if(c=='d') n=DE; else n=GE; 242*43209Sbostic op_gen(n,w,d + (e<<8),rep_count,s); 243*43209Sbostic } 244*43209Sbostic else 245*43209Sbostic { 246*43209Sbostic if(c=='e') n=E; else if(c=='d') n=D; else n=G; 247*43209Sbostic op_gen(n,w,d,rep_count,s); 248*43209Sbostic } 249*43209Sbostic break; 250*43209Sbostic case 'l': 251*43209Sbostic s = gt_num(s, &w); 252*43209Sbostic if (w==0) goto ed_err; 253*43209Sbostic op_gen(L,w,0,rep_count,s); 254*43209Sbostic break; 255*43209Sbostic case 'a': 256*43209Sbostic skip(s); 257*43209Sbostic if(isdigit(*s)) 258*43209Sbostic { s=gt_num(s,&w); 259*43209Sbostic #ifdef KOSHER 260*43209Sbostic if (w==0) goto ed_err; 261*43209Sbostic #else 262*43209Sbostic if (w==0) op_gen(A,0,0,rep_count,s); 263*43209Sbostic else 264*43209Sbostic #endif 265*43209Sbostic op_gen(AW,w,0,rep_count,s); 266*43209Sbostic break; 267*43209Sbostic } 268*43209Sbostic op_gen(A,0,0,rep_count,s); 269*43209Sbostic break; 270*43209Sbostic case 'f': 271*43209Sbostic s = gt_num(s, &w); 272*43209Sbostic if (w==0) goto ed_err; 273*43209Sbostic if(*s=='.') 274*43209Sbostic { s++; 275*43209Sbostic s=gt_num(s,&d); 276*43209Sbostic } 277*43209Sbostic else d=0; 278*43209Sbostic op_gen(F,w,d,rep_count,s); 279*43209Sbostic break; 280*43209Sbostic #ifndef KOSHER 281*43209Sbostic case 'o': /*** octal format - NOT STANDARD FORTRAN ***/ 282*43209Sbostic case 'z': /*** hex format - NOT STANDARD FORTRAN ***/ 283*43209Sbostic #endif 284*43209Sbostic case 'i': 285*43209Sbostic s = gt_num(s, &w); 286*43209Sbostic if (w==0) goto ed_err; 287*43209Sbostic if(*s =='.') 288*43209Sbostic { 289*43209Sbostic s++; 290*43209Sbostic s=gt_num(s,&d); 291*43209Sbostic x = IM; 292*43209Sbostic } 293*43209Sbostic else 294*43209Sbostic { d = 1; 295*43209Sbostic x = I; 296*43209Sbostic } 297*43209Sbostic #ifndef KOSHER 298*43209Sbostic if (c == 'o') 299*43209Sbostic op_gen(R,8,1,rep_count,s); 300*43209Sbostic else if (c == 'z') 301*43209Sbostic op_gen(R,16,1,rep_count,s); 302*43209Sbostic #endif 303*43209Sbostic op_gen(x,w,d,rep_count,s); 304*43209Sbostic #ifndef KOSHER 305*43209Sbostic if (c == 'o' || c == 'z') 306*43209Sbostic op_gen(R,10,1,rep_count,s); 307*43209Sbostic #endif 308*43209Sbostic break; 309*43209Sbostic default: 310*43209Sbostic *p = sv; 311*43209Sbostic fmtptr = s; 312*43209Sbostic return(FMTUNKN); 313*43209Sbostic } 314*43209Sbostic *p = s; 315*43209Sbostic return(FMTOK); 316*43209Sbostic ed_err: 317*43209Sbostic fmtptr = --s; 318*43209Sbostic return(FMTERR); 319*43209Sbostic } 320*43209Sbostic 321*43209Sbostic op_gen(a,b,c,rep,s) char *s; 322*43209Sbostic { struct syl *p= &syl[pc]; 323*43209Sbostic if(pc>=SYLMX) 324*43209Sbostic { fmtptr = s; 325*43209Sbostic err("format too complex"); 326*43209Sbostic } 327*43209Sbostic if( b>32767 || c>32767 || rep>32767 ) 328*43209Sbostic { fmtptr = s; 329*43209Sbostic err("field width or repeat count too large"); 330*43209Sbostic } 331*43209Sbostic #ifdef DEBUG 332*43209Sbostic fprintf(stderr,"%3d opgen: %d %d %d %d %c\n", 333*43209Sbostic pc,a,b,c,rep,*s==GLITCH?'"':*s); /* for debug */ 334*43209Sbostic #endif 335*43209Sbostic p->op=a; 336*43209Sbostic p->p1=b; 337*43209Sbostic p->p2=c; 338*43209Sbostic p->rpcnt=rep; 339*43209Sbostic return(pc++); 340*43209Sbostic } 341*43209Sbostic 342*43209Sbostic char *gt_num(s,n) char *s; int *n; 343*43209Sbostic { int m=0,a_digit=NO; 344*43209Sbostic skip(s); 345*43209Sbostic while(isdigit(*s) || isspace(*s)) 346*43209Sbostic { 347*43209Sbostic if (isdigit(*s)) 348*43209Sbostic { 349*43209Sbostic m = 10*m + (*s)-'0'; 350*43209Sbostic a_digit = YES; 351*43209Sbostic } 352*43209Sbostic s++; 353*43209Sbostic } 354*43209Sbostic if(a_digit) *n=m; 355*43209Sbostic else *n=1; 356*43209Sbostic return(s); 357*43209Sbostic } 358*43209Sbostic 359*43209Sbostic char *ap_end(s) char *s; 360*43209Sbostic { 361*43209Sbostic char quote; 362*43209Sbostic quote = *s++; 363*43209Sbostic for(;*s;s++) 364*43209Sbostic { 365*43209Sbostic if(*s==quote && *++s!=quote) return(s); 366*43209Sbostic } 367*43209Sbostic fmtptr = s; 368*43209Sbostic err("bad string"); 369*43209Sbostic } 370