Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 91 additions & 23 deletions src/hx/StdLibs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,29 +255,15 @@ void __hxcpp_stdlibs_boot()
#endif

#if defined(_MSC_VER) && !defined(HX_WINRT)
HMODULE kernel32 = LoadLibraryA("kernel32");
if (kernel32)
{
typedef BOOL (WINAPI *AttachConsoleFunc)(DWORD);
typedef HWND (WINAPI *GetConsoleWindowFunc)(void);
AttachConsoleFunc attach = (AttachConsoleFunc)GetProcAddress(kernel32,"AttachConsole");
GetConsoleWindowFunc getConsole = (GetConsoleWindowFunc)GetProcAddress(kernel32,"GetConsoleWindow");
if (attach && getConsole)
{
if (!attach( /*ATTACH_PARENT_PROCESS*/ (DWORD)-1 ))
{
//printf("Could not attach to parent console : %d\n",GetLastError());
}
else if (getConsole())
{
if (_fileno(stdout) < 0 || _get_osfhandle(fileno(stdout)) < 0)
freopen("CONOUT$", "w", stdout);
if (_fileno(stderr) < 0 || _get_osfhandle(fileno(stderr)) < 0)
freopen("CONOUT$", "w", stderr);
if (_fileno(stdin) < 0 || _get_osfhandle(fileno(stdin)) < 0)
freopen("CONIN$", "r", stdin);
}
}
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {

} else if (GetConsoleWindow()) {
if (_fileno(stdout) < 0 || _get_osfhandle(fileno(stdout)) < 0)
freopen("CONOUT$", "w", stdout);
if (_fileno(stderr) < 0 || _get_osfhandle(fileno(stderr)) < 0)
freopen("CONOUT$", "w", stderr);
if (_fileno(stdin) < 0 || _get_osfhandle(fileno(stdin)) < 0)
freopen("CONIN$", "r", stdin);
}
//_setmode(_fileno(stdout), 0x00040000); // _O_U8TEXT
//_setmode(_fileno(stderr), 0x00040000); // _O_U8TEXT
Expand All @@ -294,12 +280,72 @@ void __hxcpp_stdlibs_boot()
setbuf(stderr, 0);
}

#ifdef HX_WINDOWS
void WriteConsoleAllW(HANDLE h, const wchar_t *str, DWORD length) {
DWORD total_written = 0;
DWORD remaining = length;
while (total_written < length) {
DWORD written;
if (!WriteConsoleW(h, str + total_written, remaining, &written, NULL))
{
return;
}
if (written == remaining) {
return;
}
total_written += written;
remaining -= written;
}
}

void WriteConsoleAllA(HANDLE h, const char *str, DWORD length) {
DWORD total_written = 0;
DWORD remaining = length;
while (total_written < length) {
DWORD written;
if (!WriteConsoleA(h, str + total_written, remaining, &written, NULL))
{
return;
}
if (written == remaining) {
return;
}
total_written += written;
remaining -= written;
}
}
#endif

void __trace(Dynamic inObj, Dynamic info)
{
String text;
if (inObj != null())
text = inObj->toString();

#ifdef HX_WINDOWS
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode;
if (GetConsoleMode(handle, &mode))
{
fflush(stdout);
String s;
if (info == null()) {
s = String("?? ") + text + String("\n");
} else {
String filename = Dynamic((info)->__Field(HX_CSTRING("fileName"), HX_PROP_DYNAMIC))->toString();
int line = Dynamic((info)->__Field(HX_CSTRING("lineNumber"), HX_PROP_DYNAMIC))->__ToInt();
s = filename + String(":") + line + String(": ") + text + String("\n");
}
if (s.isUTF16Encoded())
{
WriteConsoleAllW(handle, s.__WCStr(), s.length);
} else {
// ascii
WriteConsoleAllA(handle, s.__CStr(), s.length);
}
return;
}
#endif

hx::strbuf convertBuf;
if (info==null())
Expand Down Expand Up @@ -606,12 +652,34 @@ Array<String> __get_args()

void __hxcpp_print_string(const String &inV)
{
#ifdef HX_WINDOWS
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode;
if (GetConsoleMode(handle, &mode) && inV.isUTF16Encoded())
{
fflush(stdout);
WriteConsoleAllW(handle, inV.__WCStr(), inV.length);
return;
}
#endif
hx::strbuf convertBuf;
PRINTF("%s", inV.out_str(&convertBuf) );
}

void __hxcpp_println_string(const String &inV)
{
#ifdef HX_WINDOWS
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode;
if (GetConsoleMode(handle, &mode) && inV.isUTF16Encoded())
{
fflush(stdout);
WriteConsoleAllW(handle, inV.__WCStr(), inV.length);
fwrite("\n", 1, 1, stdout);
fflush(stdout);
return;
}
#endif
hx::strbuf convertBuf;
PRINTF("%s\n", inV.out_str(&convertBuf));
fflush(stdout);
Expand Down
41 changes: 39 additions & 2 deletions src/hx/libs/std/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#ifdef NEKO_WINDOWS
# include <windows.h>
# include <io.h>
#endif

/**
Expand Down Expand Up @@ -146,7 +147,44 @@ int _hx_std_file_write( Dynamic handle, Array<unsigned char> s, int p, int n )
if( p < 0 || len < 0 || p > buflen || p + len > buflen )
return 0;

hx::EnterGCFreeZone();
hx::AutoGCFreeZone zone;
#ifdef HX_WINDOWS
if (_isatty(_fileno(f->io))) {
fflush(f->io);
HANDLE win_handle = (HANDLE)_get_osfhandle(_fileno(f->io));
static const int MAX_BUFFER_SIZE = 8192;
wchar_t buf[MAX_BUFFER_SIZE / 2];
int result = MultiByteToWideChar(CP_UTF8, 0, (char *)&s[p], len, buf, MAX_BUFFER_SIZE / 2);
DWORD written = 0;
if(!WriteConsoleW(win_handle, buf, result, &written, NULL)) {
file_error("file_write", f->name);
}
if (written == result) {
return len;
} else {
auto first_code_unit_remaining = buf[written];
if (first_code_unit_remaining > 0xDCEE && first_code_unit_remaining <= 0xDFF) {
DWORD tmp;
WriteConsoleW(win_handle, &buf[written], 1, &tmp, NULL);
written += 1;
}
int count = 0;
for (int i = 0; i < written; i++) {
wchar_t ch = buf[i];
if (ch >= 0 && ch <= 0x7F) {
count += 1;
} else if (ch >= 0x0080 && ch <= 0x07FF) {
count += 2;
} else if (ch >= 0xDCEE && ch <= 0xDFF) {
count += 1;
} else {
count += 3;
}
}
return count;
}
}
#endif
while( len > 0 )
{
POSIX_LABEL(file_write_again);
Expand All @@ -159,7 +197,6 @@ int _hx_std_file_write( Dynamic handle, Array<unsigned char> s, int p, int n )
p += d;
len -= d;
}
hx::ExitGCFreeZone();
return n;
}

Expand Down