Add missing platform wrapper fl_chdir() for chdir().

Tested under Windows and Linux, but not yet used in library code.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12549 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Albrecht Schlosser 2017-11-10 12:56:00 +00:00
parent ff1e508e5d
commit 4a088d28f5
6 changed files with 116 additions and 34 deletions

View File

@ -63,7 +63,7 @@ public:
static const int fl_YValue;
static const int fl_XNegative;
static const int fl_YNegative;
// implement if the system adds unwanted program argument(s)
virtual int single_arg(const char *arg) { return 0; }
// implement if the system adds unwanted program argument pair(s)
@ -81,7 +81,7 @@ public:
static void fatal(const char* format, ...);
// implement to set the default effect of Fl::error()
virtual void fatal(const char* format, va_list args);
// implement these to support cross-platform file operations
virtual char *utf2mbcs(const char *s) {return (char*)s;}
virtual char *getenv(const char* v) {return NULL;}
@ -100,12 +100,13 @@ public:
virtual int access(const char* f, int mode) { return -1;}
virtual int stat(const char* f, struct stat *b) { return -1;}
virtual char *getcwd(char* b, int l) {return NULL;}
virtual int chdir(const char* path) {return -1;}
virtual int unlink(const char* fname) {return -1;}
virtual int mkdir(const char* f, int mode) {return -1;}
virtual int rmdir(const char* f) {return -1;}
virtual int rename(const char* f, const char *n) {return -1;}
// the default implementation of these utf8... functions should be enough
// the default implementation of these utf8... functions should be enough
virtual unsigned utf8towc(const char* src, unsigned srclen, wchar_t* dst, unsigned dstlen);
virtual unsigned utf8fromwc(char* dst, unsigned dstlen, const wchar_t* src, unsigned srclen);
virtual int utf8locale() {return 1;}

View File

@ -160,10 +160,13 @@ FL_EXPORT int fl_chmod(const char* f, int mode);
FL_EXPORT int fl_access(const char* f, int mode);
/* OD: Portable UTF-8 aware stat wrapper */
FL_EXPORT int fl_stat( const char *path, struct stat *buffer );
FL_EXPORT int fl_stat(const char *path, struct stat *buffer);
/* OD: Portable UTF-8 aware getcwd wrapper */
FL_EXPORT char* fl_getcwd( char *buf, int maxlen);
FL_EXPORT char *fl_getcwd(char *buf, int len);
/* Portable UTF-8 aware chdir wrapper */
FL_EXPORT int fl_chdir(const char *path);
/* OD: Portable UTF-8 aware fopen wrapper */
FL_EXPORT FILE *fl_fopen(const char *f, const char *mode);
@ -175,9 +178,9 @@ FL_EXPORT int fl_system(const char* f);
FL_EXPORT int fl_execvp(const char *file, char *const *argv);
/* OD: Portable UTF-8 aware open wrapper */
FL_EXPORT int fl_open(const char* f, int o, ...);
FL_EXPORT int fl_open(const char *fname, int oflags, ...);
FL_EXPORT int fl_open_ext(const char* fname, int binary, int oflags, ...);
FL_EXPORT int fl_open_ext(const char *fname, int binary, int oflags, ...);
/* OD: Portable UTF-8 aware unlink wrapper */
FL_EXPORT int fl_unlink(const char *fname);

View File

@ -60,6 +60,7 @@ public:
virtual int access(const char* f, int mode) { return ::access(f, mode);}
virtual int stat(const char* f, struct stat *b) { return ::stat(f, b);}
virtual char *getcwd(char* b, int l) {return ::getcwd(b, l);}
virtual int chdir(const char* path) {return ::chdir(path);}
virtual int unlink(const char* f) {return ::unlink(f);}
virtual int rmdir(const char* f) {return ::rmdir(f);}
virtual int rename(const char* f, const char *n) {return ::rename(f, n);}

View File

@ -58,6 +58,7 @@ public:
virtual int access(const char* f, int mode);
virtual int stat(const char* f, struct stat *b);
virtual char *getcwd(char* b, int l);
virtual int chdir(const char* path);
virtual int unlink(const char* f);
virtual int mkdir(const char* f, int mode);
virtual int rmdir(const char* f);

View File

