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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [libiberty/] [argv.c] - Blame information for rev 1780

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

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

powered by: WebSVN 2.1.0

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