bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PROPOSED PATCH] dosname: define functions to be used instead of macros


From: Paul Eggert
Subject: [PROPOSED PATCH] dosname: define functions to be used instead of macros
Date: Fri, 23 Aug 2013 14:22:18 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7

This fixes a longstanding problem with dosname: it defines macros,
which may evaluate their arguments zero times, or more than once,
and these are more problematic to deal with.  Instead, define
functions whose behavior is more predictable.  The macros
are still present for backwards compatibility.
* lib/dosname.c: New file.
* lib/dosname.h: Use _GL_INLINE_HEADER_BEGIN, _GL_INLINE_HEADER_END.
(DOSNAME_INLINE): New macro.
(FILE_SYSTEM_PREFIX_LEN, ISSLASH, IS_ABSOLUTE_FILE_NAME)
(IS_RELATIVE_FILE_NAME): Now obsolescent.  Applications should
call the new functions instead.
(file_system_prefix_len, isslash, is_absolute_file_name):
New functions.  All Gnulib uses of the obsolescent macros changed
to use these functions.
* modules/dosname (Files): Add lib/dosname.c.
(Depends-on): Add extern-inline, stdbool.
(lib_SOURCES): Add dosname.c.
---
 ChangeLog               | 19 +++++++++++++++++++
 lib/at-func.c           |  4 ++--
 lib/at-func2.c          | 18 +++++++++---------
 lib/basename-lgpl.c     | 14 +++++++-------
 lib/basename.c          |  4 ++--
 lib/canonicalize-lgpl.c | 32 ++++++++++++++++----------------
 lib/canonicalize.c      | 41 ++++++++++++++++++-----------------------
 lib/dirname-lgpl.c      | 14 +++++++-------
 lib/dosname.c           |  3 +++
 lib/dosname.h           | 43 +++++++++++++++++++++++++++++++++++++++++++
 lib/fchdir.c            |  2 +-
 lib/filenamecat-lgpl.c  |  6 +++---
 lib/linkat.c            |  4 ++--
 lib/lstat.c             |  2 +-
 lib/mkancesdirs.c       |  8 ++++----
 lib/mkdir-p.c           |  2 +-
 lib/openat.c            |  4 ++--
 lib/rename.c            | 10 +++++-----
 lib/rmdir.c             |  4 ++--
 lib/savewd.c            |  4 ++--
 lib/stat.c              |  6 +++---
 lib/unlink.c            |  6 +++---
 lib/unlinkat.c          |  4 ++--
 modules/dosname         |  4 ++++
 24 files changed, 161 insertions(+), 97 deletions(-)
 create mode 100644 lib/dosname.c

diff --git a/ChangeLog b/ChangeLog
index 7894c2d..5efff98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2013-08-23  Paul Eggert  <address@hidden>
 
+       dosname: define functions to be used instead of macros
+       This fixes a longstanding problem with dosname: it defines macros,
+       which may evaluate their arguments zero times, or more than once,
+       and these are more problematic to deal with.  Instead, define
+       functions whose behavior is more predictable.  The macros
+       are still present for backwards compatibility.
+       * lib/dosname.c: New file.
+       * lib/dosname.h: Use _GL_INLINE_HEADER_BEGIN, _GL_INLINE_HEADER_END.
+       (DOSNAME_INLINE): New macro.
+       (FILE_SYSTEM_PREFIX_LEN, ISSLASH, IS_ABSOLUTE_FILE_NAME)
+       (IS_RELATIVE_FILE_NAME): Now obsolescent.  Applications should
+       call the new functions instead.
+       (file_system_prefix_len, isslash, is_absolute_file_name):
+       New functions.  All Gnulib uses of the obsolescent macros changed
+       to use these functions.
+       * modules/dosname (Files): Add lib/dosname.c.
+       (Depends-on): Add extern-inline, stdbool.
+       (lib_SOURCES): Add dosname.c.
+
        selinux-at: omit unnecessary include
        * lib/selinux-at.c: Don't include dosname.h; not needed, since
        this source file doesn't use its macros, and subsidiary files that
diff --git a/lib/at-func.c b/lib/at-func.c
index 03c5678..6e31c7d 100644
--- a/lib/at-func.c
+++ b/lib/at-func.c
@@ -16,7 +16,7 @@
 
 /* written by Jim Meyering */
 
-#include "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
+#include "dosname.h" /* solely for definition of is_absolute_file_name */
 
 #ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
 # include <errno.h>
