OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [libiberty/] [argv.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Create and destroy argument vectors (argv's)
2
   Copyright (C) 1992, 2001 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., 59 Temple Place - Suite 330,
19
Boston, MA 02111-1307, 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
#include "ansidecl.h"
26
#include "libiberty.h"
27
 
28
#define ISBLANK(ch) ((ch) == ' ' || (ch) == '\t')
29
 
30
/*  Routines imported from standard C runtime libraries. */
31
 
32
#ifdef __STDC__
33
 
34
#include <stddef.h>
35
#include <string.h>
36
#include <stdlib.h>
37
 
38
#else   /* !__STDC__ */
39
 
40
#if !defined _WIN32 || defined __GNUC__
41
extern char *memcpy ();         /* Copy memory region */
42
extern int strlen ();           /* Count length of string */
43
extern char *malloc ();         /* Standard memory allocater */
44
extern char *realloc ();        /* Standard memory reallocator */
45
extern void free ();            /* Free malloc'd memory */
46
extern char *strdup ();         /* Duplicate a string */
47
#endif
48
 
49
#endif  /* __STDC__ */
50
 
51
 
52
#ifndef NULL
53
#define NULL 0
54
#endif
55
 
56
#ifndef EOS
57
#define EOS '\0'
58
#endif
59
 
60
#define INITIAL_MAXARGC 8       /* Number of args + NULL in initial argv */
61
 
62
 
63
/*
64
 
65
@deftypefn Extension char** dupargv (char **@var{vector})
66
 
67
Duplicate an argument vector.  Simply scans through @var{vector},
68
duplicating each argument until the terminating @code{NULL} is found.
69
Returns a pointer to the argument vector if successful.  Returns
70
@code{NULL} if there is insufficient memory to complete building the
71
argument vector.
72
 
73
@end deftypefn
74
 
75
*/
76
 
77
char **
78
dupargv (argv)
79
     char **argv;
80
{
81
  int argc;
82
  char **copy;
83
 
84
  if (argv == NULL)
85
    return NULL;
86
 
87
  /* the vector */
88
  for (argc = 0; argv[argc] != NULL; argc++);
89
  copy = (char **) malloc ((argc + 1) * sizeof (char *));
90
  if (copy == NULL)
91
    return NULL;
92
 
93
  /* the strings */
94
  for (argc = 0; argv[argc] != NULL; argc++)
95
    {
96
      int len = strlen (argv[argc]);
97
      copy[argc] = malloc (sizeof (char *) * (len + 1));
98
      if (copy[argc] == NULL)
99
        {
100
          freeargv (copy);
101
          return NULL;
102
        }
103
      strcpy (copy[argc], argv[argc]);
104
    }
105
  copy[argc] = NULL;
106
  return copy;
107
}
108
 
109
/*
110
 
111
@deftypefn Extension void freeargv (char **@var{vector})
112
 
113
Free an argument vector that was built using @code{buildargv}.  Simply
114
scans through @var{vector}, freeing the memory for each argument until
115
the terminating @code{NULL} is found, and then frees @var{vector}
116
itself.
117
 
118
@end deftypefn
119
 
120
*/
121
 
122
void freeargv (vector)
123
char **vector;
124
{
125
  register char **scan;
126
 
127
  if (vector != NULL)
128
    {
129
      for (scan = vector; *scan != NULL; scan++)
130
        {
131
          free (*scan);
132
        }
133
      free (vector);
134
    }
135
}
136
 
137
/*
138
 
139
@deftypefn Extension char** buildargv (char *@var{sp})
140
 
141
Given a pointer to a string, parse the string extracting fields
142
separated by whitespace and optionally enclosed within either single
143
or double quotes (which are stripped off), and build a vector of
144
pointers to copies of the string for each field.  The input string
145
remains unchanged.  The last element of the vector is followed by a
146
@code{NULL} element.
147
 
148
All of the memory for the pointer array and copies of the string
149
is obtained from @code{malloc}.  All of the memory can be returned to the
150
system with the single function call @code{freeargv}, which takes the
151
returned result of @code{buildargv}, as it's argument.
152
 
153
Returns a pointer to the argument vector if successful.  Returns
154
@code{NULL} if @var{sp} is @code{NULL} or if there is insufficient
155
memory to complete building the argument vector.
156
 
157
If the input is a null string (as opposed to a @code{NULL} pointer),
158
then buildarg returns an argument vector that has one arg, a null
159
string.
160
 
161
@end deftypefn
162
 
163
The memory for the argv array is dynamically expanded as necessary.
164
 
165
In order to provide a working buffer for extracting arguments into,
166
with appropriate stripping of quotes and translation of backslash
167
sequences, we allocate a working buffer at least as long as the input
168
string.  This ensures that we always have enough space in which to
169
work, since the extracted arg is never larger than the input string.
170
 
171
The argument vector is always kept terminated with a @code{NULL} arg
172
pointer, so it can be passed to @code{freeargv} at any time, or
173
returned, as appropriate.
174
 
175
*/
176
 
177
char **buildargv (input)
178
     const char *input;
179
{
180
  char *arg;
181
  char *copybuf;
182
  int squote = 0;
183
  int dquote = 0;
184
  int bsquote = 0;
185
  int argc = 0;
186
  int maxargc = 0;
187
  char **argv = NULL;
188
  char **nargv;
189
 
190
  if (input != NULL)
191
    {
192
      copybuf = (char *) alloca (strlen (input) + 1);
193
      /* Is a do{}while to always execute the loop once.  Always return an
194
         argv, even for null strings.  See NOTES above, test case below. */
195
      do
196
        {
197
          /* Pick off argv[argc] */
198
          while (ISBLANK (*input))
199
            {
200
              input++;
201
            }
202
          if ((maxargc == 0) || (argc >= (maxargc - 1)))
203
            {
204
              /* argv needs initialization, or expansion */
205
              if (argv == NULL)
206
                {
207
                  maxargc = INITIAL_MAXARGC;
208
                  nargv = (char **) malloc (maxargc * sizeof (char *));
209
                }
210
              else
211
                {
212
                  maxargc *= 2;
213
                  nargv = (char **) realloc (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
                }
224
              argv = nargv;
225
              argv[argc] = NULL;
226
            }
227
          /* Begin scanning arg */
228
          arg = copybuf;
229
          while (*input != EOS)
230
            {
231
              if (ISBLANK (*input) && !squote && !dquote && !bsquote)
232
                {
233
                  break;
234
                }
235
              else
236
                {
237
                  if (bsquote)
238
                    {
239
                      bsquote = 0;
240
                      *arg++ = *input;
241
                    }
242
                  else if (*input == '\\')
243
                    {
244
                      bsquote = 1;
245
                    }
246
                  else if (squote)
247
                    {
248
                      if (*input == '\'')
249
                        {
250
                          squote = 0;
251
                        }
252
                      else
253
                        {
254
                          *arg++ = *input;
255
                        }
256
                    }
257
                  else if (dquote)
258
                    {
259
                      if (*input == '"')
260
                        {
261
                          dquote = 0;
262
                        }
263
                      else
264
                        {
265
                          *arg++ = *input;
266
                        }
267
                    }
268
                  else
269
                    {
270
                      if (*input == '\'')
271
                        {
272
                          squote = 1;
273
                        }
274
                      else if (*input == '"')
275
                        {
276
                          dquote = 1;
277
                        }
278
                      else
279
                        {
280
                          *arg++ = *input;
281
                        }
282
                    }
283
                  input++;
284
                }
285
            }
286
          *arg = EOS;
287
          argv[argc] = strdup (copybuf);
288
          if (argv[argc] == NULL)
289
            {
290
              freeargv (argv);
291
              argv = NULL;
292
              break;
293
            }
294
          argc++;
295
          argv[argc] = NULL;
296
 
297
          while (ISBLANK (*input))
298
            {
299
              input++;
300
            }
301
        }
302
      while (*input != EOS);
303
    }
304
  return (argv);
305
}
306
 
307
#ifdef MAIN
308
 
309
/* Simple little test driver. */
310
 
311
static const char *const tests[] =
312
{
313
  "a simple command line",
314
  "arg 'foo' is single quoted",
315
  "arg \"bar\" is double quoted",
316
  "arg \"foo bar\" has embedded whitespace",
317
  "arg 'Jack said \\'hi\\'' has single quotes",
318
  "arg 'Jack said \\\"hi\\\"' has double quotes",
319
  "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",
320
 
321
  /* This should be expanded into only one argument.  */
322
  "trailing-whitespace ",
323
 
324
  "",
325
  NULL
326
};
327
 
328
int main ()
329
{
330
  char **argv;
331
  const char *const *test;
332
  char **targs;
333
 
334
  for (test = tests; *test != NULL; test++)
335
    {
336
      printf ("buildargv(\"%s\")\n", *test);
337
      if ((argv = buildargv (*test)) == NULL)
338
        {
339
          printf ("failed!\n\n");
340
        }
341
      else
342
        {
343
          for (targs = argv; *targs != NULL; targs++)
344
            {
345
              printf ("\t\"%s\"\n", *targs);
346
            }
347
          printf ("\n");
348
        }
349
      freeargv (argv);
350
    }
351
 
352
  return 0;
353
}
354
 
355
#endif  /* MAIN */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.