1bb2e14f3Smrg 2bb2e14f3Smrg/*************************************************************************** 3bb2e14f3Smrg * * 4bb2e14f3Smrg * Porting Note * 5bb2e14f3Smrg * * 6bb2e14f3Smrg * Add the value of BOOTSTRAPCFLAGS to the cpp_argv table so that it will * 7bb2e14f3Smrg * be passed to the template file. * 8bb2e14f3Smrg * * 9bb2e14f3Smrg ***************************************************************************/ 10bb2e14f3Smrg/* 11bb2e14f3Smrg * 12bb2e14f3SmrgCopyright (c) 1985, 1986, 1987, 1998 The Open Group 13bb2e14f3Smrg 14bb2e14f3SmrgPermission to use, copy, modify, distribute, and sell this software and its 15bb2e14f3Smrgdocumentation for any purpose is hereby granted without fee, provided that 16bb2e14f3Smrgthe above copyright notice appear in all copies and that both that 17bb2e14f3Smrgcopyright notice and this permission notice appear in supporting 18bb2e14f3Smrgdocumentation. 19bb2e14f3Smrg 20bb2e14f3SmrgThe above copyright notice and this permission notice shall be included in 21bb2e14f3Smrgall copies or substantial portions of the Software. 22bb2e14f3Smrg 23bb2e14f3SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24bb2e14f3SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25bb2e14f3SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26bb2e14f3SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 27bb2e14f3SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28bb2e14f3SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29bb2e14f3Smrg 30bb2e14f3SmrgExcept as contained in this notice, the name of The Open Group shall not be 31bb2e14f3Smrgused in advertising or otherwise to promote the sale, use or other dealings 32bb2e14f3Smrgin this Software without prior written authorization from The Open Group. 33bb2e14f3Smrg * 34bb2e14f3Smrg * Original Author: 35bb2e14f3Smrg * Todd Brunhoff 36bb2e14f3Smrg * Tektronix, inc. 37bb2e14f3Smrg * While a guest engineer at Project Athena, MIT 38bb2e14f3Smrg * 39bb2e14f3Smrg * imake: the include-make program. 40bb2e14f3Smrg * 41bb2e14f3Smrg * Usage: imake [-Idir] [-Ddefine] [-T template] [-f imakefile ] [-C Imakefile.c ] [-s] [-e] [-v] [make flags] 42bb2e14f3Smrg * 43bb2e14f3Smrg * Imake takes a template file (Imake.tmpl) and a prototype (Imakefile) 44bb2e14f3Smrg * and runs cpp on them producing a Makefile. It then optionally runs make 45bb2e14f3Smrg * on the Makefile. 46bb2e14f3Smrg * Options: 47bb2e14f3Smrg * -D define. Same as cpp -D argument. 48bb2e14f3Smrg * -U undefine. Same as cpp -U argument. 49bb2e14f3Smrg * -W warning. Same as cpp -W argument. 50bb2e14f3Smrg * -I Include directory. Same as cpp -I argument. 51bb2e14f3Smrg * -T template. Designate a template other 52bb2e14f3Smrg * than Imake.tmpl 53bb2e14f3Smrg * -f specify the Imakefile file 54bb2e14f3Smrg * -C specify the name to use instead of Imakefile.c 55bb2e14f3Smrg * -s[F] show. Show the produced makefile on the standard 56bb2e14f3Smrg * output. Make is not run is this case. If a file 57bb2e14f3Smrg * argument is provided, the output is placed there. 58bb2e14f3Smrg * -e[F] execute instead of show; optionally name Makefile F 59bb2e14f3Smrg * -v verbose. Show the make command line executed. 60bb2e14f3Smrg * 61bb2e14f3Smrg * Environment variables: 62bb2e14f3Smrg * 63bb2e14f3Smrg * IMAKEINCLUDE Include directory to use in addition to "." 64bb2e14f3Smrg * IMAKECPP Cpp to use instead of /lib/cpp 65bb2e14f3Smrg * IMAKEMAKE make program to use other than what is 66bb2e14f3Smrg * found by searching the $PATH variable. 67bb2e14f3Smrg * Other features: 68bb2e14f3Smrg * imake reads the entire cpp output into memory and then scans it 69e5db2183Smrg * for occurrences of "@@". If it encounters them, it replaces it with 70bb2e14f3Smrg * a newline. It also trims any trailing white space on output lines 71bb2e14f3Smrg * (because make gets upset at them). This helps when cpp expands 72bb2e14f3Smrg * multi-line macros but you want them to appear on multiple lines. 73e5db2183Smrg * It also changes occurrences of "XCOMM" to "#", to avoid problems 74bb2e14f3Smrg * with treating commands as invalid preprocessor commands. 75bb2e14f3Smrg * 76bb2e14f3Smrg * The macros MAKEFILE and MAKE are provided as macros 77bb2e14f3Smrg * to make. MAKEFILE is set to imake's makefile (not the constructed, 78bb2e14f3Smrg * preprocessed one) and MAKE is set to argv[0], i.e. the name of 79bb2e14f3Smrg * the imake program. 80bb2e14f3Smrg * 81bb2e14f3Smrg * Theory of operation: 82bb2e14f3Smrg * 1. Determine the name of the imakefile from the command line (-f) 83bb2e14f3Smrg * or from the content of the current directory (Imakefile or imakefile). 84bb2e14f3Smrg * Call this <imakefile>. This gets added to the arguments for 85bb2e14f3Smrg * make as MAKEFILE=<imakefile>. 86bb2e14f3Smrg * 2. Determine the name of the template from the command line (-T) 87bb2e14f3Smrg * or the default, Imake.tmpl. Call this <template> 88bb2e14f3Smrg * 3. Determine the name of the imakeCfile from the command line (-C) 89bb2e14f3Smrg * or the default, Imakefile.c. Call this <imakeCfile> 90bb2e14f3Smrg * 4. Store lines of input into <imakeCfile>: 91bb2e14f3Smrg * - A c-style comment header (see ImakefileCHeader below), used 92bb2e14f3Smrg * to recognize temporary files generated by imake. 93bb2e14f3Smrg * - If DEFAULT_OS_NAME is defined, format the utsname struct and 94bb2e14f3Smrg * call the result <defaultOsName>. Add: 95bb2e14f3Smrg * #define DefaultOSName <defaultOsName> 96bb2e14f3Smrg * - If DEFAULT_OS_MAJOR_REV is defined, format the utsname struct 97bb2e14f3Smrg * and call the result <defaultOsMajorVersion>. Add: 98bb2e14f3Smrg * #define DefaultOSMajorVersion <defaultOsMajorVersion> 99bb2e14f3Smrg * - If DEFAULT_OS_MINOR_REV is defined, format the utsname struct 100bb2e14f3Smrg * and call the result <defaultOsMinorVersion>. Add: 101bb2e14f3Smrg * #define DefaultOSMinorVersion <defaultOsMinorVersion> 102bb2e14f3Smrg * - If DEFAULT_OS_TEENY_REV is defined, format the utsname struct 103bb2e14f3Smrg * and call the result <defaultOsTeenyVersion>. Add: 104bb2e14f3Smrg * #define DefaultOSTeenyVersion <defaultOsTeenyVersion> 105bb2e14f3Smrg * - If DEFAULT_MACHINE_ARCITECTURE is defined, format the utsname struct 106bb2e14f3Smrg * and define the corresponding macro. (For example on the amiga, 107bb2e14f3Smrg * this will define amiga in addition to m68k). 108bb2e14f3Smrg * - If the file "localdefines" is readable in the current 109bb2e14f3Smrg * directory, print a warning message to stderr and add: 110bb2e14f3Smrg * #define IMAKE_LOCAL_DEFINES "localdefines" 111bb2e14f3Smrg * #include IMAKE_LOCAL_DEFINES 112bb2e14f3Smrg * - If the file "admindefines" is readable in the current 113bb2e14f3Smrg * directory, print a warning message to stderr and add: 114bb2e14f3Smrg * #define IMAKE_ADMIN_DEFINES "admindefines" 115bb2e14f3Smrg * #include IMAKE_ADMIN_DEFINES 116bb2e14f3Smrg * - The following lines: 117bb2e14f3Smrg * #define INCLUDE_IMAKEFILE < <imakefile> > 118bb2e14f3Smrg * #define IMAKE_TEMPLATE " <template> " 119bb2e14f3Smrg * #include IMAKE_TEMPLATE 120bb2e14f3Smrg * - If the file "adminmacros" is readable in the current 121bb2e14f3Smrg * directory, print a warning message to stderr and add: 122bb2e14f3Smrg * #define IMAKE_ADMIN_MACROS "adminmacros" 123bb2e14f3Smrg * #include IMAKE_ADMIN_MACROS 124bb2e14f3Smrg * - If the file "localmacros" is readable in the current 125bb2e14f3Smrg * directory, print a warning message to stderr and add: 126bb2e14f3Smrg * #define IMAKE_LOCAL_MACROS "localmacros" 127bb2e14f3Smrg * #include IMAKE_LOCAL_MACROS 128bb2e14f3Smrg * 5. Start up cpp and provide it with this file. 129bb2e14f3Smrg * Note that the define for INCLUDE_IMAKEFILE is intended for 130bb2e14f3Smrg * use in the template file. This implies that the imake is 131bb2e14f3Smrg * useless unless the template file contains at least the line 132bb2e14f3Smrg * #include INCLUDE_IMAKEFILE 133bb2e14f3Smrg * 6. Gather the output from cpp, and clean it up, expanding @@ to 134bb2e14f3Smrg * newlines, stripping trailing white space, cpp control lines, 135bb2e14f3Smrg * and extra blank lines, and changing XCOMM to #. This cleaned 136bb2e14f3Smrg * output is placed in a new file, default "Makefile", but can 137bb2e14f3Smrg * be specified with -s or -e options. 138bb2e14f3Smrg * 7. Optionally start up make on the resulting file. 139bb2e14f3Smrg * 140bb2e14f3Smrg * The design of the template makefile should therefore be: 141bb2e14f3Smrg * <set global macros like CFLAGS, etc.> 142bb2e14f3Smrg * <include machine dependent additions> 143bb2e14f3Smrg * #include INCLUDE_IMAKEFILE 144bb2e14f3Smrg * <add any global targets like 'clean' and long dependencies> 145bb2e14f3Smrg */ 146a5399cb1Smrg 147a5399cb1Smrg#include "config.h" 148a5399cb1Smrg 149bb2e14f3Smrg#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) 150bb2e14f3Smrg/* This needs to be before _POSIX_SOURCE gets defined */ 151bb2e14f3Smrg# include <sys/param.h> 152bb2e14f3Smrg# include <sys/types.h> 153bb2e14f3Smrg# include <sys/sysctl.h> 154bb2e14f3Smrg#endif 155bb2e14f3Smrg#include <stdlib.h> 156bb2e14f3Smrg#include <stdio.h> 1571114aea8Smrg#include <stdarg.h> 1581114aea8Smrg#include <X11/Xfuncproto.h> 159a5399cb1Smrg#include <X11/Xosdefs.h> 160bb2e14f3Smrg#include <string.h> 161bb2e14f3Smrg#include <ctype.h> 162bb2e14f3Smrg#ifdef WIN32 163bb2e14f3Smrg# include "Xw32defs.h" 164bb2e14f3Smrg#endif 165bb2e14f3Smrg#include <sys/types.h> 166bb2e14f3Smrg#include <fcntl.h> 167bb2e14f3Smrg#ifdef X_NOT_POSIX 168bb2e14f3Smrg# ifndef WIN32 169bb2e14f3Smrg# include <sys/file.h> 170bb2e14f3Smrg# endif 171bb2e14f3Smrg#else 172bb2e14f3Smrg# include <unistd.h> 173bb2e14f3Smrg#endif 174bb2e14f3Smrg#ifdef ISC 175bb2e14f3Smrg# include <unistd.h> 176bb2e14f3Smrg#endif 177bb2e14f3Smrg#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) 178bb2e14f3Smrg# include <signal.h> 179bb2e14f3Smrg#else 180bb2e14f3Smrg# define _POSIX_SOURCE 181bb2e14f3Smrg# include <signal.h> 182bb2e14f3Smrg# undef _POSIX_SOURCE 183bb2e14f3Smrg#endif 184bb2e14f3Smrg#if !defined(SIGCHLD) && defined(SIGCLD) 185bb2e14f3Smrg# define SIGCHLD SIGCLD 186bb2e14f3Smrg#endif 187bb2e14f3Smrg#include <sys/stat.h> 188bb2e14f3Smrg#ifndef X_NOT_POSIX 189bb2e14f3Smrg# ifdef _POSIX_SOURCE 190bb2e14f3Smrg# ifdef __SCO__ 191bb2e14f3Smrg# include <sys/procset.h> 192bb2e14f3Smrg# include <sys/siginfo.h> 193bb2e14f3Smrg# endif 194bb2e14f3Smrg# include <sys/wait.h> 195bb2e14f3Smrg# else 196bb2e14f3Smrg# define _POSIX_SOURCE 197bb2e14f3Smrg# include <sys/wait.h> 198bb2e14f3Smrg# undef _POSIX_SOURCE 199bb2e14f3Smrg# endif 200bb2e14f3Smrg# define waitCode(w) WEXITSTATUS(w) 201bb2e14f3Smrg# define waitSig(w) WTERMSIG(w) 202bb2e14f3Smrgtypedef int waitType; 203bb2e14f3Smrg#else /* X_NOT_POSIX */ 204bb2e14f3Smrg# ifdef SYSV 205bb2e14f3Smrg# define waitCode(w) (((w) >> 8) & 0x7f) 206bb2e14f3Smrg# define waitSig(w) ((w) & 0xff) 207bb2e14f3Smrgtypedef int waitType; 208bb2e14f3Smrg# else /* SYSV */ 209bb2e14f3Smrg# ifdef WIN32 210bb2e14f3Smrg# include <process.h> 211bb2e14f3Smrgtypedef int waitType; 212bb2e14f3Smrg# else 213bb2e14f3Smrg# include <sys/wait.h> 214bb2e14f3Smrg# define waitCode(w) ((w).w_T.w_Retcode) 215bb2e14f3Smrg# define waitSig(w) ((w).w_T.w_Termsig) 216bb2e14f3Smrgtypedef union wait waitType; 217bb2e14f3Smrg# endif 218bb2e14f3Smrg# endif 219bb2e14f3Smrg# ifndef WIFSIGNALED 220bb2e14f3Smrg# define WIFSIGNALED(w) waitSig(w) 221bb2e14f3Smrg# endif 222bb2e14f3Smrg# ifndef WIFEXITED 223bb2e14f3Smrg# define WIFEXITED(w) waitCode(w) 224bb2e14f3Smrg# endif 225bb2e14f3Smrg#endif /* X_NOT_POSIX */ 226a5399cb1Smrg#include <stdlib.h> 227bb2e14f3Smrg#include <errno.h> 228bb2e14f3Smrg#ifdef __minix_vmd 229a5399cb1Smrg# define USE_FREOPEN 1 230bb2e14f3Smrg#endif 231bb2e14f3Smrg 232bb2e14f3Smrg#ifndef WIN32 233a5399cb1Smrg# include <sys/utsname.h> 234bb2e14f3Smrg#else 235a5399cb1Smrg# include <windows.h> 236bb2e14f3Smrg#endif 237bb2e14f3Smrg#ifndef SYS_NMLN 238bb2e14f3Smrg# ifdef _SYS_NMLN 239bb2e14f3Smrg# define SYS_NMLN _SYS_NMLN 240bb2e14f3Smrg# else 241bb2e14f3Smrg# define SYS_NMLN 257 242bb2e14f3Smrg# endif 243bb2e14f3Smrg#endif 244bb2e14f3Smrg#if defined(linux) || defined(__GNU__) || defined(__GLIBC__) 245a5399cb1Smrg# include <limits.h> 246a5399cb1Smrg# include <stdio.h> 247bb2e14f3Smrg#endif 248bb2e14f3Smrg#ifdef __QNX__ 249a5399cb1Smrg# include <unix.h> 250bb2e14f3Smrg#endif 251bb2e14f3Smrg 252bb2e14f3Smrg#if defined(__NetBSD__) /* see code clock in init() below */ 253a5399cb1Smrg# include <sys/utsname.h> 254bb2e14f3Smrg#endif 255bb2e14f3Smrg 256bb2e14f3Smrgtypedef unsigned char boolean; 257bb2e14f3Smrg#define TRUE 1 258bb2e14f3Smrg#define FALSE 0 259bb2e14f3Smrg 260a5399cb1Smrg#include "imakemdep.h" 261bb2e14f3Smrg#ifdef CROSSCOMPILE 262bb2e14f3Smrg# include "imakemdep_cpp.h" 263bb2e14f3Smrg#endif 264bb2e14f3Smrg 265bb2e14f3Smrg#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 266bb2e14f3Smrgint InRule = FALSE; 267bb2e14f3Smrg#endif 268bb2e14f3Smrg#if defined CROSSCOMPILE || defined INLINE_SYNTAX 269bb2e14f3Smrgint InInline = 0; 270bb2e14f3Smrg#endif 271bb2e14f3Smrg#if defined CROSSCOMPILE || defined MAGIC_MAKE_VARS 272bb2e14f3Smrgint xvariable = 0; 273bb2e14f3Smrgint xvariables[10]; 274bb2e14f3Smrg#endif 275bb2e14f3Smrg 276bb2e14f3Smrg#ifndef PATH_MAX 277a5399cb1Smrg# define PATH_MAX 1024 278bb2e14f3Smrg#endif 279bb2e14f3Smrg 280bb2e14f3Smrg/* 281bb2e14f3Smrg * Some versions of cpp reduce all tabs in macro expansion to a single 282bb2e14f3Smrg * space. In addition, the escaped newline may be replaced with a 283bb2e14f3Smrg * space instead of being deleted. Blech. 284bb2e14f3Smrg */ 285bb2e14f3Smrgvoid KludgeOutputLine(char **), KludgeResetRule(void); 286bb2e14f3Smrg 287bb2e14f3Smrg#ifndef CROSSCOMPILE 288bb2e14f3Smrg# ifdef USE_CC_E 289bb2e14f3Smrg# ifndef DEFAULT_CC 290bb2e14f3Smrg# define DEFAULT_CC "cc" 291bb2e14f3Smrg# endif 292bb2e14f3Smrg# else 293bb2e14f3Smrg# ifndef DEFAULT_CPP 294bb2e14f3Smrg# ifdef CPP_PROGRAM 295bb2e14f3Smrg# define DEFAULT_CPP CPP_PROGRAM 296bb2e14f3Smrg# else 297bb2e14f3Smrg# define DEFAULT_CPP "/lib/cpp" 298bb2e14f3Smrg# endif 299bb2e14f3Smrg# endif 300bb2e14f3Smrg# endif 301bb2e14f3Smrg#endif 302bb2e14f3Smrg 3031114aea8Smrgconst char *cpp = NULL; 304bb2e14f3Smrg 3051114aea8Smrgconst char *tmpMakefile; 3061114aea8Smrgconst char *tmpMakefileTemplate = "/tmp/Imf.XXXXXX"; 3071114aea8Smrgconst char *tmpImakefile; 3081114aea8Smrgconst char *tmpImakefileTemplate = "/tmp/IIf.XXXXXX"; 3091114aea8Smrgconst char *make_argv[ ARGUMENTS ] = { 310bb2e14f3Smrg#ifdef WIN32 311bb2e14f3Smrg "nmake" 312bb2e14f3Smrg#else 313bb2e14f3Smrg "make" 314bb2e14f3Smrg#endif 315bb2e14f3Smrg}; 316bb2e14f3Smrg 317bb2e14f3Smrgint make_argindex; 318bb2e14f3Smrgint cpp_argindex; 3191114aea8Smrgconst char *Imakefile = NULL; 3201114aea8Smrgconst char *Makefile = "Makefile"; 3211114aea8Smrgconst char *Template = "Imake.tmpl"; 3221114aea8Smrgconst char *ImakefileC = "Imakefile.c"; 323bb2e14f3Smrgboolean haveImakefileC = FALSE; 3241114aea8Smrgconst char *cleanedImakefile = NULL; 3251114aea8Smrgconst char *program; 3261114aea8Smrgconst char *FindImakefile(const char *Imakefile); 3271114aea8Smrgchar *ReadLine(FILE *tmpfd, const char *tmpfname); 3281114aea8Smrgconst char *CleanCppInput(const char *imakefile); 3291114aea8Smrgchar *Strdup(const char *cp); 330e5db2183Smrgchar *Emalloc(size_t size); 3311114aea8Smrgvoid LogFatal(const char *x0, ...) _X_ATTRIBUTE_PRINTF(1, 2); 3321114aea8Smrgvoid LogMsg(const char *x0, ...) _X_ATTRIBUTE_PRINTF(1, 2); 333bb2e14f3Smrg 334bb2e14f3Smrgvoid showit(FILE *fd); 335bb2e14f3Smrgvoid wrapup(void); 336bb2e14f3Smrgvoid init(void); 3371114aea8Smrgvoid AddMakeArg(const char *arg); 3381114aea8Smrgvoid AddCppArg(const char *arg); 339bb2e14f3Smrg#ifdef CROSSCOMPILE 340bb2e14f3Smrgchar *CrossCompileCPP(void); 341bb2e14f3Smrg#endif 342bb2e14f3Smrgvoid SetOpts(int argc, char **argv); 3431114aea8Smrgvoid CheckImakefileC(const char *masterc); 3441114aea8Smrgvoid cppit(const char *imakefile, const char *template, const char *masterc, 3451114aea8Smrg FILE *outfd, const char *outfname); 346bb2e14f3Smrgvoid makeit(void); 3471114aea8Smrgvoid CleanCppOutput(FILE *tmpfd, const char *tmpfname); 348bb2e14f3Smrgboolean isempty(char *line); 349e5db2183Smrgvoid writetmpfile(FILE *fd, const char *buf, size_t cnt, const char *fname); 350bb2e14f3Smrgvoid catch(int sig); 3511114aea8Smrgvoid showargs(const char **argv); 3521114aea8Smrgboolean optional_include(FILE *inFile, const char *defsym, const char *fname); 3531114aea8Smrgvoid doit(FILE *outfd, const char *cmd, const char **argv); 354bb2e14f3Smrgboolean define_os_defaults(FILE *inFile); 355bb2e14f3Smrg#ifdef CROSSCOMPILE 356bb2e14f3Smrgstatic void get_cross_compile_dir(FILE *inFile); 357bb2e14f3Smrg#endif 358bb2e14f3Smrg#ifdef CROSSCOMPILEDIR 3591114aea8Smrgconst char *CrossCompileDir = CROSSCOMPILEDIR; 360bb2e14f3Smrg#else 3611114aea8Smrgconst char *CrossCompileDir = ""; 362bb2e14f3Smrg#endif 363bb2e14f3Smrgboolean CrossCompiling = FALSE; 364bb2e14f3Smrg 365bb2e14f3Smrg 366bb2e14f3Smrg 367bb2e14f3Smrgboolean verbose = FALSE; 368bb2e14f3Smrgboolean show = TRUE; 369bb2e14f3Smrg 370bb2e14f3Smrgint 371bb2e14f3Smrgmain(int argc, char *argv[]) 372bb2e14f3Smrg{ 373bb2e14f3Smrg FILE *tmpfd = NULL; 374bb2e14f3Smrg char makeMacro[ BUFSIZ ]; 375bb2e14f3Smrg char makefileMacro[ BUFSIZ ]; 376bb2e14f3Smrg int lenCrossCompileDir = 0; 377bb2e14f3Smrg 378bb2e14f3Smrg program = argv[0]; 379bb2e14f3Smrg init(); 380bb2e14f3Smrg 381bb2e14f3Smrg lenCrossCompileDir = strlen(CrossCompileDir); 382bb2e14f3Smrg if (lenCrossCompileDir) { 383bb2e14f3Smrg if (lenCrossCompileDir > (PATH_MAX - 20)) 384bb2e14f3Smrg LogFatal("Cross compile directory path too long %s\n", 385bb2e14f3Smrg CrossCompileDir); 386bb2e14f3Smrg else 387bb2e14f3Smrg CrossCompiling = TRUE; 388bb2e14f3Smrg } 389bb2e14f3Smrg 390bb2e14f3Smrg SetOpts(argc, argv); 391bb2e14f3Smrg Imakefile = FindImakefile(Imakefile); 392bb2e14f3Smrg CheckImakefileC(ImakefileC); 393bb2e14f3Smrg if (Makefile) { 394bb2e14f3Smrg tmpMakefile = Makefile; 395bb2e14f3Smrg if ((tmpfd = fopen(tmpMakefile, "w+")) == NULL) 396bb2e14f3Smrg LogFatal("Cannot create temporary file %s.", tmpMakefile); 397bb2e14f3Smrg } else { 3981114aea8Smrg char *tmpMakefileName = Strdup(tmpMakefileTemplate); 399e5db2183Smrg 4005afa940dSmrg#ifndef HAVE_MKSTEMP 4011114aea8Smrg if (mktemp(tmpMakefileName) == NULL || 4021114aea8Smrg (tmpfd = fopen(tmpMakefileName, "w+")) == NULL) { 4031114aea8Smrg LogFatal("Cannot create temporary file %s.", tmpMakefileName); 404bb2e14f3Smrg } 405bb2e14f3Smrg#else 406e5db2183Smrg int fd = mkstemp(tmpMakefileName); 407e5db2183Smrg 408bb2e14f3Smrg if (fd == -1 || (tmpfd = fdopen(fd, "w+")) == NULL) { 409bb2e14f3Smrg if (fd != -1) { 4101114aea8Smrg unlink(tmpMakefileName); close(fd); 411bb2e14f3Smrg } 4121114aea8Smrg LogFatal("Cannot create temporary file %s.", tmpMakefileName); 413bb2e14f3Smrg } 414bb2e14f3Smrg#endif 4151114aea8Smrg tmpMakefile = tmpMakefileName; 416bb2e14f3Smrg } 417bb2e14f3Smrg AddMakeArg("-f"); 418bb2e14f3Smrg AddMakeArg( tmpMakefile ); 419bb2e14f3Smrg sprintf(makeMacro, "MAKE=%s", program); 420bb2e14f3Smrg AddMakeArg( makeMacro ); 421bb2e14f3Smrg sprintf(makefileMacro, "MAKEFILE=%s", Imakefile); 422bb2e14f3Smrg AddMakeArg( makefileMacro ); 423bb2e14f3Smrg 424bb2e14f3Smrg cleanedImakefile = CleanCppInput(Imakefile); 425bb2e14f3Smrg cppit(cleanedImakefile, Template, ImakefileC, tmpfd, tmpMakefile); 426bb2e14f3Smrg 427bb2e14f3Smrg if (show) { 428bb2e14f3Smrg if (Makefile == NULL) 429bb2e14f3Smrg showit(tmpfd); 430bb2e14f3Smrg } else 431bb2e14f3Smrg makeit(); 432bb2e14f3Smrg wrapup(); 433bb2e14f3Smrg exit(0); 434bb2e14f3Smrg} 435bb2e14f3Smrg 436bb2e14f3Smrgvoid 437bb2e14f3Smrgshowit(FILE *fd) 438bb2e14f3Smrg{ 439bb2e14f3Smrg char buf[ BUFSIZ ]; 440e5db2183Smrg size_t red; 441bb2e14f3Smrg 4428a954913Smrg fseek(fd, 0, SEEK_SET); 443bb2e14f3Smrg while ((red = fread(buf, 1, BUFSIZ, fd)) > 0) 444bb2e14f3Smrg writetmpfile(stdout, buf, red, "stdout"); 445e5db2183Smrg if (ferror(fd)) 446bb2e14f3Smrg LogFatal("Cannot read %s.", tmpMakefile); 447bb2e14f3Smrg} 448bb2e14f3Smrg 449bb2e14f3Smrgvoid 450bb2e14f3Smrgwrapup(void) 451bb2e14f3Smrg{ 452bb2e14f3Smrg if (tmpMakefile != Makefile) 453bb2e14f3Smrg unlink(tmpMakefile); 454bb2e14f3Smrg if (cleanedImakefile && cleanedImakefile != Imakefile) 455bb2e14f3Smrg unlink(cleanedImakefile); 456bb2e14f3Smrg if (haveImakefileC) 457bb2e14f3Smrg unlink(ImakefileC); 458bb2e14f3Smrg} 459bb2e14f3Smrg 460bb2e14f3Smrgvoid 461bb2e14f3Smrgcatch(int sig) 462bb2e14f3Smrg{ 463bb2e14f3Smrg errno = 0; 4641114aea8Smrg LogFatal("Signal %d.", sig); 465bb2e14f3Smrg} 466bb2e14f3Smrg 467bb2e14f3Smrg/* 468bb2e14f3Smrg * Initialize some variables. 469bb2e14f3Smrg */ 470bb2e14f3Smrgvoid 471bb2e14f3Smrginit(void) 472bb2e14f3Smrg{ 473bb2e14f3Smrg register char *p; 474bb2e14f3Smrg 475bb2e14f3Smrg make_argindex=0; 476bb2e14f3Smrg while (make_argv[ make_argindex ] != NULL) 477bb2e14f3Smrg make_argindex++; 478bb2e14f3Smrg cpp_argindex = 0; 479bb2e14f3Smrg while (cpp_argv[ cpp_argindex ] != NULL) 480bb2e14f3Smrg cpp_argindex++; 481bb2e14f3Smrg 482bb2e14f3Smrg#if defined CROSSCOMPILE 483bb2e14f3Smrg if (sys == netBSD) 484bb2e14f3Smrg if (CrossCompiling) { 485bb2e14f3Smrg LogFatal("fix imake to do crosscompiling for NetBSD\n",""); 486bb2e14f3Smrg } else 487bb2e14f3Smrg#endif 488bb2e14f3Smrg#if defined(__NetBSD__) || defined CROSSCOMPILE 489bb2e14f3Smrg { 490bb2e14f3Smrg struct utsname uts; 491bb2e14f3Smrg static char argument[512]; 492bb2e14f3Smrg 493bb2e14f3Smrg /* 494e5db2183Smrg * Shareable imake configurations require a 495bb2e14f3Smrg * machine identifier. 496bb2e14f3Smrg */ 497bb2e14f3Smrg if (uname(&uts) != 0) 498bb2e14f3Smrg LogFatal("uname(3) failed; can't tell what %s", 499bb2e14f3Smrg "kind of machine you have."); 500bb2e14f3Smrg 501bb2e14f3Smrg memset(argument, 0, sizeof(argument)); 502bb2e14f3Smrg (void)snprintf(argument, sizeof(argument) - 1, 503bb2e14f3Smrg "-D__%s__", uts.machine); 504bb2e14f3Smrg 505bb2e14f3Smrg AddCppArg(argument); 506bb2e14f3Smrg } 507bb2e14f3Smrg#endif /* __NetBSD__ */ 508bb2e14f3Smrg 509bb2e14f3Smrg /* 510bb2e14f3Smrg * See if the standard include directory is different than 511bb2e14f3Smrg * the default. Or if cpp is not the default. Or if the make 512bb2e14f3Smrg * found by the PATH variable is not the default. 513bb2e14f3Smrg */ 514bb2e14f3Smrg if ((p = getenv("IMAKEINCLUDE"))) { 515bb2e14f3Smrg if (*p != '-' || *(p+1) != 'I') 516bb2e14f3Smrg LogFatal("Environment var IMAKEINCLUDE %s", 517bb2e14f3Smrg "must begin with -I"); 518bb2e14f3Smrg AddCppArg(p); 519bb2e14f3Smrg for (; *p; p++) 520bb2e14f3Smrg if (*p == ' ') { 521bb2e14f3Smrg *p++ = '\0'; 522bb2e14f3Smrg AddCppArg(p); 523bb2e14f3Smrg } 524bb2e14f3Smrg } 525bb2e14f3Smrg if ((p = getenv("IMAKECPP"))) 526bb2e14f3Smrg cpp = p; 527bb2e14f3Smrg if ((p = getenv("IMAKEMAKE"))) 528bb2e14f3Smrg make_argv[0] = p; 529bb2e14f3Smrg 530bb2e14f3Smrg if (signal(SIGINT, SIG_IGN) != SIG_IGN) 531bb2e14f3Smrg signal(SIGINT, catch); 532bb2e14f3Smrg#ifdef SIGCHLD 533bb2e14f3Smrg signal(SIGCHLD, SIG_DFL); 534bb2e14f3Smrg#endif 535bb2e14f3Smrg} 536bb2e14f3Smrg 537bb2e14f3Smrgvoid 5381114aea8SmrgAddMakeArg(const char *arg) 539bb2e14f3Smrg{ 540bb2e14f3Smrg errno = 0; 541bb2e14f3Smrg if (make_argindex >= ARGUMENTS-1) 5421114aea8Smrg LogFatal("Out of internal storage."); 543bb2e14f3Smrg make_argv[ make_argindex++ ] = arg; 544bb2e14f3Smrg make_argv[ make_argindex ] = NULL; 545bb2e14f3Smrg} 546bb2e14f3Smrg 547bb2e14f3Smrgvoid 5481114aea8SmrgAddCppArg(const char *arg) 549bb2e14f3Smrg{ 550bb2e14f3Smrg errno = 0; 551bb2e14f3Smrg if (cpp_argindex >= ARGUMENTS-1) 5521114aea8Smrg LogFatal("Out of internal storage."); 553bb2e14f3Smrg cpp_argv[ cpp_argindex++ ] = arg; 554bb2e14f3Smrg cpp_argv[ cpp_argindex ] = NULL; 555bb2e14f3Smrg} 556bb2e14f3Smrg 557bb2e14f3Smrgvoid 558bb2e14f3SmrgSetOpts(int argc, char **argv) 559bb2e14f3Smrg{ 560bb2e14f3Smrg 561bb2e14f3Smrg errno = 0; 562bb2e14f3Smrg /* 563bb2e14f3Smrg * Now gather the arguments for make 564bb2e14f3Smrg */ 565bb2e14f3Smrg for(argc--, argv++; argc; argc--, argv++) { 566bb2e14f3Smrg /* 567bb2e14f3Smrg * We intercept these flags. 568bb2e14f3Smrg */ 569bb2e14f3Smrg if (argv[0][0] == '-') { 570bb2e14f3Smrg if (argv[0][1] == 'D') { 571bb2e14f3Smrg AddCppArg(argv[0]); 572bb2e14f3Smrg } else if (argv[0][1] == 'I') { 573bb2e14f3Smrg AddCppArg(argv[0]); 574bb2e14f3Smrg } else if (argv[0][1] == 'U') { 575bb2e14f3Smrg AddCppArg(argv[0]); 576bb2e14f3Smrg } else if (argv[0][1] == 'W') { 577bb2e14f3Smrg AddCppArg(argv[0]); 578bb2e14f3Smrg } else if (argv[0][1] == 'f') { 579bb2e14f3Smrg if (argv[0][2]) 580bb2e14f3Smrg Imakefile = argv[0]+2; 581bb2e14f3Smrg else { 582bb2e14f3Smrg argc--, argv++; 583bb2e14f3Smrg if (! argc) 5841114aea8Smrg LogFatal("No description arg after -f flag"); 585bb2e14f3Smrg Imakefile = argv[0]; 586bb2e14f3Smrg } 587bb2e14f3Smrg } else if (argv[0][1] == 's') { 588bb2e14f3Smrg if (argv[0][2]) 589bb2e14f3Smrg Makefile = ((argv[0][2] == '-') && !argv[0][3]) ? 590bb2e14f3Smrg NULL : argv[0]+2; 591bb2e14f3Smrg else { 592bb2e14f3Smrg argc--, argv++; 593bb2e14f3Smrg if (!argc) 5941114aea8Smrg LogFatal("No description arg after -s flag"); 595bb2e14f3Smrg Makefile = ((argv[0][0] == '-') && !argv[0][1]) ? 596bb2e14f3Smrg NULL : argv[0]; 597bb2e14f3Smrg } 598bb2e14f3Smrg show = TRUE; 599bb2e14f3Smrg } else if (argv[0][1] == 'e') { 600bb2e14f3Smrg Makefile = (argv[0][2] ? argv[0]+2 : NULL); 601bb2e14f3Smrg show = FALSE; 602bb2e14f3Smrg } else if (argv[0][1] == 'T') { 603bb2e14f3Smrg if (argv[0][2]) 604bb2e14f3Smrg Template = argv[0]+2; 605bb2e14f3Smrg else { 606bb2e14f3Smrg argc--, argv++; 607bb2e14f3Smrg if (! argc) 6081114aea8Smrg LogFatal("No description arg after -T flag"); 609bb2e14f3Smrg Template = argv[0]; 610bb2e14f3Smrg } 611bb2e14f3Smrg } else if (argv[0][1] == 'C') { 612bb2e14f3Smrg if (argv[0][2]) 613bb2e14f3Smrg ImakefileC = argv[0]+2; 614bb2e14f3Smrg else { 615bb2e14f3Smrg argc--, argv++; 616bb2e14f3Smrg if (! argc) 6171114aea8Smrg LogFatal("No imakeCfile arg after -C flag"); 618bb2e14f3Smrg ImakefileC = argv[0]; 619bb2e14f3Smrg } 620bb2e14f3Smrg } else if (argv[0][1] == 'v') { 621bb2e14f3Smrg verbose = TRUE; 622bb2e14f3Smrg } else 623bb2e14f3Smrg AddMakeArg(argv[0]); 624bb2e14f3Smrg } else 625bb2e14f3Smrg AddMakeArg(argv[0]); 626bb2e14f3Smrg } 627bb2e14f3Smrg 628bb2e14f3Smrg#ifndef CROSSCOMPILE 629bb2e14f3Smrg# ifdef USE_CC_E 630bb2e14f3Smrg if (!cpp) 631bb2e14f3Smrg { 632bb2e14f3Smrg AddCppArg("-E"); 633a5399cb1Smrg# ifdef __GNUC__ 634bb2e14f3Smrg if (verbose) 635bb2e14f3Smrg AddCppArg("-v"); 636a5399cb1Smrg# endif 637bb2e14f3Smrg cpp = DEFAULT_CC; 638bb2e14f3Smrg } 639bb2e14f3Smrg# else 640bb2e14f3Smrg if (!cpp) 641bb2e14f3Smrg cpp = DEFAULT_CPP; 642bb2e14f3Smrg# endif 643bb2e14f3Smrg#else 644bb2e14f3Smrg if (!cpp) 645bb2e14f3Smrg cpp = CrossCompileCPP(); 646bb2e14f3Smrg#endif 647bb2e14f3Smrg 648bb2e14f3Smrg cpp_argv[0] = cpp; 649bb2e14f3Smrg AddCppArg(ImakefileC); 650bb2e14f3Smrg} 651bb2e14f3Smrg 6521114aea8Smrgconst char * 653e5db2183SmrgFindImakefile(const char *filename) 654bb2e14f3Smrg{ 655e5db2183Smrg if (filename) { 656e5db2183Smrg if (access(filename, R_OK) < 0) 657e5db2183Smrg LogFatal("Cannot find %s.", filename); 658bb2e14f3Smrg } else { 659bb2e14f3Smrg if (access("Imakefile", R_OK) < 0) { 660bb2e14f3Smrg if (access("imakefile", R_OK) < 0) 6611114aea8Smrg LogFatal("No description file."); 662bb2e14f3Smrg else 663e5db2183Smrg filename = "imakefile"; 664bb2e14f3Smrg } else 665e5db2183Smrg filename = "Imakefile"; 666bb2e14f3Smrg } 667e5db2183Smrg return(filename); 668bb2e14f3Smrg} 669bb2e14f3Smrg 6701114aea8Smrgstatic void _X_ATTRIBUTE_PRINTF(1, 0) 6711114aea8SmrgvLogMsg(const char *fmt, va_list args) 672bb2e14f3Smrg{ 6731114aea8Smrg int error_number = errno; 6741114aea8Smrg 6751114aea8Smrg if (error_number) { 6761114aea8Smrg fprintf(stderr, "%s: ", program); 6771114aea8Smrg fprintf(stderr, "%s\n", strerror(error_number)); 6781114aea8Smrg } 6791114aea8Smrg fprintf(stderr, "%s: ", program); 6801114aea8Smrg vfprintf(stderr, fmt, args); 6811114aea8Smrg fprintf(stderr, "\n"); 682bb2e14f3Smrg} 683bb2e14f3Smrg 684bb2e14f3Smrgvoid 6851114aea8SmrgLogFatal(const char *fmt, ...) 686bb2e14f3Smrg{ 687bb2e14f3Smrg static boolean entered = FALSE; 6881114aea8Smrg va_list args; 689bb2e14f3Smrg 690bb2e14f3Smrg if (entered) 691bb2e14f3Smrg return; 692bb2e14f3Smrg entered = TRUE; 693bb2e14f3Smrg 6941114aea8Smrg va_start(args, fmt); 6951114aea8Smrg vLogMsg(fmt, args); 6961114aea8Smrg va_end(args); 697bb2e14f3Smrg fprintf(stderr, " Stop.\n"); 698bb2e14f3Smrg wrapup(); 699bb2e14f3Smrg exit(1); 700bb2e14f3Smrg} 701bb2e14f3Smrg 702bb2e14f3Smrgvoid 7031114aea8SmrgLogMsg(const char *fmt, ...) 704bb2e14f3Smrg{ 7051114aea8Smrg va_list args; 706bb2e14f3Smrg 7071114aea8Smrg va_start(args, fmt); 7081114aea8Smrg vLogMsg(fmt, args); 7091114aea8Smrg va_end(args); 710bb2e14f3Smrg} 711bb2e14f3Smrg 712bb2e14f3Smrgvoid 7131114aea8Smrgshowargs(const char **argv) 714bb2e14f3Smrg{ 715bb2e14f3Smrg for (; *argv; argv++) 716bb2e14f3Smrg fprintf(stderr, "%s ", *argv); 717bb2e14f3Smrg fprintf(stderr, "\n"); 718bb2e14f3Smrg} 719bb2e14f3Smrg 720bb2e14f3Smrg#define ImakefileCHeader "/* imake - temporary file */" 721bb2e14f3Smrg 722bb2e14f3Smrgvoid 7231114aea8SmrgCheckImakefileC(const char *masterc) 724bb2e14f3Smrg{ 725bb2e14f3Smrg char mkcbuf[1024]; 726bb2e14f3Smrg FILE *inFile; 727bb2e14f3Smrg 728bb2e14f3Smrg if (access(masterc, F_OK) == 0) { 729bb2e14f3Smrg inFile = fopen(masterc, "r"); 730bb2e14f3Smrg if (inFile == NULL) 731bb2e14f3Smrg LogFatal("Refuse to overwrite: %s", masterc); 732bb2e14f3Smrg if ((fgets(mkcbuf, sizeof(mkcbuf), inFile) && 733bb2e14f3Smrg strncmp(mkcbuf, ImakefileCHeader, 734bb2e14f3Smrg sizeof(ImakefileCHeader)-1))) 735bb2e14f3Smrg { 736bb2e14f3Smrg fclose(inFile); 737bb2e14f3Smrg LogFatal("Refuse to overwrite: %s", masterc); 738bb2e14f3Smrg } 73939f9c979Smrg else 74039f9c979Smrg fclose(inFile); 741bb2e14f3Smrg } 742bb2e14f3Smrg} 743bb2e14f3Smrg 744bb2e14f3Smrg#define LocalDefineFmt "#define %s \"%s\"\n" 745bb2e14f3Smrg#define IncludeFmt "#include %s\n" 746bb2e14f3Smrg#define ImakeDefSym "INCLUDE_IMAKEFILE" 747bb2e14f3Smrg#define ImakeTmplSym "IMAKE_TEMPLATE" 748bb2e14f3Smrg#define OverrideWarning "Warning: local file \"%s\" overrides global macros." 749bb2e14f3Smrg 750bb2e14f3Smrgboolean 7511114aea8Smrgoptional_include(FILE *inFile, const char *defsym, const char *fname) 752bb2e14f3Smrg{ 753bb2e14f3Smrg errno = 0; 754bb2e14f3Smrg if (access(fname, R_OK) == 0) { 755bb2e14f3Smrg LogMsg(OverrideWarning, fname); 756bb2e14f3Smrg return (fprintf(inFile, LocalDefineFmt, defsym, fname) < 0 || 757bb2e14f3Smrg fprintf(inFile, IncludeFmt, defsym) < 0); 758bb2e14f3Smrg } 759bb2e14f3Smrg return FALSE; 760bb2e14f3Smrg} 761bb2e14f3Smrg 762bb2e14f3Smrgvoid 7631114aea8Smrgdoit(FILE *outfd, const char *cmd, const char **argv) 764bb2e14f3Smrg{ 765bb2e14f3Smrg int pid; 766bb2e14f3Smrg waitType status; 767bb2e14f3Smrg 768bb2e14f3Smrg /* 769bb2e14f3Smrg * Fork and exec the command. 770bb2e14f3Smrg */ 771bb2e14f3Smrg#ifdef WIN32 772bb2e14f3Smrg if (outfd) 773bb2e14f3Smrg dup2(fileno(outfd), 1); 774bb2e14f3Smrg status = _spawnvp(_P_WAIT, cmd, argv); 775bb2e14f3Smrg if (status < 0) 776bb2e14f3Smrg LogFatal("Cannot spawn %s.", cmd); 777bb2e14f3Smrg if (status > 0) 7781114aea8Smrg LogFatal("Exit code %d.", status); 779bb2e14f3Smrg#else 780bb2e14f3Smrg pid = fork(); 781bb2e14f3Smrg if (pid < 0) 7821114aea8Smrg LogFatal("Cannot fork."); 783bb2e14f3Smrg if (pid) { /* parent... simply wait */ 784bb2e14f3Smrg while (wait(&status) > 0) { 785bb2e14f3Smrg errno = 0; 786bb2e14f3Smrg if (WIFSIGNALED(status)) 7871114aea8Smrg LogFatal("Signal %d.", waitSig(status)); 788bb2e14f3Smrg if (WIFEXITED(status) && waitCode(status)) 7891114aea8Smrg LogFatal("Exit code %d.", waitCode(status)); 790bb2e14f3Smrg } 791bb2e14f3Smrg } 792bb2e14f3Smrg else { /* child... dup and exec cmd */ 793bb2e14f3Smrg if (verbose) 794bb2e14f3Smrg showargs(argv); 795bb2e14f3Smrg if (outfd) 796bb2e14f3Smrg dup2(fileno(outfd), 1); 79743b8458eSmrg execvp(cmd, (char * const *) argv); 798bb2e14f3Smrg LogFatal("Cannot exec %s.", cmd); 799bb2e14f3Smrg } 800bb2e14f3Smrg#endif 801bb2e14f3Smrg} 802bb2e14f3Smrg 803bb2e14f3Smrg#if !defined WIN32 804bb2e14f3Smrgstatic void 8051114aea8Smrgparse_utsname(struct utsname *name, const char *fmt, char *result, const char *msg) 806bb2e14f3Smrg{ 807bb2e14f3Smrg char buf[SYS_NMLN * 5 + 1]; 808bb2e14f3Smrg char *ptr = buf; 809bb2e14f3Smrg int arg; 810bb2e14f3Smrg 811bb2e14f3Smrg if (!name) 812bb2e14f3Smrg LogFatal(msg,fmt); 813bb2e14f3Smrg 814bb2e14f3Smrg /* Assemble all the pieces into a buffer. */ 815bb2e14f3Smrg for (arg = 0; fmt[arg] != ' '; arg++) 816bb2e14f3Smrg { 817bb2e14f3Smrg /* Our buffer is only guaranteed to hold 5 arguments. */ 818bb2e14f3Smrg if (arg >= 5) 819bb2e14f3Smrg LogFatal(msg, fmt); 820bb2e14f3Smrg 821bb2e14f3Smrg switch (fmt[arg]) 822bb2e14f3Smrg { 823bb2e14f3Smrg case 's': 824bb2e14f3Smrg if (arg > 0) 825bb2e14f3Smrg *ptr++ = ' '; 826bb2e14f3Smrg strcpy(ptr, name->sysname); 827bb2e14f3Smrg ptr += strlen(ptr); 828bb2e14f3Smrg break; 829bb2e14f3Smrg 830bb2e14f3Smrg case 'n': 831bb2e14f3Smrg if (arg > 0) 832bb2e14f3Smrg *ptr++ = ' '; 833bb2e14f3Smrg strcpy(ptr, name->nodename); 834bb2e14f3Smrg ptr += strlen(ptr); 835bb2e14f3Smrg break; 836bb2e14f3Smrg 837bb2e14f3Smrg case 'r': 838bb2e14f3Smrg if (arg > 0) 839bb2e14f3Smrg *ptr++ = ' '; 840bb2e14f3Smrg strcpy(ptr, name->release); 841bb2e14f3Smrg ptr += strlen(ptr); 842bb2e14f3Smrg break; 843bb2e14f3Smrg 844bb2e14f3Smrg case 'v': 845bb2e14f3Smrg if (arg > 0) 846bb2e14f3Smrg *ptr++ = ' '; 847bb2e14f3Smrg strcpy(ptr, name->version); 848bb2e14f3Smrg ptr += strlen(ptr); 849bb2e14f3Smrg break; 850bb2e14f3Smrg 851bb2e14f3Smrg case 'm': 852bb2e14f3Smrg if (arg > 0) 853bb2e14f3Smrg *ptr++ = ' '; 854bb2e14f3Smrg strcpy(ptr, name->machine); 855bb2e14f3Smrg ptr += strlen(ptr); 856bb2e14f3Smrg break; 857bb2e14f3Smrg 858bb2e14f3Smrg default: 859bb2e14f3Smrg LogFatal(msg, fmt); 860bb2e14f3Smrg } 861bb2e14f3Smrg } 862bb2e14f3Smrg 863bb2e14f3Smrg /* Just in case... */ 864bb2e14f3Smrg if (strlen(buf) >= sizeof(buf)) 8651114aea8Smrg LogFatal("Buffer overflow parsing uname."); 866bb2e14f3Smrg 867bb2e14f3Smrg /* Parse the buffer. The sscanf() return value is rarely correct. */ 868bb2e14f3Smrg *result = '\0'; 869bb2e14f3Smrg (void) sscanf(buf, fmt + arg + 1, result); 870bb2e14f3Smrg} 871bb2e14f3Smrg 872bb2e14f3Smrg/* Trim leading 0's and periods from version names. The 0's cause 873bb2e14f3Smrg the number to be interpreted as octal numbers. Some version strings 874bb2e14f3Smrg have the potential for different numbers of .'s in them. 875bb2e14f3Smrg */ 876bb2e14f3Smrg 877bb2e14f3Smrgstatic char * 878bb2e14f3Smrgtrim_version(char *p) 879bb2e14f3Smrg{ 880bb2e14f3Smrg 881bb2e14f3Smrg if (p != 0 && *p != '\0') 882bb2e14f3Smrg { 883bb2e14f3Smrg while ((*p == '0' || *p == '.') && *(p + 1) != '\0') 884bb2e14f3Smrg ++p; 885bb2e14f3Smrg } 886bb2e14f3Smrg return (p); 887bb2e14f3Smrg} 888bb2e14f3Smrg#endif 889bb2e14f3Smrg 890bb2e14f3Smrg#if defined(linux) || defined(__GLIBC__) 891bb2e14f3Smrgconst char *libc_c= 892bb2e14f3Smrg"#include <stdio.h>\n" 893bb2e14f3Smrg"#include <ctype.h>\n" 894bb2e14f3Smrg"\n" 895bb2e14f3Smrg"#if 1\n" 896bb2e14f3Smrg"#pragma weak gnu_get_libc_version\n" 897bb2e14f3Smrg"#pragma weak __libc_version\n" 898bb2e14f3Smrg"#pragma weak __linux_C_lib_version\n" 899bb2e14f3Smrg"#endif\n" 900bb2e14f3Smrg"\n" 901bb2e14f3Smrg"extern const char * gnu_get_libc_version (void);\n" 902bb2e14f3Smrg"extern const char * __linux_C_lib_version;\n" 903bb2e14f3Smrg"extern const char __libc_version [];\n" 904bb2e14f3Smrg"\n" 905bb2e14f3Smrg"int\n" 906bb2e14f3Smrg"main ()\n" 907bb2e14f3Smrg"{\n" 908bb2e14f3Smrg" int libcmajor = 0, libcminor = 0, libcteeny = 0;\n" 909bb2e14f3Smrg" const char * ptr = NULL;\n" 910bb2e14f3Smrg" int glibcmajor = 0;\n" 911bb2e14f3Smrg"\n" 912bb2e14f3Smrg" if (gnu_get_libc_version != 0)\n" 913bb2e14f3Smrg" {\n" 914bb2e14f3Smrg" ptr = gnu_get_libc_version ();\n" 915bb2e14f3Smrg" glibcmajor = 4;\n" 916bb2e14f3Smrg" }\n" 917bb2e14f3Smrg" else if (&__libc_version != 0)\n" 918bb2e14f3Smrg" {\n" 919bb2e14f3Smrg" ptr = __libc_version;\n" 920bb2e14f3Smrg" glibcmajor = 4;\n" 921bb2e14f3Smrg" }\n" 922bb2e14f3Smrg" else if (&__linux_C_lib_version != 0)\n" 923bb2e14f3Smrg" {\n" 924bb2e14f3Smrg" ptr = __linux_C_lib_version;\n" 925bb2e14f3Smrg" }\n" 926bb2e14f3Smrg" else\n" 927bb2e14f3Smrg" {\n" 928bb2e14f3Smrg" libcmajor = 0; libcminor = 0; libcteeny = 0;\n" 929bb2e14f3Smrg" }\n" 930bb2e14f3Smrg"\n" 931bb2e14f3Smrg" if (ptr)\n" 932bb2e14f3Smrg" {\n" 933bb2e14f3Smrg" while (!isdigit (*ptr))\n" 934bb2e14f3Smrg" ptr++;\n" 935bb2e14f3Smrg"\n" 936bb2e14f3Smrg" sscanf (ptr, \"%d.%d.%d\", &libcmajor, &libcminor, &libcteeny);\n" 937bb2e14f3Smrg" libcmajor += glibcmajor;\n" 938bb2e14f3Smrg" }\n" 939bb2e14f3Smrg"\n" 940bb2e14f3Smrg" printf(\"#define DefaultLinuxCLibMajorVersion %d\\n\", libcmajor);\n" 941bb2e14f3Smrg" printf(\"#define DefaultLinuxCLibMinorVersion %d\\n\", libcminor);\n" 942bb2e14f3Smrg" printf(\"#define DefaultLinuxCLibTeenyVersion %d\\n\", libcteeny);\n" 943bb2e14f3Smrg"\n" 944bb2e14f3Smrg" return 0;\n" 945bb2e14f3Smrg"}\n" 946bb2e14f3Smrg; 947bb2e14f3Smrg 948bb2e14f3Smrgstatic void 949bb2e14f3Smrgget_libc_version(FILE *inFile) 950bb2e14f3Smrg{ 951bb2e14f3Smrg char aout[4096], *tmpdir; 952bb2e14f3Smrg FILE *fp; 953bb2e14f3Smrg const char *format = "%s -o %s -x c -"; 954bb2e14f3Smrg char *cc; 955bb2e14f3Smrg int len; 956bb2e14f3Smrg char *command; 957bb2e14f3Smrg 958bb2e14f3Smrg /* If $TMPDIR is defined and has an acceptable length, 959a5399cb1Smrg * use that as tmp dir, else use /tmp. That fixes 960bb2e14f3Smrg * problems with /tmp mounted "noexec". 961bb2e14f3Smrg */ 962bb2e14f3Smrg if((tmpdir = getenv("TMPDIR")) != NULL && strlen(tmpdir) < (4096-13)) 963bb2e14f3Smrg strcpy(aout, tmpdir); 964bb2e14f3Smrg else 965bb2e14f3Smrg strcpy(aout, "/tmp"); 966bb2e14f3Smrg strcat(aout, "/imakeXXXXXX"); 967bb2e14f3Smrg 968bb2e14f3Smrg /* Pre-create temp file safely */ 969bb2e14f3Smrg { 970bb2e14f3Smrg /* Linux + ELF has mkstemp() */ 971bb2e14f3Smrg int tmpfd; 972bb2e14f3Smrg if ((tmpfd = mkstemp(aout)) == -1) { 973bb2e14f3Smrg perror("mkstemp"); 974bb2e14f3Smrg abort(); 975bb2e14f3Smrg } 976bb2e14f3Smrg close(tmpfd); 977bb2e14f3Smrg } 978bb2e14f3Smrg cc = getenv ("CC"); 979bb2e14f3Smrg if (cc == NULL) 980bb2e14f3Smrg cc = "gcc"; 981bb2e14f3Smrg len = strlen (aout) + strlen (format) + strlen (cc); 982bb2e14f3Smrg if (len < 128) len = 128; 983bb2e14f3Smrg if((command = alloca (len)) == NULL) 984bb2e14f3Smrg abort(); 985bb2e14f3Smrg 986bb2e14f3Smrg if (snprintf (command , len, format, cc, aout) == len) 987bb2e14f3Smrg abort (); 988bb2e14f3Smrg 989bb2e14f3Smrg fp = popen (command, "w"); 990bb2e14f3Smrg if (fp == NULL || fprintf (fp, "%s\n", libc_c) < 0 991bb2e14f3Smrg || pclose (fp) != 0) 992bb2e14f3Smrg abort (); 993bb2e14f3Smrg 994bb2e14f3Smrg fp = popen (aout, "r"); 995bb2e14f3Smrg if (fp == NULL) 996bb2e14f3Smrg abort (); 997bb2e14f3Smrg 998bb2e14f3Smrg while (fgets (command, len, fp)) 9997af227c3Smrg fputs (command, inFile); 1000bb2e14f3Smrg 1001bb2e14f3Smrg len = pclose (fp); 1002bb2e14f3Smrg remove (aout); 1003bb2e14f3Smrg if (len) 1004bb2e14f3Smrg abort (); 1005bb2e14f3Smrg} 1006bb2e14f3Smrg#endif 1007bb2e14f3Smrg 1008bb2e14f3Smrg#if defined(__OpenBSD__) || defined(__DragonFly__) 1009bb2e14f3Smrgstatic void 1010bb2e14f3Smrgget_stackprotector(FILE *inFile) 1011bb2e14f3Smrg{ 1012bb2e14f3Smrg FILE *fp; 1013bb2e14f3Smrg char *cc; 1014bb2e14f3Smrg char command[1024], buf[1024]; 1015a5399cb1Smrg 1016bb2e14f3Smrg cc = getenv("CC"); 1017bb2e14f3Smrg if (cc == NULL) { 1018bb2e14f3Smrg cc = "cc"; 1019bb2e14f3Smrg } 1020bb2e14f3Smrg snprintf(command, sizeof(command), "%s -v 2>&1", cc); 1021bb2e14f3Smrg fp = popen(command, "r"); 1022a5399cb1Smrg if (fp == NULL) 1023bb2e14f3Smrg abort(); 1024bb2e14f3Smrg while (fgets(buf, sizeof(buf), fp)) { 1025bb2e14f3Smrg if (strstr(buf, "propolice") != NULL) { 1026bb2e14f3Smrg fprintf(inFile, "#define ProPoliceSupport YES\n"); 1027bb2e14f3Smrg break; 1028bb2e14f3Smrg } 1029bb2e14f3Smrg } 1030a5399cb1Smrg pclose(fp); 1031bb2e14f3Smrg} 1032bb2e14f3Smrg#endif 1033a5399cb1Smrg 1034bb2e14f3Smrg 1035bb2e14f3Smrg#if defined CROSSCOMPILE || defined linux || defined(__GLIBC__) 1036bb2e14f3Smrgstatic void 1037bb2e14f3Smrgget_distrib(FILE *inFile) 1038bb2e14f3Smrg{ 1039bb2e14f3Smrg struct stat sb; 1040bb2e14f3Smrg 10411114aea8Smrg static const char* suse = "/etc/SuSE-release"; 10421114aea8Smrg static const char* redhat = "/etc/redhat-release"; 10431114aea8Smrg static const char* debian = "/etc/debian_version"; 1044bb2e14f3Smrg 1045bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxUnknown 0"); 1046bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxSuSE 1"); 1047bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxCaldera 2"); 1048bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxCraftworks 3"); 1049bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxDebian 4"); 1050bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxInfoMagic 5"); 1051bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxKheops 6"); 1052bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxPro 7"); 1053bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxRedHat 8"); 1054bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxSlackware 9"); 1055bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxTurbo 10"); 1056bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxWare 11"); 1057bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxYggdrasil 12"); 1058bb2e14f3Smrg 1059a5399cb1Smrg# ifdef CROSSCOMPILE 1060bb2e14f3Smrg if (CrossCompiling) { 1061bb2e14f3Smrg fprintf (inFile, "%s\n", 1062bb2e14f3Smrg "#define DefaultLinuxDistribution LinuxUnknown"); 1063bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown"); 1064bb2e14f3Smrg return; 1065bb2e14f3Smrg } 1066a5399cb1Smrg# endif 1067bb2e14f3Smrg if (lstat (suse, &sb) == 0) { 1068bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxSuSE"); 1069bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName SuSE"); 1070bb2e14f3Smrg return; 1071bb2e14f3Smrg } 1072bb2e14f3Smrg if (lstat (redhat, &sb) == 0) { 1073bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxRedHat"); 1074bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName RedHat"); 1075bb2e14f3Smrg return; 1076bb2e14f3Smrg } 1077bb2e14f3Smrg if (lstat (debian, &sb) == 0) { 1078bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxDebian"); 1079bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Debian"); 1080bb2e14f3Smrg /* You could also try to get the version of the Debian distrib by looking 1081bb2e14f3Smrg * at the content of /etc/debian_version */ 1082bb2e14f3Smrg return; 1083bb2e14f3Smrg } 1084bb2e14f3Smrg /* what's the definitive way to tell what any particular distribution is? */ 1085bb2e14f3Smrg 1086bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxUnknown"); 1087bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown"); 1088bb2e14f3Smrg /* would like to know what version of the distribution it is */ 1089bb2e14f3Smrg} 1090bb2e14f3Smrg 1091bb2e14f3Smrgstatic void 1092bb2e14f3Smrgget_ld_version(FILE *inFile) 1093bb2e14f3Smrg{ 1094bb2e14f3Smrg FILE* ldprog; 1095bb2e14f3Smrg signed char c; 1096bb2e14f3Smrg int ldmajor, ldminor; 1097bb2e14f3Smrg const char *ld = "ld -v"; 1098bb2e14f3Smrg 1099a5399cb1Smrg# ifdef CROSSCOMPILE 1100bb2e14f3Smrg if (CrossCompiling) { 1101bb2e14f3Smrg char cmd[PATH_MAX]; 1102bb2e14f3Smrg strcpy (cmd, CrossCompileDir); 1103bb2e14f3Smrg strcat (cmd,"/"); 1104bb2e14f3Smrg strcat (cmd,ld); 1105bb2e14f3Smrg ldprog = popen (cmd, "r"); 1106bb2e14f3Smrg } else 1107a5399cb1Smrg# endif 1108bb2e14f3Smrg ldprog = popen (ld, "r"); 1109bb2e14f3Smrg 1110bb2e14f3Smrg if (ldprog) { 1111bb2e14f3Smrg do { 1112bb2e14f3Smrg c = fgetc (ldprog); 1113bb2e14f3Smrg } while (c != EOF && !isdigit (c)); 1114bb2e14f3Smrg ungetc (c, ldprog); 1115bb2e14f3Smrg (void) fscanf (ldprog, "%d.%d", &ldmajor, &ldminor); 1116bb2e14f3Smrg /* Start conversion to a more rational number */ 1117bb2e14f3Smrg if ((ldmajor > 2) || ((ldmajor == 2) && (ldminor > 9))) 1118bb2e14f3Smrg ldmajor *= 100; 1119bb2e14f3Smrg else 1120bb2e14f3Smrg ldmajor *= 10; 1121bb2e14f3Smrg 1122bb2e14f3Smrg fprintf(inFile, "#define DefaultLinuxBinUtilsMajorVersion %d\n", 1123bb2e14f3Smrg ldmajor + ldminor); 1124bb2e14f3Smrg pclose (ldprog); 1125bb2e14f3Smrg } 1126bb2e14f3Smrg} 1127bb2e14f3Smrg#endif 1128bb2e14f3Smrg 1129bb2e14f3Smrg#if defined __FreeBSD__ 1130bb2e14f3Smrgstatic void 1131bb2e14f3Smrgget_binary_format(FILE *inFile) 1132bb2e14f3Smrg{ 1133bb2e14f3Smrg int mib[2]; 1134bb2e14f3Smrg size_t len; 1135bb2e14f3Smrg int osrel = 0; 1136bb2e14f3Smrg FILE *objprog = NULL; 1137bb2e14f3Smrg int iself = 0; 1138bb2e14f3Smrg char buf[10]; 1139bb2e14f3Smrg char cmd[PATH_MAX]; 1140bb2e14f3Smrg 1141bb2e14f3Smrg mib[0] = CTL_KERN; 1142bb2e14f3Smrg mib[1] = KERN_OSRELDATE; 1143bb2e14f3Smrg len = sizeof(osrel); 1144bb2e14f3Smrg sysctl(mib, 2, &osrel, &len, NULL, 0); 1145bb2e14f3Smrg if (CrossCompiling) { 1146bb2e14f3Smrg strcpy (cmd, CrossCompileDir); 1147bb2e14f3Smrg strcat (cmd, "/"); 1148bb2e14f3Smrg strcat (cmd,"objformat"); 1149bb2e14f3Smrg } else 1150bb2e14f3Smrg strcpy (cmd, "objformat"); 1151bb2e14f3Smrg 1152bb2e14f3Smrg if (osrel >= 300004 && 1153bb2e14f3Smrg (objprog = popen(cmd, "r")) != NULL && 1154bb2e14f3Smrg fgets(buf, sizeof(buf), objprog) != NULL && 1155bb2e14f3Smrg strncmp(buf, "elf", 3) == 0) 1156bb2e14f3Smrg iself = 1; 1157bb2e14f3Smrg if (objprog) 1158bb2e14f3Smrg pclose(objprog); 1159bb2e14f3Smrg 1160bb2e14f3Smrg fprintf(inFile, "#define DefaultToElfFormat %s\n", iself ? "YES" : "NO"); 1161bb2e14f3Smrg} 1162bb2e14f3Smrg#endif 1163bb2e14f3Smrg 1164bb2e14f3Smrg#if defined(sun) && defined(__SVR4) 1165bb2e14f3Smrg/* Runs Sun compiler command and parses output - this is a bit of a hack 1166bb2e14f3Smrg * as it depends on the particular output format of the -V flag, but it's 1167bb2e14f3Smrg * worked for many releases. 1168bb2e14f3Smrg * 1169bb2e14f3Smrg * Input : cmd - command to run (called with -V flag) 1170bb2e14f3Smrg * path - path to command to run (use $PATH if NULL) 1171bb2e14f3Smrg * Output: cmajor & cminor - major and minor versions if found 1172bb2e14f3Smrg * Returns: 0 if successful, -1 if not. 1173bb2e14f3Smrg */ 1174bb2e14f3Smrgstatic int 1175a5399cb1Smrgask_sun_compiler_for_versions(const char *cmd, const char *path, 1176bb2e14f3Smrg int *cmajor, int *cminor) 1177bb2e14f3Smrg{ 1178bb2e14f3Smrg char buf[BUFSIZ]; 1179bb2e14f3Smrg char cmdtorun[PATH_MAX]; 1180bb2e14f3Smrg char* vptr; 1181bb2e14f3Smrg FILE* ccproc; 1182bb2e14f3Smrg const char vflag[] = " -V 2>&1"; 1183bb2e14f3Smrg int retval = -1; 1184a5399cb1Smrg 1185e5db2183Smrg size_t len = strlen(cmd) + sizeof(vflag); 1186bb2e14f3Smrg 1187bb2e14f3Smrg if (path != NULL) { 1188bb2e14f3Smrg len += strlen(path) + 1; 1189bb2e14f3Smrg } 1190bb2e14f3Smrg 1191bb2e14f3Smrg if (len < sizeof(cmdtorun)) { 1192bb2e14f3Smrg if (path != NULL) { 1193bb2e14f3Smrg sprintf(cmdtorun, "%s/%s %s", path, cmd, vflag); 1194bb2e14f3Smrg } else { 1195bb2e14f3Smrg sprintf(cmdtorun, "%s %s", cmd, vflag); 1196bb2e14f3Smrg } 1197bb2e14f3Smrg 1198bb2e14f3Smrg if ((ccproc = popen (cmdtorun, "r")) != NULL) { 1199bb2e14f3Smrg if (fgets (buf, sizeof(buf), ccproc) != NULL) { 1200bb2e14f3Smrg vptr = strrchr (buf, 'C'); 1201bb2e14f3Smrg if (vptr) { 1202bb2e14f3Smrg for (; (*vptr != '\0') && !isdigit(*vptr); vptr++) { 1203bb2e14f3Smrg /* Do nothing - just scanning for first digit */ 1204bb2e14f3Smrg } 1205bb2e14f3Smrg if (*vptr != '\0') { 1206bb2e14f3Smrg if (sscanf (vptr, "%d.%d", cmajor, cminor) == 2) { 1207bb2e14f3Smrg retval = 0; 1208bb2e14f3Smrg } 1209bb2e14f3Smrg } 1210bb2e14f3Smrg } 1211bb2e14f3Smrg if (retval != 0) { 1212a5399cb1Smrg fprintf(stderr, 1213bb2e14f3Smrg "warning: could not parse version number in output of:\n" 1214bb2e14f3Smrg " %s\n", cmdtorun); 1215bb2e14f3Smrg } 1216bb2e14f3Smrg while (fgets (buf, sizeof(buf), ccproc) != NULL) {}; 1217bb2e14f3Smrg } 1218bb2e14f3Smrg pclose (ccproc); 1219bb2e14f3Smrg } 1220bb2e14f3Smrg } 1221bb2e14f3Smrg return retval; 1222bb2e14f3Smrg} 1223bb2e14f3Smrg 1224bb2e14f3Smrg/* Find Sun compilers and their versions if present */ 1225bb2e14f3Smrgstatic void 1226bb2e14f3Smrgget_sun_compiler_versions (FILE *inFile) 1227bb2e14f3Smrg{ 1228bb2e14f3Smrg const char* sunpro_path = "/opt/SUNWspro/bin"; 1229bb2e14f3Smrg int cmajor, cminor, found = 0; 1230bb2e14f3Smrg 1231bb2e14f3Smrg /* If cross-compiling, only check CrossCompilerDir for compilers. 1232a5399cb1Smrg * If not cross-compiling, first check cc in users $PATH, 1233bb2e14f3Smrg * then try /opt/SUNWspro if not found in the users $PATH 1234bb2e14f3Smrg */ 1235bb2e14f3Smrg 1236a5399cb1Smrg# if defined CROSSCOMPILE 1237bb2e14f3Smrg if (CrossCompiling) { 1238bb2e14f3Smrg if (ask_sun_compiler_for_versions("cc", CrossCompileDir, 1239bb2e14f3Smrg &cmajor, &cminor) == 0) { 1240bb2e14f3Smrg found = 1; 1241bb2e14f3Smrg } 1242a5399cb1Smrg } 1243bb2e14f3Smrg else 1244a5399cb1Smrg# endif 1245a5399cb1Smrg { 1246bb2e14f3Smrg if (ask_sun_compiler_for_versions("cc", NULL, &cmajor, &cminor) == 0) { 1247bb2e14f3Smrg found = 1; 1248bb2e14f3Smrg } else if (ask_sun_compiler_for_versions("cc", sunpro_path, 1249bb2e14f3Smrg &cmajor, &cminor) == 0) { 1250bb2e14f3Smrg found = 1; 1251bb2e14f3Smrg fprintf(inFile, "#define DefaultSunProCCompilerDir %s", sunpro_path); 1252bb2e14f3Smrg } 1253bb2e14f3Smrg } 1254bb2e14f3Smrg 1255bb2e14f3Smrg if (found) { 1256bb2e14f3Smrg fprintf (inFile, 1257bb2e14f3Smrg "#define DefaultSunProCCompilerMajorVersion %d\n", cmajor); 1258bb2e14f3Smrg fprintf (inFile, 1259bb2e14f3Smrg "#define DefaultSunProCCompilerMinorVersion %d\n", cminor); 1260bb2e14f3Smrg } 1261bb2e14f3Smrg 1262bb2e14f3Smrg /* Now do it again for C++ compiler (CC) */ 1263bb2e14f3Smrg found = 0; 1264a5399cb1Smrg# if defined CROSSCOMPILE 1265bb2e14f3Smrg if (CrossCompiling) { 1266bb2e14f3Smrg if (ask_sun_compiler_for_versions("CC", CrossCompileDir, 1267bb2e14f3Smrg &cmajor, &cminor) == 0) { 1268bb2e14f3Smrg found = 1; 1269bb2e14f3Smrg } 1270a5399cb1Smrg } 1271bb2e14f3Smrg else 1272a5399cb1Smrg# endif 1273a5399cb1Smrg { 1274bb2e14f3Smrg if (ask_sun_compiler_for_versions("CC", NULL, &cmajor, &cminor) == 0) { 1275bb2e14f3Smrg found = 1; 1276bb2e14f3Smrg } else if (ask_sun_compiler_for_versions("CC", sunpro_path, 1277bb2e14f3Smrg &cmajor, &cminor) == 0) { 1278bb2e14f3Smrg found = 1; 1279a5399cb1Smrg fprintf(inFile, 1280bb2e14f3Smrg "#define DefaultSunProCplusplusCompilerDir %s", sunpro_path); 1281bb2e14f3Smrg } 1282bb2e14f3Smrg } 1283bb2e14f3Smrg 1284bb2e14f3Smrg if (found) { 1285bb2e14f3Smrg fprintf (inFile, 1286bb2e14f3Smrg "#define DefaultSunProCplusplusCompilerMajorVersion %d\n", 1287bb2e14f3Smrg cmajor); 1288bb2e14f3Smrg fprintf (inFile, 1289bb2e14f3Smrg "#define DefaultSunProCplusplusCompilerMinorVersion %d\n", 1290bb2e14f3Smrg cminor); 1291bb2e14f3Smrg } 1292bb2e14f3Smrg} 1293bb2e14f3Smrg#endif 1294bb2e14f3Smrg 1295bb2e14f3Smrg#if defined CROSSCOMPILE || defined __GNUC__ 1296bb2e14f3Smrgstatic void 1297bb2e14f3Smrgget_gcc_version(FILE *inFile, char *name) 1298bb2e14f3Smrg{ 1299bb2e14f3Smrg fprintf (inFile, "#define HasGcc 1\n"); 1300a5399cb1Smrg# ifdef CROSSCOMPILE 1301bb2e14f3Smrg if (CrossCompiling) 1302bb2e14f3Smrg { 1303bb2e14f3Smrg if (gnu_c > 1) { 1304bb2e14f3Smrg fprintf (inFile, "#define HasGcc2 1\n"); 1305bb2e14f3Smrg if (gnu_c > 2) 1306bb2e14f3Smrg fprintf (inFile, "#define HasGcc3 1\n"); 1307bb2e14f3Smrg } 1308bb2e14f3Smrg fprintf (inFile, "#define GccMajorVersion %d\n", gnu_c); 1309bb2e14f3Smrg fprintf (inFile, "#define GccMinorVersion %d\n", gnu_c_minor); 1310bb2e14f3Smrg } else 1311a5399cb1Smrg# endif 1312bb2e14f3Smrg { 1313a5399cb1Smrg# if __GNUC__ > 1 1314bb2e14f3Smrg fprintf (inFile, "#define HasGcc2 1\n"); 1315a5399cb1Smrg# if __GNUC__ > 2 1316bb2e14f3Smrg fprintf (inFile, "#define HasGcc3 1\n"); 1317a5399cb1Smrg# endif 1318bb2e14f3Smrg# endif 1319bb2e14f3Smrg fprintf (inFile, "#define GccMajorVersion %d\n", __GNUC__); 1320bb2e14f3Smrg fprintf (inFile, "#define GccMinorVersion %d\n", __GNUC_MINOR__); 1321bb2e14f3Smrg } 1322a5399cb1Smrg# if defined(HAS_MERGE_CONSTANTS) 1323bb2e14f3Smrg fprintf (inFile, "#define HasGccMergeConstants %d\n", HAS_MERGE_CONSTANTS); 1324a5399cb1Smrg# endif 1325bb2e14f3Smrg} 1326bb2e14f3Smrg#endif 1327bb2e14f3Smrg 1328bb2e14f3Smrgstatic boolean 1329bb2e14f3Smrgget_gcc(char *cmd) 1330bb2e14f3Smrg{ 1331bb2e14f3Smrg struct stat sb; 13321114aea8Smrg static const char* gcc_path[] = { 1333a5399cb1Smrg#if defined(linux) || \ 1334bb2e14f3Smrg defined(__NetBSD__) || \ 1335bb2e14f3Smrg defined(__OpenBSD__) || \ 1336bb2e14f3Smrg defined(__FreeBSD__) || \ 1337bb2e14f3Smrg defined(__DragonFly__) || \ 1338bb2e14f3Smrg defined(__APPLE__) || \ 1339bb2e14f3Smrg defined(__CYGWIN__) || \ 1340bb2e14f3Smrg defined(__MINGW32__) || \ 1341bb2e14f3Smrg defined(__GNU__) || \ 1342bb2e14f3Smrg defined(__GLIBC__) 1343bb2e14f3Smrg "/usr/bin/cc", /* for Linux PostIncDir */ 1344a5399cb1Smrg#endif 1345bb2e14f3Smrg "/usr/local/bin/gcc", 1346bb2e14f3Smrg "/opt/gnu/bin/gcc", 1347bb2e14f3Smrg "/usr/pkg/bin/gcc" 1348bb2e14f3Smrg }; 1349bb2e14f3Smrg 1350bb2e14f3Smrg#ifdef CROSSCOMPILE 13511114aea8Smrg static const char* cross_cc_name[] = { 1352bb2e14f3Smrg "cc", 1353bb2e14f3Smrg "gcc" 1354bb2e14f3Smrg }; 1355bb2e14f3Smrg 1356bb2e14f3Smrg if (CrossCompiling) { 1357e5db2183Smrg unsigned int i; 1358bb2e14f3Smrg for (i = 0; i < sizeof (cross_cc_name) / sizeof cross_cc_name[0]; i++){ 1359bb2e14f3Smrg strcpy (cmd, CrossCompileDir); 1360bb2e14f3Smrg strcat (cmd, "/"); 1361bb2e14f3Smrg strcat (cmd, cross_cc_name[i]); 1362bb2e14f3Smrg if (lstat (cmd, &sb) == 0) { 1363bb2e14f3Smrg return TRUE; 1364bb2e14f3Smrg break; 1365bb2e14f3Smrg } 1366bb2e14f3Smrg } 1367bb2e14f3Smrg } else 1368bb2e14f3Smrg#endif 1369bb2e14f3Smrg { 1370e5db2183Smrg unsigned int i; 1371bb2e14f3Smrg for (i = 0; i < sizeof (gcc_path) / sizeof gcc_path[0]; i++) { 1372bb2e14f3Smrg if (lstat (gcc_path[i], &sb) == 0) { 1373bb2e14f3Smrg strcpy (cmd, gcc_path[i]); 1374bb2e14f3Smrg return TRUE; 1375bb2e14f3Smrg } 1376bb2e14f3Smrg } 1377bb2e14f3Smrg } 1378bb2e14f3Smrg return FALSE; 1379bb2e14f3Smrg} 1380bb2e14f3Smrg 138139f9c979Smrg#ifdef CROSSCOMPILE 1382bb2e14f3Smrgstatic void 1383bb2e14f3Smrgget_gcc_incdir(FILE *inFile, char* name) 1384bb2e14f3Smrg{ 1385bb2e14f3Smrg FILE* gccproc; 1386bb2e14f3Smrg char buf[PATH_MAX]; 1387bb2e14f3Smrg char cmd[PATH_MAX]; 1388bb2e14f3Smrg char* ptr; 1389bb2e14f3Smrg 1390bb2e14f3Smrg strcpy(cmd,name); 1391bb2e14f3Smrg 1392bb2e14f3Smrg buf[0] = '\0'; 1393bb2e14f3Smrg strcat (cmd, " --print-libgcc-file-name"); 1394bb2e14f3Smrg if ((gccproc = popen (cmd, "r")) != NULL) { 1395bb2e14f3Smrg if (fgets (buf, PATH_MAX, gccproc) != NULL) { 1396bb2e14f3Smrg ptr = strstr (buf, "libgcc.a"); 1397bb2e14f3Smrg if (ptr) strcpy (ptr, "include"); 1398bb2e14f3Smrg } 1399bb2e14f3Smrg (void) pclose (gccproc); 1400bb2e14f3Smrg } 1401bb2e14f3Smrg 1402bb2e14f3Smrg if (buf[0]) 1403bb2e14f3Smrg fprintf (inFile, "#define DefaultGccIncludeDir \"%s\"\n", buf); 1404bb2e14f3Smrg} 1405bb2e14f3Smrg#endif 1406bb2e14f3Smrg 1407bb2e14f3Smrgboolean 1408bb2e14f3Smrgdefine_os_defaults(FILE *inFile) 1409bb2e14f3Smrg{ 141039f9c979Smrg#if defined CROSSCOMPILE || !defined(WIN32) 1411a5399cb1Smrg# ifdef CROSSCOMPILE 1412a5399cb1Smrg# ifdef __GNUC__ 1413bb2e14f3Smrg if (1) 1414a5399cb1Smrg# else 1415bb2e14f3Smrg if ((sys != win32) && (sys != emx)) 1416a5399cb1Smrg# endif 1417a5399cb1Smrg# endif 1418bb2e14f3Smrg { 1419bb2e14f3Smrg# if (defined(DEFAULT_OS_NAME) || defined(DEFAULT_OS_MAJOR_REV) || \ 1420bb2e14f3Smrg defined(DEFAULT_OS_MINOR_REV) || defined(DEFAULT_OS_TEENY_REV)) 1421bb2e14f3Smrg struct utsname *name = NULL; 1422bb2e14f3Smrg struct utsname uts_name; 1423bb2e14f3Smrg char buf[SYS_NMLN * 5 + 1]; 1424bb2e14f3Smrg 1425bb2e14f3Smrg /* Obtain the system information. */ 1426a5399cb1Smrg# ifdef CROSSCOMPILE 1427bb2e14f3Smrg if (!CrossCompiling) 1428a5399cb1Smrg# endif 1429bb2e14f3Smrg { 1430bb2e14f3Smrg if (uname(&uts_name) < 0) 14311114aea8Smrg LogFatal("Cannot invoke uname"); 1432bb2e14f3Smrg else 1433bb2e14f3Smrg name = &uts_name; 1434bb2e14f3Smrg } 1435a5399cb1Smrg# if defined CROSSCOMPILE && (defined linux || defined(__GLIBC__)) 1436bb2e14f3Smrg else { 1437bb2e14f3Smrg strncpy(uts_name.sysname,cross_uts_sysname,SYS_NMLN); 1438bb2e14f3Smrg strncpy(uts_name.release,cross_uts_release,SYS_NMLN); 1439bb2e14f3Smrg strncpy(uts_name.version,cross_uts_version,SYS_NMLN); 1440bb2e14f3Smrg strncpy(uts_name.machine,cross_uts_machine,SYS_NMLN); 1441bb2e14f3Smrg name = &uts_name; 1442bb2e14f3Smrg } 1443a5399cb1Smrg# endif 1444a5399cb1Smrg# ifdef __FreeBSD__ 1445bb2e14f3Smrg /* Override for compiling in chroot of other OS version, such as 1446bb2e14f3Smrg * in the bento build cluster. 1447bb2e14f3Smrg */ 1448bb2e14f3Smrg { 1449bb2e14f3Smrg char *e; 1450a5399cb1Smrg if ((e = getenv("OSREL")) != NULL && 1451bb2e14f3Smrg strlen(name->sysname) + strlen(e) + 1 < SYS_NMLN) { 1452bb2e14f3Smrg strcpy(name->release, e); 1453bb2e14f3Smrg strcpy(name->version, name->sysname); 1454bb2e14f3Smrg strcat(name->version, " "); 1455bb2e14f3Smrg strcat(name->version, e); 1456bb2e14f3Smrg } 1457bb2e14f3Smrg } 1458a5399cb1Smrg# endif 1459bb2e14f3Smrg 1460bb2e14f3Smrg# if defined DEFAULT_OS_NAME 1461bb2e14f3Smrg# if defined CROSSCOMPILE 1462bb2e14f3Smrg if (!CrossCompiling) 1463bb2e14f3Smrg# endif 1464bb2e14f3Smrg { 1465bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_NAME, buf, 1466bb2e14f3Smrg "Bad DEFAULT_OS_NAME syntax %s"); 1467bb2e14f3Smrg# ifdef DEFAULT_OS_NAME_FROB 1468bb2e14f3Smrg DEFAULT_OS_NAME_FROB(buf, sizeof buf); 1469bb2e14f3Smrg# endif 1470bb2e14f3Smrg if (buf[0] != '\0') 1471bb2e14f3Smrg fprintf(inFile, "#define DefaultOSName %s\n", buf); 1472bb2e14f3Smrg } 1473bb2e14f3Smrg# endif 1474bb2e14f3Smrg 1475bb2e14f3Smrg# if defined CROSSCOMPILE 1476bb2e14f3Smrg if (CrossCompiling && defaultOsName) { 1477bb2e14f3Smrg parse_utsname(name, defaultOsName, buf, 1478bb2e14f3Smrg "Bad DEFAULT_OS_NAME syntax %s"); 1479bb2e14f3Smrg if (defaultOsNameFrob) 1480bb2e14f3Smrg defaultOsNameFrob(buf, sizeof buf); 1481bb2e14f3Smrg if (buf[0] != '\0') 1482bb2e14f3Smrg fprintf(inFile, "#define DefaultOSName %s\n", buf); 1483bb2e14f3Smrg } 1484bb2e14f3Smrg# endif 1485bb2e14f3Smrg 1486bb2e14f3Smrg# ifdef DEFAULT_OS_MAJOR_REV 1487bb2e14f3Smrg# if defined CROSSCOMPILE 1488bb2e14f3Smrg if (!CrossCompiling) 1489bb2e14f3Smrg# endif 1490bb2e14f3Smrg { 1491bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_MAJOR_REV, buf, 1492bb2e14f3Smrg "Bad DEFAULT_OS_MAJOR_REV syntax %s"); 1493bb2e14f3Smrg# ifdef DEFAULT_OS_MAJOR_REV_FROB 1494bb2e14f3Smrg DEFAULT_OS_MAJOR_REV_FROB(buf, sizeof buf); 1495bb2e14f3Smrg# endif 1496bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion %s\n", 1497bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1498bb2e14f3Smrg } 1499bb2e14f3Smrg# endif 1500bb2e14f3Smrg 1501bb2e14f3Smrg# if defined CROSSCOMPILE 1502bb2e14f3Smrg if (CrossCompiling && defaultOsMajorRev) { 1503bb2e14f3Smrg parse_utsname(name, defaultOsMajorRev, buf, 1504bb2e14f3Smrg "Bad defaultOsMajorRev syntax %s"); 1505bb2e14f3Smrg if (defaultOsMajorRevFrob) 1506bb2e14f3Smrg defaultOsMajorRevFrob(buf, sizeof buf); 1507bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion %s\n", 1508bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1509bb2e14f3Smrg } 1510bb2e14f3Smrg# endif 1511bb2e14f3Smrg 1512bb2e14f3Smrg# ifdef DEFAULT_OS_MINOR_REV 1513bb2e14f3Smrg# if defined CROSSCOMPILE 1514bb2e14f3Smrg if (!CrossCompiling) 1515bb2e14f3Smrg# endif 1516bb2e14f3Smrg { 1517bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_MINOR_REV, buf, 1518bb2e14f3Smrg "Bad DEFAULT_OS_MINOR_REV syntax %s"); 1519bb2e14f3Smrg# ifdef DEFAULT_OS_MINOR_REV_FROB 1520bb2e14f3Smrg DEFAULT_OS_MINOR_REV_FROB(buf, sizeof buf); 1521bb2e14f3Smrg# endif 1522bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion %s\n", 1523bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1524bb2e14f3Smrg } 1525bb2e14f3Smrg# endif 1526bb2e14f3Smrg 1527bb2e14f3Smrg# if defined CROSSCOMPILE 1528bb2e14f3Smrg if (CrossCompiling && defaultOsMinorRev) { 1529bb2e14f3Smrg parse_utsname(name, defaultOsMinorRev, buf, 1530bb2e14f3Smrg "Bad defaultOsMinorRev syntax %s"); 1531bb2e14f3Smrg if (defaultOsMinorRevFrob) 1532bb2e14f3Smrg defaultOsMinorRevFrob(buf, sizeof buf); 1533bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion %s\n", 1534bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1535bb2e14f3Smrg } 1536bb2e14f3Smrg# endif 1537bb2e14f3Smrg 1538bb2e14f3Smrg# ifdef DEFAULT_OS_TEENY_REV 1539bb2e14f3Smrg# if defined CROSSCOMPILE 1540bb2e14f3Smrg if (!CrossCompiling) 1541bb2e14f3Smrg# endif 1542bb2e14f3Smrg { 1543bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_TEENY_REV, buf, 1544bb2e14f3Smrg "Bad DEFAULT_OS_TEENY_REV syntax %s"); 1545bb2e14f3Smrg# ifdef DEFAULT_OS_TEENY_REV_FROB 1546bb2e14f3Smrg DEFAULT_OS_TEENY_REV_FROB(buf, sizeof buf); 1547bb2e14f3Smrg# endif 1548bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion %s\n", 1549bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1550bb2e14f3Smrg } 1551bb2e14f3Smrg# endif 1552bb2e14f3Smrg 1553bb2e14f3Smrg# if defined CROSSCOMPILE 1554bb2e14f3Smrg if (CrossCompiling && defaultOsTeenyRev) { 1555bb2e14f3Smrg parse_utsname(name, defaultOsTeenyRev, buf, 1556bb2e14f3Smrg "Bad defaultOsTeenyRev syntax %s"); 1557bb2e14f3Smrg if (defaultOsTeenyRevFrob) 1558bb2e14f3Smrg defaultOsTeenyRevFrob(buf, sizeof buf); 1559bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion %s\n", 1560bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1561bb2e14f3Smrg } 1562bb2e14f3Smrg# endif 1563bb2e14f3Smrg 1564bb2e14f3Smrg# ifdef DEFAULT_MACHINE_ARCHITECTURE 1565bb2e14f3Smrg# if defined CROSSCOMPILE 1566bb2e14f3Smrg if (!CrossCompiling) 1567bb2e14f3Smrg# endif 1568bb2e14f3Smrg { 1569bb2e14f3Smrg parse_utsname(name, DEFAULT_MACHINE_ARCHITECTURE, buf, 1570bb2e14f3Smrg "Bad DEFAULT_MACHINE_ARCHITECTURE %s"); 1571bb2e14f3Smrg fprintf(inFile, "#ifndef %s\n# define %s\n#endif\n", buf, buf); 1572bb2e14f3Smrg } 1573bb2e14f3Smrg# endif 1574bb2e14f3Smrg 1575bb2e14f3Smrg# if defined CROSSCOMPILE 1576bb2e14f3Smrg if (CrossCompiling && defaultMachineArchitecture) { 1577bb2e14f3Smrg parse_utsname(name, defaultMachineArchitecture, buf, 1578bb2e14f3Smrg "Bad defaultMachineArchitecture syntax %s"); 1579bb2e14f3Smrg fprintf(inFile, "#ifndef %s\n# define %s\n#endif\n", buf, buf); 1580bb2e14f3Smrg } 1581bb2e14f3Smrg# endif 1582bb2e14f3Smrg# endif 1583bb2e14f3Smrg# if defined CROSSCOMPILE 1584bb2e14f3Smrg if (CrossCompiling) 1585bb2e14f3Smrg get_cross_compile_dir(inFile); 1586bb2e14f3Smrg else 1587bb2e14f3Smrg# endif 1588bb2e14f3Smrg fprintf(inFile, "#define CrossCompiling NO\n"); 1589bb2e14f3Smrg# if defined CROSSCOMPILE 1590bb2e14f3Smrg if (CrossCompiling && sys == LinuX) 1591bb2e14f3Smrg# endif 1592bb2e14f3Smrg# if defined CROSSCOMPILE || defined linux || defined(__GLIBC__) 1593bb2e14f3Smrg# if defined(CROSSCOMPILE) && defined(__linux__) 1594bb2e14f3Smrg if (sys == LinuX) 1595bb2e14f3Smrg# endif 1596bb2e14f3Smrg get_distrib (inFile); 1597bb2e14f3Smrg# endif 1598bb2e14f3Smrg# if defined linux || defined(__GLIBC__) 1599bb2e14f3Smrg# if defined CROSSCOMPILE 1600bb2e14f3Smrg if (!CrossCompiling) 1601bb2e14f3Smrg# endif 1602bb2e14f3Smrg get_libc_version (inFile); 1603bb2e14f3Smrg# if defined CROSSCOMPILE 1604bb2e14f3Smrg else { 1605bb2e14f3Smrg fprintf(inFile,"#define DefaultLinuxCLibMajorVersion %d\n", 1606bb2e14f3Smrg glibc_major); 1607bb2e14f3Smrg fprintf(inFile,"#define DefaultLinuxCLibMinorVersion %d\n", 1608bb2e14f3Smrg glibc_minor); 1609bb2e14f3Smrg fprintf(inFile,"#define DefaultLinuxCLibTeenyVersion 0\n"); 1610bb2e14f3Smrg } 1611bb2e14f3Smrg# endif 1612bb2e14f3Smrg# endif /* linux || __GLIBC__ */ 1613bb2e14f3Smrg# if defined CROSSCOMPILE || defined linux || defined(__GLIBC__) 1614bb2e14f3Smrg# if defined CROSSCOMPILE && defined(__linux__) 1615bb2e14f3Smrg if (sys == LinuX) 1616bb2e14f3Smrg# endif 1617bb2e14f3Smrg get_ld_version(inFile); 1618bb2e14f3Smrg# endif 1619bb2e14f3Smrg# if defined (sun) && defined(SVR4) 1620bb2e14f3Smrg get_sun_compiler_versions (inFile); 1621bb2e14f3Smrg# endif 1622bb2e14f3Smrg# if defined CROSSCOMPILE || defined __GNUC__ 1623bb2e14f3Smrg# if defined CROSSCOMPILE 1624bb2e14f3Smrg if (gnu_c) 1625bb2e14f3Smrg# endif 1626bb2e14f3Smrg { 1627e5db2183Smrg char gcc_name[PATH_MAX]; 1628e5db2183Smrg if (get_gcc(gcc_name)) { 1629e5db2183Smrg get_gcc_version (inFile, gcc_name); 163039f9c979Smrg# if defined CROSSCOMPILE 1631bb2e14f3Smrg if (sys != emx) 1632e5db2183Smrg get_gcc_incdir(inFile, gcc_name); 1633bb2e14f3Smrg# endif 1634bb2e14f3Smrg } 1635bb2e14f3Smrg } 1636bb2e14f3Smrg# endif 1637bb2e14f3Smrg# if defined __FreeBSD__ 1638bb2e14f3Smrg# if defined CROSSCOMPILE 1639bb2e14f3Smrg if (sys == freeBSD) 1640bb2e14f3Smrg# endif 1641bb2e14f3Smrg get_binary_format(inFile); 1642bb2e14f3Smrg# endif 1643bb2e14f3Smrg } 164439f9c979Smrg#endif /* !WIN32 */ 1645bb2e14f3Smrg#if defined WIN32 1646bb2e14f3Smrg# ifdef CROSSCOMPILE 1647bb2e14f3Smrg else if (sys == win32 && !CrossCompiling) 1648bb2e14f3Smrg# endif 1649bb2e14f3Smrg { 1650bb2e14f3Smrg OSVERSIONINFO osvi; 1651bb2e14f3Smrg static char* os_names[] = { "Win32s", "Windows 95", "Windows NT" }; 1652bb2e14f3Smrg 1653bb2e14f3Smrg memset(&osvi, 0, sizeof(OSVERSIONINFO)); 1654bb2e14f3Smrg osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); 1655bb2e14f3Smrg GetVersionEx (&osvi); 1656bb2e14f3Smrg 1657bb2e14f3Smrg fprintf (inFile, "#define DefaultOSName Microsoft %s\n", 1658bb2e14f3Smrg os_names[osvi.dwPlatformId]); 1659bb2e14f3Smrg 1660bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion %d\n", osvi.dwMajorVersion); 1661bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion %d\n", osvi.dwMinorVersion); 1662bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion %d\n", 1663bb2e14f3Smrg osvi.dwBuildNumber & 0xFFFF); 1664bb2e14f3Smrg } 1665bb2e14f3Smrg#endif /* WIN32 */ 1666bb2e14f3Smrg#ifdef CROSSCOMPILE 1667bb2e14f3Smrg else if (sys == emx) 1668bb2e14f3Smrg { 1669bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion 4\n"); 1670bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion 0\n"); 1671bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion 0\n"); 1672bb2e14f3Smrg } 1673bb2e14f3Smrg#endif /* EMX */ 1674bb2e14f3Smrg#if defined(__OpenBSD__) || defined(__DragonFly__) 1675bb2e14f3Smrg get_stackprotector(inFile); 1676bb2e14f3Smrg#endif 1677bb2e14f3Smrg return FALSE; 1678bb2e14f3Smrg} 1679bb2e14f3Smrg 1680bb2e14f3Smrgvoid 16811114aea8Smrgcppit(const char *imakefile, const char *template, const char *masterc, 16821114aea8Smrg FILE *outfd, const char *outfname) 1683bb2e14f3Smrg{ 1684bb2e14f3Smrg FILE *inFile; 1685bb2e14f3Smrg 1686bb2e14f3Smrg haveImakefileC = TRUE; 1687bb2e14f3Smrg inFile = fopen(masterc, "w"); 1688bb2e14f3Smrg if (inFile == NULL) 1689bb2e14f3Smrg LogFatal("Cannot open %s for output.", masterc); 1690bb2e14f3Smrg if (fprintf(inFile, "%s\n", ImakefileCHeader) < 0 || 1691bb2e14f3Smrg define_os_defaults(inFile) || 1692bb2e14f3Smrg optional_include(inFile, "IMAKE_LOCAL_DEFINES", "localdefines") || 1693bb2e14f3Smrg optional_include(inFile, "IMAKE_ADMIN_DEFINES", "admindefines") || 1694bb2e14f3Smrg fprintf(inFile, "#define %s <%s>\n", ImakeDefSym, imakefile) < 0 || 1695bb2e14f3Smrg fprintf(inFile, LocalDefineFmt, ImakeTmplSym, template) < 0 || 1696bb2e14f3Smrg fprintf(inFile, IncludeFmt, ImakeTmplSym) < 0 || 1697bb2e14f3Smrg optional_include(inFile, "IMAKE_ADMIN_MACROS", "adminmacros") || 1698bb2e14f3Smrg optional_include(inFile, "IMAKE_LOCAL_MACROS", "localmacros") || 169939f9c979Smrg fflush(inFile)) { 170039f9c979Smrg fclose(inFile); 170139f9c979Smrg LogFatal("Cannot write to %s.", masterc); 170239f9c979Smrg } 170339f9c979Smrg else if (fclose(inFile)) 1704bb2e14f3Smrg LogFatal("Cannot write to %s.", masterc); 1705bb2e14f3Smrg /* 1706bb2e14f3Smrg * Fork and exec cpp 1707bb2e14f3Smrg */ 1708bb2e14f3Smrg doit(outfd, cpp, cpp_argv); 1709bb2e14f3Smrg CleanCppOutput(outfd, outfname); 1710bb2e14f3Smrg} 1711bb2e14f3Smrg 1712bb2e14f3Smrgvoid 1713bb2e14f3Smrgmakeit(void) 1714bb2e14f3Smrg{ 1715bb2e14f3Smrg doit(NULL, make_argv[0], make_argv); 1716bb2e14f3Smrg} 1717bb2e14f3Smrg 17181114aea8Smrgconst char * 17191114aea8SmrgCleanCppInput(const char *imakefile) 1720bb2e14f3Smrg{ 1721bb2e14f3Smrg FILE *outFile = NULL; 1722bb2e14f3Smrg FILE *inFile; 1723bb2e14f3Smrg char *buf, /* buffer for file content */ 1724bb2e14f3Smrg *pbuf, /* walking pointer to buf */ 1725bb2e14f3Smrg *punwritten, /* pointer to unwritten portion of buf */ 1726bb2e14f3Smrg *ptoken, /* pointer to # token */ 1727bb2e14f3Smrg *pend, /* pointer to end of # token */ 1728bb2e14f3Smrg savec; /* temporary character holder */ 1729bb2e14f3Smrg int count; 1730bb2e14f3Smrg struct stat st; 1731bb2e14f3Smrg 1732bb2e14f3Smrg /* 1733bb2e14f3Smrg * grab the entire file. 1734bb2e14f3Smrg */ 1735bb2e14f3Smrg if (!(inFile = fopen(imakefile, "r"))) 1736bb2e14f3Smrg LogFatal("Cannot open %s for input.", imakefile); 1737bb2e14f3Smrg if (fstat(fileno(inFile), &st) < 0) 1738bb2e14f3Smrg LogFatal("Cannot stat %s for size.", imakefile); 1739e5db2183Smrg buf = Emalloc(st.st_size + 3); 1740bb2e14f3Smrg count = fread(buf + 2, 1, st.st_size, inFile); 1741bb2e14f3Smrg if (count == 0 && st.st_size != 0) 1742bb2e14f3Smrg LogFatal("Cannot read %s:", imakefile); 1743bb2e14f3Smrg fclose(inFile); 1744bb2e14f3Smrg buf[0] = '\n'; 1745bb2e14f3Smrg buf[1] = '\n'; 1746bb2e14f3Smrg buf[count + 2] = '\0'; 1747bb2e14f3Smrg 1748bb2e14f3Smrg punwritten = pbuf = buf + 2; 1749bb2e14f3Smrg while (*pbuf) { 1750bb2e14f3Smrg /* for compatibility, replace make comments for cpp */ 1751bb2e14f3Smrg if (*pbuf == '#' && pbuf[-1] == '\n' && pbuf[-2] != '\\') { 1752bb2e14f3Smrg ptoken = pbuf+1; 1753bb2e14f3Smrg while (*ptoken == ' ' || *ptoken == '\t') 1754bb2e14f3Smrg ptoken++; 1755bb2e14f3Smrg pend = ptoken; 1756bb2e14f3Smrg while (*pend && *pend != ' ' && *pend != '\t' && *pend != '\n' && *pend != '\r') 1757bb2e14f3Smrg pend++; 1758bb2e14f3Smrg savec = *pend; 1759bb2e14f3Smrg *pend = '\0'; 1760bb2e14f3Smrg if (strcmp(ptoken, "define") && 1761bb2e14f3Smrg strcmp(ptoken, "if") && 1762bb2e14f3Smrg strcmp(ptoken, "ifdef") && 1763bb2e14f3Smrg strcmp(ptoken, "ifndef") && 1764bb2e14f3Smrg strcmp(ptoken, "include") && 1765bb2e14f3Smrg strcmp(ptoken, "line") && 1766bb2e14f3Smrg strcmp(ptoken, "else") && 1767bb2e14f3Smrg strcmp(ptoken, "elif") && 1768bb2e14f3Smrg strcmp(ptoken, "endif") && 1769bb2e14f3Smrg strcmp(ptoken, "error") && 1770bb2e14f3Smrg strcmp(ptoken, "pragma") && 1771bb2e14f3Smrg strcmp(ptoken, "undef")) { 1772bb2e14f3Smrg if (outFile == NULL) { 17735afa940dSmrg#ifdef HAVE_MKSTEMP 1774bb2e14f3Smrg int fd; 1775bb2e14f3Smrg#endif 17761114aea8Smrg char *tmpImakefileName = Strdup(tmpImakefileTemplate); 17775afa940dSmrg#ifndef HAVE_MKSTEMP 17781114aea8Smrg if (mktemp(tmpImakefileName) == NULL || 17791114aea8Smrg (outFile = fopen(tmpImakefileName, "w+")) == NULL) { 1780bb2e14f3Smrg LogFatal("Cannot open %s for write.", 17811114aea8Smrg tmpImakefileName); 1782bb2e14f3Smrg } 1783bb2e14f3Smrg#else 17841114aea8Smrg fd=mkstemp(tmpImakefileName); 1785bb2e14f3Smrg if (fd != -1) 1786bb2e14f3Smrg outFile = fdopen(fd, "w"); 1787bb2e14f3Smrg if (outFile == NULL) { 1788bb2e14f3Smrg if (fd != -1) { 17891114aea8Smrg unlink(tmpImakefileName); close(fd); 1790bb2e14f3Smrg } 1791bb2e14f3Smrg LogFatal("Cannot open %s for write.", 17921114aea8Smrg tmpImakefileName); 1793bb2e14f3Smrg } 1794bb2e14f3Smrg#endif 17951114aea8Smrg tmpImakefile = tmpImakefileName; 1796bb2e14f3Smrg } 1797bb2e14f3Smrg writetmpfile(outFile, punwritten, pbuf-punwritten, 1798bb2e14f3Smrg tmpImakefile); 1799bb2e14f3Smrg if (ptoken > pbuf + 1) 1800bb2e14f3Smrg writetmpfile(outFile, "XCOMM", 5, tmpImakefile); 1801bb2e14f3Smrg else 1802bb2e14f3Smrg writetmpfile(outFile, "XCOMM ", 6, tmpImakefile); 1803bb2e14f3Smrg punwritten = pbuf + 1; 1804bb2e14f3Smrg } 1805bb2e14f3Smrg *pend = savec; 1806bb2e14f3Smrg } 1807bb2e14f3Smrg pbuf++; 1808bb2e14f3Smrg } 1809bb2e14f3Smrg if (outFile) { 1810bb2e14f3Smrg writetmpfile(outFile, punwritten, pbuf-punwritten, tmpImakefile); 1811bb2e14f3Smrg fclose(outFile); 1812bb2e14f3Smrg 1813bb2e14f3Smrg return tmpImakefile; 1814bb2e14f3Smrg } 1815bb2e14f3Smrg 1816bb2e14f3Smrg return(imakefile); 1817bb2e14f3Smrg} 1818bb2e14f3Smrg 1819bb2e14f3Smrgvoid 18201114aea8SmrgCleanCppOutput(FILE *tmpfd, const char *tmpfname) 1821bb2e14f3Smrg{ 1822bb2e14f3Smrg char *input; 1823bb2e14f3Smrg int blankline = 0; 1824bb2e14f3Smrg 1825bb2e14f3Smrg while((input = ReadLine(tmpfd, tmpfname))) { 1826bb2e14f3Smrg if (isempty(input)) { 1827bb2e14f3Smrg if (blankline++) 1828bb2e14f3Smrg continue; 1829bb2e14f3Smrg#ifdef CROSSCOMPILE 1830bb2e14f3Smrg if (fixup_whitespace) 1831bb2e14f3Smrg#endif 1832bb2e14f3Smrg#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 1833bb2e14f3Smrg KludgeResetRule(); 1834bb2e14f3Smrg#endif 1835bb2e14f3Smrg } else { 1836bb2e14f3Smrg blankline = 0; 1837bb2e14f3Smrg#ifdef CROSSCOMPILE 1838bb2e14f3Smrg if (fixup_whitespace) 1839bb2e14f3Smrg#endif 1840bb2e14f3Smrg#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 1841bb2e14f3Smrg KludgeOutputLine(&input); 1842bb2e14f3Smrg#endif 1843bb2e14f3Smrg writetmpfile(tmpfd, input, strlen(input), tmpfname); 1844bb2e14f3Smrg } 1845bb2e14f3Smrg writetmpfile(tmpfd, "\n", 1, tmpfname); 1846bb2e14f3Smrg } 1847bb2e14f3Smrg fflush(tmpfd); 1848bb2e14f3Smrg#ifdef NFS_STDOUT_BUG 1849bb2e14f3Smrg /* 1850bb2e14f3Smrg * On some systems, NFS seems to leave a large number of nulls at 1851bb2e14f3Smrg * the end of the file. Ralph Swick says that this kludge makes the 1852bb2e14f3Smrg * problem go away. 1853bb2e14f3Smrg */ 1854bb2e14f3Smrg ftruncate (fileno(tmpfd), (off_t)ftell(tmpfd)); 1855bb2e14f3Smrg#endif 1856bb2e14f3Smrg} 1857bb2e14f3Smrg 1858bb2e14f3Smrg/* 1859bb2e14f3Smrg * Determine if a line has nothing in it. As a side effect, we trim white 1860bb2e14f3Smrg * space from the end of the line. Cpp magic cookies are also thrown away. 1861bb2e14f3Smrg * "XCOMM" token is transformed to "#". 1862bb2e14f3Smrg */ 1863bb2e14f3Smrgboolean 1864bb2e14f3Smrgisempty(char *line) 1865bb2e14f3Smrg{ 1866bb2e14f3Smrg char *pend; 1867bb2e14f3Smrg 1868bb2e14f3Smrg /* 1869bb2e14f3Smrg * Check for lines of the form 1870bb2e14f3Smrg * # n "... 1871bb2e14f3Smrg * or 1872bb2e14f3Smrg * # line n "... 1873bb2e14f3Smrg */ 1874bb2e14f3Smrg if (*line == '#') { 1875bb2e14f3Smrg pend = line+1; 1876bb2e14f3Smrg if (*pend == ' ') 1877bb2e14f3Smrg pend++; 1878bb2e14f3Smrg if (*pend == 'l' && pend[1] == 'i' && pend[2] == 'n' && 1879bb2e14f3Smrg pend[3] == 'e' && pend[4] == ' ') 1880bb2e14f3Smrg pend += 5; 1881bb2e14f3Smrg if (isdigit(*pend)) { 1882bb2e14f3Smrg do { 1883bb2e14f3Smrg pend++; 1884bb2e14f3Smrg } while (isdigit(*pend)); 1885bb2e14f3Smrg if (*pend == '\n' || *pend == '\0') 1886bb2e14f3Smrg return(TRUE); 1887bb2e14f3Smrg if (*pend++ == ' ' && *pend == '"') 1888bb2e14f3Smrg return(TRUE); 1889bb2e14f3Smrg } 1890bb2e14f3Smrg while (*pend) 1891bb2e14f3Smrg pend++; 1892bb2e14f3Smrg } else { 1893bb2e14f3Smrg for (pend = line; *pend; pend++) { 1894bb2e14f3Smrg if (*pend == 'X' && pend[1] == 'C' && pend[2] == 'O' && 1895bb2e14f3Smrg pend[3] == 'M' && pend[4] == 'M' && 1896bb2e14f3Smrg (pend == line || pend[-1] == ' ' || pend[-1] == '\t' || pend[-1] == '\r') && 1897bb2e14f3Smrg (pend[5] == ' ' || pend[5] == '\t' || pend[5] == '\r' || pend[5] == '\0')) 1898bb2e14f3Smrg { 1899bb2e14f3Smrg *pend = '#'; 1900bb2e14f3Smrg memmove(pend+1, pend+5, strlen(pend+5)+1); 1901bb2e14f3Smrg } 1902bb2e14f3Smrg#ifdef CROSSCOMPILE 1903bb2e14f3Smrg if (magic_make_vars) 1904bb2e14f3Smrg#endif 1905bb2e14f3Smrg { 1906bb2e14f3Smrg#if defined CROSSCOMPILE || defined MAGIC_MAKE_VARS 1907bb2e14f3Smrg if (*pend == 'X' && pend[1] == 'V' && pend[2] == 'A' && 1908bb2e14f3Smrg pend[3] == 'R') 1909bb2e14f3Smrg { 1910bb2e14f3Smrg char varbuf[5]; 1911bb2e14f3Smrg int i; 1912bb2e14f3Smrg 1913bb2e14f3Smrg if (pend[4] == 'd' && pend[5] == 'e' && pend[6] == 'f' && 1914bb2e14f3Smrg pend[7] >= '0' && pend[7] <= '9') 1915bb2e14f3Smrg { 1916bb2e14f3Smrg i = pend[7] - '0'; 1917bb2e14f3Smrg sprintf(varbuf, "%0.4d", xvariable); 1918bb2e14f3Smrg strncpy(pend+4, varbuf, 4); 1919bb2e14f3Smrg xvariables[i] = xvariable; 1920bb2e14f3Smrg xvariable = (xvariable + 1) % 10000; 1921bb2e14f3Smrg } 1922bb2e14f3Smrg else if (pend[4] == 'u' && pend[5] == 's' && 1923bb2e14f3Smrg pend[6] == 'e' && pend[7] >= '0' && 1924bb2e14f3Smrg pend[7] <= '9') 1925bb2e14f3Smrg { 1926bb2e14f3Smrg i = pend[7] - '0'; 1927bb2e14f3Smrg sprintf(varbuf, "%0.4d", xvariables[i]); 1928bb2e14f3Smrg strncpy(pend+4, varbuf, 4); 1929bb2e14f3Smrg } 1930bb2e14f3Smrg } 1931bb2e14f3Smrg#endif 1932bb2e14f3Smrg } 1933bb2e14f3Smrg } 1934bb2e14f3Smrg } 1935bb2e14f3Smrg while (--pend >= line && (*pend == ' ' || *pend == '\t' || *pend == '\r')) ; 1936bb2e14f3Smrg pend[1] = '\0'; 1937bb2e14f3Smrg return (*line == '\0'); 1938bb2e14f3Smrg} 1939bb2e14f3Smrg 1940bb2e14f3Smrg/*ARGSUSED*/ 1941bb2e14f3Smrgchar * 19421114aea8SmrgReadLine(FILE *tmpfd, const char *tmpfname) 1943bb2e14f3Smrg{ 1944bb2e14f3Smrg static boolean initialized = FALSE; 1945bb2e14f3Smrg static char *buf, *pline, *end; 1946bb2e14f3Smrg register char *p1, *p2; 1947bb2e14f3Smrg 1948bb2e14f3Smrg if (! initialized) { 1949bb2e14f3Smrg#ifdef WIN32 1950bb2e14f3Smrg FILE *fp = tmpfd; 1951bb2e14f3Smrg#endif 1952bb2e14f3Smrg int total_red; 1953bb2e14f3Smrg struct stat st; 1954bb2e14f3Smrg 1955bb2e14f3Smrg /* 1956bb2e14f3Smrg * Slurp it all up. 1957bb2e14f3Smrg */ 19588a954913Smrg fseek(tmpfd, 0, SEEK_SET); 1959bb2e14f3Smrg if (fstat(fileno(tmpfd), &st) < 0) 1960bb2e14f3Smrg LogFatal("cannot stat %s for size", tmpMakefile); 1961e5db2183Smrg pline = buf = Emalloc(st.st_size + 1); 1962bb2e14f3Smrg total_red = fread(buf, 1, st.st_size, tmpfd); 1963bb2e14f3Smrg if (total_red == 0 && st.st_size != 0) 1964bb2e14f3Smrg LogFatal("cannot read %s", tmpMakefile); 1965bb2e14f3Smrg end = buf + total_red; 1966bb2e14f3Smrg *end = '\0'; 19678a954913Smrg fseek(tmpfd, 0, SEEK_SET); 1968bb2e14f3Smrg#if defined(SYSV) || defined(WIN32) || defined(USE_FREOPEN) 1969bb2e14f3Smrg tmpfd = freopen(tmpfname, "w+", tmpfd); 1970a5399cb1Smrg# ifdef WIN32 1971bb2e14f3Smrg if (! tmpfd) /* if failed try again */ 1972bb2e14f3Smrg tmpfd = freopen(tmpfname, "w+", fp); 1973a5399cb1Smrg# endif 1974bb2e14f3Smrg if (! tmpfd) 1975bb2e14f3Smrg LogFatal("cannot reopen %s\n", tmpfname); 1976bb2e14f3Smrg#else /* !SYSV */ 1977bb2e14f3Smrg ftruncate(fileno(tmpfd), (off_t) 0); 1978bb2e14f3Smrg#endif /* !SYSV */ 1979bb2e14f3Smrg initialized = TRUE; 1980bb2e14f3Smrg fprintf (tmpfd, "# Makefile generated by imake - do not edit!\n"); 1981bb2e14f3Smrg } 1982bb2e14f3Smrg 1983bb2e14f3Smrg for (p1 = pline; p1 < end; p1++) { 1984bb2e14f3Smrg if (*p1 == '@' && *(p1+1) == '@' 1985bb2e14f3Smrg /* ignore ClearCase version-extended pathnames */ 1986bb2e14f3Smrg && !(p1 != pline && !isspace(*(p1-1)) && *(p1+2) == '/')) 1987bb2e14f3Smrg { /* soft EOL */ 1988bb2e14f3Smrg *p1++ = '\0'; 1989bb2e14f3Smrg p1++; /* skip over second @ */ 1990bb2e14f3Smrg break; 1991bb2e14f3Smrg } 1992bb2e14f3Smrg else if (*p1 == '\n') { /* real EOL */ 1993bb2e14f3Smrg#if defined CROSSCOMPILE || defined WIN32 1994bb2e14f3Smrg# if defined CROSSCOMPILE 1995bb2e14f3Smrg if (sys == win32) 1996bb2e14f3Smrg# endif 1997bb2e14f3Smrg { 1998bb2e14f3Smrg if (p1 > pline && p1[-1] == '\r') 1999bb2e14f3Smrg p1[-1] = '\0'; 2000bb2e14f3Smrg } 2001bb2e14f3Smrg#endif 2002bb2e14f3Smrg *p1++ = '\0'; 2003bb2e14f3Smrg break; 2004bb2e14f3Smrg } 2005bb2e14f3Smrg } 2006bb2e14f3Smrg 2007bb2e14f3Smrg /* 2008bb2e14f3Smrg * return NULL at the end of the file. 2009bb2e14f3Smrg */ 2010bb2e14f3Smrg p2 = (pline == p1 ? NULL : pline); 2011bb2e14f3Smrg pline = p1; 2012bb2e14f3Smrg return(p2); 2013bb2e14f3Smrg} 2014bb2e14f3Smrg 2015bb2e14f3Smrgvoid 2016e5db2183Smrgwritetmpfile(FILE *fd, const char *buf, size_t cnt, const char *fname) 2017bb2e14f3Smrg{ 2018e5db2183Smrg if (fwrite(buf, sizeof(char), cnt, fd) < cnt) 2019bb2e14f3Smrg LogFatal("Cannot write to %s.", fname); 2020bb2e14f3Smrg} 2021bb2e14f3Smrg 2022bb2e14f3Smrgchar * 2023e5db2183SmrgEmalloc(size_t size) 2024bb2e14f3Smrg{ 2025bb2e14f3Smrg char *p; 2026bb2e14f3Smrg 2027bb2e14f3Smrg if ((p = malloc(size)) == NULL) 2028e5db2183Smrg LogFatal("Cannot allocate %ld bytes", (long) size); 2029bb2e14f3Smrg return(p); 2030bb2e14f3Smrg} 2031bb2e14f3Smrg 2032bb2e14f3Smrg#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 2033bb2e14f3Smrgvoid 2034bb2e14f3SmrgKludgeOutputLine(char **pline) 2035bb2e14f3Smrg{ 2036bb2e14f3Smrg char *p = *pline; 2037bb2e14f3Smrg char quotechar = '\0'; 2038bb2e14f3Smrg 2039bb2e14f3Smrg switch (*p) { 2040bb2e14f3Smrg case '#': /*Comment - ignore*/ 2041bb2e14f3Smrg break; 2042bb2e14f3Smrg case '\t': /*Already tabbed - ignore it*/ 2043bb2e14f3Smrg break; 2044bb2e14f3Smrg case ' ': /*May need a tab*/ 2045bb2e14f3Smrg default: 2046a5399cb1Smrg# ifdef CROSSCOMPILE 2047bb2e14f3Smrg if (inline_syntax) 2048a5399cb1Smrg# endif 2049a5399cb1Smrg# if defined CROSSCOMPILE || defined INLINE_SYNTAX 2050bb2e14f3Smrg { 2051bb2e14f3Smrg if (*p == '<' && p[1] == '<') { /* inline file close */ 2052bb2e14f3Smrg InInline--; 2053bb2e14f3Smrg InRule = TRUE; 2054bb2e14f3Smrg break; 2055bb2e14f3Smrg } 2056bb2e14f3Smrg } 2057a5399cb1Smrg# endif 2058bb2e14f3Smrg /* 2059bb2e14f3Smrg * The following cases should not be treated as beginning of 2060bb2e14f3Smrg * rules: 2061bb2e14f3Smrg * variable := name (GNU make) 2062bb2e14f3Smrg * variable = .*:.* (':' should be allowed as value) 2063bb2e14f3Smrg * sed 's:/a:/b:' (: used in quoted values) 2064bb2e14f3Smrg */ 2065bb2e14f3Smrg for (; *p; p++) { 2066bb2e14f3Smrg if (quotechar) { 2067bb2e14f3Smrg if (quotechar == '\\' || 2068bb2e14f3Smrg (*p == quotechar && 2069bb2e14f3Smrg# if defined CROSSCOMPILE || defined WIN32 2070bb2e14f3Smrg ( 2071bb2e14f3Smrg# if defined CROSSCOMPILE 2072bb2e14f3Smrg (sys == win32) && 2073bb2e14f3Smrg# endif 2074bb2e14f3Smrg quotechar != ')') && 2075bb2e14f3Smrg# endif 2076bb2e14f3Smrg p[-1] != '\\')) 2077bb2e14f3Smrg quotechar = '\0'; 2078bb2e14f3Smrg continue; 2079bb2e14f3Smrg } 2080bb2e14f3Smrg switch (*p) { 2081bb2e14f3Smrg case '\\': 2082bb2e14f3Smrg case '"': 2083bb2e14f3Smrg case '\'': 2084bb2e14f3Smrg quotechar = *p; 2085bb2e14f3Smrg break; 2086bb2e14f3Smrg case '(': 2087bb2e14f3Smrg quotechar = ')'; 2088bb2e14f3Smrg break; 2089bb2e14f3Smrg case '{': 2090bb2e14f3Smrg quotechar = '}'; 2091bb2e14f3Smrg break; 2092bb2e14f3Smrg case '[': 2093bb2e14f3Smrg quotechar = ']'; 2094bb2e14f3Smrg break; 2095bb2e14f3Smrg case '=': 2096a5399cb1Smrg# ifdef CROSSCOMPILE 2097bb2e14f3Smrg if (remove_cpp_leadspace) 2098a5399cb1Smrg# endif 2099a5399cb1Smrg# if defined CROSSCOMPILE || defined REMOVE_CPP_LEADSPACE 2100bb2e14f3Smrg { 2101bb2e14f3Smrg if (!InRule && **pline == ' ') { 2102bb2e14f3Smrg while (**pline == ' ') 2103bb2e14f3Smrg (*pline)++; 2104bb2e14f3Smrg } 2105bb2e14f3Smrg } 2106a5399cb1Smrg# endif 2107bb2e14f3Smrg goto breakfor; 2108a5399cb1Smrg# if defined CROSSCOMPILE || defined INLINE_SYNTAX 2109bb2e14f3Smrg case '<': 2110bb2e14f3Smrg if (inline_syntax) { 2111bb2e14f3Smrg if (p[1] == '<') /* inline file start */ 2112bb2e14f3Smrg InInline++; 2113bb2e14f3Smrg } 2114bb2e14f3Smrg break; 2115a5399cb1Smrg# endif 2116bb2e14f3Smrg case ':': 2117bb2e14f3Smrg if (p[1] == '=') 2118bb2e14f3Smrg goto breakfor; 2119bb2e14f3Smrg while (**pline == ' ') 2120bb2e14f3Smrg (*pline)++; 2121bb2e14f3Smrg InRule = TRUE; 2122bb2e14f3Smrg return; 2123bb2e14f3Smrg } 2124bb2e14f3Smrg } 2125bb2e14f3Smrgbreakfor: 2126bb2e14f3Smrg if (InRule && **pline == ' ') 2127bb2e14f3Smrg **pline = '\t'; 2128bb2e14f3Smrg break; 2129bb2e14f3Smrg } 2130bb2e14f3Smrg} 2131bb2e14f3Smrg 2132bb2e14f3Smrgvoid 2133bb2e14f3SmrgKludgeResetRule(void) 2134bb2e14f3Smrg{ 2135bb2e14f3Smrg InRule = FALSE; 2136bb2e14f3Smrg} 2137bb2e14f3Smrg#endif 2138bb2e14f3Smrgchar * 21391114aea8SmrgStrdup(const char *cp) 2140bb2e14f3Smrg{ 2141bb2e14f3Smrg char *new = Emalloc(strlen(cp) + 1); 2142bb2e14f3Smrg 2143bb2e14f3Smrg strcpy(new, cp); 2144bb2e14f3Smrg return new; 2145bb2e14f3Smrg} 2146bb2e14f3Smrg 2147bb2e14f3Smrg#ifdef CROSSCOMPILE 2148bb2e14f3Smrgchar* 2149bb2e14f3SmrgCrossCompileCPP(void) 2150bb2e14f3Smrg{ 2151bb2e14f3Smrg char *cpp, *c; 2152e5db2183Smrg size_t len; 2153bb2e14f3Smrg if (crosscompile_use_cc_e) 2154bb2e14f3Smrg AddCppArg("-E"); 2155bb2e14f3Smrg 2156bb2e14f3Smrg cpp = strrchr(crosscompile_cpp,'/'); 2157bb2e14f3Smrg if (!cpp) 2158bb2e14f3Smrg cpp = crosscompile_cpp; 2159bb2e14f3Smrg else 2160bb2e14f3Smrg cpp++; 2161bb2e14f3Smrg 2162bb2e14f3Smrg len = strlen(cpp) + strlen(CrossCompileDir) + 2; 2163bb2e14f3Smrg c = Emalloc(len); 2164bb2e14f3Smrg 2165bb2e14f3Smrg (void)snprintf(c, len,"%s/%s",CrossCompileDir,cpp); 2166bb2e14f3Smrg 2167bb2e14f3Smrg return c; 2168bb2e14f3Smrg} 2169bb2e14f3Smrg 2170bb2e14f3Smrg#endif 2171bb2e14f3Smrg 2172bb2e14f3Smrg#ifdef CROSSCOMPILE 2173bb2e14f3Smrgstatic void 2174bb2e14f3Smrgget_cross_compile_dir(FILE *inFile) 2175bb2e14f3Smrg{ 2176bb2e14f3Smrg fprintf(inFile, "#define CrossCompileDir %s\n", 2177bb2e14f3Smrg CrossCompileDir); 2178bb2e14f3Smrg fprintf(inFile, "#define CrossCompiling YES\n"); 2179bb2e14f3Smrg} 2180bb2e14f3Smrg#endif 2181