]> andersk Git - moira.git/blame - util/imake/imake.c
sync'ing files for RCS->CVS migration
[moira.git] / util / imake / imake.c
CommitLineData
62efc910 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
4c069d87 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 *
62efc910 28 * $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
4c069d87 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 *
62efc910 38 * Usage: imake [-Idir] [-Ddefine] [-T] [-f imakefile ] [-s] [-e] [-v] [make flags]
4c069d87 39 *
62efc910 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
4c069d87 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
62efc910 47 * than Imake.tmpl
48 * -s[F] show. Show the produced makefile on the standard
4c069d87 49 * output. Make is not run is this case. If a file
50 * argument is provided, the output is placed there.
62efc910 51 * -e[F] execute instead of show; optionally name Makefile F
4c069d87 52 * -v verbose. Show the make command line executed.
53 *
54 * Environment variables:
55 *
62efc910 56 * IMAKEINCLUDE Include directory to use in addition to "."
4c069d87 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)
62efc910 78 * or the default, Imake.tmpl. Call this <template>
4c069d87 79 * 3. Start up cpp an provide it with three lines of input:
62efc910 80 * #define IMAKE_TEMPLATE " <template> "
81 * #define INCLUDE_IMAKEFILE < <imakefile> >
4c069d87 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>
4c069d87 102#ifdef SYSV
62efc910 103#ifndef macII /* mac will get the stuff out of file.h */
4c069d87 104#include <fcntl.h>
62efc910 105#endif
4c069d87 106#else /* !SYSV */
107#include <sys/wait.h>
108#endif /* !SYSV */
62efc910 109#include <sys/file.h>
110#include <signal.h>
4c069d87 111#include <sys/stat.h>
62efc910 112#include "imakemdep.h"
113
4c069d87 114
4c069d87 115#define TRUE 1
116#define FALSE 0
4c069d87 117
62efc910 118#ifdef FIXUP_CPP_WHITESPACE
4c069d87 119int 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 */
62efc910 127#ifndef FIXUP_CPP_WHITESPACE
4c069d87 128#define KludgeOutputLine(arg)
129#define KludgeResetRule()
130#endif
131
62efc910 132typedef unsigned char boolean;
4c069d87 133
62efc910 134#ifndef DEFAULT_CPP
135#define DEFAULT_CPP "/lib/cpp"
bbc17d4d 136#endif
4c069d87 137
62efc910 138char *cpp = DEFAULT_CPP;
139
140char *tmpMakefile = "/tmp/Imf.XXXXXX";
141char *tmpImakefile = "/tmp/IIf.XXXXXX";
4c069d87 142char *make_argv[ ARGUMENTS ] = { "make" };
62efc910 143
4c069d87 144int make_argindex;
145int cpp_argindex;
146char *make = NULL;
147char *Imakefile = NULL;
62efc910 148char *Makefile = "Makefile";
149char *Template = "Imake.tmpl";
4c069d87 150char *program;
151char *FindImakefile();
152char *ReadLine();
153char *CleanCppInput();
154char *strdup();
155
156boolean verbose = FALSE;
62efc910 157boolean show = TRUE;
4c069d87 158extern int errno;
159extern char *Emalloc();
160extern char *realloc();
161extern char *getenv();
162extern char *mktemp();
163
164main(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
4c069d87 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
62efc910 190 cppit(Imakefile, Template, tmpfd, tmpMakefile);
4c069d87 191
192 if (show) {
193 if (Makefile == NULL)
194 showit(tmpfd);
195 } else
196 makeit();
197 wrapup();
198 exit(0);
199}
200
201showit(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
214wrapup()
215{
216 if (tmpMakefile != Makefile)
217 unlink(tmpMakefile);
218 unlink(tmpImakefile);
219}
220
62efc910 221#if SIGNALRETURNSINT
222int
223#else
224void
225#endif
4c069d87 226catch(sig)
227 int sig;
228{
229 errno = 0;
230 LogFatalI("Signal %d.", sig);
231}
232
233/*
234 * Initialize some variables.
235 */
236init()
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);
d1b2a10e 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
4c069d87 277}
278
279AddMakeArg(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
289AddCppArg(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
299SetOpts(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])
62efc910 328 Makefile = (argv[0][2] == '-') ? NULL : argv[0]+2;
4c069d87 329 else if (argc > 1 && argv[1][0] != '-') {
330 argc--, argv++;
331 Makefile = argv[0];
332 }
333 show = TRUE;
62efc910 334 } else if (argv[0][1] == 'e') {
335 Makefile = (argv[0][2] ? argv[0]+2 : NULL);
336 show = FALSE;
4c069d87 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
355char *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
376LogFatalI(s, i)
377 char *s;
378 int i;
379{
380 /*NOSTRICT*/
381 LogFatal(s, (char *)i);
382}
383
384LogFatal(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
403showargs(argv)
404 char **argv;
405{
406 for (; *argv; argv++)
407 fprintf(stderr, "%s ", *argv);
408 fprintf(stderr, "\n");
409}
410
62efc910 411cppit(Imakefile, template, outfd, outfname)
4c069d87 412 char *Imakefile;
413 char *template;
414 FILE *outfd;
62efc910 415 char *outfname;
4c069d87 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 */
62efc910 435 pid = fork();
4c069d87 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);
62efc910 445 fprintf(pipeFile, "#define INCLUDE_IMAKEFILE\t<%s>\n",
4c069d87 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 }
62efc910 463 CleanCppOutput(outfd, outfname);
4c069d87 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
475makeit()
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 */
62efc910 487 pid = fork();
4c069d87 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
516char *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
62efc910 587CleanCppOutput(tmpfd, tmpfname)
4c069d87 588 FILE *tmpfd;
62efc910 589 char *tmpfname;
4c069d87 590{
591 char *input;
592 int blankline = 0;
593
62efc910 594 while(input = ReadLine(tmpfd, tmpfname)) {
4c069d87 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);
62efc910 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
4c069d87 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 */
621isempty(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
62efc910 658/*ARGSUSED*/
659char *ReadLine(tmpfd, tmpfname)
4c069d87 660 FILE *tmpfd;
62efc910 661 char *tmpfname;
4c069d87 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);
62efc910 683#ifdef SYSV
684 freopen(tmpfname, "w+", tmpfd);
685#else /* !SYSV */
4c069d87 686 ftruncate(fileno(tmpfd), 0);
62efc910 687#endif /* !SYSV */
4c069d87 688 initialized = TRUE;
62efc910 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"#",
701NULL };
702 char **cpp;
703
704 for (cpp = cpp_warning; *cpp; cpp++) {
705 fprintf (tmpfd, "%s\n", *cpp);
706 }
707 }
708#endif /* FIXUP_CPP_WHITESPACE */
4c069d87 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
731writetmpfile(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
741char *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
62efc910 751#ifdef FIXUP_CPP_WHITESPACE
4c069d87 752KludgeOutputLine(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:
62efc910 764 for (; *p; p++) if (p[0] == ':' &&
765 p > *pline && p[-1] != '\\') {
4c069d87 766 if (**pline == ' ')
767 (*pline)++;
768 InRule = TRUE;
769 break;
770 }
771 if (InRule && **pline == ' ')
772 **pline = '\t';
773 break;
774 }
775}
776
777KludgeResetRule()
778{
779 InRule = FALSE;
780}
62efc910 781#endif /* FIXUP_CPP_WHITESPACE */
4c069d87 782
783char *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.24306 seconds and 5 git commands to generate.