feat: Added --plugin, --calc, --hash, --encode and --decode subcommands
This commit is contained in:
parent
1588365d4a
commit
e9450b490f
@ -55,7 +55,7 @@ namespace hex::subcommands {
|
||||
if (arg == "--othercmd") {
|
||||
// save command to run
|
||||
if (currentSubCommand) {
|
||||
subCommands.push_back({*currentSubCommand, currentSubCommandArgs});
|
||||
subCommands.emplace_back(*currentSubCommand, currentSubCommandArgs);
|
||||
}
|
||||
|
||||
currentSubCommand = std::nullopt;
|
||||
@ -78,7 +78,7 @@ namespace hex::subcommands {
|
||||
|
||||
// save last command to run
|
||||
if (currentSubCommand) {
|
||||
subCommands.push_back({*currentSubCommand, currentSubCommandArgs});
|
||||
subCommands.emplace_back(*currentSubCommand, currentSubCommandArgs);
|
||||
}
|
||||
|
||||
// run the subcommands
|
||||
|
@ -30,9 +30,6 @@ void loadPlugins() {
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
Window::initNative();
|
||||
|
||||
log::info("Welcome to ImHex {}!", ImHexApi::System::getImHexVersion());
|
||||
log::info("Compiled using commit {}@{}", ImHexApi::System::getCommitBranch(), ImHexApi::System::getCommitHash());
|
||||
|
||||
hex::crash::setupCrashHandlers();
|
||||
hex::unused(envp);
|
||||
|
||||
@ -43,6 +40,10 @@ int main(int argc, char **argv, char **envp) {
|
||||
hex::messaging::setupMessaging();
|
||||
hex::subcommands::processArguments(args);
|
||||
|
||||
log::info("Welcome to ImHex {}!", ImHexApi::System::getImHexVersion());
|
||||
log::info("Compiled using commit {}@{}", ImHexApi::System::getCommitBranch(), ImHexApi::System::getCommitHash());
|
||||
|
||||
|
||||
// Check if ImHex is installed in portable mode
|
||||
{
|
||||
if (const auto executablePath = wolv::io::fs::getExecutablePath(); executablePath.has_value()) {
|
||||
|
@ -8,6 +8,7 @@ add_library(${PROJECT_NAME} SHARED
|
||||
|
||||
source/content/background_services.cpp
|
||||
source/content/command_palette_commands.cpp
|
||||
source/content/command_line_interface.cpp
|
||||
source/content/communication_interface.cpp
|
||||
source/content/data_inspector.cpp
|
||||
source/content/pl_builtin_functions.cpp
|
||||
|
22
plugins/builtin/include/content/command_line_interface.hpp
Normal file
22
plugins/builtin/include/content/command_line_interface.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void handleVersionCommand(const std::vector<std::string> &args);
|
||||
void handleHelpCommand(const std::vector<std::string> &args);
|
||||
void handlePluginsCommand(const std::vector<std::string> &args);
|
||||
|
||||
void handleOpenCommand(const std::vector<std::string> &args);
|
||||
|
||||
void handleCalcCommand(const std::vector<std::string> &args);
|
||||
void handleHashCommand(const std::vector<std::string> &args);
|
||||
void handleEncodeCommand(const std::vector<std::string> &args);
|
||||
void handleDecodeCommand(const std::vector<std::string> &args);
|
||||
|
||||
|
||||
void registerCommandForwarders();
|
||||
|
||||
}
|
224
plugins/builtin/source/content/command_line_interface.cpp
Normal file
224
plugins/builtin/source/content/command_line_interface.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
#include "content/command_line_interface.hpp"
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
#include <romfs/romfs.hpp>
|
||||
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
#include <hex/subcommands/subcommands.hpp>
|
||||
|
||||
#include <wolv/utils/string.hpp>
|
||||
|
||||
#include "content/helpers/math_evaluator.hpp"
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void handleVersionCommand(const std::vector<std::string> &args) {
|
||||
hex::unused(args);
|
||||
|
||||
hex::print(romfs::get("logo.ans").string(),
|
||||
ImHexApi::System::getImHexVersion(),
|
||||
ImHexApi::System::getCommitBranch(), ImHexApi::System::getCommitHash(),
|
||||
__DATE__, __TIME__,
|
||||
ImHexApi::System::isPortableVersion() ? "Portable" : "Installed");
|
||||
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void handleHelpCommand(const std::vector<std::string> &args) {
|
||||
hex::unused(args);
|
||||
|
||||
hex::print(
|
||||
"ImHex - A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.\n"
|
||||
"\n"
|
||||
"usage: imhex [subcommand] [options]\n"
|
||||
"Available subcommands:\n"
|
||||
);
|
||||
|
||||
size_t longestCommand = 0;
|
||||
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||
for (const auto &subCommand : plugin.getSubCommands()) {
|
||||
longestCommand = std::max(longestCommand, subCommand.commandKey.size());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||
for (const auto &subCommand : plugin.getSubCommands()) {
|
||||
hex::print(" --{}{: <{}} {}\n", subCommand.commandKey, "", longestCommand - subCommand.commandKey.size(), subCommand.commandDesc);
|
||||
}
|
||||
}
|
||||
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void handleOpenCommand(const std::vector<std::string> &args) {
|
||||
if (args.empty()) {
|
||||
hex::print("No files provided to open.");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::vector<std::string> fullPaths;
|
||||
bool doubleDashFound = false;
|
||||
for (auto &arg : args) {
|
||||
|
||||
// Skip the first argument named `--`
|
||||
if (arg == "--" && !doubleDashFound) {
|
||||
doubleDashFound = true;
|
||||
} else {
|
||||
auto path = std::filesystem::weakly_canonical(arg);
|
||||
fullPaths.push_back(wolv::util::toUTF8String(path));
|
||||
}
|
||||
}
|
||||
|
||||
hex::subcommands::forwardSubCommand("open", fullPaths);
|
||||
}
|
||||
|
||||
void handleCalcCommand(const std::vector<std::string> &args) {
|
||||
if (args.empty()) {
|
||||
hex::print("No expression provided!");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
MathEvaluator<long double> evaluator;
|
||||
|
||||
auto input = hex::format("{}", fmt::join(args, " "));
|
||||
auto result = evaluator.evaluate(input);
|
||||
|
||||
if (!result.has_value())
|
||||
hex::print("{}\n> '{}'", evaluator.getLastError().value(), input);
|
||||
else
|
||||
hex::print("{}", result.value());
|
||||
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void handlePluginsCommand(const std::vector<std::string> &args) {
|
||||
hex::unused(args);
|
||||
|
||||
hex::print("Loaded plugins:\n");
|
||||
|
||||
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||
hex::print("- ");
|
||||
|
||||
if (plugin.isBuiltinPlugin())
|
||||
hex::print("{}", fmt::styled(plugin.getPluginName(), fmt::emphasis::bold | fmt::bg(fmt::terminal_color::yellow)));
|
||||
else
|
||||
hex::print("{}", fmt::styled(plugin.getPluginName(), fmt::emphasis::bold));
|
||||
|
||||
hex::print(" by {}\n", plugin.getPluginAuthor());
|
||||
|
||||
hex::print(" {}\n", fmt::styled(plugin.getPluginDescription(), fmt::emphasis::italic | fmt::emphasis::faint));
|
||||
}
|
||||
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void handleHashCommand(const std::vector<std::string> &args) {
|
||||
if (args.size() != 2) {
|
||||
hex::print("usage: imhex --hash <algorithm> <file>");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
const auto &algorithm = args[0];
|
||||
const auto &filePath = std::fs::path(args[1]);
|
||||
|
||||
wolv::io::File file(filePath, wolv::io::File::Mode::Read);
|
||||
if (!file.isValid()) {
|
||||
hex::print("Failed to open file: {}", wolv::util::toUTF8String(filePath));
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
constexpr static auto toVector = [](const auto &data) {
|
||||
return std::vector<u8>(data.begin(), data.end());
|
||||
};
|
||||
|
||||
std::vector<u8> result;
|
||||
if (algorithm == "md5") {
|
||||
result = toVector(hex::crypt::md5(file.readVector()));
|
||||
} else if (algorithm == "sha1") {
|
||||
result = toVector(hex::crypt::sha1(file.readVector()));
|
||||
} else if (algorithm == "sha224") {
|
||||
result = toVector(hex::crypt::sha224(file.readVector()));
|
||||
} else if (algorithm == "sha256") {
|
||||
result = toVector(hex::crypt::sha256(file.readVector()));
|
||||
} else if (algorithm == "sha384") {
|
||||
result = toVector(hex::crypt::sha384(file.readVector()));
|
||||
} else if (algorithm == "sha512") {
|
||||
result = toVector(hex::crypt::sha512(file.readVector()));
|
||||
} else {
|
||||
hex::print("Unknown algorithm: {}", algorithm);
|
||||
hex::print("Available algorithms: md5, sha1, sha224, sha256, sha384, sha512");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hex::print("{}({}) = {}", algorithm, wolv::util::toUTF8String(filePath.filename()), hex::crypt::encode16(result));
|
||||
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void handleEncodeCommand(const std::vector<std::string> &args) {
|
||||
if (args.size() != 2) {
|
||||
hex::print("usage: imhex --encode <algorithm> <string>");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
const auto &algorithm = args[0];
|
||||
const auto &data = std::vector<u8>(args[1].begin(), args[1].end());
|
||||
|
||||
std::string result;
|
||||
if (algorithm == "base64") {
|
||||
auto base64 = hex::crypt::encode64(data);
|
||||
result = std::string(base64.begin(), base64.end());
|
||||
} else if (algorithm == "hex") {
|
||||
result = hex::crypt::encode16(data);
|
||||
} else {
|
||||
hex::print("Unknown algorithm: {}", algorithm);
|
||||
hex::print("Available algorithms: base64, hex");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hex::print("encode_{}({}) = {}", algorithm, args[1], result);
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void handleDecodeCommand(const std::vector<std::string> &args) {
|
||||
if (args.size() != 2) {
|
||||
hex::print("usage: imhex --decode <algorithm> <string>");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
const auto &algorithm = args[0];
|
||||
const auto &data = std::vector<u8>(args[1].begin(), args[1].end());
|
||||
|
||||
std::string result;
|
||||
if (algorithm == "base64") {
|
||||
auto base64 = hex::crypt::decode64(data);
|
||||
result = std::string(base64.begin(), base64.end());
|
||||
} else if (algorithm == "hex") {
|
||||
auto base16 = hex::crypt::decode16(std::string(data.begin(), data.end()));
|
||||
result = std::string(base16.begin(), base16.end());
|
||||
} else {
|
||||
hex::print("Unknown algorithm: {}", algorithm);
|
||||
hex::print("Available algorithms: base64, hex");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hex::print("decode_{}({}) = {}", algorithm, args[1], result);
|
||||
std::exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
void registerCommandForwarders() {
|
||||
hex::subcommands::registerSubCommand("open", [](const std::vector<std::string> &args){
|
||||
for (auto &arg : args) {
|
||||
EventManager::post<RequestOpenFile>(arg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
#include <hex/plugin.hpp>
|
||||
#include <hex/subcommands/subcommands.hpp>
|
||||
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/subcommands/subcommands.hpp>
|
||||
|
||||
#include <romfs/romfs.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "content/command_line_interface.hpp"
|
||||
|
||||
using namespace hex;
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
@ -45,67 +46,19 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void handleBorderlessWindowMode();
|
||||
|
||||
void handleSubCommands();
|
||||
|
||||
}
|
||||
|
||||
IMHEX_PLUGIN_SUBCOMMANDS() {
|
||||
{ "version", "Print ImHex version and exit", [](const std::vector<std::string>&) {
|
||||
hex::print(romfs::get("logo.ans").string(),
|
||||
ImHexApi::System::getImHexVersion(),
|
||||
ImHexApi::System::getCommitBranch(), ImHexApi::System::getCommitHash(),
|
||||
__DATE__, __TIME__,
|
||||
ImHexApi::System::isPortableVersion() ? "Portable" : "Installed");
|
||||
{ "help", "Print help about this command", hex::plugin::builtin::handleHelpCommand },
|
||||
{ "version", "Print ImHex version", hex::plugin::builtin::handleVersionCommand },
|
||||
{ "plugins", "Lists all plugins that have been installed", hex::plugin::builtin::handlePluginsCommand },
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}},
|
||||
{ "help", "Print help about this command and exit", [](const std::vector<std::string>&) {
|
||||
hex::print(
|
||||
"ImHex - A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.\n"
|
||||
"\n"
|
||||
"usage: imhex [subcommand] [options]\n"
|
||||
"Available subcommands:\n"
|
||||
);
|
||||
{ "open", "Open files passed as argument. [default]", hex::plugin::builtin::handleOpenCommand },
|
||||
|
||||
size_t longestCommand = 0;
|
||||
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||
for (const auto &subCommand : plugin.getSubCommands()) {
|
||||
longestCommand = std::max(longestCommand, subCommand.commandKey.size());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &plugin : PluginManager::getPlugins()) {
|
||||
for (const auto &subCommand : plugin.getSubCommands()) {
|
||||
hex::print(" --{}{: <{}} {}\n", subCommand.commandKey, "", longestCommand - subCommand.commandKey.size(), subCommand.commandDesc);
|
||||
}
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}},
|
||||
{ "open", "Open files passed as argument. This is the default subcommand is none is entered",
|
||||
[](const std::vector<std::string> &args) {
|
||||
|
||||
hex::subcommands::registerSubCommand("open", [](const std::vector<std::string> &args){
|
||||
for (auto &arg : args) {
|
||||
EventManager::post<RequestOpenFile>(arg);
|
||||
}
|
||||
});
|
||||
|
||||
std::vector<std::string> fullPaths;
|
||||
bool doubleDashFound = false;
|
||||
for (auto &arg : args) {
|
||||
|
||||
// Skip the first argument named `--`
|
||||
if (arg == "--" && !doubleDashFound) {
|
||||
doubleDashFound = true;
|
||||
} else {
|
||||
auto path = std::filesystem::weakly_canonical(arg);
|
||||
fullPaths.push_back(wolv::util::toUTF8String(path));
|
||||
}
|
||||
}
|
||||
|
||||
hex::subcommands::forwardSubCommand("open", fullPaths);
|
||||
}}
|
||||
{ "calc", "Evaluate a mathematical expression", hex::plugin::builtin::handleCalcCommand },
|
||||
{ "hash", "Calculate the hash of a file", hex::plugin::builtin::handleHashCommand },
|
||||
{ "encode", "Encode a string", hex::plugin::builtin::handleEncodeCommand },
|
||||
{ "decode", "Decode a string", hex::plugin::builtin::handleDecodeCommand },
|
||||
};
|
||||
|
||||
IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
@ -140,6 +93,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
registerNetworkEndpoints();
|
||||
registerFileHandlers();
|
||||
registerProjectHandlers();
|
||||
registerCommandForwarders();
|
||||
|
||||
addFooterItems();
|
||||
addTitleBarButtons();
|
||||
|
Loading…
x
Reference in New Issue
Block a user