]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Add ISDIRSEP() helper macro and use it
authorPaul Smith <psmith@gnu.org>
Tue, 18 Oct 2022 03:36:36 +0000 (23:36 -0400)
committerPaul Smith <psmith@gnu.org>
Tue, 18 Oct 2022 18:20:44 +0000 (14:20 -0400)
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.

src/dir.c
src/file.c
src/function.c
src/job.c
src/main.c
src/makeint.h
src/read.c
src/remake.c
src/vpath.c

index cca968c70f6b252a48d35703070d17c24ffca9a5..ec7bb20722cdbc178d1701706482478f3bcc7747 100644 (file)
--- a/src/dir.c
+++ b/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];
 
index 62b8dd000908590c75a3b27420deef6817d40f56..d2ee2c68c69d7f1d6dec0748a3101f7ad9e52e0f 100644 (file)
@@ -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;
     }
index fb4ffbc8ed0a606c963506b11aee43ce928dd0b0..61164dcba6f090b49a18a286853c39619c6b14e3 100644 (file)
@@ -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';
index 4bbdc99068a245968c14f79203c2acec3502af50..7f855e95cab776abce3909fb217898be654029aa 100644 (file)
--- a/src/job.c
+++ b/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, '\\');
-
-  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;
+  /* find the last directory separator, or the beginning of the string.  */
+  const char *cp = path + strlen (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);
index 8adce3a56bf47dbe656a2c4f7d9a6bad7300d181..41490f4e76a2a8da14639c1291aea6ebcd9fa2de 100644 (file)
@@ -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';
           }
index 276def9a02d3e06fca6f025baa318bbb3d0737f3..8ab7ea84e19bc32d8a7a37630ea34d65a973049d 100644 (file)
@@ -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.  */
index b13d1dc89eeeb08b10fa0565a5806ac8e6a04435..3336fb83405086d030a79d96ca5b4e4e012828f3 100644 (file)
@@ -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
 
index e536c8b5b536f2de35de7620071064df440528a3..57f1042752f4d406901ce8c525d1850928805a36 100644 (file)
@@ -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
index 203fca1b61dd8fd27416b64145b3c017a9129905..343e344628f1426382e421c5273e4d55792ef983 100644 (file)
@@ -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