Annotation of sql/pgsql/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: