|
|
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.