fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

fl_utf8.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: fl_utf8.cxx 7975 2010-12-08 12:15:48Z AlbrechtS $"
00003 //
00004 // Unicode to UTF-8 conversion functions.
00005 //
00006 // Author: Jean-Marc Lienher ( http://oksid.ch )
00007 // Copyright 2000-2010 by O'ksi'D.
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Library General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Library General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Library General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00022 // USA.
00023 //
00024 // Please report all bugs and problems on the following page:
00025 //
00026 //     http://www.fltk.org/str.php
00027 
00028 
00029 #include <config.h>
00030 #include <FL/filename.H>
00031 #include <stdarg.h>
00032 
00033 #if defined(WIN32) && !defined(__CYGWIN__)
00034 # include <ctype.h>
00035 # include <io.h>
00036 # include <windows.h>
00037 # include <winbase.h>
00038 # include <process.h>
00039 #ifdef __CYGWIN__
00040 #include  <wchar.h>
00041 #else
00042 #include  <direct.h>
00043 #endif
00044 extern "C" {
00045   int XUtf8Tolower(int ucs);
00046   unsigned short XUtf8IsNonSpacing(unsigned int ucs);
00047 };
00048 
00049 #elif defined(__APPLE__)
00050 # include <stdio.h>
00051 # include <time.h>
00052 //# include <unix.h>
00053 # include <fcntl.h>
00054 # include <unistd.h>
00055 # include <wchar.h>
00056 # include <stdlib.h>
00057 #   include <sys/types.h>
00058 # include <sys/stat.h>
00059 
00060 extern "C" {
00061   int XUtf8Tolower(int ucs);
00062   unsigned short XUtf8IsNonSpacing(unsigned int ucs);
00063 }
00064 
00065 #else // X-windows platform
00066 
00067 # include <FL/Xutf8.h>
00068 # include <sys/types.h>
00069 # include <sys/stat.h>
00070 # include <fcntl.h>
00071 # include <unistd.h>
00072 #endif // WIN32
00073 
00074 #include <FL/fl_utf8.h>
00075 #include <string.h>
00076 #include <stdlib.h>
00077 
00078 #undef fl_open
00079 
00084 /*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/
00085 /***        but only 16 bits are really used under Linux and win32  ***/
00086 
00087 
00088 #define NBC 0xFFFF + 1
00089 
00090 static int
00091 Toupper(
00092         int ucs)
00093 {
00094         long i;
00095         static unsigned short *table = NULL;
00096 
00097         if (!table) {
00098                 table = (unsigned short*) malloc(
00099                         sizeof(unsigned short) * (NBC));
00100                 for (i = 0; i < NBC; i++) {
00101                         table[i] = (unsigned short) i;
00102                 }
00103                 for (i = 0; i < NBC; i++) {
00104                         int l;
00105                         l = XUtf8Tolower(i);
00106                         if (l != i) table[l] = (unsigned short) i;
00107                 }
00108 
00109         }
00110         if (ucs >= NBC || ucs < 0) return ucs;
00111         return table[ucs];
00112 }
00113 
00120 int fl_utf8len(char c)
00121 {
00122   if (!(c & 0x80)) return 1;
00123   if (c & 0x40) {
00124     if (c & 0x20) {
00125       if (c & 0x10) {
00126         if (c & 0x08) {
00127           if (c & 0x04) {
00128             return 6;
00129           }
00130           return 5;
00131         }
00132         return 4;
00133       }
00134       return 3;
00135     }
00136     return 2;
00137   }
00138   return -1;
00139 } // fl_utf8len
00140 
00141 
00149 int fl_utf8len1(char c)
00150 {
00151   if (!(c & 0x80)) return 1;
00152   if (c & 0x40) {
00153     if (c & 0x20) {
00154       if (c & 0x10) {
00155         if (c & 0x08) {
00156           if (c & 0x04) {
00157             return 6;
00158           }
00159           return 5;
00160         }
00161         return 4;
00162       }
00163       return 3;
00164     }
00165     return 2;
00166   }
00167   return 1;
00168 } // fl_utf8len1
00169 
00170 
00174 int
00175 fl_utf_nb_char(
00176         const unsigned char     *buf,
00177         int                     len)
00178 {
00179         int i = 0;
00180         int nbc = 0;
00181         while (i < len) {
00182                 int cl = fl_utf8len((buf+i)[0]);//fl_utflen(buf + i, len - i);
00183                 if (cl < 1) cl = 1;
00184                 nbc++;
00185                 i += cl;
00186         }
00187         return nbc;
00188 }
00189 
00190 /*
00191  * compare only the first n bytes
00192  * return 0 if the strings are equal;
00193  * return 1 if s1 is greater than s2
00194  * return -1 if s1 is less than s2
00195  */
00202 int fl_utf_strncasecmp(const char *s1, const char *s2, int n)
00203 {
00204         int i;
00205         int s1_l;
00206         int s2_l;
00207         char *e1, *e2; // string end pointers
00208 
00209         s1_l = 0;
00210         while (s1_l < n && s1[s1_l]) s1_l++;
00211         s2_l = 0;
00212         while (s2_l < n && s2[s2_l]) s2_l++;
00213 
00214         if (s1_l < s2_l) {
00215                 return -1;
00216         } else if (s1_l > s2_l) {
00217                 return 1;
00218         }
00219                 e1 = (char *)&s1[s1_l]; // last char to test
00220                 e2 = (char *)&s2[s2_l];
00221         for (i = 0; i < n;) {
00222                 int l1, l2;
00223                 unsigned int u1, u2;
00224                 int res;
00225 
00226 //              l1 = fl_utf2ucs((unsigned char*)s1 + i, n - i, &u1);
00227                 u1 = fl_utf8decode(s1 + i, e1, &l1);
00228 //              l2 = fl_utf2ucs((unsigned char*)s2 + i, n - i, &u2);
00229                 u2 = fl_utf8decode(s2 + i, e2, &l2);
00230                 if (l1 - l2 != 0) return l1 - l2;
00231                 res = XUtf8Tolower(u1) - XUtf8Tolower(u2);
00232                 if (res != 0) return res;
00233                 if (l1 < 1) {
00234                         i += 1;
00235                 } else {
00236                         i += l1;
00237                 }
00238         }
00239         return 0;
00240 }
00241 
00242 /*
00243  * return 0 if the strings are equal;
00244  * return 1 if s1 is greater than s2
00245  * return -1 if s1 is less than s2
00246  */
00252 int fl_utf_strcasecmp(const char *s1, const char *s2)
00253 {
00254         int s1_l = strlen(s1);
00255         int s2_l = strlen(s2);
00256 
00257         if (s1_l < s2_l) {
00258                 return -1;
00259         } else if (s1_l > s2_l) {
00260                 return 1;
00261         }
00262         return fl_utf_strncasecmp(s1, s2, s1_l);
00263 }
00264 
00268 int fl_tolower(unsigned int ucs)
00269 {
00270         return XUtf8Tolower(ucs);
00271 }
00272 
00276 int fl_toupper(unsigned int ucs)
00277 {
00278         return Toupper(ucs);
00279 }
00280 
00285 int fl_utf_tolower(const unsigned char *str, int len, char *buf)
00286 {
00287         int i;
00288         int l = 0;
00289         char *end = (char *)&str[len];
00290         for (i = 0; i < len;) {
00291                 int l1, l2;
00292                 unsigned int u1;
00293 
00294 //              l1 = fl_utf2ucs((unsigned char*)str + i, len - i, &u1);
00295                 u1 = fl_utf8decode((const char*)(str + i), end, &l1);
00296                 l2 = fl_utf8encode((unsigned int) XUtf8Tolower(u1), buf + l);
00297                 if (l1 < 1) {
00298                         i += 1;
00299                 } else {
00300                         i += l1;
00301                 }
00302                 if (l2 < 1) {
00303                         l += 1;
00304                 } else {
00305                         l += l2;
00306                 }
00307 
00308         }
00309         return l;
00310 }
00311 
00316 int fl_utf_toupper(const unsigned char *str, int len, char *buf)
00317 {
00318         int i;
00319         int l = 0;
00320         char *end = (char *)&str[len];
00321         for (i = 0; i < len;) {
00322                 int l1, l2;
00323                 unsigned int u1;
00324 
00325 //              l1 = fl_utf2ucs((unsigned char*)str + i, len - i, &u1);
00326                 u1 = fl_utf8decode((const char*)(str + i), end, &l1);
00327                 l2 = fl_utf8encode((unsigned int) Toupper(u1), buf + l);
00328                 if (l1 < 1) {
00329                         i += 1;
00330                 } else {
00331                         i += l1;
00332                 }
00333                 if (l2 < 1) {
00334                         l += 1;
00335                 } else {
00336                         l += l2;
00337                 }
00338         }
00339         return l;
00340 }
00341 
00342 #if 0 // deprecated in favour of FLTK2's fl_utf8toa
00343 /*
00344  * convert UTF-8 str to latin1
00345  * Warning: buf must be at least len long
00346  */
00347 int fl_utf2latin1(const unsigned char *str, int len, char *buf)
00348 {
00349         int i;
00350         int l = 0;
00351         char *end = (char *)&str[len];
00352         for (i = 0; i < len;) {
00353                 unsigned int u1;
00354                 int l1;
00355 
00356 //              l1 = fl_utf2ucs((unsigned char*)str + i, len - i, &u1);
00357                 u1 = fl_utf8decode((const char*)(str + i), end, &l1);
00358                 if (u1 > 0xFF) u1 = '?';
00359                 buf[l] = (char) u1;
00360                 if (l1 < 1) {
00361                         i += 1;
00362                 } else {
00363                         i += l1;
00364                 }
00365                 l++;
00366 
00367         }
00368         return l;
00369 }
00370 #endif
00371 
00372 #if 0 // deprecated in favour of FLTK2's fl_utf8froma
00373 /*
00374  * convert latin1 str to UTF-8
00375  * Warning: buf must be at least 2 * len long
00376  */
00377 int fl_latin12utf(const unsigned char *str, int len, char *buf)
00378 {
00379         int i;
00380         int l = 0;
00381         int l1 = 0;
00382         for (i = 0; i < len; i++) {
00383                 unsigned int n = (unsigned int) str[i];
00384                 l1 = fl_utf8encode(n, buf + l);
00385                 if (l1 < 1) {
00386                         l = l + 1;
00387                 } else {
00388                         l = l + l1;
00389                 }
00390 
00391         }
00392         return l;
00393 }
00394 #endif
00395 
00400 unsigned int fl_nonspacing(unsigned int ucs)
00401 {
00402 #ifdef __APPLE__
00403   return (ucs==0x20); // FIXME: what does this really do?
00404 #else
00405   return (unsigned int) XUtf8IsNonSpacing(ucs);
00406 #endif
00407 }
00408 
00409 #if defined(WIN32) && !defined(__CYGWIN__)
00410 static xchar *mbwbuf = NULL;
00411 #endif
00412 
00413 #ifdef WIN32
00414 unsigned int fl_codepage = 0;
00415 #endif
00416 
00417 #if defined (WIN32) && !defined(__CYGWIN__)
00418 
00419 static char *buf = NULL;
00420 static int buf_len = 0;
00421 static unsigned short *wbufa = NULL;
00422 
00423 // FIXME: This should *maybe* return 'const char *' instead of 'char *'
00424 char *fl_utf8_to_locale(const char *s, int len, UINT codepage)
00425 {
00426         if (!s) return (char *)"";
00427         int l = 0;
00428 //      if (buf_len < len * 2 + 1) {
00429 //              buf_len = len * 2 + 1;
00430 //              buf = (char*) realloc(buf, buf_len);
00431 //              wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short));
00432 //      }
00433         unsigned wn = fl_utf8toUtf16(s, len, NULL, 0); // Query length
00434         wn = wn * 2 + 1;
00435         if (wn >= (unsigned)buf_len) {
00436                 buf_len = wn;
00437                 buf = (char*) realloc(buf, buf_len);
00438                 wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short));
00439         }
00440         if (codepage < 1) codepage = fl_codepage;
00441 //      l = fl_utf2unicode((const unsigned char *)s, len, (xchar*) wbufa);
00442         l = fl_utf8toUtf16(s, len, wbufa, wn); // Convert string
00443         wbufa[l] = 0;
00444         buf[l] = 0;
00445         l = WideCharToMultiByte(codepage, 0, (WCHAR*)wbufa, l, buf, buf_len, NULL, NULL);
00446         if (l < 0) l = 0;
00447         buf[l] = 0;
00448         return buf;
00449 }
00450 
00451 // FIXME: This should maybe return 'const char *' instead of 'char *'
00452 char *fl_locale_to_utf8(const char *s, int len, UINT codepage)
00453 {
00454         if (!s) return (char *)"";
00455         int l = 0;
00456         if (buf_len < len * 5 + 1) {
00457                 buf_len = len * 5 + 1;
00458                 buf = (char*) realloc(buf, buf_len);
00459                 wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short));
00460         }
00461         if (codepage < 1) codepage = fl_codepage;
00462         buf[l] = 0;
00463 
00464         l = MultiByteToWideChar(codepage, 0, s, len, (WCHAR*)wbufa, buf_len);
00465         if (l < 0) l = 0;
00466         wbufa[l] = 0;
00467 //      l = fl_unicode2utf((xchar*)wbufa, l, buf);
00468         l = fl_utf8fromwc(buf, buf_len, (xchar*)wbufa, l);
00469         buf[l] = 0;
00470         return buf;
00471 }
00472 #endif
00473 
00477 char * fl_utf2mbcs(const char *s)
00478 {
00479         if (!s) return NULL;
00480 #if defined(WIN32) && !defined(__CYGWIN__)
00481         int l = strlen(s);
00482         static char *buf = NULL;
00483 
00484 //      mbwbuf = (xchar*)realloc(mbwbuf, (l+6) * sizeof(xchar));
00485 //      l = fl_utf2unicode((unsigned char*)s, l, mbwbuf);
00486 //      mbwbuf[l] = 0;
00487         unsigned wn = fl_utf8toUtf16(s, l, NULL, 0) + 7; // Query length
00488         mbwbuf = (xchar*)realloc(mbwbuf, sizeof(xchar)*wn);
00489         l = fl_utf8toUtf16(s, l, (unsigned short *)mbwbuf, wn); // Convert string
00490         mbwbuf[l] = 0;
00491 
00492         buf = (char*)realloc(buf, l * 6 + 1);
00493         l = wcstombs(buf, mbwbuf, l * 6);
00494         buf[l] = 0;
00495         return buf;
00496 #else
00497         return (char*) s;
00498 #endif
00499 }
00500 
00501 
00502 #if 0 // deprecated in favour of FLTK2's fl_utf8from_mb
00503 char * fl_mbcs2utf(const char *s)
00504 {
00505         if (!s) return NULL;
00506 #if defined(WIN32)
00507         int l = strlen(s);
00508         unsigned dstlen;
00509         static char *buf = NULL;
00510 
00511         mbwbuf = (xchar*)realloc(mbwbuf,(l * 6 + 6) * sizeof(xchar));
00512         l = mbstowcs(mbwbuf, s, l);
00513         dstlen = l * 6 + 1;
00514         buf = (char*)realloc(buf, dstlen);
00515 //      l = fl_unicode2utf(mbwbuf, l, buf);
00516         l = fl_utf8fromwc(buf, dstlen, mbwbuf, l);
00517         buf[l] = 0;
00518         return buf;
00519 #else
00520         return (char*) s;
00521 #endif
00522 } // fl_mbcs2utf
00523 #endif
00524 
00525 #if defined(WIN32)  && !defined(__CYGWIN__)
00526 static xchar *wbuf = NULL;
00527 static xchar *wbuf1 = NULL;
00528 #endif
00529 
00530 
00531 char *fl_getenv(const char* v)
00532 {
00533 #if defined (WIN32) && !defined(__CYGWIN__)
00534         int l = strlen(v);
00535 //      static xchar* wbuf = NULL;
00536 //      wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00537 //      wbuf[fl_utf2unicode((const unsigned char*)v, l, wbuf)] = 0;
00538         unsigned wn = fl_utf8toUtf16(v, l, NULL, 0) + 1; // Query length
00539         wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00540         wn = fl_utf8toUtf16(v, l, (unsigned short *)wbuf, wn); // Convert string
00541         wbuf[wn] = 0;
00542         xchar *ret = _wgetenv(wbuf);
00543         static char *buf = NULL;
00544         if (ret) {
00545                 l = wcslen(ret);
00546                 wn = fl_utf8fromwc(NULL, 0, ret, l) + 1; // query length
00547                 buf = (char*) realloc(buf, wn);
00548 //              buf[fl_unicode2utf(ret, l, buf)] = 0;
00549                 wn = fl_utf8fromwc(buf, wn, ret, l); // convert string
00550                 buf[wn] = 0;
00551                 return buf;
00552         } else {
00553                 return NULL;
00554         }
00555 #else
00556         return getenv(v);
00557 #endif
00558 }
00559 
00560 int fl_open(const char* f, int oflags, ...)
00561 {
00562         int pmode;
00563         va_list ap;
00564         va_start(ap, oflags);
00565         pmode = va_arg (ap, int);
00566         va_end(ap);
00567 #if defined (WIN32) && !defined(__CYGWIN__)
00568                 int l = strlen(f);
00569 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00570 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00571                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00572                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00573                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00574                 wbuf[wn] = 0;
00575                 if (pmode == -1) return _wopen(wbuf, oflags);
00576                 else return _wopen(wbuf, oflags, pmode);
00577 #else
00578         if (pmode == -1) return open(f, oflags);
00579         else return open(f, oflags, pmode);
00580 #endif
00581 }
00582 
00583 FILE *fl_fopen(const char* f, const char *mode)
00584 {
00585 #if  defined (WIN32) && !defined(__CYGWIN__)
00586                 int l = strlen(f);
00587 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00588 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00589                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00590                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00591                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00592                 wbuf[wn] = 0;
00593                 l = strlen(mode);
00594 //              wbuf1 = (xchar*)realloc(wbuf1, sizeof(xchar) * (l+1));
00595 //              wbuf1[fl_utf2unicode((const unsigned char*)mode, l, wbuf1)] = 0;
00596                 wn = fl_utf8toUtf16(mode, l, NULL, 0) + 1; // Query length
00597                 wbuf1 = (xchar*)realloc(wbuf1, sizeof(xchar)*wn);
00598                 wn = fl_utf8toUtf16(mode, l, (unsigned short *)wbuf1, wn); // Convert string
00599                 wbuf1[wn] = 0;
00600                 return _wfopen(wbuf, wbuf1);
00601 #else
00602         return fopen(f, mode);
00603 #endif
00604 }
00605 
00606 int fl_system(const char* f)
00607 {
00608 #if  defined (WIN32) && !defined(__CYGWIN__)
00609 #  ifdef __MINGW32__
00610         return system(fl_utf2mbcs(f));
00611 #  else
00612                 int l = strlen(f);
00613 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00614 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00615                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00616                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00617                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00618                 wbuf[wn] = 0;
00619                 return _wsystem(wbuf);
00620 #  endif
00621 #else
00622         return system(f);
00623 #endif
00624 }
00625 
00626 int fl_execvp(const char *file, char *const *argv)
00627 {
00628 #if  defined (WIN32) && !defined(__CYGWIN__)
00629 #ifdef __MINGW32__
00630         return _execvp(fl_utf2mbcs(file), argv);
00631 #else
00632                 int l = strlen(file);
00633                 int i, n, ret;
00634                 xchar **ar;
00635 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00636 //              wbuf[fl_utf2unicode((const unsigned char*)file, l, wbuf)] = 0;
00637                 unsigned wn = fl_utf8toUtf16(file, l, NULL, 0) + 1; // Query length
00638                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00639                 wn = fl_utf8toUtf16(file, l, (unsigned short *)wbuf, wn); // Convert string
00640                 wbuf[wn] = 0;
00641 
00642                 i = 0; n = 0;
00643                 while (argv[i]) {i++; n++;}
00644                 ar = (xchar**) malloc(sizeof(xchar*) * (n + 1));
00645                 i = 0;
00646                 while (i <= n) {
00647                         unsigned wn;
00648                         l = strlen(argv[i]);
00649 //                      ar[i] = (xchar *)malloc(sizeof(xchar) * (l+1));
00650 //                      ar[i][fl_utf2unicode((const unsigned char*)argv[i], l, ar[i])] = 0;
00651                         wn = fl_utf8toUtf16(argv[i], l, NULL, 0) + 1; // Query length
00652                         ar[i] = (xchar *)malloc(sizeof(xchar)*wn);
00653                         wn = fl_utf8toUtf16(argv[i], l, (unsigned short *)ar[i], wn); // Convert string
00654                         ar[i][wn] = 0;
00655                         i++;
00656                 }
00657                 ar[n] = NULL;
00658                 ret = _wexecvp(wbuf, ar);
00659                 i = 0;
00660                 while (i <= n) {
00661                         free(ar[i]);
00662                         i++;
00663                 }
00664                 free(ar);
00665                 return ret;
00666 #endif
00667 #else
00668         return execvp(file, argv);
00669 #endif
00670 }
00671 
00672 
00673 
00674 int fl_chmod(const char* f, int mode)
00675 {
00676 #if  defined (WIN32) && !defined(__CYGWIN__)
00677                 int l = strlen(f);
00678 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00679 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00680                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00681                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00682                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00683                 wbuf[wn] = 0;
00684                 return _wchmod(wbuf, mode);
00685 #else
00686         return chmod(f, mode);
00687 #endif
00688 }
00689 
00690 int fl_access(const char* f, int mode)
00691 {
00692 #if defined (WIN32) && !defined(__CYGWIN__)
00693                 int l = strlen(f);
00694 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00695 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00696                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00697                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00698                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00699                 wbuf[wn] = 0;
00700                 return _waccess(wbuf, mode);
00701 #else
00702         return access(f, mode);
00703 #endif
00704 }
00705 
00706 
00707 int fl_stat(const char* f, struct stat *b)
00708 {
00709 #if defined(WIN32) && !defined(__CYGWIN__)
00710                 int l = strlen(f);
00711 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00712 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00713                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00714                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00715                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00716                 wbuf[wn] = 0;
00717                 return _wstat(wbuf, (struct _stat*)b);
00718 #else
00719         return stat(f, b);
00720 #endif
00721 }
00722 
00723 char *fl_getcwd(char* b, int l)
00724 {
00725         if (b == NULL) {
00726                 b = (char*) malloc(l+1);
00727         }
00728 #if defined(WIN32) && !defined(__CYGWIN__)
00729                 static xchar *wbuf = NULL;
00730                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00731 //              xchar *ret = _wgetcwd(wbuf, l / 5);
00732                 xchar *ret = _wgetcwd(wbuf, l);
00733                 if (ret) {
00734                         unsigned dstlen = l;
00735                         l = wcslen(wbuf);
00736 //                      b[fl_unicode2utf(wbuf, l, b)] = 0;
00737                         dstlen = fl_utf8fromwc(b, dstlen, wbuf, l);
00738                         b[dstlen] = 0;
00739                         return b;
00740                 } else {
00741                         return NULL;
00742                 }
00743 #else
00744         return getcwd(b, l);
00745 #endif
00746 }
00747 
00748 
00749 int fl_unlink(const char* f)
00750 {
00751 #if defined(WIN32) && !defined(__CYGWIN__)
00752                 int l = strlen(f);
00753 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00754 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00755                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00756                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00757                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00758                 wbuf[wn] = 0;
00759                 return _wunlink(wbuf);
00760 #else
00761         return unlink(f);
00762 #endif
00763 }
00764 
00765 int fl_mkdir(const char* f, int mode)
00766 {
00767 #if defined(WIN32) && !defined(__CYGWIN__)
00768                 int l = strlen(f);
00769 //              wbuf = (xchar*)realloc(wbuf, sizeof(short) * (l+1));
00770 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00771                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00772                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00773                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00774                 wbuf[wn] = 0;
00775                 return _wmkdir(wbuf);
00776 #else
00777         return mkdir(f, mode);
00778 #endif
00779 }
00780 
00781 
00782 int fl_rmdir(const char* f)
00783 {
00784 #if defined (WIN32) && !defined(__CYGWIN__)
00785                 int l = strlen(f);
00786 //              wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
00787 //              wbuf[fl_utf2unicode((const unsigned char*)f, l, wbuf)] = 0;
00788                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00789                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00790                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00791                 wbuf[wn] = 0;
00792                 return _wrmdir(wbuf);
00793 #else
00794         return rmdir(f);
00795 #endif
00796 }
00797 
00798 int fl_rename(const char* f, const char *n)
00799 {
00800 #if defined (WIN32) && !defined(__CYGWIN__)
00801                 int l = strlen(f);
00802                 unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length
00803                 wbuf = (xchar*)realloc(wbuf, sizeof(xchar)*wn);
00804                 wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string
00805                 wbuf[wn] = 0;
00806                 l = strlen(n);
00807                 wn = fl_utf8toUtf16(n, l, NULL, 0) + 1; // Query length
00808                 wbuf1 = (xchar*)realloc(wbuf1, sizeof(xchar)*wn);
00809                 wn = fl_utf8toUtf16(n, l, (unsigned short *)wbuf1, wn); // Convert string
00810                 wbuf1[wn] = 0;
00811                 return _wrename(wbuf, wbuf1);
00812 #else
00813         return rename(f, n);
00814 #endif
00815 }
00816 
00817 // recursively create a path in the file system
00818 char fl_make_path( const char *path ) {
00819   if (fl_access(path, 0)) {
00820     const char *s = strrchr( path, '/' );
00821     if ( !s ) return 0;
00822     int len = s-path;
00823     char *p = (char*)malloc( len+1 );
00824     memcpy( p, path, len );
00825     p[len] = 0;
00826     fl_make_path( p );
00827     free( p );
00828     fl_mkdir(path, 0700);
00829   }
00830   return 1;
00831 }
00832 
00833 // strip the filename and create a path
00834 void fl_make_path_for_file( const char *path )
00835 {
00836   const char *s = strrchr( path, '/' );
00837   if ( !s ) return;
00838   int len = s-path;
00839   char *p = (char*)malloc( len+1 );
00840   memcpy( p, path, len );
00841   p[len] = 0;
00842   fl_make_path( p );
00843   free( p );
00844 }
00845 
00848 //
00849 // End of "$Id: fl_utf8.cxx 7975 2010-12-08 12:15:48Z AlbrechtS $".
00850 //