]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/argv.c
Use vector_operand on SSE with 16b memory operand
[thirdparty/gcc.git] / libiberty / argv.c
CommitLineData
6599da04 1/* Create and destroy argument vectors (argv's)
fabfa16b 2 Copyright (C) 1992, 2001, 2010, 2012 Free Software Foundation, Inc.
6599da04
JM
3 Written by Fred Fish @ Cygnus Support
4
5This file is part of the libiberty library.
6Libiberty is free software; you can redistribute it and/or
7modify it under the terms of the GNU Library General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11Libiberty is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14Library General Public License for more details.
15
16You should have received a copy of the GNU Library General Public
17License along with libiberty; see the file COPYING.LIB. If
ee58dffd
NC
18not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19Boston, MA 02110-1301, USA. */
6599da04
JM
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
3c60ae5a
GDR
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
6599da04
JM
28#include "ansidecl.h"
29#include "libiberty.h"
97393d0a 30#include "safe-ctype.h"
6599da04
JM
31
32/* Routines imported from standard C runtime libraries. */
33
6599da04 34#include <stddef.h>
a81c752a
RH
35#include <string.h>
36#include <stdlib.h>
97393d0a 37#include <stdio.h>
6599da04 38
6599da04
JM
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
19ddc834
JM
50/*
51
aac04c15 52@deftypefn Extension char** dupargv (char **@var{vector})
19ddc834 53
aac04c15
DD
54Duplicate an argument vector. Simply scans through @var{vector},
55duplicating each argument until the terminating @code{NULL} is found.
5bed56d9 56Returns a pointer to the argument vector if successful. Returns
aac04c15
DD
57@code{NULL} if there is insufficient memory to complete building the
58argument vector.
19ddc834 59
aac04c15 60@end deftypefn
19ddc834
JM
61
62*/
63
64char **
9486db4f 65dupargv (char **argv)
19ddc834
JM
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++);
fabfa16b
L
75 copy = (char **) xmalloc ((argc + 1) * sizeof (char *));
76
19ddc834
JM
77 /* the strings */
78 for (argc = 0; argv[argc] != NULL; argc++)
ae120683 79 copy[argc] = xstrdup (argv[argc]);
19ddc834
JM
80 copy[argc] = NULL;
81 return copy;
82}
83
6599da04
JM
84/*
85
aac04c15 86@deftypefn Extension void freeargv (char **@var{vector})
6599da04 87
aac04c15
DD
88Free an argument vector that was built using @code{buildargv}. Simply
89scans through @var{vector}, freeing the memory for each argument until
90the terminating @code{NULL} is found, and then frees @var{vector}
91itself.
6599da04 92
aac04c15 93@end deftypefn
6599da04
JM
94
95*/
96
9486db4f 97void freeargv (char **vector)
6599da04
JM
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
70277b30
DG
111static void
112consume_whitespace (const char **input)
113{
114 while (ISSPACE (**input))
115 {
116 (*input)++;
117 }
118}
119
120static int
121only_whitespace (const char* input)
122{
123 while (*input != EOS && ISSPACE (*input))
124 input++;
125
126 return (*input == EOS);
127}
128
6599da04
JM
129/*
130
aac04c15 131@deftypefn Extension char** buildargv (char *@var{sp})
6599da04 132
aac04c15
DD
133Given a pointer to a string, parse the string extracting fields
134separated by whitespace and optionally enclosed within either single
135or double quotes (which are stripped off), and build a vector of
136pointers to copies of the string for each field. The input string
137remains unchanged. The last element of the vector is followed by a
138@code{NULL} element.
6599da04 139
aac04c15 140All of the memory for the pointer array and copies of the string
fabfa16b 141is obtained from @code{xmalloc}. All of the memory can be returned to the
aac04c15
DD
142system with the single function call @code{freeargv}, which takes the
143returned result of @code{buildargv}, as it's argument.
6599da04 144
5bed56d9 145Returns a pointer to the argument vector if successful. Returns
aac04c15
DD
146@code{NULL} if @var{sp} is @code{NULL} or if there is insufficient
147memory to complete building the argument vector.
6599da04 148
aac04c15
DD
149If the input is a null string (as opposed to a @code{NULL} pointer),
150then buildarg returns an argument vector that has one arg, a null
151string.
6599da04 152
aac04c15 153@end deftypefn
6599da04 154
aac04c15 155The memory for the argv array is dynamically expanded as necessary.
6599da04 156
aac04c15
DD
157In order to provide a working buffer for extracting arguments into,
158with appropriate stripping of quotes and translation of backslash
159sequences, we allocate a working buffer at least as long as the input
160string. This ensures that we always have enough space in which to
161work, since the extracted arg is never larger than the input string.
6599da04 162
aac04c15
DD
163The argument vector is always kept terminated with a @code{NULL} arg
164pointer, so it can be passed to @code{freeargv} at any time, or
165returned, as appropriate.
6599da04 166
6599da04
JM
167*/
168
9486db4f 169char **buildargv (const char *input)
6599da04
JM
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 {
55529d36 183 copybuf = (char *) xmalloc (strlen (input) + 1);
6599da04
JM
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] */
70277b30
DG
189 consume_whitespace (&input);
190
6599da04
JM
191 if ((maxargc == 0) || (argc >= (maxargc - 1)))
192 {
193 /* argv needs initialization, or expansion */
194 if (argv == NULL)
195 {
196 maxargc = INITIAL_MAXARGC;
fabfa16b 197 nargv = (char **) xmalloc (maxargc * sizeof (char *));
6599da04
JM
198 }
199 else
200 {
201 maxargc *= 2;
fabfa16b 202 nargv = (char **) xrealloc (argv, maxargc * sizeof (char *));
6599da04
JM
203 }
204 argv = nargv;
205 argv[argc] = NULL;
206 }
207 /* Begin scanning arg */
208 arg = copybuf;
209 while (*input != EOS)
210 {
97393d0a 211 if (ISSPACE (*input) && !squote && !dquote && !bsquote)
6599da04
JM
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;
fabfa16b 267 argv[argc] = xstrdup (copybuf);
6599da04
JM
268 argc++;
269 argv[argc] = NULL;
270
70277b30 271 consume_whitespace (&input);
6599da04
JM
272 }
273 while (*input != EOS);
55529d36
L
274
275 free (copybuf);
6599da04
JM
276 }
277 return (argv);
278}
279
97393d0a
MM
280/*
281
f4e00f44 282@deftypefn Extension int writeargv (const char **@var{argv}, FILE *@var{file})
2091ff66
NF
283
284Write each member of ARGV, handling all necessary quoting, to the file
285named by FILE, separated by whitespace. Return 0 on success, non-zero
286if an error occurred while writing to FILE.
287
288@end deftypefn
289
290*/
291
292int
293writeargv (char **argv, FILE *f)
294{
295 int status = 0;
296
297 if (f == NULL)
298 return 1;
299
300 while (*argv != NULL)
301 {
2091ff66
NF
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
97393d0a
MM
337@deftypefn Extension void expandargv (int *@var{argcp}, char ***@var{argvp})
338
339The @var{argcp} and @code{argvp} arguments are pointers to the usual
340@code{argc} and @code{argv} arguments to @code{main}. This function
341looks for arguments that begin with the character @samp{@@}. Any such
342arguments are interpreted as ``response files''. The contents of the
343response file are interpreted as additional command line options. In
344particular, the file is separated into whitespace-separated strings;
345each such string is taken as a command-line option. The new options
346are 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
349been 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
352operating system to free the memory when the program exits.
353
354@end deftypefn
355
356*/
357
358void
017133fd 359expandargv (int *argcp, char ***argvp)
97393d0a
MM
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;
ec760bea
NC
365 /* Limit the number of response files that we parse in order
366 to prevent infinite recursion. */
367 unsigned int iteration_limit = 2000;
97393d0a
MM
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;
974c2c56
CD
376 /* An upper bound on the number of characters in the response
377 file. */
97393d0a 378 long pos;
974c2c56
CD
379 /* The number of characters in the response file, when actually
380 read. */
381 size_t len;
97393d0a
MM
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. */
974c2c56 389 size_t file_argc;
97393d0a
MM
390 /* We are only interested in options of the form "@file". */
391 filename = (*argvp)[i];
392 if (filename[0] != '@')
393 continue;
ec760bea
NC
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 }
97393d0a
MM
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);
974c2c56
CD
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))
97393d0a
MM
418 goto error;
419 /* Add a NUL terminator. */
974c2c56 420 buffer[len] = '\0';
70277b30
DG
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);
97393d0a
MM
432 /* If *ARGVP is not already dynamically allocated, copy it. */
433 if (!argv_dynamic)
fabfa16b 434 *argvp = dupargv (*argvp);
97393d0a
MM
435 /* Count the number of arguments. */
436 file_argc = 0;
70277b30 437 while (file_argv[file_argc])
97393d0a
MM
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
be50fcea
DE
464/*
465
466@deftypefn Extension int countargv (char **@var{argv})
467
468Return the number of elements in @var{argv}.
469Returns zero if @var{argv} is NULL.
470
471@end deftypefn
472
473*/
474
475int
476countargv (char **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
6599da04
JM
487#ifdef MAIN
488
489/* Simple little test driver. */
490
0be6abca 491static const char *const tests[] =
6599da04
JM
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
9486db4f
GDR
508int
509main (void)
6599da04
JM
510{
511 char **argv;
0be6abca 512 const char *const *test;
6599da04
JM
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
0be6abca 533 return 0;
6599da04
JM
534}
535
536#endif /* MAIN */