mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
ide: Commandline handling refactored
This commit is contained in:
parent
b8272ee30d
commit
29cf8728ec
12 changed files with 87 additions and 324 deletions
|
|
@ -1,122 +0,0 @@
|
|||
#include "CommandLineHandler.h"
|
||||
|
||||
#include "About.h"
|
||||
|
||||
#include <Draw/Draw.h>
|
||||
#include <ide/Common/CommandLineOptions.h>
|
||||
#include <ide/Debuggers/GdbUtils.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
ACommandLineHandler::ACommandLineHandler(const Vector<String>& args)
|
||||
: args(clone(args))
|
||||
{}
|
||||
|
||||
BaseCommandLineHandler::BaseCommandLineHandler(const Vector<String>& args)
|
||||
: ACommandLineHandler(args)
|
||||
{}
|
||||
|
||||
bool BaseCommandLineHandler::Handle()
|
||||
{
|
||||
if(HandleVersion())
|
||||
return true;
|
||||
if(HandleHelp())
|
||||
return true;
|
||||
|
||||
if(HandleDebugBreakProcess())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BaseCommandLineHandler::HandleVersion() const
|
||||
{
|
||||
if(args.IsEmpty() || findarg(args[0], "-v", "--version") < 0)
|
||||
return false;
|
||||
|
||||
Cout() << SplashCtrl::GenerateVersionInfo(false) << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseCommandLineHandler::HandleHelp() const
|
||||
{
|
||||
if(args.IsEmpty() || findarg(args[0], "?", "--help", "-h", "-?", "/?") < 0)
|
||||
return false;
|
||||
|
||||
Cout() << "Usage:\n"
|
||||
" theide [file..] - opens given file in editor mode (Auto detection mode).\n"
|
||||
" theide [assembly] [package] - opens given package from given assembly.\n\n";
|
||||
|
||||
Cout() << "Common options:\n"
|
||||
" -f $file - opens given file in editor mode.\n"
|
||||
" -v or --version - displays information about version.\n"
|
||||
" -h or --help - displays this site.\n\n";
|
||||
|
||||
Cout() << "Advanced options:\n"
|
||||
" " << COMMAND_LINE_SCALE_OPTION << " $percent - scale interface by \"percent\" parameter.\n\n";
|
||||
|
||||
Cout() << "Internal options (Should not be called by the user):\n"
|
||||
" " << COMMAND_LINE_GDB_DEBUG_BREAK_PROCESS_OPTION << " $pid - breaks debug process represented by \"pid\".\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseCommandLineHandler::HandleDebugBreakProcess() const
|
||||
{
|
||||
if(args.GetCount() < 2 || !args[0].IsEqual(COMMAND_LINE_GDB_DEBUG_BREAK_PROCESS_OPTION))
|
||||
return false;
|
||||
|
||||
int pid = StrInt(args[1]);
|
||||
if(IsNull(pid)) {
|
||||
Cout() << "PID should be numeric value.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto utils = GdbUtilsFactory().Create();
|
||||
auto error = utils->BreakRunning(pid);
|
||||
if(!error.IsEmpty()) {
|
||||
Cout() << error << "\n";
|
||||
SetExitCode(COMMAND_LINE_GDB_DEBUG_BREAK_PROCESS_FAILURE_STATUS);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MainCommandLineHandler::MainCommandLineHandler(const Vector<String>& args)
|
||||
: ACommandLineHandler(args)
|
||||
{}
|
||||
|
||||
bool MainCommandLineHandler::Handle()
|
||||
{
|
||||
if(HandleManipulators())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainCommandLineHandler::HandleManipulators()
|
||||
{
|
||||
if(HandleScale())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainCommandLineHandler::HandleScale()
|
||||
{
|
||||
if(args.GetCount() < 2 || !args[0].IsEqual(COMMAND_LINE_SCALE_OPTION))
|
||||
return false;
|
||||
|
||||
int scale = StrInt(args[1]);
|
||||
if(IsNull(scale)) {
|
||||
Cout() << "Scale should be numeric value.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
Font::SetStdFont(StdFont().Height(GetStdFontCy() * minmax(scale, 50, 400) / 100));
|
||||
|
||||
args.Remove(0, 2);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
#ifndef _ide_Command_Line_Handler_h_
|
||||
#define _ide_Command_Line_Handler_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
|
||||
// TODO: All TheIDE command line arguments should be consume in this file.
|
||||
|
||||
namespace Upp {
|
||||
|
||||
class ACommandLineHandler {
|
||||
public:
|
||||
ACommandLineHandler(const Vector<String>& args);
|
||||
|
||||
Vector<String> GetArgs() { return clone(args); }
|
||||
|
||||
public:
|
||||
virtual bool Handle() = 0;
|
||||
|
||||
protected:
|
||||
Vector<String> args;
|
||||
};
|
||||
|
||||
class BaseCommandLineHandler final : public ACommandLineHandler {
|
||||
public:
|
||||
BaseCommandLineHandler(const Vector<String>& args);
|
||||
|
||||
public:
|
||||
bool Handle() override;
|
||||
|
||||
private:
|
||||
bool HandleVersion() const;
|
||||
bool HandleHelp() const;
|
||||
|
||||
bool HandleDebugBreakProcess() const;
|
||||
};
|
||||
|
||||
class MainCommandLineHandler final : public ACommandLineHandler {
|
||||
public:
|
||||
MainCommandLineHandler(const Vector<String>& args);
|
||||
|
||||
public:
|
||||
bool Handle() override;
|
||||
|
||||
private:
|
||||
bool HandleManipulators();
|
||||
bool HandleScale();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef _ide_Common_CommandLineDefs_h_
|
||||
#define _ide_Common_CommandLineDefs_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
|
||||
namespace Upp {
|
||||
|
||||
const String COMMAND_LINE_SCALE_OPTION = "--scale";
|
||||
const String COMMAND_LINE_GDB_DEBUG_BREAK_PROCESS_OPTION = "--gdb_debug_break_process";
|
||||
|
||||
const int COMMAND_LINE_GDB_DEBUG_BREAK_PROCESS_FAILURE_STATUS = -1;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -12,8 +12,6 @@ file
|
|||
Module.cpp,
|
||||
Util.cpp,
|
||||
common.iml,
|
||||
Defs readonly separator,
|
||||
CommandLineOptions.h,
|
||||
Info readonly separator,
|
||||
Copying;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#define DR_LOG(x) // RLOG(x)
|
||||
|
||||
#include "GdbUtils.h"
|
||||
|
||||
#include <ide/Common/Common.h>
|
||||
|
||||
#include <HexView/HexView.h>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ file
|
|||
GdbData.cpp,
|
||||
Gdb.cpp,
|
||||
GdbMem.cpp,
|
||||
GdbUtils.h,
|
||||
GdbUtils.cpp,
|
||||
PDB readonly separator,
|
||||
Pdb.h,
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ void Gdb::BreakRunning()
|
|||
{
|
||||
Logd() << METHOD_NAME << "PID: " << pid << "\n";
|
||||
|
||||
auto error = gdb_utils->BreakRunning(pid);
|
||||
auto error = BreakRunning(pid);
|
||||
if(!error.IsEmpty()) {
|
||||
Loge() << METHOD_NAME << error;
|
||||
ErrorOK(error);
|
||||
|
|
@ -693,7 +693,6 @@ void Gdb::SerializeSession(Stream& s)
|
|||
}
|
||||
|
||||
Gdb::Gdb()
|
||||
: gdb_utils(GdbUtilsFactory().Create())
|
||||
{
|
||||
auto Mem = [=](Bar& bar, ArrayCtrl& h) {
|
||||
String s = h.GetKey();
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ protected:
|
|||
String exception;
|
||||
|
||||
const int max_stack_trace_size = 400;
|
||||
|
||||
One<IGdbUtils> gdb_utils;
|
||||
|
||||
public:
|
||||
static String BreakRunning(int pid);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,80 +1,39 @@
|
|||
#include "GdbUtils.h"
|
||||
|
||||
#include <memory>
|
||||
#include <ide/Core/Logger.h>
|
||||
#include <ide/Common/CommandLineOptions.h>
|
||||
#include "Debuggers.h"
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
One<IGdbUtils> GdbUtilsFactory::Create()
|
||||
{
|
||||
#if defined(PLATFORM_WIN32)
|
||||
return MakeOne<GdbWindowsUtils>();
|
||||
#elif defined(PLATFORM_POSIX)
|
||||
return MakeOne<GdbPosixUtils>();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_WIN32)
|
||||
|
||||
#define METHOD_NAME UPP_METHOD_NAME("GdbWindowsUtils")
|
||||
|
||||
using DeleteHandleFun = std::function<void(HANDLE)>;
|
||||
|
||||
static void DeleteHandle(HANDLE handle)
|
||||
String Gdb::BreakRunning(int pid)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
|
||||
|
||||
String GdbWindowsUtils::BreakRunning(int pid)
|
||||
{
|
||||
std::unique_ptr<void, DeleteHandleFun> handle(OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid), &DeleteHandle);
|
||||
if(!handle)
|
||||
return String().Cat() << "Failed to open process associated with " << pid << " PID.";
|
||||
|
||||
if(Is64BitIde() && !Is64BitProcess(handle.get())) {
|
||||
auto path = String().Cat() << GetExeFolder() << "\\" << GetExeTitle() << "32.exe";
|
||||
auto cmd = String().Cat() << path << " " << COMMAND_LINE_GDB_DEBUG_BREAK_PROCESS_OPTION << " " << pid;
|
||||
|
||||
String out;
|
||||
if(Sys(cmd, out) == COMMAND_LINE_GDB_DEBUG_BREAK_PROCESS_FAILURE_STATUS) {
|
||||
Logd() << METHOD_NAME << cmd;
|
||||
|
||||
return String().Cat() << "Failed to interrupt process via 32-bit TheIDE. Output from command is \"" << out << "\".";
|
||||
return String() << "Failed to open process associated with " << pid << " PID.";
|
||||
|
||||
String ret;
|
||||
BOOL is_wow_64 = FALSE;
|
||||
if(IsWow64Process(handle, &is_wow_64)) {
|
||||
if(sizeof(void*) == 8 && is_wow_64) {
|
||||
String out; // NOTE: this does not work anyway as we are not distributing theide32.exe anymore
|
||||
if(Sys(GetExeFolder() << "\\" << "theide32.exe --gdb_debug_break_process=" << pid, out) < 0)
|
||||
ret = "Failed to interrupt process via 32-bit TheIDE. Output from command is \"" << out << "\".";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
else
|
||||
ret = "Failed to check that process is under wow64 emulation layer.";
|
||||
|
||||
if (!DebugBreakProcess(handle.get()))
|
||||
if(DebugBreakProcess(handle))
|
||||
return String().Cat() << "Failed to break process associated with " << pid << " PID.";
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool GdbWindowsUtils::Is64BitIde() const
|
||||
{
|
||||
return sizeof(void*) == 8;
|
||||
}
|
||||
|
||||
bool GdbWindowsUtils::Is64BitProcess(HANDLE handle) const
|
||||
{
|
||||
BOOL is_wow_64 = FALSE;
|
||||
if(!IsWow64Process(handle, &is_wow_64)) {
|
||||
Loge() << METHOD_NAME << "Failed to check that process is under wow64 emulation layer.";
|
||||
}
|
||||
|
||||
return !is_wow_64;
|
||||
}
|
||||
|
||||
#undef METHOD_NAME
|
||||
|
||||
#elif defined(PLATFORM_POSIX)
|
||||
|
||||
String GdbPosixUtils::BreakRunning(int pid)
|
||||
String Gdb::BreakRunning(int pid)
|
||||
{
|
||||
if(kill(pid, SIGINT) == -1)
|
||||
return String().Cat() << "Failed to interrupt process associated with " << pid << " PID.";
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef _ide_Debuggers_GdbUtils_h_
|
||||
#define _ide_Debuggers_GdbUtils_h_
|
||||
|
||||
#include <Core/Core.h>
|
||||
|
||||
namespace Upp {
|
||||
|
||||
class IGdbUtils {
|
||||
public:
|
||||
virtual ~IGdbUtils() = default;
|
||||
|
||||
virtual String BreakRunning(int pid) = 0;
|
||||
};
|
||||
|
||||
class GdbUtilsFactory final {
|
||||
public:
|
||||
One<IGdbUtils> Create();
|
||||
};
|
||||
|
||||
#if defined(PLATFORM_WIN32)
|
||||
|
||||
class GdbWindowsUtils final : public IGdbUtils {
|
||||
public: /* IGdbUtils */
|
||||
virtual String BreakRunning(int pid) override;
|
||||
|
||||
private:
|
||||
bool Is64BitIde() const;
|
||||
bool Is64BitProcess(HANDLE handle) const;
|
||||
};
|
||||
|
||||
#elif defined(PLATFORM_POSIX)
|
||||
|
||||
class GdbPosixUtils final : public IGdbUtils {
|
||||
public: /* IGdbUtils */
|
||||
virtual String BreakRunning(int pid) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -73,8 +73,6 @@ file
|
|||
background.cpp,
|
||||
idewin.cpp,
|
||||
main.cpp,
|
||||
CommandLineHandler.h,
|
||||
CommandLineHandler.cpp,
|
||||
About.h,
|
||||
BuildInfo.cpp,
|
||||
About.cpp,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "ide.h"
|
||||
#include "CommandLineHandler.h"
|
||||
|
||||
#define FUNCTION_NAME UPP_FUNCTION_NAME << "(): "
|
||||
|
||||
|
|
@ -108,14 +107,6 @@ void StartEditorMode(const Vector<String>& args, Ide& ide, bool& clset)
|
|||
}
|
||||
}
|
||||
|
||||
#undef GUI_APP_MAIN_HOOK
|
||||
#define GUI_APP_MAIN_HOOK \
|
||||
{ \
|
||||
BaseCommandLineHandler cmd_handler(CommandLine()); \
|
||||
if (cmd_handler.Handle()) \
|
||||
return Upp::GetExitCode(); \
|
||||
}
|
||||
|
||||
#ifdef DYNAMIC_LIBCLANG
|
||||
bool TryLoadLibClang()
|
||||
{
|
||||
|
|
@ -230,17 +221,73 @@ void AppMain___()
|
|||
SetLanguage(LNG_ENGLISH);
|
||||
SetDefaultCharset(CHARSET_UTF8);
|
||||
|
||||
MainCommandLineHandler cmd_handler(CommandLine());
|
||||
if (cmd_handler.Handle())
|
||||
return;
|
||||
auto arg = clone(cmd_handler.GetArgs());
|
||||
bool dosplash = true;
|
||||
bool debug_exe_mode = false;
|
||||
|
||||
bool debug_exe_mode = arg.GetCount() && arg[0] == "--debug";
|
||||
|
||||
Vector<String> arg = clone(CommandLine());
|
||||
|
||||
for(int i = 0; i < arg.GetCount();) {
|
||||
String ca = arg[i];
|
||||
int number = atoi(Filter(ca, CharFilterDigit));
|
||||
auto Info = [](const char *s) {
|
||||
#ifdef PLATFORM_POSIX
|
||||
Cout() << s;
|
||||
#else
|
||||
PromptOK(String() << "[C0 \1" << s); // Console output does not work in Win32 GUI apps
|
||||
#endif
|
||||
};
|
||||
if(findarg(ca, "?", "--help", "-h", "-?", "/?") >= 0) {
|
||||
Info(
|
||||
"Usage:\n"
|
||||
" theide [file..] opens given file in editor mode (Auto detection mode).\n"
|
||||
" theide [assembly] [package] opens given package from given assembly.\n\n"
|
||||
"Common options:\n"
|
||||
" -v or --version displays information about version.\n"
|
||||
" -h or --help displays this site.\n"
|
||||
" --nosplash start without showing splash window\n"
|
||||
" --scale=number scales interface by number percent.\n"
|
||||
#ifdef PLATFORM_POSIX
|
||||
" --clangdir dir specify location of libclang.so\n"
|
||||
#endif
|
||||
);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(findarg(ca, "-v", "--version") >= 0) {
|
||||
Info(SplashCtrl::GenerateVersionInfo(false) + "\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(ca == "--nosplash") {
|
||||
dosplash = false;
|
||||
arg.Remove(i);
|
||||
}
|
||||
if(ca.StartsWith("--scale=")) {
|
||||
Font::SetStdFont(StdFont().Height(GetStdFontCy() * minmax(number, 50, 400) / 100));
|
||||
arg.Remove(i);
|
||||
}
|
||||
else
|
||||
if(ca.StartsWith("--gdb_debug_break_process=")) {
|
||||
String error = Gdb::BreakRunning(number);
|
||||
if(!error.IsEmpty()) {
|
||||
Cout() << error << "\n";
|
||||
SetExitCode(-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(ca == "--debug") {
|
||||
debug_exe_mode = true;
|
||||
arg.Remove(i);
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
SetVppLogSizeLimit(200000000);
|
||||
// SetVppLogSizeLimit(2000000000); _DBG_
|
||||
|
||||
bool dosplash = true;
|
||||
if(debug_exe_mode)
|
||||
dosplash = false;
|
||||
else {
|
||||
|
|
@ -272,12 +319,6 @@ void AppMain___()
|
|||
if(!FileExists(SearchEnginesFile()))
|
||||
SearchEnginesDefaultSetup();
|
||||
|
||||
for(int i = 0; i < arg.GetCount(); i++)
|
||||
if(arg[i] == "--nosplash") {
|
||||
dosplash = false;
|
||||
arg.Remove(i);
|
||||
break;
|
||||
}
|
||||
for(int i = 0; i < arg.GetCount(); i++) {
|
||||
#ifdef PLATFORM_WIN32
|
||||
if(arg[i] == "!") {
|
||||
|
|
@ -379,12 +420,12 @@ void AppMain___()
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(arg.GetCount() == 2 && IsAssembly(arg[0])) {
|
||||
}
|
||||
else
|
||||
if(arg.GetCount() == 2 && IsAssembly(arg[0])) {
|
||||
LoadVars(arg[0]);
|
||||
ide.SetMain(arg[1]);
|
||||
clset=true;
|
||||
}
|
||||
}
|
||||
|
||||
ide.LoadAbbr();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue