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