From: Gary V. Vaughan Date: Thu, 8 Apr 2004 14:13:07 +0000 (+0000) Subject: * libltdl/ltdl.c (argz_append, argz_create_sep, argz_insert) X-Git-Tag: release-1-9b~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21abc3918599bee2b929e92654dbb7068fab0290;p=thirdparty%2Flibtool.git * libltdl/ltdl.c (argz_append, argz_create_sep, argz_insert) (argz_next, argz_stringify): Move from here... * libltdl/argz.c: New file. ...to here. * libltdl/lt__glibc.h: New file. Rename global symbols into the lt__ namespace. * libltdl/lt__private.h: Include lt__glibc.h. * libltdl/Makefile.am (libltdl_la_SOURCES): Add new files. (AM_CPPFLAGS): Add -DLTDL. * libltdl/argz.h (argz_append, argz_create_sep, argz_insert) (argz_next, argz_stringify): New file. Declare argz functions here, including lt__glibc.h when LTDL is defined to rename global symbols for libltdl. * m4/ltdl.m4 (AC_LTDL_FUNC_ARGZ): Add argz to AC_LIBOBJ if any of our argz_* functions are missing from the system libraries. --- diff --git a/ChangeLog b/ChangeLog index b037508da..a3a523224 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2004-04-08 Gary V. Vaughan + * libltdl/ltdl.c (argz_append, argz_create_sep, argz_insert) + (argz_next, argz_stringify): Move from here... + * libltdl/argz.c: New file. ...to here. + * libltdl/lt__glibc.h: New file. Rename global symbols into the + lt__ namespace. + * libltdl/lt__private.h: Include lt__glibc.h. + * libltdl/Makefile.am (libltdl_la_SOURCES): Add new files. + (AM_CPPFLAGS): Add -DLTDL. + * libltdl/argz.h (argz_append, argz_create_sep, argz_insert) + (argz_next, argz_stringify): New file. Declare argz functions + here, including lt__glibc.h when LTDL is defined to rename global + symbols for libltdl. + * m4/ltdl.m4 (AC_LTDL_FUNC_ARGZ): Add argz to AC_LIBOBJ if any of + our argz_* functions are missing from the system libraries. + * libltdl/ltdl.c: Move standard headers and preprocessor guards from here... * libltdl/lt__private.h: ...to here. New file to declare ltdl's diff --git a/libltdl/Makefile.am b/libltdl/Makefile.am index a5096df59..72a12dffb 100644 --- a/libltdl/Makefile.am +++ b/libltdl/Makefile.am @@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I ../m4 AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -DEFS = -DHAVE_CONFIG_H="<$(CONFIG_H)>" +DEFS = -DHAVE_CONFIG_H="<$(CONFIG_H)>" -DLTDL pkgincludedir = $(includedir)/libltdl @@ -31,20 +31,22 @@ lib_LTLIBRARIES = libltdl.la endif if CONVENIENCE_LTDL -noinst_LTLIBRARIES = libltdlc.la +noinst_LTLIBRARIES = libltdlc.la endif ## Make sure these will be cleaned even when they're not built by ## default. -CLEANFILES = libltdl.la libltdlc.la +CLEANFILES = libltdl.la libltdlc.la -libltdl_la_SOURCES = lt__alloc.c lt__alloc.h lt__pre89.h lt_system.h \ - ltdl.c ltdl.h -libltdl_la_LDFLAGS = -no-undefined -version-info 5:0:2 -libltdl_la_LIBADD = $(LIBADD_DL) $(LTLIBOBJS) +libltdl_la_SOURCES = ltdl.h ltdl.c \ + lt__private.h lt__alloc.h lt__alloc.c \ + lt__pre89.h lt__glibc.h argz.h lt__dirent.h \ + lt_system.h +libltdl_la_LDFLAGS = -no-undefined -version-info 5:0:2 +libltdl_la_LIBADD = $(LIBADD_DL) $(LTLIBOBJS) libltdlc_la_SOURCES = $(libltdl_la_SOURCES) -libltdlc_la_LIBADD = $(LIBADD_DL) $(LTLIBOBJS) +libltdlc_la_LIBADD = $(LIBADD_DL) $(LTLIBOBJS) ## These are installed as a subdirectory of pkgdatadir so that ## libtoolize --ltdl can find them later: diff --git a/libltdl/argz.c b/libltdl/argz.c new file mode 100644 index 000000000..9762e96d4 --- /dev/null +++ b/libltdl/argz.c @@ -0,0 +1,226 @@ +/* argz.c -- argz implementation for non-glibc systems + Copyright (C) 2004 Free Software Foundation, Inc. + Originally by Gary V. Vaughan + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +This 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 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 it under the same +distribution terms that you use for the rest of that program. + +This 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 this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA + +*/ + +#include "argz.h" + +#include +#include +#include +#include +#include + +#if HAVE_STRING_H +# include +#elif HAVE_STRINGS_H +# include +#endif +#if HAVE_MEMORY_H +# include +#endif + +#define EOS_CHAR '\0' + +error_t +argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len) +{ + size_t argz_len; + char *argz; + + 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; + + /* Copy characters from BUF after terminating '\0' in ARGZ. */ + memcpy (argz + *pargz_len, buf, buf_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} + + +error_t +argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len) +{ + size_t argz_len; + char *argz = 0; + + assert (str); + assert (pargz); + assert (pargz_len); + + /* Make a copy of STR, but replacing each occurence of + DELIM with '\0'. */ + argz_len = 1+ strlen (str); + if (argz_len) + { + const char *p; + char *q; + + argz = (char *) malloc (argz_len); + if (!argz) + 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; + } + + /* 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; + + return 0; +} + + +error_t +argz_insert (char **pargz, size_t *pargz_len, char *before, const 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 + { + /* 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) + { + if (argz[argz_len] == EOS_CHAR) + argz[argz_len] = sep; + } + } +} diff --git a/libltdl/argz.h b/libltdl/argz.h new file mode 100644 index 000000000..4958cbb04 --- /dev/null +++ b/libltdl/argz.h @@ -0,0 +1,54 @@ +/* lt__argz.h -- internal argz interface for non-glibc systems + Copyright (C) 2004 Free Software Foundation, Inc. + Originally by Gary V. Vaughan + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +This 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 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 it under the same +distribution terms that you use for the rest of that program. + +This 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 this 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 LTDL +# include "lt__glibc.h" +#endif + +#ifdef _cplusplus +extern "C" { +#endif + +error_t argz_append (char **pargz, size_t *pargz_len, + const char *buf, size_t buf_len); +error_t argz_create_sep (const char *str, int delim, + char **pargz, size_t *pargz_len); +error_t argz_insert (char **pargz, size_t *pargz_len, + char *before, const char *entry); +char * argz_next (char *argz, size_t argz_len, const char *entry); +void argz_stringify (char *argz, size_t argz_len, int sep); + +#ifdef _cplusplus +} +#endif + +#endif /*!ARGZ_H*/ diff --git a/libltdl/lt__glibc.h b/libltdl/lt__glibc.h new file mode 100644 index 000000000..9d3af3b99 --- /dev/null +++ b/libltdl/lt__glibc.h @@ -0,0 +1,73 @@ +/* lt__glibc.h -- support for non glibc environments + Copyright (C) 2004 Free Software Foundation, Inc. + Originally by Gary V. Vaughan + + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. + +This 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 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 it under the same +distribution terms that you use for the rest of that program. + +This 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 this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA + +*/ + +#ifndef LT__GLIBC_H +#define LT__GLIBC_H 1 + +#ifdef HAVE_CONFIG_H +# include HAVE_CONFIG_H +#endif + +#include "lt_system.h" + +/* First redefine any glibc symbols we reimplement... */ +#undef argz_append +#define argz_append lt__argz_append +#undef argz_create_sep +#define argz_create_sep lt__argz_create_sep +#undef argz_insert +#define argz_insert lt__argz_insert +#undef argz_next +#define argz_next lt__argz_next +#undef argz_stringify +#define argz_stringify lt__argz_stringify + +/* ...import our implementations into the lt__ namespace... */ +#include "argz.h" + +/* ...finally, we revert to the library implementations of any symbols + that are provided by the host since they may be more optimised (say + with inline assembler) than the generic versions we provide here. */ +#if HAVE_ARGZ_APPEND +# undef argz_append +#endif +#if HAVE_ARGZ_CREATE_SEP +# undef argz_create_sep +#endif +#if HAVE_ARGZ_INSERT +# undef argz_insert +#endif +#if HAVE_ARGZ_NEXT +# undef argz_next +#endif +#if HAVE_ARGZ_STRINGIFY +# undef argz_stringify +#endif + +#endif /*!LT__GLIBC_H*/ diff --git a/libltdl/lt__private.h b/libltdl/lt__private.h index b2b91299d..82b21c7c9 100644 --- a/libltdl/lt__private.h +++ b/libltdl/lt__private.h @@ -56,6 +56,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA #include "lt__alloc.h" #include "lt__dirent.h" +#include "lt__glibc.h" #include "lt__pre89.h" #include "lt_system.h" #include "ltdl.h" diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index 0f15e5784..84a0d7d8f 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -55,207 +55,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA #define LT_SYMBOL_OVERHEAD 5 -#if ! HAVE_ARGZ_APPEND -# define argz_append rpl_argz_append - -static error_t -argz_append (char **pargz, size_t *pargz_len, const char *buf, size_t buf_len) -{ - size_t argz_len; - char *argz; - - 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; - - /* Copy characters from BUF after terminating '\0' in ARGZ. */ - memcpy (argz + *pargz_len, buf, buf_len); - - /* Assign new values. */ - *pargz = argz; - *pargz_len = argz_len; - - return 0; -} -#endif /* !HAVE_ARGZ_APPEND */ - - -#if ! HAVE_ARGZ_CREATE_SEP -# define argz_create_sep rpl_argz_create_sep - -static error_t -argz_create_sep (const char *str, int delim, char **pargz, size_t *pargz_len) -{ - size_t argz_len; - char *argz = 0; - - assert (str); - assert (pargz); - assert (pargz_len); - - /* Make a copy of STR, but replacing each occurence of - DELIM with '\0'. */ - argz_len = 1+ strlen (str); - if (argz_len) - { - const char *p; - char *q; - - argz = (char *) malloc (argz_len); - if (!argz) - return ENOMEM; - - for (p = str, q = argz; *p != LT_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] != LT_EOS_CHAR)) - *q++ = LT_EOS_CHAR; - else - --argz_len; - } - else - *q++ = *p; - } - /* Copy terminating LT_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; - - return 0; -} -#endif /* !HAVE_ARGZ_CREATE_SEP */ - - -#if ! HAVE_ARGZ_INSERT -# define argz_insert rpl_argz_insert - -static error_t -argz_insert (char **pargz, size_t *pargz_len, char *before, const 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+ LT_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] != LT_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; -} -#endif /* !HAVE_ARGZ_INSERT */ - - -#if ! HAVE_ARGZ_NEXT -# define argz_next rpl_argz_next - -static 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, LT_EOS_CHAR); - - /* Return either the new ENTRY, or else NULL if ARGZ is - exhausted. */ - return (entry >= argz + argz_len) ? 0 : (char *) entry; - } - 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; - } -} -#endif /* !HAVE_ARGZ_NEXT */ - - - -#if ! HAVE_ARGZ_STRINGIFY -# define argz_stringify rpl_argz_stringify - -static 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) - { - if (argz[argz_len] == LT_EOS_CHAR) - argz[argz_len] = sep; - } - } -} -#endif /* !HAVE_ARGZ_STRINGIFY */ - - /* --- TYPE DEFINITIONS -- */ diff --git a/m4/ltdl.m4 b/m4/ltdl.m4 index 004d5bd21..4b9994b12 100644 --- a/m4/ltdl.m4 +++ b/m4/ltdl.m4 @@ -438,6 +438,7 @@ if test x"$libltdl_cv_need_uscore" = xyes; then fi ])# AC_LTDL_DLSYM_USCORE + # AC_LTDL_FUNC_ARGZ # ----------------- AC_DEFUN([AC_LTDL_FUNC_ARGZ], @@ -451,5 +452,6 @@ AC_CHECK_TYPES([error_t], # include #endif]) -AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next argz_stringify]) +AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next \ + argz_stringify], [], [AC_LIBOBJ([argz])]) ])# AC_LTDL_FUNC_ARGZ