From 30da4970876b93fd7ac7a081a5b55662ec29ad4c Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 26 Mar 2019 23:15:56 -0400 Subject: [PATCH] win32 console debugger may need a little work, still. --- src/debug_shell.re2c | 22 ++++++- src/readline.c | 63 ++++++++++++++++-- src/win_console.c | 153 ++++++++++++++++++++++++++++++++++++++++++- src/win_generic.c | 4 +- 4 files changed, 229 insertions(+), 13 deletions(-) diff --git a/src/debug_shell.re2c b/src/debug_shell.re2c index c10c02a..72f41b5 100644 --- a/src/debug_shell.re2c +++ b/src/debug_shell.re2c @@ -1634,6 +1634,8 @@ int debug_shell(int code) { fputs("\n", stdout); if (++control_d_count < 2) continue; + fputs("quit\n", stdout); + fflush(stdout); return 0; } control_d_count = 0; @@ -1663,19 +1665,33 @@ int debug_shell(int code) { } static void do_sig_intr(int sig) { - /* todo -- raise() if halt already pending */ if (halt_sim & 4) { abort(); } set_halt(4); } + +#ifdef _WIN32 +static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) { + /* handled via a new thread */ + if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) { + do_sig_intr(SIGINT); + return TRUE; + } + return FALSE; +} +#endif + + /* also called by do_step */ -void do_go() { +void do_go() { int ret; int ok; - #ifndef _WIN32 + #ifdef _WIN32 + //SetConsoleCtrlHandler(ctrl_handler, 1); + #else /* if -g flag, start with debug shell ... */ if (isatty(STDIN_FILENO)) { struct sigaction sa; diff --git a/src/readline.c b/src/readline.c index 46e5b37..d9fd215 100644 --- a/src/readline.c +++ b/src/readline.c @@ -144,9 +144,31 @@ char *x_readline(const char *prompt) { static char buffer[1024]; DWORD count = 0; BOOL ok; - HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + + + HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + + +/* + if (h == INVALID_HANDLE_VALUE) { + //* cygwin? * / + fputs("GetStdHandle\n", stderr); + fflush(stderr); + return NULL; + + char *cp; + fputs(prompt, stdout); + fflush(stdout); + return fgets(buffer, sizeof(buffer), stdin); + } +*/ if (!readline_init) { + + //struct stat st; + + CONSOLE_HISTORY_INFO chi; DWORD mode; @@ -155,17 +177,48 @@ char *x_readline(const char *prompt) { chi.HistoryBufferSize = HISTORY_SIZE; chi.NumberOfHistoryBuffers = 1; /* ???? */ chi.dwFlags = HISTORY_NO_DUP_FLAG; - SetConsoleHistoryInfo(&chi); + ok = SetConsoleHistoryInfo(&chi); + + if (!ok) { + fprintf(stderr, "SetConsoleHistoryInfo: %lx\n", GetLastError()); + fflush(stderr); + } + mode = ENABLE_ECHO_INPUT | ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_QUICK_EDIT_MODE; - SetConsoleMode(h, mode); + ok = SetConsoleMode(hIn, mode); + + if (!ok) { + fprintf(stderr, "SetConsoleMode: %lx (h = %p)\n", GetLastError(), hIn); + fflush(stderr); + } readline_init = 1; } - ok = ReadConsole(h, buffer, sizeof(buffer), &count, NULL); - if (!ok) return NULL; + fflush(stderr); + fflush(stdout); + ok = WriteConsole(hOut, prompt, strlen(prompt), NULL, NULL); + if (!ok) { + /* msys/cygwin? */ + + fprintf(stderr, "WriteConsole: %lx (h = %p)\n", GetLastError(), hOut); + fflush(stderr); + fputs(prompt, stdout); + fflush(stdout); + char *cp = fgets(buffer, sizeof(buffer), stdin); + if (!cp) return NULL; + cleanup_buffer(buffer, strlen(buffer)); + return buffer; + } + ok = ReadConsole(hIn, buffer, sizeof(buffer), &count, NULL); + if (!ok) { + fprintf(stderr, "Error: %lx (h = %p)\n", GetLastError(), hIn); + fprintf(stderr, "Type: %08x\n", GetFileType(hIn)); + fflush(stderr); + return NULL; + } cleanup_buffer(buffer, count); return buffer; } diff --git a/src/win_console.c b/src/win_console.c index 983e6a6..dca347f 100644 --- a/src/win_console.c +++ b/src/win_console.c @@ -15,6 +15,11 @@ #include "defc.h" #include "protos_windriver.h" +#include +#include +#include +#include +#include extern void gsportinit(HWND _hwnd); extern void gsportshut(); @@ -104,9 +109,149 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin return main(0,0); } -int main(int argc, char **argv) { + +int g_win32_cygwin; +void win_init_console(void) { + /* + powershell/cmd + fd 0/1/2 closed + GetStdHandle return 0 + stdin = -2, stdout = -2, stderr = -2 + + msys/cygwin + fd 0/1/2 open + GetStdHandle return value (type = 3/pipe) + stdin = 0, stdout = 1, stderr = 2 + */ + + //struct stat st; + //int ok; + int fd; + HANDLE h; + DWORD mode; + +#if 0 + FILE *dbg = fopen("debug.txt", "a+"); + h = GetStdHandle(STD_INPUT_HANDLE); + fprintf(dbg, "STD_INPUT_HANDLE: %p\n", h); + fprintf(dbg, "GetFileType: %08x\n", GetFileType(h)); + fprintf(dbg, "%d %d %d\n", stdin->_file, stdout->_file, stderr->_file); + fclose(dbg); +#endif + + g_win32_cygwin = 0; + + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); + setvbuf(stderr, NULL, _IOLBF, BUFSIZ); + +#if 0 + if (fstat(0, &st) == 0) { + g_win32_cygwin = 1; + return; + } +#endif + + SetStdHandle(STD_INPUT_HANDLE, 0); + SetStdHandle(STD_OUTPUT_HANDLE, 0); + SetStdHandle(STD_ERROR_HANDLE, 0); + #if 0 + stdin->_file = 0; + stdout->_file = 1; + stderr->_file = 2; + #endif + + + AllocConsole(); + SetConsoleTitle("GS+"); + + + h = GetStdHandle(STD_INPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + + mode = 0; + GetConsoleMode(h, &mode); + mode |= ENABLE_VIRTUAL_TERMINAL_INPUT; + SetConsoleMode(h, mode); + + fd = _open_osfhandle((intptr_t)h, _O_TEXT); + #if DUPE + if (fd >= 0 && fd != 0) { + _dup2(fd, 0); + close(fd); + } + #else + stdin->_file = fd; + #endif + } + h = GetStdHandle(STD_OUTPUT_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + + mode = 0; + GetConsoleMode(h, &mode); + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; + SetConsoleMode(h, mode); + + //SetConsoleTextAttribute(h, BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + + + fd = _open_osfhandle((intptr_t)h, _O_TEXT); + #if DUPE + if (fd >= 0 && fd != 1) { + _dup2(fd, 1); + close(fd); + } + #else + stdout->_file = fd; + #endif + } + + + h = GetStdHandle(STD_ERROR_HANDLE); + if (h != INVALID_HANDLE_VALUE) { + + mode = 0; + GetConsoleMode(h, &mode); + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; + SetConsoleMode(h, mode); + + + fd = _open_osfhandle((intptr_t)h, _O_TEXT); + #if DUPE + if (fd >= 0 && fd != 2) { + _dup2(fd, 2); + close(fd); + } + #else + stdout->_file = fd; + #endif + } + +#if 0 + dbg = fopen("debug.txt", "a+"); + h = GetStdHandle(STD_INPUT_HANDLE); + fprintf(dbg, "STD_INPUT_HANDLE: %p\n", h); + fprintf(dbg, "GetFileType: %08x\n", GetFileType(h)); + fprintf(dbg, "%d %d %d\n", stdin->_file, stdout->_file, stderr->_file); + fclose(dbg); +#endif + +} + + +static void exit_sleep(void) { + /* todo -- "press return to continue" */ + if (!g_win32_cygwin) + sleep(10); +} + +int main(int argc, char **argv) { // Hide the console initially to reduce window flashing. We'll show the console later if needed. - x_show_console(0); + + //atexit(exit_sleep); + win_init_console(); + + //x_show_console(0); + // Register the window class. WNDCLASS wndclass; @@ -144,13 +289,14 @@ int main(int argc, char **argv) { printf("...rect is: %ld, %ld, %ld, %ld\n", rect.left, rect.top, rect.right, rect.bottom); +#if 0 // Enable non-blocking, character-at-a-time console I/O. // win_nonblock_read_stdin() expects this behavior. DWORD mode; GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); mode &= ~ENABLE_LINE_INPUT; SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode); - +#endif hook = SetWindowsHookEx(WH_KEYBOARD_LL, win_ll_keyboard, NULL, 0); @@ -160,6 +306,7 @@ int main(int argc, char **argv) { UnhookWindowsHookEx(hook); UnregisterClass(wndclass.lpszClassName,GetModuleHandle(NULL)); + gsportshut(); return ret; } diff --git a/src/win_generic.c b/src/win_generic.c index d355095..8ec9280 100644 --- a/src/win_generic.c +++ b/src/win_generic.c @@ -484,8 +484,8 @@ void x_get_kimage(Kimage *kimage_ptr) { kimage_ptr->dev_handle = NULL; } - printf("kim: %p, dev:%p data: %p, size: %08x\n", kimage_ptr, - kimage_ptr->dev_handle, kimage_ptr->data_ptr, size); + //printf("kim: %p, dev:%p data: %p, size: %08x\n", kimage_ptr, + // kimage_ptr->dev_handle, kimage_ptr->data_ptr, size); return; }