1 /* $NetBSD: vfontedpr.c,v 1.12 2004/04/23 22:14:57 christos Exp $ */
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
35 The Regents of the University of California. All rights reserved.");
40 static char sccsid
[] = "@(#)vfontedpr.c 8.1 (Berkeley) 6/6/93";
42 __RCSID("$NetBSD: vfontedpr.c,v 1.12 2004/04/23 22:14:57 christos Exp $");
45 #include <sys/types.h>
52 #include "pathnames.h"
64 * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy)
68 #define STRLEN 10 /* length of strings introducing things */
69 #define PNAMELEN 40 /* length of a function/procedure name */
70 #define PSMAX 20 /* size of procedure name stacking */
72 static int iskw
__P((char *));
73 static boolean isproc
__P((char *));
74 static void putKcp
__P((char *, char *, boolean
));
75 static void putScp
__P((char *));
76 static void putcp
__P((int));
77 static int tabs
__P((char *, char *));
78 static int width
__P((char *, char *));
84 static boolean filter
= FALSE
; /* act as a filter (like eqn) */
85 static boolean inchr
; /* in a string constant */
86 static boolean incomm
; /* in a comment of the primary type */
87 static boolean idx
= FALSE
; /* form an index */
88 static boolean instr
; /* in a string constant */
89 static boolean nokeyw
= FALSE
; /* no keywords being flagged */
90 static boolean pass
= FALSE
; /*
91 * when acting as a filter, pass indicates
92 * whether we are currently processing
96 static int blklevel
; /* current nesting level */
97 static int comtype
; /* type of comment */
98 static const char *defsfile
[2] = { _PATH_VGRINDEFS
, 0 };
99 /* name of language definitions file */
101 static int plstack
[PSMAX
]; /* the procedure nesting level stack */
102 static char pname
[BUFSIZ
+1];
103 static boolean prccont
; /* continue last procedure */
104 static int psptr
; /* the stack index of the current procedure */
105 static char pstack
[PSMAX
][PNAMELEN
+1]; /* the procedure name stack */
108 * The language specific globals
111 char *l_acmbeg
; /* string introducing a comment */
112 char *l_acmend
; /* string ending a comment */
113 char *l_blkbeg
; /* string begining of a block */
114 char *l_blkend
; /* string ending a block */
115 char *l_chrbeg
; /* delimiter for character constant */
116 char *l_chrend
; /* delimiter for character constant */
117 char *l_combeg
; /* string introducing a comment */
118 char *l_comend
; /* string ending a comment */
119 char l_escape
; /* character used to escape characters */
120 char *l_keywds
[BUFSIZ
/2]; /* keyword table address */
121 char *l_prcbeg
; /* regular expr for procedure begin */
122 char *l_strbeg
; /* delimiter for string constant */
123 char *l_strend
; /* delimiter for string constant */
124 boolean l_toplex
; /* procedures only defined at top lex level */
125 const char *language
= "c"; /* the language indicator */
127 int main
__P((int, char **));
129 #define ps(x) printf("%s", x)
130 static char minus
[] = "-";
131 static char minusn
[] = "-n";
138 const char *fname
= "";
150 if (!strcmp(argv
[0], "-h")) {
156 printf("'ds =H %s\n", argv
[1]);
164 /* act as a filter like eqn */
165 if (!strcmp(argv
[0], "-f")) {
167 argv
[0] = argv
[argc
-1];
168 argv
[argc
-1] = minus
;
172 /* take input from the standard place */
173 if (!strcmp(argv
[0], "-")) {
179 if (!strcmp(argv
[0], "-x")) {
184 /* indicate no keywords */
185 if (!strcmp(argv
[0], "-n")) {
191 /* specify the font size */
192 if (!strncmp(argv
[0], "-s", 2)) {
196 i
= i
* 10 + (*cp
++ - '0');
197 printf("'ps %d\n'vs %d\n", i
, i
+1);
202 /* specify the language */
203 if (!strncmp(argv
[0], "-l", 2)) {
204 language
= argv
[0]+2;
209 /* specify the language description file */
210 if (!strncmp(argv
[0], "-d", 2)) {
211 defsfile
[0] = argv
[1];
217 /* open the file for input */
218 if (freopen(argv
[0], "r", stdin
) == NULL
) {
223 printf("'ta 4i 4.25i 5.5iR\n'in .5i\n");
230 * get the language definition from the defs file
232 i
= cgetent(&defs
, defsfile
, language
);
234 fprintf (stderr
, "no entry for language %s\n", language
);
236 } else if (i
== -2) { fprintf(stderr
,
237 "cannot find vgrindefs file %s\n", defsfile
[0]);
239 } else if (i
== -3) { fprintf(stderr
,
240 "potential reference loop detected in vgrindefs file %s\n",
244 if (cgetustr(defs
, "kw", &cp
) == -1)
251 while (*cp
== ' ' || *cp
=='\t')
255 while (*cp
!= ' ' && *cp
!= '\t' && *cp
)
260 cgetustr(defs
, "pb", &cp
);
261 l_prcbeg
= convexp(cp
);
262 cgetustr(defs
, "cb", &cp
);
263 l_combeg
= convexp(cp
);
264 cgetustr(defs
, "ce", &cp
);
265 l_comend
= convexp(cp
);
266 cgetustr(defs
, "ab", &cp
);
267 l_acmbeg
= convexp(cp
);
268 cgetustr(defs
, "ae", &cp
);
269 l_acmend
= convexp(cp
);
270 cgetustr(defs
, "sb", &cp
);
271 l_strbeg
= convexp(cp
);
272 cgetustr(defs
, "se", &cp
);
273 l_strend
= convexp(cp
);
274 cgetustr(defs
, "bb", &cp
);
275 l_blkbeg
= convexp(cp
);
276 cgetustr(defs
, "be", &cp
);
277 l_blkend
= convexp(cp
);
278 cgetustr(defs
, "lb", &cp
);
279 l_chrbeg
= convexp(cp
);
280 cgetustr(defs
, "le", &cp
);
281 l_chrend
= convexp(cp
);
283 l_onecase
= (cgetcap(defs
, "oc", ':') != NULL
);
284 l_toplex
= (cgetcap(defs
, "tl", ':') != NULL
);
286 /* initialize the program */
293 for (psptr
=0; psptr
<PSMAX
; psptr
++) {
294 pstack
[psptr
][0] = '\0';
300 printf(".ds =F %s\n", fname
);
310 fstat(fileno(stdin
), &stbuf
);
311 cp
= ctime(&stbuf
.st_mtime
);
314 printf(".ds =M %s %s\n", cp
+4, cp
+20);
320 while (fgets(buf
, sizeof buf
, stdin
) != NULL
) {
321 if (buf
[0] == '\f') {
326 if (!strncmp (buf
+1, "vS", 2))
328 if (!strncmp (buf
+1, "vE", 2))
337 if (prccont
&& (psptr
>= 0)) {
343 printf ("com %o str %o chr %o ptr %d\n", incomm
, instr
, inchr
, psptr
);
352 #define isidchr(c) (isalnum((unsigned char)(c)) || (c) == '_')
358 char *s
= os
; /* pointer to unmatched string */
359 char dummy
[BUFSIZ
]; /* dummy to be used by expmatch */
360 char *comptr
; /* end of a comment delimiter */
361 char *acmptr
; /* end of a comment delimiter */
362 char *strptr
; /* end of a string delimiter */
363 char *chrptr
; /* end of a character const delimiter */
364 char *blksptr
; /* end of a lexical block start */
365 char *blkeptr
; /* end of a lexical block end */
367 x_start
= os
; /* remember the start for expmatch */
369 if (nokeyw
|| incomm
|| instr
)
377 strlcpy(pstack
[psptr
], pname
, sizeof(pstack
[psptr
]));
378 plstack
[psptr
] = blklevel
;
383 /* check for string, comment, blockstart, etc */
384 if (!incomm
&& !instr
&& !inchr
) {
386 blkeptr
= expmatch(s
, l_blkend
, dummy
);
387 blksptr
= expmatch(s
, l_blkbeg
, dummy
);
388 comptr
= expmatch(s
, l_combeg
, dummy
);
389 acmptr
= expmatch(s
, l_acmbeg
, dummy
);
390 strptr
= expmatch(s
, l_strbeg
, dummy
);
391 chrptr
= expmatch(s
, l_chrbeg
, dummy
);
393 /* start of a comment? */
395 if ((comptr
< strptr
|| strptr
== NIL
)
396 && (comptr
< acmptr
|| acmptr
== NIL
)
397 && (comptr
< chrptr
|| chrptr
== NIL
)
398 && (comptr
< blksptr
|| blksptr
== NIL
)
399 && (comptr
< blkeptr
|| blkeptr
== NIL
)) {
400 putKcp(s
, comptr
-1, FALSE
);
410 /* start of a comment? */
412 if ((acmptr
< strptr
|| strptr
== NIL
)
413 && (acmptr
< chrptr
|| chrptr
== NIL
)
414 && (acmptr
< blksptr
|| blksptr
== NIL
)
415 && (acmptr
< blkeptr
|| blkeptr
== NIL
)) {
416 putKcp(s
, acmptr
-1, FALSE
);
426 /* start of a string? */
428 if ((strptr
< chrptr
|| chrptr
== NIL
)
429 && (strptr
< blksptr
|| blksptr
== NIL
)
430 && (strptr
< blkeptr
|| blkeptr
== NIL
)) {
431 putKcp(s
, strptr
-1, FALSE
);
437 /* start of a character string? */
439 if ((chrptr
< blksptr
|| blksptr
== NIL
)
440 && (chrptr
< blkeptr
|| blkeptr
== NIL
)) {
441 putKcp(s
, chrptr
-1, FALSE
);
447 /* end of a lexical block */
448 if (blkeptr
!= NIL
) {
449 if (blkeptr
< blksptr
|| blksptr
== NIL
) {
450 putKcp(s
, blkeptr
- 1, FALSE
);
453 if (psptr
>= 0 && plstack
[psptr
] >= blklevel
) {
455 /* end of current procedure */
459 blklevel
= plstack
[psptr
];
461 /* see if we should print the last proc name */
471 /* start of a lexical block */
472 if (blksptr
!= NIL
) {
473 putKcp(s
, blksptr
- 1, FALSE
);
479 /* check for end of comment */
481 comptr
= expmatch(s
, l_comend
, dummy
);
482 acmptr
= expmatch(s
, l_acmend
, dummy
);
483 if (((comtype
== STANDARD
) && (comptr
!= NIL
)) ||
484 ((comtype
== ALTERNATE
) && (acmptr
!= NIL
))) {
485 if (comtype
== STANDARD
) {
486 putKcp(s
, comptr
-1, TRUE
);
489 putKcp(s
, acmptr
-1, TRUE
);
496 putKcp(s
, s
+ strlen(s
) -1, TRUE
);
501 /* check for end of string */
503 if ((strptr
= expmatch(s
, l_strend
, dummy
)) != NIL
) {
504 putKcp(s
, strptr
-1, TRUE
);
509 putKcp(s
, s
+strlen(s
)-1, TRUE
);
514 /* check for end of character string */
516 if ((chrptr
= expmatch(s
, l_chrend
, dummy
)) != NIL
) {
517 putKcp(s
, chrptr
-1, TRUE
);
522 putKcp(s
, s
+strlen(s
)-1, TRUE
);
528 /* print out the line */
529 putKcp(s
, s
+ strlen(s
) -1, FALSE
);
535 putKcp(start
, end
, force
)
536 char *start
; /* start of string to write */
537 char *end
; /* end of string to write */
538 boolean force
; /* true if we should force nokeyw */
543 while (start
<= end
) {
545 if (*start
== ' ' || *start
== '\t') {
550 while (*start
== ' ' || *start
== '\t')
556 /* take care of nice tab stops */
557 if (*start
== '\t') {
558 while (*start
== '\t')
560 i
= tabs(x_start
, start
) - margin
/ 8;
561 printf("\\h'|%dn'", i
* 10 + 1 - margin
% 8);
565 if (!nokeyw
&& !force
)
566 if ((*start
== '#' || isidchr(*start
))
567 && (start
== x_start
|| !isidchr(start
[-1]))) {
589 return (width(s
, os
) / 8);
663 ps("\\fI\\h'\\w' 'u-\\w'/'u'/\\fP");
668 putchar('^'), c
|= '@';
676 * look for a process beginning on this line
683 if (!l_toplex
|| blklevel
== 0)
684 if (expmatch(s
, l_prcbeg
, pname
) != NIL
) {
691 /* iskw - check to see if the next word is a keyword
698 char **ss
= l_keywds
;
702 while (++cp
, isidchr((unsigned char)*cp
))
704 while ((cp
= *ss
++) != NULL
)
705 if (!STRNCMP(s
,cp
,i
) && !isidchr((unsigned char)cp
[i
]))