summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author npwoods <npwoods@alumni.cmu.edu>2017-09-18 20:28:53 -0400
committer R. Belmont <rb6502@users.noreply.github.com>2017-09-18 20:28:53 -0400
commit3d553eda60e1c5657b195154d2d6623e3c50ba70 (patch)
tree9f42e91558c87f4897d349bf85243a07d46ce5f2
parenta7d79f96457f769deb43c36638293604f36320f0 (diff)
Attempted to sanitize/rationalize how we access UTF-8 command line arguments (#2532)
Specifically, this creates a call osd_get_command_line() that returns UTF-8 command line arguments as std::vector<std::string>. On non-Windows platforms, this does nothing more than build the vector. On Windows, this invokes GetCommandLineW() and CommandLineToArgvW(). This also attempts to unwind usage of wmain()/_tmain() on Windows, which is not standard. Related to this, this fixes a bug in Imgtool; specifically, non-7 bit ASCII was not being handled correctly in Windows. This is really an admission that the way that Windows handles Unicode and command line arguments sucks, and it is my belief that having a wmain() or _tmain() declaration specific for Windows is a worse solution. C'est la vie. I'm very open to the idea that src/osd/osdcore.[cpp|h] is not the best place to do this. Let me know if I should move it.
-rw-r--r--scripts/src/main.lua5
-rw-r--r--scripts/src/osd/sdl.lua8
-rw-r--r--scripts/src/osd/sdl_cfg.lua1
-rw-r--r--scripts/src/osd/windows.lua3
-rw-r--r--scripts/src/osd/windows_cfg.lua3
-rw-r--r--src/osd/osdcore.cpp48
-rw-r--r--src/osd/osdcore.h4
-rw-r--r--src/osd/sdl/sdlmain.cpp8
-rw-r--r--src/osd/windows/main.cpp24
-rw-r--r--src/osd/windows/winmain.cpp6
-rw-r--r--src/tools/imgtool/main.cpp6
11 files changed, 65 insertions, 51 deletions
diff --git a/scripts/src/main.lua b/scripts/src/main.lua
index ebad23b0c98..5e189aa3ef1 100644
--- a/scripts/src/main.lua
+++ b/scripts/src/main.lua
@@ -68,11 +68,6 @@ end
}
end
- configuration { "vs*" }
- flags {
- "Unicode",
- }
-
configuration { "winstore*" }
-- Windows Required Files
files {
diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua
index f310a11360c..be1f27e9319 100644
--- a/scripts/src/osd/sdl.lua
+++ b/scripts/src/osd/sdl.lua
@@ -94,14 +94,6 @@ function maintargetosdoptions(_target,_subtarget)
links {
"psapi",
}
- configuration { "mingw*" }
- linkoptions{
- "-municode",
- }
- configuration { "vs*" }
- flags {
- "Unicode",
- }
configuration {}
elseif _OPTIONS["targetos"]=="haiku" then
links {
diff --git a/scripts/src/osd/sdl_cfg.lua b/scripts/src/osd/sdl_cfg.lua
index e606e5ad1ea..7e74e43f911 100644
--- a/scripts/src/osd/sdl_cfg.lua
+++ b/scripts/src/osd/sdl_cfg.lua
@@ -107,7 +107,6 @@ if _OPTIONS["targetos"]=="windows" then
defines {
"UNICODE",
"_UNICODE",
- "main=utf8_main",
"_WIN32_WINNT=0x0501",
"WIN32_LEAN_AND_MEAN",
"NOMINMAX",
diff --git a/scripts/src/osd/windows.lua b/scripts/src/osd/windows.lua
index f0e301e79e1..00432b75a8e 100644
--- a/scripts/src/osd/windows.lua
+++ b/scripts/src/osd/windows.lua
@@ -16,9 +16,6 @@ function maintargetosdoptions(_target,_subtarget)
osdmodulestargetconf()
configuration { "mingw*" }
- linkoptions {
- "-municode",
- }
links {
"mingw32",
}
diff --git a/scripts/src/osd/windows_cfg.lua b/scripts/src/osd/windows_cfg.lua
index 1baa45f4255..73598da6760 100644
--- a/scripts/src/osd/windows_cfg.lua
+++ b/scripts/src/osd/windows_cfg.lua
@@ -10,8 +10,7 @@ defines {
configuration { "mingw* or vs*" }
defines {
"UNICODE",
- "_UNICODE",
- "main=utf8_main",
+ "_UNICODE"
}
configuration { "vs*" }
diff --git a/src/osd/osdcore.cpp b/src/osd/osdcore.cpp
index 58bb1157674..4da081e2111 100644
--- a/src/osd/osdcore.cpp
+++ b/src/osd/osdcore.cpp
@@ -8,6 +8,14 @@
#if defined(SDLMAME_ANDROID)
#include <SDL2/SDL.h>
#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#include <stdio.h>
+#include <shellapi.h>
+#include "strconv.h"
+#endif
+
static const int MAXSTACK = 10;
static osd_output *m_stack[MAXSTACK];
static int m_ptr = -1;
@@ -194,3 +202,43 @@ void osd_sleep(osd_ticks_t duration)
{
std::this_thread::sleep_for(std::chrono::high_resolution_clock::duration(duration));
}
+
+
+//============================================================
+// osd_get_command_line - returns command line arguments
+// in an std::vector<std::string> in UTF-8
+//
+// The real purpose of this call is to hide details necessary
+// on Windows (provided that one wants to avoid using wmain)
+//============================================================
+
+std::vector<std::string> osd_get_command_line(int argc, char *argv[])
+{
+ std::vector<std::string> results;
+#ifdef WIN32
+ {
+ // Get the command line from Windows
+ int count;
+ LPWSTR *wide_args = CommandLineToArgvW(GetCommandLineW(), &count);
+
+ // Convert the returned command line arguments to UTF8 std::vector<std::string>
+ results.reserve(count);
+ for (int i = 0; i < count; i++)
+ {
+ std::string arg = osd::text::from_wstring(wide_args[i]);
+ results.push_back(std::move(arg));
+ }
+
+ LocalFree(wide_args);
+ }
+#else // !WIN32
+ {
+ // for non Windows platforms, we are assuming that arguments are
+ // already UTF-8; we just need to convert to std::vector<std::string>
+ results.reserve(argc);
+ for (int i = 0; i < argc; i++)
+ results.emplace_back(argv[i]);
+ }
+#endif // WIN32
+ return results;
+}
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index c22bfd03800..2bfc7cb5950 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -26,6 +26,7 @@
#include <cstdint>
#include <memory>
#include <string>
+#include <vector>
/***************************************************************************
@@ -883,6 +884,9 @@ void CLIB_DECL osd_printf_info(const char *format, ...) ATTR_PRINTF(1,2);
void CLIB_DECL osd_printf_verbose(const char *format, ...) ATTR_PRINTF(1,2);
void CLIB_DECL osd_printf_debug(const char *format, ...) ATTR_PRINTF(1,2);
+// returns command line arguments as an std::vector<std::string> in UTF-8
+std::vector<std::string> osd_get_command_line(int argc, char *argv[]);
+
/* discourage the use of printf directly */
/* sadly, can't do this because of the ATTR_PRINTF under GCC */
/*
diff --git a/src/osd/sdl/sdlmain.cpp b/src/osd/sdl/sdlmain.cpp
index 3f4b3815359..4fa78bbed38 100644
--- a/src/osd/sdl/sdlmain.cpp
+++ b/src/osd/sdl/sdlmain.cpp
@@ -183,15 +183,9 @@ sdl_options::sdl_options()
extern "C" DECLSPEC void SDLCALL SDL_SetModuleHandle(void *hInst);
#endif
-// translated to utf8_main
-#if defined(SDLMAME_WIN32)
-int main(std::vector<std::string> &args)
-{
-#else
int main(int argc, char** argv)
{
- std::vector<std::string> args(argv, argv+argc);
-#endif
+ std::vector<std::string> args = osd_get_command_line(argc, argv);
int res = 0;
// disable I/O buffering
diff --git a/src/osd/windows/main.cpp b/src/osd/windows/main.cpp
index e87fa24e57c..efe2ad68d72 100644
--- a/src/osd/windows/main.cpp
+++ b/src/osd/windows/main.cpp
@@ -18,29 +18,7 @@
#include "strconv.h"
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-
-extern int utf8_main(std::vector<std::string> &args);
-//============================================================
-// main
-//============================================================
-
-#ifdef UNICODE
-extern "C" int _tmain(int argc, TCHAR **argv)
-{
- int i;
- std::vector<std::string> argv_vectors(argc);
-
- // convert arguments to UTF-8
- for (i = 0; i < argc; i++)
- argv_vectors[i] = osd::text::from_tstring(argv[i]);
-
- // run utf8_main
- return utf8_main(argv_vectors);
-}
-#endif
-
-#else
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#include "winmain.h"
diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp
index 805a769d1b8..b1702f7fac3 100644
--- a/src/osd/windows/winmain.cpp
+++ b/src/osd/windows/winmain.cpp
@@ -273,11 +273,13 @@ const options_entry windows_options::s_option_entries[] =
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
//============================================================
-// utf8_main
+// main
//============================================================
-int main(std::vector<std::string> &args)
+int main(int argc, char *argv[])
{
+ std::vector<std::string> args = osd_get_command_line(argc, argv);
+
// use small output buffers on non-TTYs (i.e. pipes)
if (!isatty(fileno(stdout)))
setvbuf(stdout, (char *) nullptr, _IOFBF, 64);
diff --git a/src/tools/imgtool/main.cpp b/src/tools/imgtool/main.cpp
index 9559b687c9d..516c4f49e4e 100644
--- a/src/tools/imgtool/main.cpp
+++ b/src/tools/imgtool/main.cpp
@@ -864,6 +864,12 @@ int main(int argc, char *argv[])
return -1;
#endif // MAME_DEBUG
+ // convert arguments to UTF-8
+ std::vector<std::string> args = osd_get_command_line(argc, argv);
+ argv = (char **)alloca(sizeof(char *) * args.size());
+ for (i = 0; i < args.size(); i++)
+ argv[i] = (char *)args[i].c_str();
+
util::stream_format(std::wcout, L"\n");
if (argc > 1)