DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2507
Version: 1.3-current


Attached file "fltk-1_v2.3.x-scandir-utf8.patch"...


Link: http://www.fltk.org/str.php?L2507
Version: 1.3-current
diff -up ./src/filename_list.cxx.scandir ./src/filename_list.cxx
--- ./src/filename_list.cxx.scandir     2010-11-28 22:06:39.000000000 +0100
+++ ./src/filename_list.cxx     2011-01-05 09:54:14.500548587 +0100
@@ -28,6 +28,7 @@
 // Wrapper for scandir with const-correct function prototypes.
 
 #include <FL/filename.H>
+#include <FL/fl_utf8.h>
 #include "flstring.h"
 #include <stdlib.h>
 
@@ -37,7 +38,6 @@ extern "C" {
   int fl_scandir (const char *dir, dirent ***namelist,
                  int (*select)(dirent *),
                  int (*compar)(dirent **, dirent **));
-#  define scandir      fl_scandir
 #endif
 }
 
@@ -81,54 +81,87 @@ int fl_casealphasort(struct dirent **a, 
 */
 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);
+  dirloc = (char *)malloc(dirlen + 1);
+
+  fl_utf8to_mb(d, dirlen, dirloc, dirlen + 1);
+
 #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__)
   // 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__)
   // 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)
   // AIX is almost standard...
-  int n = scandir(d, list, 0, (int(*)(void*, void*))sort);
-#elif !defined(__sgi)
+  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(d, 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);
+  int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort);
 #endif
 
-#if defined(WIN32) && !defined(__CYGWIN__)
-  // we did this already during fl_scandir/win32
-#else
-  // append a '/' to all filenames that are directories
-  int i, dirlen = strlen(d);
+  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++ = '/';
+  if (name!=fullname && name[-1]!='/')
+    *name++ = '/';
+
   for (i=0; i<n; i++) {
     dirent *de = (*list)[i];
     int len = strlen(de->d_name);
-    if (de->d_name[len-1]=='/' || len>FL_PATH_MAX) continue;
-    // 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)) {
-      (*list)[i] = de = (dirent*)realloc(de, de->d_name - (char*)de + len + 2);
-      char *dst = de->d_name + len;
-      *dst++ = '/';
-      *dst = 0;
+    int 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);
-#endif
+
   return n;
+
+#endif // WIN32
 }
 
 //
diff -up ./src/fl_utf.c.scandir ./src/fl_utf.c
--- ./src/fl_utf.c.scandir      2010-11-28 22:06:39.000000000 +0100
+++ ./src/fl_utf.c      2011-01-05 09:41:12.407385000 +0100
@@ -692,8 +692,6 @@ int fl_utf8locale(void) {
     needed.
 
     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,
                  char* dst, unsigned dstlen)
@@ -747,8 +745,7 @@ unsigned fl_utf8to_mb(const char* src, u
     memcpy(dst, src, srclen);
     dst[srclen] = 0;
   } else {
-    memcpy(dst, src, dstlen-1);
-    dst[dstlen-1] = 0;
+    // Buffer insufficent or buffer query
   }
   return srclen;
 }
@@ -765,8 +762,7 @@ unsigned fl_utf8to_mb(const char* src, u
     needed.
 
     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
-    the destination buffer and \p srclen is always returned.
+    does not change the data.
     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 locale.
@@ -813,8 +809,7 @@ unsigned fl_utf8from_mb(char* dst, unsig
     memcpy(dst, src, srclen);
     dst[srclen] = 0;
   } else {
-    memcpy(dst, src, dstlen-1);
-    dst[dstlen-1] = 0;
+    // Buffer insufficent or buffer query
   }
   return srclen;
 }
diff -up ./src/scandir.c.scandir ./src/scandir.c
--- ./src/scandir.c.scandir     2008-09-19 19:40:20.000000000 +0200
+++ ./src/scandir.c     2011-01-05 09:41:12.394385063 +0100
@@ -21,7 +21,6 @@ USA.  */
 #else
 
 #  include "flstring.h"
-#  include <FL/fl_utf8.h>
 
 #  if !HAVE_SCANDIR
 #    include <stdlib.h>
@@ -50,7 +49,7 @@ fl_scandir(const char *dir, struct diren
           int (*select)(struct dirent *),
           int (*compar)(struct dirent **, struct dirent **))
 {
-  DIR *dp = opendir (fl_utf2mbcs(dir));
+  DIR *dp = opendir (dir);
   struct dirent **v = NULL;
   size_t vsize = 0, i;
   struct dirent *d;
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to