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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [libiberty/] [argv.c] - Diff between revs 579 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 579 Rev 1765
/* Create and destroy argument vectors (argv's)
/* Create and destroy argument vectors (argv's)
   Copyright (C) 1992 Free Software Foundation, Inc.
   Copyright (C) 1992 Free Software Foundation, Inc.
   Written by Fred Fish @ Cygnus Support
   Written by Fred Fish @ Cygnus Support
 
 
This file is part of the libiberty library.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
version 2 of the License, or (at your option) any later version.
 
 
Libiberty is distributed in the hope that it will be useful,
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.
Library General Public License for more details.
 
 
You should have received a copy of the GNU Library General Public
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB.  If
License along with libiberty; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */
Boston, MA 02111-1307, USA.  */
 
 
 
 
/*  Create and destroy argument vectors.  An argument vector is simply an
/*  Create and destroy argument vectors.  An argument vector is simply an
    array of string pointers, terminated by a NULL pointer. */
    array of string pointers, terminated by a NULL pointer. */
 
 
#include "ansidecl.h"
#include "ansidecl.h"
#include "libiberty.h"
#include "libiberty.h"
 
 
#define ISBLANK(ch) ((ch) == ' ' || (ch) == '\t')
#define ISBLANK(ch) ((ch) == ' ' || (ch) == '\t')
 
 
/*  Routines imported from standard C runtime libraries. */
/*  Routines imported from standard C runtime libraries. */
 
 
#ifdef __STDC__
#ifdef __STDC__
 
 
#include <stddef.h>
#include <stddef.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
 
 
#else   /* !__STDC__ */
#else   /* !__STDC__ */
 
 
#if !defined _WIN32 || defined __GNUC__
#if !defined _WIN32 || defined __GNUC__
extern char *memcpy ();         /* Copy memory region */
extern char *memcpy ();         /* Copy memory region */
extern int strlen ();           /* Count length of string */
extern int strlen ();           /* Count length of string */
extern char *malloc ();         /* Standard memory allocater */
extern char *malloc ();         /* Standard memory allocater */
extern char *realloc ();        /* Standard memory reallocator */
extern char *realloc ();        /* Standard memory reallocator */
extern void free ();            /* Free malloc'd memory */
extern void free ();            /* Free malloc'd memory */
extern char *strdup ();         /* Duplicate a string */
extern char *strdup ();         /* Duplicate a string */
#endif
#endif
 
 
#endif  /* __STDC__ */
#endif  /* __STDC__ */
 
 
 
 
#ifndef NULL
#ifndef NULL
#define NULL 0
#define NULL 0
#endif
#endif
 
 
#ifndef EOS
#ifndef EOS
#define EOS '\0'
#define EOS '\0'
#endif
#endif
 
 
#define INITIAL_MAXARGC 8       /* Number of args + NULL in initial argv */
#define INITIAL_MAXARGC 8       /* Number of args + NULL in initial argv */
 
 
 
 
/*
/*
 
 
NAME
NAME
 
 
        dupargv -- duplicate an argument vector
        dupargv -- duplicate an argument vector
 
 
SYNOPSIS
SYNOPSIS
 
 
        char **dupargv (vector)
        char **dupargv (vector)
        char **vector;
        char **vector;
 
 
DESCRIPTION
DESCRIPTION
 
 
        Duplicate an argument vector.  Simply scans through the
        Duplicate an argument vector.  Simply scans through the
        vector, duplicating each argument until the
        vector, duplicating each argument until the
        terminating NULL is found.
        terminating NULL is found.
 
 
RETURNS
RETURNS
 
 
        Returns a pointer to the argument vector if
        Returns a pointer to the argument vector if
        successful. Returns NULL if there is insufficient memory to
        successful. Returns NULL if there is insufficient memory to
        complete building the argument vector.
        complete building the argument vector.
 
 
*/
*/
 
 
char **
char **
dupargv (argv)
dupargv (argv)
     char **argv;
     char **argv;
{
{
  int argc;
  int argc;
  char **copy;
  char **copy;
 
 
  if (argv == NULL)
  if (argv == NULL)
    return NULL;
    return NULL;
 
 
  /* the vector */
  /* the vector */
  for (argc = 0; argv[argc] != NULL; argc++);
  for (argc = 0; argv[argc] != NULL; argc++);
  copy = (char **) malloc ((argc + 1) * sizeof (char *));
  copy = (char **) malloc ((argc + 1) * sizeof (char *));
  if (copy == NULL)
  if (copy == NULL)
    return NULL;
    return NULL;
 
 
  /* the strings */
  /* the strings */
  for (argc = 0; argv[argc] != NULL; argc++)
  for (argc = 0; argv[argc] != NULL; argc++)
    {
    {
      int len = strlen (argv[argc]);
      int len = strlen (argv[argc]);
      copy[argc] = malloc (sizeof (char *) * (len + 1));
      copy[argc] = malloc (sizeof (char *) * (len + 1));
      if (copy[argc] == NULL)
      if (copy[argc] == NULL)
        {
        {
          freeargv (copy);
          freeargv (copy);
          return NULL;
          return NULL;
        }
        }
      strcpy (copy[argc], argv[argc]);
      strcpy (copy[argc], argv[argc]);
    }
    }
  copy[argc] = NULL;
  copy[argc] = NULL;
  return copy;
  return copy;
}
}
 
 
/*
/*
 
 
NAME
NAME
 
 
        freeargv -- free an argument vector
        freeargv -- free an argument vector
 
 
SYNOPSIS
SYNOPSIS
 
 
        void freeargv (vector)
        void freeargv (vector)
        char **vector;
        char **vector;
 
 
DESCRIPTION
DESCRIPTION
 
 
        Free an argument vector that was built using buildargv.  Simply scans
        Free an argument vector that was built using buildargv.  Simply scans
        through the vector, freeing the memory for each argument until the
        through the vector, freeing the memory for each argument until the
        terminating NULL is found, and then frees the vector itself.
        terminating NULL is found, and then frees the vector itself.
 
 
RETURNS
RETURNS
 
 
        No value.
        No value.
 
 
*/
*/
 
 
void freeargv (vector)
void freeargv (vector)
char **vector;
char **vector;
{
{
  register char **scan;
  register char **scan;
 
 
  if (vector != NULL)
  if (vector != NULL)
    {
    {
      for (scan = vector; *scan != NULL; scan++)
      for (scan = vector; *scan != NULL; scan++)
        {
        {
          free (*scan);
          free (*scan);
        }
        }
      free (vector);
      free (vector);
    }
    }
}
}
 
 
/*
/*
 
 
NAME
NAME
 
 
        buildargv -- build an argument vector from a string
        buildargv -- build an argument vector from a string
 
 
SYNOPSIS
SYNOPSIS
 
 
        char **buildargv (sp)
        char **buildargv (sp)
        char *sp;
        char *sp;
 
 
DESCRIPTION
DESCRIPTION
 
 
        Given a pointer to a string, parse the string extracting fields
        Given a pointer to a string, parse the string extracting fields
        separated by whitespace and optionally enclosed within either single
        separated by whitespace and optionally enclosed within either single
        or double quotes (which are stripped off), and build a vector of
        or double quotes (which are stripped off), and build a vector of
        pointers to copies of the string for each field.  The input string
        pointers to copies of the string for each field.  The input string
        remains unchanged.
        remains unchanged.
 
 
        All of the memory for the pointer array and copies of the string
        All of the memory for the pointer array and copies of the string
        is obtained from malloc.  All of the memory can be returned to the
        is obtained from malloc.  All of the memory can be returned to the
        system with the single function call freeargv, which takes the
        system with the single function call freeargv, which takes the
        returned result of buildargv, as it's argument.
        returned result of buildargv, as it's argument.
 
 
        The memory for the argv array is dynamically expanded as necessary.
        The memory for the argv array is dynamically expanded as necessary.
 
 
RETURNS
RETURNS
 
 
        Returns a pointer to the argument vector if successful. Returns NULL
        Returns a pointer to the argument vector if successful. Returns NULL
        if the input string pointer is NULL or if there is insufficient
        if the input string pointer is NULL or if there is insufficient
        memory to complete building the argument vector.
        memory to complete building the argument vector.
 
 
NOTES
NOTES
 
 
        In order to provide a working buffer for extracting arguments into,
        In order to provide a working buffer for extracting arguments into,
        with appropriate stripping of quotes and translation of backslash
        with appropriate stripping of quotes and translation of backslash
        sequences, we allocate a working buffer at least as long as the input
        sequences, we allocate a working buffer at least as long as the input
        string.  This ensures that we always have enough space in which to
        string.  This ensures that we always have enough space in which to
        work, since the extracted arg is never larger than the input string.
        work, since the extracted arg is never larger than the input string.
 
 
        If the input is a null string (as opposed to a NULL pointer), then
        If the input is a null string (as opposed to a NULL pointer), then
        buildarg returns an argv that has one arg, a null string.
        buildarg returns an argv that has one arg, a null string.
 
 
        Argv is always kept terminated with a NULL arg pointer, so it can
        Argv is always kept terminated with a NULL arg pointer, so it can
        be passed to freeargv at any time, or returned, as appropriate.
        be passed to freeargv at any time, or returned, as appropriate.
*/
*/
 
 
char **buildargv (input)
char **buildargv (input)
char *input;
char *input;
{
{
  char *arg;
  char *arg;
  char *copybuf;
  char *copybuf;
  int squote = 0;
  int squote = 0;
  int dquote = 0;
  int dquote = 0;
  int bsquote = 0;
  int bsquote = 0;
  int argc = 0;
  int argc = 0;
  int maxargc = 0;
  int maxargc = 0;
  char **argv = NULL;
  char **argv = NULL;
  char **nargv;
  char **nargv;
 
 
  if (input != NULL)
  if (input != NULL)
    {
    {
      copybuf = (char *) alloca (strlen (input) + 1);
      copybuf = (char *) alloca (strlen (input) + 1);
      /* Is a do{}while to always execute the loop once.  Always return an
      /* Is a do{}while to always execute the loop once.  Always return an
         argv, even for null strings.  See NOTES above, test case below. */
         argv, even for null strings.  See NOTES above, test case below. */
      do
      do
        {
        {
          /* Pick off argv[argc] */
          /* Pick off argv[argc] */
          while (ISBLANK (*input))
          while (ISBLANK (*input))
            {
            {
              input++;
              input++;
            }
            }
          if ((maxargc == 0) || (argc >= (maxargc - 1)))
          if ((maxargc == 0) || (argc >= (maxargc - 1)))
            {
            {
              /* argv needs initialization, or expansion */
              /* argv needs initialization, or expansion */
              if (argv == NULL)
              if (argv == NULL)
                {
                {
                  maxargc = INITIAL_MAXARGC;
                  maxargc = INITIAL_MAXARGC;
                  nargv = (char **) malloc (maxargc * sizeof (char *));
                  nargv = (char **) malloc (maxargc * sizeof (char *));
                }
                }
              else
              else
                {
                {
                  maxargc *= 2;
                  maxargc *= 2;
                  nargv = (char **) realloc (argv, maxargc * sizeof (char *));
                  nargv = (char **) realloc (argv, maxargc * sizeof (char *));
                }
                }
              if (nargv == NULL)
              if (nargv == NULL)
                {
                {
                  if (argv != NULL)
                  if (argv != NULL)
                    {
                    {
                      freeargv (argv);
                      freeargv (argv);
                      argv = NULL;
                      argv = NULL;
                    }
                    }
                  break;
                  break;
                }
                }
              argv = nargv;
              argv = nargv;
              argv[argc] = NULL;
              argv[argc] = NULL;
            }
            }
          /* Begin scanning arg */
          /* Begin scanning arg */
          arg = copybuf;
          arg = copybuf;
          while (*input != EOS)
          while (*input != EOS)
            {
            {
              if (ISBLANK (*input) && !squote && !dquote && !bsquote)
              if (ISBLANK (*input) && !squote && !dquote && !bsquote)
                {
                {
                  break;
                  break;
                }
                }
              else
              else
                {
                {
                  if (bsquote)
                  if (bsquote)
                    {
                    {
                      bsquote = 0;
                      bsquote = 0;
                      *arg++ = *input;
                      *arg++ = *input;
                    }
                    }
                  else if (*input == '\\')
                  else if (*input == '\\')
                    {
                    {
                      bsquote = 1;
                      bsquote = 1;
                    }
                    }
                  else if (squote)
                  else if (squote)
                    {
                    {
                      if (*input == '\'')
                      if (*input == '\'')
                        {
                        {
                          squote = 0;
                          squote = 0;
                        }
                        }
                      else
                      else
                        {
                        {
                          *arg++ = *input;
                          *arg++ = *input;
                        }
                        }
                    }
                    }
                  else if (dquote)
                  else if (dquote)
                    {
                    {
                      if (*input == '"')
                      if (*input == '"')
                        {
                        {
                          dquote = 0;
                          dquote = 0;
                        }
                        }
                      else
                      else
                        {
                        {
                          *arg++ = *input;
                          *arg++ = *input;
                        }
                        }
                    }
                    }
                  else
                  else
                    {
                    {
                      if (*input == '\'')
                      if (*input == '\'')
                        {
                        {
                          squote = 1;
                          squote = 1;
                        }
                        }
                      else if (*input == '"')
                      else if (*input == '"')
                        {
                        {
                          dquote = 1;
                          dquote = 1;
                        }
                        }
                      else
                      else
                        {
                        {
                          *arg++ = *input;
                          *arg++ = *input;
                        }
                        }
                    }
                    }
                  input++;
                  input++;
                }
                }
            }
            }
          *arg = EOS;
          *arg = EOS;
          argv[argc] = strdup (copybuf);
          argv[argc] = strdup (copybuf);
          if (argv[argc] == NULL)
          if (argv[argc] == NULL)
            {
            {
              freeargv (argv);
              freeargv (argv);
              argv = NULL;
              argv = NULL;
              break;
              break;
            }
            }
          argc++;
          argc++;
          argv[argc] = NULL;
          argv[argc] = NULL;
 
 
          while (ISBLANK (*input))
          while (ISBLANK (*input))
            {
            {
              input++;
              input++;
            }
            }
        }
        }
      while (*input != EOS);
      while (*input != EOS);
    }
    }
  return (argv);
  return (argv);
}
}
 
 
#ifdef MAIN
#ifdef MAIN
 
 
/* Simple little test driver. */
/* Simple little test driver. */
 
 
static char *tests[] =
static char *tests[] =
{
{
  "a simple command line",
  "a simple command line",
  "arg 'foo' is single quoted",
  "arg 'foo' is single quoted",
  "arg \"bar\" is double quoted",
  "arg \"bar\" is double quoted",
  "arg \"foo bar\" has embedded whitespace",
  "arg \"foo bar\" has embedded whitespace",
  "arg 'Jack said \\'hi\\'' has single quotes",
  "arg 'Jack said \\'hi\\'' has single quotes",
  "arg 'Jack said \\\"hi\\\"' has double quotes",
  "arg 'Jack said \\\"hi\\\"' has double quotes",
  "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",
  "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",
 
 
  /* This should be expanded into only one argument.  */
  /* This should be expanded into only one argument.  */
  "trailing-whitespace ",
  "trailing-whitespace ",
 
 
  "",
  "",
  NULL
  NULL
};
};
 
 
main ()
main ()
{
{
  char **argv;
  char **argv;
  char **test;
  char **test;
  char **targs;
  char **targs;
 
 
  for (test = tests; *test != NULL; test++)
  for (test = tests; *test != NULL; test++)
    {
    {
      printf ("buildargv(\"%s\")\n", *test);
      printf ("buildargv(\"%s\")\n", *test);
      if ((argv = buildargv (*test)) == NULL)
      if ((argv = buildargv (*test)) == NULL)
        {
        {
          printf ("failed!\n\n");
          printf ("failed!\n\n");
        }
        }
      else
      else
        {
        {
          for (targs = argv; *targs != NULL; targs++)
          for (targs = argv; *targs != NULL; targs++)
            {
            {
              printf ("\t\"%s\"\n", *targs);
              printf ("\t\"%s\"\n", *targs);
            }
            }
          printf ("\n");
          printf ("\n");
        }
        }
      freeargv (argv);
      freeargv (argv);
    }
    }
 
 
}
}
 
 
#endif  /* MAIN */
#endif  /* MAIN */
 
 

powered by: WebSVN 2.1.0

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