@@ -71,7 +71,7 @@ AT_FUNC_NAME (int fd, char const *file 
AT_FUNC_POST_FILE_PARAM_DECLS)
 {
   VALIDATE_FLAG (flag);
 
-  if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
+  if (fd == AT_FDCWD || is_absolute_file_name (file))
     return CALL_FUNC (file);
 
 #ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
diff --git a/lib/at-func2.c b/lib/at-func2.c
index bbbddc0..fafadb0 100644
--- a/lib/at-func2.c
+++ b/lib/at-func2.c
@@ -25,7 +25,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
+#include "dosname.h" /* solely for definition of is_absolute_file_name */
 #include "filenamecat.h"
 #include "openat.h"
 #include "same-inode.h"
@@ -74,20 +74,20 @@ at_func2 (int fd1, char const *file1,
      Try some optimizations to reduce fd to AT_FDCWD, or to at least
      avoid converting an absolute name or doing a double chdir.  */
 
-  if ((fd1 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file1))
-      && (fd2 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file2)))
+  if ((fd1 == AT_FDCWD || is_absolute_file_name (file1))
+      && (fd2 == AT_FDCWD || is_absolute_file_name (file2)))
     return func (file1, file2); /* Case 0-2, 4-6, 8-10.  */
 
   /* If /proc/self/fd works, we don't need any stat or chdir.  */
   {
     char proc_buf1[OPENAT_BUFFER_SIZE];
-    char *proc_file1 = ((fd1 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file1))
+    char *proc_file1 = ((fd1 == AT_FDCWD || is_absolute_file_name (file1))
                         ? (char *) file1
                         : openat_proc_name (proc_buf1, fd1, file1));
     if (proc_file1)
       {
         char proc_buf2[OPENAT_BUFFER_SIZE];
-        char *proc_file2 = ((fd2 == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file2))
+        char *proc_file2 = ((fd2 == AT_FDCWD || is_absolute_file_name (file2))
                             ? (char *) file2
                             : openat_proc_name (proc_buf2, fd2, file2));
         if (proc_file2)
@@ -116,9 +116,9 @@ at_func2 (int fd1, char const *file1,
 
   /* Cases 3, 7, 11-15 remain.  Time to normalize directory fds, if
      possible.  */
-  if (IS_ABSOLUTE_FILE_NAME (file1))
+  if (is_absolute_file_name (file1))
     fd1 = AT_FDCWD; /* Case 11 reduced to 3.  */
-  else if (IS_ABSOLUTE_FILE_NAME (file2))
+  else if (is_absolute_file_name (file2))
     fd2 = AT_FDCWD; /* Case 14 reduced to 12.  */
 
   /* Cases 3, 7, 12, 13, 15 remain.  */
@@ -200,7 +200,7 @@ at_func2 (int fd1, char const *file1,
   file1_alt = (char *) file1;
   file2_alt = (char *) file2;
 
-  if (fd1 == AT_FDCWD && !IS_ABSOLUTE_FILE_NAME (file1)) /* Case 7.  */
+  if (fd1 == AT_FDCWD && !is_absolute_file_name (file1)) /* Case 7.  */
     {
       /* It would be nicer to use:
          file1_alt = file_name_concat (xgetcwd (), file1, NULL);
@@ -224,7 +224,7 @@ at_func2 (int fd1, char const *file1,
         }
       free (cwd); /* Reduced to case 3.  */
     }
-  else if (fd2 == AT_FDCWD && !IS_ABSOLUTE_FILE_NAME (file2)) /* Case 13.  */
+  else if (fd2 == AT_FDCWD && !is_absolute_file_name (file2)) /* Case 13.  */
     {
       char *cwd = getcwd (NULL, 0);
       if (!cwd)
diff --git a/lib/basename-lgpl.c b/lib/basename-lgpl.c
index 9307e83..0996b62 100644
--- a/lib/basename-lgpl.c
+++ b/lib/basename-lgpl.c
@@ -29,16 +29,16 @@
 char *
 last_component (char const *name)
 {
-  char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
+  char const *base = name + file_system_prefix_len (name);
   char const *p;
   bool saw_slash = false;
 
-  while (ISSLASH (*base))
+  while (isslash (*base))
     base++;
 
   for (p = base; *p; p++)
     {
-      if (ISSLASH (*p))
+      if (isslash (*p))
         saw_slash = true;
       else if (saw_slash)
         {
@@ -58,17 +58,17 @@ size_t
 base_len (char const *name)
 {
   size_t len;
-  size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
+  size_t prefix_len = file_system_prefix_len (name);
 
-  for (len = strlen (name);  1 < len && ISSLASH (name[len - 1]);  len--)
+  for (len = strlen (name);  1 < len && isslash (name[len - 1]);  len--)
     continue;
 
   if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
-      && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
+      && isslash (name[0]) && isslash (name[1]) && ! name[2])
     return 2;
 
   if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
-      && len == prefix_len && ISSLASH (name[prefix_len]))
+      && len == prefix_len && isslash (name[prefix_len]))
     return prefix_len + 1;
 
   return len;
diff --git a/lib/basename.c b/lib/basename.c
index d73fd41..15bb01d 100644
--- a/lib/basename.c
+++ b/lib/basename.c
@@ -37,13 +37,13 @@ base_name (char const *name)
 
   /* Collapse a sequence of trailing slashes into one.  */
   length = base_len (base);
-  if (ISSLASH (base[length]))
+  if (isslash (base[length]))
     length++;
 
   /* On systems with drive letters, "a/b:c" must return "./b:c" rather
      than "b:c" to avoid confusion with a drive letter.  On systems
      with pure POSIX semantics, this is not an issue.  */
-  if (FILE_SYSTEM_PREFIX_LEN (base))
+  if (file_system_prefix_len (base))
     {
       char *p = xmalloc (length + 3);
       p[0] = '.';
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 6cbd2e0..0a0e313 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -147,9 +147,9 @@ __realpath (const char *name, char *resolved)
 
   /* This is always zero for Posix hosts, but can be 2 for MS-Windows
      and MS-DOS X:/foo/bar file names.  */
-  prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
+  prefix_len = file_system_prefix_len (name);
 
-  if (!IS_ABSOLUTE_FILE_NAME (name))
+  if (!is_absolute_file_name (name))
     {
       if (!__getcwd (rpath, path_max))
         {
@@ -158,7 +158,7 @@ __realpath (const char *name, char *resolved)
         }
       dest = strchr (rpath, '\0');
       start = name;
-      prefix_len = FILE_SYSTEM_PREFIX_LEN (rpath);
+      prefix_len = file_system_prefix_len (rpath);
     }
   else
     {
@@ -171,7 +171,7 @@ __realpath (const char *name, char *resolved)
       *dest++ = '/';
       if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
         {
-          if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
+          if (isslash (name[1]) && !isslash (name[2]) && !prefix_len)
             *dest++ = '/';
           *dest = '\0';
         }
@@ -188,11 +188,11 @@ __realpath (const char *name, char *resolved)
       int n;
 
       /* Skip sequence of multiple path-separators.  */
-      while (ISSLASH (*start))
+      while (isslash (*start))
         ++start;
 
       /* Find end of path component.  */
-      for (end = start; *end && !ISSLASH (*end); ++end)
+      for (end = start; *end && !isslash (*end); ++end)
         /* Nothing.  */;
 
       if (end - start == 0)
@@ -203,18 +203,18 @@ __realpath (const char *name, char *resolved)
         {
           /* Back up to previous component, ignore if at root already.  */
           if (dest > rpath + prefix_len + 1)
-            for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
+            for (--dest; dest > rpath && !isslash (dest[-1]); --dest)
               continue;
           if (DOUBLE_SLASH_IS_DISTINCT_ROOT
               && dest == rpath + 1 && !prefix_len
-              && ISSLASH (*dest) && !ISSLASH (dest[1]))
+              && isslash (*dest) && !isslash (dest[1]))
             dest++;
         }
       else
         {
           size_t new_size;
 
-          if (!ISSLASH (dest[-1]))
+          if (!isslash (dest[-1]))
             *dest++ = '/';
 
           if (dest + (end - start) >= rpath_limit)
@@ -315,9 +315,9 @@ __realpath (const char *name, char *resolved)
               memmove (&extra_buf[n], end, len + 1);
               name = end = memcpy (extra_buf, buf, n);
 
-              if (IS_ABSOLUTE_FILE_NAME (buf))
+              if (is_absolute_file_name (buf))
                 {
-                  size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
+                  size_t pfxlen = file_system_prefix_len (buf);
 
                   if (pfxlen)
                     memcpy (rpath, buf, pfxlen);
@@ -325,7 +325,7 @@ __realpath (const char *name, char *resolved)
                   *dest++ = '/'; /* It's an absolute symlink */
                   if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
                     {
-                      if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
+                      if (isslash (buf[1]) && !isslash (buf[2]) && !pfxlen)
                         *dest++ = '/';
                       *dest = '\0';
                     }
@@ -337,10 +337,10 @@ __realpath (const char *name, char *resolved)
                   /* Back up to previous component, ignore if at root
                      already: */
                   if (dest > rpath + prefix_len + 1)
-                    for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
+                    for (--dest; dest > rpath && !isslash (dest[-1]); --dest)
                       continue;
                   if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
-                      && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
+                      && isslash (*dest) && !isslash (dest[1]) && !prefix_len)
                     dest++;
                 }
             }
@@ -351,10 +351,10 @@ __realpath (const char *name, char *resolved)
             }
         }
     }
-  if (dest > rpath + prefix_len + 1 && ISSLASH (dest[-1]))
+  if (dest > rpath + prefix_len + 1 && isslash (dest[-1]))
     --dest;
   if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && !prefix_len
-      && ISSLASH (*dest) && !ISSLASH (dest[1]))
+      && isslash (*dest) && !isslash (dest[1]))
     dest++;
   *dest = '\0';
 
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
index 6a39a02..97eca6a 100644
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -44,12 +44,6 @@
 # define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
 #endif
 
-#if ISSLASH ('\\')
-# define SLASHES "/\\"
-#else
-# define SLASHES "/"
-#endif
-
 #if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS)      \
       || GNULIB_CANONICALIZE_LGPL)
 /* Return the canonical absolute name of file NAME.  A canonical name
@@ -131,9 +125,9 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
 
   /* This is always zero for Posix hosts, but can be 2 for MS-Windows
      and MS-DOS X:/foo/bar file names.  */
