1169695Skan/* Create and destroy argument vectors (argv's)
2169695Skan   Copyright (C) 1992, 2001 Free Software Foundation, Inc.
3169695Skan   Written by Fred Fish @ Cygnus Support
4169695Skan
5169695SkanThis file is part of the libiberty library.
6169695SkanLibiberty is free software; you can redistribute it and/or
7169695Skanmodify it under the terms of the GNU Library General Public
8169695SkanLicense as published by the Free Software Foundation; either
9169695Skanversion 2 of the License, or (at your option) any later version.
10169695Skan
11169695SkanLibiberty is distributed in the hope that it will be useful,
12169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
13169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14169695SkanLibrary General Public License for more details.
15169695Skan
16169695SkanYou should have received a copy of the GNU Library General Public
17169695SkanLicense along with libiberty; see the file COPYING.LIB.  If
18169695Skannot, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19169695SkanBoston, MA 02110-1301, USA.  */
20169695Skan
21169695Skan
22169695Skan/*  Create and destroy argument vectors.  An argument vector is simply an
23169695Skan    array of string pointers, terminated by a NULL pointer. */
24169695Skan
25169695Skan#ifdef HAVE_CONFIG_H
26169695Skan#include "config.h"
27169695Skan#endif
28169695Skan#include "ansidecl.h"
29169695Skan#include "libiberty.h"
30169695Skan#include "safe-ctype.h"
31169695Skan
32169695Skan/*  Routines imported from standard C runtime libraries. */
33169695Skan
34169695Skan#include <stddef.h>
35169695Skan#include <string.h>
36169695Skan#include <stdlib.h>
37169695Skan#include <stdio.h>
38169695Skan
39169695Skan#ifndef NULL
40169695Skan#define NULL 0
41169695Skan#endif
42169695Skan
43169695Skan#ifndef EOS
44169695Skan#define EOS '\0'
45169695Skan#endif
46169695Skan
47169695Skan#define INITIAL_MAXARGC 8	/* Number of args + NULL in initial argv */
48169695Skan
49169695Skan
50169695Skan/*
51169695Skan
52169695Skan@deftypefn Extension char** dupargv (char **@var{vector})
53169695Skan
54169695SkanDuplicate an argument vector.  Simply scans through @var{vector},
55169695Skanduplicating each argument until the terminating @code{NULL} is found.
56169695SkanReturns a pointer to the argument vector if successful.  Returns
57169695Skan@code{NULL} if there is insufficient memory to complete building the
58169695Skanargument vector.
59169695Skan
60169695Skan@end deftypefn
61169695Skan
62169695Skan*/
63169695Skan
64169695Skanchar **
65169695Skandupargv (char **argv)
66169695Skan{
67169695Skan  int argc;
68169695Skan  char **copy;
69169695Skan
70169695Skan  if (argv == NULL)
71169695Skan    return NULL;
72169695Skan
73169695Skan  /* the vector */
74169695Skan  for (argc = 0; argv[argc] != NULL; argc++);
75169695Skan  copy = (char **) malloc ((argc + 1) * sizeof (char *));
76169695Skan  if (copy == NULL)
77169695Skan    return NULL;
78169695Skan
79169695Skan  /* the strings */
80169695Skan  for (argc = 0; argv[argc] != NULL; argc++)
81169695Skan    {
82169695Skan      int len = strlen (argv[argc]);
83169695Skan      copy[argc] = (char *) malloc (len + 1);
84169695Skan      if (copy[argc] == NULL)
85169695Skan	{
86169695Skan	  freeargv (copy);
87169695Skan	  return NULL;
88169695Skan	}
89169695Skan      strcpy (copy[argc], argv[argc]);
90169695Skan    }
91169695Skan  copy[argc] = NULL;
92169695Skan  return copy;
93169695Skan}
94169695Skan
95169695Skan/*
96169695Skan
97169695Skan@deftypefn Extension void freeargv (char **@var{vector})
98169695Skan
99169695SkanFree an argument vector that was built using @code{buildargv}.  Simply
100169695Skanscans through @var{vector}, freeing the memory for each argument until
101169695Skanthe terminating @code{NULL} is found, and then frees @var{vector}
102169695Skanitself.
103169695Skan
104169695Skan@end deftypefn
105169695Skan
106169695Skan*/
107169695Skan
108169695Skanvoid freeargv (char **vector)
109169695Skan{
110169695Skan  register char **scan;
111169695Skan
112169695Skan  if (vector != NULL)
113169695Skan    {
114169695Skan      for (scan = vector; *scan != NULL; scan++)
115169695Skan	{
116169695Skan	  free (*scan);
117169695Skan	}
118169695Skan      free (vector);
119169695Skan    }
120169695Skan}
121169695Skan
122169695Skan/*
123169695Skan
124169695Skan@deftypefn Extension char** buildargv (char *@var{sp})
125169695Skan
126169695SkanGiven a pointer to a string, parse the string extracting fields
127169695Skanseparated by whitespace and optionally enclosed within either single
128169695Skanor double quotes (which are stripped off), and build a vector of
129169695Skanpointers to copies of the string for each field.  The input string
130169695Skanremains unchanged.  The last element of the vector is followed by a
131169695Skan@code{NULL} element.
132169695Skan
133169695SkanAll of the memory for the pointer array and copies of the string
134169695Skanis obtained from @code{malloc}.  All of the memory can be returned to the
135169695Skansystem with the single function call @code{freeargv}, which takes the
136169695Skanreturned result of @code{buildargv}, as it's argument.
137169695Skan
138169695SkanReturns a pointer to the argument vector if successful.  Returns
139169695Skan@code{NULL} if @var{sp} is @code{NULL} or if there is insufficient
140169695Skanmemory to complete building the argument vector.
141169695Skan
142169695SkanIf the input is a null string (as opposed to a @code{NULL} pointer),
143169695Skanthen buildarg returns an argument vector that has one arg, a null
144169695Skanstring.
145169695Skan
146169695Skan@end deftypefn
147169695Skan
148169695SkanThe memory for the argv array is dynamically expanded as necessary.
149169695Skan
150169695SkanIn order to provide a working buffer for extracting arguments into,
151169695Skanwith appropriate stripping of quotes and translation of backslash
152169695Skansequences, we allocate a working buffer at least as long as the input
153169695Skanstring.  This ensures that we always have enough space in which to
154169695Skanwork, since the extracted arg is never larger than the input string.
155169695Skan
156169695SkanThe argument vector is always kept terminated with a @code{NULL} arg
157169695Skanpointer, so it can be passed to @code{freeargv} at any time, or
158169695Skanreturned, as appropriate.
159169695Skan
160169695Skan*/
161169695Skan
162169695Skanchar **buildargv (const char *input)
163169695Skan{
164169695Skan  char *arg;
165169695Skan  char *copybuf;
166169695Skan  int squote = 0;
167169695Skan  int dquote = 0;
168169695Skan  int bsquote = 0;
169169695Skan  int argc = 0;
170169695Skan  int maxargc = 0;
171169695Skan  char **argv = NULL;
172169695Skan  char **nargv;
173169695Skan
174169695Skan  if (input != NULL)
175169695Skan    {
176169695Skan      copybuf = (char *) alloca (strlen (input) + 1);
177169695Skan      /* Is a do{}while to always execute the loop once.  Always return an
178169695Skan	 argv, even for null strings.  See NOTES above, test case below. */
179169695Skan      do
180169695Skan	{
181169695Skan	  /* Pick off argv[argc] */
182169695Skan	  while (ISBLANK (*input))
183169695Skan	    {
184169695Skan	      input++;
185169695Skan	    }
186169695Skan	  if ((maxargc == 0) || (argc >= (maxargc - 1)))
187169695Skan	    {
188169695Skan	      /* argv needs initialization, or expansion */
189169695Skan	      if (argv == NULL)
190169695Skan		{
191169695Skan		  maxargc = INITIAL_MAXARGC;
192169695Skan		  nargv = (char **) malloc (maxargc * sizeof (char *));
193169695Skan		}
194169695Skan	      else
195169695Skan		{
196169695Skan		  maxargc *= 2;
197169695Skan		  nargv = (char **) realloc (argv, maxargc * sizeof (char *));
198169695Skan		}
199169695Skan	      if (nargv == NULL)
200169695Skan		{
201169695Skan		  if (argv != NULL)
202169695Skan		    {
203169695Skan		      freeargv (argv);
204169695Skan		      argv = NULL;
205169695Skan		    }
206169695Skan		  break;
207169695Skan		}
208169695Skan	      argv = nargv;
209169695Skan	      argv[argc] = NULL;
210169695Skan	    }
211169695Skan	  /* Begin scanning arg */
212169695Skan	  arg = copybuf;
213169695Skan	  while (*input != EOS)
214169695Skan	    {
215169695Skan	      if (ISSPACE (*input) && !squote && !dquote && !bsquote)
216169695Skan		{
217169695Skan		  break;
218169695Skan		}
219169695Skan	      else
220169695Skan		{
221169695Skan		  if (bsquote)
222169695Skan		    {
223169695Skan		      bsquote = 0;
224169695Skan		      *arg++ = *input;
225169695Skan		    }
226169695Skan		  else if (*input == '\\')
227169695Skan		    {
228169695Skan		      bsquote = 1;
229169695Skan		    }
230169695Skan		  else if (squote)
231169695Skan		    {
232169695Skan		      if (*input == '\'')
233169695Skan			{
234169695Skan			  squote = 0;
235169695Skan			}
236169695Skan		      else
237169695Skan			{
238169695Skan			  *arg++ = *input;
239169695Skan			}
240169695Skan		    }
241169695Skan		  else if (dquote)
242169695Skan		    {
243169695Skan		      if (*input == '"')
244169695Skan			{
245169695Skan			  dquote = 0;
246169695Skan			}
247169695Skan		      else
248169695Skan			{
249169695Skan			  *arg++ = *input;
250169695Skan			}
251169695Skan		    }
252169695Skan		  else
253169695Skan		    {
254169695Skan		      if (*input == '\'')
255169695Skan			{
256169695Skan			  squote = 1;
257169695Skan			}
258169695Skan		      else if (*input == '"')
259169695Skan			{
260169695Skan			  dquote = 1;
261169695Skan			}
262169695Skan		      else
263169695Skan			{
264169695Skan			  *arg++ = *input;
265169695Skan			}
266169695Skan		    }
267169695Skan		  input++;
268169695Skan		}
269169695Skan	    }
270169695Skan	  *arg = EOS;
271169695Skan	  argv[argc] = strdup (copybuf);
272169695Skan	  if (argv[argc] == NULL)
273169695Skan	    {
274169695Skan	      freeargv (argv);
275169695Skan	      argv = NULL;
276169695Skan	      break;
277169695Skan	    }
278169695Skan	  argc++;
279169695Skan	  argv[argc] = NULL;
280169695Skan
281169695Skan	  while (ISSPACE (*input))
282169695Skan	    {
283169695Skan	      input++;
284169695Skan	    }
285169695Skan	}
286169695Skan      while (*input != EOS);
287169695Skan    }
288169695Skan  return (argv);
289169695Skan}
290169695Skan
291169695Skan/*
292169695Skan
293169695Skan@deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
294169695Skan
295169695SkanThe @var{argcp} and @code{argvp} arguments are pointers to the usual
296169695Skan@code{argc} and @code{argv} arguments to @code{main}.  This function
297169695Skanlooks for arguments that begin with the character @samp{@@}.  Any such
298169695Skanarguments are interpreted as ``response files''.  The contents of the
299169695Skanresponse file are interpreted as additional command line options.  In
300169695Skanparticular, the file is separated into whitespace-separated strings;
301169695Skaneach such string is taken as a command-line option.  The new options
302169695Skanare inserted in place of the option naming the response file, and
303169695Skan@code{*argcp} and @code{*argvp} will be updated.  If the value of
304169695Skan@code{*argvp} is modified by this function, then the new value has
305169695Skanbeen dynamically allocated and can be deallocated by the caller with
306169695Skan@code{freeargv}.  However, most callers will simply call
307169695Skan@code{expandargv} near the beginning of @code{main} and allow the
308169695Skanoperating system to free the memory when the program exits.
309169695Skan
310169695Skan@end deftypefn
311169695Skan
312169695Skan*/
313169695Skan
314169695Skanvoid
315169695Skanexpandargv (argcp, argvp)
316169695Skan     int *argcp;
317169695Skan     char ***argvp;
318169695Skan{
319169695Skan  /* The argument we are currently processing.  */
320169695Skan  int i = 0;
321169695Skan  /* Non-zero if ***argvp has been dynamically allocated.  */
322169695Skan  int argv_dynamic = 0;
323169695Skan  /* Loop over the arguments, handling response files.  We always skip
324169695Skan     ARGVP[0], as that is the name of the program being run.  */
325169695Skan  while (++i < *argcp)
326169695Skan    {
327169695Skan      /* The name of the response file.  */
328169695Skan      const char *filename;
329169695Skan      /* The response file.  */
330169695Skan      FILE *f;
331169695Skan      /* An upper bound on the number of characters in the response
332169695Skan	 file.  */
333169695Skan      long pos;
334169695Skan      /* The number of characters in the response file, when actually
335169695Skan	 read.  */
336169695Skan      size_t len;
337169695Skan      /* A dynamically allocated buffer used to hold options read from a
338169695Skan	 response file.  */
339169695Skan      char *buffer;
340169695Skan      /* Dynamically allocated storage for the options read from the
341169695Skan	 response file.  */
342169695Skan      char **file_argv;
343169695Skan      /* The number of options read from the response file, if any.  */
344169695Skan      size_t file_argc;
345169695Skan      /* We are only interested in options of the form "@file".  */
346169695Skan      filename = (*argvp)[i];
347169695Skan      if (filename[0] != '@')
348169695Skan	continue;
349169695Skan      /* Read the contents of the file.  */
350169695Skan      f = fopen (++filename, "r");
351169695Skan      if (!f)
352169695Skan	continue;
353169695Skan      if (fseek (f, 0L, SEEK_END) == -1)
354169695Skan	goto error;
355169695Skan      pos = ftell (f);
356169695Skan      if (pos == -1)
357169695Skan	goto error;
358169695Skan      if (fseek (f, 0L, SEEK_SET) == -1)
359169695Skan	goto error;
360169695Skan      buffer = (char *) xmalloc (pos * sizeof (char) + 1);
361169695Skan      len = fread (buffer, sizeof (char), pos, f);
362169695Skan      if (len != (size_t) pos
363169695Skan	  /* On Windows, fread may return a value smaller than POS,
364169695Skan	     due to CR/LF->CR translation when reading text files.
365169695Skan	     That does not in-and-of itself indicate failure.  */
366169695Skan	  && ferror (f))
367169695Skan	goto error;
368169695Skan      /* Add a NUL terminator.  */
369169695Skan      buffer[len] = '\0';
370169695Skan      /* Parse the string.  */
371169695Skan      file_argv = buildargv (buffer);
372169695Skan      /* If *ARGVP is not already dynamically allocated, copy it.  */
373169695Skan      if (!argv_dynamic)
374169695Skan	{
375169695Skan	  *argvp = dupargv (*argvp);
376169695Skan	  if (!*argvp)
377169695Skan	    {
378169695Skan	      fputs ("\nout of memory\n", stderr);
379169695Skan	      xexit (1);
380169695Skan	    }
381169695Skan	}
382169695Skan      /* Count the number of arguments.  */
383169695Skan      file_argc = 0;
384169695Skan      while (file_argv[file_argc] && *file_argv[file_argc])
385169695Skan	++file_argc;
386169695Skan      /* Now, insert FILE_ARGV into ARGV.  The "+1" below handles the
387169695Skan	 NULL terminator at the end of ARGV.  */
388169695Skan      *argvp = ((char **)
389169695Skan		xrealloc (*argvp,
390169695Skan			  (*argcp + file_argc + 1) * sizeof (char *)));
391169695Skan      memmove (*argvp + i + file_argc, *argvp + i + 1,
392169695Skan	       (*argcp - i) * sizeof (char *));
393169695Skan      memcpy (*argvp + i, file_argv, file_argc * sizeof (char *));
394169695Skan      /* The original option has been replaced by all the new
395169695Skan	 options.  */
396169695Skan      *argcp += file_argc - 1;
397169695Skan      /* Free up memory allocated to process the response file.  We do
398169695Skan	 not use freeargv because the individual options in FILE_ARGV
399169695Skan	 are now in the main ARGV.  */
400169695Skan      free (file_argv);
401169695Skan      free (buffer);
402169695Skan      /* Rescan all of the arguments just read to support response
403169695Skan	 files that include other response files.  */
404169695Skan      --i;
405169695Skan    error:
406169695Skan      /* We're all done with the file now.  */
407169695Skan      fclose (f);
408169695Skan    }
409169695Skan}
410169695Skan
411169695Skan#ifdef MAIN
412169695Skan
413169695Skan/* Simple little test driver. */
414169695Skan
415169695Skanstatic const char *const tests[] =
416169695Skan{
417169695Skan  "a simple command line",
418169695Skan  "arg 'foo' is single quoted",
419169695Skan  "arg \"bar\" is double quoted",
420169695Skan  "arg \"foo bar\" has embedded whitespace",
421169695Skan  "arg 'Jack said \\'hi\\'' has single quotes",
422169695Skan  "arg 'Jack said \\\"hi\\\"' has double quotes",
423169695Skan  "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",
424169695Skan
425169695Skan  /* This should be expanded into only one argument.  */
426169695Skan  "trailing-whitespace ",
427169695Skan
428169695Skan  "",
429169695Skan  NULL
430169695Skan};
431169695Skan
432169695Skanint
433169695Skanmain (void)
434169695Skan{
435169695Skan  char **argv;
436169695Skan  const char *const *test;
437169695Skan  char **targs;
438169695Skan
439169695Skan  for (test = tests; *test != NULL; test++)
440169695Skan    {
441169695Skan      printf ("buildargv(\"%s\")\n", *test);
442169695Skan      if ((argv = buildargv (*test)) == NULL)
443169695Skan	{
444169695Skan	  printf ("failed!\n\n");
445169695Skan	}
446169695Skan      else
447169695Skan	{
448169695Skan	  for (targs = argv; *targs != NULL; targs++)
449169695Skan	    {
450169695Skan	      printf ("\t\"%s\"\n", *targs);
451169695Skan	    }
452169695Skan	  printf ("\n");
453169695Skan	}
454169695Skan      freeargv (argv);
455169695Skan    }
456169695Skan
457169695Skan  return 0;
458169695Skan}
459169695Skan
460169695Skan#endif	/* MAIN */
461