Annotation of GNUtools/debug/gdb/libiberty/argv.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.