bug-gnulib
[Top][All Lists]
Advanced

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

Re: filename.h and dosname.h define identical macros


From: Bruno Haible
Subject: Re: filename.h and dosname.h define identical macros
Date: Sat, 28 Mar 2020 14:07:52 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-174-generic; KDE/5.18.0; x86_64; ; )

Hi Tim,

> dosname.h (included by dirname.h) and filename.h overlap in macro
> definition. This currently results in an error here:
> ...
> [-Werror,-Wmacro-redefined]

Please don't say that it's an error, when in fact it's a warning, and
only the build system of your package (or your own way to invoke configure)
turned it into an error.

I process reports about errors with high priority. Reports about warnings
have a lower priority, 1. because you have the option to just ignore the
error, 2. because we cannot avoid warnings on all platforms.

> But maybe it's time to consolidate the code, as we have e.g.
> _IS_DRIVE_LETTER(C) and HAS_DEVICE(P) doing the same with slightly
> different  implementations ?

Yes, you're right. While 'filename' is a better module name than 'dosname'
(because nowadays we care more about Windows than about DOS), some details
in dosname.h are better done than in filename.h. So, let me do it in two steps:
  1. Copy all interesting stuff from dosname.h to filename.h.
  2. Redirect from dosname.h to filename.h.

Part 1:


2020-03-28  Bruno Haible  <address@hidden>

        filename: Copy some definitions from module 'dosname'.
        * lib/filename.h: Include <string.h>, for IS_FILE_NAME_WITH_DIR.
        (HAS_DEVICE): Document macro.
        (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE): New macro.
        (IS_ABSOLUTE_FILE_NAME): Consider
        FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE.
        (IS_RELATIVE_FILE_NAME, IS_FILE_NAME_WITH_DIR): New macros.
        (IS_ABSOLUTE_PATH, IS_PATH_WITH_DIR): Define as deprecated aliases.
        * lib/relocatable.c (IS_FILE_NAME_WITH_DIR): Renamed from
        IS_PATH_WITH_DIR.
        (DllMain): Update.
        * lib/progreloc.c (IS_FILE_NAME_WITH_DIR): Renamed from
        IS_PATH_WITH_DIR.
        (find_executable): Update.
        * NEWS: Document the deprecations.

diff --git a/NEWS b/NEWS
index 4b9a983..3ec49f3 100644
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,11 @@ User visible incompatible changes
 
 Date        Modules         Changes
 
+2020-03-28  filename        The macro IS_ABSOLUTE_PATH is deprecated. Use
+                            IS_ABSOLUTE_FILE_NAME instead.
+                            The macro IS_PATH_WITH_DIR is deprecated. Use
+                            IS_FILE_NAME_WITH_DIR instead.
+
 2020-02-22  fchownat        This module no longer defines the functions
                             'chownat' and 'lchownat'.  Program that need these
                             functions should add the module 'chownat' to the
diff --git a/lib/filename.h b/lib/filename.h
index d4c7020..4598fb1 100644
--- a/lib/filename.h
+++ b/lib/filename.h
@@ -14,38 +14,94 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 
+/* From Paul Eggert and Jim Meyering.  */
+
 #ifndef _FILENAME_H
 #define _FILENAME_H
 
+#include <string.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 
-/* Pathname support.
-   ISSLASH(C)           tests whether C is a directory separator character.
-   IS_ABSOLUTE_PATH(P)  tests whether P is an absolute path.  If it is not,
-                        it may be concatenated to a directory pathname.
-   IS_PATH_WITH_DIR(P)  tests whether P contains a directory specification.
+/* Filename support.
+   ISSLASH(C)                  tests whether C is a directory separator
+                               character.
+   HAS_DEVICE(Filename)        tests whether Filename contains a device
+                               specification.
+   FILE_SYSTEM_PREFIX_LEN(Filename)  length of the device specification
+                                     at the beginning of Filename,
+                                     index of the part consisting of
+                                     alternating components and slashes.
+   FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+                               1 when a non-empty device specification
+                               can be followed by an empty or relative
+                               part,
+                               0 when a non-empty device specification
+                               must be followed by a slash,
+                               0 when device specification don't exist.
+   IS_ABSOLUTE_FILE_NAME(Filename)
+                               tests whether Filename is independent of
+                               any notion of "current directory".
+   IS_RELATIVE_FILE_NAME(Filename)
+                               tests whether Filename may be concatenated
+                               to a directory filename.
+   Note: On native Windows, OS/2, DOS, "c:" is neither an absolute nor a
+   relative file name!
+   IS_FILE_NAME_WITH_DIR(Filename)  tests whether Filename contains a device
+                                    or directory specification.
  */
-#if defined _WIN32 || defined __CYGWIN__ || defined __EMX__ || defined 
__DJGPP__
+#if defined _WIN32 || defined __CYGWIN__ \
+    || defined __EMX__ || defined __MSDOS__ || defined __DJGPP__
   /* Native Windows, Cygwin, OS/2, DOS */
 # define ISSLASH(C) ((C) == '/' || (C) == '\\')
