From: Sunil Dora Date: Thu, 11 Jun 2026 12:50:20 +0000 (+0530) Subject: Port expandargstr from gcc/libiberty X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcca095929a12ac590c62ff3ea680154b7f44705;p=thirdparty%2Fbinutils-gdb.git Port expandargstr from gcc/libiberty Sync recent changes to libiberty. include/ChangeLog: * libiberty.h (expandargstr): Declare. libiberty/ChangeLog: * argv.c (expandargstr): New function. Signed-off-by: Sunil Dora --- diff --git a/include/libiberty.h b/include/libiberty.h index 1af4fa86101..bdb491b9b37 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -94,6 +94,11 @@ extern int writeargv (char * const *, FILE *); extern int countargv (char * const *); +/* Expand VAL as a response file if it begins with '@' and return the + result as a shell-quoted string. */ + +extern char *expandargstr (const char *, const char *); + /* Return the last component of a path name. Note that we can't use a prototype here because the parameter is declared inconsistently across different systems, sometimes as "char *" and sometimes as diff --git a/libiberty/argv.c b/libiberty/argv.c index 64127f70c99..35e2750c5ff 100644 --- a/libiberty/argv.c +++ b/libiberty/argv.c @@ -492,6 +492,81 @@ countargv (char * const *argv) return argc; } +/* + +@deftypefn Extension {char *} expandargstr @ + (const char *@var{progname}, const char *@var{val}) + +Expand @var{val} as a response file via @code{expandargv} if it begins +with @samp{@@}, using @var{progname} as @code{argv[0]}, and return the +expanded option list as a shell-quoted string. Returns a newly +allocated string. + +@end deftypefn + +*/ + +char * +expandargstr (const char *progname, const char *val) +{ + int argc = 2; + char **argv; + char **orig; + size_t len; + char *buf; + char *p; + int i; + + if (val[0] != '@') + return xstrdup (val); + + argv = (char **) xcalloc (3, sizeof (char *)); + orig = argv; + argv[0] = xstrdup (progname); + argv[1] = xstrdup (val); + argv[2] = NULL; + expandargv (&argc, &argv); + if (argv != orig) + freeargv (orig); + + len = 1; + for (i = 1; argv[i] != NULL; i++) + { + const char *q; + if (i > 1) + len++; + len += 2; + for (q = argv[i]; *q; q++) + len += (*q == '\'') ? 4 : 1; + } + + buf = (char *) xmalloc (len); + p = buf; + for (i = 1; argv[i] != NULL; i++) + { + const char *q; + if (i > 1) + *p++ = ' '; + *p++ = '\''; + for (q = argv[i]; *q; q++) + { + if (*q == '\'') + { + *p++ = '\''; + *p++ = '\\'; + *p++ = '\''; + *p++ = '\''; + } + else + *p++ = *q; + } + *p++ = '\''; + } + *p = '\0'; + freeargv (argv); + return buf; +} + #ifdef MAIN /* Simple little test driver. */