From 8afddf605129d0d3c0de3ec085f995bed7df9132 Mon Sep 17 00:00:00 2001
From: midipix <writeonce@midipix.org>
Date: Sat, 27 Jan 2024 22:09:30 +0000
Subject: ar mode: added initial -Wprint and -Wpretty support.

---
 src/internal/slibtool_driver_impl.h |  2 ++
 src/logic/slbt_exec_ar.c            | 69 +++++++++++++++++++++++++++++++++++--
 src/skin/slbt_skin_ar.c             | 14 ++++++++
 3 files changed, 83 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index 2008324..ab4ed9b 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -85,6 +85,8 @@ enum app_tags {
 	TAG_AR_HELP,
 	TAG_AR_VERSION,
 	TAG_AR_CHECK,
+	TAG_AR_PRINT,
+	TAG_AR_PRETTY,
 };
 
 struct slbt_split_vector {
diff --git a/src/logic/slbt_exec_ar.c b/src/logic/slbt_exec_ar.c
index 57e0112..e446daa 100644
--- a/src/logic/slbt_exec_ar.c
+++ b/src/logic/slbt_exec_ar.c
@@ -7,6 +7,7 @@
 #define ARGV_DRIVER
 
 #include <slibtool/slibtool.h>
+#include <slibtool/slibtool_output.h>
 #include "slibtool_driver_impl.h"
 #include "slibtool_ar_impl.h"
 #include "slibtool_errinfo_impl.h"
@@ -14,6 +15,15 @@
 
 #define SLBT_DRIVER_MODE_AR_ACTIONS     (SLBT_DRIVER_MODE_AR_CHECK)
 
+#define SLBT_DRIVER_MODE_AR_OUTPUTS     (SLBT_OUTPUT_ARCHIVE_MEMBERS  \
+	                                 | SLBT_OUTPUT_ARCHIVE_HEADERS \
+	                                 | SLBT_OUTPUT_ARCHIVE_SYMBOLS  \
+	                                 | SLBT_OUTPUT_ARCHIVE_ARMAPS)
+
+#define SLBT_PRETTY_FLAGS               (SLBT_PRETTY_YAML      \
+	                                 | SLBT_PRETTY_POSIX    \
+	                                 | SLBT_PRETTY_HEXDATA)
+
 static int slbt_ar_usage(
 	int				fdout,
 	const char *			program,
@@ -64,6 +74,25 @@ static int slbt_exec_ar_fail(
 	return ret;
 }
 
+static int slbt_exec_ar_perform_archive_actions(
+	const struct slbt_driver_ctx *  dctx,
+	struct slbt_archive_ctx **      arctxv)
+{
+	struct slbt_archive_ctx **      arctxp;
+
+	for (arctxp=arctxv; *arctxp; arctxp++) {
+		if (dctx->cctx->fmtflags & SLBT_DRIVER_MODE_AR_OUTPUTS)
+			if (slbt_ar_output_arname(*arctxp) < 0)
+				return SLBT_NESTED_ERROR(dctx);
+
+		if (dctx->cctx->fmtflags & SLBT_OUTPUT_ARCHIVE_MEMBERS)
+			if (slbt_ar_output_members((*arctxp)->meta) < 0)
+				return SLBT_NESTED_ERROR(dctx);
+	}
+
+	return 0;
+}
+
 int slbt_exec_ar(
 	const struct slbt_driver_ctx *	dctx,
 	struct slbt_exec_ctx *		ectx)
@@ -155,6 +184,36 @@ int slbt_exec_ar(
 				case TAG_AR_CHECK:
 					ictx->cctx.drvflags |= SLBT_DRIVER_MODE_AR_CHECK;
 					break;
+
+				case TAG_AR_PRINT:
+					if (!entry->arg)
+						ictx->cctx.fmtflags |= SLBT_OUTPUT_ARCHIVE_MEMBERS;
+
+					else if (!strcmp(entry->arg,"members"))
+						ictx->cctx.fmtflags |= SLBT_OUTPUT_ARCHIVE_MEMBERS;
+
+					else if (!strcmp(entry->arg,"headers"))
+						ictx->cctx.fmtflags |= SLBT_OUTPUT_ARCHIVE_HEADERS;
+
+					else if (!strcmp(entry->arg,"symbols"))
+						ictx->cctx.fmtflags |= SLBT_OUTPUT_ARCHIVE_SYMBOLS;
+
+					else if (!strcmp(entry->arg,"armaps"))
+						ictx->cctx.fmtflags |= SLBT_OUTPUT_ARCHIVE_ARMAPS;
+
+					break;
+
+				case TAG_AR_PRETTY:
+					if (!strcmp(entry->arg,"yaml")) {
+						ictx->cctx.fmtflags &= ~(uint64_t)SLBT_PRETTY_FLAGS;
+						ictx->cctx.fmtflags |= SLBT_PRETTY_YAML;
+
+					} else if (!strcmp(entry->arg,"posix")) {
+						ictx->cctx.fmtflags &= ~(uint64_t)SLBT_PRETTY_FLAGS;
+						ictx->cctx.fmtflags |= SLBT_PRETTY_POSIX;
+					}
+
+					break;
 			}
 
 			if (entry->fval) {
@@ -173,7 +232,10 @@ int slbt_exec_ar(
 	}
 
 	/* at least one action must be specified */
-	if (!(cctx->drvflags & SLBT_DRIVER_MODE_AR_ACTIONS)) {
+	if (cctx->fmtflags & SLBT_DRIVER_MODE_AR_OUTPUTS) {
+		(void)0;
+
+	} else if (!(cctx->drvflags & SLBT_DRIVER_MODE_AR_ACTIONS)) {
 		if (cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
 			slbt_dprintf(fderr,
 				"%s: at least one action must be specified\n",
@@ -235,6 +297,9 @@ int slbt_exec_ar(
 		}
 	}
 
+	/* archive operations */
+	ret = slbt_exec_ar_perform_archive_actions(dctx,arctxv);
+
 	/* all done */
 	for (arctxp=arctxv; *arctxp; arctxp++)
 		slbt_free_archive_ctx(*arctxp);
@@ -245,5 +310,5 @@ int slbt_exec_ar(
 	argv_free(meta);
 	slbt_free_exec_ctx(actx);
 
-	return 0;
+	return ret;
 }
diff --git a/src/skin/slbt_skin_ar.c b/src/skin/slbt_skin_ar.c
index 0c021d9..2991e4e 100644
--- a/src/skin/slbt_skin_ar.c
+++ b/src/skin/slbt_skin_ar.c
@@ -14,6 +14,20 @@ const struct argv_option slbt_ar_options[] = {
 			"verify that %s is a valid archive; "
 			"supported variants are BSD, SysV, and PE/COFF"},
 
+	{"Wprint",	0,TAG_AR_PRINT,ARGV_OPTARG_OPTIONAL,
+			ARGV_OPTION_HYBRID_EQUAL|ARGV_OPTION_HYBRID_COMMA,
+			"members",0,
+			"print out information pertaining to each archive file "
+			"and its various internal elements"},
+
+	{"Wpretty",	0,TAG_AR_PRETTY,ARGV_OPTARG_REQUIRED,
+			ARGV_OPTION_HYBRID_EQUAL,
+			"posix|yaml|hexdata",0,
+			"select the pretty printer to be used: "
+			"'posix' for ar(1) compatible output; "
+			"'yaml' for yaml-formatted data; and "
+			"'hexdata' for yaml-formatted data with additional "
+			"hexdump output"},
 
 	{0,0,0,0,0,0,0,0}
 };
-- 
cgit v1.2.3