1 /* Basic filename support macros. 2 Copyright (C) 2001-2023 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 /* From Paul Eggert and Jim Meyering. */ 20 21 #ifndef _FILENAME_H 22 #define _FILENAME_H 23 24 #include <string.h> 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 31 /* Filename support. 32 ISSLASH(C) tests whether C is a directory separator 33 character. 34 HAS_DEVICE(Filename) tests whether Filename contains a device 35 specification. 36 FILE_SYSTEM_PREFIX_LEN(Filename) length of the device specification 37 at the beginning of Filename, 38 index of the part consisting of 39 alternating components and slashes. 40 FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 41 1 when a non-empty device specification 42 can be followed by an empty or relative 43 part, 44 0 when a non-empty device specification 45 must be followed by a slash, 46 0 when device specification don't exist. 47 IS_ABSOLUTE_FILE_NAME(Filename) 48 tests whether Filename is independent of 49 any notion of "current directory". 50 IS_RELATIVE_FILE_NAME(Filename) 51 tests whether Filename may be concatenated 52 to a directory filename. 53 Note: On native Windows, OS/2, DOS, "c:" is neither an absolute nor a 54 relative file name! 55 IS_FILE_NAME_WITH_DIR(Filename) tests whether Filename contains a device 56 or directory specification. 57 */ 58 #if defined _WIN32 || defined __CYGWIN__ \ 59 || defined __EMX__ || defined __MSDOS__ || defined __DJGPP__ 60 /* Native Windows, Cygwin, OS/2, DOS */ 61 # define ISSLASH(C) ((C) == '/' || (C) == '\\') 62 /* Internal macro: Tests whether a character is a drive letter. */ 63 # define _IS_DRIVE_LETTER(C) \ 64 (((C) >= 'A' && (C) <= 'Z') || ((C) >= 'a' && (C) <= 'z')) 65 /* Help the compiler optimizing it. This assumes ASCII. */ 66 # undef _IS_DRIVE_LETTER 67 # define _IS_DRIVE_LETTER(C) \ 68 (((unsigned int) (C) | ('a' - 'A')) - 'a' <= 'z' - 'a') 69 # define HAS_DEVICE(Filename) \ 70 (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':') 71 # define FILE_SYSTEM_PREFIX_LEN(Filename) (HAS_DEVICE (Filename) ? 2 : 0) 72 # ifdef __CYGWIN__ 73 # define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 74 # else 75 /* On native Windows, OS/2, DOS, the system has the notion of a 76 "current directory" on each drive. */ 77 # define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 78 # endif 79 # if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 80 # define IS_ABSOLUTE_FILE_NAME(Filename) \ 81 ISSLASH ((Filename)[FILE_SYSTEM_PREFIX_LEN (Filename)]) 82 # else 83 # define IS_ABSOLUTE_FILE_NAME(Filename) \ 84 (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename)) 85 # endif 86 # define IS_RELATIVE_FILE_NAME(Filename) \ 87 (! (ISSLASH ((Filename)[0]) || HAS_DEVICE (Filename))) 88 # define IS_FILE_NAME_WITH_DIR(Filename) \ 89 (strchr ((Filename), '/') != NULL || strchr ((Filename), '\\') != NULL \ 90 || HAS_DEVICE (Filename)) 91 #else 92 /* Unix */ 93 # define ISSLASH(C) ((C) == '/') 94 # define HAS_DEVICE(Filename) ((void) (Filename), 0) 95 # define FILE_SYSTEM_PREFIX_LEN(Filename) ((void) (Filename), 0) 96 # define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 97 # define IS_ABSOLUTE_FILE_NAME(Filename) ISSLASH ((Filename)[0]) 98 # define IS_RELATIVE_FILE_NAME(Filename) (! ISSLASH ((Filename)[0])) 99 # define IS_FILE_NAME_WITH_DIR(Filename) (strchr ((Filename), '/') != NULL) 100 #endif 101 102 /* Deprecated macros. For backward compatibility with old users of the 103 'filename' module. */ 104 #define IS_ABSOLUTE_PATH IS_ABSOLUTE_FILE_NAME 105 #define IS_PATH_WITH_DIR IS_FILE_NAME_WITH_DIR 106 107 108 #ifdef __cplusplus 109 } 110 #endif 111 112 #endif /* _FILENAME_H */