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