bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/2] Add missing argz_* functions from glibc


From: Jim Meyering
Subject: Re: [PATCH 2/2] Add missing argz_* functions from glibc
Date: Thu, 05 Jun 2008 21:01:01 +0200

Jim Meyering <address@hidden> wrote:
> In the mean time, I'm going to check in the new generated files in an
> hour or two.  So if anyone has an objection, speak up soon.
> Lower priority: I'll look into automating the procedure
> to generate these files.

As for generating the files, with the patch below,
and a glibc tree, I ran "make -C config -f argz.mk".
Automating that will come later.

I've just pushed this:

>From eb61774da0aea434755a8684e2bb2f6854bd4e1c Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 3 Jun 2008 11:42:12 +0200
Subject: [PATCH] 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.
---
 config/argz.mk     |   63 +++++++
 config/srclist.txt |    8 +-
 lib/argz.c         |  512 ++++++++++++++++++++++++++++++++++------------------
 lib/argz.in.h      |  208 +++++++++++++++------
 m4/argz.m4         |    7 +-
 modules/argz       |    6 +-
 6 files changed, 558 insertions(+), 246 deletions(-)
 create mode 100644 config/argz.mk

diff --git a/config/argz.mk b/config/argz.mk
new file mode 100644
index 0000000..14b00fd
--- /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 <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) > address@hidden && mv address@hidden $@
+
+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;'                           \
+         > address@hidden && mv address@hidden $@
+
+clean:
+       rm -f $(targets)
diff --git a/config/srclist.txt b/config/srclist.txt
index ce4f9c5..fa029bc 100644
--- a/config/srclist.txt
+++ b/config/srclist.txt
@@ -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
diff --git a/lib/argz.c b/lib/argz.c
index f31ce17..8f5d1f5 100644
--- 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 address@hidden
-
-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;
 }
diff --git a/lib/argz.in.h b/lib/argz.in.h
index 40d5176..e89f029 100644
--- 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
-
-   NOTE: The canonical source of this file is maintained with the
-   GNU Libtool package.  Report bugs to address@hidden
-
-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);
+
+/* 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 */
diff --git a/m4/argz.m4 b/m4/argz.m4
index 37c1b11..bed025a 100644
--- 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 <address@hidden>
 #
 # 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
diff --git a/modules/argz b/modules/argz
index 601abb7..19d884b 100644
--- a/modules/argz
+++ b/modules/argz
@@ -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:
address@hidden
+all
--
1.5.6.rc1.14.gc64191




reply via email to

[Prev in Thread] Current Thread [Next in Thread]