Add experimental (and undocumented) --help-verbose and --help-short options.
This commit is contained in:
+52
-14
@@ -34,6 +34,7 @@ static constexpr long long initial_win32_winnt = 0;
|
||||
#include "conf.h"
|
||||
#include "compress/compress.h" // upx_ucl_version_string()
|
||||
// for list_all_packers():
|
||||
#include "filter.h" // Filter::isValidFilter
|
||||
#include "packer.h"
|
||||
#include "packmast.h" // PackMaster::visitAllPackers
|
||||
|
||||
@@ -101,48 +102,85 @@ void show_usage(void) {
|
||||
|
||||
namespace {
|
||||
struct PackerNames final {
|
||||
PackerNames() noexcept = default;
|
||||
explicit PackerNames() noexcept = default;
|
||||
~PackerNames() noexcept = default;
|
||||
|
||||
static constexpr size_t MAX_NAMES = 64;
|
||||
static constexpr size_t MAX_METHODS = 8;
|
||||
static constexpr size_t MAX_FILTERS = 16;
|
||||
struct Entry {
|
||||
const char *fname;
|
||||
const char *sname;
|
||||
size_t methods_count;
|
||||
size_t filters_count;
|
||||
unsigned methods[MAX_METHODS];
|
||||
unsigned filters[MAX_FILTERS];
|
||||
};
|
||||
static constexpr size_t MAX_NAMES = 64;
|
||||
Entry names[MAX_NAMES];
|
||||
size_t names_count = 0;
|
||||
const Options *o = nullptr;
|
||||
|
||||
void add(const PackerBase *pb) {
|
||||
assert_noexcept(names_count < MAX_NAMES);
|
||||
names[names_count].fname = pb->getFullName(o);
|
||||
names[names_count].sname = pb->getName();
|
||||
names_count++;
|
||||
Entry &e = names[names_count++];
|
||||
e.fname = pb->getFullName(o);
|
||||
e.sname = pb->getName();
|
||||
e.methods_count = e.filters_count = 0;
|
||||
for (const int *m = pb->getCompressionMethods(M_ALL, 10); *m != M_END; m++) {
|
||||
if (*m >= 0) {
|
||||
assert_noexcept(Packer::isValidCompressionMethod(*m));
|
||||
assert_noexcept(e.methods_count < MAX_METHODS);
|
||||
e.methods[e.methods_count++] = *m;
|
||||
}
|
||||
}
|
||||
for (const int *f = pb->getFilters(); f != nullptr && *f != FT_END; f++) {
|
||||
if (*f >= 0) {
|
||||
assert_noexcept(Filter::isValidFilter(*f));
|
||||
assert_noexcept(e.filters_count < MAX_FILTERS);
|
||||
e.filters[e.filters_count++] = *f;
|
||||
}
|
||||
}
|
||||
upx_gnomesort(e.methods, e.methods_count, sizeof(e.methods[0]), ne32_compare);
|
||||
upx_gnomesort(e.filters, e.filters_count, sizeof(e.filters[0]), ne32_compare);
|
||||
}
|
||||
static tribool visit(PackerBase *pb, void *user) {
|
||||
NO_fprintf(stderr, "visit %s\n", pb->getFullName(nullptr));
|
||||
PackerNames *self = (PackerNames *) user;
|
||||
self->add(pb);
|
||||
return false;
|
||||
}
|
||||
static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) {
|
||||
static int __acc_cdecl_qsort compare_fname(const void *a, const void *b) {
|
||||
return strcmp(((const Entry *) a)->fname, ((const Entry *) b)->fname);
|
||||
}
|
||||
static int __acc_cdecl_qsort cmp_sname(const void *a, const void *b) {
|
||||
static int __acc_cdecl_qsort compare_sname(const void *a, const void *b) {
|
||||
return strcmp(((const Entry *) a)->sname, ((const Entry *) b)->sname);
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static void list_all_packers(FILE *f, int verbose) {
|
||||
static noinline void list_all_packers(FILE *f, int verbose) {
|
||||
Options o;
|
||||
o.reset();
|
||||
PackerNames pn;
|
||||
pn.o = &o;
|
||||
(void) PackMaster::visitAllPackers(PackerNames::visit, nullptr, &o, &pn);
|
||||
upx_qsort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::cmp_fname);
|
||||
upx_gnomesort(pn.names, pn.names_count, sizeof(PackerNames::Entry), PackerNames::compare_fname);
|
||||
size_t pos = 0;
|
||||
for (size_t i = 0; i < pn.names_count; ++i) {
|
||||
const char *fn = pn.names[i].fname;
|
||||
const char *sn = pn.names[i].sname;
|
||||
if (verbose > 0) {
|
||||
for (size_t i = 0; i < pn.names_count; i++) {
|
||||
const PackerNames::Entry &e = pn.names[i];
|
||||
const char *const fn = e.fname;
|
||||
const char *const sn = e.sname;
|
||||
if (verbose >= 3) {
|
||||
con_fprintf(f, " %-36s %s\n", fn, sn);
|
||||
con_fprintf(f, " methods:");
|
||||
for (size_t j = 0; j < e.methods_count; j++)
|
||||
con_fprintf(f, " %#x", e.methods[j]);
|
||||
con_fprintf(f, "\n");
|
||||
con_fprintf(f, " filters:");
|
||||
for (size_t j = 0; j < e.filters_count; j++)
|
||||
con_fprintf(f, " %#x", e.filters[j]);
|
||||
con_fprintf(f, "\n");
|
||||
} else if (verbose >= 2) {
|
||||
con_fprintf(f, " %-36s %s\n", fn, sn);
|
||||
} else {
|
||||
size_t fl = strlen(fn);
|
||||
@@ -158,7 +196,7 @@ static void list_all_packers(FILE *f, int verbose) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (verbose <= 0 && pn.names_count)
|
||||
if (verbose < 2 && pn.names_count)
|
||||
con_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user