summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2016-01-31 12:42:23 +1100
committerErik de Castro Lopo <erikd@mega-nerd.com>2016-01-31 12:42:26 +1100
commit7be5df6c7f3335ba0e3962b9b934f86cca46bb06 (patch)
treee37abc8f85b21c7ede2301dda3ae64251b9bab0a
parent7917b60bdba4df002ecf8df41faada1f9d36d7ae (diff)
downloadflac-7be5df6c7f3335ba0e3962b9b934f86cca46bb06.tar.gz
Refactoring of win_utf8_io
* Simplifies *print functions. * Improves file related functions. * Preparation to move all file related functions into libFLAC. Patch-from: lvqcl <lvqcl.mail@gmail.com>
-rw-r--r--include/share/compat.h2
-rw-r--r--include/share/win_utf8_io.h7
-rw-r--r--src/share/win_utf8_io/win_utf8_io.c327
3 files changed, 176 insertions, 160 deletions
diff --git a/include/share/compat.h b/include/share/compat.h
index faf96887..34d32db4 100644
--- a/include/share/compat.h
+++ b/include/share/compat.h
@@ -151,6 +151,7 @@
#define flac_printf printf_utf8
#define flac_fprintf fprintf_utf8
#define flac_vfprintf vfprintf_utf8
+
#define flac_fopen fopen_utf8
#define flac_chmod chmod_utf8
#define flac_utime utime_utf8
@@ -163,6 +164,7 @@
#define flac_printf printf
#define flac_fprintf fprintf
#define flac_vfprintf vfprintf
+
#define flac_fopen fopen
#define flac_chmod chmod
#define flac_utime utime
diff --git a/include/share/win_utf8_io.h b/include/share/win_utf8_io.h
index 1d153392..ba9ad75c 100644
--- a/include/share/win_utf8_io.h
+++ b/include/share/win_utf8_io.h
@@ -43,6 +43,9 @@ extern "C" {
#include <stdarg.h>
#include <windows.h>
+size_t strlen_utf8(const char *str);
+int win_get_console_width(void);
+
int get_utf8_argv(int *argc, char ***argv);
int printf_utf8(const char *format, ...);
@@ -50,15 +53,11 @@ int fprintf_utf8(FILE *stream, const char *format, ...);
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr);
FILE *fopen_utf8(const char *filename, const char *mode);
-int stat_utf8(const char *path, struct stat *buffer);
int _stat64_utf8(const char *path, struct __stat64 *buffer);
int chmod_utf8(const char *filename, int pmode);
int utime_utf8(const char *filename, struct utimbuf *times);
int unlink_utf8(const char *filename);
int rename_utf8(const char *oldname, const char *newname);
-size_t strlen_utf8(const char *str);
-int win_get_console_width(void);
-int print_console(FILE *stream, const wchar_t *text, size_t len);
HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
#ifdef __cplusplus
diff --git a/src/share/win_utf8_io/win_utf8_io.c b/src/share/win_utf8_io/win_utf8_io.c
index 846b971e..2bf0c931 100644
--- a/src/share/win_utf8_io/win_utf8_io.c
+++ b/src/share/win_utf8_io/win_utf8_io.c
@@ -40,45 +40,41 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h> /* for WideCharToMultiByte and MultiByteToWideChar */
-
#include "share/win_utf8_io.h"
#define UTF8_BUFFER_SIZE 32768
-static
-int local_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
+static int local_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
{
int rc;
#if defined _MSC_VER
if (size == 0)
return 1024;
- rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
+ rc = vsnprintf_s(str, size, _TRUNCATE, fmt, va);
if (rc < 0)
rc = size - 1;
#elif defined __MINGW32__
- rc = __mingw_vsnprintf (str, size, fmt, va);
+ rc = __mingw_vsnprintf(str, size, fmt, va);
#else
- rc = vsnprintf (str, size, fmt, va);
+ rc = vsnprintf(str, size, fmt, va);
#endif
return rc;
}
-static UINT win_utf8_io_codepage = CP_ACP;
-
/* convert WCHAR stored Unicode string to UTF-8. Caller is responsible for freeing memory */
-static
-char *utf8_from_wchar(const wchar_t *wstr)
+static char *utf8_from_wchar(const wchar_t *wstr)
{
char *utf8str;
int len;
- if (!wstr) return NULL;
- if ((len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL)) == 0) return NULL;
- if ((utf8str = (char *)malloc(++len)) == NULL) return NULL;
+ if (!wstr)
+ return NULL;
+ if ((len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL)) == 0)
+ return NULL;
+ if ((utf8str = (char *)malloc(len)) == NULL)
+ return NULL;
if (WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8str, len, NULL, NULL) == 0) {
free(utf8str);
utf8str = NULL;
@@ -88,26 +84,27 @@ char *utf8_from_wchar(const wchar_t *wstr)
}
/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */
-static
-wchar_t *wchar_from_utf8(const char *str)
+static wchar_t *wchar_from_utf8(const char *str)
{
wchar_t *widestr;
int len;
- if (!str) return NULL;
- len=(int)strlen(str)+1;
- if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) != NULL) {
- if (MultiByteToWideChar(win_utf8_io_codepage, 0, str, len, widestr, len) == 0) {
- if (MultiByteToWideChar(CP_ACP, 0, str, len, widestr, len) == 0) { /* try conversion from Ansi in case the initial UTF-8 conversion had failed */
- free(widestr);
- widestr = NULL;
- }
- }
+ if (!str)
+ return NULL;
+ if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) == 0)
+ return NULL;
+ if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) == NULL)
+ return NULL;
+ if (MultiByteToWideChar(CP_UTF8, 0, str, -1, widestr, len) == 0) {
+ free(widestr);
+ widestr = NULL;
}
return widestr;
}
+void set_filename_utf8(int b);
+
/* retrieve WCHAR commandline, expand wildcards and convert everything to UTF-8 */
int get_utf8_argv(int *argc, char ***argv)
{
@@ -126,7 +123,7 @@ int get_utf8_argv(int *argc, char ***argv)
return 1;
}
i = 0;
- /* if __wgetmainargs expands wildcards then it also erroneously converts \\?\c:\path\to\file.flac to \\file.flac */
+ /* when the 4th argument is 1, __wgetmainargs expands wildcards but also erroneously converts \\?\c:\path\to\file.flac to \\file.flac */
if (wgetmainargs(&wargc, &wargv, &wenv, 1, &i) != 0) {
FreeLibrary(handle);
return 1;
@@ -147,7 +144,7 @@ int get_utf8_argv(int *argc, char ***argv)
FreeLibrary(handle); /* do not free it when wargv or wenv are still in use */
if (ret == 0) {
- win_utf8_io_codepage = CP_UTF8;
+ set_filename_utf8(1);
*argc = wargc;
*argv = utf8argv;
} else {
@@ -163,9 +160,11 @@ int get_utf8_argv(int *argc, char ***argv)
size_t strlen_utf8(const char *str)
{
size_t len;
- if ((len = MultiByteToWideChar(win_utf8_io_codepage, 0, str, -1, NULL, 0)) == 0)
- len = strlen(str);
- return len;
+ len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); /* includes terminating null */
+ if (len != 0)
+ return len-1;
+ else
+ return strlen(str);
}
/* get the console width in characters */
@@ -174,80 +173,66 @@ int win_get_console_width(void)
int width = 80;
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- if (GetConsoleScreenBufferInfo(hOut, &csbi) != 0) width = csbi.dwSize.X;
+ if(hOut != INVALID_HANDLE_VALUE && hOut != NULL)
+ if (GetConsoleScreenBufferInfo(hOut, &csbi) != 0)
+ width = csbi.dwSize.X;
return width;
}
/* print functions */
-int print_console(FILE *stream, const wchar_t *text, size_t len)
+static int wprint_console(FILE *stream, const wchar_t *text, size_t len)
{
- static HANDLE hOut;
- static HANDLE hErr;
DWORD out;
- hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- hErr = GetStdHandle(STD_ERROR_HANDLE);
- if (stream == stdout && hOut != INVALID_HANDLE_VALUE && GetFileType(hOut) == FILE_TYPE_CHAR) {
- if (WriteConsoleW(hOut, text, len, &out, NULL) == 0) return -1;
- return out;
- } else if (stream == stderr && hErr != INVALID_HANDLE_VALUE && GetFileType(hErr) == FILE_TYPE_CHAR) {
- if (WriteConsoleW(hErr, text, len, &out, NULL) == 0) return -1;
- return out;
- } else {
- int ret = fputws(text, stream);
- if (ret < 0) return ret;
- return len;
- }
+ int ret;
+
+ do {
+ if (stream == stdout) {
+ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hOut == INVALID_HANDLE_VALUE || hOut == NULL || GetFileType(hOut) != FILE_TYPE_CHAR)
+ break;
+ if (WriteConsoleW(hOut, text, len, &out, NULL) == 0)
+ return -1;
+ return out;
+ }
+ if (stream == stderr) {
+ HANDLE hErr = GetStdHandle(STD_ERROR_HANDLE);
+ if (hErr == INVALID_HANDLE_VALUE || hErr == NULL || GetFileType(hErr) != FILE_TYPE_CHAR)
+ break;
+ if (WriteConsoleW(hErr, text, len, &out, NULL) == 0)
+ return -1;
+ return out;
+ }
+ } while(0);
+
+ ret = fputws(text, stream);
+ if (ret < 0)
+ return ret;
+ return len;
}
int printf_utf8(const char *format, ...)
{
- char *utmp = NULL;
- wchar_t *wout = NULL;
- int ret = -1;
+ int ret;
+ va_list argptr;
+ va_start(argptr, format);
- while (1) {
- va_list argptr;
- if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
- va_start(argptr, format);
- ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
- va_end(argptr);
- if (ret < 0) break;
- if (!(wout = wchar_from_utf8(utmp))) {
- ret = -1;
- break;
- }
- ret = print_console(stdout, wout, wcslen(wout));
- break;
- }
- if (utmp) free(utmp);
- if (wout) free(wout);
+ ret = vfprintf_utf8(stdout, format, argptr);
+
+ va_end(argptr);
return ret;
}
int fprintf_utf8(FILE *stream, const char *format, ...)
{
- char *utmp = NULL;
- wchar_t *wout = NULL;
- int ret = -1;
+ int ret;
+ va_list argptr;
+ va_start(argptr, format);
- while (1) {
- va_list argptr;
- if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
- va_start(argptr, format);
- ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
- va_end(argptr);
- if (ret < 0) break;
- if (!(wout = wchar_from_utf8(utmp))) {
- ret = -1;
- break;
- }
- ret = print_console(stream, wout, wcslen(wout));
- break;
- }
- if (utmp) free(utmp);
- if (wout) free(wout);
+ ret = vfprintf_utf8(stream, format, argptr);
+
+ va_end(argptr);
return ret;
}
@@ -258,125 +243,155 @@ int vfprintf_utf8(FILE *stream, const char *format, va_list argptr)
wchar_t *wout = NULL;
int ret = -1;
- while (1) {
- if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
- if ((ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr)) < 0) break;
+ do {
+ if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE))) break;
+ if ((ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr)) <= 0) break;
if (!(wout = wchar_from_utf8(utmp))) {
ret = -1;
break;
}
- ret = print_console(stream, wout, wcslen(wout));
- break;
- }
- if (utmp) free(utmp);
- if (wout) free(wout);
+ ret = wprint_console(stream, wout, wcslen(wout));
+ } while(0);
+
+ free(utmp);
+ free(wout);
return ret;
}
/* file functions */
+static int utf8_filename = 0;
+
+static void set_filename_utf8(int b)
+{
+ utf8_filename = b ? 1: 0;
+}
+
FILE *fopen_utf8(const char *filename, const char *mode)
{
- wchar_t *wname = NULL;
- wchar_t *wmode = NULL;
- FILE *f = NULL;
-
- while (1) {
- if (!(wname = wchar_from_utf8(filename))) break;
- if (!(wmode = wchar_from_utf8(mode))) break;
- f = _wfopen(wname, wmode);
- break;
- }
- if (wname) free(wname);
- if (wmode) free(wmode);
+ if (0 == utf8_filename) {
+ return fopen(filename, mode);
+ } else {
+ wchar_t *wname = NULL;
+ wchar_t *wmode = NULL;
+ FILE *f = NULL;
+
+ do {
+ if (!(wname = wchar_from_utf8(filename))) break;
+ if (!(wmode = wchar_from_utf8(mode))) break;
+ f = _wfopen(wname, wmode);
+ } while(0);
+
+ free(wname);
+ free(wmode);
- return f;
+ return f;
+ }
}
int _stat64_utf8(const char *path, struct __stat64 *buffer)
{
- wchar_t *wpath;
- int ret;
+ if (0 == utf8_filename) {
+ return _stat64(path, buffer);
+ } else {
+ wchar_t *wpath;
+ int ret;
- if (!(wpath = wchar_from_utf8(path))) return -1;
- ret = _wstat64(wpath, buffer);
- free(wpath);
+ if (!(wpath = wchar_from_utf8(path))) return -1;
+ ret = _wstat64(wpath, buffer);
+ free(wpath);
- return ret;
+ return ret;
+ }
}
int chmod_utf8(const char *filename, int pmode)
{
- wchar_t *wname;
- int ret;
+ if (0 == utf8_filename) {
+ return _chmod(filename, pmode);
+ } else {
+ wchar_t *wname;
+ int ret;
- if (!(wname = wchar_from_utf8(filename))) return -1;
- ret = _wchmod(wname, pmode);
- free(wname);
+ if (!(wname = wchar_from_utf8(filename))) return -1;
+ ret = _wchmod(wname, pmode);
+ free(wname);
- return ret;
+ return ret;
+ }
}
int utime_utf8(const char *filename, struct utimbuf *times)
{
- wchar_t *wname;
- struct __utimbuf64 ut;
- int ret;
-
- if (sizeof(*times) == sizeof(ut)) {
- memcpy(&ut, times, sizeof(ut));
+ if (0 == utf8_filename) {
+ return utime(filename, times);
} else {
+ wchar_t *wname;
+ struct __utimbuf64 ut;
+ int ret;
+
+ if (!(wname = wchar_from_utf8(filename))) return -1;
ut.actime = times->actime;
ut.modtime = times->modtime;
- }
-
- if (!(wname = wchar_from_utf8(filename))) return -1;
- ret = _wutime64(wname, &ut);
- free(wname);
+ ret = _wutime64(wname, &ut);
+ free(wname);
- return ret;
+ return ret;
+ }
}
int unlink_utf8(const char *filename)
{
- wchar_t *wname;
- int ret;
+ if (0 == utf8_filename) {
+ return _unlink(filename);
+ } else {
+ wchar_t *wname;
+ int ret;
- if (!(wname = wchar_from_utf8(filename))) return -1;
- ret = _wunlink(wname);
- free(wname);
+ if (!(wname = wchar_from_utf8(filename))) return -1;
+ ret = _wunlink(wname);
+ free(wname);
- return ret;
+ return ret;
+ }
}
int rename_utf8(const char *oldname, const char *newname)
{
- wchar_t *wold = NULL;
- wchar_t *wnew = NULL;
- int ret = -1;
+ if (0 == utf8_filename) {
+ return rename(oldname, newname);
+ } else {
+ wchar_t *wold = NULL;
+ wchar_t *wnew = NULL;
+ int ret = -1;
- while (1) {
- if (!(wold = wchar_from_utf8(oldname))) break;
- if (!(wnew = wchar_from_utf8(newname))) break;
- ret = _wrename(wold, wnew);
- break;
- }
- if (wold) free(wold);
- if (wnew) free(wnew);
+ do {
+ if (!(wold = wchar_from_utf8(oldname))) break;
+ if (!(wnew = wchar_from_utf8(newname))) break;
+ ret = _wrename(wold, wnew);
+ } while(0);
- return ret;
+ free(wold);
+ free(wnew);
+
+ return ret;
+ }
}
HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
- wchar_t *wname;
- HANDLE handle = INVALID_HANDLE_VALUE;
+ if (0 == utf8_filename) {
+ return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+ } else {
+ wchar_t *wname;
+ HANDLE handle = INVALID_HANDLE_VALUE;
- if ((wname = wchar_from_utf8(lpFileName)) != NULL) {
- handle = CreateFileW(wname, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
- free(wname);
- }
+ if ((wname = wchar_from_utf8(lpFileName)) != NULL) {
+ handle = CreateFileW(wname, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+ free(wname);
+ }
- return handle;
+ return handle;
+ }
}