Annotation of researchv9/X11/src/X.V11R1/util/imake/imake.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.