From 56cab3dc4130c61cc5a3205ee6fc8bcc9c3fa403 Mon Sep 17 00:00:00 2001 From: midipix Date: Tue, 8 Mar 2016 08:33:19 -0500 Subject: driver: slbt_split_argv: initial implementation. --- src/driver/slbt_driver_ctx.c | 136 ++++++++++++++++++++++++++++++++++-- src/internal/slibtool_driver_impl.h | 2 + 2 files changed, 134 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c index cdc309d..8d4e861 100644 --- a/src/driver/slbt_driver_ctx.c +++ b/src/driver/slbt_driver_ctx.c @@ -14,6 +14,11 @@ #include "slibtool_driver_impl.h" #include "argv/argv.h" +struct slbt_split_vector { + char ** targv; + char ** cargv; +}; + struct slbt_driver_ctx_alloc { struct argv_meta * meta; struct slbt_driver_ctx_impl ctx; @@ -89,12 +94,130 @@ static int slbt_get_driver_ctx_fail(struct argv_meta * meta) return -1; } +static int slbt_split_argv( + char ** argv, + uint32_t flags, + struct slbt_split_vector * sargv) +{ + int i; + int argc; + const char * program; + char * compiler; + char ** targv; + char ** cargv; + struct argv_meta * meta; + struct argv_entry * entry; + struct argv_entry * mode; + const struct argv_option * option; + const struct argv_option * options = slbt_default_options; + struct argv_ctx ctx = {ARGV_VERBOSITY_NONE, + ARGV_MODE_SCAN, + 0,0,0,0,0,0,0}; + + program = argv_program_name(argv[0]); + + /* missing arguments? */ + if (!argv[1] && (flags & SLBT_DRIVER_VERBOSITY_USAGE)) + return slbt_driver_usage(program,0,options,0); + + /* initial argv scan: ... --mode=xxx ... ... */ + argv_scan(argv,options,&ctx,0); + + /* invalid slibtool arguments? */ + if (ctx.erridx && !ctx.unitidx) { + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + argv_get( + argv,options, + slbt_argv_flags(flags)); + return -1; + } + + /* missing compiler? */ + if (!ctx.unitidx) { + if (flags & SLBT_DRIVER_VERBOSITY_ERRORS) + fprintf(stderr, + "%s: error: is missing.\n", + program); + return -1; + } + + /* obtain slibtool's own arguments */ + compiler = argv[ctx.unitidx]; + argv[ctx.unitidx] = 0; + + meta = argv_get(argv,options,ARGV_VERBOSITY_NONE); + argv[ctx.unitidx] = compiler; + + /* missing --mode? */ + for (mode=0, entry=meta->entries; entry->fopt; entry++) + if (entry->tag == TAG_MODE) + mode = entry; + + argv_free(meta); + + if (!mode) { + fprintf(stderr, + "%s: error: --mode must be specified.\n", + program); + return -1; + } + + /* allocate split vectors */ + for (argc=0, targv=argv; *targv; targv++) + argc++; + + if ((sargv->targv = calloc(2*(argc+1),sizeof(char *)))) + sargv->cargv = sargv->targv + argc + 1; + else + return -1; + + /* split vectors: slibtool's own options */ + for (i=0; itargv[i] = argv[i]; + + /* split vectors: legacy mixture */ + options = option_from_tag( + slbt_default_options, + TAG_OUTPUT); + + targv = sargv->targv + i; + cargv = sargv->cargv; + + for (; ilong_name; option++) + if (!(strcmp(option->long_name,&argv[i][1]))) + break; + + if (option->long_name) + *targv++ = argv[i]; + else + *cargv++ = argv[i]; + } + } + + return 0; +} + int slbt_get_driver_ctx( char ** argv, char ** envp, uint32_t flags, struct slbt_driver_ctx ** pctx) { + struct slbt_split_vector sargv; struct slbt_driver_ctx_impl * ctx; struct slbt_common_ctx cctx; const struct argv_option * options; @@ -105,16 +228,16 @@ int slbt_get_driver_ctx( options = slbt_default_options; - if (!(meta = argv_get(argv,options,slbt_argv_flags(flags)))) + if (slbt_split_argv(argv,flags,&sargv)) + return -1; + + if (!(meta = argv_get(sargv.targv,options,slbt_argv_flags(flags)))) return -1; nunits = 0; program = argv_program_name(argv[0]); memset(&cctx,0,sizeof(cctx)); - if (!argv[1] && (flags & SLBT_DRIVER_VERBOSITY_USAGE)) - return slbt_driver_usage(program,0,options,meta); - /* get options, count units */ for (entry=meta->entries; entry->fopt || entry->arg; entry++) { if (entry->fopt) { @@ -227,6 +350,8 @@ int slbt_get_driver_ctx( ctx->ctx.program = program; ctx->ctx.cctx = &ctx->cctx; + ctx->targv = sargv.targv; + ctx->cargv = sargv.cargv; *pctx = &ctx->ctx; return SLBT_OK; @@ -254,6 +379,9 @@ int slbt_create_driver_ctx( static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx) { + if (ictx->ctx.targv) + free(ictx->ctx.targv); + argv_free(ictx->meta); free(ictx); } diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h index 7160c4c..572539a 100644 --- a/src/internal/slibtool_driver_impl.h +++ b/src/internal/slibtool_driver_impl.h @@ -38,6 +38,8 @@ enum app_tags { struct slbt_driver_ctx_impl { struct slbt_common_ctx cctx; struct slbt_driver_ctx ctx; + char ** targv; + char ** cargv; }; struct slbt_unit_ctx_impl { -- cgit v1.2.3