-  prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
+  prefix_len = file_system_prefix_len (name);
 
-  if (!IS_ABSOLUTE_FILE_NAME (name))
+  if (!is_absolute_file_name (name))
     {
       rname = xgetcwd ();
       if (!rname)
@@ -151,7 +145,7 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
           rname_limit = dest;
         }
       start = name;
-      prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
+      prefix_len = file_system_prefix_len (rname);
     }
   else
     {
@@ -166,7 +160,7 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
       *dest++ = '/';
       if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
         {
-          if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
+          if (isslash (name[1]) && !isslash (name[2]) && !prefix_len)
             *dest++ = '/';
           *dest = '\0';
         }
@@ -176,11 +170,11 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
   for ( ; *start; start = end)
     {
       /* Skip sequence of multiple file name separators.  */
-      while (ISSLASH (*start))
+      while (isslash (*start))
         ++start;
 
       /* Find end of component.  */
-      for (end = start; *end && !ISSLASH (*end); ++end)
+      for (end = start; *end && !isslash (*end); ++end)
         /* Nothing.  */;
 
       if (end - start == 0)
@@ -191,17 +185,17 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
         {
           /* Back up to previous component, ignore if at root already.  */
           if (dest > rname + prefix_len + 1)
-            for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
+            for (--dest; dest > rname && !isslash (dest[-1]); --dest)
               continue;
           if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
-              && !prefix_len && ISSLASH (*dest) && !ISSLASH (dest[1]))
+              && !prefix_len && isslash (*dest) && !isslash (dest[1]))
             dest++;
         }
       else
         {
           struct stat st;
 
-          if (!ISSLASH (dest[-1]))
+          if (!isslash (dest[-1]))
             *dest++ = '/';
 
           if (dest + (end - start) >= rname_limit)
@@ -237,7 +231,8 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
                 goto error;
               if (can_mode == CAN_ALL_BUT_LAST)
                 {
-                  if (end[strspn (end, SLASHES)] || saved_errno != ENOENT)
+                  if (end[strspn (end, isslash ('\\') ? "/\\" : "/")]
+                      || saved_errno != ENOENT)
                     goto error;
                   continue;
                 }
@@ -289,9 +284,9 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
               memmove (&extra_buf[n], end, len + 1);
               name = end = memcpy (extra_buf, buf, n);
 
-              if (IS_ABSOLUTE_FILE_NAME (buf))
+              if (is_absolute_file_name (buf))
                 {
-                  size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
+                  size_t pfxlen = file_system_prefix_len (buf);
 
                   if (pfxlen)
                     memcpy (rname, buf, pfxlen);
@@ -299,7 +294,7 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
                   *dest++ = '/'; /* It's an absolute symlink */
                   if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
                     {
-                      if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
+                      if (isslash (buf[1]) && !isslash (buf[2]) && !pfxlen)
                         *dest++ = '/';
                       *dest = '\0';
                     }
@@ -311,10 +306,10 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
                   /* Back up to previous component, ignore if at root
                      already: */
                   if (dest > rname + prefix_len + 1)
-                    for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
+                    for (--dest; dest > rname && !isslash (dest[-1]); --dest)
                       continue;
                   if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
-                      && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
+                      && isslash (*dest) && !isslash (dest[1]) && !prefix_len)
                     dest++;
                 }
 
