summaryrefslogtreecommitdiff
path: root/make.h
diff options
context:
space:
mode:
Diffstat (limited to 'make.h')
-rw-r--r--make.h465
1 files changed, 307 insertions, 158 deletions
diff --git a/make.h b/make.h
index 520a6602518f..0c10706d3632 100644
--- a/make.h
+++ b/make.h
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.137 2020/09/02 23:42:58 rillig Exp $ */
+/* $NetBSD: make.h,v 1.179 2020/11/01 17:47:26 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -91,6 +91,7 @@
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
@@ -142,23 +143,31 @@
#ifdef USE_DOUBLE_BOOLEAN
/* During development, to find type mismatches in function declarations. */
typedef double Boolean;
+#define TRUE 1.0
+#define FALSE 0.0
#elif defined(USE_UCHAR_BOOLEAN)
/* During development, to find code that depends on the exact value of TRUE or
* that stores other values in Boolean variables. */
typedef unsigned char Boolean;
#define TRUE ((unsigned char)0xFF)
#define FALSE ((unsigned char)0x00)
+#elif defined(USE_CHAR_BOOLEAN)
+/* During development, to find code that uses a boolean as array index, via
+ * -Wchar-subscripts. */
+typedef char Boolean;
+#define TRUE ((char)-1)
+#define FALSE ((char)0x00)
#elif defined(USE_ENUM_BOOLEAN)
-typedef enum { FALSE, TRUE} Boolean;
+typedef enum Boolean { FALSE, TRUE } Boolean;
#else
typedef int Boolean;
-#endif
#ifndef TRUE
#define TRUE 1
-#endif /* TRUE */
+#endif
#ifndef FALSE
#define FALSE 0
-#endif /* FALSE */
+#endif
+#endif
#include "lst.h"
#include "enum.h"
@@ -196,18 +205,20 @@ typedef enum {
* communicating to other parts of the program the way in which a target
* should be made.
*
- * These constants are bitwise-OR'ed together and placed in the 'type' field
- * of each node. Any node that has a 'type' field which satisfies the OP_NOP
- * function was never never on the left-hand side of an operator, though it
- * may have been on the right-hand side... */
-typedef enum {
- /* Execution of commands depends on children (:) */
+ * Some of the OP_ constants can be combined, others cannot. */
+typedef enum GNodeType {
+ /* The dependency operator ':' is the most common one. The commands of
+ * this node are executed if any child is out-of-date. */
OP_DEPENDS = 1 << 0,
- /* Always execute commands (!) */
+ /* The dependency operator '!' always executes its commands, even if
+ * its children are up-to-date. */
OP_FORCE = 1 << 1,
- /* Execution of commands depends on children per line (::) */
+ /* The dependency operator '::' behaves like ':', except that it allows
+ * multiple dependency groups to be defined. Each of these groups is
+ * executed on its own, independently from the others. */
OP_DOUBLEDEP = 1 << 2,
+ /* Matches the dependency operators ':', '!' and '::'. */
OP_OPMASK = OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP,
/* Don't care if the target doesn't exist and can't be created */
@@ -216,8 +227,8 @@ typedef enum {
OP_USE = 1 << 4,
/* Target is never out of date, but always execute commands anyway.
* Its time doesn't matter, so it has none...sort of */
- OP_EXEC = 1 << 5,
- /* Ignore errors when creating the node */
+ OP_EXEC = 1 << 5,
+ /* Ignore non-zero exit status from shell commands when creating the node */
OP_IGNORE = 1 << 6,
/* Don't remove the target when interrupted */
OP_PRECIOUS = 1 << 7,
@@ -259,23 +270,32 @@ typedef enum {
/* The node is a transformation rule */
OP_TRANSFORM = 1 << 31,
/* Target is a member of an archive */
+ /* XXX: How does this differ from OP_ARCHV? */
OP_MEMBER = 1 << 30,
- /* Target is a library */
+ /* The node is a library,
+ * its name has the form "-l<libname>" */
OP_LIB = 1 << 29,
- /* Target is an archive construct */
+ /* The node is an archive member,
+ * its name has the form "archive(member)" */
+ /* XXX: How does this differ from OP_MEMBER? */
OP_ARCHV = 1 << 28,
/* Target has all the commands it should. Used when parsing to catch
- * multiple commands for a target. */
+ * multiple command groups for a target. Only applies to the dependency
+ * operators ':' and '!', but not to '::'. */
OP_HAS_COMMANDS = 1 << 27,
- /* Saving commands on .END (Compat) */
+ /* The special command "..." has been seen. All further commands from
+ * this node will be saved on the .END node instead, to be executed at
+ * the very end. */
OP_SAVE_CMDS = 1 << 26,
/* Already processed by Suff_FindDeps */
OP_DEPS_FOUND = 1 << 25,
/* Node found while expanding .ALLSRC */
- OP_MARK = 1 << 24
+ OP_MARK = 1 << 24,
+
+ OP_NOTARGET = OP_NOTMAIN | OP_USE | OP_EXEC | OP_TRANSFORM
} GNodeType;
-typedef enum {
+typedef enum GNodeFlags {
REMAKE = 0x0001, /* this target needs to be (re)made */
CHILDMADE = 0x0002, /* children of this target were made */
FORCE = 0x0004, /* children don't exist, and we pretend made */
@@ -288,6 +308,14 @@ typedef enum {
INTERNAL = 0x4000 /* Internal use only */
} GNodeFlags;
+typedef struct List StringList;
+typedef struct ListNode StringListNode;
+
+typedef struct List GNodeList;
+typedef struct ListNode GNodeListNode;
+
+typedef struct List /* of CachedDir */ SearchPath;
+
/* A graph node represents a target that can possibly be made, including its
* relation to other targets and a lot of other details. */
typedef struct GNode {
@@ -302,40 +330,41 @@ typedef struct GNode {
/* The type of operator used to define the sources (see the OP flags below).
* XXX: This looks like a wild mixture of type and flags. */
GNodeType type;
- /* whether it is involved in this invocation of make */
GNodeFlags flags;
/* The state of processing on this node */
GNodeMade made;
int unmade; /* The number of unmade children */
- time_t mtime; /* Its modification time */
- struct GNode *cmgn; /* The youngest child */
+ /* The modification time; 0 means the node does not have a corresponding
+ * file; see Make_OODate. */
+ time_t mtime;
+ struct GNode *youngestChild;
/* The GNodes for which this node is an implied source. May be empty.
* For example, when there is an inference rule for .c.o, the node for
* file.c has the node for file.o in this list. */
- Lst implicitParents;
+ GNodeList *implicitParents;
- /* Other nodes of the same name for the :: operator. */
- Lst cohorts;
+ /* Other nodes of the same name, for the '::' operator. */
+ GNodeList *cohorts;
/* The nodes that depend on this one, or in other words, the nodes for
* which this is a source. */
- Lst parents;
+ GNodeList *parents;
/* The nodes on which this one depends. */
- Lst children;
+ GNodeList *children;
/* .ORDER nodes we need made. The nodes that must be made (if they're
* made) before this node can be made, but that do not enter into the
* datedness of this node. */
- Lst order_pred;
+ GNodeList *order_pred;
/* .ORDER nodes who need us. The nodes that must be made (if they're made
* at all) after this node is made, but that do not depend on this node,
* in the normal sense. */
- Lst order_succ;
+ GNodeList *order_succ;
- /* #n for this cohort */
+ /* The "#n" suffix for this cohort, or "" for other nodes */
char cohort_num[8];
/* The number of unmade instances on the cohorts list */
int unmade_cohorts;
@@ -344,14 +373,17 @@ typedef struct GNode {
struct GNode *centurion;
/* Last time (sequence number) we tried to make this node */
- unsigned int checked;
+ unsigned int checked_seqno;
/* The "local" variables that are specific to this target and this target
- * only, such as $@, $<, $?. */
- Hash_Table context;
+ * only, such as $@, $<, $?.
+ *
+ * Also used for the global variable scopes VAR_GLOBAL, VAR_CMDLINE,
+ * VAR_INTERNAL, which contain variables with arbitrary names. */
+ HashTable /* of Var pointer */ context;
/* The commands to be given to a shell to create this target. */
- Lst commands;
+ StringList *commands;
/* Suffix for the node (determined by Suff_FindDeps and opaque to everyone
* but the Suff module) */
@@ -363,40 +395,21 @@ typedef struct GNode {
int lineno;
} GNode;
-#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute)
-/*
- * OP_NOP will return TRUE if the node with the given type was not the
- * object of a dependency operator
- */
-#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000)
-
-#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)
-
-/*
- * The TARG_ constants are used when calling the Targ_FindNode and
- * Targ_FindList functions in targ.c. They simply tell the functions what to
- * do if the desired node(s) is (are) not found. If the TARG_CREATE constant
- * is given, a new, empty node will be created for the target, placed in the
- * table of all targets and its address returned. If TARG_NOCREATE is given,
- * a NULL pointer will be returned.
- */
-#define TARG_NOCREATE 0x00 /* don't create it */
-#define TARG_CREATE 0x01 /* create node if not found */
-#define TARG_NOHASH 0x02 /* don't look in/add to hash table */
-
/*
* Error levels for parsing. PARSE_FATAL means the process cannot continue
- * once the makefile has been parsed. PARSE_WARNING means it can. Passed
- * as the first argument to Parse_Error.
+ * once the top-level makefile has been parsed. PARSE_WARNING and PARSE_INFO
+ * mean it can.
*/
-#define PARSE_INFO 3
-#define PARSE_WARNING 2
-#define PARSE_FATAL 1
+typedef enum ParseErrorLevel {
+ PARSE_FATAL = 1,
+ PARSE_WARNING,
+ PARSE_INFO
+} ParseErrorLevel;
/*
- * Values returned by Cond_Eval.
+ * Values returned by Cond_EvalLine and Cond_EvalCondition.
*/
-typedef enum {
+typedef enum CondEvalResult {
COND_PARSE, /* Parse the next lines */
COND_SKIP, /* Skip the next lines */
COND_INVALID /* Not a conditional statement */
@@ -405,77 +418,52 @@ typedef enum {
/*
* Definitions for the "local" variables. Used only for clarity.
*/
-#define TARGET "@" /* Target of dependency */
-#define OODATE "?" /* All out-of-date sources */
-#define ALLSRC ">" /* All sources */
-#define IMPSRC "<" /* Source implied by transformation */
-#define PREFIX "*" /* Common prefix */
-#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
-#define MEMBER "%" /* Member in "archive(member)" syntax */
-
-#define FTARGET "@F" /* file part of TARGET */
-#define DTARGET "@D" /* directory part of TARGET */
-#define FIMPSRC "<F" /* file part of IMPSRC */
-#define DIMPSRC "<D" /* directory part of IMPSRC */
-#define FPREFIX "*F" /* file part of PREFIX */
-#define DPREFIX "*D" /* directory part of PREFIX */
+#define TARGET "@" /* Target of dependency */
+#define OODATE "?" /* All out-of-date sources */
+#define ALLSRC ">" /* All sources */
+#define IMPSRC "<" /* Source implied by transformation */
+#define PREFIX "*" /* Common prefix */
+#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
+#define MEMBER "%" /* Member in "archive(member)" syntax */
+
+#define FTARGET "@F" /* file part of TARGET */
+#define DTARGET "@D" /* directory part of TARGET */
+#define FIMPSRC "<F" /* file part of IMPSRC */
+#define DIMPSRC "<D" /* directory part of IMPSRC */
+#define FPREFIX "*F" /* file part of PREFIX */
+#define DPREFIX "*D" /* directory part of PREFIX */
/*
* Global Variables
*/
-extern Lst create; /* The list of target names specified on the
- * command line. used to resolve #if
- * make(...) statements */
-extern Lst dirSearchPath; /* The list of directories to search when
+extern SearchPath *dirSearchPath;
+ /* The list of directories to search when
* looking for targets */
-
-extern Boolean compatMake; /* True if we are make compatible */
-extern Boolean ignoreErrors; /* True if should ignore all errors */
-extern Boolean beSilent; /* True if should print no commands */
-extern Boolean noExecute; /* True if should execute nothing */
-extern Boolean noRecursiveExecute; /* True if should execute nothing */
-extern Boolean allPrecious; /* True if every target is precious */
+extern Boolean allPrecious; /* True if every target is precious */
extern Boolean deleteOnError; /* True if failed targets should be deleted */
-extern Boolean keepgoing; /* True if should continue on unaffected
- * portions of the graph when have an error
- * in one portion */
-extern Boolean touchFlag; /* TRUE if targets should just be 'touched'
- * if out of date. Set by the -t flag */
-extern Boolean queryFlag; /* TRUE if we aren't supposed to really make
- * anything, just see if the targets are out-
- * of-date */
extern Boolean doing_depend; /* TRUE if processing .depend */
-extern Boolean checkEnvFirst; /* TRUE if environment should be searched for
- * variables before the global context */
-
-extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are
- * treated as errors */
-
-extern Boolean varNoExportEnv; /* TRUE if we should not export variables
- * set on the command line to the env. */
-
-extern GNode *DEFAULT; /* .DEFAULT rule */
+extern GNode *DEFAULT; /* .DEFAULT rule */
extern GNode *VAR_INTERNAL; /* Variables defined internally by make
* which should not override those set by
* makefiles.
*/
-extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
+extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
* in the Makefile itself */
-extern GNode *VAR_CMD; /* Variables defined on the command line */
-extern char var_Error[]; /* Value returned by Var_Parse when an error
+extern GNode *VAR_CMDLINE; /* Variables defined on the command line */
+extern char var_Error[]; /* Value returned by Var_Parse when an error
* is encountered. It actually points to
* an empty string, so naive callers needn't
* worry about it. */
-extern time_t now; /* The time at the start of this whole
+extern time_t now; /* The time at the start of this whole
* process */
-extern Boolean oldVars; /* Do old-style variable substitution */
+extern Boolean oldVars; /* Do old-style variable substitution */
-extern Lst sysIncPath; /* The system include path. */
-extern Lst defIncPath; /* The default include path. */
+extern SearchPath *sysIncPath; /* The system include path. */
+extern SearchPath *defSysIncPath; /* The default system include path. */
extern char curdir[]; /* Startup directory */
extern char *progname; /* The program name */
@@ -495,7 +483,7 @@ extern pid_t myPid;
#define MAKEOVERRIDES ".MAKEOVERRIDES"
#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */
#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */
-#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */
+#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all makefiles already loaded */
#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
@@ -504,61 +492,191 @@ extern pid_t myPid;
# define MAKE_LEVEL_ENV "MAKELEVEL"
#endif
-/*
- * debug control:
- * There is one bit per module. It is up to the module what debug
- * information to print.
- */
-extern FILE *debug_file; /* Output is written here - default stderr */
-extern int debug;
-#define DEBUG_ARCH 0x00001
-#define DEBUG_COND 0x00002
-#define DEBUG_DIR 0x00004
-#define DEBUG_GRAPH1 0x00008
-#define DEBUG_GRAPH2 0x00010
-#define DEBUG_JOB 0x00020
-#define DEBUG_MAKE 0x00040
-#define DEBUG_SUFF 0x00080
-#define DEBUG_TARG 0x00100
-#define DEBUG_VAR 0x00200
-#define DEBUG_FOR 0x00400
-#define DEBUG_SHELL 0x00800
-#define DEBUG_ERROR 0x01000
-#define DEBUG_LOUD 0x02000
-#define DEBUG_META 0x04000
-#define DEBUG_HASH 0x08000
-
-#define DEBUG_GRAPH3 0x10000
-#define DEBUG_SCRIPT 0x20000
-#define DEBUG_PARSE 0x40000
-#define DEBUG_CWD 0x80000
-
-#define DEBUG_LINT 0x100000
+typedef enum DebugFlags {
+ DEBUG_ARCH = 1 << 0,
+ DEBUG_COND = 1 << 1,
+ DEBUG_DIR = 1 << 2,
+ DEBUG_GRAPH1 = 1 << 3,
+ DEBUG_GRAPH2 = 1 << 4,
+ DEBUG_JOB = 1 << 5,
+ DEBUG_MAKE = 1 << 6,
+ DEBUG_SUFF = 1 << 7,
+ DEBUG_TARG = 1 << 8,
+ DEBUG_VAR = 1 << 9,
+ DEBUG_FOR = 1 << 10,
+ DEBUG_SHELL = 1 << 11,
+ DEBUG_ERROR = 1 << 12,
+ DEBUG_LOUD = 1 << 13,
+ DEBUG_META = 1 << 14,
+ DEBUG_HASH = 1 << 15,
+
+ DEBUG_GRAPH3 = 1 << 16,
+ DEBUG_SCRIPT = 1 << 17,
+ DEBUG_PARSE = 1 << 18,
+ DEBUG_CWD = 1 << 19,
+
+ DEBUG_LINT = 1 << 20
+} DebugFlags;
#define CONCAT(a,b) a##b
-#define DEBUG(module) (debug & CONCAT(DEBUG_,module))
+#define DEBUG(module) (opts.debug & CONCAT(DEBUG_,module))
+
+void debug_printf(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
+
+#define DEBUG0(module, text) \
+ if (!DEBUG(module)) (void)0; \
+ else debug_printf("%s", text)
+
+#define DEBUG1(module, fmt, arg1) \
+ if (!DEBUG(module)) (void)0; \
+ else debug_printf(fmt, arg1)
+
+#define DEBUG2(module, fmt, arg1, arg2) \
+ if (!DEBUG(module)) (void)0; \
+ else debug_printf(fmt, arg1, arg2)
+
+#define DEBUG3(module, fmt, arg1, arg2, arg3) \
+ if (!DEBUG(module)) (void)0; \
+ else debug_printf(fmt, arg1, arg2, arg3)
+
+#define DEBUG4(module, fmt, arg1, arg2, arg3, arg4) \
+ if (!DEBUG(module)) (void)0; \
+ else debug_printf(fmt, arg1, arg2, arg3, arg4)
+
+#define DEBUG5(module, fmt, arg1, arg2, arg3, arg4, arg5) \
+ if (!DEBUG(module)) (void)0; \
+ else debug_printf(fmt, arg1, arg2, arg3, arg4, arg5)
+
+typedef enum PrintVarsMode {
+ COMPAT_VARS = 1,
+ EXPAND_VARS
+} PrintVarsMode;
+
+/* Command line options */
+typedef struct CmdOpts {
+ /* -B: whether we are make compatible */
+ Boolean compatMake;
+
+ /* -d: debug control: There is one bit per module. It is up to the
+ * module what debug information to print. */
+ DebugFlags debug;
+
+ /* -df: debug output is written here - default stderr */
+ FILE *debug_file;
+
+ /* -dV: for the -V option, print unexpanded variable values */
+ Boolean debugVflag;
+
+ /* -e: check environment variables before global variables */
+ Boolean checkEnvFirst;
+
+ /* -f: the makefiles to read */
+ StringList *makefiles;
+
+ /* -i: if true, ignore all errors from shell commands */
+ Boolean ignoreErrors;
+
+ /* -j: the maximum number of jobs that can run in parallel;
+ * this is coordinated with the submakes */
+ int maxJobs;
+
+ /* -k: if true, continue on unaffected portions of the graph when an
+ * error occurs in one portion */
+ Boolean keepgoing;
+
+ /* -N: execute no commands from the targets */
+ Boolean noRecursiveExecute;
+
+ /* -n: execute almost no commands from the targets */
+ Boolean noExecute;
+
+ /* -q: if true, we aren't supposed to really make anything, just see if
+ * the targets are out-of-date */
+ Boolean queryFlag;
+
+ /* -r: raw mode, without loading the builtin rules. */
+ Boolean noBuiltins;
+
+ /* -s: don't echo the shell commands before executing them */
+ Boolean beSilent;
+
+ /* -t: touch the targets if they are out-of-date, but don't actually
+ * make them */
+ Boolean touchFlag;
+
+ /* -[Vv]: print expanded or unexpanded selected variables */
+ PrintVarsMode printVars;
+ /* -[Vv]: the variables to print */
+ StringList *variables;
+
+ /* -W: if true, makefile parsing warnings are treated as errors */
+ Boolean parseWarnFatal;
+
+ /* -w: print Entering and Leaving for submakes */
+ Boolean enterFlag;
+
+ /* -X: if true, do not export variables set on the command line to the
+ * environment. */
+ Boolean varNoExportEnv;
+
+ /* The target names specified on the command line.
+ * Used to resolve .if make(...) statements. */
+ StringList *create;
+
+} CmdOpts;
+
+extern CmdOpts opts;
#include "nonints.h"
-int Make_TimeStamp(GNode *, GNode *);
+void Make_TimeStamp(GNode *, GNode *);
Boolean Make_OODate(GNode *);
-void Make_ExpandUse(Lst);
+void Make_ExpandUse(GNodeList *);
time_t Make_Recheck(GNode *);
void Make_HandleUse(GNode *, GNode *);
void Make_Update(GNode *);
void Make_DoAllVar(GNode *);
-Boolean Make_Run(Lst);
+Boolean Make_Run(GNodeList *);
int dieQuietly(GNode *, int);
void PrintOnError(GNode *, const char *);
void Main_ExportMAKEFLAGS(Boolean);
Boolean Main_SetObjdir(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
int mkTempFile(const char *, char **);
-int str2Lst_Append(Lst, char *, const char *);
+int str2Lst_Append(StringList *, char *, const char *);
void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
+Boolean GNode_ShouldExecute(GNode *gn);
+
+/* See if the node was seen on the left-hand side of a dependency operator. */
+static MAKE_ATTR_UNUSED Boolean
+GNode_IsTarget(const GNode *gn)
+{
+ return (gn->type & OP_OPMASK) != 0;
+}
+
+static MAKE_ATTR_UNUSED const char *
+GNode_Path(const GNode *gn)
+{
+ return gn->path != NULL ? gn->path : gn->name;
+}
+
+static MAKE_ATTR_UNUSED const char *
+GNode_VarTarget(GNode *gn) { return Var_ValueDirect(TARGET, gn); }
+static MAKE_ATTR_UNUSED const char *
+GNode_VarOodate(GNode *gn) { return Var_ValueDirect(OODATE, gn); }
+static MAKE_ATTR_UNUSED const char *
+GNode_VarAllsrc(GNode *gn) { return Var_ValueDirect(ALLSRC, gn); }
+static MAKE_ATTR_UNUSED const char *
+GNode_VarImpsrc(GNode *gn) { return Var_ValueDirect(IMPSRC, gn); }
+static MAKE_ATTR_UNUSED const char *
+GNode_VarPrefix(GNode *gn) { return Var_ValueDirect(PREFIX, gn); }
+static MAKE_ATTR_UNUSED const char *
+GNode_VarArchive(GNode *gn) { return Var_ValueDirect(ARCHIVE, gn); }
+static MAKE_ATTR_UNUSED const char *
+GNode_VarMember(GNode *gn) { return Var_ValueDirect(MEMBER, gn); }
#ifdef __GNUC__
-#define UNCONST(ptr) ({ \
+#define UNCONST(ptr) ({ \
union __unconst { \
const void *__cp; \
void *__p; \
@@ -568,13 +686,6 @@ void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
#define UNCONST(ptr) (void *)(ptr)
#endif
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
#ifdef HAVE_LIMITS_H
#include <limits.h>
@@ -592,4 +703,42 @@ void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
#define KILLPG(pid, sig) killpg((pid), (sig))
#endif
+static inline MAKE_ATTR_UNUSED Boolean ch_isalnum(char ch)
+{ return isalnum((unsigned char)ch) != 0; }
+static inline MAKE_ATTR_UNUSED Boolean ch_isalpha(char ch)
+{ return isalpha((unsigned char)ch) != 0; }
+static inline MAKE_ATTR_UNUSED Boolean ch_isdigit(char ch)
+{ return isdigit((unsigned char)ch) != 0; }
+static inline MAKE_ATTR_UNUSED Boolean ch_isspace(char ch)
+{ return isspace((unsigned char)ch) != 0; }
+static inline MAKE_ATTR_UNUSED Boolean ch_isupper(char ch)
+{ return isupper((unsigned char)ch) != 0; }
+static inline MAKE_ATTR_UNUSED char ch_tolower(char ch)
+{ return (char)tolower((unsigned char)ch); }
+static inline MAKE_ATTR_UNUSED char ch_toupper(char ch)
+{ return (char)toupper((unsigned char)ch); }
+
+static inline MAKE_ATTR_UNUSED void
+cpp_skip_whitespace(const char **pp)
+{
+ while (ch_isspace(**pp))
+ (*pp)++;
+}
+
+static inline MAKE_ATTR_UNUSED void
+pp_skip_whitespace(char **pp)
+{
+ while (ch_isspace(**pp))
+ (*pp)++;
+}
+
+#ifdef MAKE_NATIVE
+# include <sys/cdefs.h>
+# ifndef lint
+# define MAKE_RCSID(id) __RCSID(id)
+# endif
+#else
+# define MAKE_RCSID(id) static volatile char rcsid[] = id
+#endif
+
#endif /* MAKE_MAKE_H */