summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--HACKING4
-rw-r--r--configure.ac4
-rw-r--r--lib/Makefile.am79
-rwxr-xr-xlib/declared.sh135
-rw-r--r--lib/exported.sh.in24
-rw-r--r--m4/exported.m421
-rw-r--r--tests/Makefile.am3
8 files changed, 285 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index d8eb308..33cc4d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2008-04-11 Bruno Haible <bruno@clisp.org>
+
+ Limit the exported symbols through a config.h trick.
+ * m4/exported.m4: New file, from GNU gettext.
+ * lib/exported.sh.in: New file, from GNU gettext.
+ * configure.ac: Invoke gt_GLOBAL_SYMBOL_PIPE.
+ (AC_CONFIG_FILES): Add lib/exported.sh.
+ * lib/declared.sh: New file, borrowing from GNU gettext's moopp.
+ * lib/Makefile.am (HEADERS_WITH_EXTERNS): New variable.
+ (libunistring.sym, config.h): New rules.
+ (MOSTLYCLEANFILES, MAINTAINERCLEANFILES): Update accordingly.
+ (EXTRA_DIST): Add libunistring.sym.
+ * tests/Makefile.am (DEFAULT_INCLUDES): New variable.
+ * HACKING: Require GNU sed.
+
2008-04-10 Bruno Haible <bruno@clisp.org>
Install all auxiliary include files in a subdirectory.
diff --git a/HACKING b/HACKING
index d4fbe66..d0e1335 100644
--- a/HACKING
+++ b/HACKING
@@ -27,6 +27,10 @@ You will need reasonably recent versions of the build tools:
+ Homepage:
http://www.gnu.org/software/gperf/
+ * GNU sed
+ + Homepage:
+ http://www.gnu.org/software/sed/
+
* Perl
+ Homepage:
http://www.perl.org/
diff --git a/configure.ac b/configure.ac
index 740516f..08541a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,6 +55,9 @@ dnl Checks for types, header files, functions and declarations.
gl_INIT
+dnl Check for prerequisites of exported.sh.
+gt_GLOBAL_SYMBOL_PIPE
+
dnl Check for tools needed for formatting the documentation.
ac_aux_dir_abs=`cd $ac_aux_dir && pwd`
AC_PATH_PROG([TEXI2DVI], [texi2dvi], [$ac_aux_dir_abs/missing texi2dvi])
@@ -66,5 +69,6 @@ AC_CONFIG_FILES([doc/Makefile],
[FIX_MAKEFILE_DISTRIB])
AC_CONFIG_FILES([gnulib-local/Makefile])
AC_CONFIG_FILES([lib/Makefile])
+AC_CONFIG_FILES([lib/exported.sh])
AC_CONFIG_FILES([tests/Makefile])
AC_OUTPUT
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 4e8d6a6..6eaed43 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -136,6 +136,85 @@ clean-local: clean-generic
fi; \
:
+# List of header files that get installed and that declared 'extern' symbols.
+HEADERS_WITH_EXTERNS = \
+ unitypes.h \
+ unistr.h \
+ uniconv.h \
+ unistdio.h \
+ uniname.h \
+ unictype.h \
+ uniwidth.h \
+ uniwbrk.h \
+ unilbrk.h \
+ uninorm.h \
+ unicase.h \
+ localcharset.h \
+ iconveh.h
+
+# List of exported symbols.
+# We extract it from the header files that get installed, removing symbols
+# start with "_UC".
+# This file has the same format as the one expected by the libtool option
+# '-export-symbols', but we don't use this option, because it would prevent us
+# from building some of the gnulib unit tests.
+libunistring.sym : $(HEADERS_WITH_EXTERNS)
+ for f in $(HEADERS_WITH_EXTERNS); do cat $(srcdir)/$$f; done \
+ | $(srcdir)/declared.sh | LC_ALL=C sort | LC_ALL=C uniq \
+ | grep -v '^_UC' \
+ > $@-t
+ mv $@-t $@
+# We distribute it because declared.sh relies on GNU sed.
+MOSTLYCLEANFILES += libunistring.sym-t
+MAINTAINERCLEANFILES += libunistring.sym
+EXTRA_DIST += libunistring.sym
+
+# Hide undesired symbols that are defined by libunistring_la_SOURCES or
+# libunistring_la_LIBADD from the global namespace, by prefixing them with
+# "libunistring_".
+all check install: config.h
+config.h: $(BUILT_SOURCES) libunistring.sym
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ : "Avoid double inclusion, to avoid a warning about redefinition of DLL_VARIABLE."; \
+ echo '#ifndef UNISTRING_CONFIG_H'; \
+ echo '#define UNISTRING_CONFIG_H'; \
+ echo; \
+ echo '#include "../config.h"'; \
+ : "All code is collected in a single library,"; \
+ : "No references to variables in other libraries exist."; \
+ echo '#undef DLL_VARIABLE'; \
+ echo '#define DLL_VARIABLE'; \
+ echo; \
+ echo '#endif /* UNISTRING_CONFIG_H */'; \
+ } > config.h && \
+ if test -n "$(HAVE_GLOBAL_SYMBOL_PIPE)"; then \
+ { \
+ for f in $(libunistring_la_SOURCES) $(libunistring_la_LIBADD); do \
+ case $$f in \
+ *.c | *.$(OBJEXT) | *.lo ) \
+ sf=`echo "$$f" | sed -e 's,\\.[^.]*$$,,'`.c; \
+ test -f $$sf || sf=$(srcdir)/$$sf; \
+ of=`echo "$$f" | sed -e 's,^.*/,,' -e 's,\\.[^.]*$$,,'`.$(OBJEXT); \
+ $(COMPILE) -c $$sf || { rm -f config.h; exit 1; }; \
+ sh ./exported.sh $$of 1>&5; \
+ rm -f $$of `echo "$$of" | sed -e 's,\\.$(OBJEXT)$$,.lo,'`; \
+ ;; \
+ esac; \
+ done; \
+ } 5>&1 \
+ | sed -e 's,.* ,,' | LC_ALL=C sort | LC_ALL=C uniq \
+ | LC_ALL=C join -v 1 - $(srcdir)/libunistring.sym \
+ | sed -e 's,^\(.*\)$$,#define \1 libunistring_\1,' > config.h-t && \
+ if test -f config.h; then \
+ cat config.h-t >> config.h; \
+ rm -f config.h-t; \
+ else \
+ rm -f config.h-t; \
+ exit 1; \
+ fi \
+ fi
+MOSTLYCLEANFILES += config.h config.h-t
+
# Libtool's library version information for libunistring.
# See the libtool documentation, section "Library interface versions".
LTV_CURRENT=0
diff --git a/lib/declared.sh b/lib/declared.sh
new file mode 100755
index 0000000..c254417
--- /dev/null
+++ b/lib/declared.sh
@@ -0,0 +1,135 @@
+#! /bin/sh
+#
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# 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/>.
+#
+
+# This script determines the declared global symbols in a C header file.
+# Assumptions:
+# - The header files are in C, with only C89 comments.
+# - No use of macros with parameters.
+# - All global declarations are marked with 'extern'.
+# - All declarations end in ';' on the same line.
+# - Not more than one symbol is declared in a declaration.
+
+# func_usage
+# outputs to stdout the --help usage message.
+func_usage ()
+{
+ echo "\
+Usage: declared.sh [OPTION]... < SOURCE.h
+
+Extracts the declared global symbols of a C header file.
+
+Options:
+ --help print this help and exit
+ --version print version information and exit
+
+Report bugs to <bruno@clisp.org>."
+}
+
+# func_version
+# outputs to stdout the --version message.
+func_version ()
+{
+ echo "declared.sh (GNU libunistring)"
+ echo "Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law."
+ echo "Written by" "Bruno Haible"
+}
+
+# func_fatal_error message
+# outputs to stderr a fatal error message, and terminates the program.
+func_fatal_error ()
+{
+ echo "declared.sh: *** $1" 1>&2
+ echo "declared.sh: *** Stop." 1>&2
+ exit 1
+}
+
+# Command-line option processing.
+while test $# -gt 0; do
+ case "$1" in
+ --help | --hel | --he | --h )
+ func_usage
+ exit 0 ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v )
+ func_version
+ exit 0 ;;
+ -- ) # Stop option prcessing
+ shift; break ;;
+ -* )
+ func_fatal_error "unrecognized option: $option"
+ ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# -gt 0; then
+ func_fatal_error "too many arguments"
+fi
+
+# A sed expression that removes ANSI C and ISO C99 comments.
+sed_remove_comments="
+/[/][/*]/{
+ ta
+ :a
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)//.*,\\1,
+ te
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*]\\([^*]\\|[*][^/*]\\)*[*][*]*/,\\1 ,
+ ta
+ /^\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*[/][*]/{
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*].*,\\1 ,
+ tu
+ :u
+ n
+ s,^\\([^*]\\|[*][^/*]\\)*[*][*]*/,,
+ tv
+ s,^.*\$,,
+ bu
+ :v
+ }
+ :e
+}"
+
+# Check that 'sed' supports the kind of regular expressions used in
+# sed_remove_comments. The use of \| meaning alternation of basic regular
+# expressions is a GNU extension.
+sed_test='s,^\(\(a\|X\)*\)//.*,\1,'
+sed_result=`echo 'aaa//bcd' | sed -e "$sed_test"`
+test "$sed_result" = 'aaa' \
+ || func_fatal_error "The 'sed' program is not GNU sed. Try installing GNU sed."
+
+# A sed expression that joins 'extern' declarations that are broken over
+# several lines.
+sed_join_multiline_externs='
+/^extern [^;]*$/{
+ :a
+ N
+ s/\n/ /g
+ /^extern [^;]*$/{
+ ba
+ }
+}'
+
+# A sed expression that extracts the identifier of each 'extern' declaration.
+sed_extract_extern_declared='s/^extern .* \([A-Za-z_][A-Za-z0-9_]*\) *[;(].*$/\1/p'
+
+sed -e "$sed_remove_comments" \
+ | sed -e "$sed_join_multiline_externs" \
+ | sed -n -e "$sed_extract_extern_declared"
diff --git a/lib/exported.sh.in b/lib/exported.sh.in
new file mode 100644
index 0000000..89e4008
--- /dev/null
+++ b/lib/exported.sh.in
@@ -0,0 +1,24 @@
+#! /bin/sh
+#
+# Copyright (C) 2006 Free Software Foundation, Inc.
+#
+# 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/>.
+#
+
+# This is a script that determines the exported symbols of an object file.
+# This is a separate script because $(GLOBAL_SYMBOL_PIPE) cannot be used in a
+# Makefile, since it may contain dollar signs.
+
+nm_cmd="@NM@ $1 | @GLOBAL_SYMBOL_PIPE@"
+eval $nm_cmd
diff --git a/m4/exported.m4 b/m4/exported.m4
new file mode 100644
index 0000000..fc37923
--- /dev/null
+++ b/m4/exported.m4
@@ -0,0 +1,21 @@
+# exported.m4 serial 1 (gettext-0.18)
+dnl Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Prerequisites of the exported.sh script:
+dnl Check for nm output filter that yields the exported symbols.
+AC_DEFUN([gt_GLOBAL_SYMBOL_PIPE], [
+ AC_REQUIRE([AC_PROG_NM]) dnl provided by libtool.m4
+ AC_SUBST([NM])
+ AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) dnl provided by libtool.m4
+ GLOBAL_SYMBOL_PIPE=$lt_cv_sys_global_symbol_pipe
+ AC_SUBST([GLOBAL_SYMBOL_PIPE])
+ if test -n "$GLOBAL_SYMBOL_PIPE"; then
+ HAVE_GLOBAL_SYMBOL_PIPE=1
+ else
+ HAVE_GLOBAL_SYMBOL_PIPE=
+ fi
+ AC_SUBST([HAVE_GLOBAL_SYMBOL_PIPE])
+])
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7fbaa85..0ec1f3a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -21,6 +21,9 @@ include Makefile.gnulib
AUTOMAKE_OPTIONS += subdir-objects
+# Ensure that ../lib/config.h is seen before ../config.h.
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/lib -I$(top_builddir)
+
# The test suite uses the 'localcharset' module.
TESTS_ENVIRONMENT += @LOCALCHARSET_TESTS_ENVIRONMENT@