From 23a60edb44d264887a398eef1b6346f8f24737e2 Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Thu, 7 Apr 2016 15:10:30 +0000 Subject: Rewrite filename_list.cxx under the driver model. One more platform-dependent type is necessary: struct dirent Create a new header file, FL/platform_types.h, to define all types whose definition is platform-dependent. This file is for C because it is included by scandir_XXX.c git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11550 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/CMakeLists.txt | 8 +- src/Makefile | 12 ++- src/drivers/Darwin/Fl_Darwin_System_Driver.H | 1 + src/drivers/Darwin/Fl_Darwin_System_Driver.cxx | 47 +++++++++ src/drivers/Posix/Fl_Posix_System_Driver.H | 1 + src/drivers/Posix/Fl_Posix_System_Driver.cxx | 85 +++++++++++++++- src/drivers/WinAPI/Fl_WinAPI_System_Driver.H | 1 + src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx | 13 +++ src/filename_list.cxx | 128 +------------------------ src/numericsort.c | 25 +---- src/scandir.c | 35 ------- src/scandir_posix.c | 1 + src/scandir_win32.c | 2 +- 13 files changed, 171 insertions(+), 188 deletions(-) delete mode 100644 src/scandir.c (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88b8137b8..7039b6724 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -366,7 +366,6 @@ set (IMGCPPFILES set (CFILES flstring.c - scandir.c numericsort.c vsnprintf.c xutf8/is_right2left.c @@ -377,6 +376,7 @@ set (CFILES if (USE_X11) list (APPEND CFILES xutf8/keysym2Ucs.c + scandir_posix.c ) if (NOT USE_XFT) list (APPEND CFILES @@ -387,6 +387,12 @@ if (USE_X11) endif (NOT USE_XFT) endif (USE_X11) +if (WIN32) + list (APPEND CFILES + scandir_win32.c + ) +endif (WIN32) + if (APPLE AND (NOT OPTION_APPLE_X11) AND (NOT OPTION_APPLE_SDL)) set (MMFILES Fl_cocoa.mm diff --git a/src/Makefile b/src/Makefile index c5bce1a7b..b33a7795e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -209,7 +209,7 @@ IMGCPPFILES = \ Fl_PNM_Image.cxx -CFILES = fl_call_main.c flstring.c scandir.c numericsort.c vsnprintf.c +CFILES = fl_call_main.c flstring.c numericsort.c vsnprintf.c UTF8CFILES = \ xutf8/case.c \ @@ -257,7 +257,8 @@ XLIBCPPFILES = \ # This C file is used under condition: BUILD_X11 XLIBCFILES = \ - xutf8/keysym2Ucs.c + xutf8/keysym2Ucs.c \ + scandir_posix.c # These C files are used under condition: BUILD_X11 AND NOT BUILD_XFT XLIBXCFILES = \ @@ -294,6 +295,10 @@ GDICPPFILES = \ Fl_Native_File_Chooser_WIN32.cxx \ Fl_get_key_win32.cxx +# These C files are used under condition: BUILD_GDI +GDICFILES = \ + scandir_win32.c + PSCPPFILES = \ drivers/PostScript/Fl_PostScript.cxx \ drivers/PostScript/Fl_PostScript_image.cxx @@ -315,6 +320,8 @@ CPPFILES += $(shell if test $(BUILD_GDI) = Yes; then echo $(GDICPPFILES); fi) CFILES += $(shell if test $(BUILD_X11) = Yes; then echo $(XLIBCFILES); fi) CFILES += $(shell if test $(BUILD_X11) = Yes -a $(BUILD_XFT) != Yes; then echo $(XLIBXCFILES); fi) +CFILES += $(shell if test $(BUILD_GDI) = Yes; then echo $(GDICFILES); fi) + OBJECTS = $(MMFILES:.mm=.o) $(CPPFILES:.cxx=.o) $(CFILES:.c=.o) $(UTF8CFILES:.c=.o) GLOBJECTS = $(GLCPPFILES:.cxx=.o) FLOBJECTS = $(FLCPPFILES:.cxx=.o) @@ -595,6 +602,7 @@ include makedepend # (like "*xft*") here: Fl_get_key_mac.o: Fl_get_key_mac.cxx Fl_get_key_win32.o: Fl_get_key_win32.cxx +scandir_win32.o scandir_win32.c Fl_Native_File_Chooser_WIN32.o : Fl_Native_File_Chooser_WIN32.cxx Fl_Native_File_Chooser_MAC.o: Fl_Native_File_Chooser_MAC.mm Fl_Native_File_Chooser_FLTK.o: Fl_Native_File_Chooser_FLTK.cxx diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.H b/src/drivers/Darwin/Fl_Darwin_System_Driver.H index 442dcd687..0803f32d5 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.H +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.H @@ -68,6 +68,7 @@ public: // these 2 are in Fl_get_key_mac.cxx virtual int event_key(int k); virtual int get_key(int k); + virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ); }; #endif // FL_DARWIN_SYSTEM_DRIVER_H diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx index 2f6d52fc6..617e8b19d 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx @@ -20,6 +20,7 @@ #include "../../config_lib.h" #include "Fl_Darwin_System_Driver.H" #include +#include #include #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 #include @@ -88,6 +89,52 @@ void *Fl_Darwin_System_Driver::get_carbon_function(const char *function_name) { return (carbon ? dlsym(carbon, function_name) : NULL); } +int Fl_Darwin_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { + int dirlen; + char *dirloc; + // Assume that locale encoding is no less dense than UTF-8 + dirlen = strlen(d); + dirloc = (char *)d; +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 + int n = scandir(dirloc, list, 0, (int(*)(const struct dirent**,const struct dirent**))sort); +# else + int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); +# endif + // convert every filename to utf-8, and append a '/' to all + // filenames that are directories + int i; + char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul + // Use memcpy for speed since we already know the length of the string... + memcpy(fullname, d, dirlen+1); + char *name = fullname + dirlen; + if (name!=fullname && name[-1]!='/') *name++ = '/'; + for (i=0; id_name); + newlen = len; + dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul + // Conversion to UTF-8 + memcpy(newde, de, de->d_name - (char*)de); + strcpy(newde->d_name, de->d_name); + // Check if dir (checks done on "old" name as we need to interact with + // the underlying OS) + if (de->d_name[len-1]!='/' && len<=FL_PATH_MAX) { + // Use memcpy for speed since we already know the length of the string... + memcpy(name, de->d_name, len+1); + if (fl_filename_isdir(fullname)) { + char *dst = newde->d_name + newlen; + *dst++ = '/'; + *dst = 0; + } + } + free(de); + (*list)[i] = newde; + } + free(fullname); + return n; +} + // // End of "$Id$". // diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.H b/src/drivers/Posix/Fl_Posix_System_Driver.H index 1c8042e3f..aa922d590 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.H +++ b/src/drivers/Posix/Fl_Posix_System_Driver.H @@ -65,6 +65,7 @@ public: // these 2 are in Fl_get_key.cxx virtual int event_key(int k); virtual int get_key(int k); + virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ); }; #endif // FL_POSIX_SYSTEM_DRIVER_H diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index dffedeb93..6ce92675f 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -16,8 +16,9 @@ // http://www.fltk.org/str.php // - +#include #include "Fl_Posix_System_Driver.H" +#include #include #include #include @@ -30,6 +31,14 @@ const char* fl_local_ctrl = "Ctrl"; const char* fl_local_meta = "Meta"; const char* fl_local_shift = "Shift"; +#ifndef HAVE_SCANDIR +extern "C" { + int fl_scandir(const char *dirname, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)); +} +#endif + /** Creates a driver that manages all screen and display related calls. @@ -57,6 +66,80 @@ int Fl_Posix_System_Driver::clocale_printf(FILE *output, const char *format, va_ return retval; } +int Fl_Posix_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { + int dirlen; + char *dirloc; + + // Assume that locale encoding is no less dense than UTF-8 + dirlen = strlen(d); + dirloc = (char *)malloc(dirlen + 1); + fl_utf8to_mb(d, dirlen, dirloc, dirlen + 1); + +#ifndef HAVE_SCANDIR + // This version is when we define our own scandir + int n = fl_scandir(dirloc, list, 0, sort); +#elif defined(HAVE_SCANDIR_POSIX) + // POSIX (2008) defines the comparison function like this: + int n = scandir(dirloc, list, 0, (int(*)(const dirent **, const dirent **))sort); +#elif defined(__osf__) + // OSF, DU 4.0x + int n = scandir(dirloc, list, 0, (int(*)(dirent **, dirent **))sort); +#elif defined(_AIX) + // AIX is almost standard... + int n = scandir(dirloc, list, 0, (int(*)(void*, void*))sort); +#elif defined(__sgi) + int n = scandir(dirloc, list, 0, sort); +#else + // The vast majority of UNIX systems want the sort function to have this + // prototype, most likely so that it can be passed to qsort without any + // changes: + int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); +#endif + + free(dirloc); + + // convert every filename to utf-8, and append a '/' to all + // filenames that are directories + int i; + char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul + // Use memcpy for speed since we already know the length of the string... + memcpy(fullname, d, dirlen+1); + + char *name = fullname + dirlen; + if (name!=fullname && name[-1]!='/') + *name++ = '/'; + + for (i=0; id_name); + newlen = fl_utf8from_mb(NULL, 0, de->d_name, len); + dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul + + // Conversion to UTF-8 + memcpy(newde, de, de->d_name - (char*)de); + fl_utf8from_mb(newde->d_name, newlen + 1, de->d_name, len); + + // Check if dir (checks done on "old" name as we need to interact with + // the underlying OS) + if (de->d_name[len-1]!='/' && len<=FL_PATH_MAX) { + // Use memcpy for speed since we already know the length of the string... + memcpy(name, de->d_name, len+1); + if (fl_filename_isdir(fullname)) { + char *dst = newde->d_name + newlen; + *dst++ = '/'; + *dst = 0; + } + } + + free(de); + (*list)[i] = newde; + } + free(fullname); + + return n; +} + // // End of "$Id$". // diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H index bb903f00a..ccf51aec0 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H @@ -68,6 +68,7 @@ public: // these 2 are in Fl_get_key_win32.cxx virtual int event_key(int k); virtual int get_key(int k); + virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ); }; #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 46bd9dc78..9a0c25d4d 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx @@ -39,6 +39,12 @@ static wchar_t *mbwbuf = NULL; static wchar_t *wbuf = NULL; static wchar_t *wbuf1 = NULL; +extern "C" { + int fl_scandir(const char *dirname, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)); +} + /** Creates a driver that manages all screen and display related calls. @@ -429,6 +435,13 @@ int Fl_WinAPI_System_Driver::clocale_printf(FILE *output, const char *format, va return retval; } +int Fl_WinAPI_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { + // For Windows we have a special scandir implementation that uses + // the Win32 "wide" functions for lookup, avoiding the code page mess + // entirely. It also fixes up the trailing '/'. + return fl_scandir(d, list, 0, sort); +} + // // End of "$Id$". // diff --git a/src/filename_list.cxx b/src/filename_list.cxx index 806df0671..461d4314f 100644 --- a/src/filename_list.cxx +++ b/src/filename_list.cxx @@ -19,27 +19,12 @@ // Wrapper for scandir with const-correct function prototypes. #include +#include +#include #include #include "flstring.h" #include -#ifdef __APPLE__ // PORTME: Fl_System_Driver - directory stuff -#include -#endif -#ifdef WIN32 -#elif defined(__APPLE__) // PORTME: Fl_System_Driver - directory stuff -#elif defined(FL_PORTING) -# pragma message "FL_PORTING: implement directory and filename handling for your platform if needed" -#else // X11 -#endif - -extern "C" { -#ifndef HAVE_SCANDIR - int fl_scandir (const char *dir, dirent ***namelist, - int (*select)(dirent *), - int (*compar)(dirent **, dirent **)); -#endif -} int fl_alphasort(struct dirent **a, struct dirent **b) { return strcmp((*a)->d_name, (*b)->d_name); @@ -79,112 +64,8 @@ int fl_casealphasort(struct dirent **a, struct dirent **b) { according to their ASCII ordering - uppercase before lowercase. \return the number of entries if no error, a negative value otherwise. */ -int fl_filename_list(const char *d, dirent ***list, - Fl_File_Sort_F *sort) { -#if defined(WIN32) && !defined(__CYGWIN__) && !defined(HAVE_SCANDIR) - // For Windows we have a special scandir implementation that uses - // the Win32 "wide" functions for lookup, avoiding the code page mess - // entirely. It also fixes up the trailing '/'. - return fl_scandir(d, list, 0, sort); - -#else // WIN32 - - int dirlen; - char *dirloc; - - // Assume that locale encoding is no less dense than UTF-8 - dirlen = strlen(d); -#ifdef __APPLE__ // PORTME: Fl_System_Driver - directory stuff - dirloc = (char *)d; -#else - dirloc = (char *)malloc(dirlen + 1); - fl_utf8to_mb(d, dirlen, dirloc, dirlen + 1); -#endif - -#ifndef HAVE_SCANDIR - // This version is when we define our own scandir - int n = fl_scandir(dirloc, list, 0, sort); -#elif defined(HAVE_SCANDIR_POSIX) && !defined(__APPLE__) // PORTME: Fl_System_Driver - directory stuff - // POSIX (2008) defines the comparison function like this: - int n = scandir(dirloc, list, 0, (int(*)(const dirent **, const dirent **))sort); -#elif defined(__osf__) - // OSF, DU 4.0x - int n = scandir(dirloc, list, 0, (int(*)(dirent **, dirent **))sort); -#elif defined(_AIX) - // AIX is almost standard... - int n = scandir(dirloc, list, 0, (int(*)(void*, void*))sort); -#elif defined(__sgi) - int n = scandir(dirloc, list, 0, sort); -#elif defined(__APPLE__) // PORTME: Fl_System_Driver - directory stuff -# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - int n = scandir(dirloc, list, 0, (int(*)(const struct dirent**,const struct dirent**))sort); -# else - int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); -# endif -#elif defined(FL_PORTING) -# pragma message "FL_PORTING: defien scandir" - int n = 0; -#else - // The vast majority of UNIX systems want the sort function to have this - // prototype, most likely so that it can be passed to qsort without any - // changes: - int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); -#endif - -#ifndef __APPLE__ // PORTME: Fl_System_Driver - directory stuff - free(dirloc); -#endif - - // convert every filename to utf-8, and append a '/' to all - // filenames that are directories - int i; - char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul - // Use memcpy for speed since we already know the length of the string... - memcpy(fullname, d, dirlen+1); - - char *name = fullname + dirlen; - if (name!=fullname && name[-1]!='/') - *name++ = '/'; - - for (i=0; id_name); -#ifdef __APPLE__ // PORTME: Fl_System_Driver - directory stuff - newlen = len; -#else - newlen = fl_utf8from_mb(NULL, 0, de->d_name, len); -#endif - dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul - - // Conversion to UTF-8 - memcpy(newde, de, de->d_name - (char*)de); -#ifdef __APPLE__ // PORTME: Fl_System_Driver - directory stuff - strcpy(newde->d_name, de->d_name); -#else - fl_utf8from_mb(newde->d_name, newlen + 1, de->d_name, len); -#endif - - // Check if dir (checks done on "old" name as we need to interact with - // the underlying OS) - if (de->d_name[len-1]!='/' && len<=FL_PATH_MAX) { - // Use memcpy for speed since we already know the length of the string... - memcpy(name, de->d_name, len+1); - if (fl_filename_isdir(fullname)) { - char *dst = newde->d_name + newlen; - *dst++ = '/'; - *dst = 0; - } - } - - free(de); - (*list)[i] = newde; - } - free(fullname); - - return n; - -#endif // WIN32 +int fl_filename_list(const char *d, dirent ***list, Fl_File_Sort_F *sort) { + return Fl::system_driver()->filename_list(d, list, sort); } /** @@ -209,7 +90,6 @@ void fl_filename_free_list(struct dirent ***list, int n) *list = 0; } - // // End of "$Id$". // diff --git a/src/numericsort.c b/src/numericsort.c index 9c4297347..e3455a8cf 100644 --- a/src/numericsort.c +++ b/src/numericsort.c @@ -16,32 +16,9 @@ * http://www.fltk.org/str.php */ -/* My own scandir sorting function, useful for the film industry where - we have many files with numbers in their names: */ - -#include #include #include -#include - -#if !defined(WIN32) || defined(__CYGWIN__) -# ifdef HAVE_DIRENT_H -# include -# else -# define dirent direct -# ifdef HAVE_SYS_NDIR_H -# include -# endif /* HAVE_SYS_NDIR_H */ -# ifdef HAVE_SYS_DIR_H -# include -# endif /* HAVE_SYS_DIR_H */ -# ifdef HAVE_NDIR_H -# include -# endif /* HAVE_NDIR_H */ -# endif /* HAVE_DIRENT_H */ -#endif /* !WIN32 || __CYGWIN__ */ - -#include +#include /* * 'numericsort()' - Compare two directory entries, possibly with diff --git a/src/scandir.c b/src/scandir.c deleted file mode 100644 index c3d5d63a0..000000000 --- a/src/scandir.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * "$Id$" - * - * This is a placekeeper stub that pulls in scandir implementations for host - * systems that do not provide a compatible one natively - * - * Copyright 1998-2013 by Bill Spitzak and others. - * - * This library is free software. Distribution and use rights are outlined in - * the file "COPYING" which should have been included with this file. If this - * file is missing or damaged, see the license at: - * - * http://www.fltk.org/COPYING.php - * - * Please report all bugs and problems on the following page: - * - * http://www.fltk.org/str.php - */ - - -#if defined(WIN32) && !defined(__CYGWIN__) -# include "scandir_win32.c" -#else -# include -# ifndef HAVE_SCANDIR -# include "scandir_posix.c" -# endif /* HAVE_SCANDIR */ -#endif - -/* Avoid "ISO C forbids an empty translation unit" warning */ -typedef int dummy; - -/* - * End of "$Id$". - */ diff --git a/src/scandir_posix.c b/src/scandir_posix.c index 64eaaf519..af33612e2 100644 --- a/src/scandir_posix.c +++ b/src/scandir_posix.c @@ -32,6 +32,7 @@ * http://womble.decadent.org.uk/readdir_r-advisory.html */ +#include #ifndef HAVE_PTHREAD /* Switch system headers into POSIX.1-1990 mode */ # define _POSIX_SOURCE diff --git a/src/scandir_win32.c b/src/scandir_win32.c index 75b0430bf..11924c4fb 100644 --- a/src/scandir_win32.c +++ b/src/scandir_win32.c @@ -19,7 +19,7 @@ #ifndef __CYGWIN__ /* Emulation of posix scandir() call */ #include -#include +#include #include "flstring.h" #include #include -- cgit v1.2.3