1 /* argz.c -- argz implementation for non-glibc systems
2 Copyright (C) 2004, 2006 Free Software Foundation, Inc.
3 Originally by Gary V. Vaughan <gary@gnu.org>
5 NOTE: The canonical source of this file is maintained with the
6 GNU Libtool package. Report bugs to bug-libtool@gnu.org.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation,
20 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
22 #if defined(LTDL) && defined LT_CONFIG_H
33 #include <sys/types.h>
40 argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len)
47 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
49 /* If nothing needs to be appended, no more work is required. */
53 /* Ensure there is enough room to append BUF_LEN. */
54 argz_len = *pargz_len + buf_len;
55 argz = (char *) realloc (*pargz, argz_len);
59 /* Copy characters from BUF after terminating '\0' in ARGZ. */
60 memcpy (argz + *pargz_len, buf, buf_len);
62 /* Assign new values. */
64 *pargz_len = argz_len;
71 argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len)
80 /* Make a copy of STR, but replacing each occurrence of
82 argz_len = 1+ strlen (str);
88 argz = (char *) malloc (argz_len);
92 for (p = str, q = argz; *p != EOS_CHAR; ++p)
96 /* Ignore leading delimiters, and fold consecutive
97 delimiters in STR into a single '\0' in ARGZ. */
98 if ((q > argz) && (q[-1] != EOS_CHAR))
106 /* Copy terminating EOS_CHAR. */
110 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
112 argz = (free (argz), (char *) 0);
114 /* Assign new values. */
116 *pargz_len = argz_len;
123 argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry)
127 assert (entry && *entry);
129 /* No BEFORE address indicates ENTRY should be inserted after the
130 current last element. */
132 return argz_append (pargz, pargz_len, entry, 1+ strlen (entry));
134 /* This probably indicates a programmer error, but to preserve
135 semantics, scan back to the start of an entry if BEFORE points
136 into the middle of it. */
137 while ((before > *pargz) && (before[-1] != EOS_CHAR))
141 size_t entry_len = 1+ strlen (entry);
142 size_t argz_len = *pargz_len + entry_len;
143 size_t offset = before - *pargz;
144 char *argz = (char *) realloc (*pargz, argz_len);
149 /* Make BEFORE point to the equivalent offset in ARGZ that it
150 used to have in *PARGZ incase realloc() moved the block. */
151 before = argz + offset;
153 /* Move the ARGZ entries starting at BEFORE up into the new
154 space at the end -- making room to copy ENTRY into the
156 memmove (before + entry_len, before, *pargz_len - offset);
157 memcpy (before, entry, entry_len);
159 /* Assign new values. */
161 *pargz_len = argz_len;
169 argz_next (char *argz, size_t argz_len, const char *entry)
171 assert ((argz && argz_len) || (!argz && !argz_len));
175 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
176 within the ARGZ vector. */
177 assert ((!argz && !argz_len)
178 || ((argz <= entry) && (entry < (argz + argz_len))));
180 /* Move to the char immediately after the terminating
182 entry = 1+ strchr (entry, EOS_CHAR);
184 /* Return either the new ENTRY, or else NULL if ARGZ is
186 return (entry >= argz + argz_len) ? 0 : (char *) entry;
190 /* This should probably be flagged as a programmer error,
191 since starting an argz_next loop with the iterator set
192 to ARGZ is safer. To preserve semantics, handle the NULL
193 case by returning the start of ARGZ (if any). */
203 argz_stringify (char *argz, size_t argz_len, int sep)
205 assert ((argz && argz_len) || (!argz && !argz_len));
209 --argz_len; /* don't stringify the terminating EOS */
210 while (--argz_len > 0)
212 if (argz[argz_len] == EOS_CHAR)
213 argz[argz_len] = sep;