VirtualBox

Changeset 51 in kBuild for trunk/src/kmk/main.c


Ignore:
Timestamp:
Apr 7, 2003 1:30:32 AM (22 years ago)
Author:
bird
Message:

kMk and porting to kLib.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/main.c

    r50 r51  
    11/*
    22 * Copyright (c) 1988, 1989, 1990, 1993
    3  *      The Regents of the University of California.  All rights reserved.
     3 *      The Regents of the University of California.  All rights reserved.
    44 * Copyright (c) 1989 by Berkeley Softworks
    55 * All rights reserved.
     
    1818 * 3. All advertising materials mentioning features or use of this software
    1919 *    must display the following acknowledgement:
    20  *      This product includes software developed by the University of
    21  *      California, Berkeley and its contributors.
     20 *      This product includes software developed by the University of
     21 *      California, Berkeley and its contributors.
    2222 * 4. Neither the name of the University nor the names of its contributors
    2323 *    may be used to endorse or promote products derived from this software
     
    4040static const char copyright[] =
    4141"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
    42         The Regents of the University of California.  All rights reserved.\n";
     42        The Regents of the University of California.  All rights reserved.\n";
    4343#endif /* not lint */
    4444
    4545#ifndef lint
    4646#if 0
    47 static char sccsid[] = "@(#)main.c      8.3 (Berkeley) 3/19/94";
     47static char sccsid[] = "@(#)main.c      8.3 (Berkeley) 3/19/94";
    4848#else
    4949static const char rcsid[] =
    5050  "$FreeBSD: src/usr.bin/make/main.c,v 1.35.2.6 2002/07/24 16:50:18 ru Exp $";
    5151#endif
     52#define KLIBFILEDEF rcsid
    5253#endif /* not lint */
    5354
    5455/*-
    5556 * main.c --
    56  *      The main file for this entire program. Exit routines etc
    57  *      reside here.
     57 *      The main file for this entire program. Exit routines etc
     58 *      reside here.
    5859 *
    5960 * Utility functions defined in this file:
    60  *      Main_ParseArgLine       Takes a line of arguments, breaks them and
    61  *                              treats them as if they were given when first
    62  *                              invoked. Used by the parse module to implement
    63  *                              the .MFLAGS target.
    64  *
    65  *      Error                   Print a tagged error message. The global
    66  *                              MAKE variable must have been defined. This
    67  *                              takes a format string and two optional
    68  *                              arguments for it.
    69  *
    70  *      Fatal                   Print an error message and exit. Also takes
    71  *                              a format string and two arguments.
    72  *
    73  *      Punt                    Aborts all jobs and exits with a message. Also
    74  *                              takes a format string and two arguments.
    75  *
    76  *      Finish                  Finish things up by printing the number of
    77  *                              errors which occured, as passed to it, and
    78  *                              exiting.
    79  */
    80 
    81 #if defined(USE_KLIB) //|| defined(KMK)
     61 *      Main_ParseArgLine       Takes a line of arguments, breaks them and
     62 *                              treats them as if they were given when first
     63 *                              invoked. Used by the parse module to implement
     64 *                              the .MFLAGS target.
     65 *
     66 *      Error                   Print a tagged error message. The global
     67 *                              MAKE variable must have been defined. This
     68 *                              takes a format string and two optional
     69 *                              arguments for it.
     70 *
     71 *      Fatal                   Print an error message and exit. Also takes
     72 *                              a format string and two arguments.
     73 *
     74 *      Punt                    Aborts all jobs and exits with a message. Also
     75 *                              takes a format string and two arguments.
     76 *
     77 *      Finish                  Finish things up by printing the number of
     78 *                              errors which occured, as passed to it, and
     79 *                              exiting.
     80 */
     81
     82#if defined(USE_KLIB)
    8283    #define KLIB_INSTRICT
    8384    #include <kLib/kLib.h>
     
    9697#endif
    9798#ifndef MACHINE
    98 # if !defined(__IBMC__)
    9999#  include <sys/utsname.h>
    100 # endif
    101 #endif
    102 #if !defined(__IBMC__)
     100#endif
     101#ifndef USE_KLIB
    103102#include <sys/wait.h>
     103#endif
    104104#include <err.h>
    105 #endif
    106105#include <stdlib.h>
    107106#include <errno.h>
    108107#include <fcntl.h>
    109108#include <stdio.h>
    110 #if !defined(__IBMC__) && !defined(__EMX__)
     109#if defined(__EMX__)
    111110#include <sysexits.h>
    112111#endif
    113 #if defined(__STDC__) || defined(__IBMC__)
     112#if defined(__STDC__)
    114113#include <stdarg.h>
    115114#else
     
    129128  #define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
    130129 #endif
    131 #endif
     130 char *realpath(const char *pszFileName, char *pszResolvedName);
     131 #define snprintf kStrNFormat
     132#endif
     133#include <getopt.h>
    132134#include "make.h"
    133135#include "hash.h"
     
    136138#include "pathnames.h"
    137139
    138 #ifndef DEFMAXLOCAL
    139 #define DEFMAXLOCAL DEFMAXJOBS
    140 #endif  /* DEFMAXLOCAL */
    141 
    142 #define MAKEFLAGS       ".MAKEFLAGS"
    143 
    144 Lst                     create;         /* Targets to be made */
    145 time_t                  now;            /* Time at start of make */
    146 GNode                   *DEFAULT;       /* .DEFAULT node */
    147 Boolean                 allPrecious;    /* .PRECIOUS given on line by itself */
    148 
    149 static Boolean          noBuiltins;     /* -r flag */
    150 static Lst              makefiles;      /* ordered list of makefiles to read */
    151 static Boolean          printVars;      /* print value of one or more vars */
    152 static Boolean          expandVars;     /* fully expand printed variables */
    153 static Lst              variables;      /* list of variables to print */
    154 int                     maxJobs;        /* -j argument */
     140#ifndef DEFMAXLOCAL
     141#define DEFMAXLOCAL DEFMAXJOBS
     142#endif  /* DEFMAXLOCAL */
     143
     144#define MAKEFLAGS       ".MAKEFLAGS"
     145
     146Lst                     create;         /* Targets to be made */
     147time_t                  now;            /* Time at start of make */
     148GNode                   *DEFAULT;       /* .DEFAULT node */
     149Boolean                 allPrecious;    /* .PRECIOUS given on line by itself */
     150
     151static Boolean          noBuiltins;     /* -r flag */
     152static Lst              makefiles;      /* ordered list of makefiles to read */
     153static Boolean          printVars;      /* print value of one or more vars */
     154static Boolean          expandVars;     /* fully expand printed variables */
     155static Lst              variables;      /* list of variables to print */
     156int                     maxJobs;        /* -j argument */
    155157static Boolean          forceJobs;      /* -j argument given */
    156 static int              maxLocal;       /* -L argument */
    157 Boolean                 compatMake;     /* -B argument */
    158 Boolean                 debug;          /* -d flag */
    159 Boolean                 noExecute;      /* -n flag */
    160 Boolean                 keepgoing;      /* -k flag */
    161 Boolean                 queryFlag;      /* -q flag */
    162 Boolean                 touchFlag;      /* -t flag */
    163 Boolean                 usePipes;       /* !-P flag */
    164 Boolean                 ignoreErrors;   /* -i flag */
    165 Boolean                 beSilent;       /* -s flag */
    166 Boolean                 beVerbose;      /* -v flag */
    167 Boolean                 oldVars;        /* variable substitution style */
    168 Boolean                 checkEnvFirst;  /* -e flag */
    169 Lst                     envFirstVars;   /* (-E) vars to override from env */
    170 static Boolean          jobsRunning;    /* TRUE if the jobs might be running */
     158static int              maxLocal;       /* -L argument */
     159Boolean                 compatMake;     /* -B argument */
     160Boolean                 debug;          /* -d flag */
     161Boolean                 noExecute;      /* -n flag */
     162Boolean                 keepgoing;      /* -k flag */
     163Boolean                 queryFlag;      /* -q flag */
     164Boolean                 touchFlag;      /* -t flag */
     165Boolean                 usePipes;       /* !-P flag */
     166Boolean                 ignoreErrors;   /* -i flag */
     167Boolean                 beSilent;       /* -s flag */
     168Boolean                 beVerbose;      /* -v flag */
     169Boolean                 oldVars;        /* variable substitution style */
     170Boolean                 checkEnvFirst;  /* -e flag */
     171Lst                     envFirstVars;   /* (-E) vars to override from env */
     172static Boolean          jobsRunning;    /* TRUE if the jobs might be running */
    171173#ifdef NMAKE
    172174static Boolean          go_to_objdir;   /* ! -o flag */
    173175#endif
    174 static void             MainParseArgs __P((int, char **));
    175 char *                  chdir_verify_path __P((char *, char *));
    176 static int              ReadMakefile __P((ClientData, ClientData));
    177 static void             usage __P((void));
    178 
    179 static char *curdir;                    /* startup directory */
    180 static char *objdir;                    /* where we chdir'ed to */
     176static void             MainParseArgs __P((int, char **));
     177char *                  chdir_verify_path __P((char *, char *));
     178static int              ReadMakefile __P((ClientData, ClientData));
     179static void             usage __P((void));
     180
     181static char *curdir;                    /* startup directory */
     182static char *objdir;                    /* where we chdir'ed to */
     183#ifdef KMK
     184char *                  argv0 = NULL;
     185#endif
    181186
    182187/*-
    183188 * MainParseArgs --
    184  *      Parse a given argument vector. Called from main() and from
    185  *      Main_ParseArgLine() when the .MAKEFLAGS target is used.
    186  *
    187  *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
     189 *      Parse a given argument vector. Called from main() and from
     190 *      Main_ParseArgLine() when the .MAKEFLAGS target is used.
     191 *
     192 *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
    188193 *
    189194 * Results:
    190  *      None
     195 *      None
    191196 *
    192197 * Side Effects:
    193  *      Various global and local flags will be set depending on the flags
    194  *      given
     198 *      Various global and local flags will be set depending on the flags
     199 *      given
    195200 */
    196201static void
    197202MainParseArgs(argc, argv)
    198         int argc;
    199         char **argv;
    200 {
    201         extern int optind;
    202         extern char *optarg;
    203         char *p;
    204         int c;
    205 
    206         optind = 1;     /* since we're called more than once */
     203        int argc;
     204        char **argv;
     205{
     206        extern int optind;
     207        extern char *optarg;
     208        char *p;
     209        int c;
     210
     211        optind = 1;     /* since we're called more than once */
    207212#ifdef REMOTE
    208213# ifdef NMAKE
     
    218223# endif
    219224#endif
    220 rearg:  while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
    221                 switch(c) {
    222                 case 'D':
    223                         Var_Set(optarg, "1", VAR_GLOBAL);
    224                         Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
    225                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    226                         break;
    227                 case 'I':
    228                         Parse_AddIncludeDir(optarg);
    229                         Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
    230                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    231                         break;
    232                 case 'V':
    233                         printVars = TRUE;
    234                         (void)Lst_AtEnd(variables, (ClientData)optarg);
    235                         Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
    236                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    237                         break;
    238                 case 'X':
    239                         expandVars = FALSE;
    240                         break;
    241                 case 'B':
    242                         compatMake = TRUE;
    243                         Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
    244                         break;
     225rearg:  while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
     226                switch(c) {
     227                case 'D':
     228                        Var_Set(optarg, "1", VAR_GLOBAL);
     229                        Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
     230                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     231                        break;
     232                case 'I':
     233                        Parse_AddIncludeDir(optarg);
     234                        Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
     235                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     236                        break;
     237                case 'V':
     238                        printVars = TRUE;
     239                        (void)Lst_AtEnd(variables, (ClientData)optarg);
     240                        Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
     241                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     242                        break;
     243                case 'X':
     244                        expandVars = FALSE;
     245                        break;
     246                case 'B':
     247                        compatMake = TRUE;
     248                        Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
     249                        break;
    245250#ifdef REMOTE
    246                 case 'L': {
    247                         char *endptr;
    248 
    249                         maxLocal = strtol(optarg, &endptr, 10);
    250                         if (maxLocal < 0 || *endptr != '\0') {
    251                                 warnx("illegal number, -L argument -- %s",
    252                                     optarg);
    253                                 usage();
    254                         }
    255                         Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
    256                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    257                         break;
    258                 }
    259 #endif
    260                 case 'P':
    261                         usePipes = FALSE;
    262                         Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
    263                         break;
    264                 case 'S':
    265                         keepgoing = FALSE;
    266                         Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
    267                         break;
    268                 case 'd': {
    269                         char *modules = optarg;
    270 
    271                         for (; *modules; ++modules)
    272                                 switch (*modules) {
    273                                 case 'A':
    274                                         debug = ~0;
    275                                         break;
    276                                 case 'a':
     251                case 'L': {
     252                        char *endptr;
     253
     254                        maxLocal = strtol(optarg, &endptr, 10);
     255                        if (maxLocal < 0 || *endptr != '\0') {
     256                                warnx("illegal number, -L argument -- %s",
     257                                    optarg);
     258                                usage();
     259                        }
     260                        Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
     261                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     262                        break;
     263                }
     264#endif
     265                case 'P':
     266                        usePipes = FALSE;
     267                        Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
     268                        break;
     269                case 'S':
     270                        keepgoing = FALSE;
     271                        Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
     272                        break;
     273                case 'd': {
     274                        char *modules = optarg;
     275
     276                        for (; *modules; ++modules)
     277                                switch (*modules) {
     278                                case 'A':
     279                                        debug = ~0;
     280                                        break;
     281                                case 'a':
    277282#ifdef USE_ARCHIVES
    278                                         debug |= DEBUG_ARCH;
     283                                        debug |= DEBUG_ARCH;
    279284#endif /* else ignore */
    280                                         break;
    281                                 case 'c':
    282                                         debug |= DEBUG_COND;
    283                                         break;
    284                                 case 'd':
    285                                         debug |= DEBUG_DIR;
    286                                         break;
    287                                 case 'f':
    288                                         debug |= DEBUG_FOR;
    289                                         break;
    290                                 case 'g':
    291                                         if (modules[1] == '1') {
    292                                                 debug |= DEBUG_GRAPH1;
    293                                                 ++modules;
    294                                         }
    295                                         else if (modules[1] == '2') {
    296                                                 debug |= DEBUG_GRAPH2;
    297                                                 ++modules;
    298                                         }
    299                                         break;
    300                                 case 'j':
    301                                         debug |= DEBUG_JOB;
    302                                         break;
    303                                 case 'l':
    304                                         debug |= DEBUG_LOUD;
    305                                         break;
    306                                 case 'm':
    307                                         debug |= DEBUG_MAKE;
    308                                         break;
     285                                        break;
     286                                case 'c':
     287                                        debug |= DEBUG_COND;
     288                                        break;
     289                                case 'd':
     290                                        debug |= DEBUG_DIR;
     291                                        break;
     292                                case 'f':
     293                                        debug |= DEBUG_FOR;
     294                                        break;
     295                                case 'g':
     296                                        if (modules[1] == '1') {
     297                                                debug |= DEBUG_GRAPH1;
     298                                                ++modules;
     299                                        }
     300                                        else if (modules[1] == '2') {
     301                                                debug |= DEBUG_GRAPH2;
     302                                                ++modules;
     303                                        }
     304                                        break;
     305                                case 'j':
     306                                        debug |= DEBUG_JOB;
     307                                        break;
     308                                case 'l':
     309                                        debug |= DEBUG_LOUD;
     310                                        break;
     311                                case 'm':
     312                                        debug |= DEBUG_MAKE;
     313                                        break;
    309314                                case 'p':     /*kso*/
    310                                         debug |= DEBUG_PARSE;
     315                                        debug |= DEBUG_PARSE;
    311316                                        break;
    312317                                case 's':
    313                                         debug |= DEBUG_SUFF;
    314                                         break;
    315                                 case 't':
    316                                         debug |= DEBUG_TARG;
    317                                         break;
    318                                 case 'v':
    319                                         debug |= DEBUG_VAR;
    320                                         break;
    321                                 default:
    322                                         warnx("illegal argument to d option -- %c", *modules);
    323                                         usage();
    324                                 }
    325                         Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
    326                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    327                         break;
    328                 }
    329                 case 'E':
    330                         p = emalloc(strlen(optarg) + 1);
    331                         (void)strcpy(p, optarg);
    332                         (void)Lst_AtEnd(envFirstVars, (ClientData)p);
    333                         Var_Append(MAKEFLAGS, "-E", VAR_GLOBAL);
    334                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    335                         break;
    336                 case 'e':
    337                         checkEnvFirst = TRUE;
    338                         Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
    339                         break;
    340                 case 'f':
    341                         (void)Lst_AtEnd(makefiles, (ClientData)optarg);
    342                         break;
    343                 case 'i':
    344                         ignoreErrors = TRUE;
    345                         Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
    346                         break;
    347                 case 'j': {
    348                         char *endptr;
    349 
    350                         forceJobs = TRUE;
    351                         maxJobs = strtol(optarg, &endptr, 10);
    352                         if (maxJobs <= 0 || *endptr != '\0') {
    353                                 warnx("illegal number, -j argument -- %s",
    354                                     optarg);
    355                                 usage();
    356                         }
     318                                        debug |= DEBUG_SUFF;
     319                                        break;
     320                                case 't':
     321                                        debug |= DEBUG_TARG;
     322                                        break;
     323                                case 'v':
     324                                        debug |= DEBUG_VAR;
     325                                        break;
     326                                default:
     327                                        warnx("illegal argument to d option -- %c", *modules);
     328                                        usage();
     329                                }
     330                        Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
     331                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     332                        break;
     333                }
     334                case 'E':
     335                        p = emalloc(strlen(optarg) + 1);
     336                        (void)strcpy(p, optarg);
     337                        (void)Lst_AtEnd(envFirstVars, (ClientData)p);
     338                        Var_Append(MAKEFLAGS, "-E", VAR_GLOBAL);
     339                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     340                        break;
     341                case 'e':
     342                        checkEnvFirst = TRUE;
     343                        Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
     344                        break;
     345                case 'f':
     346                        (void)Lst_AtEnd(makefiles, (ClientData)optarg);
     347                        break;
     348                case 'i':
     349                        ignoreErrors = TRUE;
     350                        Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
     351                        break;
     352                case 'j': {
     353                        char *endptr;
     354
     355                        forceJobs = TRUE;
     356                        maxJobs = strtol(optarg, &endptr, 10);
     357                        if (maxJobs <= 0 || *endptr != '\0') {
     358                                warnx("illegal number, -j argument -- %s",
     359                                    optarg);
     360                                usage();
     361                        }
    357362#ifndef REMOTE
    358                         maxLocal = maxJobs;
    359 #endif
    360                         Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
    361                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    362                         break;
    363                 }
    364                 case 'k':
    365                         keepgoing = TRUE;
    366                         Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
    367                         break;
    368                 case 'm':
    369                         Dir_AddDir(sysIncPath, optarg);
    370                         Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
    371                         Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
    372                         break;
    373                 case 'n':
    374                         noExecute = TRUE;
    375                         Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
    376                         break;
     363                        maxLocal = maxJobs;
     364#endif
     365                        Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
     366                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     367                        break;
     368                }
     369                case 'k':
     370                        keepgoing = TRUE;
     371                        Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
     372                        break;
     373                case 'm':
     374                        Dir_AddDir(sysIncPath, optarg);
     375                        Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
     376                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
     377                        break;
     378                case 'n':
     379                        noExecute = TRUE;
     380                        Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
     381                        break;
    377382#ifdef NMAKE
    378383                case 'o':
    379384                        go_to_objdir = TRUE;
    380                         Var_Append(MAKEFLAGS, "-o", VAR_GLOBAL);
    381                         break;
    382 #endif
    383                 case 'q':
    384                         queryFlag = TRUE;
    385                         /* Kind of nonsensical, wot? */
    386                         Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
    387                         break;
    388                 case 'r':
    389                         noBuiltins = TRUE;
    390                         Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
    391                         break;
    392                 case 's':
    393                         beSilent = TRUE;
    394                         Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
    395                         break;
    396                 case 't':
    397                         touchFlag = TRUE;
    398                         Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
    399                         break;
    400                 case 'v':
    401                         beVerbose = TRUE;
    402                         Var_Append(MAKEFLAGS, "-v", VAR_GLOBAL);
    403                         break;
    404                 default:
    405                 case '?':
    406                         usage();
    407                 }
    408         }
    409 
    410         oldVars = TRUE;
    411 
    412         /*
    413         * See if the rest of the arguments are variable assignments and
    414         * perform them if so. Else take them to be targets and stuff them
    415         * on the end of the "create" list.
    416         */
    417         for (argv += optind, argc -= optind; *argv; ++argv, --argc)
    418                 if (Parse_IsVar(*argv))
    419                         Parse_DoVar(*argv, VAR_CMD);
    420                 else {
    421                         if (!**argv)
    422                                 Punt("illegal (null) argument.");
    423                         if (**argv == '-') {
    424                                 if ((*argv)[1])
    425                                         optind = 0;     /* -flag... */
    426                                 else
    427                                         optind = 1;     /* - */
    428                                 goto rearg;
    429                         }
    430                         (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
    431                 }
     385                        Var_Append(MAKEFLAGS, "-o", VAR_GLOBAL);
     386                        break;
     387#endif
     388                case 'q':
     389                        queryFlag = TRUE;
     390                        /* Kind of nonsensical, wot? */
     391                        Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
     392                        break;
     393                case 'r':
     394                        noBuiltins = TRUE;
     395                        Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
     396                        break;
     397                case 's':
     398                        beSilent = TRUE;
     399                        Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
     400                        break;
     401                case 't':
     402                        touchFlag = TRUE;
     403                        Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
     404                        break;
     405                case 'v':
     406                        beVerbose = TRUE;
     407                        Var_Append(MAKEFLAGS, "-v", VAR_GLOBAL);
     408                        break;
     409                default:
     410                case '?':
     411                        usage();
     412                }
     413        }
     414
     415        oldVars = TRUE;
     416
     417        /*
     418        * See if the rest of the arguments are variable assignments and
     419        * perform them if so. Else take them to be targets and stuff them
     420        * on the end of the "create" list.
     421        */
     422        for (argv += optind, argc -= optind; *argv; ++argv, --argc)
     423                if (Parse_IsVar(*argv))
     424                        Parse_DoVar(*argv, VAR_CMD);
     425                else {
     426                        if (!**argv)
     427                                Punt("illegal (null) argument.");
     428                        if (**argv == '-') {
     429                                if ((*argv)[1])
     430                                        optind = 0;     /* -flag... */
     431                                else
     432                                        optind = 1;     /* - */
     433                                goto rearg;
     434                        }
     435                        (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
     436                }
    432437}
    433438
    434439/*-
    435440 * Main_ParseArgLine --
    436  *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
    437  *      is encountered and by main() when reading the .MAKEFLAGS envariable.
    438  *      Takes a line of arguments and breaks it into its
    439  *      component words and passes those words and the number of them to the
    440  *      MainParseArgs function.
    441  *      The line should have all its leading whitespace removed.
     441 *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
     442 *      is encountered and by main() when reading the .MAKEFLAGS envariable.
     443 *      Takes a line of arguments and breaks it into its
     444 *      component words and passes those words and the number of them to the
     445 *      MainParseArgs function.
     446 *      The line should have all its leading whitespace removed.
    442447 *
    443448 * Results:
    444  *      None
     449 *      None
    445450 *
    446451 * Side Effects:
    447  *      Only those that come from the various arguments.
     452 *      Only those that come from the various arguments.
    448453 */
    449454void
    450455Main_ParseArgLine(line)
    451         char *line;                     /* Line to fracture */
    452 {
    453         char **argv;                    /* Manufactured argument vector */
    454         int argc;                       /* Number of arguments in argv */
    455 
    456         if (line == NULL)
    457                 return;
    458         for (; *line == ' '; ++line)
    459                 continue;
    460         if (!*line)
    461                 return;
    462 
    463         argv = brk_string(line, &argc, TRUE);
    464         MainParseArgs(argc, argv);
     456        char *line;                     /* Line to fracture */
     457{
     458        char **argv;                    /* Manufactured argument vector */
     459        int argc;                       /* Number of arguments in argv */
     460
     461        if (line == NULL)
     462                return;
     463        for (; *line == ' '; ++line)
     464                continue;
     465        if (!*line)
     466                return;
     467
     468        argv = brk_string(line, &argc, TRUE);
     469        MainParseArgs(argc, argv);
    465470}
    466471
    467472char *
    468473chdir_verify_path(path, obpath)
    469         char *path;
    470         char *obpath;
     474        char *path;
     475        char *obpath;
    471476{
    472477        struct stat sb;
     
    476481#endif
    477482
    478         if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
    479                 if (chdir(path)) {
    480                         warn("warning: %s", path);
    481                         return 0;
    482                 }
    483                 else {
    484                         if (path[0] != '/') {
    485                                 (void) snprintf(obpath, MAXPATHLEN, "%s/%s",
    486                                                 curdir, path);
    487                                 return obpath;
    488                         }
    489                         else
    490                                 return path;
    491                 }
    492         }
    493 
    494         return 0;
     483        if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
     484                if (chdir(path)) {
     485                        warn("warning: %s", path);
     486                        return 0;
     487                }
     488                else {
     489                        if (path[0] != '/') {
     490                                (void) snprintf(obpath, MAXPATHLEN, "%s/%s",
     491                                                curdir, path);
     492                                return obpath;
     493                        }
     494                        else
     495                                return path;
     496                }
     497        }
     498
     499        return 0;
    495500}
    496501
     
    498503/*-
    499504 * main --
    500  *      The main function, for obvious reasons. Initializes variables
    501  *      and a few modules, then parses the arguments give it in the
    502  *      environment and on the command line. Reads the system makefile
    503  *      followed by either Makefile, makefile or the file given by the
    504  *      -f argument. Sets the .MAKEFLAGS PMake variable based on all the
    505  *      flags it has received by then uses either the Make or the Compat
    506  *      module to create the initial list of targets.
     505 *      The main function, for obvious reasons. Initializes variables
     506 *      and a few modules, then parses the arguments give it in the
     507 *      environment and on the command line. Reads the system makefile
     508 *      followed by either Makefile, makefile or the file given by the
     509 *      -f argument. Sets the .MAKEFLAGS PMake variable based on all the
     510 *      flags it has received by then uses either the Make or the Compat
     511 *      module to create the initial list of targets.
    507512 *
    508513 * Results:
    509  *      If -q was given, exits -1 if anything was out-of-date. Else it exits
    510  *      0.
     514 *      If -q was given, exits -1 if anything was out-of-date. Else it exits
     515 *      0.
    511516 *
    512517 * Side Effects:
    513  *      The program exits when done. Targets are created. etc. etc. etc.
     518 *      The program exits when done. Targets are created. etc. etc. etc.
    514519 */
    515520int
     
    519524main(argc, argv)
    520525#endif
    521         int argc;
    522         char **argv;
    523 {
    524         Lst targs;      /* target nodes to create -- passed to Make_Init */
    525         Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
    526         struct stat sa;
    527         char *p, *p1, *path, *pathp;
     526        int argc;
     527        char **argv;
     528{
     529        Lst targs;      /* target nodes to create -- passed to Make_Init */
     530        Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
     531        struct stat sa;
     532        char *p, *p1, *path, *pathp;
    528533#ifdef WANT_ENV_PWD
    529         struct stat sb;
    530         char *pwd;
    531 #endif
    532         char mdpath[MAXPATHLEN + 1];
    533         char obpath[MAXPATHLEN + 1];
    534         char cdpath[MAXPATHLEN + 1];
    535         char *machine = getenv("MACHINE");
    536         char *machine_arch = getenv("MACHINE_ARCH");
    537         char *machine_cpu = getenv("MACHINE_CPU");
    538         Lst sysMkPath;                  /* Path of sys.mk */
    539         char *cp = NULL, *start;
    540                                         /* avoid faults on read-only strings */
     534        struct stat sb;
     535        char *pwd;
     536#endif
     537        char mdpath[MAXPATHLEN + 1];
     538        char obpath[MAXPATHLEN + 1];
     539        char cdpath[MAXPATHLEN + 1];
     540        char *machine = getenv("MACHINE");
     541        char *machine_arch = getenv("MACHINE_ARCH");
     542        char *machine_cpu = getenv("MACHINE_CPU");
     543        Lst sysMkPath;                  /* Path of sys.mk */
     544        char *cp = NULL, *start;
     545                                        /* avoid faults on read-only strings */
    541546        #ifndef KMK
    542         static char syspath[] = _PATH_DEFSYSPATH;
     547        static char syspath[] = _PATH_DEFSYSPATH;
    543548        #endif
    544549
     550        #ifdef KMK
     551        /*
     552         * Save ourselfs.
     553         */
     554        argv0 = argv[0];
     555        #endif
     556
    545557#ifdef RLIMIT_NOFILE
    546         /*
    547         * get rid of resource limit on file descriptors
    548         */
    549         {
    550                 struct rlimit rl;
    551                 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
    552                     rl.rlim_cur != rl.rlim_max) {
    553                         rl.rlim_cur = rl.rlim_max;
    554                         (void) setrlimit(RLIMIT_NOFILE, &rl);
    555                 }
    556         }
    557 #endif
    558         /*
    559         * Find where we are and take care of PWD for the automounter...
    560         * All this code is so that we know where we are when we start up
    561         * on a different machine with pmake.
    562         */
    563         curdir = cdpath;
    564         if (getcwd(curdir, MAXPATHLEN) == NULL)
    565                 err(2, NULL);
    566 
    567         if (stat(curdir, &sa) == -1)
    568             err(2, "%s", curdir);
     558        /*
     559        * get rid of resource limit on file descriptors
     560        */
     561        {
     562                struct rlimit rl;
     563                if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
     564                    rl.rlim_cur != rl.rlim_max) {
     565                        rl.rlim_cur = rl.rlim_max;
     566                        (void) setrlimit(RLIMIT_NOFILE, &rl);
     567                }
     568        }
     569#endif
     570        /*
     571        * Find where we are and take care of PWD for the automounter...
     572        * All this code is so that we know where we are when we start up
     573        * on a different machine with pmake.
     574        */
     575        curdir = cdpath;
     576        if (getcwd(curdir, MAXPATHLEN) == NULL)
     577                err(2, NULL);
     578
     579        if (stat(curdir, &sa) == -1)
     580            err(2, "%s", curdir);
    569581
    570582#ifdef WANT_ENV_PWD
    571         if ((pwd = getenv("PWD")) != NULL) {
    572             if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
    573                 sa.st_dev == sb.st_dev)
    574                 (void) strcpy(curdir, pwd);
    575         }
     583        if ((pwd = getenv("PWD")) != NULL) {
     584            if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
     585                sa.st_dev == sb.st_dev)
     586                (void) strcpy(curdir, pwd);
     587        }
    576588#endif
    577589
    578590#if defined(__i386__) && defined(__FreeBSD_version) && \
    579591    __FreeBSD_version > 300003
    580         /*
    581         * PC-98 kernel sets the `i386' string to the utsname.machine and
    582         * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
    583         * we check machine.ispc98 and adjust the machine variable before
    584         * using usname(3) below.
    585         * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
    586         * __FreeBSD_version was defined as 300003. So, this check can
    587         * safely be done with any kernel with version > 300003.
    588         */
    589         if (!machine) {
    590                 int     ispc98;
    591                 size_t  len;
    592 
    593                 len = sizeof(ispc98);
    594                 if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
    595                         if (ispc98)
    596                                 machine = "pc98";
    597                 }
    598         }
    599 #endif
    600 
    601         /*
    602         * Get the name of this type of MACHINE from utsname
    603         * so we can share an executable for similar machines.
    604         * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
    605         *
    606         * Note that while MACHINE is decided at run-time,
    607         * MACHINE_ARCH is always known at compile time.
    608         */
    609         if (!machine) {
     592        /*
     593        * PC-98 kernel sets the `i386' string to the utsname.machine and
     594        * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
     595        * we check machine.ispc98 and adjust the machine variable before
     596        * using usname(3) below.
     597        * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
     598        * __FreeBSD_version was defined as 300003. So, this check can
     599        * safely be done with any kernel with version > 300003.
     600        */
     601        if (!machine) {
     602                int     ispc98;
     603                size_t  len;
     604
     605                len = sizeof(ispc98);
     606                if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
     607                        if (ispc98)
     608                                machine = "pc98";
     609                }
     610        }
     611#endif
     612
     613        /*
     614        * Get the name of this type of MACHINE from utsname
     615        * so we can share an executable for similar machines.
     616        * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
     617        *
     618        * Note that while MACHINE is decided at run-time,
     619        * MACHINE_ARCH is always known at compile time.
     620        */
     621        if (!machine) {
    610622#ifndef MACHINE
    611             struct utsname utsname;
    612 
    613             if (uname(&utsname) == -1) {
    614                     perror(MAKE_NAME ": uname");
    615                     exit(2);
    616             }
    617             machine = utsname.machine;
    618 #else
    619             machine = MACHINE;
    620 #endif
    621         }
    622 
    623         if (!machine_arch) {
     623            struct utsname utsname;
     624
     625            if (uname(&utsname) == -1) {
     626                    perror(MAKE_NAME ": uname");
     627                    exit(2);
     628            }
     629            machine = utsname.machine;
     630#else
     631            machine = MACHINE;
     632#endif
     633        }
     634
     635        if (!machine_arch) {
    624636#ifndef MACHINE_ARCH
    625                 machine_arch = "unknown";
    626 #else
    627                 machine_arch = MACHINE_ARCH;
    628 #endif
    629         }
    630 
    631         /*
    632         * Set machine_cpu to the minumum supported CPU revision based
    633         * on the target architecture, if not already set.
    634         */
    635         if (!machine_cpu) {
    636                 if (!strcmp(machine_arch, "i386"))
    637                         machine_cpu = "i386";
    638                 else if (!strcmp(machine_arch, "alpha"))
    639                         machine_cpu = "ev4";
    640                 else
    641                         machine_cpu = "unknown";
    642         }
    643        
     637                machine_arch = "unknown";
     638#else
     639                machine_arch = MACHINE_ARCH;
     640#endif
     641        }
     642
     643        /*
     644        * Set machine_cpu to the minumum supported CPU revision based
     645        * on the target architecture, if not already set.
     646        */
     647        if (!machine_cpu) {
     648                if (!strcmp(machine_arch, "i386"))
     649                        machine_cpu = "i386";
     650                else if (!strcmp(machine_arch, "alpha"))
     651                        machine_cpu = "ev4";
     652                else
     653                        machine_cpu = "unknown";
     654        }
     655
    644656        #ifdef KMK
    645657        /* @todo figure out how to set object directory! */
    646658        #else
    647         /*
    648         * The object directory location is determined using the
    649         * following order of preference:
    650         *
    651          *      1. MAKEOBJDIRPREFIX`cwd`
    652          *      2. MAKEOBJDIR
    653          *      3. _PATH_OBJDIR.${MACHINE}
    654          *      4. _PATH_OBJDIR
    655          *      5. _PATH_OBJDIRPREFIX`cwd`
    656         *
    657         * If one of the first two fails, use the current directory.
    658         * If the remaining three all fail, use the current directory.
    659         *
    660         * Once things are initted,
    661         * have to add the original directory to the search path,
    662         * and modify the paths for the Makefiles apropriately.  The
    663         * current directory is also placed as a variable for make scripts.
    664         */
    665         if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
    666                 if (!(path = getenv("MAKEOBJDIR"))) {
    667                         path = _PATH_OBJDIR;
    668                         pathp = _PATH_OBJDIRPREFIX;
    669                         (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
    670                                         path, machine);
    671                         if (!(objdir = chdir_verify_path(mdpath, obpath)))
    672                                 if (!(objdir=chdir_verify_path(path, obpath))) {
    673                                         (void) snprintf(mdpath, MAXPATHLEN,
    674                                                         "%s%s", pathp, curdir);
    675                                         if (!(objdir=chdir_verify_path(mdpath,
    676                                                                        obpath)))
    677                                                 objdir = curdir;
    678                                 }
    679                 }
    680                 else if (!(objdir = chdir_verify_path(path, obpath)))
    681                         objdir = curdir;
    682         }
    683         else {
    684                 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
    685                 if (!(objdir = chdir_verify_path(mdpath, obpath)))
    686                         objdir = curdir;
    687         }
     659        /*
     660        * The object directory location is determined using the
     661        * following order of preference:
     662        *
     663         *      1. MAKEOBJDIRPREFIX`cwd`
     664         *      2. MAKEOBJDIR
     665         *      3. _PATH_OBJDIR.${MACHINE}
     666         *      4. _PATH_OBJDIR
     667         *      5. _PATH_OBJDIRPREFIX`cwd`
     668        *
     669        * If one of the first two fails, use the current directory.
     670        * If the remaining three all fail, use the current directory.
     671        *
     672        * Once things are initted,
     673        * have to add the original directory to the search path,
     674        * and modify the paths for the Makefiles apropriately.  The
     675        * current directory is also placed as a variable for make scripts.
     676        */
     677        if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
     678                if (!(path = getenv("MAKEOBJDIR"))) {
     679                        path = _PATH_OBJDIR;
     680                        pathp = _PATH_OBJDIRPREFIX;
     681                        (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
     682                                        path, machine);
     683                        if (!(objdir = chdir_verify_path(mdpath, obpath)))
     684                                if (!(objdir=chdir_verify_path(path, obpath))) {
     685                                        (void) snprintf(mdpath, MAXPATHLEN,
     686                                                        "%s%s", pathp, curdir);
     687                                        if (!(objdir=chdir_verify_path(mdpath,
     688                                                                       obpath)))
     689                                                objdir = curdir;
     690                                }
     691                }
     692                else if (!(objdir = chdir_verify_path(path, obpath)))
     693                        objdir = curdir;
     694        }
     695        else {
     696                (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
     697                if (!(objdir = chdir_verify_path(mdpath, obpath)))
     698                        objdir = curdir;
     699        }
    688700        #endif
    689701
    690702#ifdef WANT_ENV_PWD
    691703        #ifdef USE_KLIB
    692         kEnvSet("PWD", objdir);
     704        kEnvSet("PWD", objdir);
    693705        #else
    694         setenv("PWD", objdir, 1);
     706        setenv("PWD", objdir, 1);
    695707        #endif
    696708#endif
    697709
    698         create = Lst_Init(FALSE);
    699         makefiles = Lst_Init(FALSE);
    700         envFirstVars = Lst_Init(FALSE);
    701         printVars = FALSE;
    702         expandVars = TRUE;
    703         variables = Lst_Init(FALSE);
    704         beSilent = FALSE;               /* Print commands as executed */
    705         ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
    706         noExecute = FALSE;              /* Execute all commands */
    707         keepgoing = FALSE;              /* Stop on error */
    708         allPrecious = FALSE;            /* Remove targets when interrupted */
    709         queryFlag = FALSE;              /* This is not just a check-run */
    710         noBuiltins = FALSE;             /* Read the built-in rules */
    711         touchFlag = FALSE;              /* Actually update targets */
    712         usePipes = TRUE;                /* Catch child output in pipes */
    713         debug = 0;                      /* No debug verbosity, please. */
    714         jobsRunning = FALSE;
     710        create = Lst_Init(FALSE);
     711        makefiles = Lst_Init(FALSE);
     712        envFirstVars = Lst_Init(FALSE);
     713        printVars = FALSE;
     714        expandVars = TRUE;
     715        variables = Lst_Init(FALSE);
     716        beSilent = FALSE;               /* Print commands as executed */
     717        ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
     718        noExecute = FALSE;              /* Execute all commands */
     719        keepgoing = FALSE;              /* Stop on error */
     720        allPrecious = FALSE;            /* Remove targets when interrupted */
     721        queryFlag = FALSE;              /* This is not just a check-run */
     722        noBuiltins = FALSE;             /* Read the built-in rules */
     723        touchFlag = FALSE;              /* Actually update targets */
     724#ifdef USE_PIPES
     725        usePipes = TRUE;                /* Catch child output in pipes */
     726#else
     727        usePipes = FALSE;               /* Don't catch child output in pipes if multiple wait isn't supported */
     728#endif
     729        debug = 0;                      /* No debug verbosity, please. */
     730        jobsRunning = FALSE;
    715731#ifdef NMAKE
    716         go_to_objdir = FALSE;
    717 #endif
    718 
    719         maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
     732        go_to_objdir = FALSE;
     733#endif
     734
     735        maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
    720736#ifdef REMOTE
    721         maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
    722 #else
    723         maxJobs = maxLocal;
    724 #endif
    725         forceJobs = FALSE;              /* No -j flag */
    726         compatMake = FALSE;             /* No compat mode */
    727 
    728 
    729         /*
    730         * Initialize the parsing, directory and variable modules to prepare
    731         * for the reading of inclusion paths and variable settings on the
    732         * command line
    733         */
    734         Dir_Init();             /* Initialize directory structures so -I flags
    735                                 * can be processed correctly */
    736         Parse_Init();           /* Need to initialize the paths of #include
    737                                 * directories */
    738         Var_Init();             /* As well as the lists of variables for
    739                                 * parsing arguments */
     737        maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
     738#else
     739        maxJobs = maxLocal;
     740#endif
     741        forceJobs = FALSE;              /* No -j flag */
     742        compatMake = FALSE;             /* No compat mode */
     743
     744
     745        /*
     746        * Initialize the parsing, directory and variable modules to prepare
     747        * for the reading of inclusion paths and variable settings on the
     748        * command line
     749        */
     750        Dir_Init();             /* Initialize directory structures so -I flags
     751                                * can be processed correctly */
     752        Parse_Init();           /* Need to initialize the paths of #include
     753                                * directories */
     754        Var_Init();             /* As well as the lists of variables for
     755                                * parsing arguments */
    740756        str_init();
    741         if (objdir != curdir)
    742                 Dir_AddDir(dirSearchPath, curdir);
    743         Var_Set(".CURDIR", curdir, VAR_GLOBAL);
    744         Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
    745 
    746         /*
    747         * Initialize various variables.
    748          *      MAKE also gets this name, for compatibility
    749          *      .MAKEFLAGS gets set to the empty string just in case.
    750          *      MFLAGS also gets initialized empty, for compatibility.
    751         */
    752         Var_Set("MAKE", argv[0], VAR_GLOBAL);
    753         Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
    754         Var_Set("MFLAGS", "", VAR_GLOBAL);
    755         Var_Set("MACHINE", machine, VAR_GLOBAL);
    756         Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
    757         Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
    758 
    759         /*
    760         * First snag any flags out of the MAKE environment variable.
    761         * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
    762         * in a different format).
    763         */
     757        if (objdir != curdir)
     758                Dir_AddDir(dirSearchPath, curdir);
     759        Var_Set(".CURDIR", curdir, VAR_GLOBAL);
     760        Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
     761
     762        /*
     763        * Initialize various variables.
     764         *      MAKE also gets this name, for compatibility
     765         *      .MAKEFLAGS gets set to the empty string just in case.
     766         *      MFLAGS also gets initialized empty, for compatibility.
     767        */
     768        Var_Set("MAKE", argv[0], VAR_GLOBAL);
     769        Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
     770        Var_Set("MFLAGS", "", VAR_GLOBAL);
     771        Var_Set("MACHINE", machine, VAR_GLOBAL);
     772        Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
     773        Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
     774
     775        /*
     776        * First snag any flags out of the MAKE environment variable.
     777        * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
     778        * in a different format).
     779        */
    764780#ifdef POSIX
    765         Main_ParseArgLine(getenv("MAKEFLAGS"));
    766 #else
    767         Main_ParseArgLine(getenv("MAKE"));
    768 #endif
    769 
    770         MainParseArgs(argc, argv);
    771 
    772         /*
    773          * Be compatible if user did not specify -j and did not explicitly
    774          * turned compatibility on
    775          */
    776         if (!compatMake && !forceJobs)
    777                 compatMake = TRUE;
    778 
    779         /*
    780          * Initialize archive, target and suffix modules in preparation for
    781          * parsing the makefile(s)
    782          */
     781        Main_ParseArgLine(getenv("MAKEFLAGS"));
     782#else
     783        Main_ParseArgLine(getenv("MAKE"));
     784#endif
     785
     786#ifdef KMK
     787        /*
     788         * Completely ignore the tool argument.
     789         */
     790        if (argc > 1 && !kStrCmp(argv[1], "--kMk"))
     791        {
     792            argc--;
     793            argv++;
     794        }
     795#endif
     796        MainParseArgs(argc, argv);
     797
     798        /*
     799         * Be compatible if user did not specify -j and did not explicitly
     800         * turned compatibility on
     801         */
     802        if (!compatMake && !forceJobs)
     803                compatMake = TRUE;
     804
     805        /*
     806         * Initialize archive, target and suffix modules in preparation for
     807         * parsing the makefile(s)
     808         */
    783809#ifdef USE_ARCHIVES
    784         Arch_Init();
    785 #endif
    786         Targ_Init();
    787         Suff_Init();
    788 
    789         DEFAULT = NILGNODE;
    790         (void)time(&now);
    791 
    792         /*
    793         * Set up the .TARGETS variable to contain the list of targets to be
    794         * created. If none specified, make the variable empty -- the parser
    795         * will fill the thing in with the default or .MAIN target.
    796         */
    797         if (!Lst_IsEmpty(create)) {
    798                 LstNode ln;
    799 
    800                 for (ln = Lst_First(create); ln != NILLNODE;
    801                     ln = Lst_Succ(ln)) {
    802                         char *name = (char *)Lst_Datum(ln);
    803 
    804                         Var_Append(".TARGETS", name, VAR_GLOBAL);
    805                 }
    806         } else
    807                 Var_Set(".TARGETS", "", VAR_GLOBAL);
     810        Arch_Init();
     811#endif
     812        Targ_Init();
     813        Suff_Init();
     814
     815        DEFAULT = NILGNODE;
     816        (void)time(&now);
     817
     818        /*
     819        * Set up the .TARGETS variable to contain the list of targets to be
     820        * created. If none specified, make the variable empty -- the parser
     821        * will fill the thing in with the default or .MAIN target.
     822        */
     823        if (!Lst_IsEmpty(create)) {
     824                LstNode ln;
     825
     826                for (ln = Lst_First(create); ln != NILLNODE;
     827                    ln = Lst_Succ(ln)) {
     828                        char *name = (char *)Lst_Datum(ln);
     829
     830                        Var_Append(".TARGETS", name, VAR_GLOBAL);
     831                }
     832        } else
     833                Var_Set(".TARGETS", "", VAR_GLOBAL);
    808834
    809835
    810836        #ifdef KMK
    811         /*
    812         * Add current directory tree to system include path all levels up to the root.
     837        /*
     838        * Add current directory tree to system include path all levels up to the root.
    813839         * ASSUMES that curdir is absolute.
    814         */
     840        */
    815841        {
    816842            char *  psz = estrdup(curdir);
     
    834860
    835861        #else
    836         /*
    837         * If no user-supplied system path was given (through the -m option)
    838         * add the directories from the DEFSYSPATH (more than one may be given
    839         * as dir1:...:dirn) to the system include path.
    840         */
    841         if (Lst_IsEmpty(sysIncPath)) {
    842                 for (start = syspath; *start != '\0'; start = cp) {
    843                         for (cp = start; *cp != '\0' && *cp != ':'; cp++)
    844                                 continue;
    845                         if (*cp == '\0') {
    846                                 Dir_AddDir(sysIncPath, start);
    847                         } else {
    848                                 *cp++ = '\0';
    849                                 Dir_AddDir(sysIncPath, start);
    850                         }
    851                 }
    852         }
     862        /*
     863        * If no user-supplied system path was given (through the -m option)
     864        * add the directories from the DEFSYSPATH (more than one may be given
     865        * as dir1:...:dirn) to the system include path.
     866        */
     867        if (Lst_IsEmpty(sysIncPath)) {
     868                for (start = syspath; *start != '\0'; start = cp) {
     869                        for (cp = start; *cp != '\0' && *cp != ':'; cp++)
     870                                continue;
     871                        if (*cp == '\0') {
     872                                Dir_AddDir(sysIncPath, start);
     873                        } else {
     874                                *cp++ = '\0';
     875                                Dir_AddDir(sysIncPath, start);
     876                        }
     877                }
     878        }
    853879        #endif
    854880
    855         /*
    856         * Read in the built-in rules first, followed by the specified
    857         * makefile, if it was (makefile != (char *) NULL), or the default
    858         * Makefile and makefile, in that order, if it wasn't.
    859         */
    860         if (!noBuiltins) {
    861                 LstNode ln;
    862 
    863                 sysMkPath = Lst_Init (FALSE);
    864                 Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
     881        /*
     882        * Read in the built-in rules first, followed by the specified
     883        * makefile, if it was (makefile != (char *) NULL), or the default
     884        * Makefile and makefile, in that order, if it wasn't.
     885        */
     886        if (!noBuiltins) {
     887                LstNode ln;
     888
     889                sysMkPath = Lst_Init (FALSE);
     890                Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
    865891#ifdef NMAKE
    866                 if (!Lst_IsEmpty(sysMkPath))
     892                if (!Lst_IsEmpty(sysMkPath))
    867893                {
    868894                    ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
     
    872898
    873899#elif defined(KMK)
    874                 if (!Lst_IsEmpty(sysMkPath))
     900                if (!Lst_IsEmpty(sysMkPath))
    875901                {
    876902                    ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
     
    879905
    880906                }
    881                 Error(MAKE_NAME ": no config rules (%s).", _PATH_DEFSYSMK);
    882 #else
    883                 if (Lst_IsEmpty(sysMkPath))
    884                         Fatal(MAKE_NAME ": no system rules (%s).", _PATH_DEFSYSMK);
    885                 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
    886                 if (ln != NILLNODE)
    887                         Fatal(MAKE_NAME ": cannot open %s.", (char *)Lst_Datum(ln));
    888 #endif
    889         }
    890 
    891         if (!Lst_IsEmpty(makefiles)) {
    892                 LstNode ln;
    893 
    894                 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
    895                 if (ln != NILLNODE)
    896                         Fatal(MAKE_NAME ": cannot open %s.", (char *)Lst_Datum(ln));
    897         } else
     907                Error(MAKE_NAME ": no config rules (%s).", _PATH_DEFSYSMK);
     908#else
     909                if (Lst_IsEmpty(sysMkPath))
     910                        Fatal(MAKE_NAME ": no system rules (%s).", _PATH_DEFSYSMK);
     911                ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
     912                if (ln != NILLNODE)
     913                        Fatal(MAKE_NAME ": cannot open %s.", (char *)Lst_Datum(ln));
     914#endif
     915        }
     916
     917        if (!Lst_IsEmpty(makefiles)) {
     918                LstNode ln;
     919
     920                ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
     921                if (ln != NILLNODE)
     922                        Fatal(MAKE_NAME ": cannot open %s.", (char *)Lst_Datum(ln));
     923        } else
    898924            #ifdef KMK
    899925            if (    !ReadMakefile("Makefile.kMk", NULL)
     
    911937            #endif
    912938
    913         (void)ReadMakefile(".depend", NULL);
    914 
    915         Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
    916         efree(p1);
    917 
    918         /* Install all the flags into the MAKE envariable. */
    919         if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
     939        (void)ReadMakefile(".depend", NULL);
     940
     941        Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
     942        efree(p1);
     943
     944        /* Install all the flags into the MAKE envariable. */
     945        if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
    920946#ifdef POSIX
    921947                #ifdef USE_KLIB
    922948                kEnvSet("MAKEFLAGS", p, TRUE);
    923949                #else
    924                 setenv("MAKEFLAGS", p, 1);
     950                setenv("MAKEFLAGS", p, 1);
    925951                #endif
    926952#else
    927953                #ifdef USE_KLIB
    928                 kEnvSet("MAKE", p, TRUE);
     954                kEnvSet("MAKE", p, TRUE);
    929955                #else
    930                 setenv("MAKE", p, 1);
     956                setenv("MAKE", p, 1);
    931957                #endif
    932958#endif
    933         efree(p1);
    934 
    935         /*
    936         * For compatibility, look at the directories in the VPATH variable
    937         * and add them to the search path, if the variable is defined. The
    938         * variable's value is in the same format as the PATH envariable, i.e.
    939         * <directory>:<directory>:<directory>...
    940         */
    941         if (Var_Exists("VPATH", VAR_CMD)) {
    942                 char *vpath, *path, *cp, savec;
    943                 /*
    944                 * GCC stores string constants in read-only memory, but
    945                 * Var_Subst will want to write this thing, so store it
    946                 * in an array
    947                 */
    948                 static char VPATH[] = "${VPATH}";
    949 
    950                 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
    951                 path = vpath;
    952                 do {
    953                         /* skip to end of directory */
    954                         for (cp = path; *cp != ':' && *cp != '\0'; cp++)
    955                                 continue;
    956                         /* Save terminator character so know when to stop */
    957                         savec = *cp;
    958                         *cp = '\0';
    959                         /* Add directory to search path */
    960                         Dir_AddDir(dirSearchPath, path);
    961                         *cp = savec;
    962                         path = cp + 1;
    963                 } while (savec == ':');
    964                 (void)efree((Address)vpath);
    965         }
    966 
    967         /*
    968         * Now that all search paths have been read for suffixes et al, it's
    969         * time to add the default search path to their lists...
    970         */
    971         Suff_DoPaths();
    972 
    973         /* print the initial graph, if the user requested it */
    974         if (DEBUG(GRAPH1))
    975                 Targ_PrintGraph(1);
    976 
    977         /* print the values of any variables requested by the user */
    978         if (printVars) {
    979                 LstNode ln;
    980 
    981                 for (ln = Lst_First(variables); ln != NILLNODE;
    982                     ln = Lst_Succ(ln)) {
    983                         char *value;
    984                         if (expandVars) {
    985                                 p1 = emalloc(strlen((char *)Lst_Datum(ln)) + 1 + 3);
    986                                 /* This sprintf is safe, because of the malloc above */
    987                                 (void)sprintf(p1, "${%s}", (char *)Lst_Datum(ln));
    988                                 value = Var_Subst(NULL, p1, VAR_GLOBAL, FALSE);
    989                         } else {
    990                                 value = Var_Value((char *)Lst_Datum(ln),
    991                                                   VAR_GLOBAL, &p1);
    992                         }
    993                         printf("%s\n", value ? value : "");
    994                         if (p1)
    995                                 efree(p1);
    996                 }
    997         }
    998 
    999         /*
    1000         * Have now read the entire graph and need to make a list of targets
    1001         * to create. If none was given on the command line, we consult the
    1002         * parsing module to find the main target(s) to create.
    1003         */
    1004         if (Lst_IsEmpty(create))
    1005                 targs = Parse_MainName();
    1006         else
    1007                 targs = Targ_FindList(create, TARG_CREATE);
    1008 
    1009         if (!compatMake && !printVars) {
    1010                 /*
    1011                 * Initialize job module before traversing the graph, now that
    1012                 * any .BEGIN and .END targets have been read.  This is done
    1013                 * only if the -q flag wasn't given (to prevent the .BEGIN from
    1014                 * being executed should it exist).
    1015                 */
    1016                 if (!queryFlag) {
    1017                         if (maxLocal == -1)
    1018                                 maxLocal = maxJobs;
    1019                         Job_Init(maxJobs, maxLocal);
    1020                         jobsRunning = TRUE;
    1021                 }
    1022 
    1023                 /* Traverse the graph, checking on all the targets */
    1024                 outOfDate = Make_Run(targs);
    1025         } else if (!printVars) {
    1026                 /*
    1027                 * Compat_Init will take care of creating all the targets as
    1028                 * well as initializing the module.
    1029                 */
    1030                 Compat_Run(targs);
    1031         }
    1032 
    1033         Lst_Destroy(targs, NOFREE);
    1034         Lst_Destroy(variables, NOFREE);
    1035         Lst_Destroy(makefiles, NOFREE);
    1036         Lst_Destroy(create, (void (*) __P((ClientData))) efree);
    1037 
    1038         /* print the graph now it's been processed if the user requested it */
    1039         if (DEBUG(GRAPH2))
    1040                 Targ_PrintGraph(2);
    1041 
    1042         Suff_End();
     959        efree(p1);
     960
     961        /*
     962        * For compatibility, look at the directories in the VPATH variable
     963        * and add them to the search path, if the variable is defined. The
     964        * variable's value is in the same format as the PATH envariable, i.e.
     965        * <directory>:<directory>:<directory>...
     966        */
     967        if (Var_Exists("VPATH", VAR_CMD)) {
     968                char *vpath, *path, *cp, savec;
     969                /*
     970                * GCC stores string constants in read-only memory, but
     971                * Var_Subst will want to write this thing, so store it
     972                * in an array
     973                */
     974                static char VPATH[] = "${VPATH}";
     975
     976                vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
     977                path = vpath;
     978                do {
     979                        /* skip to end of directory */
     980                        for (cp = path; *cp != ':' && *cp != '\0'; cp++)
     981                                continue;
     982                        /* Save terminator character so know when to stop */
     983                        savec = *cp;
     984                        *cp = '\0';
     985                        /* Add directory to search path */
     986                        Dir_AddDir(dirSearchPath, path);
     987                        *cp = savec;
     988                        path = cp + 1;
     989                } while (savec == ':');
     990                (void)efree((Address)vpath);
     991        }
     992
     993        /*
     994        * Now that all search paths have been read for suffixes et al, it's
     995        * time to add the default search path to their lists...
     996        */
     997        Suff_DoPaths();
     998
     999        /* print the initial graph, if the user requested it */
     1000        if (DEBUG(GRAPH1))
     1001                Targ_PrintGraph(1);
     1002
     1003        /* print the values of any variables requested by the user */
     1004        if (printVars) {
     1005                LstNode ln;
     1006
     1007                for (ln = Lst_First(variables); ln != NILLNODE;
     1008                    ln = Lst_Succ(ln)) {
     1009                        char *value;
     1010                        if (expandVars) {
     1011                                p1 = emalloc(strlen((char *)Lst_Datum(ln)) + 1 + 3);
     1012                                /* This sprintf is safe, because of the malloc above */
     1013                                (void)sprintf(p1, "${%s}", (char *)Lst_Datum(ln));
     1014                                value = Var_Subst(NULL, p1, VAR_GLOBAL, FALSE);
     1015                        } else {
     1016                                value = Var_Value((char *)Lst_Datum(ln),
     1017                                                  VAR_GLOBAL, &p1);
     1018                        }
     1019                        printf("%s\n", value ? value : "");
     1020                        if (p1)
     1021                                efree(p1);
     1022                }
     1023        }
     1024
     1025        /*
     1026        * Have now read the entire graph and need to make a list of targets
     1027        * to create. If none was given on the command line, we consult the
     1028        * parsing module to find the main target(s) to create.
     1029        */
     1030        if (Lst_IsEmpty(create))
     1031                targs = Parse_MainName();
     1032        else
     1033                targs = Targ_FindList(create, TARG_CREATE);
     1034
     1035        if (!compatMake && !printVars) {
     1036                /*
     1037                * Initialize job module before traversing the graph, now that
     1038                * any .BEGIN and .END targets have been read.  This is done
     1039                * only if the -q flag wasn't given (to prevent the .BEGIN from
     1040                * being executed should it exist).
     1041                */
     1042                if (!queryFlag) {
     1043                        if (maxLocal == -1)
     1044                                maxLocal = maxJobs;
     1045                        Job_Init(maxJobs, maxLocal);
     1046                        jobsRunning = TRUE;
     1047                }
     1048
     1049                /* Traverse the graph, checking on all the targets */
     1050                outOfDate = Make_Run(targs);
     1051        } else if (!printVars) {
     1052                /*
     1053                * Compat_Init will take care of creating all the targets as
     1054                * well as initializing the module.
     1055                */
     1056                Compat_Run(targs);
     1057        }
     1058
     1059        Lst_Destroy(targs, NOFREE);
     1060        Lst_Destroy(variables, NOFREE);
     1061        Lst_Destroy(makefiles, NOFREE);
     1062        Lst_Destroy(create, (void (*) __P((ClientData))) efree);
     1063
     1064        /* print the graph now it's been processed if the user requested it */
     1065        if (DEBUG(GRAPH2))
     1066                Targ_PrintGraph(2);
     1067
     1068        Suff_End();
    10431069        Targ_End();
    10441070#ifdef USE_ARCHIVES
    1045         Arch_End();
    1046 #endif
    1047         str_end();
    1048         Var_End();
    1049         Parse_End();
    1050         Dir_End();
    1051 
    1052         if (queryFlag && outOfDate)
    1053                 return(1);
    1054         else
    1055                 return(0);
     1071        Arch_End();
     1072#endif
     1073        str_end();
     1074        Var_End();
     1075        Parse_End();
     1076        Dir_End();
     1077
     1078        if (queryFlag && outOfDate)
     1079                return(1);
     1080        else
     1081                return(0);
    10561082}
    10571083
    10581084/*-
    10591085 * ReadMakefile  --
    1060  *      Open and parse the given makefile.
     1086 *      Open and parse the given makefile.
    10611087 *
    10621088 * Results:
    1063  *      TRUE if ok. FALSE if couldn't open file.
     1089 *      TRUE if ok. FALSE if couldn't open file.
    10641090 *
    10651091 * Side Effects:
    1066  *      lots
     1092 *      lots
    10671093 */
    10681094static Boolean
    10691095ReadMakefile(p, q)
    1070         ClientData p, q;
    1071 {
    1072         char *fname = p;                /* makefile to read */
    1073         extern Lst parseIncPath;
    1074         FILE *stream;
    1075         char *name, path[MAXPATHLEN + 1];
    1076         char *MAKEFILE;
    1077         int setMAKEFILE;
    1078 
    1079         if (!strcmp(fname, "-")) {
    1080                 Parse_File("(stdin)", stdin);
    1081                 Var_Set("MAKEFILE", "", VAR_GLOBAL);
    1082         } else {
    1083                 setMAKEFILE = strcmp(fname, ".depend");
    1084 
    1085                 /* if we've chdir'd, rebuild the path name */
    1086                 if (curdir != objdir && *fname != '/') {
    1087                         (void)snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
    1088                         if (realpath(path, path) != NULL &&
    1089                             (stream = fopen(path, "r")) != NULL) {
    1090                                 MAKEFILE = fname;
    1091                                 fname = path;
    1092                                 goto found;
    1093                         }
    1094                 } else if (realpath(fname, path) != NULL) {
    1095                         MAKEFILE = fname;
    1096                         fname = path;
    1097                         if ((stream = fopen(fname, "r")) != NULL)
    1098                                 goto found;
    1099                 }
    1100                 /* look in -I and system include directories. */
    1101                 name = Dir_FindFile(fname, parseIncPath);
    1102                 if (!name)
    1103                         name = Dir_FindFile(fname, sysIncPath);
    1104                 if (!name || !(stream = fopen(name, "r")))
    1105                         return(FALSE);
    1106                 MAKEFILE = fname = name;
    1107                 /*
    1108                 * set the MAKEFILE variable desired by System V fans -- the
    1109                 * placement of the setting here means it gets set to the last
    1110                 * makefile specified, as it is set by SysV make.
    1111                 */
     1096        ClientData p, q;
     1097{
     1098        char *fname = p;                /* makefile to read */
     1099        extern Lst parseIncPath;
     1100        FILE *stream;
     1101        char *name, path[MAXPATHLEN + 1];
     1102        char *MAKEFILE;
     1103        int setMAKEFILE;
     1104
     1105        if (!strcmp(fname, "-")) {
     1106                Parse_File("(stdin)", stdin);
     1107                Var_Set("MAKEFILE", "", VAR_GLOBAL);
     1108        } else {
     1109                setMAKEFILE = strcmp(fname, ".depend");
     1110
     1111                /* if we've chdir'd, rebuild the path name */
     1112                if (curdir != objdir && *fname != '/') {
     1113                        (void)snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
     1114                        if (realpath(path, path) != NULL &&
     1115                            (stream = fopen(path, "r")) != NULL) {
     1116                                MAKEFILE = fname;
     1117                                fname = path;
     1118                                goto found;
     1119                        }
     1120                } else if (realpath(fname, path) != NULL) {
     1121                        MAKEFILE = fname;
     1122                        fname = path;
     1123                        if ((stream = fopen(fname, "r")) != NULL)
     1124                                goto found;
     1125                }
     1126                /* look in -I and system include directories. */
     1127                name = Dir_FindFile(fname, parseIncPath);
     1128                if (!name)
     1129                        name = Dir_FindFile(fname, sysIncPath);
     1130                if (!name || !(stream = fopen(name, "r")))
     1131                        return(FALSE);
     1132                MAKEFILE = fname = name;
     1133                /*
     1134                * set the MAKEFILE variable desired by System V fans -- the
     1135                * placement of the setting here means it gets set to the last
     1136                * makefile specified, as it is set by SysV make.
     1137                */
    11121138found:
    1113                 if (setMAKEFILE)
    1114                         Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
    1115                 Parse_File(fname, stream);
    1116                 (void)fclose(stream);
    1117         }
    1118         return(TRUE);
     1139                if (setMAKEFILE)
     1140                        Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
     1141                Parse_File(fname, stream);
     1142                (void)fclose(stream);
     1143        }
     1144        return(TRUE);
    11191145}
    11201146
    11211147/*-
    11221148 * Cmd_Exec --
    1123  *      Execute the command in cmd, and return the output of that command
    1124  *      in a string.
     1149 *      Execute the command in cmd, and return the output of that command
     1150 *      in a string.
    11251151 *
    11261152 * Results:
    1127  *      A string containing the output of the command, or the empty string
    1128  *      If err is not NULL, it contains the reason for the command failure
     1153 *      A string containing the output of the command, or the empty string
     1154 *      If err is not NULL, it contains the reason for the command failure
    11291155 *
    11301156 * Side Effects:
    1131  *      The string must be freed by the caller.
     1157 *      The string must be freed by the caller.
    11321158 */
    11331159char *
     
    11361162    char **err;
    11371163{
    1138     char        *args[4];       /* Args for invoking the shell */
    1139     int         fds[2];         /* Pipe streams */
    1140     int         cpid;           /* Child PID */
    1141     int         pid;            /* PID from wait() */
    1142     char        *res;           /* result */
    1143     int         status;         /* command exit status */
    1144     Buffer      buf;            /* buffer to store the result */
    1145     char        *cp;
    1146     int         cc;
     1164#ifdef KMK
     1165    /** @todo this can be executed directly in the shell!!!
     1166     */
     1167    int         rc;
     1168    char *      args[4];                /* Args for invoking the shell */
     1169    KFILE       fhPipe;                 /* Pipe handle. */
     1170    KPID        cpid;                   /* Child PID */
     1171    KPROCRES    status;                 /* Child exit status. */
     1172    char *      res;                    /* result */
     1173    Buffer      buf;                    /* buffer to store the result */
     1174    char *      cp;
     1175    int         cc;
     1176
     1177
     1178    *err = NULL;
     1179
     1180    /*
     1181     * Set up arguments for shell
     1182     */
     1183    args[0] = argv0;
     1184    args[1] = "--kShell";
     1185    args[2] = cmd;
     1186    args[3] = NULL;
     1187
     1188
     1189    /*
     1190     * Execute command in pipe.
     1191     */
     1192    rc = kProcPiped(&args[0],
     1193                    KPROCPIPED_FLAGS_STDOUT,
     1194                    &cpid,
     1195                    &fhPipe);
     1196    if (!rc)
     1197    {
     1198        FILE *phPipe;
     1199        buf = Buf_Init (MAKE_BSIZE);
     1200
     1201        /*
     1202         * Read the output using a file stream for automatic '\n' newline conv.
     1203         */
     1204        phPipe = fdopen(fhPipe, "r");
     1205        cc = -1;
     1206        if (phPipe)
     1207        {
     1208            do {
     1209                char   result[BUFSIZ];
     1210                cc = fread(result, 1, sizeof(result), phPipe);
     1211                if (cc > 0)
     1212                    Buf_AddBytes(buf, cc, (Byte *) result);
     1213            }
     1214            while (cc > 0 || (cc == -1 && errno == EINTR));
     1215            fclose(phPipe);
     1216        }
     1217
     1218        /*
     1219         * Close the input side of the pipe and wait for the child to exit.
     1220         */
     1221        kFileClose(fhPipe);
     1222        rc = kProcWait(cpid, KPROCWAIT_FLAGS_WAIT, &status, NULL);
     1223
     1224        /*
     1225         * Check for errors, get buffered bits.
     1226         */
     1227        if (cc == -1)
     1228            *err = "Error reading shell's output for \"%s\"";
     1229
     1230        res = (char *)Buf_GetAll (buf, &cc);
     1231        Buf_Destroy (buf, FALSE);
     1232
     1233        if (status.uExitCode || status.fFlags != KPROCRES_FLAGS_NORMAL)
     1234            *err = "\"%s\" returned non-zero status";
     1235
     1236        /*
     1237         * Null-terminate the result, convert newlines to spaces and
     1238         * install it in the variable. Final newline is removed.
     1239         */
     1240        res[cc] = '\0';
     1241        cp = &res[cc] - 1;
     1242        if (*cp == '\n')
     1243            *cp-- = '\0';
     1244
     1245        while (cp >= res)
     1246        {
     1247            if (*cp == '\n')
     1248                *cp = ' ';
     1249            cp--;
     1250        }
     1251
     1252        return res;
     1253    }
     1254    else
     1255        *err = "Couldn't exec \"%s\"";
     1256
     1257    res = emalloc(1);
     1258    *res = '\0';
     1259    return res;
     1260
     1261#else  /* not KMK */
     1262
     1263    char        *args[4];       /* Args for invoking the shell */
     1264    int         fds[2];         /* Pipe streams */
     1265    int         cpid;           /* Child PID */
     1266    int         pid;            /* PID from wait() */
     1267    char        *res;           /* result */
     1268    int         status;         /* command exit status */
     1269    Buffer      buf;            /* buffer to store the result */
     1270    char        *cp;
     1271    int         cc;
    11471272
    11481273
     
    11611286     */
    11621287    if (pipe(fds) == -1) {
    1163         *err = "Couldn't create pipe for \"%s\"";
    1164         goto bad;
     1288        *err = "Couldn't create pipe for \"%s\"";
     1289        goto bad;
    11651290    }
    11661291
     
    11691294     */
    11701295#ifdef __EMX__
    1171     switch (cpid = fork()) {
    1172 #else
    1173     switch (cpid = vfork()) {
    1174 #endif
     1296    switch (cpid = fork())
     1297#else
     1298    switch (cpid = vfork())
     1299#endif
     1300    {
    11751301    case 0:
    1176         /*
    1177         * Close input side of pipe
    1178         */
    1179         (void) close(fds[0]);
    1180 
    1181         /*
    1182         * Duplicate the output stream to the shell's output, then
    1183         * shut the extra thing down. Note we don't fetch the error
    1184         * stream...why not? Why?
    1185         */
    1186         (void) dup2(fds[1], 1);
    1187         (void) close(fds[1]);
     1302        /*
     1303        * Close input side of pipe
     1304        */
     1305        (void) close(fds[0]);
     1306
     1307        /*
     1308        * Duplicate the output stream to the shell's output, then
     1309        * shut the extra thing down. Note we don't fetch the error
     1310        * stream...why not? Why?
     1311        */
     1312        (void) dup2(fds[1], 1);
     1313        (void) close(fds[1]);
    11881314
    11891315        #ifdef OS2
     
    11941320            if (!psz)
    11951321                psz = "c:\\os2\\cmd.exe";
    1196             (void) execv(psz, args);
     1322            (void) execv(psz, args);
    11971323        }
    11981324        #else
    1199         (void) execv("/bin/sh", args);
     1325        (void) execv("/bin/sh", args);
    12001326        #endif
    1201         _exit(1);
    1202         /*NOTREACHED*/
     1327        _exit(1);
     1328        /*NOTREACHED*/
    12031329
    12041330    case -1:
    1205         *err = "Couldn't exec \"%s\"";
    1206         goto bad;
     1331        *err = "Couldn't exec \"%s\"";
     1332        goto bad;
    12071333
    12081334    default:
    1209         /*
    1210         * No need for the writing half
    1211         */
    1212         (void) close(fds[1]);
    1213 
    1214         buf = Buf_Init (MAKE_BSIZE);
    1215 
    1216         do {
    1217             char   result[BUFSIZ];
    1218             cc = read(fds[0], result, sizeof(result));
    1219             if (cc > 0)
    1220                 Buf_AddBytes(buf, cc, (Byte *) result);
    1221         }
    1222         while (cc > 0 || (cc == -1 && errno == EINTR));
    1223 
    1224         /*
    1225         * Close the input side of the pipe.
    1226         */
    1227         (void) close(fds[0]);
    1228 
    1229         /*
    1230         * Wait for the process to exit.
    1231         */
    1232         while(((pid = wait(&status)) != cpid) && (pid >= 0))
    1233             continue;
    1234 
    1235         if (cc == -1)
    1236             *err = "Error reading shell's output for \"%s\"";
    1237 
    1238         res = (char *)Buf_GetAll (buf, &cc);
    1239         Buf_Destroy (buf, FALSE);
    1240 
    1241         if (status)
    1242             *err = "\"%s\" returned non-zero status";
    1243 
    1244         /*
    1245         * Null-terminate the result, convert newlines to spaces and
    1246         * install it in the variable.
    1247         */
    1248         res[cc] = '\0';
    1249         cp = &res[cc] - 1;
    1250 
    1251         if (*cp == '\n') {
    1252             /*
    1253              * A final newline is just stripped
    1254              */
    1255             *cp-- = '\0';
    1256         }
    1257         while (cp >= res) {
    1258             if (*cp == '\n') {
    1259                 *cp = ' ';
    1260             }
    1261             cp--;
    1262         }
    1263         break;
     1335        /*
     1336        * No need for the writing half
     1337        */
     1338        (void) close(fds[1]);
     1339
     1340        buf = Buf_Init (MAKE_BSIZE);
     1341
     1342        do {
     1343            char   result[BUFSIZ];
     1344            cc = read(fds[0], result, sizeof(result));
     1345            if (cc > 0)
     1346                Buf_AddBytes(buf, cc, (Byte *) result);
     1347        }
     1348        while (cc > 0 || (cc == -1 && errno == EINTR));
     1349
     1350        /*
     1351        * Close the input side of the pipe.
     1352        */
     1353        (void) close(fds[0]);
     1354
     1355        /*
     1356        * Wait for the process to exit.
     1357        */
     1358        while(((pid = wait(&status)) != cpid) && (pid >= 0))
     1359            continue;
     1360
     1361        if (cc == -1)
     1362            *err = "Error reading shell's output for \"%s\"";
     1363
     1364        res = (char *)Buf_GetAll (buf, &cc);
     1365        Buf_Destroy (buf, FALSE);
     1366
     1367        if (status)
     1368            *err = "\"%s\" returned non-zero status";
     1369
     1370        /*
     1371        * Null-terminate the result, convert newlines to spaces and
     1372        * install it in the variable.
     1373        */
     1374        res[cc] = '\0';
     1375        cp = &res[cc] - 1;
     1376
     1377        if (*cp == '\n') {
     1378            /*
     1379             * A final newline is just stripped
     1380             */
     1381            *cp-- = '\0';
     1382        }
     1383        while (cp >= res) {
     1384            if (*cp == '\n') {
     1385                *cp = ' ';
     1386            }
     1387            cp--;
     1388        }
     1389        break;
    12641390    }
    12651391    return res;
     
    12681394    *res = '\0';
    12691395    return res;
     1396#endif /* KMK */
    12701397}
    12711398
    12721399/*-
    12731400 * Error --
    1274  *      Print an error message given its format.
     1401 *      Print an error message given its format.
    12751402 *
    12761403 * Results:
    1277  *      None.
     1404 *      None.
    12781405 *
    12791406 * Side Effects:
    1280  *      The message is printed.
     1407 *      The message is printed.
    12811408 */
    12821409/* VARARGS */
     
    12861413#else
    12871414Error(va_alist)
    1288         va_dcl
    1289 #endif
    1290 {
    1291         va_list ap;
     1415        va_dcl
     1416#endif
     1417{
     1418        va_list ap;
    12921419#if defined(__STDC__) || defined(__IBMC__)
    1293         va_start(ap, fmt);
    1294 #else
    1295         char *fmt;
    1296 
    1297         va_start(ap);
    1298         fmt = va_arg(ap, char *);
    1299 #endif
    1300         (void)vfprintf(stderr, fmt, ap);
    1301         va_end(ap);
    1302         (void)fprintf(stderr, "\n");
    1303         (void)fflush(stderr);
     1420        va_start(ap, fmt);
     1421#else
     1422        char *fmt;
     1423
     1424        va_start(ap);
     1425        fmt = va_arg(ap, char *);
     1426#endif
     1427        (void)vfprintf(stderr, fmt, ap);
     1428        va_end(ap);
     1429        (void)fprintf(stderr, "\n");
     1430        (void)fflush(stderr);
    13041431}
    13051432
    13061433/*-
    13071434 * Fatal --
    1308  *      Produce a Fatal error message. If jobs are running, waits for them
    1309  *      to finish.
     1435 *      Produce a Fatal error message. If jobs are running, waits for them
     1436 *      to finish.
    13101437 *
    13111438 * Results:
    1312  *      None
     1439 *      None
    13131440 *
    13141441 * Side Effects:
    1315  *      The program exits
     1442 *      The program exits
    13161443 */
    13171444/* VARARGS */
     
    13211448#else
    13221449Fatal(va_alist)
    1323         va_dcl
    1324 #endif
    1325 {
    1326         va_list ap;
     1450        va_dcl
     1451#endif
     1452{
     1453        va_list ap;
    13271454#if defined(__STDC__) || defined(__IBMC__)
    1328         va_start(ap, fmt);
    1329 #else
    1330         char *fmt;
    1331 
    1332         va_start(ap);
    1333         fmt = va_arg(ap, char *);
    1334 #endif
    1335         if (jobsRunning)
    1336                 Job_Wait();
    1337 
    1338         (void)vfprintf(stderr, fmt, ap);
    1339         va_end(ap);
    1340         (void)fprintf(stderr, "\n");
    1341         (void)fflush(stderr);
    1342 
    1343         if (DEBUG(GRAPH2))
    1344                 Targ_PrintGraph(2);
    1345         exit(2);                /* Not 1 so -q can distinguish error */
     1455        va_start(ap, fmt);
     1456#else
     1457        char *fmt;
     1458
     1459        va_start(ap);
     1460        fmt = va_arg(ap, char *);
     1461#endif
     1462        if (jobsRunning)
     1463                Job_Wait();
     1464
     1465        (void)vfprintf(stderr, fmt, ap);
     1466        va_end(ap);
     1467        (void)fprintf(stderr, "\n");
     1468        (void)fflush(stderr);
     1469
     1470        if (DEBUG(GRAPH2))
     1471                Targ_PrintGraph(2);
     1472        exit(2);                /* Not 1 so -q can distinguish error */
    13461473}
    13471474
    13481475/*
    13491476 * Punt --
    1350  *      Major exception once jobs are being created. Kills all jobs, prints
    1351  *      a message and exits.
     1477 *      Major exception once jobs are being created. Kills all jobs, prints
     1478 *      a message and exits.
    13521479 *
    13531480 * Results:
    1354  *      None
     1481 *      None
    13551482 *
    13561483 * Side Effects:
    1357  *      All children are killed indiscriminately and the program Lib_Exits
     1484 *      All children are killed indiscriminately and the program Lib_Exits
    13581485 */
    13591486/* VARARGS */
     
    13631490#else
    13641491Punt(va_alist)
    1365         va_dcl
    1366 #endif
    1367 {
    1368         va_list ap;
     1492        va_dcl
     1493#endif
     1494{
     1495        va_list ap;
    13691496#if defined(__STDC__) || defined(__IBMC__)
    1370         va_start(ap, fmt);
    1371 #else
    1372         char *fmt;
    1373 
    1374         va_start(ap);
    1375         fmt = va_arg(ap, char *);
    1376 #endif
    1377 
    1378         (void)fprintf(stderr, MAKE_NAME ": ");
    1379         (void)vfprintf(stderr, fmt, ap);
    1380         va_end(ap);
    1381         (void)fprintf(stderr, "\n");
    1382         (void)fflush(stderr);
    1383 
    1384         DieHorribly();
     1497        va_start(ap, fmt);
     1498#else
     1499        char *fmt;
     1500
     1501        va_start(ap);
     1502        fmt = va_arg(ap, char *);
     1503#endif
     1504
     1505        (void)fprintf(stderr, MAKE_NAME ": ");
     1506        (void)vfprintf(stderr, fmt, ap);
     1507        va_end(ap);
     1508        (void)fprintf(stderr, "\n");
     1509        (void)fflush(stderr);
     1510
     1511        DieHorribly();
    13851512}
    13861513
    13871514/*-
    13881515 * DieHorribly --
    1389  *      Exit without giving a message.
     1516 *      Exit without giving a message.
    13901517 *
    13911518 * Results:
    1392  *      None
     1519 *      None
    13931520 *
    13941521 * Side Effects:
    1395  *      A big one...
     1522 *      A big one...
    13961523 */
    13971524void
    13981525DieHorribly()
    13991526{
    1400         if (jobsRunning)
    1401                 Job_AbortAll();
    1402         if (DEBUG(GRAPH2))
    1403                 Targ_PrintGraph(2);
    1404         exit(2);                /* Not 1, so -q can distinguish error */
     1527        if (jobsRunning)
     1528                Job_AbortAll();
     1529        if (DEBUG(GRAPH2))
     1530                Targ_PrintGraph(2);
     1531        exit(2);                /* Not 1, so -q can distinguish error */
    14051532}
    14061533
    14071534/*
    14081535 * Finish --
    1409  *      Called when aborting due to errors in child shell to signal
    1410  *      abnormal exit.
     1536 *      Called when aborting due to errors in child shell to signal
     1537 *      abnormal exit.
    14111538 *
    14121539 * Results:
    1413  *      None
     1540 *      None
    14141541 *
    14151542 * Side Effects:
    1416  *      The program exits
     1543 *      The program exits
    14171544 */
    14181545void
    14191546Finish(errors)
    1420         int errors;     /* number of errors encountered in Make_Make */
    1421 {
    1422         Fatal("%d error%s", errors, errors == 1 ? "" : "s");
     1547        int errors;     /* number of errors encountered in Make_Make */
     1548{
     1549        Fatal("%d error%s", errors, errors == 1 ? "" : "s");
    14231550}
    14241551
    14251552/*
    14261553 * emalloc --
    1427  *      malloc, but die on error.
     1554 *      malloc, but die on error.
    14281555 */
    14291556void *
    14301557emalloc(len)
    1431         size_t len;
    1432 {
    1433         void *p;
    1434 
    1435         if ((p = malloc(len)) == NULL)
    1436                 enomem();
    1437         return(p);
     1558        size_t len;
     1559{
     1560        void *p;
     1561
     1562        if ((p = malloc(len)) == NULL)
     1563                enomem();
     1564        return(p);
    14381565}
    14391566
    14401567/*
    14411568 * estrdup --
    1442  *      strdup, but die on error.
     1569 *      strdup, but die on error.
    14431570 */
    14441571char *
    14451572estrdup(str)
    1446         const char *str;
    1447 {
    1448         char *p;
    1449 
    1450         if ((p = strdup(str)) == NULL)
    1451                 enomem();
    1452         return(p);
     1573        const char *str;
     1574{
     1575        char *p;
     1576
     1577        if ((p = strdup(str)) == NULL)
     1578                enomem();
     1579        return(p);
    14531580}
    14541581
    14551582/*
    14561583 * erealloc --
    1457  *      realloc, but die on error.
     1584 *      realloc, but die on error.
    14581585 */
    14591586void *
    14601587erealloc(ptr, size)
    1461         void *ptr;
    1462         size_t size;
    1463 {
    1464         if ((ptr = realloc(ptr, size)) == NULL)
    1465                 enomem();
    1466         return(ptr);
     1588        void *ptr;
     1589        size_t size;
     1590{
     1591        if ((ptr = realloc(ptr, size)) == NULL)
     1592                enomem();
     1593        return(ptr);
    14671594}
    14681595
     
    14811608/*
    14821609 * enomem --
    1483  *      die when out of memory.
     1610 *      die when out of memory.
    14841611 */
    14851612void
    14861613enomem()
    14871614{
    1488         err(2, NULL);
     1615        err(2, NULL);
    14891616}
    14901617
    14911618/*
    14921619 * enunlink --
    1493  *      Remove a file carefully, avoiding directories.
     1620 *      Remove a file carefully, avoiding directories.
    14941621 */
    14951622int
    14961623eunlink(file)
    1497         const char *file;
    1498 {
    1499         struct stat st;
    1500 
    1501 #ifdef __EMX__
    1502         if (stat(file, &st) == -1)
    1503 #else
    1504         if (lstat(file, &st) == -1)
    1505 #endif
    1506                 return -1;
    1507 
    1508         if (S_ISDIR(st.st_mode)) {
    1509                 errno = EISDIR;
    1510                 return -1;
    1511         }
    1512         return unlink(file);
     1624        const char *file;
     1625{
     1626        struct stat st;
     1627
     1628#if defined(OS2)
     1629        if (stat(file, &st) == -1)
     1630#else
     1631        if (lstat(file, &st) == -1)
     1632#endif
     1633                return -1;
     1634
     1635        if (S_ISDIR(st.st_mode)) {
     1636                errno = EISDIR;
     1637                return -1;
     1638        }
     1639        return unlink(file);
    15131640}
    15141641
    15151642/*
    15161643 * usage --
    1517  *      exit with usage message
     1644 *      exit with usage message
    15181645 */
    15191646static void
    15201647usage()
    15211648{
    1522         (void)fprintf(stderr, "%s\n%s\n%s\n"
     1649        (void)fprintf(stderr, "%s\n%s\n%s\n"
    15231650#ifdef NMAKE
    15241651"%s\n"
     
    15381665#endif
    15391666);
    1540         exit(2);
     1667        exit(2);
    15411668}
    15421669
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette