diff options
| author | Manolo Gouy <Manolo> | 2016-04-07 15:10:30 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2016-04-07 15:10:30 +0000 |
| commit | 23a60edb44d264887a398eef1b6346f8f24737e2 (patch) | |
| tree | ae6920a8b002dd26240f560d61df84888ba3b4a5 /src/drivers/Posix/Fl_Posix_System_Driver.cxx | |
| parent | 406fcaf3053b2d8d9c8ea677c59667a7ec43a556 (diff) | |
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
Diffstat (limited to 'src/drivers/Posix/Fl_Posix_System_Driver.cxx')
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.cxx | 85 |
1 files changed, 84 insertions, 1 deletions
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 <config.h> #include "Fl_Posix_System_Driver.H" +#include <FL/filename.H> #include <FL/Fl.H> #include <X11/Xlib.h> #include <locale.h> @@ -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; i<n; i++) { + int newlen; + dirent *de = (*list)[i]; + int len = strlen(de->d_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$". // |
