Blame src/driver/sfrt_driver_ctx.c

f46039
#include <stdint.h>
f46039
#include <unistd.h>
f46039
#include <fcntl.h>
f46039
f46039
#define ARGV_DRIVER
f46039
f46039
#include <sofort/sofort.h>
1f115d
#include "sofort_version.h"
f46039
#include "sofort_driver_impl.h"
f46039
#include "argv/argv.h"
f46039
1f115d
/* package info */
1f115d
static const struct sfrt_source_version sfrt_src_version = {
1f115d
	SFRT_TAG_VER_MAJOR,
1f115d
	SFRT_TAG_VER_MINOR,
1f115d
	SFRT_TAG_VER_PATCH,
1f115d
	SOFORT_GIT_VERSION
1f115d
};
1f115d
f46039
struct sfrt_driver_ctx_alloc {
f46039
	struct argv_meta *		meta;
f46039
	struct sfrt_driver_ctx_impl	ctx;
f46039
	uint64_t			guard;
f46039
	const char *			units[];
f46039
};
f46039
f46039
static uint32_t sfrt_argv_flags(uint32_t flags)
f46039
{
f46039
	uint32_t ret = 0;
f46039
f46039
	if (flags & SFRT_DRIVER_VERBOSITY_NONE)
f46039
		ret |= ARGV_VERBOSITY_NONE;
f46039
f46039
	if (flags & SFRT_DRIVER_VERBOSITY_ERRORS)
f46039
		ret |= ARGV_VERBOSITY_ERRORS;
f46039
f46039
	if (flags & SFRT_DRIVER_VERBOSITY_STATUS)
f46039
		ret |= ARGV_VERBOSITY_STATUS;
f46039
f46039
	return ret;
f46039
}
f46039
f46039
static int sfrt_driver_usage(
f46039
	const char *			program,
f46039
	const char *			arg,
a04059
	const struct argv_option **	optv,
f46039
	struct argv_meta *		meta)
f46039
{
f46039
	char header[512];
f46039
f46039
	snprintf(header,sizeof(header),
f46039
		"Usage: %s [options] <file>...\n" "Options:\n",
f46039
		program);
f46039
871a4f
	argv_usage(STDOUT_FILENO,header,optv,arg);
f46039
	argv_free(meta);
f46039
f46039
	return SFRT_USAGE;
f46039
}
f46039
b1b699
static struct sfrt_driver_ctx_impl * sfrt_driver_ctx_alloc(
b1b699
	struct argv_meta *		meta,
b1b699
	const struct sfrt_common_ctx *	cctx,
b1b699
	size_t				nunits)
f46039
{
f46039
	struct sfrt_driver_ctx_alloc *	ictx;
f46039
	size_t				size;
f46039
	struct argv_entry *		entry;
f46039
	const char **			units;
7a0b56
	int				elements;
f46039
f46039
	size =  sizeof(struct sfrt_driver_ctx_alloc);
f46039
	size += (nunits+1)*sizeof(const char *);
f46039
a2826e
	if (!(ictx = calloc(1,size)))
f46039
		return 0;
f46039
b1b699
	if (cctx)
b1b699
		memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
b1b699
f46039
	for (entry=meta->entries,units=ictx->units; entry->fopt || entry->arg; entry++)
f46039
		if (!entry->fopt)
f46039
			*units++ = entry->arg;
f46039
7a0b56
	elements = sizeof(ictx->ctx.erribuf) / sizeof(*ictx->ctx.erribuf);
7a0b56
7a0b56
	ictx->ctx.errinfp  = &ictx->ctx.erriptr[0];
7a0b56
	ictx->ctx.erricap  = &ictx->ctx.erriptr[--elements];
7a0b56
25e033
	ictx->meta = meta;
f46039
	ictx->ctx.ctx.units = ictx->units;
7a0b56
	ictx->ctx.ctx.errv  = ictx->ctx.errinfp;
f46039
	return &ictx->ctx;
f46039
}
f46039
4b561b
static int sfrt_get_driver_ctx_fail(struct argv_meta * meta)
f46039
{
f46039
	argv_free(meta);
f46039
	return -1;
f46039
}
f46039
f46039
int sfrt_get_driver_ctx(
4a749a
	char **				argv,
4a749a
	char **				envp,
4d5fdf
	uint32_t			flags,
4d5fdf
	struct sfrt_driver_ctx **	pctx)
