122065Sdist /* 236167Sbostic * Copyright (c) 1980 The Regents of the University of California. 336167Sbostic * All rights reserved. 436167Sbostic * 5*56143Selan * Redistribution and use in source and binary forms, with or without 6*56143Selan * modification, are permitted provided that the following conditions 7*56143Selan * are met: 8*56143Selan * 1. Redistributions of source code must retain the above copyright 9*56143Selan * notice, this list of conditions and the following disclaimer. 10*56143Selan * 2. Redistributions in binary form must reproduce the above copyright 11*56143Selan * notice, this list of conditions and the following disclaimer in the 12*56143Selan * documentation and/or other materials provided with the distribution. 13*56143Selan * 3. All advertising materials mentioning features or use of this software 14*56143Selan * must display the following acknowledgement: 15*56143Selan * This product includes software developed by the University of 16*56143Selan * California, Berkeley and its contributors. 17*56143Selan * 4. Neither the name of the University nor the names of its contributors 18*56143Selan * may be used to endorse or promote products derived from this software 19*56143Selan * without specific prior written permission. 20*56143Selan * 21*56143Selan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22*56143Selan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23*56143Selan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24*56143Selan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25*56143Selan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26*56143Selan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27*56143Selan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28*56143Selan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29*56143Selan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30*56143Selan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*56143Selan * SUCH DAMAGE. 3222065Sdist */ 338760Smckusick 3422065Sdist #ifndef lint 3536167Sbostic char copyright[] = 3636167Sbostic "@(#) Copyright (c) 1980 The Regents of the University of California.\n\ 3736167Sbostic All rights reserved.\n"; 3836167Sbostic #endif /* not lint */ 3922065Sdist 4036167Sbostic #ifndef lint 41*56143Selan static char sccsid[] = "@(#)vfontedpr.c 5.7 (Berkeley) 8/6/92"; 4236167Sbostic #endif /* not lint */ 4336167Sbostic 4437561Sbostic #include <sys/types.h> 4537561Sbostic #include <sys/stat.h> 46*56143Selan #include <time.h> 471841Sroot #include <ctype.h> 48*56143Selan #include <stdlib.h> 49*56143Selan #include <string.h> 501841Sroot #include <stdio.h> 5137561Sbostic #include "pathnames.h" 52*56143Selan #include "extern.h" 531841Sroot 542199Sroot #define FALSE 0 55*56143Selan #define TRUE !(FALSE) 562199Sroot #define NIL 0 573882Spresott #define STANDARD 0 583882Spresott #define ALTERNATE 1 592199Sroot 601841Sroot /* 611841Sroot * Vfontedpr. 621841Sroot * 632199Sroot * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy) 641862Sroot * 651841Sroot */ 661862Sroot 671862Sroot #define STRLEN 10 /* length of strings introducing things */ 681862Sroot #define PNAMELEN 40 /* length of a function/procedure name */ 692199Sroot #define PSMAX 20 /* size of procedure name stacking */ 701862Sroot 71*56143Selan static int iskw __P((char *)); 72*56143Selan static boolean isproc __P((char *)); 73*56143Selan static void putKcp __P((char *, char *, boolean)); 74*56143Selan static void putScp __P((char *)); 75*56143Selan static void putcp __P((int)); 76*56143Selan static int tabs __P((char *, char *)); 77*56143Selan static int width __P((char *, char *)); 781862Sroot 792199Sroot /* 802199Sroot * The state variables 812199Sroot */ 821862Sroot 83*56143Selan static boolean filter = FALSE; /* act as a filter (like eqn) */ 84*56143Selan static boolean inchr; /* in a string constant */ 85*56143Selan static boolean incomm; /* in a comment of the primary type */ 86*56143Selan static boolean idx = FALSE; /* form an index */ 87*56143Selan static boolean instr; /* in a string constant */ 88*56143Selan static boolean nokeyw = FALSE; /* no keywords being flagged */ 89*56143Selan static boolean pass = FALSE; /* 90*56143Selan * when acting as a filter, pass indicates 912199Sroot * whether we are currently processing 922199Sroot * input. 932199Sroot */ 941862Sroot 95*56143Selan statis int blklevel; /* current nesting level */ 96*56143Selan statis int comtype; /* type of comment */ 97*56143Selan static char *defsfile[2] = { _PATH_VGRINDEFS, 0 }; 98*56143Selan /* name of language definitions file */ 99*56143Selan statis int margin; 100*56143Selan statis int plstack[PSMAX]; /* the procedure nesting level stack */ 101*56143Selan static char pname[BUFSIZ+1]; 102*56143Selan static boolean prccont; /* continue last procedure */ 103*56143Selan statis int psptr; /* the stack index of the current procedure */ 104*56143Selan static char pstack[PSMAX][PNAMELEN+1]; /* the procedure name stack */ 105*56143Selan 1062199Sroot /* 1072199Sroot * The language specific globals 1082199Sroot */ 1091862Sroot 1103882Spresott char *l_acmbeg; /* string introducing a comment */ 1113882Spresott char *l_acmend; /* string ending a comment */ 1122199Sroot char *l_blkbeg; /* string begining of a block */ 1132199Sroot char *l_blkend; /* string ending a block */ 114*56143Selan char *l_chrbeg; /* delimiter for character constant */ 115*56143Selan char *l_chrend; /* delimiter for character constant */ 116*56143Selan char *l_combeg; /* string introducing a comment */ 117*56143Selan char *l_comend; /* string ending a comment */ 118*56143Selan char l_escape; /* character used to escape characters */ 119*56143Selan char *l_keywds[BUFSIZ/2]; /* keyword table address */ 120*56143Selan char *l_prcbeg; /* regular expr for procedure begin */ 1212199Sroot char *l_strbeg; /* delimiter for string constant */ 1222199Sroot char *l_strend; /* delimiter for string constant */ 123*56143Selan boolean l_toplex; /* procedures only defined at top lex level */ 124*56143Selan char *language = "c"; /* the language indicator */ 1251878Sroot 1262199Sroot #define ps(x) printf("%s", x) 1271862Sroot 128*56143Selan void 1292199Sroot main(argc, argv) 1302199Sroot int argc; 1312199Sroot char *argv[]; 1322199Sroot { 1332199Sroot char *fname = ""; 1342199Sroot struct stat stbuf; 1352199Sroot char buf[BUFSIZ]; 136*56143Selan char *defs; 1372199Sroot int needbp = 0; 1381862Sroot 1392199Sroot argc--, argv++; 1402199Sroot do { 1412199Sroot char *cp; 1422199Sroot int i; 1431878Sroot 1442199Sroot if (argc > 0) { 1452199Sroot if (!strcmp(argv[0], "-h")) { 1462199Sroot if (argc == 1) { 1472199Sroot printf("'ds =H\n"); 1482199Sroot argc = 0; 1492199Sroot goto rest; 1502199Sroot } 1512199Sroot printf("'ds =H %s\n", argv[1]); 1523393Spresott argc--, argv++; 1533393Spresott argc--, argv++; 1542199Sroot if (argc > 0) 1552199Sroot continue; 1562199Sroot goto rest; 1572199Sroot } 1581862Sroot 1592199Sroot /* act as a filter like eqn */ 1602199Sroot if (!strcmp(argv[0], "-f")) { 1612199Sroot filter++; 1622199Sroot argv[0] = argv[argc-1]; 1632199Sroot argv[argc-1] = "-"; 1642199Sroot continue; 1652199Sroot } 1661862Sroot 1672199Sroot /* take input from the standard place */ 1682199Sroot if (!strcmp(argv[0], "-")) { 1692199Sroot argc = 0; 1702199Sroot goto rest; 1712199Sroot } 1721878Sroot 1732199Sroot /* build an index */ 1742199Sroot if (!strcmp(argv[0], "-x")) { 175*56143Selan idx++; 1762199Sroot argv[0] = "-n"; 1772199Sroot } 1781841Sroot 1792199Sroot /* indicate no keywords */ 1802199Sroot if (!strcmp(argv[0], "-n")) { 1812199Sroot nokeyw++; 1822199Sroot argc--, argv++; 1832199Sroot continue; 1842199Sroot } 1851862Sroot 1862199Sroot /* specify the font size */ 1872199Sroot if (!strncmp(argv[0], "-s", 2)) { 1882199Sroot i = 0; 1892199Sroot cp = argv[0] + 2; 1902199Sroot while (*cp) 1912199Sroot i = i * 10 + (*cp++ - '0'); 1922199Sroot printf("'ps %d\n'vs %d\n", i, i+1); 1932199Sroot argc--, argv++; 1942199Sroot continue; 1952199Sroot } 1961841Sroot 1972199Sroot /* specify the language */ 1982199Sroot if (!strncmp(argv[0], "-l", 2)) { 1992199Sroot language = argv[0]+2; 2002199Sroot argc--, argv++; 2012199Sroot continue; 2022199Sroot } 2031841Sroot 2042199Sroot /* specify the language description file */ 2052199Sroot if (!strncmp(argv[0], "-d", 2)) { 206*56143Selan defsfile[0] = argv[1]; 2072199Sroot argc--, argv++; 2082199Sroot argc--, argv++; 2092199Sroot continue; 2102199Sroot } 2111862Sroot 2122199Sroot /* open the file for input */ 2132199Sroot if (freopen(argv[0], "r", stdin) == NULL) { 2142199Sroot perror(argv[0]); 2152199Sroot exit(1); 2162199Sroot } 217*56143Selan if (idx) 2182199Sroot printf("'ta 4i 4.25i 5.5iR\n'in .5i\n"); 2192199Sroot fname = argv[0]; 2202199Sroot argc--, argv++; 2212199Sroot } 2222199Sroot rest: 2231862Sroot 2242199Sroot /* 2252199Sroot * get the language definition from the defs file 2262199Sroot */ 227*56143Selan i = cgetent(&defs, defsfile, language); 228*56143Selan if (i == -1) { 2292199Sroot fprintf (stderr, "no entry for language %s\n", language); 2302199Sroot exit (0); 231*56143Selan } else if (i == -2) { fprintf(stderr, 232*56143Selan "cannot find vgrindefs file %s\n", defsfile[0]); 2332199Sroot exit (0); 234*56143Selan } else if (i == -3) { fprintf(stderr, 235*56143Selan "potential reference loop detected in vgrindefs file %s\n", 236*56143Selan defsfile[0]); 237*56143Selan exit(0); 2382199Sroot } 239*56143Selan if (cgetustr(defs, "kw", &cp) == -1) 2402199Sroot nokeyw = TRUE; 2412199Sroot else { 2422199Sroot char **cpp; 2431878Sroot 2442199Sroot cpp = l_keywds; 2452199Sroot while (*cp) { 2462199Sroot while (*cp == ' ' || *cp =='\t') 2472199Sroot *cp++ = NULL; 2482199Sroot if (*cp) 2492199Sroot *cpp++ = cp; 2502199Sroot while (*cp != ' ' && *cp != '\t' && *cp) 2512199Sroot cp++; 2522199Sroot } 2532199Sroot *cpp = NIL; 2542199Sroot } 255*56143Selan cgetustr(defs, "pb", &cp); 256*56143Selan l_prcbeg = convexp(cp); 257*56143Selan cgetustr(defs, "cb", &cp); 258*56143Selan l_combeg = convexp(cp); 259*56143Selan cgetustr(defs, "ce", &cp); 260*56143Selan l_comend = convexp(cp); 261*56143Selan cgetustr(defs, "ab", &cp); 262*56143Selan l_acmbeg = convexp(cp); 263*56143Selan cgetustr(defs, "ae", &cp); 264*56143Selan l_acmend = convexp(cp); 265*56143Selan cgetustr(defs, "sb", &cp); 266*56143Selan l_strbeg = convexp(cp); 267*56143Selan cgetustr(defs, "se", &cp); 268*56143Selan l_strend = convexp(cp); 269*56143Selan cgetustr(defs, "bb", &cp); 270*56143Selan l_blkbeg = convexp(cp); 271*56143Selan cgetustr(defs, "be", &cp); 272*56143Selan l_blkend = convexp(cp); 273*56143Selan cgetustr(defs, "lb", &cp); 274*56143Selan l_chrbeg = convexp(cp); 275*56143Selan cgetustr(defs, "le", &cp); 276*56143Selan l_chrend = convexp(cp); 2772199Sroot l_escape = '\\'; 278*56143Selan l_onecase = (cgetcap(defs, "oc", ':') != NULL); 279*56143Selan l_toplex = (cgetcap(defs, "tl", ':') != NULL); 2803882Spresott 2812199Sroot /* initialize the program */ 2821878Sroot 2832199Sroot incomm = FALSE; 2842199Sroot instr = FALSE; 2852199Sroot inchr = FALSE; 2862199Sroot _escaped = FALSE; 2872199Sroot blklevel = 0; 2882199Sroot for (psptr=0; psptr<PSMAX; psptr++) { 2892199Sroot pstack[psptr][0] = NULL; 2902199Sroot plstack[psptr] = 0; 2912199Sroot } 2922199Sroot psptr = -1; 2932199Sroot ps("'-F\n"); 2942199Sroot if (!filter) { 2952199Sroot printf(".ds =F %s\n", fname); 2963393Spresott ps("'wh 0 vH\n"); 2973393Spresott ps("'wh -1i vF\n"); 2982199Sroot } 2992199Sroot if (needbp) { 3002199Sroot needbp = 0; 3012199Sroot printf(".()\n"); 3022199Sroot printf(".bp\n"); 3032199Sroot } 30429570Sdonn if (!filter) { 30529570Sdonn fstat(fileno(stdin), &stbuf); 30629570Sdonn cp = ctime(&stbuf.st_mtime); 30729570Sdonn cp[16] = '\0'; 30829570Sdonn cp[24] = '\0'; 30929570Sdonn printf(".ds =M %s %s\n", cp+4, cp+20); 31029570Sdonn } 3111878Sroot 3122199Sroot /* 3132199Sroot * MAIN LOOP!!! 3142199Sroot */ 3152199Sroot while (fgets(buf, sizeof buf, stdin) != NULL) { 3162199Sroot if (buf[0] == '\f') { 3172199Sroot printf(".bp\n"); 3182199Sroot } 3192199Sroot if (buf[0] == '.') { 3202199Sroot printf("%s", buf); 3212199Sroot if (!strncmp (buf+1, "vS", 2)) 3222199Sroot pass = TRUE; 3232199Sroot if (!strncmp (buf+1, "vE", 2)) 3242199Sroot pass = FALSE; 3252199Sroot continue; 3262199Sroot } 3272199Sroot prccont = FALSE; 3282199Sroot if (!filter || pass) 3292199Sroot putScp(buf); 3302199Sroot else 3312199Sroot printf("%s", buf); 3322199Sroot if (prccont && (psptr >= 0)) { 3332199Sroot ps("'FC "); 3342199Sroot ps(pstack[psptr]); 3352199Sroot ps("\n"); 3362199Sroot } 3372199Sroot #ifdef DEBUG 3382199Sroot printf ("com %o str %o chr %o ptr %d\n", incomm, instr, inchr, psptr); 3392199Sroot #endif 3402199Sroot margin = 0; 3412199Sroot } 3422199Sroot needbp = 1; 3432199Sroot } while (argc > 0); 3442199Sroot exit(0); 3451841Sroot } 3461841Sroot 3471841Sroot #define isidchr(c) (isalnum(c) || (c) == '_') 3481841Sroot 349*56143Selan static void 3501841Sroot putScp(os) 3512199Sroot char *os; 3521841Sroot { 3532199Sroot register char *s = os; /* pointer to unmatched string */ 3542199Sroot char dummy[BUFSIZ]; /* dummy to be used by expmatch */ 3552199Sroot char *comptr; /* end of a comment delimiter */ 3563882Spresott char *acmptr; /* end of a comment delimiter */ 3572199Sroot char *strptr; /* end of a string delimiter */ 3582199Sroot char *chrptr; /* end of a character const delimiter */ 3592199Sroot char *blksptr; /* end of a lexical block start */ 3602199Sroot char *blkeptr; /* end of a lexical block end */ 3611841Sroot 3622199Sroot _start = os; /* remember the start for expmatch */ 3632199Sroot _escaped = FALSE; 3642199Sroot if (nokeyw || incomm || instr) 3652199Sroot goto skip; 3662199Sroot if (isproc(s)) { 3672199Sroot ps("'FN "); 3682199Sroot ps(pname); 3692293Sroot ps("\n"); 3702199Sroot if (psptr < PSMAX) { 3712199Sroot ++psptr; 3722199Sroot strncpy (pstack[psptr], pname, PNAMELEN); 3732199Sroot pstack[psptr][PNAMELEN] = NULL; 3742199Sroot plstack[psptr] = blklevel; 3752199Sroot } 3762199Sroot } 3771841Sroot skip: 3782199Sroot do { 3792199Sroot /* check for string, comment, blockstart, etc */ 3802199Sroot if (!incomm && !instr && !inchr) { 3812199Sroot 3822199Sroot blkeptr = expmatch (s, l_blkend, dummy); 3832199Sroot blksptr = expmatch (s, l_blkbeg, dummy); 3842199Sroot comptr = expmatch (s, l_combeg, dummy); 3853882Spresott acmptr = expmatch (s, l_acmbeg, dummy); 3862199Sroot strptr = expmatch (s, l_strbeg, dummy); 3872199Sroot chrptr = expmatch (s, l_chrbeg, dummy); 3882199Sroot 3892199Sroot /* start of a comment? */ 3902199Sroot if (comptr != NIL) 3912199Sroot if ((comptr < strptr || strptr == NIL) 3923882Spresott && (comptr < acmptr || acmptr == NIL) 3932199Sroot && (comptr < chrptr || chrptr == NIL) 3942199Sroot && (comptr < blksptr || blksptr == NIL) 3952199Sroot && (comptr < blkeptr || blkeptr == NIL)) { 3962199Sroot putKcp (s, comptr-1, FALSE); 3972199Sroot s = comptr; 3982199Sroot incomm = TRUE; 3993882Spresott comtype = STANDARD; 4002199Sroot if (s != os) 4012199Sroot ps ("\\c"); 4022199Sroot ps ("\\c\n'+C\n"); 4032199Sroot continue; 4041841Sroot } 4051878Sroot 4063882Spresott /* start of a comment? */ 4073882Spresott if (acmptr != NIL) 4083882Spresott if ((acmptr < strptr || strptr == NIL) 4093882Spresott && (acmptr < chrptr || chrptr == NIL) 4103882Spresott && (acmptr < blksptr || blksptr == NIL) 4113882Spresott && (acmptr < blkeptr || blkeptr == NIL)) { 4123882Spresott putKcp (s, acmptr-1, FALSE); 4133882Spresott s = acmptr; 4143882Spresott incomm = TRUE; 4153882Spresott comtype = ALTERNATE; 4163882Spresott if (s != os) 4173882Spresott ps ("\\c"); 4183882Spresott ps ("\\c\n'+C\n"); 4193882Spresott continue; 4203882Spresott } 4213882Spresott 4222199Sroot /* start of a string? */ 4232199Sroot if (strptr != NIL) 4242199Sroot if ((strptr < chrptr || chrptr == NIL) 4252212Sroot && (strptr < blksptr || blksptr == NIL) 4262212Sroot && (strptr < blkeptr || blkeptr == NIL)) { 4272199Sroot putKcp (s, strptr-1, FALSE); 4282199Sroot s = strptr; 4292199Sroot instr = TRUE; 4302199Sroot continue; 4312199Sroot } 4321878Sroot 4332199Sroot /* start of a character string? */ 4342199Sroot if (chrptr != NIL) 4352212Sroot if ((chrptr < blksptr || blksptr == NIL) 4362212Sroot && (chrptr < blkeptr || blkeptr == NIL)) { 4372199Sroot putKcp (s, chrptr-1, FALSE); 4382199Sroot s = chrptr; 4392199Sroot inchr = TRUE; 4402199Sroot continue; 4411841Sroot } 4421878Sroot 4432199Sroot /* end of a lexical block */ 4442199Sroot if (blkeptr != NIL) { 4452199Sroot if (blkeptr < blksptr || blksptr == NIL) { 4462199Sroot putKcp (s, blkeptr - 1, FALSE); 4472199Sroot s = blkeptr; 4482199Sroot blklevel--; 4492199Sroot if (psptr >= 0 && plstack[psptr] >= blklevel) { 4501878Sroot 4512199Sroot /* end of current procedure */ 4521841Sroot if (s != os) 4532199Sroot ps ("\\c"); 4542199Sroot ps ("\\c\n'-F\n"); 4552199Sroot blklevel = plstack[psptr]; 4561878Sroot 4572199Sroot /* see if we should print the last proc name */ 4582199Sroot if (--psptr >= 0) 4592199Sroot prccont = TRUE; 4602199Sroot else 4612199Sroot psptr = -1; 4622199Sroot } 4632199Sroot continue; 4641841Sroot } 4652199Sroot } 4661878Sroot 4672199Sroot /* start of a lexical block */ 4682199Sroot if (blksptr != NIL) { 4692199Sroot putKcp (s, blksptr - 1, FALSE); 4702199Sroot s = blksptr; 4712199Sroot blklevel++; 4722199Sroot continue; 4732199Sroot } 4742199Sroot 4752199Sroot /* check for end of comment */ 4762199Sroot } else if (incomm) { 4773882Spresott comptr = expmatch (s, l_comend, dummy); 4783882Spresott acmptr = expmatch (s, l_acmend, dummy); 4793882Spresott if (((comtype == STANDARD) && (comptr != NIL)) || 4803882Spresott ((comtype == ALTERNATE) && (acmptr != NIL))) { 4813882Spresott if (comtype == STANDARD) { 4823882Spresott putKcp (s, comptr-1, TRUE); 4833882Spresott s = comptr; 4843882Spresott } else { 4853882Spresott putKcp (s, acmptr-1, TRUE); 4863882Spresott s = acmptr; 4873882Spresott } 4882199Sroot incomm = FALSE; 4892199Sroot ps("\\c\n'-C\n"); 4902199Sroot continue; 4912199Sroot } else { 49217500Sralph putKcp (s, s + strlen(s) -1, TRUE); 4932199Sroot s = s + strlen(s); 4942199Sroot continue; 4952199Sroot } 4962199Sroot 4972199Sroot /* check for end of string */ 4982199Sroot } else if (instr) { 4992199Sroot if ((strptr = expmatch (s, l_strend, dummy)) != NIL) { 5002199Sroot putKcp (s, strptr-1, TRUE); 5012199Sroot s = strptr; 5022199Sroot instr = FALSE; 5032199Sroot continue; 5042199Sroot } else { 5052199Sroot putKcp (s, s+strlen(s)-1, TRUE); 5062199Sroot s = s + strlen(s); 5072199Sroot continue; 5082199Sroot } 5092199Sroot 5102199Sroot /* check for end of character string */ 5112199Sroot } else if (inchr) { 5122199Sroot if ((chrptr = expmatch (s, l_chrend, dummy)) != NIL) { 5132199Sroot putKcp (s, chrptr-1, TRUE); 5142199Sroot s = chrptr; 5152199Sroot inchr = FALSE; 5162199Sroot continue; 5172199Sroot } else { 5182199Sroot putKcp (s, s+strlen(s)-1, TRUE); 5192199Sroot s = s + strlen(s); 5202199Sroot continue; 5212199Sroot } 5221841Sroot } 5232199Sroot 5242199Sroot /* print out the line */ 5252199Sroot putKcp (s, s + strlen(s) -1, FALSE); 5262199Sroot s = s + strlen(s); 5272199Sroot } while (*s); 5281841Sroot } 5291841Sroot 530*56143Selan static void 5312199Sroot putKcp (start, end, force) 5322199Sroot char *start; /* start of string to write */ 5332199Sroot char *end; /* end of string to write */ 5342199Sroot boolean force; /* true if we should force nokeyw */ 5352199Sroot { 5362199Sroot int i; 5372320Sroot int xfld = 0; 5382199Sroot 5392199Sroot while (start <= end) { 540*56143Selan if (idx) { 5412320Sroot if (*start == ' ' || *start == '\t') { 5422320Sroot if (xfld == 0) 5432320Sroot printf(""); 5442320Sroot printf("\t"); 5452320Sroot xfld = 1; 5462320Sroot while (*start == ' ' || *start == '\t') 5472320Sroot start++; 5482320Sroot continue; 5492320Sroot } 5502320Sroot } 5512199Sroot 5522199Sroot /* take care of nice tab stops */ 5532199Sroot if (*start == '\t') { 5542199Sroot while (*start == '\t') 5552199Sroot start++; 5562199Sroot i = tabs(_start, start) - margin / 8; 5572199Sroot printf("\\h'|%dn'", i * 10 + 1 - margin % 8); 5582199Sroot continue; 5592199Sroot } 5602199Sroot 5612199Sroot if (!nokeyw && !force) 5622199Sroot if ((*start == '#' || isidchr(*start)) 5632199Sroot && (start == _start || !isidchr(start[-1]))) { 5642199Sroot i = iskw(start); 5652199Sroot if (i > 0) { 5662199Sroot ps("\\*(+K"); 5672199Sroot do 5682199Sroot putcp(*start++); 5692199Sroot while (--i > 0); 5702199Sroot ps("\\*(-K"); 5712199Sroot continue; 5722199Sroot } 5732199Sroot } 5742199Sroot 5752199Sroot putcp (*start++); 5762199Sroot } 5772199Sroot } 5782199Sroot 5792199Sroot 580*56143Selan static int 5811841Sroot tabs(s, os) 5822199Sroot char *s, *os; 5831841Sroot { 5841841Sroot 5852199Sroot return (width(s, os) / 8); 5861841Sroot } 5871841Sroot 588*56143Selan static int 5891841Sroot width(s, os) 5901841Sroot register char *s, *os; 5911841Sroot { 5921841Sroot register int i = 0; 5931841Sroot 5941841Sroot while (s < os) { 5951841Sroot if (*s == '\t') { 5961841Sroot i = (i + 8) &~ 7; 5971841Sroot s++; 5981841Sroot continue; 5991841Sroot } 6001841Sroot if (*s < ' ') 6011841Sroot i += 2; 6021841Sroot else 6031841Sroot i++; 6041841Sroot s++; 6051841Sroot } 6061841Sroot return (i); 6071841Sroot } 6081841Sroot 609*56143Selan static void 6101841Sroot putcp(c) 6111841Sroot register int c; 6121841Sroot { 6131841Sroot 6141841Sroot switch(c) { 6151841Sroot 6162199Sroot case 0: 6172199Sroot break; 6182199Sroot 6192199Sroot case '\f': 6202199Sroot break; 6212199Sroot 6221841Sroot case '{': 6231841Sroot ps("\\*(+K{\\*(-K"); 6241841Sroot break; 6251841Sroot 6261841Sroot case '}': 6271841Sroot ps("\\*(+K}\\*(-K"); 6281841Sroot break; 6291841Sroot 6301841Sroot case '\\': 6311841Sroot ps("\\e"); 6321841Sroot break; 6331841Sroot 6341841Sroot case '_': 6351841Sroot ps("\\*_"); 6361841Sroot break; 6371841Sroot 6381841Sroot case '-': 6391841Sroot ps("\\*-"); 6401841Sroot break; 6411841Sroot 6421841Sroot case '`': 6431841Sroot ps("\\`"); 6441841Sroot break; 6451841Sroot 6461841Sroot case '\'': 6471841Sroot ps("\\'"); 6481841Sroot break; 6491841Sroot 6501841Sroot case '.': 6511841Sroot ps("\\&."); 6521841Sroot break; 6531841Sroot 6542418Sroot case '*': 6552418Sroot ps("\\fI*\\fP"); 6562418Sroot break; 6572418Sroot 6582199Sroot case '/': 6592418Sroot ps("\\fI\\h'\\w' 'u-\\w'/'u'/\\fP"); 6602199Sroot break; 6612199Sroot 6621841Sroot default: 6631841Sroot if (c < 040) 6641841Sroot putchar('^'), c |= '@'; 6651841Sroot case '\t': 6661841Sroot case '\n': 6671841Sroot putchar(c); 6681841Sroot } 6691841Sroot } 6701841Sroot 6712199Sroot /* 6722199Sroot * look for a process beginning on this line 6731878Sroot */ 674*56143Selan static boolean 6752199Sroot isproc(s) 6762199Sroot char *s; 6771878Sroot { 6782199Sroot pname[0] = NULL; 6792199Sroot if (!l_toplex || blklevel == 0) 6802199Sroot if (expmatch (s, l_prcbeg, pname) != NIL) { 6812199Sroot return (TRUE); 6822199Sroot } 6832199Sroot return (FALSE); 6841878Sroot } 6851878Sroot 6862199Sroot 6871878Sroot /* iskw - check to see if the next word is a keyword 6881878Sroot */ 6891878Sroot 690*56143Selan static int 6911841Sroot iskw(s) 6921841Sroot register char *s; 6931841Sroot { 6942199Sroot register char **ss = l_keywds; 6951841Sroot register int i = 1; 6961841Sroot register char *cp = s; 6971841Sroot 6981841Sroot while (++cp, isidchr(*cp)) 6991841Sroot i++; 7001841Sroot while (cp = *ss++) 7012199Sroot if (!STRNCMP(s,cp,i) && !isidchr(cp[i])) 7021841Sroot return (i); 7031841Sroot return (0); 7041841Sroot } 705*56143Selan 706