17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 37c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 47c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 57c478bd9Sstevel@tonic-gate */ 67c478bd9Sstevel@tonic-gate 77c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate #include <ctype.h> 107c478bd9Sstevel@tonic-gate #include <stdio.h> 117c478bd9Sstevel@tonic-gate #include <sys/types.h> 127c478bd9Sstevel@tonic-gate #include <sys/stat.h> 137c478bd9Sstevel@tonic-gate #include <locale.h> 147c478bd9Sstevel@tonic-gate #include <euc.h> 157c478bd9Sstevel@tonic-gate #include <stdlib.h> 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate #define boolean int 187c478bd9Sstevel@tonic-gate #define TRUE 1 197c478bd9Sstevel@tonic-gate #define FALSE 0 207c478bd9Sstevel@tonic-gate #define NIL 0 217c478bd9Sstevel@tonic-gate #define STANDARD 0 227c478bd9Sstevel@tonic-gate #define ALTERNATE 1 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate /* 257c478bd9Sstevel@tonic-gate * Vfontedpr. 267c478bd9Sstevel@tonic-gate * 277c478bd9Sstevel@tonic-gate * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy) 287c478bd9Sstevel@tonic-gate * 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #define STRLEN 10 /* length of strings introducing things */ 327c478bd9Sstevel@tonic-gate #define PNAMELEN 40 /* length of a function/procedure name */ 337c478bd9Sstevel@tonic-gate #define PSMAX 20 /* size of procedure name stacking */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate /* regular expression routines */ 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate char *expmatch(); /* match a string to an expression */ 387c478bd9Sstevel@tonic-gate char *STRNCMP(); /* a different kind of strncmp */ 397c478bd9Sstevel@tonic-gate char *convexp(); /* convert expression to internal form */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate char *tgetstr(); /* extract a string-valued capability */ 427c478bd9Sstevel@tonic-gate boolean isproc(); 437c478bd9Sstevel@tonic-gate char *ctime(); 447c478bd9Sstevel@tonic-gate char *strchr(); 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * The state variables 487c478bd9Sstevel@tonic-gate */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate boolean incomm; /* in a comment of the primary type */ 517c478bd9Sstevel@tonic-gate boolean instr; /* in a string constant */ 527c478bd9Sstevel@tonic-gate boolean inchr; /* in a string constant */ 537c478bd9Sstevel@tonic-gate boolean nokeyw = FALSE; /* no keywords being flagged */ 547c478bd9Sstevel@tonic-gate boolean doindex = FALSE; /* form an index */ 557c478bd9Sstevel@tonic-gate boolean twocol = FALSE; /* in two-column mode */ 567c478bd9Sstevel@tonic-gate boolean filter = FALSE; /* act as a filter (like eqn) */ 577c478bd9Sstevel@tonic-gate boolean pass = FALSE; /* when acting as a filter, pass indicates 587c478bd9Sstevel@tonic-gate * whether we are currently processing 597c478bd9Sstevel@tonic-gate * input. 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate boolean prccont; /* continue last procedure */ 627c478bd9Sstevel@tonic-gate int comtype; /* type of comment */ 637c478bd9Sstevel@tonic-gate int margin; 647c478bd9Sstevel@tonic-gate int psptr; /* the stack index of the current procedure */ 657c478bd9Sstevel@tonic-gate char pstack[PSMAX][PNAMELEN+1]; /* the procedure name stack */ 667c478bd9Sstevel@tonic-gate int plstack[PSMAX]; /* the procedure nesting level stack */ 677c478bd9Sstevel@tonic-gate int blklevel; /* current nesting level */ 687c478bd9Sstevel@tonic-gate int prclevel; /* nesting level at which procedure definitions 697c478bd9Sstevel@tonic-gate may be found, -1 if none currently valid 707c478bd9Sstevel@tonic-gate (meaningful only if l_prclevel is true) */ 717c478bd9Sstevel@tonic-gate char *defsfile = "/usr/lib/vgrindefs"; /* name of language definitions file */ 727c478bd9Sstevel@tonic-gate char pname[BUFSIZ+1]; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* 757c478bd9Sstevel@tonic-gate * The language specific globals 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate char *language = "c"; /* the language indicator */ 797c478bd9Sstevel@tonic-gate char *l_keywds[BUFSIZ/2]; /* keyword table address */ 807c478bd9Sstevel@tonic-gate char *l_prcbeg; /* regular expr for procedure begin */ 817c478bd9Sstevel@tonic-gate char *l_combeg; /* string introducing a comment */ 827c478bd9Sstevel@tonic-gate char *l_comend; /* string ending a comment */ 837c478bd9Sstevel@tonic-gate char *l_acmbeg; /* string introducing a comment */ 847c478bd9Sstevel@tonic-gate char *l_acmend; /* string ending a comment */ 857c478bd9Sstevel@tonic-gate char *l_blkbeg; /* string begining of a block */ 867c478bd9Sstevel@tonic-gate char *l_blkend; /* string ending a block */ 877c478bd9Sstevel@tonic-gate char *l_strbeg; /* delimiter for string constant */ 887c478bd9Sstevel@tonic-gate char *l_strend; /* delimiter for string constant */ 897c478bd9Sstevel@tonic-gate char *l_chrbeg; /* delimiter for character constant */ 907c478bd9Sstevel@tonic-gate char *l_chrend; /* delimiter for character constant */ 917c478bd9Sstevel@tonic-gate char *l_prcenable; /* re indicating that procedure definitions 927c478bd9Sstevel@tonic-gate can be found in the next lexical level -- 937c478bd9Sstevel@tonic-gate kludge for lisp-like languages that use 947c478bd9Sstevel@tonic-gate something like 957c478bd9Sstevel@tonic-gate (defun (proc ...) 967c478bd9Sstevel@tonic-gate (proc ...) 977c478bd9Sstevel@tonic-gate ) 987c478bd9Sstevel@tonic-gate to define procedures */ 997c478bd9Sstevel@tonic-gate char l_escape; /* character used to escape characters */ 1007c478bd9Sstevel@tonic-gate boolean l_toplex; /* procedures only defined at top lex level */ 1017c478bd9Sstevel@tonic-gate boolean l_prclevel; /* procedure definitions valid only within 1027c478bd9Sstevel@tonic-gate the nesting level indicated by the px 1037c478bd9Sstevel@tonic-gate (l_prcenable) capability */ 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate /* 1067c478bd9Sstevel@tonic-gate * for the benefit of die-hards who aren't convinced that tabs 1077c478bd9Sstevel@tonic-gate * occur every eight columns 1087c478bd9Sstevel@tonic-gate */ 1097c478bd9Sstevel@tonic-gate short tabsize = 8; 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate /* 1127c478bd9Sstevel@tonic-gate * global variables also used by expmatch 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate boolean _escaped; /* if last character was an escape */ 1157c478bd9Sstevel@tonic-gate char *Start; /* start of the current string */ 1167c478bd9Sstevel@tonic-gate boolean l_onecase; /* upper and lower case are equivalent */ 1177c478bd9Sstevel@tonic-gate char *l_idchars; /* characters legal in identifiers in addition 1187c478bd9Sstevel@tonic-gate to letters and digits (default "_") */ 1197c478bd9Sstevel@tonic-gate 120*e5af7cceScraigm static void putcp(int c); 121*e5af7cceScraigm static int width(char *s, char *os); 122*e5af7cceScraigm static int tabs(char *s, char *os); 123*e5af7cceScraigm static void putKcp(char *start, char *end, boolean force); 124*e5af7cceScraigm static void putScp(char *os); 125*e5af7cceScraigm static int iskw(char *s); 126*e5af7cceScraigm 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * The code below emits troff macros and directives that consume part of the 1297c478bd9Sstevel@tonic-gate * troff macro and register space. See tmac.vgrind for an enumeration of 1307c478bd9Sstevel@tonic-gate * these macros and registers. 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate 133*e5af7cceScraigm int 134*e5af7cceScraigm main(int argc, char *argv[]) 1357c478bd9Sstevel@tonic-gate { 1367c478bd9Sstevel@tonic-gate FILE *in; 1377c478bd9Sstevel@tonic-gate char *fname; 1387c478bd9Sstevel@tonic-gate struct stat stbuf; 1397c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 1407c478bd9Sstevel@tonic-gate char idbuf[256]; /* enough for all 8 bit chars */ 1417c478bd9Sstevel@tonic-gate char strings[2 * BUFSIZ]; 1427c478bd9Sstevel@tonic-gate char defs[2 * BUFSIZ]; 1437c478bd9Sstevel@tonic-gate int needbp = 0; 1447c478bd9Sstevel@tonic-gate int i; 1457c478bd9Sstevel@tonic-gate char *cp; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1487c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 1497c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1507c478bd9Sstevel@tonic-gate #endif 1517c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate /* 1547c478bd9Sstevel@tonic-gate * Dump the name by which we were invoked. 1557c478bd9Sstevel@tonic-gate */ 1567c478bd9Sstevel@tonic-gate argc--, argv++; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate /* 1597c478bd9Sstevel@tonic-gate * Process arguments. For the sake of compatibility with older versions 1607c478bd9Sstevel@tonic-gate * of the program, the syntax accepted below is very idiosyncratic. Some 1617c478bd9Sstevel@tonic-gate * options require space between the option and its argument; others 1627c478bd9Sstevel@tonic-gate * disallow it. No options may be bundled together. 1637c478bd9Sstevel@tonic-gate * 1647c478bd9Sstevel@tonic-gate * Actually, there is one incompatibility. Files and options formerly 1657c478bd9Sstevel@tonic-gate * could be arbitrarily intermixed, but this is no longer allowed. (This 1667c478bd9Sstevel@tonic-gate * possiblity was never documented.) 1677c478bd9Sstevel@tonic-gate */ 1687c478bd9Sstevel@tonic-gate while (argc > 0 && *argv[0] == '-') { 1697c478bd9Sstevel@tonic-gate switch (*(cp = argv[0] + 1)) { 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate case '\0': /* - */ 1727c478bd9Sstevel@tonic-gate /* Take input from stdin. */ 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * This option implies the end of the flag arguments. Leave the 1757c478bd9Sstevel@tonic-gate * "-" in place for the file processing code to see. 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate goto flagsdone; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate case '2': /* -2 */ 1807c478bd9Sstevel@tonic-gate /* Enter two column mode. */ 1817c478bd9Sstevel@tonic-gate twocol = 1; 1827c478bd9Sstevel@tonic-gate printf("'nr =2 1\n"); 1837c478bd9Sstevel@tonic-gate break; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate case 'd': /* -d <defs-file> */ 1867c478bd9Sstevel@tonic-gate /* Specify the language description file. */ 1877c478bd9Sstevel@tonic-gate defsfile = argv[1]; 1887c478bd9Sstevel@tonic-gate argc--, argv++; 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate case 'f': /* -f */ 1927c478bd9Sstevel@tonic-gate /* Act as a filter like eqn. */ 1937c478bd9Sstevel@tonic-gate filter = 1; 1947c478bd9Sstevel@tonic-gate /* 1957c478bd9Sstevel@tonic-gate * Slide remaining arguments down one position and postpend "-", 1967c478bd9Sstevel@tonic-gate * to force reading from stdin. 1977c478bd9Sstevel@tonic-gate */ 1987c478bd9Sstevel@tonic-gate for (i = 0; i < argc - 1; i++) 1997c478bd9Sstevel@tonic-gate argv[i] = argv[i + 1]; 2007c478bd9Sstevel@tonic-gate argv[argc - 1] = "-"; 2017c478bd9Sstevel@tonic-gate continue; 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate case 'h': /* -h [header] */ 2047c478bd9Sstevel@tonic-gate /* Specify header string. */ 2057c478bd9Sstevel@tonic-gate if (argc == 1) { 2067c478bd9Sstevel@tonic-gate printf("'ds =H\n"); 2077c478bd9Sstevel@tonic-gate break; 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate printf("'ds =H %s\n", argv[1]); 2107c478bd9Sstevel@tonic-gate argc--, argv++; 2117c478bd9Sstevel@tonic-gate break; 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate case 'l': /* -l<language> */ 2147c478bd9Sstevel@tonic-gate /* Specify the language. */ 2157c478bd9Sstevel@tonic-gate language = cp + 1; 2167c478bd9Sstevel@tonic-gate break; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate case 'n': /* -n */ 2197c478bd9Sstevel@tonic-gate /* Indicate no keywords. */ 2207c478bd9Sstevel@tonic-gate nokeyw = 1; 2217c478bd9Sstevel@tonic-gate break; 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate case 's': /* -s<size> */ 2247c478bd9Sstevel@tonic-gate /* Specify the font size. */ 2257c478bd9Sstevel@tonic-gate i = 0; 2267c478bd9Sstevel@tonic-gate cp++; 2277c478bd9Sstevel@tonic-gate while (*cp) 2287c478bd9Sstevel@tonic-gate i = i * 10 + (*cp++ - '0'); 2297c478bd9Sstevel@tonic-gate printf("'nr vP %d\n", i); 2307c478bd9Sstevel@tonic-gate break; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate case 't': /* -t */ 2337c478bd9Sstevel@tonic-gate /* Specify a nondefault tab size. */ 2347c478bd9Sstevel@tonic-gate tabsize = 4; 2357c478bd9Sstevel@tonic-gate break; 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate case 'x': /* -x */ 2387c478bd9Sstevel@tonic-gate /* Build an index. */ 2397c478bd9Sstevel@tonic-gate doindex = 1; 2407c478bd9Sstevel@tonic-gate /* This option implies "-n" as well; turn it on. */ 2417c478bd9Sstevel@tonic-gate argv[0] = "-n"; 2427c478bd9Sstevel@tonic-gate continue; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* Advance to next argument. */ 2467c478bd9Sstevel@tonic-gate argc--, argv++; 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate flagsdone: 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* 2527c478bd9Sstevel@tonic-gate * Get the language definition from the defs file. 2537c478bd9Sstevel@tonic-gate */ 2547c478bd9Sstevel@tonic-gate i = tgetent (defs, language, defsfile); 2557c478bd9Sstevel@tonic-gate if (i == 0) { 2567c478bd9Sstevel@tonic-gate fprintf (stderr, gettext("no entry for language %s\n"), language); 2577c478bd9Sstevel@tonic-gate exit (0); 2587c478bd9Sstevel@tonic-gate } else if (i < 0) { 2597c478bd9Sstevel@tonic-gate fprintf (stderr, gettext("cannot find vgrindefs file %s\n"), defsfile); 2607c478bd9Sstevel@tonic-gate exit (0); 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate cp = strings; 2637c478bd9Sstevel@tonic-gate if (tgetstr ("kw", &cp) == NIL) 2647c478bd9Sstevel@tonic-gate nokeyw = TRUE; 2657c478bd9Sstevel@tonic-gate else { 2667c478bd9Sstevel@tonic-gate char **cpp; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate cpp = l_keywds; 2697c478bd9Sstevel@tonic-gate cp = strings; 2707c478bd9Sstevel@tonic-gate while (*cp) { 2717c478bd9Sstevel@tonic-gate while (*cp == ' ' || *cp =='\t') 2727c478bd9Sstevel@tonic-gate *cp++ = NULL; 2737c478bd9Sstevel@tonic-gate if (*cp) 2747c478bd9Sstevel@tonic-gate *cpp++ = cp; 2757c478bd9Sstevel@tonic-gate while (*cp != ' ' && *cp != '\t' && *cp) 2767c478bd9Sstevel@tonic-gate cp++; 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate *cpp = NIL; 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate cp = buf; 2817c478bd9Sstevel@tonic-gate l_prcbeg = convexp (tgetstr ("pb", &cp)); 2827c478bd9Sstevel@tonic-gate cp = buf; 2837c478bd9Sstevel@tonic-gate l_combeg = convexp (tgetstr ("cb", &cp)); 2847c478bd9Sstevel@tonic-gate cp = buf; 2857c478bd9Sstevel@tonic-gate l_comend = convexp (tgetstr ("ce", &cp)); 2867c478bd9Sstevel@tonic-gate cp = buf; 2877c478bd9Sstevel@tonic-gate l_acmbeg = convexp (tgetstr ("ab", &cp)); 2887c478bd9Sstevel@tonic-gate cp = buf; 2897c478bd9Sstevel@tonic-gate l_acmend = convexp (tgetstr ("ae", &cp)); 2907c478bd9Sstevel@tonic-gate cp = buf; 2917c478bd9Sstevel@tonic-gate l_strbeg = convexp (tgetstr ("sb", &cp)); 2927c478bd9Sstevel@tonic-gate cp = buf; 2937c478bd9Sstevel@tonic-gate l_strend = convexp (tgetstr ("se", &cp)); 2947c478bd9Sstevel@tonic-gate cp = buf; 2957c478bd9Sstevel@tonic-gate l_blkbeg = convexp (tgetstr ("bb", &cp)); 2967c478bd9Sstevel@tonic-gate cp = buf; 2977c478bd9Sstevel@tonic-gate l_blkend = convexp (tgetstr ("be", &cp)); 2987c478bd9Sstevel@tonic-gate cp = buf; 2997c478bd9Sstevel@tonic-gate l_chrbeg = convexp (tgetstr ("lb", &cp)); 3007c478bd9Sstevel@tonic-gate cp = buf; 3017c478bd9Sstevel@tonic-gate l_chrend = convexp (tgetstr ("le", &cp)); 3027c478bd9Sstevel@tonic-gate cp = buf; 3037c478bd9Sstevel@tonic-gate l_prcenable = convexp (tgetstr ("px", &cp)); 3047c478bd9Sstevel@tonic-gate cp = idbuf; 3057c478bd9Sstevel@tonic-gate l_idchars = tgetstr ("id", &cp); 3067c478bd9Sstevel@tonic-gate /* Set default, for compatibility with old version */ 3077c478bd9Sstevel@tonic-gate if (l_idchars == NIL) 3087c478bd9Sstevel@tonic-gate l_idchars = "_"; 3097c478bd9Sstevel@tonic-gate l_escape = '\\'; 3107c478bd9Sstevel@tonic-gate l_onecase = tgetflag ("oc"); 3117c478bd9Sstevel@tonic-gate l_toplex = tgetflag ("tl"); 3127c478bd9Sstevel@tonic-gate l_prclevel = tgetflag ("pl"); 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* 3157c478bd9Sstevel@tonic-gate * Emit a call to the initialization macro. If not in filter mode, emit a 3167c478bd9Sstevel@tonic-gate * call to the vS macro, so that tmac.vgrind can uniformly assume that all 3177c478bd9Sstevel@tonic-gate * program input is bracketed with vS-vE pairs. 3187c478bd9Sstevel@tonic-gate */ 3197c478bd9Sstevel@tonic-gate printf("'vI\n"); 3207c478bd9Sstevel@tonic-gate if (!filter) 3217c478bd9Sstevel@tonic-gate printf("'vS\n"); 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate if (doindex) { 3247c478bd9Sstevel@tonic-gate /* 3257c478bd9Sstevel@tonic-gate * XXX: Hard-wired spacing information. This should probably turn 3267c478bd9Sstevel@tonic-gate * into the emission of a macro invocation, so that tmac.vgrind 3277c478bd9Sstevel@tonic-gate * can make up its own mind about what spacing is appropriate. 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate if (twocol) 3307c478bd9Sstevel@tonic-gate printf("'ta 2.5i 2.75i 4.0iR\n'in .25i\n"); 3317c478bd9Sstevel@tonic-gate else 3327c478bd9Sstevel@tonic-gate printf("'ta 4i 4.25i 5.5iR\n'in .5i\n"); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate while (argc > 0) { 3367c478bd9Sstevel@tonic-gate if (strcmp(argv[0], "-") == 0) { 3377c478bd9Sstevel@tonic-gate /* Embed an instance of the original stdin. */ 3387c478bd9Sstevel@tonic-gate in = fdopen(fileno(stdin), "r"); 3397c478bd9Sstevel@tonic-gate fname = ""; 3407c478bd9Sstevel@tonic-gate } else { 3417c478bd9Sstevel@tonic-gate /* Open the file for input. */ 3427c478bd9Sstevel@tonic-gate if ((in = fopen(argv[0], "r")) == NULL) { 3437c478bd9Sstevel@tonic-gate perror(argv[0]); 3447c478bd9Sstevel@tonic-gate exit(1); 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate fname = argv[0]; 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate argc--, argv++; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* 3517c478bd9Sstevel@tonic-gate * Reinitialize for the current file. 3527c478bd9Sstevel@tonic-gate */ 3537c478bd9Sstevel@tonic-gate incomm = FALSE; 3547c478bd9Sstevel@tonic-gate instr = FALSE; 3557c478bd9Sstevel@tonic-gate inchr = FALSE; 3567c478bd9Sstevel@tonic-gate _escaped = FALSE; 3577c478bd9Sstevel@tonic-gate blklevel = 0; 3587c478bd9Sstevel@tonic-gate prclevel = -1; 3597c478bd9Sstevel@tonic-gate for (psptr=0; psptr<PSMAX; psptr++) { 3607c478bd9Sstevel@tonic-gate pstack[psptr][0] = NULL; 3617c478bd9Sstevel@tonic-gate plstack[psptr] = 0; 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate psptr = -1; 3647c478bd9Sstevel@tonic-gate printf("'-F\n"); 3657c478bd9Sstevel@tonic-gate if (!filter) { 3667c478bd9Sstevel@tonic-gate char *cp; 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate printf(".ds =F %s\n", fname); 3697c478bd9Sstevel@tonic-gate if (needbp) { 3707c478bd9Sstevel@tonic-gate needbp = 0; 3717c478bd9Sstevel@tonic-gate printf(".()\n"); 3727c478bd9Sstevel@tonic-gate printf(".bp\n"); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate fstat(fileno(in), &stbuf); 3757c478bd9Sstevel@tonic-gate cp = ctime(&stbuf.st_mtime); 3767c478bd9Sstevel@tonic-gate cp[16] = '\0'; 3777c478bd9Sstevel@tonic-gate cp[24] = '\0'; 3787c478bd9Sstevel@tonic-gate printf(".ds =M %s %s\n", cp+4, cp+20); 3797c478bd9Sstevel@tonic-gate printf("'wh 0 vH\n"); 3807c478bd9Sstevel@tonic-gate printf("'wh -1i vF\n"); 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate if (needbp && filter) { 3837c478bd9Sstevel@tonic-gate needbp = 0; 3847c478bd9Sstevel@tonic-gate printf(".()\n"); 3857c478bd9Sstevel@tonic-gate printf(".bp\n"); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate /* 3897c478bd9Sstevel@tonic-gate * MAIN LOOP!!! 3907c478bd9Sstevel@tonic-gate */ 3917c478bd9Sstevel@tonic-gate while (fgets(buf, sizeof buf, in) != NULL) { 3927c478bd9Sstevel@tonic-gate if (buf[0] == '\f') { 3937c478bd9Sstevel@tonic-gate printf(".bp\n"); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate if (buf[0] == '.') { 3967c478bd9Sstevel@tonic-gate printf("%s", buf); 3977c478bd9Sstevel@tonic-gate if (!strncmp (buf+1, "vS", 2)) 3987c478bd9Sstevel@tonic-gate pass = TRUE; 3997c478bd9Sstevel@tonic-gate if (!strncmp (buf+1, "vE", 2)) 4007c478bd9Sstevel@tonic-gate pass = FALSE; 4017c478bd9Sstevel@tonic-gate continue; 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate prccont = FALSE; 4047c478bd9Sstevel@tonic-gate if (!filter || pass) 4057c478bd9Sstevel@tonic-gate putScp(buf); 4067c478bd9Sstevel@tonic-gate else 4077c478bd9Sstevel@tonic-gate printf("%s", buf); 4087c478bd9Sstevel@tonic-gate if (prccont && (psptr >= 0)) 4097c478bd9Sstevel@tonic-gate printf("'FC %s\n", pstack[psptr]); 4107c478bd9Sstevel@tonic-gate #ifdef DEBUG 4117c478bd9Sstevel@tonic-gate printf ("com %o str %o chr %o ptr %d\n", incomm, instr, inchr, psptr); 4127c478bd9Sstevel@tonic-gate #endif 4137c478bd9Sstevel@tonic-gate margin = 0; 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate needbp = 1; 4177c478bd9Sstevel@tonic-gate (void) fclose(in); 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate /* Close off the vS-vE pair. */ 4217c478bd9Sstevel@tonic-gate if (!filter) 4227c478bd9Sstevel@tonic-gate printf("'vE\n"); 4237c478bd9Sstevel@tonic-gate 424*e5af7cceScraigm return (0); 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate #define isidchr(c) (isalnum(c) || ((c) != NIL && strchr(l_idchars, (c)) != NIL)) 4287c478bd9Sstevel@tonic-gate 429*e5af7cceScraigm static void 430*e5af7cceScraigm putScp(char *os) 4317c478bd9Sstevel@tonic-gate { 432*e5af7cceScraigm char *s = os; /* pointer to unmatched string */ 4337c478bd9Sstevel@tonic-gate char dummy[BUFSIZ]; /* dummy to be used by expmatch */ 4347c478bd9Sstevel@tonic-gate char *comptr; /* end of a comment delimiter */ 4357c478bd9Sstevel@tonic-gate char *acmptr; /* end of a comment delimiter */ 4367c478bd9Sstevel@tonic-gate char *strptr; /* end of a string delimiter */ 4377c478bd9Sstevel@tonic-gate char *chrptr; /* end of a character const delimiter */ 4387c478bd9Sstevel@tonic-gate char *blksptr; /* end of a lexical block start */ 4397c478bd9Sstevel@tonic-gate char *blkeptr; /* end of a lexical block end */ 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate Start = os; /* remember the start for expmatch */ 4427c478bd9Sstevel@tonic-gate _escaped = FALSE; 4437c478bd9Sstevel@tonic-gate if (nokeyw || incomm || instr) 4447c478bd9Sstevel@tonic-gate goto skip; 4457c478bd9Sstevel@tonic-gate if (isproc(s)) { 4467c478bd9Sstevel@tonic-gate printf("'FN %s\n", pname); 4477c478bd9Sstevel@tonic-gate if (psptr < PSMAX-1) { 4487c478bd9Sstevel@tonic-gate ++psptr; 4497c478bd9Sstevel@tonic-gate strncpy (pstack[psptr], pname, PNAMELEN); 4507c478bd9Sstevel@tonic-gate pstack[psptr][PNAMELEN] = NULL; 4517c478bd9Sstevel@tonic-gate plstack[psptr] = blklevel; 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate /* 4557c478bd9Sstevel@tonic-gate * if l_prclevel is set, check to see whether this lexical level 4567c478bd9Sstevel@tonic-gate * is one immediately below which procedure definitions are allowed. 4577c478bd9Sstevel@tonic-gate */ 4587c478bd9Sstevel@tonic-gate if (l_prclevel && !incomm && !instr && !inchr) { 4597c478bd9Sstevel@tonic-gate if (expmatch (s, l_prcenable, dummy) != NIL) 4607c478bd9Sstevel@tonic-gate prclevel = blklevel + 1; 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate skip: 4637c478bd9Sstevel@tonic-gate do { 4647c478bd9Sstevel@tonic-gate /* check for string, comment, blockstart, etc */ 4657c478bd9Sstevel@tonic-gate if (!incomm && !instr && !inchr) { 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate blkeptr = expmatch (s, l_blkend, dummy); 4687c478bd9Sstevel@tonic-gate blksptr = expmatch (s, l_blkbeg, dummy); 4697c478bd9Sstevel@tonic-gate comptr = expmatch (s, l_combeg, dummy); 4707c478bd9Sstevel@tonic-gate acmptr = expmatch (s, l_acmbeg, dummy); 4717c478bd9Sstevel@tonic-gate strptr = expmatch (s, l_strbeg, dummy); 4727c478bd9Sstevel@tonic-gate chrptr = expmatch (s, l_chrbeg, dummy); 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* start of a comment? */ 4757c478bd9Sstevel@tonic-gate if (comptr != NIL) 4767c478bd9Sstevel@tonic-gate if ((comptr < strptr || strptr == NIL) 4777c478bd9Sstevel@tonic-gate && (comptr < acmptr || acmptr == NIL) 4787c478bd9Sstevel@tonic-gate && (comptr < chrptr || chrptr == NIL) 4797c478bd9Sstevel@tonic-gate && (comptr < blksptr || blksptr == NIL) 4807c478bd9Sstevel@tonic-gate && (comptr < blkeptr || blkeptr == NIL)) { 4817c478bd9Sstevel@tonic-gate putKcp (s, comptr-1, FALSE); 4827c478bd9Sstevel@tonic-gate s = comptr; 4837c478bd9Sstevel@tonic-gate incomm = TRUE; 4847c478bd9Sstevel@tonic-gate comtype = STANDARD; 4857c478bd9Sstevel@tonic-gate if (s != os) 4867c478bd9Sstevel@tonic-gate printf ("\\c"); 4877c478bd9Sstevel@tonic-gate printf ("\\c\n'+C\n"); 4887c478bd9Sstevel@tonic-gate continue; 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate /* start of a comment? */ 4927c478bd9Sstevel@tonic-gate if (acmptr != NIL) 4937c478bd9Sstevel@tonic-gate if ((acmptr < strptr || strptr == NIL) 4947c478bd9Sstevel@tonic-gate && (acmptr < chrptr || chrptr == NIL) 4957c478bd9Sstevel@tonic-gate && (acmptr < blksptr || blksptr == NIL) 4967c478bd9Sstevel@tonic-gate && (acmptr < blkeptr || blkeptr == NIL)) { 4977c478bd9Sstevel@tonic-gate putKcp (s, acmptr-1, FALSE); 4987c478bd9Sstevel@tonic-gate s = acmptr; 4997c478bd9Sstevel@tonic-gate incomm = TRUE; 5007c478bd9Sstevel@tonic-gate comtype = ALTERNATE; 5017c478bd9Sstevel@tonic-gate if (s != os) 5027c478bd9Sstevel@tonic-gate printf ("\\c"); 5037c478bd9Sstevel@tonic-gate printf ("\\c\n'+C\n"); 5047c478bd9Sstevel@tonic-gate continue; 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate /* start of a string? */ 5087c478bd9Sstevel@tonic-gate if (strptr != NIL) 5097c478bd9Sstevel@tonic-gate if ((strptr < chrptr || chrptr == NIL) 5107c478bd9Sstevel@tonic-gate && (strptr < blksptr || blksptr == NIL) 5117c478bd9Sstevel@tonic-gate && (strptr < blkeptr || blkeptr == NIL)) { 5127c478bd9Sstevel@tonic-gate putKcp (s, strptr-1, FALSE); 5137c478bd9Sstevel@tonic-gate s = strptr; 5147c478bd9Sstevel@tonic-gate instr = TRUE; 5157c478bd9Sstevel@tonic-gate continue; 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* start of a character string? */ 5197c478bd9Sstevel@tonic-gate if (chrptr != NIL) 5207c478bd9Sstevel@tonic-gate if ((chrptr < blksptr || blksptr == NIL) 5217c478bd9Sstevel@tonic-gate && (chrptr < blkeptr || blkeptr == NIL)) { 5227c478bd9Sstevel@tonic-gate putKcp (s, chrptr-1, FALSE); 5237c478bd9Sstevel@tonic-gate s = chrptr; 5247c478bd9Sstevel@tonic-gate inchr = TRUE; 5257c478bd9Sstevel@tonic-gate continue; 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate /* end of a lexical block */ 5297c478bd9Sstevel@tonic-gate if (blkeptr != NIL) { 5307c478bd9Sstevel@tonic-gate if (blkeptr < blksptr || blksptr == NIL) { 5317c478bd9Sstevel@tonic-gate /* reset prclevel if necessary */ 5327c478bd9Sstevel@tonic-gate if (l_prclevel && prclevel == blklevel) 5337c478bd9Sstevel@tonic-gate prclevel = -1; 5347c478bd9Sstevel@tonic-gate putKcp (s, blkeptr - 1, FALSE); 5357c478bd9Sstevel@tonic-gate s = blkeptr; 5367c478bd9Sstevel@tonic-gate blklevel--; 5377c478bd9Sstevel@tonic-gate if (psptr >= 0 && plstack[psptr] >= blklevel) { 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate /* end of current procedure */ 5407c478bd9Sstevel@tonic-gate if (s != os) 5417c478bd9Sstevel@tonic-gate printf ("\\c"); 5427c478bd9Sstevel@tonic-gate printf ("\\c\n'-F\n"); 5437c478bd9Sstevel@tonic-gate blklevel = plstack[psptr]; 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate /* see if we should print the last proc name */ 5467c478bd9Sstevel@tonic-gate if (--psptr >= 0) 5477c478bd9Sstevel@tonic-gate prccont = TRUE; 5487c478bd9Sstevel@tonic-gate else 5497c478bd9Sstevel@tonic-gate psptr = -1; 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate continue; 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate /* start of a lexical block */ 5567c478bd9Sstevel@tonic-gate if (blksptr != NIL) { 5577c478bd9Sstevel@tonic-gate putKcp (s, blksptr - 1, FALSE); 5587c478bd9Sstevel@tonic-gate s = blksptr; 5597c478bd9Sstevel@tonic-gate blklevel++; 5607c478bd9Sstevel@tonic-gate continue; 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* check for end of comment */ 5647c478bd9Sstevel@tonic-gate } else if (incomm) { 5657c478bd9Sstevel@tonic-gate comptr = expmatch (s, l_comend, dummy); 5667c478bd9Sstevel@tonic-gate acmptr = expmatch (s, l_acmend, dummy); 5677c478bd9Sstevel@tonic-gate if (((comtype == STANDARD) && (comptr != NIL)) || 5687c478bd9Sstevel@tonic-gate ((comtype == ALTERNATE) && (acmptr != NIL))) { 5697c478bd9Sstevel@tonic-gate if (comtype == STANDARD) { 5707c478bd9Sstevel@tonic-gate putKcp (s, comptr-1, TRUE); 5717c478bd9Sstevel@tonic-gate s = comptr; 5727c478bd9Sstevel@tonic-gate } else { 5737c478bd9Sstevel@tonic-gate putKcp (s, acmptr-1, TRUE); 5747c478bd9Sstevel@tonic-gate s = acmptr; 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate incomm = FALSE; 5777c478bd9Sstevel@tonic-gate printf("\\c\n'-C\n"); 5787c478bd9Sstevel@tonic-gate continue; 5797c478bd9Sstevel@tonic-gate } else { 5807c478bd9Sstevel@tonic-gate putKcp (s, s + strlen(s) -1, TRUE); 5817c478bd9Sstevel@tonic-gate s = s + strlen(s); 5827c478bd9Sstevel@tonic-gate continue; 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate /* check for end of string */ 5867c478bd9Sstevel@tonic-gate } else if (instr) { 5877c478bd9Sstevel@tonic-gate if ((strptr = expmatch (s, l_strend, dummy)) != NIL) { 5887c478bd9Sstevel@tonic-gate putKcp (s, strptr-1, TRUE); 5897c478bd9Sstevel@tonic-gate s = strptr; 5907c478bd9Sstevel@tonic-gate instr = FALSE; 5917c478bd9Sstevel@tonic-gate continue; 5927c478bd9Sstevel@tonic-gate } else { 5937c478bd9Sstevel@tonic-gate putKcp (s, s+strlen(s)-1, TRUE); 5947c478bd9Sstevel@tonic-gate s = s + strlen(s); 5957c478bd9Sstevel@tonic-gate continue; 5967c478bd9Sstevel@tonic-gate } 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate /* check for end of character string */ 5997c478bd9Sstevel@tonic-gate } else if (inchr) { 6007c478bd9Sstevel@tonic-gate if ((chrptr = expmatch (s, l_chrend, dummy)) != NIL) { 6017c478bd9Sstevel@tonic-gate putKcp (s, chrptr-1, TRUE); 6027c478bd9Sstevel@tonic-gate s = chrptr; 6037c478bd9Sstevel@tonic-gate inchr = FALSE; 6047c478bd9Sstevel@tonic-gate continue; 6057c478bd9Sstevel@tonic-gate } else { 6067c478bd9Sstevel@tonic-gate putKcp (s, s+strlen(s)-1, TRUE); 6077c478bd9Sstevel@tonic-gate s = s + strlen(s); 6087c478bd9Sstevel@tonic-gate continue; 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate /* print out the line */ 6137c478bd9Sstevel@tonic-gate putKcp (s, s + strlen(s) -1, FALSE); 6147c478bd9Sstevel@tonic-gate s = s + strlen(s); 6157c478bd9Sstevel@tonic-gate } while (*s); 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 618*e5af7cceScraigm static void 619*e5af7cceScraigm putKcp(char *start, char *end, boolean force) 620*e5af7cceScraigm /* start - start of string to write */ 621*e5af7cceScraigm /* end - end of string to write */ 622*e5af7cceScraigm /* force - true if we should force nokeyw */ 6237c478bd9Sstevel@tonic-gate { 6247c478bd9Sstevel@tonic-gate int i; 6257c478bd9Sstevel@tonic-gate int xfld = 0; 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate while (start <= end) { 6287c478bd9Sstevel@tonic-gate if (doindex) { 6297c478bd9Sstevel@tonic-gate if (*start == ' ' || *start == '\t') { 6307c478bd9Sstevel@tonic-gate if (xfld == 0) 6317c478bd9Sstevel@tonic-gate printf(""); 6327c478bd9Sstevel@tonic-gate printf("\t"); 6337c478bd9Sstevel@tonic-gate xfld = 1; 6347c478bd9Sstevel@tonic-gate while (*start == ' ' || *start == '\t') 6357c478bd9Sstevel@tonic-gate start++; 6367c478bd9Sstevel@tonic-gate continue; 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate } 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate /* take care of nice tab stops */ 6417c478bd9Sstevel@tonic-gate if (*start == '\t') { 6427c478bd9Sstevel@tonic-gate while (*start == '\t') 6437c478bd9Sstevel@tonic-gate start++; 6447c478bd9Sstevel@tonic-gate i = tabs(Start, start) - margin / tabsize; 6457c478bd9Sstevel@tonic-gate printf ("\\h'|%dn'", 6467c478bd9Sstevel@tonic-gate i * (tabsize == 4 ? 5 : 10) + 1 - margin % tabsize); 6477c478bd9Sstevel@tonic-gate continue; 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate if (!nokeyw && !force) 6517c478bd9Sstevel@tonic-gate if ( (*start == '#' || isidchr(*start)) 6527c478bd9Sstevel@tonic-gate && (start == Start || !isidchr(start[-1])) 6537c478bd9Sstevel@tonic-gate ) { 6547c478bd9Sstevel@tonic-gate i = iskw(start); 6557c478bd9Sstevel@tonic-gate if (i > 0) { 6567c478bd9Sstevel@tonic-gate printf("\\*(+K"); 6577c478bd9Sstevel@tonic-gate do 6587c478bd9Sstevel@tonic-gate putcp(*start++); 6597c478bd9Sstevel@tonic-gate while (--i > 0); 6607c478bd9Sstevel@tonic-gate printf("\\*(-K"); 6617c478bd9Sstevel@tonic-gate continue; 6627c478bd9Sstevel@tonic-gate } 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate putcp (*start++); 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate 670*e5af7cceScraigm static int 671*e5af7cceScraigm tabs(char *s, char *os) 6727c478bd9Sstevel@tonic-gate { 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate return (width(s, os) / tabsize); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate 677*e5af7cceScraigm static int 678*e5af7cceScraigm width(char *s, char *os) 6797c478bd9Sstevel@tonic-gate { 680*e5af7cceScraigm int i = 0; 6817c478bd9Sstevel@tonic-gate unsigned char c; 6827c478bd9Sstevel@tonic-gate int n; 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate while (s < os) { 6857c478bd9Sstevel@tonic-gate if (*s == '\t') { 6867c478bd9Sstevel@tonic-gate i = (i + tabsize) &~ (tabsize-1); 6877c478bd9Sstevel@tonic-gate s++; 6887c478bd9Sstevel@tonic-gate continue; 6897c478bd9Sstevel@tonic-gate } 6907c478bd9Sstevel@tonic-gate c = *(unsigned char *)s; 6917c478bd9Sstevel@tonic-gate if (c < ' ') 6927c478bd9Sstevel@tonic-gate i += 2, s++; 6937c478bd9Sstevel@tonic-gate else if (c >= 0200) { 6947c478bd9Sstevel@tonic-gate if ((n = mblen(s, MB_CUR_MAX)) > 0) { 6957c478bd9Sstevel@tonic-gate i += csetcol(csetno(c)); 6967c478bd9Sstevel@tonic-gate s += n; 6977c478bd9Sstevel@tonic-gate } else 6987c478bd9Sstevel@tonic-gate s++; 6997c478bd9Sstevel@tonic-gate } else 7007c478bd9Sstevel@tonic-gate i++, s++; 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate return (i); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 705*e5af7cceScraigm static void 706*e5af7cceScraigm putcp(int c) 7077c478bd9Sstevel@tonic-gate { 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate switch(c) { 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate case 0: 7127c478bd9Sstevel@tonic-gate break; 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate case '\f': 7157c478bd9Sstevel@tonic-gate break; 7167c478bd9Sstevel@tonic-gate 7177c478bd9Sstevel@tonic-gate case '{': 7187c478bd9Sstevel@tonic-gate printf("\\*(+K{\\*(-K"); 7197c478bd9Sstevel@tonic-gate break; 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate case '}': 7227c478bd9Sstevel@tonic-gate printf("\\*(+K}\\*(-K"); 7237c478bd9Sstevel@tonic-gate break; 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate case '\\': 7267c478bd9Sstevel@tonic-gate printf("\\e"); 7277c478bd9Sstevel@tonic-gate break; 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate case '_': 7307c478bd9Sstevel@tonic-gate printf("\\*_"); 7317c478bd9Sstevel@tonic-gate break; 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate case '-': 7347c478bd9Sstevel@tonic-gate printf("\\*-"); 7357c478bd9Sstevel@tonic-gate break; 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate /* 7387c478bd9Sstevel@tonic-gate * The following two cases deal with the accent characters. 7397c478bd9Sstevel@tonic-gate * If they're part of a comment, we assume that they're part 7407c478bd9Sstevel@tonic-gate * of running text and hand them to troff as regular quote 7417c478bd9Sstevel@tonic-gate * characters. Otherwise, we assume they're being used as 7427c478bd9Sstevel@tonic-gate * special characters (e.g., string delimiters) and arrange 7437c478bd9Sstevel@tonic-gate * for troff to render them as accents. This is an imperfect 7447c478bd9Sstevel@tonic-gate * heuristic that produces slightly better appearance than the 7457c478bd9Sstevel@tonic-gate * former behavior of unconditionally rendering the characters 7467c478bd9Sstevel@tonic-gate * as accents. (See bug 1040343.) 7477c478bd9Sstevel@tonic-gate */ 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate case '`': 7507c478bd9Sstevel@tonic-gate if (incomm) 7517c478bd9Sstevel@tonic-gate printf("`"); 7527c478bd9Sstevel@tonic-gate else 7537c478bd9Sstevel@tonic-gate printf("\\`"); 7547c478bd9Sstevel@tonic-gate break; 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate case '\'': 7577c478bd9Sstevel@tonic-gate if (incomm) 7587c478bd9Sstevel@tonic-gate printf("'"); 7597c478bd9Sstevel@tonic-gate else 7607c478bd9Sstevel@tonic-gate printf("\\'"); 7617c478bd9Sstevel@tonic-gate break; 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate case '.': 7647c478bd9Sstevel@tonic-gate printf("\\&."); 7657c478bd9Sstevel@tonic-gate break; 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate /* 7687c478bd9Sstevel@tonic-gate * The following two cases contain special hacking 7697c478bd9Sstevel@tonic-gate * to make C-style comments line up. The tests aren't 7707c478bd9Sstevel@tonic-gate * really adequate; they lead to grotesqueries such 7717c478bd9Sstevel@tonic-gate * as italicized multiplication and division operators. 7727c478bd9Sstevel@tonic-gate * However, the obvious test (!incomm) doesn't work, 7737c478bd9Sstevel@tonic-gate * because incomm isn't set until after we've put out 7747c478bd9Sstevel@tonic-gate * the comment-begin characters. The real problem is 7757c478bd9Sstevel@tonic-gate * that expmatch() doesn't give us enough information. 7767c478bd9Sstevel@tonic-gate */ 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate case '*': 7797c478bd9Sstevel@tonic-gate if (instr || inchr) 7807c478bd9Sstevel@tonic-gate printf("*"); 7817c478bd9Sstevel@tonic-gate else 7827c478bd9Sstevel@tonic-gate printf("\\f2*\\fP"); 7837c478bd9Sstevel@tonic-gate break; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate case '/': 7867c478bd9Sstevel@tonic-gate if (instr || inchr) 7877c478bd9Sstevel@tonic-gate printf("/"); 7887c478bd9Sstevel@tonic-gate else 7897c478bd9Sstevel@tonic-gate printf("\\f2\\h'\\w' 'u-\\w'/'u'/\\fP"); 7907c478bd9Sstevel@tonic-gate break; 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate default: 7937c478bd9Sstevel@tonic-gate if (c < 040) 7947c478bd9Sstevel@tonic-gate putchar('^'), c |= '@'; 7957c478bd9Sstevel@tonic-gate case '\t': 7967c478bd9Sstevel@tonic-gate case '\n': 7977c478bd9Sstevel@tonic-gate putchar(c); 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate /* 8027c478bd9Sstevel@tonic-gate * look for a process beginning on this line 8037c478bd9Sstevel@tonic-gate */ 8047c478bd9Sstevel@tonic-gate boolean 8057c478bd9Sstevel@tonic-gate isproc(s) 8067c478bd9Sstevel@tonic-gate char *s; 8077c478bd9Sstevel@tonic-gate { 8087c478bd9Sstevel@tonic-gate pname[0] = NULL; 8097c478bd9Sstevel@tonic-gate if (l_prclevel ? (prclevel == blklevel) : (!l_toplex || blklevel == 0)) 8107c478bd9Sstevel@tonic-gate if (expmatch (s, l_prcbeg, pname) != NIL) { 8117c478bd9Sstevel@tonic-gate return (TRUE); 8127c478bd9Sstevel@tonic-gate } 8137c478bd9Sstevel@tonic-gate return (FALSE); 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate 8177c478bd9Sstevel@tonic-gate /* 8187c478bd9Sstevel@tonic-gate * iskw - check to see if the next word is a keyword 8197c478bd9Sstevel@tonic-gate * Return its length if it is or 0 if it isn't. 8207c478bd9Sstevel@tonic-gate */ 8217c478bd9Sstevel@tonic-gate 822*e5af7cceScraigm static int 823*e5af7cceScraigm iskw(char *s) 8247c478bd9Sstevel@tonic-gate { 825*e5af7cceScraigm char **ss = l_keywds; 826*e5af7cceScraigm int i = 1; 827*e5af7cceScraigm char *cp = s; 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate /* Get token length. */ 8307c478bd9Sstevel@tonic-gate while (++cp, isidchr(*cp)) 8317c478bd9Sstevel@tonic-gate i++; 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate while (cp = *ss++) { 8347c478bd9Sstevel@tonic-gate if (!STRNCMP(s,cp,i) && !isidchr(cp[i])) 8357c478bd9Sstevel@tonic-gate return (i); 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate return (0); 8387c478bd9Sstevel@tonic-gate } 839