Skip to content

Commit

Permalink
command line UTF-8 support for Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
bbbradsmith committed Apr 22, 2024
1 parent d5c2d6d commit 8f923c0
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 7 deletions.
38 changes: 31 additions & 7 deletions cmd/cmd.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
// stub

#include <nsfplaycore.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdio> // std::fprintf
#include <cstdlib> // std::exit
#include <cstring> // std::strlen

void error_log(const char* msg) { std::fprintf(stderr,"Error: %s\n",msg); }
void debug_print(const char* msg) { std::fprintf(stdout,"Debug: %s\n",msg); }
void fatal_log(const char* msg) { std::fprintf(stderr,"Fatal: %s\n",msg); std::exit(-1); }
// platform.cpp
void platform_setup(int argc, char** argv);
void platform_shutdown();
int platform_argc();
const char* platform_argv(int index);

int main()
void error_log(const char* msg)
{
std::fprintf(stderr,"Error: %s\n",msg);
}

void debug_print(const char* msg)
{
std::fprintf(stdout,"Debug: %s\n",msg);
}

void fatal_log(const char* msg)
{
std::fprintf(stderr,"Fatal: %s\n",msg);
platform_shutdown();
std::exit(-1);
}

int main(int argc, char** argv)
{
platform_setup(argc,argv);
nsfplay_set_error_log(error_log);
nsfplay_set_debug_print(debug_print);
nsfplay_set_fatal(fatal_log);

for (int i=0; i<platform_argc(); ++i)
printf("arg(%d)=[%s]\n",i,platform_argv(i));

const char* TEST_INI =
"# test comment\n"
Expand Down Expand Up @@ -77,5 +100,6 @@ int main()

nsfplay_destroy(core);

platform_shutdown();
return 0;
}
1 change: 1 addition & 0 deletions cmd/cmd.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cmd.cpp" />
<ClCompile Include="platform.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
1 change: 1 addition & 0 deletions cmd/cmd.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="cmd.cpp" />
<ClCompile Include="platform.cpp" />
</ItemGroup>
</Project>
84 changes: 84 additions & 0 deletions cmd/platform.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// platform.cpp
// sets up the console for the chosen platform

#if defined(_WIN32) || defined(_WIN64)

#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // GetConsoleOutputCP, SetConsoleOutputCP
#include <shellapi.h> // GetCommandLineW, CommandLineToArgW
#include <cstdlib> // std::malloc, std::free
#include <stdio.h> // HACK

static UINT startup_cp = 0;
static LPWSTR* store_argv;
static int store_argc;
static char* store_convert = NULL;
static int store_convert_size = 0;

void platform_setup(int argc, char** argv)
{
// Ignore argc/argv from main and get the wide command line from Windows
(void)argc;
(void)argv;
store_argv = CommandLineToArgvW(GetCommandLineW(), &store_argc);

// Windows needs its console set to a UTF8 code page
startup_cp = GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);
}

void platform_shutdown()
{
std::free(store_convert);
SetConsoleOutputCP(startup_cp);
LocalFree(store_argv);
}

int platform_argc()
{
return store_argc;
}

const char* platform_argv(int index)
{
// convert wchar arguments to UTF-8
int new_size = WideCharToMultiByte(CP_UTF8,0,store_argv[index],-1,NULL,0,NULL,NULL);
if (new_size > store_convert_size)
{
free(store_convert);
store_convert_size = new_size;
store_convert = (char*)malloc(store_convert_size);
}
WideCharToMultiByte(CP_UTF8,0,store_argv[index],-1,store_convert,store_convert_size,NULL,NULL);
return store_convert;
}

#else

// other platforms assume a UTF-8 by default

static int store_argc;
static const char* const* store_argv;

void platform_setup(int argc, char** argv)
{
store_argc = argc;
store_argv = argv;
}

void platform_shutdown()
{
}

int platform_argc()
{
return store_argc;
}

const char* platform_argv(int index)
{
return store_argv[index];
}

#endif

0 comments on commit 8f923c0

Please sign in to comment.