imake.c revision 39f9c979
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 69bb2e14f3Smrg * for occurences 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. 73bb2e14f3Smrg * It also changes occurences 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); 330bb2e14f3Smrgchar *Emalloc(int 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); 3491114aea8Smrgvoid writetmpfile(FILE *fd, const char *buf, int cnt, const char *fname); 350bb2e14f3Smrg#ifdef SIGNALRETURNSINT 351bb2e14f3Smrgint catch(int sig); 352bb2e14f3Smrg#else 353bb2e14f3Smrgvoid catch(int sig); 354bb2e14f3Smrg#endif 3551114aea8Smrgvoid showargs(const char **argv); 3561114aea8Smrgboolean optional_include(FILE *inFile, const char *defsym, const char *fname); 3571114aea8Smrgvoid doit(FILE *outfd, const char *cmd, const char **argv); 358bb2e14f3Smrgboolean define_os_defaults(FILE *inFile); 359bb2e14f3Smrg#ifdef CROSSCOMPILE 360bb2e14f3Smrgstatic void get_cross_compile_dir(FILE *inFile); 361bb2e14f3Smrg#endif 362bb2e14f3Smrg#ifdef CROSSCOMPILEDIR 3631114aea8Smrgconst char *CrossCompileDir = CROSSCOMPILEDIR; 364bb2e14f3Smrg#else 3651114aea8Smrgconst char *CrossCompileDir = ""; 366bb2e14f3Smrg#endif 367bb2e14f3Smrgboolean CrossCompiling = FALSE; 368bb2e14f3Smrg 369bb2e14f3Smrg 370bb2e14f3Smrg 371bb2e14f3Smrgboolean verbose = FALSE; 372bb2e14f3Smrgboolean show = TRUE; 373bb2e14f3Smrg 374bb2e14f3Smrgint 375bb2e14f3Smrgmain(int argc, char *argv[]) 376bb2e14f3Smrg{ 377bb2e14f3Smrg FILE *tmpfd = NULL; 378bb2e14f3Smrg char makeMacro[ BUFSIZ ]; 379bb2e14f3Smrg char makefileMacro[ BUFSIZ ]; 380bb2e14f3Smrg int lenCrossCompileDir = 0; 381bb2e14f3Smrg 382bb2e14f3Smrg program = argv[0]; 383bb2e14f3Smrg init(); 384bb2e14f3Smrg 385bb2e14f3Smrg lenCrossCompileDir = strlen(CrossCompileDir); 386bb2e14f3Smrg if (lenCrossCompileDir) { 387bb2e14f3Smrg if (lenCrossCompileDir > (PATH_MAX - 20)) 388bb2e14f3Smrg LogFatal("Cross compile directory path too long %s\n", 389bb2e14f3Smrg CrossCompileDir); 390bb2e14f3Smrg else 391bb2e14f3Smrg CrossCompiling = TRUE; 392bb2e14f3Smrg } 393bb2e14f3Smrg 394bb2e14f3Smrg SetOpts(argc, argv); 395bb2e14f3Smrg Imakefile = FindImakefile(Imakefile); 396bb2e14f3Smrg CheckImakefileC(ImakefileC); 397bb2e14f3Smrg if (Makefile) { 398bb2e14f3Smrg tmpMakefile = Makefile; 399bb2e14f3Smrg if ((tmpfd = fopen(tmpMakefile, "w+")) == NULL) 400bb2e14f3Smrg LogFatal("Cannot create temporary file %s.", tmpMakefile); 401bb2e14f3Smrg } else { 4025afa940dSmrg#ifdef HAVE_MKSTEMP 403bb2e14f3Smrg int fd; 404bb2e14f3Smrg#endif 4051114aea8Smrg char *tmpMakefileName = Strdup(tmpMakefileTemplate); 4065afa940dSmrg#ifndef HAVE_MKSTEMP 4071114aea8Smrg if (mktemp(tmpMakefileName) == NULL || 4081114aea8Smrg (tmpfd = fopen(tmpMakefileName, "w+")) == NULL) { 4091114aea8Smrg LogFatal("Cannot create temporary file %s.", tmpMakefileName); 410bb2e14f3Smrg } 411bb2e14f3Smrg#else 4121114aea8Smrg fd = mkstemp(tmpMakefileName); 413bb2e14f3Smrg if (fd == -1 || (tmpfd = fdopen(fd, "w+")) == NULL) { 414bb2e14f3Smrg if (fd != -1) { 4151114aea8Smrg unlink(tmpMakefileName); close(fd); 416bb2e14f3Smrg } 4171114aea8Smrg LogFatal("Cannot create temporary file %s.", tmpMakefileName); 418bb2e14f3Smrg } 419bb2e14f3Smrg#endif 4201114aea8Smrg tmpMakefile = tmpMakefileName; 421bb2e14f3Smrg } 422bb2e14f3Smrg AddMakeArg("-f"); 423bb2e14f3Smrg AddMakeArg( tmpMakefile ); 424bb2e14f3Smrg sprintf(makeMacro, "MAKE=%s", program); 425bb2e14f3Smrg AddMakeArg( makeMacro ); 426bb2e14f3Smrg sprintf(makefileMacro, "MAKEFILE=%s", Imakefile); 427bb2e14f3Smrg AddMakeArg( makefileMacro ); 428bb2e14f3Smrg 429bb2e14f3Smrg cleanedImakefile = CleanCppInput(Imakefile); 430bb2e14f3Smrg cppit(cleanedImakefile, Template, ImakefileC, tmpfd, tmpMakefile); 431bb2e14f3Smrg 432bb2e14f3Smrg if (show) { 433bb2e14f3Smrg if (Makefile == NULL) 434bb2e14f3Smrg showit(tmpfd); 435bb2e14f3Smrg } else 436bb2e14f3Smrg makeit(); 437bb2e14f3Smrg wrapup(); 438bb2e14f3Smrg exit(0); 439bb2e14f3Smrg} 440bb2e14f3Smrg 441bb2e14f3Smrgvoid 442bb2e14f3Smrgshowit(FILE *fd) 443bb2e14f3Smrg{ 444bb2e14f3Smrg char buf[ BUFSIZ ]; 445bb2e14f3Smrg int red; 446bb2e14f3Smrg 447bb2e14f3Smrg fseek(fd, 0, 0); 448bb2e14f3Smrg while ((red = fread(buf, 1, BUFSIZ, fd)) > 0) 449bb2e14f3Smrg writetmpfile(stdout, buf, red, "stdout"); 450bb2e14f3Smrg if (red < 0) 451bb2e14f3Smrg LogFatal("Cannot read %s.", tmpMakefile); 452bb2e14f3Smrg} 453bb2e14f3Smrg 454bb2e14f3Smrgvoid 455bb2e14f3Smrgwrapup(void) 456bb2e14f3Smrg{ 457bb2e14f3Smrg if (tmpMakefile != Makefile) 458bb2e14f3Smrg unlink(tmpMakefile); 459bb2e14f3Smrg if (cleanedImakefile && cleanedImakefile != Imakefile) 460bb2e14f3Smrg unlink(cleanedImakefile); 461bb2e14f3Smrg if (haveImakefileC) 462bb2e14f3Smrg unlink(ImakefileC); 463bb2e14f3Smrg} 464bb2e14f3Smrg 465bb2e14f3Smrg#ifdef SIGNALRETURNSINT 466bb2e14f3Smrgint 467bb2e14f3Smrg#else 468bb2e14f3Smrgvoid 469bb2e14f3Smrg#endif 470bb2e14f3Smrgcatch(int sig) 471bb2e14f3Smrg{ 472bb2e14f3Smrg errno = 0; 4731114aea8Smrg LogFatal("Signal %d.", sig); 474bb2e14f3Smrg} 475bb2e14f3Smrg 476bb2e14f3Smrg/* 477bb2e14f3Smrg * Initialize some variables. 478bb2e14f3Smrg */ 479bb2e14f3Smrgvoid 480bb2e14f3Smrginit(void) 481bb2e14f3Smrg{ 482bb2e14f3Smrg register char *p; 483bb2e14f3Smrg 484bb2e14f3Smrg make_argindex=0; 485bb2e14f3Smrg while (make_argv[ make_argindex ] != NULL) 486bb2e14f3Smrg make_argindex++; 487bb2e14f3Smrg cpp_argindex = 0; 488bb2e14f3Smrg while (cpp_argv[ cpp_argindex ] != NULL) 489bb2e14f3Smrg cpp_argindex++; 490bb2e14f3Smrg 491bb2e14f3Smrg#if defined CROSSCOMPILE 492bb2e14f3Smrg if (sys == netBSD) 493bb2e14f3Smrg if (CrossCompiling) { 494bb2e14f3Smrg LogFatal("fix imake to do crosscompiling for NetBSD\n",""); 495bb2e14f3Smrg } else 496bb2e14f3Smrg#endif 497bb2e14f3Smrg#if defined(__NetBSD__) || defined CROSSCOMPILE 498bb2e14f3Smrg { 499bb2e14f3Smrg struct utsname uts; 500bb2e14f3Smrg static char argument[512]; 501bb2e14f3Smrg 502bb2e14f3Smrg /* 503bb2e14f3Smrg * Sharable imake configurations require a 504bb2e14f3Smrg * machine identifier. 505bb2e14f3Smrg */ 506bb2e14f3Smrg if (uname(&uts) != 0) 507bb2e14f3Smrg LogFatal("uname(3) failed; can't tell what %s", 508bb2e14f3Smrg "kind of machine you have."); 509bb2e14f3Smrg 510bb2e14f3Smrg memset(argument, 0, sizeof(argument)); 511bb2e14f3Smrg (void)snprintf(argument, sizeof(argument) - 1, 512bb2e14f3Smrg "-D__%s__", uts.machine); 513bb2e14f3Smrg 514bb2e14f3Smrg AddCppArg(argument); 515bb2e14f3Smrg } 516bb2e14f3Smrg#endif /* __NetBSD__ */ 517bb2e14f3Smrg 518bb2e14f3Smrg /* 519bb2e14f3Smrg * See if the standard include directory is different than 520bb2e14f3Smrg * the default. Or if cpp is not the default. Or if the make 521bb2e14f3Smrg * found by the PATH variable is not the default. 522bb2e14f3Smrg */ 523bb2e14f3Smrg if ((p = getenv("IMAKEINCLUDE"))) { 524bb2e14f3Smrg if (*p != '-' || *(p+1) != 'I') 525bb2e14f3Smrg LogFatal("Environment var IMAKEINCLUDE %s", 526bb2e14f3Smrg "must begin with -I"); 527bb2e14f3Smrg AddCppArg(p); 528bb2e14f3Smrg for (; *p; p++) 529bb2e14f3Smrg if (*p == ' ') { 530bb2e14f3Smrg *p++ = '\0'; 531bb2e14f3Smrg AddCppArg(p); 532bb2e14f3Smrg } 533bb2e14f3Smrg } 534bb2e14f3Smrg if ((p = getenv("IMAKECPP"))) 535bb2e14f3Smrg cpp = p; 536bb2e14f3Smrg if ((p = getenv("IMAKEMAKE"))) 537bb2e14f3Smrg make_argv[0] = p; 538bb2e14f3Smrg 539bb2e14f3Smrg if (signal(SIGINT, SIG_IGN) != SIG_IGN) 540bb2e14f3Smrg signal(SIGINT, catch); 541bb2e14f3Smrg#ifdef SIGCHLD 542bb2e14f3Smrg signal(SIGCHLD, SIG_DFL); 543bb2e14f3Smrg#endif 544bb2e14f3Smrg} 545bb2e14f3Smrg 546bb2e14f3Smrgvoid 5471114aea8SmrgAddMakeArg(const char *arg) 548bb2e14f3Smrg{ 549bb2e14f3Smrg errno = 0; 550bb2e14f3Smrg if (make_argindex >= ARGUMENTS-1) 5511114aea8Smrg LogFatal("Out of internal storage."); 552bb2e14f3Smrg make_argv[ make_argindex++ ] = arg; 553bb2e14f3Smrg make_argv[ make_argindex ] = NULL; 554bb2e14f3Smrg} 555bb2e14f3Smrg 556bb2e14f3Smrgvoid 5571114aea8SmrgAddCppArg(const char *arg) 558bb2e14f3Smrg{ 559bb2e14f3Smrg errno = 0; 560bb2e14f3Smrg if (cpp_argindex >= ARGUMENTS-1) 5611114aea8Smrg LogFatal("Out of internal storage."); 562bb2e14f3Smrg cpp_argv[ cpp_argindex++ ] = arg; 563bb2e14f3Smrg cpp_argv[ cpp_argindex ] = NULL; 564bb2e14f3Smrg} 565bb2e14f3Smrg 566bb2e14f3Smrgvoid 567bb2e14f3SmrgSetOpts(int argc, char **argv) 568bb2e14f3Smrg{ 569bb2e14f3Smrg 570bb2e14f3Smrg errno = 0; 571bb2e14f3Smrg /* 572bb2e14f3Smrg * Now gather the arguments for make 573bb2e14f3Smrg */ 574bb2e14f3Smrg for(argc--, argv++; argc; argc--, argv++) { 575bb2e14f3Smrg /* 576bb2e14f3Smrg * We intercept these flags. 577bb2e14f3Smrg */ 578bb2e14f3Smrg if (argv[0][0] == '-') { 579bb2e14f3Smrg if (argv[0][1] == 'D') { 580bb2e14f3Smrg AddCppArg(argv[0]); 581bb2e14f3Smrg } else if (argv[0][1] == 'I') { 582bb2e14f3Smrg AddCppArg(argv[0]); 583bb2e14f3Smrg } else if (argv[0][1] == 'U') { 584bb2e14f3Smrg AddCppArg(argv[0]); 585bb2e14f3Smrg } else if (argv[0][1] == 'W') { 586bb2e14f3Smrg AddCppArg(argv[0]); 587bb2e14f3Smrg } else if (argv[0][1] == 'f') { 588bb2e14f3Smrg if (argv[0][2]) 589bb2e14f3Smrg Imakefile = argv[0]+2; 590bb2e14f3Smrg else { 591bb2e14f3Smrg argc--, argv++; 592bb2e14f3Smrg if (! argc) 5931114aea8Smrg LogFatal("No description arg after -f flag"); 594bb2e14f3Smrg Imakefile = argv[0]; 595bb2e14f3Smrg } 596bb2e14f3Smrg } else if (argv[0][1] == 's') { 597bb2e14f3Smrg if (argv[0][2]) 598bb2e14f3Smrg Makefile = ((argv[0][2] == '-') && !argv[0][3]) ? 599bb2e14f3Smrg NULL : argv[0]+2; 600bb2e14f3Smrg else { 601bb2e14f3Smrg argc--, argv++; 602bb2e14f3Smrg if (!argc) 6031114aea8Smrg LogFatal("No description arg after -s flag"); 604bb2e14f3Smrg Makefile = ((argv[0][0] == '-') && !argv[0][1]) ? 605bb2e14f3Smrg NULL : argv[0]; 606bb2e14f3Smrg } 607bb2e14f3Smrg show = TRUE; 608bb2e14f3Smrg } else if (argv[0][1] == 'e') { 609bb2e14f3Smrg Makefile = (argv[0][2] ? argv[0]+2 : NULL); 610bb2e14f3Smrg show = FALSE; 611bb2e14f3Smrg } else if (argv[0][1] == 'T') { 612bb2e14f3Smrg if (argv[0][2]) 613bb2e14f3Smrg Template = argv[0]+2; 614bb2e14f3Smrg else { 615bb2e14f3Smrg argc--, argv++; 616bb2e14f3Smrg if (! argc) 6171114aea8Smrg LogFatal("No description arg after -T flag"); 618bb2e14f3Smrg Template = argv[0]; 619bb2e14f3Smrg } 620bb2e14f3Smrg } else if (argv[0][1] == 'C') { 621bb2e14f3Smrg if (argv[0][2]) 622bb2e14f3Smrg ImakefileC = argv[0]+2; 623bb2e14f3Smrg else { 624bb2e14f3Smrg argc--, argv++; 625bb2e14f3Smrg if (! argc) 6261114aea8Smrg LogFatal("No imakeCfile arg after -C flag"); 627bb2e14f3Smrg ImakefileC = argv[0]; 628bb2e14f3Smrg } 629bb2e14f3Smrg } else if (argv[0][1] == 'v') { 630bb2e14f3Smrg verbose = TRUE; 631bb2e14f3Smrg } else 632bb2e14f3Smrg AddMakeArg(argv[0]); 633bb2e14f3Smrg } else 634bb2e14f3Smrg AddMakeArg(argv[0]); 635bb2e14f3Smrg } 636bb2e14f3Smrg 637bb2e14f3Smrg#ifndef CROSSCOMPILE 638bb2e14f3Smrg# ifdef USE_CC_E 639bb2e14f3Smrg if (!cpp) 640bb2e14f3Smrg { 641bb2e14f3Smrg AddCppArg("-E"); 642a5399cb1Smrg# ifdef __GNUC__ 643bb2e14f3Smrg if (verbose) 644bb2e14f3Smrg AddCppArg("-v"); 645a5399cb1Smrg# endif 646bb2e14f3Smrg cpp = DEFAULT_CC; 647bb2e14f3Smrg } 648bb2e14f3Smrg# else 649bb2e14f3Smrg if (!cpp) 650bb2e14f3Smrg cpp = DEFAULT_CPP; 651bb2e14f3Smrg# endif 652bb2e14f3Smrg#else 653bb2e14f3Smrg if (!cpp) 654bb2e14f3Smrg cpp = CrossCompileCPP(); 655bb2e14f3Smrg#endif 656bb2e14f3Smrg 657bb2e14f3Smrg cpp_argv[0] = cpp; 658bb2e14f3Smrg AddCppArg(ImakefileC); 659bb2e14f3Smrg} 660bb2e14f3Smrg 6611114aea8Smrgconst char * 6621114aea8SmrgFindImakefile(const char *Imakefile) 663bb2e14f3Smrg{ 664bb2e14f3Smrg if (Imakefile) { 665bb2e14f3Smrg if (access(Imakefile, R_OK) < 0) 666bb2e14f3Smrg LogFatal("Cannot find %s.", Imakefile); 667bb2e14f3Smrg } else { 668bb2e14f3Smrg if (access("Imakefile", R_OK) < 0) { 669bb2e14f3Smrg if (access("imakefile", R_OK) < 0) 6701114aea8Smrg LogFatal("No description file."); 671bb2e14f3Smrg else 672bb2e14f3Smrg Imakefile = "imakefile"; 673bb2e14f3Smrg } else 674bb2e14f3Smrg Imakefile = "Imakefile"; 675bb2e14f3Smrg } 676bb2e14f3Smrg return(Imakefile); 677bb2e14f3Smrg} 678bb2e14f3Smrg 6791114aea8Smrgstatic void _X_ATTRIBUTE_PRINTF(1, 0) 6801114aea8SmrgvLogMsg(const char *fmt, va_list args) 681bb2e14f3Smrg{ 6821114aea8Smrg int error_number = errno; 6831114aea8Smrg 6841114aea8Smrg if (error_number) { 6851114aea8Smrg fprintf(stderr, "%s: ", program); 6861114aea8Smrg fprintf(stderr, "%s\n", strerror(error_number)); 6871114aea8Smrg } 6881114aea8Smrg fprintf(stderr, "%s: ", program); 6891114aea8Smrg vfprintf(stderr, fmt, args); 6901114aea8Smrg fprintf(stderr, "\n"); 691bb2e14f3Smrg} 692bb2e14f3Smrg 693bb2e14f3Smrgvoid 6941114aea8SmrgLogFatal(const char *fmt, ...) 695bb2e14f3Smrg{ 696bb2e14f3Smrg static boolean entered = FALSE; 6971114aea8Smrg va_list args; 698bb2e14f3Smrg 699bb2e14f3Smrg if (entered) 700bb2e14f3Smrg return; 701bb2e14f3Smrg entered = TRUE; 702bb2e14f3Smrg 7031114aea8Smrg va_start(args, fmt); 7041114aea8Smrg vLogMsg(fmt, args); 7051114aea8Smrg va_end(args); 706bb2e14f3Smrg fprintf(stderr, " Stop.\n"); 707bb2e14f3Smrg wrapup(); 708bb2e14f3Smrg exit(1); 709bb2e14f3Smrg} 710bb2e14f3Smrg 711bb2e14f3Smrgvoid 7121114aea8SmrgLogMsg(const char *fmt, ...) 713bb2e14f3Smrg{ 7141114aea8Smrg va_list args; 715bb2e14f3Smrg 7161114aea8Smrg va_start(args, fmt); 7171114aea8Smrg vLogMsg(fmt, args); 7181114aea8Smrg va_end(args); 719bb2e14f3Smrg} 720bb2e14f3Smrg 721bb2e14f3Smrgvoid 7221114aea8Smrgshowargs(const char **argv) 723bb2e14f3Smrg{ 724bb2e14f3Smrg for (; *argv; argv++) 725bb2e14f3Smrg fprintf(stderr, "%s ", *argv); 726bb2e14f3Smrg fprintf(stderr, "\n"); 727bb2e14f3Smrg} 728bb2e14f3Smrg 729bb2e14f3Smrg#define ImakefileCHeader "/* imake - temporary file */" 730bb2e14f3Smrg 731bb2e14f3Smrgvoid 7321114aea8SmrgCheckImakefileC(const char *masterc) 733bb2e14f3Smrg{ 734bb2e14f3Smrg char mkcbuf[1024]; 735bb2e14f3Smrg FILE *inFile; 736bb2e14f3Smrg 737bb2e14f3Smrg if (access(masterc, F_OK) == 0) { 738bb2e14f3Smrg inFile = fopen(masterc, "r"); 739bb2e14f3Smrg if (inFile == NULL) 740bb2e14f3Smrg LogFatal("Refuse to overwrite: %s", masterc); 741bb2e14f3Smrg if ((fgets(mkcbuf, sizeof(mkcbuf), inFile) && 742bb2e14f3Smrg strncmp(mkcbuf, ImakefileCHeader, 743bb2e14f3Smrg sizeof(ImakefileCHeader)-1))) 744bb2e14f3Smrg { 745bb2e14f3Smrg fclose(inFile); 746bb2e14f3Smrg LogFatal("Refuse to overwrite: %s", masterc); 747bb2e14f3Smrg } 74839f9c979Smrg else 74939f9c979Smrg fclose(inFile); 750bb2e14f3Smrg } 751bb2e14f3Smrg} 752bb2e14f3Smrg 753bb2e14f3Smrg#define LocalDefineFmt "#define %s \"%s\"\n" 754bb2e14f3Smrg#define IncludeFmt "#include %s\n" 755bb2e14f3Smrg#define ImakeDefSym "INCLUDE_IMAKEFILE" 756bb2e14f3Smrg#define ImakeTmplSym "IMAKE_TEMPLATE" 757bb2e14f3Smrg#define OverrideWarning "Warning: local file \"%s\" overrides global macros." 758bb2e14f3Smrg 759bb2e14f3Smrgboolean 7601114aea8Smrgoptional_include(FILE *inFile, const char *defsym, const char *fname) 761bb2e14f3Smrg{ 762bb2e14f3Smrg errno = 0; 763bb2e14f3Smrg if (access(fname, R_OK) == 0) { 764bb2e14f3Smrg LogMsg(OverrideWarning, fname); 765bb2e14f3Smrg return (fprintf(inFile, LocalDefineFmt, defsym, fname) < 0 || 766bb2e14f3Smrg fprintf(inFile, IncludeFmt, defsym) < 0); 767bb2e14f3Smrg } 768bb2e14f3Smrg return FALSE; 769bb2e14f3Smrg} 770bb2e14f3Smrg 771bb2e14f3Smrgvoid 7721114aea8Smrgdoit(FILE *outfd, const char *cmd, const char **argv) 773bb2e14f3Smrg{ 774bb2e14f3Smrg int pid; 775bb2e14f3Smrg waitType status; 776bb2e14f3Smrg 777bb2e14f3Smrg /* 778bb2e14f3Smrg * Fork and exec the command. 779bb2e14f3Smrg */ 780bb2e14f3Smrg#ifdef WIN32 781bb2e14f3Smrg if (outfd) 782bb2e14f3Smrg dup2(fileno(outfd), 1); 783bb2e14f3Smrg status = _spawnvp(_P_WAIT, cmd, argv); 784bb2e14f3Smrg if (status < 0) 785bb2e14f3Smrg LogFatal("Cannot spawn %s.", cmd); 786bb2e14f3Smrg if (status > 0) 7871114aea8Smrg LogFatal("Exit code %d.", status); 788bb2e14f3Smrg#else 789bb2e14f3Smrg pid = fork(); 790bb2e14f3Smrg if (pid < 0) 7911114aea8Smrg LogFatal("Cannot fork."); 792bb2e14f3Smrg if (pid) { /* parent... simply wait */ 793bb2e14f3Smrg while (wait(&status) > 0) { 794bb2e14f3Smrg errno = 0; 795bb2e14f3Smrg if (WIFSIGNALED(status)) 7961114aea8Smrg LogFatal("Signal %d.", waitSig(status)); 797bb2e14f3Smrg if (WIFEXITED(status) && waitCode(status)) 7981114aea8Smrg LogFatal("Exit code %d.", waitCode(status)); 799bb2e14f3Smrg } 800bb2e14f3Smrg } 801bb2e14f3Smrg else { /* child... dup and exec cmd */ 802bb2e14f3Smrg if (verbose) 803bb2e14f3Smrg showargs(argv); 804bb2e14f3Smrg if (outfd) 805bb2e14f3Smrg dup2(fileno(outfd), 1); 806bb2e14f3Smrg execvp(cmd, argv); 807bb2e14f3Smrg LogFatal("Cannot exec %s.", cmd); 808bb2e14f3Smrg } 809bb2e14f3Smrg#endif 810bb2e14f3Smrg} 811bb2e14f3Smrg 812bb2e14f3Smrg#if !defined WIN32 813bb2e14f3Smrgstatic void 8141114aea8Smrgparse_utsname(struct utsname *name, const char *fmt, char *result, const char *msg) 815bb2e14f3Smrg{ 816bb2e14f3Smrg char buf[SYS_NMLN * 5 + 1]; 817bb2e14f3Smrg char *ptr = buf; 818bb2e14f3Smrg int arg; 819bb2e14f3Smrg 820bb2e14f3Smrg if (!name) 821bb2e14f3Smrg LogFatal(msg,fmt); 822bb2e14f3Smrg 823bb2e14f3Smrg /* Assemble all the pieces into a buffer. */ 824bb2e14f3Smrg for (arg = 0; fmt[arg] != ' '; arg++) 825bb2e14f3Smrg { 826bb2e14f3Smrg /* Our buffer is only guaranteed to hold 5 arguments. */ 827bb2e14f3Smrg if (arg >= 5) 828bb2e14f3Smrg LogFatal(msg, fmt); 829bb2e14f3Smrg 830bb2e14f3Smrg switch (fmt[arg]) 831bb2e14f3Smrg { 832bb2e14f3Smrg case 's': 833bb2e14f3Smrg if (arg > 0) 834bb2e14f3Smrg *ptr++ = ' '; 835bb2e14f3Smrg strcpy(ptr, name->sysname); 836bb2e14f3Smrg ptr += strlen(ptr); 837bb2e14f3Smrg break; 838bb2e14f3Smrg 839bb2e14f3Smrg case 'n': 840bb2e14f3Smrg if (arg > 0) 841bb2e14f3Smrg *ptr++ = ' '; 842bb2e14f3Smrg strcpy(ptr, name->nodename); 843bb2e14f3Smrg ptr += strlen(ptr); 844bb2e14f3Smrg break; 845bb2e14f3Smrg 846bb2e14f3Smrg case 'r': 847bb2e14f3Smrg if (arg > 0) 848bb2e14f3Smrg *ptr++ = ' '; 849bb2e14f3Smrg strcpy(ptr, name->release); 850bb2e14f3Smrg ptr += strlen(ptr); 851bb2e14f3Smrg break; 852bb2e14f3Smrg 853bb2e14f3Smrg case 'v': 854bb2e14f3Smrg if (arg > 0) 855bb2e14f3Smrg *ptr++ = ' '; 856bb2e14f3Smrg strcpy(ptr, name->version); 857bb2e14f3Smrg ptr += strlen(ptr); 858bb2e14f3Smrg break; 859bb2e14f3Smrg 860bb2e14f3Smrg case 'm': 861bb2e14f3Smrg if (arg > 0) 862bb2e14f3Smrg *ptr++ = ' '; 863bb2e14f3Smrg strcpy(ptr, name->machine); 864bb2e14f3Smrg ptr += strlen(ptr); 865bb2e14f3Smrg break; 866bb2e14f3Smrg 867bb2e14f3Smrg default: 868bb2e14f3Smrg LogFatal(msg, fmt); 869bb2e14f3Smrg } 870bb2e14f3Smrg } 871bb2e14f3Smrg 872bb2e14f3Smrg /* Just in case... */ 873bb2e14f3Smrg if (strlen(buf) >= sizeof(buf)) 8741114aea8Smrg LogFatal("Buffer overflow parsing uname."); 875bb2e14f3Smrg 876bb2e14f3Smrg /* Parse the buffer. The sscanf() return value is rarely correct. */ 877bb2e14f3Smrg *result = '\0'; 878bb2e14f3Smrg (void) sscanf(buf, fmt + arg + 1, result); 879bb2e14f3Smrg} 880bb2e14f3Smrg 881bb2e14f3Smrg/* Trim leading 0's and periods from version names. The 0's cause 882bb2e14f3Smrg the number to be interpreted as octal numbers. Some version strings 883bb2e14f3Smrg have the potential for different numbers of .'s in them. 884bb2e14f3Smrg */ 885bb2e14f3Smrg 886bb2e14f3Smrgstatic char * 887bb2e14f3Smrgtrim_version(char *p) 888bb2e14f3Smrg{ 889bb2e14f3Smrg 890bb2e14f3Smrg if (p != 0 && *p != '\0') 891bb2e14f3Smrg { 892bb2e14f3Smrg while ((*p == '0' || *p == '.') && *(p + 1) != '\0') 893bb2e14f3Smrg ++p; 894bb2e14f3Smrg } 895bb2e14f3Smrg return (p); 896bb2e14f3Smrg} 897bb2e14f3Smrg#endif 898bb2e14f3Smrg 899bb2e14f3Smrg#if defined(linux) || defined(__GLIBC__) 900bb2e14f3Smrgconst char *libc_c= 901bb2e14f3Smrg"#include <stdio.h>\n" 902bb2e14f3Smrg"#include <ctype.h>\n" 903bb2e14f3Smrg"\n" 904bb2e14f3Smrg"#if 1\n" 905bb2e14f3Smrg"#pragma weak gnu_get_libc_version\n" 906bb2e14f3Smrg"#pragma weak __libc_version\n" 907bb2e14f3Smrg"#pragma weak __linux_C_lib_version\n" 908bb2e14f3Smrg"#endif\n" 909bb2e14f3Smrg"\n" 910bb2e14f3Smrg"extern const char * gnu_get_libc_version (void);\n" 911bb2e14f3Smrg"extern const char * __linux_C_lib_version;\n" 912bb2e14f3Smrg"extern const char __libc_version [];\n" 913bb2e14f3Smrg"\n" 914bb2e14f3Smrg"int\n" 915bb2e14f3Smrg"main ()\n" 916bb2e14f3Smrg"{\n" 917bb2e14f3Smrg" int libcmajor = 0, libcminor = 0, libcteeny = 0;\n" 918bb2e14f3Smrg" const char * ptr = NULL;\n" 919bb2e14f3Smrg" int glibcmajor = 0;\n" 920bb2e14f3Smrg"\n" 921bb2e14f3Smrg" if (gnu_get_libc_version != 0)\n" 922bb2e14f3Smrg" {\n" 923bb2e14f3Smrg" ptr = gnu_get_libc_version ();\n" 924bb2e14f3Smrg" glibcmajor = 4;\n" 925bb2e14f3Smrg" }\n" 926bb2e14f3Smrg" else if (&__libc_version != 0)\n" 927bb2e14f3Smrg" {\n" 928bb2e14f3Smrg" ptr = __libc_version;\n" 929bb2e14f3Smrg" glibcmajor = 4;\n" 930bb2e14f3Smrg" }\n" 931bb2e14f3Smrg" else if (&__linux_C_lib_version != 0)\n" 932bb2e14f3Smrg" {\n" 933bb2e14f3Smrg" ptr = __linux_C_lib_version;\n" 934bb2e14f3Smrg" }\n" 935bb2e14f3Smrg" else\n" 936bb2e14f3Smrg" {\n" 937bb2e14f3Smrg" libcmajor = 0; libcminor = 0; libcteeny = 0;\n" 938bb2e14f3Smrg" }\n" 939bb2e14f3Smrg"\n" 940bb2e14f3Smrg" if (ptr)\n" 941bb2e14f3Smrg" {\n" 942bb2e14f3Smrg" while (!isdigit (*ptr))\n" 943bb2e14f3Smrg" ptr++;\n" 944bb2e14f3Smrg"\n" 945bb2e14f3Smrg" sscanf (ptr, \"%d.%d.%d\", &libcmajor, &libcminor, &libcteeny);\n" 946bb2e14f3Smrg" libcmajor += glibcmajor;\n" 947bb2e14f3Smrg" }\n" 948bb2e14f3Smrg"\n" 949bb2e14f3Smrg" printf(\"#define DefaultLinuxCLibMajorVersion %d\\n\", libcmajor);\n" 950bb2e14f3Smrg" printf(\"#define DefaultLinuxCLibMinorVersion %d\\n\", libcminor);\n" 951bb2e14f3Smrg" printf(\"#define DefaultLinuxCLibTeenyVersion %d\\n\", libcteeny);\n" 952bb2e14f3Smrg"\n" 953bb2e14f3Smrg" return 0;\n" 954bb2e14f3Smrg"}\n" 955bb2e14f3Smrg; 956bb2e14f3Smrg 957bb2e14f3Smrgstatic void 958bb2e14f3Smrgget_libc_version(FILE *inFile) 959bb2e14f3Smrg{ 960bb2e14f3Smrg char aout[4096], *tmpdir; 961bb2e14f3Smrg FILE *fp; 962bb2e14f3Smrg const char *format = "%s -o %s -x c -"; 963bb2e14f3Smrg char *cc; 964bb2e14f3Smrg int len; 965bb2e14f3Smrg char *command; 966bb2e14f3Smrg 967bb2e14f3Smrg /* If $TMPDIR is defined and has an acceptable length, 968a5399cb1Smrg * use that as tmp dir, else use /tmp. That fixes 969bb2e14f3Smrg * problems with /tmp mounted "noexec". 970bb2e14f3Smrg */ 971bb2e14f3Smrg if((tmpdir = getenv("TMPDIR")) != NULL && strlen(tmpdir) < (4096-13)) 972bb2e14f3Smrg strcpy(aout, tmpdir); 973bb2e14f3Smrg else 974bb2e14f3Smrg strcpy(aout, "/tmp"); 975bb2e14f3Smrg strcat(aout, "/imakeXXXXXX"); 976bb2e14f3Smrg 977bb2e14f3Smrg /* Pre-create temp file safely */ 978bb2e14f3Smrg { 979bb2e14f3Smrg /* Linux + ELF has mkstemp() */ 980bb2e14f3Smrg int tmpfd; 981bb2e14f3Smrg if ((tmpfd = mkstemp(aout)) == -1) { 982bb2e14f3Smrg perror("mkstemp"); 983bb2e14f3Smrg abort(); 984bb2e14f3Smrg } 985bb2e14f3Smrg close(tmpfd); 986bb2e14f3Smrg } 987bb2e14f3Smrg cc = getenv ("CC"); 988bb2e14f3Smrg if (cc == NULL) 989bb2e14f3Smrg cc = "gcc"; 990bb2e14f3Smrg len = strlen (aout) + strlen (format) + strlen (cc); 991bb2e14f3Smrg if (len < 128) len = 128; 992bb2e14f3Smrg if((command = alloca (len)) == NULL) 993bb2e14f3Smrg abort(); 994bb2e14f3Smrg 995bb2e14f3Smrg if (snprintf (command , len, format, cc, aout) == len) 996bb2e14f3Smrg abort (); 997bb2e14f3Smrg 998bb2e14f3Smrg fp = popen (command, "w"); 999bb2e14f3Smrg if (fp == NULL || fprintf (fp, "%s\n", libc_c) < 0 1000bb2e14f3Smrg || pclose (fp) != 0) 1001bb2e14f3Smrg abort (); 1002bb2e14f3Smrg 1003bb2e14f3Smrg fp = popen (aout, "r"); 1004bb2e14f3Smrg if (fp == NULL) 1005bb2e14f3Smrg abort (); 1006bb2e14f3Smrg 1007bb2e14f3Smrg while (fgets (command, len, fp)) 1008bb2e14f3Smrg fprintf (inFile, command); 1009bb2e14f3Smrg 1010bb2e14f3Smrg len = pclose (fp); 1011bb2e14f3Smrg remove (aout); 1012bb2e14f3Smrg if (len) 1013bb2e14f3Smrg abort (); 1014bb2e14f3Smrg} 1015bb2e14f3Smrg#endif 1016bb2e14f3Smrg 1017bb2e14f3Smrg#if defined(__OpenBSD__) || defined(__DragonFly__) 1018bb2e14f3Smrgstatic void 1019bb2e14f3Smrgget_stackprotector(FILE *inFile) 1020bb2e14f3Smrg{ 1021bb2e14f3Smrg FILE *fp; 1022bb2e14f3Smrg char *cc; 1023bb2e14f3Smrg char command[1024], buf[1024]; 1024a5399cb1Smrg 1025bb2e14f3Smrg cc = getenv("CC"); 1026bb2e14f3Smrg if (cc == NULL) { 1027bb2e14f3Smrg cc = "cc"; 1028bb2e14f3Smrg } 1029bb2e14f3Smrg snprintf(command, sizeof(command), "%s -v 2>&1", cc); 1030bb2e14f3Smrg fp = popen(command, "r"); 1031a5399cb1Smrg if (fp == NULL) 1032bb2e14f3Smrg abort(); 1033bb2e14f3Smrg while (fgets(buf, sizeof(buf), fp)) { 1034bb2e14f3Smrg if (strstr(buf, "propolice") != NULL) { 1035bb2e14f3Smrg fprintf(inFile, "#define ProPoliceSupport YES\n"); 1036bb2e14f3Smrg break; 1037bb2e14f3Smrg } 1038bb2e14f3Smrg } 1039a5399cb1Smrg pclose(fp); 1040bb2e14f3Smrg} 1041bb2e14f3Smrg#endif 1042a5399cb1Smrg 1043bb2e14f3Smrg 1044bb2e14f3Smrg#if defined CROSSCOMPILE || defined linux || defined(__GLIBC__) 1045bb2e14f3Smrgstatic void 1046bb2e14f3Smrgget_distrib(FILE *inFile) 1047bb2e14f3Smrg{ 1048bb2e14f3Smrg struct stat sb; 1049bb2e14f3Smrg 10501114aea8Smrg static const char* suse = "/etc/SuSE-release"; 10511114aea8Smrg static const char* redhat = "/etc/redhat-release"; 10521114aea8Smrg static const char* debian = "/etc/debian_version"; 1053bb2e14f3Smrg 1054bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxUnknown 0"); 1055bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxSuSE 1"); 1056bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxCaldera 2"); 1057bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxCraftworks 3"); 1058bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxDebian 4"); 1059bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxInfoMagic 5"); 1060bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxKheops 6"); 1061bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxPro 7"); 1062bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxRedHat 8"); 1063bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxSlackware 9"); 1064bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxTurbo 10"); 1065bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxWare 11"); 1066bb2e14f3Smrg fprintf (inFile, "%s\n", "#define LinuxYggdrasil 12"); 1067bb2e14f3Smrg 1068a5399cb1Smrg# ifdef CROSSCOMPILE 1069bb2e14f3Smrg if (CrossCompiling) { 1070bb2e14f3Smrg fprintf (inFile, "%s\n", 1071bb2e14f3Smrg "#define DefaultLinuxDistribution LinuxUnknown"); 1072bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown"); 1073bb2e14f3Smrg return; 1074bb2e14f3Smrg } 1075a5399cb1Smrg# endif 1076bb2e14f3Smrg if (lstat (suse, &sb) == 0) { 1077bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxSuSE"); 1078bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName SuSE"); 1079bb2e14f3Smrg return; 1080bb2e14f3Smrg } 1081bb2e14f3Smrg if (lstat (redhat, &sb) == 0) { 1082bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxRedHat"); 1083bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName RedHat"); 1084bb2e14f3Smrg return; 1085bb2e14f3Smrg } 1086bb2e14f3Smrg if (lstat (debian, &sb) == 0) { 1087bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxDebian"); 1088bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Debian"); 1089bb2e14f3Smrg /* You could also try to get the version of the Debian distrib by looking 1090bb2e14f3Smrg * at the content of /etc/debian_version */ 1091bb2e14f3Smrg return; 1092bb2e14f3Smrg } 1093bb2e14f3Smrg /* what's the definitive way to tell what any particular distribution is? */ 1094bb2e14f3Smrg 1095bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxUnknown"); 1096bb2e14f3Smrg fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown"); 1097bb2e14f3Smrg /* would like to know what version of the distribution it is */ 1098bb2e14f3Smrg} 1099bb2e14f3Smrg 1100bb2e14f3Smrgstatic void 1101bb2e14f3Smrgget_ld_version(FILE *inFile) 1102bb2e14f3Smrg{ 1103bb2e14f3Smrg FILE* ldprog; 1104bb2e14f3Smrg signed char c; 1105bb2e14f3Smrg int ldmajor, ldminor; 1106bb2e14f3Smrg const char *ld = "ld -v"; 1107bb2e14f3Smrg 1108a5399cb1Smrg# ifdef CROSSCOMPILE 1109bb2e14f3Smrg if (CrossCompiling) { 1110bb2e14f3Smrg char cmd[PATH_MAX]; 1111bb2e14f3Smrg strcpy (cmd, CrossCompileDir); 1112bb2e14f3Smrg strcat (cmd,"/"); 1113bb2e14f3Smrg strcat (cmd,ld); 1114bb2e14f3Smrg ldprog = popen (cmd, "r"); 1115bb2e14f3Smrg } else 1116a5399cb1Smrg# endif 1117bb2e14f3Smrg ldprog = popen (ld, "r"); 1118bb2e14f3Smrg 1119bb2e14f3Smrg if (ldprog) { 1120bb2e14f3Smrg do { 1121bb2e14f3Smrg c = fgetc (ldprog); 1122bb2e14f3Smrg } while (c != EOF && !isdigit (c)); 1123bb2e14f3Smrg ungetc (c, ldprog); 1124bb2e14f3Smrg (void) fscanf (ldprog, "%d.%d", &ldmajor, &ldminor); 1125bb2e14f3Smrg /* Start conversion to a more rational number */ 1126bb2e14f3Smrg if ((ldmajor > 2) || ((ldmajor == 2) && (ldminor > 9))) 1127bb2e14f3Smrg ldmajor *= 100; 1128bb2e14f3Smrg else 1129bb2e14f3Smrg ldmajor *= 10; 1130bb2e14f3Smrg 1131bb2e14f3Smrg fprintf(inFile, "#define DefaultLinuxBinUtilsMajorVersion %d\n", 1132bb2e14f3Smrg ldmajor + ldminor); 1133bb2e14f3Smrg pclose (ldprog); 1134bb2e14f3Smrg } 1135bb2e14f3Smrg} 1136bb2e14f3Smrg#endif 1137bb2e14f3Smrg 1138bb2e14f3Smrg#if defined __FreeBSD__ 1139bb2e14f3Smrgstatic void 1140bb2e14f3Smrgget_binary_format(FILE *inFile) 1141bb2e14f3Smrg{ 1142bb2e14f3Smrg int mib[2]; 1143bb2e14f3Smrg size_t len; 1144bb2e14f3Smrg int osrel = 0; 1145bb2e14f3Smrg FILE *objprog = NULL; 1146bb2e14f3Smrg int iself = 0; 1147bb2e14f3Smrg char buf[10]; 1148bb2e14f3Smrg char cmd[PATH_MAX]; 1149bb2e14f3Smrg 1150bb2e14f3Smrg mib[0] = CTL_KERN; 1151bb2e14f3Smrg mib[1] = KERN_OSRELDATE; 1152bb2e14f3Smrg len = sizeof(osrel); 1153bb2e14f3Smrg sysctl(mib, 2, &osrel, &len, NULL, 0); 1154bb2e14f3Smrg if (CrossCompiling) { 1155bb2e14f3Smrg strcpy (cmd, CrossCompileDir); 1156bb2e14f3Smrg strcat (cmd, "/"); 1157bb2e14f3Smrg strcat (cmd,"objformat"); 1158bb2e14f3Smrg } else 1159bb2e14f3Smrg strcpy (cmd, "objformat"); 1160bb2e14f3Smrg 1161bb2e14f3Smrg if (osrel >= 300004 && 1162bb2e14f3Smrg (objprog = popen(cmd, "r")) != NULL && 1163bb2e14f3Smrg fgets(buf, sizeof(buf), objprog) != NULL && 1164bb2e14f3Smrg strncmp(buf, "elf", 3) == 0) 1165bb2e14f3Smrg iself = 1; 1166bb2e14f3Smrg if (objprog) 1167bb2e14f3Smrg pclose(objprog); 1168bb2e14f3Smrg 1169bb2e14f3Smrg fprintf(inFile, "#define DefaultToElfFormat %s\n", iself ? "YES" : "NO"); 1170bb2e14f3Smrg} 1171bb2e14f3Smrg#endif 1172bb2e14f3Smrg 1173bb2e14f3Smrg#if defined(sun) && defined(__SVR4) 1174bb2e14f3Smrg/* Runs Sun compiler command and parses output - this is a bit of a hack 1175bb2e14f3Smrg * as it depends on the particular output format of the -V flag, but it's 1176bb2e14f3Smrg * worked for many releases. 1177bb2e14f3Smrg * 1178bb2e14f3Smrg * Input : cmd - command to run (called with -V flag) 1179bb2e14f3Smrg * path - path to command to run (use $PATH if NULL) 1180bb2e14f3Smrg * Output: cmajor & cminor - major and minor versions if found 1181bb2e14f3Smrg * Returns: 0 if successful, -1 if not. 1182bb2e14f3Smrg */ 1183bb2e14f3Smrgstatic int 1184a5399cb1Smrgask_sun_compiler_for_versions(const char *cmd, const char *path, 1185bb2e14f3Smrg int *cmajor, int *cminor) 1186bb2e14f3Smrg{ 1187bb2e14f3Smrg char buf[BUFSIZ]; 1188bb2e14f3Smrg char cmdtorun[PATH_MAX]; 1189bb2e14f3Smrg char* vptr; 1190bb2e14f3Smrg FILE* ccproc; 1191bb2e14f3Smrg const char vflag[] = " -V 2>&1"; 1192bb2e14f3Smrg int retval = -1; 1193a5399cb1Smrg 1194bb2e14f3Smrg int len = strlen(cmd) + sizeof(vflag); 1195bb2e14f3Smrg 1196bb2e14f3Smrg if (path != NULL) { 1197bb2e14f3Smrg len += strlen(path) + 1; 1198bb2e14f3Smrg } 1199bb2e14f3Smrg 1200bb2e14f3Smrg if (len < sizeof(cmdtorun)) { 1201bb2e14f3Smrg if (path != NULL) { 1202bb2e14f3Smrg sprintf(cmdtorun, "%s/%s %s", path, cmd, vflag); 1203bb2e14f3Smrg } else { 1204bb2e14f3Smrg sprintf(cmdtorun, "%s %s", cmd, vflag); 1205bb2e14f3Smrg } 1206bb2e14f3Smrg 1207bb2e14f3Smrg if ((ccproc = popen (cmdtorun, "r")) != NULL) { 1208bb2e14f3Smrg if (fgets (buf, sizeof(buf), ccproc) != NULL) { 1209bb2e14f3Smrg vptr = strrchr (buf, 'C'); 1210bb2e14f3Smrg if (vptr) { 1211bb2e14f3Smrg for (; (*vptr != '\0') && !isdigit(*vptr); vptr++) { 1212bb2e14f3Smrg /* Do nothing - just scanning for first digit */ 1213bb2e14f3Smrg } 1214bb2e14f3Smrg if (*vptr != '\0') { 1215bb2e14f3Smrg if (sscanf (vptr, "%d.%d", cmajor, cminor) == 2) { 1216bb2e14f3Smrg retval = 0; 1217bb2e14f3Smrg } 1218bb2e14f3Smrg } 1219bb2e14f3Smrg } 1220bb2e14f3Smrg if (retval != 0) { 1221a5399cb1Smrg fprintf(stderr, 1222bb2e14f3Smrg "warning: could not parse version number in output of:\n" 1223bb2e14f3Smrg " %s\n", cmdtorun); 1224bb2e14f3Smrg } 1225bb2e14f3Smrg while (fgets (buf, sizeof(buf), ccproc) != NULL) {}; 1226bb2e14f3Smrg } 1227bb2e14f3Smrg pclose (ccproc); 1228bb2e14f3Smrg } 1229bb2e14f3Smrg } 1230bb2e14f3Smrg return retval; 1231bb2e14f3Smrg} 1232bb2e14f3Smrg 1233bb2e14f3Smrg/* Find Sun compilers and their versions if present */ 1234bb2e14f3Smrgstatic void 1235bb2e14f3Smrgget_sun_compiler_versions (FILE *inFile) 1236bb2e14f3Smrg{ 1237bb2e14f3Smrg const char* sunpro_path = "/opt/SUNWspro/bin"; 1238bb2e14f3Smrg int cmajor, cminor, found = 0; 1239bb2e14f3Smrg 1240bb2e14f3Smrg /* If cross-compiling, only check CrossCompilerDir for compilers. 1241a5399cb1Smrg * If not cross-compiling, first check cc in users $PATH, 1242bb2e14f3Smrg * then try /opt/SUNWspro if not found in the users $PATH 1243bb2e14f3Smrg */ 1244bb2e14f3Smrg 1245a5399cb1Smrg# if defined CROSSCOMPILE 1246bb2e14f3Smrg if (CrossCompiling) { 1247bb2e14f3Smrg if (ask_sun_compiler_for_versions("cc", CrossCompileDir, 1248bb2e14f3Smrg &cmajor, &cminor) == 0) { 1249bb2e14f3Smrg found = 1; 1250bb2e14f3Smrg } 1251a5399cb1Smrg } 1252bb2e14f3Smrg else 1253a5399cb1Smrg# endif 1254a5399cb1Smrg { 1255bb2e14f3Smrg if (ask_sun_compiler_for_versions("cc", NULL, &cmajor, &cminor) == 0) { 1256bb2e14f3Smrg found = 1; 1257bb2e14f3Smrg } else if (ask_sun_compiler_for_versions("cc", sunpro_path, 1258bb2e14f3Smrg &cmajor, &cminor) == 0) { 1259bb2e14f3Smrg found = 1; 1260bb2e14f3Smrg fprintf(inFile, "#define DefaultSunProCCompilerDir %s", sunpro_path); 1261bb2e14f3Smrg } 1262bb2e14f3Smrg } 1263bb2e14f3Smrg 1264bb2e14f3Smrg if (found) { 1265bb2e14f3Smrg fprintf (inFile, 1266bb2e14f3Smrg "#define DefaultSunProCCompilerMajorVersion %d\n", cmajor); 1267bb2e14f3Smrg fprintf (inFile, 1268bb2e14f3Smrg "#define DefaultSunProCCompilerMinorVersion %d\n", cminor); 1269bb2e14f3Smrg } 1270bb2e14f3Smrg 1271bb2e14f3Smrg /* Now do it again for C++ compiler (CC) */ 1272bb2e14f3Smrg found = 0; 1273a5399cb1Smrg# if defined CROSSCOMPILE 1274bb2e14f3Smrg if (CrossCompiling) { 1275bb2e14f3Smrg if (ask_sun_compiler_for_versions("CC", CrossCompileDir, 1276bb2e14f3Smrg &cmajor, &cminor) == 0) { 1277bb2e14f3Smrg found = 1; 1278bb2e14f3Smrg } 1279a5399cb1Smrg } 1280bb2e14f3Smrg else 1281a5399cb1Smrg# endif 1282a5399cb1Smrg { 1283bb2e14f3Smrg if (ask_sun_compiler_for_versions("CC", NULL, &cmajor, &cminor) == 0) { 1284bb2e14f3Smrg found = 1; 1285bb2e14f3Smrg } else if (ask_sun_compiler_for_versions("CC", sunpro_path, 1286bb2e14f3Smrg &cmajor, &cminor) == 0) { 1287bb2e14f3Smrg found = 1; 1288a5399cb1Smrg fprintf(inFile, 1289bb2e14f3Smrg "#define DefaultSunProCplusplusCompilerDir %s", sunpro_path); 1290bb2e14f3Smrg } 1291bb2e14f3Smrg } 1292bb2e14f3Smrg 1293bb2e14f3Smrg if (found) { 1294bb2e14f3Smrg fprintf (inFile, 1295bb2e14f3Smrg "#define DefaultSunProCplusplusCompilerMajorVersion %d\n", 1296bb2e14f3Smrg cmajor); 1297bb2e14f3Smrg fprintf (inFile, 1298bb2e14f3Smrg "#define DefaultSunProCplusplusCompilerMinorVersion %d\n", 1299bb2e14f3Smrg cminor); 1300bb2e14f3Smrg } 1301bb2e14f3Smrg} 1302bb2e14f3Smrg#endif 1303bb2e14f3Smrg 1304bb2e14f3Smrg#if defined CROSSCOMPILE || defined __GNUC__ 1305bb2e14f3Smrgstatic void 1306bb2e14f3Smrgget_gcc_version(FILE *inFile, char *name) 1307bb2e14f3Smrg{ 1308bb2e14f3Smrg fprintf (inFile, "#define HasGcc 1\n"); 1309a5399cb1Smrg# ifdef CROSSCOMPILE 1310bb2e14f3Smrg if (CrossCompiling) 1311bb2e14f3Smrg { 1312bb2e14f3Smrg if (gnu_c > 1) { 1313bb2e14f3Smrg fprintf (inFile, "#define HasGcc2 1\n"); 1314bb2e14f3Smrg if (gnu_c > 2) 1315bb2e14f3Smrg fprintf (inFile, "#define HasGcc3 1\n"); 1316bb2e14f3Smrg } 1317bb2e14f3Smrg fprintf (inFile, "#define GccMajorVersion %d\n", gnu_c); 1318bb2e14f3Smrg fprintf (inFile, "#define GccMinorVersion %d\n", gnu_c_minor); 1319bb2e14f3Smrg } else 1320a5399cb1Smrg# endif 1321bb2e14f3Smrg { 1322a5399cb1Smrg# if __GNUC__ > 1 1323bb2e14f3Smrg fprintf (inFile, "#define HasGcc2 1\n"); 1324a5399cb1Smrg# if __GNUC__ > 2 1325bb2e14f3Smrg fprintf (inFile, "#define HasGcc3 1\n"); 1326a5399cb1Smrg# endif 1327bb2e14f3Smrg# endif 1328bb2e14f3Smrg fprintf (inFile, "#define GccMajorVersion %d\n", __GNUC__); 1329bb2e14f3Smrg fprintf (inFile, "#define GccMinorVersion %d\n", __GNUC_MINOR__); 1330bb2e14f3Smrg } 1331a5399cb1Smrg# if defined(HAS_MERGE_CONSTANTS) 1332bb2e14f3Smrg fprintf (inFile, "#define HasGccMergeConstants %d\n", HAS_MERGE_CONSTANTS); 1333a5399cb1Smrg# endif 1334bb2e14f3Smrg} 1335bb2e14f3Smrg#endif 1336bb2e14f3Smrg 1337bb2e14f3Smrgstatic boolean 1338bb2e14f3Smrgget_gcc(char *cmd) 1339bb2e14f3Smrg{ 1340bb2e14f3Smrg struct stat sb; 13411114aea8Smrg static const char* gcc_path[] = { 1342a5399cb1Smrg#if defined(linux) || \ 1343bb2e14f3Smrg defined(__NetBSD__) || \ 1344bb2e14f3Smrg defined(__OpenBSD__) || \ 1345bb2e14f3Smrg defined(__FreeBSD__) || \ 1346bb2e14f3Smrg defined(__DragonFly__) || \ 1347bb2e14f3Smrg defined(__APPLE__) || \ 1348bb2e14f3Smrg defined(__CYGWIN__) || \ 1349bb2e14f3Smrg defined(__MINGW32__) || \ 1350bb2e14f3Smrg defined(__GNU__) || \ 1351bb2e14f3Smrg defined(__GLIBC__) 1352bb2e14f3Smrg "/usr/bin/cc", /* for Linux PostIncDir */ 1353a5399cb1Smrg#endif 1354bb2e14f3Smrg "/usr/local/bin/gcc", 1355bb2e14f3Smrg "/opt/gnu/bin/gcc", 1356bb2e14f3Smrg "/usr/pkg/bin/gcc" 1357bb2e14f3Smrg }; 1358bb2e14f3Smrg 1359bb2e14f3Smrg#ifdef CROSSCOMPILE 13601114aea8Smrg static const char* cross_cc_name[] = { 1361bb2e14f3Smrg "cc", 1362bb2e14f3Smrg "gcc" 1363bb2e14f3Smrg }; 1364bb2e14f3Smrg 1365bb2e14f3Smrg if (CrossCompiling) { 1366bb2e14f3Smrg int i; 1367bb2e14f3Smrg for (i = 0; i < sizeof (cross_cc_name) / sizeof cross_cc_name[0]; i++){ 1368bb2e14f3Smrg strcpy (cmd, CrossCompileDir); 1369bb2e14f3Smrg strcat (cmd, "/"); 1370bb2e14f3Smrg strcat (cmd, cross_cc_name[i]); 1371bb2e14f3Smrg if (lstat (cmd, &sb) == 0) { 1372bb2e14f3Smrg return TRUE; 1373bb2e14f3Smrg break; 1374bb2e14f3Smrg } 1375bb2e14f3Smrg } 1376bb2e14f3Smrg } else 1377bb2e14f3Smrg#endif 1378bb2e14f3Smrg { 1379bb2e14f3Smrg int i; 1380bb2e14f3Smrg for (i = 0; i < sizeof (gcc_path) / sizeof gcc_path[0]; i++) { 1381bb2e14f3Smrg if (lstat (gcc_path[i], &sb) == 0) { 1382bb2e14f3Smrg strcpy (cmd, gcc_path[i]); 1383bb2e14f3Smrg return TRUE; 1384bb2e14f3Smrg } 1385bb2e14f3Smrg } 1386bb2e14f3Smrg } 1387bb2e14f3Smrg return FALSE; 1388bb2e14f3Smrg} 1389bb2e14f3Smrg 139039f9c979Smrg#ifdef CROSSCOMPILE 1391bb2e14f3Smrgstatic void 1392bb2e14f3Smrgget_gcc_incdir(FILE *inFile, char* name) 1393bb2e14f3Smrg{ 1394bb2e14f3Smrg FILE* gccproc; 1395bb2e14f3Smrg char buf[PATH_MAX]; 1396bb2e14f3Smrg char cmd[PATH_MAX]; 1397bb2e14f3Smrg char* ptr; 1398bb2e14f3Smrg 1399bb2e14f3Smrg strcpy(cmd,name); 1400bb2e14f3Smrg 1401bb2e14f3Smrg buf[0] = '\0'; 1402bb2e14f3Smrg strcat (cmd, " --print-libgcc-file-name"); 1403bb2e14f3Smrg if ((gccproc = popen (cmd, "r")) != NULL) { 1404bb2e14f3Smrg if (fgets (buf, PATH_MAX, gccproc) != NULL) { 1405bb2e14f3Smrg ptr = strstr (buf, "libgcc.a"); 1406bb2e14f3Smrg if (ptr) strcpy (ptr, "include"); 1407bb2e14f3Smrg } 1408bb2e14f3Smrg (void) pclose (gccproc); 1409bb2e14f3Smrg } 1410bb2e14f3Smrg 1411bb2e14f3Smrg if (buf[0]) 1412bb2e14f3Smrg fprintf (inFile, "#define DefaultGccIncludeDir \"%s\"\n", buf); 1413bb2e14f3Smrg} 1414bb2e14f3Smrg#endif 1415bb2e14f3Smrg 1416bb2e14f3Smrgboolean 1417bb2e14f3Smrgdefine_os_defaults(FILE *inFile) 1418bb2e14f3Smrg{ 141939f9c979Smrg#if defined CROSSCOMPILE || !defined(WIN32) 1420a5399cb1Smrg# ifdef CROSSCOMPILE 1421a5399cb1Smrg# ifdef __GNUC__ 1422bb2e14f3Smrg if (1) 1423a5399cb1Smrg# else 1424bb2e14f3Smrg if ((sys != win32) && (sys != emx)) 1425a5399cb1Smrg# endif 1426a5399cb1Smrg# endif 1427bb2e14f3Smrg { 1428bb2e14f3Smrg# if (defined(DEFAULT_OS_NAME) || defined(DEFAULT_OS_MAJOR_REV) || \ 1429bb2e14f3Smrg defined(DEFAULT_OS_MINOR_REV) || defined(DEFAULT_OS_TEENY_REV)) 1430bb2e14f3Smrg struct utsname *name = NULL; 1431bb2e14f3Smrg struct utsname uts_name; 1432bb2e14f3Smrg char buf[SYS_NMLN * 5 + 1]; 1433bb2e14f3Smrg 1434bb2e14f3Smrg /* Obtain the system information. */ 1435a5399cb1Smrg# ifdef CROSSCOMPILE 1436bb2e14f3Smrg if (!CrossCompiling) 1437a5399cb1Smrg# endif 1438bb2e14f3Smrg { 1439bb2e14f3Smrg if (uname(&uts_name) < 0) 14401114aea8Smrg LogFatal("Cannot invoke uname"); 1441bb2e14f3Smrg else 1442bb2e14f3Smrg name = &uts_name; 1443bb2e14f3Smrg } 1444a5399cb1Smrg# if defined CROSSCOMPILE && (defined linux || defined(__GLIBC__)) 1445bb2e14f3Smrg else { 1446bb2e14f3Smrg strncpy(uts_name.sysname,cross_uts_sysname,SYS_NMLN); 1447bb2e14f3Smrg strncpy(uts_name.release,cross_uts_release,SYS_NMLN); 1448bb2e14f3Smrg strncpy(uts_name.version,cross_uts_version,SYS_NMLN); 1449bb2e14f3Smrg strncpy(uts_name.machine,cross_uts_machine,SYS_NMLN); 1450bb2e14f3Smrg name = &uts_name; 1451bb2e14f3Smrg } 1452a5399cb1Smrg# endif 1453a5399cb1Smrg# ifdef __FreeBSD__ 1454bb2e14f3Smrg /* Override for compiling in chroot of other OS version, such as 1455bb2e14f3Smrg * in the bento build cluster. 1456bb2e14f3Smrg */ 1457bb2e14f3Smrg { 1458bb2e14f3Smrg char *e; 1459a5399cb1Smrg if ((e = getenv("OSREL")) != NULL && 1460bb2e14f3Smrg strlen(name->sysname) + strlen(e) + 1 < SYS_NMLN) { 1461bb2e14f3Smrg strcpy(name->release, e); 1462bb2e14f3Smrg strcpy(name->version, name->sysname); 1463bb2e14f3Smrg strcat(name->version, " "); 1464bb2e14f3Smrg strcat(name->version, e); 1465bb2e14f3Smrg } 1466bb2e14f3Smrg } 1467a5399cb1Smrg# endif 1468bb2e14f3Smrg 1469bb2e14f3Smrg# if defined DEFAULT_OS_NAME 1470bb2e14f3Smrg# if defined CROSSCOMPILE 1471bb2e14f3Smrg if (!CrossCompiling) 1472bb2e14f3Smrg# endif 1473bb2e14f3Smrg { 1474bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_NAME, buf, 1475bb2e14f3Smrg "Bad DEFAULT_OS_NAME syntax %s"); 1476bb2e14f3Smrg# ifdef DEFAULT_OS_NAME_FROB 1477bb2e14f3Smrg DEFAULT_OS_NAME_FROB(buf, sizeof buf); 1478bb2e14f3Smrg# endif 1479bb2e14f3Smrg if (buf[0] != '\0') 1480bb2e14f3Smrg fprintf(inFile, "#define DefaultOSName %s\n", buf); 1481bb2e14f3Smrg } 1482bb2e14f3Smrg# endif 1483bb2e14f3Smrg 1484bb2e14f3Smrg# if defined CROSSCOMPILE 1485bb2e14f3Smrg if (CrossCompiling && defaultOsName) { 1486bb2e14f3Smrg parse_utsname(name, defaultOsName, buf, 1487bb2e14f3Smrg "Bad DEFAULT_OS_NAME syntax %s"); 1488bb2e14f3Smrg if (defaultOsNameFrob) 1489bb2e14f3Smrg defaultOsNameFrob(buf, sizeof buf); 1490bb2e14f3Smrg if (buf[0] != '\0') 1491bb2e14f3Smrg fprintf(inFile, "#define DefaultOSName %s\n", buf); 1492bb2e14f3Smrg } 1493bb2e14f3Smrg# endif 1494bb2e14f3Smrg 1495bb2e14f3Smrg# ifdef DEFAULT_OS_MAJOR_REV 1496bb2e14f3Smrg# if defined CROSSCOMPILE 1497bb2e14f3Smrg if (!CrossCompiling) 1498bb2e14f3Smrg# endif 1499bb2e14f3Smrg { 1500bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_MAJOR_REV, buf, 1501bb2e14f3Smrg "Bad DEFAULT_OS_MAJOR_REV syntax %s"); 1502bb2e14f3Smrg# ifdef DEFAULT_OS_MAJOR_REV_FROB 1503bb2e14f3Smrg DEFAULT_OS_MAJOR_REV_FROB(buf, sizeof buf); 1504bb2e14f3Smrg# endif 1505bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion %s\n", 1506bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1507bb2e14f3Smrg } 1508bb2e14f3Smrg# endif 1509bb2e14f3Smrg 1510bb2e14f3Smrg# if defined CROSSCOMPILE 1511bb2e14f3Smrg if (CrossCompiling && defaultOsMajorRev) { 1512bb2e14f3Smrg parse_utsname(name, defaultOsMajorRev, buf, 1513bb2e14f3Smrg "Bad defaultOsMajorRev syntax %s"); 1514bb2e14f3Smrg if (defaultOsMajorRevFrob) 1515bb2e14f3Smrg defaultOsMajorRevFrob(buf, sizeof buf); 1516bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion %s\n", 1517bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1518bb2e14f3Smrg } 1519bb2e14f3Smrg# endif 1520bb2e14f3Smrg 1521bb2e14f3Smrg# ifdef DEFAULT_OS_MINOR_REV 1522bb2e14f3Smrg# if defined CROSSCOMPILE 1523bb2e14f3Smrg if (!CrossCompiling) 1524bb2e14f3Smrg# endif 1525bb2e14f3Smrg { 1526bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_MINOR_REV, buf, 1527bb2e14f3Smrg "Bad DEFAULT_OS_MINOR_REV syntax %s"); 1528bb2e14f3Smrg# ifdef DEFAULT_OS_MINOR_REV_FROB 1529bb2e14f3Smrg DEFAULT_OS_MINOR_REV_FROB(buf, sizeof buf); 1530bb2e14f3Smrg# endif 1531bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion %s\n", 1532bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1533bb2e14f3Smrg } 1534bb2e14f3Smrg# endif 1535bb2e14f3Smrg 1536bb2e14f3Smrg# if defined CROSSCOMPILE 1537bb2e14f3Smrg if (CrossCompiling && defaultOsMinorRev) { 1538bb2e14f3Smrg parse_utsname(name, defaultOsMinorRev, buf, 1539bb2e14f3Smrg "Bad defaultOsMinorRev syntax %s"); 1540bb2e14f3Smrg if (defaultOsMinorRevFrob) 1541bb2e14f3Smrg defaultOsMinorRevFrob(buf, sizeof buf); 1542bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion %s\n", 1543bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1544bb2e14f3Smrg } 1545bb2e14f3Smrg# endif 1546bb2e14f3Smrg 1547bb2e14f3Smrg# ifdef DEFAULT_OS_TEENY_REV 1548bb2e14f3Smrg# if defined CROSSCOMPILE 1549bb2e14f3Smrg if (!CrossCompiling) 1550bb2e14f3Smrg# endif 1551bb2e14f3Smrg { 1552bb2e14f3Smrg parse_utsname(name, DEFAULT_OS_TEENY_REV, buf, 1553bb2e14f3Smrg "Bad DEFAULT_OS_TEENY_REV syntax %s"); 1554bb2e14f3Smrg# ifdef DEFAULT_OS_TEENY_REV_FROB 1555bb2e14f3Smrg DEFAULT_OS_TEENY_REV_FROB(buf, sizeof buf); 1556bb2e14f3Smrg# endif 1557bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion %s\n", 1558bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1559bb2e14f3Smrg } 1560bb2e14f3Smrg# endif 1561bb2e14f3Smrg 1562bb2e14f3Smrg# if defined CROSSCOMPILE 1563bb2e14f3Smrg if (CrossCompiling && defaultOsTeenyRev) { 1564bb2e14f3Smrg parse_utsname(name, defaultOsTeenyRev, buf, 1565bb2e14f3Smrg "Bad defaultOsTeenyRev syntax %s"); 1566bb2e14f3Smrg if (defaultOsTeenyRevFrob) 1567bb2e14f3Smrg defaultOsTeenyRevFrob(buf, sizeof buf); 1568bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion %s\n", 1569bb2e14f3Smrg *buf ? trim_version(buf) : "0"); 1570bb2e14f3Smrg } 1571bb2e14f3Smrg# endif 1572bb2e14f3Smrg 1573bb2e14f3Smrg# ifdef DEFAULT_MACHINE_ARCHITECTURE 1574bb2e14f3Smrg# if defined CROSSCOMPILE 1575bb2e14f3Smrg if (!CrossCompiling) 1576bb2e14f3Smrg# endif 1577bb2e14f3Smrg { 1578bb2e14f3Smrg parse_utsname(name, DEFAULT_MACHINE_ARCHITECTURE, buf, 1579bb2e14f3Smrg "Bad DEFAULT_MACHINE_ARCHITECTURE %s"); 1580bb2e14f3Smrg fprintf(inFile, "#ifndef %s\n# define %s\n#endif\n", buf, buf); 1581bb2e14f3Smrg } 1582bb2e14f3Smrg# endif 1583bb2e14f3Smrg 1584bb2e14f3Smrg# if defined CROSSCOMPILE 1585bb2e14f3Smrg if (CrossCompiling && defaultMachineArchitecture) { 1586bb2e14f3Smrg parse_utsname(name, defaultMachineArchitecture, buf, 1587bb2e14f3Smrg "Bad defaultMachineArchitecture syntax %s"); 1588bb2e14f3Smrg fprintf(inFile, "#ifndef %s\n# define %s\n#endif\n", buf, buf); 1589bb2e14f3Smrg } 1590bb2e14f3Smrg# endif 1591bb2e14f3Smrg# endif 1592bb2e14f3Smrg# if defined CROSSCOMPILE 1593bb2e14f3Smrg if (CrossCompiling) 1594bb2e14f3Smrg get_cross_compile_dir(inFile); 1595bb2e14f3Smrg else 1596bb2e14f3Smrg# endif 1597bb2e14f3Smrg fprintf(inFile, "#define CrossCompiling NO\n"); 1598bb2e14f3Smrg# if defined CROSSCOMPILE 1599bb2e14f3Smrg if (CrossCompiling && sys == LinuX) 1600bb2e14f3Smrg# endif 1601bb2e14f3Smrg# if defined CROSSCOMPILE || defined linux || defined(__GLIBC__) 1602bb2e14f3Smrg# if defined(CROSSCOMPILE) && defined(__linux__) 1603bb2e14f3Smrg if (sys == LinuX) 1604bb2e14f3Smrg# endif 1605bb2e14f3Smrg get_distrib (inFile); 1606bb2e14f3Smrg# endif 1607bb2e14f3Smrg# if defined linux || defined(__GLIBC__) 1608bb2e14f3Smrg# if defined CROSSCOMPILE 1609bb2e14f3Smrg if (!CrossCompiling) 1610bb2e14f3Smrg# endif 1611bb2e14f3Smrg get_libc_version (inFile); 1612bb2e14f3Smrg# if defined CROSSCOMPILE 1613bb2e14f3Smrg else { 1614bb2e14f3Smrg fprintf(inFile,"#define DefaultLinuxCLibMajorVersion %d\n", 1615bb2e14f3Smrg glibc_major); 1616bb2e14f3Smrg fprintf(inFile,"#define DefaultLinuxCLibMinorVersion %d\n", 1617bb2e14f3Smrg glibc_minor); 1618bb2e14f3Smrg fprintf(inFile,"#define DefaultLinuxCLibTeenyVersion 0\n"); 1619bb2e14f3Smrg } 1620bb2e14f3Smrg# endif 1621bb2e14f3Smrg# endif /* linux || __GLIBC__ */ 1622bb2e14f3Smrg# if defined CROSSCOMPILE || defined linux || defined(__GLIBC__) 1623bb2e14f3Smrg# if defined CROSSCOMPILE && defined(__linux__) 1624bb2e14f3Smrg if (sys == LinuX) 1625bb2e14f3Smrg# endif 1626bb2e14f3Smrg get_ld_version(inFile); 1627bb2e14f3Smrg# endif 1628bb2e14f3Smrg# if defined (sun) && defined(SVR4) 1629bb2e14f3Smrg get_sun_compiler_versions (inFile); 1630bb2e14f3Smrg# endif 1631bb2e14f3Smrg# if defined CROSSCOMPILE || defined __GNUC__ 1632bb2e14f3Smrg# if defined CROSSCOMPILE 1633bb2e14f3Smrg if (gnu_c) 1634bb2e14f3Smrg# endif 1635bb2e14f3Smrg { 1636bb2e14f3Smrg char name[PATH_MAX]; 1637bb2e14f3Smrg if (get_gcc(name)) { 1638bb2e14f3Smrg get_gcc_version (inFile,name); 163939f9c979Smrg# if defined CROSSCOMPILE 1640bb2e14f3Smrg if (sys != emx) 1641bb2e14f3Smrg get_gcc_incdir(inFile,name); 1642bb2e14f3Smrg# endif 1643bb2e14f3Smrg } 1644bb2e14f3Smrg } 1645bb2e14f3Smrg# endif 1646bb2e14f3Smrg# if defined __FreeBSD__ 1647bb2e14f3Smrg# if defined CROSSCOMPILE 1648bb2e14f3Smrg if (sys == freeBSD) 1649bb2e14f3Smrg# endif 1650bb2e14f3Smrg get_binary_format(inFile); 1651bb2e14f3Smrg# endif 1652bb2e14f3Smrg } 165339f9c979Smrg#endif /* !WIN32 */ 1654bb2e14f3Smrg#if defined WIN32 1655bb2e14f3Smrg# ifdef CROSSCOMPILE 1656bb2e14f3Smrg else if (sys == win32 && !CrossCompiling) 1657bb2e14f3Smrg# endif 1658bb2e14f3Smrg { 1659bb2e14f3Smrg OSVERSIONINFO osvi; 1660bb2e14f3Smrg static char* os_names[] = { "Win32s", "Windows 95", "Windows NT" }; 1661bb2e14f3Smrg 1662bb2e14f3Smrg memset(&osvi, 0, sizeof(OSVERSIONINFO)); 1663bb2e14f3Smrg osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); 1664bb2e14f3Smrg GetVersionEx (&osvi); 1665bb2e14f3Smrg 1666bb2e14f3Smrg fprintf (inFile, "#define DefaultOSName Microsoft %s\n", 1667bb2e14f3Smrg os_names[osvi.dwPlatformId]); 1668bb2e14f3Smrg 1669bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion %d\n", osvi.dwMajorVersion); 1670bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion %d\n", osvi.dwMinorVersion); 1671bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion %d\n", 1672bb2e14f3Smrg osvi.dwBuildNumber & 0xFFFF); 1673bb2e14f3Smrg } 1674bb2e14f3Smrg#endif /* WIN32 */ 1675bb2e14f3Smrg#ifdef CROSSCOMPILE 1676bb2e14f3Smrg else if (sys == emx) 1677bb2e14f3Smrg { 1678bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMajorVersion 4\n"); 1679bb2e14f3Smrg fprintf(inFile, "#define DefaultOSMinorVersion 0\n"); 1680bb2e14f3Smrg fprintf(inFile, "#define DefaultOSTeenyVersion 0\n"); 1681bb2e14f3Smrg } 1682bb2e14f3Smrg#endif /* EMX */ 1683bb2e14f3Smrg#if defined(__OpenBSD__) || defined(__DragonFly__) 1684bb2e14f3Smrg get_stackprotector(inFile); 1685bb2e14f3Smrg#endif 1686bb2e14f3Smrg return FALSE; 1687bb2e14f3Smrg} 1688bb2e14f3Smrg 1689bb2e14f3Smrgvoid 16901114aea8Smrgcppit(const char *imakefile, const char *template, const char *masterc, 16911114aea8Smrg FILE *outfd, const char *outfname) 1692bb2e14f3Smrg{ 1693bb2e14f3Smrg FILE *inFile; 1694bb2e14f3Smrg 1695bb2e14f3Smrg haveImakefileC = TRUE; 1696bb2e14f3Smrg inFile = fopen(masterc, "w"); 1697bb2e14f3Smrg if (inFile == NULL) 1698bb2e14f3Smrg LogFatal("Cannot open %s for output.", masterc); 1699bb2e14f3Smrg if (fprintf(inFile, "%s\n", ImakefileCHeader) < 0 || 1700bb2e14f3Smrg define_os_defaults(inFile) || 1701bb2e14f3Smrg optional_include(inFile, "IMAKE_LOCAL_DEFINES", "localdefines") || 1702bb2e14f3Smrg optional_include(inFile, "IMAKE_ADMIN_DEFINES", "admindefines") || 1703bb2e14f3Smrg fprintf(inFile, "#define %s <%s>\n", ImakeDefSym, imakefile) < 0 || 1704bb2e14f3Smrg fprintf(inFile, LocalDefineFmt, ImakeTmplSym, template) < 0 || 1705bb2e14f3Smrg fprintf(inFile, IncludeFmt, ImakeTmplSym) < 0 || 1706bb2e14f3Smrg optional_include(inFile, "IMAKE_ADMIN_MACROS", "adminmacros") || 1707bb2e14f3Smrg optional_include(inFile, "IMAKE_LOCAL_MACROS", "localmacros") || 170839f9c979Smrg fflush(inFile)) { 170939f9c979Smrg fclose(inFile); 171039f9c979Smrg LogFatal("Cannot write to %s.", masterc); 171139f9c979Smrg } 171239f9c979Smrg else if (fclose(inFile)) 1713bb2e14f3Smrg LogFatal("Cannot write to %s.", masterc); 1714bb2e14f3Smrg /* 1715bb2e14f3Smrg * Fork and exec cpp 1716bb2e14f3Smrg */ 1717bb2e14f3Smrg doit(outfd, cpp, cpp_argv); 1718bb2e14f3Smrg CleanCppOutput(outfd, outfname); 1719bb2e14f3Smrg} 1720bb2e14f3Smrg 1721bb2e14f3Smrgvoid 1722bb2e14f3Smrgmakeit(void) 1723bb2e14f3Smrg{ 1724bb2e14f3Smrg doit(NULL, make_argv[0], make_argv); 1725bb2e14f3Smrg} 1726bb2e14f3Smrg 17271114aea8Smrgconst char * 17281114aea8SmrgCleanCppInput(const char *imakefile) 1729bb2e14f3Smrg{ 1730bb2e14f3Smrg FILE *outFile = NULL; 1731bb2e14f3Smrg FILE *inFile; 1732bb2e14f3Smrg char *buf, /* buffer for file content */ 1733bb2e14f3Smrg *pbuf, /* walking pointer to buf */ 1734bb2e14f3Smrg *punwritten, /* pointer to unwritten portion of buf */ 1735bb2e14f3Smrg *ptoken, /* pointer to # token */ 1736bb2e14f3Smrg *pend, /* pointer to end of # token */ 1737bb2e14f3Smrg savec; /* temporary character holder */ 1738bb2e14f3Smrg int count; 1739bb2e14f3Smrg struct stat st; 1740bb2e14f3Smrg 1741bb2e14f3Smrg /* 1742bb2e14f3Smrg * grab the entire file. 1743bb2e14f3Smrg */ 1744bb2e14f3Smrg if (!(inFile = fopen(imakefile, "r"))) 1745bb2e14f3Smrg LogFatal("Cannot open %s for input.", imakefile); 1746bb2e14f3Smrg if (fstat(fileno(inFile), &st) < 0) 1747bb2e14f3Smrg LogFatal("Cannot stat %s for size.", imakefile); 1748bb2e14f3Smrg buf = Emalloc((int)st.st_size+3); 1749bb2e14f3Smrg count = fread(buf + 2, 1, st.st_size, inFile); 1750bb2e14f3Smrg if (count == 0 && st.st_size != 0) 1751bb2e14f3Smrg LogFatal("Cannot read %s:", imakefile); 1752bb2e14f3Smrg fclose(inFile); 1753bb2e14f3Smrg buf[0] = '\n'; 1754bb2e14f3Smrg buf[1] = '\n'; 1755bb2e14f3Smrg buf[count + 2] = '\0'; 1756bb2e14f3Smrg 1757bb2e14f3Smrg punwritten = pbuf = buf + 2; 1758bb2e14f3Smrg while (*pbuf) { 1759bb2e14f3Smrg /* for compatibility, replace make comments for cpp */ 1760bb2e14f3Smrg if (*pbuf == '#' && pbuf[-1] == '\n' && pbuf[-2] != '\\') { 1761bb2e14f3Smrg ptoken = pbuf+1; 1762bb2e14f3Smrg while (*ptoken == ' ' || *ptoken == '\t') 1763bb2e14f3Smrg ptoken++; 1764bb2e14f3Smrg pend = ptoken; 1765bb2e14f3Smrg while (*pend && *pend != ' ' && *pend != '\t' && *pend != '\n' && *pend != '\r') 1766bb2e14f3Smrg pend++; 1767bb2e14f3Smrg savec = *pend; 1768bb2e14f3Smrg *pend = '\0'; 1769bb2e14f3Smrg if (strcmp(ptoken, "define") && 1770bb2e14f3Smrg strcmp(ptoken, "if") && 1771bb2e14f3Smrg strcmp(ptoken, "ifdef") && 1772bb2e14f3Smrg strcmp(ptoken, "ifndef") && 1773bb2e14f3Smrg strcmp(ptoken, "include") && 1774bb2e14f3Smrg strcmp(ptoken, "line") && 1775bb2e14f3Smrg strcmp(ptoken, "else") && 1776bb2e14f3Smrg strcmp(ptoken, "elif") && 1777bb2e14f3Smrg strcmp(ptoken, "endif") && 1778bb2e14f3Smrg strcmp(ptoken, "error") && 1779bb2e14f3Smrg strcmp(ptoken, "pragma") && 1780bb2e14f3Smrg strcmp(ptoken, "undef")) { 1781bb2e14f3Smrg if (outFile == NULL) { 17825afa940dSmrg#ifdef HAVE_MKSTEMP 1783bb2e14f3Smrg int fd; 1784bb2e14f3Smrg#endif 17851114aea8Smrg char *tmpImakefileName = Strdup(tmpImakefileTemplate); 17865afa940dSmrg#ifndef HAVE_MKSTEMP 17871114aea8Smrg if (mktemp(tmpImakefileName) == NULL || 17881114aea8Smrg (outFile = fopen(tmpImakefileName, "w+")) == NULL) { 1789bb2e14f3Smrg LogFatal("Cannot open %s for write.", 17901114aea8Smrg tmpImakefileName); 1791bb2e14f3Smrg } 1792bb2e14f3Smrg#else 17931114aea8Smrg fd=mkstemp(tmpImakefileName); 1794bb2e14f3Smrg if (fd != -1) 1795bb2e14f3Smrg outFile = fdopen(fd, "w"); 1796bb2e14f3Smrg if (outFile == NULL) { 1797bb2e14f3Smrg if (fd != -1) { 17981114aea8Smrg unlink(tmpImakefileName); close(fd); 1799bb2e14f3Smrg } 1800bb2e14f3Smrg LogFatal("Cannot open %s for write.", 18011114aea8Smrg tmpImakefileName); 1802bb2e14f3Smrg } 1803bb2e14f3Smrg#endif 18041114aea8Smrg tmpImakefile = tmpImakefileName; 1805bb2e14f3Smrg } 1806bb2e14f3Smrg writetmpfile(outFile, punwritten, pbuf-punwritten, 1807bb2e14f3Smrg tmpImakefile); 1808bb2e14f3Smrg if (ptoken > pbuf + 1) 1809bb2e14f3Smrg writetmpfile(outFile, "XCOMM", 5, tmpImakefile); 1810bb2e14f3Smrg else 1811bb2e14f3Smrg writetmpfile(outFile, "XCOMM ", 6, tmpImakefile); 1812bb2e14f3Smrg punwritten = pbuf + 1; 1813bb2e14f3Smrg } 1814bb2e14f3Smrg *pend = savec; 1815bb2e14f3Smrg } 1816bb2e14f3Smrg pbuf++; 1817bb2e14f3Smrg } 1818bb2e14f3Smrg if (outFile) { 1819bb2e14f3Smrg writetmpfile(outFile, punwritten, pbuf-punwritten, tmpImakefile); 1820bb2e14f3Smrg fclose(outFile); 1821bb2e14f3Smrg 1822bb2e14f3Smrg return tmpImakefile; 1823bb2e14f3Smrg } 1824bb2e14f3Smrg 1825bb2e14f3Smrg return(imakefile); 1826bb2e14f3Smrg} 1827bb2e14f3Smrg 1828bb2e14f3Smrgvoid 18291114aea8SmrgCleanCppOutput(FILE *tmpfd, const char *tmpfname) 1830bb2e14f3Smrg{ 1831bb2e14f3Smrg char *input; 1832bb2e14f3Smrg int blankline = 0; 1833bb2e14f3Smrg 1834bb2e14f3Smrg while((input = ReadLine(tmpfd, tmpfname))) { 1835bb2e14f3Smrg if (isempty(input)) { 1836bb2e14f3Smrg if (blankline++) 1837bb2e14f3Smrg continue; 1838bb2e14f3Smrg#ifdef CROSSCOMPILE 1839bb2e14f3Smrg if (fixup_whitespace) 1840bb2e14f3Smrg#endif 1841bb2e14f3Smrg#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 1842bb2e14f3Smrg KludgeResetRule(); 1843bb2e14f3Smrg#endif 1844bb2e14f3Smrg } else { 1845bb2e14f3Smrg blankline = 0; 1846bb2e14f3Smrg#ifdef CROSSCOMPILE 1847bb2e14f3Smrg if (fixup_whitespace) 1848bb2e14f3Smrg#endif 1849bb2e14f3Smrg#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 1850bb2e14f3Smrg KludgeOutputLine(&input); 1851bb2e14f3Smrg#endif 1852bb2e14f3Smrg writetmpfile(tmpfd, input, strlen(input), tmpfname); 1853bb2e14f3Smrg } 1854bb2e14f3Smrg writetmpfile(tmpfd, "\n", 1, tmpfname); 1855bb2e14f3Smrg } 1856bb2e14f3Smrg fflush(tmpfd); 1857bb2e14f3Smrg#ifdef NFS_STDOUT_BUG 1858bb2e14f3Smrg /* 1859bb2e14f3Smrg * On some systems, NFS seems to leave a large number of nulls at 1860bb2e14f3Smrg * the end of the file. Ralph Swick says that this kludge makes the 1861bb2e14f3Smrg * problem go away. 1862bb2e14f3Smrg */ 1863bb2e14f3Smrg ftruncate (fileno(tmpfd), (off_t)ftell(tmpfd)); 1864bb2e14f3Smrg#endif 1865bb2e14f3Smrg} 1866bb2e14f3Smrg 1867bb2e14f3Smrg/* 1868bb2e14f3Smrg * Determine if a line has nothing in it. As a side effect, we trim white 1869bb2e14f3Smrg * space from the end of the line. Cpp magic cookies are also thrown away. 1870bb2e14f3Smrg * "XCOMM" token is transformed to "#". 1871bb2e14f3Smrg */ 1872bb2e14f3Smrgboolean 1873bb2e14f3Smrgisempty(char *line) 1874bb2e14f3Smrg{ 1875bb2e14f3Smrg char *pend; 1876bb2e14f3Smrg 1877bb2e14f3Smrg /* 1878bb2e14f3Smrg * Check for lines of the form 1879bb2e14f3Smrg * # n "... 1880bb2e14f3Smrg * or 1881bb2e14f3Smrg * # line n "... 1882bb2e14f3Smrg */ 1883bb2e14f3Smrg if (*line == '#') { 1884bb2e14f3Smrg pend = line+1; 1885bb2e14f3Smrg if (*pend == ' ') 1886bb2e14f3Smrg pend++; 1887bb2e14f3Smrg if (*pend == 'l' && pend[1] == 'i' && pend[2] == 'n' && 1888bb2e14f3Smrg pend[3] == 'e' && pend[4] == ' ') 1889bb2e14f3Smrg pend += 5; 1890bb2e14f3Smrg if (isdigit(*pend)) { 1891bb2e14f3Smrg do { 1892bb2e14f3Smrg pend++; 1893bb2e14f3Smrg } while (isdigit(*pend)); 1894bb2e14f3Smrg if (*pend == '\n' || *pend == '\0') 1895bb2e14f3Smrg return(TRUE); 1896bb2e14f3Smrg if (*pend++ == ' ' && *pend == '"') 1897bb2e14f3Smrg return(TRUE); 1898bb2e14f3Smrg } 1899bb2e14f3Smrg while (*pend) 1900bb2e14f3Smrg pend++; 1901bb2e14f3Smrg } else { 1902bb2e14f3Smrg for (pend = line; *pend; pend++) { 1903bb2e14f3Smrg if (*pend == 'X' && pend[1] == 'C' && pend[2] == 'O' && 1904bb2e14f3Smrg pend[3] == 'M' && pend[4] == 'M' && 1905bb2e14f3Smrg (pend == line || pend[-1] == ' ' || pend[-1] == '\t' || pend[-1] == '\r') && 1906bb2e14f3Smrg (pend[5] == ' ' || pend[5] == '\t' || pend[5] == '\r' || pend[5] == '\0')) 1907bb2e14f3Smrg { 1908bb2e14f3Smrg *pend = '#'; 1909bb2e14f3Smrg memmove(pend+1, pend+5, strlen(pend+5)+1); 1910bb2e14f3Smrg } 1911bb2e14f3Smrg#ifdef CROSSCOMPILE 1912bb2e14f3Smrg if (magic_make_vars) 1913bb2e14f3Smrg#endif 1914bb2e14f3Smrg { 1915bb2e14f3Smrg#if defined CROSSCOMPILE || defined MAGIC_MAKE_VARS 1916bb2e14f3Smrg if (*pend == 'X' && pend[1] == 'V' && pend[2] == 'A' && 1917bb2e14f3Smrg pend[3] == 'R') 1918bb2e14f3Smrg { 1919bb2e14f3Smrg char varbuf[5]; 1920bb2e14f3Smrg int i; 1921bb2e14f3Smrg 1922bb2e14f3Smrg if (pend[4] == 'd' && pend[5] == 'e' && pend[6] == 'f' && 1923bb2e14f3Smrg pend[7] >= '0' && pend[7] <= '9') 1924bb2e14f3Smrg { 1925bb2e14f3Smrg i = pend[7] - '0'; 1926bb2e14f3Smrg sprintf(varbuf, "%0.4d", xvariable); 1927bb2e14f3Smrg strncpy(pend+4, varbuf, 4); 1928bb2e14f3Smrg xvariables[i] = xvariable; 1929bb2e14f3Smrg xvariable = (xvariable + 1) % 10000; 1930bb2e14f3Smrg } 1931bb2e14f3Smrg else if (pend[4] == 'u' && pend[5] == 's' && 1932bb2e14f3Smrg pend[6] == 'e' && pend[7] >= '0' && 1933bb2e14f3Smrg pend[7] <= '9') 1934bb2e14f3Smrg { 1935bb2e14f3Smrg i = pend[7] - '0'; 1936bb2e14f3Smrg sprintf(varbuf, "%0.4d", xvariables[i]); 1937bb2e14f3Smrg strncpy(pend+4, varbuf, 4); 1938bb2e14f3Smrg } 1939bb2e14f3Smrg } 1940bb2e14f3Smrg#endif 1941bb2e14f3Smrg } 1942bb2e14f3Smrg } 1943bb2e14f3Smrg } 1944bb2e14f3Smrg while (--pend >= line && (*pend == ' ' || *pend == '\t' || *pend == '\r')) ; 1945bb2e14f3Smrg pend[1] = '\0'; 1946bb2e14f3Smrg return (*line == '\0'); 1947bb2e14f3Smrg} 1948bb2e14f3Smrg 1949bb2e14f3Smrg/*ARGSUSED*/ 1950bb2e14f3Smrgchar * 19511114aea8SmrgReadLine(FILE *tmpfd, const char *tmpfname) 1952bb2e14f3Smrg{ 1953bb2e14f3Smrg static boolean initialized = FALSE; 1954bb2e14f3Smrg static char *buf, *pline, *end; 1955bb2e14f3Smrg register char *p1, *p2; 1956bb2e14f3Smrg 1957bb2e14f3Smrg if (! initialized) { 1958bb2e14f3Smrg#ifdef WIN32 1959bb2e14f3Smrg FILE *fp = tmpfd; 1960bb2e14f3Smrg#endif 1961bb2e14f3Smrg int total_red; 1962bb2e14f3Smrg struct stat st; 1963bb2e14f3Smrg 1964bb2e14f3Smrg /* 1965bb2e14f3Smrg * Slurp it all up. 1966bb2e14f3Smrg */ 1967bb2e14f3Smrg fseek(tmpfd, 0, 0); 1968bb2e14f3Smrg if (fstat(fileno(tmpfd), &st) < 0) 1969bb2e14f3Smrg LogFatal("cannot stat %s for size", tmpMakefile); 1970bb2e14f3Smrg pline = buf = Emalloc((int)st.st_size+1); 1971bb2e14f3Smrg total_red = fread(buf, 1, st.st_size, tmpfd); 1972bb2e14f3Smrg if (total_red == 0 && st.st_size != 0) 1973bb2e14f3Smrg LogFatal("cannot read %s", tmpMakefile); 1974bb2e14f3Smrg end = buf + total_red; 1975bb2e14f3Smrg *end = '\0'; 1976bb2e14f3Smrg fseek(tmpfd, 0, 0); 1977bb2e14f3Smrg#if defined(SYSV) || defined(WIN32) || defined(USE_FREOPEN) 1978bb2e14f3Smrg tmpfd = freopen(tmpfname, "w+", tmpfd); 1979a5399cb1Smrg# ifdef WIN32 1980bb2e14f3Smrg if (! tmpfd) /* if failed try again */ 1981bb2e14f3Smrg tmpfd = freopen(tmpfname, "w+", fp); 1982a5399cb1Smrg# endif 1983bb2e14f3Smrg if (! tmpfd) 1984bb2e14f3Smrg LogFatal("cannot reopen %s\n", tmpfname); 1985bb2e14f3Smrg#else /* !SYSV */ 1986bb2e14f3Smrg ftruncate(fileno(tmpfd), (off_t) 0); 1987bb2e14f3Smrg#endif /* !SYSV */ 1988bb2e14f3Smrg initialized = TRUE; 1989bb2e14f3Smrg fprintf (tmpfd, "# Makefile generated by imake - do not edit!\n"); 1990bb2e14f3Smrg } 1991bb2e14f3Smrg 1992bb2e14f3Smrg for (p1 = pline; p1 < end; p1++) { 1993bb2e14f3Smrg if (*p1 == '@' && *(p1+1) == '@' 1994bb2e14f3Smrg /* ignore ClearCase version-extended pathnames */ 1995bb2e14f3Smrg && !(p1 != pline && !isspace(*(p1-1)) && *(p1+2) == '/')) 1996bb2e14f3Smrg { /* soft EOL */ 1997bb2e14f3Smrg *p1++ = '\0'; 1998bb2e14f3Smrg p1++; /* skip over second @ */ 1999bb2e14f3Smrg break; 2000bb2e14f3Smrg } 2001bb2e14f3Smrg else if (*p1 == '\n') { /* real EOL */ 2002bb2e14f3Smrg#if defined CROSSCOMPILE || defined WIN32 2003bb2e14f3Smrg# if defined CROSSCOMPILE 2004bb2e14f3Smrg if (sys == win32) 2005bb2e14f3Smrg# endif 2006bb2e14f3Smrg { 2007bb2e14f3Smrg if (p1 > pline && p1[-1] == '\r') 2008bb2e14f3Smrg p1[-1] = '\0'; 2009bb2e14f3Smrg } 2010bb2e14f3Smrg#endif 2011bb2e14f3Smrg *p1++ = '\0'; 2012bb2e14f3Smrg break; 2013bb2e14f3Smrg } 2014bb2e14f3Smrg } 2015bb2e14f3Smrg 2016bb2e14f3Smrg /* 2017bb2e14f3Smrg * return NULL at the end of the file. 2018bb2e14f3Smrg */ 2019bb2e14f3Smrg p2 = (pline == p1 ? NULL : pline); 2020bb2e14f3Smrg pline = p1; 2021bb2e14f3Smrg return(p2); 2022bb2e14f3Smrg} 2023bb2e14f3Smrg 2024bb2e14f3Smrgvoid 20251114aea8Smrgwritetmpfile(FILE *fd, const char *buf, int cnt, const char *fname) 2026bb2e14f3Smrg{ 2027bb2e14f3Smrg if (fwrite(buf, sizeof(char), cnt, fd) == -1) 2028bb2e14f3Smrg LogFatal("Cannot write to %s.", fname); 2029bb2e14f3Smrg} 2030bb2e14f3Smrg 2031bb2e14f3Smrgchar * 2032bb2e14f3SmrgEmalloc(int size) 2033bb2e14f3Smrg{ 2034bb2e14f3Smrg char *p; 2035bb2e14f3Smrg 2036bb2e14f3Smrg if ((p = malloc(size)) == NULL) 20371114aea8Smrg LogFatal("Cannot allocate %d bytes", size); 2038bb2e14f3Smrg return(p); 2039bb2e14f3Smrg} 2040bb2e14f3Smrg 2041bb2e14f3Smrg#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 2042bb2e14f3Smrgvoid 2043bb2e14f3SmrgKludgeOutputLine(char **pline) 2044bb2e14f3Smrg{ 2045bb2e14f3Smrg char *p = *pline; 2046bb2e14f3Smrg char quotechar = '\0'; 2047bb2e14f3Smrg 2048bb2e14f3Smrg switch (*p) { 2049bb2e14f3Smrg case '#': /*Comment - ignore*/ 2050bb2e14f3Smrg break; 2051bb2e14f3Smrg case '\t': /*Already tabbed - ignore it*/ 2052bb2e14f3Smrg break; 2053bb2e14f3Smrg case ' ': /*May need a tab*/ 2054bb2e14f3Smrg default: 2055a5399cb1Smrg# ifdef CROSSCOMPILE 2056bb2e14f3Smrg if (inline_syntax) 2057a5399cb1Smrg# endif 2058a5399cb1Smrg# if defined CROSSCOMPILE || defined INLINE_SYNTAX 2059bb2e14f3Smrg { 2060bb2e14f3Smrg if (*p == '<' && p[1] == '<') { /* inline file close */ 2061bb2e14f3Smrg InInline--; 2062bb2e14f3Smrg InRule = TRUE; 2063bb2e14f3Smrg break; 2064bb2e14f3Smrg } 2065bb2e14f3Smrg } 2066a5399cb1Smrg# endif 2067bb2e14f3Smrg /* 2068bb2e14f3Smrg * The following cases should not be treated as beginning of 2069bb2e14f3Smrg * rules: 2070bb2e14f3Smrg * variable := name (GNU make) 2071bb2e14f3Smrg * variable = .*:.* (':' should be allowed as value) 2072bb2e14f3Smrg * sed 's:/a:/b:' (: used in quoted values) 2073bb2e14f3Smrg */ 2074bb2e14f3Smrg for (; *p; p++) { 2075bb2e14f3Smrg if (quotechar) { 2076bb2e14f3Smrg if (quotechar == '\\' || 2077bb2e14f3Smrg (*p == quotechar && 2078bb2e14f3Smrg# if defined CROSSCOMPILE || defined WIN32 2079bb2e14f3Smrg ( 2080bb2e14f3Smrg# if defined CROSSCOMPILE 2081bb2e14f3Smrg (sys == win32) && 2082bb2e14f3Smrg# endif 2083bb2e14f3Smrg quotechar != ')') && 2084bb2e14f3Smrg# endif 2085bb2e14f3Smrg p[-1] != '\\')) 2086bb2e14f3Smrg quotechar = '\0'; 2087bb2e14f3Smrg continue; 2088bb2e14f3Smrg } 2089bb2e14f3Smrg switch (*p) { 2090bb2e14f3Smrg case '\\': 2091bb2e14f3Smrg case '"': 2092bb2e14f3Smrg case '\'': 2093bb2e14f3Smrg quotechar = *p; 2094bb2e14f3Smrg break; 2095bb2e14f3Smrg case '(': 2096bb2e14f3Smrg quotechar = ')'; 2097bb2e14f3Smrg break; 2098bb2e14f3Smrg case '{': 2099bb2e14f3Smrg quotechar = '}'; 2100bb2e14f3Smrg break; 2101bb2e14f3Smrg case '[': 2102bb2e14f3Smrg quotechar = ']'; 2103bb2e14f3Smrg break; 2104bb2e14f3Smrg case '=': 2105a5399cb1Smrg# ifdef CROSSCOMPILE 2106bb2e14f3Smrg if (remove_cpp_leadspace) 2107a5399cb1Smrg# endif 2108a5399cb1Smrg# if defined CROSSCOMPILE || defined REMOVE_CPP_LEADSPACE 2109bb2e14f3Smrg { 2110bb2e14f3Smrg if (!InRule && **pline == ' ') { 2111bb2e14f3Smrg while (**pline == ' ') 2112bb2e14f3Smrg (*pline)++; 2113bb2e14f3Smrg } 2114bb2e14f3Smrg } 2115a5399cb1Smrg# endif 2116bb2e14f3Smrg goto breakfor; 2117a5399cb1Smrg# if defined CROSSCOMPILE || defined INLINE_SYNTAX 2118bb2e14f3Smrg case '<': 2119bb2e14f3Smrg if (inline_syntax) { 2120bb2e14f3Smrg if (p[1] == '<') /* inline file start */ 2121bb2e14f3Smrg InInline++; 2122bb2e14f3Smrg } 2123bb2e14f3Smrg break; 2124a5399cb1Smrg# endif 2125bb2e14f3Smrg case ':': 2126bb2e14f3Smrg if (p[1] == '=') 2127bb2e14f3Smrg goto breakfor; 2128bb2e14f3Smrg while (**pline == ' ') 2129bb2e14f3Smrg (*pline)++; 2130bb2e14f3Smrg InRule = TRUE; 2131bb2e14f3Smrg return; 2132bb2e14f3Smrg } 2133bb2e14f3Smrg } 2134bb2e14f3Smrgbreakfor: 2135bb2e14f3Smrg if (InRule && **pline == ' ') 2136bb2e14f3Smrg **pline = '\t'; 2137bb2e14f3Smrg break; 2138bb2e14f3Smrg } 2139bb2e14f3Smrg} 2140bb2e14f3Smrg 2141bb2e14f3Smrgvoid 2142bb2e14f3SmrgKludgeResetRule(void) 2143bb2e14f3Smrg{ 2144bb2e14f3Smrg InRule = FALSE; 2145bb2e14f3Smrg} 2146bb2e14f3Smrg#endif 2147bb2e14f3Smrgchar * 21481114aea8SmrgStrdup(const char *cp) 2149bb2e14f3Smrg{ 2150bb2e14f3Smrg char *new = Emalloc(strlen(cp) + 1); 2151bb2e14f3Smrg 2152bb2e14f3Smrg strcpy(new, cp); 2153bb2e14f3Smrg return new; 2154bb2e14f3Smrg} 2155bb2e14f3Smrg 2156bb2e14f3Smrg#ifdef CROSSCOMPILE 2157bb2e14f3Smrgchar* 2158bb2e14f3SmrgCrossCompileCPP(void) 2159bb2e14f3Smrg{ 2160bb2e14f3Smrg char *cpp, *c; 2161bb2e14f3Smrg int len ; 2162bb2e14f3Smrg if (crosscompile_use_cc_e) 2163bb2e14f3Smrg AddCppArg("-E"); 2164bb2e14f3Smrg 2165bb2e14f3Smrg cpp = strrchr(crosscompile_cpp,'/'); 2166bb2e14f3Smrg if (!cpp) 2167bb2e14f3Smrg cpp = crosscompile_cpp; 2168bb2e14f3Smrg else 2169bb2e14f3Smrg cpp++; 2170bb2e14f3Smrg 2171bb2e14f3Smrg len = strlen(cpp) + strlen(CrossCompileDir) + 2; 2172bb2e14f3Smrg c = Emalloc(len); 2173bb2e14f3Smrg 2174bb2e14f3Smrg (void)snprintf(c, len,"%s/%s",CrossCompileDir,cpp); 2175bb2e14f3Smrg 2176bb2e14f3Smrg return c; 2177bb2e14f3Smrg} 2178bb2e14f3Smrg 2179bb2e14f3Smrg#endif 2180bb2e14f3Smrg 2181bb2e14f3Smrg#ifdef CROSSCOMPILE 2182bb2e14f3Smrgstatic void 2183bb2e14f3Smrgget_cross_compile_dir(FILE *inFile) 2184bb2e14f3Smrg{ 2185bb2e14f3Smrg fprintf(inFile, "#define CrossCompileDir %s\n", 2186bb2e14f3Smrg CrossCompileDir); 2187bb2e14f3Smrg fprintf(inFile, "#define CrossCompiling YES\n"); 2188bb2e14f3Smrg} 2189bb2e14f3Smrg#endif 2190