diff --git a/Red_Panda_CPP.pro b/Red_Panda_CPP.pro
index 148bb77d..029b91c0 100644
--- a/Red_Panda_CPP.pro
+++ b/Red_Panda_CPP.pro
@@ -2,5 +2,6 @@ TEMPLATE = subdirs
SUBDIRS += \
# ../QScintilla/src/qscintilla.pro \
- RedPandaIDE
+ RedPandaIDE \
+ consolepauser
diff --git a/consolepauser/consolepauser.pro b/consolepauser/consolepauser.pro
new file mode 100644
index 00000000..62a643d0
--- /dev/null
+++ b/consolepauser/consolepauser.pro
@@ -0,0 +1,26 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+win32: {
+SOURCES += \
+ main.windows.cpp
+}
+
+unix: {
+SOURCES += \
+ main.unix.cpp
+}
+
+CONFIG += lrelease
+CONFIG += embed_translations
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
diff --git a/consolepauser/main.windows.cpp b/consolepauser/main.windows.cpp
new file mode 100644
index 00000000..ce4d3d81
--- /dev/null
+++ b/consolepauser/main.windows.cpp
@@ -0,0 +1,256 @@
+/*
+ * This file is part of Red Panda Dev-C++ 7
+ * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+/*
+ * This file is part of Red Panda Dev-C++ 7
+ * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+using std::string;
+#include
+#include
+#include
+
+#define MAX_COMMAND_LENGTH 32768
+#define MAX_ERROR_LENGTH 2048
+
+enum RunProgramFlag {
+ RPF_PAUSE_CONSOLE = 0x0001,
+ RPF_REDIRECT_INPUT = 0x0002
+};
+
+HANDLE hJob;
+
+LONGLONG GetClockTick() {
+ LARGE_INTEGER dummy;
+ QueryPerformanceCounter(&dummy);
+ return dummy.QuadPart;
+}
+
+LONGLONG GetClockFrequency() {
+ LARGE_INTEGER dummy;
+ QueryPerformanceFrequency(&dummy);
+ return dummy.QuadPart;
+}
+
+
+string GetErrorMessage() {
+ string result(MAX_ERROR_LENGTH,0);
+ FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),&result[0],result.size(),NULL);
+
+ // Clear newlines at end of string
+ for(int i = result.length()-1;i >= 0;i--) {
+ if(isspace(result[i])) {
+ result[i] = 0;
+ } else {
+ break;
+ }
+ }
+ return result;
+}
+
+void PauseExit(int exitcode, bool reInp) {
+ HANDLE hInp=NULL;
+ if (reInp) {
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ HANDLE hInp = CreateFileA("CONIN$", GENERIC_WRITE | GENERIC_READ,
+ FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
+ //si.hStdInput = hInp;
+ SetStdHandle(STD_INPUT_HANDLE,hInp);
+ freopen("CONIN$","r",stdin);
+ }
+ FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
+ fflush(stdin);
+ printf("\n");
+ printf("Press ANY key to exit...");
+ getch();
+ if (reInp) {
+ CloseHandle(hInp);
+ }
+ exit(exitcode);
+}
+
+string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit) {
+ string result;
+ int flags = atoi(argv[1]);
+ reInp = flags & RPF_REDIRECT_INPUT;
+ pauseAfterExit = flags & RPF_PAUSE_CONSOLE;
+ for(int i = 2;i < argc;i++) {
+ // Quote the argument in case the path name contains spaces
+ result += string("\"") + string(argv[i]) + string("\"");
+
+ // Add a space except for the last argument
+ if(i != (argc-1)) {
+ result += string(" ");
+ }
+ }
+
+ if(result.length() > MAX_COMMAND_LENGTH) {
+ printf("\n--------------------------------");
+ printf("\nError: Length of command line string is over %d characters\n",MAX_COMMAND_LENGTH);
+ PauseExit(EXIT_FAILURE,reInp);
+ }
+
+ return result;
+}
+
+DWORD ExecuteCommand(string& command,bool reInp) {
+ STARTUPINFOA si;
+ PROCESS_INFORMATION pi;
+
+ memset(&si,0,sizeof(si));
+ si.cb = sizeof(si);
+ memset(&pi,0,sizeof(pi));
+
+ DWORD dwCreationFlags = CREATE_BREAKAWAY_FROM_JOB;
+
+
+ if(!CreateProcessA(NULL, (LPSTR)command.c_str(), NULL, NULL, true, dwCreationFlags, NULL, NULL, &si, &pi)) {
+ printf("\n--------------------------------");
+ printf("\nFailed to execute \"%s\":",command.c_str());
+ printf("\nError %lu: %s\n",GetLastError(),GetErrorMessage().c_str());
+ PauseExit(EXIT_FAILURE,reInp);
+ }
+ WINBOOL bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
+ if ( bSuccess == FALSE ) {
+ printf( "AssignProcessToJobObject failed: error %d\n", GetLastError() );
+ return 0;
+ }
+
+ WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish
+
+
+ DWORD result = 0;
+ GetExitCodeProcess(pi.hProcess, &result);
+ return result;
+}
+
+int main(int argc, char** argv) {
+
+ // First make sure we aren't going to read nonexistent arrays
+ if(argc < 3) {
+ printf("\n--------------------------------");
+ printf("\nUsage: ConsolePauser.exe <0|1> \n");
+ printf("\n 1 means the STDIN is redirected by Dev-CPP;0 means not\n");
+ PauseExit(EXIT_SUCCESS,false);
+ }
+
+ // Make us look like the paused program
+ SetConsoleTitleA(argv[2]);
+
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = FALSE;
+
+ hJob= CreateJobObject( &sa, NULL );
+
+ if ( hJob == NULL ) {
+ printf( "CreateJobObject failed: error %d\n", GetLastError() );
+ return 0;
+ }
+
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION info = { 0 };
+ info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+ WINBOOL bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &info, sizeof( info ) );
+ if ( bSuccess == FALSE ) {
+ printf( "SetInformationJobObject failed: error %d\n", GetLastError() );
+ return 0;
+ }
+
+ bool reInp;
+ bool pauseAfterExit;
+ // Then build the to-run application command
+ string command = GetCommand(argc,argv,reInp, pauseAfterExit);
+ HANDLE hOutput = NULL;
+ if (reInp) {
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ hOutput = CreateFileA("CONOUT$", GENERIC_WRITE | GENERIC_READ,
+ FILE_SHARE_WRITE , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
+ SetStdHandle(STD_OUTPUT_HANDLE, hOutput);
+ SetStdHandle(STD_ERROR_HANDLE, hOutput);
+ freopen("CONOUT$","w+",stdout);
+ freopen("CONOUT$","w+",stderr);
+ } else {
+ FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
+ }
+
+ HANDLE hSharedMemory=INVALID_HANDLE_VALUE;
+ int BUF_SIZE=1024;
+ char* pBuf=nullptr;
+ hSharedMemory = OpenFileMappingA(
+ FILE_MAP_ALL_ACCESS,
+ FALSE,
+ "RED_PANDA_IDE_CONSOLE_PAUSER20211223"
+ );
+ if (hSharedMemory != NULL)
+ {
+ pBuf = (char*) MapViewOfFile(hSharedMemory, // handle to map object
+ FILE_MAP_ALL_ACCESS, // read/write permission
+ 0,
+ 0,
+ BUF_SIZE);
+ } else {
+ printf("can't open shared memory!");
+ }
+
+ // Save starting timestamp
+ LONGLONG starttime = GetClockTick();
+
+ // Then execute said command
+ DWORD returnvalue = ExecuteCommand(command,reInp);
+
+ // Get ending timestamp
+ LONGLONG endtime = GetClockTick();
+ double seconds = (endtime - starttime) / (double)GetClockFrequency();
+
+ if (pBuf) {
+ strcpy(pBuf,"FINISHED");
+ }
+
+ // Done? Print return value of executed program
+ printf("\n--------------------------------");
+ printf("\nProcess exited after %.4g seconds with return value %lu\n",seconds,returnvalue);
+ if (pauseAfterExit)
+ PauseExit(returnvalue,reInp);
+ return 0;
+}
+
diff --git a/tools/ConsolePauser/.gitignore b/tools/ConsolePauser/.gitignore
deleted file mode 100644
index b5be7eb0..00000000
--- a/tools/ConsolePauser/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-/ConsolePauser.layout
-/Makefile.win
-/ConsolePauser.exe
-/main.o
diff --git a/tools/ConsolePauser/ConsolePauser.dev b/tools/ConsolePauser/ConsolePauser.dev
deleted file mode 100644
index c182a345..00000000
--- a/tools/ConsolePauser/ConsolePauser.dev
+++ /dev/null
@@ -1,74 +0,0 @@
-[Project]
-FileName = ConsolePauser.dev
-Name = ConsolePauser
-Type = 1
-Ver = 3
-ObjFiles =
-Includes =
-Libs =
-PrivateResource =
-ResourceIncludes =
-MakeIncludes =
-Compiler =
-CppCompiler =
-Linker =
-IsCpp = 1
-Icon =
-ExeOutput =
-ObjectOutput =
-LogOutput =
-LogOutputEnabled = 0
-OverrideOutput = 0
-OverrideOutputName = ConsolePauser.exe
-HostApplication =
-Folders =
-CommandLine =
-UseCustomMakefile = 0
-CustomMakefile =
-IncludeVersionInfo = 0
-SupportXPThemes = 0
-CompilerSet = 0
-CompilerSettings = 000000a000000000000010001
-UnitCount = 1
-UsePrecompiledHeader = 0
-PrecompiledHeader =
-UseUTF8 = 0
-StaticLink = 1
-AddCharset = 1
-Encoding = AUTO
-CompilerSetType = 0
-
-
-[VersionInfo]
-Major = 1
-Minor = 0
-Release = 0
-Build = 0
-LanguageID = 1033
-CharsetID = 1252
-CompanyName =
-FileVersion = 1.0.0.0
-FileDescription = Developed using the Dev-C++ IDE
-InternalName =
-LegalCopyright =
-LegalTrademarks =
-OriginalFilename =
-ProductName =
-ProductVersion = 1.0.0.0
-AutoIncBuildNr = 0
-SyncProduct = 1
-
-
-[Unit1]
-FileName = main.cpp
-CompileCpp = 1
-Folder =
-Compile = 1
-Link = 1
-Priority = 1000
-OverrideBuildCmd = 0
-BuildCmd =
-UseUTF8 = 1
-DetectEncoding = 1
-Encoding = 0
-FileEncoding = AUTO
diff --git a/tools/ConsolePauser/main.cpp b/tools/ConsolePauser/main.cpp
deleted file mode 100644
index 00ce5cfd..00000000
--- a/tools/ConsolePauser/main.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * This file is part of Red Panda Dev-C++ 7
- * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include
-using std::string;
-#include
-#include
-#include
-
-#define MAX_COMMAND_LENGTH 32768
-#define MAX_ERROR_LENGTH 2048
-
-enum RunProgramFlag {
- RPF_PAUSE_CONSOLE = 0x0001,
- RPF_REDIRECT_INPUT = 0x0002
-};
-
-HANDLE hJob;
-
-LONGLONG GetClockTick() {
- LARGE_INTEGER dummy;
- QueryPerformanceCounter(&dummy);
- return dummy.QuadPart;
-}
-
-LONGLONG GetClockFrequency() {
- LARGE_INTEGER dummy;
- QueryPerformanceFrequency(&dummy);
- return dummy.QuadPart;
-}
-
-
-string GetErrorMessage() {
- string result(MAX_ERROR_LENGTH,0);
- FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),&result[0],result.size(),NULL);
-
- // Clear newlines at end of string
- for(int i = result.length()-1;i >= 0;i--) {
- if(isspace(result[i])) {
- result[i] = 0;
- } else {
- break;
- }
- }
- return result;
-}
-
-void PauseExit(int exitcode, bool reInp) {
- HANDLE hInp=NULL;
- if (reInp) {
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
-
- HANDLE hInp = CreateFile("CONIN$", GENERIC_WRITE | GENERIC_READ,
- FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
- //si.hStdInput = hInp;
- SetStdHandle(STD_INPUT_HANDLE,hInp);
- freopen("CONIN$","r",stdin);
- }
- FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
- fflush(stdin);
- printf("\n");
- printf("Press ANY key to exit...");
- getch();
- if (reInp) {
- CloseHandle(hInp);
- }
- exit(exitcode);
-}
-
-string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit) {
- string result;
- int flags = atoi(argv[1]);
- reInp = flags & RPF_REDIRECT_INPUT;
- pauseAfterExit = flags & RPF_PAUSE_CONSOLE;
- for(int i = 2;i < argc;i++) {
- // Quote the argument in case the path name contains spaces
- result += string("\"") + string(argv[i]) + string("\"");
-
- // Add a space except for the last argument
- if(i != (argc-1)) {
- result += string(" ");
- }
- }
-
- if(result.length() > MAX_COMMAND_LENGTH) {
- printf("\n--------------------------------");
- printf("\nError: Length of command line string is over %d characters\n",MAX_COMMAND_LENGTH);
- PauseExit(EXIT_FAILURE,reInp);
- }
-
- return result;
-}
-
-DWORD ExecuteCommand(string& command,bool reInp) {
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
-
- memset(&si,0,sizeof(si));
- si.cb = sizeof(si);
- memset(&pi,0,sizeof(pi));
-
- DWORD dwCreationFlags = CREATE_BREAKAWAY_FROM_JOB;
-
-
- if(!CreateProcess(NULL, (LPSTR)command.c_str(), NULL, NULL, true, dwCreationFlags, NULL, NULL, &si, &pi)) {
- printf("\n--------------------------------");
- printf("\nFailed to execute \"%s\":",command.c_str());
- printf("\nError %lu: %s\n",GetLastError(),GetErrorMessage().c_str());
- PauseExit(EXIT_FAILURE,reInp);
- }
- WINBOOL bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
- if ( bSuccess == FALSE ) {
- printf( "AssignProcessToJobObject failed: error %d\n", GetLastError() );
- return 0;
- }
-
- WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish
-
-
- DWORD result = 0;
- GetExitCodeProcess(pi.hProcess, &result);
- return result;
-}
-
-int main(int argc, char** argv) {
-
- // First make sure we aren't going to read nonexistent arrays
- if(argc < 3) {
- printf("\n--------------------------------");
- printf("\nUsage: ConsolePauser.exe <0|1> \n");
- printf("\n 1 means the STDIN is redirected by Dev-CPP;0 means not\n");
- PauseExit(EXIT_SUCCESS,false);
- }
-
- // Make us look like the paused program
- SetConsoleTitle(argv[2]);
-
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = FALSE;
-
- hJob= CreateJobObject( &sa, NULL );
-
- if ( hJob == NULL ) {
- printf( "CreateJobObject failed: error %d\n", GetLastError() );
- return 0;
- }
-
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION info = { 0 };
- info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
- WINBOOL bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &info, sizeof( info ) );
- if ( bSuccess == FALSE ) {
- printf( "SetInformationJobObject failed: error %d\n", GetLastError() );
- return 0;
- }
-
- bool reInp;
- bool pauseAfterExit;
- // Then build the to-run application command
- string command = GetCommand(argc,argv,reInp, pauseAfterExit);
- HANDLE hOutput = NULL;
- if (reInp) {
- SECURITY_ATTRIBUTES sa;
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = TRUE;
-
- hOutput = CreateFile("CONOUT$", GENERIC_WRITE | GENERIC_READ,
- FILE_SHARE_WRITE , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
- SetStdHandle(STD_OUTPUT_HANDLE, hOutput);
- SetStdHandle(STD_ERROR_HANDLE, hOutput);
- freopen("CONOUT$","w+",stdout);
- freopen("CONOUT$","w+",stderr);
- } else {
- FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
- }
-
- HANDLE hSharedMemory=INVALID_HANDLE_VALUE;
- int BUF_SIZE=1024;
- char* pBuf=nullptr;
- hSharedMemory = OpenFileMappingA(
- FILE_MAP_ALL_ACCESS,
- FALSE,
- "RED_PANDA_IDE_CONSOLE_PAUSER20211223"
- );
- if (hSharedMemory != NULL)
- {
- pBuf = (char*) MapViewOfFile(hSharedMemory, // handle to map object
- FILE_MAP_ALL_ACCESS, // read/write permission
- 0,
- 0,
- BUF_SIZE);
- } else {
- printf("can't open shared memory!");
- }
-
- // Save starting timestamp
- LONGLONG starttime = GetClockTick();
-
- // Then execute said command
- DWORD returnvalue = ExecuteCommand(command,reInp);
-
- // Get ending timestamp
- LONGLONG endtime = GetClockTick();
- double seconds = (endtime - starttime) / (double)GetClockFrequency();
-
- if (pBuf) {
- strcpy(pBuf,"FINISHED");
- }
-
- // Done? Print return value of executed program
- printf("\n--------------------------------");
- printf("\nProcess exited after %.4g seconds with return value %lu\n",seconds,returnvalue);
- if (pauseAfterExit)
- PauseExit(returnvalue,reInp);
- return 0;
-}