diff options
Diffstat (limited to 'make.h')
-rw-r--r-- | make.h | 465 |
1 files changed, 307 insertions, 158 deletions
@@ -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 */ |