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_* macros 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 require or work better 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 * Some set GP_SET_* operations are implemented using shell dnl functions to reduce the size of the emitted sh code. The goal dnl is for the shell functions to be as compatible with different dnl shells as possible, but if necessary, we can revert to avoiding dnl shell functions and just emitting the same sh code 40 times. dnl dnl dnl ###################################################################### dnl dnl FIXME: Do we need a sh-based replacement for ${COMM} if it is not present? 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_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/^/ * <>/' "${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 or where comm(1) does not work. 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 AC_REQUIRE([GP_PROG_COMM])dnl cat>confset_a.txt<confset_b.txt<confset_res_23.txt< confset_diff_23.txt], [dnl AS_IF([${CMP} confset_diff_23.txt confset_res_23.txt > /dev/null 2>&1], [dnl AC_MSG_RESULT([yes]) rm -f confset_a.txt confset_b.txt confset_diff_23.txt confset_res_23.txt ], [dnl AC_MSG_RESULT([no (wrong result)]) AC_MSG_ERROR([comm -23 must work for GP_SET difference calculations]) ]) ], [dnl AC_MSG_RESULT([no (does not run)]) AC_MSG_ERROR([comm -23 must work for GP_SET difference calculations]) ]) 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: