|
|
1.1 ! root 1: #include "defs" ! 2: #include "tokdefs" ! 3: ! 4: # define BLANK ' ' ! 5: # define MYQUOTE (2) ! 6: # define SEOF 0 ! 7: ! 8: /* card types */ ! 9: ! 10: # define STEOF 1 ! 11: # define STINITIAL 2 ! 12: # define STCONTINUE 3 ! 13: ! 14: /* lex states */ ! 15: ! 16: #define NEWSTMT 1 ! 17: #define FIRSTTOKEN 2 ! 18: #define OTHERTOKEN 3 ! 19: #define RETEOS 4 ! 20: ! 21: ! 22: LOCAL int stkey; ! 23: LOCAL int lastend = 1; ! 24: ftnint yystno; ! 25: flag intonly; ! 26: LOCAL long int stno; ! 27: LOCAL long int nxtstno; ! 28: LOCAL int parlev; ! 29: LOCAL int expcom; ! 30: LOCAL int expeql; ! 31: LOCAL char *nextch; ! 32: LOCAL char *lastch; ! 33: LOCAL char *nextcd = NULL; ! 34: LOCAL char *endcd; ! 35: LOCAL int prevlin; ! 36: LOCAL int thislin; ! 37: LOCAL int code; ! 38: LOCAL int lexstate = NEWSTMT; ! 39: LOCAL char s[1390]; ! 40: LOCAL char *send = s+20*66; ! 41: LOCAL int nincl = 0; ! 42: LOCAL int getcds(), getcd(), crunch(), analyz(), getkwd(), gettok(); ! 43: ! 44: struct Inclfile ! 45: { ! 46: struct Inclfile *inclnext; ! 47: FILEP inclfp; ! 48: char *inclname; ! 49: int incllno; ! 50: char *incllinp; ! 51: int incllen; ! 52: int inclcode; ! 53: ftnint inclstno; ! 54: }; ! 55: ! 56: LOCAL struct Inclfile *inclp = NULL; ! 57: LOCAL struct Keylist { ! 58: char *keyname; ! 59: int keyval; ! 60: char notinf66; ! 61: }; ! 62: LOCAL struct Punctlist { ! 63: char punchar; ! 64: int punval; ! 65: }; ! 66: LOCAL struct Fmtlist { ! 67: char fmtchar; ! 68: int fmtval; ! 69: }; ! 70: LOCAL struct Dotlist { ! 71: char *dotname; ! 72: int dotval; ! 73: }; ! 74: LOCAL struct Keylist *keystart[26], *keyend[26]; ! 75: ! 76: ! 77: ! 78: ! 79: inilex(name) ! 80: char *name; ! 81: { ! 82: nincl = 0; ! 83: inclp = NULL; ! 84: doinclude(name); ! 85: lexstate = NEWSTMT; ! 86: return(NO); ! 87: } ! 88: ! 89: ! 90: ! 91: /* throw away the rest of the current line */ ! 92: flline() ! 93: { ! 94: lexstate = RETEOS; ! 95: } ! 96: ! 97: ! 98: ! 99: char *lexline(n) ! 100: int *n; ! 101: { ! 102: *n = (lastch - nextch) + 1; ! 103: return(nextch); ! 104: } ! 105: ! 106: ! 107: ! 108: ! 109: ! 110: doinclude(name) ! 111: char *name; ! 112: { ! 113: FILEP fp; ! 114: struct Inclfile *t; ! 115: char temp[100]; ! 116: register char *lastslash, *s; ! 117: ! 118: if(inclp) ! 119: { ! 120: inclp->incllno = thislin; ! 121: inclp->inclcode = code; ! 122: inclp->inclstno = nxtstno; ! 123: if(nextcd) ! 124: inclp->incllinp = copyn(inclp->incllen = endcd-nextcd , nextcd); ! 125: else ! 126: inclp->incllinp = 0; ! 127: } ! 128: nextcd = NULL; ! 129: ! 130: if(++nincl >= MAXINCLUDES) ! 131: fatal("includes nested too deep"); ! 132: if(name[0] == '\0') ! 133: fp = stdin; ! 134: else if(name[0]=='/' || inclp==NULL) ! 135: fp = fopen(name, "r"); ! 136: else { ! 137: lastslash = NULL; ! 138: for(s = inclp->inclname ; *s ; ++s) ! 139: if(*s == '/') ! 140: lastslash = s; ! 141: if(lastslash) ! 142: { ! 143: *lastslash = '\0'; ! 144: sprintf(temp, "%s/%s", inclp->inclname, name); ! 145: *lastslash = '/'; ! 146: } ! 147: else ! 148: strcpy(temp, name); ! 149: ! 150: if( (fp = fopen(temp, "r")) == NULL ) ! 151: { ! 152: sprintf(temp, "/usr/include/%s", name); ! 153: fp = fopen(temp, "r"); ! 154: } ! 155: if(fp) ! 156: name = copys(temp); ! 157: } ! 158: ! 159: if( fp ) ! 160: { ! 161: t = inclp; ! 162: inclp = ALLOC(Inclfile); ! 163: inclp->inclnext = t; ! 164: prevlin = thislin = 0; ! 165: infname = inclp->inclname = name; ! 166: infile = inclp->inclfp = fp; ! 167: } ! 168: else ! 169: { ! 170: fprintf(diagfile, "Cannot open file %s", name); ! 171: done(1); ! 172: } ! 173: } ! 174: ! 175: ! 176: ! 177: ! 178: LOCAL popinclude() ! 179: { ! 180: struct Inclfile *t; ! 181: register char *p; ! 182: register int k; ! 183: ! 184: if(infile != stdin) ! 185: clf(&infile); ! 186: free(infname); ! 187: ! 188: --nincl; ! 189: t = inclp->inclnext; ! 190: free( (charptr) inclp); ! 191: inclp = t; ! 192: if(inclp == NULL) ! 193: return(NO); ! 194: ! 195: infile = inclp->inclfp; ! 196: infname = inclp->inclname; ! 197: prevlin = thislin = inclp->incllno; ! 198: code = inclp->inclcode; ! 199: stno = nxtstno = inclp->inclstno; ! 200: if(inclp->incllinp) ! 201: { ! 202: endcd = nextcd = s; ! 203: k = inclp->incllen; ! 204: p = inclp->incllinp; ! 205: while(--k >= 0) ! 206: *endcd++ = *p++; ! 207: free( (charptr) (inclp->incllinp) ); ! 208: } ! 209: else ! 210: nextcd = NULL; ! 211: return(YES); ! 212: } ! 213: ! 214: ! 215: ! 216: ! 217: yylex() ! 218: { ! 219: static int tokno; ! 220: ! 221: switch(lexstate) ! 222: { ! 223: case NEWSTMT : /* need a new statement */ ! 224: if(getcds() == STEOF) ! 225: return(SEOF); ! 226: lastend = stkey == SEND; ! 227: crunch(); ! 228: tokno = 0; ! 229: lexstate = FIRSTTOKEN; ! 230: yystno = stno; ! 231: stno = nxtstno; ! 232: toklen = 0; ! 233: return(SLABEL); ! 234: ! 235: first: ! 236: case FIRSTTOKEN : /* first step on a statement */ ! 237: analyz(); ! 238: lexstate = OTHERTOKEN; ! 239: tokno = 1; ! 240: return(stkey); ! 241: ! 242: case OTHERTOKEN : /* return next token */ ! 243: if(nextch > lastch) ! 244: goto reteos; ! 245: ++tokno; ! 246: if( (stkey==SLOGIF || stkey==SELSEIF) && parlev==0 && tokno>3) ! 247: goto first; ! 248: ! 249: if(stkey==SASSIGN && tokno==3 && nextch<lastch && ! 250: nextch[0]=='t' && nextch[1]=='o') ! 251: { ! 252: nextch+=2; ! 253: return(STO); ! 254: } ! 255: return(gettok()); ! 256: ! 257: reteos: ! 258: case RETEOS: ! 259: lexstate = NEWSTMT; ! 260: return(SEOS); ! 261: } ! 262: fatali("impossible lexstate %d", lexstate); ! 263: /* NOTREACHED */ ! 264: } ! 265: ! 266: LOCAL getcds() ! 267: { ! 268: register char *p, *q; ! 269: ! 270: top: ! 271: if(nextcd == NULL) ! 272: { ! 273: code = getcd( nextcd = s ); ! 274: stno = nxtstno; ! 275: prevlin = thislin; ! 276: } ! 277: if(code == STEOF) ! 278: if( popinclude() ) ! 279: goto top; ! 280: else ! 281: return(STEOF); ! 282: ! 283: if(code == STCONTINUE) ! 284: { ! 285: lineno = thislin; ! 286: err("illegal continuation card ignored"); ! 287: nextcd = NULL; ! 288: goto top; ! 289: } ! 290: ! 291: if(nextcd > s) ! 292: { ! 293: q = nextcd; ! 294: p = s; ! 295: while(q < endcd) ! 296: *p++ = *q++; ! 297: endcd = p; ! 298: } ! 299: for(nextcd = endcd ; ! 300: nextcd+66<=send && (code = getcd(nextcd))==STCONTINUE ; ! 301: nextcd = endcd ) ! 302: ; ! 303: nextch = s; ! 304: lastch = nextcd - 1; ! 305: if(nextcd >= send) ! 306: nextcd = NULL; ! 307: lineno = prevlin; ! 308: prevlin = thislin; ! 309: return(STINITIAL); ! 310: } ! 311: ! 312: LOCAL getcd(b) ! 313: register char *b; ! 314: { ! 315: register int c; ! 316: register char *p, *bend; ! 317: int speclin; ! 318: static char a[6]; ! 319: static char *aend = a+6; ! 320: ! 321: top: ! 322: endcd = b; ! 323: bend = b+66; ! 324: speclin = NO; ! 325: ! 326: if( (c = getc(infile)) == '&') ! 327: { ! 328: a[0] = BLANK; ! 329: a[5] = 'x'; ! 330: speclin = YES; ! 331: bend = send; ! 332: } ! 333: else if(c=='c' || c=='C' || c=='*') ! 334: { ! 335: while( (c = getc(infile)) != '\n') ! 336: if(c == EOF) ! 337: return(STEOF); ! 338: ++thislin; ! 339: goto top; ! 340: } ! 341: ! 342: else if(c != EOF) ! 343: { ! 344: /* a tab in columns 1-6 skips to column 7 */ ! 345: ungetc(c, infile); ! 346: for(p=a; p<aend && (c=getc(infile)) != '\n' && c!=EOF; ) ! 347: if(c == '\t') ! 348: { ! 349: while(p < aend) ! 350: *p++ = BLANK; ! 351: speclin = YES; ! 352: bend = send; ! 353: } ! 354: else ! 355: *p++ = c; ! 356: } ! 357: if(c == EOF) ! 358: return(STEOF); ! 359: if(c == '\n') ! 360: { ! 361: while(p < aend) ! 362: *p++ = BLANK; ! 363: if( ! speclin ) ! 364: while(endcd < bend) ! 365: *endcd++ = BLANK; ! 366: } ! 367: else { /* read body of line */ ! 368: while( endcd<bend && (c=getc(infile)) != '\n' && c!=EOF ) ! 369: *endcd++ = c; ! 370: if(c == EOF) ! 371: return(STEOF); ! 372: if(c != '\n') ! 373: { ! 374: while( (c=getc(infile)) != '\n') ! 375: if(c == EOF) ! 376: return(STEOF); ! 377: } ! 378: ! 379: if( ! speclin ) ! 380: while(endcd < bend) ! 381: *endcd++ = BLANK; ! 382: } ! 383: ++thislin; ! 384: if( !isspace(a[5]) && a[5]!='0') ! 385: return(STCONTINUE); ! 386: for(p=a; p<aend; ++p) ! 387: if( !isspace(*p) ) goto initline; ! 388: for(p = b ; p<endcd ; ++p) ! 389: if( !isspace(*p) ) goto initline; ! 390: goto top; ! 391: ! 392: initline: ! 393: nxtstno = 0; ! 394: for(p = a ; p<a+5 ; ++p) ! 395: if( !isspace(*p) ) ! 396: if(isdigit(*p)) ! 397: nxtstno = 10*nxtstno + (*p - '0'); ! 398: else { ! 399: lineno = thislin; ! 400: err("nondigit in statement number field"); ! 401: nxtstno = 0; ! 402: break; ! 403: } ! 404: return(STINITIAL); ! 405: } ! 406: ! 407: LOCAL crunch() ! 408: { ! 409: register char *i, *j, *j0, *j1, *prvstr; ! 410: int ten, nh, quote; ! 411: ! 412: /* i is the next input character to be looked at ! 413: j is the next output character */ ! 414: parlev = 0; ! 415: expcom = 0; /* exposed ','s */ ! 416: expeql = 0; /* exposed equal signs */ ! 417: j = s; ! 418: prvstr = s; ! 419: for(i=s ; i<=lastch ; ++i) ! 420: { ! 421: if(isspace(*i) ) ! 422: continue; ! 423: if(*i=='\'' || *i=='"') ! 424: { ! 425: quote = *i; ! 426: *j = MYQUOTE; /* special marker */ ! 427: for(;;) ! 428: { ! 429: if(++i > lastch) ! 430: { ! 431: err("unbalanced quotes; closing quote supplied"); ! 432: break; ! 433: } ! 434: if(*i == quote) ! 435: if(i<lastch && i[1]==quote) ++i; ! 436: else break; ! 437: else if(*i=='\\' && i<lastch) ! 438: switch(*++i) ! 439: { ! 440: case 't': ! 441: *i = '\t'; ! 442: break; ! 443: case 'b': ! 444: *i = '\b'; ! 445: break; ! 446: case 'n': ! 447: *i = '\n'; ! 448: break; ! 449: case 'f': ! 450: *i = '\f'; ! 451: break; ! 452: case 'v': ! 453: *i = '\v'; ! 454: break; ! 455: case '0': ! 456: *i = '\0'; ! 457: break; ! 458: default: ! 459: break; ! 460: } ! 461: *++j = *i; ! 462: } ! 463: j[1] = MYQUOTE; ! 464: j += 2; ! 465: prvstr = j; ! 466: } ! 467: else if( (*i=='h' || *i=='H') && j>prvstr) /* test for Hollerith strings */ ! 468: { ! 469: if( ! isdigit(j[-1])) goto copychar; ! 470: nh = j[-1] - '0'; ! 471: ten = 10; ! 472: j1 = prvstr - 1; ! 473: if (j1<j-5) j1=j-5; ! 474: for(j0=j-2 ; j0>j1; -- j0) ! 475: { ! 476: if( ! isdigit(*j0 ) ) break; ! 477: nh += ten * (*j0-'0'); ! 478: ten*=10; ! 479: } ! 480: if(j0 <= j1) goto copychar; ! 481: /* a hollerith must be preceded by a punctuation mark. ! 482: '*' is possible only as repetition factor in a data statement ! 483: not, in particular, in character*2h ! 484: */ ! 485: ! 486: if( !(*j0=='*'&&s[0]=='d') && *j0!='/' && *j0!='(' && ! 487: *j0!=',' && *j0!='=' && *j0!='.') ! 488: goto copychar; ! 489: if(i+nh > lastch) ! 490: { ! 491: erri("%dH too big", nh); ! 492: nh = lastch - i; ! 493: } ! 494: j0[1] = MYQUOTE; /* special marker */ ! 495: j = j0 + 1; ! 496: while(nh-- > 0) ! 497: { ! 498: if(*++i == '\\') ! 499: switch(*++i) ! 500: { ! 501: case 't': ! 502: *i = '\t'; ! 503: break; ! 504: case 'b': ! 505: *i = '\b'; ! 506: break; ! 507: case 'n': ! 508: *i = '\n'; ! 509: break; ! 510: case 'f': ! 511: *i = '\f'; ! 512: break; ! 513: case '0': ! 514: *i = '\0'; ! 515: break; ! 516: default: ! 517: break; ! 518: } ! 519: *++j = *i; ! 520: } ! 521: j[1] = MYQUOTE; ! 522: j+=2; ! 523: prvstr = j; ! 524: } ! 525: else { ! 526: if(*i == '(') ++parlev; ! 527: else if(*i == ')') --parlev; ! 528: else if(parlev == 0) ! 529: if(*i == '=') expeql = 1; ! 530: else if(*i == ',') expcom = 1; ! 531: copychar: /*not a string or space -- copy, shifting case if necessary */ ! 532: if(shiftcase && isupper(*i)) ! 533: *j++ = tolower(*i); ! 534: else *j++ = *i; ! 535: } ! 536: } ! 537: lastch = j - 1; ! 538: nextch = s; ! 539: } ! 540: ! 541: LOCAL analyz() ! 542: { ! 543: register char *i; ! 544: ! 545: if(parlev != 0) ! 546: { ! 547: err("unbalanced parentheses, statement skipped"); ! 548: stkey = SUNKNOWN; ! 549: return; ! 550: } ! 551: if(nextch+2<=lastch && nextch[0]=='i' && nextch[1]=='f' && nextch[2]=='(') ! 552: { ! 553: /* assignment or if statement -- look at character after balancing paren */ ! 554: parlev = 1; ! 555: for(i=nextch+3 ; i<=lastch; ++i) ! 556: if(*i == (MYQUOTE)) ! 557: { ! 558: while(*++i != MYQUOTE) ! 559: ; ! 560: } ! 561: else if(*i == '(') ! 562: ++parlev; ! 563: else if(*i == ')') ! 564: { ! 565: if(--parlev == 0) ! 566: break; ! 567: } ! 568: if(i >= lastch) ! 569: stkey = SLOGIF; ! 570: else if(i[1] == '=') ! 571: stkey = SLET; ! 572: else if( isdigit(i[1]) ) ! 573: stkey = SARITHIF; ! 574: else stkey = SLOGIF; ! 575: if(stkey != SLET) ! 576: nextch += 2; ! 577: } ! 578: else if(expeql) /* may be an assignment */ ! 579: { ! 580: if(expcom && nextch<lastch && ! 581: nextch[0]=='d' && nextch[1]=='o') ! 582: { ! 583: stkey = SDO; ! 584: nextch += 2; ! 585: } ! 586: else stkey = SLET; ! 587: } ! 588: /* otherwise search for keyword */ ! 589: else { ! 590: stkey = getkwd(); ! 591: if(stkey==SGOTO && lastch>=nextch) ! 592: if(nextch[0]=='(') ! 593: stkey = SCOMPGOTO; ! 594: else if(isalpha(nextch[0])) ! 595: stkey = SASGOTO; ! 596: } ! 597: parlev = 0; ! 598: } ! 599: ! 600: ! 601: ! 602: LOCAL getkwd() ! 603: { ! 604: register char *i, *j; ! 605: register struct Keylist *pk, *pend; ! 606: int k; ! 607: ! 608: if(! isalpha(nextch[0]) ) ! 609: return(SUNKNOWN); ! 610: k = nextch[0] - 'a'; ! 611: if(pk = keystart[k]) ! 612: for(pend = keyend[k] ; pk<=pend ; ++pk ) ! 613: { ! 614: i = pk->keyname; ! 615: j = nextch; ! 616: while(*++i==*++j && *i!='\0') ! 617: ; ! 618: if(*i=='\0' && j<=lastch+1) ! 619: { ! 620: nextch = j; ! 621: if(no66flag && pk->notinf66) ! 622: errstr("Not a Fortran 66 keyword: %s", ! 623: pk->keyname); ! 624: return(pk->keyval); ! 625: } ! 626: } ! 627: return(SUNKNOWN); ! 628: } ! 629: ! 630: ! 631: ! 632: LOCAL struct Dotlist dots[ ] = ! 633: { ! 634: "and.", SAND, ! 635: "or.", SOR, ! 636: "not.", SNOT, ! 637: "true.", STRUE, ! 638: "false.", SFALSE, ! 639: "eq.", SEQ, ! 640: "ne.", SNE, ! 641: "lt.", SLT, ! 642: "le.", SLE, ! 643: "gt.", SGT, ! 644: "ge.", SGE, ! 645: "neqv.", SNEQV, ! 646: "eqv.", SEQV, ! 647: 0, 0 }; ! 648: ! 649: LOCAL struct Keylist keys[ ] = ! 650: { ! 651: { "assign", SASSIGN }, ! 652: { "automatic", SAUTOMATIC, YES }, ! 653: { "backspace", SBACKSPACE }, ! 654: { "blockdata", SBLOCK }, ! 655: { "call", SCALL }, ! 656: { "character", SCHARACTER, YES }, ! 657: { "close", SCLOSE, YES }, ! 658: { "common", SCOMMON }, ! 659: { "complex", SCOMPLEX }, ! 660: { "continue", SCONTINUE }, ! 661: { "data", SDATA }, ! 662: { "dimension", SDIMENSION }, ! 663: { "doubleprecision", SDOUBLE }, ! 664: { "doublecomplex", SDCOMPLEX, YES }, ! 665: { "elseif", SELSEIF, YES }, ! 666: { "else", SELSE, YES }, ! 667: { "endfile", SENDFILE }, ! 668: { "endif", SENDIF, YES }, ! 669: { "end", SEND }, ! 670: { "entry", SENTRY, YES }, ! 671: { "equivalence", SEQUIV }, ! 672: { "external", SEXTERNAL }, ! 673: { "format", SFORMAT }, ! 674: { "function", SFUNCTION }, ! 675: { "goto", SGOTO }, ! 676: { "implicit", SIMPLICIT, YES }, ! 677: { "include", SINCLUDE, YES }, ! 678: { "inquire", SINQUIRE, YES }, ! 679: { "intrinsic", SINTRINSIC, YES }, ! 680: { "integer", SINTEGER }, ! 681: { "logical", SLOGICAL }, ! 682: { "namelist", SNAMELIST, YES }, ! 683: { "none", SUNDEFINED, YES }, ! 684: { "open", SOPEN, YES }, ! 685: { "parameter", SPARAM, YES }, ! 686: { "pause", SPAUSE }, ! 687: { "print", SPRINT }, ! 688: { "program", SPROGRAM, YES }, ! 689: { "punch", SPUNCH, YES }, ! 690: { "read", SREAD }, ! 691: { "real", SREAL }, ! 692: { "return", SRETURN }, ! 693: { "rewind", SREWIND }, ! 694: { "save", SSAVE, YES }, ! 695: { "static", SSTATIC, YES }, ! 696: { "stop", SSTOP }, ! 697: { "subroutine", SSUBROUTINE }, ! 698: { "then", STHEN, YES }, ! 699: { "undefined", SUNDEFINED, YES }, ! 700: { "write", SWRITE }, ! 701: { 0, 0 } ! 702: }; ! 703: ! 704: ! 705: initkey() ! 706: { ! 707: register struct Keylist *p; ! 708: register int i,j; ! 709: ! 710: for(i = 0 ; i<26 ; ++i) ! 711: keystart[i] = NULL; ! 712: ! 713: for(p = keys ; p->keyname ; ++p) ! 714: { ! 715: j = p->keyname[0] - 'a'; ! 716: if(keystart[j] == NULL) ! 717: keystart[j] = p; ! 718: keyend[j] = p; ! 719: } ! 720: } ! 721: ! 722: LOCAL gettok() ! 723: { ! 724: int havdot, havexp, havdbl; ! 725: int radix, val; ! 726: extern struct Punctlist puncts[]; ! 727: struct Punctlist *pp; ! 728: extern struct Fmtlist fmts[]; ! 729: struct Dotlist *pd; ! 730: ! 731: char *i, *j, *n1, *p; ! 732: ! 733: if(*nextch == (MYQUOTE)) ! 734: { ! 735: ++nextch; ! 736: p = token; ! 737: while(*nextch != MYQUOTE) ! 738: *p++ = *nextch++; ! 739: ++nextch; ! 740: toklen = p - token; ! 741: *p = '\0'; ! 742: return (SHOLLERITH); ! 743: } ! 744: /* ! 745: if(stkey == SFORMAT) ! 746: { ! 747: for(pf = fmts; pf->fmtchar; ++pf) ! 748: { ! 749: if(*nextch == pf->fmtchar) ! 750: { ! 751: ++nextch; ! 752: if(pf->fmtval == SLPAR) ! 753: ++parlev; ! 754: else if(pf->fmtval == SRPAR) ! 755: --parlev; ! 756: return(pf->fmtval); ! 757: } ! 758: } ! 759: if( isdigit(*nextch) ) ! 760: { ! 761: p = token; ! 762: *p++ = *nextch++; ! 763: while(nextch<=lastch && isdigit(*nextch) ) ! 764: *p++ = *nextch++; ! 765: toklen = p - token; ! 766: *p = '\0'; ! 767: if(nextch<=lastch && *nextch=='p') ! 768: { ! 769: ++nextch; ! 770: return(SSCALE); ! 771: } ! 772: else return(SICON); ! 773: } ! 774: if( isalpha(*nextch) ) ! 775: { ! 776: p = token; ! 777: *p++ = *nextch++; ! 778: while(nextch<=lastch && ! 779: (*nextch=='.' || isdigit(*nextch) || isalpha(*nextch) )) ! 780: *p++ = *nextch++; ! 781: toklen = p - token; ! 782: *p = '\0'; ! 783: return(SFIELD); ! 784: } ! 785: goto badchar; ! 786: } ! 787: /* Not a format statement */ ! 788: ! 789: if(needkwd) ! 790: { ! 791: needkwd = 0; ! 792: return( getkwd() ); ! 793: } ! 794: ! 795: for(pp=puncts; pp->punchar; ++pp) ! 796: if(*nextch == pp->punchar) ! 797: { ! 798: if( (*nextch=='*' || *nextch=='/') && ! 799: nextch<lastch && nextch[1]==nextch[0]) ! 800: { ! 801: if(*nextch == '*') ! 802: val = SPOWER; ! 803: else val = SCONCAT; ! 804: nextch+=2; ! 805: } ! 806: else { ! 807: val = pp->punval; ! 808: if(val==SLPAR) ! 809: ++parlev; ! 810: else if(val==SRPAR) ! 811: --parlev; ! 812: ++nextch; ! 813: } ! 814: return(val); ! 815: } ! 816: if(*nextch == '.') ! 817: if(nextch >= lastch) goto badchar; ! 818: else if(isdigit(nextch[1])) goto numconst; ! 819: else { ! 820: for(pd=dots ; (j=pd->dotname) ; ++pd) ! 821: { ! 822: for(i=nextch+1 ; i<=lastch ; ++i) ! 823: if(*i != *j) break; ! 824: else if(*i != '.') ++j; ! 825: else { ! 826: nextch = i+1; ! 827: return(pd->dotval); ! 828: } ! 829: } ! 830: goto badchar; ! 831: } ! 832: if( isalpha(*nextch) ) ! 833: { ! 834: p = token; ! 835: *p++ = *nextch++; ! 836: while(nextch<=lastch) ! 837: if( isalpha(*nextch) || isdigit(*nextch) ) ! 838: *p++ = *nextch++; ! 839: else break; ! 840: toklen = p - token; ! 841: *p = '\0'; ! 842: if(inioctl && nextch<=lastch && *nextch=='=') ! 843: { ! 844: ++nextch; ! 845: return(SNAMEEQ); ! 846: } ! 847: if(toklen>8 && eqn(8,token,"function") && isalpha(token[8]) && ! 848: nextch<lastch && nextch[0]=='(' && ! 849: (nextch[1]==')' | isalpha(nextch[1])) ) ! 850: { ! 851: nextch -= (toklen - 8); ! 852: return(SFUNCTION); ! 853: } ! 854: if(toklen > VL) ! 855: { ! 856: char buff[30]; ! 857: sprintf(buff, "name %s too long, truncated to %d", ! 858: token, VL); ! 859: err(buff); ! 860: toklen = VL; ! 861: token[VL] = '\0'; ! 862: } ! 863: if(toklen==1 && *nextch==MYQUOTE) ! 864: { ! 865: switch(token[0]) ! 866: { ! 867: case 'z': ! 868: case 'Z': ! 869: case 'x': ! 870: case 'X': ! 871: radix = 16; ! 872: break; ! 873: case 'o': ! 874: case 'O': ! 875: radix = 8; ! 876: break; ! 877: case 'b': ! 878: case 'B': ! 879: radix = 2; ! 880: break; ! 881: default: ! 882: err("bad bit identifier"); ! 883: return(SNAME); ! 884: } ! 885: ++nextch; ! 886: for(p = token ; *nextch!=MYQUOTE ; ) ! 887: if( hextoi(*p++ = *nextch++) >= radix) ! 888: { ! 889: err("invalid binary character"); ! 890: break; ! 891: } ! 892: ++nextch; ! 893: toklen = p - token; ! 894: return( radix==16 ? SHEXCON : ! 895: (radix==8 ? SOCTCON : SBITCON) ); ! 896: } ! 897: return(SNAME); ! 898: } ! 899: if( ! isdigit(*nextch) ) goto badchar; ! 900: numconst: ! 901: havdot = NO; ! 902: havexp = NO; ! 903: havdbl = NO; ! 904: for(n1 = nextch ; nextch<=lastch ; ++nextch) ! 905: { ! 906: if(*nextch == '.') ! 907: if(havdot) break; ! 908: else if(nextch+2<=lastch && isalpha(nextch[1]) ! 909: && isalpha(nextch[2])) ! 910: break; ! 911: else havdot = YES; ! 912: else if( !intonly && (*nextch=='d' || *nextch=='e') ) ! 913: { ! 914: p = nextch; ! 915: havexp = YES; ! 916: if(*nextch == 'd') ! 917: havdbl = YES; ! 918: if(nextch<lastch) ! 919: if(nextch[1]=='+' || nextch[1]=='-') ! 920: ++nextch; ! 921: if( ! isdigit(*++nextch) ) ! 922: { ! 923: nextch = p; ! 924: havdbl = havexp = NO; ! 925: break; ! 926: } ! 927: for(++nextch ; ! 928: nextch<=lastch && isdigit(*nextch); ! 929: ++nextch); ! 930: break; ! 931: } ! 932: else if( ! isdigit(*nextch) ) ! 933: break; ! 934: } ! 935: p = token; ! 936: i = n1; ! 937: while(i < nextch) ! 938: *p++ = *i++; ! 939: toklen = p - token; ! 940: *p = '\0'; ! 941: if(havdbl) return(SDCON); ! 942: if(havdot || havexp) return(SRCON); ! 943: return(SICON); ! 944: badchar: ! 945: s[0] = *nextch++; ! 946: return(SUNKNOWN); ! 947: } ! 948: ! 949: /* KEYWORD AND SPECIAL CHARACTER TABLES ! 950: */ ! 951: ! 952: struct Punctlist puncts[ ] = ! 953: { ! 954: '(', SLPAR, ! 955: ')', SRPAR, ! 956: '=', SEQUALS, ! 957: ',', SCOMMA, ! 958: '+', SPLUS, ! 959: '-', SMINUS, ! 960: '*', SSTAR, ! 961: '/', SSLASH, ! 962: '$', SCURRENCY, ! 963: ':', SCOLON, ! 964: 0, 0 }; ! 965: ! 966: /* ! 967: LOCAL struct Fmtlist fmts[ ] = ! 968: { ! 969: '(', SLPAR, ! 970: ')', SRPAR, ! 971: '/', SSLASH, ! 972: ',', SCOMMA, ! 973: '-', SMINUS, ! 974: ':', SCOLON, ! 975: 0, 0 } ; ! 976: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.