@ -64,6 +64,42 @@ extern "C" {
int (*compar)(struct dirent **, struct dirent **));
}
/*
Convert a filename or path from UTF-8 to Windows wide character encoding (UTF-16).
This helper function is used througout this file to convert UTF-8 strings
to Windows specific UTF-8 encoding for filenames and paths.
The argument 'wbuf' must have been initialized with NULL or a previous call
to malloc() or realloc(). The global static variables above, particularly
wbuf, may be used to share one static pointer for many calls. Ideally
every call to this function would have its own static pointer though.
If the converted string doesn't fit into the allocated size of 'wbuf' or
'wbuf' is NULL a new buffer is allocated with realloc(). Hence, the pointer
'wbuf' can be shared among multiple calls of this function if it has been
initialized with NULL (or malloc or realloc) before the first call.
The return value is either the old value of 'wbuf' (if the string fits)
or a pointer at the (re)allocated buffer.
Pseudo doxygen docs (static function intentionally not documented):
param[in] path path to new working directory
param[in,out] wbuf pointer to string buffer (in)
new string (out, pointer may be changed)
returns pointer to (new) string (buffer); may be changed
*/
static wchar_t *path_to_wchar(const char *path, wchar_t *&wbuf) {
unsigned len = (unsigned)strlen(path);
unsigned wn = fl_utf8toUtf16(path, len, NULL, 0) + 1; // Query length
wbuf = (wchar_t *)realloc(wbuf, sizeof(wchar_t) * wn);
wn = fl_utf8toUtf16(path, len, (unsigned short *)wbuf, wn); // Convert string
wbuf[wn] = 0;
return wbuf;
}
/*
Creates a driver that manages all system related calls.
@ -250,11 +286,15 @@ char *Fl_WinAPI_System_Driver::getcwd(char* b, int l) {
}
}
int Fl_WinAPI_System_Driver::unlink(const char* f) {
size_t l = strlen(f);
unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length
int Fl_WinAPI_System_Driver::chdir(const char *path) {
return _wchdir(path_to_wchar(path, wbuf));
}
int Fl_WinAPI_System_Driver::unlink(const char *fname) {
size_t len = strlen(fname);
unsigned wn = fl_utf8toUtf16(fname, (unsigned)len, NULL, 0) + 1; // Query length
wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn);
wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string
wn = fl_utf8toUtf16(fname, (unsigned)len, (unsigned short *)wbuf, wn); // Convert string
wbuf[wn] = 0;
return _wunlink(wbuf);
}

View File

@ -318,35 +318,38 @@ char *fl_getenv(const char* v) {
This function is especially useful on the Windows platform where the
standard open() function fails with UTF-8 encoded non-ASCII filenames.
\param f the UTF-8 encoded filename
\param oflags other arguments are as in the standard open() function
\return a file descriptor upon successful completion, or -1 in case of error.
\sa fl_fopen(), fl_open_ext().
\param[in] fname the UTF-8 encoded filename
\param[in] oflags other arguments are as in the standard open() function
\return a file descriptor upon successful completion, or -1 in case of error.
\see fl_fopen(), fl_open_ext().
*/
int fl_open(const char* f, int oflags, ...)
{
int fl_open(const char* fname, int oflags, ...) {
int pmode;
va_list ap;
va_start(ap, oflags);
pmode = va_arg (ap, int);
va_end(ap);
return Fl::system_driver()->open(f, oflags, pmode);
return Fl::system_driver()->open(fname, oflags, pmode);
}
/** Cross-platform function to open files with a UTF-8 encoded name.
In comparison with fl_open(), this function allows to control whether
the file is opened in binary (a.k.a. untranslated) mode. This is especially
useful on the Windows platform where files are by default opened in
text (translated) mode.
\param fname the UTF-8 encoded filename
\param binary if non-zero, the file is to be accessed in binary (a.k.a.
untranslated) mode.
\param oflags,... these arguments are as in the standard open() function.
Setting \p oflags to zero opens the file for reading.
\param[in] fname the UTF-8 encoded filename
\param[in] binary if non-zero, the file is to be accessed in binary
(a.k.a. untranslated) mode.
\param[in] oflags,... these arguments are as in the standard open() function.
Setting \p oflags to zero opens the file for reading.
\return a file descriptor upon successful completion, or -1 in case of error.
*/
int fl_open_ext(const char* fname, int binary, int oflags, ...)
{
int fl_open_ext(const char* fname, int binary, int oflags, ...) {
int pmode;
va_list ap;
va_start(ap, oflags);
@ -432,7 +435,36 @@ int fl_stat(const char* f, struct stat *b) {
return Fl::system_driver()->stat(f, b);
}
// TODO: add fl_chdir if we have fl_getcwd
/** Cross-platform function to change the current working directory,
given as a UTF-8 encoded string.
This function is especially useful on the Windows platform where the
standard _wchdir() function needs a \p path in UTF-16 encoding.
The \p path is converted to a system specific encoding if necessary
and the system specific \p chdir(converted_path) function is called.
The function returns 0 on success and -1 on error. Depending on the
platform, \p errno \b may be set if an error occurs.
\note The possible errno values are platform specific. Refer to the
documentation of the platform specific chdir() function.
If the function is not implemented on a particular platform the
default implementation returns -1 and \p errno is \b not set.
If the \p path is \p NULL the function returns -1, but \p errno is
\b not changed. This is a convenience feature of fl_chdir() as
opposed to chdir().
\param[in] path the target directory for chdir (may be \p NULL)
\return 0 if successful, -1 on error (errno may be set)
*/
int fl_chdir(const char* path) {
if (!path)
return -1;
return Fl::system_driver()->chdir(path);
}
/** Cross-platform function to get the current working directory
as a UTF-8 encoded value.
@ -440,15 +472,19 @@ int fl_stat(const char* f, struct stat *b) {
This function is especially useful on the Windows platform where the
standard _wgetcwd() function returns UTF-16 encoded non-ASCII filenames.
\param b the buffer to populate
\param l the length of the buffer
\return the CWD encoded as UTF-8.
If \p buf is \p NULL a buffer of size \p (len+1) is allocated, filled with
the current working directory, and returned. In this case the buffer must
be released by the caller with free() to prevent memory leaks.
\param[in] buf the buffer to populate (may be NULL)
\param[in] len the length of the buffer
\return the CWD encoded as UTF-8
*/
char *fl_getcwd(char* b, int l) {
if (b == NULL) {
b = (char*) malloc(l+1);
char *fl_getcwd(char *buf, int len) {
if (buf == NULL) {
buf = (char*)malloc(len + 1);
}
return Fl::system_driver()->getcwd(b, l);
return Fl::system_driver()->getcwd(buf, len);
}
/** Cross-platform function to unlink() (that is, delete) a file using