summaryrefslogtreecommitdiffhomepage
path: root/src/driver/slbt_driver_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/driver/slbt_driver_ctx.c')
-rw-r--r--src/driver/slbt_driver_ctx.c151
1 files changed, 129 insertions, 22 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index 401bb43..cac449e 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -5,6 +5,7 @@
/*******************************************************************/
#include <stdint.h>
+#include <string.h>
#include <unistd.h>
#include <fcntl.h>
@@ -69,11 +70,6 @@ static const char aclr_blue [] = "\x1b[34m";
static const char aclr_cyan [] = "\x1b[36m";
static const char aclr_white [] = "\x1b[37m";
-struct slbt_split_vector {
- char ** targv;
- char ** cargv;
-};
-
struct slbt_driver_ctx_alloc {
struct argv_meta * meta;
struct slbt_driver_ctx_impl ctx;
@@ -130,12 +126,27 @@ static uint32_t slbt_argv_flags(uint32_t flags)
return ret;
}
+static int slbt_free_argv_buffer(struct slbt_split_vector * sargv)
+{
+ if (sargv->dargs)
+ free(sargv->dargs);
+
+ if (sargv->dargv)
+ free(sargv->dargv);
+
+ if (sargv->targv)
+ free(sargv->targv);
+
+ return -1;
+}
+
static int slbt_driver_usage(
int fdout,
const char * program,
const char * arg,
const struct argv_option ** optv,
- struct argv_meta * meta)
+ struct argv_meta * meta,
+ struct slbt_split_vector * sargv)
{
char header[512];
@@ -145,6 +156,7 @@ static int slbt_driver_usage(
argv_usage(fdout,header,optv,arg);
argv_free(meta);
+ slbt_free_argv_buffer(sargv);
return SLBT_USAGE;
}
@@ -152,7 +164,8 @@ static int slbt_driver_usage(
static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc(
struct argv_meta * meta,
const struct slbt_fd_ctx * fdctx,
- const struct slbt_common_ctx * cctx)
+ const struct slbt_common_ctx * cctx,
+ struct slbt_split_vector * sargv)
{
struct slbt_driver_ctx_alloc * ictx;
size_t size;
@@ -160,8 +173,15 @@ static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc(
size = sizeof(struct slbt_driver_ctx_alloc);
- if (!(ictx = calloc(1,size)))
+ if (!(ictx = calloc(1,size))) {
+ slbt_free_argv_buffer(sargv);
return 0;
+ }
+
+ ictx->ctx.dargs = sargv->dargs;
+ ictx->ctx.dargv = sargv->dargv;
+ ictx->ctx.targv = sargv->targv;
+ ictx->ctx.cargv = sargv->cargv;
memcpy(&ictx->ctx.fdctx,fdctx,sizeof(*fdctx));
memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
@@ -200,8 +220,13 @@ static int slbt_split_argv(
int argc;
const char * program;
char * compiler;
+ char ** dargv;
char ** targv;
char ** cargv;
+ char * dst;
+ bool flast;
+ bool fcopy;
+ size_t size;
struct argv_meta * meta;
struct argv_entry * entry;
struct argv_entry * mode;
@@ -223,7 +248,7 @@ static int slbt_split_argv(
if (!argv[1] && (flags & SLBT_DRIVER_VERBOSITY_USAGE))
return slbt_driver_usage(
fderr,program,
- 0,optv,0);
+ 0,optv,0,sargv);
/* initial argv scan: ... --mode=xxx ... <compiler> ... */
argv_scan(argv,optv,&ctx,0);
@@ -280,10 +305,87 @@ static int slbt_split_argv(
return -1;
}
- /* allocate split vectors */
- for (argc=0, targv=argv; *targv; targv++)
- argc++;
+ /* clone and normalize the argv vector (-l, --library) */
+ for (argc=0,size=0,dargv=argv; *dargv; argc++,dargv++)
+ size += strlen(*dargv) + 1;
+
+ if (!(sargv->dargv = calloc(argc+1,sizeof(char *))))
+ return -1;
+ else if (!(sargv->dargs = calloc(1,size+1)))
+ return -1;
+
+ for (i=0,flast=false,dargv=sargv->dargv,dst=sargv->dargs; i<argc; i++) {
+ if ((fcopy = flast)) {
+ (void)0;
+
+ } else if (!strcmp(argv[i],"--")) {
+ flast = true;
+ fcopy = true;
+
+ } else if (!strcmp(argv[i],"-l")) {
+ *dargv++ = dst;
+ *dst++ = '-';
+ *dst++ = 'l';
+ strcpy(dst,argv[++i]);
+ dst += strlen(dst)+1;
+
+ } else if (!strncmp(argv[i],"-l",2)) {
+ fcopy = true;
+
+ } else if (!strcmp(argv[i],"--library")) {
+ *dargv++ = dst;
+ *dst++ = '-';
+ *dst++ = 'l';
+ strcpy(dst,argv[++i]);
+ dst += strlen(dst)+1;
+
+ } else if (!strncmp(argv[i],"--library=",10)) {
+ *dargv++ = dst;
+ *dst++ = '-';
+ *dst++ = 'l';
+ strcpy(dst,&argv[++i][10]);
+ dst += strlen(dst)+1;
+
+ } else if (!strcmp(argv[i],"-L")) {
+ *dargv++ = dst;
+ *dst++ = '-';
+ *dst++ = 'L';
+ strcpy(dst,argv[++i]);
+ dst += strlen(dst)+1;
+
+ } else if (!strncmp(argv[i],"-L",2)) {
+ fcopy = true;
+
+ } else if (!strcmp(argv[i],"--library-path")) {
+ *dargv++ = dst;
+ *dst++ = '-';
+ *dst++ = 'L';
+ strcpy(dst,argv[++i]);
+ dst += strlen(dst)+1;
+
+ } else if (!strncmp(argv[i],"--library-path=",15)) {
+ *dargv++ = dst;
+ *dst++ = '-';
+ *dst++ = 'L';
+ strcpy(dst,&argv[++i][15]);
+ dst += strlen(dst)+1;
+ } else {
+ fcopy = true;
+ }
+
+ if (fcopy) {
+ *dargv++ = dst;
+ strcpy(dst,argv[i]);
+ dst += strlen(dst)+1;
+ }
+ }
+
+ /* update argc,argv */
+ argc = dargv - sargv->dargv;
+ argv = sargv->dargv;
+
+ /* allocate split vectors */
if ((sargv->targv = calloc(2*(argc+1),sizeof(char *))))
sargv->cargv = sargv->targv + argc + 1;
else
@@ -991,14 +1093,19 @@ int slbt_get_driver_ctx(
};
}
+ sargv.dargs = 0;
+ sargv.dargv = 0;
+ sargv.targv = 0;
+ sargv.cargv = 0;
+
if (slbt_split_argv(argv,flags,&sargv,fdctx->fderr))
- return -1;
+ return slbt_free_argv_buffer(&sargv);
if (!(meta = argv_get(
sargv.targv,optv,
- slbt_argv_flags(flags) | ARGV_CLONE_VECTOR,
+ slbt_argv_flags(flags),
fdctx->fderr)))
- return -1;
+ return slbt_free_argv_buffer(&sargv);
lconf = 0;
program = argv_program_name(argv[0]);
@@ -1020,7 +1127,8 @@ int slbt_get_driver_ctx(
if (flags & SLBT_DRIVER_VERBOSITY_USAGE)
return slbt_driver_usage(
fdctx->fdout,program,
- entry->arg,optv,meta);
+ entry->arg,optv,
+ meta,&sargv);
case TAG_VERSION:
cctx.drvflags |= SLBT_DRIVER_VERSION;
@@ -1301,14 +1409,12 @@ int slbt_get_driver_ctx(
cctx.tag = SLBT_TAG_CC;
/* driver context */
- if (!(ctx = slbt_driver_ctx_alloc(meta,fdctx,&cctx)))
+ if (!(ctx = slbt_driver_ctx_alloc(meta,fdctx,&cctx,&sargv)))
return slbt_get_driver_ctx_fail(0,meta);
/* ctx */
ctx->ctx.program = program;
ctx->ctx.cctx = &ctx->cctx;
- ctx->targv = sargv.targv;
- ctx->cargv = sargv.cargv;
ctx->cctx.targv = sargv.targv;
ctx->cctx.cargv = sargv.cargv;
@@ -1370,12 +1476,13 @@ int slbt_get_driver_ctx(
static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx)
{
- if (ictx->ctx.targv)
- free(ictx->ctx.targv);
-
if (ictx->ctx.libname)
free(ictx->ctx.libname);
+ free(ictx->ctx.dargs);
+ free(ictx->ctx.dargv);
+ free(ictx->ctx.targv);
+
slbt_free_host_params(&ictx->ctx.host);
slbt_free_host_params(&ictx->ctx.ahost);
argv_free(ictx->meta);