summaryrefslogtreecommitdiff
path: root/libshouldbeinlibc/=argz.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-12-21 16:31:30 +0000
committerMiles Bader <miles@gnu.org>1995-12-21 16:31:30 +0000
commit0721ca63fab1108269056eec439591cb71470a31 (patch)
treea213ed308c90f88c980ceca43448f823d10e0464 /libshouldbeinlibc/=argz.c
parent381412294cc990bda245f638ad376e48a98837a0 (diff)
(argz_insert):
Instead of an integer position N, take a pointer into ARGZ to insert before.
Diffstat (limited to 'libshouldbeinlibc/=argz.c')
-rw-r--r--libshouldbeinlibc/=argz.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/libshouldbeinlibc/=argz.c b/libshouldbeinlibc/=argz.c
index d6b4e16f..f519a434 100644
--- a/libshouldbeinlibc/=argz.c
+++ b/libshouldbeinlibc/=argz.c
@@ -144,36 +144,42 @@ argz_remove (char **argz, unsigned *argz_len, char *entry)
}
}
-/* Insert ENTRY into ARGZ & ARGZ_LEN at position N. */
+/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
+ existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
+ Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN,
+ ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not
+ in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
+ ARGZ, ENOMEM is returned, else 0. */
error_t
-argz_insert (char **argz, unsigned *argz_len, unsigned n, char *entry)
+argz_insert (char **argz, unsigned *argz_len, char *before, char *entry)
{
- char *place = *argz;
- unsigned left = *argz_len;
- while (n > 0 && left > 0)
- {
- int len = strlen (place) + 1;
- place += len;
- left -= len;
- n--;
- }
- if (left < 0 || n > 0)
+ if (! before)
+ return argz_add (argz, argz_len, entry);
+
+ if (before < *argz || before >= *argz + *argz_len)
return EINVAL;
- else
- {
- unsigned entry_len = strlen (entry) + 1;
- unsigned new_argz_len = *argz_len + entry_len;
- char *new_argz = realloc (*argz, new_argz_len);
- if (new_argz)
- {
- place = new_argz + (place - *argz);
- bcopy (place, place + entry_len, left);
- bcopy (entry, place, entry_len);
- *argz = new_argz;
- *argz_len = new_argz_len;
- return 0;
- }
- else
- return ENOMEM;
- }
+
+ if (before > argz)
+ /* Make sure before is actually the beginning of an entry. */
+ while (before[-1])
+ before--;
+
+ {
+ unsigned after_before = *argz_len - (before - *argz);
+ unsigned entry_len = strlen (entry) + 1;
+ unsigned new_argz_len = *argz_len + entry_len;
+ char *new_argz = realloc (*argz, new_argz_len);
+
+ if (new_argz)
+ {
+ before = new_argz + (before - *argz);
+ bcopy (before, before + entry_len, after_before);
+ bcopy (entry, before, entry_len);
+ *argz = new_argz;
+ *argz_len = new_argz_len;
+ return 0;
+ }
+ else
+ return ENOMEM;
+ }
}