|
|
1.1 ! root 1: /* ! 2: * ! 3: * Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology ! 4: * ! 5: * Permission to use, copy, modify, and distribute this ! 6: * software and its documentation for any purpose and without ! 7: * fee is hereby granted, provided that the above copyright ! 8: * notice appear in all copies and that both that copyright ! 9: * notice and this permission notice appear in supporting ! 10: * documentation, and that the name of M.I.T. not be used in ! 11: * advertising or publicity pertaining to distribution of the ! 12: * software without specific, written prior permission. ! 13: * M.I.T. makes no representations about the suitability of ! 14: * this software for any purpose. It is provided "as is" ! 15: * without express or implied warranty. ! 16: * ! 17: * $Header: imake.c,v 1.20 87/09/14 00:00:47 toddb Exp $ ! 18: * $Locker: $ ! 19: * ! 20: * Author: ! 21: * Todd Brunhoff ! 22: * Tektronix, inc. ! 23: * While a guest engineer at Project Athena, MIT ! 24: * ! 25: * imake: the include-make program. ! 26: * ! 27: * Usage: imake [-Idir] [-Ddefine] [-T] [-f imakefile ] [-s] [-v] [make flags] ! 28: * ! 29: * Imake takes a template makefile (Imake.template) and runs cpp on it ! 30: * producing a temporary makefile in /usr/tmp. It then runs make on ! 31: * this pre-processed makefile. ! 32: * Options: ! 33: * -D define. Same as cpp -D argument. ! 34: * -I Include directory. Same as cpp -I argument. ! 35: * -T template. Designate a template other ! 36: * than Imake.template ! 37: * -s show. Show the produced makefile on the standard ! 38: * output. Make is not run is this case. If a file ! 39: * argument is provided, the output is placed there. ! 40: * -v verbose. Show the make command line executed. ! 41: * ! 42: * Environment variables: ! 43: * ! 44: * IMAKEINCLUDE Include directory to use in addition to ! 45: * "." and "/usr/lib/local/imake.include". ! 46: * IMAKECPP Cpp to use instead of /lib/cpp ! 47: * IMAKEMAKE make program to use other than what is ! 48: * found by searching the $PATH variable. ! 49: * Other features: ! 50: * imake reads the entire cpp output into memory and then scans it ! 51: * for occurences of "@@". If it encounters them, it replaces it with ! 52: * a newline. It also trims any trailing white space on output lines ! 53: * (because make gets upset at them). This helps when cpp expands ! 54: * multi-line macros but you want them to appear on multiple lines. ! 55: * ! 56: * The macros MAKEFILE and MAKE are provided as macros ! 57: * to make. MAKEFILE is set to imake's makefile (not the constructed, ! 58: * preprocessed one) and MAKE is set to argv[0], i.e. the name of ! 59: * the imake program. ! 60: * ! 61: * Theory of operation: ! 62: * 1. Determine the name of the imakefile from the command line (-f) ! 63: * or from the content of the current directory (Imakefile or imakefile). ! 64: * Call this <imakefile>. This gets added to the arguments for ! 65: * make as MAKEFILE=<imakefile>. ! 66: * 2. Determine the name of the template from the command line (-T) ! 67: * or the default, Imake.template. Call this <template> ! 68: * 3. Start up cpp an provide it with three lines of input: ! 69: * #define IMAKE_TEMPLATE "<template>" ! 70: * #define INCLUDE_IMAKEFILE "<imakefile>" ! 71: * #include IMAKE_TEMPLATE ! 72: * Note that the define for INCLUDE_IMAKEFILE is intended for ! 73: * use in the template file. This implies that the imake is ! 74: * useless unless the template file contains at least the line ! 75: * #include INCLUDE_IMAKEFILE ! 76: * 4. Gather the output from cpp, and clean it up, expanding @@ to ! 77: * newlines, stripping trailing white space, cpp control lines, ! 78: * and extra blank lines. This cleaned output is placed in a ! 79: * temporary file. Call this <makefile>. ! 80: * 5. Start up make specifying <makefile> as its input. ! 81: * ! 82: * The design of the template makefile should therefore be: ! 83: * <set global macros like CFLAGS, etc.> ! 84: * <include machine dependent additions> ! 85: * #include INCLUDE_IMAKEFILE ! 86: * <add any global targets like 'clean' and long dependencies> ! 87: */ ! 88: #include <stdio.h> ! 89: #include <ctype.h> ! 90: #include <sys/types.h> ! 91: #include <sys/file.h> ! 92: #include <sys/wait.h> ! 93: #include <sys/signal.h> ! 94: #include <sys/stat.h> ! 95: ! 96: #define TRUE 1 ! 97: #define FALSE 0 ! 98: #define ARGUMENTS 50 ! 99: ! 100: #ifdef sun ! 101: #define REDUCED_TO_ASCII_SPACE ! 102: int InRule = FALSE; ! 103: #endif ! 104: ! 105: /* ! 106: * Some versions of cpp reduce all tabs in macro expansion to a single ! 107: * space. In addition, the escaped newline may be replaced with a ! 108: * space instead of being deleted. Blech. ! 109: */ ! 110: #ifndef REDUCED_TO_ASCII_SPACE ! 111: #define KludgeOutputLine(arg) ! 112: #define KludgeResetRule() ! 113: #endif ! 114: ! 115: typedef u_char boolean; ! 116: ! 117: #ifndef apollo ! 118: char *cpp = "/lib/cpp"; ! 119: #else apollo ! 120: char *cpp = "/usr/lib/cpp"; ! 121: #endif apollo ! 122: ! 123: char *tmpMakefile = "/usr/tmp/tmp-make.XXXXXX"; ! 124: char *tmpImakefile = "/usr/tmp/tmp-imake.XXXXXX"; ! 125: char *make_argv[ ARGUMENTS ] = { "make" }; ! 126: char *cpp_argv[ ARGUMENTS ] = { ! 127: "cpp", ! 128: "-I.", ! 129: #ifdef unix ! 130: "-Uunix", ! 131: #endif unix ! 132: }; ! 133: int make_argindex = 1; ! 134: int cpp_argindex = 3; ! 135: char *make = NULL; ! 136: char *Imakefile = NULL; ! 137: char *Makefile = NULL; ! 138: char *Template = "Imake.template"; ! 139: char *program; ! 140: char *FindImakefile(); ! 141: char *ReadLine(); ! 142: char *CleanCppInput(); ! 143: boolean verbose = FALSE; ! 144: boolean show = FALSE; ! 145: extern int errno; ! 146: extern char *Emalloc(); ! 147: extern char *realloc(); ! 148: extern char *getenv(); ! 149: extern char *mktemp(); ! 150: ! 151: main(argc, argv) ! 152: int argc; ! 153: char **argv; ! 154: { ! 155: FILE *tmpfd; ! 156: char makeMacro[ BUFSIZ ]; ! 157: char makefileMacro[ BUFSIZ ]; ! 158: ! 159: init(); ! 160: SetOpts(argc, argv); ! 161: ! 162: AddCppArg("-I/usr/lib/local/imake.includes"); ! 163: ! 164: Imakefile = FindImakefile(Imakefile); ! 165: if (Makefile) ! 166: tmpMakefile = Makefile; ! 167: else ! 168: tmpMakefile = mktemp(tmpMakefile); ! 169: AddMakeArg("-f"); ! 170: AddMakeArg( tmpMakefile ); ! 171: sprintf(makeMacro, "MAKE=%s", program); ! 172: AddMakeArg( makeMacro ); ! 173: sprintf(makefileMacro, "MAKEFILE=%s", Imakefile); ! 174: AddMakeArg( makefileMacro ); ! 175: ! 176: if ((tmpfd = fopen(tmpMakefile, "w+")) == NULL) ! 177: LogFatal("Cannot create temporary file %s.", tmpMakefile); ! 178: ! 179: cppit(Imakefile, Template, tmpfd); ! 180: ! 181: if (show) { ! 182: if (Makefile == NULL) ! 183: showit(tmpfd); ! 184: } else ! 185: makeit(); ! 186: wrapup(); ! 187: exit(0); ! 188: } ! 189: ! 190: showit(fd) ! 191: FILE *fd; ! 192: { ! 193: char buf[ BUFSIZ ]; ! 194: int red; ! 195: ! 196: fseek(fd, 0, 0); ! 197: while ((red = fread(buf, 1, BUFSIZ, fd)) > 0) ! 198: fwrite(buf, red, 1, stdout); ! 199: if (red < 0) ! 200: LogFatal("Cannot write stdout."); ! 201: } ! 202: ! 203: wrapup() ! 204: { ! 205: if (tmpMakefile != Makefile) ! 206: unlink(tmpMakefile); ! 207: unlink(tmpImakefile); ! 208: } ! 209: ! 210: catch(sig) ! 211: int sig; ! 212: { ! 213: errno = 0; ! 214: LogFatal("Signal %d.", sig); ! 215: } ! 216: ! 217: /* ! 218: * Initialize some variables. ! 219: */ ! 220: init() ! 221: { ! 222: char *p; ! 223: ! 224: /* ! 225: * See if the standard include directory is different than ! 226: * the default. Or if cpp is not the default. Or if the make ! 227: * found by the PATH variable is not the default. ! 228: */ ! 229: if (p = getenv("IMAKEINCLUDE")) { ! 230: if (*p != '-' || *(p+1) != 'I') ! 231: LogFatal("Environment var IMAKEINCLUDE %s\n", ! 232: "must begin with -I"); ! 233: AddCppArg(p); ! 234: for (; *p; p++) ! 235: if (*p == ' ') { ! 236: *p++ = '\0'; ! 237: AddCppArg(p); ! 238: } ! 239: } ! 240: if (p = getenv("IMAKECPP")) ! 241: cpp = p; ! 242: if (p = getenv("IMAKEMAKE")) ! 243: make = p; ! 244: ! 245: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 246: signal(SIGINT, catch); ! 247: } ! 248: ! 249: AddMakeArg(arg) ! 250: char *arg; ! 251: { ! 252: errno = 0; ! 253: if (make_argindex >= ARGUMENTS-1) ! 254: LogFatal("Out of internal storage."); ! 255: make_argv[ make_argindex++ ] = arg; ! 256: make_argv[ make_argindex ] = NULL; ! 257: } ! 258: ! 259: AddCppArg(arg) ! 260: char *arg; ! 261: { ! 262: errno = 0; ! 263: if (cpp_argindex >= ARGUMENTS-1) ! 264: LogFatal("Out of internal storage."); ! 265: cpp_argv[ cpp_argindex++ ] = arg; ! 266: cpp_argv[ cpp_argindex ] = NULL; ! 267: } ! 268: ! 269: SetOpts(argc, argv) ! 270: int argc; ! 271: char **argv; ! 272: { ! 273: errno = 0; ! 274: /* ! 275: * Now gather the arguments for make ! 276: */ ! 277: program = argv[0]; ! 278: for(argc--, argv++; argc; argc--, argv++) { ! 279: /* ! 280: * We intercept these flags. ! 281: */ ! 282: if (argv[0][0] == '-') { ! 283: if (argv[0][1] == 'D') { ! 284: AddCppArg(argv[0]); ! 285: } else if (argv[0][1] == 'I') { ! 286: AddCppArg(argv[0]); ! 287: } else if (argv[0][1] == 'f') { ! 288: if (argv[0][2]) ! 289: Imakefile = argv[0]+2; ! 290: else { ! 291: argc--, argv++; ! 292: if (! argc) ! 293: LogFatal("No description arg after -f flag\n"); ! 294: Imakefile = argv[0]; ! 295: } ! 296: } else if (argv[0][1] == 's') { ! 297: if (argv[0][2]) ! 298: Makefile = argv[0]+2; ! 299: else if (argc > 1 && argv[1][0] != '-') { ! 300: argc--, argv++; ! 301: Makefile = argv[0]; ! 302: } ! 303: show = TRUE; ! 304: } else if (argv[0][1] == 'T') { ! 305: if (argv[0][2]) ! 306: Template = argv[0]+2; ! 307: else { ! 308: argc--, argv++; ! 309: if (! argc) ! 310: LogFatal("No description arg after -T flag\n"); ! 311: Template = argv[0]; ! 312: } ! 313: } else if (argv[0][1] == 'v') { ! 314: verbose = TRUE; ! 315: } else ! 316: AddMakeArg(argv[0]); ! 317: } else ! 318: AddMakeArg(argv[0]); ! 319: } ! 320: } ! 321: ! 322: char *FindImakefile(Imakefile) ! 323: char *Imakefile; ! 324: { ! 325: int fd; ! 326: ! 327: if (Imakefile) { ! 328: if ((fd = open(Imakefile, O_RDONLY)) < 0) ! 329: LogFatal("Cannot open %s.", Imakefile); ! 330: } else { ! 331: if ((fd = open("Imakefile", O_RDONLY)) < 0) ! 332: if ((fd = open("imakefile", O_RDONLY)) < 0) ! 333: LogFatal("No description file."); ! 334: else ! 335: Imakefile = "imakefile"; ! 336: else ! 337: Imakefile = "Imakefile"; ! 338: } ! 339: close (fd); ! 340: return(Imakefile); ! 341: } ! 342: ! 343: LogFatal(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9) ! 344: { ! 345: extern char *sys_errlist[]; ! 346: static boolean entered = FALSE; ! 347: ! 348: if (entered) ! 349: return; ! 350: entered = TRUE; ! 351: ! 352: fprintf(stderr, "%s: ", program); ! 353: if (errno) ! 354: fprintf(stderr, "%s: ", sys_errlist[ errno ]); ! 355: fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9); ! 356: fprintf(stderr, " Stop.\n"); ! 357: wrapup(); ! 358: exit(1); ! 359: } ! 360: ! 361: showargs(argv) ! 362: char **argv; ! 363: { ! 364: for (; *argv; argv++) ! 365: fprintf(stderr, "%s ", *argv); ! 366: fprintf(stderr, "\n"); ! 367: } ! 368: ! 369: cppit(Imakefile, template, outfd) ! 370: char *Imakefile; ! 371: char *template; ! 372: FILE *outfd; ! 373: { ! 374: FILE *pipeFile; ! 375: int pid, pipefd[2]; ! 376: union wait status; ! 377: char *cleanedImakefile; ! 378: ! 379: /* ! 380: * Get a pipe. ! 381: */ ! 382: if (pipe(pipefd) < 0) ! 383: LogFatal("Cannot make a pipe."); ! 384: ! 385: /* ! 386: * Fork and exec cpp ! 387: */ ! 388: pid = vfork(); ! 389: if (pid < 0) ! 390: LogFatal("Cannot fork."); ! 391: if (pid) { /* parent */ ! 392: close(pipefd[0]); ! 393: cleanedImakefile = CleanCppInput(Imakefile); ! 394: if ((pipeFile = fdopen(pipefd[1], "w")) == NULL) ! 395: LogFatal("Cannot fdopen fd %d for output.", outfd); ! 396: fprintf(pipeFile, "#define IMAKE_TEMPLATE\t\"%s\"\n", ! 397: template); ! 398: fprintf(pipeFile, "#define INCLUDE_IMAKEFILE\t\"%s\"\n", ! 399: cleanedImakefile); ! 400: fprintf(pipeFile, "#include IMAKE_TEMPLATE\n"); ! 401: fclose(pipeFile); ! 402: while (wait(&status) > 0) { ! 403: errno = 0; ! 404: if (status.w_termsig) ! 405: LogFatal("Signal %d.", status.w_termsig); ! 406: if (status.w_retcode) ! 407: LogFatal("Exit code %d.", status.w_retcode); ! 408: } ! 409: CleanCppOutput(outfd); ! 410: } else { /* child... dup and exec cpp */ ! 411: if (verbose) ! 412: showargs(cpp_argv); ! 413: dup2(pipefd[0], 0); ! 414: dup2(fileno(outfd), 1); ! 415: close(pipefd[1]); ! 416: execv(cpp, cpp_argv); ! 417: LogFatal("Cannot exec %s.", cpp); ! 418: } ! 419: } ! 420: ! 421: makeit() ! 422: { ! 423: int pid; ! 424: union wait status; ! 425: ! 426: /* ! 427: * Fork and exec make ! 428: */ ! 429: pid = vfork(); ! 430: if (pid < 0) ! 431: LogFatal("Cannot fork."); ! 432: if (pid) { /* parent... simply wait */ ! 433: while (wait(&status) > 0) { ! 434: errno = 0; ! 435: if (status.w_termsig) ! 436: LogFatal("Signal %d.", status.w_termsig); ! 437: if (status.w_retcode) ! 438: LogFatal("Exit code %d.", status.w_retcode); ! 439: } ! 440: } else { /* child... dup and exec cpp */ ! 441: if (verbose) ! 442: showargs(make_argv); ! 443: if (make) ! 444: execv(make, make_argv); ! 445: else ! 446: execvp("make", make_argv); ! 447: LogFatal("Cannot exec %s.", cpp); ! 448: } ! 449: } ! 450: ! 451: char *CleanCppInput(Imakefile) ! 452: char *Imakefile; ! 453: { ! 454: FILE *outFile = NULL; ! 455: int infd, got; ! 456: char *buf, /* buffer for file content */ ! 457: *pbuf, /* walking pointer to buf */ ! 458: *punwritten, /* pointer to unwritten portion of buf */ ! 459: *cleanedImakefile = Imakefile, /* return value */ ! 460: *ptoken, /* pointer to # token */ ! 461: *pend, /* pointer to end of # token */ ! 462: savec; /* temporary character holder */ ! 463: struct stat st; ! 464: ! 465: /* ! 466: * grab the entire file. ! 467: */ ! 468: if ((infd = open(Imakefile, O_RDONLY)) < 0) ! 469: LogFatal("Cannot open %s for input.", Imakefile); ! 470: fstat(infd, &st); ! 471: buf = Emalloc(st.st_size+1); ! 472: if ((got = read(infd, buf, st.st_size)) != st.st_size) ! 473: LogFatal("Cannot read all of %s: want %d, got %d\n", ! 474: Imakefile, st.st_size, got); ! 475: close(infd); ! 476: buf[ st.st_size ] = '\0'; ! 477: ! 478: punwritten = pbuf = buf; ! 479: while (*pbuf) { ! 480: /* pad make comments for cpp */ ! 481: if (*pbuf == '#' && (pbuf == buf || pbuf[-1] == '\n')) { ! 482: ! 483: ptoken = pbuf+1; ! 484: while (*ptoken == ' ' || *ptoken == '\t') ! 485: ptoken++; ! 486: pend = ptoken; ! 487: while (*pend && *pend != ' ' && *pend != '\t' && *pend != '\n') ! 488: pend++; ! 489: savec = *pend; ! 490: *pend = '\0'; ! 491: if (strcmp(ptoken, "include") ! 492: && strcmp(ptoken, "define") ! 493: && strcmp(ptoken, "undef") ! 494: && strcmp(ptoken, "ifdef") ! 495: && strcmp(ptoken, "ifndef") ! 496: && strcmp(ptoken, "else") ! 497: && strcmp(ptoken, "endif") ! 498: && strcmp(ptoken, "if")) { ! 499: if (outFile == NULL) { ! 500: tmpImakefile = mktemp(tmpImakefile); ! 501: cleanedImakefile = tmpImakefile; ! 502: outFile = fopen(tmpImakefile, "w"); ! 503: if (outFile == NULL) ! 504: LogFatal("Cannot open %s for write.\n", ! 505: tmpImakefile); ! 506: } ! 507: fwrite(punwritten, sizeof(char), pbuf-punwritten, outFile); ! 508: fputs("/**/", outFile); ! 509: punwritten = pbuf; ! 510: } ! 511: *pend = savec; ! 512: } ! 513: pbuf++; ! 514: } ! 515: if (outFile) { ! 516: fwrite(punwritten, sizeof(char), pbuf-punwritten, outFile); ! 517: fclose(outFile); /* also closes the pipe */ ! 518: } ! 519: ! 520: return(cleanedImakefile); ! 521: } ! 522: ! 523: CleanCppOutput(tmpfd) ! 524: FILE *tmpfd; ! 525: { ! 526: char *input; ! 527: int blankline = 0; ! 528: ! 529: while(input = ReadLine(tmpfd)) { ! 530: if (isempty(input)) { ! 531: if (blankline++) ! 532: continue; ! 533: KludgeResetRule(); ! 534: } else { ! 535: blankline = 0; ! 536: KludgeOutputLine(&input); ! 537: fputs(input, tmpfd); ! 538: } ! 539: putc('\n', tmpfd); ! 540: } ! 541: fflush(tmpfd); ! 542: } ! 543: ! 544: /* ! 545: * Determine of a line has nothing in it. As a side effect, we trim white ! 546: * space from the end of the line. Cpp magic cookies are also thrown away. ! 547: */ ! 548: isempty(line) ! 549: char *line; ! 550: { ! 551: char *pend; ! 552: ! 553: /* ! 554: * Check for lines of the form ! 555: * # n "... ! 556: * or ! 557: * # line n "... ! 558: */ ! 559: if (*line == '#') { ! 560: pend = line+1; ! 561: if (*pend == ' ') ! 562: pend++; ! 563: if (strncmp(pend, "line ", 5) == 0) ! 564: pend += 5; ! 565: if (isdigit(*pend)) { ! 566: while (isdigit(*pend)) ! 567: pend++; ! 568: if (*pend++ == ' ' && *pend == '"') ! 569: return(TRUE); ! 570: } ! 571: } ! 572: ! 573: /* ! 574: * Find the end of the line and then walk back. ! 575: */ ! 576: for (pend=line; *pend; pend++) ; ! 577: ! 578: pend--; ! 579: while (pend >= line && (*pend == ' ' || *pend == '\t')) ! 580: pend--; ! 581: *++pend = '\0'; ! 582: return (*line == '\0'); ! 583: } ! 584: ! 585: char *ReadLine(tmpfd) ! 586: FILE *tmpfd; ! 587: { ! 588: static boolean initialized = FALSE; ! 589: static char *buf, *pline, *end; ! 590: char *p1, *p2; ! 591: ! 592: if (! initialized) { ! 593: int total_red; ! 594: struct stat st; ! 595: ! 596: /* ! 597: * Slurp it all up. ! 598: */ ! 599: fseek(tmpfd, 0, 0); ! 600: fstat(fileno(tmpfd), &st); ! 601: pline = buf = Emalloc(st.st_size+1); ! 602: total_red = read(fileno(tmpfd), buf, st.st_size); ! 603: if (total_red != st.st_size) ! 604: LogFatal("cannot read %s\n", tmpMakefile); ! 605: end = buf + st.st_size; ! 606: *end = '\0'; ! 607: lseek(fileno(tmpfd), 0, 0); ! 608: ftruncate(fileno(tmpfd), 0); ! 609: initialized = TRUE; ! 610: #ifdef REDUCED_TO_ASCII_SPACE ! 611: fprintf(tmpfd, "#\n"); ! 612: fprintf(tmpfd, "# Warning: the cpp used on this machine replaces\n"); ! 613: fprintf(tmpfd, "# all newlines and multiple tabs/spaces in a macro\n"); ! 614: fprintf(tmpfd, "# expansion with a single space. Imake tries to\n"); ! 615: fprintf(tmpfd, "# compensate for this, but is not always\n"); ! 616: fprintf(tmpfd, "# successful.\n"); ! 617: fprintf(tmpfd, "#\n"); ! 618: #endif REDUCED_TO_ASCII_SPACE ! 619: } ! 620: ! 621: for (p1 = pline; p1 < end; p1++) { ! 622: if (*p1 == '@' && *(p1+1) == '@') { /* soft EOL */ ! 623: *p1++ = '\0'; ! 624: p1++; /* skip over second @ */ ! 625: break; ! 626: } ! 627: else if (*p1 == '\n') { /* real EOL */ ! 628: *p1++ = '\0'; ! 629: break; ! 630: } ! 631: } ! 632: ! 633: /* ! 634: * return NULL at the end of the file. ! 635: */ ! 636: p2 = (pline == p1 ? NULL : pline); ! 637: pline = p1; ! 638: return(p2); ! 639: } ! 640: ! 641: writetmpfile(fd, buf, cnt) ! 642: FILE *fd; ! 643: int cnt; ! 644: char *buf; ! 645: { ! 646: errno = 0; ! 647: if (fwrite(buf, cnt, 1, fd) != 1) ! 648: LogFatal("Cannot write to %s.", tmpMakefile); ! 649: } ! 650: ! 651: char *Emalloc(size) ! 652: int size; ! 653: { ! 654: char *p, *malloc(); ! 655: ! 656: if ((p = malloc(size)) == NULL) ! 657: LogFatal("Cannot allocate %d bytes\n", size); ! 658: return(p); ! 659: } ! 660: ! 661: #ifdef REDUCED_TO_ASCII_SPACE ! 662: KludgeOutputLine(pline) ! 663: char **pline; ! 664: { ! 665: char *p = *pline; ! 666: ! 667: switch (*p) { ! 668: case '#': /*Comment - ignore*/ ! 669: break; ! 670: case '\t': /*Already tabbed - ignore it*/ ! 671: break; ! 672: case ' ': /*May need a tab*/ ! 673: default: ! 674: while (*p) if (*p++ == ':') { ! 675: if (**pline == ' ') ! 676: (*pline)++; ! 677: InRule = TRUE; ! 678: break; ! 679: } ! 680: if (InRule && **pline == ' ') ! 681: **pline = '\t'; ! 682: break; ! 683: } ! 684: } ! 685: ! 686: KludgeResetRule() ! 687: { ! 688: InRule = FALSE; ! 689: } ! 690: #endif REDUCED_TO_ASCII_SPACE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.