generate argz.c and argz.in.h from glibc sources
authorJim Meyering <meyering@redhat.com>
Tue, 3 Jun 2008 09:42:12 +0000 (11:42 +0200)
committerJim Meyering <meyering@redhat.com>
Thu, 5 Jun 2008 18:02:00 +0000 (20:02 +0200)
* 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.

config/argz.mk [new file with mode: 0644]
config/srclist.txt
lib/argz.c
lib/argz.in.h
m4/argz.m4
modules/argz

diff --git a/config/argz.mk b/config/argz.mk
new file mode 100644 (file)
index 0000000..14b00fd
--- /dev/null
@@ -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 <config.h>"                                                  \
+""                                                                     \
+"#include <argz.h>"                                                    \
+"#include <errno.h>"                                                   \
+"#include <stdlib.h>"                                                  \
+"#include <string.h>"
+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 <features\.h>|__(?: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)
index ce4f9c5..fa029bc 100644 (file)
@@ -230,6 +230,8 @@ $LIBCSRC/stdlib/strtoul.c           lib gpl
 #$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
index f31ce17..8f5d1f5 100644 (file)
-/* 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.
-
-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.
-
-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.
-
-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.
-*/
-
-#if defined(LTDL) && defined LT_CONFIG_H
-#  include LT_CONFIG_H
-#else
-#  include <config.h>
-#endif
+/* 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.
 
-#include <argz.h>
+   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.
 
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <sys/types.h>
+   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 <config.h>
+
+#include <argz.h>
 #include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 
-#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_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len)
+argz_add (char **argz, size_t *argz_len, const char *str)
 {
-  size_t argz_len;
-  char  *argz;
+  return argz_append (argz, argz_len, str, strlen (str) + 1);
+}
 
-  assert (pargz);
-  assert (pargz_len);
-  assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
 
-  /* If nothing needs to be appended, no more work is required.  */
-  if (buf_len == 0)
-    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_add_sep (char **argz, size_t *argz_len, const char *string, int delim)
+{
+  size_t nlen = strlen (string) + 1;
+
+  if (nlen > 1)
+    {
+      const char *rp;
+      char *wp;
 
-  /* Copy characters from BUF after terminating '\0' in ARGZ.  */
-  memcpy (argz + *pargz_len, buf, buf_len);
+      *argz = (char *) realloc (*argz, *argz_len + nlen);
+      if (*argz == NULL)
+       return ENOMEM;
 
-  /* Assign new values.  */
-  *pargz = argz;
-  *pargz_len = argz_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');
+
+      *argz_len += nlen;
+    }
 
   return 0;
 }
 
 
-/* Add a string to the argz vector.  */
-error_t
-argz_add (char **pargz, size_t *pargz_len, const char *str)
-{
-  return argz_append (pargz, pargz_len, str, strlen (str) + 1);
-}
-
 
 error_t
-argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len)
+argz_create_sep (const char *string, int delim, char **argz, size_t *len)
 {
-  size_t argz_len;
-  char *argz = 0;
+  size_t nlen = strlen (string) + 1;
 
-  assert (str);
-  assert (pargz);
-  assert (pargz_len);
-
-  /* Make a copy of STR, but replacing each occurrence of
-     DELIM with '\0'.  */
-  argz_len = 1+ strlen (str);
-  if (argz_len)
+  if (nlen > 1)
     {
-      const char *p;
-      char *q;
+      const char *rp;
+      char *wp;
 
-      argz = (char *) malloc (argz_len);
-      if (!argz)
+      *argz = (char *) malloc (nlen);
+      if (*argz == NULL)
        return ENOMEM;
 
-      for (p = str, q = argz; *p != EOS_CHAR; ++p)
+      rp = string;
+      wp = *argz;
+      do
+       if (*rp == delim)
+         {
+           if (wp > *argz && wp[-1] != '\0')
+             *wp++ = '\0';
+           else
+             --nlen;
+         }
+       else
+         *wp++ = *rp;
+      while (*rp++ != '\0');
+
+      if (nlen == 0)
        {
-         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;
+         free (*argz);
+         *argz = NULL;
+         *len = 0;
        }
-      /* Copy terminating EOS_CHAR.  */
-      *q = *p;
-    }
-
-  /* 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 = nlen;
+    }
+  else
+    {
+      *argz = NULL;
+      *len = 0;
+    }
 
   return 0;
 }
 
 
+/* 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 **pargz, size_t *pargz_len, char *before, const char *entry)
+argz_insert (char **argz, size_t *argz_len, char *before, const char *entry)
 {
-  assert (pargz);
-  assert (pargz_len);
-  assert (entry && *entry);
+  if (! before)
+    return argz_add (argz, argz_len, 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));
+  if (before < *argz || before >= *argz + *argz_len)
+    return EINVAL;
 
-  /* 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;
+  if (before > *argz)
+    /* Make sure before is actually the beginning of an entry.  */
+    while (before[-1])
+      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)
+    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;
+  }
+}
 
