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