summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/driver/slbt_driver_ctx.c493
-rw-r--r--src/driver/slbt_split_argv.c509
-rw-r--r--src/internal/slibtool_driver_impl.h23
3 files changed, 534 insertions, 491 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index ec468a2..2eee876 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -48,9 +48,6 @@ static const struct slbt_fd_ctx slbt_default_fdctx = {
.fdlog = (-1),
};
-/* default compiler argv */
-static char * slbt_default_cargv[] = {"cc",0};
-
static const char aclr_reset [] = "\x1b[0m";
static const char aclr_bold [] = "\x1b[1m";
static const char aclr_red [] = "\x1b[31m";
@@ -94,7 +91,7 @@ static void slbt_output_raw_vector(int fderr, char ** argv, char ** envp, bool f
slbt_dprintf(fderr,"%s\n\n",fcolor ? aclr_reset : "");
}
-static uint64_t slbt_argv_flags(uint64_t flags)
+uint64_t slbt_argv_flags(uint64_t flags)
{
uint32_t ret = 0;
@@ -137,7 +134,7 @@ static int slbt_free_argv_buffer(
return -1;
}
-static int slbt_driver_usage(
+int slbt_driver_usage(
int fdout,
const char * program,
const char * arg,
@@ -224,492 +221,6 @@ static int slbt_get_driver_ctx_fail(
return -1;
}
-static int slbt_split_argv(
- char ** argv,
- uint64_t flags,
- struct slbt_split_vector * sargv,
- struct slbt_obj_list ** aobjlistv,
- int fderr,
- int fdcwd)
-{
- int i;
- int argc;
- int objc;
- const char * program;
- char * compiler;
- char * csysroot;
- char ** dargv;
- char ** targv;
- char ** cargv;
- char ** objp;
- struct slbt_obj_list * objlistv;
- struct slbt_obj_list * objlistp;
- char * dst;
- bool flast;
- bool fcopy;
- bool altmode;
- size_t size;
- const char * base;
- struct argv_meta * meta;
- struct argv_entry * entry;
- struct argv_entry * mode;
- struct argv_entry * help;
- struct argv_entry * version;
- struct argv_entry * config;
- struct argv_entry * finish;
- struct argv_entry * features;
- struct argv_entry * ccwrap;
- struct argv_entry * dumpmachine;
- struct argv_entry * aropt;
- const struct argv_option ** popt;
- const struct argv_option ** optout;
- const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
- 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 ((altmode = (flags & SLBT_DRIVER_MODE_AR))) {
- argv_optv_init(slbt_ar_options,optv);
- } else {
- argv_optv_init(slbt_default_options,optv);
- }
-
-
- if (!argv[1] && !altmode && (flags & SLBT_DRIVER_VERBOSITY_USAGE))
- return slbt_driver_usage(
- fderr,program,
- 0,optv,0,sargv,0,
- !!getenv("NO_COLOR"));
-
- /* initial argv scan: ... --mode=xxx ... <compiler> ... */
- argv_scan(argv,optv,&ctx,0);
-
- /* invalid slibtool arguments? */
- if (ctx.erridx && !ctx.unitidx && altmode) {
- if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
- argv_get(
- argv,optv,
- slbt_argv_flags(flags),
- fderr);
- return -1;
- }
-
- /* error possibly due to an altmode argument? */
- if (ctx.erridx && !ctx.unitidx)
- ctx.unitidx = ctx.erridx;
-
- /* obtain slibtool's own arguments */
- if (ctx.unitidx) {
- compiler = argv[ctx.unitidx];
- argv[ctx.unitidx] = 0;
-
- meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr);
- argv[ctx.unitidx] = compiler;
- } else {
- meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr);
- }
-
- if (!meta) {
- if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
- argv_get(
- argv,optv,
- slbt_argv_flags(flags),
- fderr);
- return -1;
- }
-
- /* missing all of --mode, --help, --version, --config, --dumpmachine, --features, and --finish? */
- mode = help = version = config = finish = features = ccwrap = dumpmachine = aropt = 0;
-
- for (entry=meta->entries; entry->fopt; entry++)
- if (entry->tag == TAG_MODE)
- mode = entry;
- else if (entry->tag == TAG_HELP)
- help = entry;
- else if (entry->tag == TAG_VERSION)
- version = entry;
- else if (entry->tag == TAG_CONFIG)
- config = entry;
- else if (entry->tag == TAG_FINISH)
- finish = entry;
- else if (entry->tag == TAG_FEATURES)
- features = entry;
- else if (entry->tag == TAG_CCWRAP)
- ccwrap = entry;
- else if (entry->tag == TAG_DUMPMACHINE)
- dumpmachine = entry;
-
- /* alternate execusion mode? */
- if (!altmode && mode && !strcmp(mode->arg,"ar"))
- aropt = mode;
-
- /* release temporary argv meta context */
- argv_free(meta);
-
- /* error not due to an altmode argument? */
- if (!aropt && ctx.erridx && (ctx.erridx == ctx.unitidx)) {
- if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
- argv_get(
- argv,optv,
- slbt_argv_flags(flags),
- fderr);
- return -1;
- }
-
- if (!mode && !help && !version && !config && !finish && !features && !dumpmachine && !altmode) {
- slbt_dprintf(fderr,
- "%s: error: --mode must be specified.\n",
- program);
- return -1;
- }
-
- /* missing compiler? */
- if (!ctx.unitidx && !help && !version && !finish && !features && !dumpmachine && !altmode && !aropt) {
- if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
- slbt_dprintf(fderr,
- "%s: error: <compiler> is missing.\n",
- program);
- return -1;
- }
-
- /* 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;
-
- else if (!(*aobjlistv = calloc(argc,sizeof(**aobjlistv)))) {
- free(sargv->dargv);
- free(sargv->dargs);
- return -1;
- }
-
- objlistv = *aobjlistv;
- objlistp = objlistv;
- csysroot = 0;
-
- for (i=0,flast=false,dargv=sargv->dargv,dst=sargv->dargs; i<argc; i++) {
- if ((fcopy = (flast || altmode || aropt))) {
- (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],"-Xlinker")) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'W';
- *dst++ = 'l';
- *dst++ = ',';
- strcpy(dst,argv[++i]);
- dst += strlen(dst)+1;
-
- } 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 if (!strcmp(argv[i],"--sysroot") && (i<ctx.unitidx)) {
- *dargv++ = dst;
- csysroot = dst;
- strcpy(dst,argv[i]);
- dst[9] = '=';
- strcpy(&dst[10],argv[++i]);
- dst += strlen(dst)+1;
- ctx.unitidx--;
-
- } else if (!strncmp(argv[i],"--sysroot=",10) && (i<ctx.unitidx)) {
- *dargv++ = dst;
- csysroot = dst;
- strcpy(dst,argv[i]);
- dst += strlen(dst)+1;
-
- } else if (!strcmp(argv[i],"-objectlist")) {
- *dargv++ = dst;
- strcpy(dst,argv[i++]);
- dst += strlen(dst)+1;
-
- objlistp->name = dst;
- objlistp++;
- fcopy = true;
-
- } 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;
-
- /* iterate through the object list vector: map, parse, store */
- for (objlistp=objlistv; objlistp->name; objlistp++)
- if (slbt_objlist_read(fdcwd,objlistp) < 0)
- return -1;
-
- for (objc=0,objlistp=objlistv; objlistp->name; objlistp++)
- objc += objlistp->objc;
-
- /* allocate split vectors, account for cargv's added sysroot */
- if ((sargv->targv = calloc(objc + 2*(argc+3),sizeof(char *))))
- sargv->cargv = sargv->targv + argc + 2;
- else
- return -1;
-
- /* --features and no <compiler>? */
- if (ctx.unitidx) {
- (void)0;
-
- } else if (help || version || features || dumpmachine || altmode) {
- for (i=0; i<argc; i++)
- sargv->targv[i] = argv[i];
-
- sargv->cargv = altmode ? sargv->targv : slbt_default_cargv;
-
- return 0;
- }
-
- /* --mode=ar and no ar-specific arguments? */
- if (aropt && !ctx.unitidx)
- ctx.unitidx = argc;
-
- /* split vectors: slibtool's own options */
- for (i=0; i<ctx.unitidx; i++)
- sargv->targv[i] = argv[i];
-
- /* split vector marks */
- targv = sargv->targv + i;
- cargv = sargv->cargv;
-
- /* known wrappers */
- if (ctx.unitidx && !ccwrap && !aropt) {
- if ((base = strrchr(argv[i],'/')))
- base++;
- else if ((base = strrchr(argv[i],'\\')))
- base++;
- else
- base = argv[i];
-
- if (!strcmp(base,"ccache")
- || !strcmp(base,"distcc")
- || !strcmp(base,"compiler")
- || !strcmp(base,"purify")) {
- *targv++ = "--ccwrap";
- *targv++ = argv[i++];
- }
- }
-
- /* split vectors: legacy mixture */
- for (optout=optv; optout[0] && (optout[0]->tag != TAG_OUTPUT); optout++)
- (void)0;
-
- /* compiler, archiver, etc. */
- if (altmode) {
- i = 0;
- } else if (aropt) {
- *cargv++ = argv[0];
- } else {
- *cargv++ = argv[i++];
- }
-
- /* sysroot */
- if (csysroot)
- *cargv++ = csysroot;
-
- /* remaining vector */
- for (objlistp=objlistv; i<argc; i++) {
- if (aropt && (i >= ctx.unitidx)) {
- *cargv++ = argv[i];
-
- } else if (argv[i][0] != '-') {
- if (argv[i+1] && (argv[i+1][0] == '+')
- && (argv[i+1][1] == '=')
- && (argv[i+1][2] == 0)
- && !(strrchr(argv[i],'.')))
- /* libfoo_la_LDFLAGS += -Wl,.... */
- i++;
- else
- *cargv++ = argv[i];
-
- /* must capture -objectlist prior to -o */
- } else if (!(strcmp("objectlist",&argv[i][1]))) {
- for (objp=objlistp->objv; *objp; objp++)
- *cargv++ = *objp;
-
- i++;
- objlistp++;
-
- } else if (argv[i][1] == 'o') {
- *targv++ = argv[i];
-
- if (argv[i][2] == 0)
- *targv++ = argv[++i];
- } else if ((argv[i][1] == 'W') && (argv[i][2] == 'c')) {
- *cargv++ = argv[i];
-
- } else if (!(strcmp("Xcompiler",&argv[i][1]))) {
- *cargv++ = argv[++i];
-
- } else if (!(strcmp("XCClinker",&argv[i][1]))) {
- *cargv++ = argv[++i];
-
- } else if ((argv[i][1] == 'R') && (argv[i][2] == 0)) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (argv[i][1] == 'R') {
- *targv++ = argv[i];
-
- } else if (!(strncmp("-target=",&argv[i][1],8))) {
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strcmp("-target",&argv[i][1]))) {
- *cargv++ = argv[i];
- *targv++ = argv[i++];
-
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strcmp("target",&argv[i][1]))) {
- *cargv++ = argv[i];
- *targv++ = argv[i++];
-
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strncmp("-sysroot=",&argv[i][1],9))) {
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strcmp("-sysroot",&argv[i][1]))) {
- *cargv++ = argv[i];
- *targv++ = argv[i++];
-
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strcmp("bindir",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("shrext",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("rpath",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("release",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("dlopen",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("weak",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("static-libtool-libs",&argv[i][1]))) {
- *targv++ = argv[i];
-
- } else if (!(strcmp("export-dynamic",&argv[i][1]))) {
- *targv++ = argv[i];
-
- } else if (!(strcmp("export-symbols",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("export-symbols-regex",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("version-info",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("version-number",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("dlpreopen",&argv[i][1]))) {
- (void)0;
-
- } else {
- for (popt=optout; popt[0] && popt[0]->long_name; popt++)
- if (!(strcmp(popt[0]->long_name,&argv[i][1])))
- break;
-
- if (popt[0] && popt[0]->long_name)
- *targv++ = argv[i];
- else
- *cargv++ = argv[i];
- }
- }
-
- return 0;
-}
-
static int slbt_init_version_info(
struct slbt_driver_ctx_impl * ictx,
diff --git a/src/driver/slbt_split_argv.c b/src/driver/slbt_split_argv.c
new file mode 100644
index 0000000..8ec189b
--- /dev/null
+++ b/src/driver/slbt_split_argv.c
@@ -0,0 +1,509 @@
+/*******************************************************************/
+/* slibtool: a skinny libtool implementation, written in C */
+/* Copyright (C) 2016--2021 SysDeer Technologies, LLC */
+/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
+/*******************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#define ARGV_DRIVER
+
+#include <slibtool/slibtool.h>
+#include "slibtool_version.h"
+#include "slibtool_driver_impl.h"
+#include "slibtool_objlist_impl.h"
+#include "slibtool_errinfo_impl.h"
+#include "slibtool_ar_impl.h"
+#include "argv/argv.h"
+
+static char * slbt_default_cargv[] = {"cc",0};
+
+int slbt_split_argv(
+ char ** argv,
+ uint64_t flags,
+ struct slbt_split_vector * sargv,
+ struct slbt_obj_list ** aobjlistv,
+ int fderr,
+ int fdcwd)
+{
+ int i;
+ int argc;
+ int objc;
+ const char * program;
+ char * compiler;
+ char * csysroot;
+ char ** dargv;
+ char ** targv;
+ char ** cargv;
+ char ** objp;
+ struct slbt_obj_list * objlistv;
+ struct slbt_obj_list * objlistp;
+ char * dst;
+ bool flast;
+ bool fcopy;
+ bool altmode;
+ size_t size;
+ const char * base;
+ struct argv_meta * meta;
+ struct argv_entry * entry;
+ struct argv_entry * mode;
+ struct argv_entry * help;
+ struct argv_entry * version;
+ struct argv_entry * config;
+ struct argv_entry * finish;
+ struct argv_entry * features;
+ struct argv_entry * ccwrap;
+ struct argv_entry * dumpmachine;
+ struct argv_entry * aropt;
+ const struct argv_option ** popt;
+ const struct argv_option ** optout;
+ const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
+ 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 ((altmode = (flags & SLBT_DRIVER_MODE_AR))) {
+ argv_optv_init(slbt_ar_options,optv);
+ } else {
+ argv_optv_init(slbt_default_options,optv);
+ }
+
+
+ if (!argv[1] && !altmode && (flags & SLBT_DRIVER_VERBOSITY_USAGE))
+ return slbt_driver_usage(
+ fderr,program,
+ 0,optv,0,sargv,0,
+ !!getenv("NO_COLOR"));
+
+ /* initial argv scan: ... --mode=xxx ... <compiler> ... */
+ argv_scan(argv,optv,&ctx,0);
+
+ /* invalid slibtool arguments? */
+ if (ctx.erridx && !ctx.unitidx && altmode) {
+ if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
+ argv_get(
+ argv,optv,
+ slbt_argv_flags(flags),
+ fderr);
+ return -1;
+ }
+
+ /* error possibly due to an altmode argument? */
+ if (ctx.erridx && !ctx.unitidx)
+ ctx.unitidx = ctx.erridx;
+
+ /* obtain slibtool's own arguments */
+ if (ctx.unitidx) {
+ compiler = argv[ctx.unitidx];
+ argv[ctx.unitidx] = 0;
+
+ meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr);
+ argv[ctx.unitidx] = compiler;
+ } else {
+ meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr);
+ }
+
+ if (!meta) {
+ if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
+ argv_get(
+ argv,optv,
+ slbt_argv_flags(flags),
+ fderr);
+ return -1;
+ }
+
+ /* missing all of --mode, --help, --version, --config, --dumpmachine, --features, and --finish? */
+ mode = help = version = config = finish = features = ccwrap = dumpmachine = aropt = 0;
+
+ for (entry=meta->entries; entry->fopt; entry++)
+ if (entry->tag == TAG_MODE)
+ mode = entry;
+ else if (entry->tag == TAG_HELP)
+ help = entry;
+ else if (entry->tag == TAG_VERSION)
+ version = entry;
+ else if (entry->tag == TAG_CONFIG)
+ config = entry;
+ else if (entry->tag == TAG_FINISH)
+ finish = entry;
+ else if (entry->tag == TAG_FEATURES)
+ features = entry;
+ else if (entry->tag == TAG_CCWRAP)
+ ccwrap = entry;
+ else if (entry->tag == TAG_DUMPMACHINE)
+ dumpmachine = entry;
+
+ /* alternate execusion mode? */
+ if (!altmode && mode && !strcmp(mode->arg,"ar"))
+ aropt = mode;
+
+ /* release temporary argv meta context */
+ argv_free(meta);
+
+ /* error not due to an altmode argument? */
+ if (!aropt && ctx.erridx && (ctx.erridx == ctx.unitidx)) {
+ if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
+ argv_get(
+ argv,optv,
+ slbt_argv_flags(flags),
+ fderr);
+ return -1;
+ }
+
+ if (!mode && !help && !version && !config && !finish && !features && !dumpmachine && !altmode) {
+ slbt_dprintf(fderr,
+ "%s: error: --mode must be specified.\n",
+ program);
+ return -1;
+ }
+
+ /* missing compiler? */
+ if (!ctx.unitidx && !help && !version && !finish && !features && !dumpmachine && !altmode && !aropt) {
+ if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
+ slbt_dprintf(fderr,
+ "%s: error: <compiler> is missing.\n",
+ program);
+ return -1;
+ }
+
+ /* 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;
+
+ else if (!(*aobjlistv = calloc(argc,sizeof(**aobjlistv)))) {
+ free(sargv->dargv);
+ free(sargv->dargs);
+ return -1;
+ }
+
+ objlistv = *aobjlistv;
+ objlistp = objlistv;
+ csysroot = 0;
+
+ for (i=0,flast=false,dargv=sargv->dargv,dst=sargv->dargs; i<argc; i++) {
+ if ((fcopy = (flast || altmode || aropt))) {
+ (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],"-Xlinker")) {
+ *dargv++ = dst;
+ *dst++ = '-';
+ *dst++ = 'W';
+ *dst++ = 'l';
+ *dst++ = ',';
+ strcpy(dst,argv[++i]);
+ dst += strlen(dst)+1;
+
+ } 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 if (!strcmp(argv[i],"--sysroot") && (i<ctx.unitidx)) {
+ *dargv++ = dst;
+ csysroot = dst;
+ strcpy(dst,argv[i]);
+ dst[9] = '=';
+ strcpy(&dst[10],argv[++i]);
+ dst += strlen(dst)+1;
+ ctx.unitidx--;
+
+ } else if (!strncmp(argv[i],"--sysroot=",10) && (i<ctx.unitidx)) {
+ *dargv++ = dst;
+ csysroot = dst;
+ strcpy(dst,argv[i]);
+ dst += strlen(dst)+1;
+
+ } else if (!strcmp(argv[i],"-objectlist")) {
+ *dargv++ = dst;
+ strcpy(dst,argv[i++]);
+ dst += strlen(dst)+1;
+
+ objlistp->name = dst;
+ objlistp++;
+ fcopy = true;
+
+ } 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;
+
+ /* iterate through the object list vector: map, parse, store */
+ for (objlistp=objlistv; objlistp->name; objlistp++)
+ if (slbt_objlist_read(fdcwd,objlistp) < 0)
+ return -1;
+
+ for (objc=0,objlistp=objlistv; objlistp->name; objlistp++)
+ objc += objlistp->objc;
+
+ /* allocate split vectors, account for cargv's added sysroot */
+ if ((sargv->targv = calloc(objc + 2*(argc+3),sizeof(char *))))
+ sargv->cargv = sargv->targv + argc + 2;
+ else
+ return -1;
+
+ /* --features and no <compiler>? */
+ if (ctx.unitidx) {
+ (void)0;
+
+ } else if (help || version || features || dumpmachine || altmode) {
+ for (i=0; i<argc; i++)
+ sargv->targv[i] = argv[i];
+
+ sargv->cargv = altmode ? sargv->targv : slbt_default_cargv;
+
+ return 0;
+ }
+
+ /* --mode=ar and no ar-specific arguments? */
+ if (aropt && !ctx.unitidx)
+ ctx.unitidx = argc;
+
+ /* split vectors: slibtool's own options */
+ for (i=0; i<ctx.unitidx; i++)
+ sargv->targv[i] = argv[i];
+
+ /* split vector marks */
+ targv = sargv->targv + i;
+ cargv = sargv->cargv;
+
+ /* known wrappers */
+ if (ctx.unitidx && !ccwrap && !aropt) {
+ if ((base = strrchr(argv[i],'/')))
+ base++;
+ else if ((base = strrchr(argv[i],'\\')))
+ base++;
+ else
+ base = argv[i];
+
+ if (!strcmp(base,"ccache")
+ || !strcmp(base,"distcc")
+ || !strcmp(base,"compiler")
+ || !strcmp(base,"purify")) {
+ *targv++ = "--ccwrap";
+ *targv++ = argv[i++];
+ }
+ }
+
+ /* split vectors: legacy mixture */
+ for (optout=optv; optout[0] && (optout[0]->tag != TAG_OUTPUT); optout++)
+ (void)0;
+
+ /* compiler, archiver, etc. */
+ if (altmode) {
+ i = 0;
+ } else if (aropt) {
+ *cargv++ = argv[0];
+ } else {
+ *cargv++ = argv[i++];
+ }
+
+ /* sysroot */
+ if (csysroot)
+ *cargv++ = csysroot;
+
+ /* remaining vector */
+ for (objlistp=objlistv; i<argc; i++) {
+ if (aropt && (i >= ctx.unitidx)) {
+ *cargv++ = argv[i];
+
+ } else if (argv[i][0] != '-') {
+ if (argv[i+1] && (argv[i+1][0] == '+')
+ && (argv[i+1][1] == '=')
+ && (argv[i+1][2] == 0)
+ && !(strrchr(argv[i],'.')))
+ /* libfoo_la_LDFLAGS += -Wl,.... */
+ i++;
+ else
+ *cargv++ = argv[i];
+
+ /* must capture -objectlist prior to -o */
+ } else if (!(strcmp("objectlist",&argv[i][1]))) {
+ for (objp=objlistp->objv; *objp; objp++)
+ *cargv++ = *objp;
+
+ i++;
+ objlistp++;
+
+ } else if (argv[i][1] == 'o') {
+ *targv++ = argv[i];
+
+ if (argv[i][2] == 0)
+ *targv++ = argv[++i];
+ } else if ((argv[i][1] == 'W') && (argv[i][2] == 'c')) {
+ *cargv++ = argv[i];
+
+ } else if (!(strcmp("Xcompiler",&argv[i][1]))) {
+ *cargv++ = argv[++i];
+
+ } else if (!(strcmp("XCClinker",&argv[i][1]))) {
+ *cargv++ = argv[++i];
+
+ } else if ((argv[i][1] == 'R') && (argv[i][2] == 0)) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (argv[i][1] == 'R') {
+ *targv++ = argv[i];
+
+ } else if (!(strncmp("-target=",&argv[i][1],8))) {
+ *cargv++ = argv[i];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("-target",&argv[i][1]))) {
+ *cargv++ = argv[i];
+ *targv++ = argv[i++];
+
+ *cargv++ = argv[i];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("target",&argv[i][1]))) {
+ *cargv++ = argv[i];
+ *targv++ = argv[i++];
+
+ *cargv++ = argv[i];
+ *targv++ = argv[i];
+
+ } else if (!(strncmp("-sysroot=",&argv[i][1],9))) {
+ *cargv++ = argv[i];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("-sysroot",&argv[i][1]))) {
+ *cargv++ = argv[i];
+ *targv++ = argv[i++];
+
+ *cargv++ = argv[i];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("bindir",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("shrext",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("rpath",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("release",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("dlopen",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("weak",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("static-libtool-libs",&argv[i][1]))) {
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("export-dynamic",&argv[i][1]))) {
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("export-symbols",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("export-symbols-regex",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("version-info",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("version-number",&argv[i][1]))) {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+
+ } else if (!(strcmp("dlpreopen",&argv[i][1]))) {
+ (void)0;
+
+ } else {
+ for (popt=optout; popt[0] && popt[0]->long_name; popt++)
+ if (!(strcmp(popt[0]->long_name,&argv[i][1])))
+ break;
+
+ if (popt[0] && popt[0]->long_name)
+ *targv++ = argv[i];
+ else
+ *cargv++ = argv[i];
+ }
+ }
+
+ return 0;
+}
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index 32ae6c8..9a32c9b 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -169,6 +169,29 @@ struct slbt_archive_ctx_impl {
};
+uint64_t slbt_argv_flags(uint64_t flags);
+
+
+int slbt_driver_usage(
+ int fdout,
+ const char * program,
+ const char * arg,
+ const struct argv_option ** optv,
+ struct argv_meta * meta,
+ struct slbt_split_vector * sargv,
+ struct slbt_obj_list * objlistv,
+ int noclr);
+
+
+int slbt_split_argv(
+ char ** argv,
+ uint64_t flags,
+ struct slbt_split_vector * sargv,
+ struct slbt_obj_list ** aobjlistv,
+ int fderr,
+ int fdcwd);
+
+
int slbt_init_host_params(
const struct slbt_driver_ctx * dctx,
const struct slbt_common_ctx * cctx,