@@ -330,10 +325,10 @@ canonicalize_filename_mode (const char *name, 
canonicalize_mode_t can_mode)
             }
         }
     }
-  if (dest > rname + prefix_len + 1 && ISSLASH (dest[-1]))
+  if (dest > rname + prefix_len + 1 && isslash (dest[-1]))
     --dest;
   if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && !prefix_len
-      && ISSLASH (*dest) && !ISSLASH (dest[1]))
+      && isslash (*dest) && !isslash (dest[1]))
     dest++;
   *dest = '\0';
   if (rname_limit != dest + 1)
diff --git a/lib/dirname-lgpl.c b/lib/dirname-lgpl.c
index 82f6630..71b3329 100644
--- a/lib/dirname-lgpl.c
+++ b/lib/dirname-lgpl.c
@@ -31,23 +31,23 @@
 size_t
 dir_len (char const *file)
 {
-  size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
+  size_t prefix_length = file_system_prefix_len (file);
   size_t length;
 
   /* Advance prefix_length beyond important leading slashes.  */
   prefix_length += (prefix_length != 0
                     ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
-                       && ISSLASH (file[prefix_length]))
-                    : (ISSLASH (file[0])
+                       && isslash (file[prefix_length]))
+                    : (isslash (file[0])
                        ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
-                           && ISSLASH (file[1]) && ! ISSLASH (file[2])
+                           && isslash (file[1]) && ! isslash (file[2])
                            ? 2 : 1))
                        : 0));
 
   /* Strip the basename and any redundant slashes before it.  */
   for (length = last_component (file) - file;
        prefix_length < length; length--)
