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