|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)vfontedpr.c 5.5 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/types.h> ! 31: #include <sys/stat.h> ! 32: #include <ctype.h> ! 33: #include <stdio.h> ! 34: #include "pathnames.h" ! 35: ! 36: #define boolean int ! 37: #define TRUE 1 ! 38: #define FALSE 0 ! 39: #define NIL 0 ! 40: #define STANDARD 0 ! 41: #define ALTERNATE 1 ! 42: ! 43: /* ! 44: * Vfontedpr. ! 45: * ! 46: * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy) ! 47: * ! 48: */ ! 49: ! 50: #define STRLEN 10 /* length of strings introducing things */ ! 51: #define PNAMELEN 40 /* length of a function/procedure name */ ! 52: #define PSMAX 20 /* size of procedure name stacking */ ! 53: ! 54: /* regular expression routines */ ! 55: ! 56: char *expmatch(); /* match a string to an expression */ ! 57: char *STRNCMP(); /* a different kindof strncmp */ ! 58: char *convexp(); /* convert expression to internal form */ ! 59: char *tgetstr(); ! 60: ! 61: boolean isproc(); ! 62: ! 63: ! 64: char *ctime(); ! 65: ! 66: /* ! 67: * The state variables ! 68: */ ! 69: ! 70: boolean incomm; /* in a comment of the primary type */ ! 71: boolean instr; /* in a string constant */ ! 72: boolean inchr; /* in a string constant */ ! 73: boolean nokeyw = FALSE; /* no keywords being flagged */ ! 74: boolean index = FALSE; /* form an index */ ! 75: boolean filter = FALSE; /* act as a filter (like eqn) */ ! 76: boolean pass = FALSE; /* when acting as a filter, pass indicates ! 77: * whether we are currently processing ! 78: * input. ! 79: */ ! 80: boolean prccont; /* continue last procedure */ ! 81: int comtype; /* type of comment */ ! 82: int margin; ! 83: int psptr; /* the stack index of the current procedure */ ! 84: char pstack[PSMAX][PNAMELEN+1]; /* the procedure name stack */ ! 85: int plstack[PSMAX]; /* the procedure nesting level stack */ ! 86: int blklevel; /* current nesting level */ ! 87: char *defsfile = _PATH_VGRINDEFS; /* name of language definitions file */ ! 88: char pname[BUFSIZ+1]; ! 89: ! 90: /* ! 91: * The language specific globals ! 92: */ ! 93: ! 94: char *language = "c"; /* the language indicator */ ! 95: char *l_keywds[BUFSIZ/2]; /* keyword table address */ ! 96: char *l_prcbeg; /* regular expr for procedure begin */ ! 97: char *l_combeg; /* string introducing a comment */ ! 98: char *l_comend; /* string ending a comment */ ! 99: char *l_acmbeg; /* string introducing a comment */ ! 100: char *l_acmend; /* string ending a comment */ ! 101: char *l_blkbeg; /* string begining of a block */ ! 102: char *l_blkend; /* string ending a block */ ! 103: char *l_strbeg; /* delimiter for string constant */ ! 104: char *l_strend; /* delimiter for string constant */ ! 105: char *l_chrbeg; /* delimiter for character constant */ ! 106: char *l_chrend; /* delimiter for character constant */ ! 107: char l_escape; /* character used to escape characters */ ! 108: boolean l_toplex; /* procedures only defined at top lex level */ ! 109: ! 110: /* ! 111: * global variables also used by expmatch ! 112: */ ! 113: boolean _escaped; /* if last character was an escape */ ! 114: char *_start; /* start of the current string */ ! 115: boolean l_onecase; /* upper and lower case are equivalent */ ! 116: ! 117: #define ps(x) printf("%s", x) ! 118: ! 119: main(argc, argv) ! 120: int argc; ! 121: char *argv[]; ! 122: { ! 123: int lineno; ! 124: char *fname = ""; ! 125: char *ptr; ! 126: struct stat stbuf; ! 127: char buf[BUFSIZ]; ! 128: char strings[2 * BUFSIZ]; ! 129: char defs[2 * BUFSIZ]; ! 130: int needbp = 0; ! 131: ! 132: argc--, argv++; ! 133: do { ! 134: char *cp; ! 135: int i; ! 136: ! 137: if (argc > 0) { ! 138: if (!strcmp(argv[0], "-h")) { ! 139: if (argc == 1) { ! 140: printf("'ds =H\n"); ! 141: argc = 0; ! 142: goto rest; ! 143: } ! 144: printf("'ds =H %s\n", argv[1]); ! 145: argc--, argv++; ! 146: argc--, argv++; ! 147: if (argc > 0) ! 148: continue; ! 149: goto rest; ! 150: } ! 151: ! 152: /* act as a filter like eqn */ ! 153: if (!strcmp(argv[0], "-f")) { ! 154: filter++; ! 155: argv[0] = argv[argc-1]; ! 156: argv[argc-1] = "-"; ! 157: continue; ! 158: } ! 159: ! 160: /* take input from the standard place */ ! 161: if (!strcmp(argv[0], "-")) { ! 162: argc = 0; ! 163: goto rest; ! 164: } ! 165: ! 166: /* build an index */ ! 167: if (!strcmp(argv[0], "-x")) { ! 168: index++; ! 169: argv[0] = "-n"; ! 170: } ! 171: ! 172: /* indicate no keywords */ ! 173: if (!strcmp(argv[0], "-n")) { ! 174: nokeyw++; ! 175: argc--, argv++; ! 176: continue; ! 177: } ! 178: ! 179: /* specify the font size */ ! 180: if (!strncmp(argv[0], "-s", 2)) { ! 181: i = 0; ! 182: cp = argv[0] + 2; ! 183: while (*cp) ! 184: i = i * 10 + (*cp++ - '0'); ! 185: printf("'ps %d\n'vs %d\n", i, i+1); ! 186: argc--, argv++; ! 187: continue; ! 188: } ! 189: ! 190: /* specify the language */ ! 191: if (!strncmp(argv[0], "-l", 2)) { ! 192: language = argv[0]+2; ! 193: argc--, argv++; ! 194: continue; ! 195: } ! 196: ! 197: /* specify the language description file */ ! 198: if (!strncmp(argv[0], "-d", 2)) { ! 199: defsfile = argv[1]; ! 200: argc--, argv++; ! 201: argc--, argv++; ! 202: continue; ! 203: } ! 204: ! 205: /* open the file for input */ ! 206: if (freopen(argv[0], "r", stdin) == NULL) { ! 207: perror(argv[0]); ! 208: exit(1); ! 209: } ! 210: if (index) ! 211: printf("'ta 4i 4.25i 5.5iR\n'in .5i\n"); ! 212: fname = argv[0]; ! 213: argc--, argv++; ! 214: } ! 215: rest: ! 216: ! 217: /* ! 218: * get the language definition from the defs file ! 219: */ ! 220: i = tgetent (defs, language, defsfile); ! 221: if (i == 0) { ! 222: fprintf (stderr, "no entry for language %s\n", language); ! 223: exit (0); ! 224: } else if (i < 0) { ! 225: fprintf (stderr, "cannot find vgrindefs file %s\n", defsfile); ! 226: exit (0); ! 227: } ! 228: cp = strings; ! 229: if (tgetstr ("kw", &cp) == NIL) ! 230: nokeyw = TRUE; ! 231: else { ! 232: char **cpp; ! 233: ! 234: cpp = l_keywds; ! 235: cp = strings; ! 236: while (*cp) { ! 237: while (*cp == ' ' || *cp =='\t') ! 238: *cp++ = NULL; ! 239: if (*cp) ! 240: *cpp++ = cp; ! 241: while (*cp != ' ' && *cp != '\t' && *cp) ! 242: cp++; ! 243: } ! 244: *cpp = NIL; ! 245: } ! 246: cp = buf; ! 247: l_prcbeg = convexp (tgetstr ("pb", &cp)); ! 248: cp = buf; ! 249: l_combeg = convexp (tgetstr ("cb", &cp)); ! 250: cp = buf; ! 251: l_comend = convexp (tgetstr ("ce", &cp)); ! 252: cp = buf; ! 253: l_acmbeg = convexp (tgetstr ("ab", &cp)); ! 254: cp = buf; ! 255: l_acmend = convexp (tgetstr ("ae", &cp)); ! 256: cp = buf; ! 257: l_strbeg = convexp (tgetstr ("sb", &cp)); ! 258: cp = buf; ! 259: l_strend = convexp (tgetstr ("se", &cp)); ! 260: cp = buf; ! 261: l_blkbeg = convexp (tgetstr ("bb", &cp)); ! 262: cp = buf; ! 263: l_blkend = convexp (tgetstr ("be", &cp)); ! 264: cp = buf; ! 265: l_chrbeg = convexp (tgetstr ("lb", &cp)); ! 266: cp = buf; ! 267: l_chrend = convexp (tgetstr ("le", &cp)); ! 268: l_escape = '\\'; ! 269: l_onecase = tgetflag ("oc"); ! 270: l_toplex = tgetflag ("tl"); ! 271: ! 272: /* initialize the program */ ! 273: ! 274: incomm = FALSE; ! 275: instr = FALSE; ! 276: inchr = FALSE; ! 277: _escaped = FALSE; ! 278: blklevel = 0; ! 279: for (psptr=0; psptr<PSMAX; psptr++) { ! 280: pstack[psptr][0] = NULL; ! 281: plstack[psptr] = 0; ! 282: } ! 283: psptr = -1; ! 284: ps("'-F\n"); ! 285: if (!filter) { ! 286: printf(".ds =F %s\n", fname); ! 287: ps("'wh 0 vH\n"); ! 288: ps("'wh -1i vF\n"); ! 289: } ! 290: if (needbp) { ! 291: needbp = 0; ! 292: printf(".()\n"); ! 293: printf(".bp\n"); ! 294: } ! 295: if (!filter) { ! 296: fstat(fileno(stdin), &stbuf); ! 297: cp = ctime(&stbuf.st_mtime); ! 298: cp[16] = '\0'; ! 299: cp[24] = '\0'; ! 300: printf(".ds =M %s %s\n", cp+4, cp+20); ! 301: } ! 302: ! 303: /* ! 304: * MAIN LOOP!!! ! 305: */ ! 306: while (fgets(buf, sizeof buf, stdin) != NULL) { ! 307: if (buf[0] == '\f') { ! 308: printf(".bp\n"); ! 309: } ! 310: if (buf[0] == '.') { ! 311: printf("%s", buf); ! 312: if (!strncmp (buf+1, "vS", 2)) ! 313: pass = TRUE; ! 314: if (!strncmp (buf+1, "vE", 2)) ! 315: pass = FALSE; ! 316: continue; ! 317: } ! 318: prccont = FALSE; ! 319: if (!filter || pass) ! 320: putScp(buf); ! 321: else ! 322: printf("%s", buf); ! 323: if (prccont && (psptr >= 0)) { ! 324: ps("'FC "); ! 325: ps(pstack[psptr]); ! 326: ps("\n"); ! 327: } ! 328: #ifdef DEBUG ! 329: printf ("com %o str %o chr %o ptr %d\n", incomm, instr, inchr, psptr); ! 330: #endif ! 331: margin = 0; ! 332: } ! 333: needbp = 1; ! 334: } while (argc > 0); ! 335: exit(0); ! 336: } ! 337: ! 338: #define isidchr(c) (isalnum(c) || (c) == '_') ! 339: ! 340: putScp(os) ! 341: char *os; ! 342: { ! 343: register char *s = os; /* pointer to unmatched string */ ! 344: char dummy[BUFSIZ]; /* dummy to be used by expmatch */ ! 345: char *comptr; /* end of a comment delimiter */ ! 346: char *acmptr; /* end of a comment delimiter */ ! 347: char *strptr; /* end of a string delimiter */ ! 348: char *chrptr; /* end of a character const delimiter */ ! 349: char *blksptr; /* end of a lexical block start */ ! 350: char *blkeptr; /* end of a lexical block end */ ! 351: ! 352: _start = os; /* remember the start for expmatch */ ! 353: _escaped = FALSE; ! 354: if (nokeyw || incomm || instr) ! 355: goto skip; ! 356: if (isproc(s)) { ! 357: ps("'FN "); ! 358: ps(pname); ! 359: ps("\n"); ! 360: if (psptr < PSMAX) { ! 361: ++psptr; ! 362: strncpy (pstack[psptr], pname, PNAMELEN); ! 363: pstack[psptr][PNAMELEN] = NULL; ! 364: plstack[psptr] = blklevel; ! 365: } ! 366: } ! 367: skip: ! 368: do { ! 369: /* check for string, comment, blockstart, etc */ ! 370: if (!incomm && !instr && !inchr) { ! 371: ! 372: blkeptr = expmatch (s, l_blkend, dummy); ! 373: blksptr = expmatch (s, l_blkbeg, dummy); ! 374: comptr = expmatch (s, l_combeg, dummy); ! 375: acmptr = expmatch (s, l_acmbeg, dummy); ! 376: strptr = expmatch (s, l_strbeg, dummy); ! 377: chrptr = expmatch (s, l_chrbeg, dummy); ! 378: ! 379: /* start of a comment? */ ! 380: if (comptr != NIL) ! 381: if ((comptr < strptr || strptr == NIL) ! 382: && (comptr < acmptr || acmptr == NIL) ! 383: && (comptr < chrptr || chrptr == NIL) ! 384: && (comptr < blksptr || blksptr == NIL) ! 385: && (comptr < blkeptr || blkeptr == NIL)) { ! 386: putKcp (s, comptr-1, FALSE); ! 387: s = comptr; ! 388: incomm = TRUE; ! 389: comtype = STANDARD; ! 390: if (s != os) ! 391: ps ("\\c"); ! 392: ps ("\\c\n'+C\n"); ! 393: continue; ! 394: } ! 395: ! 396: /* start of a comment? */ ! 397: if (acmptr != NIL) ! 398: if ((acmptr < strptr || strptr == NIL) ! 399: && (acmptr < chrptr || chrptr == NIL) ! 400: && (acmptr < blksptr || blksptr == NIL) ! 401: && (acmptr < blkeptr || blkeptr == NIL)) { ! 402: putKcp (s, acmptr-1, FALSE); ! 403: s = acmptr; ! 404: incomm = TRUE; ! 405: comtype = ALTERNATE; ! 406: if (s != os) ! 407: ps ("\\c"); ! 408: ps ("\\c\n'+C\n"); ! 409: continue; ! 410: } ! 411: ! 412: /* start of a string? */ ! 413: if (strptr != NIL) ! 414: if ((strptr < chrptr || chrptr == NIL) ! 415: && (strptr < blksptr || blksptr == NIL) ! 416: && (strptr < blkeptr || blkeptr == NIL)) { ! 417: putKcp (s, strptr-1, FALSE); ! 418: s = strptr; ! 419: instr = TRUE; ! 420: continue; ! 421: } ! 422: ! 423: /* start of a character string? */ ! 424: if (chrptr != NIL) ! 425: if ((chrptr < blksptr || blksptr == NIL) ! 426: && (chrptr < blkeptr || blkeptr == NIL)) { ! 427: putKcp (s, chrptr-1, FALSE); ! 428: s = chrptr; ! 429: inchr = TRUE; ! 430: continue; ! 431: } ! 432: ! 433: /* end of a lexical block */ ! 434: if (blkeptr != NIL) { ! 435: if (blkeptr < blksptr || blksptr == NIL) { ! 436: putKcp (s, blkeptr - 1, FALSE); ! 437: s = blkeptr; ! 438: blklevel--; ! 439: if (psptr >= 0 && plstack[psptr] >= blklevel) { ! 440: ! 441: /* end of current procedure */ ! 442: if (s != os) ! 443: ps ("\\c"); ! 444: ps ("\\c\n'-F\n"); ! 445: blklevel = plstack[psptr]; ! 446: ! 447: /* see if we should print the last proc name */ ! 448: if (--psptr >= 0) ! 449: prccont = TRUE; ! 450: else ! 451: psptr = -1; ! 452: } ! 453: continue; ! 454: } ! 455: } ! 456: ! 457: /* start of a lexical block */ ! 458: if (blksptr != NIL) { ! 459: putKcp (s, blksptr - 1, FALSE); ! 460: s = blksptr; ! 461: blklevel++; ! 462: continue; ! 463: } ! 464: ! 465: /* check for end of comment */ ! 466: } else if (incomm) { ! 467: comptr = expmatch (s, l_comend, dummy); ! 468: acmptr = expmatch (s, l_acmend, dummy); ! 469: if (((comtype == STANDARD) && (comptr != NIL)) || ! 470: ((comtype == ALTERNATE) && (acmptr != NIL))) { ! 471: if (comtype == STANDARD) { ! 472: putKcp (s, comptr-1, TRUE); ! 473: s = comptr; ! 474: } else { ! 475: putKcp (s, acmptr-1, TRUE); ! 476: s = acmptr; ! 477: } ! 478: incomm = FALSE; ! 479: ps("\\c\n'-C\n"); ! 480: continue; ! 481: } else { ! 482: putKcp (s, s + strlen(s) -1, TRUE); ! 483: s = s + strlen(s); ! 484: continue; ! 485: } ! 486: ! 487: /* check for end of string */ ! 488: } else if (instr) { ! 489: if ((strptr = expmatch (s, l_strend, dummy)) != NIL) { ! 490: putKcp (s, strptr-1, TRUE); ! 491: s = strptr; ! 492: instr = FALSE; ! 493: continue; ! 494: } else { ! 495: putKcp (s, s+strlen(s)-1, TRUE); ! 496: s = s + strlen(s); ! 497: continue; ! 498: } ! 499: ! 500: /* check for end of character string */ ! 501: } else if (inchr) { ! 502: if ((chrptr = expmatch (s, l_chrend, dummy)) != NIL) { ! 503: putKcp (s, chrptr-1, TRUE); ! 504: s = chrptr; ! 505: inchr = FALSE; ! 506: continue; ! 507: } else { ! 508: putKcp (s, s+strlen(s)-1, TRUE); ! 509: s = s + strlen(s); ! 510: continue; ! 511: } ! 512: } ! 513: ! 514: /* print out the line */ ! 515: putKcp (s, s + strlen(s) -1, FALSE); ! 516: s = s + strlen(s); ! 517: } while (*s); ! 518: } ! 519: ! 520: putKcp (start, end, force) ! 521: char *start; /* start of string to write */ ! 522: char *end; /* end of string to write */ ! 523: boolean force; /* true if we should force nokeyw */ ! 524: { ! 525: int i; ! 526: int xfld = 0; ! 527: ! 528: while (start <= end) { ! 529: if (index) { ! 530: if (*start == ' ' || *start == '\t') { ! 531: if (xfld == 0) ! 532: printf("&"); ! 533: printf("\t"); ! 534: xfld = 1; ! 535: while (*start == ' ' || *start == '\t') ! 536: start++; ! 537: continue; ! 538: } ! 539: } ! 540: ! 541: /* take care of nice tab stops */ ! 542: if (*start == '\t') { ! 543: while (*start == '\t') ! 544: start++; ! 545: i = tabs(_start, start) - margin / 8; ! 546: printf("\\h'|%dn'", i * 10 + 1 - margin % 8); ! 547: continue; ! 548: } ! 549: ! 550: if (!nokeyw && !force) ! 551: if ((*start == '#' || isidchr(*start)) ! 552: && (start == _start || !isidchr(start[-1]))) { ! 553: i = iskw(start); ! 554: if (i > 0) { ! 555: ps("\\*(+K"); ! 556: do ! 557: putcp(*start++); ! 558: while (--i > 0); ! 559: ps("\\*(-K"); ! 560: continue; ! 561: } ! 562: } ! 563: ! 564: putcp (*start++); ! 565: } ! 566: } ! 567: ! 568: ! 569: tabs(s, os) ! 570: char *s, *os; ! 571: { ! 572: ! 573: return (width(s, os) / 8); ! 574: } ! 575: ! 576: width(s, os) ! 577: register char *s, *os; ! 578: { ! 579: register int i = 0; ! 580: ! 581: while (s < os) { ! 582: if (*s == '\t') { ! 583: i = (i + 8) &~ 7; ! 584: s++; ! 585: continue; ! 586: } ! 587: if (*s < ' ') ! 588: i += 2; ! 589: else ! 590: i++; ! 591: s++; ! 592: } ! 593: return (i); ! 594: } ! 595: ! 596: putcp(c) ! 597: register int c; ! 598: { ! 599: ! 600: switch(c) { ! 601: ! 602: case 0: ! 603: break; ! 604: ! 605: case '\f': ! 606: break; ! 607: ! 608: case '{': ! 609: ps("\\*(+K{\\*(-K"); ! 610: break; ! 611: ! 612: case '}': ! 613: ps("\\*(+K}\\*(-K"); ! 614: break; ! 615: ! 616: case '\\': ! 617: ps("\\e"); ! 618: break; ! 619: ! 620: case '_': ! 621: ps("\\*_"); ! 622: break; ! 623: ! 624: case '-': ! 625: ps("\\*-"); ! 626: break; ! 627: ! 628: case '`': ! 629: ps("\\`"); ! 630: break; ! 631: ! 632: case '\'': ! 633: ps("\\'"); ! 634: break; ! 635: ! 636: case '.': ! 637: ps("\\&."); ! 638: break; ! 639: ! 640: case '*': ! 641: ps("\\fI*\\fP"); ! 642: break; ! 643: ! 644: case '/': ! 645: ps("\\fI\\h'\\w' 'u-\\w'/'u'/\\fP"); ! 646: break; ! 647: ! 648: default: ! 649: if (c < 040) ! 650: putchar('^'), c |= '@'; ! 651: case '\t': ! 652: case '\n': ! 653: putchar(c); ! 654: } ! 655: } ! 656: ! 657: /* ! 658: * look for a process beginning on this line ! 659: */ ! 660: boolean ! 661: isproc(s) ! 662: char *s; ! 663: { ! 664: pname[0] = NULL; ! 665: if (!l_toplex || blklevel == 0) ! 666: if (expmatch (s, l_prcbeg, pname) != NIL) { ! 667: return (TRUE); ! 668: } ! 669: return (FALSE); ! 670: } ! 671: ! 672: ! 673: /* iskw - check to see if the next word is a keyword ! 674: */ ! 675: ! 676: iskw(s) ! 677: register char *s; ! 678: { ! 679: register char **ss = l_keywds; ! 680: register int i = 1; ! 681: register char *cp = s; ! 682: ! 683: while (++cp, isidchr(*cp)) ! 684: i++; ! 685: while (cp = *ss++) ! 686: if (!STRNCMP(s,cp,i) && !isidchr(cp[i])) ! 687: return (i); ! 688: return (0); ! 689: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.