mirror of
https://github.com/mirror/make.git
synced 2025-01-06 10:21:00 +08:00
Add ISDIRSEP() helper macro and use it
Create a ISDIRSEP() macro to check for directory separator chars using the stopchar_map, and replace inline checks and explicit STOP_SET calls with this macro. * src/makeint.h (ISDIRSEP): Create the macro using MAP_DIRSEP. * src/dir.c (find_directory): Replace inline checks with ISDIRSEP. (file_exists_p): Ditto. (file_impossible): Ditto. (file_impossible_p): Ditto. (local_stat): Ditto. * src/file.c (lookup_file): Ditto. * src/function.c (abspath): Ditto. * src/job.c (_is_unixy_shell): Ditto. (is_bourne_compatible_shell): Ditto. (construct_command_argv): Ditto. * src/main.c (find_and_set_default_shell): Ditto. (main): Ditto. * src/read.c (eval): Ditto. (parse_file_seq): Ditto. * src/remake.c (name_mtime): Ditto. * src/vpath.c (construct_vpath_list): Ditto.
This commit is contained in:
parent
b79791533b
commit
7bb7bb4ba4
13
src/dir.c
13
src/dir.c
@ -530,9 +530,7 @@ find_directory (const char *name)
|
|||||||
tstart = tem;
|
tstart = tem;
|
||||||
if (tstart[1] == ':')
|
if (tstart[1] == ':')
|
||||||
tstart += 2;
|
tstart += 2;
|
||||||
for (tend = tem + (len - 1);
|
for (tend = tem + (len - 1); tend > tstart && ISDIRSEP (*tend); tend--)
|
||||||
tend > tstart && (*tend == '/' || *tend == '\\');
|
|
||||||
tend--)
|
|
||||||
*tend = '\0';
|
*tend = '\0';
|
||||||
|
|
||||||
r = stat (tem, &st);
|
r = stat (tem, &st);
|
||||||
@ -867,7 +865,7 @@ file_exists_p (const char *name)
|
|||||||
#ifdef HAVE_DOS_PATHS
|
#ifdef HAVE_DOS_PATHS
|
||||||
/* d:/ and d: are *very* different... */
|
/* d:/ and d: are *very* different... */
|
||||||
if (dirend < name + 3 && name[1] == ':' &&
|
if (dirend < name + 3 && name[1] == ':' &&
|
||||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||||
dirend++;
|
dirend++;
|
||||||
#endif
|
#endif
|
||||||
p = alloca (dirend - name + 1);
|
p = alloca (dirend - name + 1);
|
||||||
@ -943,7 +941,7 @@ file_impossible (const char *filename)
|
|||||||
#ifdef HAVE_DOS_PATHS
|
#ifdef HAVE_DOS_PATHS
|
||||||
/* d:/ and d: are *very* different... */
|
/* d:/ and d: are *very* different... */
|
||||||
if (dirend < p + 3 && p[1] == ':' &&
|
if (dirend < p + 3 && p[1] == ':' &&
|
||||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||||
dirend++;
|
dirend++;
|
||||||
#endif
|
#endif
|
||||||
cp = alloca (dirend - p + 1);
|
cp = alloca (dirend - p + 1);
|
||||||
@ -1041,7 +1039,7 @@ file_impossible_p (const char *filename)
|
|||||||
#ifdef HAVE_DOS_PATHS
|
#ifdef HAVE_DOS_PATHS
|
||||||
/* d:/ and d: are *very* different... */
|
/* d:/ and d: are *very* different... */
|
||||||
if (dirend < filename + 3 && filename[1] == ':' &&
|
if (dirend < filename + 3 && filename[1] == ':' &&
|
||||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||||
dirend++;
|
dirend++;
|
||||||
#endif
|
#endif
|
||||||
cp = alloca (dirend - filename + 1);
|
cp = alloca (dirend - filename + 1);
|
||||||
@ -1314,8 +1312,7 @@ local_stat (const char *path, struct stat *buf)
|
|||||||
/* Make sure the parent of "." exists and is a directory, not a
|
/* Make sure the parent of "." exists and is a directory, not a
|
||||||
file. This is because 'stat' on Windows normalizes the argument
|
file. This is because 'stat' on Windows normalizes the argument
|
||||||
foo/. => foo without checking first that foo is a directory. */
|
foo/. => foo without checking first that foo is a directory. */
|
||||||
if (plen > 2 && path[plen - 1] == '.'
|
if (plen > 2 && path[plen - 1] == '.' && ISDIRSEP (path[plen - 2]))
|
||||||
&& (path[plen - 2] == '/' || path[plen - 2] == '\\'))
|
|
||||||
{
|
{
|
||||||
char parent[MAXPATHLEN+1];
|
char parent[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
14
src/file.c
14
src/file.c
@ -108,20 +108,10 @@ lookup_file (const char *name)
|
|||||||
while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
|
while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
|
||||||
name += 2;
|
name += 2;
|
||||||
#endif
|
#endif
|
||||||
while (name[0] == '.'
|
while (name[0] == '.' && ISDIRSEP (name[1]) && name[2] != '\0')
|
||||||
#ifdef HAVE_DOS_PATHS
|
|
||||||
&& (name[1] == '/' || name[1] == '\\')
|
|
||||||
#else
|
|
||||||
&& name[1] == '/'
|
|
||||||
#endif
|
|
||||||
&& name[2] != '\0')
|
|
||||||
{
|
{
|
||||||
name += 2;
|
name += 2;
|
||||||
while (*name == '/'
|
while (ISDIRSEP (*name))
|
||||||
#ifdef HAVE_DOS_PATHS
|
|
||||||
|| *name == '\\'
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
|
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
|
||||||
++name;
|
++name;
|
||||||
}
|
}
|
||||||
|
@ -2135,7 +2135,7 @@ func_not (char *o, char **argv, char *funcname UNUSED)
|
|||||||
|
|
||||||
#ifdef HAVE_DOS_PATHS
|
#ifdef HAVE_DOS_PATHS
|
||||||
# ifdef __CYGWIN__
|
# ifdef __CYGWIN__
|
||||||
# define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || STOP_SET (n[0], MAP_DIRSEP))
|
# define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || ISDIRSEP (n[0]))
|
||||||
# else
|
# else
|
||||||
# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
|
# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
|
||||||
# endif
|
# endif
|
||||||
@ -2169,9 +2169,9 @@ abspath (const char *name, char *apath)
|
|||||||
strcpy (apath, starting_directory);
|
strcpy (apath, starting_directory);
|
||||||
|
|
||||||
#ifdef HAVE_DOS_PATHS
|
#ifdef HAVE_DOS_PATHS
|
||||||
if (STOP_SET (name[0], MAP_DIRSEP))
|
if (ISDIRSEP (name[0]))
|
||||||
{
|
{
|
||||||
if (STOP_SET (name[1], MAP_DIRSEP))
|
if (ISDIRSEP (name[1]))
|
||||||
{
|
{
|
||||||
/* A UNC. Don't prepend a drive letter. */
|
/* A UNC. Don't prepend a drive letter. */
|
||||||
apath[0] = name[0];
|
apath[0] = name[0];
|
||||||
@ -2191,7 +2191,7 @@ abspath (const char *name, char *apath)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
|
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
|
||||||
if (STOP_SET (name[0], MAP_DIRSEP))
|
if (ISDIRSEP (name[0]))
|
||||||
root_len = 1;
|
root_len = 1;
|
||||||
#endif
|
#endif
|
||||||
memcpy (apath, name, root_len);
|
memcpy (apath, name, root_len);
|
||||||
@ -2200,7 +2200,7 @@ abspath (const char *name, char *apath)
|
|||||||
/* Get past the root, since we already copied it. */
|
/* Get past the root, since we already copied it. */
|
||||||
name += root_len;
|
name += root_len;
|
||||||
#ifdef HAVE_DOS_PATHS
|
#ifdef HAVE_DOS_PATHS
|
||||||
if (! STOP_SET (apath[root_len - 1], MAP_DIRSEP))
|
if (! ISDIRSEP (apath[root_len - 1]))
|
||||||
{
|
{
|
||||||
/* Convert d:foo into d:./foo and increase root_len. */
|
/* Convert d:foo into d:./foo and increase root_len. */
|
||||||
apath[2] = '.';
|
apath[2] = '.';
|
||||||
@ -2220,7 +2220,7 @@ abspath (const char *name, char *apath)
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* Skip sequence of multiple path-separators. */
|
/* Skip sequence of multiple path-separators. */
|
||||||
while (STOP_SET (*start, MAP_DIRSEP))
|
while (ISDIRSEP (*start))
|
||||||
++start;
|
++start;
|
||||||
|
|
||||||
/* Find end of path component. */
|
/* Find end of path component. */
|
||||||
@ -2237,12 +2237,12 @@ abspath (const char *name, char *apath)
|
|||||||
{
|
{
|
||||||
/* Back up to previous component, ignore if at root already. */
|
/* Back up to previous component, ignore if at root already. */
|
||||||
if (dest > apath + root_len)
|
if (dest > apath + root_len)
|
||||||
for (--dest; ! STOP_SET (dest[-1], MAP_DIRSEP); --dest)
|
for (--dest; ! ISDIRSEP (dest[-1]); --dest)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (! STOP_SET (dest[-1], MAP_DIRSEP))
|
if (! ISDIRSEP (dest[-1]))
|
||||||
*dest++ = '/';
|
*dest++ = '/';
|
||||||
|
|
||||||
if (dest + len >= apath_limit)
|
if (dest + len >= apath_limit)
|
||||||
@ -2254,7 +2254,7 @@ abspath (const char *name, char *apath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unless it is root strip trailing separator. */
|
/* Unless it is root strip trailing separator. */
|
||||||
if (dest > apath + root_len && STOP_SET (dest[-1], MAP_DIRSEP))
|
if (dest > apath + root_len && ISDIRSEP (dest[-1]))
|
||||||
--dest;
|
--dest;
|
||||||
|
|
||||||
*dest = '\0';
|
*dest = '\0';
|
||||||
|
33
src/job.c
33
src/job.c
@ -416,7 +416,8 @@ _is_unixy_shell (const char *path)
|
|||||||
else if (!name) /* name and p must be 0 */
|
else if (!name) /* name and p must be 0 */
|
||||||
name = path;
|
name = path;
|
||||||
|
|
||||||
if (*name == '/' || *name == '\\') name++;
|
if (ISDIRSEP (*name))
|
||||||
|
name++;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (known_os2shells[i] != NULL)
|
while (known_os2shells[i] != NULL)
|
||||||
@ -439,38 +440,30 @@ is_bourne_compatible_shell (const char *path)
|
|||||||
static const char *unix_shells[] = {
|
static const char *unix_shells[] = {
|
||||||
"sh",
|
"sh",
|
||||||
"bash",
|
"bash",
|
||||||
|
"dash",
|
||||||
"ksh",
|
"ksh",
|
||||||
"rksh",
|
"rksh",
|
||||||
"zsh",
|
"zsh",
|
||||||
"ash",
|
"ash",
|
||||||
"dash",
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
const char **s;
|
const char **s;
|
||||||
|
|
||||||
/* find the rightmost '/' or '\\' */
|
/* find the last directory separator, or the beginning of the string. */
|
||||||
const char *name = strrchr (path, '/');
|
const char *cp = path + strlen (path);
|
||||||
char *p = strrchr (path, '\\');
|
|
||||||
|
|
||||||
if (name && p) /* take the max */
|
while (cp > path && !ISDIRSEP (cp[-1]))
|
||||||
name = (name > p) ? name : p;
|
--cp;
|
||||||
else if (p) /* name must be 0 */
|
|
||||||
name = p;
|
|
||||||
else if (!name) /* name and p must be 0 */
|
|
||||||
name = path;
|
|
||||||
|
|
||||||
if (*name == '/' || *name == '\\')
|
|
||||||
++name;
|
|
||||||
|
|
||||||
/* this should be able to deal with extensions on Windows-like systems */
|
/* this should be able to deal with extensions on Windows-like systems */
|
||||||
for (s = unix_shells; *s != NULL; ++s)
|
for (s = unix_shells; *s != NULL; ++s)
|
||||||
{
|
{
|
||||||
#if defined(WINDOWS32) || defined(__MSDOS__)
|
#if defined(WINDOWS32) || defined(__MSDOS__)
|
||||||
size_t len = strlen (*s);
|
size_t len = strlen (*s);
|
||||||
if ((strlen (name) >= len && STOP_SET (name[len], MAP_DOT|MAP_NUL))
|
if ((strlen (cp) >= len && STOP_SET (cp[len], MAP_DOT|MAP_NUL))
|
||||||
&& strncasecmp (name, *s, len) == 0)
|
&& strncasecmp (cp, *s, len) == 0)
|
||||||
#else
|
#else
|
||||||
if (strcmp (name, *s) == 0)
|
if (strcmp (cp, *s) == 0)
|
||||||
#endif
|
#endif
|
||||||
return 1; /* a known unix-style shell */
|
return 1; /* a known unix-style shell */
|
||||||
}
|
}
|
||||||
@ -3053,8 +3046,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (p[1] != '\\' && p[1] != '\''
|
if (p[1] != '\\' && p[1] != '\'' && !ISSPACE (p[1])
|
||||||
&& !ISSPACE (p[1])
|
|
||||||
&& strchr (sh_chars_sh, p[1]) == 0)
|
&& strchr (sh_chars_sh, p[1]) == 0)
|
||||||
/* back up one notch, to copy the backslash */
|
/* back up one notch, to copy the backslash */
|
||||||
--p;
|
--p;
|
||||||
@ -3688,8 +3680,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
|
|||||||
performed) and if shell is an absolute path without drive letter,
|
performed) and if shell is an absolute path without drive letter,
|
||||||
try whether it exists e.g.: if "/bin/sh" does not exist use
|
try whether it exists e.g.: if "/bin/sh" does not exist use
|
||||||
"$UNIXROOT/bin/sh" instead. */
|
"$UNIXROOT/bin/sh" instead. */
|
||||||
if (unixroot && shell && strcmp (shell, last_shell) != 0
|
if (unixroot && shell && ISDIRSEP (shell[0]) && !streq (shell, last_shell))
|
||||||
&& (shell[0] == '/' || shell[0] == '\\'))
|
|
||||||
{
|
{
|
||||||
/* trying a new shell, check whether it exists */
|
/* trying a new shell, check whether it exists */
|
||||||
size_t size = strlen (shell);
|
size_t size = strlen (shell);
|
||||||
|
10
src/main.c
10
src/main.c
@ -1016,12 +1016,10 @@ find_and_set_default_shell (const char *token)
|
|||||||
"cmd.exe" case-insensitive. */
|
"cmd.exe" case-insensitive. */
|
||||||
tokend = search_token + strlen (search_token) - 3;
|
tokend = search_token + strlen (search_token) - 3;
|
||||||
if (((tokend == search_token
|
if (((tokend == search_token
|
||||||
|| (tokend > search_token
|
|| (tokend > search_token && ISDIRSEP (tokend[-1])))
|
||||||
&& (tokend[-1] == '/' || tokend[-1] == '\\')))
|
|
||||||
&& !strcasecmp (tokend, "cmd"))
|
&& !strcasecmp (tokend, "cmd"))
|
||||||
|| ((tokend - 4 == search_token
|
|| ((tokend - 4 == search_token
|
||||||
|| (tokend - 4 > search_token
|
|| (tokend - 4 > search_token && ISDIRSEP (tokend[-5])))
|
||||||
&& (tokend[-5] == '/' || tokend[-5] == '\\')))
|
|
||||||
&& !strcasecmp (tokend - 4, "cmd.exe")))
|
&& !strcasecmp (tokend - 4, "cmd.exe")))
|
||||||
{
|
{
|
||||||
batch_mode_shell = 1;
|
batch_mode_shell = 1;
|
||||||
@ -1320,7 +1318,7 @@ main (int argc, char **argv, char **envp)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
program = start + strlen (start);
|
program = start + strlen (start);
|
||||||
while (program > start && ! STOP_SET (program[-1], MAP_DIRSEP))
|
while (program > start && ! ISDIRSEP (program[-1]))
|
||||||
--program;
|
--program;
|
||||||
|
|
||||||
/* Remove the .exe extension if present. */
|
/* Remove the .exe extension if present. */
|
||||||
@ -1762,7 +1760,7 @@ main (int argc, char **argv, char **envp)
|
|||||||
But allow -C/ just in case someone wants that. */
|
But allow -C/ just in case someone wants that. */
|
||||||
{
|
{
|
||||||
char *p = (char *)dir + strlen (dir) - 1;
|
char *p = (char *)dir + strlen (dir) - 1;
|
||||||
while (p > dir && (p[0] == '/' || p[0] == '\\'))
|
while (p > dir && ISDIRSEP (p[0]))
|
||||||
--p;
|
--p;
|
||||||
p[1] = '\0';
|
p[1] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -468,6 +468,8 @@ extern int unixy_shell;
|
|||||||
|
|
||||||
#define STOP_SET(_v,_m) ANY_SET(stopchar_map[(unsigned char)(_v)],(_m))
|
#define STOP_SET(_v,_m) ANY_SET(stopchar_map[(unsigned char)(_v)],(_m))
|
||||||
|
|
||||||
|
/* True if C is a directory separator on the current system. */
|
||||||
|
#define ISDIRSEP(c) STOP_SET((c),MAP_DIRSEP)
|
||||||
/* True if C is whitespace but not newline. */
|
/* True if C is whitespace but not newline. */
|
||||||
#define ISBLANK(c) STOP_SET((c),MAP_BLANK)
|
#define ISBLANK(c) STOP_SET((c),MAP_BLANK)
|
||||||
/* True if C is whitespace including newlines. */
|
/* True if C is whitespace including newlines. */
|
||||||
|
@ -1108,7 +1108,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
|||||||
Note that the only separators of targets in this context are
|
Note that the only separators of targets in this context are
|
||||||
whitespace and a left paren. If others are possible, add them
|
whitespace and a left paren. If others are possible, add them
|
||||||
to the string in the call to strchr. */
|
to the string in the call to strchr. */
|
||||||
while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
|
while (colonp && ISDIRSEP (colonp[1]) &&
|
||||||
isalpha ((unsigned char) colonp[-1]) &&
|
isalpha ((unsigned char) colonp[-1]) &&
|
||||||
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
|
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
|
||||||
colonp = find_char_unquote (colonp + 1, ':');
|
colonp = find_char_unquote (colonp + 1, ':');
|
||||||
@ -1279,8 +1279,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
|||||||
do {
|
do {
|
||||||
check_again = 0;
|
check_again = 0;
|
||||||
/* For DOS-style paths, skip a "C:\..." or a "C:/..." */
|
/* For DOS-style paths, skip a "C:\..." or a "C:/..." */
|
||||||
if (p != 0 && (p[1] == '\\' || p[1] == '/') &&
|
if (p != 0 && ISDIRSEP (p[1]) && isalpha ((unsigned char)p[-1]) &&
|
||||||
isalpha ((unsigned char)p[-1]) &&
|
|
||||||
(p == p2 + 1 || strchr (" \t:(", p[-2]) != 0)) {
|
(p == p2 + 1 || strchr (" \t:(", p[-2]) != 0)) {
|
||||||
p = strchr (p + 1, ':');
|
p = strchr (p + 1, ':');
|
||||||
check_again = 1;
|
check_again = 1;
|
||||||
@ -3270,7 +3269,7 @@ parse_file_seq (char **stringp, size_t size, int stopmap,
|
|||||||
Tokens separated by spaces are treated as separate paths since make
|
Tokens separated by spaces are treated as separate paths since make
|
||||||
doesn't allow path names with spaces. */
|
doesn't allow path names with spaces. */
|
||||||
if (p && p == s+1 && p[0] == ':'
|
if (p && p == s+1 && p[0] == ':'
|
||||||
&& isalpha ((unsigned char)s[0]) && STOP_SET (p[1], MAP_DIRSEP))
|
&& isalpha ((unsigned char)s[0]) && ISDIRSEP (p[1]))
|
||||||
p = find_map_unquote (p+1, findmap);
|
p = find_map_unquote (p+1, findmap);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1564,7 +1564,7 @@ name_mtime (const char *name)
|
|||||||
tend--;
|
tend--;
|
||||||
if (*tend == '.' && tend > tstart)
|
if (*tend == '.' && tend > tstart)
|
||||||
tend--;
|
tend--;
|
||||||
for ( ; tend > tstart && (*tend == '/' || *tend == '\\'); tend--)
|
for ( ; tend > tstart && ISDIRSEP (*tend); tend--)
|
||||||
*tend = '\0';
|
*tend = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -239,8 +239,7 @@ construct_vpath_list (char *pattern, char *dirpath)
|
|||||||
also define HAVE_DOS_PATHS would like us to recognize
|
also define HAVE_DOS_PATHS would like us to recognize
|
||||||
colons after the drive letter in the likes of
|
colons after the drive letter in the likes of
|
||||||
"D:/foo/bar:C:/xyzzy". */
|
"D:/foo/bar:C:/xyzzy". */
|
||||||
&& (*p != PATH_SEPARATOR_CHAR
|
&& (*p != PATH_SEPARATOR_CHAR || (p == v + 1 && ISDIRSEP (p[1])))
|
||||||
|| (p == v + 1 && (p[1] == '/' || p[1] == '\\')))
|
|
||||||
#else
|
#else
|
||||||
&& *p != PATH_SEPARATOR_CHAR
|
&& *p != PATH_SEPARATOR_CHAR
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user