Mercurial > hg > CbC > CbC_gcc
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[] = |