-    if (! ISSLASH (file[length - 1]))
+    if (! isslash (file[length - 1]))
       break;
   return length;
 }
@@ -73,8 +73,8 @@ mdir_name (char const *file)
   size_t length = dir_len (file);
   bool append_dot = (length == 0
                      || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
-                         && length == FILE_SYSTEM_PREFIX_LEN (file)
-                         && file[2] != '\0' && ! ISSLASH (file[2])));
+                         && length == file_system_prefix_len (file)
+                         && file[2] != '\0' && ! isslash (file[2])));
   char *dir = malloc (length + append_dot + 1);
   if (!dir)
     return NULL;
diff --git a/lib/dosname.c b/lib/dosname.c
new file mode 100644
index 0000000..a30bfab
--- /dev/null
+++ b/lib/dosname.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#define DOSNAME_INLINE _GL_EXTERN_INLINE
+#include "dosname.h"
diff --git a/lib/dosname.h b/lib/dosname.h
index ba63ce4..603f275 100644
--- a/lib/dosname.h
+++ b/lib/dosname.h
@@ -20,6 +20,20 @@
 #ifndef _DOSNAME_H
 #define _DOSNAME_H
 
+#include <stdbool.h>
+#include <stddef.h>
+
+_GL_INLINE_HEADER_BEGIN
+#ifndef DOSNAME_INLINE
+# define DOSNAME_INLINE _GL_INLINE
+#endif
+
+/* Define macros for backward compatibility with older versions of
+   this header file.  New applications should avoid the obsolescent
+   macros FILE_SYSTEM_PREFIX_LEN, ISSLASH, IS_ABSOLUTE_FILE_NAME, and
+   IS_RELATIVE_FILE_NAME.  The macros might evaluate their arguments
+   more than once, or might not evaluate them at all.  */
+
 #if (defined _WIN32 || defined __WIN32__ ||     \
      defined __MSDOS__ || defined __CYGWIN__ || \
      defined __EMX__ || defined __DJGPP__)
@@ -50,4 +64,33 @@
 #endif
 #define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
 
+/* Return the length of the file system prefix length of FILENAME.
+   Always zero on POSIXish systems.  */
+
+DOSNAME_INLINE size_t
+file_system_prefix_len (char const *filename)
+{
+  return FILE_SYSTEM_PREFIX_LEN (filename);
+}
+
+/* Return true if C is a directory separator.  Equivalent to C == '/'
+   on POSIXish systems.  */
+
+DOSNAME_INLINE bool
+isslash (char c)
+{
+  return ISSLASH (c);
+}
+
+/* Return true if F is an absolute file name, i.e., not relative to
+   the working directory.  Equivalent to F[0] == '/' on POSIXish systems.  */
+
+DOSNAME_INLINE bool
+is_absolute_file_name (char const *f)
+{
+  return IS_ABSOLUTE_FILE_NAME (f);
+}
+
+_GL_INLINE_HEADER_END
+
 #endif /* DOSNAME_H_ */
