# HG changeset patch # User Jim Meyering # Date 1212486132 -7200 # Node ID 101fa85f1d56459c3858e1fe7c0f1af3563d9603 # Parent 5d2f07baed4c3a9ad0b405022782360a4e43e9cf generate argz.c and argz.in.h from glibc sources * config/argz.mk: New file, with rules to generate the two files. * modules/argz (Depends-on): Add mempcpy, stpcpy, strndup and strnlen. Suggested by David Lutterkort. * m4/argz.m4: Require AC_C_RESTRICT. Check only for the existence of one function, argz_replace, since it seems to have been added most recently. Also, remove the side effect of defining HAVE_ARGZ_* symbols. * lib/argz.c: Now generated directly from glibc sources, rather than imported from libtool. Includes the following additional functions: argz_extract, argz_create, argz_delete, str_append, argz_replace. * lib/argz.in.h: Likewise. * config/srclist.txt: Reflect that argz* files are no longer pulled from libtool. diff --git a/config/argz.mk b/config/argz.mk new file mode 100644 --- /dev/null +++ b/config/argz.mk @@ -0,0 +1,63 @@ +# Generate argz.c and argz.in.h from glibc sources. + +glibc_dir = ../glibc +glibc_dir = /mirror/d/glibc + +argz_names = \ + append addsep ctsep insert next stringify count \ + extract create delete replace +argz_files = $(patsubst %, $(glibc_dir)/string/argz-%.c, $(argz_names)) + +define print-header + printf '%s\n' \ +"/* Functions for dealing with '\0' separated arg vectors." \ +" Copyright (C) 1995-1998, 2000-2002, 2006 Free Software Foundation, Inc."\ +" This file is part of the GNU C Library." \ +"" \ +" This program is free software; you can redistribute it and/or modify"\ +" it under the terms of the GNU General Public License as published by"\ +" the Free Software Foundation; either version 2, or (at your option)"\ +" any later version." \ +"" \ +" This program is distributed in the hope that it will be useful," \ +" but WITHOUT ANY WARRANTY; without even the implied warranty of" \ +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" \ +" GNU General Public License for more details." \ +"" \ +" You should have received a copy of the GNU General Public License along"\ +" with this program; if not, write to the Free Software Foundation," \ +" Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */"\ +"" \ +"#include " \ +"" \ +"#include " \ +"#include " \ +"#include " \ +"#include " +endef + +targets = argz.c argz.in.h + +all: $(targets) + +argz.c: $(argz_files) + ($(print-header); \ + for i in $^; do \ + perl -pe 's/__(argz_|st|mem)/$$1/g' $$i \ + | perl -0x0 -pe 's,/\*(.|\n)+?\*/\n,,' \ + | grep -vE '^(#include|INTDEF|weak_alias|libc_hidden_def)'; \ + done) > $@-t && mv $@-t $@ + +argz.in.h: $(glibc_dir)/string/argz.h + perl -pe 's/__(restrict|const|st|mem)/$$1/g;' \ + -e 's/\s*__THROW//;' \ + -e 's/\s*__attribute_pure__//;' \ + $< \ + | perl -ne \ + '/^(#include |__(?:BEGIN|END)_DECLS)/ or print' \ + | perl -0x3b -pe 's/extern \S+ \*?__argz_(.|\n)*?\)\n*;//' \ + | perl -pe 's/__(argz_next)/$$1/g;' \ + > $@-t && mv $@-t $@ + +clean: + rm -f $(targets) diff --git a/config/srclist.txt b/config/srclist.txt --- a/config/srclist.txt +++ b/config/srclist.txt @@ -230,6 +230,8 @@ #$LIBCSRC/sysdeps/unix/sysv/gethostname.c lib gpl #$LIBCSRC/sysdeps/unix/utime.c lib gpl -$LIBTOOL/libltdl/argz.c lib gpl -$LIBTOOL/libltdl/argz_.h lib gpl -$LIBTOOL/libltdl/m4/argz.m4 m4 +# Now derived from concatenation of separate .c files in glibc. +# See argz.mk for details. +#$LIBTOOL/libltdl/argz.c lib gpl +#$LIBTOOL/libltdl/argz_.h lib gpl +#$LIBTOOL/libltdl/m4/argz.m4 m4 diff --git a/lib/argz.c b/lib/argz.c --- a/lib/argz.c +++ b/lib/argz.c @@ -1,254 +1,406 @@ -/* argz.c -- argz implementation for non-glibc systems - - Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc. - Written by Gary V. Vaughan, 2004 - - NOTE: The canonical source of this file is maintained with the - GNU Libtool package. Report bugs to bug-libtool@gnu.org. +/* Functions for dealing with '\0' separated arg vectors. + Copyright (C) 1995-1998, 2000-2002, 2006, 2008 Free Software Foundation, Inc. + This file is part of the GNU C Library. -GNU Libltdl is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -As a special exception to the GNU Lesser General Public License, -if you distribute this file as part of a program or library that -is built using GNU Libtool, you may include this file under the -same distribution terms that you use for the rest of that program. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. -GNU Libltdl is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU Lesser General Public -License along with GNU Libltdl; see the file COPYING.LIB. If not, a -copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, -or obtained by writing to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#if defined(LTDL) && defined LT_CONFIG_H -# include LT_CONFIG_H -#else -# include -#endif +#include #include - -#include -#include +#include #include -#include -#include #include -#define EOS_CHAR '\0' + + +/* Add BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */ +error_t +argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len) +{ + size_t new_argz_len = *argz_len + buf_len; + char *new_argz = realloc (*argz, new_argz_len); + if (new_argz) + { + memcpy (new_argz + *argz_len, buf, buf_len); + *argz = new_argz; + *argz_len = new_argz_len; + return 0; + } + else + return ENOMEM; +} + +/* Add STR to the argz vector in ARGZ & ARGZ_LEN. This should be moved into + argz.c in libshouldbelibc. */ +error_t +argz_add (char **argz, size_t *argz_len, const char *str) +{ + return argz_append (argz, argz_len, str, strlen (str) + 1); +} + + error_t -argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len) +argz_add_sep (char **argz, size_t *argz_len, const char *string, int delim) { - size_t argz_len; - char *argz; + size_t nlen = strlen (string) + 1; + + if (nlen > 1) + { + const char *rp; + char *wp; + + *argz = (char *) realloc (*argz, *argz_len + nlen); + if (*argz == NULL) + return ENOMEM; - assert (pargz); - assert (pargz_len); - assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); + wp = *argz + *argz_len; + rp = string; + do + if (*rp == delim) + { + if (wp > *argz && wp[-1] != '\0') + *wp++ = '\0'; + else + --nlen; + } + else + *wp++ = *rp; + while (*rp++ != '\0'); - /* If nothing needs to be appended, no more work is required. */ - if (buf_len == 0) - return 0; + *argz_len += nlen; + } + + return 0; +} + + - /* Ensure there is enough room to append BUF_LEN. */ - argz_len = *pargz_len + buf_len; - argz = (char *) realloc (*pargz, argz_len); - if (!argz) - return ENOMEM; +error_t +argz_create_sep (const char *string, int delim, char **argz, size_t *len) +{ + size_t nlen = strlen (string) + 1; + + if (nlen > 1) + { + const char *rp; + char *wp; + + *argz = (char *) malloc (nlen); + if (*argz == NULL) + return ENOMEM; - /* Copy characters from BUF after terminating '\0' in ARGZ. */ - memcpy (argz + *pargz_len, buf, buf_len); + rp = string; + wp = *argz; + do + if (*rp == delim) + { + if (wp > *argz && wp[-1] != '\0') + *wp++ = '\0'; + else + --nlen; + } + else + *wp++ = *rp; + while (*rp++ != '\0'); - /* Assign new values. */ - *pargz = argz; - *pargz_len = argz_len; + if (nlen == 0) + { + free (*argz); + *argz = NULL; + *len = 0; + } + + *len = nlen; + } + else + { + *argz = NULL; + *len = 0; + } return 0; } -/* Add a string to the argz vector. */ +/* 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_add (char **pargz, size_t *pargz_len, const char *str) +argz_insert (char **argz, size_t *argz_len, char *before, const char *entry) { - return argz_append (pargz, pargz_len, str, strlen (str) + 1); + if (! before) + return argz_add (argz, argz_len, entry); + + if (before < *argz || before >= *argz + *argz_len) + return EINVAL; + + if (before > *argz) + /* Make sure before is actually the beginning of an entry. */ + while (before[-1]) + before--; + + { + size_t after_before = *argz_len - (before - *argz); + size_t entry_len = strlen (entry) + 1; + size_t new_argz_len = *argz_len + entry_len; + char *new_argz = realloc (*argz, new_argz_len); + + if (new_argz) + { + before = new_argz + (before - *argz); + memmove (before + entry_len, before, after_before); + memmove (before, entry, entry_len); + *argz = new_argz; + *argz_len = new_argz_len; + return 0; + } + else + return ENOMEM; + } +} + + +char * +argz_next (const char *argz, size_t argz_len, const char *entry) +{ + if (entry) + { + if (entry < argz + argz_len) + entry = strchr (entry, '\0') + 1; + + return entry >= argz + argz_len ? NULL : (char *) entry; + } + else + if (argz_len > 0) + return (char *) argz; + else + return NULL; } -error_t -argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len) +/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's + except the last into the character SEP. */ +void +argz_stringify (char *argz, size_t len, int sep) { - size_t argz_len; - char *argz = 0; + if (len > 0) + while (1) + { + size_t part_len = strnlen (argz, len); + argz += part_len; + len -= part_len; + if (len-- <= 1) /* includes final '\0' we want to stop at */ + break; + *argz++ = sep; + } +} + - assert (str); - assert (pargz); - assert (pargz_len); +/* Returns the number of strings in ARGZ. */ +size_t +argz_count (const char *argz, size_t len) +{ + size_t count = 0; + while (len > 0) + { + size_t part_len = strlen(argz); + argz += part_len + 1; + len -= part_len + 1; + count++; + } + return count; +} + - /* Make a copy of STR, but replacing each occurrence of - DELIM with '\0'. */ - argz_len = 1+ strlen (str); - if (argz_len) +/* Puts pointers to each string in ARGZ, plus a terminating 0 element, into + ARGV, which must be large enough to hold them all. */ +void +argz_extract (const char *argz, size_t len, char **argv) +{ + while (len > 0) { - const char *p; - char *q; + size_t part_len = strlen (argz); + *argv++ = (char *) argz; + argz += part_len + 1; + len -= part_len + 1; + } + *argv = 0; +} + - argz = (char *) malloc (argz_len); - if (!argz) +/* Make a '\0' separated arg vector from a unix argv vector, returning it in + ARGZ, and the total length in LEN. If a memory allocation error occurs, + ENOMEM is returned, otherwise 0. */ +error_t +argz_create (char *const argv[], char **argz, size_t *len) +{ + int argc; + size_t tlen = 0; + char *const *ap; + char *p; + + for (argc = 0; argv[argc] != NULL; ++argc) + tlen += strlen (argv[argc]) + 1; + + if (tlen == 0) + *argz = NULL; + else + { + *argz = malloc (tlen); + if (*argz == NULL) return ENOMEM; - for (p = str, q = argz; *p != EOS_CHAR; ++p) - { - if (*p == delim) - { - /* Ignore leading delimiters, and fold consecutive - delimiters in STR into a single '\0' in ARGZ. */ - if ((q > argz) && (q[-1] != EOS_CHAR)) - *q++ = EOS_CHAR; - else - --argz_len; - } - else - *q++ = *p; - } - /* Copy terminating EOS_CHAR. */ - *q = *p; + for (p = *argz, ap = argv; *ap; ++ap, ++p) + p = stpcpy (p, *ap); } - - /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ - if (!argz_len) - argz = (free (argz), (char *) 0); - - /* Assign new values. */ - *pargz = argz; - *pargz_len = argz_len; + *len = tlen; return 0; } -error_t -argz_insert (char **pargz, size_t *pargz_len, char *before, const char *entry) +/* Delete ENTRY from ARGZ & ARGZ_LEN, if any. */ +void +argz_delete (char **argz, size_t *argz_len, char *entry) { - assert (pargz); - assert (pargz_len); - assert (entry && *entry); - - /* No BEFORE address indicates ENTRY should be inserted after the - current last element. */ - if (!before) - return argz_append (pargz, pargz_len, entry, 1+ strlen (entry)); - - /* This probably indicates a programmer error, but to preserve - semantics, scan back to the start of an entry if BEFORE points - into the middle of it. */ - while ((before > *pargz) && (before[-1] != EOS_CHAR)) - --before; - - { - size_t entry_len = 1+ strlen (entry); - size_t argz_len = *pargz_len + entry_len; - size_t offset = before - *pargz; - char *argz = (char *) realloc (*pargz, argz_len); - - if (!argz) - return ENOMEM; - - /* Make BEFORE point to the equivalent offset in ARGZ that it - used to have in *PARGZ incase realloc() moved the block. */ - before = argz + offset; - - /* Move the ARGZ entries starting at BEFORE up into the new - space at the end -- making room to copy ENTRY into the - resulting gap. */ - memmove (before + entry_len, before, *pargz_len - offset); - memcpy (before, entry, entry_len); - - /* Assign new values. */ - *pargz = argz; - *pargz_len = argz_len; - } - - return 0; -} - - -char * -argz_next (char *argz, size_t argz_len, const char *entry) -{ - assert ((argz && argz_len) || (!argz && !argz_len)); - if (entry) - { - /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address - within the ARGZ vector. */ - assert ((!argz && !argz_len) - || ((argz <= entry) && (entry < (argz + argz_len)))); - - /* Move to the char immediately after the terminating - '\0' of ENTRY. */ - entry = 1+ strchr (entry, EOS_CHAR); - - /* Return either the new ENTRY, or else NULL if ARGZ is - exhausted. */ - return (entry >= argz + argz_len) ? 0 : (char *) entry; - } - else + /* Get rid of the old value for NAME. */ { - /* This should probably be flagged as a programmer error, - since starting an argz_next loop with the iterator set - to ARGZ is safer. To preserve semantics, handle the NULL - case by returning the start of ARGZ (if any). */ - if (argz_len > 0) - return argz; - else - return 0; - } -} - - -void -argz_stringify (char *argz, size_t argz_len, int sep) -{ - assert ((argz && argz_len) || (!argz && !argz_len)); - - if (sep) - { - --argz_len; /* don't stringify the terminating EOS */ - while (--argz_len > 0) + size_t entry_len = strlen (entry) + 1; + *argz_len -= entry_len; + memmove (entry, entry + entry_len, *argz_len - (entry - *argz)); + if (*argz_len == 0) { - if (argz[argz_len] == EOS_CHAR) - argz[argz_len] = sep; + free (*argz); + *argz = 0; } } } -/* Count number of elements (null bytes) in argz vector. */ +/* Append BUF, of length BUF_LEN to *TO, of length *TO_LEN, reallocating and + updating *TO & *TO_LEN appropriately. If an allocation error occurs, + *TO's old value is freed, and *TO is set to 0. */ +static void +str_append (char **to, size_t *to_len, const char *buf, const size_t buf_len) +{ + size_t new_len = *to_len + buf_len; + char *new_to = realloc (*to, new_len + 1); + + if (new_to) + { + *((char *) mempcpy (new_to + *to_len, buf, buf_len)) = '\0'; + *to = new_to; + *to_len = new_len; + } + else + { + free (*to); + *to = 0; + } +} -size_t -argz_count (const char *argz, size_t argz_len) +/* Replace any occurrences of the string STR in ARGZ with WITH, reallocating + ARGZ as necessary. If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be + incremented by number of replacements performed. */ +error_t +argz_replace (char **argz, size_t *argz_len, const char *str, const char *with, + unsigned *replace_count) { - size_t count = 0; + error_t err = 0; + + if (str && *str) + { + char *arg = 0; + char *src = *argz; + size_t src_len = *argz_len; + char *dst = 0; + size_t dst_len = 0; + int delayed_copy = 1; /* True while we've avoided copying anything. */ + size_t str_len = strlen (str), with_len = strlen (with); + + while (!err && (arg = argz_next (src, src_len, arg))) + { + char *match = strstr (arg, str); + if (match) + { + char *from = match + str_len; + size_t to_len = match - arg; + char *to = strndup (arg, to_len); - assert ((argz && argz_len) || (!argz && !argz_len)); + while (to && from) + { + str_append (&to, &to_len, with, with_len); + if (to) + { + match = strstr (from, str); + if (match) + { + str_append (&to, &to_len, from, match - from); + from = match + str_len; + } + else + { + str_append (&to, &to_len, from, strlen (from)); + from = 0; + } + } + } - while (argz_len > 0) - { - size_t part_len = strlen (argz); - argz += part_len + 1; - argz_len -= part_len + 1; - count++; + if (to) + { + if (delayed_copy) + /* We avoided copying SRC to DST until we found a match; + now that we've done so, copy everything from the start + of SRC. */ + { + if (arg > src) + err = argz_append (&dst, &dst_len, src, (arg - src)); + delayed_copy = 0; + } + if (! err) + err = argz_add (&dst, &dst_len, to); + free (to); + } + else + err = ENOMEM; + + if (replace_count) + (*replace_count)++; + } + else if (! delayed_copy) + err = argz_add (&dst, &dst_len, arg); + } + + if (! err) + { + if (! delayed_copy) + /* We never found any instances of str. */ + { + free (src); + *argz = dst; + *argz_len = dst_len; + } + } + else if (dst_len > 0) + free (dst); } - return count; + return err; } diff --git a/lib/argz.in.h b/lib/argz.in.h --- a/lib/argz.in.h +++ b/lib/argz.in.h @@ -1,71 +1,161 @@ -/* lt__argz.h -- internal argz interface for non-glibc systems - - Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. - Written by Gary V. Vaughan, 2004 +/* Routines for dealing with '\0' separated arg vectors. + Copyright (C) 1995,96,97,98,99,2000,2004,2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. - NOTE: The canonical source of this file is maintained with the - GNU Libtool package. Report bugs to bug-libtool@gnu.org. - -GNU Libltdl is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. -As a special exception to the GNU Lesser General Public License, -if you distribute this file as part of a program or library that -is built using GNU Libtool, you may include this file under the -same distribution terms that you use for the rest of that program. - -GNU Libltdl is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. -You should have received a copy of the GNU Lesser General Public -License along with GNU Libltdl; see the file COPYING.LIB. If not, a -copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, -or obtained by writing to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ -#if !defined(LT__ARGZ_H) -#define LT__ARGZ_H 1 +#ifndef _ARGZ_H +#define _ARGZ_H 1 -#include + #define __need_error_t #include -#include +#include /* Need size_t, and strchr is called below. */ -#if defined(LTDL) -# include "lt__glibc.h" -# include "lt_system.h" -#else -# define LT_SCOPE +#ifndef const +# define const const #endif -#if defined(__cplusplus) -extern "C" { +#ifndef __error_t_defined +typedef int error_t; #endif -LT_SCOPE error_t argz_append (char **pargz, size_t *pargz_len, - const char *buf, size_t buf_len); -LT_SCOPE error_t argz_add (char **pargz, size_t *pargz_len, - const char *str); -LT_SCOPE error_t argz_create_sep(const char *str, int delim, - char **pargz, size_t *pargz_len); -LT_SCOPE error_t argz_insert (char **pargz, size_t *pargz_len, - char *before, const char *entry); -LT_SCOPE char * argz_next (char *argz, size_t argz_len, - const char *entry); -LT_SCOPE void argz_stringify (char *argz, size_t argz_len, int sep); -LT_SCOPE size_t argz_count (const char *argz, size_t argz_len); + + +/* Make a '\0' separated arg vector from a unix argv vector, returning it in + ARGZ, and the total length in LEN. If a memory allocation error occurs, + ENOMEM is returned, otherwise 0. The result can be destroyed using free. */ + +extern error_t argz_create (char *const __argv[], char **restrict __argz, + size_t *restrict __len); + +/* Make a '\0' separated arg vector from a SEP separated list in + STRING, returning it in ARGZ, and the total length in LEN. If a + memory allocation error occurs, ENOMEM is returned, otherwise 0. + The result can be destroyed using free. */ + +extern error_t argz_create_sep (const char *restrict string, + int __sep, char **restrict __argz, + size_t *restrict __len); + +/* Returns the number of strings in ARGZ. */ + +extern size_t argz_count (const char *__argz, size_t __len) +; + +/* Puts pointers to each string in ARGZ into ARGV, which must be large enough + to hold them all. */ + +extern void argz_extract (const char *restrict __argz, size_t __len, + char **restrict __argv); + +/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's + except the last into the character SEP. */ + +extern void argz_stringify (char *__argz, size_t __len, int __sep); + +/* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */ + +extern error_t argz_append (char **restrict __argz, + size_t *restrict __argz_len, + const char *restrict __buf, size_t __buf_len) +; + +/* Append STR to the argz vector in ARGZ & ARGZ_LEN. */ + +extern error_t argz_add (char **restrict __argz, + size_t *restrict __argz_len, + const char *restrict str); + +/* Append SEP separated list in STRING to the argz vector in ARGZ & + ARGZ_LEN. */ + +extern error_t argz_add_sep (char **restrict __argz, + size_t *restrict __argz_len, + const char *restrict string, int __delim) +; + +/* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there. */ + +extern void argz_delete (char **restrict __argz, + size_t *restrict __argz_len, + char *restrict __entry); -#if defined(__cplusplus) -} -#endif +/* 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. */ + +extern error_t argz_insert (char **restrict __argz, + size_t *restrict __argz_len, + char *restrict __before, + const char *restrict __entry); + +/* Replace any occurrences of the string STR in ARGZ with WITH, reallocating + ARGZ as necessary. If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be + incremented by number of replacements performed. */ + +extern error_t argz_replace (char **restrict __argz, + size_t *restrict __argz_len, + const char *restrict str, + const char *restrict __with, + unsigned int *restrict __replace_count); + +/* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there + are no more. If entry is NULL, then the first entry is returned. This + behavior allows two convenient iteration styles: + + char *entry = 0; + while ((entry = argz_next (argz, argz_len, entry))) + ...; + + or -#if !defined(LTDL) -# undef LT_SCOPE -#endif + char *entry; + for (entry = argz; entry; entry = argz_next (argz, argz_len, entry)) + ...; +*/ + +extern char *argz_next (const char *restrict __argz, size_t __argz_len, + const char *restrict __entry); -#endif /*!defined(LT__ARGZ_H)*/ +#ifdef __USE_EXTERN_INLINES +__extern_inline char * +__NTH (argz_next (const char *__argz, size_t __argz_len, + const char *__entry)) +{ + if (__entry) + { + if (__entry < __argz + __argz_len) + __entry = strchr (__entry, '\0') + 1; + + return __entry >= __argz + __argz_len ? (char *) NULL : (char *) __entry; + } + else + return __argz_len > 0 ? (char *) __argz : 0; +} +__extern_inline char * +__NTH (argz_next (const char *__argz, size_t __argz_len, + const char *__entry)) +{ + return argz_next (__argz, __argz_len, __entry); +} +#endif /* Use extern inlines. */ + + +#endif /* argz.h */ diff --git a/m4/argz.m4 b/m4/argz.m4 --- a/m4/argz.m4 +++ b/m4/argz.m4 @@ -1,6 +1,6 @@ # Portability macros for glibc argz. -*- Autoconf -*- # -# Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +# Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan # # This file is free software; the Free Software Foundation gives @@ -12,6 +12,8 @@ AC_DEFUN([gl_FUNC_ARGZ], [gl_PREREQ_ARGZ +AC_REQUIRE([AC_C_RESTRICT]) + AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_TYPES([error_t], @@ -25,8 +27,7 @@ #endif]) ARGZ_H= -AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \ - argz_next argz_stringify], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) +AC_CHECK_FUNC([argz_replace], [], [ARGZ_H=argz.h; AC_LIBOBJ([argz])]) dnl if have system argz functions, allow forced use of dnl libltdl-supplied implementation (and default to do so diff --git a/modules/argz b/modules/argz --- a/modules/argz +++ b/modules/argz @@ -7,6 +7,10 @@ m4/argz.m4 Depends-on: +mempcpy +stpcpy +strndup +strnlen configure.ac: gl_FUNC_ARGZ @@ -30,4 +34,4 @@ LGPLv2+ Maintainer: -bug-libtool@gnu.org +all