]> andersk Git - moira.git/blob - util/imake/imake.c
new version
[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
272 AddMakeArg(arg)
273         char    *arg;
274 {
275         errno = 0;
276         if (make_argindex >= ARGUMENTS-1)
277                 LogFatal("Out of internal storage.", "");
278         make_argv[ make_argindex++ ] = arg;
279         make_argv[ make_argindex ] = NULL;
280 }
281
282 AddCppArg(arg)
283         char    *arg;
284 {
285         errno = 0;
286         if (cpp_argindex >= ARGUMENTS-1)
287                 LogFatal("Out of internal storage.", "");
288         cpp_argv[ cpp_argindex++ ] = arg;
289         cpp_argv[ cpp_argindex ] = NULL;
290 }
291
292 SetOpts(argc, argv)
293         int     argc;
294         char    **argv;
295 {
296         errno = 0;
297         /*
298          * Now gather the arguments for make
299          */
300         program = argv[0];
301         for(argc--, argv++; argc; argc--, argv++) {
302             /*
303              * We intercept these flags.
304              */
305             if (argv[0][0] == '-') {
306                 if (argv[0][1] == 'D') {
307                     AddCppArg(argv[0]);
308                 } else if (argv[0][1] == 'I') {
309                     AddCppArg(argv[0]);
310                 } else if (argv[0][1] == 'f') {
311                     if (argv[0][2])
312                         Imakefile = argv[0]+2;
313                     else {
314                         argc--, argv++;
315                         if (! argc)
316                             LogFatal("No description arg after -f flag\n", "");
317                         Imakefile = argv[0];
318                     }
319                 } else if (argv[0][1] == 's') {
320                     if (argv[0][2])
321                         Makefile = (argv[0][2] == '-') ? NULL : argv[0]+2;
322                     else if (argc > 1 && argv[1][0] != '-') {
323                         argc--, argv++;
324                         Makefile = argv[0];
325                     }
326                     show = TRUE;
327                 } else if (argv[0][1] == 'e') {
328                    Makefile = (argv[0][2] ? argv[0]+2 : NULL);
329                    show = FALSE;
330                 } else if (argv[0][1] == 'T') {
331                     if (argv[0][2])
332                         Template = argv[0]+2;
333                     else {
334                         argc--, argv++;
335                         if (! argc)
336                             LogFatal("No description arg after -T flag\n", "");
337                         Template = argv[0];
338                     }
339                 } else if (argv[0][1] == 'v') {
340                     verbose = TRUE;
341                 } else
342                     AddMakeArg(argv[0]);
343             } else
344                 AddMakeArg(argv[0]);
345         }
346 }
347
348 char *FindImakefile(Imakefile)
349         char    *Imakefile;
350 {
351         int     fd;
352
353         if (Imakefile) {
354                 if ((fd = open(Imakefile, O_RDONLY)) < 0)
355                         LogFatal("Cannot open %s.", Imakefile);
356         } else {
357                 if ((fd = open("Imakefile", O_RDONLY)) < 0)
358                         if ((fd = open("imakefile", O_RDONLY)) < 0)
359                                 LogFatal("No description file.", "");
360                         else
361                                 Imakefile = "imakefile";
362                 else
363                         Imakefile = "Imakefile";
364         }
365         close (fd);
366         return(Imakefile);
367 }
368
369 LogFatalI(s, i)
370         char *s;
371         int i;
372 {
373         /*NOSTRICT*/
374         LogFatal(s, (char *)i);
375 }
376
377 LogFatal(x0,x1)
378         char *x0, *x1;
379 {
380         extern char     *sys_errlist[];
381         static boolean  entered = FALSE;
382
383         if (entered)
384                 return;
385         entered = TRUE;
386
387         fprintf(stderr, "%s: ", program);
388         if (errno)
389                 fprintf(stderr, "%s: ", sys_errlist[ errno ]);
390         fprintf(stderr, x0,x1);
391         fprintf(stderr, "  Stop.\n");
392         wrapup();
393         exit(1);
394 }
395
396 showargs(argv)
397         char    **argv;
398 {
399         for (; *argv; argv++)
400                 fprintf(stderr, "%s ", *argv);
401         fprintf(stderr, "\n");
402 }
403
404 cppit(Imakefile, template, outfd, outfname)
405         char    *Imakefile;
406         char    *template;
407         FILE    *outfd;
408         char    *outfname;
409 {
410         FILE    *pipeFile;
411         int     pid, pipefd[2];
412 #ifdef SYSV
413         int     status;
414 #else   /* !SYSV */
415         union wait      status;
416 #endif  /* !SYSV */
417         char    *cleanedImakefile;
418
419         /*
420          * Get a pipe.
421          */
422         if (pipe(pipefd) < 0)
423                 LogFatal("Cannot make a pipe.", "");
424
425         /*
426          * Fork and exec cpp
427          */
428         pid = fork();
429         if (pid < 0)
430                 LogFatal("Cannot fork.", "");
431         if (pid) {      /* parent */
432                 close(pipefd[0]);
433                 cleanedImakefile = CleanCppInput(Imakefile);
434                 if ((pipeFile = fdopen(pipefd[1], "w")) == NULL)
435                         LogFatalI("Cannot fdopen fd %d for output.", pipefd[1]);
436                 fprintf(pipeFile, "#define IMAKE_TEMPLATE\t\"%s\"\n",
437                         template);
438                 fprintf(pipeFile, "#define INCLUDE_IMAKEFILE\t<%s>\n",
439                         cleanedImakefile);
440                 fprintf(pipeFile, "#include IMAKE_TEMPLATE\n");
441                 fclose(pipeFile);
442                 while (wait(&status) > 0) {
443                         errno = 0;
444 #ifdef SYSV
445                         if ((status >> 8) & 0xff)
446                                 LogFatalI("Signal %d.", (status >> 8) & 0xff);
447                         if (status & 0xff)
448                                 LogFatalI("Exit code %d.", status & 0xff);
449 #else   /* !SYSV */
450                         if (status.w_termsig)
451                                 LogFatalI("Signal %d.", status.w_termsig);
452                         if (status.w_retcode)
453                                 LogFatalI("Exit code %d.", status.w_retcode);
454 #endif  /* !SYSV */
455                 }
456                 CleanCppOutput(outfd, outfname);
457         } else {        /* child... dup and exec cpp */
458                 if (verbose)
459                         showargs(cpp_argv);
460                 dup2(pipefd[0], 0);
461                 dup2(fileno(outfd), 1);
462                 close(pipefd[1]);
463                 execv(cpp, cpp_argv);
464                 LogFatal("Cannot exec %s.", cpp);
465         }
466 }
467
468 makeit()
469 {
470         int     pid;
471 #ifdef SYSV
472         int     status;
473 #else   /* !SYSV */
474         union wait      status;
475 #endif  /* !SYSV */
476
477         /*
478          * Fork and exec make
479          */
480         pid = fork();
481         if (pid < 0)
482                 LogFatal("Cannot fork.", "");
483         if (pid) {      /* parent... simply wait */
484                 while (wait(&status) > 0) {
485                         errno = 0;
486 #ifdef SYSV
487                         if ((status >> 8) & 0xff)
488                                 LogFatalI("Signal %d.", (status >> 8) & 0xff);
489                         if (status & 0xff)
490                                 LogFatalI("Exit code %d.", status & 0xff);
491 #else   /* !SYSV */
492                         if (status.w_termsig)
493                                 LogFatalI("Signal %d.", status.w_termsig);
494                         if (status.w_retcode)
495                                 LogFatalI("Exit code %d.", status.w_retcode);
496 #endif  /* !SYSV */
497                 }
498         } else {        /* child... dup and exec cpp */
499                 if (verbose)
500                         showargs(make_argv);
501                 if (make)
502                         execv(make, make_argv);
503                 else
504                         execvp("make", make_argv);
505                 LogFatal("Cannot exec %s.", cpp);
506         }
507 }
508
509 char *CleanCppInput(Imakefile)
510         char    *Imakefile;
511 {
512         FILE    *outFile = NULL;
513         int     infd;
514         char    *buf,           /* buffer for file content */
515                 *pbuf,          /* walking pointer to buf */
516                 *punwritten,    /* pointer to unwritten portion of buf */
517                 *cleanedImakefile = Imakefile,  /* return value */
518                 *ptoken,        /* pointer to # token */
519                 *pend,          /* pointer to end of # token */
520                 savec;          /* temporary character holder */
521         struct stat     st;
522
523         /*
524          * grab the entire file.
525          */
526         if ((infd = open(Imakefile, O_RDONLY)) < 0)
527                 LogFatal("Cannot open %s for input.", Imakefile);
528         fstat(infd, &st);
529         buf = Emalloc(st.st_size+1);
530         if (read(infd, buf, st.st_size) != st.st_size)
531                 LogFatal("Cannot read all of %s:", Imakefile);
532         close(infd);
533         buf[ st.st_size ] = '\0';
534
535         punwritten = pbuf = buf;
536         while (*pbuf) {
537             /* pad make comments for cpp */
538             if (*pbuf == '#' && (pbuf == buf || pbuf[-1] == '\n')) {
539
540                 ptoken = pbuf+1;
541                 while (*ptoken == ' ' || *ptoken == '\t')
542                         ptoken++;
543                 pend = ptoken;
544                 while (*pend && *pend != ' ' && *pend != '\t' && *pend != '\n')
545                         pend++;
546                 savec = *pend;
547                 *pend = '\0';
548                 if (strcmp(ptoken, "include")
549                  && strcmp(ptoken, "define")
550                  && strcmp(ptoken, "undef")
551                  && strcmp(ptoken, "ifdef")
552                  && strcmp(ptoken, "ifndef")
553                  && strcmp(ptoken, "else")
554                  && strcmp(ptoken, "endif")
555                  && strcmp(ptoken, "if")) {
556                     if (outFile == NULL) {
557                         tmpImakefile = mktemp(strdup(tmpImakefile));
558                         cleanedImakefile = tmpImakefile;
559                         outFile = fopen(tmpImakefile, "w");
560                         if (outFile == NULL)
561                             LogFatal("Cannot open %s for write.\n",
562                                 tmpImakefile);
563                     }
564                     fwrite(punwritten, sizeof(char), pbuf-punwritten, outFile);
565                     fputs("/**/", outFile);
566                     punwritten = pbuf;
567                 }
568                 *pend = savec;
569             }
570             pbuf++;
571         }
572         if (outFile) {
573             fwrite(punwritten, sizeof(char), pbuf-punwritten, outFile);
574             fclose(outFile); /* also closes the pipe */
575         }
576
577         return(cleanedImakefile);
578 }
579
580 CleanCppOutput(tmpfd, tmpfname)
581         FILE    *tmpfd;
582         char    *tmpfname;
583 {
584         char    *input;
585         int     blankline = 0;
586
587         while(input = ReadLine(tmpfd, tmpfname)) {
588                 if (isempty(input)) {
589                         if (blankline++)
590                                 continue;
591                         KludgeResetRule();
592                 } else {
593                         blankline = 0;
594                         KludgeOutputLine(&input);
595                         fputs(input, tmpfd);
596                 }
597                 putc('\n', tmpfd);
598         }
599         fflush(tmpfd);
600 #ifdef NFS_STDOUT_BUG
601         /*
602          * On some systems, NFS seems to leave a large number of nulls at
603          * the end of the file.  Ralph Swick says that this kludge makes the
604          * problem go away.
605          */
606         ftruncate (fileno(tmpfd), (off_t)ftell(tmpfd));
607 #endif
608 }
609
610 /*
611  * Determine of a line has nothing in it.  As a side effect, we trim white
612  * space from the end of the line.  Cpp magic cookies are also thrown away.
613  */
614 isempty(line)
615         char    *line;
616 {
617         char    *pend;
618
619         /*
620          * Check for lines of the form
621          *      # n "...
622          * or
623          *      # line n "...
624          */
625         if (*line == '#') {
626                 pend = line+1;
627                 if (*pend == ' ')
628                         pend++;
629                 if (strncmp(pend, "line ", 5) == 0)
630                         pend += 5;
631                 if (isdigit(*pend)) {
632                         while (isdigit(*pend))
633                                 pend++;
634                         if (*pend++ == ' ' && *pend == '"')
635                                 return(TRUE);
636                 }
637         }
638
639         /*
640          * Find the end of the line and then walk back.
641          */
642         for (pend=line; *pend; pend++) ;
643
644         pend--;
645         while (pend >= line && (*pend == ' ' || *pend == '\t'))
646                 pend--;
647         *++pend = '\0';
648         return (*line == '\0');
649 }
650
651 /*ARGSUSED*/
652 char *ReadLine(tmpfd, tmpfname)
653         FILE    *tmpfd;
654         char    *tmpfname;
655 {
656         static boolean  initialized = FALSE;
657         static char     *buf, *pline, *end;
658         char    *p1, *p2;
659
660         if (! initialized) {
661                 int     total_red;
662                 struct stat     st;
663
664                 /*
665                  * Slurp it all up.
666                  */
667                 fseek(tmpfd, 0, 0);
668                 fstat(fileno(tmpfd), &st);
669                 pline = buf = Emalloc(st.st_size+1);
670                 total_red = read(fileno(tmpfd), buf, st.st_size);
671                 if (total_red != st.st_size)
672                         LogFatal("cannot read %s\n", tmpMakefile);
673                 end = buf + st.st_size;
674                 *end = '\0';
675                 lseek(fileno(tmpfd), 0, 0);
676 #ifdef SYSV
677                 freopen(tmpfname, "w+", tmpfd);
678 #else   /* !SYSV */
679                 ftruncate(fileno(tmpfd), 0);
680 #endif  /* !SYSV */
681                 initialized = TRUE;
682             fprintf (tmpfd, "# Makefile generated by imake - do not edit!\n");
683             fprintf (tmpfd, "# %s\n",
684                 "$XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $");
685
686 #ifdef FIXUP_CPP_WHITESPACE
687             {
688                 static char *cpp_warning[] = {
689 "#",
690 "# The cpp used on this machine replaces all newlines and multiple tabs and",
691 "# spaces in a macro expansion with a single space.  Imake tries to compensate",
692 "# for this, but is not always successful.",
693 "#",
694 NULL };
695                 char **cpp;
696
697                 for (cpp = cpp_warning; *cpp; cpp++) {
698                     fprintf (tmpfd, "%s\n", *cpp);
699                 }
700             }
701 #endif /* FIXUP_CPP_WHITESPACE */
702         }
703
704         for (p1 = pline; p1 < end; p1++) {
705                 if (*p1 == '@' && *(p1+1) == '@') { /* soft EOL */
706                         *p1++ = '\0';
707                         p1++; /* skip over second @ */
708                         break;
709                 }
710                 else if (*p1 == '\n') { /* real EOL */
711                         *p1++ = '\0';
712                         break;
713                 }
714         }
715
716         /*
717          * return NULL at the end of the file.
718          */
719         p2 = (pline == p1 ? NULL : pline);
720         pline = p1;
721         return(p2);
722 }
723
724 writetmpfile(fd, buf, cnt)
725         FILE    *fd;
726         int     cnt;
727         char    *buf;
728 {
729         errno = 0;
730         if (fwrite(buf, cnt, 1, fd) != 1)
731                 LogFatal("Cannot write to %s.", tmpMakefile);
732 }
733
734 char *Emalloc(size)
735         int     size;
736 {
737         char    *p, *malloc();
738
739         if ((p = malloc(size)) == NULL)
740                 LogFatalI("Cannot allocate %d bytes\n", size);
741         return(p);
742 }
743
744 #ifdef FIXUP_CPP_WHITESPACE
745 KludgeOutputLine(pline)
746         char    **pline;
747 {
748         char    *p = *pline;
749
750         switch (*p) {
751             case '#':   /*Comment - ignore*/
752                 break;
753             case '\t':  /*Already tabbed - ignore it*/
754                 break;
755             case ' ':   /*May need a tab*/
756             default:
757                 for (; *p; p++) if (p[0] == ':' && 
758                                     p > *pline && p[-1] != '\\') {
759                     if (**pline == ' ')
760                         (*pline)++;
761                     InRule = TRUE;
762                     break;
763                 }
764                 if (InRule && **pline == ' ')
765                     **pline = '\t';
766                 break;
767         }
768 }
769
770 KludgeResetRule()
771 {
772         InRule = FALSE;
773 }
774 #endif /* FIXUP_CPP_WHITESPACE */
775
776 char *strdup(cp)
777         register char *cp;
778 {
779         register char *new = Emalloc(strlen(cp) + 1);
780
781         strcpy(new, cp);
782         return new;
783 }
This page took 0.104876 seconds and 5 git commands to generate.