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