diff --git a/lib/fchdir.c b/lib/fchdir.c
index 36a8e35..6c42570 100644
--- a/lib/fchdir.c
+++ b/lib/fchdir.c
@@ -92,7 +92,7 @@ get_name (char const *dir)
   char *result;
   int saved_errno;
 
-  if (IS_ABSOLUTE_FILE_NAME (dir))
+  if (is_absolute_file_name (dir))
     return strdup (dir);
 
   /* We often encounter "."; treat it as a special case.  */
diff --git a/lib/filenamecat-lgpl.c b/lib/filenamecat-lgpl.c
index 60c4988..8b379af 100644
--- a/lib/filenamecat-lgpl.c
+++ b/lib/filenamecat-lgpl.c
@@ -37,7 +37,7 @@
 static char const * _GL_ATTRIBUTE_PURE
 longest_relative_suffix (char const *f)
 {
-  for (f += FILE_SYSTEM_PREFIX_LEN (f); ISSLASH (*f); f++)
+  for (f += file_system_prefix_len (f); isslash (*f); f++)
     continue;
   return f;
 }
@@ -63,7 +63,7 @@ mfile_name_concat (char const *dir, char const *abase, char 
**base_in_result)
   char const *dirbase = last_component (dir);
   size_t dirbaselen = base_len (dirbase);
   size_t dirlen = dirbase - dir + dirbaselen;
-  size_t needs_separator = (dirbaselen && ! ISSLASH (dirbase[dirbaselen - 1]));
+  size_t needs_separator = (dirbaselen && ! isslash (dirbase[dirbaselen - 1]));
 
   char const *base = longest_relative_suffix (abase);
   size_t baselen = strlen (base);
@@ -79,7 +79,7 @@ mfile_name_concat (char const *dir, char const *abase, char 
**base_in_result)
   p += needs_separator;
 
   if (base_in_result)
-    *base_in_result = p - IS_ABSOLUTE_FILE_NAME (abase);
+    *base_in_result = p - is_absolute_file_name (abase);
 
   p = mempcpy (p, base, baselen);
   *p = '\0';
