Annotation of researchv9/X11/src/X.V11R1/util/imake/imake.c, revision 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.