comparison libiberty/argv.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Create and destroy argument vectors (argv's) 1 /* Create and destroy argument vectors (argv's)
2 Copyright (C) 1992, 2001, 2010 Free Software Foundation, Inc. 2 Copyright (C) 1992-2017 Free Software Foundation, Inc.
3 Written by Fred Fish @ Cygnus Support 3 Written by Fred Fish @ Cygnus Support
4 4
5 This file is part of the libiberty library. 5 This file is part of the libiberty library.
6 Libiberty is free software; you can redistribute it and/or 6 Libiberty is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public 7 modify it under the terms of the GNU Library General Public
33 33
34 #include <stddef.h> 34 #include <stddef.h>
35 #include <string.h> 35 #include <string.h>
36 #include <stdlib.h> 36 #include <stdlib.h>
37 #include <stdio.h> 37 #include <stdio.h>
38 #include <sys/types.h>
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #if HAVE_SYS_STAT_H
43 #include <sys/stat.h>
44 #endif
38 45
39 #ifndef NULL 46 #ifndef NULL
40 #define NULL 0 47 #define NULL 0
41 #endif 48 #endif
42 49
47 #define INITIAL_MAXARGC 8 /* Number of args + NULL in initial argv */ 54 #define INITIAL_MAXARGC 8 /* Number of args + NULL in initial argv */
48 55
49 56
50 /* 57 /*
51 58
52 @deftypefn Extension char** dupargv (char **@var{vector}) 59 @deftypefn Extension char** dupargv (char * const *@var{vector})
53 60
54 Duplicate an argument vector. Simply scans through @var{vector}, 61 Duplicate an argument vector. Simply scans through @var{vector},
55 duplicating each argument until the terminating @code{NULL} is found. 62 duplicating each argument until the terminating @code{NULL} is found.
56 Returns a pointer to the argument vector if successful. Returns 63 Returns a pointer to the argument vector if successful. Returns
57 @code{NULL} if there is insufficient memory to complete building the 64 @code{NULL} if there is insufficient memory to complete building the
60 @end deftypefn 67 @end deftypefn
61 68
62 */ 69 */
63 70
64 char ** 71 char **
65 dupargv (char **argv) 72 dupargv (char * const *argv)
66 { 73 {
67 int argc; 74 int argc;
68 char **copy; 75 char **copy;
69 76
70 if (argv == NULL) 77 if (argv == NULL)
71 return NULL; 78 return NULL;
72 79
73 /* the vector */ 80 /* the vector */
74 for (argc = 0; argv[argc] != NULL; argc++); 81 for (argc = 0; argv[argc] != NULL; argc++);
75 copy = (char **) malloc ((argc + 1) * sizeof (char *)); 82 copy = (char **) xmalloc ((argc + 1) * sizeof (char *));
76 if (copy == NULL) 83
77 return NULL;
78
79 /* the strings */ 84 /* the strings */
80 for (argc = 0; argv[argc] != NULL; argc++) 85 for (argc = 0; argv[argc] != NULL; argc++)
81 { 86 copy[argc] = xstrdup (argv[argc]);
82 int len = strlen (argv[argc]);
83 copy[argc] = (char *) malloc (len + 1);
84 if (copy[argc] == NULL)
85 {
86 freeargv (copy);
87 return NULL;
88 }
89 strcpy (copy[argc], argv[argc]);
90 }
91 copy[argc] = NULL; 87 copy[argc] = NULL;
92 return copy; 88 return copy;
93 } 89 }
94 90
95 /* 91 /*
147 pointers to copies of the string for each field. The input string 143 pointers to copies of the string for each field. The input string
148 remains unchanged. The last element of the vector is followed by a 144 remains unchanged. The last element of the vector is followed by a
149 @code{NULL} element. 145 @code{NULL} element.
150 146
151 All of the memory for the pointer array and copies of the string 147 All of the memory for the pointer array and copies of the string
152 is obtained from @code{malloc}. All of the memory can be returned to the 148 is obtained from @code{xmalloc}. All of the memory can be returned to the
153 system with the single function call @code{freeargv}, which takes the 149 system with the single function call @code{freeargv}, which takes the
154 returned result of @code{buildargv}, as it's argument. 150 returned result of @code{buildargv}, as it's argument.
155 151
156 Returns a pointer to the argument vector if successful. Returns 152 Returns a pointer to the argument vector if successful. Returns
157 @code{NULL} if @var{sp} is @code{NULL} or if there is insufficient 153 @code{NULL} if @var{sp} is @code{NULL} or if there is insufficient
189 char **argv = NULL; 185 char **argv = NULL;
190 char **nargv; 186 char **nargv;
191 187
192 if (input != NULL) 188 if (input != NULL)
193 { 189 {
194 copybuf = (char *) alloca (strlen (input) + 1); 190 copybuf = (char *) xmalloc (strlen (input) + 1);
195 /* Is a do{}while to always execute the loop once. Always return an 191 /* Is a do{}while to always execute the loop once. Always return an
196 argv, even for null strings. See NOTES above, test case below. */ 192 argv, even for null strings. See NOTES above, test case below. */
197 do 193 do
198 { 194 {
199 /* Pick off argv[argc] */ 195 /* Pick off argv[argc] */
203 { 199 {
204 /* argv needs initialization, or expansion */ 200 /* argv needs initialization, or expansion */
205 if (argv == NULL) 201 if (argv == NULL)
206 { 202 {
207 maxargc = INITIAL_MAXARGC; 203 maxargc = INITIAL_MAXARGC;
208 nargv = (char **) malloc (maxargc * sizeof (char *)); 204 nargv = (char **) xmalloc (maxargc * sizeof (char *));
209 } 205 }
210 else 206 else
211 { 207 {
212 maxargc *= 2; 208 maxargc *= 2;
213 nargv = (char **) realloc (argv, maxargc * sizeof (char *)); 209 nargv = (char **) xrealloc (argv, maxargc * sizeof (char *));
214 }
215 if (nargv == NULL)
216 {
217 if (argv != NULL)
218 {
219 freeargv (argv);
220 argv = NULL;
221 }
222 break;
223 } 210 }
224 argv = nargv; 211 argv = nargv;
225 argv[argc] = NULL; 212 argv[argc] = NULL;
226 } 213 }
227 /* Begin scanning arg */ 214 /* Begin scanning arg */
282 } 269 }
283 input++; 270 input++;
284 } 271 }
285 } 272 }
286 *arg = EOS; 273 *arg = EOS;
287 argv[argc] = strdup (copybuf); 274 argv[argc] = xstrdup (copybuf);
288 if (argv[argc] == NULL)
289 {
290 freeargv (argv);
291 argv = NULL;
292 break;
293 }
294 argc++; 275 argc++;
295 argv[argc] = NULL; 276 argv[argc] = NULL;
296 277
297 consume_whitespace (&input); 278 consume_whitespace (&input);
298 } 279 }
299 while (*input != EOS); 280 while (*input != EOS);
281
282 free (copybuf);
300 } 283 }
301 return (argv); 284 return (argv);
302 } 285 }
303 286
304 /* 287 /*
305 288
306 @deftypefn Extension int writeargv (const char **@var{argv}, FILE *@var{file}) 289 @deftypefn Extension int writeargv (char * const *@var{argv}, FILE *@var{file})
307 290
308 Write each member of ARGV, handling all necessary quoting, to the file 291 Write each member of ARGV, handling all necessary quoting, to the file
309 named by FILE, separated by whitespace. Return 0 on success, non-zero 292 named by FILE, separated by whitespace. Return 0 on success, non-zero
310 if an error occurred while writing to FILE. 293 if an error occurred while writing to FILE.
311 294
312 @end deftypefn 295 @end deftypefn
313 296
314 */ 297 */
315 298
316 int 299 int
317 writeargv (char **argv, FILE *f) 300 writeargv (char * const *argv, FILE *f)
318 { 301 {
319 int status = 0; 302 int status = 0;
320 303
321 if (f == NULL) 304 if (f == NULL)
322 return 1; 305 return 1;
409 /* Dynamically allocated storage for the options read from the 392 /* Dynamically allocated storage for the options read from the
410 response file. */ 393 response file. */
411 char **file_argv; 394 char **file_argv;
412 /* The number of options read from the response file, if any. */ 395 /* The number of options read from the response file, if any. */
413 size_t file_argc; 396 size_t file_argc;
397 #ifdef S_ISDIR
398 struct stat sb;
399 #endif
414 /* We are only interested in options of the form "@file". */ 400 /* We are only interested in options of the form "@file". */
415 filename = (*argvp)[i]; 401 filename = (*argvp)[i];
416 if (filename[0] != '@') 402 if (filename[0] != '@')
417 continue; 403 continue;
418 /* If we have iterated too many times then stop. */ 404 /* If we have iterated too many times then stop. */
419 if (-- iteration_limit == 0) 405 if (-- iteration_limit == 0)
420 { 406 {
421 fprintf (stderr, "%s: error: too many @-files encountered\n", (*argvp)[0]); 407 fprintf (stderr, "%s: error: too many @-files encountered\n", (*argvp)[0]);
422 xexit (1); 408 xexit (1);
423 } 409 }
410 #ifdef S_ISDIR
411 if (stat (filename+1, &sb) < 0)
412 continue;
413 if (S_ISDIR(sb.st_mode))
414 {
415 fprintf (stderr, "%s: error: @-file refers to a directory\n", (*argvp)[0]);
416 xexit (1);
417 }
418 #endif
424 /* Read the contents of the file. */ 419 /* Read the contents of the file. */
425 f = fopen (++filename, "r"); 420 f = fopen (++filename, "r");
426 if (!f) 421 if (!f)
427 continue; 422 continue;
428 if (fseek (f, 0L, SEEK_END) == -1) 423 if (fseek (f, 0L, SEEK_END) == -1)
453 else 448 else
454 /* Parse the string. */ 449 /* Parse the string. */
455 file_argv = buildargv (buffer); 450 file_argv = buildargv (buffer);
456 /* If *ARGVP is not already dynamically allocated, copy it. */ 451 /* If *ARGVP is not already dynamically allocated, copy it. */
457 if (!argv_dynamic) 452 if (!argv_dynamic)
458 { 453 *argvp = dupargv (*argvp);
459 *argvp = dupargv (*argvp);
460 if (!*argvp)
461 {
462 fputs ("\nout of memory\n", stderr);
463 xexit (1);
464 }
465 }
466 /* Count the number of arguments. */ 454 /* Count the number of arguments. */
467 file_argc = 0; 455 file_argc = 0;
468 while (file_argv[file_argc]) 456 while (file_argv[file_argc])
469 ++file_argc; 457 ++file_argc;
470 /* Now, insert FILE_ARGV into ARGV. The "+1" below handles the 458 /* Now, insert FILE_ARGV into ARGV. The "+1" below handles the
490 /* We're all done with the file now. */ 478 /* We're all done with the file now. */
491 fclose (f); 479 fclose (f);
492 } 480 }
493 } 481 }
494 482
483 /*
484
485 @deftypefn Extension int countargv (char * const *@var{argv})
486
487 Return the number of elements in @var{argv}.
488 Returns zero if @var{argv} is NULL.
489
490 @end deftypefn
491
492 */
493
494 int
495 countargv (char * const *argv)
496 {
497 int argc;
498
499 if (argv == NULL)
500 return 0;
501 for (argc = 0; argv[argc] != NULL; argc++)
502 continue;
503 return argc;
504 }
505
495 #ifdef MAIN 506 #ifdef MAIN
496 507
497 /* Simple little test driver. */ 508 /* Simple little test driver. */
498 509
499 static const char *const tests[] = 510 static const char *const tests[] =