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