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

Defined functions

iskw defined in line 605; used 1 times
isproc defined in line 589; used 2 times
main defined in line 83; never used
putKcp defined in line 449; used 12 times
putScp defined in line 297; used 1 times
putcp defined in line 525; used 2 times
tabs defined in line 498; used 1 times
width defined in line 505; used 1 times

Defined variables

_start defined in line 78; used 3 times
blklevel defined in line 52; used 7 times
defsfile defined in line 53; used 3 times
l_blkbeg defined in line 65; used 2 times
l_blkend defined in line 66; used 2 times
l_chrbeg defined in line 69; used 2 times
l_chrend defined in line 70; used 2 times
l_combeg defined in line 63; used 2 times
l_comend defined in line 64; used 2 times
l_escape defined in line 71; used 1 times
l_keywds defined in line 61; used 2 times
l_prcbeg defined in line 62; used 2 times
l_strbeg defined in line 67; used 2 times
l_strend defined in line 68; used 2 times
language defined in line 60; used 3 times
margin defined in line 48; used 3 times
plstack defined in line 51; used 4 times
pname defined in line 54; used 4 times
psptr defined in line 49; used 19 times
pstack defined in line 50; used 4 times

Defined macros

FALSE defined in line 8; used 21 times
NIL defined in line 9; used 21 times
PNAMELEN defined in line 19; used 3 times
PSMAX defined in line 20; used 4 times
STRLEN defined in line 18; never used
TRUE defined in line 7; used 12 times
boolean defined in line 6; used 14 times
isidchr defined in line 295; used 4 times
ps defined in line 81; used 26 times
Last modified: 1982-09-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1279
Valid CSS Valid XHTML 1.0 Strict