X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=libiberty%2Fargv.c;h=3084248b96cabd54c7606498cbaa5075873e6394;hb=308d96edc1e82c7bb9440d20b868ee9dd93959ea;hp=e76c1f825d26cb1c2f111f1585222cb6bafaa6bd;hpb=8535fe175a8039d33e9d13dd425abbd6d71ed648;p=deliverable%2Fbinutils-gdb.git diff --git a/libiberty/argv.c b/libiberty/argv.c index e76c1f825d..3084248b96 100644 --- a/libiberty/argv.c +++ b/libiberty/argv.c @@ -119,6 +119,24 @@ void freeargv (char **vector) } } +static void +consume_whitespace (const char **input) +{ + while (ISSPACE (**input)) + { + (*input)++; + } +} + +static int +only_whitespace (const char* input) +{ + while (*input != EOS && ISSPACE (*input)) + input++; + + return (*input == EOS); +} + /* @deftypefn Extension char** buildargv (char *@var{sp}) @@ -179,10 +197,8 @@ char **buildargv (const char *input) do { /* Pick off argv[argc] */ - while (ISBLANK (*input)) - { - input++; - } + consume_whitespace (&input); + if ((maxargc == 0) || (argc >= (maxargc - 1))) { /* argv needs initialization, or expansion */ @@ -278,10 +294,7 @@ char **buildargv (const char *input) argc++; argv[argc] = NULL; - while (ISSPACE (*input)) - { - input++; - } + consume_whitespace (&input); } while (*input != EOS); } @@ -290,6 +303,61 @@ char **buildargv (const char *input) /* +@deftypefn Extension int writeargv (const char **@var{argv}, FILE *@var{file}) + +Write each member of ARGV, handling all necessary quoting, to the file +named by FILE, separated by whitespace. Return 0 on success, non-zero +if an error occurred while writing to FILE. + +@end deftypefn + +*/ + +int +writeargv (char **argv, FILE *f) +{ + int status = 0; + + if (f == NULL) + return 1; + + while (*argv != NULL) + { + const char *arg = *argv; + + while (*arg != EOS) + { + char c = *arg; + + if (ISSPACE(c) || c == '\\' || c == '\'' || c == '"') + if (EOF == fputc ('\\', f)) + { + status = 1; + goto done; + } + + if (EOF == fputc (c, f)) + { + status = 1; + goto done; + } + arg++; + } + + if (EOF == fputc ('\n', f)) + { + status = 1; + goto done; + } + argv++; + } + + done: + return status; +} + +/* + @deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp}) The @var{argcp} and @code{argvp} arguments are pointers to the usual @@ -365,8 +433,17 @@ expandargv (int *argcp, char ***argvp) goto error; /* Add a NUL terminator. */ buffer[len] = '\0'; - /* Parse the string. */ - file_argv = buildargv (buffer); + /* If the file is empty or contains only whitespace, buildargv would + return a single empty argument. In this context we want no arguments, + instead. */ + if (only_whitespace (buffer)) + { + file_argv = (char **) xmalloc (sizeof (char *)); + file_argv[0] = NULL; + } + else + /* Parse the string. */ + file_argv = buildargv (buffer); /* If *ARGVP is not already dynamically allocated, copy it. */ if (!argv_dynamic) { @@ -379,7 +456,7 @@ expandargv (int *argcp, char ***argvp) } /* Count the number of arguments. */ file_argc = 0; - while (file_argv[file_argc] && *file_argv[file_argc]) + while (file_argv[file_argc]) ++file_argc; /* Now, insert FILE_ARGV into ARGV. The "+1" below handles the NULL terminator at the end of ARGV. */