mirror of
https://github.com/fltk/fltk.git
synced 2025-12-16 01:26:37 +08:00
Fix STR #2507. Applied supplied patch modified for Mac OS X. Checked OK on Linux.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8192 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
// Wrapper for scandir with const-correct function prototypes.
|
// Wrapper for scandir with const-correct function prototypes.
|
||||||
|
|
||||||
#include <FL/filename.H>
|
#include <FL/filename.H>
|
||||||
|
#include <FL/fl_utf8.h>
|
||||||
#include "flstring.h"
|
#include "flstring.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -37,7 +38,6 @@ extern "C" {
|
|||||||
int fl_scandir (const char *dir, dirent ***namelist,
|
int fl_scandir (const char *dir, dirent ***namelist,
|
||||||
int (*select)(dirent *),
|
int (*select)(dirent *),
|
||||||
int (*compar)(dirent **, dirent **));
|
int (*compar)(dirent **, dirent **));
|
||||||
# define scandir fl_scandir
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,54 +81,101 @@ int fl_casealphasort(struct dirent **a, struct dirent **b) {
|
|||||||
*/
|
*/
|
||||||
int fl_filename_list(const char *d, dirent ***list,
|
int fl_filename_list(const char *d, dirent ***list,
|
||||||
Fl_File_Sort_F *sort) {
|
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__
|
||||||
|
dirloc = (char *)d;
|
||||||
|
#else
|
||||||
|
dirloc = (char *)malloc(dirlen + 1);
|
||||||
|
fl_utf8to_mb(d, dirlen, dirloc, dirlen + 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_SCANDIR
|
#ifndef HAVE_SCANDIR
|
||||||
int n = scandir(d, list, 0, sort);
|
// This version is when we define our own scandir
|
||||||
|
int n = fl_scandir(dirloc, list, 0, sort);
|
||||||
#elif defined(HAVE_SCANDIR_POSIX) && !defined(__APPLE__)
|
#elif defined(HAVE_SCANDIR_POSIX) && !defined(__APPLE__)
|
||||||
// POSIX (2008) defines the comparison function like this:
|
// POSIX (2008) defines the comparison function like this:
|
||||||
int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort);
|
int n = scandir(dirloc, list, 0, (int(*)(const dirent **, const dirent **))sort);
|
||||||
#elif defined(__osf__)
|
#elif defined(__osf__)
|
||||||
// OSF, DU 4.0x
|
// OSF, DU 4.0x
|
||||||
int n = scandir(d, list, 0, (int(*)(dirent **, dirent **))sort);
|
int n = scandir(dirloc, list, 0, (int(*)(dirent **, dirent **))sort);
|
||||||
#elif defined(_AIX)
|
#elif defined(_AIX)
|
||||||
// AIX is almost standard...
|
// AIX is almost standard...
|
||||||
int n = scandir(d, list, 0, (int(*)(void*, void*))sort);
|
int n = scandir(dirloc, list, 0, (int(*)(void*, void*))sort);
|
||||||
#elif !defined(__sgi)
|
#elif defined(__sgi)
|
||||||
|
int n = scandir(dirloc, list, 0, sort);
|
||||||
|
#else
|
||||||
// The vast majority of UNIX systems want the sort function to have this
|
// 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
|
// prototype, most likely so that it can be passed to qsort without any
|
||||||
// changes:
|
// changes:
|
||||||
int n = scandir(d, list, 0, (int(*)(const void*,const void*))sort);
|
int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort);
|
||||||
#else
|
|
||||||
// This version is when we define our own scandir (WIN32 and perhaps
|
|
||||||
// some Unix systems) and apparently on IRIX:
|
|
||||||
int n = scandir(d, list, 0, sort);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
#ifndef __APPLE__
|
||||||
// we did this already during fl_scandir/win32
|
free(dirloc);
|
||||||
#else
|
#endif
|
||||||
// append a '/' to all filenames that are directories
|
|
||||||
int i, dirlen = strlen(d);
|
// 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
|
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...
|
// Use memcpy for speed since we already know the length of the string...
|
||||||
memcpy(fullname, d, dirlen+1);
|
memcpy(fullname, d, dirlen+1);
|
||||||
|
|
||||||
char *name = fullname + dirlen;
|
char *name = fullname + dirlen;
|
||||||
if (name!=fullname && name[-1]!='/') *name++ = '/';
|
if (name!=fullname && name[-1]!='/')
|
||||||
|
*name++ = '/';
|
||||||
|
|
||||||
for (i=0; i<n; i++) {
|
for (i=0; i<n; i++) {
|
||||||
|
int newlen;
|
||||||
dirent *de = (*list)[i];
|
dirent *de = (*list)[i];
|
||||||
int len = strlen(de->d_name);
|
int len = strlen(de->d_name);
|
||||||
if (de->d_name[len-1]=='/' || len>FL_PATH_MAX) continue;
|
#ifdef __APPLE__
|
||||||
// Use memcpy for speed since we already know the length of the string...
|
newlen = len;
|
||||||
memcpy(name, de->d_name, len+1);
|
#else
|
||||||
if (fl_filename_isdir(fullname)) {
|
newlen = fl_utf8from_mb(NULL, 0, de->d_name, len);
|
||||||
(*list)[i] = de = (dirent*)realloc(de, de->d_name - (char*)de + len + 2);
|
#endif
|
||||||
char *dst = de->d_name + len;
|
dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul
|
||||||
*dst++ = '/';
|
|
||||||
*dst = 0;
|
// Conversion to UTF-8
|
||||||
|
memcpy(newde, de, de->d_name - (char*)de);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
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);
|
free(fullname);
|
||||||
#endif
|
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
|
#endif // WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
11
src/fl_utf.c
11
src/fl_utf.c
@@ -692,8 +692,6 @@ int fl_utf8locale(void) {
|
|||||||
needed.
|
needed.
|
||||||
|
|
||||||
If fl_utf8locale() returns true then this does not change the data.
|
If fl_utf8locale() returns true then this does not change the data.
|
||||||
It is copied and truncated as necessary to
|
|
||||||
the destination buffer and \p srclen is always returned.
|
|
||||||
*/
|
*/
|
||||||
unsigned fl_utf8to_mb(const char* src, unsigned srclen,
|
unsigned fl_utf8to_mb(const char* src, unsigned srclen,
|
||||||
char* dst, unsigned dstlen)
|
char* dst, unsigned dstlen)
|
||||||
@@ -747,8 +745,7 @@ unsigned fl_utf8to_mb(const char* src, unsigned srclen,
|
|||||||
memcpy(dst, src, srclen);
|
memcpy(dst, src, srclen);
|
||||||
dst[srclen] = 0;
|
dst[srclen] = 0;
|
||||||
} else {
|
} else {
|
||||||
memcpy(dst, src, dstlen-1);
|
// Buffer insufficent or buffer query
|
||||||
dst[dstlen-1] = 0;
|
|
||||||
}
|
}
|
||||||
return srclen;
|
return srclen;
|
||||||
}
|
}
|
||||||
@@ -765,8 +762,7 @@ unsigned fl_utf8to_mb(const char* src, unsigned srclen,
|
|||||||
needed.
|
needed.
|
||||||
|
|
||||||
On Unix or on Windows when a UTF-8 locale is in effect, this
|
On Unix or on Windows when a UTF-8 locale is in effect, this
|
||||||
does not change the data. It is copied and truncated as necessary to
|
does not change the data.
|
||||||
the destination buffer and \p srclen is always returned.
|
|
||||||
You may also want to check if fl_utf8test() returns non-zero, so that
|
You may also want to check if fl_utf8test() returns non-zero, so that
|
||||||
the filesystem can store filenames in UTF-8 encoding regardless of
|
the filesystem can store filenames in UTF-8 encoding regardless of
|
||||||
the locale.
|
the locale.
|
||||||
@@ -813,8 +809,7 @@ unsigned fl_utf8from_mb(char* dst, unsigned dstlen,
|
|||||||
memcpy(dst, src, srclen);
|
memcpy(dst, src, srclen);
|
||||||
dst[srclen] = 0;
|
dst[srclen] = 0;
|
||||||
} else {
|
} else {
|
||||||
memcpy(dst, src, dstlen-1);
|
// Buffer insufficent or buffer query
|
||||||
dst[dstlen-1] = 0;
|
|
||||||
}
|
}
|
||||||
return srclen;
|
return srclen;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ USA. */
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
# include "flstring.h"
|
# include "flstring.h"
|
||||||
# include <FL/fl_utf8.h>
|
|
||||||
|
|
||||||
# if !HAVE_SCANDIR
|
# if !HAVE_SCANDIR
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
@@ -50,7 +49,7 @@ fl_scandir(const char *dir, struct dirent ***namelist,
|
|||||||
int (*select)(struct dirent *),
|
int (*select)(struct dirent *),
|
||||||
int (*compar)(struct dirent **, struct dirent **))
|
int (*compar)(struct dirent **, struct dirent **))
|
||||||
{
|
{
|
||||||
DIR *dp = opendir (fl_utf2mbcs(dir));
|
DIR *dp = opendir (dir);
|
||||||
struct dirent **v = NULL;
|
struct dirent **v = NULL;
|
||||||
size_t vsize = 0, i;
|
size_t vsize = 0, i;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
|
|||||||
Reference in New Issue
Block a user