Initial import of binutils 2.27 on vendor branch
[dragonfly.git] / contrib / binutils-2.27 / libiberty / argv.c
1 /* Create and destroy argument vectors (argv's)
2    Copyright (C) 1992, 2001, 2010, 2012 Free Software Foundation, Inc.
3    Written by Fred Fish @ Cygnus Support
4
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.
10
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.
15
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., 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA.  */
20
21
22 /*  Create and destroy argument vectors.  An argument vector is simply an
23     array of string pointers, terminated by a NULL pointer. */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 #include "ansidecl.h"
29 #include "libiberty.h"
30 #include "safe-ctype.h"
31
32 /*  Routines imported from standard C runtime libraries. */
33
34 #include <stddef.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38
39 #ifndef NULL
40 #define NULL 0
41 #endif
42
43 #ifndef EOS
44 #define EOS '\0'
45 #endif
46
47 #define INITIAL_MAXARGC 8       /* Number of args + NULL in initial argv */
48
49
50 /*
51
52 @deftypefn Extension char** dupargv (char * const *@var{vector})
53
54 Duplicate an argument vector.  Simply scans through @var{vector},
55 duplicating each argument until the terminating @code{NULL} is found.
56 Returns a pointer to the argument vector if successful.  Returns
57 @code{NULL} if there is insufficient memory to complete building the
58 argument vector.
59
60 @end deftypefn
61
62 */
63
64 char **
65 dupargv (char * const *argv)
66 {
67   int argc;
68   char **copy;
69   
70   if (argv == NULL)
71     return NULL;
72   
73   /* the vector */
74   for (argc = 0; argv[argc] != NULL; argc++);
75   copy = (char **) xmalloc ((argc + 1) * sizeof (char *));
76
77   /* the strings */
78   for (argc = 0; argv[argc] != NULL; argc++)
79     copy[argc] = xstrdup (argv[argc]);
80   copy[argc] = NULL;
81   return copy;
82 }
83
84 /*
85
86 @deftypefn Extension void freeargv (char **@var{vector})
87
88 Free an argument vector that was built using @code{buildargv}.  Simply
89 scans through @var{vector}, freeing the memory for each argument until
90 the terminating @code{NULL} is found, and then frees @var{vector}
91 itself.
92
93 @end deftypefn
94
95 */
96
97 void freeargv (char **vector)
98 {
99   register char **scan;
100
101   if (vector != NULL)
102     {
103       for (scan = vector; *scan != NULL; scan++)
104         {
105           free (*scan);
106         }
107       free (vector);
108     }
109 }
110
111 static void
112 consume_whitespace (const char **input)
113 {
114   while (ISSPACE (**input))
115     {
116       (*input)++;
117     }
118 }
119
120 static int
121 only_whitespace (const char* input)
122 {
123   while (*input != EOS && ISSPACE (*input))
124     input++;
125
126   return (*input == EOS);
127 }
128
129 /*
130
131 @deftypefn Extension char** buildargv (char *@var{sp})
132
133 Given a pointer to a string, parse the string extracting fields
134 separated by whitespace and optionally enclosed within either single
135 or double quotes (which are stripped off), and build a vector of
136 pointers to copies of the string for each field.  The input string
137 remains unchanged.  The last element of the vector is followed by a
138 @code{NULL} element.
139
140 All of the memory for the pointer array and copies of the string
141 is obtained from @code{xmalloc}.  All of the memory can be returned to the
142 system with the single function call @code{freeargv}, which takes the
143 returned result of @code{buildargv}, as it's argument.
144
145 Returns a pointer to the argument vector if successful.  Returns
146 @code{NULL} if @var{sp} is @code{NULL} or if there is insufficient
147 memory to complete building the argument vector.
148
149 If the input is a null string (as opposed to a @code{NULL} pointer),
150 then buildarg returns an argument vector that has one arg, a null
151 string.
152
153 @end deftypefn
154
155 The memory for the argv array is dynamically expanded as necessary.
156
157 In order to provide a working buffer for extracting arguments into,
158 with appropriate stripping of quotes and translation of backslash
159 sequences, we allocate a working buffer at least as long as the input
160 string.  This ensures that we always have enough space in which to
161 work, since the extracted arg is never larger than the input string.
162
163 The argument vector is always kept terminated with a @code{NULL} arg
164 pointer, so it can be passed to @code{freeargv} at any time, or
165 returned, as appropriate.
166
167 */
168
169 char **buildargv (const char *input)
170 {
171   char *arg;
172   char *copybuf;
173   int squote = 0;
174   int dquote = 0;
175   int bsquote = 0;
176   int argc = 0;
177   int maxargc = 0;
178   char **argv = NULL;
179   char **nargv;
180
181   if (input != NULL)
182     {
183       copybuf = (char *) xmalloc (strlen (input) + 1);
184       /* Is a do{}while to always execute the loop once.  Always return an
185          argv, even for null strings.  See NOTES above, test case below. */
186       do
187         {
188           /* Pick off argv[argc] */
189           consume_whitespace (&input);
190
191           if ((maxargc == 0) || (argc >= (maxargc - 1)))
192             {
193               /* argv needs initialization, or expansion */
194               if (argv == NULL)
195                 {
196                   maxargc = INITIAL_MAXARGC;
197                   nargv = (char **) xmalloc (maxargc * sizeof (char *));
198                 }
199               else
200                 {
201                   maxargc *= 2;
202                   nargv = (char **) xrealloc (argv, maxargc * sizeof (char *));
203                 }
204               argv = nargv;
205               argv[argc] = NULL;
206             }
207           /* Begin scanning arg */
208           arg = copybuf;
209           while (*input != EOS)
210             {
211               if (ISSPACE (*input) && !squote && !dquote && !bsquote)
212                 {
213                   break;
214                 }
215               else
216                 {
217                   if (bsquote)
218                     {
219                       bsquote = 0;
220                       *arg++ = *input;
221                     }
222                   else if (*input == '\\')
223                     {
224                       bsquote = 1;
225                     }
226                   else if (squote)
227                     {
228                       if (*input == '\'')
229                         {
230                           squote = 0;
231                         }
232                       else
233                         {
234                           *arg++ = *input;
235                         }
236                     }
237                   else if (dquote)
238                     {
239                       if (*input == '"')
240                         {
241                           dquote = 0;
242                         }
243                       else
244                         {
245                           *arg++ = *input;
246                         }
247                     }
248                   else
249                     {
250                       if (*input == '\'')
251                         {
252                           squote = 1;
253                         }
254                       else if (*input == '"')
255                         {
256                           dquote = 1;
257                         }
258                       else
259                         {
260                           *arg++ = *input;
261                         }
262                     }
263                   input++;
264                 }
265             }
266           *arg = EOS;
267           argv[argc] = xstrdup (copybuf);
268           argc++;
269           argv[argc] = NULL;
270
271           consume_whitespace (&input);
272         }
273       while (*input != EOS);
274
275       free (copybuf);
276     }
277   return (argv);
278 }
279
280 /*
281
282 @deftypefn Extension int writeargv (char * const *@var{argv}, FILE *@var{file})
283
284 Write each member of ARGV, handling all necessary quoting, to the file
285 named by FILE, separated by whitespace.  Return 0 on success, non-zero
286 if an error occurred while writing to FILE.
287
288 @end deftypefn
289
290 */
291
292 int
293 writeargv (char * const *argv, FILE *f)
294 {
295   int status = 0;
296
297   if (f == NULL)
298     return 1;
299
300   while (*argv != NULL)
301     {
302       const char *arg = *argv;
303
304       while (*arg != EOS)
305         {
306           char c = *arg;
307
308           if (ISSPACE(c) || c == '\\' || c == '\'' || c == '"')
309             if (EOF == fputc ('\\', f))
310               {
311                 status = 1;
312                 goto done;
313               }
314
315           if (EOF == fputc (c, f))
316             {
317               status = 1;
318               goto done;
319             }
320           arg++;
321         }
322
323       if (EOF == fputc ('\n', f))
324         {
325           status = 1;
326           goto done;
327         }
328       argv++;
329     }
330
331  done:
332   return status;
333 }
334
335 /*
336
337 @deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
338
339 The @var{argcp} and @code{argvp} arguments are pointers to the usual
340 @code{argc} and @code{argv} arguments to @code{main}.  This function
341 looks for arguments that begin with the character @samp{@@}.  Any such
342 arguments are interpreted as ``response files''.  The contents of the
343 response file are interpreted as additional command line options.  In
344 particular, the file is separated into whitespace-separated strings;
345 each such string is taken as a command-line option.  The new options
346 are inserted in place of the option naming the response file, and
347 @code{*argcp} and @code{*argvp} will be updated.  If the value of
348 @code{*argvp} is modified by this function, then the new value has
349 been dynamically allocated and can be deallocated by the caller with
350 @code{freeargv}.  However, most callers will simply call
351 @code{expandargv} near the beginning of @code{main} and allow the
352 operating system to free the memory when the program exits.
353
354 @end deftypefn
355
356 */
357
358 void
359 expandargv (int *argcp, char ***argvp)
360 {
361   /* The argument we are currently processing.  */
362   int i = 0;
363   /* Non-zero if ***argvp has been dynamically allocated.  */
364   int argv_dynamic = 0;
365   /* Limit the number of response files that we parse in order
366      to prevent infinite recursion.  */
367   unsigned int iteration_limit = 2000;
368   /* Loop over the arguments, handling response files.  We always skip
369      ARGVP[0], as that is the name of the program being run.  */
370   while (++i < *argcp)
371     {
372       /* The name of the response file.  */
373       const char *filename;
374       /* The response file.  */
375       FILE *f;
376       /* An upper bound on the number of characters in the response
377          file.  */
378       long pos;
379       /* The number of characters in the response file, when actually
380          read.  */
381       size_t len;
382       /* A dynamically allocated buffer used to hold options read from a
383          response file.  */
384       char *buffer;
385       /* Dynamically allocated storage for the options read from the
386          response file.  */
387       char **file_argv;
388       /* The number of options read from the response file, if any.  */
389       size_t file_argc;
390       /* We are only interested in options of the form "@file".  */
391       filename = (*argvp)[i];
392       if (filename[0] != '@')
393         continue;
394       /* If we have iterated too many times then stop.  */
395       if (-- iteration_limit == 0)
396         {
397           fprintf (stderr, "%s: error: too many @-files encountered\n", (*argvp)[0]);
398           xexit (1);
399         }
400       /* Read the contents of the file.  */
401       f = fopen (++filename, "r");
402       if (!f)
403         continue;
404       if (fseek (f, 0L, SEEK_END) == -1)
405         goto error;
406       pos = ftell (f);
407       if (pos == -1)
408         goto error;
409       if (fseek (f, 0L, SEEK_SET) == -1)
410         goto error;
411       buffer = (char *) xmalloc (pos * sizeof (char) + 1);
412       len = fread (buffer, sizeof (char), pos, f);
413       if (len != (size_t) pos
414           /* On Windows, fread may return a value smaller than POS,
415              due to CR/LF->CR translation when reading text files.
416              That does not in-and-of itself indicate failure.  */
417           && ferror (f))
418         goto error;
419       /* Add a NUL terminator.  */
420       buffer[len] = '\0';
421       /* If the file is empty or contains only whitespace, buildargv would
422          return a single empty argument.  In this context we want no arguments,
423          instead.  */
424       if (only_whitespace (buffer))
425         {
426           file_argv = (char **) xmalloc (sizeof (char *));
427           file_argv[0] = NULL;
428         }
429       else
430         /* Parse the string.  */
431         file_argv = buildargv (buffer);
432       /* If *ARGVP is not already dynamically allocated, copy it.  */
433       if (!argv_dynamic)
434         *argvp = dupargv (*argvp);
435       /* Count the number of arguments.  */
436       file_argc = 0;
437       while (file_argv[file_argc])
438         ++file_argc;
439       /* Now, insert FILE_ARGV into ARGV.  The "+1" below handles the
440          NULL terminator at the end of ARGV.  */ 
441       *argvp = ((char **) 
442                 xrealloc (*argvp, 
443                           (*argcp + file_argc + 1) * sizeof (char *)));
444       memmove (*argvp + i + file_argc, *argvp + i + 1, 
445                (*argcp - i) * sizeof (char *));
446       memcpy (*argvp + i, file_argv, file_argc * sizeof (char *));
447       /* The original option has been replaced by all the new
448          options.  */
449       *argcp += file_argc - 1;
450       /* Free up memory allocated to process the response file.  We do
451          not use freeargv because the individual options in FILE_ARGV
452          are now in the main ARGV.  */
453       free (file_argv);
454       free (buffer);
455       /* Rescan all of the arguments just read to support response
456          files that include other response files.  */
457       --i;
458     error:
459       /* We're all done with the file now.  */
460       fclose (f);
461     }
462 }
463
464 /*
465
466 @deftypefn Extension int countargv (char * const *@var{argv})
467
468 Return the number of elements in @var{argv}.
469 Returns zero if @var{argv} is NULL.
470
471 @end deftypefn
472
473 */
474
475 int
476 countargv (char * const *argv)
477 {
478   int argc;
479
480   if (argv == NULL)
481     return 0;
482   for (argc = 0; argv[argc] != NULL; argc++)
483     continue;
484   return argc;
485 }
486
487 #ifdef MAIN
488
489 /* Simple little test driver. */
490
491 static const char *const tests[] =
492 {
493   "a simple command line",
494   "arg 'foo' is single quoted",
495   "arg \"bar\" is double quoted",
496   "arg \"foo bar\" has embedded whitespace",
497   "arg 'Jack said \\'hi\\'' has single quotes",
498   "arg 'Jack said \\\"hi\\\"' has double quotes",
499   "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",
500   
501   /* This should be expanded into only one argument.  */
502   "trailing-whitespace ",
503
504   "",
505   NULL
506 };
507
508 int
509 main (void)
510 {
511   char **argv;
512   const char *const *test;
513   char **targs;
514
515   for (test = tests; *test != NULL; test++)
516     {
517       printf ("buildargv(\"%s\")\n", *test);
518       if ((argv = buildargv (*test)) == NULL)
519         {
520           printf ("failed!\n\n");
521         }
522       else
523         {
524           for (targs = argv; *targs != NULL; targs++)
525             {
526               printf ("\t\"%s\"\n", *targs);
527             }
528           printf ("\n");
529         }
530       freeargv (argv);
531     }
532
533   return 0;
534 }
535
536 #endif  /* MAIN */