Skip to content

Instantly share code, notes, and snippets.

@trueroad
Last active August 29, 2015 14:16
Show Gist options
  • Save trueroad/fb4d0c3f67285bf66804 to your computer and use it in GitHub Desktop.
Save trueroad/fb4d0c3f67285bf66804 to your computer and use it in GitHub Desktop.
Unicode Filename Support for MinGW.org / MinGW-w64 Platform Software (__wgetmainargs)
Unicode Filename Support for MinGW.org / MinGW-w64 Platform Software (__wgetmainargs)
CXX = x86_64-w64-mingw32-g++
testmain: testmain.cc mingw-utf8-commandline.cc mingw-utf8-filename.cc
$(CXX) -static -o testmain \
testmain.cc mingw-utf8-commandline.cc mingw-utf8-filename.cc
clean:
-rm -fr *~
#include<windows.h>
#include<cwchar>
#include<vector>
#include "mingw-utf8.hh"
namespace
{
std::vector<char> utf16_to_utf8(const wchar_t *wc);
}
extern "C"
int __wgetmainargs(int*, wchar_t***, wchar_t***, int, int*);
#undef main
int main(int, char**, char**)
{
int argc, si=0;
wchar_t **wargv;
wchar_t **wenvp;
__wgetmainargs(&argc, &wargv, &wenvp, 1, &si);
std::vector<std::vector<char> > argv_vvc(argc);
std::vector<char*> argv_vc(argc);
for(int i=0; i<argc; i++)
{
argv_vvc.at(i)=utf16_to_utf8(wargv[i]);
argv_vc.at(i)=argv_vvc.at(i).data();
}
wchar_t **we=wenvp;
int env_count=0;
while(*we)
{
we++;
env_count++;
}
std::vector<std::vector<char> > env_vvc(env_count);
std::vector<char*> env_vc(env_count);
for(int i=0; i<env_count; i++)
{
env_vvc.at(i)=utf16_to_utf8(wenvp[i]);
env_vc.at(i)=env_vvc.at(i).data();
}
env_vc.push_back(NULL);
char **argv=argv_vc.data();
char **envp=env_vc.data();
return utf8_main(argc, argv, envp);
}
namespace
{
std::vector<char> utf16_to_utf8(const wchar_t *wc)
{
int size = WideCharToMultiByte(CP_UTF8, 0, wc, -1, NULL, 0, NULL, NULL);
std::vector<char> retval (size);
if(size)
{
WideCharToMultiByte(CP_UTF8, 0, wc, -1,
retval.data(), retval.size(), NULL, NULL);
}
else
retval.push_back('\0');
return retval;
}
}
#include<windows.h>
#include<cwchar>
#include<vector>
#include<cstdio>
#include<sys/stat.h>
#include"mingw-utf8.hh"
namespace
{
std::vector<wchar_t> utf8_to_utf16(const char *c);
}
FILE *utf8_fopen(const char *path, const char *mode)
{
std::vector<wchar_t> wpath(utf8_to_utf16(path));
std::vector<wchar_t> wmode(utf8_to_utf16(mode));
return _wfopen(wpath.data(), wmode.data());
}
FILE *utf8_freopen(const char *path, const char *mode, FILE *stream)
{
std::vector<wchar_t> wpath(utf8_to_utf16(path));
std::vector<wchar_t> wmode(utf8_to_utf16(mode));
return _wfreopen(wpath.data(), wmode.data(), stream);
}
int utf8_stat(const char *path, struct stat *buff)
{
std::vector<wchar_t> wpath(utf8_to_utf16(path));
return wstat(wpath.data(), buff);
}
namespace
{
std::vector<wchar_t> utf8_to_utf16(const char *c)
{
int size = MultiByteToWideChar(CP_UTF8, 0, c, -1, NULL, 0);
std::vector<wchar_t> retval (size);
if(size)
{
MultiByteToWideChar(CP_UTF8, 0, c, -1,
retval.data(), retval.size());
}
else
retval.push_back(L'\0');
return retval;
}
}
#ifdef __MINGW32__
#define main(...) utf8_main(__VA_ARGS__)
#define fopen(P, M) utf8_fopen(P, M)
#define freopen(P, M ,S) utf8_freopen(P, M, S)
#define stat(P, B) utf8_stat(P, B)
int utf8_main(int argc, char **argv, char **envp);
FILE *utf8_fopen(const char *path, const char *mode);
FILE *utf8_freopen(const char *path, const char *mode, FILE *stream);
int utf8_stat(const char *path, struct stat *buff);
#endif // __MINGW32__
#include <iostream>
#include <cstdio>
#include "mingw-utf8.hh"
int main(int argc, char **argv, char **envp)
{
std::cout << "argc " << argc << std::endl;
for(int i=0; i<argc; i++)
{
std::cout << "argv " << i << " " << argv[i] << std::endl;
}
std::cout << std::endl << "env" << std::endl;
char **e_tmp=envp;
while(*e_tmp)
{
std::cout << *e_tmp++ << std::endl;
}
if(argc>1)
{
std::cout << std::endl << "try to fopen " << argv[1] << std::endl;
FILE *fp = fopen(argv[1], "wb");
fclose(fp);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment