Annotation of sql/sqlite/libltdl/argz.c, revision 1.1

1.1     ! moko        1: /* argz.c -- argz implementation for non-glibc systems
        !             2: 
        !             3:    Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
        !             4:    Written by Gary V. Vaughan, 2004
        !             5: 
        !             6:    NOTE: The canonical source of this file is maintained with the
        !             7:    GNU Libtool package.  Report bugs to bug-libtool@gnu.org.
        !             8: 
        !             9: GNU Libltdl is free software; you can redistribute it and/or
        !            10: modify it under the terms of the GNU Lesser General Public
        !            11: License as published by the Free Software Foundation; either
        !            12: version 2 of the License, or (at your option) any later version.
        !            13: 
        !            14: As a special exception to the GNU Lesser General Public License,
        !            15: if you distribute this file as part of a program or library that
        !            16: is built using GNU Libtool, you may include this file under the
        !            17: same distribution terms that you use for the rest of that program.
        !            18: 
        !            19: GNU Libltdl is distributed in the hope that it will be useful,
        !            20: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            21: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            22: GNU Lesser General Public License for more details.
        !            23: 
        !            24: You should have received a copy of the GNU Lesser General Public
        !            25: License along with GNU Libltdl; see the file COPYING.LIB.  If not, a
        !            26: copy can be downloaded from  http://www.gnu.org/licenses/lgpl.html,
        !            27: or obtained by writing to the Free Software Foundation, Inc.,
        !            28: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
        !            29: */
        !            30: 
        !            31: #if defined(LTDL) && defined LT_CONFIG_H
        !            32: #  include LT_CONFIG_H
        !            33: #else
        !            34: #  include <config.h>
        !            35: #endif
        !            36: 
        !            37: #include <argz.h>
        !            38: 
        !            39: #include <assert.h>
        !            40: #include <stddef.h>
        !            41: #include <stdlib.h>
        !            42: #include <sys/types.h>
        !            43: #include <errno.h>
        !            44: #include <string.h>
        !            45: 
        !            46: #define EOS_CHAR '\0'
        !            47: 
        !            48: error_t
        !            49: argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len)
        !            50: {
        !            51:   size_t argz_len;
        !            52:   char  *argz;
        !            53: 
        !            54:   assert (pargz);
        !            55:   assert (pargz_len);
        !            56:   assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
        !            57: 
        !            58:   /* If nothing needs to be appended, no more work is required.  */
        !            59:   if (buf_len == 0)
        !            60:     return 0;
        !            61: 
        !            62:   /* Ensure there is enough room to append BUF_LEN.  */
        !            63:   argz_len = *pargz_len + buf_len;
        !            64:   argz = (char *) realloc (*pargz, argz_len);
        !            65:   if (!argz)
        !            66:     return ENOMEM;
        !            67: 
        !            68:   /* Copy characters from BUF after terminating '\0' in ARGZ.  */
        !            69:   memcpy (argz + *pargz_len, buf, buf_len);
        !            70: 
        !            71:   /* Assign new values.  */
        !            72:   *pargz = argz;
        !            73:   *pargz_len = argz_len;
        !            74: 
        !            75:   return 0;
        !            76: }
        !            77: 
        !            78: 
        !            79: error_t
        !            80: argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len)
        !            81: {
        !            82:   size_t argz_len;
        !            83:   char *argz = 0;
        !            84: 
        !            85:   assert (str);
        !            86:   assert (pargz);
        !            87:   assert (pargz_len);
        !            88: 
        !            89:   /* Make a copy of STR, but replacing each occurrence of
        !            90:      DELIM with '\0'.  */
        !            91:   argz_len = 1+ strlen (str);
        !            92:   if (argz_len)
        !            93:     {
        !            94:       const char *p;
        !            95:       char *q;
        !            96: 
        !            97:       argz = (char *) malloc (argz_len);
        !            98:       if (!argz)
        !            99:        return ENOMEM;
        !           100: 
        !           101:       for (p = str, q = argz; *p != EOS_CHAR; ++p)
        !           102:        {
        !           103:          if (*p == delim)
        !           104:            {
        !           105:              /* Ignore leading delimiters, and fold consecutive
        !           106:                 delimiters in STR into a single '\0' in ARGZ.  */
        !           107:              if ((q > argz) && (q[-1] != EOS_CHAR))
        !           108:                *q++ = EOS_CHAR;
        !           109:              else
        !           110:                --argz_len;
        !           111:            }
        !           112:          else
        !           113:            *q++ = *p;
        !           114:        }
        !           115:       /* Copy terminating EOS_CHAR.  */
        !           116:       *q = *p;
        !           117:     }
        !           118: 
        !           119:   /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory.  */
        !           120:   if (!argz_len)
        !           121:     argz = (free (argz), (char *) 0);
        !           122: 
        !           123:   /* Assign new values.  */
        !           124:   *pargz = argz;
        !           125:   *pargz_len = argz_len;
        !           126: 
        !           127:   return 0;
        !           128: }
        !           129: 
        !           130: 
        !           131: error_t
        !           132: argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry)
        !           133: {
        !           134:   assert (pargz);
        !           135:   assert (pargz_len);
        !           136:   assert (entry && *entry);
        !           137: 
        !           138:   /* No BEFORE address indicates ENTRY should be inserted after the
        !           139:      current last element.  */
        !           140:   if (!before)
        !           141:     return argz_append (pargz, pargz_len, entry, 1+ strlen (entry));
        !           142: 
        !           143:   /* This probably indicates a programmer error, but to preserve
        !           144:      semantics, scan back to the start of an entry if BEFORE points
        !           145:      into the middle of it.  */
        !           146:   while ((before > *pargz) && (before[-1] != EOS_CHAR))
        !           147:     --before;
        !           148: 
        !           149:   {
        !           150:     size_t entry_len   = 1+ strlen (entry);
        !           151:     size_t argz_len    = *pargz_len + entry_len;
        !           152:     size_t offset      = before - *pargz;
        !           153:     char   *argz       = (char *) realloc (*pargz, argz_len);
        !           154: 
        !           155:     if (!argz)
        !           156:       return ENOMEM;
        !           157: 
        !           158:     /* Make BEFORE point to the equivalent offset in ARGZ that it
        !           159:        used to have in *PARGZ incase realloc() moved the block.  */
        !           160:     before = argz + offset;
        !           161: 
        !           162:     /* Move the ARGZ entries starting at BEFORE up into the new
        !           163:        space at the end -- making room to copy ENTRY into the
        !           164:        resulting gap.  */
        !           165:     memmove (before + entry_len, before, *pargz_len - offset);
        !           166:     memcpy  (before, entry, entry_len);
        !           167: 
        !           168:     /* Assign new values.  */
        !           169:     *pargz = argz;
        !           170:     *pargz_len = argz_len;
        !           171:   }
        !           172: 
        !           173:   return 0;
        !           174: }
        !           175: 
        !           176: 
        !           177: char *
        !           178: argz_next (char *argz, size_t argz_len, const char *entry)
        !           179: {
        !           180:   assert ((argz && argz_len) || (!argz && !argz_len));
        !           181: 
        !           182:   if (entry)
        !           183:     {
        !           184:       /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
        !           185:         within the ARGZ vector.  */
        !           186:       assert ((!argz && !argz_len)
        !           187:              || ((argz <= entry) && (entry < (argz + argz_len))));
        !           188: 
        !           189:       /* Move to the char immediately after the terminating
        !           190:         '\0' of ENTRY.  */
        !           191:       entry = 1+ strchr (entry, EOS_CHAR);
        !           192: 
        !           193:       /* Return either the new ENTRY, or else NULL if ARGZ is
        !           194:         exhausted.  */
        !           195:       return (entry >= argz + argz_len) ? 0 : (char *) entry;
        !           196:     }
        !           197:   else
        !           198:     {
        !           199:       /* This should probably be flagged as a programmer error,
        !           200:         since starting an argz_next loop with the iterator set
        !           201:         to ARGZ is safer.  To preserve semantics, handle the NULL
        !           202:         case by returning the start of ARGZ (if any).  */
        !           203:       if (argz_len > 0)
        !           204:        return argz;
        !           205:       else
        !           206:        return 0;
        !           207:     }
        !           208: }
        !           209: 
        !           210: 
        !           211: void
        !           212: argz_stringify (char *argz, size_t argz_len, int sep)
        !           213: {
        !           214:   assert ((argz && argz_len) || (!argz && !argz_len));
        !           215: 
        !           216:   if (sep)
        !           217:     {
        !           218:       --argz_len;              /* don't stringify the terminating EOS */
        !           219:       while (--argz_len > 0)
        !           220:        {
        !           221:          if (argz[argz_len] == EOS_CHAR)
        !           222:            argz[argz_len] = sep;
        !           223:        }
        !           224:     }
        !           225: }
        !           226: 

E-mail: