+2013-06-22 Paul Smith <psmith@gnu.org>
+
+ Improve performance by using a character map to determine where we
+ want to stop searching strings, rather than discrete comparisons.
+
+ * read.c (find_char_unquote): Pass a stop map instead of various
+ flags and use that to check when to stop parsing the string.
+ (eval): Use the new find_char_unquote() calling signature.
+ (remove_comments): Ditto.
+ (unescape_char): Ditto.
+ (find_percent_cached): Ditto.
+ (parse_file_seq): Use a stop-map flag.
+ * main.c (stopchar_map): Character map definition.
+ (initialize_stopchar_map): Initialize the map definition.
+ (main): Invoke the map initialization function.
+ * misc.c (end_of_token_w32): Remove unused function.
+ * dir.c (dosify): Use STOP_SET to check for stop chars.
+ * main.c (main): Ditto.
+ * misc.c (end_of_token): Ditto.
+ * function.c (subst_expand): Ditto.
+ (func_notdir_suffix): Ditto.
+ (func_basename_dir): Ditto.
+ (abspath): Ditto.
+ * job.c (is_bourne_compatible_shell): Ditto.
+ * variable.c (parse_variable_definition): Ditto.
+ * read.c (eval): Ditto.
+ (conditional_line): Ditto.
+ (find_percent_cached): Ditto.
+ * dep.h (PARSE_FILE_SEQ): Update function declaration.
+ * default.c (set_default_suffixes): Update PARSE_FILE_SEQ() call.
+ * file.c (split_prereqs): Ditto.
+ * function.c (string_glob): Ditto.
+ * implicit.c (pattern_search): Ditto.
+ * rule.c (install_pattern_rule): Ditto.
+ * main.c (main): Ditto.
+
2013-06-21 Paul Smith <psmith@gnu.org>
* main.c (verify_flag): Global variable to determine whether to
{
struct dep *d;
char *p = default_suffixes;
- suffix_file->deps = enter_prereqs (PARSE_FILE_SEQ (&p, struct dep, '\0',
+ suffix_file->deps = enter_prereqs (PARSE_FILE_SEQ (&p, struct dep, MAP_NUL,
NULL, 0),
NULL);
for (d = suffix_file->deps; d; d = d->next)
const char *name;
};
-
-#define PARSEFS_NONE (0x0000)
-#define PARSEFS_NOSTRIP (0x0001)
-#define PARSEFS_NOAR (0x0002)
-#define PARSEFS_NOGLOB (0x0004)
-#define PARSEFS_EXISTS (0x0008)
-#define PARSEFS_NOCACHE (0x0010)
+#define PARSEFS_NONE 0x0000
+#define PARSEFS_NOSTRIP 0x0001
+#define PARSEFS_NOAR 0x0002
+#define PARSEFS_NOGLOB 0x0004
+#define PARSEFS_EXISTS 0x0008
+#define PARSEFS_NOCACHE 0x0010
#define PARSE_FILE_SEQ(_s,_t,_c,_p,_f) \
(_t *)parse_file_seq ((_s),sizeof (_t),(_c),(_p),(_f))
void *parse_file_seq ();
#else
void *parse_file_seq (char **stringp, unsigned int size,
- int stopchar, const char *prefix, int flags);
+ int stopmap, const char *prefix, int flags);
#endif
char *tilde_expand (const char *name);
#include "makeint.h"
#include "hash.h"
+#include "dep.h"
#ifdef HAVE_DIRENT_H
# include <dirent.h>
df = dos_filename;
/* First, transform the name part. */
- for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
+ for (i = 0; i < 8 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
*df++ = tolower ((unsigned char)*filename++);
/* Now skip to the next dot. */
- while (*filename != '\0' && *filename != '.')
+ while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
++filename;
if (*filename != '\0')
{
*df++ = *filename++;
- for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
+ for (i = 0; i < 3 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
*df++ = tolower ((unsigned char)*filename++);
}
/* Look for more dots. */
- while (*filename != '\0' && *filename != '.')
+ while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
++filename;
if (*filename == '.')
return filename;
struct dep *
split_prereqs (char *p)
{
- struct dep *new = PARSE_FILE_SEQ (&p, struct dep, '|', NULL, 0);
+ struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL, 0);
if (*p)
{
struct dep *ood;
++p;
- ood = PARSE_FILE_SEQ (&p, struct dep, '\0', NULL, 0);
+ ood = PARSE_FILE_SEQ (&p, struct dep, MAP_NUL, NULL, 0);
if (! new)
new = ood;
or only at the ends of words, check that this case qualifies. */
if (by_word
&& ((p > text && !isblank ((unsigned char)p[-1]))
- || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
+ || ! STOP_SET (p[slen], MAP_BLANK|MAP_NUL)))
/* Struck out. Output the rest of the string that is
no longer to be replaced. */
o = variable_buffer_output (o, subst, slen);
struct nameseq *chain;
unsigned int idx;
- chain = PARSE_FILE_SEQ (&line, struct nameseq, '\0', NULL,
+ chain = PARSE_FILE_SEQ (&line, struct nameseq, MAP_NUL, NULL,
/* We do not want parse_file_seq to strip './'s.
That would break examples like:
$(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
return o;
}
-#ifdef VMS
-# define IS_PATHSEP(c) ((c) == ']')
-#else
-# ifdef HAVE_DOS_PATHS
-# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
-# else
-# define IS_PATHSEP(c) ((c) == '/')
-# endif
-#endif
-
static char *
func_notdir_suffix (char *o, char **argv, const char *funcname)
int is_suffix = funcname[0] == 's';
int is_notdir = !is_suffix;
+ int stop = MAP_PATHSEP | (is_suffix ? MAP_DOT : 0);
while ((p2 = find_next_token (&list_iterator, &len)) != 0)
{
- const char *p = p2 + len;
+ const char *p = p2 + len - 1;
-
- while (p >= p2 && (!is_suffix || *p != '.'))
- {
- if (IS_PATHSEP (*p))
- break;
- --p;
- }
+ while (p >= p2 && ! STOP_SET (*p, stop))
+ --p;
if (p >= p2)
{
int is_basename = funcname[0] == 'b';
int is_dir = !is_basename;
-
+ int stop = MAP_PATHSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
while ((p2 = find_next_token (&p3, &len)) != 0)
{
- const char *p = p2 + len;
- while (p >= p2 && (!is_basename || *p != '.'))
- {
- if (IS_PATHSEP (*p))
- break;
- --p;
- }
+ const char *p = p2 + len - 1;
+ while (p >= p2 && ! STOP_SET (*p, stop))
+ --p;
if (p >= p2 && (is_dir))
o = variable_buffer_output (o, p2, ++p - p2);
strcpy (apath, starting_directory);
#ifdef HAVE_DOS_PATHS
- if (IS_PATHSEP(name[0]))
+ if (STOP_SET (name[0], MAP_PATHSEP))
{
- if (IS_PATHSEP(name[1]))
+ if (STOP_SET (name[1], MAP_PATHSEP))
{
/* A UNC. Don't prepend a drive letter. */
apath[0] = name[0];
/* Get past the root, since we already copied it. */
name += root_len;
#ifdef HAVE_DOS_PATHS
- if (!IS_PATHSEP(apath[2]))
+ if (! STOP_SET (apath[2], MAP_PATHSEP))
{
/* Convert d:foo into d:./foo and increase root_len. */
apath[2] = '.';
unsigned long len;
/* Skip sequence of multiple path-separators. */
- while (IS_PATHSEP(*start))
+ while (STOP_SET (*start, MAP_PATHSEP))
++start;
/* Find end of path component. */
- for (end = start; *end != '\0' && !IS_PATHSEP(*end); ++end)
+ for (end = start; ! STOP_SET (*end, MAP_PATHSEP|MAP_NUL); ++end)
;
len = end - start;
{
/* Back up to previous component, ignore if at root already. */
if (dest > apath + root_len)
- for (--dest; !IS_PATHSEP(dest[-1]); --dest);
+ for (--dest; ! STOP_SET (dest[-1], MAP_PATHSEP); --dest)
+ ;
}
else
{
- if (!IS_PATHSEP(dest[-1]))
+ if (! STOP_SET (dest[-1], MAP_PATHSEP))
*dest++ = '/';
if (dest + len >= apath_limit)
}
/* Unless it is root strip trailing separator. */
- if (dest > apath + root_len && IS_PATHSEP(dest[-1]))
+ if (dest > apath + root_len && STOP_SET (dest[-1], MAP_PATHSEP))
--dest;
*dest = '\0';
p = variable_expand_for_file (depname, file);
/* Parse the expanded string. */
- dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? '\0' : '|',
+ dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? MAP_NUL : MAP_PIPE,
add_dir ? dir : NULL, 0);
for (d = dl; d != NULL; d = d->next)
len = strlen (unix_shells[i]);
#if defined(WINDOWS32) || defined(__MSDOS__)
if ((strncasecmp (name, unix_shells[i], len) == 0) &&
- (strlen (name) >= len && (name[len] == '\0' || name[len] == '.')))
+ (strlen (name) >= len && STOP_SET (name[len], MAP_DOT|MAP_NUL)))
#else
if ((strncmp (name, unix_shells[i], len) == 0) &&
(strlen (name) >= len && name[len] == '\0'))
warning at the end of the run. */
int clock_skew_detected;
+
+/* Map of possible stop characters for searching strings. */
+#ifndef UCHAR_MAX
+# define UCHAR_MAX 255
+#endif
+unsigned short stopchar_map[UCHAR_MAX + 1] = {0};
+
\f
/* Mask of signals that are being caught with fatal_error_signal. */
hash_init_function_table ();
}
+/* This character map locate stop chars when parsing GNU makefiles.
+ Each element is true if we should stop parsing on that character. */
+
+static void
+initialize_stopchar_map ()
+{
+ int i;
+
+ stopchar_map[(int)'\0'] = MAP_NUL;
+ stopchar_map[(int)'#'] = MAP_COMMENT;
+ stopchar_map[(int)';'] = MAP_SEMI;
+ stopchar_map[(int)'='] = MAP_EQUALS;
+ stopchar_map[(int)':'] = MAP_COLON;
+ stopchar_map[(int)'%'] = MAP_PERCENT;
+ stopchar_map[(int)'|'] = MAP_PIPE;
+ stopchar_map[(int)'.'] = MAP_DOT;
+ stopchar_map[(int)','] = MAP_COMMA;
+ stopchar_map[(int)'$'] = MAP_VARIABLE;
+
+ stopchar_map[(int)'/'] = MAP_PATHSEP;
+#if defined(VMS)
+ stopchar_map[(int)']'] = MAP_PATHSEP;
+#elif defined(HAVE_DOS_PATHS)
+ stopchar_map[(int)'\\'] = MAP_PATHSEP;
+#endif
+
+ for (i = 1; i <= UCHAR_MAX; ++i)
+ {
+ if (isblank(i))
+ stopchar_map[i] = MAP_BLANK;
+ if (isspace(i))
+ stopchar_map[i] |= MAP_SPACE;
+ }
+}
+
static const char *
expand_command_line_file (char *name)
{
no_default_sh_exe = 1;
#endif
+ initialize_stopchar_map();
+
#ifdef SET_STACK_SIZE
/* Get rid of any avoidable limit on stack size. */
{
int do_not_define = 0;
char *ep = envp[i];
- while (*ep != '\0' && *ep != '=')
+ while (! STOP_SET (*ep, MAP_EQUALS))
++ep;
#ifdef WINDOWS32
if (!unix_path && strneq (envp[i], "PATH=", 5))
{
struct nameseq *ns;
- ns = PARSE_FILE_SEQ (&p, struct nameseq, '\0', NULL, 0);
+ ns = PARSE_FILE_SEQ (&p, struct nameseq, MAP_NUL, NULL, 0);
if (ns)
{
/* .DEFAULT_GOAL should contain one target. */
void sync_Path_environment (void);
int w32_kill (pid_t pid, int sig);
-char *end_of_token_w32 (const char *s, char stopchar);
int find_and_set_default_shell (const char *token);
/* indicates whether or not we have Bourne shell */
#define WIN32_LEAN_AND_MEAN
#endif /* WINDOWS32 */
+#define ANY_SET(_v,_m) (((_v)&(_m)) != 0)
+#define NONE_SET(_v,_m) (! ANY_SET ((_v),(_m)))
+
+#define MAP_NUL 0x0001
+#define MAP_BLANK 0x0002
+#define MAP_SPACE 0x0004
+#define MAP_COMMENT 0x0008
+#define MAP_SEMI 0x0010
+#define MAP_EQUALS 0x0020
+#define MAP_COLON 0x0040
+#define MAP_PERCENT 0x0080
+#define MAP_PIPE 0x0100
+#define MAP_DOT 0x0200
+#define MAP_COMMA 0x0400
+
+/* This means not only a '$', but skip the variable reference. */
+#define MAP_VARIABLE 0x4000
+/* The set of characters which are path separators is OS-specific. */
+#define MAP_PATHSEP 0x8000
+
+#ifdef VMS
+# define MAP_VMSCOMMA MAP_COMMA
+#else
+# define MAP_VMSCOMMA 0x0000
+#endif
+
+#define STOP_SET(_v,_m) ANY_SET (stopchar_map[(int)(_v)],(_m))
+
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
# define SET_STACK_SIZE
#endif
extern char **environ;
+extern unsigned short stopchar_map[];
+
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
extern int print_data_base_flag, question_flag, touch_flag, always_make_flag;
extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
char *
end_of_token (const char *s)
{
- while (*s != '\0' && !isblank ((unsigned char)*s))
+ while (! STOP_SET (*s, MAP_BLANK|MAP_NUL))
++s;
return (char *)s;
}
-#ifdef WINDOWS32
-/*
- * Same as end_of_token, but take into account a stop character
- */
-char *
-end_of_token_w32 (const char *s, char stopchar)
-{
- const char *p = s;
- int backslash = 0;
-
- while (*p != '\0' && *p != stopchar
- && (backslash || !isblank ((unsigned char)*p)))
- {
- if (*p++ == '\\')
- {
- backslash = !backslash;
- while (*p == '\\')
- {
- backslash = !backslash;
- ++p;
- }
- }
- else
- backslash = 0;
- }
-
- return (char *)p;
-}
-#endif
-
/* Return the address of the first nonwhitespace or null in the string S. */
char *
static enum make_word_type get_next_mword (char *buffer, char *delim,
char **startp, unsigned int *length);
static void remove_comments (char *line);
-static char *find_char_unquote (char *string, int stop1, int stop2,
- int blank, int ignorevars);
+static char *find_char_unquote (char *string, int map);
static char *unescape_char (char *string, int c);
if (in_ignored_define)
{
/* See if this is an endef line (plus optional comment). */
- if (word1eq ("endef") && (*p2 == '\0' || *p2 == '#'))
+ if (word1eq ("endef") && STOP_SET (*p2, MAP_COMMENT|MAP_NUL))
in_ignored_define = 0;
continue;
/* Parse the list of file names. Don't expand archive references! */
p2 = p;
- files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL,
+ files = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_NUL, NULL,
PARSEFS_NOAR);
free (p);
/* Parse the list of file names.
Don't expand archive references or strip "./" */
p2 = p;
- files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL,
+ files = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_NUL, NULL,
PARSEFS_NOAR);
free (p);
/* Search the line for an unquoted ; that is not after an
unquoted #. */
- cmdleft = find_char_unquote (line, ';', '#', 0, 1);
+ cmdleft = find_char_unquote (line, MAP_SEMI|MAP_COMMENT|MAP_VARIABLE);
if (cmdleft != 0 && *cmdleft == '#')
{
/* We found a comment before a semicolon. */
if (cmdleft == 0)
{
/* Look for a semicolon in the expanded line. */
- cmdleft = find_char_unquote (p2, ';', 0, 0, 0);
+ cmdleft = find_char_unquote (p2, MAP_SEMI);
if (cmdleft != 0)
{
}
}
- colonp = find_char_unquote (p2, ':', 0, 0, 0);
+ colonp = find_char_unquote (p2, MAP_COLON);
#ifdef HAVE_DOS_PATHS
/* The drive spec brain-damage strikes again... */
/* Note that the only separators of targets in this context
while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
colonp > p2 && isalpha ((unsigned char)colonp[-1]) &&
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
- colonp = find_char_unquote (colonp + 1, ':', 0, 0, 0);
+ colonp = find_char_unquote (colonp + 1, MAP_COLON);
#endif
if (colonp != 0)
break;
/* Make the colon the end-of-string so we know where to stop
looking for targets. Start there again once we're done. */
*colonp = '\0';
- filenames = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, 0);
+ filenames = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_NUL, NULL, 0);
*colonp = ':';
p2 = colonp;
/* This is a normal target, _not_ a target-specific variable.
Unquote any = in the dependency list. */
- find_char_unquote (lb_next, '=', 0, 0, 0);
+ find_char_unquote (lb_next, MAP_EQUALS);
/* Remember the command prefix for this target. */
prefix = cmd_prefix;
/* Look for a semicolon in the expanded line. */
if (cmdleft == 0)
{
- cmdleft = find_char_unquote (p2, ';', 0, 0, 0);
+ cmdleft = find_char_unquote (p2, MAP_SEMI);
if (cmdleft != 0)
*(cmdleft++) = '\0';
}
if (p != 0)
{
struct nameseq *target;
- target = PARSE_FILE_SEQ (&p2, struct nameseq, ':', NULL,
+ target = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_COLON, NULL,
PARSEFS_NOGLOB);
++p2;
if (target == 0)
{
char *comment;
- comment = find_char_unquote (line, '#', 0, 0, 0);
+ comment = find_char_unquote (line, MAP_COMMENT);
if (comment != 0)
/* Cut off the line at the #. */
and cannot be an 'else' or 'endif'. */
/* Find the length of the next word. */
- for (p = line+1; *p != '\0' && !isspace ((unsigned char)*p); ++p)
+ for (p = line+1; ! STOP_SET (*p, MAP_SPACE|MAP_NUL); ++p)
;
len = p - line;
STOPCHAR _cannot_ be '$' if IGNOREVARS is true. */
static char *
-find_char_unquote (char *string, int stop1, int stop2, int blank,
- int ignorevars)
+find_char_unquote (char *string, int map)
{
unsigned int string_len = 0;
char *p = string;
- if (ignorevars)
- ignorevars = '$';
+ /* Always stop on NUL. */
+ map |= MAP_NUL;
while (1)
{
- if (stop2 && blank)
- while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2
- && ! isblank ((unsigned char) *p))
- ++p;
- else if (stop2)
- while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2)
- ++p;
- else if (blank)
- while (*p != '\0' && *p != ignorevars && *p != stop1
- && ! isblank ((unsigned char) *p))
- ++p;
- else
- while (*p != '\0' && *p != ignorevars && *p != stop1)
- ++p;
+ while (! STOP_SET (*p, map))
+ ++p;
if (*p == '\0')
break;
/* If we stopped due to a variable reference, skip over its contents. */
- if (*p == ignorevars)
+ if (STOP_SET (*p, MAP_VARIABLE))
{
char openparen = p[1];
char *
find_percent (char *pattern)
{
- return find_char_unquote (pattern, '%', 0, 0, 0);
+ return find_char_unquote (pattern, MAP_PERCENT);
}
/* Search STRING for an unquoted % and handle quoting. Returns a pointer to
while (1)
{
- while (*p != '\0' && *p != '%')
+ while (! STOP_SET (*p, MAP_PERCENT|MAP_NUL))
++p;
if (*p == '\0')
*/
void *
-parse_file_seq (char **stringp, unsigned int size, int stopchar,
+parse_file_seq (char **stringp, unsigned int size, int stopmap,
const char *prefix, int flags)
{
extern void dir_setup_glob (glob_t *glob);
static char *tmpbuf = NULL;
static int tmpbuf_len = 0;
- int cachep = (! (flags & PARSEFS_NOCACHE));
+ int cachep = NONE_SET (flags, PARSEFS_NOCACHE);
struct nameseq *new = 0;
struct nameseq **newp = &new;
glob_t gl;
char *tp;
-#ifdef VMS
-# define VMS_COMMA ','
-#else
-# define VMS_COMMA 0
-#endif
+ /* Always stop on NUL. */
+ stopmap |= MAP_NUL;
if (size < sizeof (struct nameseq))
size = sizeof (struct nameseq);
- if (! (flags & PARSEFS_NOGLOB))
+ if (NONE_SET (flags, PARSEFS_NOGLOB))
dir_setup_glob (&gl);
/* Get enough temporary space to construct the largest possible target. */
/* Skip whitespace; at the end of the string or STOPCHAR we're done. */
p = next_token (p);
- if (*p == '\0' || *p == stopchar)
+ if (STOP_SET (*p, stopmap))
break;
/* There are names left, so find the end of the next name.
Throughout this iteration S points to the start. */
s = p;
- p = find_char_unquote (p, stopchar, VMS_COMMA, 1, 0);
+ p = find_char_unquote (p, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#ifdef VMS
/* convert comma separated list to space separated */
if (p && *p == ',')
*p =' ';
#endif
#ifdef _AMIGA
- if (stopchar == ':' && p && *p == ':'
+ if (p && STOP_SET (*p, stopmap & MAP_COLON)
&& !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
- p = find_char_unquote (p+1, stopchar, VMS_COMMA, 1, 0);
+ p = find_char_unquote (p+1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif
#ifdef HAVE_DOS_PATHS
/* For DOS paths, skip a "C:\..." or a "C:/..." until we find the
first colon which isn't followed by a slash or a backslash.
Note that tokens separated by spaces should be treated as separate
tokens since make doesn't allow path names with spaces */
- if (stopchar == ':')
+ if (stopmap | MAP_COLON)
while (p != 0 && !isspace ((unsigned char)*p) &&
(p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1]))
- p = find_char_unquote (p + 1, stopchar, VMS_COMMA, 1, 0);
+ p = find_char_unquote (p + 1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif
if (p == 0)
p = s + strlen (s);
/* Strip leading "this directory" references. */
- if (! (flags & PARSEFS_NOSTRIP))
+ if (NONE_SET (flags, PARSEFS_NOSTRIP))
#ifdef VMS
/* Skip leading '[]'s. */
while (p - s > 2 && s[0] == '[' && s[1] == ']')
Finally, note that archive groups must end with ')' as the last
character, so ensure there's some word ending like that before
considering this an archive group. */
- if (! (flags & PARSEFS_NOAR)
+ if (NONE_SET (flags, PARSEFS_NOAR)
&& tp == tmpbuf && tp[0] != '(' && tp[nlen-1] != ')')
{
char *n = strchr (tp, '(');
/* Find the end of this word. We don't want to unquote and
we don't care about quoting since we're looking for the
last char in the word. */
- while (*e != '\0' && *e != stopchar && *e != VMS_COMMA
- && ! isblank ((unsigned char) *e))
+ while (! STOP_SET (*e, stopmap|MAP_BLANK|MAP_VMSCOMMA))
++e;
/* If we didn't move, we're done now. */
if (e == o)
/* If we're not globbing we're done: add it to the end of the chain.
Go to the next item in the string. */
- if (flags & PARSEFS_NOGLOB)
+ if (ANY_SET (flags, PARSEFS_NOGLOB))
{
NEWELT (concat (2, prefix, tmpbuf));
continue;
/* If NAME is an archive member reference replace it with the archive
file name, and save the member name in MEMNAME. We will glob on the
archive name and then reattach MEMNAME later. */
- if (! (flags & PARSEFS_NOAR) && ar_name (name))
+ if (NONE_SET (flags, PARSEFS_NOAR) && ar_name (name))
{
ar_parse_name (name, &arname, &memname);
name = arname;
#endif /* !NO_ARCHIVES */
/* glob() is expensive: don't call it unless we need to. */
- if (!(flags & PARSEFS_EXISTS) && strpbrk (name, "?*[") == NULL)
+ if (NONE_SET (flags, PARSEFS_EXISTS) && strpbrk (name, "?*[") == NULL)
{
globme = 0;
i = 1;
case GLOB_NOMATCH:
/* If we want only existing items, skip this one. */
- if (flags & PARSEFS_EXISTS)
+ if (ANY_SET (flags, PARSEFS_EXISTS))
{
i = 0;
break;
++r->suffixes[0];
ptr = p->dep;
- r->deps = PARSE_FILE_SEQ (&ptr, struct dep, '\0', NULL, 0);
+ r->deps = PARSE_FILE_SEQ (&ptr, struct dep, MAP_NUL, NULL, 0);
if (new_pattern_rule (r, 0))
{
int c = *p++;
/* If we find a comment or EOS, it's not a variable definition. */
- if (c == '\0' || c == '#')
+ if (STOP_SET (c, MAP_COMMENT|MAP_NUL))
return NULL;
if (c == '$')