summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2025-05-29 00:53:15 +0000
committermidipix <writeonce@midipix.org>2025-05-29 03:35:46 +0000
commit59b920bb87eab928e77b5227a1ed9023292a7552 (patch)
treedf0f396edc1cec2156f5ee7d543b39ed05e20a4b /src
parentbbc6acc8f263e26cd487b936ee5ab7a61b59b277 (diff)
downloadperk-59b920bb87eab928e77b5227a1ed9023292a7552.tar.bz2
perk-59b920bb87eab928e77b5227a1ed9023292a7552.tar.xz
driver: become multi-cmd ready, added pe_cmd_perk().
Diffstat (limited to 'src')
-rw-r--r--src/cmds/pe_cmd_perk.c83
-rw-r--r--src/driver/pe_amain.c71
-rw-r--r--src/driver/pe_driver_ctx.c329
-rw-r--r--src/internal/perk_driver_impl.h2
-rw-r--r--src/skin/pe_skin_default.c44
-rw-r--r--src/skin/pe_skin_perk.c54
6 files changed, 401 insertions, 182 deletions
diff --git a/src/cmds/pe_cmd_perk.c b/src/cmds/pe_cmd_perk.c
new file mode 100644
index 0000000..d2b11a2
--- /dev/null
+++ b/src/cmds/pe_cmd_perk.c
@@ -0,0 +1,83 @@
+/***************************************************************/
+/* perk: PE Resource Kit */
+/* Copyright (C) 2015--2025 SysDeer Technologies, LLC */
+/* Released under GPLv2 and GPLv3; see COPYING.PERK. */
+/***************************************************************/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <perk/perk.h>
+#include <perk/perk_output.h>
+#include "perk_driver_impl.h"
+#include "perk_dprintf_impl.h"
+
+static void pe_perform_hdrdump_actions(
+ const struct pe_driver_ctx * dctx,
+ const struct pe_unit_ctx * uctx)
+{
+ if (dctx->cctx->hdrdump & PERK_HDRDUMP_IMAGE_DOS_HEADER)
+ pe_hdrdump_image_dos_hdr(dctx,uctx->meta);
+
+ if (dctx->cctx->hdrdump & PERK_HDRDUMP_COFF_IMAGE_HEADER)
+ pe_hdrdump_coff_image_hdr(dctx,uctx->meta);
+
+ if (dctx->cctx->hdrdump & PERK_HDRDUMP_COFF_OBJECT_HEADER)
+ pe_hdrdump_coff_object_hdr(dctx,uctx->meta);
+
+ if (dctx->cctx->hdrdump & PERK_HDRDUMP_COFF_OPT_HEADER)
+ pe_hdrdump_coff_opt_hdr(dctx,uctx->meta);
+
+ if (dctx->cctx->hdrdump & PERK_HDRDUMP_SECTION_TABLE)
+ pe_hdrdump_sec_tbl(dctx,uctx->meta);
+
+ if (dctx->cctx->hdrdump & PERK_HDRDUMP_EXPORT_HEADER)
+ pe_hdrdump_export_hdr(dctx,uctx->meta);
+
+ if (dctx->cctx->hdrdump & PERK_HDRDUMP_IMPORT_TABLE)
+ pe_hdrdump_import_tbl(dctx,uctx->meta);
+}
+
+static void pe_perform_unit_actions(
+ const struct pe_driver_ctx * dctx,
+ const struct pe_unit_ctx * uctx)
+{
+ uint64_t flags = dctx->cctx->fmtflags;
+
+ if (flags & PERK_OUTPUT_IMAGE_CATEGORY)
+ pe_output_image_category(dctx,uctx->meta);
+
+ if (flags & PERK_OUTPUT_IMAGE_SECTIONS)
+ pe_output_image_sections(dctx,uctx->meta);
+
+ if (flags & PERK_OUTPUT_IMAGE_SYMBOLS)
+ pe_output_image_symbols(dctx,uctx->meta);
+
+ if (flags & PERK_OUTPUT_IMAGE_STRINGS)
+ pe_output_image_strings(dctx,uctx->meta);
+
+ if (flags & PERK_OUTPUT_EXPORT_SYMS)
+ pe_output_export_symbols(dctx,uctx->meta);
+
+ if ((flags & PERK_OUTPUT_IMPORT_LIBS) || (flags & PERK_OUTPUT_IMPORT_SYMS))
+ pe_output_import_libraries(dctx,uctx->meta);
+
+ if ((flags & PERK_OUTPUT_MDSO_LIBS) || (flags & PERK_OUTPUT_MDSO_SYMS))
+ pe_output_mdso_libraries(dctx,uctx->meta);
+
+ if (dctx->cctx->hdrdump)
+ pe_perform_hdrdump_actions(dctx,uctx);
+}
+
+int pe_cmd_perk(const struct pe_driver_ctx * dctx, const char * path)
+{
+ int ret;
+ struct pe_unit_ctx * uctx;
+
+ if ((ret = pe_get_unit_ctx(dctx,path,&uctx)) < 0)
+ return ret;
+
+ pe_perform_unit_actions(dctx,uctx);
+ pe_free_unit_ctx(uctx);
+
+ return 0;
+}
diff --git a/src/driver/pe_amain.c b/src/driver/pe_amain.c
index 286e111..1804246 100644
--- a/src/driver/pe_amain.c
+++ b/src/driver/pe_amain.c
@@ -48,63 +48,6 @@ static ssize_t pe_version(struct pe_driver_ctx * dctx, int fdout)
verclr[4],verinfo->commit,verclr[5]);
}
-static void pe_perform_hdrdump_actions(
- const struct pe_driver_ctx * dctx,
- struct pe_unit_ctx * uctx)
-{
- if (dctx->cctx->hdrdump & PERK_HDRDUMP_IMAGE_DOS_HEADER)
- pe_hdrdump_image_dos_hdr(dctx,uctx->meta);
-
- if (dctx->cctx->hdrdump & PERK_HDRDUMP_COFF_IMAGE_HEADER)
- pe_hdrdump_coff_image_hdr(dctx,uctx->meta);
-
- if (dctx->cctx->hdrdump & PERK_HDRDUMP_COFF_OBJECT_HEADER)
- pe_hdrdump_coff_object_hdr(dctx,uctx->meta);
-
- if (dctx->cctx->hdrdump & PERK_HDRDUMP_COFF_OPT_HEADER)
- pe_hdrdump_coff_opt_hdr(dctx,uctx->meta);
-
- if (dctx->cctx->hdrdump & PERK_HDRDUMP_SECTION_TABLE)
- pe_hdrdump_sec_tbl(dctx,uctx->meta);
-
- if (dctx->cctx->hdrdump & PERK_HDRDUMP_EXPORT_HEADER)
- pe_hdrdump_export_hdr(dctx,uctx->meta);
-
- if (dctx->cctx->hdrdump & PERK_HDRDUMP_IMPORT_TABLE)
- pe_hdrdump_import_tbl(dctx,uctx->meta);
-}
-
-static void pe_perform_unit_actions(
- const struct pe_driver_ctx * dctx,
- struct pe_unit_ctx * uctx)
-{
- uint64_t flags = dctx->cctx->fmtflags;
-
- if (flags & PERK_OUTPUT_IMAGE_CATEGORY)
- pe_output_image_category(dctx,uctx->meta);
-
- if (flags & PERK_OUTPUT_IMAGE_SECTIONS)
- pe_output_image_sections(dctx,uctx->meta);
-
- if (flags & PERK_OUTPUT_IMAGE_SYMBOLS)
- pe_output_image_symbols(dctx,uctx->meta);
-
- if (flags & PERK_OUTPUT_IMAGE_STRINGS)
- pe_output_image_strings(dctx,uctx->meta);
-
- if (flags & PERK_OUTPUT_EXPORT_SYMS)
- pe_output_export_symbols(dctx,uctx->meta);
-
- if ((flags & PERK_OUTPUT_IMPORT_LIBS) || (flags & PERK_OUTPUT_IMPORT_SYMS))
- pe_output_import_libraries(dctx,uctx->meta);
-
- if ((flags & PERK_OUTPUT_MDSO_LIBS) || (flags & PERK_OUTPUT_MDSO_SYMS))
- pe_output_mdso_libraries(dctx,uctx->meta);
-
- if (dctx->cctx->hdrdump)
- pe_perform_hdrdump_actions(dctx,uctx);
-}
-
static int pe_exit(struct pe_driver_ctx * dctx, int ret)
{
pe_output_error_vector(dctx);
@@ -118,7 +61,6 @@ int pe_main(char ** argv, char ** envp, const struct pe_fd_ctx * fdctx)
int fdout;
uint64_t flags;
struct pe_driver_ctx * dctx;
- struct pe_unit_ctx * uctx;
const char ** unit;
flags = PERK_DRIVER_FLAGS;
@@ -133,11 +75,14 @@ int pe_main(char ** argv, char ** envp, const struct pe_fd_ctx * fdctx)
if ((pe_version(dctx,fdout)) < 0)
return pe_exit(dctx,PERK_ERROR);
- for (unit=dctx->units; *unit; unit++) {
- if (!(pe_get_unit_ctx(dctx,*unit,&uctx))) {
- pe_perform_unit_actions(dctx,uctx);
- pe_free_unit_ctx(uctx);
- }
+ switch (dctx->cctx->cmd) {
+ case PERK_CMD_PERK:
+ for (unit=dctx->units; *unit; unit++)
+ pe_cmd_perk(dctx,*unit);
+ break;
+
+ default:
+ break;
}
return pe_exit(dctx,dctx->errv[0] ? PERK_ERROR : PERK_OK);
diff --git a/src/driver/pe_driver_ctx.c b/src/driver/pe_driver_ctx.c
index 9955548..04483eb 100644
--- a/src/driver/pe_driver_ctx.c
+++ b/src/driver/pe_driver_ctx.c
@@ -24,6 +24,17 @@ static const struct pe_source_version pe_src_version = {
PERK_GIT_VERSION
};
+/* perk command names */
+static const char * const perk_cmd_name[PERK_CMD_CAP] = {
+ [PERK_CMD_PERK] = "perk",
+};
+
+/* perk command options */
+static const struct argv_option * perk_cmd_options[PERK_CMD_CAP] = {
+ [PERK_CMD_DEFAULT] = pe_default_options,
+ [PERK_CMD_PERK] = pe_perk_options,
+};
+
/* default fd context */
static const struct pe_fd_ctx pe_default_fdctx = {
.fdin = STDIN_FILENO,
@@ -62,13 +73,30 @@ static int pe_driver_usage(
const char * program,
const char * arg,
const struct argv_option ** optv,
- struct argv_meta * meta)
+ struct argv_meta * meta,
+ enum pe_cmd cmd)
{
- char header[512];
+ char header[512];
+ char * cmdarg[2];
+ const char * cmdname;
+
+ if (cmd == PERK_CMD_DEFAULT) {
+ cmdarg[0] = "";
+ cmdarg[1] = "";
+ cmdname = "";
+ } else {
+ cmdarg[0] = " (--cmd=";
+ cmdarg[1] = ")";
+ cmdname = perk_cmd_name[cmd];
+ }
snprintf(header,sizeof(header),
- "Usage: %s [options] <file>...\n" "Options:\n",
- program);
+ "Usage: %s [options] ...\n"
+ "Usage: %s [options] [--cmd=<command>] <arg> <arg> ...\n\n"
+ "Notes: --cmd must precede all non-option arguments, as well as\n"
+ " all arguments that are specific to the selected command.\n\n"
+ "Options%s%s%s:\n",
+ program,program,cmdarg[0],cmdname,cmdarg[1]);
argv_usage(fdout,header,optv,arg);
argv_free(meta);
@@ -113,52 +141,43 @@ static struct pe_driver_ctx_impl * pe_driver_ctx_alloc(
return &ictx->ctx;
}
-static int pe_get_driver_ctx_fail(struct argv_meta * meta)
-{
- argv_free(meta);
- return -1;
-}
-
-int pe_get_driver_ctx(
- char ** argv,
- char ** envp,
- uint32_t flags,
- const struct pe_fd_ctx * fdctx,
- struct pe_driver_ctx ** pctx)
+static int pe_cmd_from_program(const char * program)
{
- struct pe_driver_ctx_impl * ctx;
- struct pe_common_ctx cctx;
- const struct argv_option * optv[PERK_OPTV_ELEMENTS];
- struct argv_meta * meta;
- struct argv_entry * entry;
- size_t nunits;
- const char * program;
- const char * pretty;
+ const char * dot;
+ const char * hyphen;
+ const char * mark;
- (void)envp;
+ dot = strrchr(program,'.');
+ hyphen = strrchr(program,'-');
- if (!fdctx)
- fdctx = &pe_default_fdctx;
+ if (hyphen > dot)
+ mark = ++hyphen;
+ else if (dot > hyphen)
+ mark = ++dot;
+ else
+ mark = program;
- argv_optv_init(pe_default_options,optv);
+ if (!strcmp(mark,"perk")) {
+ return PERK_CMD_PERK;
- if (!(meta = argv_get(
- argv,optv,
- pe_argv_flags(flags),
- fdctx->fderr)))
- return -1;
+ } else {
+ return PERK_CMD_DEFAULT;
+ }
+}
- pretty = 0;
- nunits = 0;
- program = argv_program_name(argv[0]);
- memset(&cctx,0,sizeof(cctx));
- cctx.drvflags = flags;
+static int pe_cctx_update(
+ const char * program,
+ const struct argv_option ** optv,
+ struct argv_meta * meta,
+ uint32_t flags,
+ const struct pe_fd_ctx * fdctx,
+ struct pe_common_ctx * cctx,
+ size_t * nunits)
+{
+ struct argv_entry * entry;
+ const char * pretty;
- if (!argv[1] && (flags & PERK_DRIVER_VERBOSITY_USAGE))
- return pe_driver_usage(
- fdctx->fderr,
- program,
- 0,optv,meta);
+ pretty = 0;
/* get options, count units */
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
@@ -169,11 +188,21 @@ int pe_get_driver_ctx(
return pe_driver_usage(
fdctx->fdout,
program,entry->arg,
- optv,meta);
+ optv,0,cctx->cmd);
+ break;
+
+ case TAG_CMD:
+ if (*nunits)
+ return pe_driver_usage(
+ fdctx->fderr,
+ program,0,
+ optv,0,cctx->cmd);
+
+ cctx->cmd = pe_cmd_from_program(entry->arg);
break;
case TAG_VERSION:
- cctx.drvflags |= PERK_DRIVER_VERSION;
+ cctx->drvflags |= PERK_DRIVER_VERSION;
break;
case TAG_PRETTY:
@@ -181,86 +210,230 @@ int pe_get_driver_ctx(
break;
case TAG_CATEGORY:
- cctx.fmtflags |= PERK_OUTPUT_IMAGE_CATEGORY;
+ cctx->fmtflags |= PERK_OUTPUT_IMAGE_CATEGORY;
break;
case TAG_SECTIONS:
- cctx.fmtflags |= PERK_OUTPUT_IMAGE_SECTIONS;
+ cctx->fmtflags |= PERK_OUTPUT_IMAGE_SECTIONS;
break;
case TAG_SYMBOLS:
- cctx.fmtflags |= PERK_OUTPUT_IMAGE_SYMBOLS;
+ cctx->fmtflags |= PERK_OUTPUT_IMAGE_SYMBOLS;
break;
case TAG_STRINGS:
- cctx.fmtflags |= PERK_OUTPUT_IMAGE_STRINGS;
+ cctx->fmtflags |= PERK_OUTPUT_IMAGE_STRINGS;
break;
case TAG_EXPSYMS:
- cctx.fmtflags |= PERK_OUTPUT_EXPORT_SYMS;
+ cctx->fmtflags |= PERK_OUTPUT_EXPORT_SYMS;
break;
case TAG_IMPLIBS:
- cctx.fmtflags |= PERK_OUTPUT_IMPORT_LIBS;
+ cctx->fmtflags |= PERK_OUTPUT_IMPORT_LIBS;
break;
case TAG_IMPSYMS:
- cctx.fmtflags |= PERK_OUTPUT_IMPORT_SYMS;
+ cctx->fmtflags |= PERK_OUTPUT_IMPORT_SYMS;
break;
case TAG_DSOLIBS:
- cctx.fmtflags |= PERK_OUTPUT_MDSO_LIBS;
+ cctx->fmtflags |= PERK_OUTPUT_MDSO_LIBS;
break;
case TAG_DSOSYMS:
- cctx.fmtflags |= PERK_OUTPUT_MDSO_SYMS;
+ cctx->fmtflags |= PERK_OUTPUT_MDSO_SYMS;
break;
case TAG_HDRDUMP:
if (!entry->arg) {
- cctx.hdrdump = 0;
- cctx.hdrdump = ~cctx.hdrdump;
+ cctx->hdrdump = 0;
+ cctx->hdrdump = ~cctx->hdrdump;
} else if (!strcmp(entry->arg,"dos")) {
- cctx.hdrdump = PERK_HDRDUMP_IMAGE_DOS_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_IMAGE_DOS_HEADER;
} else if (!strcmp(entry->arg,"image.dos")) {
- cctx.hdrdump = PERK_HDRDUMP_IMAGE_DOS_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_IMAGE_DOS_HEADER;
} else if (!strcmp(entry->arg,"coff")) {
- cctx.hdrdump = PERK_HDRDUMP_COFF_IMAGE_HEADER;
- cctx.hdrdump |= PERK_HDRDUMP_COFF_OBJECT_HEADER;
- cctx.hdrdump |= PERK_HDRDUMP_COFF_OPT_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_COFF_IMAGE_HEADER;
+ cctx->hdrdump |= PERK_HDRDUMP_COFF_OBJECT_HEADER;
+ cctx->hdrdump |= PERK_HDRDUMP_COFF_OPT_HEADER;
} else if (!strcmp(entry->arg,"coff.image")) {
- cctx.hdrdump = PERK_HDRDUMP_COFF_IMAGE_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_COFF_IMAGE_HEADER;
} else if (!strcmp(entry->arg,"coff.obj")) {
- cctx.hdrdump = PERK_HDRDUMP_COFF_OBJECT_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_COFF_OBJECT_HEADER;
} else if (!strcmp(entry->arg,"coff.object")) {
- cctx.hdrdump = PERK_HDRDUMP_COFF_OBJECT_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_COFF_OBJECT_HEADER;
} else if (!strcmp(entry->arg,"coff.opt")) {
- cctx.hdrdump = PERK_HDRDUMP_COFF_OPT_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_COFF_OPT_HEADER;
} else if (!strcmp(entry->arg,"coff.optional")) {
- cctx.hdrdump = PERK_HDRDUMP_COFF_OPT_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_COFF_OPT_HEADER;
} else if (!strcmp(entry->arg,"sectbl")) {
- cctx.hdrdump = PERK_HDRDUMP_SECTION_TABLE;
+ cctx->hdrdump = PERK_HDRDUMP_SECTION_TABLE;
} else if (!strcmp(entry->arg,"section.table")) {
- cctx.hdrdump = PERK_HDRDUMP_SECTION_TABLE;
+ cctx->hdrdump = PERK_HDRDUMP_SECTION_TABLE;
} else if (!strcmp(entry->arg,"exphdr")) {
- cctx.hdrdump = PERK_HDRDUMP_EXPORT_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_EXPORT_HEADER;
} else if (!strcmp(entry->arg,"export.header")) {
- cctx.hdrdump = PERK_HDRDUMP_EXPORT_HEADER;
+ cctx->hdrdump = PERK_HDRDUMP_EXPORT_HEADER;
} else if (!strcmp(entry->arg,"imptbl")) {
- cctx.hdrdump = PERK_HDRDUMP_IMPORT_TABLE;
+ cctx->hdrdump = PERK_HDRDUMP_IMPORT_TABLE;
} else if (!strcmp(entry->arg,"import.table")) {
- cctx.hdrdump = PERK_HDRDUMP_IMPORT_TABLE;
+ cctx->hdrdump = PERK_HDRDUMP_IMPORT_TABLE;
}
break;
}
- } else
- nunits++;
+ } else {
+ (*nunits)++;
+ }
+ }
+
+ if (pretty && !strcmp(pretty,"yaml")) {
+ cctx->fmtflags |= PERK_PRETTY_YAML;
+
+ } else if (pretty && !strcmp(pretty,"dlltool")) {
+ cctx->fmtflags |= PERK_PRETTY_DLLTOOL;
+ }
+
+ return 0;
+}
+
+static int pe_get_driver_ctx_fail(struct argv_meta * meta)
+{
+ argv_free(meta);
+ return -1;
+}
+
+int pe_get_driver_ctx(
+ char ** argv,
+ char ** envp,
+ uint32_t flags,
+ const struct pe_fd_ctx * fdctx,
+ struct pe_driver_ctx ** pctx)
+{
+ struct pe_driver_ctx_impl * ctx;
+ struct pe_common_ctx cctx;
+ const struct argv_option * optv[PERK_OPTV_ELEMENTS];
+ struct argv_meta * meta;
+ size_t nunits;
+ const char * program;
+ char ** parg;
+ char ** pargcap;
+ char ** cmdargv;
+ char * cmdmark;
+ struct argv_ctx actx = {ARGV_VERBOSITY_NONE,
+ ARGV_MODE_SCAN,
+ 0,0,0,0,0,0,0,0};
+
+
+ (void)envp;
+
+ /* fdctx */
+ if (!fdctx)
+ fdctx = &pe_default_fdctx;
+
+ /* cctx */
+ memset(&cctx,0,sizeof(cctx));
+
+ program = argv_program_name(argv[0]);\
+ cctx.cmd = pe_cmd_from_program(program);
+ cctx.drvflags = flags;
+ nunits = 0;
+
+ /* missing arguments? */
+ argv_optv_init(perk_cmd_options[cctx.cmd],optv);
+
+ if (!argv[1] && (flags & PERK_DRIVER_VERBOSITY_USAGE))
+ return pe_driver_usage(
+ fdctx->fderr,
+ program,0,
+ optv,0,cctx.cmd);
+
+ /* initial argv scan: ... --cmd=xxx ... */
+ argv_scan(argv,optv,&actx,0);
+
+ /* position of last base perk argument */
+ if (actx.erridx && actx.unitidx)
+ pargcap = &argv[actx.unitidx];
+
+ else if (actx.erridx)
+ pargcap = &argv[actx.erridx];
+
+ else
+ for (pargcap=argv; *pargcap; pargcap++)
+ (void)0;
+
+ /* scan for --cmd */
+ for (parg=argv, cmdargv=0; (parg<pargcap) && !cmdargv; parg++) {
+ if (!strcmp(*parg,"--cmd") && parg[1]) {
+ cmdargv = &parg[2];
+ cmdmark = parg[2];
+ } else if (!strncmp(*parg,"--cmd=",6)) {
+ cmdargv = &parg[1];
+ cmdmark = parg[1];
+ }
+ }
+
+ /* invalid perk arguments? */
+ if (!actx.erridx) {
+ (void)0;
+
+ } else if (&argv[actx.erridx] >= cmdargv) {
+ (void)0;
+
+ } else {
+ if (flags & PERK_DRIVER_VERBOSITY_ERRORS)
+ argv_get(
+ argv,optv,
+ ARGV_VERBOSITY_ERRORS,
+ fdctx->fderr);
+ return -1;
+ }
+
+ /* process argv entries preceding --cmd */
+ if (cmdargv) {
+ *cmdargv = 0;
+
+ if (!(meta = argv_get(
+ argv,optv,
+ pe_argv_flags(flags),
+ fdctx->fderr)))
+ return -1;
+
+ if (pe_cctx_update(
+ program,optv,meta,flags,
+ fdctx,&cctx,&nunits)) {
+ argv_free(meta);
+ return -1;
+ }
+
+ argv_free(meta);
+
+ *cmdargv-- = cmdmark;
+ *cmdargv = argv[0];
+ argv = cmdargv;
}
- if (pretty && !strcmp(pretty,"yaml"))
- cctx.fmtflags |= PERK_PRETTY_YAML;
- else if (pretty && !strcmp(pretty,"dlltool"))
- cctx.fmtflags |= PERK_PRETTY_DLLTOOL;
+ /* set option vector by command */
+ if (cctx.cmd == PERK_CMD_DEFAULT) {
+ argv_optv_init(pe_default_options,optv);
+
+ } else if (cctx.cmd == PERK_CMD_PERK) {
+ argv_optv_init(pe_perk_options,optv);
+ }
+
+ /* process the selected tool's command-line arguments */
+ if (!(meta = argv_get(
+ argv,optv,
+ pe_argv_flags(flags),
+ fdctx->fderr)))
+ return -1;
+
+ if (pe_cctx_update(
+ program,optv,meta,flags,
+ fdctx,&cctx,&nunits)) {
+ argv_free(meta);
+ return -1;
+ }
if (!(ctx = pe_driver_ctx_alloc(meta,fdctx,&cctx,nunits)))
return pe_get_driver_ctx_fail(meta);
diff --git a/src/internal/perk_driver_impl.h b/src/internal/perk_driver_impl.h
index dafad86..46fed8b 100644
--- a/src/internal/perk_driver_impl.h
+++ b/src/internal/perk_driver_impl.h
@@ -13,10 +13,12 @@
#define PERK_OPTV_ELEMENTS 64
extern const struct argv_option pe_default_options[];
+extern const struct argv_option pe_perk_options[];
enum app_tags {
TAG_HELP,
TAG_VERSION,
+ TAG_CMD,
TAG_PRETTY,
TAG_CATEGORY,
TAG_SECTIONS,
diff --git a/src/skin/pe_skin_default.c b/src/skin/pe_skin_default.c
index 963af6e..b27daf5 100644
--- a/src/skin/pe_skin_default.c
+++ b/src/skin/pe_skin_default.c
@@ -8,47 +8,9 @@ const struct argv_option pe_default_options[] = {
{"help", 'h',TAG_HELP,ARGV_OPTARG_OPTIONAL,0,"short|long",0,
"show usage information [listing %s options only]"},
- {"pretty", 'p',TAG_PRETTY,ARGV_OPTARG_REQUIRED,0,"yaml|dlltool",0,
- "format output for parsing by %s"},
-
- {"category", 'y',TAG_CATEGORY,ARGV_OPTARG_NONE,0,0,0,
- "print image category"},
-
- {"sections", 'c',TAG_SECTIONS,ARGV_OPTARG_NONE,0,0,0,
- "list image sections"},
-
- {"symbols", 'm',TAG_SYMBOLS,ARGV_OPTARG_NONE,0,0,0,
- "list symbols found in the coff symbol table"},
-
- {"strings", 's',TAG_STRINGS,ARGV_OPTARG_NONE,0,0,0,
- "list strings found in the coff string table"},
-
- {"expsyms", 'e',TAG_EXPSYMS,ARGV_OPTARG_NONE,0,0,0,
- "list exported symbols" },
-
- {"implibs", 'i',TAG_IMPLIBS,ARGV_OPTARG_NONE,0,0,0,
- "list .idata dependency libraries"},
-
- {"impsyms", 'I',TAG_IMPSYMS,ARGV_OPTARG_NONE,0,0,0,
- "list .idata dependency libraries "
- "along with imported symbols"},
-
- {"dsolibs", 'd',TAG_DSOLIBS,ARGV_OPTARG_NONE,0,0,0,
- "list .dsometa (mdso) dependency libraries"},
-
- {"dsosyms", 'D',TAG_DSOSYMS,ARGV_OPTARG_NONE,0,0,0,
- "list .dsometa (mdso) dependency libraries "
- "along with referenced symbols"},
-
- {"hdrdump", 'X',TAG_HDRDUMP,ARGV_OPTARG_OPTIONAL,0,
- "dos|image.dos|"
- "coff|coff.image|coff.object|coff.optional|"
- "sectbl|section.table|"
- "exphdr|export.header|"
- "imptbl|import.table",0,
- "output struct-based information for "
- "either all headers (the default) "
- "or a specific header"},
+ {"cmd", 0,TAG_CMD,ARGV_OPTARG_REQUIRED,0,
+ "perk",0,
+ "invoke one of the following perk commands: {%s}"},
{0,0,0,0,0,0,0,0}
};
diff --git a/src/skin/pe_skin_perk.c b/src/skin/pe_skin_perk.c
new file mode 100644
index 0000000..20c84a8
--- /dev/null
+++ b/src/skin/pe_skin_perk.c
@@ -0,0 +1,54 @@
+#include "perk_driver_impl.h"
+#include "argv/argv.h"
+
+const struct argv_option pe_perk_options[] = {
+ {"version", 'v',TAG_VERSION,ARGV_OPTARG_NONE,0,0,0,
+ "show version information"},
+
+ {"help", 'h',TAG_HELP,ARGV_OPTARG_OPTIONAL,0,"short|long",0,
+ "show usage information [listing %s options only]"},
+
+ {"pretty", 'p',TAG_PRETTY,ARGV_OPTARG_REQUIRED,0,"yaml|dlltool",0,
+ "format output for parsing by %s"},
+
+ {"category", 'y',TAG_CATEGORY,ARGV_OPTARG_NONE,0,0,0,
+ "print image category"},
+
+ {"sections", 'c',TAG_SECTIONS,ARGV_OPTARG_NONE,0,0,0,
+ "list image sections"},
+
+ {"symbols", 'm',TAG_SYMBOLS,ARGV_OPTARG_NONE,0,0,0,
+ "list symbols found in the coff symbol table"},
+
+ {"strings", 's',TAG_STRINGS,ARGV_OPTARG_NONE,0,0,0,
+ "list strings found in the coff string table"},
+
+ {"expsyms", 'e',TAG_EXPSYMS,ARGV_OPTARG_NONE,0,0,0,
+ "list exported symbols" },
+
+ {"implibs", 'i',TAG_IMPLIBS,ARGV_OPTARG_NONE,0,0,0,
+ "list .idata dependency libraries"},
+
+ {"impsyms", 'I',TAG_IMPSYMS,ARGV_OPTARG_NONE,0,0,0,
+ "list .idata dependency libraries "
+ "along with imported symbols"},
+
+ {"dsolibs", 'd',TAG_DSOLIBS,ARGV_OPTARG_NONE,0,0,0,
+ "list .dsometa (mdso) dependency libraries"},
+
+ {"dsosyms", 'D',TAG_DSOSYMS,ARGV_OPTARG_NONE,0,0,0,
+ "list .dsometa (mdso) dependency libraries "
+ "along with referenced symbols"},
+
+ {"hdrdump", 'X',TAG_HDRDUMP,ARGV_OPTARG_OPTIONAL,0,
+ "dos|image.dos|"
+ "coff|coff.image|coff.object|coff.optional|"
+ "sectbl|section.table|"
+ "exphdr|export.header|"
+ "imptbl|import.table",0,
+ "output struct-based information for "
+ "either all headers (the default) "
+ "or a specific header"},
+
+ {0,0,0,0,0,0,0,0}
+};