1
/* Create and destroy argument vectors (argv's)
2
Copyright (C) 1992 Free Software Foundation, Inc.
3
Written by Fred Fish @ Cygnus Support
5
This file is part of the libiberty library.
6
Libiberty is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Library General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
11
Libiberty is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Library General Public
17
License along with libiberty; see the file COPYING.LIB. If
18
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
Boston, MA 02111-1307, USA. */
22
/* Create and destroy argument vectors. An argument vector is simply an
23
array of string pointers, terminated by a NULL pointer. */
26
#include "libiberty.h"
28
#define ISBLANK(ch) ((ch) == ' ' || (ch) == '\t')
30
/* Routines imported from standard C runtime libraries. */
40
#if !defined _WIN32 || defined __GNUC__
41
extern char *memcpy (); /* Copy memory region */
42
extern int strlen (); /* Count length of string */
43
extern char *malloc (); /* Standard memory allocater */
44
extern char *realloc (); /* Standard memory reallocator */
45
extern void free (); /* Free malloc'd memory */
46
extern char *strdup (); /* Duplicate a string */
51
#include "alloca-conf.h"
61
#define INITIAL_MAXARGC 8 /* Number of args + NULL in initial argv */
68
dupargv -- duplicate an argument vector
72
char **dupargv (vector)
77
Duplicate an argument vector. Simply scans through the
78
vector, duplicating each argument until the
79
terminating NULL is found.
83
Returns a pointer to the argument vector if
84
successful. Returns NULL if there is insufficient memory to
85
complete building the argument vector.
100
for (argc = 0; argv[argc] != NULL; argc++);
101
copy = (char **) malloc ((argc + 1) * sizeof (char *));
106
for (argc = 0; argv[argc] != NULL; argc++)
108
int len = strlen (argv[argc]);
109
copy[argc] = malloc (sizeof (char *) * (len + 1));
110
if (copy[argc] == NULL)
115
strcpy (copy[argc], argv[argc]);
125
freeargv -- free an argument vector
129
void freeargv (vector)
134
Free an argument vector that was built using buildargv. Simply scans
135
through the vector, freeing the memory for each argument until the
136
terminating NULL is found, and then frees the vector itself.
144
void freeargv (vector)
147
register char **scan;
151
for (scan = vector; *scan != NULL; scan++)
163
buildargv -- build an argument vector from a string
167
char **buildargv (sp)
172
Given a pointer to a string, parse the string extracting fields
173
separated by whitespace and optionally enclosed within either single
174
or double quotes (which are stripped off), and build a vector of
175
pointers to copies of the string for each field. The input string
178
All of the memory for the pointer array and copies of the string
179
is obtained from malloc. All of the memory can be returned to the
180
system with the single function call freeargv, which takes the
181
returned result of buildargv, as it's argument.
183
The memory for the argv array is dynamically expanded as necessary.
187
Returns a pointer to the argument vector if successful. Returns NULL
188
if the input string pointer is NULL or if there is insufficient
189
memory to complete building the argument vector.
193
In order to provide a working buffer for extracting arguments into,
194
with appropriate stripping of quotes and translation of backslash
195
sequences, we allocate a working buffer at least as long as the input
196
string. This ensures that we always have enough space in which to
197
work, since the extracted arg is never larger than the input string.
199
If the input is a null string (as opposed to a NULL pointer), then
200
buildarg returns an argv that has one arg, a null string.
202
Argv is always kept terminated with a NULL arg pointer, so it can
203
be passed to freeargv at any time, or returned, as appropriate.
206
char **buildargv (input)
221
copybuf = (char *) alloca (strlen (input) + 1);
222
/* Is a do{}while to always execute the loop once. Always return an
223
argv, even for null strings. See NOTES above, test case below. */
226
/* Pick off argv[argc] */
227
while (ISBLANK (*input))
231
if ((maxargc == 0) || (argc >= (maxargc - 1)))
233
/* argv needs initialization, or expansion */
236
maxargc = INITIAL_MAXARGC;
237
nargv = (char **) malloc (maxargc * sizeof (char *));
242
nargv = (char **) realloc (argv, maxargc * sizeof (char *));
256
/* Begin scanning arg */
258
while (*input != EOS)
260
if (ISBLANK (*input) && !squote && !dquote && !bsquote)
271
else if (*input == '\\')
303
else if (*input == '"')
316
argv[argc] = strdup (copybuf);
317
if (argv[argc] == NULL)
326
while (ISBLANK (*input))
331
while (*input != EOS);
338
/* Simple little test driver. */
340
static char *tests[] =
342
"a simple command line",
343
"arg 'foo' is single quoted",
344
"arg \"bar\" is double quoted",
345
"arg \"foo bar\" has embedded whitespace",
346
"arg 'Jack said \\'hi\\'' has single quotes",
347
"arg 'Jack said \\\"hi\\\"' has double quotes",
348
"a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9",
350
/* This should be expanded into only one argument. */
351
"trailing-whitespace ",
363
for (test = tests; *test != NULL; test++)
365
printf ("buildargv(\"%s\")\n", *test);
366
if ((argv = buildargv (*test)) == NULL)
368
printf ("failed!\n\n");
372
for (targs = argv; *targs != NULL; targs++)
374
printf ("\t\"%s\"\n", *targs);