From 051828344ecaeff0140034693e3f63355f490e9b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 20 Aug 2017 01:39:24 -0700 Subject: [PATCH] Improve unicode handling for makehrtf Command line parameters and filenames are now unicode-aware (the .def files should be UTF-8 encoded, if they contain any non-ASCII-7 characters). Unicode characters might not display correctly in the console, but it should process them correctly. --- CMakeLists.txt | 3 ++ utils/makehrtf.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63c2411b..5adfac25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1399,6 +1399,9 @@ IF(ALSOFT_UTILS) IF(HAVE_LIBM) TARGET_LINK_LIBRARIES(makehrtf m) ENDIF() + IF(WIN32 AND CMAKE_COMPILER_IS_GNUCC) + SET_PROPERTY(TARGET makehrtf APPEND_STRING PROPERTY LINK_FLAGS " -municode") + ENDIF() ADD_EXECUTABLE(bsincgen utils/bsincgen.c) SET_PROPERTY(TARGET bsincgen APPEND PROPERTY COMPILE_FLAGS ${EXTRA_CFLAGS}) diff --git a/utils/makehrtf.c b/utils/makehrtf.c index c7f5d4ad..344754e9 100644 --- a/utils/makehrtf.c +++ b/utils/makehrtf.c @@ -60,6 +60,7 @@ #include "config.h" +#define _UNICODE #include #include #include @@ -83,6 +84,61 @@ #define HUGE_VAL (1.0 / 0.0) #endif + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include + +static char *ToUTF8(const wchar_t *from) +{ + char *out = NULL; + int len; + if((len=WideCharToMultiByte(CP_UTF8, 0, from, -1, NULL, 0, NULL, NULL)) > 0) + { + out = calloc(sizeof(*out), len); + WideCharToMultiByte(CP_UTF8, 0, from, -1, out, len, NULL, NULL); + out[len-1] = 0; + } + return out; +} + +static WCHAR *FromUTF8(const char *str) +{ + WCHAR *out = NULL; + int len; + + if((len=MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) > 0) + { + out = calloc(sizeof(WCHAR), len); + MultiByteToWideChar(CP_UTF8, 0, str, -1, out, len); + out[len-1] = 0; + } + return out; +} + + +static FILE *my_fopen(const char *fname, const char *mode) +{ + WCHAR *wname=NULL, *wmode=NULL; + FILE *file = NULL; + + wname = FromUTF8(fname); + wmode = FromUTF8(mode); + if(!wname) + fprintf(stderr, "Failed to convert UTF-8 filename: \"%s\"\n", fname); + else if(!wmode) + fprintf(stderr, "Failed to convert UTF-8 mode: \"%s\"\n", mode); + else + file = _wfopen(wname, wmode); + + free(wname); + free(wmode); + + return file; +} +#define fopen my_fopen +#endif + // The epsilon used to maintain signal stability. #define EPSILON (1e-9) @@ -2872,8 +2928,34 @@ static void PrintHelp(const char *argv0, FILE *ofile) fprintf(ofile, " Use of '%%r' will be substituted with the data set sample rate.\n"); } +#ifdef _WIN32 +#define main my_main +int main(int argc, const char *argv[]); + +static char **arglist; +static void cleanup_arglist(void) +{ + int i; + for(i = 0;arglist[i];i++) + free(arglist[i]); + free(arglist); +} + +int wmain(int argc, const wchar_t *wargv[]) +{ + int i; + + atexit(cleanup_arglist); + arglist = calloc(sizeof(*arglist), argc); + for(i = 0;i < argc;i++) + arglist[i] = ToUTF8(wargv[i]); + + return main(argc, (const char**)arglist); +} +#endif + // Standard command line dispatch. -int main(const int argc, const char *argv[]) +int main(int argc, const char *argv[]) { const char *inName = NULL, *outName = NULL; OutputFormatT outFormat; -- 2.11.4.GIT