1 /* argz.c -- argz implementation for non-glibc systems
2 Copyright (C) 2004 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(HAVE_CONFIG_H)
23 # if defined(LTDL) && defined LT_CONFIG_H
35 #include <sys/types.h>
38 #if defined(HAVE_STRING_H)
40 #elif defined(HAVE_STRINGS_H)
43 #if defined(HAVE_MEMORY_H)
50 argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len)
57 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
59 /* If nothing needs to be appended, no more work is required. */
63 /* Ensure there is enough room to append BUF_LEN. */
64 argz_len = *pargz_len + buf_len;
65 argz = (char *) realloc (*pargz, argz_len);
69 /* Copy characters from BUF after terminating '\0' in ARGZ. */
70 memcpy (argz + *pargz_len, buf, buf_len);
72 /* Assign new values. */
74 *pargz_len = argz_len;
81 argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len)
90 /* Make a copy of STR, but replacing each occurrence of
92 argz_len = 1+ strlen (str);
98 argz = (char *) malloc (argz_len);
102 for (p = str, q = argz; *p != EOS_CHAR; ++p)
106 /* Ignore leading delimiters, and fold consecutive
107 delimiters in STR into a single '\0' in ARGZ. */
108 if ((q > argz) && (q[-1] != EOS_CHAR))
116 /* Copy terminating EOS_CHAR. */
120 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
122 argz = (free (argz), (char *) 0);
124 /* Assign new values. */
126 *pargz_len = argz_len;
133 argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry)
137 assert (entry && *entry);
139 /* No BEFORE address indicates ENTRY should be inserted after the
140 current last element. */
142 return argz_append (pargz, pargz_len, entry, 1+ strlen (entry));
144 /* This probably indicates a programmer error, but to preserve
145 semantics, scan back to the start of an entry if BEFORE points
146 into the middle of it. */
147 while ((before > *pargz) && (before[-1] != EOS_CHAR))
151 size_t entry_len = 1+ strlen (entry);
152 size_t argz_len = *pargz_len + entry_len;
153 size_t offset = before - *pargz;
154 char *argz = (char *) realloc (*pargz, argz_len);
159 /* Make BEFORE point to the equivalent offset in ARGZ that it
160 used to have in *PARGZ incase realloc() moved the block. */
161 before = argz + offset;
163 /* Move the ARGZ entries starting at BEFORE up into the new
164 space at the end -- making room to copy ENTRY into the
166 memmove (before + entry_len, before, *pargz_len - offset);
167 memcpy (before, entry, entry_len);
169 /* Assign new values. */
171 *pargz_len = argz_len;
179 argz_next (char *argz, size_t argz_len, const char *entry)
181 assert ((argz && argz_len) || (!argz && !argz_len));
185 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
186 within the ARGZ vector. */
187 assert ((!argz && !argz_len)
188 || ((argz <= entry) && (entry < (argz + argz_len))));
190 /* Move to the char immediately after the terminating
192 entry = 1+ strchr (entry, EOS_CHAR);
194 /* Return either the new ENTRY, or else NULL if ARGZ is
196 return (entry >= argz + argz_len) ? 0 : (char *) entry;
200 /* This should probably be flagged as a programmer error,
201 since starting an argz_next loop with the iterator set
202 to ARGZ is safer. To preserve semantics, handle the NULL
203 case by returning the start of ARGZ (if any). */
213 argz_stringify (char *argz, size_t argz_len, int sep)
215 assert ((argz && argz_len) || (!argz && !argz_len));
219 --argz_len; /* don't stringify the terminating EOS */
220 while (--argz_len > 0)
222 if (argz[argz_len] == EOS_CHAR)
223 argz[argz_len] = sep;