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