f46039
{
f46039
	struct sfrt_driver_ctx_impl *	ctx;
927287
	struct sfrt_common_ctx		cctx;
a04059
	const struct argv_option *	optv[SFRT_OPTV_ELEMENTS];
f46039
	struct argv_meta *		meta;
f46039
	struct argv_entry *		entry;
f46039
	size_t				nunits;
f46039
	const char *			program;
f46039
a862c4
	(void)envp;
a862c4
a04059
	argv_optv_init(sfrt_default_options,optv);
f46039
871a4f
	if (!(meta = argv_get(
871a4f
			argv,optv,
871a4f
			sfrt_argv_flags(flags),
871a4f
			STDERR_FILENO)))
f46039
		return -1;
f46039
f46039
	nunits	= 0;
f46039
	program = argv_program_name(argv[0]);
927287
	memset(&cctx,0,sizeof(cctx));
7247c3
	cctx.drvflags = flags;
f46039
f46039
	if (!argv[1] && (flags & SFRT_DRIVER_VERBOSITY_USAGE))
a04059
		return sfrt_driver_usage(program,0,optv,meta);
f46039
f46039
	/* get options, count units */
f46039
	for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
f46039
		if (entry->fopt) {
f46039
			switch (entry->tag) {
f46039
				case TAG_HELP:
f46039
					if (flags & SFRT_DRIVER_VERBOSITY_USAGE)
a04059
						return sfrt_driver_usage(program,entry->arg,optv,meta);
f46039
f46039
				case TAG_VERSION:
927287
					cctx.drvflags |= SFRT_DRIVER_VERSION;
f46039
					break;
bbc20f
/* dummy */
bbc20f
/* dummy */			case TAG_OUTPUT_DUMMY:
927287
/* dummy */				cctx.anystring = entry->arg;
bbc20f
/* dummy */				break;
bbc20f
/* dummy */
bbc20f
/* dummy */			case TAG_OUTPUT_PROPERTY:
bbc20f
/* dummy */				if (!(strcmp(entry->arg,"name")))
927287
/* dummy */					cctx.actflags |= SFRT_OUTPUT_NAME;
bbc20f
/* dummy */				else if (!(strcmp(entry->arg,"address")))
927287
/* dummy */					cctx.actflags |= SFRT_OUTPUT_ADDRESS;
bbc20f
/* dummy */				break;
f46039
			}
f46039
		} else
f46039
			nunits++;
f46039
	}
f46039
b1b699
	if (!(ctx = sfrt_driver_ctx_alloc(meta,&cctx,nunits)))
f46039
		return sfrt_get_driver_ctx_fail(meta);
f46039
f46039
	ctx->ctx.program	= program;
f46039
	ctx->ctx.cctx		= &ctx->cctx;
f46039
f46039
	*pctx = &ctx->ctx;
f46039
	return SFRT_OK;
f46039
}
f46039
333bf0
int sfrt_create_driver_ctx(
333bf0
	const struct sfrt_common_ctx *	cctx,
333bf0
	struct sfrt_driver_ctx **	pctx)
333bf0
{
a04059
	const struct argv_option *	optv[SFRT_OPTV_ELEMENTS];
333bf0
	struct argv_meta *		meta;
333bf0
	struct sfrt_driver_ctx_impl *	ctx;
4a749a
	char *				argv[] = {"sofort_driver",0};
333bf0
a04059
	argv_optv_init(sfrt_default_options,optv);
a04059
871a4f
	if (!(meta = argv_get(argv,optv,0,STDERR_FILENO)))
333bf0
		return -1;
333bf0
b1b699
	if (!(ctx = sfrt_driver_ctx_alloc(meta,cctx,0)))
333bf0
		return sfrt_get_driver_ctx_fail(0);
333bf0
333bf0
	ctx->ctx.cctx = &ctx->cctx;
333bf0
	memcpy(&ctx->cctx,cctx,sizeof(*cctx));
333bf0
	*pctx = &ctx->ctx;
333bf0
	return SFRT_OK;
333bf0
}
333bf0
f46039
static void sfrt_free_driver_ctx_impl(struct sfrt_driver_ctx_alloc * ictx)
f46039
{
f46039
	argv_free(ictx->meta);
f46039
	free(ictx);
f46039
}
f46039
f46039
void sfrt_free_driver_ctx(struct sfrt_driver_ctx * ctx)
f46039
{
f46039
	struct sfrt_driver_ctx_alloc *	ictx;
f46039
	uintptr_t			addr;
f46039
f46039
	if (ctx) {
1cf7fa
		addr = (uintptr_t)ctx - offsetof(struct sfrt_driver_ctx_impl,ctx);
1cf7fa
		addr = addr - offsetof(struct sfrt_driver_ctx_alloc,ctx);
f46039
		ictx = (struct sfrt_driver_ctx_alloc *)addr;
f46039
		sfrt_free_driver_ctx_impl(ictx);
f46039
	}
f46039
}
1f115d
1f115d
const struct sfrt_source_version * sfrt_source_version(void)
1f115d
{
1f115d
	return &sfrt_src_version;
1f115d
}