📄 imake.c
字号:
/* $TOG: imake.c /main/97 1997/06/20 20:23:51 kaleb $ *//*************************************************************************** * * * Porting Note * * * * Add the value of BOOTSTRAPCFLAGS to the cpp_argv table so that it will * * be passed to the template file. * * * ***************************************************************************//* $XFree86: xc/config/imake/imake.c,v 3.13.2.16 1998/03/01 00:34:54 dawes Exp $ *//* * Copyright (c) 1985, 1986, 1987 X ConsortiumPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER INAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shall not beused in advertising or otherwise to promote the sale, use or other dealingsin this Software without prior written authorization from the X Consortium. * * Original Author: * Todd Brunhoff * Tektronix, inc. * While a guest engineer at Project Athena, MIT * * imake: the include-make program. * * Usage: imake [-Idir] [-Ddefine] [-T template] [-f imakefile ] [-C Imakefile.c ] [-s] [-e] [-v] [make flags] * * Imake takes a template file (Imake.tmpl) and a prototype (Imakefile) * and runs cpp on them producing a Makefile. It then optionally runs make * on the Makefile. * Options: * -D define. Same as cpp -D argument. * -I Include directory. Same as cpp -I argument. * -T template. Designate a template other * than Imake.tmpl * -f specify the Imakefile file * -C specify the name to use instead of Imakefile.c * -s[F] show. Show the produced makefile on the standard * output. Make is not run is this case. If a file * argument is provided, the output is placed there. * -e[F] execute instead of show; optionally name Makefile F * -v verbose. Show the make command line executed. * * Environment variables: * * IMAKEINCLUDE Include directory to use in addition to "." * IMAKECPP Cpp to use instead of /lib/cpp * IMAKEMAKE make program to use other than what is * found by searching the $PATH variable. * Other features: * imake reads the entire cpp output into memory and then scans it * for occurences of "@@". If it encounters them, it replaces it with * a newline. It also trims any trailing white space on output lines * (because make gets upset at them). This helps when cpp expands * multi-line macros but you want them to appear on multiple lines. * It also changes occurences of "XCOMM" to "#", to avoid problems * with treating commands as invalid preprocessor commands. * * The macros MAKEFILE and MAKE are provided as macros * to make. MAKEFILE is set to imake's makefile (not the constructed, * preprocessed one) and MAKE is set to argv[0], i.e. the name of * the imake program. * * Theory of operation: * 1. Determine the name of the imakefile from the command line (-f) * or from the content of the current directory (Imakefile or imakefile). * Call this <imakefile>. This gets added to the arguments for * make as MAKEFILE=<imakefile>. * 2. Determine the name of the template from the command line (-T) * or the default, Imake.tmpl. Call this <template> * 3. Determine the name of the imakeCfile from the command line (-C) * or the default, Imakefile.c. Call this <imakeCfile> * 4. Store lines of input into <imakeCfile>: * - A c-style comment header (see ImakefileCHeader below), used * to recognize temporary files generated by imake. * - If DEFAULT_OS_NAME is defined, format the utsname struct and * call the result <defaultOsName>. Add: * #define DefaultOSName <defaultOsName> * - If DEFAULT_OS_MAJOR_REV is defined, format the utsname struct * and call the result <defaultOsMajorVersion>. Add: * #define DefaultOSMajorVersion <defaultOsMajorVersion> * - If DEFAULT_OS_MINOR_REV is defined, format the utsname struct * and call the result <defaultOsMinorVersion>. Add: * #define DefaultOSMinorVersion <defaultOsMinorVersion> * - If DEFAULT_OS_TEENY_REV is defined, format the utsname struct * and call the result <defaultOsTeenyVersion>. Add: * #define DefaultOSTeenyVersion <defaultOsTeenyVersion> * - If DEFAULT_MACHINE_ARCITECTURE is defined, format the utsname struct * and define the corresponding macro. (For example on the amiga, * this will define amiga in addition to m68k). * - If the file "localdefines" is readable in the current * directory, print a warning message to stderr and add: * #define IMAKE_LOCAL_DEFINES "localdefines" * #include IMAKE_LOCAL_DEFINES * - If the file "admindefines" is readable in the current * directory, print a warning message to stderr and add: * #define IMAKE_ADMIN_DEFINES "admindefines" * #include IMAKE_ADMIN_DEFINES * - The following lines: * #define INCLUDE_IMAKEFILE < <imakefile> > * #define IMAKE_TEMPLATE " <template> " * #include IMAKE_TEMPLATE * - If the file "adminmacros" is readable in the current * directory, print a warning message to stderr and add: * #define IMAKE_ADMIN_MACROS "adminmacros" * #include IMAKE_ADMIN_MACROS * - If the file "localmacros" is readable in the current * directory, print a warning message to stderr and add: * #define IMAKE_LOCAL_MACROS "localmacros" * #include IMAKE_LOCAL_MACROS * 5. Start up cpp and provide it with this file. * Note that the define for INCLUDE_IMAKEFILE is intended for * use in the template file. This implies that the imake is * useless unless the template file contains at least the line * #include INCLUDE_IMAKEFILE * 6. Gather the output from cpp, and clean it up, expanding @@ to * newlines, stripping trailing white space, cpp control lines, * and extra blank lines, and changing XCOMM to #. This cleaned * output is placed in a new file, default "Makefile", but can * be specified with -s or -e options. * 7. Optionally start up make on the resulting file. * * The design of the template makefile should therefore be: * <set global macros like CFLAGS, etc.> * <include machine dependent additions> * #include INCLUDE_IMAKEFILE * <add any global targets like 'clean' and long dependencies> */#if defined(__FreeBSD__) || defined(__NetBSD__)/* This needs to be before _POSIX_SOURCE gets defined */# include <sys/param.h># include <sys/types.h># include <sys/sysctl.h>#endif#include <stdio.h>#include "Xosdefs.h"#ifndef X_NOT_STDC_ENV#include <string.h>#endif#include <ctype.h>#ifdef WIN32# include "Xw32defs.h"#endif#ifndef X_NOT_POSIX# ifndef _POSIX_SOURCE# define _POSIX_SOURCE# endif#endif#include <sys/types.h>#include <fcntl.h>#ifdef X_NOT_POSIX# ifndef WIN32# include <sys/file.h># endif#else# include <unistd.h>#endif#ifdef ISC# include <unistd.h>#endif#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)# include <signal.h>#else# define _POSIX_SOURCE# include <signal.h># undef _POSIX_SOURCE#endif#if !defined(SIGCHLD) && defined(SIGCLD)# define SIGCHLD SIGCLD#endif#include <sys/stat.h>#ifndef X_NOT_POSIX# ifdef _POSIX_SOURCE# ifdef SCO325# include <sys/procset.h># include <sys/siginfo.h># endif# include <sys/wait.h># else# define _POSIX_SOURCE# include <sys/wait.h># undef _POSIX_SOURCE# endif# define waitCode(w) WEXITSTATUS(w)# define waitSig(w) WTERMSIG(w)typedef int waitType;#else /* X_NOT_POSIX */# ifdef SYSV# define waitCode(w) (((w) >> 8) & 0x7f)# define waitSig(w) ((w) & 0xff)typedef int waitType;# else /* SYSV */# ifdef WIN32# include <process.h>typedef int waitType;# else# include <sys/wait.h># define waitCode(w) ((w).w_T.w_Retcode)# define waitSig(w) ((w).w_T.w_Termsig)typedef union wait waitType;# endif# endif# ifndef WIFSIGNALED# define WIFSIGNALED(w) waitSig(w)# endif# ifndef WIFEXITED# define WIFEXITED(w) waitCode(w)# endif#endif /* X_NOT_POSIX */#ifndef X_NOT_STDC_ENV# include <stdlib.h>#elsechar *malloc(), *realloc();void exit();#endif#if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */char *malloc(), *realloc();#endif /* macII */#ifdef X_NOT_STDC_ENVextern char *getenv();#endif#include <errno.h>#ifdef X_NOT_STDC_ENVextern int errno;#endif#ifdef __minix_vmd#define USE_FREOPEN 1#endif#if !(defined(X_NOT_STDC_ENV) || (defined(sun) && !defined(SVR4)) || defined(macII))#define USE_STRERROR 1#endif#ifdef __EMX__#define USE_STRERROR 1#endif#ifndef WIN32#include <sys/utsname.h>#endif#ifndef SYS_NMLN# ifdef _SYS_NMLN# define SYS_NMLN _SYS_NMLN# else# define SYS_NMLN 257# endif#endif#ifdef linux#include <limits.h>#endif/* * is strstr() in <strings.h> on X_NOT_STDC_ENV? * are there any X_NOT_STDC_ENV machines left in the world? */#include <string.h>#include "imakemdep.h"/* * This define of strerror is copied from (and should be identical to) * Xos.h, which we don't want to include here for bootstrapping reasons. */#ifndef USE_STRERROR# ifndef strerrorextern char *sys_errlist[];extern int sys_nerr;# define strerror(n) \ (((n) >= 0 && (n) < sys_nerr) ? sys_errlist[n] : "unknown error")# endif#endif#define TRUE 1#define FALSE 0#ifdef FIXUP_CPP_WHITESPACEint InRule = FALSE;# ifdef INLINE_SYNTAXint InInline = 0;# endif#endif#ifdef MAGIC_MAKE_VARSint xvariable = 0;int xvariables[10];#endif/* * Some versions of cpp reduce all tabs in macro expansion to a single * space. In addition, the escaped newline may be replaced with a * space instead of being deleted. Blech. */#ifdef FIXUP_CPP_WHITESPACEvoid KludgeOutputLine(), KludgeResetRule();#else# define KludgeOutputLine(arg)# define KludgeResetRule()#endiftypedef unsigned char boolean;#ifdef USE_CC_E# ifndef DEFAULT_CC# define DEFAULT_CC "cc"# endif#else# ifndef DEFAULT_CPP# ifdef CPP_PROGRAM# define DEFAULT_CPP CPP_PROGRAM# else# define DEFAULT_CPP "/lib/cpp"# endif# endif#endifchar *cpp = NULL;char *tmpMakefile = "/tmp/Imf.XXXXXX";char *tmpImakefile = "/tmp/IIf.XXXXXX";char *make_argv[ ARGUMENTS ] = {#ifdef WIN32 "nmake"#else "make"#endif};int make_argindex;int cpp_argindex;char *Imakefile = NULL;char *Makefile = "Makefile";char *Template = "Imake.tmpl";char *ImakefileC = "Imakefile.c";boolean haveImakefileC = FALSE;char *cleanedImakefile = NULL;char *program;char *FindImakefile();char *ReadLine();char *CleanCppInput();char *Strdup();char *Emalloc();void LogFatalI(), LogFatal(), LogMsg();void showit();void wrapup();void init();void AddMakeArg();void AddCppArg();void SetOpts();void CheckImakefileC();void cppit();void makeit();void CleanCppOutput();boolean isempty();void writetmpfile();boolean verbose = FALSE;boolean show = TRUE;intmain(argc, argv) int argc; char **argv;{ FILE *tmpfd; char makeMacro[ BUFSIZ ]; char makefileMacro[ BUFSIZ ]; program = argv[0]; init(); SetOpts(argc, argv); Imakefile = FindImakefile(Imakefile); CheckImakefileC(ImakefileC); if (Makefile) tmpMakefile = Makefile; else { tmpMakefile = Strdup(tmpMakefile); (void) mktemp(tmpMakefile); } AddMakeArg("-f"); AddMakeArg( tmpMakefile ); sprintf(makeMacro, "MAKE=%s", program); AddMakeArg( makeMacro ); sprintf(makefileMacro, "MAKEFILE=%s", Imakefile); AddMakeArg( makefileMacro ); if ((tmpfd = fopen(tmpMakefile, "w+")) == NULL) LogFatal("Cannot create temporary file %s.", tmpMakefile); cleanedImakefile = CleanCppInput(Imakefile); cppit(cleanedImakefile, Template, ImakefileC, tmpfd, tmpMakefile); if (show) { if (Makefile == NULL) showit(tmpfd); } else makeit(); wrapup(); exit(0);}voidshowit(fd) FILE *fd;{ char buf[ BUFSIZ ]; int red; fseek(fd, 0, 0); while ((red = fread(buf, 1, BUFSIZ, fd)) > 0) writetmpfile(stdout, buf, red, "stdout"); if (red < 0) LogFatal("Cannot read %s.", tmpMakefile);}voidwrapup(){ if (tmpMakefile != Makefile) unlink(tmpMakefile); if (cleanedImakefile && cleanedImakefile != Imakefile) unlink(cleanedImakefile); if (haveImakefileC) unlink(ImakefileC);}#ifdef SIGNALRETURNSINTint#elsevoid#endifcatch(sig) int sig;{ errno = 0; LogFatalI("Signal %d.", sig);}/* * Initialize some variables. */voidinit(){ register char *p; make_argindex=0; while (make_argv[ make_argindex ] != NULL) make_argindex++; cpp_argindex = 0; while (cpp_argv[ cpp_argindex ] != NULL) cpp_argindex++; /* * See if the standard include directory is different than * the default. Or if cpp is not the default. Or if the make * found by the PATH variable is not the default. */ if (p = getenv("IMAKEINCLUDE")) { if (*p != '-' || *(p+1) != 'I') LogFatal("Environment var IMAKEINCLUDE %s", "must begin with -I"); AddCppArg(p); for (; *p; p++) if (*p == ' ') { *p++ = '\0'; AddCppArg(p); } } if (p = getenv("IMAKECPP")) cpp = p; if (p = getenv("IMAKEMAKE")) make_argv[0] = p; if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, catch);#ifdef SIGCHLD signal(SIGCHLD, SIG_DFL);#endif}voidAddMakeArg(arg) char *arg;{ errno = 0; if (make_argindex >= ARGUMENTS-1) LogFatal("Out of internal storage.", ""); make_argv[ make_argindex++ ] = arg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -