commit 03ae83d90e6836824eeaa61796608f2b62220c1d4cf9b061f2ab8b43497169e4 Author: Christian Goll Date: Wed Oct 9 13:04:34 2024 +0000 - update to 1.29.1 which increased the internal buffer in nodeattr for large cluster hostranges - removed also-check-for-python3.patch OBS-URL: https://build.opensuse.org/package/show/network:cluster/genders?expand=0&rev=33 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/Fix-Python-package-installation-use-root.patch b/Fix-Python-package-installation-use-root.patch new file mode 100644 index 0000000..eb60ddd --- /dev/null +++ b/Fix-Python-package-installation-use-root.patch @@ -0,0 +1,48 @@ +From: Egbert Eich +Date: Sat Jan 27 23:50:57 2018 +0100 +Subject: Fix Python package installation: use --root +Patch-mainline: Not yet +Git-commit: f8aa6871f9ac452134c4077d47adef28d5e8a0a1 +References: + +Python allows the use of an alternative installation directory +using the --root option. Do not code the root directory into +the --prefix and --exec-prefix paths. + +Signed-off-by: Egbert Eich +--- + src/extensions/python/Makefile.am | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) +diff --git a/src/extensions/python/Makefile.am b/src/extensions/python/Makefile.am +index 5d62ae6..86ba50d 100644 +--- a/src/extensions/python/Makefile.am ++++ b/src/extensions/python/Makefile.am +@@ -7,23 +7,21 @@ + # Use Python's distutils to make/install everything into the right place. + + # DESTDIR is usually set during make install time, not configure or +-# make time, so we work around it with the --with-extension-destdir +-# autoconf option. +- +-PYTHON_DESTDIR = @EXTENSION_DESTDIR@ ++# make time, so we work around it with a shell command. ++PYDEST=$$(test -z "${DESTDIR}" || echo "--root=${DESTDIR}") + + if WITH_PYTHON_EXTENSIONS + all: genderssetup.py libgendersmodule.c genders.py + $(PYTHON) genderssetup.py build + + install: +- $(PYTHON) genderssetup.py install --prefix=$(PYTHON_DESTDIR)$(prefix) --exec-prefix=$(PYTHON_DESTDIR)$(exec_prefix) ++ $(PYTHON) genderssetup.py install --prefix=$(prefix) --exec-prefix=$(exec_prefix) $(PYDEST) + + pure_install: +- $(PYTHON) genderssetup.py install --prefix=$(PYTHON_DESTDIR)$(prefix) --exec-prefix=$(PYTHON_DESTDIR)$(exec_prefix) ++ $(PYTHON) genderssetup.py install --prefix=$(prefix) --exec-prefix=$(exec_prefix) $(PYDEST) + + install-data-local: +- $(PYTHON) genderssetup.py install --prefix=$(PYTHON_DESTDIR)$(prefix) --exec-prefix=$(PYTHON_DESTDIR)$(exec_prefix) ++ $(PYTHON) genderssetup.py install --prefix=$(prefix) --exec-prefix=$(exec_prefix) $(PYDEST) + + clean: + rm -rf build diff --git a/Remove-PERL_DESTDIR-use-DESTDIR-instead.patch b/Remove-PERL_DESTDIR-use-DESTDIR-instead.patch new file mode 100644 index 0000000..11775bf --- /dev/null +++ b/Remove-PERL_DESTDIR-use-DESTDIR-instead.patch @@ -0,0 +1,55 @@ +From: Egbert Eich +Date: Sun Jan 28 01:06:12 2018 +0100 +Subject: Remove PERL_DESTDIR - use DESTDIR instead +Patch-mainline: Not yet +Git-commit: ecdfb6b2a5fac8510284e183dcbab6fce52a6e01 +References: + +DESTDIR is set at installation time - it should be sufficient +for our use case. + +Signed-off-by: Egbert Eich +--- + configure.ac | 5 ----- + src/extensions/perl/Libgenders/Makefile.am | 8 +------- + 2 files changed, 1 insertion(+), 12 deletions(-) +diff --git a/configure.ac b/configure.ac +index 31cb8b4..3d4199d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -157,11 +157,6 @@ AC_CHECK_HEADERS( \ + AC_GENDERS_FILE + + # +-# Check for extension stuff +-# +-AC_EXTENSION_DESTDIR +- +-# + # Check for perl stuff + # + AC_PERL_EXTENSIONS +diff --git a/src/extensions/perl/Libgenders/Makefile.am b/src/extensions/perl/Libgenders/Makefile.am +index c544df2..440cc01 100644 +--- a/src/extensions/perl/Libgenders/Makefile.am ++++ b/src/extensions/perl/Libgenders/Makefile.am +@@ -7,18 +7,12 @@ + # Use Perl's ExtUtils::MakeMaker to get autoconf/automake to install + # into the correct location + +-# DESTDIR is usually set during make install time, not configure or +-# make time, so we work around it with the --with-extension-destdir +-# autoconf option. +- +-PERL_DESTDIR = @EXTENSION_DESTDIR@ +- + PERL_INC = "-I$(srcdir)/../../../../config -I$(srcdir)/../../../libgenders" + + PERL_LIBS = "-L$(srcdir)/../../../libgenders/.libs -lgenders" + + MAKEMAKERFLAGS = INSTALLDIRS=$(PERL_ARCH_INSTALL) \ +- DESTDIR=$(PERL_DESTDIR) \ ++ DESTDIR=$(DESTDIR) \ + PREFIX=$(prefix) \ + INC=$(PERL_INC) \ + LIBS=$(PERL_LIBS) \ diff --git a/also-check-for-python3.patch b/also-check-for-python3.patch new file mode 100644 index 0000000..e60d7db --- /dev/null +++ b/also-check-for-python3.patch @@ -0,0 +1,13 @@ +Index: genders-1.27.3/configure.ac +=================================================================== +--- genders-1.27.3.orig/configure.ac ++++ genders-1.27.3/configure.ac +@@ -80,7 +80,7 @@ AM_PROG_LEX + AC_PROG_YACC + AM_CONDITIONAL(WITH_GNU_LD, test "$with_gnu_ld" = "yes") + AC_PATH_PROG([PERL], [perl]) +-AC_PATH_PROG([PYTHON], [python]) ++AC_PATH_PROG([PYTHON], [python], [python3]) + AC_PATH_PROG([POD2MAN], [pod2man], [/usr/bin/pod2man], [$PATH:/usr/perl5/bin/]) + AC_PATH_PROG([JAVAC], [javac]) + AC_PATH_PROG([JAVAH], [javah]) diff --git a/genders-1.28.1.tar.gz b/genders-1.28.1.tar.gz new file mode 100644 index 0000000..671811d --- /dev/null +++ b/genders-1.28.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ca8b4771b2bf39383a3c383d36d308fa113de5c481e16fdef9cabd643359d09 +size 1142795 diff --git a/genders-1.29.1.tar.gz b/genders-1.29.1.tar.gz new file mode 100644 index 0000000..dadfd21 --- /dev/null +++ b/genders-1.29.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42c37c53a831e007b4fd5a5596060417186724e18cbd5c9dbb3a7185144200c2 +size 1170941 diff --git a/genders.changes b/genders.changes new file mode 100644 index 0000000..a479d29 --- /dev/null +++ b/genders.changes @@ -0,0 +1,121 @@ +------------------------------------------------------------------- +Wed Oct 9 12:58:01 UTC 2024 - Christian Goll + +- update to 1.29.1 which increased the internal buffer in nodeattr for large + cluster hostranges +- removed also-check-for-python3.patch + +------------------------------------------------------------------- +Tue Dec 6 12:14:45 UTC 2022 - Dirk Müller + +- update to 1.28.1: + * Build Bindings for *both* python2 and python3 + +------------------------------------------------------------------- +Tue Dec 6 03:46:15 UTC 2022 - Steve Kowalik + +- Do not Provides/Obsoletes Python 2 packages with Python 3 ones. + +------------------------------------------------------------------- +Thu Dec 1 02:13:43 UTC 2022 - Steve Kowalik + +- Actually move Python plugin to building with Python 3, and rename the + Python binding package to reflect this. +- Add patch also-check-for-python3.patch to check for Python 3 as well. + +------------------------------------------------------------------- +Mon Jul 25 12:25:49 UTC 2022 - Christian Goll + +- remove the hard coded rpath explicitly + +------------------------------------------------------------------- +Thu Dec 19 14:19:10 UTC 2019 - Christian Goll + +- moved python plugin to python3 + +------------------------------------------------------------------- +Fri Nov 29 09:35:37 UTC 2019 - Ana Guerrero Lopez + +- Update to version 1.27.3: + * Fix parsing corner case, newlines are not required at end + of lines + * Add make target for genders_query.tab.c to fix gentoo build issue. + * javadoc fix && to & amp;& amp; + * fix testsuite to operate where there isn't a default genders file + +------------------------------------------------------------------- +Thu Jul 18 14:27:16 UTC 2019 - Christian Goll + +- updated to ver 1.26 (jsc#SLE-9949) which has faster parsing + * updated Fix-Python-package-installation-use-root.patch + * Removed Remove-all-remains-of-EXTENSION_DESTDIR.patch + as not relevant any more + +------------------------------------------------------------------- +Sat Dec 1 18:10:22 UTC 2018 - eich@suse.com + +- Fix %%license. + +------------------------------------------------------------------- +Fri Oct 19 13:45:47 UTC 2018 - cgoll@suse.com + +- Added lua binding with lua_bindings.patch + * package lua-genders cotains the bindings (FATE#326456). + +------------------------------------------------------------------- +Tue Feb 20 14:31:39 UTC 2018 - jjolly@suse.com + +- Added new package genders-base for the configuration file common + to the libraries (bsc#1081479) + * genders, libgenders, and libgendersplusplus now require + geners-base +- %install comments out sample configuration using sed + +------------------------------------------------------------------- +Thu Feb 1 11:35:21 UTC 2018 - eich@suse.com + +- Changed license to GPL-2.0+ as suggested by babelworx. + +------------------------------------------------------------------- +Thu Feb 1 00:19:45 UTC 2018 - jengelh@inai.de + +- There is already a macro for name, do not reinvent it. +- Replace old $RPM_* shell vars. +- %if blocks must surround %files because empty packages are + not allowed. + +------------------------------------------------------------------- +Wed Jan 31 13:42:28 UTC 2018 - cgoll@suse.com + +- Put the libraries to external packages + * added sample config files + * rename compat file and updated its description + +------------------------------------------------------------------- +Tue Jan 30 13:38:14 UTC 2018 - cgoll@suse.com + +- removed .la and .a files + +------------------------------------------------------------------- +Tue Jan 30 11:34:06 UTC 2018 - cgoll@suse.com + +- moved the perl and python bindings to seperate packages + +------------------------------------------------------------------- +Sun Jan 28 00:18:51 UTC 2018 - eich@suse.com + +- Fix error in SLES build: use proper --root argument with + 'python genderssetup.py ...'. With this the entire + --with-extension-destdir infrastructure becomes pointless. + The following patches remove it and make the install process + rely on the DESTDIR make macro which is used by the autotools + already: + * Fix-Python-package-installation-use-root.patch + * Remove-PERL_DESTDIR-use-DESTDIR-instead.patch + * Remove-all-remains-of-EXTENSION_DESTDIR.patch + +------------------------------------------------------------------- +Fri Dec 8 11:07:09 UTC 2017 - cgoll@suse.com + +- Needed by (FATE#324149) +- intial commit if genders version 1.22 diff --git a/genders.spec b/genders.spec new file mode 100644 index 0000000..33fe279 --- /dev/null +++ b/genders.spec @@ -0,0 +1,270 @@ +# +# spec file for package genders +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +# Check file META in sources: update so_version to (API_CURRENT - API_AGE) +%define c_api 0 +%define cpp_api 2 +%define slash_ver 1-29-1 + +Name: genders +Version: 1.29.1 +Release: 0 +Summary: Static cluster configuration database +License: GPL-2.0-or-later +Group: System/Management +Source: https://github.com/chaos/genders/archive/genders-%{slash_ver}/%{name}-%{version}.tar.gz +Patch1: Fix-Python-package-installation-use-root.patch +Patch2: Remove-PERL_DESTDIR-use-DESTDIR-instead.patch +Patch4: lua_bindings.patch +#Patch5: also-check-for-python3.patch +URL: https://github.com/chaos/genders +BuildRequires: autoconf +BuildRequires: autoconf-archive +BuildRequires: automake +BuildRequires: bison +BuildRequires: flex +BuildRequires: gcc-c++ +BuildRequires: libtool +BuildRequires: lua-devel +BuildRequires: patchelf +BuildRequires: python3-devel +BuildRequires: perl(ExtUtils::MakeMaker) +Requires: %{name}-base + +%description +Genders is a static cluster configuration database used for cluster +configuration management. It is used by a variety of tools and +scripts for management of large clusters. The genders database is +typically replicated on every node of the cluster. It describes the +layout and configuration of the cluster so that tools and scripts can +sense the variations of cluster nodes. By abstracting this information +into a plain text file, it becomes possible to change the +configuration of a cluster by modifying only one file. + +%package base +Summary: Base configuration for gender programs and libraries +Group: System/Management + +%description base +Base configuration files needed by the gender and libgender packages + +%package perl-compat +Summary: Perl compatibility Library +Group: Development/Languages/Perl + +%description -n %{name}-perl-compat +Perl genders API for the most part used exclusively by LLNL. It is compatible with earlier releases of genders. + +%package devel +Summary: Headers and development files +Group: Development/Libraries/C and C++ +Requires: %{name} = %{version} + +%description devel +genders headers and libraries files needed for development + +%package -n python3-%{name} +Summary: Python bindings for genders +Group: Development/Languages/Python +Requires: %{name} = %{version} + +%description -n python3-%{name} +Necessary files for using genders with Python. + +%package -n lua-%{name} +Summary: Lua bindings for genders +Group: Development/Languages/Lua +Requires: %{name} = %{version} +Requires: lua + +%description -n lua-%{name} +Necessary files for using genders with lua. + +%package -n perl-%{name} +Summary: Perl bindings for genders +Group: Development/Languages/Perl +Requires: %{name} = %{version} +Requires: perl-base = %{perl_version} + +%description -n perl-%{name} +Necessary files for using genders with Perl. + +%package -n lib%{name}%{c_api} +Summary: C library API for genders +Group: System/Libraries +Requires: %{name}-base + +%description -n lib%{name}%{c_api} +This package contains the library needed to run programs dynamically linked +with genders. This is the C API. + +%package -n lib%{name}plusplus%{cpp_api} +Summary: C++ library API for genders +Group: System/Libraries +Requires: %{name}-base + +%description -n lib%{name}plusplus%{cpp_api} +This package contains the library needed to run programs dynamically linked +with genders. This is the C++ API. + +%{!?_with_perl_extensions: %{!?_without_perl_extensions: %global _with_perl_extensions --with-perl-extensions}} +%{!?_with_python_extensions: %{!?_without_python_extensions: %global _with_python_extensions --with-python-extensions}} +%{!?_with_cplusplus_extensions: %{!?_without_cplusplus_extensions: %global _with_cplusplus_extensions --with-cplusplus-extensions}} + +# choose vendor arch by default +%{!?_with_perl_site_arch: %{!?_with_perl_vendor_arch: %global _with_perl_vendor_arch --with-perl-vendor-arch}} + +%if %{?_with_perl_site_arch:1}%{!?_with_perl_site_arch:0} +%define _perldir %(perl -e 'use Config; $T=$Config{installsitearch}; $P=$Config{siteprefix}; $T=~/$P\\/(.*)/; print "%{_prefix}/$1\\n"') +%endif +%if %{?_with_perl_vendor_arch:1}%{!?_with_perl_vendor_arch:0} +%define _perldir %(perl -e 'use Config; $T=$Config{installvendorarch}; $P=$Config{vendorprefix}; $T=~/$P\\/(.*)/; print "%{_prefix}/$1\\n"') +%endif + +%prep +%setup -c -q -n %{name}-%{version} +mv genders-genders-%{slash_ver}/* . +rm -r genders-genders-%{slash_ver} +%autopatch -p1 + +%build +export PYTHON=python3 +aclocal --force --install -I config +libtoolize -f -i +automake -a -f +autoconf --force +export GENDERS_LIBDIR=%{_libdir} +%configure --program-prefix=%{?_program_prefix:%{_program_prefix}} \ + %{?_with_perl_extensions} \ + %{?_without_perl_extensions} \ + %{?_with_perl_site_arch} \ + %{?_without_perl_site_arch} \ + %{?_with_perl_vendor_arch} \ + %{?_without_perl_vendor_arch} \ + %{?_with_python_extensions} \ + %{?_without_python_extensions} \ + %{?_with_cplusplus_extensions} \ + %{?_without_cplusplus_extensions} \ + --with-lua-extensions \ + --without-java-extensions \ + --disable-static + +make all #%%{?_smp_mflags} + +%install +# turn off rpath check... causes failure on libgenders library +# is a bug in perl-ExtUtils-MakeMaker +export NO_BRP_CHECK_RPATH=true + +%make_install + +find "%{buildroot}" -name .packlist -exec sed -i "s#%{buildroot}##" {} + +find "%{buildroot}" -name .packlist -exec sed -i '/BUILDROOT/d' {} + + +for file in %{buildroot}%{_prefix}/lib/genders/*.pl; do grep '#!/usr/bin/perl' $file || sed -i '1s,^,#!/usr/bin/perl\n,' $file ;done + +# remove .a files +%if %{?_with_cplusplus_extensions:1}%{!?_with_cplusplus_extensions:0} +rm -v %{buildroot}%{_libdir}/libgendersplusplus.la +%endif +rm -v %{buildroot}%{_libdir}/libgenders.la +find %{buildroot}%{_libdir}/lua -name \*.la -delete +mkdir -p %{buildroot}%{_sysconfdir} +# create sample config, but remove comments +cat > %{buildroot}%{_sysconfdir}/genders <> %{buildroot}%{_sysconfdir}/genders + +sed -i -e 's/^\([^#]\)/## \1/' %{buildroot}%{_sysconfdir}/genders +# remove rpath the hard way +brklib=$(find %{buildroot} -name Libgenders.so -print) +chmod 644 $brklib +patchelf --remove-rpath $brklib +chmod 444 $brklib + +%post -n lib%{name}plusplus%{cpp_api} -p /sbin/ldconfig + +%postun -n lib%{name}plusplus%{cpp_api} -p /sbin/ldconfig + +%post -n lib%{name}%{c_api} -p /sbin/ldconfig + +%postun -n lib%{name}%{c_api} -p /sbin/ldconfig + +%files +%defattr(-,root,root) +# It doesn't matter if the user chooses a 32bit or 64bit target. The +# packaging must work off whatever Perl is installed. +%{_mandir}/man1/* +%{_bindir}/* + +%files base +%doc README NEWS ChangeLog DISCLAIMER DISCLAIMER.UC TUTORIAL genders.sample +%license COPYING +%config(noreplace) %{_sysconfdir}/genders + +%files perl-compat +%dir %{_prefix}/lib/genders +%{_prefix}/lib/genders/* +%{_mandir}/man3/gendlib* + +%files devel +%{_includedir}/* +%{_libdir}/libgenders.so +%if %{?_with_cplusplus_extensions:1}%{!?_with_cplusplus_extensions:0} +%{_libdir}/libgendersplusplus.so +%endif +%{_mandir}/man3/genders* +%{_mandir}/man3/libgenders* + +%if %{?_with_python_extensions:1}%{!?_with_python_extensions:0} +%files -n python3-%{name} +%{_libdir}/python* +%endif + +%files -n lua-%{name} +%{_libdir}/lua + +%if %{?_with_perl_extensions:1}%{!?_with_perl_extensions:0} +%files -n perl-%{name} +%{_mandir}/man3/Libgenders* +%{_mandir}/man3/Genders* +%{_perldir}/* +%endif + +%files -n lib%{name}%{c_api} +%{_libdir}/libgenders.so.* + +%if %{?_with_cplusplus_extensions:1}%{!?_with_cplusplus_extensions:0} +%files -n lib%{name}plusplus%{cpp_api} +%{_libdir}/libgendersplusplus.so.* +%endif + +%changelog diff --git a/lua_bindings.patch b/lua_bindings.patch new file mode 100644 index 0000000..e43c90f --- /dev/null +++ b/lua_bindings.patch @@ -0,0 +1,821 @@ +From 93e668aa34d1315140349217cb39563c78b33fe2 Mon Sep 17 00:00:00 2001 +From: Christian Goll +Date: Fri, 22 Jul 2022 14:39:37 +0200 +Subject: [PATCH 1/2] added lua bindings + +--- + config/ac_lua_extensions.m4 | 21 ++ + config/x_ac_lua.m4 | 60 ++++ + configure.ac | 21 ++ + genders.spec | 110 ++++++ + src/extensions/Makefile.am | 2 +- + .../lua/GendersTest/GendersTest.lua | 134 ++++++++ + src/extensions/lua/GendersTest/testgenders | 21 ++ + src/extensions/lua/Makefile.am | 21 ++ + src/extensions/lua/genderslua.c | 322 ++++++++++++++++++ + 9 files changed, 711 insertions(+), 1 deletion(-) + create mode 100644 config/ac_lua_extensions.m4 + create mode 100644 config/x_ac_lua.m4 + create mode 100644 genders.spec + create mode 100755 src/extensions/lua/GendersTest/GendersTest.lua + create mode 100644 src/extensions/lua/GendersTest/testgenders + create mode 100644 src/extensions/lua/Makefile.am + create mode 100644 src/extensions/lua/genderslua.c + +diff --git a/config/ac_lua_extensions.m4 b/config/ac_lua_extensions.m4 +new file mode 100644 +index 0000000..9421588 +--- /dev/null ++++ b/config/ac_lua_extensions.m4 +@@ -0,0 +1,21 @@ ++ ++AC_DEFUN([AC_LUA_EXTENSIONS], ++[ ++ AC_MSG_CHECKING(for --with-lua-extensions) ++ AC_ARG_WITH(lua-extensions, ++ AC_HELP_STRING([--with-lua-extensions=], ++ [enable or disable lua extensions build]), ++ [ case "$withval" in ++ yes) ++ ac_with_lua_extensions=yes ++ ;; ++ no) ++ ac_with_lua_extensions=no ++ ;; ++ *) ++ ac_with_lua_extensions=yes ++ ;; ++ esac ] ++ ) ++ AC_MSG_RESULT(${ac_with_lua_extensions=no}) ++]) +diff --git a/config/x_ac_lua.m4 b/config/x_ac_lua.m4 +new file mode 100644 +index 0000000..2f5f587 +--- /dev/null ++++ b/config/x_ac_lua.m4 +@@ -0,0 +1,60 @@ ++##***************************************************************************** ++# AUTHOR: ++# Mark Grondona ++# ++# SYNOPSIS: ++# AC_LUA ++# ++# DESCRIPTION: ++# Check for presence of lua libs and headers ++##***************************************************************************** ++ ++ ++AC_DEFUN([X_AC_LUA], ++[ ++ x_ac_lua_pkg_name="lua" ++ #check for 5.3 then 5.2 then 5.1 ++ PKG_CHECK_EXISTS([lua5.3], [x_ac_lua_pkg_name=lua5.3], ++ [PKG_CHECK_EXISTS([lua-5.3], [x_ac_lua_pkg_name=lua-5.3], ++ [PKG_CHECK_EXISTS([lua5.2], [x_ac_lua_pkg_name=lua5.2], ++ [PKG_CHECK_EXISTS([lua-5.2], [x_ac_lua_pkg_name=lua-5.2], ++ [PKG_CHECK_EXISTS([lua5.1], [x_ac_lua_pkg_name=lua5.1], ++ [PKG_CHECK_EXISTS([lua-5.1], [x_ac_lua_pkg_name=lua-5.1], ++ [x_ac_lua_pkg_name="lua >= 5.1"])])])])])]) ++ PKG_CHECK_MODULES([lua], ${x_ac_lua_pkg_name}, ++ [x_ac_have_lua="yes"], ++ [x_ac_have_lua="no"]) ++ ++ if test "x$x_ac_have_lua" = "xyes"; then ++ saved_CFLAGS="$CFLAGS" ++ saved_LIBS="$LIBS" ++ lua_CFLAGS="$lua_CFLAGS" ++ CFLAGS="$CFLAGS $lua_CFLAGS" ++ LIBS="$LIBS $lua_LIBS" ++ AC_MSG_CHECKING([for whether we can link to liblua]) ++ AC_TRY_LINK( ++ [#include ++ #include ++ #include ++ ], ++ [lua_State *L = luaL_newstate (); luaL_openlibs(L); ++ ], ++ [], [x_ac_have_lua="no"]) ++ ++ AC_MSG_RESULT([$x_ac_have_lua $x_ac_lua_pkg_name]) ++ if test "x$x_ac_have_lua" = "xno"; then ++ AC_MSG_WARN([unable to link against lua libraries]) ++ else ++ AC_DEFINE(HAVE_LUA, 1, [Define to 1 if we have the Lua library]) ++ # We can not define something here to determine version for systems ++ # that use just liblua we will not know what version we are using. ++ # Use LUA_VERSION_NUM as in lua.h it will always be right. ++ fi ++ CFLAGS="$saved_CFLAGS" ++ LIBS="$saved_LIBS" ++ else ++ AC_MSG_WARN([unable to locate lua package]) ++ fi ++ ++ AM_CONDITIONAL(HAVE_LUA, test "x$x_ac_have_lua" = "xyes") ++]) +diff --git a/configure.ac b/configure.ac +index 07496ea..58c6684 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -68,6 +68,7 @@ PYTHONGENDERS_MINOR=2 + PYTHONGENDERS_VERSION=$PYTHONGENDERS_MAJOR.$PYTHONGENDERS_MINOR + AC_SUBST([PYTHONGENDERS_VERSION]) + ++ + ## + # Checks for programs. + ## +@@ -86,6 +87,7 @@ AC_PATH_PROG([JAVAH], [javah]) + AC_PATH_PROG([JAVA], [java]) + AC_PATH_PROG([JAR], [jar]) + AC_PATH_PROG([JAVADOC], [javadoc]) ++AC_PATH_PROG([JAVADOC], [lua]) + AC_DEBUG + + ## +@@ -206,6 +208,24 @@ AM_CONDITIONAL(WITH_CPLUSPLUS_EXTENSIONS, [test "$ac_with_cplusplus_extensions" + AC_JAVA_EXTENSIONS + AM_CONDITIONAL(WITH_JAVA_EXTENSIONS, [test "$ac_with_java_extensions" = "yes"]) + ++# ++# Check for lua, which means create commanline conditional ++# ++AC_LUA_EXTENSIONS ++AM_CONDITIONAL(WITH_LUA_EXTENSIONS, [test "$ac_with_lua_extensions" = "yes"]) ++# ++# expand lua ++# ++if test "x$ac_with_lua_extensions" = "xyes" ; then ++# beware, the ACTION-IF-NOT-FOUND is not working ++AX_PROG_LUA([5.3],,,:) ++# The test of headers fail, if LUA_VERSION is empty ++if test LUA_VERSION ; then ++AX_LUA_HEADERS ++AX_LUA_LIBS ++fi ++fi ++ + ## + # Checks for typedefs, structures, and compiler characteristics. + ## +@@ -246,6 +266,7 @@ AC_CONFIG_FILES( \ + src/extensions/perl/Genders/Makefile \ + src/extensions/perl/Genders/Genders.pm \ + src/extensions/python/Makefile \ ++ src/extensions/lua/Makefile \ + src/extensions/python/genderssetup.py \ + src/extensions/java/Makefile \ + src/testsuite/Makefile \ +diff --git a/genders.spec b/genders.spec +new file mode 100644 +index 0000000..cd09930 +--- /dev/null ++++ b/genders.spec +@@ -0,0 +1,110 @@ ++Name: genders ++Version: 1.26 ++Release: 1 ++Summary: Static cluster configuration database ++URL: https://github.com/chaos/genders ++Group: System Environment/Base ++License: GPL ++Source: %{name}-%{version}.tar.gz ++Requires: perl ++BuildRequires: bison flex ++BuildRequires: perl(ExtUtils::MakeMaker) ++BuildRequires: python ++BuildRequires: python-devel ++BuildRequires: libtool ++BuildRoot: %{_tmppath}/%{name}-%{version} ++ ++%description ++Genders is a static cluster configuration database used for cluster ++configuration management. It is used by a variety of tools and ++scripts for management of large clusters. The genders database is ++typically replicated on every node of the cluster. It describes the ++layout and configuration of the cluster so that tools and scripts can ++sense the variations of cluster nodes. By abstracting this information ++into a plain text file, it becomes possible to change the ++configuration of a cluster by modifying only one file. ++ ++%package compat ++Summary: Compatibility library ++Group: System Environment/Base ++%description compat ++genders API that is compatible with earlier releases of genders ++ ++%{!?_with_perl_extensions: %{!?_without_perl_extensions: %define _with_perl_extensions --with-perl-extensions}} ++%{!?_with_python_extensions: %{!?_without_python_extensions: %define _with_python_extensions --with-python-extensions}} ++%{!?_with_cplusplus_extensions: %{!?_without_cplusplus_extensions: %define _with_cplusplus_extensions --with-cplusplus-extensions}} ++%{!?_with_java_extensions: %{!?_without_java_extensions: %define _without_java_extensions --without-java-extensions}} ++%{!?_with_lua_extensions: %{!?_without_lua_extensions: %define _without_lua_extensions --without-lua-extensions}} ++ ++# choose vendor arch by default ++%{!?_with_perl_site_arch: %{!?_with_perl_vendor_arch: %define _with_perl_vendor_arch --with-perl-vendor-arch}} ++ ++%prep ++%setup -q -n %{name}-%{version} ++ ++%build ++%configure --program-prefix=%{?_program_prefix:%{_program_prefix}} \ ++ --with-extension-destdir="$RPM_BUILD_ROOT" \ ++ %{?_with_perl_extensions} \ ++ %{?_without_perl_extensions} \ ++ %{?_with_perl_site_arch} \ ++ %{?_without_perl_site_arch} \ ++ %{?_with_perl_vendor_arch} \ ++ %{?_without_perl_vendor_arch} \ ++ %{?_with_python_extensions} \ ++ %{?_without_python_extensions} \ ++ %{?_with_cplusplus_extensions} \ ++ %{?_without_cplusplus_extensions} \ ++ %{?_with_java_extensions} \ ++ %{?_without_java_extensions}\ ++ %{?_with_lua_extensions} \ ++ %{?_without_lua_extension} ++make ++ ++%install ++rm -rf $RPM_BUILD_ROOT ++DESTDIR="$RPM_BUILD_ROOT" make install ++ ++%files ++%defattr(-,root,root) ++%doc README NEWS ChangeLog DISCLAIMER DISCLAIMER.UC COPYING TUTORIAL genders.sample ++%if %{?_with_java_extensions:1}%{!?_with_java_extensions:0} ++%dir %{_datadir}/doc/%{name}-%{version}-javadoc/ ++%doc %{_datadir}/doc/%{name}-%{version}-javadoc/* ++%endif ++# It doesn't matter if the user chooses a 32bit or 64bit target. The ++# packaging must work off whatever Perl is installed. ++%if %{?_with_perl_site_arch:1}%{!?_with_perl_site_arch:0} ++%define _perldir %(perl -e 'use Config; $T=$Config{installsitearch}; $P=$Config{siteprefix}; $T=~/$P\\/(.*)/; print "%{_prefix}/$1\\n"') ++%endif ++%if %{?_with_perl_vendor_arch:1}%{!?_with_perl_vendor_arch:0} ++%define _perldir %(perl -e 'use Config; $T=$Config{installvendorarch}; $P=$Config{vendorprefix}; $T=~/$P\\/(.*)/; print "%{_prefix}/$1\\n"') ++%endif ++%{_mandir}/man1/* ++%{_mandir}/man3/genders* ++%{_mandir}/man3/libgenders* ++%{_includedir}/* ++%{_bindir}/* ++%{_libdir}/libgenders.* ++%if %{?_with_perl_extensions:1}%{!?_with_perl_extensions:0} ++%{_mandir}/man3/Libgenders* ++%{_mandir}/man3/Genders* ++%{_perldir}/* ++%endif ++%if %{?_with_python_extensions:1}%{!?_with_python_extensions:0} ++%{_exec_prefix}/lib*/python* ++%endif ++%if %{?_with_cplusplus_extensions:1}%{!?_with_cplusplus_extensions:0} ++%{_libdir}/libgendersplusplus.* ++%endif ++%if %{?_with_java_extensions:1}%{!?_with_java_extensions:0} ++%{_javadir}/* ++%{_libdir}/libGendersjni.* ++%endif ++ ++%files compat ++%defattr(-,root,root) ++%{_mandir}/man3/gendlib* ++%{_prefix}/lib/genders/* ++ ++ +diff --git a/src/extensions/Makefile.am b/src/extensions/Makefile.am +index ec963c4..e85f6c2 100644 +--- a/src/extensions/Makefile.am ++++ b/src/extensions/Makefile.am +@@ -4,4 +4,4 @@ + ## Process this file with automake to produce Makefile.in. + ##***************************************************************************** + +-SUBDIRS = cplusplus java perl python ++SUBDIRS = cplusplus java perl python lua +diff --git a/src/extensions/lua/GendersTest/GendersTest.lua b/src/extensions/lua/GendersTest/GendersTest.lua +new file mode 100755 +index 0000000..7e28473 +--- /dev/null ++++ b/src/extensions/lua/GendersTest/GendersTest.lua +@@ -0,0 +1,134 @@ ++#!/usr/bin/lua ++ ++db_file = "testgenders" ++ ++genders_lib = require("genders") ++genders_handle = nil ++ ++-- wrapper to for using pcall ++function wrapper_new() ++ genders_handle = genders_lib.new(db_file) ++end ++ ++str_err = "" ++str_out = "" ++ ++no_load = nil ++error_status = 0 ++ ++getter_funcs = {"getnumattrs","getnumnodes","getnodes"} ++list_nodes = {"foobar","hype355","null"} ++list_attr = {"foobar","mgmt"} ++-- attr <-> value mismatch as this is dict! ++list_attrval = {["foobaar"] = "cfhost", ["hypei"] = "cfhost"} ++list_query = { "mgmt","mgmt||login","mhmt&&login","~mgmt"} ++ ++local open_lib, genders_handle = pcall(genders_lib.new,db_file,genders_lib) ++if open_lib then ++ print("Loaded database \""..db_file.."\"") ++ for _, func_name in ipairs(getter_funcs) do ++ local str = "return function(handle) return pcall(handle."..func_name..",handle) end" ++ local wrap_func = assert(load(str)) ++ local func = wrap_func() ++ local ok,ret_val = func(genders_handle) ++ if ok then ++ if type(ret_val) ~= "table" then ++ print(func_name.." :: "..ret_val) ++ else ++ local tmp_str = func_name.." :: " ++ for _,val in ipairs(ret_val) do ++ tmp_str = tmp_str..val..", " ++ end ++ print(tmp_str) ++ end ++ else ++ error_status = 1 ++ str_err = "Could not call "..func_name..": "..ret_val ++ end ++ end ++ local ok, ret_val = pcall(genders_handle.getnodes,genders_handle,"mgmt") ++ if ok then ++ local tmp_str = "getnodes(\"mgmt\") :: " for _,val in ipairs(ret_val) do tmp_str = tmp_str..val..", " end ++ print(tmp_str) ++ else ++ error_status = 1 ++ str_err = "Could not call: getnodes(\"mgmt\")"..ret_val ++ end ++ local ok, ret_val = pcall(genders_handle.getnodes,genders_handle,"foobarlalala") ++ if ok then ++ local tmp_str = "getnodes(\"foobarlalala\") :: " for _,val in ipairs(ret_val) do tmp_str = tmp_str..val..", " end ++ print(tmp_str) ++ else ++ error_status = 1 ++ str_err = "Could not call: getnodes(\"foobarlalala\")"..ret_val ++ end ++ local ok, ret_val = pcall(genders_handle.getnodes,genders_handle,"cfhost","foobar") ++ if ok then ++ local tmp_str = "getnodes(\"cfhost\",\"foobar\") :: " for _,val in ipairs(ret_val) do tmp_str = tmp_str..val..", " end ++ print(tmp_str) ++ else ++ error_status = 1 ++ str_err = "Could not call: getnodes(\"cfhost\",\"foobar\")"..ret_val ++ end ++ local ok, ret_val = pcall(genders_handle.getnodes,genders_handle,"cfhost","hypei") ++ if ok then ++ local tmp_str = "getnodes(\"cfhost\",\"hypei\") :: " for _,val in ipairs(ret_val) do tmp_str = tmp_str..val..", " end ++ print(tmp_str) ++ else ++ error_status = 1 ++ str_err = "Could not call: getnodes(\"cfhost\",\"hypei\")"..ret_val ++ end ++ local ok, ret_val = pcall(genders_handle.getattr,genders_handle,"hype355") ++ if ok then ++ local tmp_str = "getattr(\"hype355\") :: " for key,value in pairs(ret_val) do tmp_str = tmp_str..key if value == "" then tmp_str = tmp_str..", " else tmp_str = tmp_str.."="..value.."," end end ++ print(tmp_str) ++ else ++ error_status = 1 ++ str_err = "Could not call: getattr(\"hype355\")"..ret_val ++ end ++ for _,node in ipairs(list_nodes) do ++ local ok, ret_val = pcall(genders_handle.isnode,genders_handle,node) ++ if ok then ++ if ret_val then print("isnode("..node..") = true") else print("isnode("..node..") = false") end ++ else ++ error_status = 1 ++ str_err = "Could not call: isnode("..node..") "..ret_val ++ end ++ end ++ for _,attr in ipairs(list_attr) do ++ local ok, ret_val = pcall(genders_handle.isattr,genders_handle,attr) ++ if ok then ++ if ret_val then print("isattr("..attr..") = true") else print("isattr("..attr..") = false") end ++ else ++ error_status = 1 ++ str_err = "Could not call: isattr("..attr..") "..ret_val ++ end ++ end ++ for value,attr in pairs(list_attrval) do ++ local ok, ret_val = pcall(genders_handle.isattrval,genders_handle,attr,value) ++ if ok then ++ if ret_val then print("isattrval("..attr..","..value..") = true") else print("isattrval("..attr..","..value..") = false") end ++ else ++ error_status = 1 ++ str_err = "Could not call: isattr("..attr..") "..ret_val ++ end ++ end ++ for _,qry in ipairs(list_query) do ++ local ok, ret_val = pcall(genders_handle.query,genders_handle,qry) ++ if ok then ++ local tmp_str = "query("..qry..") :: " for _,val in pairs(ret_val) do tmp_str = tmp_str..val..", " end ++ print(tmp_str) ++ else ++ error_status = 1 ++ str_err = "Could not call: query("..qry..")"..ret_val ++ end ++ end ++else ++ str_err = "Failure in loading database \""..db_file.."\"" ++ error_status = 1 ++end ++if error_status == 0 then ++ print("No errors") ++else ++ print("Collected errors are: "..str_err) ++end +diff --git a/src/extensions/lua/GendersTest/testgenders b/src/extensions/lua/GendersTest/testgenders +new file mode 100644 +index 0000000..4d17db1 +--- /dev/null ++++ b/src/extensions/lua/GendersTest/testgenders +@@ -0,0 +1,21 @@ ++########################################################################## ++# $URL: file:///var/svn/cfengine/clusters/hype/genders $ ++# $Author: tdhooge $ ++# $Date: 2012-06-29 17:05:40 -0700 (Fri, 29 Jun 2012) $ ++# $Rev: 3594 $ ++########################################################################### ++ ++# Mgmt ++hype[137,355] pdsh_all_skip,mgmt,dhcpd,sshd,tftp,named,nfs,ntpserv ++hype[137,355] networker,crond,rsshd ++ ++hype355 primgmt,opensmd,powerman,conman,sendmail,sysloghost,moab ++hype355 passwdhost=hype:hypei,sshkeyhost,cfhost=hypei,mysqld ++hype355 skummee,perfmgr,httpd,logarch ++hype137 httpd ++hype137 altmgmt ++ ++# Login ++hype[136,356] login,cups,iptables,ksshd,ksshd_client,bluenet,atd ++hype136 ipforw,skummee,mysqld ++hype[136,356] crond,rsshd,psacct +diff --git a/src/extensions/lua/Makefile.am b/src/extensions/lua/Makefile.am +new file mode 100644 +index 0000000..4512cee +--- /dev/null ++++ b/src/extensions/lua/Makefile.am +@@ -0,0 +1,21 @@ ++# DESTDIR is usually set during make install time, not configure or ++# make time, so we work around it with the --with-extension-destdir ++# autoconf option. ++ ++ ++if WITH_LUA_EXTENSIONS ++ ++luaexec_LTLIBRARIES = genders.la ++ ++genders_la_SOURCES = genderslua.c ++ ++genders_la_CFLAGS = @LUA_INCLUDE@ -I../../libgenders/ ++ ++genders_la_LDFLAGS = -module -avoid-version ++ ++genders_la_LIBADD = ../../libgenders/libgenders.la $(OTHER_FLAGS) @LUA_LIB@ ++ ++ ++endif ++ ++EXTRA_DIST = genderslua.c +diff --git a/src/extensions/lua/genderslua.c b/src/extensions/lua/genderslua.c +new file mode 100644 +index 0000000..f2364af +--- /dev/null ++++ b/src/extensions/lua/genderslua.c +@@ -0,0 +1,322 @@ ++/***************************************************************************** ++ * Copyright (C) 2018 SUSE LLC ++ * Written by Christian Goll ++ * ++ * This file is part of Genders, a cluster configuration database. ++ * For details, see . ++ * ++ * Genders 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 2 of the License, or (at your option) ++ * any later version. ++ * ++ * Genders 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 Genders. If not, see . ++\*****************************************************************************/ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif /* HAVE_CONFIG_H */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++typedef struct { ++ /* genders_t itself is a pointer */ ++ genders_t handle; ++ char *db_name; ++ } lgenders_userdata_t; ++ ++static int lgenders_new(lua_State *L) { ++ lgenders_userdata_t *dbh; ++ const char *db_name, *g_error; ++ /* check for argument vailidy */ ++ db_name = luaL_checkstring(L,1); ++ if (db_name == NULL) ++ luaL_error(L,"database name could not be empty"); ++ /* Create the user data pushing it onto the stack. We also pre-initialize ++ * the member of the userdata in case initialization fails in some way. If ++ * that happens we want the userdata to be in a consistent state for __gc. ++ */ ++ dbh = (lgenders_userdata_t *)lua_newuserdata(L, sizeof(*dbh)); ++ dbh->handle = NULL; ++ dbh->db_name = NULL; ++ /* Add the metatable to the stack. */ ++ luaL_getmetatable(L, "LGenders"); ++ /* Set the metatable on the userdata. */ ++ lua_setmetatable(L, -2); ++ /* Create the handle */ ++ dbh->handle = genders_handle_create(); ++ dbh->db_name = strdup(db_name); ++ if(genders_load_data(dbh->handle,dbh->db_name) != 0) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ return 1; ++} ++static int lgenders_reload(lua_State *L) { ++ lgenders_userdata_t *dbh; ++ const char *db_name, *g_error; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ /* check for argument vailidy */ ++ db_name = luaL_checkstring(L,2); ++ if (db_name == NULL) ++ db_name = strdup(dbh->db_name); ++ if (dbh->handle != NULL) ++ genders_handle_destroy(dbh->handle); ++ dbh->db_name = NULL; ++ /* Create the handle */ ++ dbh->handle = genders_handle_create(); ++ dbh->db_name = strdup(db_name); ++ if(genders_load_data(dbh->handle,dbh->db_name) != 0) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ return 0; ++} ++static int lgenders_destroy(lua_State *L) { ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ /* pass return value to lus */ ++ if (dbh->handle != NULL) ++ genders_handle_destroy(dbh->handle); ++ ++ if (dbh->db_name != NULL) ++ free(dbh->db_name); ++ dbh->db_name = NULL; ++ return 0; ++} ++ ++static int lgenders_getnumnodes(lua_State *L) { ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ lua_pushinteger(L,genders_getnumnodes(dbh->handle)); ++ return 1; ++} ++ ++static int lgenders_getnumattrs(lua_State *L) { ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ lua_pushinteger(L,genders_getnumattrs(dbh->handle)); ++ return 1; ++} ++ ++static int lgenders_getnodes(lua_State *L) { ++ char** nodelist; ++ const char *g_error, *attr, *val; ++ int size, nr_nodes, i, nr_args = 0; ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ /* create space for the genders stuff */ ++ size = genders_nodelist_create(dbh->handle,&nodelist); ++ if(size == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ attr = NULL; val = NULL; ++ /* check for attr and val */ ++ nr_args = lua_gettop(L); ++ if(nr_args > 1) ++ attr = luaL_checkstring(L,2); ++ if(nr_args > 2) ++ val = luaL_checkstring(L,3); ++ if(nr_args > 3) ++ luaL_error(L,"getnodes accepts none,one or two arguments"); ++ nr_nodes = genders_getnodes(dbh->handle,nodelist,size,attr,val); ++ lua_newtable(L); ++ for(i = 0; i < nr_nodes; i++) { ++ lua_pushstring(L,nodelist[i]); ++ lua_rawseti(L,-2,i+1); ++ } ++ /* destroy list of nodes */ ++ if(genders_nodelist_destroy(dbh->handle,nodelist) == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ return 1; ++} ++ ++static int lgenders_query(lua_State *L) { ++ char** nodelist; ++ const char *g_error, *query; ++ int size, nr_nodes, i, nr_args = 0; ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ /* create space for the genders stuff */ ++ size = genders_nodelist_create(dbh->handle,&nodelist); ++ if(size == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ nr_args = lua_gettop(L); ++ if(nr_args == 2) ++ query = luaL_checkstring(L,2); ++ else ++ luaL_error(L,"query must be called with one argument"); ++ nr_nodes = genders_query(dbh->handle,nodelist,size,query); ++ lua_newtable(L); ++ for(i = 0; i < nr_nodes; i++) { ++ lua_pushstring(L,nodelist[i]); ++ lua_rawseti(L,-2,i+1); ++ } ++ /* destroy list of nodes */ ++ if(genders_nodelist_destroy(dbh->handle,nodelist) == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ return 1; ++} ++static int lgenders_getattr(lua_State *L) { ++ char **attr_list, **val_list; ++ const char *node, *g_error; ++ int ret_code, nr_args, size_attr, i = 0; ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ nr_args = lua_gettop(L); ++ if(nr_args == 2) ++ node = luaL_checkstring(L,2); ++ else ++ luaL_error(L,"query must be called with one argument"); ++ /* create space for the lists */ ++ ret_code = genders_attrlist_create(dbh->handle,&attr_list); ++ if(ret_code == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ ret_code = genders_vallist_create(dbh->handle,&val_list); ++ if(ret_code == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ /* hopefully size (which is in ret_code) of attr_list and val_list are the same */ ++ size_attr = genders_getattr(dbh->handle,attr_list,val_list,ret_code,node); ++ if(size_attr == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ lua_newtable(L); ++ for(i = 0; i < size_attr; i++) { ++ lua_pushstring(L, attr_list[i]); ++ lua_pushstring(L, val_list[i]); ++ lua_settable(L, -3); ++ } ++ /* destroy list of nodes */ ++ if(genders_vallist_destroy(dbh->handle,val_list) == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ if(genders_attrlist_destroy(dbh->handle,attr_list) == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ return 1; ++} ++ ++static int lgenders_isnode(lua_State *L) { ++ const char *node, *g_error; ++ int ret_code, nr_args; ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ nr_args = lua_gettop(L); ++ if(nr_args == 2) ++ node = luaL_checkstring(L,2); ++ else ++ luaL_error(L,"isnode must be called with one argument"); ++ ret_code = genders_isnode(dbh->handle,node); ++ if(ret_code == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ lua_pushboolean(L,ret_code); ++ return 1; ++} ++ ++static int lgenders_isattr(lua_State *L) { ++ const char *attr, *g_error; ++ int ret_code, nr_args; ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ nr_args = lua_gettop(L); ++ if(nr_args == 2) ++ attr = luaL_checkstring(L,2); ++ else ++ luaL_error(L,"isattr must be called with one argument"); ++ ret_code = genders_isattr(dbh->handle,attr); ++ if(ret_code == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ lua_pushboolean(L,ret_code); ++ return 1; ++} ++ ++static int lgenders_isattrval(lua_State *L) { ++ const char *attr, *val, *g_error; ++ int ret_code, nr_args; ++ lgenders_userdata_t *dbh; ++ dbh = (lgenders_userdata_t *)luaL_checkudata(L, 1, "LGenders"); ++ nr_args = lua_gettop(L); ++ if(nr_args == 3) { ++ attr = luaL_checkstring(L,2); ++ val = luaL_checkstring(L,3); ++ } ++ else ++ luaL_error(L,"isattrval must be called with two arguments"); ++ ret_code = genders_isattrval(dbh->handle,attr,val); ++ if(ret_code == -1) { ++ g_error = strdup(genders_errormsg(dbh->handle)); ++ luaL_error(L,g_error); ++ } ++ lua_pushboolean(L,ret_code); ++ return 1; ++} ++ ++static const struct luaL_Reg genders_methods[] = { ++ {"getnumattrs",lgenders_getnumattrs}, ++ {"getnumnodes",lgenders_getnumnodes}, ++ {"getnodes",lgenders_getnodes}, ++ {"getattr",lgenders_getattr}, ++ {"query",lgenders_query}, ++ {"isnode",lgenders_isnode}, ++ {"isattr",lgenders_isattr}, ++ {"isattrval",lgenders_isattrval}, ++ {"reload",lgenders_reload}, ++ {"__gc",lgenders_destroy}, ++ {NULL,NULL}, ++}; ++ ++static const struct luaL_Reg genders_functions[] = { ++ { "new", lgenders_new }, ++ { NULL, NULL} ++}; ++ ++ ++int luaopen_genders(lua_State *L) { ++ /* Create the metatable and put it on the stack. */ ++ luaL_newmetatable(L, "LGenders"); ++ /* Duplicate the metatable on the stack (We know have 2). */ ++ lua_pushvalue(L, -1); ++ /* Pop the first metatable off the stack and assign it to __index ++ * of the second one. We set the metatable for the table to itself. ++ * This is equivalent to the following in lua: ++ * metatable = {} ++ * metatable.__index = metatable ++ */ ++ lua_setfield(L, -2, "__index"); ++ ++ /* Set the methods to the metatable that should be accessed via object:func */ ++ luaL_setfuncs(L, genders_methods, 0); ++ ++ /* Register the object.func functions into the table that is at the top of the ++ * stack. */ ++ luaL_newlib(L, genders_functions); ++ ++ return 1; ++} +-- +2.37.1 +