diff --git a/internal/c/libqb.cpp b/internal/c/libqb.cpp index 3f0484ede..09a041727 100644 --- a/internal/c/libqb.cpp +++ b/internal/c/libqb.cpp @@ -23,6 +23,7 @@ #include "error_handle.h" #include "filepath.h" #include "filesystem.h" +#include "file-fields.h" #include "font.h" #include "game_controller.h" #include "gfs.h" @@ -36,6 +37,7 @@ #include "mutex.h" #include "qbs.h" #include "rounding.h" +#include "shell.h" #include "thread.h" int32 disableEvents = 0; @@ -957,7 +959,6 @@ int32 lpos = 1; int32 width_lprint = 80; // forward refs -void sub_shell4(qbs *, int32); //_DONTWAIT & _HIDE int32 func__source(); int32 func_pos(int32 ignore); @@ -18963,1499 +18964,6 @@ void sub_file_line_input_string(int32 fileno, qbs *deststr) { return; } -int32 shell_call_in_progress = 0; - -#ifdef QB64_WINDOWS -int32 cmd_available = -1; -int32 cmd_ok() { - if (cmd_available == -1) { - static STARTUPINFO si; - static PROCESS_INFORMATION pi; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess(NULL, // No module name (use command line) - "cmd.exe /c ver", // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NO_WINDOW, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi // Pointer to PROCESS_INFORMATION structure - )) { - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - cmd_available = 1; - } else { - cmd_available = 0; - } - } //-1 - return cmd_available; -} -#endif - -int32 cmd_command(qbs *str2) { - static qbs *str = NULL; - static int32 s; - if (!str) - str = qbs_new(0, 0); - qbs_set(str, qbs_ucase(str2)); - s = 0; - if (qbs_equal(str, qbs_new_txt("ASSOC"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("BREAK"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("BCDBOOT"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("BCDEDIT"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("CALL"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("CD"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("CHDIR"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("CLS"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("COLOR"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("COPY"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("DATE"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("DEFRAG"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("DEL"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("DIR"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("ECHO"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("ENDLOCAL"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("ERASE"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("FOR"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("FTYPE"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("GOTO"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("GRAFTABL"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("IF"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("MD"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("MKDIR"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("MKLINK"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("MOVE"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("PATH"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("PAUSE"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("POPD"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("PROMPT"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("PUSHD"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("RD"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("REM"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("REN"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("RENAME"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("RMDIR"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("SET"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("SETLOCAL"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("SHIFT"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("START"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("TIME"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("TITLE"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("TYPE"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("VER"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("VERIFY"))) - s = 1; - if (qbs_equal(str, qbs_new_txt("VOL"))) - s = 1; - return s; -} - -int64 func_shell(qbs *str) { - if (is_error_pending()) - return 1; - - int64 return_code; - - // exit full screen mode if necessary - static int32 full_screen_mode; - full_screen_mode = full_screen; - if (full_screen_mode) { - full_screen_set = 0; - do { - Sleep(0); - } while (full_screen); - } // full_screen_mode - static qbs *strz = NULL; - static qbs *str1 = NULL; - static qbs *str1z = NULL; - static qbs *str2 = NULL; - static qbs *str2z = NULL; - static int32 i; - - static int32 use_console; - use_console = 0; - if (console) { - if (console_active) { - use_console = 1; - } - } - - if (!strz) - strz = qbs_new(0, 0); - if (!str1) - str1 = qbs_new(0, 0); - if (!str1z) - str1z = qbs_new(0, 0); - if (!str2) - str2 = qbs_new(0, 0); - if (!str2z) - str2z = qbs_new(0, 0); - - if (str->len) { - -#ifdef QB64_WINDOWS - - if (use_console) { - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - shell_call_in_progress = 1; - /* - freopen("stdout.buf", "w", stdout); - freopen("stderr.buf", "w", stderr); - */ - return_code = system((char *)strz->chr); - /* - freopen("CON", "w", stdout); - freopen("CON", "w", stderr); - static char buf[1024]; - static int buflen; - static int fd; - fd = open("stdout.buf", O_RDONLY); - while((buflen = read(fd, buf, 1024)) > 0) - { - write(1, buf, buflen); - } - close(fd); - fd = open("stderr.buf", O_RDONLY); - while((buflen = read(fd, buf, 1024)) > 0) - { - write(1, buf, buflen); - } - close(fd); - remove("stdout.buf"); - remove("stderr.buf"); - */ - shell_call_in_progress = 0; - goto shell_complete; - } - - static STARTUPINFO si; - static PROCESS_INFORMATION pi; - - if (cmd_ok()) { - - static SHELLEXECUTEINFO shi; - static char cmd[10] = "cmd\0"; - - // attempt to separate file name (if any) from parameters - static int32 x, quotes; - - qbs_set(str1, str); - qbs_set(str2, qbs_new_txt("")); - if (!str1->len) - goto shell_complete; // failed! - - if (!cmd_command(str1)) { - // try directly, as is - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - - x = 0; - quotes = 0; - while (x < str1->len) { - if (str1->chr[x] == 34) { - if (!quotes) - quotes = 1; - else - quotes = 0; - } - if (str1->chr[x] == 32) { - if (quotes == 0) { - qbs_set(str2, qbs_right(str1, str1->len - x - 1)); - qbs_set(str1, qbs_left(str1, x)); - goto split; - } - } - x++; - } - split: - if (!str1->len) - goto shell_complete; // failed! - - if (str2->len) { - if (!cmd_command(str1)) { - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = (char *)&str2z->chr[0]; - // if (str2->len<=1) shi.lpParameters=NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - } - - // failed, try cmd /c method... - if (str2->len) - qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); - qbs_set(strz, qbs_add(str1, str2)); - qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = &cmd[0]; - shi.lpParameters = (char *)&strz->chr[0]; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - - /* - qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); - qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); - ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcess( - NULL, // No module name (use command line) - (char*)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - DETACHED_PROCESS, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi ) // Pointer to PROCESS_INFORMATION structure - ){ - shell_call_in_progress=1; - // Wait until child process exits. - WaitForSingleObject( pi.hProcess, INFINITE ); - // Close process and thread handles. - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - shell_call_in_progress=0; - goto shell_complete; - } - */ - - return_code = 1; - goto shell_complete; // failed - - } else { - - qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess(NULL, // No module name (use command line) - (char *)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) // Pointer to PROCESS_INFORMATION structure - ) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(pi.hProcess, INFINITE); - // Close process and thread handles. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - shell_call_in_progress = 0; - goto shell_complete; - } - goto shell_complete; // failed - - } // cmd_ok() - -#else - - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - shell_call_in_progress = 1; - return_code = system((char *)strz->chr); - shell_call_in_progress = 0; - if (return_code == -1) { /* do nothing */ - } else { - return_code = WEXITSTATUS(return_code); - } - -#endif - - } else { - -// SHELL (with no parameters) -// note: opening a new shell is only available in windows atm via cmd -// note: assumes cmd available -#ifdef QB64_WINDOWS - if (!use_console) - AllocConsole(); - qbs_set(strz, qbs_new_txt_len("cmd\0", 4)); - shell_call_in_progress = 1; - return_code = system((char *)strz->chr); - shell_call_in_progress = 0; - if (!use_console) - FreeConsole(); - goto shell_complete; -#endif - } - -shell_complete: - // reenter full screen mode if necessary - if (full_screen_mode) { - full_screen_set = full_screen_mode; - do { - Sleep(0); - } while (!full_screen); - } // full_screen_mode - - return return_code; -} // func SHELL(... - -int64 func__shellhide(qbs *str) { // func _SHELLHIDE(... - if (is_error_pending()) - return 1; - - static int64 return_code; - return_code = 0; - - static qbs *strz = NULL; - static int32 i; - if (!strz) - strz = qbs_new(0, 0); - if (!str->len) { - error(5); - return 1; - } // cannot launch a hidden console - - static qbs *str1 = NULL; - static qbs *str2 = NULL; - static qbs *str1z = NULL; - static qbs *str2z = NULL; - if (!str1) - str1 = qbs_new(0, 0); - if (!str2) - str2 = qbs_new(0, 0); - if (!str1z) - str1z = qbs_new(0, 0); - if (!str2z) - str2z = qbs_new(0, 0); - -#ifdef QB64_WINDOWS - - static STARTUPINFO si; - static PROCESS_INFORMATION pi; - - if (cmd_ok()) { - - static SHELLEXECUTEINFO shi; - static char cmd[10] = "cmd\0"; - - // attempt to separate file name (if any) from parameters - static int32 x, quotes; - - qbs_set(str1, str); - qbs_set(str2, qbs_new_txt("")); - - if (!cmd_command(str1)) { - // try directly, as is - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - - x = 0; - quotes = 0; - while (x < str1->len) { - if (str1->chr[x] == 34) { - if (!quotes) - quotes = 1; - else - quotes = 0; - } - if (str1->chr[x] == 32) { - if (quotes == 0) { - qbs_set(str2, qbs_right(str1, str1->len - x - 1)); - qbs_set(str1, qbs_left(str1, x)); - goto split; - } - } - x++; - } - split: - if (!str1->len) { - return_code = 1; - goto shell_complete; - } // failed! - - if (str2->len) { - if (!cmd_command(str1)) { - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = (char *)&str2z->chr[0]; - // if (str2->len<=1) shi.lpParameters=NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - } - - // failed, try cmd /c method... - if (str2->len) - qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); - qbs_set(strz, qbs_add(str1, str2)); - qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = &cmd[0]; - shi.lpParameters = (char *)&strz->chr[0]; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - - /* - qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); - qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); - ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcess( - NULL, // No module name (use command line) - (char*)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NO_WINDOW, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi ) // Pointer to PROCESS_INFORMATION structure - ){ - shell_call_in_progress=1; - // Wait until child process exits. - WaitForSingleObject( pi.hProcess, INFINITE ); - // Close process and thread handles. - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - shell_call_in_progress=0; - goto shell_complete; - } - */ - - return_code = 1; - goto shell_complete; // failed - - } else { - - qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess( - - NULL, // No module name (use command line) - (char *)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) // Pointer to PROCESS_INFORMATION structure - ) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(pi.hProcess, INFINITE); - // Close process and thread handles. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - shell_call_in_progress = 0; - goto shell_complete; - } - goto shell_complete; // failed - - } // cmd_ok() - -#else - - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - shell_call_in_progress = 1; - return_code = system((char *)strz->chr); - shell_call_in_progress = 0; - return return_code; - -#endif - -shell_complete:; - - return return_code; -} // func _SHELLHIDE(... - -void sub_shell(qbs *str, int32 passed) { - if (is_error_pending()) - return; - - // exit full screen mode if necessary - static int32 full_screen_mode; - full_screen_mode = full_screen; - if (full_screen_mode) { - full_screen_set = 0; - do { - Sleep(0); - } while (full_screen); - } // full_screen_mode - static qbs *strz = NULL; - static qbs *str1 = NULL; - static qbs *str1z = NULL; - static qbs *str2 = NULL; - static qbs *str2z = NULL; - static int32 i; - - static int32 use_console; - use_console = 0; - if (console) { - if (console_active) { - use_console = 1; - } - } - - if (!strz) - strz = qbs_new(0, 0); - if (!str1) - str1 = qbs_new(0, 0); - if (!str1z) - str1z = qbs_new(0, 0); - if (!str2) - str2 = qbs_new(0, 0); - if (!str2z) - str2z = qbs_new(0, 0); - - if (passed) - if (str->len == 0) - passed = 0; //"" means launch a CONSOLE - if (passed) { - -#ifdef QB64_WINDOWS - - if (use_console) { - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - shell_call_in_progress = 1; - /* - freopen("stdout.buf", "w", stdout); - freopen("stderr.buf", "w", stderr); - */ - system((char *)strz->chr); - /* - freopen("CON", "w", stdout); - freopen("CON", "w", stderr); - static char buf[1024]; - static int buflen; - static int fd; - fd = open("stdout.buf", O_RDONLY); - while((buflen = read(fd, buf, 1024)) > 0) - { - write(1, buf, buflen); - } - close(fd); - fd = open("stderr.buf", O_RDONLY); - while((buflen = read(fd, buf, 1024)) > 0) - { - write(1, buf, buflen); - } - close(fd); - remove("stdout.buf"); - remove("stderr.buf"); - */ - shell_call_in_progress = 0; - goto shell_complete; - } - - static STARTUPINFO si; - static PROCESS_INFORMATION pi; - - if (cmd_ok()) { - - static SHELLEXECUTEINFO shi; - static char cmd[10] = "cmd\0"; - - // attempt to separate file name (if any) from parameters - static int32 x, quotes; - - qbs_set(str1, str); - qbs_set(str2, qbs_new_txt("")); - if (!str1->len) - goto shell_complete; // failed! - - if (!cmd_command(str1)) { - // try directly, as is - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - - x = 0; - quotes = 0; - while (x < str1->len) { - if (str1->chr[x] == 34) { - if (!quotes) - quotes = 1; - else - quotes = 0; - } - if (str1->chr[x] == 32) { - if (quotes == 0) { - qbs_set(str2, qbs_right(str1, str1->len - x - 1)); - qbs_set(str1, qbs_left(str1, x)); - goto split; - } - } - x++; - } - split: - if (!str1->len) - goto shell_complete; // failed! - - if (str2->len) { - if (!cmd_command(str1)) { - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = (char *)&str2z->chr[0]; - // if (str2->len<=1) shi.lpParameters=NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - } - - // failed, try cmd /c method... - if (str2->len) - qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); - qbs_set(strz, qbs_add(str1, str2)); - qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = &cmd[0]; - shi.lpParameters = (char *)&strz->chr[0]; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - - /* - qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); - qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); - ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcess( - NULL, // No module name (use command line) - (char*)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - DETACHED_PROCESS, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi ) // Pointer to PROCESS_INFORMATION structure - ){ - shell_call_in_progress=1; - // Wait until child process exits. - WaitForSingleObject( pi.hProcess, INFINITE ); - // Close process and thread handles. - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - shell_call_in_progress=0; - goto shell_complete; - } - */ - - goto shell_complete; // failed - - } else { - - qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess(NULL, // No module name (use command line) - (char *)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) // Pointer to PROCESS_INFORMATION structure - ) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(pi.hProcess, INFINITE); - // Close process and thread handles. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - shell_call_in_progress = 0; - goto shell_complete; - } - goto shell_complete; // failed - - } // cmd_ok() - -#else - - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - shell_call_in_progress = 1; - system((char *)strz->chr); - shell_call_in_progress = 0; - -#endif - - } else { - -// SHELL (with no parameters) -// note: opening a new shell is only available in windows atm via cmd -// note: assumes cmd available -#ifdef QB64_WINDOWS - if (!use_console) - AllocConsole(); - qbs_set(strz, qbs_new_txt_len("cmd\0", 4)); - shell_call_in_progress = 1; - system((char *)strz->chr); - shell_call_in_progress = 0; - if (!use_console) - FreeConsole(); - goto shell_complete; -#endif - } - -shell_complete: - // reenter full screen mode if necessary - if (full_screen_mode) { - full_screen_set = full_screen_mode; - do { - Sleep(0); - } while (!full_screen); - } // full_screen_mode -} - -void sub_shell2(qbs *str, int32 passed) { // HIDE - if (is_error_pending()) - return; - - if (passed & 1) { - sub_shell4(str, passed & 2); - return; - } - if (!(passed & 2)) { - error(5); - return; - } // should not hide a shell waiting for input - - static qbs *strz = NULL; - static int32 i; - if (!strz) - strz = qbs_new(0, 0); - if (!str->len) { - error(5); - return; - } // cannot launch a hidden console - - static qbs *str1 = NULL; - static qbs *str2 = NULL; - static qbs *str1z = NULL; - static qbs *str2z = NULL; - if (!str1) - str1 = qbs_new(0, 0); - if (!str2) - str2 = qbs_new(0, 0); - if (!str1z) - str1z = qbs_new(0, 0); - if (!str2z) - str2z = qbs_new(0, 0); - -#ifdef QB64_WINDOWS - - static STARTUPINFO si; - static PROCESS_INFORMATION pi; - - if (cmd_ok()) { - - static SHELLEXECUTEINFO shi; - static char cmd[10] = "cmd\0"; - - // attempt to separate file name (if any) from parameters - static int32 x, quotes; - - qbs_set(str1, str); - qbs_set(str2, qbs_new_txt("")); - - if (!cmd_command(str1)) { - // try directly, as is - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - - x = 0; - quotes = 0; - while (x < str1->len) { - if (str1->chr[x] == 34) { - if (!quotes) - quotes = 1; - else - quotes = 0; - } - if (str1->chr[x] == 32) { - if (quotes == 0) { - qbs_set(str2, qbs_right(str1, str1->len - x - 1)); - qbs_set(str1, qbs_left(str1, x)); - goto split; - } - } - x++; - } - split: - if (!str1->len) - goto shell_complete; // failed! - - if (str2->len) { - if (!cmd_command(str1)) { - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = (char *)&str2z->chr[0]; - // if (str2->len<=1) shi.lpParameters=NULL; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - } - } - - // failed, try cmd /c method... - if (str2->len) - qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); - qbs_set(strz, qbs_add(str1, str2)); - qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = &cmd[0]; - shi.lpParameters = (char *)&strz->chr[0]; - shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(shi.hProcess, INFINITE); - CloseHandle(shi.hProcess); - shell_call_in_progress = 0; - goto shell_complete; - } - - /* - qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); - qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); - ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcess( - NULL, // No module name (use command line) - (char*)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NO_WINDOW, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi ) // Pointer to PROCESS_INFORMATION structure - ){ - shell_call_in_progress=1; - // Wait until child process exits. - WaitForSingleObject( pi.hProcess, INFINITE ); - // Close process and thread handles. - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - shell_call_in_progress=0; - goto shell_complete; - } - */ - - goto shell_complete; // failed - - } else { - - qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess( - - NULL, // No module name (use command line) - (char *)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) // Pointer to PROCESS_INFORMATION structure - ) { - shell_call_in_progress = 1; - // Wait until child process exits. - WaitForSingleObject(pi.hProcess, INFINITE); - // Close process and thread handles. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - shell_call_in_progress = 0; - goto shell_complete; - } - goto shell_complete; // failed - - } // cmd_ok() - -#else - - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - shell_call_in_progress = 1; - system((char *)strz->chr); - shell_call_in_progress = 0; - return; - -#endif - -shell_complete:; -} - -void sub_shell3(qbs *str, int32 passed) { //_DONTWAIT - // shell3 launches 'str' but does not wait for it to complete - if (is_error_pending()) - return; - - if (passed & 1) { - sub_shell4(str, passed & 2); - return; - } - - static qbs *strz = NULL; - static int32 i; - - static qbs *str1 = NULL; - static qbs *str2 = NULL; - static qbs *str1z = NULL; - static qbs *str2z = NULL; - if (!str1) - str1 = qbs_new(0, 0); - if (!str2) - str2 = qbs_new(0, 0); - if (!str1z) - str1z = qbs_new(0, 0); - if (!str2z) - str2z = qbs_new(0, 0); - - if (!strz) - strz = qbs_new(0, 0); - -#ifdef QB64_WINDOWS - - static STARTUPINFO si; - static PROCESS_INFORMATION pi; - - if (cmd_ok()) { - - static SHELLEXECUTEINFO shi; - static char cmd[10] = "cmd\0"; - - // attempt to separate file name (if any) from parameters - static int32 x, quotes; - - // allow for launching of a console - if (!(passed & 2)) { - qbs_set(str1, qbs_new_txt("cmd")); - } else { - qbs_set(str1, str); - if (!str1->len) - qbs_set(str1, qbs_new_txt("cmd")); - } - qbs_set(str2, qbs_new_txt("")); - - if (!cmd_command(str1)) { - // try directly, as is - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = NULL; - shi.fMask = SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - goto shell_complete; - } - } - - x = 0; - quotes = 0; - while (x < str1->len) { - if (str1->chr[x] == 34) { - if (!quotes) - quotes = 1; - else - quotes = 0; - } - if (str1->chr[x] == 32) { - if (quotes == 0) { - qbs_set(str2, qbs_right(str1, str1->len - x - 1)); - qbs_set(str1, qbs_left(str1, x)); - goto split; - } - } - x++; - } - split: - if (!str1->len) - goto shell_complete; // failed! - - if (str2->len) { - if (!cmd_command(str1)) { - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = (char *)&str2z->chr[0]; - // if (str2->len<=1) shi.lpParameters=NULL; - shi.fMask = SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - goto shell_complete; - } - } - } - - // failed, try cmd /c method... - if (str2->len) - qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); - qbs_set(strz, qbs_add(str1, str2)); - qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = &cmd[0]; - shi.lpParameters = (char *)&strz->chr[0]; - shi.fMask = SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_SHOW; - if (ShellExecuteEx(&shi)) { - goto shell_complete; - } - - /* - qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); - qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); - ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcess( - NULL, // No module name (use command line) - (char*)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - DETACHED_PROCESS, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi ) // Pointer to PROCESS_INFORMATION structure - ){ - //ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its - threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to - CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - goto shell_complete; - } - */ - - goto shell_complete; // failed - - } else { - - qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess(NULL, // No module name (use command line) - (char *)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) // Pointer to PROCESS_INFORMATION structure - ) { - // ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its - // threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to - // CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - goto shell_complete; - } - goto shell_complete; // failed - - } // cmd_ok() - -#else - - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - pid_t pid = fork(); - if (pid == 0) - _exit(system((char *)strz->chr)); - return; - -#endif - -shell_complete:; -} // SHELL _DONTWAIT - -void sub_shell4(qbs *str, int32 passed) { //_DONTWAIT & _HIDE - // if passed&2 set a string was given - if (!(passed & 2)) { - error(5); - return; - } // should not hide a shell waiting for input - - static qbs *strz = NULL; - static int32 i; - - static qbs *str1 = NULL; - static qbs *str2 = NULL; - static qbs *str1z = NULL; - static qbs *str2z = NULL; - if (!str1) - str1 = qbs_new(0, 0); - if (!str2) - str2 = qbs_new(0, 0); - if (!str1z) - str1z = qbs_new(0, 0); - if (!str2z) - str2z = qbs_new(0, 0); - - if (!strz) - strz = qbs_new(0, 0); - - if (!str->len) { - error(5); - return; - } // console unsupported - -#ifdef QB64_WINDOWS - - static STARTUPINFO si; - static PROCESS_INFORMATION pi; - - if (cmd_ok()) { - - static SHELLEXECUTEINFO shi; - static char cmd[10] = "cmd\0"; - - // attempt to separate file name (if any) from parameters - static int32 x, quotes; - - qbs_set(str1, str); - qbs_set(str2, qbs_new_txt("")); - - if (!cmd_command(str1)) { - // try directly, as is - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = NULL; - shi.fMask = SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - goto shell_complete; - } - } - - x = 0; - quotes = 0; - while (x < str1->len) { - if (str1->chr[x] == 34) { - if (!quotes) - quotes = 1; - else - quotes = 0; - } - if (str1->chr[x] == 32) { - if (quotes == 0) { - qbs_set(str2, qbs_right(str1, str1->len - x - 1)); - qbs_set(str1, qbs_left(str1, x)); - goto split; - } - } - x++; - } - split: - if (!str1->len) - goto shell_complete; // failed! - - if (str2->len) { - if (!cmd_command(str1)) { - qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); - qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = (char *)&str1z->chr[0]; - shi.lpParameters = (char *)&str2z->chr[0]; - // if (str2->len<=1) shi.lpParameters=NULL; - shi.fMask = SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - goto shell_complete; - } - } - } - - // failed, try cmd /c method... - if (str2->len) - qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); - qbs_set(strz, qbs_add(str1, str2)); - qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&shi, sizeof(shi)); - shi.cbSize = sizeof(shi); - shi.lpFile = &cmd[0]; - shi.lpParameters = (char *)&strz->chr[0]; - shi.fMask = SEE_MASK_FLAG_NO_UI; - shi.nShow = SW_HIDE; - if (ShellExecuteEx(&shi)) { - goto shell_complete; - } - - /* - qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); - qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); - ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); - if(CreateProcess( - NULL, // No module name (use command line) - (char*)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - DETACHED_PROCESS, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi ) // Pointer to PROCESS_INFORMATION structure - ){ - //ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its - threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to - CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - goto shell_complete; - } - */ - - goto shell_complete; // failed - - } else { - - qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); - qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess(NULL, // No module name (use command line) - (char *)&strz->chr[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi) // Pointer to PROCESS_INFORMATION structure - ) { - // ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its - // threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to - // CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - goto shell_complete; - } - goto shell_complete; // failed - - } // cmd_ok() - -#else - - qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); - pid_t pid = fork(); - if (pid == 0) - _exit(system((char *)strz->chr)); - return; - -#endif - -shell_complete:; - -} //_DONTWAIT & _HIDE - int32 func_freefile() { return gfs_fileno_freefile(); } void sub__mousehide() { @@ -27772,341 +26280,6 @@ int32 func__keydown(int32 x) { return 0; } -static int32 field_failed = 1; -static int32 field_fileno; -static int32 field_totalsize; -static int32 field_maxsize; - -void field_new(int32 fileno) { - field_failed = 1; - if (is_error_pending()) - return; - // validate file - static int32 i; - static gfs_file_struct *gfs; - i = fileno; - if (i < 0) { - error(54); - return; - } // bad file mode (TCP/IP exclusion) - if (gfs_fileno_valid(i) != 1) { - error(52); - return; - } // Bad file name or number - i = gfs_get_fileno(i); // convert fileno to gfs index - gfs = gfs_get_file_struct(i); - if (gfs->type != 1) { - error(54); - return; - } // Bad file mode (note: must have RANDOM access) - // set global variables for field_add - field_fileno = fileno; - field_totalsize = 0; - field_maxsize = gfs->record_length; - field_failed = 0; - return; -} - -void field_update(int32 fileno) { - - // validate file - static int32 i; - static gfs_file_struct *gfs; - i = fileno; - if (i < 0) { - exit(7701); - } // bad file mode (TCP/IP exclusion) - if (gfs_fileno_valid(i) != 1) { - exit(7702); - } // Bad file name or number - i = gfs_get_fileno(i); // convert fileno to gfs index - gfs = gfs_get_file_struct(i); - if (gfs->type != 1) { - exit(7703); - } // Bad file mode (note: must have RANDOM access) - - static qbs *str; - for (i = 0; i < gfs->field_strings_n; i++) { - str = gfs->field_strings[i]; - if (!str) - exit(7704); - - // fix length if necessary - if (str->len != str->field->size) { - if (str->len > str->field->size) - str->len = str->field->size; - else - qbs_set(str, qbs_new(str->field->size, 1)); - } - - // copy data from field into string - memmove(str->chr, gfs->field_buffer + str->field->offset, str->field->size); - - } // i -} - -void lrset_field(qbs *str) { - // validate file - static int32 i; - static gfs_file_struct *gfs; - i = str->field->fileno; - if (gfs_fileno_valid(i) != 1) - goto remove; - i = gfs_get_fileno(i); // convert fileno to gfs index - - gfs = gfs_get_file_struct(i); - if (gfs->type != 1) - goto remove; - // check file ID - if (gfs->id != str->field->fileid) - goto remove; - - // store in field buffer, padding with spaces or truncating data if necessary - if (str->field->size <= str->len) { - - memmove(gfs->field_buffer + str->field->offset, str->chr, str->field->size); - } else { - memmove(gfs->field_buffer + str->field->offset, str->chr, str->len); - memset(gfs->field_buffer + str->field->offset + str->len, 32, str->field->size - str->len); - } - - // update field strings for this file - field_update(str->field->fileno); - - return; -remove:; - free(str->field); - str->field = NULL; -} - -void field_free(qbs *str) { - - // validate file - static int32 i; - static gfs_file_struct *gfs; - i = str->field->fileno; - if (gfs_fileno_valid(i) != 1) - goto remove; - i = gfs_get_fileno(i); // convert fileno to gfs index - gfs = gfs_get_file_struct(i); - if (gfs->type != 1) - goto remove; - // check file ID - if (gfs->id != str->field->fileid) - goto remove; - - // remove from string list - static qbs *str2; - for (i = 0; i < gfs->field_strings_n; i++) { - str2 = gfs->field_strings[i]; - if (str == str2) { // match found - // truncate list - memmove(&(gfs->field_strings[i]), &(gfs->field_strings[i + 1]), (gfs->field_strings_n - i - 1) * ptrsz); - goto remove; - } - } // i - -remove: - free(str->field); - str->field = NULL; -} - -void field_add(qbs *str, int64 size) { - if (field_failed) - return; - if (is_error_pending()) - goto fail; - if (size < 0) { - error(5); - goto fail; - } - if ((field_totalsize + size) > field_maxsize) { - error(50); - goto fail; - } - - // revalidate file - static int32 i; - static gfs_file_struct *gfs; - i = field_fileno; - // TCP/IP exclusion (reason: multi-reading from same TCP/IP position would require a more complex implementation) - if (i < 0) { - error(54); - goto fail; - } // bad file mode - if (gfs_fileno_valid(i) != 1) { - error(52); - goto fail; - } // Bad file name or number - i = gfs_get_fileno(i); // convert fileno to gfs index - gfs = gfs_get_file_struct(i); - if (gfs->type != 1) { - error(54); - goto fail; - } // Bad file mode (note: must have RANDOM access) - - // 1) Remove str from any previous FIELD allocations - if (str->field) - field_free(str); - - // 2) Setup qbs field info - str->field = (qbs_field *)malloc(sizeof(qbs_field)); - str->field->fileno = field_fileno; - str->field->fileid = gfs->id; - str->field->size = size; - str->field->offset = field_totalsize; - - // 3) Add str to qbs list of gfs - if (!gfs->field_strings) { - gfs->field_strings_n = 1; - gfs->field_strings = (qbs **)malloc(ptrsz); - gfs->field_strings[0] = str; - } else { - gfs->field_strings_n++; - gfs->field_strings = (qbs **)realloc(gfs->field_strings, ptrsz * gfs->field_strings_n); - gfs->field_strings[gfs->field_strings_n - 1] = str; - } - - // 4) Update field strings for this file - field_update(field_fileno); - - field_totalsize += size; - return; -fail: - field_failed = 1; - return; -} - -void field_get(int32 fileno, int64 offset, int32 passed) { - if (is_error_pending()) - return; - - // validate file - static int32 i; - static gfs_file_struct *gfs; - i = fileno; - if (i < 0) { - error(54); - return; - } // bad file mode (TCP/IP exclusion) - if (gfs_fileno_valid(i) != 1) { - error(52); - return; - } // Bad file name or number - i = gfs_get_fileno(i); // convert fileno to gfs index - gfs = gfs_get_file_struct(i); - if (gfs->type != 1) { - error(54); - return; - } // Bad file mode (note: must have RANDOM access) - - if (!gfs->read) { - error(75); - return; - } // Path/file access error - - if (passed) { - offset--; - if (offset < 0) { - error(63); - return; - } // Bad record number - offset *= gfs->record_length; - } else { - offset = -1; - } - - static int32 e; - e = gfs_read(i, offset, gfs->field_buffer, gfs->record_length); - if (e) { - if (e != -10) { // note: on eof, unread buffer area becomes NULL - if (e == -2) { - error(258); - return; - } // invalid handle - if (e == -3) { - error(54); - return; - } // bad file mode - if (e == -4) { - error(5); - return; - } // illegal function call - if (e == -7) { - error(70); - return; - } // permission denied - error(75); - return; // assume[-9]: path/file access error - } - } - - field_update(fileno); -} - -void field_put(int32 fileno, int64 offset, int32 passed) { - if (is_error_pending()) - return; - - // validate file - static int32 i; - static gfs_file_struct *gfs; - i = fileno; - if (i < 0) { - error(54); - return; - } // bad file mode (TCP/IP exclusion) - if (gfs_fileno_valid(i) != 1) { - error(52); - return; - } // Bad file name or number - i = gfs_get_fileno(i); // convert fileno to gfs index - gfs = gfs_get_file_struct(i); - if (gfs->type != 1) { - error(54); - return; - } // Bad file mode (note: must have RANDOM access) - - if (!gfs->write) { - error(75); - return; - } // Path/file access error - - if (passed) { - offset--; - if (offset < 0) { - error(63); - return; - } // Bad record number - offset *= gfs->record_length; - } else { - offset = -1; - } - - static int32 e; - e = gfs_write(i, offset, gfs->field_buffer, gfs->record_length); - if (e) { - if (e == -2) { - error(258); - return; - } // invalid handle - if (e == -3) { - error(54); - return; - } // bad file mode - if (e == -4) { - error(5); - return; - } // illegal function call - if (e == -7) { - error(70); - return; - } // permission denied - error(75); - return; // assume[-9]: path/file access error - } -} - void sub__mapunicode(int32 unicode_code, int32 ascii_code) { if (is_error_pending()) return; diff --git a/internal/c/libqb.h b/internal/c/libqb.h index 8a92b6de1..72e8abf72 100644 --- a/internal/c/libqb.h +++ b/internal/c/libqb.h @@ -5,7 +5,6 @@ #include "cmem.h" #include "qbs.h" -void sub_shell4(qbs *, int32); //_DONTWAIT & _HIDE int32 func__source(); int32 func_pos(int32 ignore); void sub__printimage(int32 i); diff --git a/internal/c/libqb/build.mk b/internal/c/libqb/build.mk index 1e4f62f59..294a61f02 100644 --- a/internal/c/libqb/build.mk +++ b/internal/c/libqb/build.mk @@ -4,6 +4,7 @@ libqb-objs-y += $(PATH_LIBQB)/src/buffer.o libqb-objs-y += $(PATH_LIBQB)/src/bitops.o libqb-objs-y += $(PATH_LIBQB)/src/command.o libqb-objs-y += $(PATH_LIBQB)/src/environ.o +libqb-objs-y += $(PATH_LIBQB)/src/file-fields.o libqb-objs-y += $(PATH_LIBQB)/src/filepath.o libqb-objs-y += $(PATH_LIBQB)/src/filesystem.o libqb-objs-y += $(PATH_LIBQB)/src/datetime.o @@ -13,6 +14,7 @@ libqb-objs-y += $(PATH_LIBQB)/src/qblist.o libqb-objs-y += $(PATH_LIBQB)/src/mem.o libqb-objs-y += $(PATH_LIBQB)/src/math.o libqb-objs-y += $(PATH_LIBQB)/src/rounding.o +libqb-objs-y += $(PATH_LIBQB)/src/shell.o libqb-objs-y += $(PATH_LIBQB)/src/qbs.o libqb-objs-y += $(PATH_LIBQB)/src/qbs_str.o libqb-objs-y += $(PATH_LIBQB)/src/qbs_cmem.o diff --git a/internal/c/libqb/include/file-fields.h b/internal/c/libqb/include/file-fields.h new file mode 100644 index 000000000..fa6324f6a --- /dev/null +++ b/internal/c/libqb/include/file-fields.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include "qbs.h" + +void lrset_field(qbs *str); +void field_free(qbs *str); +void field_new(int32_t fileno); +void field_update(int32_t fileno); +void lrset_field(qbs *str); +void field_free(qbs *str); +void field_add(qbs *str, int64_t size); +void field_get(int32_t fileno, int64_t offset, int32_t passed); +void field_put(int32_t fileno, int64_t offset, int32_t passed); diff --git a/internal/c/libqb/include/qbs.h b/internal/c/libqb/include/qbs.h index ee757d952..23de8cbcd 100644 --- a/internal/c/libqb/include/qbs.h +++ b/internal/c/libqb/include/qbs.h @@ -103,8 +103,4 @@ qbs *qbs__trim(qbs *str); int32_t func__str_nc_compare(qbs *s1, qbs *s2); int32_t func__str_compare(qbs *s1, qbs *s2); -// FIXME: Maybe put this in a gfs related header? -void lrset_field(qbs *str); -void field_free(qbs *str); - #endif diff --git a/internal/c/libqb/include/shell.h b/internal/c/libqb/include/shell.h new file mode 100644 index 000000000..95a544036 --- /dev/null +++ b/internal/c/libqb/include/shell.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include "qbs.h" + +extern int32_t shell_call_in_progress; + +int64_t func_shell(qbs *str); +int64_t func__shellhide(qbs *str); +void sub_shell(qbs *str, int32_t passed); +void sub_shell2(qbs *str, int32_t passed); +void sub_shell3(qbs *str, int32_t passed); +void sub_shell4(qbs *str, int32_t passed); diff --git a/internal/c/libqb/src/file-fields.cpp b/internal/c/libqb/src/file-fields.cpp new file mode 100644 index 000000000..bc6fbc6b0 --- /dev/null +++ b/internal/c/libqb/src/file-fields.cpp @@ -0,0 +1,346 @@ + +#include "libqb-common.h" + +#include +#include +#include + +#include "error_handle.h" +#include "qbs.h" +#include "gfs.h" +#include "file-fields.h" + +static int32_t field_failed = 1; +static int32_t field_fileno; +static int32_t field_totalsize; +static int32_t field_maxsize; + +void field_new(int32_t fileno) { + field_failed = 1; + if (is_error_pending()) + return; + // validate file + static int32_t i; + static gfs_file_struct *gfs; + i = fileno; + if (i < 0) { + error(54); + return; + } // bad file mode (TCP/IP exclusion) + if (gfs_fileno_valid(i) != 1) { + error(52); + return; + } // Bad file name or number + i = gfs_get_fileno(i); // convert fileno to gfs index + gfs = gfs_get_file_struct(i); + if (gfs->type != 1) { + error(54); + return; + } // Bad file mode (note: must have RANDOM access) + // set global variables for field_add + field_fileno = fileno; + field_totalsize = 0; + field_maxsize = gfs->record_length; + field_failed = 0; + return; +} + +void field_update(int32_t fileno) { + + // validate file + static int32_t i; + static gfs_file_struct *gfs; + i = fileno; + if (i < 0) { + exit(7701); + } // bad file mode (TCP/IP exclusion) + if (gfs_fileno_valid(i) != 1) { + exit(7702); + } // Bad file name or number + i = gfs_get_fileno(i); // convert fileno to gfs index + gfs = gfs_get_file_struct(i); + if (gfs->type != 1) { + exit(7703); + } // Bad file mode (note: must have RANDOM access) + + static qbs *str; + for (i = 0; i < gfs->field_strings_n; i++) { + str = gfs->field_strings[i]; + if (!str) + exit(7704); + + // fix length if necessary + if (str->len != str->field->size) { + if (str->len > str->field->size) + str->len = str->field->size; + else + qbs_set(str, qbs_new(str->field->size, 1)); + } + + // copy data from field into string + memmove(str->chr, gfs->field_buffer + str->field->offset, str->field->size); + + } // i +} + +void lrset_field(qbs *str) { + // validate file + static int32_t i; + static gfs_file_struct *gfs; + i = str->field->fileno; + if (gfs_fileno_valid(i) != 1) + goto remove; + i = gfs_get_fileno(i); // convert fileno to gfs index + + gfs = gfs_get_file_struct(i); + if (gfs->type != 1) + goto remove; + // check file ID + if (gfs->id != str->field->fileid) + goto remove; + + // store in field buffer, padding with spaces or truncating data if necessary + if (str->field->size <= str->len) { + + memmove(gfs->field_buffer + str->field->offset, str->chr, str->field->size); + } else { + memmove(gfs->field_buffer + str->field->offset, str->chr, str->len); + memset(gfs->field_buffer + str->field->offset + str->len, 32, str->field->size - str->len); + } + + // update field strings for this file + field_update(str->field->fileno); + + return; +remove:; + free(str->field); + str->field = NULL; +} + +void field_free(qbs *str) { + + // validate file + static int32_t i; + static gfs_file_struct *gfs; + i = str->field->fileno; + if (gfs_fileno_valid(i) != 1) + goto remove; + i = gfs_get_fileno(i); // convert fileno to gfs index + gfs = gfs_get_file_struct(i); + if (gfs->type != 1) + goto remove; + // check file ID + if (gfs->id != str->field->fileid) + goto remove; + + // remove from string list + static qbs *str2; + for (i = 0; i < gfs->field_strings_n; i++) { + str2 = gfs->field_strings[i]; + if (str == str2) { // match found + // truncate list + memmove(&(gfs->field_strings[i]), &(gfs->field_strings[i + 1]), (gfs->field_strings_n - i - 1) * sizeof(void *)); + goto remove; + } + } // i + +remove: + free(str->field); + str->field = NULL; +} + +void field_add(qbs *str, int64_t size) { + if (field_failed) + return; + if (is_error_pending()) + goto fail; + if (size < 0) { + error(5); + goto fail; + } + if ((field_totalsize + size) > field_maxsize) { + error(50); + goto fail; + } + + // revalidate file + static int32_t i; + static gfs_file_struct *gfs; + i = field_fileno; + // TCP/IP exclusion (reason: multi-reading from same TCP/IP position would require a more complex implementation) + if (i < 0) { + error(54); + goto fail; + } // bad file mode + if (gfs_fileno_valid(i) != 1) { + error(52); + goto fail; + } // Bad file name or number + i = gfs_get_fileno(i); // convert fileno to gfs index + gfs = gfs_get_file_struct(i); + if (gfs->type != 1) { + error(54); + goto fail; + } // Bad file mode (note: must have RANDOM access) + + // 1) Remove str from any previous FIELD allocations + if (str->field) + field_free(str); + + // 2) Setup qbs field info + str->field = (qbs_field *)malloc(sizeof(qbs_field)); + str->field->fileno = field_fileno; + str->field->fileid = gfs->id; + str->field->size = size; + str->field->offset = field_totalsize; + + // 3) Add str to qbs list of gfs + if (!gfs->field_strings) { + gfs->field_strings_n = 1; + gfs->field_strings = (qbs **)malloc(sizeof(qbs **)); + gfs->field_strings[0] = str; + } else { + gfs->field_strings_n++; + gfs->field_strings = (qbs **)realloc(gfs->field_strings, sizeof(qbs **) * gfs->field_strings_n); + gfs->field_strings[gfs->field_strings_n - 1] = str; + } + + // 4) Update field strings for this file + field_update(field_fileno); + + field_totalsize += size; + return; +fail: + field_failed = 1; + return; +} + +void field_get(int32_t fileno, int64_t offset, int32_t passed) { + if (is_error_pending()) + return; + + // validate file + static int32_t i; + static gfs_file_struct *gfs; + i = fileno; + if (i < 0) { + error(54); + return; + } // bad file mode (TCP/IP exclusion) + if (gfs_fileno_valid(i) != 1) { + error(52); + return; + } // Bad file name or number + i = gfs_get_fileno(i); // convert fileno to gfs index + gfs = gfs_get_file_struct(i); + if (gfs->type != 1) { + error(54); + return; + } // Bad file mode (note: must have RANDOM access) + + if (!gfs->read) { + error(75); + return; + } // Path/file access error + + if (passed) { + offset--; + if (offset < 0) { + error(63); + return; + } // Bad record number + offset *= gfs->record_length; + } else { + offset = -1; + } + + static int32_t e; + e = gfs_read(i, offset, gfs->field_buffer, gfs->record_length); + if (e) { + if (e != -10) { // note: on eof, unread buffer area becomes NULL + if (e == -2) { + error(258); + return; + } // invalid handle + if (e == -3) { + error(54); + return; + } // bad file mode + if (e == -4) { + error(5); + return; + } // illegal function call + if (e == -7) { + error(70); + return; + } // permission denied + error(75); + return; // assume[-9]: path/file access error + } + } + + field_update(fileno); +} + +void field_put(int32_t fileno, int64_t offset, int32_t passed) { + if (is_error_pending()) + return; + + // validate file + static int32_t i; + static gfs_file_struct *gfs; + i = fileno; + if (i < 0) { + error(54); + return; + } // bad file mode (TCP/IP exclusion) + if (gfs_fileno_valid(i) != 1) { + error(52); + return; + } // Bad file name or number + i = gfs_get_fileno(i); // convert fileno to gfs index + gfs = gfs_get_file_struct(i); + if (gfs->type != 1) { + error(54); + return; + } // Bad file mode (note: must have RANDOM access) + + if (!gfs->write) { + error(75); + return; + } // Path/file access error + + if (passed) { + offset--; + if (offset < 0) { + error(63); + return; + } // Bad record number + offset *= gfs->record_length; + } else { + offset = -1; + } + + static int32_t e; + e = gfs_write(i, offset, gfs->field_buffer, gfs->record_length); + if (e) { + if (e == -2) { + error(258); + return; + } // invalid handle + if (e == -3) { + error(54); + return; + } // bad file mode + if (e == -4) { + error(5); + return; + } // illegal function call + if (e == -7) { + error(70); + return; + } // permission denied + error(75); + return; // assume[-9]: path/file access error + } +} diff --git a/internal/c/libqb/src/filepath.cpp b/internal/c/libqb/src/filepath.cpp index de9d56b1c..48eab031f 100644 --- a/internal/c/libqb/src/filepath.cpp +++ b/internal/c/libqb/src/filepath.cpp @@ -4,8 +4,9 @@ #include "libqb-common.h" #include +#include -#include "../../libqb.h" +#include "qbs.h" #include "filepath.h" const char *filepath_get_filename(const char *path) { diff --git a/internal/c/libqb/src/qbs.cpp b/internal/c/libqb/src/qbs.cpp index 5337c67ce..c1f9952e4 100644 --- a/internal/c/libqb/src/qbs.cpp +++ b/internal/c/libqb/src/qbs.cpp @@ -5,6 +5,7 @@ #include #include "error_handle.h" +#include "file-fields.h" #include "qbs.h" // FIXME: Put in internal header diff --git a/internal/c/libqb/src/shell.cpp b/internal/c/libqb/src/shell.cpp new file mode 100644 index 000000000..dc398caaf --- /dev/null +++ b/internal/c/libqb/src/shell.cpp @@ -0,0 +1,1518 @@ + +#include "libqb-common.h" + +#include +#include +#include + +#ifdef QB64_WINDOWS +# include +#endif + +#include "command.h" +#include "datetime.h" +#include "error_handle.h" +#include "qbs.h" +#include "shell.h" + +// FIXME +extern int32_t console; +extern int32_t console_active; + +int32_t shell_call_in_progress = 0; + +#ifdef QB64_WINDOWS +static int32_t cmd_available = -1; + +static int32_t cmd_ok() { + if (cmd_available == -1) { + static STARTUPINFO si; + static PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (CreateProcess(NULL, // No module name (use command line) + "cmd.exe /c ver", // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NO_WINDOW, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi // Pointer to PROCESS_INFORMATION structure + )) { + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + cmd_available = 1; + } else { + cmd_available = 0; + } + } //-1 + return cmd_available; +} +#endif + +static int32_t cmd_command(qbs *str2) { + static qbs *str = NULL; + static int32_t s; + if (!str) + str = qbs_new(0, 0); + qbs_set(str, qbs_ucase(str2)); + s = 0; + if (qbs_equal(str, qbs_new_txt("ASSOC"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("BREAK"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("BCDBOOT"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("BCDEDIT"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("CALL"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("CD"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("CHDIR"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("CLS"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("COLOR"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("COPY"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("DATE"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("DEFRAG"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("DEL"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("DIR"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("ECHO"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("ENDLOCAL"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("ERASE"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("FOR"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("FTYPE"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("GOTO"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("GRAFTABL"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("IF"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("MD"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("MKDIR"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("MKLINK"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("MOVE"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("PATH"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("PAUSE"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("POPD"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("PROMPT"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("PUSHD"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("RD"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("REM"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("REN"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("RENAME"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("RMDIR"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("SET"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("SETLOCAL"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("SHIFT"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("START"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("TIME"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("TITLE"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("TYPE"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("VER"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("VERIFY"))) + s = 1; + if (qbs_equal(str, qbs_new_txt("VOL"))) + s = 1; + return s; +} + +// FIXME: Move this elsewhere +extern int32_t full_screen; +extern int32_t full_screen_set; + +int64_t func_shell(qbs *str) { + if (is_error_pending()) + return 1; + + int64_t return_code; + + // exit full screen mode if necessary + static int32_t full_screen_mode; + full_screen_mode = full_screen; + if (full_screen_mode) { + full_screen_set = 0; + do { + Sleep(0); + } while (full_screen); + } // full_screen_mode + static qbs *strz = NULL; + static qbs *str1 = NULL; + static qbs *str1z = NULL; + static qbs *str2 = NULL; + static qbs *str2z = NULL; + static int32_t i; + + static int32_t use_console; + use_console = 0; + if (console) { + if (console_active) { + use_console = 1; + } + } + + if (!strz) + strz = qbs_new(0, 0); + if (!str1) + str1 = qbs_new(0, 0); + if (!str1z) + str1z = qbs_new(0, 0); + if (!str2) + str2 = qbs_new(0, 0); + if (!str2z) + str2z = qbs_new(0, 0); + + if (str->len) { + +#ifdef QB64_WINDOWS + + if (use_console) { + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + shell_call_in_progress = 1; + /* + freopen("stdout.buf", "w", stdout); + freopen("stderr.buf", "w", stderr); + */ + return_code = system((char *)strz->chr); + /* + freopen("CON", "w", stdout); + freopen("CON", "w", stderr); + static char buf[1024]; + static int buflen; + static int fd; + fd = open("stdout.buf", O_RDONLY); + while((buflen = read(fd, buf, 1024)) > 0) + { + write(1, buf, buflen); + } + close(fd); + fd = open("stderr.buf", O_RDONLY); + while((buflen = read(fd, buf, 1024)) > 0) + { + write(1, buf, buflen); + } + close(fd); + remove("stdout.buf"); + remove("stderr.buf"); + */ + shell_call_in_progress = 0; + goto shell_complete; + } + + static STARTUPINFO si; + static PROCESS_INFORMATION pi; + + if (cmd_ok()) { + + static SHELLEXECUTEINFO shi; + static char cmd[10] = "cmd\0"; + + // attempt to separate file name (if any) from parameters + static int32_t x, quotes; + + qbs_set(str1, str); + qbs_set(str2, qbs_new_txt("")); + if (!str1->len) + goto shell_complete; // failed! + + if (!cmd_command(str1)) { + // try directly, as is + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + + x = 0; + quotes = 0; + while (x < str1->len) { + if (str1->chr[x] == 34) { + if (!quotes) + quotes = 1; + else + quotes = 0; + } + if (str1->chr[x] == 32) { + if (quotes == 0) { + qbs_set(str2, qbs_right(str1, str1->len - x - 1)); + qbs_set(str1, qbs_left(str1, x)); + goto split; + } + } + x++; + } + split: + if (!str1->len) + goto shell_complete; // failed! + + if (str2->len) { + if (!cmd_command(str1)) { + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = (char *)&str2z->chr[0]; + // if (str2->len<=1) shi.lpParameters=NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + } + + // failed, try cmd /c method... + if (str2->len) + qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); + qbs_set(strz, qbs_add(str1, str2)); + qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = &cmd[0]; + shi.lpParameters = (char *)&strz->chr[0]; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + + /* + qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); + qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); + ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); + if(CreateProcess( + NULL, // No module name (use command line) + (char*)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + DETACHED_PROCESS, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi ) // Pointer to PROCESS_INFORMATION structure + ){ + shell_call_in_progress=1; + // Wait until child process exits. + WaitForSingleObject( pi.hProcess, INFINITE ); + // Close process and thread handles. + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + shell_call_in_progress=0; + goto shell_complete; + } + */ + + return_code = 1; + goto shell_complete; // failed + + } else { + + qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (CreateProcess(NULL, // No module name (use command line) + (char *)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(pi.hProcess, INFINITE); + // Close process and thread handles. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + shell_call_in_progress = 0; + goto shell_complete; + } + goto shell_complete; // failed + + } // cmd_ok() + +#else + + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + shell_call_in_progress = 1; + return_code = system((char *)strz->chr); + shell_call_in_progress = 0; + if (return_code == -1) { /* do nothing */ + } else { + return_code = WEXITSTATUS(return_code); + } + +#endif + + } else { + +// SHELL (with no parameters) +// note: opening a new shell is only available in windows atm via cmd +// note: assumes cmd available +#ifdef QB64_WINDOWS + if (!use_console) + AllocConsole(); + qbs_set(strz, qbs_new_txt_len("cmd\0", 4)); + shell_call_in_progress = 1; + return_code = system((char *)strz->chr); + shell_call_in_progress = 0; + if (!use_console) + FreeConsole(); + goto shell_complete; +#endif + } + +shell_complete: + // reenter full screen mode if necessary + if (full_screen_mode) { + full_screen_set = full_screen_mode; + do { + Sleep(0); + } while (!full_screen); + } // full_screen_mode + + return return_code; +} // func SHELL(... + +int64_t func__shellhide(qbs *str) { // func _SHELLHIDE(... + if (is_error_pending()) + return 1; + + static int64_t return_code; + return_code = 0; + + static qbs *strz = NULL; + static int32_t i; + if (!strz) + strz = qbs_new(0, 0); + if (!str->len) { + error(5); + return 1; + } // cannot launch a hidden console + + static qbs *str1 = NULL; + static qbs *str2 = NULL; + static qbs *str1z = NULL; + static qbs *str2z = NULL; + if (!str1) + str1 = qbs_new(0, 0); + if (!str2) + str2 = qbs_new(0, 0); + if (!str1z) + str1z = qbs_new(0, 0); + if (!str2z) + str2z = qbs_new(0, 0); + +#ifdef QB64_WINDOWS + + static STARTUPINFO si; + static PROCESS_INFORMATION pi; + + if (cmd_ok()) { + + static SHELLEXECUTEINFO shi; + static char cmd[10] = "cmd\0"; + + // attempt to separate file name (if any) from parameters + static int32_t x, quotes; + + qbs_set(str1, str); + qbs_set(str2, qbs_new_txt("")); + + if (!cmd_command(str1)) { + // try directly, as is + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + + x = 0; + quotes = 0; + while (x < str1->len) { + if (str1->chr[x] == 34) { + if (!quotes) + quotes = 1; + else + quotes = 0; + } + if (str1->chr[x] == 32) { + if (quotes == 0) { + qbs_set(str2, qbs_right(str1, str1->len - x - 1)); + qbs_set(str1, qbs_left(str1, x)); + goto split; + } + } + x++; + } + split: + if (!str1->len) { + return_code = 1; + goto shell_complete; + } // failed! + + if (str2->len) { + if (!cmd_command(str1)) { + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = (char *)&str2z->chr[0]; + // if (str2->len<=1) shi.lpParameters=NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + } + + // failed, try cmd /c method... + if (str2->len) + qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); + qbs_set(strz, qbs_add(str1, str2)); + qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = &cmd[0]; + shi.lpParameters = (char *)&strz->chr[0]; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + GetExitCodeProcess(shi.hProcess, (DWORD *)&return_code); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + + /* + qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); + qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); + ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); + if(CreateProcess( + NULL, // No module name (use command line) + (char*)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NO_WINDOW, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi ) // Pointer to PROCESS_INFORMATION structure + ){ + shell_call_in_progress=1; + // Wait until child process exits. + WaitForSingleObject( pi.hProcess, INFINITE ); + // Close process and thread handles. + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + shell_call_in_progress=0; + goto shell_complete; + } + */ + + return_code = 1; + goto shell_complete; // failed + + } else { + + qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (CreateProcess( + + NULL, // No module name (use command line) + (char *)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(pi.hProcess, INFINITE); + // Close process and thread handles. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + shell_call_in_progress = 0; + goto shell_complete; + } + goto shell_complete; // failed + + } // cmd_ok() + +#else + + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + shell_call_in_progress = 1; + return_code = system((char *)strz->chr); + shell_call_in_progress = 0; + return return_code; + +#endif + +shell_complete:; + + return return_code; +} // func _SHELLHIDE(... + +void sub_shell(qbs *str, int32_t passed) { + if (is_error_pending()) + return; + + // exit full screen mode if necessary + static int32_t full_screen_mode; + full_screen_mode = full_screen; + if (full_screen_mode) { + full_screen_set = 0; + do { + Sleep(0); + } while (full_screen); + } // full_screen_mode + static qbs *strz = NULL; + static qbs *str1 = NULL; + static qbs *str1z = NULL; + static qbs *str2 = NULL; + static qbs *str2z = NULL; + static int32_t i; + + static int32_t use_console; + use_console = 0; + if (console) { + if (console_active) { + use_console = 1; + } + } + + if (!strz) + strz = qbs_new(0, 0); + if (!str1) + str1 = qbs_new(0, 0); + if (!str1z) + str1z = qbs_new(0, 0); + if (!str2) + str2 = qbs_new(0, 0); + if (!str2z) + str2z = qbs_new(0, 0); + + if (passed) + if (str->len == 0) + passed = 0; //"" means launch a CONSOLE + if (passed) { + +#ifdef QB64_WINDOWS + + if (use_console) { + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + shell_call_in_progress = 1; + /* + freopen("stdout.buf", "w", stdout); + freopen("stderr.buf", "w", stderr); + */ + system((char *)strz->chr); + /* + freopen("CON", "w", stdout); + freopen("CON", "w", stderr); + static char buf[1024]; + static int buflen; + static int fd; + fd = open("stdout.buf", O_RDONLY); + while((buflen = read(fd, buf, 1024)) > 0) + { + write(1, buf, buflen); + } + close(fd); + fd = open("stderr.buf", O_RDONLY); + while((buflen = read(fd, buf, 1024)) > 0) + { + write(1, buf, buflen); + } + close(fd); + remove("stdout.buf"); + remove("stderr.buf"); + */ + shell_call_in_progress = 0; + goto shell_complete; + } + + static STARTUPINFO si; + static PROCESS_INFORMATION pi; + + if (cmd_ok()) { + + static SHELLEXECUTEINFO shi; + static char cmd[10] = "cmd\0"; + + // attempt to separate file name (if any) from parameters + static int32_t x, quotes; + + qbs_set(str1, str); + qbs_set(str2, qbs_new_txt("")); + if (!str1->len) + goto shell_complete; // failed! + + if (!cmd_command(str1)) { + // try directly, as is + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + + x = 0; + quotes = 0; + while (x < str1->len) { + if (str1->chr[x] == 34) { + if (!quotes) + quotes = 1; + else + quotes = 0; + } + if (str1->chr[x] == 32) { + if (quotes == 0) { + qbs_set(str2, qbs_right(str1, str1->len - x - 1)); + qbs_set(str1, qbs_left(str1, x)); + goto split; + } + } + x++; + } + split: + if (!str1->len) + goto shell_complete; // failed! + + if (str2->len) { + if (!cmd_command(str1)) { + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = (char *)&str2z->chr[0]; + // if (str2->len<=1) shi.lpParameters=NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + } + + // failed, try cmd /c method... + if (str2->len) + qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); + qbs_set(strz, qbs_add(str1, str2)); + qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = &cmd[0]; + shi.lpParameters = (char *)&strz->chr[0]; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + + /* + qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); + qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); + ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); + if(CreateProcess( + NULL, // No module name (use command line) + (char*)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + DETACHED_PROCESS, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi ) // Pointer to PROCESS_INFORMATION structure + ){ + shell_call_in_progress=1; + // Wait until child process exits. + WaitForSingleObject( pi.hProcess, INFINITE ); + // Close process and thread handles. + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + shell_call_in_progress=0; + goto shell_complete; + } + */ + + goto shell_complete; // failed + + } else { + + qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (CreateProcess(NULL, // No module name (use command line) + (char *)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(pi.hProcess, INFINITE); + // Close process and thread handles. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + shell_call_in_progress = 0; + goto shell_complete; + } + goto shell_complete; // failed + + } // cmd_ok() + +#else + + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + shell_call_in_progress = 1; + system((char *)strz->chr); + shell_call_in_progress = 0; + +#endif + + } else { + +// SHELL (with no parameters) +// note: opening a new shell is only available in windows atm via cmd +// note: assumes cmd available +#ifdef QB64_WINDOWS + if (!use_console) + AllocConsole(); + qbs_set(strz, qbs_new_txt_len("cmd\0", 4)); + shell_call_in_progress = 1; + system((char *)strz->chr); + shell_call_in_progress = 0; + if (!use_console) + FreeConsole(); + goto shell_complete; +#endif + } + +shell_complete: + // reenter full screen mode if necessary + if (full_screen_mode) { + full_screen_set = full_screen_mode; + do { + Sleep(0); + } while (!full_screen); + } // full_screen_mode +} + +void sub_shell2(qbs *str, int32_t passed) { // HIDE + if (is_error_pending()) + return; + + if (passed & 1) { + sub_shell4(str, passed & 2); + return; + } + if (!(passed & 2)) { + error(5); + return; + } // should not hide a shell waiting for input + + static qbs *strz = NULL; + static int32_t i; + if (!strz) + strz = qbs_new(0, 0); + if (!str->len) { + error(5); + return; + } // cannot launch a hidden console + + static qbs *str1 = NULL; + static qbs *str2 = NULL; + static qbs *str1z = NULL; + static qbs *str2z = NULL; + if (!str1) + str1 = qbs_new(0, 0); + if (!str2) + str2 = qbs_new(0, 0); + if (!str1z) + str1z = qbs_new(0, 0); + if (!str2z) + str2z = qbs_new(0, 0); + +#ifdef QB64_WINDOWS + + static STARTUPINFO si; + static PROCESS_INFORMATION pi; + + if (cmd_ok()) { + + static SHELLEXECUTEINFO shi; + static char cmd[10] = "cmd\0"; + + // attempt to separate file name (if any) from parameters + static int32_t x, quotes; + + qbs_set(str1, str); + qbs_set(str2, qbs_new_txt("")); + + if (!cmd_command(str1)) { + // try directly, as is + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + + x = 0; + quotes = 0; + while (x < str1->len) { + if (str1->chr[x] == 34) { + if (!quotes) + quotes = 1; + else + quotes = 0; + } + if (str1->chr[x] == 32) { + if (quotes == 0) { + qbs_set(str2, qbs_right(str1, str1->len - x - 1)); + qbs_set(str1, qbs_left(str1, x)); + goto split; + } + } + x++; + } + split: + if (!str1->len) + goto shell_complete; // failed! + + if (str2->len) { + if (!cmd_command(str1)) { + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = (char *)&str2z->chr[0]; + // if (str2->len<=1) shi.lpParameters=NULL; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + } + } + + // failed, try cmd /c method... + if (str2->len) + qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); + qbs_set(strz, qbs_add(str1, str2)); + qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = &cmd[0]; + shi.lpParameters = (char *)&strz->chr[0]; + shi.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(shi.hProcess, INFINITE); + CloseHandle(shi.hProcess); + shell_call_in_progress = 0; + goto shell_complete; + } + + /* + qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); + qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); + ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); + if(CreateProcess( + NULL, // No module name (use command line) + (char*)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NO_WINDOW, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi ) // Pointer to PROCESS_INFORMATION structure + ){ + shell_call_in_progress=1; + // Wait until child process exits. + WaitForSingleObject( pi.hProcess, INFINITE ); + // Close process and thread handles. + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + shell_call_in_progress=0; + goto shell_complete; + } + */ + + goto shell_complete; // failed + + } else { + + qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (CreateProcess( + + NULL, // No module name (use command line) + (char *)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) { + shell_call_in_progress = 1; + // Wait until child process exits. + WaitForSingleObject(pi.hProcess, INFINITE); + // Close process and thread handles. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + shell_call_in_progress = 0; + goto shell_complete; + } + goto shell_complete; // failed + + } // cmd_ok() + +#else + + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + shell_call_in_progress = 1; + system((char *)strz->chr); + shell_call_in_progress = 0; + return; + +#endif + +shell_complete:; +} + +void sub_shell3(qbs *str, int32_t passed) { //_DONTWAIT + // shell3 launches 'str' but does not wait for it to complete + if (is_error_pending()) + return; + + if (passed & 1) { + sub_shell4(str, passed & 2); + return; + } + + static qbs *strz = NULL; + static int32_t i; + + static qbs *str1 = NULL; + static qbs *str2 = NULL; + static qbs *str1z = NULL; + static qbs *str2z = NULL; + if (!str1) + str1 = qbs_new(0, 0); + if (!str2) + str2 = qbs_new(0, 0); + if (!str1z) + str1z = qbs_new(0, 0); + if (!str2z) + str2z = qbs_new(0, 0); + + if (!strz) + strz = qbs_new(0, 0); + +#ifdef QB64_WINDOWS + + static STARTUPINFO si; + static PROCESS_INFORMATION pi; + + if (cmd_ok()) { + + static SHELLEXECUTEINFO shi; + static char cmd[10] = "cmd\0"; + + // attempt to separate file name (if any) from parameters + static int32_t x, quotes; + + // allow for launching of a console + if (!(passed & 2)) { + qbs_set(str1, qbs_new_txt("cmd")); + } else { + qbs_set(str1, str); + if (!str1->len) + qbs_set(str1, qbs_new_txt("cmd")); + } + qbs_set(str2, qbs_new_txt("")); + + if (!cmd_command(str1)) { + // try directly, as is + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = NULL; + shi.fMask = SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + goto shell_complete; + } + } + + x = 0; + quotes = 0; + while (x < str1->len) { + if (str1->chr[x] == 34) { + if (!quotes) + quotes = 1; + else + quotes = 0; + } + if (str1->chr[x] == 32) { + if (quotes == 0) { + qbs_set(str2, qbs_right(str1, str1->len - x - 1)); + qbs_set(str1, qbs_left(str1, x)); + goto split; + } + } + x++; + } + split: + if (!str1->len) + goto shell_complete; // failed! + + if (str2->len) { + if (!cmd_command(str1)) { + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = (char *)&str2z->chr[0]; + // if (str2->len<=1) shi.lpParameters=NULL; + shi.fMask = SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + goto shell_complete; + } + } + } + + // failed, try cmd /c method... + if (str2->len) + qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); + qbs_set(strz, qbs_add(str1, str2)); + qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = &cmd[0]; + shi.lpParameters = (char *)&strz->chr[0]; + shi.fMask = SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_SHOW; + if (ShellExecuteEx(&shi)) { + goto shell_complete; + } + + /* + qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); + qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); + ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); + if(CreateProcess( + NULL, // No module name (use command line) + (char*)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + DETACHED_PROCESS, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi ) // Pointer to PROCESS_INFORMATION structure + ){ + //ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its + threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to + CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + goto shell_complete; + } + */ + + goto shell_complete; // failed + + } else { + + qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (CreateProcess(NULL, // No module name (use command line) + (char *)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) { + // ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its + // threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to + // CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + goto shell_complete; + } + goto shell_complete; // failed + + } // cmd_ok() + +#else + + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + pid_t pid = fork(); + if (pid == 0) + _exit(system((char *)strz->chr)); + return; + +#endif + +shell_complete:; +} // SHELL _DONTWAIT + +void sub_shell4(qbs *str, int32_t passed) { //_DONTWAIT & _HIDE + // if passed&2 set a string was given + if (!(passed & 2)) { + error(5); + return; + } // should not hide a shell waiting for input + + static qbs *strz = NULL; + static int32_t i; + + static qbs *str1 = NULL; + static qbs *str2 = NULL; + static qbs *str1z = NULL; + static qbs *str2z = NULL; + if (!str1) + str1 = qbs_new(0, 0); + if (!str2) + str2 = qbs_new(0, 0); + if (!str1z) + str1z = qbs_new(0, 0); + if (!str2z) + str2z = qbs_new(0, 0); + + if (!strz) + strz = qbs_new(0, 0); + + if (!str->len) { + error(5); + return; + } // console unsupported + +#ifdef QB64_WINDOWS + + static STARTUPINFO si; + static PROCESS_INFORMATION pi; + + if (cmd_ok()) { + + static SHELLEXECUTEINFO shi; + static char cmd[10] = "cmd\0"; + + // attempt to separate file name (if any) from parameters + static int32_t x, quotes; + + qbs_set(str1, str); + qbs_set(str2, qbs_new_txt("")); + + if (!cmd_command(str1)) { + // try directly, as is + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = NULL; + shi.fMask = SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + goto shell_complete; + } + } + + x = 0; + quotes = 0; + while (x < str1->len) { + if (str1->chr[x] == 34) { + if (!quotes) + quotes = 1; + else + quotes = 0; + } + if (str1->chr[x] == 32) { + if (quotes == 0) { + qbs_set(str2, qbs_right(str1, str1->len - x - 1)); + qbs_set(str1, qbs_left(str1, x)); + goto split; + } + } + x++; + } + split: + if (!str1->len) + goto shell_complete; // failed! + + if (str2->len) { + if (!cmd_command(str1)) { + qbs_set(str1z, qbs_add(str1, qbs_new_txt_len("\0", 1))); + qbs_set(str2z, qbs_add(str2, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = (char *)&str1z->chr[0]; + shi.lpParameters = (char *)&str2z->chr[0]; + // if (str2->len<=1) shi.lpParameters=NULL; + shi.fMask = SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + goto shell_complete; + } + } + } + + // failed, try cmd /c method... + if (str2->len) + qbs_set(str2, qbs_add(qbs_new_txt(" "), str2)); + qbs_set(strz, qbs_add(str1, str2)); + qbs_set(strz, qbs_add(qbs_new_txt(" /c "), strz)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&shi, sizeof(shi)); + shi.cbSize = sizeof(shi); + shi.lpFile = &cmd[0]; + shi.lpParameters = (char *)&strz->chr[0]; + shi.fMask = SEE_MASK_FLAG_NO_UI; + shi.nShow = SW_HIDE; + if (ShellExecuteEx(&shi)) { + goto shell_complete; + } + + /* + qbs_set(strz,qbs_add(qbs_new_txt("cmd.exe /c "),str)); + qbs_set(strz,qbs_add(strz,qbs_new_txt_len("\0",1))); + ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); + if(CreateProcess( + NULL, // No module name (use command line) + (char*)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + DETACHED_PROCESS, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi ) // Pointer to PROCESS_INFORMATION structure + ){ + //ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its + threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to + CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + goto shell_complete; + } + */ + + goto shell_complete; // failed + + } else { + + qbs_set(strz, qbs_add(qbs_new_txt("command.com /c "), str)); + qbs_set(strz, qbs_add(strz, qbs_new_txt_len("\0", 1))); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + if (CreateProcess(NULL, // No module name (use command line) + (char *)&strz->chr[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // note: cannot hide new console, but can preserve existing one + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) { + // ref: The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its + // threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to + // CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + goto shell_complete; + } + goto shell_complete; // failed + + } // cmd_ok() + +#else + + qbs_set(strz, qbs_add(str, qbs_new_txt_len("\0", 1))); + pid_t pid = fork(); + if (pid == 0) + _exit(system((char *)strz->chr)); + return; + +#endif + +shell_complete:; + +} //_DONTWAIT & _HIDE diff --git a/internal/c/libqb/src/string_functions.cpp b/internal/c/libqb/src/string_functions.cpp index a0de72617..648bd1b61 100644 --- a/internal/c/libqb/src/string_functions.cpp +++ b/internal/c/libqb/src/string_functions.cpp @@ -5,6 +5,7 @@ #include #include "error_handle.h" +#include "file-fields.h" #include "qbs.h" extern qbs *nothingstring; diff --git a/internal/c/parts/compression/compression.cpp b/internal/c/parts/compression/compression.cpp index bfb064ee7..974f786f0 100644 --- a/internal/c/parts/compression/compression.cpp +++ b/internal/c/parts/compression/compression.cpp @@ -3,8 +3,10 @@ // Powered by miniz (https://github.com/richgel999/miniz) //----------------------------------------------------------------------------------------------------- +#include "libqb-common.h" + #include "compression.h" -#include "../../libqb.h" +#include "qbs.h" #include "miniz.h" uint32_t func__adler32(qbs *text) { @@ -53,4 +55,4 @@ qbs *func__inflate(qbs *text, int64_t originalsize, int32_t passed) { free(dest); return ret; } -} \ No newline at end of file +} diff --git a/internal/c/parts/gui/gui.cpp b/internal/c/parts/gui/gui.cpp index 56c25d813..d81582b19 100644 --- a/internal/c/parts/gui/gui.cpp +++ b/internal/c/parts/gui/gui.cpp @@ -10,12 +10,16 @@ // //----------------------------------------------------------------------------------------------------- +#include "libqb-common.h" + +#include "qbs.h" #include "gui.h" -#include "../../libqb.h" #include "image.h" #include "tinyfiledialogs.h" #include #include +#include +#include /// @brief Splits a string delimited by '|' into an array of strings /// @param input The string to be parsed diff --git a/internal/c/qbx.cpp b/internal/c/qbx.cpp index 0e4b53323..a7265145c 100755 --- a/internal/c/qbx.cpp +++ b/internal/c/qbx.cpp @@ -8,6 +8,7 @@ #include "event.h" #include "extended_math.h" #include "filepath.h" +#include "file-fields.h" #include "filesystem.h" #include "font.h" #include "gui.h" @@ -15,6 +16,7 @@ #include "qbmath.h" #include "qbs.h" #include "qbs-mk-cv.h" +#include "shell.h" #include "error_handle.h" #include "mem.h" #include "rounding.h" @@ -129,11 +131,6 @@ extern int64 GetTicks(); extern mem_block func__memimage(int32, int32); -extern int64 func__shellhide(qbs *str); -extern int64 func_shell(qbs *str); -extern void sub_shell(qbs *str, int32 passed); -extern void sub_shell2(qbs *str, int32 passed); -extern void sub_shell3(qbs *str, int32 passed); extern void sub__consoletitle(qbs *); extern void sub__screenshow(); extern void sub__screenhide(); @@ -178,10 +175,6 @@ extern void sub__mousemove(float x, float y); extern qbs *func__os(); extern void sub__mapunicode(int32 unicode_code, int32 ascii_code); extern int32 func__mapunicode(int32 ascii_code); -extern void field_new(int32 fileno); -extern void field_add(qbs *str, int64 size); -extern void field_get(int32 fileno, int64 seekpos, int32 passed); -extern void field_put(int32 fileno, int64 seekpos, int32 passed); extern int32 func__keydown(int32 x); extern int32 func__keyhit(); extern int32 func_lpos(int32); @@ -250,19 +243,6 @@ extern int32 func_peek(int32 offset); extern void sub_poke(int32 offset, int32 value); extern void more_return_points(); extern qbs *func_varptr_helper(uint8 type, uint16 offset); -extern void sub_lset(qbs *dest, qbs *source); -extern void sub_rset(qbs *dest, qbs *source); -extern qbs *func_space(int32 spaces); -extern qbs *func_string(int32 characters, int32 asciivalue); -extern int32 func_instr(int32 start, qbs *str, qbs *substr, int32 passed); -extern int32 func__instrrev(int32 start, qbs *str, qbs *substr, int32 passed); -extern void sub_mid(qbs *dest, int32 start, int32 l, qbs *src, int32 passed); -extern qbs *func_mid(qbs *str, int32 start, int32 l, int32 passed); -extern qbs *qbs_ltrim(qbs *str); -extern qbs *qbs_rtrim(qbs *str); -extern qbs *qbs__trim(qbs *str); -extern int32 func__str_nc_compare(qbs *s1, qbs *s2); -extern int32 func__str_compare(qbs *s1, qbs *s2); extern qbs *qbs_inkey(); extern void sub__keyclear(int32 buf, int32 passed); extern void lineclip(int32 x1, int32 y1, int32 x2, int32 y2, int32 xmin,