~ubuntu-branches/ubuntu/wily/ntop/wily-proposed

« back to all changes in this revision

Viewing changes to ntop/intop/argv.c

  • Committer: Bazaar Package Importer
  • Author(s): Dennis Schoen
  • Date: 2002-04-12 11:38:47 UTC
  • Revision ID: james.westby@ubuntu.com-20020412113847-4k4yydw0pzybc6g8
Tags: upstream-2.0.0
ImportĀ upstreamĀ versionĀ 2.0.0

Show diffs side-by-side

added added

removed removed

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