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/* 11 * 12Copyright (c) 1985, 1986, 1987, 1998 The Open Group 13 14Permission to use, copy, modify, distribute, and sell this software and its 15documentation for any purpose is hereby granted without fee, provided that 16the above copyright notice appear in all copies and that both that 17copyright notice and this permission notice appear in supporting 18documentation. 19 20The above copyright notice and this permission notice shall be included in 21all copies or substantial portions of the Software. 22 23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 27AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 30Except as contained in this notice, the name of The Open Group shall not be 31used in advertising or otherwise to promote the sale, use or other dealings 32in this Software without prior written authorization from The Open Group. 33 * 34 * Original Author: 35 * Todd Brunhoff 36 * Tektronix, inc. 37 * While a guest engineer at Project Athena, MIT 38 * 39 * imake: the include-make program. 40 * 41 * Usage: imake [-Idir] [-Ddefine] [-T template] [-f imakefile ] [-C Imakefile.c ] [-s] [-e] [-v] [make flags] 42 * 43 * Imake takes a template file (Imake.tmpl) and a prototype (Imakefile) 44 * and runs cpp on them producing a Makefile. It then optionally runs make 45 * on the Makefile. 46 * Options: 47 * -D define. Same as cpp -D argument. 48 * -U undefine. Same as cpp -U argument. 49 * -W warning. Same as cpp -W argument. 50 * -I Include directory. Same as cpp -I argument. 51 * -T template. Designate a template other 52 * than Imake.tmpl 53 * -f specify the Imakefile file 54 * -C specify the name to use instead of Imakefile.c 55 * -s[F] show. Show the produced makefile on the standard 56 * output. Make is not run is this case. If a file 57 * argument is provided, the output is placed there. 58 * -e[F] execute instead of show; optionally name Makefile F 59 * -v verbose. Show the make command line executed. 60 * 61 * Environment variables: 62 * 63 * IMAKEINCLUDE Include directory to use in addition to "." 64 * IMAKECPP Cpp to use instead of /lib/cpp 65 * IMAKEMAKE make program to use other than what is 66 * found by searching the $PATH variable. 67 * Other features: 68 * imake reads the entire cpp output into memory and then scans it 69 * for occurrences of "@@". If it encounters them, it replaces it with 70 * a newline. It also trims any trailing white space on output lines 71 * (because make gets upset at them). This helps when cpp expands 72 * multi-line macros but you want them to appear on multiple lines. 73 * It also changes occurrences of "XCOMM" to "#", to avoid problems 74 * with treating commands as invalid preprocessor commands. 75 * 76 * The macros MAKEFILE and MAKE are provided as macros 77 * to make. MAKEFILE is set to imake's makefile (not the constructed, 78 * preprocessed one) and MAKE is set to argv[0], i.e. the name of 79 * the imake program. 80 * 81 * Theory of operation: 82 * 1. Determine the name of the imakefile from the command line (-f) 83 * or from the content of the current directory (Imakefile or imakefile). 84 * Call this <imakefile>. This gets added to the arguments for 85 * make as MAKEFILE=<imakefile>. 86 * 2. Determine the name of the template from the command line (-T) 87 * or the default, Imake.tmpl. Call this <template> 88 * 3. Determine the name of the imakeCfile from the command line (-C) 89 * or the default, Imakefile.c. Call this <imakeCfile> 90 * 4. Store lines of input into <imakeCfile>: 91 * - A c-style comment header (see ImakefileCHeader below), used 92 * to recognize temporary files generated by imake. 93 * - If DEFAULT_OS_NAME is defined, format the utsname struct and 94 * call the result <defaultOsName>. Add: 95 * #define DefaultOSName <defaultOsName> 96 * - If DEFAULT_OS_MAJOR_REV is defined, format the utsname struct 97 * and call the result <defaultOsMajorVersion>. Add: 98 * #define DefaultOSMajorVersion <defaultOsMajorVersion> 99 * - If DEFAULT_OS_MINOR_REV is defined, format the utsname struct 100 * and call the result <defaultOsMinorVersion>. Add: 101 * #define DefaultOSMinorVersion <defaultOsMinorVersion> 102 * - If DEFAULT_OS_TEENY_REV is defined, format the utsname struct 103 * and call the result <defaultOsTeenyVersion>. Add: 104 * #define DefaultOSTeenyVersion <defaultOsTeenyVersion> 105 * - If DEFAULT_MACHINE_ARCITECTURE is defined, format the utsname struct 106 * and define the corresponding macro. (For example on the amiga, 107 * this will define amiga in addition to m68k). 108 * - If the file "localdefines" is readable in the current 109 * directory, print a warning message to stderr and add: 110 * #define IMAKE_LOCAL_DEFINES "localdefines" 111 * #include IMAKE_LOCAL_DEFINES 112 * - If the file "admindefines" is readable in the current 113 * directory, print a warning message to stderr and add: 114 * #define IMAKE_ADMIN_DEFINES "admindefines" 115 * #include IMAKE_ADMIN_DEFINES 116 * - The following lines: 117 * #define INCLUDE_IMAKEFILE < <imakefile> > 118 * #define IMAKE_TEMPLATE " <template> " 119 * #include IMAKE_TEMPLATE 120 * - If the file "adminmacros" is readable in the current 121 * directory, print a warning message to stderr and add: 122 * #define IMAKE_ADMIN_MACROS "adminmacros" 123 * #include IMAKE_ADMIN_MACROS 124 * - If the file "localmacros" is readable in the current 125 * directory, print a warning message to stderr and add: 126 * #define IMAKE_LOCAL_MACROS "localmacros" 127 * #include IMAKE_LOCAL_MACROS 128 * 5. Start up cpp and provide it with this file. 129 * Note that the define for INCLUDE_IMAKEFILE is intended for 130 * use in the template file. This implies that the imake is 131 * useless unless the template file contains at least the line 132 * #include INCLUDE_IMAKEFILE 133 * 6. Gather the output from cpp, and clean it up, expanding @@ to 134 * newlines, stripping trailing white space, cpp control lines, 135 * and extra blank lines, and changing XCOMM to #. This cleaned 136 * output is placed in a new file, default "Makefile", but can 137 * be specified with -s or -e options. 138 * 7. Optionally start up make on the resulting file. 139 * 140 * The design of the template makefile should therefore be: 141 * <set global macros like CFLAGS, etc.> 142 * <include machine dependent additions> 143 * #include INCLUDE_IMAKEFILE 144 * <add any global targets like 'clean' and long dependencies> 145 */ 146 147#include "config.h" 148 149#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) 150/* This needs to be before _POSIX_SOURCE gets defined */ 151# include <sys/param.h> 152# include <sys/types.h> 153# include <sys/sysctl.h> 154#endif 155#include <stdlib.h> 156#include <stdio.h> 157#include <stdarg.h> 158#include <X11/Xfuncproto.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 303const char *cpp = NULL; 304 305const char *tmpMakefile; 306const char *tmpMakefileTemplate = "/tmp/Imf.XXXXXX"; 307const char *tmpImakefile; 308const char *tmpImakefileTemplate = "/tmp/IIf.XXXXXX"; 309const char *make_argv[ ARGUMENTS ] = { 310#ifdef WIN32 311 "nmake" 312#else 313 "make" 314#endif 315}; 316 317int make_argindex; 318int cpp_argindex; 319const char *Imakefile = NULL; 320const char *Makefile = "Makefile"; 321const char *Template = "Imake.tmpl"; 322const char *ImakefileC = "Imakefile.c"; 323boolean haveImakefileC = FALSE; 324const char *cleanedImakefile = NULL; 325const char *program; 326const char *FindImakefile(const char *Imakefile); 327char *ReadLine(FILE *tmpfd, const char *tmpfname); 328const char *CleanCppInput(const char *imakefile); 329char *Strdup(const char *cp); 330char *Emalloc(size_t size); 331void LogFatal(const char *x0, ...) _X_ATTRIBUTE_PRINTF(1, 2); 332void LogMsg(const char *x0, ...) _X_ATTRIBUTE_PRINTF(1, 2); 333 334void showit(FILE *fd); 335void wrapup(void); 336void init(void); 337void AddMakeArg(const char *arg); 338void AddCppArg(const char *arg); 339#ifdef CROSSCOMPILE 340char *CrossCompileCPP(void); 341#endif 342void SetOpts(int argc, char **argv); 343void CheckImakefileC(const char *masterc); 344void cppit(const char *imakefile, const char *template, const char *masterc, 345 FILE *outfd, const char *outfname); 346void makeit(void); 347void CleanCppOutput(FILE *tmpfd, const char *tmpfname); 348boolean isempty(char *line); 349void writetmpfile(FILE *fd, const char *buf, size_t cnt, const char *fname); 350void catch(int sig); 351void showargs(const char **argv); 352boolean optional_include(FILE *inFile, const char *defsym, const char *fname); 353void doit(FILE *outfd, const char *cmd, const char **argv); 354boolean define_os_defaults(FILE *inFile); 355#ifdef CROSSCOMPILE 356static void get_cross_compile_dir(FILE *inFile); 357#endif 358#ifdef CROSSCOMPILEDIR 359const char *CrossCompileDir = CROSSCOMPILEDIR; 360#else 361const char *CrossCompileDir = ""; 362#endif 363boolean CrossCompiling = FALSE; 364 365 366 367boolean verbose = FALSE; 368boolean show = TRUE; 369 370int 371main(int argc, char *argv[]) 372{ 373 FILE *tmpfd = NULL; 374 char makeMacro[ BUFSIZ ]; 375 char makefileMacro[ BUFSIZ ]; 376 int lenCrossCompileDir = 0; 377 378 program = argv[0]; 379 init(); 380 381 lenCrossCompileDir = strlen(CrossCompileDir); 382 if (lenCrossCompileDir) { 383 if (lenCrossCompileDir > (PATH_MAX - 20)) 384 LogFatal("Cross compile directory path too long %s\n", 385 CrossCompileDir); 386 else 387 CrossCompiling = TRUE; 388 } 389 390 SetOpts(argc, argv); 391 Imakefile = FindImakefile(Imakefile); 392 CheckImakefileC(ImakefileC); 393 if (Makefile) { 394 tmpMakefile = Makefile; 395 if ((tmpfd = fopen(tmpMakefile, "w+")) == NULL) 396 LogFatal("Cannot create temporary file %s.", tmpMakefile); 397 } else { 398 char *tmpMakefileName = Strdup(tmpMakefileTemplate); 399 400#ifndef HAVE_MKSTEMP 401 if (mktemp(tmpMakefileName) == NULL || 402 (tmpfd = fopen(tmpMakefileName, "w+")) == NULL) { 403 LogFatal("Cannot create temporary file %s.", tmpMakefileName); 404 } 405#else 406 int fd = mkstemp(tmpMakefileName); 407 408 if (fd == -1 || (tmpfd = fdopen(fd, "w+")) == NULL) { 409 if (fd != -1) { 410 unlink(tmpMakefileName); close(fd); 411 } 412 LogFatal("Cannot create temporary file %s.", tmpMakefileName); 413 } 414#endif 415 tmpMakefile = tmpMakefileName; 416 } 417 AddMakeArg("-f"); 418 AddMakeArg( tmpMakefile ); 419 sprintf(makeMacro, "MAKE=%s", program); 420 AddMakeArg( makeMacro ); 421 sprintf(makefileMacro, "MAKEFILE=%s", Imakefile); 422 AddMakeArg( makefileMacro ); 423 424 cleanedImakefile = CleanCppInput(Imakefile); 425 cppit(cleanedImakefile, Template, ImakefileC, tmpfd, tmpMakefile); 426 427 if (show) { 428 if (Makefile == NULL) 429 showit(tmpfd); 430 } else 431 makeit(); 432 wrapup(); 433 exit(0); 434} 435 436void 437showit(FILE *fd) 438{ 439 char buf[ BUFSIZ ]; 440 size_t red; 441 442 fseek(fd, 0, SEEK_SET); 443 while ((red = fread(buf, 1, BUFSIZ, fd)) > 0) 444 writetmpfile(stdout, buf, red, "stdout"); 445 if (ferror(fd)) 446 LogFatal("Cannot read %s.", tmpMakefile); 447} 448 449void 450wrapup(void) 451{ 452 if (tmpMakefile != Makefile) 453 unlink(tmpMakefile); 454 if (cleanedImakefile && cleanedImakefile != Imakefile) 455 unlink(cleanedImakefile); 456 if (haveImakefileC) 457 unlink(ImakefileC); 458} 459 460void 461catch(int sig) 462{ 463 errno = 0; 464 LogFatal("Signal %d.", sig); 465} 466 467/* 468 * Initialize some variables. 469 */ 470void 471init(void) 472{ 473 register char *p; 474 475 make_argindex=0; 476 while (make_argv[ make_argindex ] != NULL) 477 make_argindex++; 478 cpp_argindex = 0; 479 while (cpp_argv[ cpp_argindex ] != NULL) 480 cpp_argindex++; 481 482#if defined CROSSCOMPILE 483 if (sys == netBSD) 484 if (CrossCompiling) { 485 LogFatal("fix imake to do crosscompiling for NetBSD\n",""); 486 } else 487#endif 488#if defined(__NetBSD__) || defined CROSSCOMPILE 489 { 490 struct utsname uts; 491 static char argument[512]; 492 493 /* 494 * Shareable imake configurations require a 495 * machine identifier. 496 */ 497 if (uname(&uts) != 0) 498 LogFatal("uname(3) failed; can't tell what %s", 499 "kind of machine you have."); 500 501 memset(argument, 0, sizeof(argument)); 502 (void)snprintf(argument, sizeof(argument) - 1, 503 "-D__%s__", uts.machine); 504 505 AddCppArg(argument); 506 } 507#endif /* __NetBSD__ */ 508 509 /* 510 * See if the standard include directory is different than 511 * the default. Or if cpp is not the default. Or if the make 512 * found by the PATH variable is not the default. 513 */ 514 if ((p = getenv("IMAKEINCLUDE"))) { 515 if (*p != '-' || *(p+1) != 'I') 516 LogFatal("Environment var IMAKEINCLUDE %s", 517 "must begin with -I"); 518 AddCppArg(p); 519 for (; *p; p++) 520 if (*p == ' ') { 521 *p++ = '\0'; 522 AddCppArg(p); 523 } 524 } 525 if ((p = getenv("IMAKECPP"))) 526 cpp = p; 527 if ((p = getenv("IMAKEMAKE"))) 528 make_argv[0] = p; 529 530 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 531 signal(SIGINT, catch); 532#ifdef SIGCHLD 533 signal(SIGCHLD, SIG_DFL); 534#endif 535} 536 537void 538AddMakeArg(const char *arg) 539{ 540 errno = 0; 541 if (make_argindex >= ARGUMENTS-1) 542 LogFatal("Out of internal storage."); 543 make_argv[ make_argindex++ ] = arg; 544 make_argv[ make_argindex ] = NULL; 545} 546 547void 548AddCppArg(const char *arg) 549{ 550 errno = 0; 551 if (cpp_argindex >= ARGUMENTS-1) 552 LogFatal("Out of internal storage."); 553 cpp_argv[ cpp_argindex++ ] = arg; 554 cpp_argv[ cpp_argindex ] = NULL; 555} 556 557void 558SetOpts(int argc, char **argv) 559{ 560 561 errno = 0; 562 /* 563 * Now gather the arguments for make 564 */ 565 for(argc--, argv++; argc; argc--, argv++) { 566 /* 567 * We intercept these flags. 568 */ 569 if (argv[0][0] == '-') { 570 if (argv[0][1] == 'D') { 571 AddCppArg(argv[0]); 572 } else if (argv[0][1] == 'I') { 573 AddCppArg(argv[0]); 574 } else if (argv[0][1] == 'U') { 575 AddCppArg(argv[0]); 576 } else if (argv[0][1] == 'W') { 577 AddCppArg(argv[0]); 578 } else if (argv[0][1] == 'f') { 579 if (argv[0][2]) 580 Imakefile = argv[0]+2; 581 else { 582 argc--, argv++; 583 if (! argc) 584 LogFatal("No description arg after -f flag"); 585 Imakefile = argv[0]; 586 } 587 } else if (argv[0][1] == 's') { 588 if (argv[0][2]) 589 Makefile = ((argv[0][2] == '-') && !argv[0][3]) ? 590 NULL : argv[0]+2; 591 else { 592 argc--, argv++; 593 if (!argc) 594 LogFatal("No description arg after -s flag"); 595 Makefile = ((argv[0][0] == '-') && !argv[0][1]) ? 596 NULL : argv[0]; 597 } 598 show = TRUE; 599 } else if (argv[0][1] == 'e') { 600 Makefile = (argv[0][2] ? argv[0]+2 : NULL); 601 show = FALSE; 602 } else if (argv[0][1] == 'T') { 603 if (argv[0][2]) 604 Template = argv[0]+2; 605 else { 606 argc--, argv++; 607 if (! argc) 608 LogFatal("No description arg after -T flag"); 609 Template = argv[0]; 610 } 611 } else if (argv[0][1] == 'C') { 612 if (argv[0][2]) 613 ImakefileC = argv[0]+2; 614 else { 615 argc--, argv++; 616 if (! argc) 617 LogFatal("No imakeCfile arg after -C flag"); 618 ImakefileC = argv[0]; 619 } 620 } else if (argv[0][1] == 'v') { 621 verbose = TRUE; 622 } else 623 AddMakeArg(argv[0]); 624 } else 625 AddMakeArg(argv[0]); 626 } 627 628#ifndef CROSSCOMPILE 629# ifdef USE_CC_E 630 if (!cpp) 631 { 632 AddCppArg("-E"); 633# ifdef __GNUC__ 634 if (verbose) 635 AddCppArg("-v"); 636# endif 637 cpp = DEFAULT_CC; 638 } 639# else 640 if (!cpp) 641 cpp = DEFAULT_CPP; 642# endif 643#else 644 if (!cpp) 645 cpp = CrossCompileCPP(); 646#endif 647 648 cpp_argv[0] = cpp; 649 AddCppArg(ImakefileC); 650} 651 652const char * 653FindImakefile(const char *filename) 654{ 655 if (filename) { 656 if (access(filename, R_OK) < 0) 657 LogFatal("Cannot find %s.", filename); 658 } else { 659 if (access("Imakefile", R_OK) < 0) { 660 if (access("imakefile", R_OK) < 0) 661 LogFatal("No description file."); 662 else 663 filename = "imakefile"; 664 } else 665 filename = "Imakefile"; 666 } 667 return(filename); 668} 669 670static void _X_ATTRIBUTE_PRINTF(1, 0) 671vLogMsg(const char *fmt, va_list args) 672{ 673 int error_number = errno; 674 675 if (error_number) { 676 fprintf(stderr, "%s: ", program); 677 fprintf(stderr, "%s\n", strerror(error_number)); 678 } 679 fprintf(stderr, "%s: ", program); 680 vfprintf(stderr, fmt, args); 681 fprintf(stderr, "\n"); 682} 683 684void 685LogFatal(const char *fmt, ...) 686{ 687 static boolean entered = FALSE; 688 va_list args; 689 690 if (entered) 691 return; 692 entered = TRUE; 693 694 va_start(args, fmt); 695 vLogMsg(fmt, args); 696 va_end(args); 697 fprintf(stderr, " Stop.\n"); 698 wrapup(); 699 exit(1); 700} 701 702void 703LogMsg(const char *fmt, ...) 704{ 705 va_list args; 706 707 va_start(args, fmt); 708 vLogMsg(fmt, args); 709 va_end(args); 710} 711 712void 713showargs(const 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(const 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 else 740 fclose(inFile); 741 } 742} 743 744#define LocalDefineFmt "#define %s \"%s\"\n" 745#define IncludeFmt "#include %s\n" 746#define ImakeDefSym "INCLUDE_IMAKEFILE" 747#define ImakeTmplSym "IMAKE_TEMPLATE" 748#define OverrideWarning "Warning: local file \"%s\" overrides global macros." 749 750boolean 751optional_include(FILE *inFile, const char *defsym, const char *fname) 752{ 753 errno = 0; 754 if (access(fname, R_OK) == 0) { 755 LogMsg(OverrideWarning, fname); 756 return (fprintf(inFile, LocalDefineFmt, defsym, fname) < 0 || 757 fprintf(inFile, IncludeFmt, defsym) < 0); 758 } 759 return FALSE; 760} 761 762void 763doit(FILE *outfd, const char *cmd, const char **argv) 764{ 765 int pid; 766 waitType status; 767 768 /* 769 * Fork and exec the command. 770 */ 771#ifdef WIN32 772 if (outfd) 773 dup2(fileno(outfd), 1); 774 status = _spawnvp(_P_WAIT, cmd, argv); 775 if (status < 0) 776 LogFatal("Cannot spawn %s.", cmd); 777 if (status > 0) 778 LogFatal("Exit code %d.", status); 779#else 780 pid = fork(); 781 if (pid < 0) 782 LogFatal("Cannot fork."); 783 if (pid) { /* parent... simply wait */ 784 while (wait(&status) > 0) { 785 errno = 0; 786 if (WIFSIGNALED(status)) 787 LogFatal("Signal %d.", waitSig(status)); 788 if (WIFEXITED(status) && waitCode(status)) 789 LogFatal("Exit code %d.", waitCode(status)); 790 } 791 } 792 else { /* child... dup and exec cmd */ 793 if (verbose) 794 showargs(argv); 795 if (outfd) 796 dup2(fileno(outfd), 1); 797 execvp(cmd, (char * const *) argv); 798 LogFatal("Cannot exec %s.", cmd); 799 } 800#endif 801} 802 803#if !defined WIN32 804static void 805parse_utsname(struct utsname *name, const char *fmt, char *result, const char *msg) 806{ 807 char buf[SYS_NMLN * 5 + 1]; 808 char *ptr = buf; 809 int arg; 810 811 if (!name) 812 LogFatal(msg,fmt); 813 814 /* Assemble all the pieces into a buffer. */ 815 for (arg = 0; fmt[arg] != ' '; arg++) 816 { 817 /* Our buffer is only guaranteed to hold 5 arguments. */ 818 if (arg >= 5) 819 LogFatal(msg, fmt); 820 821 switch (fmt[arg]) 822 { 823 case 's': 824 if (arg > 0) 825 *ptr++ = ' '; 826 strcpy(ptr, name->sysname); 827 ptr += strlen(ptr); 828 break; 829 830 case 'n': 831 if (arg > 0) 832 *ptr++ = ' '; 833 strcpy(ptr, name->nodename); 834 ptr += strlen(ptr); 835 break; 836 837 case 'r': 838 if (arg > 0) 839 *ptr++ = ' '; 840 strcpy(ptr, name->release); 841 ptr += strlen(ptr); 842 break; 843 844 case 'v': 845 if (arg > 0) 846 *ptr++ = ' '; 847 strcpy(ptr, name->version); 848 ptr += strlen(ptr); 849 break; 850 851 case 'm': 852 if (arg > 0) 853 *ptr++ = ' '; 854 strcpy(ptr, name->machine); 855 ptr += strlen(ptr); 856 break; 857 858 default: 859 LogFatal(msg, fmt); 860 } 861 } 862 863 /* Just in case... */ 864 if (strlen(buf) >= sizeof(buf)) 865 LogFatal("Buffer overflow parsing uname."); 866 867 /* Parse the buffer. The sscanf() return value is rarely correct. */ 868 *result = '\0'; 869 (void) sscanf(buf, fmt + arg + 1, result); 870} 871 872/* Trim leading 0's and periods from version names. The 0's cause 873 the number to be interpreted as octal numbers. Some version strings 874 have the potential for different numbers of .'s in them. 875 */ 876 877static char * 878trim_version(char *p) 879{ 880 881 if (p != 0 && *p != '\0') 882 { 883 while ((*p == '0' || *p == '.') && *(p + 1) != '\0') 884 ++p; 885 } 886 return (p); 887} 888#endif 889 890#if defined(linux) || defined(__GLIBC__) 891const char *libc_c= 892"#include <stdio.h>\n" 893"#include <ctype.h>\n" 894"\n" 895"#if 1\n" 896"#pragma weak gnu_get_libc_version\n" 897"#pragma weak __libc_version\n" 898"#pragma weak __linux_C_lib_version\n" 899"#endif\n" 900"\n" 901"extern const char * gnu_get_libc_version (void);\n" 902"extern const char * __linux_C_lib_version;\n" 903"extern const char __libc_version [];\n" 904"\n" 905"int\n" 906"main ()\n" 907"{\n" 908" int libcmajor = 0, libcminor = 0, libcteeny = 0;\n" 909" const char * ptr = NULL;\n" 910" int glibcmajor = 0;\n" 911"\n" 912" if (gnu_get_libc_version != 0)\n" 913" {\n" 914" ptr = gnu_get_libc_version ();\n" 915" glibcmajor = 4;\n" 916" }\n" 917" else if (&__libc_version != 0)\n" 918" {\n" 919" ptr = __libc_version;\n" 920" glibcmajor = 4;\n" 921" }\n" 922" else if (&__linux_C_lib_version != 0)\n" 923" {\n" 924" ptr = __linux_C_lib_version;\n" 925" }\n" 926" else\n" 927" {\n" 928" libcmajor = 0; libcminor = 0; libcteeny = 0;\n" 929" }\n" 930"\n" 931" if (ptr)\n" 932" {\n" 933" while (!isdigit (*ptr))\n" 934" ptr++;\n" 935"\n" 936" sscanf (ptr, \"%d.%d.%d\", &libcmajor, &libcminor, &libcteeny);\n" 937" libcmajor += glibcmajor;\n" 938" }\n" 939"\n" 940" printf(\"#define DefaultLinuxCLibMajorVersion %d\\n\", libcmajor);\n" 941" printf(\"#define DefaultLinuxCLibMinorVersion %d\\n\", libcminor);\n" 942" printf(\"#define DefaultLinuxCLibTeenyVersion %d\\n\", libcteeny);\n" 943"\n" 944" return 0;\n" 945"}\n" 946; 947 948static void 949get_libc_version(FILE *inFile) 950{ 951 char aout[4096], *tmpdir; 952 FILE *fp; 953 const char *format = "%s -o %s -x c -"; 954 char *cc; 955 int len; 956 char *command; 957 958 /* If $TMPDIR is defined and has an acceptable length, 959 * use that as tmp dir, else use /tmp. That fixes 960 * problems with /tmp mounted "noexec". 961 */ 962 if((tmpdir = getenv("TMPDIR")) != NULL && strlen(tmpdir) < (4096-13)) 963 strcpy(aout, tmpdir); 964 else 965 strcpy(aout, "/tmp"); 966 strcat(aout, "/imakeXXXXXX"); 967 968 /* Pre-create temp file safely */ 969 { 970 /* Linux + ELF has mkstemp() */ 971 int tmpfd; 972 if ((tmpfd = mkstemp(aout)) == -1) { 973 perror("mkstemp"); 974 abort(); 975 } 976 close(tmpfd); 977 } 978 cc = getenv ("CC"); 979 if (cc == NULL) 980 cc = "gcc"; 981 len = strlen (aout) + strlen (format) + strlen (cc); 982 if (len < 128) len = 128; 983 if((command = alloca (len)) == NULL) 984 abort(); 985 986 if (snprintf (command , len, format, cc, aout) == len) 987 abort (); 988 989 fp = popen (command, "w"); 990 if (fp == NULL || fprintf (fp, "%s\n", libc_c) < 0 991 || pclose (fp) != 0) 992 abort (); 993 994 fp = popen (aout, "r"); 995 if (fp == NULL) 996 abort (); 997 998 while (fgets (command, len, fp)) 999 fputs (command, inFile); 1000 1001 len = pclose (fp); 1002 remove (aout); 1003 if (len) 1004 abort (); 1005} 1006#endif 1007 1008#if defined(__OpenBSD__) || defined(__DragonFly__) 1009static void 1010get_stackprotector(FILE *inFile) 1011{ 1012 FILE *fp; 1013 char *cc; 1014 char command[1024], buf[1024]; 1015 1016 cc = getenv("CC"); 1017 if (cc == NULL) { 1018 cc = "cc"; 1019 } 1020 snprintf(command, sizeof(command), "%s -v 2>&1", cc); 1021 fp = popen(command, "r"); 1022 if (fp == NULL) 1023 abort(); 1024 while (fgets(buf, sizeof(buf), fp)) { 1025 if (strstr(buf, "propolice") != NULL) { 1026 fprintf(inFile, "#define ProPoliceSupport YES\n"); 1027 break; 1028 } 1029 } 1030 pclose(fp); 1031} 1032#endif 1033 1034 1035#if defined CROSSCOMPILE || defined linux || defined(__GLIBC__) 1036static void 1037get_distrib(FILE *inFile) 1038{ 1039 struct stat sb; 1040 1041 static const char* suse = "/etc/SuSE-release"; 1042 static const char* redhat = "/etc/redhat-release"; 1043 static const char* debian = "/etc/debian_version"; 1044 1045 fprintf (inFile, "%s\n", "#define LinuxUnknown 0"); 1046 fprintf (inFile, "%s\n", "#define LinuxSuSE 1"); 1047 fprintf (inFile, "%s\n", "#define LinuxCaldera 2"); 1048 fprintf (inFile, "%s\n", "#define LinuxCraftworks 3"); 1049 fprintf (inFile, "%s\n", "#define LinuxDebian 4"); 1050 fprintf (inFile, "%s\n", "#define LinuxInfoMagic 5"); 1051 fprintf (inFile, "%s\n", "#define LinuxKheops 6"); 1052 fprintf (inFile, "%s\n", "#define LinuxPro 7"); 1053 fprintf (inFile, "%s\n", "#define LinuxRedHat 8"); 1054 fprintf (inFile, "%s\n", "#define LinuxSlackware 9"); 1055 fprintf (inFile, "%s\n", "#define LinuxTurbo 10"); 1056 fprintf (inFile, "%s\n", "#define LinuxWare 11"); 1057 fprintf (inFile, "%s\n", "#define LinuxYggdrasil 12"); 1058 1059# ifdef CROSSCOMPILE 1060 if (CrossCompiling) { 1061 fprintf (inFile, "%s\n", 1062 "#define DefaultLinuxDistribution LinuxUnknown"); 1063 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown"); 1064 return; 1065 } 1066# endif 1067 if (lstat (suse, &sb) == 0) { 1068 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxSuSE"); 1069 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName SuSE"); 1070 return; 1071 } 1072 if (lstat (redhat, &sb) == 0) { 1073 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxRedHat"); 1074 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName RedHat"); 1075 return; 1076 } 1077 if (lstat (debian, &sb) == 0) { 1078 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxDebian"); 1079 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Debian"); 1080 /* You could also try to get the version of the Debian distrib by looking 1081 * at the content of /etc/debian_version */ 1082 return; 1083 } 1084 /* what's the definitive way to tell what any particular distribution is? */ 1085 1086 fprintf (inFile, "%s\n", "#define DefaultLinuxDistribution LinuxUnknown"); 1087 fprintf (inFile, "%s\n", "#define DefaultLinuxDistName Unknown"); 1088 /* would like to know what version of the distribution it is */ 1089} 1090 1091static void 1092get_ld_version(FILE *inFile) 1093{ 1094 FILE* ldprog; 1095 signed char c; 1096 int ldmajor, ldminor; 1097 const char *ld = "ld -v"; 1098 1099# ifdef CROSSCOMPILE 1100 if (CrossCompiling) { 1101 char cmd[PATH_MAX]; 1102 strcpy (cmd, CrossCompileDir); 1103 strcat (cmd,"/"); 1104 strcat (cmd,ld); 1105 ldprog = popen (cmd, "r"); 1106 } else 1107# endif 1108 ldprog = popen (ld, "r"); 1109 1110 if (ldprog) { 1111 do { 1112 c = fgetc (ldprog); 1113 } while (c != EOF && !isdigit (c)); 1114 ungetc (c, ldprog); 1115 (void) fscanf (ldprog, "%d.%d", &ldmajor, &ldminor); 1116 /* Start conversion to a more rational number */ 1117 if ((ldmajor > 2) || ((ldmajor == 2) && (ldminor > 9))) 1118 ldmajor *= 100; 1119 else 1120 ldmajor *= 10; 1121 1122 fprintf(inFile, "#define DefaultLinuxBinUtilsMajorVersion %d\n", 1123 ldmajor + ldminor); 1124 pclose (ldprog); 1125 } 1126} 1127#endif 1128 1129#if defined __FreeBSD__ 1130static void 1131get_binary_format(FILE *inFile) 1132{ 1133 int mib[2]; 1134 size_t len; 1135 int osrel = 0; 1136 FILE *objprog = NULL; 1137 int iself = 0; 1138 char buf[10]; 1139 char cmd[PATH_MAX]; 1140 1141 mib[0] = CTL_KERN; 1142 mib[1] = KERN_OSRELDATE; 1143 len = sizeof(osrel); 1144 sysctl(mib, 2, &osrel, &len, NULL, 0); 1145 if (CrossCompiling) { 1146 strcpy (cmd, CrossCompileDir); 1147 strcat (cmd, "/"); 1148 strcat (cmd,"objformat"); 1149 } else 1150 strcpy (cmd, "objformat"); 1151 1152 if (osrel >= 300004 && 1153 (objprog = popen(cmd, "r")) != NULL && 1154 fgets(buf, sizeof(buf), objprog) != NULL && 1155 strncmp(buf, "elf", 3) == 0) 1156 iself = 1; 1157 if (objprog) 1158 pclose(objprog); 1159 1160 fprintf(inFile, "#define DefaultToElfFormat %s\n", iself ? "YES" : "NO"); 1161} 1162#endif 1163 1164#if defined(sun) && defined(__SVR4) 1165/* Runs Sun compiler command and parses output - this is a bit of a hack 1166 * as it depends on the particular output format of the -V flag, but it's 1167 * worked for many releases. 1168 * 1169 * Input : cmd - command to run (called with -V flag) 1170 * path - path to command to run (use $PATH if NULL) 1171 * Output: cmajor & cminor - major and minor versions if found 1172 * Returns: 0 if successful, -1 if not. 1173 */ 1174static int 1175ask_sun_compiler_for_versions(const char *cmd, const char *path, 1176 int *cmajor, int *cminor) 1177{ 1178 char buf[BUFSIZ]; 1179 char cmdtorun[PATH_MAX]; 1180 char* vptr; 1181 FILE* ccproc; 1182 const char vflag[] = " -V 2>&1"; 1183 int retval = -1; 1184 1185 size_t len = strlen(cmd) + sizeof(vflag); 1186 1187 if (path != NULL) { 1188 len += strlen(path) + 1; 1189 } 1190 1191 if (len < sizeof(cmdtorun)) { 1192 if (path != NULL) { 1193 sprintf(cmdtorun, "%s/%s %s", path, cmd, vflag); 1194 } else { 1195 sprintf(cmdtorun, "%s %s", cmd, vflag); 1196 } 1197 1198 if ((ccproc = popen (cmdtorun, "r")) != NULL) { 1199 if (fgets (buf, sizeof(buf), ccproc) != NULL) { 1200 vptr = strrchr (buf, 'C'); 1201 if (vptr) { 1202 for (; (*vptr != '\0') && !isdigit(*vptr); vptr++) { 1203 /* Do nothing - just scanning for first digit */ 1204 } 1205 if (*vptr != '\0') { 1206 if (sscanf (vptr, "%d.%d", cmajor, cminor) == 2) { 1207 retval = 0; 1208 } 1209 } 1210 } 1211 if (retval != 0) { 1212 fprintf(stderr, 1213 "warning: could not parse version number in output of:\n" 1214 " %s\n", cmdtorun); 1215 } 1216 while (fgets (buf, sizeof(buf), ccproc) != NULL) {}; 1217 } 1218 pclose (ccproc); 1219 } 1220 } 1221 return retval; 1222} 1223 1224/* Find Sun compilers and their versions if present */ 1225static void 1226get_sun_compiler_versions (FILE *inFile) 1227{ 1228 const char* sunpro_path = "/opt/SUNWspro/bin"; 1229 int cmajor, cminor, found = 0; 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 const 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 const char* cross_cc_name[] = { 1352 "cc", 1353 "gcc" 1354 }; 1355 1356 if (CrossCompiling) { 1357 unsigned 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 unsigned 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#ifdef CROSSCOMPILE 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) 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 gcc_name[PATH_MAX]; 1628 if (get_gcc(gcc_name)) { 1629 get_gcc_version (inFile, gcc_name); 1630# if defined CROSSCOMPILE 1631 if (sys != emx) 1632 get_gcc_incdir(inFile, gcc_name); 1633# endif 1634 } 1635 } 1636# endif 1637# if defined __FreeBSD__ 1638# if defined CROSSCOMPILE 1639 if (sys == freeBSD) 1640# endif 1641 get_binary_format(inFile); 1642# endif 1643 } 1644#endif /* !WIN32 */ 1645#if defined WIN32 1646# ifdef CROSSCOMPILE 1647 else if (sys == win32 && !CrossCompiling) 1648# endif 1649 { 1650 OSVERSIONINFO osvi; 1651 static char* os_names[] = { "Win32s", "Windows 95", "Windows NT" }; 1652 1653 memset(&osvi, 0, sizeof(OSVERSIONINFO)); 1654 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); 1655 GetVersionEx (&osvi); 1656 1657 fprintf (inFile, "#define DefaultOSName Microsoft %s\n", 1658 os_names[osvi.dwPlatformId]); 1659 1660 fprintf(inFile, "#define DefaultOSMajorVersion %d\n", osvi.dwMajorVersion); 1661 fprintf(inFile, "#define DefaultOSMinorVersion %d\n", osvi.dwMinorVersion); 1662 fprintf(inFile, "#define DefaultOSTeenyVersion %d\n", 1663 osvi.dwBuildNumber & 0xFFFF); 1664 } 1665#endif /* WIN32 */ 1666#ifdef CROSSCOMPILE 1667 else if (sys == emx) 1668 { 1669 fprintf(inFile, "#define DefaultOSMajorVersion 4\n"); 1670 fprintf(inFile, "#define DefaultOSMinorVersion 0\n"); 1671 fprintf(inFile, "#define DefaultOSTeenyVersion 0\n"); 1672 } 1673#endif /* EMX */ 1674#if defined(__OpenBSD__) || defined(__DragonFly__) 1675 get_stackprotector(inFile); 1676#endif 1677 return FALSE; 1678} 1679 1680void 1681cppit(const char *imakefile, const char *template, const char *masterc, 1682 FILE *outfd, const char *outfname) 1683{ 1684 FILE *inFile; 1685 1686 haveImakefileC = TRUE; 1687 inFile = fopen(masterc, "w"); 1688 if (inFile == NULL) 1689 LogFatal("Cannot open %s for output.", masterc); 1690 if (fprintf(inFile, "%s\n", ImakefileCHeader) < 0 || 1691 define_os_defaults(inFile) || 1692 optional_include(inFile, "IMAKE_LOCAL_DEFINES", "localdefines") || 1693 optional_include(inFile, "IMAKE_ADMIN_DEFINES", "admindefines") || 1694 fprintf(inFile, "#define %s <%s>\n", ImakeDefSym, imakefile) < 0 || 1695 fprintf(inFile, LocalDefineFmt, ImakeTmplSym, template) < 0 || 1696 fprintf(inFile, IncludeFmt, ImakeTmplSym) < 0 || 1697 optional_include(inFile, "IMAKE_ADMIN_MACROS", "adminmacros") || 1698 optional_include(inFile, "IMAKE_LOCAL_MACROS", "localmacros") || 1699 fflush(inFile)) { 1700 fclose(inFile); 1701 LogFatal("Cannot write to %s.", masterc); 1702 } 1703 else if (fclose(inFile)) 1704 LogFatal("Cannot write to %s.", masterc); 1705 /* 1706 * Fork and exec cpp 1707 */ 1708 doit(outfd, cpp, cpp_argv); 1709 CleanCppOutput(outfd, outfname); 1710} 1711 1712void 1713makeit(void) 1714{ 1715 doit(NULL, make_argv[0], make_argv); 1716} 1717 1718const char * 1719CleanCppInput(const char *imakefile) 1720{ 1721 FILE *outFile = NULL; 1722 FILE *inFile; 1723 char *buf, /* buffer for file content */ 1724 *pbuf, /* walking pointer to buf */ 1725 *punwritten, /* pointer to unwritten portion of buf */ 1726 *ptoken, /* pointer to # token */ 1727 *pend, /* pointer to end of # token */ 1728 savec; /* temporary character holder */ 1729 int count; 1730 struct stat st; 1731 1732 /* 1733 * grab the entire file. 1734 */ 1735 if (!(inFile = fopen(imakefile, "r"))) 1736 LogFatal("Cannot open %s for input.", imakefile); 1737 if (fstat(fileno(inFile), &st) < 0) 1738 LogFatal("Cannot stat %s for size.", imakefile); 1739 buf = Emalloc(st.st_size + 3); 1740 count = fread(buf + 2, 1, st.st_size, inFile); 1741 if (count == 0 && st.st_size != 0) 1742 LogFatal("Cannot read %s:", imakefile); 1743 fclose(inFile); 1744 buf[0] = '\n'; 1745 buf[1] = '\n'; 1746 buf[count + 2] = '\0'; 1747 1748 punwritten = pbuf = buf + 2; 1749 while (*pbuf) { 1750 /* for compatibility, replace make comments for cpp */ 1751 if (*pbuf == '#' && pbuf[-1] == '\n' && pbuf[-2] != '\\') { 1752 ptoken = pbuf+1; 1753 while (*ptoken == ' ' || *ptoken == '\t') 1754 ptoken++; 1755 pend = ptoken; 1756 while (*pend && *pend != ' ' && *pend != '\t' && *pend != '\n' && *pend != '\r') 1757 pend++; 1758 savec = *pend; 1759 *pend = '\0'; 1760 if (strcmp(ptoken, "define") && 1761 strcmp(ptoken, "if") && 1762 strcmp(ptoken, "ifdef") && 1763 strcmp(ptoken, "ifndef") && 1764 strcmp(ptoken, "include") && 1765 strcmp(ptoken, "line") && 1766 strcmp(ptoken, "else") && 1767 strcmp(ptoken, "elif") && 1768 strcmp(ptoken, "endif") && 1769 strcmp(ptoken, "error") && 1770 strcmp(ptoken, "pragma") && 1771 strcmp(ptoken, "undef")) { 1772 if (outFile == NULL) { 1773#ifdef HAVE_MKSTEMP 1774 int fd; 1775#endif 1776 char *tmpImakefileName = Strdup(tmpImakefileTemplate); 1777#ifndef HAVE_MKSTEMP 1778 if (mktemp(tmpImakefileName) == NULL || 1779 (outFile = fopen(tmpImakefileName, "w+")) == NULL) { 1780 LogFatal("Cannot open %s for write.", 1781 tmpImakefileName); 1782 } 1783#else 1784 fd=mkstemp(tmpImakefileName); 1785 if (fd != -1) 1786 outFile = fdopen(fd, "w"); 1787 if (outFile == NULL) { 1788 if (fd != -1) { 1789 unlink(tmpImakefileName); close(fd); 1790 } 1791 LogFatal("Cannot open %s for write.", 1792 tmpImakefileName); 1793 } 1794#endif 1795 tmpImakefile = tmpImakefileName; 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, const 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, const 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, SEEK_SET); 1959 if (fstat(fileno(tmpfd), &st) < 0) 1960 LogFatal("cannot stat %s for size", tmpMakefile); 1961 pline = buf = Emalloc(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, SEEK_SET); 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 } 1982 1983 for (p1 = pline; p1 < end; p1++) { 1984 if (*p1 == '@' && *(p1+1) == '@' 1985 /* ignore ClearCase version-extended pathnames */ 1986 && !(p1 != pline && !isspace(*(p1-1)) && *(p1+2) == '/')) 1987 { /* soft EOL */ 1988 *p1++ = '\0'; 1989 p1++; /* skip over second @ */ 1990 break; 1991 } 1992 else if (*p1 == '\n') { /* real EOL */ 1993#if defined CROSSCOMPILE || defined WIN32 1994# if defined CROSSCOMPILE 1995 if (sys == win32) 1996# endif 1997 { 1998 if (p1 > pline && p1[-1] == '\r') 1999 p1[-1] = '\0'; 2000 } 2001#endif 2002 *p1++ = '\0'; 2003 break; 2004 } 2005 } 2006 2007 /* 2008 * return NULL at the end of the file. 2009 */ 2010 p2 = (pline == p1 ? NULL : pline); 2011 pline = p1; 2012 return(p2); 2013} 2014 2015void 2016writetmpfile(FILE *fd, const char *buf, size_t cnt, const char *fname) 2017{ 2018 if (fwrite(buf, sizeof(char), cnt, fd) < cnt) 2019 LogFatal("Cannot write to %s.", fname); 2020} 2021 2022char * 2023Emalloc(size_t size) 2024{ 2025 char *p; 2026 2027 if ((p = malloc(size)) == NULL) 2028 LogFatal("Cannot allocate %ld bytes", (long) size); 2029 return(p); 2030} 2031 2032#if defined CROSSCOMPILE || defined FIXUP_CPP_WHITESPACE 2033void 2034KludgeOutputLine(char **pline) 2035{ 2036 char *p = *pline; 2037 char quotechar = '\0'; 2038 2039 switch (*p) { 2040 case '#': /*Comment - ignore*/ 2041 break; 2042 case '\t': /*Already tabbed - ignore it*/ 2043 break; 2044 case ' ': /*May need a tab*/ 2045 default: 2046# ifdef CROSSCOMPILE 2047 if (inline_syntax) 2048# endif 2049# if defined CROSSCOMPILE || defined INLINE_SYNTAX 2050 { 2051 if (*p == '<' && p[1] == '<') { /* inline file close */ 2052 InInline--; 2053 InRule = TRUE; 2054 break; 2055 } 2056 } 2057# endif 2058 /* 2059 * The following cases should not be treated as beginning of 2060 * rules: 2061 * variable := name (GNU make) 2062 * variable = .*:.* (':' should be allowed as value) 2063 * sed 's:/a:/b:' (: used in quoted values) 2064 */ 2065 for (; *p; p++) { 2066 if (quotechar) { 2067 if (quotechar == '\\' || 2068 (*p == quotechar && 2069# if defined CROSSCOMPILE || defined WIN32 2070 ( 2071# if defined CROSSCOMPILE 2072 (sys == win32) && 2073# endif 2074 quotechar != ')') && 2075# endif 2076 p[-1] != '\\')) 2077 quotechar = '\0'; 2078 continue; 2079 } 2080 switch (*p) { 2081 case '\\': 2082 case '"': 2083 case '\'': 2084 quotechar = *p; 2085 break; 2086 case '(': 2087 quotechar = ')'; 2088 break; 2089 case '{': 2090 quotechar = '}'; 2091 break; 2092 case '[': 2093 quotechar = ']'; 2094 break; 2095 case '=': 2096# ifdef CROSSCOMPILE 2097 if (remove_cpp_leadspace) 2098# endif 2099# if defined CROSSCOMPILE || defined REMOVE_CPP_LEADSPACE 2100 { 2101 if (!InRule && **pline == ' ') { 2102 while (**pline == ' ') 2103 (*pline)++; 2104 } 2105 } 2106# endif 2107 goto breakfor; 2108# if defined CROSSCOMPILE || defined INLINE_SYNTAX 2109 case '<': 2110 if (inline_syntax) { 2111 if (p[1] == '<') /* inline file start */ 2112 InInline++; 2113 } 2114 break; 2115# endif 2116 case ':': 2117 if (p[1] == '=') 2118 goto breakfor; 2119 while (**pline == ' ') 2120 (*pline)++; 2121 InRule = TRUE; 2122 return; 2123 } 2124 } 2125breakfor: 2126 if (InRule && **pline == ' ') 2127 **pline = '\t'; 2128 break; 2129 } 2130} 2131 2132void 2133KludgeResetRule(void) 2134{ 2135 InRule = FALSE; 2136} 2137#endif 2138char * 2139Strdup(const char *cp) 2140{ 2141 char *new = Emalloc(strlen(cp) + 1); 2142 2143 strcpy(new, cp); 2144 return new; 2145} 2146 2147#ifdef CROSSCOMPILE 2148char* 2149CrossCompileCPP(void) 2150{ 2151 char *cpp, *c; 2152 size_t len; 2153 if (crosscompile_use_cc_e) 2154 AddCppArg("-E"); 2155 2156 cpp = strrchr(crosscompile_cpp,'/'); 2157 if (!cpp) 2158 cpp = crosscompile_cpp; 2159 else 2160 cpp++; 2161 2162 len = strlen(cpp) + strlen(CrossCompileDir) + 2; 2163 c = Emalloc(len); 2164 2165 (void)snprintf(c, len,"%s/%s",CrossCompileDir,cpp); 2166 2167 return c; 2168} 2169 2170#endif 2171 2172#ifdef CROSSCOMPILE 2173static void 2174get_cross_compile_dir(FILE *inFile) 2175{ 2176 fprintf(inFile, "#define CrossCompileDir %s\n", 2177 CrossCompileDir); 2178 fprintf(inFile, "#define CrossCompiling YES\n"); 2179} 2180#endif 2181