2 /***************************************************************************
6 * Add the value of BOOTSTRAPCFLAGS to the cpp_argv table so that it will *
7 * be passed to the template file. *
9 ***************************************************************************/
12 Copyright (c) 1985, 1986, 1987, 1998 The Open Group
14 Permission to use, copy, modify, distribute, and sell this software and its
15 documentation for any purpose is hereby granted without fee, provided that
16 the above copyright notice appear in all copies and that both that
17 copyright notice and this permission notice appear in supporting
20 The above copyright notice and this permission notice shall be included in
21 all copies or substantial portions of the Software.
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
27 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 Except as contained in this notice, the name of The Open Group shall not be
31 used in advertising or otherwise to promote the sale, use or other dealings
32 in this Software without prior written authorization from The Open Group.
37 * While a guest engineer at Project Athena, MIT
39 * imake: the include-make program.
41 * Usage: imake [-Idir] [-Ddefine] [-T template] [-f imakefile ] [-C Imakefile.c ] [-s] [-e] [-v] [make flags]
43 * Imake takes a template file (Imake.tmpl) and a prototype (Imakefile)
44 * and runs cpp on them producing a Makefile. It then optionally runs make
47 * -D define. Same as cpp -D argument.
48 * -U undefine. Same as cpp -U argument.
49 * -W warning. Same as cpp -W argument.
50 * -I Include directory. Same as cpp -I argument.
51 * -T template. Designate a template other
53 * -f specify the Imakefile file
54 * -C specify the name to use instead of Imakefile.c
55 * -s[F] show. Show the produced makefile on the standard
56 * output. Make is not run is this case. If a file
57 * argument is provided, the output is placed there.
58 * -e[F] execute instead of show; optionally name Makefile F
59 * -v verbose. Show the make command line executed.
61 * Environment variables:
63 * IMAKEINCLUDE Include directory to use in addition to "."
64 * IMAKECPP Cpp to use instead of /lib/cpp
65 * IMAKEMAKE make program to use other than what is
66 * found by searching the $PATH variable.
68 * imake reads the entire cpp output into memory and then scans it
69 * for occurences of "@@". If it encounters them, it replaces it with
70 * a newline. It also trims any trailing white space on output lines
71 * (because make gets upset at them). This helps when cpp expands
72 * multi-line macros but you want them to appear on multiple lines.
73 * It also changes occurences of "XCOMM" to "#", to avoid problems
74 * with treating commands as invalid preprocessor commands.
76 * The macros MAKEFILE and MAKE are provided as macros
77 * to make. MAKEFILE is set to imake's makefile (not the constructed,
78 * preprocessed one) and MAKE is set to argv[0], i.e. the name of
81 * Theory of operation:
82 * 1. Determine the name of the imakefile from the command line (-f)
83 * or from the content of the current directory (Imakefile or imakefile).
84 * Call this <imakefile>. This gets added to the arguments for
85 * make as MAKEFILE=<imakefile>.
86 * 2. Determine the name of the template from the command line (-T)
87 * or the default, Imake.tmpl. Call this <template>
88 * 3. Determine the name of the imakeCfile from the command line (-C)
89 * or the default, Imakefile.c. Call this <imakeCfile>
90 * 4. Store lines of input into <imakeCfile>:
91 * - A c-style comment header (see ImakefileCHeader below), used
92 * to recognize temporary files generated by imake.
93 * - If DEFAULT_OS_NAME is defined, format the utsname struct and
94 * call the result <defaultOsName>. Add:
95 * #define DefaultOSName <defaultOsName>
96 * - If DEFAULT_OS_MAJOR_REV is defined, format the utsname struct
97 * and call the result <defaultOsMajorVersion>. Add:
98 * #define DefaultOSMajorVersion <defaultOsMajorVersion>
99 * - If DEFAULT_OS_MINOR_REV is defined, format the utsname struct
100 * and call the result <defaultOsMinorVersion>. Add:
101 * #define DefaultOSMinorVersion <defaultOsMinorVersion>
102 * - If DEFAULT_OS_TEENY_REV is defined, format the utsname struct
103 * and call the result <defaultOsTeenyVersion>. Add:
104 * #define DefaultOSTeenyVersion <defaultOsTeenyVersion>
105 * - If DEFAULT_MACHINE_ARCITECTURE is defined, format the utsname struct
106 * and define the corresponding macro. (For example on the amiga,
107 * this will define amiga in addition to m68k).
108 * - If the file "localdefines" is readable in the current
109 * directory, print a warning message to stderr and add:
110 * #define IMAKE_LOCAL_DEFINES "localdefines"
111 * #include IMAKE_LOCAL_DEFINES
112 * - If the file "admindefines" is readable in the current
113 * directory, print a warning message to stderr and add:
114 * #define IMAKE_ADMIN_DEFINES "admindefines"
115 * #include IMAKE_ADMIN_DEFINES
116 * - The following lines:
117 * #define INCLUDE_IMAKEFILE < <imakefile> >
118 * #define IMAKE_TEMPLATE " <template> "
119 * #include IMAKE_TEMPLATE
120 * - If the file "adminmacros" is readable in the current
121 * directory, print a warning message to stderr and add:
122 * #define IMAKE_ADMIN_MACROS "adminmacros"
123 * #include IMAKE_ADMIN_MACROS
124 * - If the file "localmacros" is readable in the current
125 * directory, print a warning message to stderr and add:
126 * #define IMAKE_LOCAL_MACROS "localmacros"
127 * #include IMAKE_LOCAL_MACROS
128 * 5. Start up cpp and provide it with this file.
129 * Note that the define for INCLUDE_IMAKEFILE is intended for
130 * use in the template file. This implies that the imake is
131 * useless unless the template file contains at least the line
132 * #include INCLUDE_IMAKEFILE
133 * 6. Gather the output from cpp, and clean it up, expanding @@ to
134 * newlines, stripping trailing white space, cpp control lines,
135 * and extra blank lines, and changing XCOMM to #. This cleaned
136 * output is placed in a new file, default "Makefile", but can
137 * be specified with -s or -e options.
138 * 7. Optionally start up make on the resulting file.
140 * The design of the template makefile should therefore be:
141 * <set global macros like CFLAGS, etc.>
142 * <include machine dependent additions>
143 * #include INCLUDE_IMAKEFILE
144 * <add any global targets like 'clean' and long dependencies>
149 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
150 /* This needs to be before _POSIX_SOURCE gets defined */
151 # include <sys/param.h>
152 # include <sys/types.h>
153 # include <sys/sysctl.h>
158 #include <X11/Xfuncproto.h>
159 #include <X11/Xosdefs.h>
163 # include "Xw32defs.h"
165 #include <sys/types.h>
169 # include <sys/file.h>
177 #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
180 # define _POSIX_SOURCE
182 # undef _POSIX_SOURCE
184 #if !defined(SIGCHLD) && defined(SIGCLD)
185 # define SIGCHLD SIGCLD
187 #include <sys/stat.h>
189 # ifdef _POSIX_SOURCE
191 # include <sys/procset.h>
192 # include <sys/siginfo.h>
194 # include <sys/wait.h>
196 # define _POSIX_SOURCE
197 # include <sys/wait.h>
198 # undef _POSIX_SOURCE
200 # define waitCode(w) WEXITSTATUS(w)
201 # define waitSig(w) WTERMSIG(w)
202 typedef int waitType;
203 #else /* X_NOT_POSIX */
205 # define waitCode(w) (((w) >> 8) & 0x7f)
206 # define waitSig(w) ((w) & 0xff)
207 typedef int waitType;
210 # include <process.h>
211 typedef int waitType;
213 # include <sys/wait.h>
214 # define waitCode(w) ((w).w_T.w_Retcode)
215 # define waitSig(w) ((w).w_T.w_Termsig)
216 typedef union wait waitType;
220 # define WIFSIGNALED(w) waitSig(w)
223 # define WIFEXITED(w) waitCode(w)
225 #endif /* X_NOT_POSIX */
229 # define USE_FREOPEN 1
233 # include <sys/utsname.h>
235 # include <windows.h>
239 # define SYS_NMLN _SYS_NMLN
241 # define SYS_NMLN 257
244 #if defined(linux) || defined(__GNU__) || defined(__GLIBC__)
252 #if defined(__NetBSD__) /* see code clock in init() below */
253 # include <sys/utsname.h>
256 typedef unsigned char boolean;
260 #include "imakemdep.h"
262 # include "imakemdep_cpp.h"
265 #if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE
268 #if defined CROSSCOMPILE || defined INLINE_SYNTAX
271 #if defined CROSSCOMPILE || defined MAGIC_MAKE_VARS
277 # define PATH_MAX 1024
281 * Some versions of cpp reduce all tabs in macro expansion to a single
282 * space. In addition, the escaped newline may be replaced with a
283 * space instead of being deleted. Blech.
285 void KludgeOutputLine(char **), KludgeResetRule(void);
290 # define DEFAULT_CC "cc"
295 # define DEFAULT_CPP CPP_PROGRAM
297 # define DEFAULT_CPP "/lib/cpp"
303 const char *cpp = NULL;
305 const char *tmpMakefile;
306 const char *tmpMakefileTemplate = "/tmp/Imf.XXXXXX";
307 const char *tmpImakefile;
308 const char *tmpImakefileTemplate = "/tmp/IIf.XXXXXX";
309 const char *make_argv[ ARGUMENTS ] = {
319 const char *Imakefile = NULL;
320 const char *Makefile = "Makefile";
321 const char *Template = "Imake.tmpl";
322 const char *ImakefileC = "Imakefile.c";
323 boolean haveImakefileC = FALSE;
324 const char *cleanedImakefile = NULL;
326 const char *FindImakefile(const char *Imakefile);
327 char *ReadLine(FILE *tmpfd, const char *tmpfname);
328 const char *CleanCppInput(const char *imakefile);
329 char *Strdup(const char *cp);
330 char *Emalloc(int size);
331 void LogFatal(const char *x0, ...) _X_ATTRIBUTE_PRINTF(1, 2);
332 void LogMsg(const char *x0, ...) _X_ATTRIBUTE_PRINTF(1, 2);
334 void showit(FILE *fd);
337 void AddMakeArg(const char *arg);
338 void AddCppArg(const char *arg);
340 char *CrossCompileCPP(void);
342 void SetOpts(int argc, char **argv);
343 void CheckImakefileC(const char *masterc);
344 void cppit(const char *imakefile, const char *template, const char *masterc,
345 FILE *outfd, const char *outfname);
347 void CleanCppOutput(FILE *tmpfd, const char *tmpfname);
348 boolean isempty(char *line);
349 void writetmpfile(FILE *fd, const char *buf, int cnt, const char *fname);
350 #ifdef SIGNALRETURNSINT
355 void showargs(const char **argv);
356 boolean optional_include(FILE *inFile, const char *defsym, const char *fname);
357 void doit(FILE *outfd, const char *cmd, const char **argv);
358 boolean define_os_defaults(FILE *inFile);
360 static void get_cross_compile_dir(FILE *inFile);
362 #ifdef CROSSCOMPILEDIR
363 const char *CrossCompileDir = CROSSCOMPILEDIR;
365 const char *CrossCompileDir = "";
367 boolean CrossCompiling = FALSE;
371 boolean verbose = FALSE;
375 main(int argc, char *argv[])
378 char makeMacro[ BUFSIZ ];
379 char makefileMacro[ BUFSIZ ];
380 int lenCrossCompileDir = 0;
385 lenCrossCompileDir = strlen(CrossCompileDir);
386 if (lenCrossCompileDir) {
387 if (lenCrossCompileDir > (PATH_MAX - 20))
388 LogFatal("Cross compile directory path too long %s\n",
391 CrossCompiling = TRUE;
395 Imakefile = FindImakefile(Imakefile);
396 CheckImakefileC(ImakefileC);
398 tmpMakefile = Makefile;
399 if ((tmpfd = fopen(tmpMakefile, "w+")) == NULL)
400 LogFatal("Cannot create temporary file %s.", tmpMakefile);
405 char *tmpMakefileName = Strdup(tmpMakefileTemplate);
407 if (mktemp(tmpMakefileName) == NULL ||
408 (tmpfd = fopen(tmpMakefileName, "w+")) == NULL) {
409 LogFatal("Cannot create temporary file %s.", tmpMakefileName);
412 fd = mkstemp(tmpMakefileName);
413 if (fd == -1 || (tmpfd = fdopen(fd, "w+")) == NULL) {
415 unlink(tmpMakefileName); close(fd);
417 LogFatal("Cannot create temporary file %s.", tmpMakefileName);
420 tmpMakefile = tmpMakefileName;
423 AddMakeArg( tmpMakefile );
424 sprintf(makeMacro, "MAKE=%s", program);
425 AddMakeArg( makeMacro );
426 sprintf(makefileMacro, "MAKEFILE=%s", Imakefile);
427 AddMakeArg( makefileMacro );
429 cleanedImakefile = CleanCppInput(Imakefile);
430 cppit(cleanedImakefile, Template, ImakefileC, tmpfd, tmpMakefile);
433 if (Makefile == NULL)
448 while ((red = fread(buf, 1, BUFSIZ, fd)) > 0)
449 writetmpfile(stdout, buf, red, "stdout");
451 LogFatal("Cannot read %s.", tmpMakefile);
457 if (tmpMakefile != Makefile)
459 if (cleanedImakefile && cleanedImakefile != Imakefile)
460 unlink(cleanedImakefile);
465 #ifdef SIGNALRETURNSINT
473 LogFatal("Signal %d.", sig);
477 * Initialize some variables.
485 while (make_argv[ make_argindex ] != NULL)
488 while (cpp_argv[ cpp_argindex ] != NULL)
491 #if defined CROSSCOMPILE
493 if (CrossCompiling) {
494 LogFatal("fix imake to do crosscompiling for NetBSD\n","");
497 #if defined(__NetBSD__) || defined CROSSCOMPILE
500 static char argument[512];
503 * Sharable imake configurations require a
504 * machine identifier.
506 if (uname(&uts) != 0)
507 LogFatal("uname(3) failed; can't tell what %s",
508 "kind of machine you have.");
510 memset(argument, 0, sizeof(argument));
511 (void)snprintf(argument, sizeof(argument) - 1,
512 "-D__%s__", uts.machine);
516 #endif /* __NetBSD__ */
519 * See if the standard include directory is different than
520 * the default. Or if cpp is not the default. Or if the make
521 * found by the PATH variable is not the default.
523 if ((p = getenv("IMAKEINCLUDE"))) {
524 if (*p != '-' || *(p+1) != 'I')
525 LogFatal("Environment var IMAKEINCLUDE %s",
526 "must begin with -I");
534 if ((p = getenv("IMAKECPP")))
536 if ((p = getenv("IMAKEMAKE")))
539 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
540 signal(SIGINT, catch);
542 signal(SIGCHLD, SIG_DFL);
547 AddMakeArg(const char *arg)
550 if (make_argindex >= ARGUMENTS-1)
551 LogFatal("Out of internal storage.");
552 make_argv[ make_argindex++ ] = arg;
553 make_argv[ make_argindex ] = NULL;
557 AddCppArg(const char *arg)
560 if (cpp_argindex >= ARGUMENTS-1)
561 LogFatal("Out of internal storage.");
562 cpp_argv[ cpp_argindex++ ] = arg;
563 cpp_argv[ cpp_argindex ] = NULL;
567 SetOpts(int argc, char **argv)
572 * Now gather the arguments for make
574 for(argc--, argv++; argc; argc--, argv++) {
576 * We intercept these flags.
578 if (argv[0][0] == '-') {
579 if (argv[0][1] == 'D') {
581 } else if (argv[0][1] == 'I') {
583 } else if (argv[0][1] == 'U') {
585 } else if (argv[0][1] == 'W') {
587 } else if (argv[0][1] == 'f') {
589 Imakefile = argv[0]+2;
593 LogFatal("No description arg after -f flag");
596 } else if (argv[0][1] == 's') {
598 Makefile = ((argv[0][2] == '-') && !argv[0][3]) ?
603 LogFatal("No description arg after -s flag");
604 Makefile = ((argv[0][0] == '-') && !argv[0][1]) ?
608 } else if (argv[0][1] == 'e') {
609 Makefile = (argv[0][2] ? argv[0]+2 : NULL);
611 } else if (argv[0][1] == 'T') {
613 Template = argv[0]+2;
617 LogFatal("No description arg after -T flag");
620 } else if (argv[0][1] == 'C') {
622 ImakefileC = argv[0]+2;
626 LogFatal("No imakeCfile arg after -C flag");
627 ImakefileC = argv[0];
629 } else if (argv[0][1] == 'v') {
654 cpp = CrossCompileCPP();
658 AddCppArg(ImakefileC);
662 FindImakefile(const char *Imakefile)
665 if (access(Imakefile, R_OK) < 0)
666 LogFatal("Cannot find %s.", Imakefile);
668 if (access("Imakefile", R_OK) < 0) {
669 if (access("imakefile", R_OK) < 0)
670 LogFatal("No description file.");
672 Imakefile = "imakefile";
674 Imakefile = "Imakefile";
679 static void _X_ATTRIBUTE_PRINTF(1, 0)
680 vLogMsg(const char *fmt, va_list args)
682 int error_number = errno;
685 fprintf(stderr, "%s: ", program);
686 fprintf(stderr, "%s\n", strerror(error_number));
688 fprintf(stderr, "%s: ", program);
689 vfprintf(stderr, fmt, args);
690 fprintf(stderr, "\n");
694 LogFatal(const char *fmt, ...)
696 static boolean entered = FALSE;
706 fprintf(stderr, " Stop.\n");
712 LogMsg(const char *fmt, ...)
722 showargs(const char **argv)
724 for (; *argv; argv++)
725 fprintf(stderr, "%s ", *argv);
726 fprintf(stderr, "\n");
729 #define ImakefileCHeader "/* imake - temporary file */"
732 CheckImakefileC(const char *masterc)
737 if (access(masterc, F_OK) == 0) {
738 inFile = fopen(masterc, "r");
740 LogFatal("Refuse to overwrite: %s", masterc);
741 if ((fgets(mkcbuf, sizeof(mkcbuf), inFile) &&
742 strncmp(mkcbuf, ImakefileCHeader,
743 sizeof(ImakefileCHeader)-1)))
746 LogFatal("Refuse to overwrite: %s", masterc);
752 #define LocalDefineFmt "#define %s \"%s\"\n"
753 #define IncludeFmt "#include %s\n"
754 #define ImakeDefSym "INCLUDE_IMAKEFILE"
755 #define ImakeTmplSym "IMAKE_TEMPLATE"
756 #define OverrideWarning "Warning: local file \"%s\" overrides global macros."
759 optional_include(FILE *inFile, const char *defsym, const char *fname)
762 if (access(fname, R_OK) == 0) {
763 LogMsg(OverrideWarning, fname);
764 return (fprintf(inFile, LocalDefineFmt, defsym, fname) < 0 ||
765 fprintf(inFile, IncludeFmt, defsym) < 0);
771 doit(FILE *outfd, const char *cmd, const char **argv)
777 * Fork and exec the command.
781 dup2(fileno(outfd), 1);
782 status = _spawnvp(_P_WAIT, cmd, argv);
784 LogFatal("Cannot spawn %s.", cmd);
786 LogFatal("Exit code %d.", status);
790 LogFatal("Cannot fork.");
791 if (pid) { /* parent... simply wait */
792 while (wait(&status) > 0) {
794 if (WIFSIGNALED(status))
795 LogFatal("Signal %d.", waitSig(status));
796 if (WIFEXITED(status) && waitCode(status))
797 LogFatal("Exit code %d.", waitCode(status));
800 else { /* child... dup and exec cmd */
804 dup2(fileno(outfd), 1);
806 LogFatal("Cannot exec %s.", cmd);
813 parse_utsname(struct utsname *name, const char *fmt, char *result, const char *msg)
815 char buf[SYS_NMLN * 5 + 1];
822 /* Assemble all the pieces into a buffer. */
823 for (arg = 0; fmt[arg] != ' '; arg++)
825 /* Our buffer is only guaranteed to hold 5 arguments. */
834 strcpy(ptr, name->sysname);
841 strcpy(ptr, name->nodename);
848 strcpy(ptr, name->release);
855 strcpy(ptr, name->version);
862 strcpy(ptr, name->machine);
871 /* Just in case... */
872 if (strlen(buf) >= sizeof(buf))
873 LogFatal("Buffer overflow parsing uname.");
875 /* Parse the buffer. The sscanf() return value is rarely correct. */
877 (void) sscanf(buf, fmt + arg + 1, result);
880 /* Trim leading 0's and periods from version names. The 0's cause
881 the number to be interpreted as octal numbers. Some version strings
882 have the potential for different numbers of .'s in them.
886 trim_version(char *p)
889 if (p != 0 && *p != '\0')
891 while ((*p == '0' || *p == '.') && *(p + 1) != '\0')
898 #if defined(linux) || defined(__GLIBC__)
900 "#include <stdio.h>\n"
901 "#include <ctype.h>\n"
904 "#pragma weak gnu_get_libc_version\n"
905 "#pragma weak __libc_version\n"
906 "#pragma weak __linux_C_lib_version\n"
909 "extern const char * gnu_get_libc_version (void);\n"
910 "extern const char * __linux_C_lib_version;\n"
911 "extern const char __libc_version [];\n"
916 " int libcmajor = 0, libcminor = 0, libcteeny = 0;\n"
917 " const char * ptr = NULL;\n"
918 " int glibcmajor = 0;\n"
920 " if (gnu_get_libc_version != 0)\n"
922 " ptr = gnu_get_libc_version ();\n"
925 " else if (&__libc_version != 0)\n"
927 " ptr = __libc_version;\n"
930 " else if (&__linux_C_lib_version != 0)\n"
932 " ptr = __linux_C_lib_version;\n"
936 " libcmajor = 0; libcminor = 0; libcteeny = 0;\n"
941 " while (!isdigit (*ptr))\n"
944 " sscanf (ptr, \"%d.%d.%d\", &libcmajor, &libcminor, &libcteeny);\n"
945 " libcmajor += glibcmajor;\n"
948 " printf(\"#define DefaultLinuxCLibMajorVersion %d\\n\", libcmajor);\n"
949 " printf(\"#define DefaultLinuxCLibMinorVersion %d\\n\", libcminor);\n"
950 " printf(\"#define DefaultLinuxCLibTeenyVersion %d\\n\", libcteeny);\n"
957 get_libc_version(FILE *inFile)
959 char aout[4096], *tmpdir;
961 const char *format = "%s -o %s -x c -";
966 /* If $TMPDIR is defined and has an acceptable length,
967 * use that as tmp dir, else use /tmp. That fixes
968 * problems with /tmp mounted "noexec".
970 if((tmpdir = getenv("TMPDIR")) != NULL && strlen(tmpdir) < (4096-13))
971 strcpy(aout, tmpdir);
973 strcpy(aout, "/tmp");
974 strcat(aout, "/imakeXXXXXX");
976 /* Pre-create temp file safely */
978 /* Linux + ELF has mkstemp() */
980 if ((tmpfd = mkstemp(aout)) == -1) {
989 len = strlen (aout) + strlen (format) + strlen (cc);
990 if (len < 128) len = 128;
991 if((command = alloca (len)) == NULL)
994 if (snprintf (command , len, format, cc, aout) == len)
997 fp = popen (command, "w");
998 if (fp == NULL || fprintf (fp, "%s\n", libc_c) < 0
1002 fp = popen (aout, "r");
1006 while (fgets (command, len, fp))
1007 fprintf (inFile, command);
1016 #if defined(__OpenBSD__) || defined(__DragonFly__)
1018 get_stackprotector(FILE *inFile)
1022 char command[1024], buf[1024];
1028 snprintf(command, sizeof(command), "%s -v 2>&1", cc);
1029 fp = popen(command, "r");
1032 while (fgets(buf, sizeof(buf), fp)) {
1033 if (strstr(buf, "propolice") != NULL) {
1034 fprintf(inFile, "#define ProPoliceSupport YES\n");
1043 #if defined CROSSCOMPILE || defined linux || defined(__GLIBC__)
1045 get_distrib(FILE *inFile)
1049 static const char* suse = "/etc/SuSE-release";
1050 static const char* redhat = "/etc/redhat-release";
1051 static const char* debian = "/etc/debian_version";
1053 fprintf (inFile, "%s\n", "#define LinuxUnknown 0");
1054 fprintf (inFile, "%s\n", "#define LinuxSuSE 1");
1055 fprintf (inFile, "%s\n", "#define LinuxCaldera 2");
1056 fprintf (inFile, "%s\n", "#define LinuxCraftworks 3");
1057 fprintf (inFile, "%s\n", "#define LinuxDebian 4");
1058 fprintf (inFile, "%s\n", "#define LinuxInfoMagic 5");
1059 fprintf (inFile, "%s\n", "#define LinuxKheops 6");
1060 fprintf (inFile, "%s\n", "#define LinuxPro 7");
1061 fprintf (inFile, "%s\n", "#define LinuxRedHat 8");
1062 fprintf (inFile, "%s\n", "#define LinuxSlackware 9");
1063 fprintf (inFile, "%s\n", "#define LinuxTurbo 10");
1064 fprintf (inFile, "%s\n", "#define LinuxWare 11");
1065 fprintf (inFile, "%s\n", "#define LinuxYggdrasil 12");
1067 # ifdef CROSSCOMPILE
1068 if (CrossCompiling) {
1069 fprintf (inFile, "%s\n",
1070 "#define DefaultLinuxDistribution LinuxUnknown");
1071 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown");
1075 if (lstat (suse, &sb) == 0) {
1076 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxSuSE");
1077 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName SuSE");
1080 if (lstat (redhat, &sb) == 0) {
1081 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxRedHat");
1082 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName RedHat");
1085 if (lstat (debian, &sb) == 0) {
1086 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxDebian");
1087 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Debian");
1088 /* You could also try to get the version of the Debian distrib by looking
1089 * at the content of /etc/debian_version */
1092 /* what's the definitive way to tell what any particular distribution is? */
1094 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxUnknown");
1095 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown");
1096 /* would like to know what version of the distribution it is */
1100 get_ld_version(FILE *inFile)
1104 int ldmajor, ldminor;
1105 const char *ld = "ld -v";
1107 # ifdef CROSSCOMPILE
1108 if (CrossCompiling) {
1110 strcpy (cmd, CrossCompileDir);
1113 ldprog = popen (cmd, "r");
1116 ldprog = popen (ld, "r");
1121 } while (c != EOF && !isdigit (c));
1123 (void) fscanf (ldprog, "%d.%d", &ldmajor, &ldminor);
1124 /* Start conversion to a more rational number */
1125 if ((ldmajor > 2) || ((ldmajor == 2) && (ldminor > 9)))
1130 fprintf(inFile, "#define DefaultLinuxBinUtilsMajorVersion %d\n",
1137 #if defined __FreeBSD__
1139 get_binary_format(FILE *inFile)
1144 FILE *objprog = NULL;
1150 mib[1] = KERN_OSRELDATE;
1151 len = sizeof(osrel);
1152 sysctl(mib, 2, &osrel, &len, NULL, 0);
1153 if (CrossCompiling) {
1154 strcpy (cmd, CrossCompileDir);
1156 strcat (cmd,"objformat");
1158 strcpy (cmd, "objformat");
1160 if (osrel >= 300004 &&
1161 (objprog = popen(cmd, "r")) != NULL &&
1162 fgets(buf, sizeof(buf), objprog) != NULL &&
1163 strncmp(buf, "elf", 3) == 0)
1168 fprintf(inFile, "#define DefaultToElfFormat %s\n", iself ? "YES" : "NO");
1172 #if defined(sun) && defined(__SVR4)
1173 /* Runs Sun compiler command and parses output - this is a bit of a hack
1174 * as it depends on the particular output format of the -V flag, but it's
1175 * worked for many releases.
1177 * Input : cmd - command to run (called with -V flag)
1178 * path - path to command to run (use $PATH if NULL)
1179 * Output: cmajor & cminor - major and minor versions if found
1180 * Returns: 0 if successful, -1 if not.
1183 ask_sun_compiler_for_versions(const char *cmd, const char *path,
1184 int *cmajor, int *cminor)
1187 char cmdtorun[PATH_MAX];
1190 const char vflag[] = " -V 2>&1";
1193 int len = strlen(cmd) + sizeof(vflag);
1196 len += strlen(path) + 1;
1199 if (len < sizeof(cmdtorun)) {
1201 sprintf(cmdtorun, "%s/%s %s", path, cmd, vflag);
1203 sprintf(cmdtorun, "%s %s", cmd, vflag);
1206 if ((ccproc = popen (cmdtorun, "r")) != NULL) {
1207 if (fgets (buf, sizeof(buf), ccproc) != NULL) {
1208 vptr = strrchr (buf, 'C');
1210 for (; (*vptr != '\0') && !isdigit(*vptr); vptr++) {
1211 /* Do nothing - just scanning for first digit */
1213 if (*vptr != '\0') {
1214 if (sscanf (vptr, "%d.%d", cmajor, cminor) == 2) {
1221 "warning: could not parse version number in output of:\n"
1224 while (fgets (buf, sizeof(buf), ccproc) != NULL) {};
1232 /* Find Sun compilers and their versions if present */
1234 get_sun_compiler_versions (FILE *inFile)
1236 const char* sunpro_path = "/opt/SUNWspro/bin";
1237 int cmajor, cminor, found = 0;
1239 /* If cross-compiling, only check CrossCompilerDir for compilers.
1240 * If not cross-compiling, first check cc in users $PATH,
1241 * then try /opt/SUNWspro if not found in the users $PATH
1244 # if defined CROSSCOMPILE
1245 if (CrossCompiling) {
1246 if (ask_sun_compiler_for_versions("cc", CrossCompileDir,
1247 &cmajor, &cminor) == 0) {
1254 if (ask_sun_compiler_for_versions("cc", NULL, &cmajor, &cminor) == 0) {
1256 } else if (ask_sun_compiler_for_versions("cc", sunpro_path,
1257 &cmajor, &cminor) == 0) {
1259 fprintf(inFile, "#define DefaultSunProCCompilerDir %s", sunpro_path);
1265 "#define DefaultSunProCCompilerMajorVersion %d\n", cmajor);
1267 "#define DefaultSunProCCompilerMinorVersion %d\n", cminor);
1270 /* Now do it again for C++ compiler (CC) */
1272 # if defined CROSSCOMPILE
1273 if (CrossCompiling) {
1274 if (ask_sun_compiler_for_versions("CC", CrossCompileDir,
1275 &cmajor, &cminor) == 0) {
1282 if (ask_sun_compiler_for_versions("CC", NULL, &cmajor, &cminor) == 0) {
1284 } else if (ask_sun_compiler_for_versions("CC", sunpro_path,
1285 &cmajor, &cminor) == 0) {
1288 "#define DefaultSunProCplusplusCompilerDir %s", sunpro_path);
1294 "#define DefaultSunProCplusplusCompilerMajorVersion %d\n",
1297 "#define DefaultSunProCplusplusCompilerMinorVersion %d\n",
1303 #if defined CROSSCOMPILE || defined __GNUC__
1305 get_gcc_version(FILE *inFile, char *name)
1307 fprintf (inFile, "#define HasGcc 1\n");
1308 # ifdef CROSSCOMPILE
1312 fprintf (inFile, "#define HasGcc2 1\n");
1314 fprintf (inFile, "#define HasGcc3 1\n");
1316 fprintf (inFile, "#define GccMajorVersion %d\n", gnu_c);
1317 fprintf (inFile, "#define GccMinorVersion %d\n", gnu_c_minor);
1322 fprintf (inFile, "#define HasGcc2 1\n");
1324 fprintf (inFile, "#define HasGcc3 1\n");
1327 fprintf (inFile, "#define GccMajorVersion %d\n", __GNUC__);
1328 fprintf (inFile, "#define GccMinorVersion %d\n", __GNUC_MINOR__);
1330 # if defined(HAS_MERGE_CONSTANTS)
1331 fprintf (inFile, "#define HasGccMergeConstants %d\n", HAS_MERGE_CONSTANTS);
1340 static const char* gcc_path[] = {
1341 #if defined(linux) || \
1342 defined(__NetBSD__) || \
1343 defined(__OpenBSD__) || \
1344 defined(__FreeBSD__) || \
1345 defined(__DragonFly__) || \
1346 defined(__APPLE__) || \
1347 defined(__CYGWIN__) || \
1348 defined(__MINGW32__) || \
1349 defined(__GNU__) || \
1351 "/usr/bin/cc", /* for Linux PostIncDir */
1353 "/usr/local/bin/gcc",
1359 static const char* cross_cc_name[] = {
1364 if (CrossCompiling) {
1366 for (i = 0; i < sizeof (cross_cc_name) / sizeof cross_cc_name[0]; i++){
1367 strcpy (cmd, CrossCompileDir);
1369 strcat (cmd, cross_cc_name[i]);
1370 if (lstat (cmd, &sb) == 0) {
1379 for (i = 0; i < sizeof (gcc_path) / sizeof gcc_path[0]; i++) {
1380 if (lstat (gcc_path[i], &sb) == 0) {
1381 strcpy (cmd, gcc_path[i]);
1389 #if defined CROSSCOMPILE || !defined __UNIXOS2__
1391 get_gcc_incdir(FILE *inFile, char* name)
1401 strcat (cmd, " --print-libgcc-file-name");
1402 if ((gccproc = popen (cmd, "r")) != NULL) {
1403 if (fgets (buf, PATH_MAX, gccproc) != NULL) {
1404 ptr = strstr (buf, "libgcc.a");
1405 if (ptr) strcpy (ptr, "include");
1407 (void) pclose (gccproc);
1411 fprintf (inFile, "#define DefaultGccIncludeDir \"%s\"\n", buf);
1416 define_os_defaults(FILE *inFile)
1418 #if defined CROSSCOMPILE || ( !defined(WIN32) && !defined(__UNIXOS2__) )
1419 # ifdef CROSSCOMPILE
1423 if ((sys != win32) && (sys != emx))
1427 # if (defined(DEFAULT_OS_NAME) || defined(DEFAULT_OS_MAJOR_REV) || \
1428 defined(DEFAULT_OS_MINOR_REV) || defined(DEFAULT_OS_TEENY_REV))
1429 struct utsname *name = NULL;
1430 struct utsname uts_name;
1431 char buf[SYS_NMLN * 5 + 1];
1433 /* Obtain the system information. */
1434 # ifdef CROSSCOMPILE
1435 if (!CrossCompiling)
1438 if (uname(&uts_name) < 0)
1439 LogFatal("Cannot invoke uname");
1443 # if defined CROSSCOMPILE && (defined linux || defined(__GLIBC__))
1445 strncpy(uts_name.sysname,cross_uts_sysname,SYS_NMLN);
1446 strncpy(uts_name.release,cross_uts_release,SYS_NMLN);
1447 strncpy(uts_name.version,cross_uts_version,SYS_NMLN);
1448 strncpy(uts_name.machine,cross_uts_machine,SYS_NMLN);
1453 /* Override for compiling in chroot of other OS version, such as
1454 * in the bento build cluster.
1458 if ((e = getenv("OSREL")) != NULL &&
1459 strlen(name->sysname) + strlen(e) + 1 < SYS_NMLN) {
1460 strcpy(name->release, e);
1461 strcpy(name->version, name->sysname);
1462 strcat(name->version, " ");
1463 strcat(name->version, e);
1468 # if defined DEFAULT_OS_NAME
1469 # if defined CROSSCOMPILE
1470 if (!CrossCompiling)
1473 parse_utsname(name, DEFAULT_OS_NAME, buf,
1474 "Bad DEFAULT_OS_NAME syntax %s");
1475 # ifdef DEFAULT_OS_NAME_FROB
1476 DEFAULT_OS_NAME_FROB(buf, sizeof buf);
1479 fprintf(inFile, "#define DefaultOSName %s\n", buf);
1483 # if defined CROSSCOMPILE
1484 if (CrossCompiling && defaultOsName) {
1485 parse_utsname(name, defaultOsName, buf,
1486 "Bad DEFAULT_OS_NAME syntax %s");
1487 if (defaultOsNameFrob)
1488 defaultOsNameFrob(buf, sizeof buf);
1490 fprintf(inFile, "#define DefaultOSName %s\n", buf);
1494 # ifdef DEFAULT_OS_MAJOR_REV
1495 # if defined CROSSCOMPILE
1496 if (!CrossCompiling)
1499 parse_utsname(name, DEFAULT_OS_MAJOR_REV, buf,
1500 "Bad DEFAULT_OS_MAJOR_REV syntax %s");
1501 # ifdef DEFAULT_OS_MAJOR_REV_FROB
1502 DEFAULT_OS_MAJOR_REV_FROB(buf, sizeof buf);
1504 fprintf(inFile, "#define DefaultOSMajorVersion %s\n",
1505 *buf ? trim_version(buf) : "0");
1509 # if defined CROSSCOMPILE
1510 if (CrossCompiling && defaultOsMajorRev) {
1511 parse_utsname(name, defaultOsMajorRev, buf,
1512 "Bad defaultOsMajorRev syntax %s");
1513 if (defaultOsMajorRevFrob)
1514 defaultOsMajorRevFrob(buf, sizeof buf);
1515 fprintf(inFile, "#define DefaultOSMajorVersion %s\n",
1516 *buf ? trim_version(buf) : "0");
1520 # ifdef DEFAULT_OS_MINOR_REV
1521 # if defined CROSSCOMPILE
1522 if (!CrossCompiling)
1525 parse_utsname(name, DEFAULT_OS_MINOR_REV, buf,
1526 "Bad DEFAULT_OS_MINOR_REV syntax %s");
1527 # ifdef DEFAULT_OS_MINOR_REV_FROB
1528 DEFAULT_OS_MINOR_REV_FROB(buf, sizeof buf);
1530 fprintf(inFile, "#define DefaultOSMinorVersion %s\n",
1531 *buf ? trim_version(buf) : "0");
1535 # if defined CROSSCOMPILE
1536 if (CrossCompiling && defaultOsMinorRev) {
1537 parse_utsname(name, defaultOsMinorRev, buf,
1538 "Bad defaultOsMinorRev syntax %s");
1539 if (defaultOsMinorRevFrob)
1540 defaultOsMinorRevFrob(buf, sizeof buf);
1541 fprintf(inFile, "#define DefaultOSMinorVersion %s\n",
1542 *buf ? trim_version(buf) : "0");
1546 # ifdef DEFAULT_OS_TEENY_REV
1547 # if defined CROSSCOMPILE
1548 if (!CrossCompiling)
1551 parse_utsname(name, DEFAULT_OS_TEENY_REV, buf,
1552 "Bad DEFAULT_OS_TEENY_REV syntax %s");
1553 # ifdef DEFAULT_OS_TEENY_REV_FROB
1554 DEFAULT_OS_TEENY_REV_FROB(buf, sizeof buf);
1556 fprintf(inFile, "#define DefaultOSTeenyVersion %s\n",
1557 *buf ? trim_version(buf) : "0");
1561 # if defined CROSSCOMPILE
1562 if (CrossCompiling && defaultOsTeenyRev) {
1563 parse_utsname(name, defaultOsTeenyRev, buf,
1564 "Bad defaultOsTeenyRev syntax %s");
1565 if (defaultOsTeenyRevFrob)
1566 defaultOsTeenyRevFrob(buf, sizeof buf);
1567 fprintf(inFile, "#define DefaultOSTeenyVersion %s\n",
1568 *buf ? trim_version(buf) : "0");
1572 # ifdef DEFAULT_MACHINE_ARCHITECTURE
1573 # if defined CROSSCOMPILE
1574 if (!CrossCompiling)
1577 parse_utsname(name, DEFAULT_MACHINE_ARCHITECTURE, buf,
1578 "Bad DEFAULT_MACHINE_ARCHITECTURE %s");
1579 fprintf(inFile, "#ifndef %s\n# define %s\n#endif\n", buf, buf);
1583 # if defined CROSSCOMPILE
1584 if (CrossCompiling && defaultMachineArchitecture) {
1585 parse_utsname(name, defaultMachineArchitecture, buf,
1586 "Bad defaultMachineArchitecture syntax %s");
1587 fprintf(inFile, "#ifndef %s\n# define %s\n#endif\n", buf, buf);
1591 # if defined CROSSCOMPILE
1593 get_cross_compile_dir(inFile);
1596 fprintf(inFile, "#define CrossCompiling NO\n");
1597 # if defined CROSSCOMPILE
1598 if (CrossCompiling && sys == LinuX)
1600 # if defined CROSSCOMPILE || defined linux || defined(__GLIBC__)
1601 # if defined(CROSSCOMPILE) && defined(__linux__)
1604 get_distrib (inFile);
1606 # if defined linux || defined(__GLIBC__)
1607 # if defined CROSSCOMPILE
1608 if (!CrossCompiling)
1610 get_libc_version (inFile);
1611 # if defined CROSSCOMPILE
1613 fprintf(inFile,"#define DefaultLinuxCLibMajorVersion %d\n",
1615 fprintf(inFile,"#define DefaultLinuxCLibMinorVersion %d\n",
1617 fprintf(inFile,"#define DefaultLinuxCLibTeenyVersion 0\n");
1620 # endif /* linux || __GLIBC__ */
1621 # if defined CROSSCOMPILE || defined linux || defined(__GLIBC__)
1622 # if defined CROSSCOMPILE && defined(__linux__)
1625 get_ld_version(inFile);
1627 # if defined (sun) && defined(SVR4)
1628 get_sun_compiler_versions (inFile);
1630 # if defined CROSSCOMPILE || defined __GNUC__
1631 # if defined CROSSCOMPILE
1635 char name[PATH_MAX];
1636 if (get_gcc(name)) {
1637 get_gcc_version (inFile,name);
1638 # if defined CROSSCOMPILE || !defined __UNIXOS2__
1639 # if defined CROSSCOMPILE
1642 get_gcc_incdir(inFile,name);
1647 # if defined __FreeBSD__
1648 # if defined CROSSCOMPILE
1651 get_binary_format(inFile);
1654 #endif /* !WIN32 && !__UNIXOS2__*/
1656 # ifdef CROSSCOMPILE
1657 else if (sys == win32 && !CrossCompiling)
1661 static char* os_names[] = { "Win32s", "Windows 95", "Windows NT" };
1663 memset(&osvi, 0, sizeof(OSVERSIONINFO));
1664 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
1665 GetVersionEx (&osvi);
1667 fprintf (inFile, "#define DefaultOSName Microsoft %s\n",
1668 os_names[osvi.dwPlatformId]);
1670 fprintf(inFile, "#define DefaultOSMajorVersion %d\n", osvi.dwMajorVersion);
1671 fprintf(inFile, "#define DefaultOSMinorVersion %d\n", osvi.dwMinorVersion);
1672 fprintf(inFile, "#define DefaultOSTeenyVersion %d\n",
1673 osvi.dwBuildNumber & 0xFFFF);
1677 else if (sys == emx)
1679 #if defined CROSSCOMPILE || defined __UNIXOS2__
1681 fprintf(inFile, "#define DefaultOSMajorVersion 4\n");
1682 fprintf(inFile, "#define DefaultOSMinorVersion 0\n");
1683 fprintf(inFile, "#define DefaultOSTeenyVersion 0\n");
1686 #if defined(__OpenBSD__) || defined(__DragonFly__)
1687 get_stackprotector(inFile);
1693 cppit(const char *imakefile, const char *template, const char *masterc,
1694 FILE *outfd, const char *outfname)
1698 haveImakefileC = TRUE;
1699 inFile = fopen(masterc, "w");
1701 LogFatal("Cannot open %s for output.", masterc);
1702 if (fprintf(inFile, "%s\n", ImakefileCHeader) < 0 ||
1703 define_os_defaults(inFile) ||
1704 optional_include(inFile, "IMAKE_LOCAL_DEFINES", "localdefines") ||
1705 optional_include(inFile, "IMAKE_ADMIN_DEFINES", "admindefines") ||
1706 fprintf(inFile, "#define %s <%s>\n", ImakeDefSym, imakefile) < 0 ||
1707 fprintf(inFile, LocalDefineFmt, ImakeTmplSym, template) < 0 ||
1708 fprintf(inFile, IncludeFmt, ImakeTmplSym) < 0 ||
1709 optional_include(inFile, "IMAKE_ADMIN_MACROS", "adminmacros") ||
1710 optional_include(inFile, "IMAKE_LOCAL_MACROS", "localmacros") ||
1713 LogFatal("Cannot write to %s.", masterc);
1717 doit(outfd, cpp, cpp_argv);
1718 CleanCppOutput(outfd, outfname);
1724 doit(NULL, make_argv[0], make_argv);
1728 CleanCppInput(const char *imakefile)
1730 FILE *outFile = NULL;
1732 char *buf, /* buffer for file content */
1733 *pbuf, /* walking pointer to buf */
1734 *punwritten, /* pointer to unwritten portion of buf */
1735 *ptoken, /* pointer to # token */
1736 *pend, /* pointer to end of # token */
1737 savec; /* temporary character holder */
1742 * grab the entire file.
1744 if (!(inFile = fopen(imakefile, "r")))
1745 LogFatal("Cannot open %s for input.", imakefile);
1746 if (fstat(fileno(inFile), &st) < 0)
1747 LogFatal("Cannot stat %s for size.", imakefile);
1748 buf = Emalloc((int)st.st_size+3);
1749 count = fread(buf + 2, 1, st.st_size, inFile);
1750 if (count == 0 && st.st_size != 0)
1751 LogFatal("Cannot read %s:", imakefile);
1755 buf[count + 2] = '\0';
1757 punwritten = pbuf = buf + 2;
1759 /* for compatibility, replace make comments for cpp */
1760 if (*pbuf == '#' && pbuf[-1] == '\n' && pbuf[-2] != '\\') {
1762 while (*ptoken == ' ' || *ptoken == '\t')
1765 while (*pend && *pend != ' ' && *pend != '\t' && *pend != '\n' && *pend != '\r')
1769 if (strcmp(ptoken, "define") &&
1770 strcmp(ptoken, "if") &&
1771 strcmp(ptoken, "ifdef") &&
1772 strcmp(ptoken, "ifndef") &&
1773 strcmp(ptoken, "include") &&
1774 strcmp(ptoken, "line") &&
1775 strcmp(ptoken, "else") &&
1776 strcmp(ptoken, "elif") &&
1777 strcmp(ptoken, "endif") &&
1778 strcmp(ptoken, "error") &&
1779 strcmp(ptoken, "pragma") &&
1780 strcmp(ptoken, "undef")) {
1781 if (outFile == NULL) {
1785 char *tmpImakefileName = Strdup(tmpImakefileTemplate);
1786 #ifndef HAVE_MKSTEMP
1787 if (mktemp(tmpImakefileName) == NULL ||
1788 (outFile = fopen(tmpImakefileName, "w+")) == NULL) {
1789 LogFatal("Cannot open %s for write.",
1793 fd=mkstemp(tmpImakefileName);
1795 outFile = fdopen(fd, "w");
1796 if (outFile == NULL) {
1798 unlink(tmpImakefileName); close(fd);
1800 LogFatal("Cannot open %s for write.",
1804 tmpImakefile = tmpImakefileName;
1806 writetmpfile(outFile, punwritten, pbuf-punwritten,
1808 if (ptoken > pbuf + 1)
1809 writetmpfile(outFile, "XCOMM", 5, tmpImakefile);
1811 writetmpfile(outFile, "XCOMM ", 6, tmpImakefile);
1812 punwritten = pbuf + 1;
1819 writetmpfile(outFile, punwritten, pbuf-punwritten, tmpImakefile);
1822 return tmpImakefile;
1829 CleanCppOutput(FILE *tmpfd, const char *tmpfname)
1834 while((input = ReadLine(tmpfd, tmpfname))) {
1835 if (isempty(input)) {
1839 if (fixup_whitespace)
1841 #if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE
1847 if (fixup_whitespace)
1849 #if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE
1850 KludgeOutputLine(&input);
1852 writetmpfile(tmpfd, input, strlen(input), tmpfname);
1854 writetmpfile(tmpfd, "\n", 1, tmpfname);
1857 #ifdef NFS_STDOUT_BUG
1859 * On some systems, NFS seems to leave a large number of nulls at
1860 * the end of the file. Ralph Swick says that this kludge makes the
1863 ftruncate (fileno(tmpfd), (off_t)ftell(tmpfd));
1868 * Determine if a line has nothing in it. As a side effect, we trim white
1869 * space from the end of the line. Cpp magic cookies are also thrown away.
1870 * "XCOMM" token is transformed to "#".
1878 * Check for lines of the form
1887 if (*pend == 'l' && pend[1] == 'i' && pend[2] == 'n' &&
1888 pend[3] == 'e' && pend[4] == ' ')
1890 if (isdigit(*pend)) {
1893 } while (isdigit(*pend));
1894 if (*pend == '\n' || *pend == '\0')
1896 if (*pend++ == ' ' && *pend == '"')
1902 for (pend = line; *pend; pend++) {
1903 if (*pend == 'X' && pend[1] == 'C' && pend[2] == 'O' &&
1904 pend[3] == 'M' && pend[4] == 'M' &&
1905 (pend == line || pend[-1] == ' ' || pend[-1] == '\t' || pend[-1] == '\r') &&
1906 (pend[5] == ' ' || pend[5] == '\t' || pend[5] == '\r' || pend[5] == '\0'))
1909 memmove(pend+1, pend+5, strlen(pend+5)+1);
1912 if (magic_make_vars)
1915 #if defined CROSSCOMPILE || defined MAGIC_MAKE_VARS
1916 if (*pend == 'X' && pend[1] == 'V' && pend[2] == 'A' &&
1922 if (pend[4] == 'd' && pend[5] == 'e' && pend[6] == 'f' &&
1923 pend[7] >= '0' && pend[7] <= '9')
1926 sprintf(varbuf, "%0.4d", xvariable);
1927 strncpy(pend+4, varbuf, 4);
1928 xvariables[i] = xvariable;
1929 xvariable = (xvariable + 1) % 10000;
1931 else if (pend[4] == 'u' && pend[5] == 's' &&
1932 pend[6] == 'e' && pend[7] >= '0' &&
1936 sprintf(varbuf, "%0.4d", xvariables[i]);
1937 strncpy(pend+4, varbuf, 4);
1944 while (--pend >= line && (*pend == ' ' || *pend == '\t' || *pend == '\r')) ;
1946 return (*line == '\0');
1951 ReadLine(FILE *tmpfd, const char *tmpfname)
1953 static boolean initialized = FALSE;
1954 static char *buf, *pline, *end;
1955 register char *p1, *p2;
1957 if (! initialized) {
1968 if (fstat(fileno(tmpfd), &st) < 0)
1969 LogFatal("cannot stat %s for size", tmpMakefile);
1970 pline = buf = Emalloc((int)st.st_size+1);
1971 total_red = fread(buf, 1, st.st_size, tmpfd);
1972 if (total_red == 0 && st.st_size != 0)
1973 LogFatal("cannot read %s", tmpMakefile);
1974 end = buf + total_red;
1977 #if defined(SYSV) || defined(WIN32) || defined(USE_FREOPEN)
1978 tmpfd = freopen(tmpfname, "w+", tmpfd);
1980 if (! tmpfd) /* if failed try again */
1981 tmpfd = freopen(tmpfname, "w+", fp);
1984 LogFatal("cannot reopen %s\n", tmpfname);
1986 ftruncate(fileno(tmpfd), (off_t) 0);
1989 fprintf (tmpfd, "# Makefile generated by imake - do not edit!\n");
1992 for (p1 = pline; p1 < end; p1++) {
1993 if (*p1 == '@' && *(p1+1) == '@'
1994 /* ignore ClearCase version-extended pathnames */
1995 && !(p1 != pline && !isspace(*(p1-1)) && *(p1+2) == '/'))
1998 p1++; /* skip over second @ */
2001 else if (*p1 == '\n') { /* real EOL */
2002 #if defined CROSSCOMPILE || defined WIN32
2003 # if defined CROSSCOMPILE
2007 if (p1 > pline && p1[-1] == '\r')
2017 * return NULL at the end of the file.
2019 p2 = (pline == p1 ? NULL : pline);
2025 writetmpfile(FILE *fd, const char *buf, int cnt, const char *fname)
2027 if (fwrite(buf, sizeof(char), cnt, fd) == -1)
2028 LogFatal("Cannot write to %s.", fname);
2036 if ((p = malloc(size)) == NULL)
2037 LogFatal("Cannot allocate %d bytes", size);
2041 #if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE
2043 KludgeOutputLine(char **pline)
2046 char quotechar = '\0';
2049 case '#': /*Comment - ignore*/
2051 case '\t': /*Already tabbed - ignore it*/
2053 case ' ': /*May need a tab*/
2055 # ifdef CROSSCOMPILE
2058 # if defined CROSSCOMPILE || defined INLINE_SYNTAX
2060 if (*p == '<' && p[1] == '<') { /* inline file close */
2068 * The following cases should not be treated as beginning of
2070 * variable := name (GNU make)
2071 * variable = .*:.* (':' should be allowed as value)
2072 * sed 's:/a:/b:' (: used in quoted values)
2076 if (quotechar == '\\' ||
2078 # if defined CROSSCOMPILE || defined WIN32
2080 # if defined CROSSCOMPILE
2083 quotechar != ')') &&
2105 # ifdef CROSSCOMPILE
2106 if (remove_cpp_leadspace)
2108 # if defined CROSSCOMPILE || defined REMOVE_CPP_LEADSPACE
2110 if (!InRule && **pline == ' ') {
2111 while (**pline == ' ')
2117 # if defined CROSSCOMPILE || defined INLINE_SYNTAX
2119 if (inline_syntax) {
2120 if (p[1] == '<') /* inline file start */
2128 while (**pline == ' ')
2135 if (InRule && **pline == ' ')
2142 KludgeResetRule(void)
2148 Strdup(const char *cp)
2150 char *new = Emalloc(strlen(cp) + 1);
2158 CrossCompileCPP(void)
2162 if (crosscompile_use_cc_e)
2165 cpp = strrchr(crosscompile_cpp,'/');
2167 cpp = crosscompile_cpp;
2171 len = strlen(cpp) + strlen(CrossCompileDir) + 2;
2174 (void)snprintf(c, len,"%s/%s",CrossCompileDir,cpp);
2183 get_cross_compile_dir(FILE *inFile)
2185 fprintf(inFile, "#define CrossCompileDir %s\n",
2187 fprintf(inFile, "#define CrossCompiling YES\n");