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