mirror of
https://github.com/mirror/make.git
synced 2025-01-01 07:50:52 +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;
|
||||
if (tstart[1] == ':')
|
||||
tstart += 2;
|
||||
for (tend = tem + (len - 1);
|
||||
tend > tstart && (*tend == '/' || *tend == '\\');
|
||||
tend--)
|
||||
for (tend = tem + (len - 1); tend > tstart && ISDIRSEP (*tend); tend--)
|
||||
*tend = '\0';
|
||||
|
||||
r = stat (tem, &st);
|
||||
@ -867,7 +865,7 @@ file_exists_p (const char *name)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < name + 3 && name[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
p = alloca (dirend - name + 1);
|
||||
@ -943,7 +941,7 @@ file_impossible (const char *filename)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < p + 3 && p[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
cp = alloca (dirend - p + 1);
|
||||
@ -1041,7 +1039,7 @@ file_impossible_p (const char *filename)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < filename + 3 && filename[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
(ISDIRSEP (*dirend) || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
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
|
||||
file. This is because 'stat' on Windows normalizes the argument
|
||||
foo/. => foo without checking first that foo is a directory. */
|
||||
if (plen > 2 && path[plen - 1] == '.'
|
||||
&& (path[plen - 2] == '/' || path[plen - 2] == '\\'))
|
||||
if (plen > 2 && path[plen - 1] == '.' && ISDIRSEP (path[plen - 2]))
|
||||
{
|
||||
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')
|
||||
name += 2;
|
||||
#endif
|
||||
while (name[0] == '.'
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
&& (name[1] == '/' || name[1] == '\\')
|
||||
#else
|
||||
&& name[1] == '/'
|
||||
#endif
|
||||
&& name[2] != '\0')
|
||||
while (name[0] == '.' && ISDIRSEP (name[1]) && name[2] != '\0')
|
||||
{
|
||||
name += 2;
|
||||
while (*name == '/'
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
|| *name == '\\'
|
||||
#endif
|
||||
)
|
||||
while (ISDIRSEP (*name))
|
||||
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
|
||||
++name;
|
||||
}
|
||||
|
@ -2135,7 +2135,7 @@ func_not (char *o, char **argv, char *funcname UNUSED)
|
||||
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
# 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
|
||||
# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
|
||||
# endif
|
||||
@ -2169,9 +2169,9 @@ abspath (const char *name, char *apath)
|
||||
strcpy (apath, starting_directory);
|
||||
|
||||
#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. */
|
||||
apath[0] = name[0];
|
||||
@ -2191,7 +2191,7 @@ abspath (const char *name, char *apath)
|
||||
else
|
||||
{
|
||||
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
|
||||
if (STOP_SET (name[0], MAP_DIRSEP))
|
||||
if (ISDIRSEP (name[0]))
|
||||
root_len = 1;
|
||||
#endif
|
||||
memcpy (apath, name, root_len);
|
||||
@ -2200,7 +2200,7 @@ abspath (const char *name, char *apath)
|
||||
/* Get past the root, since we already copied it. */
|
||||
name += root_len;
|
||||
#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. */
|
||||
apath[2] = '.';
|
||||
@ -2220,7 +2220,7 @@ abspath (const char *name, char *apath)
|
||||
size_t len;
|
||||
|
||||
/* Skip sequence of multiple path-separators. */
|
||||
while (STOP_SET (*start, MAP_DIRSEP))
|
||||
while (ISDIRSEP (*start))
|
||||
++start;
|
||||
|
||||
/* 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. */
|
||||
if (dest > apath + root_len)
|
||||
for (--dest; ! STOP_SET (dest[-1], MAP_DIRSEP); --dest)
|
||||
for (--dest; ! ISDIRSEP (dest[-1]); --dest)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! STOP_SET (dest[-1], MAP_DIRSEP))
|
||||
if (! ISDIRSEP (dest[-1]))
|
||||
*dest++ = '/';
|
||||
|
||||
if (dest + len >= apath_limit)
|
||||
@ -2254,7 +2254,7 @@ abspath (const char *name, char *apath)
|
||||
}
|
||||
|
||||
/* 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 = '\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 */
|
||||
name = path;
|
||||
|
||||
if (*name == '/' || *name == '\\') name++;
|
||||
if (ISDIRSEP (*name))
|
||||
name++;
|
||||
|
||||
i = 0;
|
||||
while (known_os2shells[i] != NULL)
|
||||
@ -439,38 +440,30 @@ is_bourne_compatible_shell (const char *path)
|
||||
static const char *unix_shells[] = {
|
||||
"sh",
|
||||
"bash",
|
||||
"dash",
|
||||
"ksh",
|
||||
"rksh",
|
||||
"zsh",
|
||||
"ash",
|
||||
"dash",
|
||||
NULL
|
||||
};
|
||||
const char **s;
|
||||
|
||||
/* find the rightmost '/' or '\\' */
|
||||
const char *name = strrchr (path, '/');
|
||||
char *p = strrchr (path, '\\');
|
||||
/* find the last directory separator, or the beginning of the string. */
|
||||
const char *cp = path + strlen (path);
|
||||
|
||||
if (name && p) /* take the max */
|
||||
name = (name > p) ? name : p;
|
||||
else if (p) /* name must be 0 */
|
||||
name = p;
|
||||
else if (!name) /* name and p must be 0 */
|
||||
name = path;
|
||||
|
||||
if (*name == '/' || *name == '\\')
|
||||
++name;
|
||||
while (cp > path && !ISDIRSEP (cp[-1]))
|
||||
--cp;
|
||||
|
||||
/* this should be able to deal with extensions on Windows-like systems */
|
||||
for (s = unix_shells; *s != NULL; ++s)
|
||||
{
|
||||
#if defined(WINDOWS32) || defined(__MSDOS__)
|
||||
size_t len = strlen (*s);
|
||||
if ((strlen (name) >= len && STOP_SET (name[len], MAP_DOT|MAP_NUL))
|
||||
&& strncasecmp (name, *s, len) == 0)
|
||||
if ((strlen (cp) >= len && STOP_SET (cp[len], MAP_DOT|MAP_NUL))
|
||||
&& strncasecmp (cp, *s, len) == 0)
|
||||
#else
|
||||
if (strcmp (name, *s) == 0)
|
||||
if (strcmp (cp, *s) == 0)
|
||||
#endif
|
||||
return 1; /* a known unix-style shell */
|
||||
}
|
||||
@ -3053,8 +3046,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (p[1] != '\\' && p[1] != '\''
|
||||
&& !ISSPACE (p[1])
|
||||
if (p[1] != '\\' && p[1] != '\'' && !ISSPACE (p[1])
|
||||
&& strchr (sh_chars_sh, p[1]) == 0)
|
||||
/* back up one notch, to copy the backslash */
|
||||
--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,
|
||||
try whether it exists e.g.: if "/bin/sh" does not exist use
|
||||
"$UNIXROOT/bin/sh" instead. */
|
||||
if (unixroot && shell && strcmp (shell, last_shell) != 0
|
||||
&& (shell[0] == '/' || shell[0] == '\\'))
|
||||
if (unixroot && shell && ISDIRSEP (shell[0]) && !streq (shell, last_shell))
|
||||
{
|
||||
/* trying a new shell, check whether it exists */
|
||||
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. */
|
||||
tokend = search_token + strlen (search_token) - 3;
|
||||
if (((tokend == search_token
|
||||
|| (tokend > search_token
|
||||
&& (tokend[-1] == '/' || tokend[-1] == '\\')))
|
||||
|| (tokend > search_token && ISDIRSEP (tokend[-1])))
|
||||
&& !strcasecmp (tokend, "cmd"))
|
||||
|| ((tokend - 4 == search_token
|
||||
|| (tokend - 4 > search_token
|
||||
&& (tokend[-5] == '/' || tokend[-5] == '\\')))
|
||||
|| (tokend - 4 > search_token && ISDIRSEP (tokend[-5])))
|
||||
&& !strcasecmp (tokend - 4, "cmd.exe")))
|
||||
{
|
||||
batch_mode_shell = 1;
|
||||
@ -1320,7 +1318,7 @@ main (int argc, char **argv, char **envp)
|
||||
else
|
||||
{
|
||||
program = start + strlen (start);
|
||||
while (program > start && ! STOP_SET (program[-1], MAP_DIRSEP))
|
||||
while (program > start && ! ISDIRSEP (program[-1]))
|
||||
--program;
|
||||
|
||||
/* 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. */
|
||||
{
|
||||
char *p = (char *)dir + strlen (dir) - 1;
|
||||
while (p > dir && (p[0] == '/' || p[0] == '\\'))
|
||||
while (p > dir && ISDIRSEP (p[0]))
|
||||
--p;
|
||||
p[1] = '\0';
|
||||
}
|
||||
|
@ -468,6 +468,8 @@ extern int unixy_shell;
|
||||
|
||||
#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. */
|
||||
#define ISBLANK(c) STOP_SET((c),MAP_BLANK)
|
||||
/* 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
|
||||
whitespace and a left paren. If others are possible, add them
|
||||
to the string in the call to strchr. */
|
||||
while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
|
||||
while (colonp && ISDIRSEP (colonp[1]) &&
|
||||
isalpha ((unsigned char) colonp[-1]) &&
|
||||
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
|
||||
colonp = find_char_unquote (colonp + 1, ':');
|
||||
@ -1279,8 +1279,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
do {
|
||||
check_again = 0;
|
||||
/* For DOS-style paths, skip a "C:\..." or a "C:/..." */
|
||||
if (p != 0 && (p[1] == '\\' || p[1] == '/') &&
|
||||
isalpha ((unsigned char)p[-1]) &&
|
||||
if (p != 0 && ISDIRSEP (p[1]) && isalpha ((unsigned char)p[-1]) &&
|
||||
(p == p2 + 1 || strchr (" \t:(", p[-2]) != 0)) {
|
||||
p = strchr (p + 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
|
||||
doesn't allow path names with spaces. */
|
||||
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);
|
||||
#endif
|
||||
|
||||
|
@ -1564,7 +1564,7 @@ name_mtime (const char *name)
|
||||
tend--;
|
||||
if (*tend == '.' && tend > tstart)
|
||||
tend--;
|
||||
for ( ; tend > tstart && (*tend == '/' || *tend == '\\'); tend--)
|
||||
for ( ; tend > tstart && ISDIRSEP (*tend); tend--)
|
||||
*tend = '\0';
|
||||
}
|
||||
else
|
||||
|
@ -239,8 +239,7 @@ construct_vpath_list (char *pattern, char *dirpath)
|
||||
also define HAVE_DOS_PATHS would like us to recognize
|
||||
colons after the drive letter in the likes of
|
||||
"D:/foo/bar:C:/xyzzy". */
|
||||
&& (*p != PATH_SEPARATOR_CHAR
|
||||
|| (p == v + 1 && (p[1] == '/' || p[1] == '\\')))
|
||||
&& (*p != PATH_SEPARATOR_CHAR || (p == v + 1 && ISDIRSEP (p[1])))
|
||||
#else
|
||||
&& *p != PATH_SEPARATOR_CHAR
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user