mirror of
https://github.com/Atmosphere-NX/hac2l.git
synced 2025-06-20 18:52:39 +02:00
hac2l: first pass at automatic usage print
This commit is contained in:
parent
271d1e3e34
commit
690c649efa
@ -80,10 +80,11 @@ namespace ams::hactool {
|
||||
char short_name;
|
||||
bool takes_arg;
|
||||
const char *name;
|
||||
const char *desc;
|
||||
u8 handler_storage[0x20];
|
||||
const OptionHandlerFunction &handler;
|
||||
|
||||
OptionHandler(const char *n, char sn, bool ta, auto f) : short_name(sn), takes_arg(ta), name(n), handler(*reinterpret_cast<const decltype(OptionHandlerFunction::Make(f)) *>(handler_storage)) {
|
||||
OptionHandler(const char *n, const char *d, char sn, bool ta, auto f) : short_name(sn), takes_arg(ta), name(n), desc(d), handler(*reinterpret_cast<const decltype(OptionHandlerFunction::Make(f)) *>(handler_storage)) {
|
||||
using FunctionType = decltype(OptionHandlerFunction::Make(f));
|
||||
static_assert(sizeof(this->handler_storage) >= sizeof(FunctionType));
|
||||
std::construct_at(reinterpret_cast<FunctionType *>(this->handler_storage), OptionHandlerFunction::Make(f));
|
||||
@ -93,28 +94,28 @@ namespace ams::hactool {
|
||||
template<typename T>
|
||||
concept NotCharacterOverloadHelper = !std::convertible_to<char, T>;
|
||||
|
||||
OptionHandler MakeOptionHandler(const char *s, char sn, auto f) {
|
||||
OptionHandler MakeOptionHandler(const char *s, const char *d, char sn, auto f) {
|
||||
if constexpr (requires { f(std::declval<Options &>(), std::declval<const char *>()); }) {
|
||||
if constexpr (std::convertible_to<decltype(f(std::declval<Options &>(), std::declval<const char *>())), bool>) {
|
||||
return OptionHandler(s, sn, true, f);
|
||||
return OptionHandler(s, d, sn, true, f);
|
||||
} else {
|
||||
return OptionHandler(s, sn, true, [&] (Options &options, const char *arg) -> bool { f(options, arg); return true; });
|
||||
return OptionHandler(s, d, sn, true, [&] (Options &options, const char *arg) -> bool { f(options, arg); return true; });
|
||||
}
|
||||
} else {
|
||||
if constexpr (std::convertible_to<decltype(f(std::declval<Options &>())), bool>) {
|
||||
return OptionHandler(s, sn, false, [&] (Options &options, const char *) -> bool { return f(options); });
|
||||
return OptionHandler(s, d, sn, false, [&] (Options &options, const char *) -> bool { return f(options); });
|
||||
} else {
|
||||
return OptionHandler(s, sn, false, [&] (Options &options, const char *) -> bool { f(options); return true; });
|
||||
return OptionHandler(s, d, sn, false, [&] (Options &options, const char *) -> bool { f(options); return true; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OptionHandler MakeOptionHandler(const char *s, NotCharacterOverloadHelper auto f) {
|
||||
return MakeOptionHandler(s, 0, f);
|
||||
OptionHandler MakeOptionHandler(const char *s, const char *d, NotCharacterOverloadHelper auto f) {
|
||||
return MakeOptionHandler(s, d, 0, f);
|
||||
}
|
||||
|
||||
const OptionHandler OptionHandlers[] = {
|
||||
MakeOptionHandler("intype", 't', [] (Options &options, const char *arg) {
|
||||
MakeOptionHandler("intype", "Specify input file type [nca, xci, pfs or pfs0 or nsp, appfs, npdm]", 't', [] (Options &options, const char *arg) {
|
||||
if (std::strcmp(arg, "npdm") == 0) {
|
||||
options.file_type = FileType::Npdm;
|
||||
} else if (std::strcmp(arg, "nca") == 0) {
|
||||
@ -131,58 +132,82 @@ namespace ams::hactool {
|
||||
|
||||
return true;
|
||||
}),
|
||||
MakeOptionHandler("dev", 'd', [] (Options &options) { options.dev = true; }),
|
||||
MakeOptionHandler("verify", 'y', [] (Options &options) { options.verify = true; }),
|
||||
MakeOptionHandler("raw", 'r', [] (Options &options) { options.raw = true; }),
|
||||
MakeOptionHandler("enablehash", 'h', [] (Options &options) { options.enable_hash = true; }),
|
||||
MakeOptionHandler("disablekeywarns", [] (Options &options) { options.disable_key_warns = true; }),
|
||||
MakeOptionHandler("onlyupdated", [] (Options &options) { options.only_updated = true; }),
|
||||
MakeOptionHandler("keyset", 'k', [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.key_file_path), arg); }),
|
||||
MakeOptionHandler("titlekeys", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.titlekey_path), arg); }),
|
||||
MakeOptionHandler("consolekeys", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.consolekey_path), arg); }),
|
||||
MakeOptionHandler("section0", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[0]), arg); }),
|
||||
MakeOptionHandler("section1", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[1]), arg); }),
|
||||
MakeOptionHandler("section2", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[2]), arg); }),
|
||||
MakeOptionHandler("section3", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[3]), arg); }),
|
||||
MakeOptionHandler("section0dir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[0]), arg); }),
|
||||
MakeOptionHandler("section1dir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[1]), arg); }),
|
||||
MakeOptionHandler("section2dir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[2]), arg); }),
|
||||
MakeOptionHandler("section3dir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[3]), arg); }),
|
||||
MakeOptionHandler("header", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.header_out_path), arg); }),
|
||||
MakeOptionHandler("exefs", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.exefs_out_file_path), arg); }),
|
||||
MakeOptionHandler("romfs", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.romfs_out_file_path), arg); }),
|
||||
MakeOptionHandler("exefsdir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.exefs_out_dir_path), arg); }),
|
||||
MakeOptionHandler("romfsdir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.romfs_out_dir_path), arg); }),
|
||||
MakeOptionHandler("outdir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.default_out_dir_path), arg); }),
|
||||
MakeOptionHandler("outfile", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.default_out_file_path), arg); }),
|
||||
MakeOptionHandler("plaintext", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.plaintext_out_path), arg); }),
|
||||
MakeOptionHandler("ciphertext", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.ciphertext_out_path), arg); }),
|
||||
MakeOptionHandler("json", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.json_out_file_path), arg); }),
|
||||
MakeOptionHandler("rootdir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.root_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("securedir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.secure_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("normaldir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.normal_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("updatedir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.update_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("logodir", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.logo_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("basenca", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_nca_path), arg); }),
|
||||
MakeOptionHandler("basexci", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_xci_path), arg); }),
|
||||
MakeOptionHandler("basepfs", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_pfs_path), arg); }),
|
||||
MakeOptionHandler("basensp", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_pfs_path), arg); }),
|
||||
MakeOptionHandler("baseappfs", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_appfs_path), arg); }),
|
||||
MakeOptionHandler("listromfs", [] (Options &options) { options.list_romfs = true; }),
|
||||
MakeOptionHandler("listupdate", [] (Options &options) { options.list_update = true; }),
|
||||
MakeOptionHandler("appindex", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.preferred_app_index), arg); }),
|
||||
MakeOptionHandler("programindex", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.preferred_program_index), arg); }),
|
||||
MakeOptionHandler("appversion", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.preferred_version), arg); }),
|
||||
MakeOptionHandler("updatedsince", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.updated_generation), arg); }),
|
||||
MakeOptionHandler("raw", "Keep raw data, don't unpack.", 'r', [] (Options &options) { options.raw = true; }),
|
||||
MakeOptionHandler("verify", "Verify hashes and signatures.", 'y', [] (Options &options) { options.verify = true; }),
|
||||
MakeOptionHandler("dev", "Decrypt with development keys instead of retail.", 'd', [] (Options &options) { options.dev = true; }),
|
||||
MakeOptionHandler("enablehash", "Enable hash enforcement.", 'h', [] (Options &options) { options.enable_hash = true; }),
|
||||
MakeOptionHandler("disablekeywarns", "Disable warning output when loading external keys.", [] (Options &options) { options.disable_key_warns = true; }),
|
||||
MakeOptionHandler("keyset", "Load keys from an external file.", 'k', [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.key_file_path), arg); }),
|
||||
MakeOptionHandler("titlekeys", "Load title keys from an external file.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.titlekey_path), arg); }),
|
||||
MakeOptionHandler("consolekeys","Load console-specific keys from an external file.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.consolekey_path), arg); }),
|
||||
MakeOptionHandler("outdir", "Specify output directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.default_out_dir_path), arg); }),
|
||||
MakeOptionHandler("outfile", "Specify output file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.default_out_file_path), arg); }),
|
||||
MakeOptionHandler("basenca", "Specify a base nca to use when processing.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_nca_path), arg); }),
|
||||
MakeOptionHandler("basexci", "Specify a base xci to use when processing.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_xci_path), arg); }),
|
||||
MakeOptionHandler("basepfs", "Specify a base pfs to use when processing.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_pfs_path), arg); }),
|
||||
MakeOptionHandler("basensp", "Specify a base nsp to use when processing. Synonym for basepfs.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_pfs_path), arg); }),
|
||||
MakeOptionHandler("baseappfs", "Specify a base appfs to use when processing.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.base_appfs_path), arg); }),
|
||||
MakeOptionHandler("appindex", "[appfs] Specify a preferred application index.", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.preferred_app_index), arg); }),
|
||||
MakeOptionHandler("programindex", "[appfs] Specify a preferred program index.", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.preferred_program_index), arg); }),
|
||||
MakeOptionHandler("appversion", "[appfs] Specify a preferred application version.", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.preferred_version), arg); }),
|
||||
MakeOptionHandler("header", "[nca] Specify header file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.header_out_path), arg); }),
|
||||
MakeOptionHandler("plaintext", "[nca] Specify plaintext output path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.plaintext_out_path), arg); }),
|
||||
MakeOptionHandler("exefs", "[nca] Specify exefs file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.exefs_out_file_path), arg); }),
|
||||
MakeOptionHandler("romfs", "[nca] Specify romfs file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.romfs_out_file_path), arg); }),
|
||||
MakeOptionHandler("exefsdir", "[nca] Specify exefs directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.exefs_out_dir_path), arg); }),
|
||||
MakeOptionHandler("romfsdir", "[nca] Specify romfs file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.romfs_out_dir_path), arg); }),
|
||||
MakeOptionHandler("listromfs", "[nca/romfs] List files in romfs.", [] (Options &options) { options.list_romfs = true; }),
|
||||
MakeOptionHandler("section0", "[nca] Specify Section 0 file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[0]), arg); }),
|
||||
MakeOptionHandler("section1", "[nca] Specify Section 1 file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[1]), arg); }),
|
||||
MakeOptionHandler("section2", "[nca] Specify Section 2 file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[2]), arg); }),
|
||||
MakeOptionHandler("section3", "[nca] Specify Section 3 file path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_file_paths[3]), arg); }),
|
||||
MakeOptionHandler("section0dir", "[nca] Specify Section 0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[0]), arg); }),
|
||||
MakeOptionHandler("section1dir", "[nca] Specify Section 1 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[1]), arg); }),
|
||||
MakeOptionHandler("section2dir", "[nca] Specify Section 2 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[2]), arg); }),
|
||||
MakeOptionHandler("section3dir", "[nca] Specify Section 3 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.section_out_dir_paths[3]), arg); }),
|
||||
MakeOptionHandler("listupdate", "[nca] List update details.", [] (Options &options) { options.list_update = true; }),
|
||||
MakeOptionHandler("onlyupdated", "[nca] Ignore non-updated files in update partitions.", [] (Options &options) { options.only_updated = true; }),
|
||||
MakeOptionHandler("updatedsince", "[nca] Ignore files updated prior to a specific update generation.", [] (Options &options, const char *arg) { return ParseIntegerArgument(std::addressof(options.updated_generation), arg); }),
|
||||
MakeOptionHandler("json", "[nca/exefs/npdm/kip] Specify file path for saving JSON representation of program permissions.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.json_out_file_path), arg); }),
|
||||
MakeOptionHandler("rootdir", "[xci] Specify xci root hfs0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.root_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("securedir", "[xci] Specify xci secure hfs0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.secure_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("normaldir", "[xci] Specify xci normal hfs0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.normal_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("updatedir", "[xci] Specify xci update hfs0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.update_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("logodir", "[xci] Specify xci logo hfs0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.logo_partition_out_dir), arg); }),
|
||||
MakeOptionHandler("ciphertext", "[unused] Specify ciphertext output path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.ciphertext_out_path), arg); }),
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void PrintUsage() {
|
||||
printf("hac2l (c) SciresM/Atmosphere-NX\n");
|
||||
printf("Built: %s %s\n", __TIME__, __DATE__);
|
||||
printf("\n");
|
||||
printf("Usage: hac2l [options...] path\n");
|
||||
printf("Full usage print remains TODO\n");
|
||||
printf("Options:\n");
|
||||
for (const auto &o : OptionHandlers) {
|
||||
printf(" ");
|
||||
size_t len = 2;
|
||||
if (o.short_name) {
|
||||
printf("-%c, ", o.short_name);
|
||||
len += 4;
|
||||
}
|
||||
if (o.takes_arg) {
|
||||
printf("--%s=* ", o.name);
|
||||
len += 5 + std::strlen(o.name);
|
||||
} else {
|
||||
printf("--%s ", o.name);
|
||||
len += 3 + std::strlen(o.name);
|
||||
}
|
||||
|
||||
{
|
||||
char pad[0x20] = {};
|
||||
memset(pad, ' ', 0x18 - len);
|
||||
printf("%s", pad);
|
||||
}
|
||||
|
||||
printf("%s\n", o.desc);
|
||||
}
|
||||
}
|
||||
|
||||
const char *GetKeysFilePath(const char *fn) {
|
||||
|
Loading…
Reference in New Issue
Block a user