11841Sroot #include <ctype.h> 21841Sroot #include <stdio.h> 31841Sroot #include <sys/types.h> 41841Sroot #include <sys/stat.h> 51841Sroot 62199Sroot #define boolean int 72199Sroot #define TRUE 1 82199Sroot #define FALSE 0 92199Sroot #define NIL 0 102199Sroot 111841Sroot /* 121841Sroot * Vfontedpr. 131841Sroot * 142199Sroot * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy) 151862Sroot * 161841Sroot */ 171862Sroot 181862Sroot #define STRLEN 10 /* length of strings introducing things */ 191862Sroot #define PNAMELEN 40 /* length of a function/procedure name */ 202199Sroot #define PSMAX 20 /* size of procedure name stacking */ 211862Sroot 222199Sroot /* regular expression routines */ 231862Sroot 242199Sroot char *expmatch(); /* match a string to an expression */ 252199Sroot char *STRNCMP(); /* a different kindof strncmp */ 262199Sroot char *convexp(); /* convert expression to internal form */ 271862Sroot 282199Sroot boolean isproc(); 291862Sroot 301862Sroot 312199Sroot char *ctime(); 321862Sroot 332199Sroot /* 342199Sroot * The state variables 352199Sroot */ 361862Sroot 372199Sroot boolean incomm; /* in a comment of the primary type */ 382199Sroot boolean instr; /* in a string constant */ 392199Sroot boolean inchr; /* in a string constant */ 402199Sroot boolean nokeyw = FALSE; /* no keywords being flagged */ 412199Sroot boolean index = FALSE; /* form an index */ 422199Sroot boolean filter = FALSE; /* act as a filter (like eqn) */ 432199Sroot boolean pass = FALSE; /* when acting as a filter, pass indicates 442199Sroot * whether we are currently processing 452199Sroot * input. 462199Sroot */ 472199Sroot boolean prccont; /* continue last procedure */ 482199Sroot int margin; 492199Sroot int psptr; /* the stack index of the current procedure */ 502199Sroot char pstack[PSMAX][PNAMELEN+1]; /* the procedure name stack */ 512199Sroot int plstack[PSMAX]; /* the procedure nesting level stack */ 522199Sroot int blklevel; /* current nesting level */ 532199Sroot char *defsfile = "/usr/lib/vgrindefs"; /* name of language definitions file */ 542199Sroot char pname[BUFSIZ+1]; 551862Sroot 562199Sroot /* 572199Sroot * The language specific globals 582199Sroot */ 591862Sroot 602199Sroot char *language = "c"; /* the language indicator */ 612199Sroot char *l_keywds[BUFSIZ/2]; /* keyword table address */ 622199Sroot char *l_prcbeg; /* regular expr for procedure begin */ 632199Sroot char *l_combeg; /* string introducing a comment */ 642199Sroot char *l_comend; /* string ending a comment */ 652199Sroot char *l_blkbeg; /* string begining of a block */ 662199Sroot char *l_blkend; /* string ending a block */ 672199Sroot char *l_strbeg; /* delimiter for string constant */ 682199Sroot char *l_strend; /* delimiter for string constant */ 692199Sroot char *l_chrbeg; /* delimiter for character constant */ 702199Sroot char *l_chrend; /* delimiter for character constant */ 712199Sroot char l_escape; /* character used to escape characters */ 722199Sroot boolean l_toplex; /* procedures only defined at top lex level */ 731878Sroot 741862Sroot /* 752199Sroot * global variables also used by expmatch 761862Sroot */ 772199Sroot boolean _escaped; /* if last character was an escape */ 782199Sroot char *_start; /* start of the current string */ 792199Sroot boolean l_onecase; /* upper and lower case are equivalent */ 801862Sroot 812199Sroot #define ps(x) printf("%s", x) 821862Sroot 832199Sroot main(argc, argv) 842199Sroot int argc; 852199Sroot char *argv[]; 862199Sroot { 872199Sroot int lineno; 882199Sroot char *fname = ""; 892199Sroot char *ptr; 902199Sroot struct stat stbuf; 912199Sroot char buf[BUFSIZ]; 922199Sroot char strings[2 * BUFSIZ]; 932199Sroot char defs[2 * BUFSIZ]; 942199Sroot int needbp = 0; 951862Sroot 962199Sroot argc--, argv++; 972199Sroot do { 982199Sroot char *cp; 992199Sroot int i; 1001878Sroot 1012199Sroot if (argc > 0) { 1022199Sroot if (!strcmp(argv[0], "-h")) { 1032199Sroot if (argc == 1) { 1042199Sroot printf("'ds =H\n"); 1052199Sroot argc = 0; 1062199Sroot goto rest; 1072199Sroot } 1082199Sroot printf("'ds =H %s\n", argv[1]); 1092199Sroot argc -= 2; 1102199Sroot argv += 2; 1112199Sroot if (argc > 0) 1122199Sroot continue; 1132199Sroot goto rest; 1142199Sroot } 1151862Sroot 1162199Sroot /* act as a filter like eqn */ 1172199Sroot if (!strcmp(argv[0], "-f")) { 1182199Sroot filter++; 1192199Sroot argv[0] = argv[argc-1]; 1202199Sroot argv[argc-1] = "-"; 1212199Sroot continue; 1222199Sroot } 1231862Sroot 1242199Sroot /* take input from the standard place */ 1252199Sroot if (!strcmp(argv[0], "-")) { 1262199Sroot argc = 0; 1272199Sroot goto rest; 1282199Sroot } 1291878Sroot 1302199Sroot /* build an index */ 1312199Sroot if (!strcmp(argv[0], "-x")) { 1322199Sroot index++; 1332199Sroot argv[0] = "-n"; 1342199Sroot } 1351841Sroot 1362199Sroot /* indicate no keywords */ 1372199Sroot if (!strcmp(argv[0], "-n")) { 1382199Sroot nokeyw++; 1392199Sroot argc--, argv++; 1402199Sroot continue; 1412199Sroot } 1421862Sroot 1432199Sroot /* specify the font size */ 1442199Sroot if (!strncmp(argv[0], "-s", 2)) { 1452199Sroot i = 0; 1462199Sroot cp = argv[0] + 2; 1472199Sroot while (*cp) 1482199Sroot i = i * 10 + (*cp++ - '0'); 1492199Sroot printf("'ps %d\n'vs %d\n", i, i+1); 1502199Sroot argc--, argv++; 1512199Sroot continue; 1522199Sroot } 1531841Sroot 1542199Sroot /* specify the language */ 1552199Sroot if (!strncmp(argv[0], "-l", 2)) { 1562199Sroot language = argv[0]+2; 1572199Sroot argc--, argv++; 1582199Sroot continue; 1592199Sroot } 1601841Sroot 1612199Sroot /* specify the language description file */ 1622199Sroot if (!strncmp(argv[0], "-d", 2)) { 1632199Sroot defsfile = argv[1]; 1642199Sroot argc--, argv++; 1652199Sroot argc--, argv++; 1662199Sroot continue; 1672199Sroot } 1681862Sroot 1692199Sroot /* open the file for input */ 1702199Sroot if (freopen(argv[0], "r", stdin) == NULL) { 1712199Sroot perror(argv[0]); 1722199Sroot exit(1); 1732199Sroot } 1742199Sroot if (index) 1752199Sroot printf("'ta 4i 4.25i 5.5iR\n'in .5i\n"); 1762199Sroot fname = argv[0]; 1772199Sroot argc--, argv++; 1782199Sroot } 1792199Sroot rest: 1801862Sroot 1812199Sroot /* 1822199Sroot * get the language definition from the defs file 1832199Sroot */ 1842199Sroot i = tgetent (defs, language, defsfile); 1852199Sroot if (i == 0) { 1862199Sroot fprintf (stderr, "no entry for language %s\n", language); 1872199Sroot exit (0); 1882199Sroot } else if (i < 0) { 1892199Sroot fprintf (stderr, "cannot find vgrindefs file %s\n", defsfile); 1902199Sroot exit (0); 1912199Sroot } 1922199Sroot cp = strings; 1932199Sroot if (tgetstr ("kw", &cp) == NIL) 1942199Sroot nokeyw = TRUE; 1952199Sroot else { 1962199Sroot char **cpp; 1971878Sroot 1982199Sroot cpp = l_keywds; 1992199Sroot cp = strings; 2002199Sroot while (*cp) { 2012199Sroot while (*cp == ' ' || *cp =='\t') 2022199Sroot *cp++ = NULL; 2032199Sroot if (*cp) 2042199Sroot *cpp++ = cp; 2052199Sroot while (*cp != ' ' && *cp != '\t' && *cp) 2062199Sroot cp++; 2072199Sroot } 2082199Sroot *cpp = NIL; 2092199Sroot } 2102199Sroot cp = buf; 2112199Sroot l_prcbeg = convexp (tgetstr ("pb", &cp)); 2122199Sroot cp = buf; 2132199Sroot l_combeg = convexp (tgetstr ("cb", &cp)); 2142199Sroot cp = buf; 2152199Sroot l_comend = convexp (tgetstr ("ce", &cp)); 2162199Sroot cp = buf; 2172199Sroot l_strbeg = convexp (tgetstr ("sb", &cp)); 2182199Sroot cp = buf; 2192199Sroot l_strend = convexp (tgetstr ("se", &cp)); 2202199Sroot cp = buf; 2212199Sroot l_blkbeg = convexp (tgetstr ("bb", &cp)); 2222199Sroot cp = buf; 2232199Sroot l_blkend = convexp (tgetstr ("be", &cp)); 2242199Sroot cp = buf; 2252199Sroot l_chrbeg = convexp (tgetstr ("lb", &cp)); 2262199Sroot cp = buf; 2272199Sroot l_chrend = convexp (tgetstr ("le", &cp)); 2282199Sroot l_escape = '\\'; 2292199Sroot l_onecase = tgetflag ("oc"); 2302199Sroot l_toplex = tgetflag ("tl"); 2312199Sroot /* initialize the program */ 2321878Sroot 2332199Sroot incomm = FALSE; 2342199Sroot instr = FALSE; 2352199Sroot inchr = FALSE; 2362199Sroot _escaped = FALSE; 2372199Sroot blklevel = 0; 2382199Sroot for (psptr=0; psptr<PSMAX; psptr++) { 2392199Sroot pstack[psptr][0] = NULL; 2402199Sroot plstack[psptr] = 0; 2412199Sroot } 2422199Sroot psptr = -1; 2432199Sroot ps("'-F\n"); 2442199Sroot if (!filter) { 2452199Sroot printf(".ds =F %s\n", fname); 2462199Sroot fstat(fileno(stdin), &stbuf); 2472199Sroot cp = ctime(&stbuf.st_mtime); 2482199Sroot cp[16] = '\0'; 2492199Sroot cp[24] = '\0'; 2502199Sroot printf(".ds =M %s %s\n", cp+4, cp+20); 2512199Sroot } 2522199Sroot if (needbp) { 2532199Sroot needbp = 0; 2542199Sroot printf(".()\n"); 2552199Sroot printf(".bp\n"); 2562199Sroot } 2571878Sroot 2582199Sroot /* 2592199Sroot * MAIN LOOP!!! 2602199Sroot */ 2612199Sroot while (fgets(buf, sizeof buf, stdin) != NULL) { 2622199Sroot if (buf[0] == '\f') { 2632199Sroot printf(".bp\n"); 2642199Sroot } 2652199Sroot if (buf[0] == '.') { 2662199Sroot printf("%s", buf); 2672199Sroot if (!strncmp (buf+1, "vS", 2)) 2682199Sroot pass = TRUE; 2692199Sroot if (!strncmp (buf+1, "vE", 2)) 2702199Sroot pass = FALSE; 2712199Sroot continue; 2722199Sroot } 2732199Sroot prccont = FALSE; 2742199Sroot if (!filter || pass) 2752199Sroot putScp(buf); 2762199Sroot else 2772199Sroot printf("%s", buf); 2782199Sroot if (prccont && (psptr >= 0)) { 2792199Sroot ps("'FC "); 2802199Sroot ps(pstack[psptr]); 2812199Sroot ps("\n"); 2822199Sroot } 2832199Sroot #ifdef DEBUG 2842199Sroot printf ("com %o str %o chr %o ptr %d\n", incomm, instr, inchr, psptr); 2852199Sroot #endif 2862199Sroot margin = 0; 2872199Sroot } 2882199Sroot needbp = 1; 2892199Sroot } while (argc > 0); 2902199Sroot exit(0); 2911841Sroot } 2921841Sroot 2931841Sroot #define isidchr(c) (isalnum(c) || (c) == '_') 2941841Sroot 2951841Sroot putScp(os) 2962199Sroot char *os; 2971841Sroot { 2982199Sroot register char *s = os; /* pointer to unmatched string */ 2992199Sroot char dummy[BUFSIZ]; /* dummy to be used by expmatch */ 3002199Sroot char *comptr; /* end of a comment delimiter */ 3012199Sroot char *strptr; /* end of a string delimiter */ 3022199Sroot char *chrptr; /* end of a character const delimiter */ 3032199Sroot char *blksptr; /* end of a lexical block start */ 3042199Sroot char *blkeptr; /* end of a lexical block end */ 3051841Sroot 3062199Sroot _start = os; /* remember the start for expmatch */ 3072199Sroot _escaped = FALSE; 3082199Sroot if (nokeyw || incomm || instr) 3092199Sroot goto skip; 3102199Sroot if (isproc(s)) { 3112199Sroot ps("'FN "); 3122199Sroot ps(pname); 3132293Sroot ps("\n"); 3142199Sroot if (psptr < PSMAX) { 3152199Sroot ++psptr; 3162199Sroot strncpy (pstack[psptr], pname, PNAMELEN); 3172199Sroot pstack[psptr][PNAMELEN] = NULL; 3182199Sroot plstack[psptr] = blklevel; 3192199Sroot } 3202199Sroot } 3211841Sroot skip: 3222199Sroot do { 3232199Sroot /* check for string, comment, blockstart, etc */ 3242199Sroot if (!incomm && !instr && !inchr) { 3252199Sroot 3262199Sroot blkeptr = expmatch (s, l_blkend, dummy); 3272199Sroot blksptr = expmatch (s, l_blkbeg, dummy); 3282199Sroot comptr = expmatch (s, l_combeg, dummy); 3292199Sroot strptr = expmatch (s, l_strbeg, dummy); 3302199Sroot chrptr = expmatch (s, l_chrbeg, dummy); 3312199Sroot 3322199Sroot /* start of a comment? */ 3332199Sroot if (comptr != NIL) 3342199Sroot if ((comptr < strptr || strptr == NIL) 3352199Sroot && (comptr < chrptr || chrptr == NIL) 3362199Sroot && (comptr < blksptr || blksptr == NIL) 3372199Sroot && (comptr < blkeptr || blkeptr == NIL)) { 3382199Sroot putKcp (s, comptr-1, FALSE); 3392199Sroot s = comptr; 3402199Sroot incomm = TRUE; 3412199Sroot if (s != os) 3422199Sroot ps ("\\c"); 3432199Sroot ps ("\\c\n'+C\n"); 3442199Sroot continue; 3451841Sroot } 3461878Sroot 3472199Sroot /* start of a string? */ 3482199Sroot if (strptr != NIL) 3492199Sroot if ((strptr < chrptr || chrptr == NIL) 3502212Sroot && (strptr < blksptr || blksptr == NIL) 3512212Sroot && (strptr < blkeptr || blkeptr == NIL)) { 3522199Sroot putKcp (s, strptr-1, FALSE); 3532199Sroot s = strptr; 3542199Sroot instr = TRUE; 3552199Sroot continue; 3562199Sroot } 3571878Sroot 3582199Sroot /* start of a character string? */ 3592199Sroot if (chrptr != NIL) 3602212Sroot if ((chrptr < blksptr || blksptr == NIL) 3612212Sroot && (chrptr < blkeptr || blkeptr == NIL)) { 3622199Sroot putKcp (s, chrptr-1, FALSE); 3632199Sroot s = chrptr; 3642199Sroot inchr = TRUE; 3652199Sroot continue; 3661841Sroot } 3671878Sroot 3682199Sroot /* end of a lexical block */ 3692199Sroot if (blkeptr != NIL) { 3702199Sroot if (blkeptr < blksptr || blksptr == NIL) { 3712199Sroot putKcp (s, blkeptr - 1, FALSE); 3722199Sroot s = blkeptr; 3732199Sroot blklevel--; 3742199Sroot if (psptr >= 0 && plstack[psptr] >= blklevel) { 3751878Sroot 3762199Sroot /* end of current procedure */ 3771841Sroot if (s != os) 3782199Sroot ps ("\\c"); 3792199Sroot ps ("\\c\n'-F\n"); 3802199Sroot blklevel = plstack[psptr]; 3811878Sroot 3822199Sroot /* see if we should print the last proc name */ 3832199Sroot if (--psptr >= 0) 3842199Sroot prccont = TRUE; 3852199Sroot else 3862199Sroot psptr = -1; 3872199Sroot } 3882199Sroot continue; 3891841Sroot } 3902199Sroot } 3911878Sroot 3922199Sroot /* start of a lexical block */ 3932199Sroot if (blksptr != NIL) { 3942199Sroot putKcp (s, blksptr - 1, FALSE); 3952199Sroot s = blksptr; 3962199Sroot blklevel++; 3972199Sroot continue; 3982199Sroot } 3992199Sroot 4002199Sroot /* check for end of comment */ 4012199Sroot } else if (incomm) { 4022199Sroot if ((comptr = expmatch (s, l_comend, dummy)) != NIL) { 4032199Sroot putKcp (s, comptr-1, TRUE); 4042199Sroot s = comptr; 4052199Sroot incomm = FALSE; 4062199Sroot ps("\\c\n'-C\n"); 4072199Sroot continue; 4082199Sroot } else { 4092199Sroot putKcp (s, s + strlen(s) -1); 4102199Sroot s = s + strlen(s); 4112199Sroot continue; 4122199Sroot } 4132199Sroot 4142199Sroot /* check for end of string */ 4152199Sroot } else if (instr) { 4162199Sroot if ((strptr = expmatch (s, l_strend, dummy)) != NIL) { 4172199Sroot putKcp (s, strptr-1, TRUE); 4182199Sroot s = strptr; 4192199Sroot instr = FALSE; 4202199Sroot continue; 4212199Sroot } else { 4222199Sroot putKcp (s, s+strlen(s)-1, TRUE); 4232199Sroot s = s + strlen(s); 4242199Sroot continue; 4252199Sroot } 4262199Sroot 4272199Sroot /* check for end of character string */ 4282199Sroot } else if (inchr) { 4292199Sroot if ((chrptr = expmatch (s, l_chrend, dummy)) != NIL) { 4302199Sroot putKcp (s, chrptr-1, TRUE); 4312199Sroot s = chrptr; 4322199Sroot inchr = FALSE; 4332199Sroot continue; 4342199Sroot } else { 4352199Sroot putKcp (s, s+strlen(s)-1, TRUE); 4362199Sroot s = s + strlen(s); 4372199Sroot continue; 4382199Sroot } 4391841Sroot } 4402199Sroot 4412199Sroot /* print out the line */ 4422199Sroot putKcp (s, s + strlen(s) -1, FALSE); 4432199Sroot s = s + strlen(s); 4442199Sroot } while (*s); 4451841Sroot } 4461841Sroot 4472199Sroot putKcp (start, end, force) 4482199Sroot char *start; /* start of string to write */ 4492199Sroot char *end; /* end of string to write */ 4502199Sroot boolean force; /* true if we should force nokeyw */ 4512199Sroot { 4522199Sroot int i; 453*2320Sroot int xfld = 0; 4542199Sroot 4552199Sroot while (start <= end) { 456*2320Sroot if (index) { 457*2320Sroot if (*start == ' ' || *start == '\t') { 458*2320Sroot if (xfld == 0) 459*2320Sroot printf(""); 460*2320Sroot printf("\t"); 461*2320Sroot xfld = 1; 462*2320Sroot while (*start == ' ' || *start == '\t') 463*2320Sroot start++; 464*2320Sroot continue; 465*2320Sroot } 466*2320Sroot } 4672199Sroot 4682199Sroot /* take care of nice tab stops */ 4692199Sroot if (*start == '\t') { 4702199Sroot while (*start == '\t') 4712199Sroot start++; 4722199Sroot i = tabs(_start, start) - margin / 8; 4732199Sroot printf("\\h'|%dn'", i * 10 + 1 - margin % 8); 4742199Sroot continue; 4752199Sroot } 4762199Sroot 4772199Sroot if (!nokeyw && !force) 4782199Sroot if ((*start == '#' || isidchr(*start)) 4792199Sroot && (start == _start || !isidchr(start[-1]))) { 4802199Sroot i = iskw(start); 4812199Sroot if (i > 0) { 4822199Sroot ps("\\*(+K"); 4832199Sroot do 4842199Sroot putcp(*start++); 4852199Sroot while (--i > 0); 4862199Sroot ps("\\*(-K"); 4872199Sroot continue; 4882199Sroot } 4892199Sroot } 4902199Sroot 4912199Sroot putcp (*start++); 4922199Sroot } 4932199Sroot } 4942199Sroot 4952199Sroot 4961841Sroot tabs(s, os) 4972199Sroot char *s, *os; 4981841Sroot { 4991841Sroot 5002199Sroot return (width(s, os) / 8); 5011841Sroot } 5021841Sroot 5031841Sroot width(s, os) 5041841Sroot register char *s, *os; 5051841Sroot { 5061841Sroot register int i = 0; 5071841Sroot 5081841Sroot while (s < os) { 5091841Sroot if (*s == '\t') { 5101841Sroot i = (i + 8) &~ 7; 5111841Sroot s++; 5121841Sroot continue; 5131841Sroot } 5141841Sroot if (*s < ' ') 5151841Sroot i += 2; 5161841Sroot else 5171841Sroot i++; 5181841Sroot s++; 5191841Sroot } 5201841Sroot return (i); 5211841Sroot } 5221841Sroot 5231841Sroot putcp(c) 5241841Sroot register int c; 5251841Sroot { 5261841Sroot 5271841Sroot switch(c) { 5281841Sroot 5292199Sroot case 0: 5302199Sroot break; 5312199Sroot 5322199Sroot case '\f': 5332199Sroot break; 5342199Sroot 5351841Sroot case '{': 5361841Sroot ps("\\*(+K{\\*(-K"); 5371841Sroot break; 5381841Sroot 5391841Sroot case '}': 5401841Sroot ps("\\*(+K}\\*(-K"); 5411841Sroot break; 5421841Sroot 5431841Sroot case '\\': 5441841Sroot ps("\\e"); 5451841Sroot break; 5461841Sroot 5471841Sroot case '_': 5481841Sroot ps("\\*_"); 5491841Sroot break; 5501841Sroot 5511841Sroot case '-': 5521841Sroot ps("\\*-"); 5531841Sroot break; 5541841Sroot 5551841Sroot case '`': 5561841Sroot ps("\\`"); 5571841Sroot break; 5581841Sroot 5591841Sroot case '\'': 5601841Sroot ps("\\'"); 5611841Sroot break; 5621841Sroot 5631841Sroot case '.': 5641841Sroot ps("\\&."); 5651841Sroot break; 5661841Sroot 5672199Sroot case '/': 5682199Sroot ps("\\*/"); 5692199Sroot break; 5702199Sroot 5711841Sroot default: 5721841Sroot if (c < 040) 5731841Sroot putchar('^'), c |= '@'; 5741841Sroot case '\t': 5751841Sroot case '\n': 5761841Sroot putchar(c); 5771841Sroot } 5781841Sroot } 5791841Sroot 5802199Sroot /* 5812199Sroot * look for a process beginning on this line 5821878Sroot */ 5832199Sroot boolean 5842199Sroot isproc(s) 5852199Sroot char *s; 5861878Sroot { 5872199Sroot pname[0] = NULL; 5882199Sroot if (!l_toplex || blklevel == 0) 5892199Sroot if (expmatch (s, l_prcbeg, pname) != NIL) { 5902199Sroot return (TRUE); 5912199Sroot } 5922199Sroot return (FALSE); 5931878Sroot } 5941878Sroot 5952199Sroot 5961878Sroot /* iskw - check to see if the next word is a keyword 5971878Sroot */ 5981878Sroot 5991841Sroot iskw(s) 6001841Sroot register char *s; 6011841Sroot { 6022199Sroot register char **ss = l_keywds; 6031841Sroot register int i = 1; 6041841Sroot register char *cp = s; 6051841Sroot 6061841Sroot while (++cp, isidchr(*cp)) 6071841Sroot i++; 6081841Sroot while (cp = *ss++) 6092199Sroot if (!STRNCMP(s,cp,i) && !isidchr(cp[i])) 6101841Sroot return (i); 6111841Sroot return (0); 6121841Sroot } 613