|
Packit Service |
a2ae7a |
/* Functions for dealing with '\0' separated arg vectors.
|
|
Packit Service |
a2ae7a |
Copyright (C) 1995-1998, 2000-2002, 2006, 2008-2019 Free Software
|
|
Packit Service |
a2ae7a |
Foundation, Inc.
|
|
Packit Service |
a2ae7a |
This file is part of the GNU C Library.
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
a2ae7a |
it under the terms of the GNU Lesser General Public License as published by
|
|
Packit Service |
a2ae7a |
the Free Software Foundation; either version 2.1, or (at your option)
|
|
Packit Service |
a2ae7a |
any later version.
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
This program is distributed in the hope that it will be useful,
|
|
Packit Service |
a2ae7a |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
a2ae7a |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
a2ae7a |
GNU Lesser General Public License for more details.
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
You should have received a copy of the GNU Lesser General Public License along
|
|
Packit Service |
a2ae7a |
with this program; if not, see <https://www.gnu.org/licenses/>. */
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
#include <config.h>
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
#include <argz.h>
|
|
Packit Service |
a2ae7a |
#include <errno.h>
|
|
Packit Service |
a2ae7a |
#include <stdlib.h>
|
|
Packit Service |
a2ae7a |
#include <string.h>
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Add BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */
|
|
Packit Service |
a2ae7a |
error_t
|
|
Packit Service |
a2ae7a |
argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t new_argz_len = *argz_len + buf_len;
|
|
Packit Service |
a2ae7a |
char *new_argz = realloc (*argz, new_argz_len);
|
|
Packit Service |
a2ae7a |
if (new_argz)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
memcpy (new_argz + *argz_len, buf, buf_len);
|
|
Packit Service |
a2ae7a |
*argz = new_argz;
|
|
Packit Service |
a2ae7a |
*argz_len = new_argz_len;
|
|
Packit Service |
a2ae7a |
return 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
return ENOMEM;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Add STR to the argz vector in ARGZ & ARGZ_LEN. This should be moved into
|
|
Packit Service |
a2ae7a |
argz.c in libshouldbelibc. */
|
|
Packit Service |
a2ae7a |
error_t
|
|
Packit Service |
a2ae7a |
argz_add (char **argz, size_t *argz_len, const char *str)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
return argz_append (argz, argz_len, str, strlen (str) + 1);
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
error_t
|
|
Packit Service |
a2ae7a |
argz_add_sep (char **argz, size_t *argz_len, const char *string, int delim)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t nlen = strlen (string) + 1;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (nlen > 1)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
const char *rp;
|
|
Packit Service |
a2ae7a |
char *wp;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
*argz = (char *) realloc (*argz, *argz_len + nlen);
|
|
Packit Service |
a2ae7a |
if (*argz == NULL)
|
|
Packit Service |
a2ae7a |
return ENOMEM;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
wp = *argz + *argz_len;
|
|
Packit Service |
a2ae7a |
rp = string;
|
|
Packit Service |
a2ae7a |
do
|
|
Packit Service |
a2ae7a |
if (*rp == delim)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (wp > *argz && wp[-1] != '\0')
|
|
Packit Service |
a2ae7a |
*wp++ = '\0';
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
--nlen;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
*wp++ = *rp;
|
|
Packit Service |
a2ae7a |
while (*rp++ != '\0');
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
*argz_len += nlen;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
return 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
error_t
|
|
Packit Service |
a2ae7a |
argz_create_sep (const char *string, int delim, char **argz, size_t *len)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t nlen = strlen (string) + 1;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (nlen > 1)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
const char *rp;
|
|
Packit Service |
a2ae7a |
char *wp;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
*argz = (char *) malloc (nlen);
|
|
Packit Service |
a2ae7a |
if (*argz == NULL)
|
|
Packit Service |
a2ae7a |
return ENOMEM;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
rp = string;
|
|
Packit Service |
a2ae7a |
wp = *argz;
|
|
Packit Service |
a2ae7a |
do
|
|
Packit Service |
a2ae7a |
if (*rp == delim)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (wp > *argz && wp[-1] != '\0')
|
|
Packit Service |
a2ae7a |
*wp++ = '\0';
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
--nlen;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
*wp++ = *rp;
|
|
Packit Service |
a2ae7a |
while (*rp++ != '\0');
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (nlen == 0)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
free (*argz);
|
|
Packit Service |
a2ae7a |
*argz = NULL;
|
|
Packit Service |
a2ae7a |
*len = 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
*len = nlen;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
*argz = NULL;
|
|
Packit Service |
a2ae7a |
*len = 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
return 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
|
|
Packit Service |
a2ae7a |
existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
|
|
Packit Service |
a2ae7a |
Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN,
|
|
Packit Service |
a2ae7a |
ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not
|
|
Packit Service |
a2ae7a |
in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
|
|
Packit Service |
a2ae7a |
ARGZ, ENOMEM is returned, else 0. */
|
|
Packit Service |
a2ae7a |
error_t
|
|
Packit Service |
a2ae7a |
argz_insert (char **argz, size_t *argz_len, char *before, const char *entry)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (! before)
|
|
Packit Service |
a2ae7a |
return argz_add (argz, argz_len, entry);
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (before < *argz || before >= *argz + *argz_len)
|
|
Packit Service |
a2ae7a |
return EINVAL;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (before > *argz)
|
|
Packit Service |
a2ae7a |
/* Make sure before is actually the beginning of an entry. */
|
|
Packit Service |
a2ae7a |
while (before[-1])
|
|
Packit Service |
a2ae7a |
before--;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t after_before = *argz_len - (before - *argz);
|
|
Packit Service |
a2ae7a |
size_t entry_len = strlen (entry) + 1;
|
|
Packit Service |
a2ae7a |
size_t new_argz_len = *argz_len + entry_len;
|
|
Packit Service |
a2ae7a |
char *new_argz = realloc (*argz, new_argz_len);
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (new_argz)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
before = new_argz + (before - *argz);
|
|
Packit Service |
a2ae7a |
memmove (before + entry_len, before, after_before);
|
|
Packit Service |
a2ae7a |
memmove (before, entry, entry_len);
|
|
Packit Service |
a2ae7a |
*argz = new_argz;
|
|
Packit Service |
a2ae7a |
*argz_len = new_argz_len;
|
|
Packit Service |
a2ae7a |
return 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
return ENOMEM;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
char *
|
|
Packit Service |
a2ae7a |
argz_next (const char *argz, size_t argz_len, const char *entry)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (entry)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (entry < argz + argz_len)
|
|
Packit Service |
a2ae7a |
entry = strchr (entry, '\0') + 1;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
return entry >= argz + argz_len ? NULL : (char *) entry;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
if (argz_len > 0)
|
|
Packit Service |
a2ae7a |
return (char *) argz;
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
return NULL;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
|
|
Packit Service |
a2ae7a |
except the last into the character SEP. */
|
|
Packit Service |
a2ae7a |
void
|
|
Packit Service |
a2ae7a |
argz_stringify (char *argz, size_t len, int sep)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (len > 0)
|
|
Packit Service |
a2ae7a |
while (1)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t part_len = strnlen (argz, len);
|
|
Packit Service |
a2ae7a |
argz += part_len;
|
|
Packit Service |
a2ae7a |
len -= part_len;
|
|
Packit Service |
a2ae7a |
if (len-- <= 1) /* includes final '\0' we want to stop at */
|
|
Packit Service |
a2ae7a |
break;
|
|
Packit Service |
a2ae7a |
*argz++ = sep;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Returns the number of strings in ARGZ. */
|
|
Packit Service |
a2ae7a |
size_t
|
|
Packit Service |
a2ae7a |
argz_count (const char *argz, size_t len)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t count = 0;
|
|
Packit Service |
a2ae7a |
while (len > 0)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t part_len = strlen (argz);
|
|
Packit Service |
a2ae7a |
argz += part_len + 1;
|
|
Packit Service |
a2ae7a |
len -= part_len + 1;
|
|
Packit Service |
a2ae7a |
count++;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
return count;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Puts pointers to each string in ARGZ, plus a terminating 0 element, into
|
|
Packit Service |
a2ae7a |
ARGV, which must be large enough to hold them all. */
|
|
Packit Service |
a2ae7a |
void
|
|
Packit Service |
a2ae7a |
argz_extract (const char *argz, size_t len, char **argv)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
while (len > 0)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t part_len = strlen (argz);
|
|
Packit Service |
a2ae7a |
*argv++ = (char *) argz;
|
|
Packit Service |
a2ae7a |
argz += part_len + 1;
|
|
Packit Service |
a2ae7a |
len -= part_len + 1;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
*argv = 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Make a '\0' separated arg vector from a unix argv vector, returning it in
|
|
Packit Service |
a2ae7a |
ARGZ, and the total length in LEN. If a memory allocation error occurs,
|
|
Packit Service |
a2ae7a |
ENOMEM is returned, otherwise 0. */
|
|
Packit Service |
a2ae7a |
error_t
|
|
Packit Service |
a2ae7a |
argz_create (char *const argv[], char **argz, size_t *len)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
int argc;
|
|
Packit Service |
a2ae7a |
size_t tlen = 0;
|
|
Packit Service |
a2ae7a |
char *const *ap;
|
|
Packit Service |
a2ae7a |
char *p;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
for (argc = 0; argv[argc] != NULL; ++argc)
|
|
Packit Service |
a2ae7a |
tlen += strlen (argv[argc]) + 1;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (tlen == 0)
|
|
Packit Service |
a2ae7a |
*argz = NULL;
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
*argz = malloc (tlen);
|
|
Packit Service |
a2ae7a |
if (*argz == NULL)
|
|
Packit Service |
a2ae7a |
return ENOMEM;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
for (p = *argz, ap = argv; *ap; ++ap, ++p)
|
|
Packit Service |
a2ae7a |
p = stpcpy (p, *ap);
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
*len = tlen;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
return 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Delete ENTRY from ARGZ & ARGZ_LEN, if any. */
|
|
Packit Service |
a2ae7a |
void
|
|
Packit Service |
a2ae7a |
argz_delete (char **argz, size_t *argz_len, char *entry)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (entry)
|
|
Packit Service |
a2ae7a |
/* Get rid of the old value for NAME. */
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t entry_len = strlen (entry) + 1;
|
|
Packit Service |
a2ae7a |
*argz_len -= entry_len;
|
|
Packit Service |
a2ae7a |
memmove (entry, entry + entry_len, *argz_len - (entry - *argz));
|
|
Packit Service |
a2ae7a |
if (*argz_len == 0)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
free (*argz);
|
|
Packit Service |
a2ae7a |
*argz = 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Append BUF, of length BUF_LEN to *TO, of length *TO_LEN, reallocating and
|
|
Packit Service |
a2ae7a |
updating *TO & *TO_LEN appropriately. If an allocation error occurs,
|
|
Packit Service |
a2ae7a |
*TO's old value is freed, and *TO is set to 0. */
|
|
Packit Service |
a2ae7a |
static void
|
|
Packit Service |
a2ae7a |
str_append (char **to, size_t *to_len, const char *buf, const size_t buf_len)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
size_t new_len = *to_len + buf_len;
|
|
Packit Service |
a2ae7a |
char *new_to = realloc (*to, new_len + 1);
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (new_to)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
*((char *) mempcpy (new_to + *to_len, buf, buf_len)) = '\0';
|
|
Packit Service |
a2ae7a |
*to = new_to;
|
|
Packit Service |
a2ae7a |
*to_len = new_len;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
free (*to);
|
|
Packit Service |
a2ae7a |
*to = 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
/* Replace any occurrences of the string STR in ARGZ with WITH, reallocating
|
|
Packit Service |
a2ae7a |
ARGZ as necessary. If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be
|
|
Packit Service |
a2ae7a |
incremented by number of replacements performed. */
|
|
Packit Service |
a2ae7a |
error_t
|
|
Packit Service |
a2ae7a |
argz_replace (char **argz, size_t *argz_len, const char *str, const char *with,
|
|
Packit Service |
a2ae7a |
unsigned *replace_count)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
error_t err = 0;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (str && *str)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
char *arg = 0;
|
|
Packit Service |
a2ae7a |
char *src = *argz;
|
|
Packit Service |
a2ae7a |
size_t src_len = *argz_len;
|
|
Packit Service |
a2ae7a |
char *dst = 0;
|
|
Packit Service |
a2ae7a |
size_t dst_len = 0;
|
|
Packit Service |
a2ae7a |
int delayed_copy = 1; /* True while we've avoided copying anything. */
|
|
Packit Service |
a2ae7a |
size_t str_len = strlen (str), with_len = strlen (with);
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
while (!err && (arg = argz_next (src, src_len, arg)))
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
char *match = strstr (arg, str);
|
|
Packit Service |
a2ae7a |
if (match)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
char *from = match + str_len;
|
|
Packit Service |
a2ae7a |
size_t to_len = match - arg;
|
|
Packit Service |
a2ae7a |
char *to = strndup (arg, to_len);
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
while (to && from)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
str_append (&to, &to_len, with, with_len);
|
|
Packit Service |
a2ae7a |
if (to)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
match = strstr (from, str);
|
|
Packit Service |
a2ae7a |
if (match)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
str_append (&to, &to_len, from, match - from);
|
|
Packit Service |
a2ae7a |
from = match + str_len;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
str_append (&to, &to_len, from, strlen (from));
|
|
Packit Service |
a2ae7a |
from = 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (to)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (delayed_copy)
|
|
Packit Service |
a2ae7a |
/* We avoided copying SRC to DST until we found a match;
|
|
Packit Service |
a2ae7a |
now that we've done so, copy everything from the start
|
|
Packit Service |
a2ae7a |
of SRC. */
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (arg > src)
|
|
Packit Service |
a2ae7a |
err = argz_append (&dst, &dst_len, src, (arg - src));
|
|
Packit Service |
a2ae7a |
delayed_copy = 0;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
if (! err)
|
|
Packit Service |
a2ae7a |
err = argz_add (&dst, &dst_len, to);
|
|
Packit Service |
a2ae7a |
free (to);
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else
|
|
Packit Service |
a2ae7a |
err = ENOMEM;
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (replace_count)
|
|
Packit Service |
a2ae7a |
(*replace_count)++;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else if (! delayed_copy)
|
|
Packit Service |
a2ae7a |
err = argz_add (&dst, &dst_len, arg);
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
if (! err)
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
if (! delayed_copy)
|
|
Packit Service |
a2ae7a |
/* We never found any instances of str. */
|
|
Packit Service |
a2ae7a |
{
|
|
Packit Service |
a2ae7a |
free (src);
|
|
Packit Service |
a2ae7a |
*argz = dst;
|
|
Packit Service |
a2ae7a |
*argz_len = dst_len;
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
else if (dst_len > 0)
|
|
Packit Service |
a2ae7a |
free (dst);
|
|
Packit Service |
a2ae7a |
}
|
|
Packit Service |
a2ae7a |
|
|
Packit Service |
a2ae7a |
return err;
|
|
Packit Service |
a2ae7a |
}
|