mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Add experimental (and undocumented) --help-verbose and --help-short options.
This commit is contained in:
parent
eb3c55b5cb
commit
9d26713b1a
|
@ -436,9 +436,13 @@ include(CTest)
|
|||
if(NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
|
||||
add_test(NAME upx-version COMMAND upx --version)
|
||||
add_test(NAME upx-version-short COMMAND upx --version-short)
|
||||
add_test(NAME upx-help COMMAND upx --help)
|
||||
add_test(NAME upx-license COMMAND upx --license)
|
||||
add_test(NAME upx-sysinfo COMMAND upx --sysinfo -v)
|
||||
add_test(NAME upx-help-1 COMMAND upx --help)
|
||||
add_test(NAME upx-help-2 COMMAND upx --help-short)
|
||||
add_test(NAME upx-help-3 COMMAND upx --help-verbose)
|
||||
add_test(NAME upx-sysinfo-1 COMMAND upx --sysinfo)
|
||||
add_test(NAME upx-sysinfo-2 COMMAND upx --sysinfo -v)
|
||||
add_test(NAME upx-sysinfo-3 COMMAND upx --sysinfo -vv)
|
||||
if(NOT UPX_CONFIG_DISABLE_SELF_PACK_TEST)
|
||||
# IMPORTANT NOTE: these tests can only work if the host executable format is supported by UPX!
|
||||
set(emu "")
|
||||
|
|
|
@ -25,6 +25,7 @@ if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
|||
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||
[[ -f $upx_exe ]] || exit 1
|
||||
|
||||
# set emu and run_upx
|
||||
emu=()
|
||||
if [[ -n $upx_exe_runner ]]; then
|
||||
|
@ -67,9 +68,13 @@ export UPX="--no-color --no-progress"
|
|||
|
||||
"${run_upx[@]}" --version
|
||||
"${run_upx[@]}" --version-short
|
||||
"${run_upx[@]}" --help
|
||||
"${run_upx[@]}" --license
|
||||
"${run_upx[@]}" --help
|
||||
"${run_upx[@]}" --help-short
|
||||
"${run_upx[@]}" --help-verbose
|
||||
"${run_upx[@]}" --sysinfo
|
||||
"${run_upx[@]}" --sysinfo -v
|
||||
"${run_upx[@]}" --sysinfo -vv
|
||||
|
||||
if [[ $UPX_CONFIG_DISABLE_SELF_PACK_TEST == ON ]]; then
|
||||
echo "Self-pack test disabled. All done."; exit 0
|
||||
|
|
|
@ -40,6 +40,7 @@ if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
|||
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||
[[ -f $upx_exe ]] || exit 1
|
||||
|
||||
# set emu and run_upx
|
||||
emu=()
|
||||
if [[ -n $upx_exe_runner ]]; then
|
||||
|
|
|
@ -29,6 +29,7 @@ if [[ -z $upx_exe ]]; then echo "UPX-ERROR: please set \$upx_exe"; exit 1; fi
|
|||
if [[ ! -f $upx_exe ]]; then echo "UPX-ERROR: file '$upx_exe' does not exist"; exit 1; fi
|
||||
upx_exe=$(readlink -fn "$upx_exe") # make absolute
|
||||
[[ -f $upx_exe ]] || exit 1
|
||||
|
||||
# set emu and run_upx
|
||||
emu=()
|
||||
if [[ -n $upx_exe_runner ]]; then
|
||||
|
@ -43,7 +44,7 @@ fi
|
|||
run_upx=( "${emu[@]}" "$upx_exe" )
|
||||
echo "run_upx='${run_upx[*]}'"
|
||||
|
||||
# run_upx sanity check, part1
|
||||
# run_upx sanity check
|
||||
if ! "${run_upx[@]}" --version-short >/dev/null; then echo "UPX-ERROR: FATAL: upx --version-short FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||
|
@ -75,19 +76,30 @@ fi
|
|||
mkdir -p "$upx_testsuite_BUILDDIR" || exit 1
|
||||
upx_testsuite_BUILDDIR=$(readlink -fn "$upx_testsuite_BUILDDIR") # make absolute
|
||||
[[ -d $upx_testsuite_BUILDDIR ]] || exit 1
|
||||
|
||||
cd / && cd "$upx_testsuite_BUILDDIR" || exit 1
|
||||
: > ./.mfxnobackup
|
||||
|
||||
# run_upx sanity check, part2
|
||||
# run_upx sanity check after "cd"
|
||||
if ! "${run_upx[@]}" --version-short >/dev/null; then
|
||||
echo "UPX-ERROR: FATAL: upx --version-short FAILED"
|
||||
echo "please make sure that \$upx_exe contains ABSOLUTE file paths and can be run from any directory"
|
||||
echo "INFO: run_upx='${run_upx[*]}'"
|
||||
exit 1
|
||||
fi
|
||||
if ! "${run_upx[@]}" -L >/dev/null 2>&1; then echo "UPX-ERROR: FATAL: upx -L FAILED"; exit 1; fi
|
||||
if ! "${run_upx[@]}" --help >/dev/null; then echo "UPX-ERROR: FATAL: upx --help FAILED"; exit 1; fi
|
||||
|
||||
#***********************************************************************
|
||||
# setup
|
||||
#***********************************************************************
|
||||
|
||||
#set -x # debug
|
||||
|
||||
exit_code=0
|
||||
num_errors=0
|
||||
all_errors=
|
||||
|
||||
export UPX="--prefer-ucl --no-color --no-progress"
|
||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
||||
|
||||
case $UPX_TESTSUITE_LEVEL in
|
||||
[0-8]) ;;
|
||||
|
@ -98,19 +110,6 @@ if [[ $UPX_TESTSUITE_LEVEL == 0 ]]; then
|
|||
exit 0
|
||||
fi
|
||||
|
||||
#***********************************************************************
|
||||
# setup
|
||||
#***********************************************************************
|
||||
|
||||
#set -x # debug
|
||||
exit_code=0
|
||||
num_errors=0
|
||||
all_errors=
|
||||
|
||||
export UPX="--prefer-ucl --no-color --no-progress"
|
||||
export UPX_DEBUG_DISABLE_GITREV_WARNING=1
|
||||
export UPX_DEBUG_DOCTEST_VERBOSE=0
|
||||
|
||||
rm -rf ./testsuite_1
|
||||
mkdir testsuite_1 || exit 1
|
||||
cd testsuite_1 || exit 1
|
||||
|
|
|
@ -822,7 +822,7 @@ int do_files(int i, int argc, char *argv[]) may_throw;
|
|||
// help.cpp
|
||||
extern const char gitrev[];
|
||||
void show_header();
|
||||
void show_help(int verbose = 0);
|
||||
void show_help(int verbose);
|
||||
void show_license();
|
||||
void show_sysinfo(const char *options_var);
|
||||
void show_usage();
|
||||
|
|
66
src/help.cpp
66
src/help.cpp
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
15
src/main.cpp
15
src/main.cpp
|
@ -218,7 +218,7 @@ static void check_and_update_options(int i, int argc) {
|
|||
**************************************************************************/
|
||||
|
||||
static void e_help(void) {
|
||||
show_help();
|
||||
show_help(0);
|
||||
e_exit(EXIT_USAGE);
|
||||
}
|
||||
|
||||
|
@ -386,6 +386,8 @@ static int do_option(int optc, const char *arg) {
|
|||
set_cmd(CMD_HELP);
|
||||
break;
|
||||
case 'h' + 256:
|
||||
case 996:
|
||||
case 997:
|
||||
#if 1
|
||||
if (!acc_isatty(STDOUT_FILENO)) {
|
||||
/* according to GNU standards */
|
||||
|
@ -393,7 +395,7 @@ static int do_option(int optc, const char *arg) {
|
|||
opt->console = CON_FILE;
|
||||
}
|
||||
#endif
|
||||
show_help(1);
|
||||
show_help(optc == 996 ? 1 : (optc == 997 ? 3 : 2));
|
||||
e_exit(EXIT_OK);
|
||||
break;
|
||||
case 'i':
|
||||
|
@ -1172,9 +1174,14 @@ static void first_options(int argc, char **argv) {
|
|||
if (strcmp(argv[i], "--version-short") == 0)
|
||||
do_option(998, argv[i]);
|
||||
}
|
||||
for (i = 1; i < n; i++)
|
||||
for (i = 1; i < n; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0)
|
||||
do_option('h' + 256, argv[i]);
|
||||
if (strcmp(argv[i], "--help-short") == 0) // undocumented and subject to change
|
||||
do_option(996, argv[i]);
|
||||
if (strcmp(argv[i], "--help-verbose") == 0) // undocumented and subject to change
|
||||
do_option(997, argv[i]);
|
||||
}
|
||||
for (i = 1; i < n; i++)
|
||||
if (strcmp(argv[i], "--no-env") == 0)
|
||||
do_option(519, argv[i]);
|
||||
|
@ -1272,7 +1279,7 @@ int upx_main(int argc, char *argv[]) may_throw {
|
|||
e_exit(EXIT_OK);
|
||||
break;
|
||||
case CMD_HELP:
|
||||
show_help(1);
|
||||
show_help(2);
|
||||
e_exit(EXIT_OK);
|
||||
break;
|
||||
case CMD_LICENSE:
|
||||
|
|
|
@ -58,8 +58,10 @@ void Packer::assertPacker() const {
|
|||
assert(getVersion() <= 14);
|
||||
assert(strlen(getName()) <= 15);
|
||||
// info: 36 is the limit for show_all_packers() in help.cpp, but 32 should be enough
|
||||
assert(strlen(getFullName(opt)) <= 32);
|
||||
assert(strlen(getFullName(nullptr)) <= 32);
|
||||
assert(strlen(getFullName(opt)) <= 32);
|
||||
assert(getCompressionMethods(M_ALL, 10) != nullptr);
|
||||
(void) getFilters();
|
||||
if (bele == nullptr)
|
||||
fprintf(stderr, "%s\n", getName());
|
||||
assert(bele != nullptr);
|
||||
|
|
|
@ -293,13 +293,13 @@ static inline void memswap_no_overlap(byte *a, byte *b, size_t bytes) noexcept {
|
|||
upx_memswap(a, b, bytes);
|
||||
#else // clang bug
|
||||
upx_alignas_max byte tmp_buf[16];
|
||||
#define SWAP(x) \
|
||||
#define SWAP(n) \
|
||||
do { \
|
||||
upx_memcpy_inline(tmp_buf, a, x); \
|
||||
upx_memcpy_inline(a, b, x); \
|
||||
upx_memcpy_inline(b, tmp_buf, x); \
|
||||
a += x; \
|
||||
b += x; \
|
||||
upx_memcpy_inline(tmp_buf, a, n); \
|
||||
upx_memcpy_inline(a, b, n); \
|
||||
upx_memcpy_inline(b, tmp_buf, n); \
|
||||
a += n; \
|
||||
b += n; \
|
||||
} while (0)
|
||||
|
||||
for (; bytes >= 16; bytes -= 16)
|
||||
|
@ -382,7 +382,7 @@ void upx_shellsort_memcpy(void *array, size_t n, size_t element_size, upx_compar
|
|||
// wrap std::stable_sort()
|
||||
template <size_t ElementSize>
|
||||
void upx_std_stable_sort(void *array, size_t n, upx_compare_func_t compare) {
|
||||
static_assert(ElementSize > 0 && ElementSize <= UPX_RSIZE_MAX);
|
||||
static_assert(ElementSize >= 1 && ElementSize <= UPX_RSIZE_MAX);
|
||||
mem_size_assert(ElementSize, n); // check size
|
||||
#if 0
|
||||
// just for testing
|
||||
|
@ -412,7 +412,7 @@ template void upx_std_stable_sort<16>(void *, size_t, upx_compare_func_t);
|
|||
template void upx_std_stable_sort<32>(void *, size_t, upx_compare_func_t);
|
||||
template void upx_std_stable_sort<56>(void *, size_t, upx_compare_func_t);
|
||||
template void upx_std_stable_sort<72>(void *, size_t, upx_compare_func_t);
|
||||
#endif
|
||||
#endif // UPX_CONFIG_USE_STABLE_SORT
|
||||
|
||||
#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG
|
||||
#if __cplusplus >= 202002L // use C++20 std::next_permutation() to test all permutations
|
||||
|
|
Loading…
Reference in New Issue
Block a user