Improve handling main() with UTF-8 args on Windows
parent
476e9d7522
commit
fd52c828a9
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
static void GetUnicodeArgs(int *argc, 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);
|
||||
}
|
||||
|
||||
total = sizeof(**argv) * nargs;
|
||||
for(i = 0;i < nargs;i++)
|
||||
total += WideCharToMultiByte(CP_UTF8, 0, args[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++)
|
||||
{
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, args[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)
|
||||
|
||||
#else
|
||||
|
||||
/* Do nothing. */
|
||||
#define GET_UNICODE_ARGS(argc, argv)
|
||||
/* 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
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int wmain(int argc, wchar_t **wargv)
|
||||
{
|
||||
char **argv;
|
||||
size_t total;
|
||||
int i;
|
||||
|
||||
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));
|
||||
|
||||
#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, wargv[i], -1, argv[i], 65535, NULL, NULL);
|
||||
argv[i+1] = argv[i] + len;
|
||||
}
|
||||
WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], 65535, NULL, NULL);
|
||||
|
||||
#ifdef __cplusplus
|
||||
return main(argc, argv);
|
||||
#else
|
||||
i = main(argc, argv);
|
||||
|
||||
free(argv);
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
#endif /* !defined(SDL_MAIN_NEEDED) && !defined(SDL_MAIN_AVAILABLE) */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* WIN_MAIN_UTF8_H */
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#include "common/alhelpers.h"
|
||||
|
||||
#include "win_main_utf8.h"
|
||||
|
||||
|
||||
#if defined(_WIN64)
|
||||
#define SZFMT "%I64u"
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
#include "common/alhelpers.h"
|
||||
|
||||
#include "win_main_utf8.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
Loading…
Reference in New Issue