diff --git a/lib/linkat.c b/lib/linkat.c
index f358b2d..ae70894 100644
--- a/lib/linkat.c
+++ b/lib/linkat.c
@@ -112,7 +112,7 @@ link_follow (char const *file1, char const *file2)
      intermediate symlinks, just the basename of each iteration.  */
   while (i-- && (target = areadlink (name)))
     {
-      if (IS_ABSOLUTE_FILE_NAME (target))
+      if (is_absolute_file_name (target))
         {
           if (name != file1)
             free (name);
@@ -232,7 +232,7 @@ linkat_follow (int fd1, char const *file1, int fd2, char 
const *file2)
   /* There is no realpathat.  */
   while (i-- && (target = areadlinkat (fd1, name)))
     {
-      if (IS_ABSOLUTE_FILE_NAME (target))
+      if (is_absolute_file_name (target))
         {
           if (name != file1)
             free (name);
diff --git a/lib/lstat.c b/lib/lstat.c
index 1a613a8..060f651 100644
--- a/lib/lstat.c
+++ b/lib/lstat.c
@@ -73,7 +73,7 @@ rpl_lstat (const char *file, struct stat *sbuf)
     return lstat_result;
 
   /* This replacement file can blindly check against '/' rather than
-     using the ISSLASH macro, because all platforms with '\\' either
+     using the isslash function, because all platforms with '\\' either
      lack symlinks (mingw) or have working lstat (cygwin) and thus do
      not compile this file.  0 len should have already been filtered
      out above, with a failure return of ENOENT.  */
diff --git a/lib/mkancesdirs.c b/lib/mkancesdirs.c
index 0c60a93..ff51d8b 100644
--- a/lib/mkancesdirs.c
+++ b/lib/mkancesdirs.c
@@ -77,7 +77,7 @@ mkancesdirs (char *file, struct savewd *wd,
      been processed.  */
   char *component = file;
 
-  char *p = file + FILE_SYSTEM_PREFIX_LEN (file);
+  char *p = file + file_system_prefix_len (file);
   char c;
   bool made_dir = false;
 
@@ -88,12 +88,12 @@ mkancesdirs (char *file, struct savewd *wd,
      point to its start and SEP point just after its end.  */
 
   while ((c = *p++))
-    if (ISSLASH (*p))
+    if (isslash (*p))
       {
-        if (! ISSLASH (c))
+        if (! isslash (c))
           sep = p;
       }
-    else if (ISSLASH (c) && *p && sep)
+    else if (isslash (c) && *p && sep)
       {
         /* Don't bother to make or test for "." since it does not
            affect the algorithm.  */
diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c
index b86aa34..80257a4 100644
--- a/lib/mkdir-p.c
+++ b/lib/mkdir-p.c
@@ -93,7 +93,7 @@ make_dir_parents (char *dir,
                   gid_t group,
                   bool preserve_existing)
 {
-  int mkdir_errno = (IS_ABSOLUTE_FILE_NAME (dir) ? 0 : savewd_errno (wd));
+  int mkdir_errno = (is_absolute_file_name (dir) ? 0 : savewd_errno (wd));
 
   if (mkdir_errno == 0)
     {
diff --git a/lib/openat.c b/lib/openat.c
index fd1ff91..934c8d8 100644
--- a/lib/openat.c
+++ b/lib/openat.c
@@ -141,7 +141,7 @@ rpl_openat (int dfd, char const *filename, int flags, ...)
 
 #else /* !HAVE_OPENAT */
 
-# include "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
+# include "dosname.h" /* solely for definition of is_absolute_file_name */
 # include "openat-priv.h"
 # include "save-cwd.h"
 
@@ -193,7 +193,7 @@ openat_permissive (int fd, char const *file, int flags, 
mode_t mode,
   int err;
   bool save_ok;
 
-  if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
+  if (fd == AT_FDCWD || is_absolute_file_name (file))
     return open (file, flags, mode);
 
   {
diff --git a/lib/rename.c b/lib/rename.c
index 3e463ea..a68282a 100644
--- a/lib/rename.c
+++ b/lib/rename.c
@@ -86,8 +86,8 @@ rpl_rename (char const *src, char const *dst)
      into a directory, give up now.  Otherwise, strip trailing slashes
      before calling rename.  There are no symlinks on mingw, so stat
      works instead of lstat.  */
-  src_slash = ISSLASH (src[src_len - 1]);
-  dst_slash = ISSLASH (dst[dst_len - 1]);
+  src_slash = isslash (src[src_len - 1]);
+  dst_slash = isslash (dst[dst_len - 1]);
   if (stat (src, &src_st))
     return -1;
   if (stat (dst, &dst_st))
@@ -123,7 +123,7 @@ rpl_rename (char const *src, char const *dst)
       char *dst_temp;
       if (!cwd || chdir (cwd))
         return -1;
-      if (IS_ABSOLUTE_FILE_NAME (src))
+      if (is_absolute_file_name (src))
         {
           dst_temp = chdir (dst) ? NULL : getcwd (NULL, 0);
           src_temp = chdir (src) ? NULL : getcwd (NULL, 0);
@@ -131,7 +131,7 @@ rpl_rename (char const *src, char const *dst)
       else
         {
           src_temp = chdir (src) ? NULL : getcwd (NULL, 0);
-          if (!IS_ABSOLUTE_FILE_NAME (dst) && chdir (cwd))
+          if (!is_absolute_file_name (dst) && chdir (cwd))
             abort ();
           dst_temp = chdir (dst) ? NULL : getcwd (NULL, 0);
         }
@@ -147,7 +147,7 @@ rpl_rename (char const *src, char const *dst)
         }
       src_len = strlen (src_temp);
       if (strncmp (src_temp, dst_temp, src_len) == 0
-          && (ISSLASH (dst_temp[src_len]) || dst_temp[src_len] == '\0'))
+          && (isslash (dst_temp[src_len]) || dst_temp[src_len] == '\0'))
         {
           error = dst_temp[src_len];
           free (src_temp);
diff --git a/lib/rmdir.c b/lib/rmdir.c
index a8d907e..d7b8c75 100644
--- a/lib/rmdir.c
+++ b/lib/rmdir.c
@@ -36,9 +36,9 @@ rpl_rmdir (char const *dir)
   /* Work around cygwin 1.5.x bug where rmdir("dir/./") succeeds.  */
   size_t len = strlen (dir);
   int result;
-  while (len && ISSLASH (dir[len - 1]))
+  while (len && isslash (dir[len - 1]))
     len--;
-  if (len && dir[len - 1] == '.' && (1 == len || ISSLASH (dir[len - 2])))
+  if (len && dir[len - 1] == '.' && (1 == len || isslash (dir[len - 2])))
     {
       errno = EINVAL;
       return -1;
diff --git a/lib/savewd.c b/lib/savewd.c
index 728bc8a..d2c141e 100644
--- a/lib/savewd.c
+++ b/lib/savewd.c
@@ -274,7 +274,7 @@ savewd_process_files (int n_files, char **file,
   savewd_init (&wd);
 
   for (last_relative = n_files - 1; 0 <= last_relative; last_relative--)
-    if (! IS_ABSOLUTE_FILE_NAME (file[last_relative]))
+    if (! is_absolute_file_name (file[last_relative]))
       break;
 
   for (; i < last_relative; i++)
@@ -286,7 +286,7 @@ savewd_process_files (int n_files, char **file,
             exit_status = s;
         }
 
-      if (! IS_ABSOLUTE_FILE_NAME (file[i + 1]))
+      if (! is_absolute_file_name (file[i + 1]))
         {
           int r = savewd_restore (&wd, exit_status);
           if (exit_status < r)
diff --git a/lib/stat.c b/lib/stat.c
index f888130..f834886 100644
--- a/lib/stat.c
+++ b/lib/stat.c
@@ -86,7 +86,7 @@ rpl_stat (char const *name, struct stat *st)
   if (result == 0 && !S_ISDIR (st->st_mode))
     {
       size_t len = strlen (name);
-      if (ISSLASH (name[len - 1]))
+      if (isslash (name[len - 1]))
         {
           errno = ENOTDIR;
           return -1;
@@ -115,10 +115,10 @@ rpl_stat (char const *name, struct stat *st)
       else if (len)
         {
           strcpy (fixed_name, name);
-          if (ISSLASH (fixed_name[len - 1]))
+          if (isslash (fixed_name[len - 1]))
             {
               check_dir = true;
-              while (len && ISSLASH (fixed_name[len - 1]))
+              while (len && isslash (fixed_name[len - 1]))
                 fixed_name[--len] = '\0';
               if (!len)
                 fixed_name[0] = '/';
diff --git a/lib/unlink.c b/lib/unlink.c
index fdd5565..bbf21b6 100644
--- a/lib/unlink.c
+++ b/lib/unlink.c
@@ -37,7 +37,7 @@ rpl_unlink (char const *name)
   /* Work around Solaris 9 bug where unlink("file/") succeeds.  */
   size_t len = strlen (name);
   int result = 0;
-  if (len && ISSLASH (name[len - 1]))
+  if (len && isslash (name[len - 1]))
     {
       /* We can't unlink(2) something if it doesn't exist.  If it does
          exist, then it resolved to a directory, due to the trailing
@@ -70,7 +70,7 @@ rpl_unlink (char const *name)
               return -1;
             }
           memcpy (short_name, name, len);
-          while (len && ISSLASH (short_name[len - 1]))
+          while (len && isslash (short_name[len - 1]))
             short_name[--len] = '\0';
           if (len && (lstat (short_name, &st) || S_ISLNK (st.st_mode)))
             {
@@ -85,7 +85,7 @@ rpl_unlink (char const *name)
     {
 #if UNLINK_PARENT_BUG
       if (len >= 2 && name[len - 1] == '.' && name[len - 2] == '.'
-          && (len == 2 || ISSLASH (name[len - 3])))
+          && (len == 2 || isslash (name[len - 3])))
         {
           errno = EISDIR; /* could also use EPERM */
           return -1;
diff --git a/lib/unlinkat.c b/lib/unlinkat.c
index 6726372..0b4be66 100644
--- a/lib/unlinkat.c
+++ b/lib/unlinkat.c
@@ -49,7 +49,7 @@ rpl_unlinkat (int fd, char const *name, int flag)
     return unlinkat (fd, name, flag);
 
   len = strlen (name);
-  if (len && ISSLASH (name[len - 1]))
+  if (len && isslash (name[len - 1]))
     {
       /* See the lengthy comment in unlink.c why we disobey the POSIX
          rule of letting unlink("link-to-dir/") attempt to unlink a
@@ -66,7 +66,7 @@ rpl_unlinkat (int fd, char const *name, int flag)
               return -1;
             }
           memcpy (short_name, name, len);
-          while (len && ISSLASH (short_name[len - 1]))
+          while (len && isslash (short_name[len - 1]))
             short_name[--len] = '\0';
           if (len && (lstatat (fd, short_name, &st) || S_ISLNK (st.st_mode)))
             {
diff --git a/modules/dosname b/modules/dosname
index 0e8703c..cfe9b8c 100644
--- a/modules/dosname
+++ b/modules/dosname
@@ -2,13 +2,17 @@ Description:
 Macros for porting to systems with DOS-style file names.
 
 Files:
+lib/dosname.c
 lib/dosname.h
 
 Depends-on:
+extern-inline
+stdbool
 
 configure.ac:
 
 Makefile.am:
+lib_SOURCES += dosname.c
 
 Include:
 "dosname.h"
-- 
1.7.11.7




reply via email to

[Prev in Thread] Current Thread [Next in Thread]