summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Ulrich Niedermann <hun@n-dimensional.de>2020-02-14 11:48:34 +0100
committerHans Ulrich Niedermann <hun@n-dimensional.de>2020-02-16 17:09:13 +0100
commit59dbd89143316ae7df9716e6cce59876549648f9 (patch)
tree7b87b56e125447782f7b45bf804873e84c419bf8
parent94c0fdb0e15b1309ab3de81de8da5d7ca3912ca4 (diff)
downloadlibgphoto2-issue-467-wip4.tar.gz
Set based camlib definition and --with-camlibs handlingissue-467-wip4
This uses proper set operations both for GP_CAMLIB and for handling the --with-camlibs value. This allows all GP_CAMLIB definitions to be present at autoreconf time (as m4 code) time but some being conditional at the time of the configure run (in the sh code). The ./configure output is still a bit verbose, but we can reduce that verbosity later when we have found out that this works well on people's different systems. Fixes: https://github.com/gphoto/libgphoto2/issues/467
-rw-r--r--camlibs/Makefile.am84
-rw-r--r--camlibs/lumix/lumix.c28
-rw-r--r--configure.ac54
-rw-r--r--gphoto-m4/gp-camlibs.m4557
-rw-r--r--gphoto-m4/gp-progs.m496
-rw-r--r--gphoto-m4/gp-set.m4725
-rw-r--r--libgphoto2/gphoto2-version.c45
7 files changed, 1384 insertions, 205 deletions
diff --git a/camlibs/Makefile.am b/camlibs/Makefile.am
index c6a6e257a..34926281a 100644
--- a/camlibs/Makefile.am
+++ b/camlibs/Makefile.am
@@ -6,8 +6,8 @@
# or
# ( cd camlibs && make agfa_cl20.la )
#
-# If you only want to install a single camlib or two, run
-# make BUILD_THESE_CAMLIBS="canon.la agfa_cl20.la" install
+# If you only want to build/install a single camlib or two, run
+# make GP_CAMLIB_SET="canon.la agfa_cl20.la" install
# in the camlibs/ subdir or in the libgphoto2 top-level directory.
########################################################################
@@ -35,6 +35,18 @@ EXTRA_LTLIBRARIES =
########################################################################
+# We pass the list of camlibs through this set of variables in order
+# to remain compatible with older calling conventions.
+
+# Actually implement BUILD_THESE_CAMLIBS as documented
+BUILD_THESE_CAMLIBS = $(GP_CAMLIB_SET)
+
+# while keeping compatibility with the variable which has been working
+# for so long
+INSTALL_THESE_CAMLIBS = $(BUILD_THESE_CAMLIBS)
+
+
+########################################################################
# All camlibs are defined as EXTRA_LTLIBRARIES. This requires that
# all camlibs have -rpath set explicitly in foobar_la_LDFLAGS.
# You're probably best off by using the camlib_* variables defined
@@ -46,17 +58,29 @@ camlib_LTLIBRARIES = $(INSTALL_THESE_CAMLIBS)
# Define the compile/link/etc. flags common to all camlibs in one place,
# i.e. here.
-camlib_dependencies = $(top_srcdir)/camlibs/camlib.sym
-camlib_ldflags = -module -no-undefined -avoid-version -export-dynamic \
- -export-symbols '$(top_srcdir)/camlibs/camlib.sym' \
- -rpath '$(camlibdir)'
-camlib_libadd = $(top_builddir)/libgphoto2/libgphoto2.la $(top_builddir)/libgphoto2_port/libgphoto2_port/libgphoto2_port.la
+camlib_dependencies =
+camlib_dependencies += $(top_srcdir)/camlibs/camlib.sym
+
+camlib_ldflags =
+camlib_ldflags += -module
+camlib_ldflags += -no-undefined
+camlib_ldflags += -avoid-version
+camlib_ldflags += -export-dynamic
+camlib_ldflags += -export-symbols '$(top_srcdir)/camlibs/camlib.sym'
+camlib_ldflags += -rpath '$(camlibdir)'
+
+camlib_libadd =
+camlib_libadd += $(top_builddir)/libgphoto2/libgphoto2.la
+camlib_libadd += $(top_builddir)/libgphoto2_port/libgphoto2_port/libgphoto2_port.la
+
+AM_CPPFLAGS += -I$(top_srcdir) -I$(top_builddir)
+AM_CPPFLAGS += -I$(top_srcdir)/libgphoto2_port
+AM_CPPFLAGS += -I$(top_srcdir)/libgphoto2 -I$(top_builddir)/libgphoto2
-AM_CPPFLAGS += -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/libgphoto2_port -I$(top_srcdir)/libgphoto2 -I$(top_builddir)/libgphoto2
########################################################################
# You can generate this Makefile-files include list by running
-# find . -name Makefile-files -exec echo include {} \; | sort | sed 's| ./| |g'
+# find . -name Makefile-files -exec echo include {} \; | sort | sed 's| ./| |g'
include adc65/Makefile-files
include agfa-cl20/Makefile-files
include aox/Makefile-files
@@ -136,17 +160,33 @@ print-camlibs: Makefile
# Make sure that the list of camlibs defined in configure.ac using
# GP_CAMLIB(...) and the list of camlibs defined in */Makefile-files
# match.
-CLEANFILES += all-src-camlibs all-def-camlibs
-all-local: Makefile
- @:; \
- (for x in $(EXTRA_LTLIBRARIES) template.la; do echo "$$(basename "$$x" ".la")"; done) \
- | sort > all-src-camlibs; \
- (for x in $(ALL_DEFINED_CAMLIBS); do echo "$$x"; done) \
- | sort > all-def-camlibs; \
- if cmp all-def-camlibs all-src-camlibs; then :; else \
- diff -u all-def-camlibs all-src-camlibs; \
- echo "List of camlibs in configure.ac is out of date."; \
- echo "Have a developer update it using \"make -C camlibs print-camlibs\"."; \
+
+# List all camlibs defined in configure.ac
+CLEANFILES += all-cfg-camlibs
+all-cfg-camlibs: Makefile
+ @(for x in $(GP_CAMLIB_SET_EVERYTHING); do echo "$$x"; done) \
+ | LC_ALL=C $(SORT) > all-cfg-camlibs
+
+# List all camlibs defined in the camlibs/ source subtree Makefile-files
+CLEANFILES += all-mkf-camlibs
+all-mkf-camlibs: Makefile
+ @(for x in $(EXTRA_LTLIBRARIES) $(noinst_LTLIBRARIES); do echo "$$(basename "$$x" ".la")"; done) \
+ | LC_ALL=C $(SORT) > all-mkf-camlibs
+
+.PHONY: all-local
+all-local: all-cfg-camlibs all-mkf-camlibs
+ @if $(CMP) all-cfg-camlibs all-mkf-camlibs > /dev/null 2>&1; then :; else \
+ echo "#"; \
+ for camlib in $$($(COMM) -23 all-cfg-camlibs all-mkf-camlibs); do \
+ echo "# - '$${camlib}' camlib in 'configure.ac', but not in Makefiles."; \
+ done; \
+ for camlib in $$($(COMM) -13 all-cfg-camlibs all-mkf-camlibs); do \
+ echo "# - '$${camlib}' camlib in Makefiles, but not in 'configure.ac'"; \
+ done; \
+ echo "#"; \
+ echo "# The camlib set definitions in 'configure.ac' and Makefiles are inconsistent"; \
+ echo "# Have a developer sync them, maybe using \"make -C camlibs print-camlibs\"."; \
+ echo "#"; \
exit 1; \
fi
@@ -155,8 +195,8 @@ all-local: Makefile
# Shortcut for installation of a subset of camlibs
# Usage: make CAMLIBS="canon.la ptp2.la" install-camlibs
-install-camlibs:
- $(MAKE) $(AM_MAKEFLAGS) BUILD_THESE_CAMLIBS="$(CAMLIBS)" install-camlibLTLIBRARIES
+install-camlibs: $(GP_CAMLIB_SET)
+ $(MAKE) $(AM_MAKEFLAGS) GP_CAMLIB_SET="$(GP_CAMLIB_SET)" install-camlibLTLIBRARIES
########################################################################
diff --git a/camlibs/lumix/lumix.c b/camlibs/lumix/lumix.c
index 3115b0648..5cb8ee450 100644
--- a/camlibs/lumix/lumix.c
+++ b/camlibs/lumix/lumix.c
@@ -27,17 +27,13 @@
#include <string.h>
#include <errno.h>
-#ifdef HAVE_LIBCURL
-# include <curl/curl.h>
-#endif
+#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
-#ifdef HAVE_LIBXML2
-# include <libxml/parser.h>
-# include <libxml/tree.h>
-# include <libxml/xmlmemory.h>
-# include <libxml/xmlreader.h>
-#endif
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlreader.h>
#include <sys/socket.h>
@@ -87,7 +83,6 @@
# define N_(String) (String)
#endif
-#if defined(HAVE_LIBCURL) && defined(HAVE_LIBXML2)
char* CDS_Control = ":60606/Server0/CDS_control";
int ReadoutMode = 2; // this should be picked up from the settings.... 0-> JPG; 1->RAW; 2 -> Thumbnails
@@ -1919,19 +1914,6 @@ camera_init (Camera *camera, GPContext *context)
return GP_ERROR_IO;
}
-#else
-/* no XML2 or no CURL -> no camera here */
-int
-camera_init (Camera *camera, GPContext *context)
-{
- return GP_OK;
-}
-
-int camera_abilities (CameraAbilitiesList *list)
-{
- return GP_OK;
-}
-#endif
int
camera_id (CameraText *id)
diff --git a/configure.ac b/configure.ac
index 7b7bd7f24..e2839ca86 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
dnl Process this file with autoreconf to produce a configure script.
-AC_PREREQ(2.59)
+AC_PREREQ(2.62)
dnl NOTE: Be version style _higher_ than the last release.
dnl So lastversion.X.trunk for instance. Bump X if necessary.
@@ -255,6 +255,13 @@ AC_CHECK_LIB(m, sqrt)
dnl ---------------------------------------------------------------------------
+dnl test GP_SET_ macros from gp-set.m4
+dnl ---------------------------------------------------------------------------
+dnl GP_SET_TESTSUITE
+dnl AC_MSG_ERROR([gp-set.m4 testsuite done.])
+
+
+dnl ---------------------------------------------------------------------------
dnl check for libjpeg
dnl ---------------------------------------------------------------------------
LIBJPEG=""
@@ -289,7 +296,11 @@ GP_CHECK_LIBRARY([LIBCURL],[libcurl],[>= 7.1],
)
GP_CONFIG_MSG([CURL support for Lumix Wifi],[${have_LIBCURL}])
-AM_CONDITIONAL([BUILD_LUMIX], [test -n "$have_LIBCURL" && test "X$have_LIBCURL" != "Xno" && test -n "$have_LIBXML2" && test "X$have_LIBXML2" != "Xno"])
+AM_CONDITIONAL([HAVE_LIBCURL],
+ [test -n "$have_LIBCURL" && test "X$have_LIBCURL" != "Xno"])
+AM_CONDITIONAL([HAVE_LIBXML2],
+ [test -n "$have_LIBXML2" && test "X$have_LIBXML2" != "Xno"])
+
dnl ---------------------------------------------------------------------------
dnl check for libgd
@@ -476,13 +487,15 @@ AM_CPPFLAGS="$AM_CPPFLAGS -DCAMLIBS=\\\"\$(camlibdir)\\\""
dnl ---------------------------------------------------------------------------
dnl Camera drivers (camlibs)
dnl ---------------------------------------------------------------------------
-dnl * See m4m/gp-camlibs.m4 for usage details, e.g. for marking camlibs as
+dnl * See gp-camlibs.m4 for usage details, e.g. for marking camlibs as
dnl unlisted.
dnl * Please add new camlibs in alphabetical order.
dnl * Selective build:
dnl $ make -C camlibs canon.la ptp2.la
+dnl or
+dnl $ make -C camlibs GP_CAMLIB_SET="canon.la ptp2.la"
dnl * Selective install:
-dnl $ make CAMLIBS="canon.la ptp2.la" install-camlibs
+dnl $ make GP_CAMLIB_SET="canon.la ptp2.la" install-camlibs
GP_CAMLIB([adc65],[outdated])dnl very old serial camera
GP_CAMLIB([agfa_cl20],[outdated])dnl
GP_CAMLIB([aox],[outdated])dnl
@@ -513,7 +526,11 @@ GP_CAMLIB([konica],[outdated])dnl
GP_CAMLIB([konica_qm150],[outdated])dnl
GP_CAMLIB([largan],[outdated])dnl
GP_CAMLIB([lg_gsm],[outdated])dnl
+AM_COND_IF([HAVE_LIBCURL], [dnl
+AM_COND_IF([HAVE_LIBXML2], [dnl
GP_CAMLIB([lumix])dnl
+])
+])
GP_CAMLIB([mars])dnl
GP_CAMLIB([dimagev])dnl
GP_CAMLIB([mustek],[outdated])dnl
@@ -552,7 +569,6 @@ GP_CAMLIB([toshiba_pdrm11],[outdated])dnl
GP_CAMLIB([tp6801])dnl
dnl
GP_CAMLIBS_DEFINE()dnl
-GP_CONFIG_MSG([Camlibs],[${camlibs}])
dnl --------------------------------------------------------------------
@@ -626,13 +642,21 @@ if test -d "$srcdir/libgphoto2_port"; then
AC_CONFIG_SUBDIRS([libgphoto2_port])
else
AC_MSG_ERROR([
-*** Hey, where have you hidden my libgphoto2_port?
-*** I needed that!
+******************************************************
+*** Hey, where have you hidden my libgphoto2_port? ***
+*** I needed that! ***
+******************************************************
])
fi
# ---------------------------------------------------------------------------
+# clean up
+# ---------------------------------------------------------------------------
+GP_SET_CLEAN_FILES
+
+
+# ---------------------------------------------------------------------------
# Create output files
# ---------------------------------------------------------------------------
AC_CONFIG_FILES([
@@ -662,11 +686,13 @@ doc/api/Makefile
],[
dnl This relies on this code being called for each of the above files
dnl with ac_file set to the filename.
- if echo "$ac_file" | grep '.sh$' > /dev/null; then
- if test -f "$ac_file"; then
- chmod +x "$ac_file"
- fi
+case "$ac_file" in #(
+*.sh)
+ if test -f "$ac_file"; then
+ chmod +x "$ac_file"
fi
+ ;;
+esac
])
AC_OUTPUT
@@ -685,11 +711,7 @@ GP_CONFIG_OUTPUT
dnl Catch the Gentoo folks about to shoot themselves in the foot.
dnl Just enabling "foo" often does not make a camera made by
dnl manufacturer "Foo" work.
-if test "x$camlibs" = "xall"; then
- :
-else
- GP_CAMLIBS_WARNING
-fi
+GP_CAMLIBS_CONDITIONAL_WARNING
cat<<_GP_EOF
Please check whether the configuration I have detected matches what
diff --git a/gphoto-m4/gp-camlibs.m4 b/gphoto-m4/gp-camlibs.m4
index a7c82fe97..c798b4f71 100644
--- a/gphoto-m4/gp-camlibs.m4
+++ b/gphoto-m4/gp-camlibs.m4
@@ -1,191 +1,476 @@
+dnl ####################################################################
+dnl
dnl GP_CAMLIB & Co.
dnl
+dnl ####################################################################
+dnl
dnl Redundancy free definition of libgphoto2 camlibs.
dnl
dnl Removes the redundany from the camlib lists, and executes
-dnl additional consistency checks, e.g. to ensure that subdirectories
-dnl actually exist.
+dnl additional consistency checks on the build system.
+dnl
+dnl Every camlib belongs to one of the following (disjunct) sets of
+dnl camlibs:
+dnl
+dnl * the 'standard' set
dnl
-dnl You can mark camlibs as unlisted, i.e. they won't be listed
-dnl explicitly but still be recognized.
+dnl The set of camlibs which is most likely to support the most
+dnl cameras. This is the default when --with-camlibs=... is not
+dnl given. This used to be called 'all', even though it
+dnl definitively does not comprise all camlibs.
+dnl
+dnl * the 'outdated' set
+dnl
+dnl These cameras are outdated in some way. The cameras may have
+dnl fallen out of use, the camlib might have been superseded by
+dnl another one, or other reasons. Not built by default.
+dnl
+dnl * the 'unlisted' set
+dnl
+dnl These camlibs will not be listed by './configure --help', but
+dnl they can still be added to the set of camlibs to be built.
dnl
dnl Example usage:
dnl
dnl GP_CAMLIB([canon])
dnl GP_CAMLIB([casio])
dnl [...]
+dnl AM_COND_IF([HAVE_LIBCURL], [dnl
+dnl AM_COND_IF([HAVE_LIBXML2], [dnl
+dnl GP_CAMLIB([lumix])dnl
+dnl ])
+dnl ])
+dnl [...]
dnl GP_CAMLIB([ptp],[unlisted])
dnl GP_CAMLIB([ptp2])
dnl [...]
dnl GP_CAMLIB([toshiba])
-dnl GP_CAMLIBS_DEFINE([camlibs])
+dnl GP_CAMLIBS_DEFINE()
dnl
-dnl The camlibs basedir parameter of GP_CAMLIBS_DEFINE is optional.
dnl
dnl ####################################################################
+dnl Implementation remarks
+dnl ####################################################################
+dnl
+dnl Note that at this time, the set names are hard coded, but could be
+dnl moved to a m4 time automatic set of set names at a later time.
+dnl
+dnl A few notes on macro and variable naming:
+dnl
+dnl * GP_* are the macros to be called from configure.ac
+dnl * GP_CAMLIBS_* are also shell variables exported to configure.ac
+dnl shell code and Makefile.am files
+dnl * gp_m4_* are the macros used inside those macros as m4 variables
+dnl * gp_sh_* are the shell variables used inside the GP_ shell code
+dnl * The old, inconsistent names of the as untouched variables
+dnl exported to configure.ac and Makefile.am are still inconsistent.
+dnl
dnl
-AC_DEFUN([GP_CAMLIBS_INIT],[dnl
+dnl ####################################################################
+dnl Forbid everything first, allow specific variable names later
+dnl ####################################################################
+m4_pattern_forbid([GP_CAMLIBS_])dnl
+m4_pattern_forbid([GP_CAMLIB_])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl _GP_CAMLIBS_INIT
+dnl Called internally when required.
+dnl ####################################################################
+AC_DEFUN_ONCE([_GP_CAMLIBS_INIT],[dnl
+dnl # BEGIN $0($@)
AC_BEFORE([$0],[GP_CAMLIB])dnl
-m4_define_default([gp_camlib_srcdir], [camlibs])dnl
-m4_define_default([gp_camlibs], [])dnl
-m4_define_default([gp_camlibs_unlisted], [])dnl
-m4_define_default([gp_camlibs_outdated], [])dnl
+AC_REQUIRE([AC_PROG_GREP])dnl
+AC_REQUIRE([AC_PROG_SED])dnl
+AC_REQUIRE([GP_PROG_CMP])dnl
+AC_REQUIRE([GP_PROG_SORT])dnl
+AC_REQUIRE([GP_PROG_TR])dnl
+AC_REQUIRE([GP_PROG_UNIQ])dnl
+m4_foreach_w([var], [everything standard unlisted outdated], [dnl
+ m4_set_empty([gp_m4s_camlib_set_]var, [], [dnl
+ m4_errprintn([Error: non-empty set gp_m4s_camlib_set_]var[ already defined])dnl
+ m4_exit(1)dnl
+ ])dnl
+])dnl
+GP_SET_DEFINE([camlib-set-standard])dnl
+GP_SET_DEFINE([camlib-set-unlisted])dnl
+GP_SET_DEFINE([camlib-set-outdated])dnl
+dnl # END $0($@)
])dnl
dnl
-dnl ####################################################################
dnl
+dnl ####################################################################
+dnl GP_CAMLIB([mycamlib])
+dnl GP_CAMLIB([mycamlib], [outdated])
+dnl Add the camlib 'mycamlib' to the "standard" set of camlibs or
+dnl the "outdated" set of camlibs, respectively.
+dnl ####################################################################
+m4_pattern_forbid([GP_CAMLIB])dnl
AC_DEFUN([GP_CAMLIB],[dnl
-AC_REQUIRE([GP_CAMLIBS_INIT])dnl
+dnl # BEGIN $0($@)
+AC_REQUIRE([_GP_CAMLIBS_INIT])dnl
AC_BEFORE([$0],[GP_CAMLIBS_DEFINE])dnl
-m4_if([$2],[unlisted],[dnl
-# $0($1,$2)
-m4_append([gp_camlibs_unlisted], [$1], [ ])dnl
-],
-[$2],[outdated],[dnl
-# $0($1,$2)
-m4_append([gp_camlibs_outdated], [$1], [ ])dnl
-],
-[$#],[1],[dnl
-# $0($1)
-m4_append([gp_camlibs], [$1], [ ])dnl
-],[dnl
-m4_errprint(__file__:__line__:[ Error:
-*** Illegal parameter 2 to $0: `$2'
-*** Valid values are: undefined, [unlisted] or [outdated]
-])dnl
+m4_case([$#],[2],[dnl
+ m4_case([$2], [unlisted], [dnl
+ GP_SET_ADD([camlib-set-unlisted], [$1])
+ m4_set_add([gp_m4s_camlib_set_unlisted], [$1])dnl
+ ], [outdated], [dnl
+ GP_SET_ADD([camlib-set-outdated], [$1])
+ m4_set_add([gp_m4s_camlib_set_outdated], [$1])dnl
+ ], [dnl
+ m4_errprintn(__file__:__line__:[ Error: Wrong second argument to GP_CAMLIB])dnl
+ m4_exit(1)dnl
+ ])dnl
+], [1], [dnl
+ GP_SET_ADD([camlib-set-standard], [$1])
+ m4_set_add([gp_m4s_camlib_set_standard], [$1])dnl
+], [dnl
+ m4_errprintn(__file__:__line__:[ Error: Wrong number of arguments to GP_CAMLIB])dnl
+ m4_exit(1)dnl
+])dnl m4_case $#
+m4_set_add([gp_m4s_camlib_set_everything], [$1], [], [dnl
+m4_errprintn(__file__:__line__:[Duplicate declaration of camlib $1])dnl
m4_exit(1)dnl
])dnl
-])dnl
+dnl # END $0($@)
+])dnl AC_DEFUN GP_CAMLIB
dnl
-dnl ####################################################################
dnl
+dnl ####################################################################
+dnl GP_CAMLIBS_WARNING
+dnl Print warning about building a non-"standard" set of camlibs.
+dnl ####################################################################
AC_DEFUN([GP_CAMLIBS_WARNING],[dnl
AC_MSG_WARN([
-# Caution: You have chosen to build a non-standard set of camlibs.
-# You may have disabled the camlib required for your camera, or
-# enabled a camlib that does *not* work, and overrides the camlib
-# that does work. Consequently,
-# YOUR CAMERA MAY NOT WORK!
-#
-# Many cameras of several brands are supported by a camlib with a
-# name different from the name of the camera brand or model. If you
-# are unsure, please
-# * enable at least the "ptp2" camlib
-# * or even better, just build "all" camlibs.
+ #=====================================================================#
+ # Caution: You have chosen to build a non-standard set of camlibs. #
+ # You may have disabled the camlib required for your camera, #
+ # or enabled a camlib which does *not* work and overrides #
+ # the camlib which *does* work. Consequently, #
+ # YOUR CAMERA MAY NOT WORK! #
+ # #
+ # Many cameras of several brands are supported by a camlib with a #
+ # name different from the name of the camera brand or model. If you #
+ # are unsure, please #
+ # * enable at least the 'ptp2' camlib #
+ # * or even better, just build the standard set of camlibs. #
+ #=====================================================================#
])
-sleep 2
+sleep 5
])
dnl
+dnl
dnl ####################################################################
+dnl GP_CAMLIBS_CONDITIONAL_WARNING
+dnl Call GP_CAMLIBS_WARNING when required.
+dnl ####################################################################
+AC_DEFUN([GP_CAMLIBS_CONDITIONAL_WARNING], [dnl
+AS_VAR_IF([gp_sh_with_camlibs], [standard], [dnl
+], [dnl
+GP_CAMLIBS_WARNING
+])
+])dnl
dnl
+dnl
+dnl ####################################################################
+dnl GP_CAMLIBS_DEFINE
+dnl Determine the set of camlibs to build from the --with-camlibs
+dnl parameter, and set the build variables accordingly.
+dnl ####################################################################
AC_DEFUN([GP_CAMLIBS_DEFINE],[dnl
-AC_REQUIRE([GP_CAMLIBS_INIT])dnl
-m4_pattern_allow([m4_strip])dnl
-m4_ifval([$1],[m4_define([gp_camlib_srcdir],[$1])])dnl
-dnl for camlib in m4_strip(gp_camlibs) m4_strip(gp_camlibs_unlisted)
-dnl do
-dnl if test -d "$srcdir/m4_strip(gp_camlib_srcdir)/$camlib"; then :; else
-dnl AC_MSG_ERROR([
-dnl * Fatal:
-dnl * Source subdirectory for camlib \`$camlib' not found in
-dnl * directory \`$srcdir/m4_strip(gp_camlib_srcdir)/'
-dnl ])
-dnl fi
-dnl done
-AC_MSG_CHECKING([which camlibs to compile])
+# BEGIN $0($@)
+AC_REQUIRE([_GP_CAMLIBS_INIT])dnl
+AC_REQUIRE([GP_PROG_EXPR])dnl
+
+dnl GP_SET_MSG([camlib-set-standard])
+dnl GP_SET_MSG([camlib-set-outdated])
+dnl GP_SET_MSG([camlib-set-unlisted])
+
+dnl Convert sets defined at m4 time (i.e. autoreconf time)
+dnl into the same format as the sh time (i.e. configure time)
+dnl defined sets.
+m4_foreach_w([var], [everything standard outdated unlisted], [dnl
+GP_SET_DEFINE([m4-camlib-set-]var)
+GP_SET_ADD_ALL([m4-camlib-set-]var[]m4_set_listc([gp_m4s_camlib_set_]var))
+])dnl
+
+dnl GP_SET_MSG([m4-camlib-set-standard])
+dnl GP_SET_MSG([m4-camlib-set-unlisted])
+dnl GP_SET_MSG([m4-camlib-set-outdated])
+
+GP_SET_DEFINE([camlib-set-everything])dnl
+GP_SET_UNION([camlib-set-everything], [camlib-set-standard], [camlib-set-outdated], [camlib-set-unlisted])
+
+dnl GP_SET_MSG([camlib-set-everything])
+dnl GP_SET_MSG([m4-camlib-set-everything])
+
dnl Yes, that help output won't be all that pretty, but we at least
dnl do not have to edit it by hand.
AC_ARG_WITH([camlibs],[AS_HELP_STRING(
[--with-camlibs=<list>],
[Compile camera drivers (camlibs) in <list>. ]dnl
- [Drivers may be separated with commas. ]dnl
+ [Camlibs may be separated with commas. ]dnl
[CAUTION: DRIVER NAMES AND CAMERA NAMES MAY DIFFER. ]dnl
- ['all' is the default and compiles all camlibs, ]dnl
- ['outdated' compiles additional camlibs for very old cameras. ]dnl
- [Possible camlibs to specify are: ]dnl
- m4_strip(gp_camlibs)
- [Camlibs for very old (>10 years) cameras: ]dnl
- m4_strip(gp_camlibs_outdated))]dnl
-,
- [camlibs="$withval"],
- [camlibs="all"])dnl
-dnl
-ALL_DEFINED_CAMLIBS="m4_strip(gp_camlibs) m4_strip(gp_camlibs_outdated) m4_strip(gp_camlibs_unlisted)"
-ALL_DEFAULT_CAMLIBS="m4_strip(gp_camlibs)"
-BUILD_THESE_CAMLIBS_BASE=""
-INSTALL_THESE_CAMLIBS_BASE=""
-if test "$camlibs" = "all"; then
- INSTALL_THESE_CAMLIBS_BASE="$ALL_DEFAULT_CAMLIBS"
- AC_MSG_RESULT([all])
-else
- # If the string starts with "all,", we start with the default list
- # and add the explicitly defined ones later
- if echo "$camlibs" | grep "^all," > /dev/null; then
- INSTALL_THESE_CAMLIBS_BASE="$ALL_DEFAULT_CAMLIBS"
- camlibs="$(echo "$camlibs" | sed 's/^all,//')"
- fi
- if echo "$camlibs" | grep "outdated" > /dev/null; then
- INSTALL_THESE_CAMLIBS_BASE="$INSTALL_THESE_CAMLIBS_BASE m4_strip(gp_camlibs_outdated)"
- camlibs="$(echo "$camlibs" | sed 's/outdated[,]*//')"
- fi
-
- # camlibs=$(echo $camlibs | sed 's/,/ /g')
- IFS_save="$IFS"
- IFS=",$IFS"
- # Walk through enumeration of camlibs given by user and add them to list
- # of camlibs to build if we know them.
- for camlib in ${camlibs}; do
- IFS="$IFS_save"
- found=false
- for from_all_camlib in ${ALL_DEFINED_CAMLIBS}; do
- if test "$camlib" = "$from_all_camlib"; then
- if test "x$INSTALL_THESE_CAMLIBS_BASE" = "x"; then
- INSTALL_THESE_CAMLIBS_BASE="$camlib"
- else
- INSTALL_THESE_CAMLIBS_BASE="$INSTALL_THESE_CAMLIBS_BASE $camlib"
- fi
- found=:
- break
- fi
- done
- if $found; then :; else
- AC_MSG_ERROR([Unknown camlib $camlib!])
- fi
- done
- if test "x$INSTALL_THESE_CAMLIBS_BASE" = "xcanon" ; then
- # Gentoo mode... if user just said "canon", add "ptp2" ... should save support requests.
- INSTALL_THESE_CAMLIBS_BASE="$INSTALL_THESE_CAMLIBS_BASE ptp2"
- camlibs="$camlibs ptp2"
- AC_MSG_WARN([
- "You have just selected the old canon driver. However most current Canons\n"
- "are supported by the PTP2 driver.\n"
- "Autoselecting ptp2 driver too to avoid support requests.\n"
- ])
- fi
- IFS="$IFS_save"
- AC_MSG_RESULT([$camlibs])
- GP_CAMLIBS_WARNING
- AC_DEFINE_UNQUOTED([INCOMPLETE_CAMLIB_SET], ["$INSTALL_THESE_CAMLIBS_BASE"],
- [Whether the set of camlibs built is incomplete])
-fi
-BUILD_THESE_CAMLIBS=""
-for f in $ALL_DEFINED_CAMLIBS
+ ['standard' is the default is a standard set of camlibs: ]dnl
+ m4_set_contents(gp_m4s_camlib_set_standard, [ ]).
+ ['outdated' is a set of camlibs for very old cameras: ]dnl
+ m4_set_contents(gp_m4s_camlib_set_outdated, [ ]).dnl
+ [You can add or remove camlibs or named camlib sets by adding ]dnl
+ [them to the list with a + or - sign in front.])],
+ [gp_sh_with_camlibs="${withval}"],
+ [gp_sh_with_camlibs="standard"])dnl
+
+dnl For backwards compatibility, accept --with-camlibs='all' and
+dnl interpret it as --with-camlibs='standard'.
+AS_VAR_IF([gp_sh_with_camlibs], [all], [dnl
+ gp_sh_with_camlibs="standard"
+])dnl
+
+dnl Gentoo mode... if user just requested "canon",
+dnl add "ptp2" to save support requests.
+AS_VAR_IF([gp_sh_with_camlibs], [canon], [dnl
+ gp_sh_with_camlibs="${gp_sh_with_camlibs} ptp2"
+ AC_MSG_WARN([
+
+ #==============================================================#
+ # You have selected only the old 'canon' driver. However, most #
+ # current Canon camera models require the 'ptp2' driver. #
+ # #
+ # Autoselecting the 'ptp2' driver in addition to the 'canon' #
+ # driver to prevent unnecessary support requests. #
+ #==============================================================#
+ sleep 5
+])])dnl
+
+dnl set -x
+
+AC_MSG_CHECKING([with-camlibs requested])
+AS_VAR_IF([gp_sh_with_camlibs], [standard], [dnl
+ AC_MSG_RESULT([standard set])
+], [dnl
+ gp_sh_with_camlibs="$(echo "${gp_sh_with_camlibs}" | ${TR} ',' ' ')"
+ AC_MSG_RESULT([${gp_sh_with_camlibs}])
+])
+
+dnl AC_MSG_CHECKING([for nothing])
+dnl AC_MSG_RESULT([nihil])
+
+dnl Iterate over the list of given camlibs.
+dnl
+dnl Replace 'standard', 'outdated', 'unlisted', and 'everything' with
+dnl the respective set of camlibs, and make sure any camlibs specified
+dnl explicitly are actually valid defined camlibs.
+GP_SET_DEFINE([m4-camlib-set])
+GP_SET_DEFINE([camlib-set])
+for gp_camlib in ${gp_sh_with_camlibs}
do
- BUILD_THESE_CAMLIBS="${BUILD_THESE_CAMLIBS}${BUILD_THESE_CAMLIBS+ }${f}.la"
+ operator="add"
+ case "X$gp_camlib" in #(
+ X-*)
+ operator=remove
+ gp_camlib="$(echo "Y${gp_camlib}" | ${SED} 's/^Y.//')"
+ ;; #(
+ X+*)
+ gp_camlib="$(echo "Y${gp_camlib}" | ${SED} 's/^Y.//')"
+ ;;
+ esac
+ dnl AC_MSG_CHECKING([with-camlibs operator])
+ dnl AC_MSG_RESULT([${operator}])
+ dnl AC_MSG_CHECKING([with-camlibs camlib])
+ dnl AC_MSG_RESULT([${gp_camlib}])
+
+ dnl Convert deprecated "all" parameter to "standard".
+ case "$gp_camlib" in #(
+ all)
+ AC_MSG_WARN([
+
+ #==================================================================#
+ # You have called the configure script with the --with-camlibs=all #
+ # parameter. The name 'all' is a deprecated name for the #
+ # 'standard' camlib set. #
+ # #
+ # Please change your call to the configure script to use #
+ # --with-camlibs=standard instead. #
+ #==================================================================#
+])
+ sleep 5
+ gp_camlib="standard"
+ ;;
+ esac
+
+ dnl Now gp_camlib contains the camlib string, and operator 'add' or 'remove'.
+ case "$operator" in #(
+ add)
+ case "$gp_camlib" in #(
+ standard)
+ GP_SET_UNION([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-standard])
+ GP_SET_UNION([camlib-set], [camlib-set], [camlib-set-standard])
+ ;; #(
+ outdated)
+ GP_SET_UNION([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-outdated])
+ GP_SET_UNION([camlib-set], [camlib-set], [camlib-set-outdated])
+ ;; #(
+ unlisted)
+ GP_SET_UNION([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-unlisted])
+ GP_SET_UNION([camlib-set], [camlib-set], [camlib-set-unlisted])
+ ;; #(
+ everything)
+ GP_SET_UNION([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-everything])
+ GP_SET_UNION([camlib-set], [camlib-set], [camlib-set-everything])
+ ;; #(
+ *)
+ GP_SET_CONTAINS_IFELSE([m4-camlib-set-everything], ["${gp_camlib}"], [dnl
+ GP_SET_ADD([m4-camlib-set], ["$gp_camlib"])
+ GP_SET_ADD([camlib-set], ["$gp_camlib"])
+ ], [dnl
+ AC_MSG_ERROR([Unknown camlib found in --with-camlibs: '${gp_camlib}'])
+ ])
+ ;;
+ esac
+ ;; #(
+ remove)
+ case "$gp_camlib" in #(
+ standard)
+ GP_SET_DIFFERENCE([camlib-set], [camlib-set], [camlib-set-standard])
+ GP_SET_DIFFERENCE([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-standard])
+ ;; #(
+ outdated)
+ GP_SET_DIFFERENCE([camlib-set], [camlib-set], [camlib-set-outdated])
+ GP_SET_DIFFERENCE([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-outdated])
+ ;; #(
+ unlisted)
+ GP_SET_DIFFERENCE([camlib-set], [camlib-set], [camlib-set-unlisted])
+ GP_SET_DIFFERENCE([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-unlisted])
+ ;; #(
+ everything)
+ GP_SET_DIFFERENCE([camlib-set], [camlib-set], [camlib-set-everything])
+ GP_SET_DIFFERENCE([m4-camlib-set], [m4-camlib-set], [m4-camlib-set-everything])
+ ;; #(
+ *)
+ GP_SET_CONTAINS_IFELSE([m4-camlib-set-everything], ["${gp_camlib}"], [dnl
+ GP_SET_REMOVE([camlib-set], ["$gp_camlib"])
+ GP_SET_CONTAINS_IFELSE([m4-camlib-set], ["$gp_camlib"], [dnl
+ GP_SET_REMOVE([m4-camlib-set], ["$gp_camlib"])
+ ], [dnl
+ AC_MSG_WARN([Removing camlib ${gp_camlib} from m4-camlib-set which does not contain ${gp_camlib}])
+ ])
+ ], [dnl
+ AC_MSG_ERROR([Unknown camlib found in --with-camlibs: '${gp_camlib}'])
+ ])
+ ;;
+ esac
+ ;;
+ esac
done
+AS_UNSET([gp_camlib])
+AC_MSG_CHECKING([with-camlibs parsing])
+AC_MSG_RESULT([finished])
+
+dnl GP_SET_MSG([m4-camlib-set])
+dnl GP_SET_MSG([camlib-set])
+
+dnl Camlibs requested, but cannot be built.
+GP_SET_DEFINE([camlib-set-diff-skipping])
+GP_SET_DIFFERENCE([camlib-set-diff-skipping], [m4-camlib-set], [camlib-set])
+GP_SET_MSG([camlib-set-diff-skipping])
-INSTALL_THESE_CAMLIBS=""
-for f in $INSTALL_THESE_CAMLIBS_BASE
+dnl Camlibs added over the standard set
+GP_SET_DEFINE([camlib-set-diff-over-standard])
+GP_SET_DIFFERENCE([camlib-set-diff-over-standard], [camlib-set], [camlib-set-standard])
+GP_SET_MSG([camlib-set-diff-over-standard])
+
+dnl Camlibs missing from the standard set
+GP_SET_DEFINE([camlib-set-diff-from-standard])
+GP_SET_DIFFERENCE([camlib-set-diff-from-standard], [camlib-set-standard], [camlib-set])
+GP_SET_MSG([camlib-set-diff-from-standard])
+
+GP_SET_DEBUG_MSG([camlib-set-diff-skipping])
+GP_SET_DEBUG_MSG([camlib-set-diff-from-standard])
+GP_SET_DEBUG_MSG([camlib-set-diff-over-standard])
+
+GP_SET_SPACE_VAR([camlib-set-diff-skipping], [gp_camlib_set_skipping])dnl
+
+dnl We could use the cardinality of the difference sets to determine
+dnl how far we are from the standard set. If we do not differ too
+dnl much, we can still show the camlib set as "standard plus these
+dnl minus those skipping that" instead of just listing the camlib
+dnl names.
+
+dnl gp_camlibs_from_standard="$(GP_SET_CARDINALITY([camlib-set-diff-from-standard]))"
+dnl AC_MSG_CHECKING([camlibs removed from standard set])
+dnl AC_MSG_RESULT([${gp_camlibs_from_standard}])
+
+dnl gp_camlibs_over_standard="$(GP_SET_CARDINALITY([camlib-set-diff-over-standard]))"
+dnl AC_MSG_CHECKING([camlibs added over standard set])
+dnl AC_MSG_RESULT([${gp_camlibs_over_standard}])
+
+dnl gp_camlibs_non_standard="$(${EXPR} ${gp_camlibs_from_standard} + ${gp_camlibs_over_standard})"
+dnl AC_MSG_CHECKING([total number of camlibs differing from standard set])
+dnl AC_MSG_RESULT([${gp_camlibs_non_standard}])
+
+AC_MSG_CHECKING([whether skipping some requested camlibs])
+AS_IF([test "x$gp_camlib_set_skipping" = "x"], [dnl
+ AC_MSG_RESULT([no])
+], [dnl
+ AC_MSG_RESULT([yes (${gp_camlib_set_skipping})])
+ AC_DEFINE_UNQUOTED([GP_CAMLIB_SET_SKIPPING], ["${gp_camlib_set_skipping}"],
+ [If defined, the camlibs which are skipped due to missing dependencies])
+ AC_MSG_WARN([
+
+ #============================================================#
+ # We are skipping building a few requested camlibs, probably #
+ # due to missing dependencies. Check the dependencies if #
+ # you insist on building these camlibs. #
+ #============================================================#
+])
+ sleep 5
+])
+
+GP_SET_SPACE_VAR([camlib-set], [gp_camlib_set])
+AC_MSG_CHECKING([camlib set to build in detail])
+AC_MSG_RESULT([${gp_camlib_set}])
+
+GP_CAMLIBS_CONDITIONAL_WARNING
+
+dnl Whether user has requested a non-standard set of camlibs
+GP_SET_EQUAL_IFELSE([camlib-set], [camlib-set-standard], [dnl
+ AS_IF([test "x$gp_camlib_set_skipping" = "x"], [dnl
+ GP_CONFIG_MSG([Camlibs],[standard set (${gp_camlib_set})])
+ ], [dnl
+ GP_CONFIG_MSG([Camlibs],[standard set (${gp_camlib_set} SKIPPING ${gp_camlib_set_skipping})])
+ ])
+], [dnl
+ AS_IF([test "x$gp_camlib_set_skipping" = "x"], [dnl
+ GP_CONFIG_MSG([Camlibs],[non-standard set (${gp_camlib_set})])
+ ], [dnl
+ GP_CONFIG_MSG([Camlibs],[non-standard set (${gp_camlib_set} SKIPPING ${gp_camlib_set_skipping})])
+ ])
+ m4_pattern_allow([GP_CAMLIB_SET_IS_NONSTANDARD])dnl
+ AC_DEFINE_UNQUOTED([GP_CAMLIB_SET_IS_NONSTANDARD], [1],
+ [define when the camlib set to buidl is non-standard])
+])dnl
+
+m4_pattern_allow([GP_CAMLIB_SET])dnl
+AC_DEFINE_UNQUOTED([GP_CAMLIB_SET], ["${gp_camlib_set}"],
+ [The actually defined set of camlibs to build])
+
+AS_UNSET([GP_CAMLIB_SET])
+for f in ${gp_camlib_set}
do
- INSTALL_THESE_CAMLIBS="${INSTALL_THESE_CAMLIBS}${INSTALL_THESE_CAMLIBS+ }${f}.la"
+ GP_CAMLIB_SET="${GP_CAMLIB_SET}${GP_CAMLIB_SET+ }${f}.la"
done
-AC_SUBST([BUILD_THESE_CAMLIBS])
-AC_SUBST([INSTALL_THESE_CAMLIBS])
-AC_SUBST([ALL_DEFINED_CAMLIBS])
-AC_SUBST([ALL_DEFAULT_CAMLIBS])
+AS_UNSET([f])
+AC_SUBST([GP_CAMLIB_SET])
+
+m4_pattern_allow([GP_CAMLIB_SET_EVERYTHING])dnl
+AC_SUBST([GP_CAMLIB_SET_EVERYTHING],
+ ["m4_set_contents([gp_m4s_camlib_set_everything], [ ])"])
+
+# END $0($@)
])dnl
dnl
+dnl
dnl ####################################################################
dnl
dnl Local Variables:
diff --git a/gphoto-m4/gp-progs.m4 b/gphoto-m4/gp-progs.m4
new file mode 100644
index 000000000..2a0df6f3a
--- /dev/null
+++ b/gphoto-m4/gp-progs.m4
@@ -0,0 +1,96 @@
+dnl ####################################################################
+dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl ####################################################################
+m4_pattern_forbid([GP_PROG_CMP])dnl
+AC_DEFUN_ONCE([GP_PROG_CMP],[dnl
+AC_ARG_VAR([CMP], [cmp file comparison command])dnl
+AC_PATH_PROG([CMP], [cmp])dnl
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl ####################################################################
+m4_pattern_forbid([GP_PROG_COMM])dnl
+AC_DEFUN_ONCE([GP_PROG_COMM],[dnl
+AC_ARG_VAR([COMM], [comm line by line comparison command])dnl
+AC_PATH_PROG([COMM], [comm])dnl
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl ####################################################################
+m4_pattern_forbid([GP_PROG_DIFF])dnl
+AC_DEFUN_ONCE([GP_PROG_DIFF],[dnl
+AC_ARG_VAR([DIFF], [diff file comparison command])dnl
+AC_PATH_PROG([DIFF], [diff])dnl
+dnl
+dnl DIFF_MAYBE_U only contains -u for readability, so if diff does not
+dnl support -u, we can still just run DIFF without -u.
+AC_MSG_CHECKING([whether DIFF supports -u])
+:>gp-empty-file-a
+:>gp-empty-file-b
+AS_IF([diff -u gp-empty-file-a gp-empty-file-b], [dnl
+ AC_MSG_RESULT([yes])
+ DIFF_MAYBE_U="${DIFF} -u"
+], [dnl
+ AC_MSG_RESULT([no])
+ DIFF_MAYBE_U="${DIFF}"
+])
+rm -f gp-empty-file-a gp-empty-file-b
+AC_SUBST([DIFF_MAYBE_U])
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl ####################################################################
+m4_pattern_forbid([GP_PROG_EXPR])dnl
+AC_DEFUN_ONCE([GP_PROG_EXPR],[dnl
+AC_ARG_VAR([EXPR], [expr expression evaluation command])dnl
+AC_PATH_PROG([EXPR], [expr])dnl
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl ####################################################################
+m4_pattern_forbid([GP_PROG_SORT])dnl
+AC_DEFUN_ONCE([GP_PROG_SORT],[dnl
+AC_ARG_VAR([SORT], [sort text file line sorting command])dnl
+AC_PATH_PROG([SORT], [sort])dnl
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl ####################################################################
+m4_pattern_forbid([^GP_PROG_TR\(])dnl
+m4_pattern_forbid([^GP_PROG_TR$])dnl
+AC_DEFUN_ONCE([GP_PROG_TR],[dnl
+AC_ARG_VAR([TR], [tr string character translation command])dnl
+AC_PATH_PROG([TR], [tr])dnl
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl ####################################################################
+m4_pattern_forbid([^GP_PROG_UNIQ\(])dnl
+m4_pattern_forbid([^GP_PROG_UNIQ$])dnl
+AC_DEFUN_ONCE([GP_PROG_UNIQ],[dnl
+AC_ARG_VAR([UNIQ], [uniq sorted file uniquification command])dnl
+AC_PATH_PROG([UNIQ], [uniq])dnl
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl End:
diff --git a/gphoto-m4/gp-set.m4 b/gphoto-m4/gp-set.m4
new file mode 100644
index 000000000..0168a263d
--- /dev/null
+++ b/gphoto-m4/gp-set.m4
@@ -0,0 +1,725 @@
+dnl ######################################################################
+dnl Set operations using shell
+dnl ######################################################################
+dnl
+dnl This implements a set of set operations ('set' in the sense of
+dnl 'set theory') as shell code for use at configure time. At m4 time
+dnl (aka autoreconf time), there already exists a set of m4_set_*
+dnl macros, but we cannot use those for user specified and
+dnl autodetected changes at configure time.
+dnl
+dnl Not all set operations are implemented, but a few basic ones we
+dnl need for gp-camlibs.m4 are.
+dnl
+dnl * Basic definitions:
+dnl
+dnl * GP_SET_DEFINE
+dnl * GP_SET_UNDEFINE
+dnl
+dnl * Operations on sets:
+dnl
+dnl * GP_SET_ADD
+dnl * GP_SET_ADD_ALL
+dnl * GP_SET_REMOVE
+dnl
+dnl * GP_SET_CARDINALITY
+dnl * GP_SET_DIFFERENCE
+dnl * GP_SET_UNION
+dnl
+dnl * GP_SET_FOREACH
+dnl
+dnl * Conditionals:
+dnl
+dnl * GP_SET_CONTAINS_IFELSE
+dnl * GP_SET_EMPTY_IFELSE
+dnl * GP_SET_EQUAL_IFELSE
+dnl
+dnl * GP_SET_CLEAN_FILES
+dnl
+dnl * Internals and debugging help:
+dnl
+dnl * GP_SET_CANONICALIZE
+dnl * GP_SET_DUMP_ALL
+dnl * GP_SET_TESTSUITE
+dnl
+dnl * Fill shell variables with set contents:
+dnl
+dnl * GP_SET_DEBUG_VAR
+dnl * GP_SET_SPACE_VAR
+dnl
+dnl * Output AC_MSG_* for GP_SET_* sets:
+dnl
+dnl * GP_SET_DEBUG_MSG
+dnl * GP_SET_MSG_DEBUG_RESULT
+dnl
+dnl * GP_SET_SPACE_MSG
+dnl * GP_SET_MSG_SPACE_RESULT
+dnl
+dnl ######################################################################
+dnl Remarks on usage and implementation of GP_SET_*
+dnl
+dnl * Sets are stored in text files, one element per line. An empty
+dnl file is an empty set, and empty lines mean empty elements.
+dnl Non-empty files not ending with a newline are undefined behaviour.
+dnl
+dnl * At this time, GP_SET_* functions work with set elements
+dnl consisting of a limited set of characters, but the storage
+dnl format allows for a future code cleanup to allow for handling
+dnl more arbitrarily called elements.
+dnl
+dnl * Set names given to GP_SET_ macros must be defined at m4
+dnl (autoreconf) time, not at sh (configure) time.
+dnl
+dnl * Every set must be declared before use with GP_SET_DEFINE so we
+dnl can create an empty file for them and keep track of the name of
+dnl that file for cleaning up later.
+dnl
+dnl * Use GP_SET_CLEAN_FILES after your last set operations to remove
+dnl all left over set files.
+dnl
+dnl * Set text files may contain set elements in any order, and in
+dnl any number. There is no difference between a set text file
+dnl containing the same line seven times and one which only contains
+dnl it one time.
+dnl
+dnl * Some set operations work better or require on sorted files, so
+dnl sometimes the implementation sorts the set text files. If you
+dnl need a set text file sorted for some another reason, use
+dnl GP_SET_CANONICALIZE([set-name]).
+dnl
+dnl
+dnl ######################################################################
+dnl
+dnl FIXME: Do we need to test ${COMM} works before using it?
+dnl FIXME: Do we need a sh-based replacement for ${COMM} if it is not present?
+dnl FIXME: Abort if _DIFFERENCE is called with ${COMM} not found/not working.
+dnl FIXME: Do we need to stop using shell functions?
+dnl
+dnl
+dnl ######################################################################
+dnl Try catching unexpanded macros in the output.
+dnl ######################################################################
+m4_pattern_forbid([GP_SET_])dnl
+m4_pattern_forbid([_GP_SET_])dnl
+m4_pattern_allow([GP_SET_EOF])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_INIT
+dnl Called internally before any set operation.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_INIT], [dnl
+AC_REQUIRE([AC_PROG_GREP])dnl
+AC_REQUIRE([GP_PROG_COMM])dnl
+AC_REQUIRE([GP_PROG_SORT])dnl
+AC_REQUIRE([GP_PROG_UNIQ])dnl
+m4_set_empty([gp_set_all_sets], [], [dnl
+ m4_set_foreach([gp_set_all_sets], [elt], [dnl
+ m4_errprintn(__file__: __line__:[ Set gp_set_all_sets contains element ]elt)dnl
+ ])dnl
+ m4_errprintn(__file__:__line__:[ Error: gp_set_all_sets already defined])dnl
+ dnl m4_exit(1)dnl
+])dnl
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_FILENAME([set_name])
+dnl _GP_SET_FILENAME([set_name], [extra-extension])
+dnl Convert set name to set file name. If present, add the given
+dnl extra-extension to the file name in some position.
+dnl ######################################################################
+AC_DEFUN([_GP_SET_FILENAME], [dnl
+[gp-set-file--][$1]m4_if([$2],[],[],[.$2])])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_CHECK_INIT
+dnl Implement the gp_set_shfn_check() shell function which checks that the
+dnl given set exists and is in general working order.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_CHECK_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+gp_set_shfn_check ()
+{
+ if test -f "[$]1"; then :; else
+ AC_MSG_ERROR(["Error: set [$]1 has not been defined yet"])
+ fi
+} # gp_set_shfn_check
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_CHECK([set_name])
+dnl Check that the given set exists and is in general working order.
+dnl Works by calling the gp_set_shfn_check() shell function.
+dnl ######################################################################
+AC_DEFUN([_GP_SET_CHECK], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_CHECK_INIT])dnl
+gp_set_shfn_check "_GP_SET_FILENAME([$1])"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_DUMP_ALL
+dnl Dump all sets to stdout. Intended for helping with debugging.
+dnl ######################################################################
+AC_DEFUN([GP_SET_DUMP_ALL], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+for setfile in gp-set-file--*
+do
+ AS_ECHO(["Set file: ${setfile}"])
+ ${SED} 's/^/ * <</; s/$/>>/' "${setfile}"
+done
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_DEFINE([set_name])
+dnl Declare a set of given name, initializing it to an empty set.
+dnl Not a shell function, as the emitted shell code is shorter than
+dnl calling a shell function.
+dnl ######################################################################
+AC_DEFUN([GP_SET_DEFINE], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+m4_set_add([gp_set_all_sets], [$1])dnl
+: > "_GP_SET_FILENAME([$1])"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_UNDEFINE([set_name])
+dnl Undefine a set of given name, removing its file.
+dnl Not a shell function, as the emitted shell code is shorter than
+dnl calling a shell function.
+dnl ######################################################################
+AC_DEFUN([GP_SET_UNDEFINE], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+_GP_SET_CHECK([$1])dnl
+rm -f "_GP_SET_FILENAME([$1])"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_ADD_INIT
+dnl Implement the gp_set_shfn_set_add() shell function which adds a given
+dnl element to a given set.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_ADD_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_CHECK_INIT])dnl
+gp_set_shfn_set_add ()
+{
+ gp_set_shfn_check "[$]1"
+ AS_ECHO(["[$]2"]) >> "[$]1"
+} # gp_set_shfn_set_add
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_ADD([set_name], [element])
+dnl Add the given element to the given set. Implemented by calling the
+dnl gp_set_shfn_set_add() shell function.
+dnl Note: Unlike m4_set_add, this does not handle IF-UNIQ and IF-DUP
+dnl macro parameters.
+dnl ######################################################################
+AC_DEFUN([GP_SET_ADD], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_ADD_INIT])dnl
+gp_set_shfn_set_add "_GP_SET_FILENAME([$1])" "$2"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_ADD_ALL([set_name], [element]...)
+dnl Add the given elements to the given set, similar to m4_set_add_all.
+dnl This can be very useful for initializing a GP_SET_* set from a
+dnl m4_set_* in one go.
+dnl Not a shell function, as the emitted shell code is shorter than
+dnl calling a shell function.
+dnl ######################################################################
+AC_DEFUN([GP_SET_ADD_ALL], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+_GP_SET_CHECK([$1])dnl
+cat>>"_GP_SET_FILENAME([$1])"<<_GP_EOF
+m4_foreach([myvar], [m4_shift($@)], [dnl
+myvar
+])dnl
+_GP_EOF
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_REMOVE_INIT
+dnl Implement the gp_set_shfn_remove() shell function removing a given
+dnl element from a given set.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_REMOVE_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+gp_set_shfn_remove ()
+{
+ gp_set_shfn_check "[$]1"
+ ${GREP} -v "^[$]2$" < "[$]1" > "[$]1.tmp"
+ mv -f "[$]1.tmp" "[$]1"
+} # gp_set_shfn_remove
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_REMOVE([set_name], [element])
+dnl Remove a given element from a given set.
+dnl Calls the gp_set_shfn_remove() shell function for the actual work.
+dnl ######################################################################
+AC_DEFUN([GP_SET_REMOVE], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_REMOVE_INIT])dnl
+gp_set_shfn_remove "_GP_SET_FILENAME([$1])" "$2"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_UNION_INIT
+dnl Define the gp_set_shfn_union() shell function which defines a
+dnl result set as the union of 0 or more sets.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_UNION_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+dnl This functions uses the shell builtin 'shift', so it needs to store
+dnl the original $1 in a local variable.
+gp_set_shfn_union ()
+{
+ local result_fname="[$]1"
+ gp_set_shfn_check "[$]result_fname"
+ if shift; then
+ cat "[$]@" > "[$]{result_fname}.tmp"
+ mv -f "[$]{result_fname}.tmp" "[$]{result_fname}"
+ fi
+} # gp_set_shfn_union
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_UNION([result_set], [setname]...)
+dnl Define result_set as the union of 0 or more setnames.
+dnl Calls the gp_set_shfn_union() shell function for the actual work.
+dnl ######################################################################
+AC_DEFUN([GP_SET_UNION], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_UNION_INIT])dnl
+m4_set_add([gp_set_all_sets], [$1])dnl
+gp_set_shfn_union m4_foreach([setname], [$@], [ "_GP_SET_FILENAME(setname)"])
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_DIFFERENCE_INIT([result_set_fname], [set_fname]...)
+dnl This uses comm(1), which is a POSIX command. We can always
+dnl re-implement comm(1) with a lot of speed penalties in a bunch
+dnl of nested sh loops if we run into a system which does not have
+dnl comm(1) installed.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_DIFFERENCE_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_CHECK_INIT])dnl
+AC_REQUIRE([_GP_SET_CANONICALIZE_INIT])dnl
+dnl This functions uses the shell builtin 'shift', so it needs to store
+dnl the original $1 and $2 in local variables.
+gp_set_shfn_difference ()
+{
+ local result_fname="[$]1"
+ gp_set_shfn_check "[$]result_fname"
+ if shift; then
+ gp_set_shfn_canonicalize "[$]1"
+ cat "[$]1" > "[$]result_fname"
+ if shift; then
+ for gp_s
+ do
+ gp_set_shfn_canonicalize "[$]gp_s"
+ ${COMM} -23 "[$]{result_fname}" "[$]gp_s" > "[$]{result_fname}.tmp"
+ mv -f "[$]{result_fname}.tmp" "[$]{result_fname}"
+ done
+ fi
+ fi
+} # gp_set_shfn_difference
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_DIFFERENCE([result_set], [setname]...)
+dnl Define result_set as the first setname with the element of all
+dnl the other sets removed from it.
+dnl ######################################################################
+AC_DEFUN([GP_SET_DIFFERENCE], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_DIFFERENCE_INIT])dnl
+m4_set_add([gp_set_all_sets], [$1])dnl
+gp_set_shfn_difference m4_foreach([setname], [$@], [ "_GP_SET_FILENAME(setname)"])
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_CARDINALITY_INIT
+dnl Define gp_set_shfn_cardinality() shell function which writes
+dnl set cardinality to stdout.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_CARDINALITY_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+gp_set_shfn_cardinality ()
+{
+ gp_set_shfn_check "[$]1"
+ wc -l < "[$]1"
+} # gp_set_shfn_cardinality
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_CARDINALITY([set_name])
+dnl Write set cardinality to stdout.
+dnl ######################################################################
+AC_DEFUN([GP_SET_CARDINALITY], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_CARDINALITY_INIT])dnl
+gp_set_shfn_cardinality "_GP_SET_FILENAME([$1])"])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_EMPTY_IFELSE([set_name], [if-empty], [if-not-empty])
+dnl Run if-empty block or if-not-empty block, depending on whether
+dnl the named set is empty or not.
+dnl ######################################################################
+AC_DEFUN([GP_SET_EMPTY_IFELSE], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+_GP_SET_CHECK([$1])dnl
+AS_IF([test "0" -eq "$(wc -l < "_GP_SET_FILENAME([$1])")"], m4_shift($@))
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_EQUAL_IFELSE([set_a], [set_b], [if-equal], [if-not-equal])
+dnl When set_a and set_b are equal, run the if-equal block. Otherwise,
+dnl run the if-not-equal block.
+dnl ######################################################################
+AC_DEFUN([GP_SET_EQUAL_IFELSE], [dnl
+gp_set_shfn_canonicalize "_GP_SET_FILENAME([$1])"
+gp_set_shfn_canonicalize "_GP_SET_FILENAME([$2])"
+AS_IF([${CMP} "_GP_SET_FILENAME([$1])" "_GP_SET_FILENAME([$2])" > /dev/null 2>&1],
+ m4_shift2($@))
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_CONTAINS_IFELSE([set_name], [element], [yes-block], [no-block])
+dnl If set_name contains element, run the yes-block. Otherwise,
+dnl run the no-block.
+dnl ######################################################################
+AC_DEFUN([GP_SET_CONTAINS_IFELSE], [dnl
+_GP_SET_CHECK([$1])dnl
+AS_IF([test "0" -lt "$(${GREP} -c "^$2\$" < "_GP_SET_FILENAME([$1])")"],
+ m4_shift2($@))
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_DEBUG_VAR_INIT
+dnl Define gp_set_shfn_debug_var() shell function which sets a shell
+dnl variable to a string representing a human readable form for of
+dnl the given set.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_DEBUG_VAR_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+gp_set_shfn_debug_var ()
+{
+ gp_set_shfn_check "[$]1"
+ gp_set_shfn_canonicalize "[$]1"
+ local element
+ local gp_set_is_first=:
+ local gp_set_saved_ifs="$IFS"
+ IFS=""
+ while read element
+ do
+ if "$gp_set_is_first"
+ then
+ eval "[$]2=\"{ \""
+ gp_set_is_first=false
+ else
+ eval "[$]2=\"\${[$]2}, \""
+ fi
+ if test "x$element" = "x"
+ then
+ eval "[$]2=\"\${[$]2}''\""
+ else
+ eval "[$]2=\"\${[$]2}'\$element'\""
+ fi
+ done < "[$]1"
+ IFS="$gp_set_saved_ifs"
+ if "$gp_set_is_first"
+ then
+ eval "[$]2=\"{ }\""
+ else
+ eval "[$]2=\"\${[$]2} }\""
+ fi
+} # gp_set_shfn_debug_var
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_DEBUG_VAR([set_name], [shell_var_name])
+dnl Set shell variable shell_var_name to a string representing a human
+dnl readable for of the given set.
+dnl ######################################################################
+AC_DEFUN([GP_SET_DEBUG_VAR], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_DEBUG_VAR_INIT])dnl
+gp_set_shfn_debug_var "_GP_SET_FILENAME([$1])" "$2"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_DEBUG_MSG([set-name])
+dnl For a given set, expand to a simple pair of AC_MSG_CHECKING and
+dnl AC_MSG_RESULT showing the GP_SET_DEBUG_VAR, mostly to help with
+dnl debugging.
+dnl ######################################################################
+AC_DEFUN([GP_SET_DEBUG_MSG], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_MSG_CHECKING([value of set ]$1)
+GP_SET_MSG_DEBUG_RESULT([$1])
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_SPACE_MSG([set-name])
+dnl For a given set, expand to a simple pair of AC_MSG_CHECKING and
+dnl AC_MSG_RESULT showing the GP_SET_SPACE_VAR, both to help with
+dnl debugging gp-set.m4 and possibly for produnction use.
+dnl ######################################################################
+AC_DEFUN([GP_SET_MSG], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_MSG_CHECKING([value of set ]$1)
+GP_SET_MSG_RESULT([$1])
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_SPACE_VAR([set-name], [var-name])
+dnl ######################################################################
+AC_DEFUN([GP_SET_SPACE_VAR], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+$2=""
+GP_SET_FOREACH([$1], [element], [dnl
+AS_IF([test "x[$]$2" = "x"], [dnl
+ $2="[$]element"
+], [dnl
+ $2="[$]$2 [$]element"
+])
+])
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_MSG_RESULT([set-name])
+dnl Shortcut for setting a shell variable to a space separated list of
+dnl elements, and then expanding to AC_MSG_RESULT([$shellvar]).
+dnl ######################################################################
+AC_DEFUN([GP_SET_MSG_RESULT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+GP_SET_SPACE_VAR([$1], [gp_set_msg_result_var])dnl
+AC_MSG_RESULT([${gp_set_msg_result_var}])
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_MSG_DEBUG_RESULT([set-name])
+dnl Shortcut for setting a shell variable to a human readable list of
+dnl elements, and then expanding to AC_MSG_RESULT([$shellvar]).
+dnl ######################################################################
+AC_DEFUN([GP_SET_MSG_DEBUG_RESULT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+GP_SET_DEBUG_VAR([$1], [gp_set_msg_result_var])dnl
+AC_MSG_RESULT([${gp_set_msg_result_var}])
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl _GP_SET_CANONICALIZE_INIT
+dnl Implement the gp_set_shfn_canonicalize() shell function.
+dnl ######################################################################
+AC_DEFUN_ONCE([_GP_SET_CANONICALIZE_INIT], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+gp_set_shfn_canonicalize ()
+{
+ gp_set_shfn_check "[$]1"
+ { set -e
+ [$]{SORT} < "[$]1" | [$]{UNIQ} > "[$]1.tmp"
+ mv -f "[$]1.tmp" "[$]1"; }
+} # gp_set_shfn_canonicalize
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_CANONICALIZE([set_name])
+dnl Convert the set file for set_name into a canonical form.
+dnl
+dnl Implementation detail: Sorts the lines, and makes them unique.
+dnl ######################################################################
+AC_DEFUN([GP_SET_CANONICALIZE], [dnl
+AC_REQUIRE([_GP_SET_INIT])dnl
+AC_REQUIRE([_GP_SET_CANONICALIZE_INIT])dnl
+gp_set_shfn_canonicalize "_GP_SET_FILENAME([$1])"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_FOREACH([set_name], [shell-var], [shell-block])
+dnl For each element in set_name, run the shell-block with the given
+dnl shell variable set to every element in turn.
+dnl ######################################################################
+AC_DEFUN([GP_SET_FOREACH], [dnl
+_GP_SET_CHECK([$1])dnl
+gp_set_saved_ifs="$IFS"
+IFS=""
+while read $2
+do
+ IFS="$gp_set_saved_ifs"
+ $3
+done < "_GP_SET_FILENAME([$1])"
+IFS="$gp_set_saved_ifs"
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_CLEAN_FILES
+dnl Remove all the files used for storing sets. Invoke this macro near
+dnl the end of configure.ac after you have finished doing anything with
+dnl GP_SET_* sets.
+dnl ######################################################################
+AC_DEFUN([GP_SET_CLEAN_FILES], [dnl
+AC_BEFORE([_GP_SET_INIT], [$0])dnl
+AC_BEFORE([GP_SET_DEFINE], [$0])dnl
+AC_BEFORE([GP_SET_UNDEFINE], [$0])dnl
+AC_BEFORE([GP_SET_ADD], [$0])dnl
+AC_BEFORE([GP_SET_ADD_ALL], [$0])dnl
+AC_BEFORE([GP_SET_REMOVE], [$0])dnl
+AC_BEFORE([GP_SET_EMPTY_IFELSE], [$0])dnl
+AC_BEFORE([GP_SET_EQUAL_IFELSE], [$0])dnl
+AC_BEFORE([GP_SET_CONTAINS_IFELSE], [$0])dnl
+AC_BEFORE([GP_SET_DEBUG_VAR], [$0])dnl
+AC_BEFORE([GP_SET_SPACE_VAR], [$0])dnl
+dnl
+dnl GP_SET_DUMP_ALL()dnl
+dnl
+dnl m4_set_foreach([gp_set_all_sets], [set_name], [dnl
+dnl AS_ECHO(["Set defined somewhere: set_name"])
+dnl ])dnl
+dnl
+[rm -f]m4_set_foreach([gp_set_all_sets], [setname],
+ [ "_GP_SET_FILENAME(setname)"])dnl
+])dnl
+dnl
+dnl
+dnl ######################################################################
+dnl GP_SET_TESTSUITE()
+dnl Does a number of tests for the GP_SET_* macros.
+dnl
+dnl Should be mostly useful while debugging gp-set.m4 itself.
+dnl ######################################################################
+AC_DEFUN([GP_SET_TESTSUITE], [dnl
+# BEGIN $0
+_GP_SET_INIT
+
+GP_SET_DEFINE([foo])
+GP_SET_DEFINE([bar])
+GP_SET_DEFINE([foobar])
+GP_SET_DEFINE([everything])
+
+GP_SET_DEBUG_MSG([foo])
+
+GP_SET_DEFINE([bax])
+GP_SET_UNDEFINE([bax])
+
+GP_SET_UNDEFINE([bar])
+GP_SET_DEFINE([bar])
+
+dnl GP_SET_ADD([moo], [meh])
+GP_SET_ADD_ALL([everything], [foo], [bar], [bar ], [bla])
+
+GP_SET_DUMP_ALL
+
+m4_set_add_all([m4testset], [a], [b c], [d e], [f], [g])
+AC_MSG_CHECKING([for value of m4 testset])
+AC_MSG_RESULT([m4_set_contents([m4testset], [, ])])
+
+GP_SET_ADD_ALL([everything]m4_set_listc([m4testset]))
+
+GP_SET_DUMP_ALL
+
+GP_SET_ADD([foo], [barfoo])
+GP_SET_ADD([foo], [foobar])
+GP_SET_ADD([foo], [fox])
+GP_SET_ADD([foo], [fux])
+GP_SET_ADD([foo], [fox])
+GP_SET_ADD([foo], [])
+GP_SET_ADD([foo], [fox])
+GP_SET_ADD([foo], [barfoo])
+GP_SET_ADD([foo], [ barfoo])
+GP_SET_ADD([foo], ["barfoo "])
+GP_SET_ADD([foo], [])
+GP_SET_REMOVE([foo], [fox])
+GP_SET_ADD([foo], [barfoo])
+
+GP_SET_ADD([foobar], [bar])
+GP_SET_ADD([foobar], [foobar])
+GP_SET_ADD([foobar], [barfoo])
+
+GP_SET_DEBUG_MSG([foo])
+
+GP_SET_MSG([bar])
+GP_SET_MSG([foo])
+GP_SET_MSG([foobar])
+GP_SET_MSG([everything])
+
+GP_SET_DEFINE([union])
+GP_SET_UNION([union], [foo], [bar], [foobar])
+AC_MSG_CHECKING([value of union of foo bar foobar])
+GP_SET_MSG_RESULT([union])
+
+GP_SET_DEFINE([difference])
+GP_SET_DIFFERENCE([difference], [foo], [bar], [foobar])
+GP_SET_MSG([difference])
+
+AC_MSG_CHECKING([whether sets foo and bar are equal])
+GP_SET_EQUAL_IFELSE([foo], [bar], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether set foo is empty])
+GP_SET_EMPTY_IFELSE([foo], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether set bar is empty])
+GP_SET_EMPTY_IFELSE([bar], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether set foo contains element bar])
+GP_SET_CONTAINS_IFELSE([foo], [bar], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether set foobar contains element bar])
+GP_SET_CONTAINS_IFELSE([foobar], [bar], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+
+GP_SET_FOREACH([foobar], [gp_set_var], [dnl
+ AC_MSG_CHECKING([foobar element])
+ AC_MSG_RESULT([${gp_set_var}])
+])dnl
+GP_SET_FOREACH([foobar], [gp_set_var], [dnl
+ AS_ECHO([" * element ${gp_set_var}"])
+])dnl
+GP_SET_FOREACH([foobar], [gp_set_var], [echo " * ELEMENT ${gp_set_var}"])dnl
+AS_ECHO(["Moo."])
+
+GP_SET_DUMP_ALL
+# END $0
+])dnl
+dnl
+dnl
+dnl ####################################################################
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl End:
diff --git a/libgphoto2/gphoto2-version.c b/libgphoto2/gphoto2-version.c
index bacf06a34..6cf16254c 100644
--- a/libgphoto2/gphoto2-version.c
+++ b/libgphoto2/gphoto2-version.c
@@ -34,12 +34,23 @@ const char **gp_library_version(GPVersionVerbosity verbose)
static const char *shrt[] =
{
PACKAGE_VERSION,
-#ifdef INCOMPLETE_CAMLIB_SET
- "INCOMPLETE CAMLIB SET ("
- INCOMPLETE_CAMLIB_SET
+#if GP_CAMLIB_SET_IS_NONSTANDARD
+ "NON-STANDARD CAMLIB SET"
+ " ("
+ GP_CAMLIB_SET
+#ifdef GP_CAMLIB_SET_SKIPPING
+ " SKIPPING "
+ GP_CAMLIB_SET_SKIPPING
+#endif
")",
#else
- "all camlibs",
+ "standard camlibs"
+#ifdef GP_CAMLIB_SET_SKIPPING
+ " (SKIPPING "
+ GP_CAMLIB_SET_SKIPPING
+ ")"
+#endif
+ ,
#endif
#ifdef HAVE_CC
HAVE_CC,
@@ -61,12 +72,30 @@ const char **gp_library_version(GPVersionVerbosity verbose)
static const char *verb[] =
{
PACKAGE_VERSION,
-#ifdef INCOMPLETE_CAMLIB_SET
- "INCOMPLETE CAMLIB SET ("
- INCOMPLETE_CAMLIB_SET
+#if GP_CAMLIB_SET_IS_NONSTANDARD
+ "NON-STANDARD CAMLIB SET"
+#ifdef GP_CAMLIB_SET_SKIPPING
+ " SKIPPING SOME"
+#endif
+ " ("
+ GP_CAMLIB_SET
+#ifdef GP_CAMLIB_SET_SKIPPING
+ " SKIPPING "
+ GP_CAMLIB_SET_SKIPPING
+#endif
")",
#else
- "all camlibs",
+ "standard camlib set"
+#ifdef GP_CAMLIB_SET_SKIPPING
+ " SKIPPING SOME"
+#endif
+ " ("
+ GP_CAMLIB_SET
+#ifdef GP_CAMLIB_SET_SKIPPING
+ " SKIPPING "
+ GP_CAMLIB_SET_SKIPPING
+#endif
+ ")",
#endif
#ifdef HAVE_CC
HAVE_CC " (C compiler used)",