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