-    /* 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);
+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;
 
-    /* Assign new values.  */
-    *pargz = argz;
-    *pargz_len = argz_len;
-  }
+      return entry >= argz + argz_len ? NULL : (char *) entry;
+    }
+  else
+    if (argz_len > 0)
+      return (char *) argz;
+    else
+      return NULL;
+}
 
-  return 0;
+
+/* 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)
+{
+  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;
+      }
 }
 
 
-char *
-argz_next (char *argz, size_t argz_len, const char *entry)
+/* Returns the number of strings in ARGZ.  */
+size_t
+argz_count (const char *argz, size_t len)
 {
-  assert ((argz && argz_len) || (!argz && !argz_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;
+}
 
-  if (entry)
+
+/* 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)
     {
-      /* 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;
+      size_t part_len = strlen (argz);
+      *argv++ = (char *) argz;
+      argz += part_len + 1;
+      len -= part_len + 1;
     }
+  *argv = 0;
+}
+
+
+/* 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
     {
-      /* 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;
+      *argz = malloc (tlen);
+      if (*argz == NULL)
+       return ENOMEM;
+
+      for (p = *argz, ap = argv; *ap; ++ap, ++p)
+       p = stpcpy (p, *ap);
     }
+  *len = tlen;
+
+  return 0;
 }
 
 
+/* Delete ENTRY from ARGZ & ARGZ_LEN, if any.  */
 void
-argz_stringify (char *argz, size_t argz_len, int sep)
+argz_delete (char **argz, size_t *argz_len, char *entry)
 {
-  assert ((argz && argz_len) || (!argz && !argz_len));
-
-  if (sep)
+  if (entry)
+    /* Get rid of the old value for NAME.  */
     {
-      --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.  */
-
-size_t
-argz_count (const char *argz, size_t argz_len)
+/* 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 count = 0;
+  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;
+    }
+}
 
-  assert ((argz && argz_len) || (!argz && !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)
+{
+  error_t err = 0;
 
-  while (argz_len > 0)
+  if (str && *str)
     {
-      size_t part_len = strlen (argz);
-      argz += part_len + 1;
-      argz_len -= part_len + 1;
-      count++;
+      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);
+
+             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;
+                       }
+                   }
+               }
+
+             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;
 }
index 40d5176..e89f029 100644 (file)
-/* 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
-
-   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.
-
-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.
-
-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
-*/
+/* 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.
+
+   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.
+
+   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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _ARGZ_H
+#define _ARGZ_H        1
 
-#if !defined(LT__ARGZ_H)
-#define LT__ARGZ_H 1
 
-#include <stdlib.h>
 #define __need_error_t
 #include <errno.h>
-#include <sys/types.h>
+#include <string.h>            /* 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);
-
-#if defined(__cplusplus)
+
+
+/* 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);
+
+/* 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);
+\f
+/* 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
+
+    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);
+
+#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;
 }
-#endif
+__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.  */
 
-#if !defined(LTDL)
-#  undef LT_SCOPE
-#endif
 
-#endif /*!defined(LT__ARGZ_H)*/
+#endif /* argz.h */
index 37c1b11..bed025a 100644 (file)
@@ -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 <gary@gnu.org>
 #
 # 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 @@ AC_CHECK_TYPES([error_t],
 #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
index 601abb7..19d884b 100644 (file)
@@ -7,6 +7,10 @@ lib/argz.c
 m4/argz.m4
 
 Depends-on:
+mempcpy
+stpcpy
+strndup
+strnlen
 
 configure.ac:
 gl_FUNC_ARGZ
@@ -30,4 +34,4 @@ License:
 LGPLv2+
 
 Maintainer:
-bug-libtool@gnu.org
+all