diff options
author | Chris Robinson <[email protected]> | 2020-08-12 17:40:00 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-08-12 17:40:00 -0700 |
commit | fd52c828a9c4f4bb7ed3a4dcfe4a5b4ed5664246 (patch) | |
tree | 622b82e411c1b27a520ac1234b4baf39d0dd909f | |
parent | 476e9d7522bef4de85dab2113e9cba85007e2e2a (diff) |
Improve handling main() with UTF-8 args on Windows
-rw-r--r-- | CMakeLists.txt | 33 | ||||
-rw-r--r-- | common/win_main_utf8.h | 92 | ||||
-rw-r--r-- | examples/alrecord.c | 2 | ||||
-rw-r--r-- | examples/altonegen.c | 2 | ||||
-rw-r--r-- | utils/makemhr/makemhr.cpp | 2 | ||||
-rw-r--r-- | utils/openal-info.c | 3 | ||||
-rw-r--r-- | utils/sofa-info.cpp | 4 |
7 files changed, 85 insertions, 53 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f02dc89a..8fe3c8de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1342,12 +1342,16 @@ if(ALSOFT_INSTALL_AMBDEC_PRESETS) endif() message(STATUS "") +set(UNICODE_FLAG ) +if(MINGW) + set(UNICODE_FLAG ${UNICODE_FLAG} -municode) +endif() set(EXTRA_INSTALLS ) if(ALSOFT_UTILS) add_executable(openal-info utils/openal-info.c) target_include_directories(openal-info PRIVATE ${OpenAL_SOURCE_DIR}/common) target_compile_options(openal-info PRIVATE ${C_FLAGS}) - target_link_libraries(openal-info PRIVATE ${LINKER_FLAGS} OpenAL) + target_link_libraries(openal-info PRIVATE ${LINKER_FLAGS} OpenAL ${UNICODE_FLAG}) if(ALSOFT_INSTALL_EXAMPLES) set(EXTRA_INSTALLS ${EXTRA_INSTALLS} openal-info) endif() @@ -1378,7 +1382,7 @@ if(ALSOFT_UTILS) target_include_directories(makemhr PRIVATE ${OpenAL_BINARY_DIR} ${OpenAL_SOURCE_DIR}/utils) target_compile_options(makemhr PRIVATE ${C_FLAGS}) - target_link_libraries(makemhr PRIVATE ${LINKER_FLAGS} sofa-support) + target_link_libraries(makemhr PRIVATE ${LINKER_FLAGS} sofa-support ${UNICODE_FLAG}) if(ALSOFT_INSTALL_EXAMPLES) set(EXTRA_INSTALLS ${EXTRA_INSTALLS} makemhr) endif() @@ -1388,7 +1392,7 @@ if(ALSOFT_UTILS) target_compile_definitions(sofa-info PRIVATE ${CPP_DEFS}) target_include_directories(sofa-info PRIVATE ${OpenAL_SOURCE_DIR}/utils) target_compile_options(sofa-info PRIVATE ${C_FLAGS}) - target_link_libraries(sofa-info PRIVATE ${LINKER_FLAGS} sofa-support) + target_link_libraries(sofa-info PRIVATE ${LINKER_FLAGS} sofa-support ${UNICODE_FLAG}) endif() message(STATUS "Building utility programs") @@ -1410,10 +1414,10 @@ target_link_libraries(ex-common PUBLIC OpenAL PRIVATE ${RT_LIB}) if(ALSOFT_EXAMPLES) add_executable(altonegen examples/altonegen.c) - target_link_libraries(altonegen PRIVATE ${LINKER_FLAGS} ${MATH_LIB} ex-common) + target_link_libraries(altonegen PRIVATE ${LINKER_FLAGS} ${MATH_LIB} ex-common ${UNICODE_FLAG}) add_executable(alrecord examples/alrecord.c) - target_link_libraries(alrecord PRIVATE ${LINKER_FLAGS} ex-common) + target_link_libraries(alrecord PRIVATE ${LINKER_FLAGS} ex-common ${UNICODE_FLAG}) if(ALSOFT_INSTALL_EXAMPLES) set(EXTRA_INSTALLS ${EXTRA_INSTALLS} altonegen alrecord) @@ -1423,27 +1427,32 @@ if(ALSOFT_EXAMPLES) if(SNDFILE_FOUND) add_executable(alplay examples/alplay.c) - target_link_libraries(alplay PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common) + target_link_libraries(alplay PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common + ${UNICODE_FLAG}) add_executable(alstream examples/alstream.c) - target_link_libraries(alstream PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common) + target_link_libraries(alstream PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common + ${UNICODE_FLAG}) add_executable(alreverb examples/alreverb.c) - target_link_libraries(alreverb PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common) + target_link_libraries(alreverb PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common + ${UNICODE_FLAG}) add_executable(almultireverb examples/almultireverb.c) target_link_libraries(almultireverb - PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common ${MATH_LIB}) + PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common ${MATH_LIB} ${UNICODE_FLAG}) add_executable(allatency examples/allatency.c) - target_link_libraries(allatency PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common) + target_link_libraries(allatency PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common + ${UNICODE_FLAG}) add_executable(alhrtf examples/alhrtf.c) target_link_libraries(alhrtf - PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common ${MATH_LIB}) + PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common ${MATH_LIB} ${UNICODE_FLAG}) add_executable(alstreamcb examples/alstreamcb.cpp) - target_link_libraries(alstreamcb PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common) + target_link_libraries(alstreamcb PRIVATE ${LINKER_FLAGS} SndFile::SndFile ex-common + ${UNICODE_FLAG}) if(ALSOFT_INSTALL_EXAMPLES) set(EXTRA_INSTALLS ${EXTRA_INSTALLS} alplay alstream alreverb almultireverb allatency diff --git a/common/win_main_utf8.h b/common/win_main_utf8.h index 242d3b8a..e40c2158 100644 --- a/common/win_main_utf8.h +++ b/common/win_main_utf8.h @@ -13,10 +13,23 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <shellapi.h> +#include <wchar.h> + +#ifdef __cplusplus +#include <memory> + +#define STATIC_CAST(...) static_cast<__VA_ARGS__> +#define REINTERPRET_CAST(...) reinterpret_cast<__VA_ARGS__> + +#else + +#define STATIC_CAST(...) (__VA_ARGS__) +#define REINTERPRET_CAST(...) (__VA_ARGS__) +#endif static FILE *my_fopen(const char *fname, const char *mode) { - WCHAR *wname=NULL, *wmode=NULL; + wchar_t *wname=NULL, *wmode=NULL; int namelen, modelen; FILE *file = NULL; errno_t err; @@ -30,7 +43,12 @@ static FILE *my_fopen(const char *fname, const char *mode) return NULL; } - wname = (WCHAR*)calloc(sizeof(WCHAR), namelen+modelen); +#ifdef __cplusplus + auto strbuf = std::make_unique<wchar_t[]>(static_cast<size_t>(namelen+modelen)); + wname = strbuf.get(); +#else + wname = (wchar_t*)calloc(sizeof(wchar_t), (size_t)(namelen+modelen)); +#endif wmode = wname + namelen; MultiByteToWideChar(CP_UTF8, 0, fname, -1, wname, namelen); MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, modelen); @@ -42,56 +60,58 @@ static FILE *my_fopen(const char *fname, const char *mode) file = NULL; } +#ifndef __cplusplus free(wname); - +#endif return file; } #define fopen my_fopen -static char **arglist; -static void cleanup_arglist(void) -{ - free(arglist); -} +/* SDL overrides main and provides UTF-8 args for us. */ +#if !defined(SDL_MAIN_NEEDED) && !defined(SDL_MAIN_AVAILABLE) +int my_main(int, char**); +#define main my_main -static void GetUnicodeArgs(int *argc, char ***argv) +#ifdef __cplusplus +extern "C" +#endif +int wmain(int argc, wchar_t **wargv) { + char **argv; size_t total; - wchar_t **args; - int nargs, i; - - args = CommandLineToArgvW(GetCommandLineW(), &nargs); - if(!args) - { - fprintf(stderr, "Failed to get command line args: %ld\n", GetLastError()); - exit(EXIT_FAILURE); - } + int i; - total = sizeof(**argv) * nargs; - for(i = 0;i < nargs;i++) - total += WideCharToMultiByte(CP_UTF8, 0, args[i], -1, NULL, 0, NULL, NULL); + total = sizeof(*argv) * STATIC_CAST(size_t)(argc); + for(i = 0;i < argc;i++) + total += STATIC_CAST(size_t)(WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, + NULL)); - atexit(cleanup_arglist); - arglist = *argv = (char**)calloc(1, total); - (*argv)[0] = (char*)(*argv + nargs); - for(i = 0;i < nargs-1;i++) +#ifdef __cplusplus + auto argbuf = std::make_unique<char[]>(total); + argv = reinterpret_cast<char**>(argbuf.get()); +#else + argv = (char**)calloc(1, total); +#endif + argv[0] = REINTERPRET_CAST(char*)(argv + argc); + for(i = 0;i < argc-1;i++) { - int len = WideCharToMultiByte(CP_UTF8, 0, args[i], -1, (*argv)[i], 65535, NULL, NULL); - (*argv)[i+1] = (*argv)[i] + len; + int len = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], 65535, NULL, NULL); + argv[i+1] = argv[i] + len; } - WideCharToMultiByte(CP_UTF8, 0, args[i], -1, (*argv)[i], 65535, NULL, NULL); - *argc = nargs; - - LocalFree(args); -} -#define GET_UNICODE_ARGS(argc, argv) GetUnicodeArgs(argc, argv) + WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], 65535, NULL, NULL); +#ifdef __cplusplus + return main(argc, argv); #else + i = main(argc, argv); -/* Do nothing. */ -#define GET_UNICODE_ARGS(argc, argv) - + free(argv); + return i; #endif +} +#endif /* !defined(SDL_MAIN_NEEDED) && !defined(SDL_MAIN_AVAILABLE) */ + +#endif /* _WIN32 */ #endif /* WIN_MAIN_UTF8_H */ diff --git a/examples/alrecord.c b/examples/alrecord.c index a66e5471..0e81eb76 100644 --- a/examples/alrecord.c +++ b/examples/alrecord.c @@ -35,6 +35,8 @@ #include "common/alhelpers.h" +#include "win_main_utf8.h" + #if defined(_WIN64) #define SZFMT "%I64u" diff --git a/examples/altonegen.c b/examples/altonegen.c index 553bc996..a09cbdf8 100644 --- a/examples/altonegen.c +++ b/examples/altonegen.c @@ -44,6 +44,8 @@ #include "common/alhelpers.h" +#include "win_main_utf8.h" + #ifndef M_PI #define M_PI (3.14159265358979323846) #endif diff --git a/utils/makemhr/makemhr.cpp b/utils/makemhr/makemhr.cpp index ba1d5d68..96823745 100644 --- a/utils/makemhr/makemhr.cpp +++ b/utils/makemhr/makemhr.cpp @@ -1534,8 +1534,6 @@ int main(int argc, char *argv[]) double limit; int opt; - GET_UNICODE_ARGS(&argc, &argv); - if(argc < 2) { fprintf(stdout, "HRTF Processing and Composition Utility\n\n"); diff --git a/utils/openal-info.c b/utils/openal-info.c index 46e66d45..1788d118 100644 --- a/utils/openal-info.c +++ b/utils/openal-info.c @@ -31,6 +31,9 @@ #include "AL/al.h" #include "AL/alext.h" +#include "win_main_utf8.h" + + #ifndef ALC_ENUMERATE_ALL_EXT #define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012 #define ALC_ALL_DEVICES_SPECIFIER 0x1013 diff --git a/utils/sofa-info.cpp b/utils/sofa-info.cpp index 6117b1e6..26a2ee3f 100644 --- a/utils/sofa-info.cpp +++ b/utils/sofa-info.cpp @@ -27,10 +27,10 @@ #include <vector> #include "sofa-support.h" -#include "win_main_utf8.h" #include "mysofa.h" +#include "win_main_utf8.h" using uint = unsigned int; @@ -118,8 +118,6 @@ static void SofaInfo(const char *filename) int main(int argc, char *argv[]) { - GET_UNICODE_ARGS(&argc, &argv); - if(argc != 2) { fprintf(stdout, "Usage: %s <sofa-file>\n", argv[0]); |