summaryrefslogtreecommitdiff
path: root/gettext-tools/src/libexpat-compat.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-12-24 07:38:37 +0000
committer <>2015-02-02 12:02:29 +0000
commit482840e61f86ca321838a91e902c41d40c098bbb (patch)
tree01ea2e242fd2792d19fe192476601587901db794 /gettext-tools/src/libexpat-compat.c
downloadgettext-tarball-482840e61f86ca321838a91e902c41d40c098bbb.tar.gz
Imported from /home/lorry/working-area/delta_gettext-tarball/gettext-0.19.4.tar.xz.gettext-0.19.4
Diffstat (limited to 'gettext-tools/src/libexpat-compat.c')
-rw-r--r--gettext-tools/src/libexpat-compat.c326
1 files changed, 326 insertions, 0 deletions
diff --git a/gettext-tools/src/libexpat-compat.c b/gettext-tools/src/libexpat-compat.c
new file mode 100644
index 0000000..ad680db
--- /dev/null
+++ b/gettext-tools/src/libexpat-compat.c
@@ -0,0 +1,326 @@
+/* xgettext libexpat compatibility.
+ Copyright (C) 2002-2003, 2005-2009, 2013 Free Software Foundation, Inc.
+
+ This file was written by Bruno Haible <haible@clisp.cons.org>, 2002.
+
+ 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#if DYNLOAD_LIBEXPAT
+# include <dlfcn.h>
+#else
+# if HAVE_LIBEXPAT
+# include <expat.h>
+# endif
+#endif
+
+/* Keep the references to XML_GetCurrent{Line,Column}Number symbols
+ before loading libexpat-compat.h, since they are redefined to
+ rpl_XML_GetCurrent{Line,Column}Number . */
+#if !DYNLOAD_LIBEXPAT && XML_MAJOR_VERSION >= 2
+static void *p_XML_GetCurrentLineNumber = (void *) &XML_GetCurrentLineNumber;
+static void *p_XML_GetCurrentColumnNumber = (void *) &XML_GetCurrentColumnNumber;
+#endif
+
+#include "libexpat-compat.h"
+
+/* ======================= Different libexpat ABIs. ======================= */
+
+/* There are three different ABIs of libexpat, regarding the functions
+ XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber.
+ In expat < 2.0, they return an 'int'.
+ In expat >= 2.0, they return
+ - a 'long' if expat was compiled with the default flags, or
+ - a 'long long' if expat was compiled with -DXML_LARGE_SIZE.
+ But the <expat.h> include file does not contain the information whether
+ expat was compiled with -DXML_LARGE_SIZE; so the include file is lying!
+ For this information, we need to call XML_GetFeatureList(), for
+ expat >= 2.0.1; for expat = 2.0.0, we have to assume the default flags. */
+
+#if !DYNLOAD_LIBEXPAT && XML_MAJOR_VERSION >= 2
+
+/* expat >= 2.0 -> Return type is 'int64_t' worst-case. */
+
+/* Return true if libexpat was compiled with -DXML_LARGE_SIZE. */
+static bool
+is_XML_LARGE_SIZE_ABI (void)
+{
+ static bool tested;
+ static bool is_large;
+
+ if (!tested)
+ {
+ const XML_Feature *features;
+
+ is_large = false;
+ for (features = XML_GetFeatureList (); features->name != NULL; features++)
+ if (strcmp (features->name, "XML_LARGE_SIZE") == 0)
+ {
+ is_large = true;
+ break;
+ }
+
+ tested = true;
+ }
+ return is_large;
+}
+
+int64_t
+rpl_XML_GetCurrentLineNumber (XML_Parser parser)
+{
+ if (is_XML_LARGE_SIZE_ABI ())
+ return ((int64_t (*) (XML_Parser)) p_XML_GetCurrentLineNumber) (parser);
+ else
+ return ((long (*) (XML_Parser)) p_XML_GetCurrentLineNumber) (parser);
+}
+
+int64_t
+rpl_XML_GetCurrentColumnNumber (XML_Parser parser)
+{
+ if (is_XML_LARGE_SIZE_ABI ())
+ return ((int64_t (*) (XML_Parser)) p_XML_GetCurrentColumnNumber) (parser);
+ else
+ return ((long (*) (XML_Parser)) p_XML_GetCurrentColumnNumber) (parser);
+}
+#endif
+
+
+/* ===================== Dynamic loading of libexpat. ===================== */
+
+#if DYNLOAD_LIBEXPAT
+
+static XML_Expat_Version (*p_XML_ExpatVersionInfo) (void);
+
+XML_Expat_Version
+XML_ExpatVersionInfo (void)
+{
+ return (*p_XML_ExpatVersionInfo) ();
+}
+
+static const XML_Feature * (*p_XML_GetFeatureList) (void);
+
+const XML_Feature *
+XML_GetFeatureList (void)
+{
+ return (*p_XML_GetFeatureList) ();
+}
+
+enum XML_Size_ABI
+get_XML_Size_ABI (void)
+{
+ static bool tested;
+ static enum XML_Size_ABI abi;
+
+ if (!tested)
+ {
+ if (XML_ExpatVersionInfo () .major >= 2)
+ /* expat >= 2.0 -> XML_Size is 'int64_t' or 'long'. */
+ {
+ const XML_Feature *features;
+
+ abi = is_long;
+ for (features = XML_GetFeatureList ();
+ features->name != NULL;
+ features++)
+ if (strcmp (features->name, "XML_LARGE_SIZE") == 0)
+ {
+ abi = is_int64_t;
+ break;
+ }
+ }
+ else
+ /* expat < 2.0 -> XML_Size is 'int'. */
+ abi = is_int;
+ tested = true;
+ }
+ return abi;
+}
+
+static XML_Parser (*p_XML_ParserCreate) (const XML_Char *encoding);
+
+XML_Parser
+XML_ParserCreate (const XML_Char *encoding)
+{
+ return (*p_XML_ParserCreate) (encoding);
+}
+
+static void (*p_XML_SetElementHandler) (XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end);
+
+void
+XML_SetElementHandler (XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end)
+{
+ (*p_XML_SetElementHandler) (parser, start, end);
+}
+
+
+static void (*p_XML_SetCharacterDataHandler) (XML_Parser parser,
+ XML_CharacterDataHandler handler);
+
+void
+XML_SetCharacterDataHandler (XML_Parser parser,
+ XML_CharacterDataHandler handler)
+{
+ (*p_XML_SetCharacterDataHandler) (parser, handler);
+}
+
+
+static void (*p_XML_SetCommentHandler) (XML_Parser parser,
+ XML_CommentHandler handler);
+
+void
+XML_SetCommentHandler (XML_Parser parser, XML_CommentHandler handler)
+{
+ (*p_XML_SetCommentHandler) (parser, handler);
+}
+
+
+static int (*p_XML_Parse) (XML_Parser parser, const char *s,
+ int len, int isFinal);
+
+int
+XML_Parse (XML_Parser parser, const char *s, int len, int isFinal)
+{
+ return (*p_XML_Parse) (parser, s, len, isFinal);
+}
+
+
+static enum XML_Error (*p_XML_GetErrorCode) (XML_Parser parser);
+
+enum XML_Error
+XML_GetErrorCode (XML_Parser parser)
+{
+ return (*p_XML_GetErrorCode) (parser);
+}
+
+
+static void *p_XML_GetCurrentLineNumber;
+
+int64_t
+XML_GetCurrentLineNumber (XML_Parser parser)
+{
+ switch (get_XML_Size_ABI ())
+ {
+ case is_int:
+ return ((int (*) (XML_Parser)) p_XML_GetCurrentLineNumber) (parser);
+ case is_long:
+ return ((long (*) (XML_Parser)) p_XML_GetCurrentLineNumber) (parser);
+ case is_int64_t:
+ return ((int64_t (*) (XML_Parser)) p_XML_GetCurrentLineNumber) (parser);
+ default:
+ abort ();
+ }
+}
+
+static void *p_XML_GetCurrentColumnNumber;
+
+int64_t
+XML_GetCurrentColumnNumber (XML_Parser parser)
+{
+ switch (get_XML_Size_ABI ())
+ {
+ case is_int:
+ return ((int (*) (XML_Parser)) p_XML_GetCurrentColumnNumber) (parser);
+ case is_long:
+ return ((long (*) (XML_Parser)) p_XML_GetCurrentColumnNumber) (parser);
+ case is_int64_t:
+ return ((int64_t (*) (XML_Parser)) p_XML_GetCurrentColumnNumber) (parser);
+ default:
+ abort ();
+ }
+}
+
+
+static const XML_LChar * (*p_XML_ErrorString) (int code);
+
+const XML_LChar *
+XML_ErrorString (int code)
+{
+ return (*p_XML_ErrorString) (code);
+}
+
+static void (*p_XML_ParserFree) (XML_Parser parser);
+
+void
+XML_ParserFree (XML_Parser parser)
+{
+ return (*p_XML_ParserFree) (parser);
+}
+
+static int libexpat_loaded = 0;
+
+bool
+load_libexpat ()
+{
+ if (libexpat_loaded == 0)
+ {
+ void *handle;
+
+ /* Try to load libexpat-2.x. */
+ handle = dlopen ("libexpat.so.1", RTLD_LAZY);
+ if (handle == NULL)
+ /* Try to load libexpat-1.x. */
+ handle = dlopen ("libexpat.so.0", RTLD_LAZY);
+ if (handle != NULL
+ && (p_XML_ExpatVersionInfo =
+ (XML_Expat_Version (*) (void))
+ dlsym (handle, "XML_ExpatVersionInfo")) != NULL
+ && (p_XML_GetFeatureList =
+ (const XML_Feature * (*) (void))
+ dlsym (handle, "XML_GetFeatureList")) != NULL
+ && (p_XML_ParserCreate =
+ (XML_Parser (*) (const XML_Char *))
+ dlsym (handle, "XML_ParserCreate")) != NULL
+ && (p_XML_SetElementHandler =
+ (void (*) (XML_Parser, XML_StartElementHandler, XML_EndElementHandler))
+ dlsym (handle, "XML_SetElementHandler")) != NULL
+ && (p_XML_SetCharacterDataHandler =
+ (void (*) (XML_Parser, XML_CharacterDataHandler))
+ dlsym (handle, "XML_SetCharacterDataHandler")) != NULL
+ && (p_XML_SetCommentHandler =
+ (void (*) (XML_Parser, XML_CommentHandler))
+ dlsym (handle, "XML_SetCommentHandler")) != NULL
+ && (p_XML_Parse =
+ (int (*) (XML_Parser, const char *, int, int))
+ dlsym (handle, "XML_Parse")) != NULL
+ && (p_XML_GetErrorCode =
+ (enum XML_Error (*) (XML_Parser))
+ dlsym (handle, "XML_GetErrorCode")) != NULL
+ && (p_XML_GetCurrentLineNumber =
+ dlsym (handle, "XML_GetCurrentLineNumber")) != NULL
+ && (p_XML_GetCurrentColumnNumber =
+ dlsym (handle, "XML_GetCurrentColumnNumber")) != NULL
+ && (p_XML_ParserFree =
+ (void (*) (XML_Parser))
+ dlsym (handle, "XML_ParserFree")) != NULL
+ && (p_XML_ErrorString =
+ (const XML_LChar * (*) (int))
+ dlsym (handle, "XML_ErrorString")) != NULL)
+ libexpat_loaded = 1;
+ else
+ libexpat_loaded = -1;
+ }
+ return libexpat_loaded >= 0;
+}
+
+#endif