diff --git a/FL/Fl_System_Driver.H b/FL/Fl_System_Driver.H index 03364e2f4..867db56f9 100644 --- a/FL/Fl_System_Driver.H +++ b/FL/Fl_System_Driver.H @@ -106,6 +106,10 @@ public: virtual int filename_relative(char *to, int tolen, const char *from, const char *base); // the default implementation of filename_absolute() is in src/filename_absolute.cxx and may be enough virtual int filename_absolute(char *to, int tolen, const char *from); + // the default implementation of filename_isdir() is in src/filename_isdir.cxx and may be enough + virtual int filename_isdir(const char* n); + // the default implementation of filename_isdir_quick() is in src/filename_isdir.cxx and may be enough + virtual int filename_isdir_quick(const char* n); }; #endif // FL_SYSTEM_DRIVER_H diff --git a/FL/filename.H b/FL/filename.H index 745a14591..949bacc11 100644 --- a/FL/filename.H +++ b/FL/filename.H @@ -100,17 +100,6 @@ FL_EXPORT int fl_open_uri(const char *uri, char *msg = (char *)0, FL_EXPORT void fl_decode_uri(char *uri); -# ifndef FL_DOXYGEN -/* - * _fl_filename_isdir_quick() is a private function that checks for a - * trailing slash and assumes that the passed name is a directory if - * it finds one. This function is used by Fl_File_Browser and - * Fl_File_Chooser to avoid extra stat() calls, but is not supported - * outside of FLTK... - */ -int _fl_filename_isdir_quick(const char *name); -# endif - # endif /* __cplusplus */ /* diff --git a/src/Fl_File_Browser.cxx b/src/Fl_File_Browser.cxx index dbbf26c5c..0d8c20b5b 100644 --- a/src/Fl_File_Browser.cxx +++ b/src/Fl_File_Browser.cxx @@ -37,6 +37,8 @@ // #include +#include +#include #include #include #include // icon @@ -700,7 +702,7 @@ Fl_File_Browser::load(const char *directory,// I - Directory to load icon = Fl_File_Icon::find(filename); if ((icon && icon->type() == Fl_File_Icon::DIRECTORY) || - _fl_filename_isdir_quick(filename)) { + Fl::system_driver()->filename_isdir_quick(filename)) { num_dirs ++; insert(num_dirs, files[i]->d_name, icon); } else if (filetype_ == FILES && diff --git a/src/Fl_File_Chooser2.cxx b/src/Fl_File_Chooser2.cxx index d592ff39f..d79466987 100644 --- a/src/Fl_File_Chooser2.cxx +++ b/src/Fl_File_Chooser2.cxx @@ -344,7 +344,8 @@ // #include -#include // for struct stat +#include +#include #include #include #include @@ -724,9 +725,9 @@ Fl_File_Chooser::fileListCB() if (Fl::event_clicks()) { #if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) if ((strlen(pathname) == 2 && pathname[1] == ':') || - _fl_filename_isdir_quick(pathname)) + Fl::system_driver()->filename_isdir_quick(pathname)) #else - if (_fl_filename_isdir_quick(pathname)) + if (Fl::system_driver()->filename_isdir_quick(pathname)) #endif /* WIN32 || __EMX__ */ { // Change directories... @@ -790,7 +791,7 @@ Fl_File_Chooser::fileListCB() if (callback_) (*callback_)(this, data_); // Activate the OK button as needed... - if (!_fl_filename_isdir_quick(pathname) || (type_ & DIRECTORY)) + if (!Fl::system_driver()->filename_isdir_quick(pathname) || (type_ & DIRECTORY)) okButton->activate(); else okButton->deactivate(); @@ -857,15 +858,15 @@ Fl_File_Chooser::fileNameCB() // Enter pressed - select or change directory... #if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) if ((isalpha(pathname[0] & 255) && pathname[1] == ':' && !pathname[2]) || - (_fl_filename_isdir_quick(pathname) && + (Fl::system_driver()->filename_isdir_quick(pathname) && compare_dirnames(pathname, directory_))) { #else - if (_fl_filename_isdir_quick(pathname) && + if (Fl::system_driver()->filename_isdir_quick(pathname) && compare_dirnames(pathname, directory_)) { #endif /* WIN32 || __EMX__ */ directory(pathname); } else if ((type_ & CREATE) || access(pathname, 0) == 0) { - if (!_fl_filename_isdir_quick(pathname) || (type_ & DIRECTORY)) { + if (!Fl::system_driver()->filename_isdir_quick(pathname) || (type_ & DIRECTORY)) { // Update the preview box... update_preview(); diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H index cd7e03c50..8203317ac 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H @@ -72,6 +72,8 @@ public: virtual int filename_expand(char *to,int tolen, const char *from); virtual int filename_relative(char *to, int tolen, const char *from, const char *base); virtual int filename_absolute(char *to, int tolen, const char *from); + virtual int filename_isdir(const char* n); + virtual int filename_isdir_quick(const char* n); }; #endif // FL_WINAPI_SYSTEM_DRIVER_H diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx index 6d32b4f6b..693fd296d 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx @@ -21,6 +21,7 @@ #include "Fl_WinAPI_System_Driver.H" #include #include +#include #include #include #include @@ -614,6 +615,39 @@ int Fl_WinAPI_System_Driver::filename_absolute(char *to, int tolen, const char * return 1; } +int Fl_WinAPI_System_Driver::filename_isdir(const char* n) +{ + struct stat s; + char fn[FL_PATH_MAX]; + int length; + length = (int) strlen(n); + // This workaround brought to you by the fine folks at Microsoft! + // (read lots of sarcasm in that...) + if (length < (int)(sizeof(fn) - 1)) { + if (length < 4 && isalpha(n[0]) && n[1] == ':' && + (isdirsep(n[2]) || !n[2])) { + // Always use D:/ for drive letters + fn[0] = n[0]; + strcpy(fn + 1, ":/"); + n = fn; + } else if (length > 0 && isdirsep(n[length - 1])) { + // Strip trailing slash from name... + length --; + memcpy(fn, n, length); + fn[length] = '\0'; + n = fn; + } + } + return !stat(n, &s) && (s.st_mode & S_IFMT) == S_IFDIR; +} + +int Fl_WinAPI_System_Driver::filename_isdir_quick(const char* n) +{ + // Do a quick optimization for filenames with a trailing slash... + if (*n && isdirsep(n[strlen(n) - 1])) return 1; + return filename_isdir(n); +} + // // End of "$Id$". // diff --git a/src/filename_isdir.cxx b/src/filename_isdir.cxx index 4e69445c1..378f17e4e 100644 --- a/src/filename_isdir.cxx +++ b/src/filename_isdir.cxx @@ -19,22 +19,21 @@ // Used by fl_file_chooser #include "flstring.h" -#include -#include // for struct stat -#include +#include #include -#include +#include -#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) -static inline int isdirsep(char c) {return c=='/' || c=='\\';} -#else -#define isdirsep(c) ((c)=='/') -#endif - -int _fl_filename_isdir_quick(const char* n) { +/* + * filename_isdir_quick() is a private function that checks for a + * trailing slash and assumes that the passed name is a directory if + * it finds one. This function is used by Fl_File_Browser and + * Fl_File_Chooser to avoid extra stat() calls, but is not supported + * outside of FLTK... + */ +int Fl_System_Driver::filename_isdir_quick(const char* n) { // Do a quick optimization for filenames with a trailing slash... - if (*n && isdirsep(n[strlen(n) - 1])) return 1; - return fl_filename_isdir(n); + if (*n && n[strlen(n) - 1] == '/') return 1; + return filename_isdir(n); } /** @@ -49,43 +48,24 @@ int _fl_filename_isdir_quick(const char* n) { \return non zero if file exists and is a directory, zero otherwise */ int fl_filename_isdir(const char* n) { + return Fl::system_driver()->filename_isdir(n); +} + +int Fl_System_Driver::filename_isdir(const char* n) { struct stat s; char fn[FL_PATH_MAX]; int length; - length = (int) strlen(n); - -#ifdef WIN32 - // This workaround brought to you by the fine folks at Microsoft! - // (read lots of sarcasm in that...) - if (length < (int)(sizeof(fn) - 1)) { - if (length < 4 && isalpha(n[0]) && n[1] == ':' && - (isdirsep(n[2]) || !n[2])) { - // Always use D:/ for drive letters - fn[0] = n[0]; - strcpy(fn + 1, ":/"); - n = fn; - } else if (length > 0 && isdirsep(n[length - 1])) { - // Strip trailing slash from name... - length --; - memcpy(fn, n, length); - fn[length] = '\0'; - n = fn; - } - } -#else // Matt: Just in case, we strip the slash for other operating // systems as well, avoid bugs by sloppy implementations // of "stat". - if (length > 1 && isdirsep(n[length - 1])) { + if (length > 1 && n[length - 1] == '/') { length --; memcpy(fn, n, length); fn[length] = '\0'; n = fn; } -#endif - - return !fl_stat(n, &s) && (s.st_mode & S_IFMT) == S_IFDIR; + return !stat(n, &s) && (s.st_mode & S_IFMT) == S_IFDIR; } //