source: trunk/third/motif/config/imake.c @ 12415

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