-# define HAS_DEVICE(P) \
-    ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
-     && (P)[1] == ':')
-# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
-# define IS_PATH_WITH_DIR(P) \
-    (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
-# define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
+  /* Internal macro: Tests whether a character is a drive letter.  */
+# define _IS_DRIVE_LETTER(C) \
+    (((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z'))
+  /* Help the compiler optimizing it.  This assumes ASCII.  */
+# undef _IS_DRIVE_LETTER
+# define _IS_DRIVE_LETTER(C) \
+    (((unsigned int) (C) | ('a' - 'A')) - 'a' <= 'z' - 'a')
+# define HAS_DEVICE(Filename) \
+    (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':')
+# define FILE_SYSTEM_PREFIX_LEN(Filename) (HAS_DEVICE (Filename) ? 2 : 0)
+# ifdef __CYGWIN__
+#  define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
+# else
+   /* On native Windows, OS/2, DOS, the system has the notion of a
+      "current directory" on each drive.  */
+#  define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1
+# endif
+# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+#  define IS_ABSOLUTE_FILE_NAME(Filename) \
+     ISSLASH ((Filename)[FILE_SYSTEM_PREFIX_LEN (Filename)])
+# else
+#  define IS_ABSOLUTE_FILE_NAME(Filename) \
+     (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename))
+# endif
+# define IS_RELATIVE_FILE_NAME(Filename) \
+    (! (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename)))
+# define IS_FILE_NAME_WITH_DIR(Filename) \
+    (strchr ((Filename), '/') != NULL || strchr ((Filename), '\\') != NULL \
+     || HAS_DEVICE (Filename))
 #else
   /* Unix */
 # define ISSLASH(C) ((C) == '/')
-# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
-# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
-# define FILE_SYSTEM_PREFIX_LEN(P) 0
+# define HAS_DEVICE(Filename) ((void) (Filename), 0)
+# define FILE_SYSTEM_PREFIX_LEN(Filename) ((void) (Filename), 0)
+# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
+# define IS_ABSOLUTE_FILE_NAME(Filename) ISSLASH ((Filename)[0])
+# define IS_RELATIVE_FILE_NAME(Filename) (! ISSLASH ((Filename)[0]))
+# define IS_FILE_NAME_WITH_DIR(Filename) (strchr ((Filename), '/') != NULL)
 #endif
 
+/* Deprecated macros.  For backward compatibility with old users of the
+   'filename' module.  */
+#define IS_ABSOLUTE_PATH IS_ABSOLUTE_FILE_NAME
+#define IS_PATH_WITH_DIR IS_FILE_NAME_WITH_DIR
+
 
 #ifdef __cplusplus
 }
diff --git a/lib/progreloc.c b/lib/progreloc.c
index 2acf3fb..b555211 100644
--- a/lib/progreloc.c
+++ b/lib/progreloc.c
@@ -76,8 +76,8 @@
 extern char * canonicalize_file_name (const char *name);
 
 /* Pathname support.
-   ISSLASH(C)           tests whether C is a directory separator character.
-   IS_PATH_WITH_DIR(P)  tests whether P contains a directory specification.
+   ISSLASH(C)                tests whether C is a directory separator 
character.
+   IS_FILE_NAME_WITH_DIR(P)  tests whether P contains a directory 
specification.
  */
 #if (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ || defined 
__DJGPP__
   /* Native Windows, OS/2, DOS */
@@ -85,13 +85,13 @@ extern char * canonicalize_file_name (const char *name);
 # define HAS_DEVICE(P) \
     ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
      && (P)[1] == ':')
-# define IS_PATH_WITH_DIR(P) \
+# define IS_FILE_NAME_WITH_DIR(P) \
     (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
 # define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
 #else
   /* Unix */
 # define ISSLASH(C) ((C) == '/')
-# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
+# define IS_FILE_NAME_WITH_DIR(P) (strchr (P, '/') != NULL)
 # define FILE_SYSTEM_PREFIX_LEN(P) 0
 #endif
 
@@ -206,7 +206,7 @@ find_executable (const char *argv0)
   int length = GetModuleFileName (NULL, location, sizeof (location));
   if (length < 0)
     return NULL;
-  if (!IS_PATH_WITH_DIR (location))
+  if (!IS_FILE_NAME_WITH_DIR (location))
     /* Shouldn't happen.  */
     return NULL;
   return xstrdup (location);
diff --git a/lib/relocatable.c b/lib/relocatable.c
index 7e81c83..e4b867b 100644
--- a/lib/relocatable.c
+++ b/lib/relocatable.c
@@ -74,8 +74,8 @@
 #define true 1
 
 /* Pathname support.
-   ISSLASH(C)           tests whether C is a directory separator character.
-   IS_PATH_WITH_DIR(P)  tests whether P contains a directory specification.
+   ISSLASH(C)                tests whether C is a directory separator 
character.
+   IS_FILE_NAME_WITH_DIR(P)  tests whether P contains a directory 
specification.
  */
 #if (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ || defined 
__DJGPP__
   /* Native Windows, OS/2, DOS */
@@ -83,13 +83,13 @@
 # define HAS_DEVICE(P) \
     ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
      && (P)[1] == ':')
-# define IS_PATH_WITH_DIR(P) \
+# define IS_FILE_NAME_WITH_DIR(P) \
     (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
 # define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
 #else
   /* Unix */
 # define ISSLASH(C) ((C) == '/')
-# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
+# define IS_FILE_NAME_WITH_DIR(P) (strchr (P, '/') != NULL)
 # define FILE_SYSTEM_PREFIX_LEN(P) 0
 #endif
 
@@ -333,7 +333,7 @@ DllMain (HINSTANCE module_handle, DWORD event, LPVOID 
reserved)
         /* Shouldn't happen.  */
         return FALSE;
 
-      if (!IS_PATH_WITH_DIR (location))
+      if (!IS_FILE_NAME_WITH_DIR (location))
         /* Shouldn't happen.  */
         return FALSE;
 




reply via email to

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