summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2017-11-10 12:56:00 +0000
committerAlbrecht Schlosser <albrechts.fltk@online.de>2017-11-10 12:56:00 +0000
commit4a088d28f5607ee2713069de71b497eef335e9fd (patch)
treeafb49c2d5c08e5b1ed1c4046be237e0b031f1cdb /src
parentff1e508e5d3462c2da910fedfa442b0f2b9b3617 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/drivers/Posix/Fl_Posix_System_Driver.H1
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.H1
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx48
-rw-r--r--src/fl_utf8.cxx80
4 files changed, 104 insertions, 26 deletions
diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.H b/src/drivers/Posix/Fl_Posix_System_Driver.H
index 5b2060283..6b6d25f61 100644
--- a/src/drivers/Posix/Fl_Posix_System_Driver.H
+++ b/src/drivers/Posix/Fl_Posix_System_Driver.H
@@ -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);}
diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H
index 6b3a1e85e..36a7bf471 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H
+++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H
@@ -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);
diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
index 806a76b22..b1fb5a7e1 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
@@ -65,6 +65,42 @@ extern "C" {
}
/*
+ 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.
This function must be implemented once for every platform.
@@ -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);
}
diff --git a/src/fl_utf8.cxx b/src/fl_utf8.cxx
index 60d7614d6..a116cac9d 100644
--- a/src/fl_utf8.cxx
+++ b/src/fl_utf8.cxx
@@ -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