aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-08-12 17:40:00 -0700
committerChris Robinson <[email protected]>2020-08-12 17:40:00 -0700
commitfd52c828a9c4f4bb7ed3a4dcfe4a5b4ed5664246 (patch)
tree622b82e411c1b27a520ac1234b4baf39d0dd909f
parent476e9d7522bef4de85dab2113e9cba85007e2e2a (diff)
Improve handling main() with UTF-8 args on Windows
-rw-r--r--CMakeLists.txt33
-rw-r--r--common/win_main_utf8.h92
-rw-r--r--examples/alrecord.c2
-rw-r--r--examples/altonegen.c2
-rw-r--r--utils/makemhr/makemhr.cpp2
-rw-r--r--utils/openal-info.c3
-rw-r--r--utils/sofa-info.cpp4
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]);