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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [libiberty/] [argv.c] - Blame information for rev 1771

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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