Redfoxmoon / cross / slibtool

Forked from cross/slibtool 8 months ago
Clone

Blame src/logic/slbt_exec_ar.c

11f3c7
/*******************************************************************/
11f3c7
/*  slibtool: a skinny libtool implementation, written in C        */
11f3c7
/*  Copyright (C) 2016--2024  SysDeer Technologies, LLC            */
11f3c7
/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
11f3c7
/*******************************************************************/
11f3c7
11f3c7
#define ARGV_DRIVER
11f3c7
11f3c7
#include <slibtool/slibtool.h>
11f3c7
#include "slibtool_driver_impl.h"
11f3c7
#include "slibtool_ar_impl.h"
11f3c7
#include "slibtool_errinfo_impl.h"
11f3c7
#include "argv/argv.h"
11f3c7
11f3c7
static int slbt_ar_usage(
11f3c7
	int				fdout,
11f3c7
	const char *			program,
11f3c7
	const char *			arg,
11f3c7
	const struct argv_option **	optv,
11f3c7
	struct argv_meta *		meta,
11f3c7
	struct slbt_exec_ctx *		ectx,
11f3c7
	int				noclr)
11f3c7
{
11f3c7
	char		header[512];
11f3c7
	bool		armode;
11f3c7
	const char *	dash;
11f3c7
11f3c7
	armode = (dash = strrchr(program,'-'))
11f3c7
		&& !strcmp(++dash,"ar");
11f3c7
11f3c7
	snprintf(header,sizeof(header),
11f3c7
		"Usage: %s%s [options] [ARCHIVE-FILE] [ARCHIVE_FILE] ...\n"
11f3c7
		"Options:\n",
11f3c7
		program,
11f3c7
		armode ? "" : " --mode=ar");
11f3c7
11f3c7
	switch (noclr) {
11f3c7
		case 0:
11f3c7
			argv_usage(fdout,header,optv,arg);
11f3c7
			break;
11f3c7
11f3c7
		default:
11f3c7
			argv_usage_plain(fdout,header,optv,arg);
11f3c7
			break;
11f3c7
	}
11f3c7
11f3c7
	if (ectx)
11f3c7
		slbt_free_exec_ctx(ectx);
11f3c7
11f3c7
	argv_free(meta);
11f3c7
11f3c7
	return SLBT_USAGE;
11f3c7
}
11f3c7
11f3c7
static int slbt_exec_ar_fail(
11f3c7
	struct slbt_exec_ctx *	actx,
11f3c7
	struct argv_meta *	meta,
11f3c7
	int			ret)
11f3c7
{
11f3c7
	argv_free(meta);
11f3c7
	slbt_free_exec_ctx(actx);
11f3c7
	return ret;
11f3c7
}
11f3c7
11f3c7
int slbt_exec_ar(
11f3c7
	const struct slbt_driver_ctx *	dctx,
11f3c7
	struct slbt_exec_ctx *		ectx)
11f3c7
{
11f3c7
	int				ret;
11f3c7
	int				fdout;
11f3c7
	char **				argv;
11f3c7
	char **				iargv;
11f3c7
	struct slbt_archive_ctx **	arctxv;
11f3c7
	const char **			unitv;
11f3c7
	const char **			unitp;
11f3c7
	size_t				nunits;
11f3c7
	struct slbt_exec_ctx *		actx;
11f3c7
	struct argv_meta *		meta;
11f3c7
	struct argv_entry *		entry;
11f3c7
	const struct argv_option *	optv[SLBT_OPTV_ELEMENTS];
11f3c7
11f3c7
	/* context */
11f3c7
	if (ectx)
11f3c7
		actx = 0;
11f3c7
	else if ((ret = slbt_get_exec_ctx(dctx,&ectx)))
11f3c7
		return ret;
11f3c7
	else
11f3c7
		actx = ectx;
11f3c7
11f3c7
	/* initial state, ar mode skin */
11f3c7
	slbt_reset_arguments(ectx);
11f3c7
	slbt_disable_placeholders(ectx);
11f3c7
	iargv = ectx->cargv;
11f3c7
	fdout = slbt_driver_fdout(dctx);
11f3c7
11f3c7
	/* missing arguments? */
11f3c7
	argv_optv_init(slbt_ar_options,optv);
11f3c7
11f3c7
	if (!iargv[1] && (dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_USAGE))
11f3c7
		return slbt_ar_usage(
11f3c7
			fdout,
11f3c7
			dctx->program,
11f3c7
			0,optv,0,actx,
11f3c7
			dctx->cctx->drvflags & SLBT_DRIVER_ANNOTATE_NEVER);
11f3c7
11f3c7
	/* <ar> argv meta */
11f3c7
	if (!(meta = argv_get(
11f3c7
			iargv,optv,
11f3c7
			dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS
11f3c7
				? ARGV_VERBOSITY_ERRORS
11f3c7
				: ARGV_VERBOSITY_NONE,
11f3c7
			fdout)))
11f3c7
		return slbt_exec_ar_fail(
11f3c7
			actx,meta,
11f3c7
			SLBT_CUSTOM_ERROR(dctx,SLBT_ERR_AR_FAIL));
11f3c7
11f3c7
	/* dest, alternate argument vector options */
11f3c7
	argv    = ectx->altv;
11f3c7
	*argv++ = iargv[0];
11f3c7
	nunits  = 0;
11f3c7
11f3c7
	for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
11f3c7
		if (entry->fopt) {
11f3c7
			switch (entry->tag) {
11f3c7
				case TAG_AR_HELP:
11f3c7
					slbt_ar_usage(
11f3c7
						fdout,
11f3c7
						dctx->program,
11f3c7
						0,optv,0,ectx,
11f3c7
						dctx->cctx->drvflags
11f3c7
							& SLBT_DRIVER_ANNOTATE_NEVER);
11f3c7
					return 0;
11f3c7
			}
11f3c7
11f3c7
			if (entry->fval) {
11f3c7
				*argv++ = (char *)entry->arg;
11f3c7
			}
11f3c7
		} else {
11f3c7
			nunits++;
11f3c7
		};
11f3c7
	}
11f3c7
11f3c7
	/* archive vector allocation */
11f3c7
	if (!(arctxv = calloc(nunits+1,sizeof(struct slbt_archive_ctx *))))
11f3c7
		return slbt_exec_ar_fail(
11f3c7
			actx,meta,
11f3c7
			SLBT_SYSTEM_ERROR(dctx,0));
11f3c7
11f3c7
	/* unit vector allocation */
11f3c7
	if (!(unitv = calloc(nunits+1,sizeof(const char *)))) {
11f3c7
		free (arctxv);
11f3c7
11f3c7
		return slbt_exec_ar_fail(
11f3c7
			actx,meta,
11f3c7
			SLBT_SYSTEM_ERROR(dctx,0));
11f3c7
	}
11f3c7
11f3c7
	/* unit vector initialization */
11f3c7
	for (entry=meta->entries,unitp=unitv; entry->fopt || entry->arg; entry++)
11f3c7
		if (!entry->fopt)
11f3c7
			*unitp++ = entry->arg;
11f3c7
11f3c7
	/* all done */
11f3c7
	free(unitv);
11f3c7
	free(arctxv);
11f3c7
11f3c7
	argv_free(meta);
11f3c7
	slbt_free_exec_ctx(actx);
11f3c7
11f3c7
	return 0;
11f3c7
}