diff options
author | Chris Robinson <[email protected]> | 2017-08-20 01:39:24 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-08-20 01:50:27 -0700 |
commit | 051828344ecaeff0140034693e3f63355f490e9b (patch) | |
tree | 7558878fe72f9f1033809f4ab6f6145fad281cea | |
parent | 3e56e7f562845829db30292c822d06a85111e4a3 (diff) |
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.
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | utils/makehrtf.c | 84 |
2 files changed, 86 insertions, 1 deletions
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 <stdio.h> #include <stdlib.h> #include <stdarg.h> @@ -83,6 +84,61 @@ #define HUGE_VAL (1.0 / 0.0) #endif + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +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; |