diff options
author | 2017-09-18 20:28:53 -0400 | |
---|---|---|
committer | 2017-09-18 20:28:53 -0400 | |
commit | 3d553eda60e1c5657b195154d2d6623e3c50ba70 (patch) | |
tree | 9f42e91558c87f4897d349bf85243a07d46ce5f2 /src/osd/osdcore.cpp | |
parent | a7d79f96457f769deb43c36638293604f36320f0 (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.
Diffstat (limited to 'src/osd/osdcore.cpp')
-rw-r--r-- | src/osd/osdcore.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
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; +} |