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