From f0b9d8d20eca1a23e6a342653aa48b133f1b40f2 Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Wed, 6 Feb 2013 20:00:09 +0000 Subject: [PATCH 01/34] .gitignore: rework for release branch, where generated sources are included. --- .gitignore | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index ea988ba..0be030c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,8 @@ -/COPYING -/ChangeLog -/Makefile.in -/Makefile -/aclocal.m4 /autom4te.cache -/build-aux -/configure /config.log /config.status /luarocks /luarocks-config.lua /release-notes-* -/stdlib-*.zip -/*.rockspec +/stdlib-*.tar.gz +/stdlib-*/ From 611db188cf67a280bd2b5cadf93e2a509ae0cf66 Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Wed, 6 Feb 2013 21:55:26 +0000 Subject: [PATCH 02/34] Release v29 --- Makefile | 679 ++++++++ Makefile.am | 28 +- Makefile.in | 679 ++++++++ aclocal.m4 | 676 ++++++++ build-aux/install-sh | 527 ++++++ build-aux/missing | 331 ++++ configure | 3851 ++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- src/set.lua | 8 +- stdlib-29-1.rockspec | 25 + stdlib.rockspec | 25 + stdlib.rockspec.in | 2 +- 12 files changed, 6818 insertions(+), 15 deletions(-) create mode 100644 Makefile create mode 100644 Makefile.in create mode 100644 aclocal.m4 create mode 100755 build-aux/install-sh create mode 100755 build-aux/missing create mode 100755 configure create mode 100644 stdlib-29-1.rockspec create mode 100644 stdlib.rockspec diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3c62f69 --- /dev/null +++ b/Makefile @@ -0,0 +1,679 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/stdlib +pkgincludedir = $(includedir)/stdlib +pkglibdir = $(libdir)/stdlib +pkglibexecdir = $(libexecdir)/stdlib +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = . +DIST_COMMON = README $(am__configure_deps) $(dist_data_DATA) \ + $(dist_doc_DATA) $(dist_files_DATA) $(dist_modules_DATA) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/luarocks-config.lua.in $(top_srcdir)/configure \ + $(top_srcdir)/src/std.lua.in AUTHORS INSTALL \ + build-aux/install-sh build-aux/missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ + $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = luarocks-config.lua src/std.lua +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)" +DATA = $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ + $(dist_modules_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = ${SHELL} /home/rrt/Software/Lua/lua-stdlib/build-aux/missing --run aclocal-1.11 +AMTAR = $${TAR-tar} +AM_DEFAULT_VERBOSITY = 0 +AUTOCONF = ${SHELL} /home/rrt/Software/Lua/lua-stdlib/build-aux/missing --run autoconf +AUTOHEADER = ${SHELL} /home/rrt/Software/Lua/lua-stdlib/build-aux/missing --run autoheader +AUTOMAKE = ${SHELL} /home/rrt/Software/Lua/lua-stdlib/build-aux/missing --run automake-1.11 +AWK = gawk +CYGPATH_W = echo +DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"29\" -DPACKAGE_STRING=\"stdlib\ 29\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"29\" +ECHO_C = +ECHO_N = -n +ECHO_T = +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LIBOBJS = +LIBS = +LTLIBOBJS = +LUA = /home/rrt/local/bin/x86_64-linux-gnu/lua +LUA_EXEC_PREFIX = ${exec_prefix} +LUA_MIN_VERSION = 5.1 +LUA_PLATFORM = unknown +LUA_PREFIX = ${prefix} +LUA_SHORT_VERSION = 52 +LUA_VERSION = 5.2 +MAKEINFO = ${SHELL} /home/rrt/Software/Lua/lua-stdlib/build-aux/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +PACKAGE = stdlib +PACKAGE_BUGREPORT = rrt@sc3d.org +PACKAGE_NAME = stdlib +PACKAGE_STRING = stdlib 29 +PACKAGE_TARNAME = stdlib +PACKAGE_URL = +PACKAGE_VERSION = 29 +PATH_SEPARATOR = : +SET_MAKE = +SHELL = /bin/bash +STRIP = +VERSION = 29 +abs_builddir = /home/rrt/Software/Lua/lua-stdlib +abs_srcdir = /home/rrt/Software/Lua/lua-stdlib +abs_top_builddir = /home/rrt/Software/Lua/lua-stdlib +abs_top_srcdir = /home/rrt/Software/Lua/lua-stdlib +am__leading_dot = . +am__tar = $${TAR-tar} chof - "$$tardir" +am__untar = $${TAR-tar} xf - +bindir = /home/rrt/local/bin/x86_64-linux-gnu +build_alias = +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host_alias = +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/rrt/Software/Lua/lua-stdlib/build-aux/install-sh +libdir = ${exec_prefix}/lib +libexecdir = /home/rrt/local/libexec/x86_64-linux-gnu +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +luadir = ${prefix}/share/lua/5.2 +luaexecdir = ${exec_prefix}/lib/lua/5.2 +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +pkgluadir = ${luadir}/stdlib +pkgluaexecdir = ${luaexecdir}/stdlib +prefix = /home/rrt/local +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = +top_builddir = . +top_srcdir = . +ACLOCAL_AMFLAGS = -I m4 +SOURCES = $(wildcard $(srcdir)/src/*.lua) +dist_data_DATA = $(SOURCES) +dist_doc_DATA = \ + $(top_srcdir)/src/index.html \ + $(top_srcdir)/src/luadoc.css + +filesdir = $(docdir)/files +dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) +modulesdir = $(docdir)/modules +dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) +EXTRA_DIST = \ + src/std.lua.in \ + $(PACKAGE).rockspec.in + +DISTCLEANFILES = $(PACKAGE).rockspec +ROCKSPEC = $(PACKAGE)-$(VERSION)-1.rockspec +all: all-am + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +luarocks-config.lua: $(top_builddir)/config.status $(srcdir)/luarocks-config.lua.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +src/std.lua: $(top_builddir)/config.status $(top_srcdir)/src/std.lua.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-dist_dataDATA: $(dist_data_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(datadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(datadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(datadir)" || exit $$?; \ + done + +uninstall-dist_dataDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(datadir)'; $(am__uninstall_files_from_dir) +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) +install-dist_filesDATA: $(dist_files_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(filesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(filesdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(filesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(filesdir)" || exit $$?; \ + done + +uninstall-dist_filesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(filesdir)'; $(am__uninstall_files_from_dir) +install-dist_modulesDATA: $(dist_modules_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(modulesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(modulesdir)" || exit $$?; \ + done + +uninstall-dist_modulesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod u+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_dataDATA install-dist_docDATA \ + install-dist_filesDATA install-dist_modulesDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ + uninstall-dist_filesDATA uninstall-dist_modulesDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am am--refresh check check-am clean clean-generic dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-generic distcleancheck distdir distuninstallcheck \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_dataDATA \ + install-dist_docDATA install-dist_filesDATA \ + install-dist_modulesDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am uninstall uninstall-am uninstall-dist_dataDATA \ + uninstall-dist_docDATA uninstall-dist_filesDATA \ + uninstall-dist_modulesDATA + + +$(dist_doc_DATA): $(SOURCES) + cd src && luadoc *.lua + +$(ROCKSPEC): $(PACKAGE).rockspec + cp $< $@ + +tag-release: + git diff --exit-code && \ + git tag -a -m "Release tag" v$(VERSION) && \ + git push && git push --tags + +check-in-release: distcheck + git checkout release && \ + tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cp -af $(PACKAGE)-$(VERSION)/* . && \ + git add . && git ci -m "Release v$(VERSION)" && \ + git tag -a -m "Release tag" release-v$(VERSION) && \ + git push && git push --tags && \ + git checkout master + +release: $(ROCKSPEC) + $(MAKE) tag-release && \ + $(MAKE) check-in-release && \ + LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(ROCKSPEC) && \ + woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Makefile.am b/Makefile.am index 199494c..9bee4ca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,16 +2,16 @@ ACLOCAL_AMFLAGS = -I m4 -SOURCES = $(wildcard src/*.lua) +SOURCES = $(wildcard $(srcdir)/src/*.lua) dist_data_DATA = $(SOURCES) dist_doc_DATA = \ - src/index.html \ - src/luadoc.css + $(top_srcdir)/src/index.html \ + $(top_srcdir)/src/luadoc.css filesdir = $(docdir)/files -dist_files_DATA = $(wildcard src/files/*.html) +dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) modulesdir = $(docdir)/modules -dist_modules_DATA = $(wildcard src/modules/*.html) +dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ src/std.lua.in \ @@ -24,15 +24,25 @@ ROCKSPEC = $(PACKAGE)-$(VERSION)-1.rockspec $(dist_doc_DATA): $(SOURCES) cd src && luadoc *.lua -ChangeLog: - git2cl > ChangeLog - $(ROCKSPEC): $(PACKAGE).rockspec cp $< $@ -release: $(ROCKSPEC) distcheck +tag-release: git diff --exit-code && \ git tag -a -m "Release tag" v$(VERSION) && \ + git push && git push --tags + +check-in-release: distcheck + git checkout release && \ + tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cp -af $(PACKAGE)-$(VERSION)/* . && \ + git add . && git ci -m "Release v$(VERSION)" && \ + git tag -a -m "Release tag" release-v$(VERSION) && \ git push && git push --tags && \ + git checkout master + +release: $(ROCKSPEC) + $(MAKE) tag-release && \ + $(MAKE) check-in-release && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(ROCKSPEC) && \ woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..d8d5f7c --- /dev/null +++ b/Makefile.in @@ -0,0 +1,679 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = . +DIST_COMMON = README $(am__configure_deps) $(dist_data_DATA) \ + $(dist_doc_DATA) $(dist_files_DATA) $(dist_modules_DATA) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/luarocks-config.lua.in $(top_srcdir)/configure \ + $(top_srcdir)/src/std.lua.in AUTHORS INSTALL \ + build-aux/install-sh build-aux/missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ + $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = luarocks-config.lua src/std.lua +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)" +DATA = $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ + $(dist_modules_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +LUA = @LUA@ +LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ +LUA_MIN_VERSION = @LUA_MIN_VERSION@ +LUA_PLATFORM = @LUA_PLATFORM@ +LUA_PREFIX = @LUA_PREFIX@ +LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ +LUA_VERSION = @LUA_VERSION@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +luadir = @luadir@ +luaexecdir = @luaexecdir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgluadir = @pkgluadir@ +pkgluaexecdir = @pkgluaexecdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 +SOURCES = $(wildcard $(srcdir)/src/*.lua) +dist_data_DATA = $(SOURCES) +dist_doc_DATA = \ + $(top_srcdir)/src/index.html \ + $(top_srcdir)/src/luadoc.css + +filesdir = $(docdir)/files +dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) +modulesdir = $(docdir)/modules +dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) +EXTRA_DIST = \ + src/std.lua.in \ + $(PACKAGE).rockspec.in + +DISTCLEANFILES = $(PACKAGE).rockspec +ROCKSPEC = $(PACKAGE)-$(VERSION)-1.rockspec +all: all-am + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +luarocks-config.lua: $(top_builddir)/config.status $(srcdir)/luarocks-config.lua.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +src/std.lua: $(top_builddir)/config.status $(top_srcdir)/src/std.lua.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-dist_dataDATA: $(dist_data_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(datadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(datadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(datadir)" || exit $$?; \ + done + +uninstall-dist_dataDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(datadir)'; $(am__uninstall_files_from_dir) +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) +install-dist_filesDATA: $(dist_files_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(filesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(filesdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(filesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(filesdir)" || exit $$?; \ + done + +uninstall-dist_filesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(filesdir)'; $(am__uninstall_files_from_dir) +install-dist_modulesDATA: $(dist_modules_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(modulesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(modulesdir)" || exit $$?; \ + done + +uninstall-dist_modulesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod u+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_dataDATA install-dist_docDATA \ + install-dist_filesDATA install-dist_modulesDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ + uninstall-dist_filesDATA uninstall-dist_modulesDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am am--refresh check check-am clean clean-generic dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-generic distcleancheck distdir distuninstallcheck \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_dataDATA \ + install-dist_docDATA install-dist_filesDATA \ + install-dist_modulesDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am uninstall uninstall-am uninstall-dist_dataDATA \ + uninstall-dist_docDATA uninstall-dist_filesDATA \ + uninstall-dist_modulesDATA + + +$(dist_doc_DATA): $(SOURCES) + cd src && luadoc *.lua + +$(ROCKSPEC): $(PACKAGE).rockspec + cp $< $@ + +tag-release: + git diff --exit-code && \ + git tag -a -m "Release tag" v$(VERSION) && \ + git push && git push --tags + +check-in-release: distcheck + git checkout release && \ + tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cp -af $(PACKAGE)-$(VERSION)/* . && \ + git add . && git ci -m "Release v$(VERSION)" && \ + git tag -a -m "Release tag" release-v$(VERSION) && \ + git push && git push --tags && \ + git checkout master + +release: $(ROCKSPEC) + $(MAKE) tag-release && \ + $(MAKE) check-in-release && \ + LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(ROCKSPEC) && \ + woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..799b77b --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,676 @@ +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.6], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.6])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2009, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# (`yes' being less verbose, `no' or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], +[ --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0')]) +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few `make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using `$V' instead of `$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ax_compare_version.m4]) +m4_include([m4/ax_lua.m4]) diff --git a/build-aux/install-sh b/build-aux/install-sh new file mode 100755 index 0000000..a9244eb --- /dev/null +++ b/build-aux/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/build-aux/missing b/build-aux/missing new file mode 100755 index 0000000..86a8fc3 --- /dev/null +++ b/build-aux/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..951dfb8 --- /dev/null +++ b/configure @@ -0,0 +1,3851 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for stdlib 29. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and rrt@sc3d.org about +$0: your system, including any error possibly output before +$0: this message. Then install a modern shell, or manually +$0: run the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='stdlib' +PACKAGE_TARNAME='stdlib' +PACKAGE_VERSION='29' +PACKAGE_STRING='stdlib 29' +PACKAGE_BUGREPORT='rrt@sc3d.org' +PACKAGE_URL='' + +ac_subst_vars='LTLIBOBJS +LIBOBJS +pkgluaexecdir +luaexecdir +pkgluadir +luadir +LUA_EXEC_PREFIX +LUA_PREFIX +LUA_PLATFORM +LUA_SHORT_VERSION +LUA_VERSION +LUA +LUA_MIN_VERSION +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +' + ac_precious_vars='build_alias +host_alias +target_alias +LUA' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures stdlib 29 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/stdlib] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of stdlib 29:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0') + +Some influential environment variables: + LUA The Lua interpreter, e.g. /usr/bin/lua5.1 + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +stdlib configure 29 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by stdlib $as_me 29, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in build-aux "$srcdir"/build-aux; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='stdlib' + VERSION='29' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + +LUA_MIN_VERSION=5.1 + + + + + + + if test "x$LUA" != 'x'; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LUA is a Lua interprester" >&5 +$as_echo_n "checking if $LUA is a Lua interprester... " >&6; } + + if $LUA -e "print('Hello ' .. _VERSION .. '!')" &>/dev/null; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "not a Lua interpreter" "$LINENO" 5 + +fi + + _ax_check_text="whether $LUA version >= $LUA_MIN_VERSION, < 5.3" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 +$as_echo_n "checking $_ax_check_text... " >&6; } + + _ax_test_ver=`$LUA -e "print(_VERSION)" 2>/dev/null | \ + sed "s|^Lua \(.*\)|\1|" | grep -o "^[0-9]\+\\.[0-9]\+"` + if test "x$_ax_test_ver" = 'x'; then : + _ax_test_ver='0' +fi + + + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + + ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version_B=`echo "$LUA_MIN_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version=`echo "x$ax_compare_version_A +x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` + + + + if test "$ax_compare_version" = "true" ; then + : + fi + + if $ax_compare_version; then : + + + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + + ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version_B=`echo "5.3" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version=`echo "x$ax_compare_version_A +x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/false/;s/x${ax_compare_version_B}/true/;1q"` + + + + if test "$ax_compare_version" = "true" ; then + : + fi + +fi + + if $ax_compare_version; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "version is out of range for specified LUA" "$LINENO" 5 +fi + + ax_display_LUA=$LUA + +else + _ax_check_text="for a Lua interpreter with version >= $LUA_MIN_VERSION, < 5.3" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 +$as_echo_n "checking $_ax_check_text... " >&6; } +if ${ax_cv_pathless_LUA+:} false; then : + $as_echo_n "(cached) " >&6 +else + for ax_cv_pathless_LUA in lua lua5.2 lua5.1 lua50 none; do + test "x$ax_cv_pathless_LUA" = 'xnone' && break + + if $ax_cv_pathless_LUA -e "print('Hello ' .. _VERSION .. '!')" &>/dev/null; then : + +else + continue +fi + + + _ax_test_ver=`$ax_cv_pathless_LUA -e "print(_VERSION)" 2>/dev/null | \ + sed "s|^Lua \(.*\)|\1|" | grep -o "^[0-9]\+\\.[0-9]\+"` + if test "x$_ax_test_ver" = 'x'; then : + _ax_test_ver='0' +fi + + + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + + ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version_B=`echo "$LUA_MIN_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version=`echo "x$ax_compare_version_A +x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` + + + + if test "$ax_compare_version" = "true" ; then + : + fi + + if $ax_compare_version; then : + + + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + + ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version_B=`echo "5.3" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ + -e 's/[^0-9]//g'` + + + ax_compare_version=`echo "x$ax_compare_version_A +x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/false/;s/x${ax_compare_version_B}/true/;1q"` + + + + if test "$ax_compare_version" = "true" ; then + : + fi + +fi + + if $ax_compare_version; then : + break +fi + + done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_pathless_LUA" >&5 +$as_echo "$ax_cv_pathless_LUA" >&6; } + if test "x$ax_cv_pathless_LUA" = 'xnone'; then : + LUA=':' +else + # Extract the first word of "$ax_cv_pathless_LUA", so it can be a program name with args. +set dummy $ax_cv_pathless_LUA; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LUA+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LUA in + [\\/]* | ?:[\\/]*) + ac_cv_path_LUA="$LUA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LUA="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +LUA=$ac_cv_path_LUA +if test -n "$LUA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LUA" >&5 +$as_echo "$LUA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi + ax_display_LUA=$ax_cv_pathless_LUA + +fi + + + if test "x$LUA" = 'x:'; then : + as_fn_error $? "cannot find suitable Lua interpreter" "$LINENO" 5 + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA version" >&5 +$as_echo_n "checking for $ax_display_LUA version... " >&6; } +if ${ax_cv_lua_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_lua_version=`$LUA -e "print(_VERSION)" | \ + sed "s|^Lua \(.*\)|\1|" | \ + grep -o "^[0-9]\+\\.[0-9]\+"` + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_version" >&5 +$as_echo "$ax_cv_lua_version" >&6; } + if test "x$ax_cv_lua_version" = 'x'; then : + as_fn_error $? "invalid Lua version number" "$LINENO" 5 +fi + LUA_VERSION=$ax_cv_lua_version + + LUA_SHORT_VERSION=`echo "$LUA_VERSION" | sed 's|\.||'` + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA platform" >&5 +$as_echo_n "checking for $ax_display_LUA platform... " >&6; } +if ${ax_cv_lua_platform+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_lua_platform=`$LUA -e "print('unknown')"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_platform" >&5 +$as_echo "$ax_cv_lua_platform" >&6; } + LUA_PLATFORM=$ax_cv_lua_platform + + + LUA_PREFIX='${prefix}' + + LUA_EXEC_PREFIX='${exec_prefix}' + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA script directory" >&5 +$as_echo_n "checking for $ax_display_LUA script directory... " >&6; } +if ${ax_cv_lua_luadir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$prefix" = 'xNONE'; then : + ax_lua_prefix=$ac_default_prefix +else + ax_lua_prefix=$prefix +fi + + ax_cv_lua_luadir="$LUA_PREFIX/share/lua/$LUA_VERSION" + + + + ax_lua_prefixed_path='' + _ax_package_paths=`$LUA -e 'print(package.path)' 2>/dev/null | sed 's|;|\n|g'` + for _ax_package_path in $_ax_package_paths; do + _ax_path_parts=`echo "$_ax_package_path" | sed 's|/|\n|g'` + _ax_reassembled='' + for _ax_path_part in $_ax_path_parts; do + echo "$_ax_path_part" | grep '\?' >/dev/null && break + _ax_reassembled="$_ax_reassembled/$_ax_path_part" + done + _ax_package_path=$_ax_reassembled + if echo "$_ax_package_path" | grep "^$ax_lua_prefix" >/dev/null; then + ax_lua_prefixed_path=$_ax_package_path + break + fi + done + + if test "x$ax_lua_prefixed_path" != 'x'; then : + _ax_strip_prefix=`echo "$ax_lua_prefix" | sed 's|.|.|g'` + ax_cv_lua_luadir=`echo "$ax_lua_prefixed_path" | \ + sed "s,^$_ax_strip_prefix,$LUA_PREFIX,"` + +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_luadir" >&5 +$as_echo "$ax_cv_lua_luadir" >&6; } + luadir=$ax_cv_lua_luadir + + pkgluadir=\${luadir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA module directory" >&5 +$as_echo_n "checking for $ax_display_LUA module directory... " >&6; } +if ${ax_cv_lua_luaexecdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$exec_prefix" = 'xNONE'; then : + ax_lua_exec_prefix=$ax_lua_prefix +else + ax_lua_exec_prefix=$exec_prefix +fi + + ax_cv_lua_luaexecdir="$LUA_EXEC_PREFIX/lib/lua/$LUA_VERSION" + + + + ax_lua_prefixed_path='' + _ax_package_paths=`$LUA -e 'print(package.cpathd)' 2>/dev/null | sed 's|;|\n|g'` + for _ax_package_path in $_ax_package_paths; do + _ax_path_parts=`echo "$_ax_package_path" | sed 's|/|\n|g'` + _ax_reassembled='' + for _ax_path_part in $_ax_path_parts; do + echo "$_ax_path_part" | grep '\?' >/dev/null && break + _ax_reassembled="$_ax_reassembled/$_ax_path_part" + done + _ax_package_path=$_ax_reassembled + if echo "$_ax_package_path" | grep "^$ax_lua_exec_prefix" >/dev/null; then + ax_lua_prefixed_path=$_ax_package_path + break + fi + done + + if test "x$ax_lua_prefixed_path" != 'x'; then : + _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | sed 's|.|.|g'` + ax_cv_lua_luaexecdir=`echo "$ax_lua_prefixed_path" | \ + sed "s,^$_ax_strip_prefix,$LUA_EXEC_PREFIX,"` + +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_luaexecdir" >&5 +$as_echo "$ax_cv_lua_luaexecdir" >&6; } + luaexecdir=$ax_cv_lua_luaexecdir + + pkgluaexecdir=\${luaexecdir}/$PACKAGE + + + + +fi + + + +ac_config_files="$ac_config_files Makefile $PACKAGE.rockspec luarocks-config.lua src/std.lua" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by stdlib $as_me 29, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +stdlib config.status 29 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "$PACKAGE.rockspec") CONFIG_FILES="$CONFIG_FILES $PACKAGE.rockspec" ;; + "luarocks-config.lua") CONFIG_FILES="$CONFIG_FILES luarocks-config.lua" ;; + "src/std.lua") CONFIG_FILES="$CONFIG_FILES src/std.lua" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.ac b/configure.ac index 205f368..9970100 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake -AC_INIT(stdlib, 28, rrt@sc3d.org) +AC_INIT(stdlib, 29, rrt@sc3d.org) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) AM_SILENT_RULES([yes]) diff --git a/src/set.lua b/src/set.lua index 8ce1cfb..6754c43 100644 --- a/src/set.lua +++ b/src/set.lua @@ -12,21 +12,21 @@ module ("set", package.seeall) -- @return true if e is in set, false -- otherwise function member (s, e) - return rawget (s, e) == true + return rawget (s.contents, e) == true end --- Insert an element into a set -- @param s set -- @param e element function insert (s, e) - rawset (s, e, true) + rawset (s.contents, e, true) end --- Delete an element from a set -- @param s set -- @param e element function delete (s, e) - rawset (s, e, nil) + rawset (s.contents, e, nil) end --- Make a list into a set @@ -34,7 +34,7 @@ end -- @return set local metatable = {} function new (l) - local s = setmetatable ({}, metatable) + local s = setmetatable ({contents={}}, metatable) for e in list.elems (l) do insert (s, e) end diff --git a/stdlib-29-1.rockspec b/stdlib-29-1.rockspec new file mode 100644 index 0000000..25933b0 --- /dev/null +++ b/stdlib-29-1.rockspec @@ -0,0 +1,25 @@ +package="stdlib" +version="29-1" +source = { + url = "git://github.com/rrthomas/lua-stdlib.git", + branch = "v29", +} +description = { + summary = "General Lua libraries", + detailed = [[ + stdlib is a library of modules for common programming tasks, + including list, table and functional operations, regexps, objects, + pickling, pretty-printing and getopt. + ]], + homepage = "http://github.com/rrthomas/lua-stdlib/", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1" +} +build = { + type = "command", + build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + install_command = "make install", + copy_directories = {} +} diff --git a/stdlib.rockspec b/stdlib.rockspec new file mode 100644 index 0000000..25933b0 --- /dev/null +++ b/stdlib.rockspec @@ -0,0 +1,25 @@ +package="stdlib" +version="29-1" +source = { + url = "git://github.com/rrthomas/lua-stdlib.git", + branch = "v29", +} +description = { + summary = "General Lua libraries", + detailed = [[ + stdlib is a library of modules for common programming tasks, + including list, table and functional operations, regexps, objects, + pickling, pretty-printing and getopt. + ]], + homepage = "http://github.com/rrthomas/lua-stdlib/", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1" +} +build = { + type = "command", + build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + install_command = "make install", + copy_directories = {} +} diff --git a/stdlib.rockspec.in b/stdlib.rockspec.in index 751d22d..bc69d01 100644 --- a/stdlib.rockspec.in +++ b/stdlib.rockspec.in @@ -2,7 +2,7 @@ package="stdlib" version="@VERSION@-1" source = { url = "git://github.com/rrthomas/lua-stdlib.git", - branch = "v@VERSION@", + branch = "release-v@VERSION@", } description = { summary = "General Lua libraries", From 736f96a2b5de4f1a2af84fe6ce2532e54c315c39 Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Thu, 7 Feb 2013 12:35:29 +0000 Subject: [PATCH 03/34] src/.gitignore: remove it, as we actually want all the files it was filtering out in releases. --- src/.gitignore | 5 ----- 1 file changed, 5 deletions(-) delete mode 100755 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore deleted file mode 100755 index cf640d2..0000000 --- a/src/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/std.lua -/luadoc.css -/index.html -/files -/modules From 4e3f2f10dcd9a277d5ff37162de10204ae9bd8df Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Thu, 7 Feb 2013 12:40:16 +0000 Subject: [PATCH 04/34] Release v29 take 2 (now with all files) --- src/files/base.html | 1595 ++++++++++++++++++++++++++++++++++++ src/files/bin.html | 332 ++++++++ src/files/debug_ext.html | 407 +++++++++ src/files/debug_init.html | 258 ++++++ src/files/fstable.html | 308 +++++++ src/files/getopt.html | 477 +++++++++++ src/files/io_ext.html | 540 ++++++++++++ src/files/lcs.html | 312 +++++++ src/files/list.html | 1216 +++++++++++++++++++++++++++ src/files/math_ext.html | 346 ++++++++ src/files/mbox.html | 304 +++++++ src/files/modules.html | 258 ++++++ src/files/object.html | 296 +++++++ src/files/package_ext.html | 308 +++++++ src/files/parser.html | 346 ++++++++ src/files/set.html | 644 +++++++++++++++ src/files/std.html | 260 ++++++ src/files/strbuf.html | 342 ++++++++ src/files/strict.html | 258 ++++++ src/files/string_ext.html | 769 +++++++++++++++++ src/files/table_ext.html | 630 ++++++++++++++ src/files/tree.html | 419 ++++++++++ src/files/xml.html | 307 +++++++ src/index.html | 464 +++++++++++ src/luadoc.css | 286 +++++++ src/modules/base.html | 1591 +++++++++++++++++++++++++++++++++++ src/modules/bin.html | 328 ++++++++ src/modules/debug.html | 403 +++++++++ src/modules/fstable.html | 304 +++++++ src/modules/getopt.html | 473 +++++++++++ src/modules/io.html | 536 ++++++++++++ src/modules/lcs.html | 308 +++++++ src/modules/list.html | 1212 +++++++++++++++++++++++++++ src/modules/math.html | 342 ++++++++ src/modules/mbox.html | 300 +++++++ src/modules/object.html | 292 +++++++ src/modules/package.html | 304 +++++++ src/modules/parser.html | 342 ++++++++ src/modules/set.html | 640 +++++++++++++++ src/modules/std.html | 256 ++++++ src/modules/strbuf.html | 338 ++++++++ src/modules/string.html | 765 +++++++++++++++++ src/modules/table.html | 626 ++++++++++++++ src/modules/tree.html | 415 ++++++++++ src/std.lua | 16 + 45 files changed, 21473 insertions(+) create mode 100644 src/files/base.html create mode 100644 src/files/bin.html create mode 100644 src/files/debug_ext.html create mode 100644 src/files/debug_init.html create mode 100644 src/files/fstable.html create mode 100644 src/files/getopt.html create mode 100644 src/files/io_ext.html create mode 100644 src/files/lcs.html create mode 100644 src/files/list.html create mode 100644 src/files/math_ext.html create mode 100644 src/files/mbox.html create mode 100644 src/files/modules.html create mode 100644 src/files/object.html create mode 100644 src/files/package_ext.html create mode 100644 src/files/parser.html create mode 100644 src/files/set.html create mode 100644 src/files/std.html create mode 100644 src/files/strbuf.html create mode 100644 src/files/strict.html create mode 100644 src/files/string_ext.html create mode 100644 src/files/table_ext.html create mode 100644 src/files/tree.html create mode 100644 src/files/xml.html create mode 100644 src/index.html create mode 100644 src/luadoc.css create mode 100644 src/modules/base.html create mode 100644 src/modules/bin.html create mode 100644 src/modules/debug.html create mode 100644 src/modules/fstable.html create mode 100644 src/modules/getopt.html create mode 100644 src/modules/io.html create mode 100644 src/modules/lcs.html create mode 100644 src/modules/list.html create mode 100644 src/modules/math.html create mode 100644 src/modules/mbox.html create mode 100644 src/modules/object.html create mode 100644 src/modules/package.html create mode 100644 src/modules/parser.html create mode 100644 src/modules/set.html create mode 100644 src/modules/std.html create mode 100644 src/modules/strbuf.html create mode 100644 src/modules/string.html create mode 100644 src/modules/table.html create mode 100644 src/modules/tree.html create mode 100644 src/std.lua diff --git a/src/files/base.html b/src/files/base.html new file mode 100644 index 0000000..c6218e9 --- /dev/null +++ b/src/files/base.html @@ -0,0 +1,1595 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File base.lua

+ + +

Adds to the existing global functions

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_G.assert (v, f, ...)Extend to allow formatted arguments.
_G.bind (f, ...)Partially apply a function.
_G.collect (i, ...)Collect the results of an iterator.
_G.compose (..., f1...fn)Compose functions.
_G.curry (f, n)Curry a function.
_G.die (...)Die with error.
_G.eval (s)Evaluate a string.
_G.filter (p, i, ...)Filter an iterator with a predicate.
_G.fold (f, d, i, ...)Fold a binary function into an iterator.
_G.id (...)Identity function.
_G.ileaves (tr)Tree iterator which returns just numbered leaves, in order.
_G.inodes (tr)Tree iterator over numbered nodes, in order.
_G.leaves (tr)Tree iterator which returns just leaves.
_G.map (f, i, ...)Map a function over an iterator.
_G.memoize (fn)Memoize a function, by wrapping it in a functable.
_G.metamethod (x, n)Return given metamethod, if any, or nil.
_G.nodes (tr)Tree iterator.
_G.pack (...)Turn a tuple into a list.
_G.pickle (x)Convert a value to a string.
_G.prettytostring (t, indent, spacing)Pretty-print a table.
_G.render (x, open, close, elem, pair, sep, roots)Turn tables into strings with recursion detection.
_G.require_version (module, min, too_big, pattern)Require a module with a particular version
_G.ripairs (t)An iterator like ipairs, but in reverse.
_G.tostring (x)Extend tostring to work better on tables.
_G.totable (x)Turn an object into a table according to __totable metamethod.
_G.warn (...)Give warning with the name of program and file (if any).
render_CloseRenderer (t)
render_ElementRenderer (e)
render_OpenRenderer (t)
render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
render_SeparatorRenderer (t, i, v, j, w)
tree_Iterator (it, tr, n)
+ + + + +

Tables

+ + + + + + + +
_G.opFunctional forms of infix operators.
+ + + +
+
+ + + + +

Functions

+
+ + + +
_G.assert (v, f, ...)
+
+Extend to allow formatted arguments. + + +

Parameters

+
    + +
  • + v: value to assert +
  • + +
  • + f: format +
  • + +
  • + ...: arguments to format +
  • + +
+ + + + + + +

Return value:

+value + + + +
+ + + + +
_G.bind (f, ...)
+
+Partially apply a function. + + +

Parameters

+
    + +
  • + f: function to apply partially +
  • + +
  • + ...: arguments to bind +
  • + +
+ + + + + + +

Return value:

+function with ai already bound + + + +
+ + + + +
_G.collect (i, ...)
+
+Collect the results of an iterator. + + +

Parameters

+
    + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+results of running the iterator on its arguments + + + +
+ + + + +
_G.compose (..., f1...fn)
+
+Compose functions. + + +

Parameters

+
    + +
  • + ...: +
  • + +
  • + f1...fn: functions to compose +
  • + +
+ + + + + + +

Return value:

+composition of f1 ... fn + + + +
+ + + + +
_G.curry (f, n)
+
+Curry a function. + + +

Parameters

+
    + +
  • + f: function to curry +
  • + +
  • + n: number of arguments +
  • + +
+ + + + + + +

Return value:

+curried version of f + + + +
+ + + + +
_G.die (...)
+
+Die with error. + + +

Parameters

+
    + +
  • + ...: arguments for format +
  • + +
+ + + + + + + + +
+ + + + +
_G.eval (s)
+
+Evaluate a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
+ + + + + + +

Return value:

+value of string + + + +
+ + + + +
_G.filter (p, i, ...)
+
+Filter an iterator with a predicate. + + +

Parameters

+
    + +
  • + p: predicate +
  • + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+result table containing elements e for which p (e) + + + +
+ + + + +
_G.fold (f, d, i, ...)
+
+Fold a binary function into an iterator. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + d: initial first argument +
  • + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+result + + + +
+ + + + +
_G.id (...)
+
+Identity function. + + +

Parameters

+
    + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+the arguments passed to the function + + + +
+ + + + +
_G.ileaves (tr)
+
+Tree iterator which returns just numbered leaves, in order. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +
+ + + + +
_G.inodes (tr)
+
+Tree iterator over numbered nodes, in order. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +

See also:

+ + +
+ + + + +
_G.leaves (tr)
+
+Tree iterator which returns just leaves. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +
+ + + + +
_G.map (f, i, ...)
+
+Map a function over an iterator. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+result table + + + +
+ + + + +
_G.memoize (fn)
+
+Memoize a function, by wrapping it in a functable. + + +

Parameters

+
    + +
  • + fn: function that returns a single result +
  • + +
+ + + + + + +

Return value:

+memoized function + + + +
+ + + + +
_G.metamethod (x, n)
+
+Return given metamethod, if any, or nil. + + +

Parameters

+
    + +
  • + x: object to get metamethod of +
  • + +
  • + n: name of metamethod to get +
  • + +
+ + + + + + +

Return value:

+metamethod function or nil if no metamethod or not a function + + + +
+ + + + +
_G.nodes (tr)
+
+Tree iterator. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +

See also:

+ + +
+ + + + +
_G.pack (...)
+
+Turn a tuple into a list. + + +

Parameters

+
    + +
  • + ...: tuple +
  • + +
+ + + + + + +

Return value:

+list + + + +
+ + + + +
_G.pickle (x)
+
+Convert a value to a string. The string can be passed to dostring to retrieve the value.
TODO: Make it work for recursive tables. + + +

Parameters

+
    + +
  • + x: object to pickle +
  • + +
+ + + + + + +

Return value:

+string such that eval (s) is the same value as x + + + +
+ + + + +
_G.prettytostring (t, indent, spacing)
+
+Pretty-print a table. + + +

Parameters

+
    + +
  • + t: table to print +
  • + +
  • + indent: indent between levels ["\t"] +
  • + +
  • + spacing: space before every line +
  • + +
+ + + + + + +

Return value:

+pretty-printed string + + + +
+ + + + +
_G.render (x, open, close, elem, pair, sep, roots)
+
+Turn tables into strings with recursion detection. N.B. Functions calling render should not recurse, or recursion detection will not work. + + +

Parameters

+
    + +
  • + x: object to convert to string +
  • + +
  • + open: open table renderer +
  • + +
  • + close: close table renderer +
  • + +
  • + elem: element renderer +
  • + +
  • + pair: pair renderer +
  • + +
  • + sep: separator renderer +
  • + +
  • + roots: +
  • + +
+ + + + + + +

Return value:

+string representation + + + +

See also:

+ + +
+ + + + +
_G.require_version (module, min, too_big, pattern)
+
+Require a module with a particular version + + +

Parameters

+
    + +
  • + module: module to require +
  • + +
  • + min: lowest acceptable version (default: any) +
  • + +
  • + too_big: lowest version that is too big (default: none) +
  • + +
  • + pattern: +
  • + +
+ + + + + + + + +
+ + + + +
_G.ripairs (t)
+
+An iterator like ipairs, but in reverse. + + +

Parameters

+
    + +
  • + t: table to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the table, as above + +
  3. #t + 1 + +
+ + + +
+ + + + +
_G.tostring (x)
+
+Extend tostring to work better on tables. + + +

Parameters

+
    + +
  • + x: object to convert to string +
  • + +
+ + + + + + +

Return value:

+string representation + + + +
+ + + + +
_G.totable (x)
+
+Turn an object into a table according to __totable metamethod. + + +

Parameters

+
    + +
  • + x: object to turn into a table +
  • + +
+ + + + + + +

Return value:

+table or nil + + + +
+ + + + +
_G.warn (...)
+
+Give warning with the name of program and file (if any). + + +

Parameters

+
    + +
  • + ...: arguments for format +
  • + +
+ + + + + + + + +
+ + + + +
render_CloseRenderer (t)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+close table string + + + +
+ + + + +
render_ElementRenderer (e)
+
+ + + +

Parameters

+
    + +
  • + e: element +
  • + +
+ + + + + + +

Return value:

+element string + + + +
+ + + + +
render_OpenRenderer (t)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+open table string + + + +
+ + + + +
render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + i: index +
  • + +
  • + v: value +
  • + +
  • + is: index string +
  • + +
  • + vs: value string +
  • + +
+ + + + + + +

Return value:

+element string + + + +
+ + + + +
render_SeparatorRenderer (t, i, v, j, w)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + i: preceding index (nil on first call) +
  • + +
  • + v: preceding value (nil on first call) +
  • + +
  • + j: following index (nil on last call) +
  • + +
  • + w: following value (nil on last call) +
  • + +
+ + + + + + +

Return value:

+separator string + + + +
+ + + + +
tree_Iterator (it, tr, n)
+
+ + + +

Parameters

+
    + +
  • + it: +
  • + +
  • + tr: +
  • + +
  • + n: current node +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. type ("leaf", "branch" (pre-order) or "join" (post-order)) + +
  2. path to node ({i1...ik}) + +
  3. node + +
+ + + +
+ + +
+ + + + +

Tables

+
+ +
_G.op
+
Functional forms of infix operators. Defined here so that other modules can write to it. + + + +
+ + +
+ + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/bin.html b/src/files/bin.html new file mode 100644 index 0000000..d6da0bb --- /dev/null +++ b/src/files/bin.html @@ -0,0 +1,332 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File bin.lua

+ + +

Binary data utilities

+ + + + + + +

Functions

+ + + + + + + + + + + + +
le_to_hex (s)Turn a little-endian word into a hex string
le_to_number (s)Turn a little-endian word into a number
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
le_to_hex (s)
+
+Turn a little-endian word into a hex string + + +

Parameters

+
    + +
  • + s: +
  • + +
+ + + + + + + + +
+ + + + +
le_to_number (s)
+
+Turn a little-endian word into a number + + +

Parameters

+
    + +
  • + s: +
  • + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/debug_ext.html b/src/files/debug_ext.html new file mode 100644 index 0000000..f0f8c97 --- /dev/null +++ b/src/files/debug_ext.html @@ -0,0 +1,407 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File debug_ext.lua

+ + +

Additions to the debug module

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + +
debug ()The global function debug is an abbreviation for debug.say (1, ...)
say (n, ...)Print a debugging message
trace (event)Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set.
+ + + + +

Tables

+ + + + + + + +
_DEBUGTo activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below.
+ + + +
+
+ + + + +

Functions

+
+ + + +
debug ()
+
+The global function debug is an abbreviation for debug.say (1, ...) + + + + + + + + + +

See also:

+ + +
+ + + + +
say (n, ...)
+
+Print a debugging message + + +

Parameters

+
    + +
  • + n: debugging level, defaults to 1 +
  • + +
  • + ...: objects to print (as for print) +
  • + +
+ + + + + + + + +
+ + + + +
trace (event)
+
+Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set. Based on test/trace-calls.lua from the Lua distribution. + + +

Parameters

+
    + +
  • + event: event causing the call +
  • + +
+ + + + + + + + +
+ + +
+ + + + +

Tables

+
+ +
_DEBUG
+
To activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below. + + +Fields +
    + +
  • + level: debugging level +
  • + +
  • + call: do call trace debugging +
  • + +
  • + std: do standard library debugging (run examples & test code) +
  • + +
+ + +
+ + +
+ + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/debug_init.html b/src/files/debug_init.html new file mode 100644 index 0000000..9e1d5f0 --- /dev/null +++ b/src/files/debug_init.html @@ -0,0 +1,258 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File debug_init.lua

+ + + + + + + + + + + + +
+
+ + + + + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/fstable.html b/src/files/fstable.html new file mode 100644 index 0000000..3dc07e5 --- /dev/null +++ b/src/files/fstable.html @@ -0,0 +1,308 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File fstable.lua

+ + +

Tables mapped to the filing system Only string keys are permitted; package.dirsep characters are converted to underscores. Values are stored as strings (converted by tostring). As with disk operations, a table's elements must be set to nil (deleted) before the table itself can be set to nil.

+ + + + + + +

Functions

+ + + + + + + +
new (path, t)Bind a directory to a table
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
new (path, t)
+
+Bind a directory to a table + + +

Parameters

+
    + +
  • + path: directory path +
  • + +
  • + t: table to merge with directory +
  • + +
+ + + + + + +

Return value:

+table bound to directory + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/getopt.html b/src/files/getopt.html new file mode 100644 index 0000000..41e1771 --- /dev/null +++ b/src/files/getopt.html @@ -0,0 +1,477 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File getopt.lua

+ + +

Simplified getopt, based on Svenne Panne's Haskell GetOpt.
Usage:

  • options = {Option {...}, ...}
    getopt.processArgs ()
  • Assumes prog = {name[, banner] [, purpose] [, notes] [, usage]}
  • Options take a single dash, but may have a double dash.
  • Arguments may be given as -opt=arg or -opt arg.
  • If an option taking an argument is given multiple times, only the last value is returned; missing arguments are returned as 1.
getOpt, usageInfo and usage can be called directly (see below, and the example at the end). Set _DEBUG.std to a non-nil value to run the example.
  • TODO: Sort out the packaging. getopt.Option is tedious to type, but surely Option shouldn't be in the root namespace?
  • TODO: Wrap all messages; do all wrapping in processArgs, not usageInfo; use sdoc-like library (see string.format todos).
  • TODO: Don't require name to be repeated in banner.
  • TODO: Store version separately (construct banner?).

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
getOpt (argIn, options)Perform argument processing
makeOptions (t)Options table constructor: adds lookup tables for the option names
processArgs ()Simple getOpt wrapper.
usage ()Emit a usage message.
usageInfo (header, optDesc, pageWidth)Produce usage info for the given options
+ + + + +

Tables

+ + + + + + + +
_G.OptionOptions table type.
+ + + +
+
+ + + + +

Functions

+
+ + + +
getOpt (argIn, options)
+
+Perform argument processing + + +

Parameters

+
    + +
  • + argIn: list of command-line args +
  • + +
  • + options: options table +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. table of remaining non-options + +
  2. table of option key-value list pairs + +
  3. table of error messages + +
+ + + +
+ + + + +
makeOptions (t)
+
+Options table constructor: adds lookup tables for the option names + + +

Parameters

+
    + +
  • + t: +
  • + +
+ + + + + + + + +
+ + + + +
processArgs ()
+
+Simple getOpt wrapper. Adds -version/-V and -help/-h automatically; stops program if there was an error, or if -help or -version was used. + + + + + + + + + +
+ + + + +
usage ()
+
+Emit a usage message. + + + + + + + + + +
+ + + + +
usageInfo (header, optDesc, pageWidth)
+
+Produce usage info for the given options + + +

Parameters

+
    + +
  • + header: header string +
  • + +
  • + optDesc: option descriptors +
  • + +
  • + pageWidth: width to format to [78] +
  • + +
+ + + + + + +

Return value:

+formatted string + + + +
+ + +
+ + + + +

Tables

+
+ +
_G.Option
+
Options table type. + + +Fields +
    + +
  • + name: list of names +
  • + +
  • + desc: description of this option +
  • + +
  • + type: type of argument (if any): Req(uired), Opt(ional) +
  • + +
  • + var: descriptive name for the argument +
  • + +
+ + +
+ + +
+ + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/io_ext.html b/src/files/io_ext.html new file mode 100644 index 0000000..7508eca --- /dev/null +++ b/src/files/io_ext.html @@ -0,0 +1,540 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File io_ext.lua

+ + +

Additions to the io module

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
catdir (...)Concatenate two or more directories into a path, removing the trailing slash.
catfile (...)Concatenate one or more directories and a filename into a path.
processFiles (f)Process files specified on the command-line.
readlines (h)Read a file or file handle into a list of lines.
shell (c)Perform a shell command and return its output.
slurp (h)Slurp a file handle.
splitdir (path)Split a directory path into components.
writelines (h, ...)Write values adding a newline after each.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
catdir (...)
+
+Concatenate two or more directories into a path, removing the trailing slash. + + +

Parameters

+
    + +
  • + ...: path components +
  • + +
+ + + + + + +

Return value:

+path + + + +
+ + + + +
catfile (...)
+
+Concatenate one or more directories and a filename into a path. + + +

Parameters

+
    + +
  • + ...: path components +
  • + +
+ + + + + + +

Return value:

+path + + + +
+ + + + +
processFiles (f)
+
+Process files specified on the command-line. If no files given, process io.stdin; in list of files, - means io.stdin.
FIXME: Make the file list an argument to the function. + + +

Parameters

+
    + +
  • + f: function to process files with, which is passed (name, arg_no) +
  • + +
+ + + + + + + + +
+ + + + +
readlines (h)
+
+Read a file or file handle into a list of lines. + + +

Parameters

+
    + +
  • + h: file handle or name (default: io.input ()); if h is a handle, the file is closed after reading +
  • + +
+ + + + + + +

Return value:

+list of lines + + + +
+ + + + +
shell (c)
+
+Perform a shell command and return its output. + + +

Parameters

+
    + +
  • + c: command +
  • + +
+ + + + + + +

Return value:

+output, or nil if error + + + +
+ + + + +
slurp (h)
+
+Slurp a file handle. + + +

Parameters

+
    + +
  • + h: file handle or name (default: io.input ()) +
  • + +
+ + + + + + +

Return value:

+contents of file or handle, or nil if error + + + +
+ + + + +
splitdir (path)
+
+Split a directory path into components. Empty components are retained: the root directory becomes {"", ""}. + + +

Parameters

+
    + +
  • + path: path +
  • + +
+ + + + + + +

Return value:

+list of path components + + + +
+ + + + +
writelines (h, ...)
+
+Write values adding a newline after each. + + +

Parameters

+
    + +
  • + h: file handle (default: io.output () +
  • + +
  • + ...: values to write (as for write) +
  • + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/lcs.html b/src/files/lcs.html new file mode 100644 index 0000000..8520885 --- /dev/null +++ b/src/files/lcs.html @@ -0,0 +1,312 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File lcs.lua

+ + +

Longest Common Subsequence algorithm. After pseudo-code in lecture notes by David Eppstein.

+ + + + + + +

Functions

+ + + + + + + +
longestCommonSubseq (a, b, s)Find the longest common subsequence of two sequences.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
longestCommonSubseq (a, b, s)
+
+Find the longest common subsequence of two sequences. The sequence objects must have an __append metamethod. This is provided by string_ext for strings, and by list for lists. + + +

Parameters

+
    + +
  • + a: first sequence +
  • + +
  • + b: second sequence +
  • + +
  • + s: an empty sequence of the same type, to hold the result +
  • + +
+ + + + + + +

Return value:

+the LCS of a and b + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/list.html b/src/files/list.html new file mode 100644 index 0000000..f14c8f7 --- /dev/null +++ b/src/files/list.html @@ -0,0 +1,1216 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File list.lua

+ + +

Tables as lists.

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
append (l, x)Append an item to a list.
compare (l, m)Compare two lists element by element left-to-right
concat (...)Concatenate lists.
cons (l, x)Prepend an item to a list.
depair (ls)Turn a list of pairs into a table.
elems (l)An iterator over the elements of a list.
enpair (t)Turn a table into a list of pairs.
filter (p, l)Filter a list according to a predicate.
flatten (l)Flatten a list.
foldl (f, e, l)Fold a binary function through a list left associatively.
foldr (f, e, l)Fold a binary function through a list right associatively.
indexKey (f, l)Make an index of a list of tables on a given field
indexValue (f, l)Copy a list of tables, indexed on a given field
map (f, l)Map a function over a list.
mapWith (f, l, ls)Map a function over a list of lists.
new (l, t)List constructor.
project (f, l)Project a list of fields from a list of tables.
relems (l)An iterator over the elements of a list, in reverse.
rep (l, n)Repeat a list.
reverse (l)Reverse a list.
shape (s, l)Shape a list according to a list of dimensions.
slice (l, from, to)Return a slice of a list.
tail (l)Return a list with its first element removed.
transpose (ls)Transpose a list of lists.
zipWith (f, ls)Zip lists together with a function.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
append (l, x)
+
+Append an item to a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + x: item +
  • + +
+ + + + + + +

Return value:

+{l[1], ..., l[#l], x} + + + +
+ + + + +
compare (l, m)
+
+Compare two lists element by element left-to-right + + +

Parameters

+
    + +
  • + l: first list +
  • + +
  • + m: second list +
  • + +
+ + + + + + +

Return value:

+-1 if l is less than m, 0 if they are the same, and 1 if l is greater than m + + + +
+ + + + +
concat (...)
+
+Concatenate lists. + + +

Parameters

+
    + +
  • + ...: lists +
  • + +
+ + + + + + +

Return value:

+{l1[1], ..., l1[#l1], ..., ln[1], ..., ln[#ln]} + + + +
+ + + + +
cons (l, x)
+
+Prepend an item to a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + x: item +
  • + +
+ + + + + + +

Return value:

+{x, unpack (l)} + + + +
+ + + + +
depair (ls)
+
+Turn a list of pairs into a table.
FIXME: Find a better name. + + +

Parameters

+
    + +
  • + ls: list {{i1, v1}, ..., {in, vn}} +
  • + +
+ + + + + + +

Return value:

+table {i1=v1, ..., in=vn} + + + +
+ + + + +
elems (l)
+
+An iterator over the elements of a list. + + +

Parameters

+
    + +
  • + l: list to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function which returns successive elements of the list + +
  2. the list l as above + +
  3. true + +
+ + + +
+ + + + +
enpair (t)
+
+Turn a table into a list of pairs.
FIXME: Find a better name. + + +

Parameters

+
    + +
  • + t: table {i1=v1, ..., in=vn} +
  • + +
+ + + + + + +

Return value:

+list {{i1, v1}, ..., {in, vn}} + + + +
+ + + + +
filter (p, l)
+
+Filter a list according to a predicate. + + +

Parameters

+
    + +
  • + p: predicate (function of one argument returning a boolean) +
  • + +
  • + l: list of lists +
  • + +
+ + + + + + +

Return value:

+result list containing elements e of l for which p (e) is true + + + +
+ + + + +
flatten (l)
+
+Flatten a list. + + +

Parameters

+
    + +
  • + l: list to flatten +
  • + +
+ + + + + + +

Return value:

+flattened list + + + +
+ + + + +
foldl (f, e, l)
+
+Fold a binary function through a list left associatively. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + e: element to place in left-most position +
  • + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+result + + + +
+ + + + +
foldr (f, e, l)
+
+Fold a binary function through a list right associatively. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + e: element to place in right-most position +
  • + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+result + + + +
+ + + + +
indexKey (f, l)
+
+Make an index of a list of tables on a given field + + +

Parameters

+
    + +
  • + f: field +
  • + +
  • + l: list of tables {t1, ..., tn} +
  • + +
+ + + + + + +

Return value:

+index {t1[f]=1, ..., tn[f]=n} + + + +
+ + + + +
indexValue (f, l)
+
+Copy a list of tables, indexed on a given field + + +

Parameters

+
    + +
  • + f: field whose value should be used as index +
  • + +
  • + l: list of tables {i1=t1, ..., in=tn} +
  • + +
+ + + + + + +

Return value:

+index {t1[f]=t1, ..., tn[f]=tn} + + + +
+ + + + +
map (f, l)
+
+Map a function over a list. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+result list {f (l[1]), ..., f (l[#l])} + + + +
+ + + + +
mapWith (f, l, ls)
+
+Map a function over a list of lists. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + l: +
  • + +
  • + ls: list of lists +
  • + +
+ + + + + + +

Return value:

+result list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} + + + +
+ + + + +
new (l, t)
+
+List constructor. Needed in order to use metamethods. + + +

Parameters

+
    + +
  • + l: +
  • + +
  • + t: list (as a table) +
  • + +
+ + + + + + +

Return value:

+list (with list metamethods) + + + +
+ + + + +
project (f, l)
+
+Project a list of fields from a list of tables. + + +

Parameters

+
    + +
  • + f: field to project +
  • + +
  • + l: list of tables +
  • + +
+ + + + + + +

Return value:

+list of f fields + + + +
+ + + + +
relems (l)
+
+An iterator over the elements of a list, in reverse. + + +

Parameters

+
    + +
  • + l: list to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function which returns precessive elements of the list + +
  2. the list l as above + +
  3. true + +
+ + + +
+ + + + +
rep (l, n)
+
+Repeat a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + n: number of times to repeat +
  • + +
+ + + + + + +

Return value:

+n copies of l appended together + + + +
+ + + + +
reverse (l)
+
+Reverse a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+list {l[#l], ..., l[1]} + + + +
+ + + + +
shape (s, l)
+
+Shape a list according to a list of dimensions. Dimensions are given outermost first and items from the original list are distributed breadth first; there may be one 0 indicating an indefinite number. Hence, {0} is a flat list, {1} is a singleton, {2, 0} is a list of two lists, and {0, 2} is a list of pairs.
Algorithm: turn shape into all positive numbers, calculating the zero if necessary and making sure there is at most one; recursively walk the shape, adding empty tables until the bottom level is reached at which point add table items instead, using a counter to walk the flattened original list.
+ + +

Parameters

+
    + +
  • + s: {d1, ..., dn} +
  • + +
  • + l: list to reshape +
  • + +
+ + + + + + +

Return value:

+reshaped list FIXME: Use ileaves instead of flatten (needs a while instead of a for in fill function) + + + +
+ + + + +
slice (l, from, to)
+
+Return a slice of a list. (Negative list indices count from the end of the list.) + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + from: start of slice (default: 1) +
  • + +
  • + to: end of slice (default: #l) +
  • + +
+ + + + + + +

Return value:

+{l[from], ..., l[to]} + + + +
+ + + + +
tail (l)
+
+Return a list with its first element removed. + + +

Parameters

+
    + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+{l[2], ..., l[#l]} + + + +
+ + + + +
transpose (ls)
+
+Transpose a list of lists. This function in Lua is equivalent to zip and unzip in more strongly typed languages. + + +

Parameters

+
    + +
  • + ls: {{l1,1, ..., l1,c}, ..., {lr,1, ..., lr,c}} +
  • + +
+ + + + + + +

Return value:

+{{l1,1, ..., lr,1}, ..., {l1,c, ..., lr,c}} + + + +
+ + + + +
zipWith (f, ls)
+
+Zip lists together with a function. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + ls: list of lists +
  • + +
+ + + + + + +

Return value:

+{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) where N = max {map (function (l) return #l end, ls)} + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/math_ext.html b/src/files/math_ext.html new file mode 100644 index 0000000..c7e1e58 --- /dev/null +++ b/src/files/math_ext.html @@ -0,0 +1,346 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File math_ext.lua

+ + +

Additions to the math module.

+ + + + + + +

Functions

+ + + + + + + + + + + + +
floor (n, p)Extend math.floor to take the number of decimal places.
round (n, p)Round a number to a given number of decimal places
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
floor (n, p)
+
+Extend math.floor to take the number of decimal places. + + +

Parameters

+
    + +
  • + n: number +
  • + +
  • + p: number of decimal places to truncate to (default: 0) +
  • + +
+ + + + + + +

Return value:

+n truncated to p decimal places + + + +
+ + + + +
round (n, p)
+
+Round a number to a given number of decimal places + + +

Parameters

+
    + +
  • + n: number +
  • + +
  • + p: number of decimal places to round to (default: 0) +
  • + +
+ + + + + + +

Return value:

+n rounded to p decimal places + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/mbox.html b/src/files/mbox.html new file mode 100644 index 0000000..3940403 --- /dev/null +++ b/src/files/mbox.html @@ -0,0 +1,304 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File mbox.lua

+ + +

mbox parser. Based on code by Diego Nahab.

+ + + + + + +

Functions

+ + + + + + + +
parse (s)Parse a mailbox into messages.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
parse (s)
+
+Parse a mailbox into messages. + + +

Parameters

+
    + +
  • + s: mailbox as a string +
  • + +
+ + + + + + +

Return value:

+list of messages, each of form {header = {...}, body = "..."} + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/modules.html b/src/files/modules.html new file mode 100644 index 0000000..2be7970 --- /dev/null +++ b/src/files/modules.html @@ -0,0 +1,258 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File modules.lua

+ + + + + + + + + + + + +
+
+ + + + + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/object.html b/src/files/object.html new file mode 100644 index 0000000..dc7ceef --- /dev/null +++ b/src/files/object.html @@ -0,0 +1,296 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File object.lua

+ + +

Prototype-based objects

  • Create an object/class:
    • Either, if the _init field is a list:
      • object/Class = prototype {value, ...; field = value, ...}
      • Named values are assigned to the corresponding fields, and unnamed values to the fields given by _init.
    • Or, if the _init field is a function:
      • object/Class = prototype (value, ...)
      • The given values are passed as arguments to the _init function.
    • An object's metatable is itself.
    • Private fields and methods start with "_".
  • Access an object field: object.field
  • Call an object method: object:method (...)
  • Call a class method: Class.method (object, ...)
  • Add a field: object.field = x
  • Add a method: function object:method (...) ... end
  • + + + + + + + + + +

    Tables

    + + + + + + + +
    ObjectRoot object
    + + + +
    +
    + + + + + + + +

    Tables

    +
    + +
    Object
    +
    Root object + + +Fields +
      + +
    • + _init: constructor method or list of fields to be initialised by the constructor +
    • + +
    • + _clone: object constructor which provides the behaviour for _init documented above +
    • + +
    + + +
    + + +
    + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/package_ext.html b/src/files/package_ext.html new file mode 100644 index 0000000..abf2c83 --- /dev/null +++ b/src/files/package_ext.html @@ -0,0 +1,308 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File package_ext.lua

+ + +

Make named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents).

+ + + + + + + + + +

Tables

+ + + + + + + +
packageMake named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents).
+ + + +
+
+ + + + + + + +

Tables

+
+ +
package
+
Make named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents). + + +Fields +
    + +
  • + dirsep: directory separator +
  • + +
  • + pathsep: path separator +
  • + +
  • + path_mark: string that marks substitution points in a path template +
  • + +
  • + execdir: (Windows only) replaced by the executable's directory in a path +
  • + +
  • + igmark: Mark to ignore all before it when building luaopen_ function name. +
  • + +
+ + +
+ + +
+ + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/parser.html b/src/files/parser.html new file mode 100644 index 0000000..251cbdf --- /dev/null +++ b/src/files/parser.html @@ -0,0 +1,346 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File parser.lua

+ + +

Parser generator.

A parser is created by

p = Parser {grammar}

and called with

result = p:parse (start_token, token_list[, from])

where start_token is the non-terminal at which to start parsing in the grammar, token_list is a list of tokens of the form

{ty = "token_type", tok = "token_text"}

and from is the token in the list from which to start (the default value is 1).

The output of the parser is a tree, each of whose nodes is of the form:

{ty = symbol, node1 = tree1, node2 = tree2, ... [, list]}

where each nodei is a symbolic name, and list is the list of trees returned if the corresponding token was a list token.

A grammar is a table of rules of the form

non-terminal = {production1, production2, ...}

plus a special item

lexemes = Set {"class1", "class2", ...}

Each production gives a form that a non-terminal may take. A production has the form

production = {"token1", "token2", ..., [action][,abstract]}

A production

  • must not start with the non-terminal being defined (it must not be left-recursive)
  • must not be a prefix of a later production in the same non-terminal

Each token may be

  • a non-terminal, i.e. a token defined by the grammar
    • an optional symbol is indicated by the suffix _opt
    • a list is indicated by the suffix _list, and may be followed by _≤separator-symbol> (default is no separator)
  • a lexeme class
  • a string to match literally

The parse tree for a literal string or lexeme class is the string that was matched. The parse tree for a non-terminal is a table of the form

{ty = "non_terminal_name", tree1, tree2, ...}

where the treei are the parse trees for the corresponding terminals and non-terminals.

An action is of the form

action = function (tree, token, pos) ... return tree_ end

It is passed the parse tree for the current node, the token list, and the current position in the token list, and returns a new parse tree.

An abstract syntax rule is of the form

name = {i1, i2, ...}

where i1, i2, ... are numbers. This results in a parse tree of the form

{ty = "name"; treei1, treei2, ...}

If a production has no abstract syntax rule, the result is the parse node for the current node.

FIXME: Give lexemes as an extra argument to Parser?
FIXME: Rename second argument to parse method to "tokens"?
FIXME: Make start_token an optional argument to parse? (swap with token list) and have it default to the first non-terminal?

+ + + + + + +

Functions

+ + + + + + + + + + + + +
Parser:_init (grammar)Parser constructor
Parser:parse (start, token, from)Parse a token list.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
Parser:_init (grammar)
+
+Parser constructor + + +

Parameters

+
    + +
  • + grammar: parser grammar +
  • + +
+ + + + + + +

Return value:

+parser + + + +
+ + + + +
Parser:parse (start, token, from)
+
+Parse a token list. + + +

Parameters

+
    + +
  • + start: the token at which to start +
  • + +
  • + token: the list of tokens +
  • + +
  • + from: the index of the token to start from (default: 1) +
  • + +
+ + + + + + +

Return value:

+parse tree + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/set.html b/src/files/set.html new file mode 100644 index 0000000..5e4697e --- /dev/null +++ b/src/files/set.html @@ -0,0 +1,644 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File set.lua

+ + +

Say whether an element is in a set

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
delete (s, e)Delete an element from a set
difference (s, t)Find the difference of two sets
equal (s, t)Find whether two sets are equal
insert (s, e)Insert an element into a set
intersection (s, t)Find the intersection of two sets
member (s, e)Say whether an element is in a set
propersubset (s, t)Find whether one set is a proper subset of another
subset (s, t)Find whether one set is a subset of another
symmetric_difference (s, t)Find the symmetric difference of two sets
union (s, t)Find the union of two sets
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
delete (s, e)
+
+Delete an element from a set + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + e: element +
  • + +
+ + + + + + + + +
+ + + + +
difference (s, t)
+
+Find the difference of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+s with elements of t removed + + + +
+ + + + +
equal (s, t)
+
+Find whether two sets are equal + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+true if sets are equal, false otherwise + + + +
+ + + + +
insert (s, e)
+
+Insert an element into a set + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + e: element +
  • + +
+ + + + + + + + +
+ + + + +
intersection (s, t)
+
+Find the intersection of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+set intersection of s and t + + + +
+ + + + +
member (s, e)
+
+Say whether an element is in a set + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + e: element +
  • + +
+ + + + + + +

Return value:

+true if e is in set, false otherwise + + + +
+ + + + +
propersubset (s, t)
+
+Find whether one set is a proper subset of another + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+true if s is a proper subset of t, false otherwise + + + +
+ + + + +
subset (s, t)
+
+Find whether one set is a subset of another + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+true if s is a subset of t, false otherwise + + + +
+ + + + +
symmetric_difference (s, t)
+
+Find the symmetric difference of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+elements of s and t that are in s or t but not both + + + +
+ + + + +
union (s, t)
+
+Find the union of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+set union of s and t + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/std.html b/src/files/std.html new file mode 100644 index 0000000..f69c3d9 --- /dev/null +++ b/src/files/std.html @@ -0,0 +1,260 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File std.lua

+ + +

Lua standard library

  • TODO: Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call error, not die; OO vs non-OO (a thorny problem).
  • TODO: Add tests for each function immediately after the function; this also helps to check module dependencies.
  • TODO: pre-compile.

+ + + + + + + + + + + +
+
+ + + + + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/strbuf.html b/src/files/strbuf.html new file mode 100644 index 0000000..1447797 --- /dev/null +++ b/src/files/strbuf.html @@ -0,0 +1,342 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File strbuf.lua

+ + +

String buffers

+ + + + + + +

Functions

+ + + + + + + + + + + + +
concat (b, s)Add a string to a buffer
tostring (b)Convert a buffer to a string
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
concat (b, s)
+
+Add a string to a buffer + + +

Parameters

+
    + +
  • + b: buffer +
  • + +
  • + s: string to add +
  • + +
+ + + + + + +

Return value:

+buffer + + + +
+ + + + +
tostring (b)
+
+Convert a buffer to a string + + +

Parameters

+
    + +
  • + b: buffer +
  • + +
+ + + + + + +

Return value:

+string + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/strict.html b/src/files/strict.html new file mode 100644 index 0000000..cbcf54a --- /dev/null +++ b/src/files/strict.html @@ -0,0 +1,258 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File strict.lua

+ + + + + + + + + + + + +
+
+ + + + + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/string_ext.html b/src/files/string_ext.html new file mode 100644 index 0000000..53621ee --- /dev/null +++ b/src/files/string_ext.html @@ -0,0 +1,769 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File string_ext.lua

+ + +

Additions to the string module TODO: Pretty printing (use in getopt); see source for details.

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
caps (s)Capitalise each word in a string.
chomp (s)Remove any final newline from a string.
escapePattern (s)Escape a string to be used as a pattern
finds (s, p, init, plain)Do multiple finds on a string.
ltrim (s, r)Remove leading matter from a string.
numbertosi (n)Write a number using SI suffixes.
ordinalSuffix (n)Return the English suffix for an ordinal.
pad (s, w, p)Justify a string.
rtrim (s, r)Remove trailing matter from a string.
split (s, sep)Split a string at a given separator.
tfind (s, p, init, plain)Do find, returning captures as a list.
trim (s, r)Remove leading and trailing matter from a string.
wrap (s, w, ind, ind1)Wrap a string into a paragraph.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
caps (s)
+
+Capitalise each word in a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
+ + + + + + +

Return value:

+capitalised string + + + +
+ + + + +
chomp (s)
+
+Remove any final newline from a string. + + +

Parameters

+
    + +
  • + s: string to process +
  • + +
+ + + + + + +

Return value:

+processed string + + + +
+ + + + +
escapePattern (s)
+
+Escape a string to be used as a pattern + + +

Parameters

+
    + +
  • + s: string to process @return +
  • + +
+ + + + + + + + +
+ + + + +
finds (s, p, init, plain)
+
+Do multiple finds on a string. + + +

Parameters

+
    + +
  • + s: target string +
  • + +
  • + p: pattern +
  • + +
  • + init: start position (default: 1) +
  • + +
  • + plain: inhibit magic characters (default: nil) +
  • + +
+ + + + + + +

Return value:

+list of {from, to; capt = {captures}} + + + +
+ + + + +
ltrim (s, r)
+
+Remove leading matter from a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
  • + r: leading regex (default: "%s+") +
  • + +
+ + + + + + +

Return value:

+string without leading r + + + +
+ + + + +
numbertosi (n)
+
+Write a number using SI suffixes. The number is always written to 3 s.f. + + +

Parameters

+
    + +
  • + n: number +
  • + +
+ + + + + + +

Return value:

+string + + + +
+ + + + +
ordinalSuffix (n)
+
+Return the English suffix for an ordinal. + + +

Parameters

+
    + +
  • + n: number of the day +
  • + +
+ + + + + + +

Return value:

+suffix + + + +
+ + + + +
pad (s, w, p)
+
+Justify a string. When the string is longer than w, it is truncated (left or right according to the sign of w). + + +

Parameters

+
    + +
  • + s: string to justify +
  • + +
  • + w: width to justify to (-ve means right-justify; +ve means left-justify) +
  • + +
  • + p: string to pad with (default: " ") +
  • + +
+ + + + + + +

Return value:

+justified string + + + +
+ + + + +
rtrim (s, r)
+
+Remove trailing matter from a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
  • + r: trailing regex (default: "%s+") +
  • + +
+ + + + + + +

Return value:

+string without trailing r + + + +
+ + + + +
split (s, sep)
+
+Split a string at a given separator. FIXME: Consider Perl and Python versions. + + +

Parameters

+
    + +
  • + s: string to split +
  • + +
  • + sep: separator regex +
  • + +
+ + + + + + +

Return value:

+list of strings + + + +
+ + + + +
tfind (s, p, init, plain)
+
+Do find, returning captures as a list. + + +

Parameters

+
    + +
  • + s: target string +
  • + +
  • + p: pattern +
  • + +
  • + init: start position (default: 1) +
  • + +
  • + plain: inhibit magic characters (default: nil) +
  • + +
+ + + + + + +

Return value:

+start of match, end of match, table of captures + + + +
+ + + + +
trim (s, r)
+
+Remove leading and trailing matter from a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
  • + r: leading/trailing regex (default: "%s+") +
  • + +
+ + + + + + +

Return value:

+string without leading/trailing r + + + +
+ + + + +
wrap (s, w, ind, ind1)
+
+Wrap a string into a paragraph. + + +

Parameters

+
    + +
  • + s: string to wrap +
  • + +
  • + w: width to wrap to (default: 78) +
  • + +
  • + ind: indent (default: 0) +
  • + +
  • + ind1: indent of first line (default: ind) +
  • + +
+ + + + + + +

Return value:

+wrapped paragraph + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/table_ext.html b/src/files/table_ext.html new file mode 100644 index 0000000..bb58dc0 --- /dev/null +++ b/src/files/table_ext.html @@ -0,0 +1,630 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File table_ext.lua

+ + +

Make table.sort return its result.

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
clone (t, nometa)Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone).
clone_rename (map, t)Clone a table, renaming some keys.
empty (t)Return whether table is empty.
invert (t)Invert a table.
keys (t)Make the list of keys of a table.
merge (t, u)Merge one table into another.
new (x, t)Make a table with a default value for unset keys.
size (t)Find the number of elements in a table.
sort (t, c)Make table.sort return its result.
values (t)Make the list of values of a table.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
clone (t, nometa)
+
+Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone). + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + nometa: if non-nil don't copy metatable +
  • + +
+ + + + + + +

Return value:

+copy of table + + + +
+ + + + +
clone_rename (map, t)
+
+Clone a table, renaming some keys. + + +

Parameters

+
    + +
  • + map: table {old_key=new_key, ...} +
  • + +
  • + t: table to copy +
  • + +
+ + + + + + +

Return value:

+copy of table + + + +
+ + + + +
empty (t)
+
+Return whether table is empty. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+true if empty or false otherwise + + + +
+ + + + +
invert (t)
+
+Invert a table. + + +

Parameters

+
    + +
  • + t: table {i=v, ...} +
  • + +
+ + + + + + +

Return value:

+inverted table {v=i, ...} + + + +
+ + + + +
keys (t)
+
+Make the list of keys of a table. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+list of keys + + + +
+ + + + +
merge (t, u)
+
+Merge one table into another. u is merged into t. + + +

Parameters

+
    + +
  • + t: first table +
  • + +
  • + u: second table +
  • + +
+ + + + + + +

Return value:

+first table + + + +
+ + + + +
new (x, t)
+
+Make a table with a default value for unset keys. + + +

Parameters

+
    + +
  • + x: default entry value (default: nil) +
  • + +
  • + t: initial table (default: {}) +
  • + +
+ + + + + + +

Return value:

+table whose unset elements are x + + + +
+ + + + +
size (t)
+
+Find the number of elements in a table. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+number of elements in t + + + +
+ + + + +
sort (t, c)
+
+Make table.sort return its result. + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + c: comparator function +
  • + +
+ + + + + + +

Return value:

+sorted table + + + +
+ + + + +
values (t)
+
+Make the list of values of a table. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+list of values + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/tree.html b/src/files/tree.html new file mode 100644 index 0000000..988feca --- /dev/null +++ b/src/files/tree.html @@ -0,0 +1,419 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File tree.lua

+ + +

Tables as trees.

+ + + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + +
clone (t, nometa)Make a deep copy of a tree, including any metatables
metatable.__index (tr, i)Tree __index metamethod.
metatable.__newindex (tr, i, v)Tree __newindex metamethod.
new (t)Make a table into a tree
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
clone (t, nometa)
+
+Make a deep copy of a tree, including any metatables + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + nometa: if non-nil don't copy metatables +
  • + +
+ + + + + + +

Return value:

+copy of table + + + +
+ + + + +
metatable.__index (tr, i)
+
+Tree __index metamethod. + + +

Parameters

+
    + +
  • + tr: tree +
  • + +
  • + i: non-table, or list of keys {i1 ... in} +
  • + +
+ + + + + + +

Return value:

+tr[i]...[in] if i is a table, or tr[i] otherwise + + + +
+ + + + +
metatable.__newindex (tr, i, v)
+
+Tree __newindex metamethod. Sets tr[i1]...[in] = v if i is a table, or tr[i] = v otherwise + + +

Parameters

+
    + +
  • + tr: tree +
  • + +
  • + i: non-table, or list of keys {i1 ... in} +
  • + +
  • + v: value +
  • + +
+ + + + + + + + +
+ + + + +
new (t)
+
+Make a table into a tree + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+tree + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/files/xml.html b/src/files/xml.html new file mode 100644 index 0000000..8767581 --- /dev/null +++ b/src/files/xml.html @@ -0,0 +1,307 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

File xml.lua

+ + + + + + + +

Functions

+ + + + + + + +
string.writeXML (t, indent, spacing)Write a table as XML.
+ + + + + + +
+
+ + + + +

Functions

+
+ + + +
string.writeXML (t, indent, spacing)
+
+Write a table as XML. The input format is assumed to be that output by luaexpat. + + +

Parameters

+
    + +
  • + t: table to print. In each element, tag is its name, attr is the table of attributes, and the sub-elements are held in the integer keys +
  • + +
  • + indent: indent between levels (default: "\t") +
  • + +
  • + spacing: space before every line +
  • + +
+ + + + + + + + +
+ + +
+ + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..c6675f6 --- /dev/null +++ b/src/index.html @@ -0,0 +1,464 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ + + +

Modules

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
baseAdds to the existing global functions
binBinary data utilities
debugAdditions to the debug module
fstableTables mapped to the filing system Only string keys are permitted; package.dirsep characters are converted to underscores.
getoptSimplified getopt, based on Svenne Panne's Haskell GetOpt.
Usage:
  • options = {Option {...}, ...}
    getopt.processArgs ()
  • Assumes prog = {name[, banner] [, purpose] [, notes] [, usage]}
  • Options take a single dash, but may have a double dash.
  • Arguments may be given as -opt=arg or -opt arg.
  • If an option taking an argument is given multiple times, only the last value is returned; missing arguments are returned as 1.
getOpt, usageInfo and usage can be called directly (see below, and the example at the end).
ioAdditions to the io module
lcsLongest Common Subsequence algorithm.
listTables as lists.
mathAdditions to the math module.
mboxmbox parser.
objectPrototype-based objects
  • Create an object/class:
    • Either, if the _init field is a list:
      • object/Class = prototype {value, ...; field = value, ...}
      • Named values are assigned to the corresponding fields, and unnamed values to the fields given by _init.
    • Or, if the _init field is a function:
      • object/Class = prototype (value, ...)
      • The given values are passed as arguments to the _init function.
    • An object's metatable is itself.
    • Private fields and methods start with "_".
  • Access an object field: object.field
  • Call an object method: object:method (...)
  • Call a class method: Class.method (object, ...)
  • Add a field: object.field = x
  • Add a method: function object:method (...) ...
package
parserParser generator.
set
stdLua standard library
  • TODO: Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call error, not die; OO vs non-OO (a thorny problem).
  • TODO: Add tests for each function immediately after the function; this also helps to check module dependencies.
  • TODO: pre-compile.
strbufString buffers
stringAdditions to the string module TODO: Pretty printing (use in getopt); see source for details.
table
treeTables as trees.
+ + + + + +

Files

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
base.lua
bin.lua
debug_ext.lua
debug_init.lua
fstable.lua
getopt.lua
io_ext.lua
lcs.lua
list.lua
math_ext.lua
mbox.lua
modules.lua
object.lua
package_ext.lua
parser.lua
set.lua
std.lua
strbuf.lua
strict.lua
string_ext.lua
table_ext.lua
tree.lua
xml.lua
+ + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/luadoc.css b/src/luadoc.css new file mode 100644 index 0000000..bc0f98a --- /dev/null +++ b/src/luadoc.css @@ -0,0 +1,286 @@ +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color:#ffffff; margin:0px; +} + +code { + font-family: "Andale Mono", monospace; +} + +tt { + font-family: "Andale Mono", monospace; +} + +body, td, th { font-size: 11pt; } + +h1, h2, h3, h4 { margin-left: 0em; } + +textarea, pre, tt { font-size:10pt; } +body, td, th { color:#000000; } +small { font-size:0.85em; } +h1 { font-size:1.5em; } +h2 { font-size:1.25em; } +h3 { font-size:1.15em; } +h4 { font-size:1.06em; } + +a:link { font-weight:bold; color: #004080; text-decoration: none; } +a:visited { font-weight:bold; color: #006699; text-decoration: none; } +a:link:hover { text-decoration:underline; } +hr { color:#cccccc } +img { border-width: 0px; } + + +h3 { padding-top: 1em; } + +p { margin-left: 1em; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; + margin-left: 0em; +} + +blockquote { margin-left: 3em; } + +pre.example { + background-color: rgb(245, 245, 245); + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-right-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-top-color: silver; + border-right-color: silver; + border-bottom-color: silver; + border-left-color: silver; + padding: 1em; + margin-left: 1em; + margin-right: 1em; + font-family: "Andale Mono", monospace; + font-size: smaller; +} + + +hr { + margin-left: 0em; + background: #00007f; + border: 0px; + height: 1px; +} + +ul { list-style-type: disc; } + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } +table.index ul { padding-top: 0em; margin-top: 0em; } + +table { + border: 1px solid black; + border-collapse: collapse; + margin-left: auto; + margin-right: auto; +} +th { + border: 1px solid black; + padding: 0.5em; +} +td { + border: 1px solid black; + padding: 0.5em; +} +div.header, div.footer { margin-left: 0em; } + +#container +{ + margin-left: 1em; + margin-right: 1em; + background-color: #f0f0f0; +} + +#product +{ + text-align: center; + border-bottom: 1px solid #cccccc; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#product_logo +{ +} + +#product_name +{ +} + +#product_description +{ +} + +#main +{ + background-color: #f0f0f0; + border-left: 2px solid #cccccc; +} + +#navigation +{ + float: left; + width: 18em; + margin: 0; + vertical-align: top; + background-color: #f0f0f0; + overflow:visible; +} + +#navigation h1 { + background-color:#e7e7e7; + font-size:1.1em; + color:#000000; + text-align:left; + margin:0px; + padding:0.2em; + border-top:1px solid #dddddd; + border-bottom:1px solid #dddddd; +} + +#navigation ul +{ + font-size:1em; + list-style-type: none; + padding: 0; + margin: 1px; +} + +#navigation li +{ + text-indent: -1em; + margin: 0em 0em 0em 0.5em; + display: block; + padding: 3px 0px 0px 12px; +} + +#navigation li li a +{ + padding: 0px 3px 0px -1em; +} + +#content +{ + margin-left: 18em; + padding: 1em; + border-left: 2px solid #cccccc; + border-right: 2px solid #cccccc; + background-color: #ffffff; +} + +#about +{ + clear: both; + margin: 0; + padding: 5px; + border-top: 2px solid #cccccc; + background-color: #ffffff; +} + +@media print { + body { + font: 12pt "Times New Roman", "TimeNR", Times, serif; + } + a { font-weight:bold; color: #004080; text-decoration: underline; } + + #main { background-color: #ffffff; border-left: 0px; } + #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } + + #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } + + #navigation { display: none; + } + pre.example { + font-family: "Andale Mono", monospace; + font-size: 10pt; + page-break-inside: avoid; + } +} + +table.module_list td +{ + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.module_list td.name { background-color: #f0f0f0; } +table.module_list td.summary { width: 100%; } + +table.file_list +{ + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.file_list td +{ + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.file_list td.name { background-color: #f0f0f0; } +table.file_list td.summary { width: 100%; } + + +table.function_list +{ + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.function_list td +{ + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.function_list td.name { background-color: #f0f0f0; } +table.function_list td.summary { width: 100%; } + + +table.table_list +{ + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.table_list td +{ + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.table_list td.name { background-color: #f0f0f0; } +table.table_list td.summary { width: 100%; } + +dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.function dd {padding-bottom: 1em;} +dl.function h3 {padding: 0; margin: 0; font-size: medium;} + +dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.table dd {padding-bottom: 1em;} +dl.table h3 {padding: 0; margin: 0; font-size: medium;} + +#TODO: make module_list, file_list, function_list, table_list inherit from a list + diff --git a/src/modules/base.html b/src/modules/base.html new file mode 100644 index 0000000..f1aee30 --- /dev/null +++ b/src/modules/base.html @@ -0,0 +1,1591 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module base

+ +

Adds to the existing global functions

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_G.assert (v, f, ...)Extend to allow formatted arguments.
_G.bind (f, ...)Partially apply a function.
_G.collect (i, ...)Collect the results of an iterator.
_G.compose (..., f1...fn)Compose functions.
_G.curry (f, n)Curry a function.
_G.die (...)Die with error.
_G.eval (s)Evaluate a string.
_G.filter (p, i, ...)Filter an iterator with a predicate.
_G.fold (f, d, i, ...)Fold a binary function into an iterator.
_G.id (...)Identity function.
_G.ileaves (tr)Tree iterator which returns just numbered leaves, in order.
_G.inodes (tr)Tree iterator over numbered nodes, in order.
_G.leaves (tr)Tree iterator which returns just leaves.
_G.map (f, i, ...)Map a function over an iterator.
_G.memoize (fn)Memoize a function, by wrapping it in a functable.
_G.metamethod (x, n)Return given metamethod, if any, or nil.
_G.nodes (tr)Tree iterator.
_G.pack (...)Turn a tuple into a list.
_G.pickle (x)Convert a value to a string.
_G.prettytostring (t, indent, spacing)Pretty-print a table.
_G.render (x, open, close, elem, pair, sep, roots)Turn tables into strings with recursion detection.
_G.require_version (module, min, too_big, pattern)Require a module with a particular version
_G.ripairs (t)An iterator like ipairs, but in reverse.
_G.tostring (x)Extend tostring to work better on tables.
_G.totable (x)Turn an object into a table according to __totable metamethod.
_G.warn (...)Give warning with the name of program and file (if any).
render_CloseRenderer (t)
render_ElementRenderer (e)
render_OpenRenderer (t)
render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
render_SeparatorRenderer (t, i, v, j, w)
tree_Iterator (it, tr, n)
+ + + + +

Tables

+ + + + + + + +
_G.opFunctional forms of infix operators.
+ + + +
+
+ + + +

Functions

+
+ + + +
_G.assert (v, f, ...)
+
+Extend to allow formatted arguments. + + +

Parameters

+
    + +
  • + v: value to assert +
  • + +
  • + f: format +
  • + +
  • + ...: arguments to format +
  • + +
+ + + + + + +

Return value:

+value + + + +
+ + + + +
_G.bind (f, ...)
+
+Partially apply a function. + + +

Parameters

+
    + +
  • + f: function to apply partially +
  • + +
  • + ...: arguments to bind +
  • + +
+ + + + + + +

Return value:

+function with ai already bound + + + +
+ + + + +
_G.collect (i, ...)
+
+Collect the results of an iterator. + + +

Parameters

+
    + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+results of running the iterator on its arguments + + + +
+ + + + +
_G.compose (..., f1...fn)
+
+Compose functions. + + +

Parameters

+
    + +
  • + ...: +
  • + +
  • + f1...fn: functions to compose +
  • + +
+ + + + + + +

Return value:

+composition of f1 ... fn + + + +
+ + + + +
_G.curry (f, n)
+
+Curry a function. + + +

Parameters

+
    + +
  • + f: function to curry +
  • + +
  • + n: number of arguments +
  • + +
+ + + + + + +

Return value:

+curried version of f + + + +
+ + + + +
_G.die (...)
+
+Die with error. + + +

Parameters

+
    + +
  • + ...: arguments for format +
  • + +
+ + + + + + + + +
+ + + + +
_G.eval (s)
+
+Evaluate a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
+ + + + + + +

Return value:

+value of string + + + +
+ + + + +
_G.filter (p, i, ...)
+
+Filter an iterator with a predicate. + + +

Parameters

+
    + +
  • + p: predicate +
  • + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+result table containing elements e for which p (e) + + + +
+ + + + +
_G.fold (f, d, i, ...)
+
+Fold a binary function into an iterator. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + d: initial first argument +
  • + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+result + + + +
+ + + + +
_G.id (...)
+
+Identity function. + + +

Parameters

+
    + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+the arguments passed to the function + + + +
+ + + + +
_G.ileaves (tr)
+
+Tree iterator which returns just numbered leaves, in order. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +
+ + + + +
_G.inodes (tr)
+
+Tree iterator over numbered nodes, in order. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +

See also:

+ + +
+ + + + +
_G.leaves (tr)
+
+Tree iterator which returns just leaves. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +
+ + + + +
_G.map (f, i, ...)
+
+Map a function over an iterator. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + i: iterator +
  • + +
  • + ...: +
  • + +
+ + + + + + +

Return value:

+result table + + + +
+ + + + +
_G.memoize (fn)
+
+Memoize a function, by wrapping it in a functable. + + +

Parameters

+
    + +
  • + fn: function that returns a single result +
  • + +
+ + + + + + +

Return value:

+memoized function + + + +
+ + + + +
_G.metamethod (x, n)
+
+Return given metamethod, if any, or nil. + + +

Parameters

+
    + +
  • + x: object to get metamethod of +
  • + +
  • + n: name of metamethod to get +
  • + +
+ + + + + + +

Return value:

+metamethod function or nil if no metamethod or not a function + + + +
+ + + + +
_G.nodes (tr)
+
+Tree iterator. + + +

Parameters

+
    + +
  • + tr: tree to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the tree, as above + +
+ + + +

See also:

+ + +
+ + + + +
_G.pack (...)
+
+Turn a tuple into a list. + + +

Parameters

+
    + +
  • + ...: tuple +
  • + +
+ + + + + + +

Return value:

+list + + + +
+ + + + +
_G.pickle (x)
+
+Convert a value to a string. The string can be passed to dostring to retrieve the value.
TODO: Make it work for recursive tables. + + +

Parameters

+
    + +
  • + x: object to pickle +
  • + +
+ + + + + + +

Return value:

+string such that eval (s) is the same value as x + + + +
+ + + + +
_G.prettytostring (t, indent, spacing)
+
+Pretty-print a table. + + +

Parameters

+
    + +
  • + t: table to print +
  • + +
  • + indent: indent between levels ["\t"] +
  • + +
  • + spacing: space before every line +
  • + +
+ + + + + + +

Return value:

+pretty-printed string + + + +
+ + + + +
_G.render (x, open, close, elem, pair, sep, roots)
+
+Turn tables into strings with recursion detection. N.B. Functions calling render should not recurse, or recursion detection will not work. + + +

Parameters

+
    + +
  • + x: object to convert to string +
  • + +
  • + open: open table renderer +
  • + +
  • + close: close table renderer +
  • + +
  • + elem: element renderer +
  • + +
  • + pair: pair renderer +
  • + +
  • + sep: separator renderer +
  • + +
  • + roots: +
  • + +
+ + + + + + +

Return value:

+string representation + + + +

See also:

+ + +
+ + + + +
_G.require_version (module, min, too_big, pattern)
+
+Require a module with a particular version + + +

Parameters

+
    + +
  • + module: module to require +
  • + +
  • + min: lowest acceptable version (default: any) +
  • + +
  • + too_big: lowest version that is too big (default: none) +
  • + +
  • + pattern: +
  • + +
+ + + + + + + + +
+ + + + +
_G.ripairs (t)
+
+An iterator like ipairs, but in reverse. + + +

Parameters

+
    + +
  • + t: table to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function + +
  2. the table, as above + +
  3. #t + 1 + +
+ + + +
+ + + + +
_G.tostring (x)
+
+Extend tostring to work better on tables. + + +

Parameters

+
    + +
  • + x: object to convert to string +
  • + +
+ + + + + + +

Return value:

+string representation + + + +
+ + + + +
_G.totable (x)
+
+Turn an object into a table according to __totable metamethod. + + +

Parameters

+
    + +
  • + x: object to turn into a table +
  • + +
+ + + + + + +

Return value:

+table or nil + + + +
+ + + + +
_G.warn (...)
+
+Give warning with the name of program and file (if any). + + +

Parameters

+
    + +
  • + ...: arguments for format +
  • + +
+ + + + + + + + +
+ + + + +
render_CloseRenderer (t)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+close table string + + + +
+ + + + +
render_ElementRenderer (e)
+
+ + + +

Parameters

+
    + +
  • + e: element +
  • + +
+ + + + + + +

Return value:

+element string + + + +
+ + + + +
render_OpenRenderer (t)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+open table string + + + +
+ + + + +
render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + i: index +
  • + +
  • + v: value +
  • + +
  • + is: index string +
  • + +
  • + vs: value string +
  • + +
+ + + + + + +

Return value:

+element string + + + +
+ + + + +
render_SeparatorRenderer (t, i, v, j, w)
+
+ + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + i: preceding index (nil on first call) +
  • + +
  • + v: preceding value (nil on first call) +
  • + +
  • + j: following index (nil on last call) +
  • + +
  • + w: following value (nil on last call) +
  • + +
+ + + + + + +

Return value:

+separator string + + + +
+ + + + +
tree_Iterator (it, tr, n)
+
+ + + +

Parameters

+
    + +
  • + it: +
  • + +
  • + tr: +
  • + +
  • + n: current node +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. type ("leaf", "branch" (pre-order) or "join" (post-order)) + +
  2. path to node ({i1...ik}) + +
  3. node + +
+ + + +
+ + +
+ + + + +

Tables

+
+ +
_G.op
+
Functional forms of infix operators. Defined here so that other modules can write to it. + + + +
+ + +
+ + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/bin.html b/src/modules/bin.html new file mode 100644 index 0000000..3491814 --- /dev/null +++ b/src/modules/bin.html @@ -0,0 +1,328 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module bin

+ +

Binary data utilities

+ + + + + +

Functions

+ + + + + + + + + + + + +
le_to_hex (s)Turn a little-endian word into a hex string
le_to_number (s)Turn a little-endian word into a number
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
le_to_hex (s)
+
+Turn a little-endian word into a hex string + + +

Parameters

+
    + +
  • + s: +
  • + +
+ + + + + + + + +
+ + + + +
le_to_number (s)
+
+Turn a little-endian word into a number + + +

Parameters

+
    + +
  • + s: +
  • + +
+ + + + + + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/debug.html b/src/modules/debug.html new file mode 100644 index 0000000..494cb93 --- /dev/null +++ b/src/modules/debug.html @@ -0,0 +1,403 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module debug

+ +

Additions to the debug module

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + +
debug ()The global function debug is an abbreviation for debug.say (1, ...)
say (n, ...)Print a debugging message
trace (event)Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set.
+ + + + +

Tables

+ + + + + + + +
_DEBUGTo activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below.
+ + + +
+
+ + + +

Functions

+
+ + + +
debug ()
+
+The global function debug is an abbreviation for debug.say (1, ...) + + + + + + + + + +

See also:

+ + +
+ + + + +
say (n, ...)
+
+Print a debugging message + + +

Parameters

+
    + +
  • + n: debugging level, defaults to 1 +
  • + +
  • + ...: objects to print (as for print) +
  • + +
+ + + + + + + + +
+ + + + +
trace (event)
+
+Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set. Based on test/trace-calls.lua from the Lua distribution. + + +

Parameters

+
    + +
  • + event: event causing the call +
  • + +
+ + + + + + + + +
+ + +
+ + + + +

Tables

+
+ +
_DEBUG
+
To activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below. + + +Fields +
    + +
  • + level: debugging level +
  • + +
  • + call: do call trace debugging +
  • + +
  • + std: do standard library debugging (run examples & test code) +
  • + +
+ + +
+ + +
+ + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/fstable.html b/src/modules/fstable.html new file mode 100644 index 0000000..f998230 --- /dev/null +++ b/src/modules/fstable.html @@ -0,0 +1,304 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module fstable

+ +

Tables mapped to the filing system Only string keys are permitted; package.dirsep characters are converted to underscores. Values are stored as strings (converted by tostring). As with disk operations, a table's elements must be set to nil (deleted) before the table itself can be set to nil.

+ + + + + +

Functions

+ + + + + + + +
new (path, t)Bind a directory to a table
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
new (path, t)
+
+Bind a directory to a table + + +

Parameters

+
    + +
  • + path: directory path +
  • + +
  • + t: table to merge with directory +
  • + +
+ + + + + + +

Return value:

+table bound to directory + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/getopt.html b/src/modules/getopt.html new file mode 100644 index 0000000..0a6f18f --- /dev/null +++ b/src/modules/getopt.html @@ -0,0 +1,473 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module getopt

+ +

Simplified getopt, based on Svenne Panne's Haskell GetOpt.
Usage:

  • options = {Option {...}, ...}
    getopt.processArgs ()
  • Assumes prog = {name[, banner] [, purpose] [, notes] [, usage]}
  • Options take a single dash, but may have a double dash.
  • Arguments may be given as -opt=arg or -opt arg.
  • If an option taking an argument is given multiple times, only the last value is returned; missing arguments are returned as 1.
getOpt, usageInfo and usage can be called directly (see below, and the example at the end). Set _DEBUG.std to a non-nil value to run the example.
  • TODO: Sort out the packaging. getopt.Option is tedious to type, but surely Option shouldn't be in the root namespace?
  • TODO: Wrap all messages; do all wrapping in processArgs, not usageInfo; use sdoc-like library (see string.format todos).
  • TODO: Don't require name to be repeated in banner.
  • TODO: Store version separately (construct banner?).

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
getOpt (argIn, options)Perform argument processing
makeOptions (t)Options table constructor: adds lookup tables for the option names
processArgs ()Simple getOpt wrapper.
usage ()Emit a usage message.
usageInfo (header, optDesc, pageWidth)Produce usage info for the given options
+ + + + +

Tables

+ + + + + + + +
_G.OptionOptions table type.
+ + + +
+
+ + + +

Functions

+
+ + + +
getOpt (argIn, options)
+
+Perform argument processing + + +

Parameters

+
    + +
  • + argIn: list of command-line args +
  • + +
  • + options: options table +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. table of remaining non-options + +
  2. table of option key-value list pairs + +
  3. table of error messages + +
+ + + +
+ + + + +
makeOptions (t)
+
+Options table constructor: adds lookup tables for the option names + + +

Parameters

+
    + +
  • + t: +
  • + +
+ + + + + + + + +
+ + + + +
processArgs ()
+
+Simple getOpt wrapper. Adds -version/-V and -help/-h automatically; stops program if there was an error, or if -help or -version was used. + + + + + + + + + +
+ + + + +
usage ()
+
+Emit a usage message. + + + + + + + + + +
+ + + + +
usageInfo (header, optDesc, pageWidth)
+
+Produce usage info for the given options + + +

Parameters

+
    + +
  • + header: header string +
  • + +
  • + optDesc: option descriptors +
  • + +
  • + pageWidth: width to format to [78] +
  • + +
+ + + + + + +

Return value:

+formatted string + + + +
+ + +
+ + + + +

Tables

+
+ +
_G.Option
+
Options table type. + + +Fields +
    + +
  • + name: list of names +
  • + +
  • + desc: description of this option +
  • + +
  • + type: type of argument (if any): Req(uired), Opt(ional) +
  • + +
  • + var: descriptive name for the argument +
  • + +
+ + +
+ + +
+ + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/io.html b/src/modules/io.html new file mode 100644 index 0000000..554c0ee --- /dev/null +++ b/src/modules/io.html @@ -0,0 +1,536 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module io

+ +

Additions to the io module

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
catdir (...)Concatenate two or more directories into a path, removing the trailing slash.
catfile (...)Concatenate one or more directories and a filename into a path.
processFiles (f)Process files specified on the command-line.
readlines (h)Read a file or file handle into a list of lines.
shell (c)Perform a shell command and return its output.
slurp (h)Slurp a file handle.
splitdir (path)Split a directory path into components.
writelines (h, ...)Write values adding a newline after each.
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
catdir (...)
+
+Concatenate two or more directories into a path, removing the trailing slash. + + +

Parameters

+
    + +
  • + ...: path components +
  • + +
+ + + + + + +

Return value:

+path + + + +
+ + + + +
catfile (...)
+
+Concatenate one or more directories and a filename into a path. + + +

Parameters

+
    + +
  • + ...: path components +
  • + +
+ + + + + + +

Return value:

+path + + + +
+ + + + +
processFiles (f)
+
+Process files specified on the command-line. If no files given, process io.stdin; in list of files, - means io.stdin.
FIXME: Make the file list an argument to the function. + + +

Parameters

+
    + +
  • + f: function to process files with, which is passed (name, arg_no) +
  • + +
+ + + + + + + + +
+ + + + +
readlines (h)
+
+Read a file or file handle into a list of lines. + + +

Parameters

+
    + +
  • + h: file handle or name (default: io.input ()); if h is a handle, the file is closed after reading +
  • + +
+ + + + + + +

Return value:

+list of lines + + + +
+ + + + +
shell (c)
+
+Perform a shell command and return its output. + + +

Parameters

+
    + +
  • + c: command +
  • + +
+ + + + + + +

Return value:

+output, or nil if error + + + +
+ + + + +
slurp (h)
+
+Slurp a file handle. + + +

Parameters

+
    + +
  • + h: file handle or name (default: io.input ()) +
  • + +
+ + + + + + +

Return value:

+contents of file or handle, or nil if error + + + +
+ + + + +
splitdir (path)
+
+Split a directory path into components. Empty components are retained: the root directory becomes {"", ""}. + + +

Parameters

+
    + +
  • + path: path +
  • + +
+ + + + + + +

Return value:

+list of path components + + + +
+ + + + +
writelines (h, ...)
+
+Write values adding a newline after each. + + +

Parameters

+
    + +
  • + h: file handle (default: io.output () +
  • + +
  • + ...: values to write (as for write) +
  • + +
+ + + + + + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/lcs.html b/src/modules/lcs.html new file mode 100644 index 0000000..7dc03d2 --- /dev/null +++ b/src/modules/lcs.html @@ -0,0 +1,308 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module lcs

+ +

Longest Common Subsequence algorithm. After pseudo-code in lecture notes by David Eppstein.

+ + + + + +

Functions

+ + + + + + + +
longestCommonSubseq (a, b, s)Find the longest common subsequence of two sequences.
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
longestCommonSubseq (a, b, s)
+
+Find the longest common subsequence of two sequences. The sequence objects must have an __append metamethod. This is provided by string_ext for strings, and by list for lists. + + +

Parameters

+
    + +
  • + a: first sequence +
  • + +
  • + b: second sequence +
  • + +
  • + s: an empty sequence of the same type, to hold the result +
  • + +
+ + + + + + +

Return value:

+the LCS of a and b + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/list.html b/src/modules/list.html new file mode 100644 index 0000000..002336a --- /dev/null +++ b/src/modules/list.html @@ -0,0 +1,1212 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module list

+ +

Tables as lists.

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
append (l, x)Append an item to a list.
compare (l, m)Compare two lists element by element left-to-right
concat (...)Concatenate lists.
cons (l, x)Prepend an item to a list.
depair (ls)Turn a list of pairs into a table.
elems (l)An iterator over the elements of a list.
enpair (t)Turn a table into a list of pairs.
filter (p, l)Filter a list according to a predicate.
flatten (l)Flatten a list.
foldl (f, e, l)Fold a binary function through a list left associatively.
foldr (f, e, l)Fold a binary function through a list right associatively.
indexKey (f, l)Make an index of a list of tables on a given field
indexValue (f, l)Copy a list of tables, indexed on a given field
map (f, l)Map a function over a list.
mapWith (f, l, ls)Map a function over a list of lists.
new (l, t)List constructor.
project (f, l)Project a list of fields from a list of tables.
relems (l)An iterator over the elements of a list, in reverse.
rep (l, n)Repeat a list.
reverse (l)Reverse a list.
shape (s, l)Shape a list according to a list of dimensions.
slice (l, from, to)Return a slice of a list.
tail (l)Return a list with its first element removed.
transpose (ls)Transpose a list of lists.
zipWith (f, ls)Zip lists together with a function.
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
append (l, x)
+
+Append an item to a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + x: item +
  • + +
+ + + + + + +

Return value:

+{l[1], ..., l[#l], x} + + + +
+ + + + +
compare (l, m)
+
+Compare two lists element by element left-to-right + + +

Parameters

+
    + +
  • + l: first list +
  • + +
  • + m: second list +
  • + +
+ + + + + + +

Return value:

+-1 if l is less than m, 0 if they are the same, and 1 if l is greater than m + + + +
+ + + + +
concat (...)
+
+Concatenate lists. + + +

Parameters

+
    + +
  • + ...: lists +
  • + +
+ + + + + + +

Return value:

+{l1[1], ..., l1[#l1], ..., ln[1], ..., ln[#ln]} + + + +
+ + + + +
cons (l, x)
+
+Prepend an item to a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + x: item +
  • + +
+ + + + + + +

Return value:

+{x, unpack (l)} + + + +
+ + + + +
depair (ls)
+
+Turn a list of pairs into a table.
FIXME: Find a better name. + + +

Parameters

+
    + +
  • + ls: list {{i1, v1}, ..., {in, vn}} +
  • + +
+ + + + + + +

Return value:

+table {i1=v1, ..., in=vn} + + + +
+ + + + +
elems (l)
+
+An iterator over the elements of a list. + + +

Parameters

+
    + +
  • + l: list to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function which returns successive elements of the list + +
  2. the list l as above + +
  3. true + +
+ + + +
+ + + + +
enpair (t)
+
+Turn a table into a list of pairs.
FIXME: Find a better name. + + +

Parameters

+
    + +
  • + t: table {i1=v1, ..., in=vn} +
  • + +
+ + + + + + +

Return value:

+list {{i1, v1}, ..., {in, vn}} + + + +
+ + + + +
filter (p, l)
+
+Filter a list according to a predicate. + + +

Parameters

+
    + +
  • + p: predicate (function of one argument returning a boolean) +
  • + +
  • + l: list of lists +
  • + +
+ + + + + + +

Return value:

+result list containing elements e of l for which p (e) is true + + + +
+ + + + +
flatten (l)
+
+Flatten a list. + + +

Parameters

+
    + +
  • + l: list to flatten +
  • + +
+ + + + + + +

Return value:

+flattened list + + + +
+ + + + +
foldl (f, e, l)
+
+Fold a binary function through a list left associatively. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + e: element to place in left-most position +
  • + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+result + + + +
+ + + + +
foldr (f, e, l)
+
+Fold a binary function through a list right associatively. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + e: element to place in right-most position +
  • + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+result + + + +
+ + + + +
indexKey (f, l)
+
+Make an index of a list of tables on a given field + + +

Parameters

+
    + +
  • + f: field +
  • + +
  • + l: list of tables {t1, ..., tn} +
  • + +
+ + + + + + +

Return value:

+index {t1[f]=1, ..., tn[f]=n} + + + +
+ + + + +
indexValue (f, l)
+
+Copy a list of tables, indexed on a given field + + +

Parameters

+
    + +
  • + f: field whose value should be used as index +
  • + +
  • + l: list of tables {i1=t1, ..., in=tn} +
  • + +
+ + + + + + +

Return value:

+index {t1[f]=t1, ..., tn[f]=tn} + + + +
+ + + + +
map (f, l)
+
+Map a function over a list. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+result list {f (l[1]), ..., f (l[#l])} + + + +
+ + + + +
mapWith (f, l, ls)
+
+Map a function over a list of lists. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + l: +
  • + +
  • + ls: list of lists +
  • + +
+ + + + + + +

Return value:

+result list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} + + + +
+ + + + +
new (l, t)
+
+List constructor. Needed in order to use metamethods. + + +

Parameters

+
    + +
  • + l: +
  • + +
  • + t: list (as a table) +
  • + +
+ + + + + + +

Return value:

+list (with list metamethods) + + + +
+ + + + +
project (f, l)
+
+Project a list of fields from a list of tables. + + +

Parameters

+
    + +
  • + f: field to project +
  • + +
  • + l: list of tables +
  • + +
+ + + + + + +

Return value:

+list of f fields + + + +
+ + + + +
relems (l)
+
+An iterator over the elements of a list, in reverse. + + +

Parameters

+
    + +
  • + l: list to iterate over +
  • + +
+ + + + + + +

Return values:

+
    + +
  1. iterator function which returns precessive elements of the list + +
  2. the list l as above + +
  3. true + +
+ + + +
+ + + + +
rep (l, n)
+
+Repeat a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + n: number of times to repeat +
  • + +
+ + + + + + +

Return value:

+n copies of l appended together + + + +
+ + + + +
reverse (l)
+
+Reverse a list. + + +

Parameters

+
    + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+list {l[#l], ..., l[1]} + + + +
+ + + + +
shape (s, l)
+
+Shape a list according to a list of dimensions. Dimensions are given outermost first and items from the original list are distributed breadth first; there may be one 0 indicating an indefinite number. Hence, {0} is a flat list, {1} is a singleton, {2, 0} is a list of two lists, and {0, 2} is a list of pairs.
Algorithm: turn shape into all positive numbers, calculating the zero if necessary and making sure there is at most one; recursively walk the shape, adding empty tables until the bottom level is reached at which point add table items instead, using a counter to walk the flattened original list.
+ + +

Parameters

+
    + +
  • + s: {d1, ..., dn} +
  • + +
  • + l: list to reshape +
  • + +
+ + + + + + +

Return value:

+reshaped list FIXME: Use ileaves instead of flatten (needs a while instead of a for in fill function) + + + +
+ + + + +
slice (l, from, to)
+
+Return a slice of a list. (Negative list indices count from the end of the list.) + + +

Parameters

+
    + +
  • + l: list +
  • + +
  • + from: start of slice (default: 1) +
  • + +
  • + to: end of slice (default: #l) +
  • + +
+ + + + + + +

Return value:

+{l[from], ..., l[to]} + + + +
+ + + + +
tail (l)
+
+Return a list with its first element removed. + + +

Parameters

+
    + +
  • + l: list +
  • + +
+ + + + + + +

Return value:

+{l[2], ..., l[#l]} + + + +
+ + + + +
transpose (ls)
+
+Transpose a list of lists. This function in Lua is equivalent to zip and unzip in more strongly typed languages. + + +

Parameters

+
    + +
  • + ls: {{l1,1, ..., l1,c}, ..., {lr,1, ..., lr,c}} +
  • + +
+ + + + + + +

Return value:

+{{l1,1, ..., lr,1}, ..., {l1,c, ..., lr,c}} + + + +
+ + + + +
zipWith (f, ls)
+
+Zip lists together with a function. + + +

Parameters

+
    + +
  • + f: function +
  • + +
  • + ls: list of lists +
  • + +
+ + + + + + +

Return value:

+{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) where N = max {map (function (l) return #l end, ls)} + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/math.html b/src/modules/math.html new file mode 100644 index 0000000..91d1f35 --- /dev/null +++ b/src/modules/math.html @@ -0,0 +1,342 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module math

+ +

Additions to the math module.

+ + + + + +

Functions

+ + + + + + + + + + + + +
floor (n, p)Extend math.floor to take the number of decimal places.
round (n, p)Round a number to a given number of decimal places
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
floor (n, p)
+
+Extend math.floor to take the number of decimal places. + + +

Parameters

+
    + +
  • + n: number +
  • + +
  • + p: number of decimal places to truncate to (default: 0) +
  • + +
+ + + + + + +

Return value:

+n truncated to p decimal places + + + +
+ + + + +
round (n, p)
+
+Round a number to a given number of decimal places + + +

Parameters

+
    + +
  • + n: number +
  • + +
  • + p: number of decimal places to round to (default: 0) +
  • + +
+ + + + + + +

Return value:

+n rounded to p decimal places + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/mbox.html b/src/modules/mbox.html new file mode 100644 index 0000000..4e5d5ed --- /dev/null +++ b/src/modules/mbox.html @@ -0,0 +1,300 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module mbox

+ +

mbox parser. Based on code by Diego Nahab.

+ + + + + +

Functions

+ + + + + + + +
parse (s)Parse a mailbox into messages.
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
parse (s)
+
+Parse a mailbox into messages. + + +

Parameters

+
    + +
  • + s: mailbox as a string +
  • + +
+ + + + + + +

Return value:

+list of messages, each of form {header = {...}, body = "..."} + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/object.html b/src/modules/object.html new file mode 100644 index 0000000..6522980 --- /dev/null +++ b/src/modules/object.html @@ -0,0 +1,292 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module object

+ +

Prototype-based objects

  • Create an object/class:
    • Either, if the _init field is a list:
      • object/Class = prototype {value, ...; field = value, ...}
      • Named values are assigned to the corresponding fields, and unnamed values to the fields given by _init.
    • Or, if the _init field is a function:
      • object/Class = prototype (value, ...)
      • The given values are passed as arguments to the _init function.
    • An object's metatable is itself.
    • Private fields and methods start with "_".
  • Access an object field: object.field
  • Call an object method: object:method (...)
  • Call a class method: Class.method (object, ...)
  • Add a field: object.field = x
  • Add a method: function object:method (...) ... end
  • + + + + + + + + +

    Tables

    + + + + + + + +
    ObjectRoot object
    + + + +
    +
    + + + + + + +

    Tables

    +
    + +
    Object
    +
    Root object + + +Fields +
      + +
    • + _init: constructor method or list of fields to be initialised by the constructor +
    • + +
    • + _clone: object constructor which provides the behaviour for _init documented above +
    • + +
    + + +
    + + +
    + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/package.html b/src/modules/package.html new file mode 100644 index 0000000..3d284e4 --- /dev/null +++ b/src/modules/package.html @@ -0,0 +1,304 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module package

+ +

+ + + + + + + + +

Tables

+ + + + + + + +
packageMake named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents).
+ + + +
+
+ + + + + + +

Tables

+
+ +
package
+
Make named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents). + + +Fields +
    + +
  • + dirsep: directory separator +
  • + +
  • + pathsep: path separator +
  • + +
  • + path_mark: string that marks substitution points in a path template +
  • + +
  • + execdir: (Windows only) replaced by the executable's directory in a path +
  • + +
  • + igmark: Mark to ignore all before it when building luaopen_ function name. +
  • + +
+ + +
+ + +
+ + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/parser.html b/src/modules/parser.html new file mode 100644 index 0000000..9c6c08e --- /dev/null +++ b/src/modules/parser.html @@ -0,0 +1,342 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module parser

+ +

Parser generator.

A parser is created by

p = Parser {grammar}

and called with

result = p:parse (start_token, token_list[, from])

where start_token is the non-terminal at which to start parsing in the grammar, token_list is a list of tokens of the form

{ty = "token_type", tok = "token_text"}

and from is the token in the list from which to start (the default value is 1).

The output of the parser is a tree, each of whose nodes is of the form:

{ty = symbol, node1 = tree1, node2 = tree2, ... [, list]}

where each nodei is a symbolic name, and list is the list of trees returned if the corresponding token was a list token.

A grammar is a table of rules of the form

non-terminal = {production1, production2, ...}

plus a special item

lexemes = Set {"class1", "class2", ...}

Each production gives a form that a non-terminal may take. A production has the form

production = {"token1", "token2", ..., [action][,abstract]}

A production

  • must not start with the non-terminal being defined (it must not be left-recursive)
  • must not be a prefix of a later production in the same non-terminal

Each token may be

  • a non-terminal, i.e. a token defined by the grammar
    • an optional symbol is indicated by the suffix _opt
    • a list is indicated by the suffix _list, and may be followed by _≤separator-symbol> (default is no separator)
  • a lexeme class
  • a string to match literally

The parse tree for a literal string or lexeme class is the string that was matched. The parse tree for a non-terminal is a table of the form

{ty = "non_terminal_name", tree1, tree2, ...}

where the treei are the parse trees for the corresponding terminals and non-terminals.

An action is of the form

action = function (tree, token, pos) ... return tree_ end

It is passed the parse tree for the current node, the token list, and the current position in the token list, and returns a new parse tree.

An abstract syntax rule is of the form

name = {i1, i2, ...}

where i1, i2, ... are numbers. This results in a parse tree of the form

{ty = "name"; treei1, treei2, ...}

If a production has no abstract syntax rule, the result is the parse node for the current node.

FIXME: Give lexemes as an extra argument to Parser?
FIXME: Rename second argument to parse method to "tokens"?
FIXME: Make start_token an optional argument to parse? (swap with token list) and have it default to the first non-terminal?

+ + + + + +

Functions

+ + + + + + + + + + + + +
Parser:_init (grammar)Parser constructor
Parser:parse (start, token, from)Parse a token list.
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
Parser:_init (grammar)
+
+Parser constructor + + +

Parameters

+
    + +
  • + grammar: parser grammar +
  • + +
+ + + + + + +

Return value:

+parser + + + +
+ + + + +
Parser:parse (start, token, from)
+
+Parse a token list. + + +

Parameters

+
    + +
  • + start: the token at which to start +
  • + +
  • + token: the list of tokens +
  • + +
  • + from: the index of the token to start from (default: 1) +
  • + +
+ + + + + + +

Return value:

+parse tree + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/set.html b/src/modules/set.html new file mode 100644 index 0000000..90cd4e8 --- /dev/null +++ b/src/modules/set.html @@ -0,0 +1,640 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module set

+ +

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
delete (s, e)Delete an element from a set
difference (s, t)Find the difference of two sets
equal (s, t)Find whether two sets are equal
insert (s, e)Insert an element into a set
intersection (s, t)Find the intersection of two sets
member (s, e)Say whether an element is in a set
propersubset (s, t)Find whether one set is a proper subset of another
subset (s, t)Find whether one set is a subset of another
symmetric_difference (s, t)Find the symmetric difference of two sets
union (s, t)Find the union of two sets
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
delete (s, e)
+
+Delete an element from a set + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + e: element +
  • + +
+ + + + + + + + +
+ + + + +
difference (s, t)
+
+Find the difference of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+s with elements of t removed + + + +
+ + + + +
equal (s, t)
+
+Find whether two sets are equal + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+true if sets are equal, false otherwise + + + +
+ + + + +
insert (s, e)
+
+Insert an element into a set + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + e: element +
  • + +
+ + + + + + + + +
+ + + + +
intersection (s, t)
+
+Find the intersection of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+set intersection of s and t + + + +
+ + + + +
member (s, e)
+
+Say whether an element is in a set + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + e: element +
  • + +
+ + + + + + +

Return value:

+true if e is in set, false otherwise + + + +
+ + + + +
propersubset (s, t)
+
+Find whether one set is a proper subset of another + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+true if s is a proper subset of t, false otherwise + + + +
+ + + + +
subset (s, t)
+
+Find whether one set is a subset of another + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+true if s is a subset of t, false otherwise + + + +
+ + + + +
symmetric_difference (s, t)
+
+Find the symmetric difference of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+elements of s and t that are in s or t but not both + + + +
+ + + + +
union (s, t)
+
+Find the union of two sets + + +

Parameters

+
    + +
  • + s: set +
  • + +
  • + t: set +
  • + +
+ + + + + + +

Return value:

+set union of s and t + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/std.html b/src/modules/std.html new file mode 100644 index 0000000..907beef --- /dev/null +++ b/src/modules/std.html @@ -0,0 +1,256 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module std

+ +

Lua standard library

  • TODO: Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call error, not die; OO vs non-OO (a thorny problem).
  • TODO: Add tests for each function immediately after the function; this also helps to check module dependencies.
  • TODO: pre-compile.

+ + + + + + + + + + +
+
+ + + + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/strbuf.html b/src/modules/strbuf.html new file mode 100644 index 0000000..e6b6aca --- /dev/null +++ b/src/modules/strbuf.html @@ -0,0 +1,338 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module strbuf

+ +

String buffers

+ + + + + +

Functions

+ + + + + + + + + + + + +
concat (b, s)Add a string to a buffer
tostring (b)Convert a buffer to a string
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
concat (b, s)
+
+Add a string to a buffer + + +

Parameters

+
    + +
  • + b: buffer +
  • + +
  • + s: string to add +
  • + +
+ + + + + + +

Return value:

+buffer + + + +
+ + + + +
tostring (b)
+
+Convert a buffer to a string + + +

Parameters

+
    + +
  • + b: buffer +
  • + +
+ + + + + + +

Return value:

+string + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/string.html b/src/modules/string.html new file mode 100644 index 0000000..09103c7 --- /dev/null +++ b/src/modules/string.html @@ -0,0 +1,765 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module string

+ +

Additions to the string module TODO: Pretty printing (use in getopt); see source for details.

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
caps (s)Capitalise each word in a string.
chomp (s)Remove any final newline from a string.
escapePattern (s)Escape a string to be used as a pattern
finds (s, p, init, plain)Do multiple finds on a string.
ltrim (s, r)Remove leading matter from a string.
numbertosi (n)Write a number using SI suffixes.
ordinalSuffix (n)Return the English suffix for an ordinal.
pad (s, w, p)Justify a string.
rtrim (s, r)Remove trailing matter from a string.
split (s, sep)Split a string at a given separator.
tfind (s, p, init, plain)Do find, returning captures as a list.
trim (s, r)Remove leading and trailing matter from a string.
wrap (s, w, ind, ind1)Wrap a string into a paragraph.
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
caps (s)
+
+Capitalise each word in a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
+ + + + + + +

Return value:

+capitalised string + + + +
+ + + + +
chomp (s)
+
+Remove any final newline from a string. + + +

Parameters

+
    + +
  • + s: string to process +
  • + +
+ + + + + + +

Return value:

+processed string + + + +
+ + + + +
escapePattern (s)
+
+Escape a string to be used as a pattern + + +

Parameters

+
    + +
  • + s: string to process @return +
  • + +
+ + + + + + + + +
+ + + + +
finds (s, p, init, plain)
+
+Do multiple finds on a string. + + +

Parameters

+
    + +
  • + s: target string +
  • + +
  • + p: pattern +
  • + +
  • + init: start position (default: 1) +
  • + +
  • + plain: inhibit magic characters (default: nil) +
  • + +
+ + + + + + +

Return value:

+list of {from, to; capt = {captures}} + + + +
+ + + + +
ltrim (s, r)
+
+Remove leading matter from a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
  • + r: leading regex (default: "%s+") +
  • + +
+ + + + + + +

Return value:

+string without leading r + + + +
+ + + + +
numbertosi (n)
+
+Write a number using SI suffixes. The number is always written to 3 s.f. + + +

Parameters

+
    + +
  • + n: number +
  • + +
+ + + + + + +

Return value:

+string + + + +
+ + + + +
ordinalSuffix (n)
+
+Return the English suffix for an ordinal. + + +

Parameters

+
    + +
  • + n: number of the day +
  • + +
+ + + + + + +

Return value:

+suffix + + + +
+ + + + +
pad (s, w, p)
+
+Justify a string. When the string is longer than w, it is truncated (left or right according to the sign of w). + + +

Parameters

+
    + +
  • + s: string to justify +
  • + +
  • + w: width to justify to (-ve means right-justify; +ve means left-justify) +
  • + +
  • + p: string to pad with (default: " ") +
  • + +
+ + + + + + +

Return value:

+justified string + + + +
+ + + + +
rtrim (s, r)
+
+Remove trailing matter from a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
  • + r: trailing regex (default: "%s+") +
  • + +
+ + + + + + +

Return value:

+string without trailing r + + + +
+ + + + +
split (s, sep)
+
+Split a string at a given separator. FIXME: Consider Perl and Python versions. + + +

Parameters

+
    + +
  • + s: string to split +
  • + +
  • + sep: separator regex +
  • + +
+ + + + + + +

Return value:

+list of strings + + + +
+ + + + +
tfind (s, p, init, plain)
+
+Do find, returning captures as a list. + + +

Parameters

+
    + +
  • + s: target string +
  • + +
  • + p: pattern +
  • + +
  • + init: start position (default: 1) +
  • + +
  • + plain: inhibit magic characters (default: nil) +
  • + +
+ + + + + + +

Return value:

+start of match, end of match, table of captures + + + +
+ + + + +
trim (s, r)
+
+Remove leading and trailing matter from a string. + + +

Parameters

+
    + +
  • + s: string +
  • + +
  • + r: leading/trailing regex (default: "%s+") +
  • + +
+ + + + + + +

Return value:

+string without leading/trailing r + + + +
+ + + + +
wrap (s, w, ind, ind1)
+
+Wrap a string into a paragraph. + + +

Parameters

+
    + +
  • + s: string to wrap +
  • + +
  • + w: width to wrap to (default: 78) +
  • + +
  • + ind: indent (default: 0) +
  • + +
  • + ind1: indent of first line (default: ind) +
  • + +
+ + + + + + +

Return value:

+wrapped paragraph + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/table.html b/src/modules/table.html new file mode 100644 index 0000000..85f660d --- /dev/null +++ b/src/modules/table.html @@ -0,0 +1,626 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module table

+ +

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
clone (t, nometa)Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone).
clone_rename (map, t)Clone a table, renaming some keys.
empty (t)Return whether table is empty.
invert (t)Invert a table.
keys (t)Make the list of keys of a table.
merge (t, u)Merge one table into another.
new (x, t)Make a table with a default value for unset keys.
size (t)Find the number of elements in a table.
sort (t, c)Make table.sort return its result.
values (t)Make the list of values of a table.
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
clone (t, nometa)
+
+Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone). + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + nometa: if non-nil don't copy metatable +
  • + +
+ + + + + + +

Return value:

+copy of table + + + +
+ + + + +
clone_rename (map, t)
+
+Clone a table, renaming some keys. + + +

Parameters

+
    + +
  • + map: table {old_key=new_key, ...} +
  • + +
  • + t: table to copy +
  • + +
+ + + + + + +

Return value:

+copy of table + + + +
+ + + + +
empty (t)
+
+Return whether table is empty. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+true if empty or false otherwise + + + +
+ + + + +
invert (t)
+
+Invert a table. + + +

Parameters

+
    + +
  • + t: table {i=v, ...} +
  • + +
+ + + + + + +

Return value:

+inverted table {v=i, ...} + + + +
+ + + + +
keys (t)
+
+Make the list of keys of a table. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+list of keys + + + +
+ + + + +
merge (t, u)
+
+Merge one table into another. u is merged into t. + + +

Parameters

+
    + +
  • + t: first table +
  • + +
  • + u: second table +
  • + +
+ + + + + + +

Return value:

+first table + + + +
+ + + + +
new (x, t)
+
+Make a table with a default value for unset keys. + + +

Parameters

+
    + +
  • + x: default entry value (default: nil) +
  • + +
  • + t: initial table (default: {}) +
  • + +
+ + + + + + +

Return value:

+table whose unset elements are x + + + +
+ + + + +
size (t)
+
+Find the number of elements in a table. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+number of elements in t + + + +
+ + + + +
sort (t, c)
+
+Make table.sort return its result. + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + c: comparator function +
  • + +
+ + + + + + +

Return value:

+sorted table + + + +
+ + + + +
values (t)
+
+Make the list of values of a table. + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+list of values + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/modules/tree.html b/src/modules/tree.html new file mode 100644 index 0000000..543f3b6 --- /dev/null +++ b/src/modules/tree.html @@ -0,0 +1,415 @@ + + + + Reference + + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ +

Module tree

+ +

Tables as trees.

+ + + + + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + +
clone (t, nometa)Make a deep copy of a tree, including any metatables
metatable.__index (tr, i)Tree __index metamethod.
metatable.__newindex (tr, i, v)Tree __newindex metamethod.
new (t)Make a table into a tree
+ + + + + + +
+
+ + + +

Functions

+
+ + + +
clone (t, nometa)
+
+Make a deep copy of a tree, including any metatables + + +

Parameters

+
    + +
  • + t: table +
  • + +
  • + nometa: if non-nil don't copy metatables +
  • + +
+ + + + + + +

Return value:

+copy of table + + + +
+ + + + +
metatable.__index (tr, i)
+
+Tree __index metamethod. + + +

Parameters

+
    + +
  • + tr: tree +
  • + +
  • + i: non-table, or list of keys {i1 ... in} +
  • + +
+ + + + + + +

Return value:

+tr[i]...[in] if i is a table, or tr[i] otherwise + + + +
+ + + + +
metatable.__newindex (tr, i, v)
+
+Tree __newindex metamethod. Sets tr[i1]...[in] = v if i is a table, or tr[i] = v otherwise + + +

Parameters

+
    + +
  • + tr: tree +
  • + +
  • + i: non-table, or list of keys {i1 ... in} +
  • + +
  • + v: value +
  • + +
+ + + + + + + + +
+ + + + +
new (t)
+
+Make a table into a tree + + +

Parameters

+
    + +
  • + t: table +
  • + +
+ + + + + + +

Return value:

+tree + + + +
+ + +
+ + + + + + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/src/std.lua b/src/std.lua new file mode 100644 index 0000000..9bbf5a3 --- /dev/null +++ b/src/std.lua @@ -0,0 +1,16 @@ +--- Lua standard library +--
    +--
  • TODO: Write a style guide (indenting/wrapping, capitalisation, +-- function and variable names); library functions should call +-- error, not die; OO vs non-OO (a thorny problem).
  • +--
  • TODO: Add tests for each function immediately after the function; +-- this also helps to check module dependencies.
  • +--
  • TODO: pre-compile.
  • +--
+module ("std", package.seeall) + +version = "General Lua libraries / 29" + +for _, m in ipairs (require "modules") do + require (m) +end From b6e14db43d62bb7db757de54eeb05911f2975fe9 Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Thu, 7 Feb 2013 13:13:52 +0000 Subject: [PATCH 05/34] Add changes that prevent documentation being rebuilt during build from release sources. --- Makefile.am | 19 +++++++++++++++++-- Makefile.in | 26 +++++++++++++++++++------- configure | 3 +-- configure.ac | 2 +- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9bee4ca..f259afc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,12 +21,23 @@ DISTCLEANFILES = $(PACKAGE).rockspec ROCKSPEC = $(PACKAGE)-$(VERSION)-1.rockspec +# In order to avoid regenerating std.lua at configure time, which +# causes the documentation to be rebuilt and hence requires users to +# have luadoc installed, put src/std.lua in as a Makefile dependency. +# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) +src/std.lua: src/std.lua.in + ./config.status --file=$@ + $(dist_doc_DATA): $(SOURCES) cd src && luadoc *.lua $(ROCKSPEC): $(PACKAGE).rockspec cp $< $@ +bootstrap: + autoreconf -i && \ + ./configure + tag-release: git diff --exit-code && \ git tag -a -m "Release tag" v$(VERSION) && \ @@ -37,12 +48,16 @@ check-in-release: distcheck tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ cp -af $(PACKAGE)-$(VERSION)/* . && \ git add . && git ci -m "Release v$(VERSION)" && \ - git tag -a -m "Release tag" release-v$(VERSION) && \ + git tag -a -m "Full source release tag" release-v$(VERSION) && \ git push && git push --tags && \ - git checkout master + git checkout master && \ + rm -rf $(PACKAGE)-$(VERSION)/ +# After check-in-release we need to bootstrap to get the build files back release: $(ROCKSPEC) $(MAKE) tag-release && \ $(MAKE) check-in-release && \ + $(MAKE) bootstrap && \ + $(MAKE) $(ROCKSPEC) && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(ROCKSPEC) && \ woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" diff --git a/Makefile.in b/Makefile.in index d8d5f7c..df73add 100644 --- a/Makefile.in +++ b/Makefile.in @@ -54,8 +54,7 @@ DIST_COMMON = README $(am__configure_deps) $(dist_data_DATA) \ $(dist_doc_DATA) $(dist_files_DATA) $(dist_modules_DATA) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/luarocks-config.lua.in $(top_srcdir)/configure \ - $(top_srcdir)/src/std.lua.in AUTHORS INSTALL \ - build-aux/install-sh build-aux/missing + AUTHORS INSTALL build-aux/install-sh build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/configure.ac @@ -64,7 +63,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = luarocks-config.lua src/std.lua +CONFIG_CLEAN_FILES = luarocks-config.lua CONFIG_CLEAN_VPATH_FILES = AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) @@ -264,8 +263,6 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): luarocks-config.lua: $(top_builddir)/config.status $(srcdir)/luarocks-config.lua.in cd $(top_builddir) && $(SHELL) ./config.status $@ -src/std.lua: $(top_builddir)/config.status $(top_srcdir)/src/std.lua.in - cd $(top_builddir) && $(SHELL) ./config.status $@ install-dist_dataDATA: $(dist_data_DATA) @$(NORMAL_INSTALL) @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ @@ -648,12 +645,23 @@ uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ uninstall-dist_modulesDATA +# In order to avoid regenerating std.lua at configure time, which +# causes the documentation to be rebuilt and hence requires users to +# have luadoc installed, put src/std.lua in as a Makefile dependency. +# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) +src/std.lua: src/std.lua.in + ./config.status --file=$@ + $(dist_doc_DATA): $(SOURCES) cd src && luadoc *.lua $(ROCKSPEC): $(PACKAGE).rockspec cp $< $@ +bootstrap: + autoreconf -i && \ + ./configure + tag-release: git diff --exit-code && \ git tag -a -m "Release tag" v$(VERSION) && \ @@ -664,13 +672,17 @@ check-in-release: distcheck tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ cp -af $(PACKAGE)-$(VERSION)/* . && \ git add . && git ci -m "Release v$(VERSION)" && \ - git tag -a -m "Release tag" release-v$(VERSION) && \ + git tag -a -m "Full source release tag" release-v$(VERSION) && \ git push && git push --tags && \ - git checkout master + git checkout master && \ + rm -rf $(PACKAGE)-$(VERSION)/ +# After check-in-release we need to bootstrap to get the build files back release: $(ROCKSPEC) $(MAKE) tag-release && \ $(MAKE) check-in-release && \ + $(MAKE) bootstrap && \ + $(MAKE) $(ROCKSPEC) && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(ROCKSPEC) && \ woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" diff --git a/configure b/configure index 951dfb8..3129e87 100755 --- a/configure +++ b/configure @@ -2674,7 +2674,7 @@ fi -ac_config_files="$ac_config_files Makefile $PACKAGE.rockspec luarocks-config.lua src/std.lua" +ac_config_files="$ac_config_files Makefile $PACKAGE.rockspec luarocks-config.lua" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -3388,7 +3388,6 @@ do "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "$PACKAGE.rockspec") CONFIG_FILES="$CONFIG_FILES $PACKAGE.rockspec" ;; "luarocks-config.lua") CONFIG_FILES="$CONFIG_FILES luarocks-config.lua" ;; - "src/std.lua") CONFIG_FILES="$CONFIG_FILES src/std.lua" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index 9970100..0a52be1 100644 --- a/configure.ac +++ b/configure.ac @@ -12,5 +12,5 @@ AX_PROG_LUA([$LUA_MIN_VERSION], [5.3]) dnl Generate output files AC_CONFIG_MACRO_DIR(m4) -AC_CONFIG_FILES(Makefile $PACKAGE.rockspec luarocks-config.lua src/std.lua) +AC_CONFIG_FILES(Makefile $PACKAGE.rockspec luarocks-config.lua) AC_OUTPUT From 4d54e5ffe7b0c14367460c46d8f505cd99f37462 Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Sun, 17 Feb 2013 23:15:58 +0000 Subject: [PATCH 06/34] Release v30 --- Makefile.am | 19 +- Makefile.in | 195 ++++++-------------- aclocal.m4 | 291 ++++++++++++++++-------------- build-aux/install-sh | 14 +- build-aux/missing | 414 +++++++++++++++++++++++++++---------------- configure | 146 +++++---------- 6 files changed, 535 insertions(+), 544 deletions(-) diff --git a/Makefile.am b/Makefile.am index 578ea34..77b1b10 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,8 @@ ACLOCAL_AMFLAGS = -I m4 LUA_PATH ?= ; LUA_ENV = LUA_PATH="$(abs_srcdir)/src/?.lua;$(LUA_PATH)" -SOURCES = $(wildcard $(srcdir)/src/*.lua) $(srcdir)/src/std.lua +SOURCES = $(filter-out $(srcdir)/src/std.lua, $(wildcard $(srcdir)/src/*.lua)) +SOURCES += $(srcdir)/src/std.lua dist_data_DATA = $(SOURCES) dist_doc_DATA = \ @@ -17,8 +18,7 @@ modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ - src/std.lua.in \ - $(PACKAGE).rockspec.in + src/std.lua.in DISTCLEANFILES = $(PACKAGE).rockspec @@ -47,20 +47,17 @@ tag-release: git push && git push --tags check-in-release: distcheck - git checkout release && \ - tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cd ../lua-stdlib-release && \ + tar zxf ../lua-stdlib/$(PACKAGE)-$(VERSION).tar.gz && \ cp -af $(PACKAGE)-$(VERSION)/* . && \ + rm -rf $(PACKAGE)-$(VERSION)/ && \ git add . && git ci -m "Release v$(VERSION)" && \ git tag -a -m "Full source release tag" release-v$(VERSION) && \ - git push && git push --tags && \ - git checkout master && \ - rm -rf $(PACKAGE)-$(VERSION)/ + git push && git push --tags # After check-in-release we need to bootstrap to get the build files back release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ - $(MAKE) bootstrap && \ - $(MAKE) rockspecs && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" diff --git a/Makefile.in b/Makefile.in index 88f9ecb..d0d9a60 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.13.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. - +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -49,13 +50,11 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/luarocks-config.lua.in $(dist_data_DATA) \ +DIST_COMMON = README $(am__configure_deps) $(dist_data_DATA) \ $(dist_doc_DATA) $(dist_files_DATA) $(dist_modules_DATA) \ - AUTHORS INSTALL README build-aux/install-sh build-aux/missing \ - $(top_srcdir)/build-aux/install-sh \ - $(top_srcdir)/build-aux/missing + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/luarocks-config.lua.in $(top_srcdir)/configure \ + AUTHORS INSTALL build-aux/install-sh build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/m4/ax_with_prog.m4 \ @@ -67,18 +66,12 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = luarocks-config.lua CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = +am__v_GEN_0 = @echo " GEN " $@; AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ -am__v_at_1 = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -116,27 +109,6 @@ am__installdirs = "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)" DATA = $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ $(dist_modules_DATA) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -146,10 +118,8 @@ am__remove_distdir = \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi -am__post_remove_distdir = $(am__remove_distdir) DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best -DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -241,7 +211,8 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 LUA_ENV = LUA_PATH="$(abs_srcdir)/src/?.lua;$(LUA_PATH)" -SOURCES = $(wildcard $(srcdir)/src/*.lua) $(srcdir)/src/std.lua +SOURCES = $(filter-out $(srcdir)/src/std.lua, $(wildcard \ + $(srcdir)/src/*.lua)) $(srcdir)/src/std.lua dist_data_DATA = $(SOURCES) dist_doc_DATA = \ $(top_srcdir)/src/index.html \ @@ -252,8 +223,7 @@ dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ - src/std.lua.in \ - $(PACKAGE).rockspec.in + src/std.lua.in DISTCLEANFILES = $(PACKAGE).rockspec all: all-am @@ -379,65 +349,12 @@ uninstall-dist_modulesDATA: @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files +ctags: CTAGS +CTAGS: -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) @@ -480,36 +397,40 @@ distdir: $(DISTFILES) || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) + $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) + $(am__remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) + $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) + $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) + $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) + $(am__remove_distdir) -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -520,6 +441,8 @@ distcheck: dist GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ @@ -531,9 +454,9 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst + chmod -R a-w $(distdir); chmod u+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ @@ -565,7 +488,7 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__post_remove_distdir) + $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' @@ -640,7 +563,7 @@ clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags +distclean-am: clean-am distclean-generic dvi: dvi-am @@ -706,23 +629,22 @@ uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ - clean-cscope clean-generic cscope cscopelist-am ctags ctags-am \ - dist dist-all dist-bzip2 dist-gzip dist-lzip dist-shar \ +.PHONY: all all-am am--refresh check check-am clean clean-generic dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-generic distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_dataDATA install-dist_docDATA \ - install-dist_filesDATA install-dist_modulesDATA install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-dist_dataDATA uninstall-dist_docDATA \ - uninstall-dist_filesDATA uninstall-dist_modulesDATA + distclean-generic distcleancheck distdir distuninstallcheck \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_dataDATA \ + install-dist_docDATA install-dist_filesDATA \ + install-dist_modulesDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am uninstall uninstall-am uninstall-dist_dataDATA \ + uninstall-dist_docDATA uninstall-dist_filesDATA \ + uninstall-dist_modulesDATA LUA_PATH ?= ; @@ -752,23 +674,20 @@ tag-release: git push && git push --tags check-in-release: distcheck - git checkout release && \ - tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cd ../lua-stdlib-release && \ + tar zxf ../lua-stdlib/$(PACKAGE)-$(VERSION).tar.gz && \ cp -af $(PACKAGE)-$(VERSION)/* . && \ + rm -rf $(PACKAGE)-$(VERSION)/ && \ git add . && git ci -m "Release v$(VERSION)" && \ git tag -a -m "Full source release tag" release-v$(VERSION) && \ - git push && git push --tags && \ - git checkout master && \ - rm -rf $(PACKAGE)-$(VERSION)/ + git push && git push --tags # After check-in-release we need to bootstrap to get the build files back release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ - $(MAKE) bootstrap && \ - $(MAKE) rockspecs && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/aclocal.m4 b/aclocal.m4 index e0d6b76..e995adf 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,7 +1,8 @@ -# generated automatically by aclocal 1.13.1 -*- Autoconf -*- - -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,31 +12,33 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) +To do so, use the procedure documented by the package, typically `autoreconf'.])]) -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.13' +[am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.13.1], [], +m4_if([$1], [1.11.6], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,22 +54,24 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.13.1])dnl +[AM_AUTOMAKE_VERSION([1.11.6])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -85,7 +90,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you +# harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -111,12 +116,15 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 16 + # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -132,7 +140,7 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl +[AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -161,40 +169,31 @@ AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -205,32 +204,28 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], @@ -258,12 +253,15 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -277,14 +275,16 @@ if test x"${install_sh}" != xset; then install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST([install_sh])]) +AC_SUBST(install_sh)]) -# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 2 + # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -300,12 +300,15 @@ AC_SUBST([am__leading_dot])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 6 + # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -313,10 +316,11 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) + # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -329,22 +333,54 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " else am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) + AC_MSG_WARN([`missing' script is too old or missing]) fi ]) +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 5 + # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -354,7 +390,7 @@ AC_DEFUN([_AM_MANGLE_OPTION], # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ @@ -370,16 +406,22 @@ AC_DEFUN([_AM_IF_OPTION], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 5 + # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -390,40 +432,32 @@ case `pwd` in esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac -# Do 'set' in a subshell so we don't clobber the current shell's +# Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + test "$[2]" = conftest.file ) then @@ -433,50 +467,31 @@ else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) +AC_MSG_RESULT(yes)]) -# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 2009, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 2 + # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). +# (`yes' being less verbose, `no' or empty being verbose). AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +[AC_ARG_ENABLE([silent-rules], +[ --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0')]) +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl A few `make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} @@ -494,7 +509,7 @@ else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. + dnl Using `$V' instead of `$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else @@ -511,40 +526,44 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 1 + # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor 'install' (even GNU) is that you can't +# One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize +# always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 3 + # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -558,16 +577,18 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# serial 2 + # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -590,7 +611,7 @@ AC_MSG_CHECKING([how to create a $1 tar archive]) _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of '-'. +# Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in diff --git a/build-aux/install-sh b/build-aux/install-sh index 377bb86..a9244eb 100755 --- a/build-aux/install-sh +++ b/build-aux/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-11-20.07; # UTC +scriptversion=2011-01-19.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2011-11-20.07; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it +# `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,7 +156,7 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. + # Protect names problematic for `test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -190,7 +190,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg - # Protect names problematic for 'test' and other utilities. + # Protect names problematic for `test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -202,7 +202,7 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call 'install-sh -d' without argument. + # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi @@ -240,7 +240,7 @@ fi for src do - # Protect names problematic for 'test' and other utilities. + # Protect names problematic for `test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac @@ -354,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. + # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in diff --git a/build-aux/missing b/build-aux/missing index cdea514..86a8fc3 100755 --- a/build-aux/missing +++ b/build-aux/missing @@ -1,10 +1,11 @@ #! /bin/sh -# Common wrapper for a few potentially missing GNU programs. +# Common stub for a few missing GNU programs while installing. -scriptversion=2012-06-26.16; # UTC +scriptversion=2012-01-06.13; # UTC -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Originally written by Fran,cois Pinard , 1996. +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -25,40 +26,68 @@ scriptversion=2012-06-26.16; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" + echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi -case $1 in +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - --is-lightweight) - # Used by our autoconf macros to check whether the available missing - # script is modern enough. - exit 0 - ;; +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi - --run) - # Back-compat with the calling convention used by older automake. - shift - ;; +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due -to PROGRAM being missing or too old. +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal autoconf autoheader autom4te automake makeinfo - bison yacc flex lex help2man + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. Send bug reports to ." exit $? @@ -70,141 +99,228 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac -# Run the given program, remember its exit status. -"$@"; st=$? - -# If it succeeded, we are done. -test $st -eq 0 && exit 0 - -# Also exit now if we it failed (or wasn't found), and '--version' was -# passed; such an option is passed most likely to detect whether the -# program is present and works. -case $2 in --version|--help) exit $st;; esac - -# Exit code 63 means version mismatch. This often happens when the user -# tries to use an ancient version of a tool on a file that requires a -# minimum version. -if test $st -eq 63; then - msg="probably too old" -elif test $st -eq 127; then - # Program was missing. - msg="missing on your system" -else - # Program was found and executed, but failed. Give up. - exit $st -fi +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software - -program_details () -{ - case $1 in - aclocal|automake) - echo "The '$1' program is part of the GNU Automake package:" - echo "<$gnu_software_URL/automake>" - echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/autoconf>" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - autoconf|autom4te|autoheader) - echo "The '$1' program is part of the GNU Autoconf package:" - echo "<$gnu_software_URL/autoconf/>" - echo "It also requires GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - esac -} - -give_advice () -{ - # Normalize program name to check for. - normalized_program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - - printf '%s\n' "'$1' is $msg." - - configure_deps="'configure.ac' or m4 files included by 'configure.ac'" - case $normalized_program in - autoconf*) - echo "You should only need it if you modified 'configure.ac'," - echo "or m4 files included by it." - program_details 'autoconf' - ;; - autoheader*) - echo "You should only need it if you modified 'acconfig.h' or" - echo "$configure_deps." - program_details 'autoheader' - ;; - automake*) - echo "You should only need it if you modified 'Makefile.am' or" - echo "$configure_deps." - program_details 'automake' - ;; - aclocal*) - echo "You should only need it if you modified 'acinclude.m4' or" - echo "$configure_deps." - program_details 'aclocal' - ;; - autom4te*) - echo "You might have modified some maintainer files that require" - echo "the 'automa4te' program to be rebuilt." - program_details 'autom4te' - ;; - bison*|yacc*) - echo "You should only need it if you modified a '.y' file." - echo "You may want to install the GNU Bison package:" - echo "<$gnu_software_URL/bison/>" - ;; - lex*|flex*) - echo "You should only need it if you modified a '.l' file." - echo "You may want to install the Fast Lexical Analyzer package:" - echo "<$flex_URL>" - ;; - help2man*) - echo "You should only need it if you modified a dependency" \ - "of a man page." - echo "You may want to install the GNU Help2man package:" - echo "<$gnu_software_URL/help2man/>" + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files ;; - makeinfo*) - echo "You should only need it if you modified a '.texi' file, or" - echo "any other file indirectly affecting the aspect of the manual." - echo "You might want to install the Texinfo package:" - echo "<$gnu_software_URL/texinfo/>" - echo "The spurious makeinfo call might also be the consequence of" - echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" - echo "want to install GNU make:" - echo "<$gnu_software_URL/make/>" - ;; - *) - echo "You might have modified some files without having the proper" - echo "tools for further handling them. Check the 'README' file, it" - echo "often tells you about the needed prerequisites for installing" - echo "this package. You may also peek at any GNU archive site, in" - echo "case some other package contains this missing '$1' program." - ;; - esac -} - -give_advice "$1" | sed -e '1s/^/WARNING: /' \ - -e '2,$s/^/ /' >&2 - -# Propagate the correct exit status (expected to be 127 for a program -# not found, 63 for a program that failed due to version mismatch). -exit $st + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/configure b/configure index 7524b94..f014030 100755 --- a/configure +++ b/configure @@ -1287,8 +1287,8 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") + --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0') Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1759,7 +1759,7 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -am__api_version='1.13' +am__api_version='1.11' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -1856,6 +1856,9 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -1866,40 +1869,32 @@ case `pwd` in esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac -# Do 'set' in a subshell so we don't clobber the current shell's +# Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + test "$2" = conftest.file ) then @@ -1911,16 +1906,6 @@ Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -1943,12 +1928,12 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -1960,10 +1945,10 @@ if test x"${install_sh}" != xset; then esac fi -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. +# will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -2102,6 +2087,12 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -2184,45 +2175,6 @@ else fi rmdir .tst 2>/dev/null -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -2273,12 +2225,6 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used @@ -2296,10 +2242,10 @@ if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 @@ -3018,14 +2964,6 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } : "${CONFIG_STATUS=./config.status}" From b2373e50989f3e7cf3f0b9a40e6fbc5e882169b7 Mon Sep 17 00:00:00 2001 From: Reuben Thomas Date: Wed, 20 Feb 2013 23:20:16 +0000 Subject: [PATCH 07/34] Release v31 --- Makefile.am | 7 +-- Makefile.in | 7 +-- configure | 24 ++++----- configure.ac | 2 +- m4/ax_lua.m4 | 122 ++++++++++++++++++-------------------------- src/files/list.html | 14 ++--- src/list.lua | 97 +++++++++++++++++++++++------------ 7 files changed, 135 insertions(+), 138 deletions(-) diff --git a/Makefile.am b/Makefile.am index 77b1b10..ee1339e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,10 +37,6 @@ rockspecs: $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git -bootstrap: - autoreconf -i && \ - ./configure - tag-release: git diff --exit-code && \ git tag -a -m "Release tag" v$(VERSION) && \ @@ -55,9 +51,8 @@ check-in-release: distcheck git tag -a -m "Full source release tag" release-v$(VERSION) && \ git push && git push --tags -# After check-in-release we need to bootstrap to get the build files back release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" diff --git a/Makefile.in b/Makefile.in index d0d9a60..c0e0524 100644 --- a/Makefile.in +++ b/Makefile.in @@ -664,10 +664,6 @@ rockspecs: $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git -bootstrap: - autoreconf -i && \ - ./configure - tag-release: git diff --exit-code && \ git tag -a -m "Release tag" v$(VERSION) && \ @@ -682,12 +678,11 @@ check-in-release: distcheck git tag -a -m "Full source release tag" release-v$(VERSION) && \ git push && git push --tags -# After check-in-release we need to bootstrap to get the build files back release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/configure b/configure index f014030..2f9f8d5 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 30. +# Generated by GNU Autoconf 2.69 for stdlib 31. # # Report bugs to . # @@ -578,8 +578,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='30' -PACKAGE_STRING='stdlib 30' +PACKAGE_VERSION='31' +PACKAGE_STRING='stdlib 31' PACKAGE_BUGREPORT='rrt@sc3d.org' PACKAGE_URL='' @@ -1213,7 +1213,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 30 to adapt to many kinds of systems. +\`configure' configures stdlib 31 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1279,7 +1279,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 30:";; + short | recursive ) echo "Configuration of stdlib 31:";; esac cat <<\_ACEOF @@ -1365,7 +1365,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 30 +stdlib configure 31 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1382,7 +1382,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 30, which was +It was created by stdlib $as_me 31, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2197,7 +2197,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='30' + VERSION='31' cat >>confdefs.h <<_ACEOF @@ -2285,8 +2285,8 @@ LUA_MIN_VERSION=5.1 if test "x$LUA" != 'x'; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LUA is a Lua interprester" >&5 -$as_echo_n "checking if $LUA is a Lua interprester... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LUA is a Lua interpreter" >&5 +$as_echo_n "checking if $LUA is a Lua interpreter... " >&6; } if $LUA -e "print('Hello ' .. _VERSION .. '!')" &>/dev/null; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -3362,7 +3362,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 30, which was +This file was extended by stdlib $as_me 31, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3415,7 +3415,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 30 +stdlib config.status 31 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index d6daabf..a765abd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake -AC_INIT(stdlib, 30, rrt@sc3d.org) +AC_INIT(stdlib, 31, rrt@sc3d.org) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) AM_SILENT_RULES([yes]) diff --git a/m4/ax_lua.m4 b/m4/ax_lua.m4 index c5b54f6..c6f5974 100644 --- a/m4/ax_lua.m4 +++ b/m4/ax_lua.m4 @@ -1,11 +1,10 @@ # =========================================================================== -# ax_lua.m4 +# http://www.gnu.org/software/autoconf-archive/ax_lua.html # =========================================================================== # # SYNOPSIS # -# AX_PROG_LUA[([MINIMUM-VERSION], [TOO-BIG-VERSION], -# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] +# AX_PROG_LUA[([MINIMUM-VERSION], [TOO-BIG-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_HEADERS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_LIBS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_READLINE[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] @@ -18,15 +17,14 @@ # # Also detect Lua headers and libraries. The Lua version contained in the # header is checked to match the Lua interpreter version exactly. When -# searching for Lua libraries, the version number is used as a suffix. This -# is done with the goal of supporting multiple Lua installs (5.1 and 5.2 -# side-by-side). +# searching for Lua libraries, the version number is used as a suffix. +# This is done with the goal of supporting multiple Lua installs (5.1 and +# 5.2 side-by-side). # -# -# *** A note on compatibility with previous versions: This file has been +# A note on compatibility with previous versions: This file has been # mostly rewritten for serial 18. Most developers should be able to use # these macros without needing to modify configure.ac. Care has been taken -# to preserve each macro's behaviour, but there are some differences: +# to preserve each macro's behavior, but there are some differences: # # 1) AX_WITH_LUA is deprecated; it now expands to the exact same thing as # AX_PROG_LUA with no arguments. @@ -39,26 +37,25 @@ # should instead specify the LUA precious variable on the command line. # See the AX_PROG_LUA description for details. # -# Please read the macro descriptions for more information. *** -# +# Please read the macro descriptions below for more information. # +# This file was inspired by Andrew Dalke's and James Henstridge's +# python.m4 and Tom Payne's, Matthieu Moy's, and Reuben Thomas's ax_lua.m4 +# (serial 17). Basically, this file is a mash-up of those two files. I +# like to think it combines the best of the two! # -# AX_PROG_LUA[([MINIMUM-VERSION], [TOO-BIG-VERSION], -# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# ------------------------------------------------------- -# -# Search for the Lua interpreter, and set up important Lua paths. -# Adds precious variable LUA, which may contain the path of the Lua +# AX_PROG_LUA: Search for the Lua interpreter, and set up important Lua +# paths. Adds precious variable LUA, which may contain the path of the Lua # interpreter. If LUA is blank, the user's path is searched for an # suitable interpreter. # -# If MINIMUM-VERSION is supplied, then only Lua interpreters with a version -# number greater or equal to MINIMUM-VERSION will be accepted. If TOO-BIG- -# VERSION is also supplied, then only Lua interpreters with a version -# number greater or equal to MINIMUM-VERSION and less than TOO-BIG-VERSION -# will be accepted. +# If MINIMUM-VERSION is supplied, then only Lua interpreters with a +# version number greater or equal to MINIMUM-VERSION will be accepted. If +# TOO-BIG- VERSION is also supplied, then only Lua interpreters with a +# version number greater or equal to MINIMUM-VERSION and less than +# TOO-BIG-VERSION will be accepted. # -# Version comparisions require the AX_COMPARE_VERSION macro, which is +# Version comparisons require the AX_COMPARE_VERSION macro, which is # provided by ax_compare_version.m4 from the Autoconf Archive. # # The Lua version number, LUA_VERSION, is found from the interpreter, and @@ -82,8 +79,8 @@ # luadir Default: $prefix/share/lua/$LUA_VERSION # luaexecdir Default: $exec_prefix/lib/lua/$LUA_VERSION # -# These directories can be used by Automake as install destinations. -# The variable name minus 'dir' needs to be used as a prefix to the +# These directories can be used by Automake as install destinations. The +# variable name minus 'dir' needs to be used as a prefix to the # appropriate Automake primary, e.g. lua_SCRIPS or luaexec_LIBRARIES. # # If an acceptable Lua interpreter is found, then ACTION-IF-FOUND is @@ -91,23 +88,20 @@ # FOUND is blank, then it will default to printing an error. To prevent # the default behavior, give ':' as an action. # +# AX_LUA_HEADERS: Search for Lua headers. Requires that AX_PROG_LUA be +# expanded before this macro. Adds precious variable LUA_INCLUDE, which +# may contain Lua specific include flags, e.g. -I/usr/include/lua5.1. If +# LUA_INCLUDE is blank, then this macro will attempt to find suitable +# flags. # -# AX_LUA_HEADERS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# ---------------------------------------------------------- -# -# Search for Lua headers. Requires that AX_PROG_LUA be expanded before this -# macro. Adds precious variable LUA_INCLUDE, which may contain Lua specific -# include flags, e.g. -I/usr/include/lua5.1. If LUA_INCLUDE is blank, then -# this macro will attempt to find suitable flags. -# -# LUA_INCLUDE can be used by Automake to compile Lua modules or executables -# with embedded interpreters. The *_CPPFLAGS variables should be used for -# this purpose, e.g. myprog_CPPFLAGS = $(LUA_INCLUDE). +# LUA_INCLUDE can be used by Automake to compile Lua modules or +# executables with embedded interpreters. The *_CPPFLAGS variables should +# be used for this purpose, e.g. myprog_CPPFLAGS = $(LUA_INCLUDE). # # This macro searches for the header lua.h (and others). The search is # performed with a combination of CPPFLAGS, CPATH, etc, and LUA_INCLUDE. -# If the search is unsuccessful, then some common directories are tried. If -# the headers are then found, then LUA_INCLUDE is set accordingly. +# If the search is unsuccessful, then some common directories are tried. +# If the headers are then found, then LUA_INCLUDE is set accordingly. # # The paths automatically searched are: # @@ -125,18 +119,14 @@ # version numbers are not accepted. # # If headers are found, then ACTION-IF-FOUND is performed, otherwise -# ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, -# then it will default to printing an error. To prevent the default -# behavior, set the action to ':'. -# -# -# AX_LUA_LIBS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# ------------------------------------------------------- +# ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then +# it will default to printing an error. To prevent the default behavior, +# set the action to ':'. # -# Search for Lua libraries. Requires that AX_PROG_LUA be expanded before -# this macro. Adds precious variable LUA_LIB, which may contain Lua specific -# linker flags, e.g. -llua5.1. If LUA_LIB is blank, then this macro will -# attempt to find suitable flags. +# AX_LUA_LIBS: Search for Lua libraries. Requires that AX_PROG_LUA be +# expanded before this macro. Adds precious variable LUA_LIB, which may +# contain Lua specific linker flags, e.g. -llua5.1. If LUA_LIB is blank, +# then this macro will attempt to find suitable flags. # # LUA_LIB can be used by Automake to link Lua modules or executables with # embedded interpreters. The *_LIBADD and *_LDADD variables should be used @@ -150,25 +140,21 @@ # flags will be added to LUA_LIB. # # If libraries are found, then ACTION-IF-FOUND is performed, otherwise -# ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, -# then it will default to printing an error. To prevent the default -# behavior, set the action to ':'. -# -# -# AX_LUA_READLINE[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# ----------------------------------------------------------- +# ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then +# it will default to printing an error. To prevent the default behavior, +# set the action to ':'. # -# Search for readline headers and libraries. Requires the AX_LIB_READLINE -# macro, which is provided by ax_lib_readline.m4 from the Autoconf Archive. +# AX_LUA_READLINE: Search for readline headers and libraries. Requires the +# AX_LIB_READLINE macro, which is provided by ax_lib_readline.m4 from the +# Autoconf Archive. # # If a readline compatible library is found, then ACTION-IF-FOUND is # performed, otherwise ACTION-IF-NOT-FOUND is performed. # -# # LICENSE # -# Copyright (C) 2013 Tim Perkins -# Copyright (C) 2013 Reuben Thomas +# Copyright (c) 2013 Tim Perkins +# Copyright (c) 2013 Reuben Thomas # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -195,16 +181,8 @@ # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -# -# THANKS -# -# This file was inspired by Andrew Dalke's and James Henstridge's python.m4 -# and Tom Payne's, Matthieu Moy's, and Reuben Thomas's ax_lua.m4 (serial -# 17). Basically, this file is a mashup of those two files. I like to think -# it combines the best of the two! - -#serial 18 +#serial 20 dnl ========================================================================= dnl AX_PROG_LUA([MINIMUM-VERSION], [TOO-BIG-VERSION], @@ -226,7 +204,7 @@ AC_DEFUN([AX_PROG_LUA], ax_display_LUA='lua' dnl At least check if this is a Lua interpreter. - AC_MSG_CHECKING([if $LUA is a Lua interprester]) + AC_MSG_CHECKING([if $LUA is a Lua interpreter]) _AX_LUA_CHK_IS_INTRP([$LUA], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) @@ -236,7 +214,7 @@ AC_DEFUN([AX_PROG_LUA], [ dnl A version check is needed. AS_IF([test "x$LUA" != 'x'], [ dnl Check if this is a Lua interpreter. - AC_MSG_CHECKING([if $LUA is a Lua interprester]) + AC_MSG_CHECKING([if $LUA is a Lua interpreter]) _AX_LUA_CHK_IS_INTRP([$LUA], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) diff --git a/src/files/list.html b/src/files/list.html index 5cd6182..60705a9 100644 --- a/src/files/list.html +++ b/src/files/list.html @@ -289,8 +289,8 @@

Functions

- slice (l, from, to) - Return a slice of a list. + sub (l, from, to) + Return a sub-range of a list. @@ -834,7 +834,7 @@

Parameters

  • - t: list (as a table) + t: list (as a table), or nil for empty list
  • @@ -1019,9 +1019,9 @@

    Return value:

    -
    slice (l, from, to)
    +
    sub (l, from, to)
    -Return a slice of a list. (Negative list indices count from the end of the list.) +Return a sub-range of a list. (The equivalent of string.sub on strings; negative list indices count from the end of the list.)

    Parameters

    @@ -1032,11 +1032,11 @@

    Parameters

  • - from: start of slice (default: 1) + from: start of range (default: 1)
  • - to: end of slice (default: #l) + to: end of range (default: #l)
  • diff --git a/src/list.lua b/src/list.lua index f86a4ff..213cf3e 100644 --- a/src/list.lua +++ b/src/list.lua @@ -60,14 +60,14 @@ local function filter (p, l) return _G.filter (p, elems, l) end ---- Return a slice of a list. --- (Negative list indices count from the end of the list.) +--- Return a sub-range of a list. (The equivalent of string.sub +-- on strings; negative list indices count from the end of the list.) -- @param l list --- @param from start of slice (default: 1) --- @param to end of slice (default: #l) +-- @param from start of range (default: 1) +-- @param to end of range (default: #l) -- @return {l[from], ..., l[to]} -local function slice (l, from, to) - local m = {} +local function sub (l, from, to) + local r = list.new () local len = #l from = from or 1 to = to or len @@ -78,16 +78,16 @@ local function slice (l, from, to) to = to + len + 1 end for i = from, to do - table.insert (m, l[i]) + table.insert (r, l[i]) end - return m + return r end --- Return a list with its first element removed. -- @param l list -- @return {l[2], ..., l[#l]} local function tail (l) - return slice (l, 2) + return sub (l, 2) end --- Fold a binary function through a list left associatively. @@ -133,7 +133,7 @@ end -- l1[#l1], ..., ln[1], ..., -- ln[#ln]} local function concat (...) - local r = {} + local r = list.new () for l in elems ({...}) do for v in elems (l) do table.insert (r, v) @@ -147,7 +147,7 @@ end -- @param n number of times to repeat -- @return n copies of l appended together local function rep (l, n) - local r = {} + local r = list.new () for i = 1, n do r = concat (r, l) end @@ -158,11 +158,11 @@ end -- @param l list -- @return list {l[#l], ..., l[1]} local function reverse (l) - local m = {} + local r = list.new () for i = #l, 1, -1 do - table.insert (m, l[i]) + table.insert (r, l[i]) end - return m + return r end --- Transpose a list of lists. @@ -173,14 +173,14 @@ end -- @return {{l1,1, ..., lr,1}, ..., -- {l1,c, ..., lr,c}} local function transpose (ls) - local ms, len = {}, #ls + local rs, len = list.new (), #ls for i = 1, math.max (unpack (map (function (l) return #l end, ls))) do - ms[i] = {} + rs[i] = list.new () for j = 1, len do - ms[i][j] = ls[j][i] + rs[i][j] = ls[j][i] end end - return ms + return rs end --- Zip lists together with a function. @@ -207,7 +207,7 @@ end -- @return list {{i1, v1}, ..., -- {in, vn}} local function enpair (t) - local ls = {} + local ls = list.new () for i, v in pairs (t) do table.insert (ls, {i, v}) end @@ -232,11 +232,11 @@ end -- @param l list to flatten -- @return flattened list local function flatten (l) - local m = {} + local r = list.new () for v in ileaves (l) do - table.insert (m, v) + table.insert (r, v) end - return m + return r end --- Shape a list according to a list of dimensions. @@ -281,13 +281,13 @@ local function shape (s, l) if d > #s then return l[i], i + 1 else - local t = {} + local r = list.new () for j = 1, s[d] do local e e, i = fill (i, d + 1) - table.insert (t, e) + table.insert (r, e) end - return t, i + return r, i end end return (fill (1, 1)) @@ -300,14 +300,14 @@ end -- @return index {t1[f]=1, ..., -- tn[f]=n} local function indexKey (f, l) - local m = {} + local r = list.new () for i, v in ipairs (l) do local k = v[f] if k then - m[k] = i + r[k] = i end end - return m + return r end --- Copy a list of tables, indexed on a given field @@ -317,14 +317,14 @@ end -- @return index {t1[f]=t1, ..., -- tn[f]=tn} local function indexValue (f, l) - local m = {} + local r = list.new () for i, v in ipairs (l) do local k = v[f] if k then - m[k] = v + r[k] = v end end - return m + return r end permuteOn = indexValue @@ -349,6 +349,33 @@ local function compare (l, m) return 0 end +-- Methods for lists +local methods = { + append = append, + compare = compare, + concat = concat, + cons = cons, + depair = depair, + elems = elems, + filter = function (self, p) return filter (p, self) end, + flatten = flatten, + foldl = function (self, f, e) return foldl (f, e, self) end, + foldr = function (self, f, e) return foldr (f, e, self) end, + indexKey = function (self, f) return indexKey (self, f) end, + indexValue = function (self, f) return indexValue (self, f) end, + map = function (self, f) return map (f, self) end, + mapWith = function (self, f) return mapWith (f, self) end, + project = function (self, f) return project (f, self) end, + relems = relems, + rep = rep, + reverse = reverse, + shape = function (self, s) return shape (s, self) end, + sub = sub, + tail = tail, + transpose = transpose, + zipWith = function (self, f) return zipWith (f, self) end, +} + -- Metamethods for lists local metatable = { -- list .. table = list.concat @@ -359,14 +386,15 @@ local metatable = { -- list <= list = list.compare returns <= 0 __le = function (l, m) return compare (l, m) <= 0 end, __append = append, + __index = methods, } --- List constructor. -- Needed in order to use metamethods. --- @param t list (as a table) +-- @param t list (as a table), or nil for empty list -- @return list (with list metamethods) local function new (l) - return setmetatable (l, metatable) + return setmetatable (l or {}, metatable) end -- Function forms of operators @@ -395,7 +423,8 @@ local M = { rep = rep, reverse = reverse, shape = shape, - slice = slice, + slice = sub, -- backwards compatibility + sub = sub, tail = tail, transpose = transpose, zipWith = zipWith, From b50833e4a76a5df22b77c6e112a5f2ec9cca507b Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Fri, 22 Feb 2013 02:09:48 +0700 Subject: [PATCH 08/34] Release v32 --- Makefile | 120 ++++-- Makefile.am | 92 ++++- Makefile.in | 270 +++++++++--- aclocal.m4 | 291 ++++++------- build-aux/install-sh | 14 +- build-aux/missing | 414 +++++++------------ configure | 166 +++++--- configure.ac | 2 +- specs/lib/specl.lua | 329 +++++++++++++++ specs/package_ext_spec.lua | 34 ++ specs/specl | 86 ++++ specs/table_ext_spec.lua | 326 +++++++++++++++ src/getopt.lua | 13 +- src/index.html | 18 - src/io_ext.lua | 2 +- src/package_ext.lua | 9 +- src/std.lua | 2 +- src/table_ext.lua | 48 ++- stdlib-30-1.rockspec => stdlib-32-1.rockspec | 8 +- stdlib-git-1.rockspec | 26 +- 20 files changed, 1614 insertions(+), 656 deletions(-) create mode 100644 specs/lib/specl.lua create mode 100644 specs/package_ext_spec.lua create mode 100755 specs/specl create mode 100644 specs/table_ext_spec.lua rename stdlib-30-1.rockspec => stdlib-32-1.rockspec (94%) diff --git a/Makefile b/Makefile index 975b9c2..1c83fbd 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ AUTOHEADER = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing AUTOMAKE = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing automake-1.13 AWK = awk CYGPATH_W = echo -DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"30\" -DPACKAGE_STRING=\"stdlib\ 30\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"30\" +DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"32\" -DPACKAGE_STRING=\"stdlib\ 32\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"32\" ECHO_C = \c ECHO_N = ECHO_T = @@ -187,15 +187,15 @@ MKDIR_P = build-aux/install-sh -c -d PACKAGE = stdlib PACKAGE_BUGREPORT = rrt@sc3d.org PACKAGE_NAME = stdlib -PACKAGE_STRING = stdlib 30 +PACKAGE_STRING = stdlib 32 PACKAGE_TARNAME = stdlib PACKAGE_URL = -PACKAGE_VERSION = 30 +PACKAGE_VERSION = 32 PATH_SEPARATOR = : SET_MAKE = SHELL = /bin/sh STRIP = -VERSION = 30 +VERSION = 32 abs_builddir = /Volumes/Home/Devo/lua-stdlib--master--0 abs_srcdir = /Volumes/Home/Devo/lua-stdlib--master--0 abs_top_builddir = /Volumes/Home/Devo/lua-stdlib--master--0 @@ -240,8 +240,42 @@ top_build_prefix = top_builddir = . top_srcdir = . ACLOCAL_AMFLAGS = -I m4 -LUA_ENV = LUA_PATH="$(abs_srcdir)/src/?.lua;$(LUA_PATH)" -SOURCES = $(wildcard $(srcdir)/src/*.lua) $(srcdir)/src/std.lua +src_spec = $(abs_srcdir)/src/?.lua +lib_spec = $(abs_srcdir)/specs/lib/?.lua +LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" +SPEC_ENV = LUA_PATH="$(lib_spec);$(src_spec);$(LUA_PATH)" +NOTHING_ELSE = +SOURCES = \ + src/base.lua \ + src/bin.lua \ + src/debug_ext.lua \ + src/debug_init.lua \ + src/fstable.lua \ + src/getopt.lua \ + src/io_ext.lua \ + src/lcs.lua \ + src/list.lua \ + src/math_ext.lua \ + src/mbox.lua \ + src/modules.lua \ + src/object.lua \ + src/package_ext.lua \ + src/parser.lua \ + src/set.lua \ + src/std.lua \ + src/strbuf.lua \ + src/strict.lua \ + src/string_ext.lua \ + src/table_ext.lua \ + src/tree.lua \ + src/xml.lua \ + $(NOTHING_ELSE) + +SPECS = \ + specs/package_ext_spec.lua \ + specs/table_ext_spec.lua \ + $(NOTHING_ELSE) + dist_data_DATA = $(SOURCES) dist_doc_DATA = \ $(top_srcdir)/src/index.html \ @@ -252,8 +286,11 @@ dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ + specs/specl \ + specs/lib/specl.lua \ src/std.lua.in \ - $(PACKAGE).rockspec.in + $(SPECS) \ + $(NOTHING_ELSE) DISTCLEANFILES = $(PACKAGE).rockspec all: all-am @@ -596,6 +633,7 @@ distcleancheck: distclean $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile $(DATA) installdirs: @@ -704,16 +742,16 @@ ps-am: uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ uninstall-dist_filesDATA uninstall-dist_modulesDATA -.MAKE: install-am install-strip +.MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ - clean-cscope clean-generic cscope cscopelist-am ctags ctags-am \ - dist dist-all dist-bzip2 dist-gzip dist-lzip dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-generic distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_dataDATA install-dist_docDATA \ +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am \ + check-local clean clean-cscope clean-generic cscope \ + cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dist_dataDATA install-dist_docDATA \ install-dist_filesDATA install-dist_modulesDATA install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ @@ -742,33 +780,45 @@ rockspecs: $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git -bootstrap: - autoreconf -i && \ - ./configure +check-local: + $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua + +GIT ?= git +LN_S ?= ln -sf tag-release: - git diff --exit-code && \ - git tag -a -m "Release tag" v$(VERSION) && \ - git push && git push --tags + $(GIT) diff --exit-code && \ + $(GIT) tag -f -a -m "Release tag" v$(VERSION) -check-in-release: distcheck - git checkout release && \ +define unpack-distcheck-release + rm -rf $(PACKAGE)-$(VERSION)/ && \ tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ - cp -af $(PACKAGE)-$(VERSION)/* . && \ - git add . && git ci -m "Release v$(VERSION)" && \ - git tag -a -m "Full source release tag" release-v$(VERSION) && \ - git push && git push --tags && \ - git checkout master && \ - rm -rf $(PACKAGE)-$(VERSION)/ - -# After check-in-release we need to bootstrap to get the build files back + cp -a -f $(PACKAGE)-$(VERSION)/* . && \ + rm -rf $(PACKAGE)-$(VERSION)/ && \ + echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ + echo './configure && make all rockspecs' && \ + ./configure --version && ./configure && \ + $(MAKE) all rockspecs +endef + +check-in-release: distcheck + current_branch=`$(GIT) symbolic-ref HEAD`; \ + { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ + { $(GIT) pull origin release || true; } && \ + $(unpack-distcheck-release) && \ + $(GIT) add . && \ + $(GIT) commit -a -m "Release v$(VERSION)" && \ + $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ + $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` + +GIT_PUBLISH ?= $(GIT) + release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ - $(MAKE) bootstrap && \ - $(MAKE) rockspecs && \ + $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + $(WOGER) lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/Makefile.am b/Makefile.am index ee1339e..bb7e73e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,11 +2,46 @@ ACLOCAL_AMFLAGS = -I m4 +src_spec = $(abs_srcdir)/src/?.lua +lib_spec = $(abs_srcdir)/specs/lib/?.lua + LUA_PATH ?= ; -LUA_ENV = LUA_PATH="$(abs_srcdir)/src/?.lua;$(LUA_PATH)" +LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" +SPEC_ENV = LUA_PATH="$(lib_spec);$(src_spec);$(LUA_PATH)" + +NOTHING_ELSE = + +SOURCES = \ + src/base.lua \ + src/bin.lua \ + src/debug_ext.lua \ + src/debug_init.lua \ + src/fstable.lua \ + src/getopt.lua \ + src/io_ext.lua \ + src/lcs.lua \ + src/list.lua \ + src/math_ext.lua \ + src/mbox.lua \ + src/modules.lua \ + src/object.lua \ + src/package_ext.lua \ + src/parser.lua \ + src/set.lua \ + src/std.lua \ + src/strbuf.lua \ + src/strict.lua \ + src/string_ext.lua \ + src/table_ext.lua \ + src/tree.lua \ + src/xml.lua \ + $(NOTHING_ELSE) + +SPECS = \ + specs/package_ext_spec.lua \ + specs/table_ext_spec.lua \ + $(NOTHING_ELSE) -SOURCES = $(filter-out $(srcdir)/src/std.lua, $(wildcard $(srcdir)/src/*.lua)) -SOURCES += $(srcdir)/src/std.lua dist_data_DATA = $(SOURCES) dist_doc_DATA = \ @@ -18,7 +53,11 @@ modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ - src/std.lua.in + specs/specl \ + specs/lib/specl.lua \ + src/std.lua.in \ + $(SPECS) \ + $(NOTHING_ELSE) DISTCLEANFILES = $(PACKAGE).rockspec @@ -37,22 +76,45 @@ rockspecs: $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git +check-local: + $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua + +GIT ?= git +LN_S ?= ln -sf + tag-release: - git diff --exit-code && \ - git tag -a -m "Release tag" v$(VERSION) && \ - git push && git push --tags + $(GIT) diff --exit-code && \ + $(GIT) tag -f -a -m "Release tag" v$(VERSION) -check-in-release: distcheck - cd ../lua-stdlib-release && \ - tar zxf ../lua-stdlib/$(PACKAGE)-$(VERSION).tar.gz && \ - cp -af $(PACKAGE)-$(VERSION)/* . && \ +define unpack-distcheck-release + rm -rf $(PACKAGE)-$(VERSION)/ && \ + tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cp -a -f $(PACKAGE)-$(VERSION)/* . && \ rm -rf $(PACKAGE)-$(VERSION)/ && \ - git add . && git ci -m "Release v$(VERSION)" && \ - git tag -a -m "Full source release tag" release-v$(VERSION) && \ - git push && git push --tags + echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ + echo './configure && make all rockspecs' && \ + ./configure --version && ./configure && \ + $(MAKE) all rockspecs +endef + +check-in-release: distcheck + current_branch=`$(GIT) symbolic-ref HEAD`; \ + { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ + { $(GIT) pull origin release || true; } && \ + $(unpack-distcheck-release) && \ + $(GIT) add . && \ + $(GIT) commit -a -m "Release v$(VERSION)" && \ + $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ + $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` + + +## To test the release process without publishing upstream, use: +## make release WOGER=: GIT_PUBLISH=: +GIT_PUBLISH ?= $(GIT) release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ + $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + $(WOGER) lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" diff --git a/Makefile.in b/Makefile.in index c0e0524..af94d5b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -50,11 +49,13 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . -DIST_COMMON = README $(am__configure_deps) $(dist_data_DATA) \ +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/luarocks-config.lua.in $(dist_data_DATA) \ $(dist_doc_DATA) $(dist_files_DATA) $(dist_modules_DATA) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/luarocks-config.lua.in $(top_srcdir)/configure \ - AUTHORS INSTALL build-aux/install-sh build-aux/missing + AUTHORS INSTALL README build-aux/install-sh build-aux/missing \ + $(top_srcdir)/build-aux/install-sh \ + $(top_srcdir)/build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/m4/ax_with_prog.m4 \ @@ -66,12 +67,18 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = luarocks-config.lua CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ +am__v_at_1 = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -109,6 +116,27 @@ am__installdirs = "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)" DATA = $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ $(dist_modules_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -118,8 +146,10 @@ am__remove_distdir = \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi +am__post_remove_distdir = $(am__remove_distdir) DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best +DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -210,9 +240,42 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 -LUA_ENV = LUA_PATH="$(abs_srcdir)/src/?.lua;$(LUA_PATH)" -SOURCES = $(filter-out $(srcdir)/src/std.lua, $(wildcard \ - $(srcdir)/src/*.lua)) $(srcdir)/src/std.lua +src_spec = $(abs_srcdir)/src/?.lua +lib_spec = $(abs_srcdir)/specs/lib/?.lua +LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" +SPEC_ENV = LUA_PATH="$(lib_spec);$(src_spec);$(LUA_PATH)" +NOTHING_ELSE = +SOURCES = \ + src/base.lua \ + src/bin.lua \ + src/debug_ext.lua \ + src/debug_init.lua \ + src/fstable.lua \ + src/getopt.lua \ + src/io_ext.lua \ + src/lcs.lua \ + src/list.lua \ + src/math_ext.lua \ + src/mbox.lua \ + src/modules.lua \ + src/object.lua \ + src/package_ext.lua \ + src/parser.lua \ + src/set.lua \ + src/std.lua \ + src/strbuf.lua \ + src/strict.lua \ + src/string_ext.lua \ + src/table_ext.lua \ + src/tree.lua \ + src/xml.lua \ + $(NOTHING_ELSE) + +SPECS = \ + specs/package_ext_spec.lua \ + specs/table_ext_spec.lua \ + $(NOTHING_ELSE) + dist_data_DATA = $(SOURCES) dist_doc_DATA = \ $(top_srcdir)/src/index.html \ @@ -223,7 +286,11 @@ dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ - src/std.lua.in + specs/specl \ + specs/lib/specl.lua \ + src/std.lua.in \ + $(SPECS) \ + $(NOTHING_ELSE) DISTCLEANFILES = $(PACKAGE).rockspec all: all-am @@ -349,12 +416,65 @@ uninstall-dist_modulesDATA: @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) -tags: TAGS -TAGS: -ctags: CTAGS -CTAGS: +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) @@ -397,40 +517,36 @@ distdir: $(DISTFILES) || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__remove_distdir) + $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__remove_distdir) - -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) + $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) + $(am__post_remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) + $(am__post_remove_distdir) -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -441,8 +557,6 @@ distcheck: dist GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ @@ -454,9 +568,9 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod u+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ @@ -488,7 +602,7 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__remove_distdir) + $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' @@ -519,6 +633,7 @@ distcleancheck: distclean $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am all-am: Makefile $(DATA) installdirs: @@ -563,7 +678,7 @@ clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile -distclean-am: clean-am distclean-generic +distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am @@ -627,24 +742,25 @@ ps-am: uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ uninstall-dist_filesDATA uninstall-dist_modulesDATA -.MAKE: install-am install-strip - -.PHONY: all all-am am--refresh check check-am clean clean-generic dist \ - dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-generic distcleancheck distdir distuninstallcheck \ - dvi dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dist_dataDATA \ - install-dist_docDATA install-dist_filesDATA \ - install-dist_modulesDATA install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am uninstall uninstall-am uninstall-dist_dataDATA \ - uninstall-dist_docDATA uninstall-dist_filesDATA \ - uninstall-dist_modulesDATA +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am \ + check-local clean clean-cscope clean-generic cscope \ + cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dist_dataDATA install-dist_docDATA \ + install-dist_filesDATA install-dist_modulesDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-dist_dataDATA uninstall-dist_docDATA \ + uninstall-dist_filesDATA uninstall-dist_modulesDATA LUA_PATH ?= ; @@ -664,25 +780,45 @@ rockspecs: $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git +check-local: + $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua + +GIT ?= git +LN_S ?= ln -sf + tag-release: - git diff --exit-code && \ - git tag -a -m "Release tag" v$(VERSION) && \ - git push && git push --tags + $(GIT) diff --exit-code && \ + $(GIT) tag -f -a -m "Release tag" v$(VERSION) -check-in-release: distcheck - cd ../lua-stdlib-release && \ - tar zxf ../lua-stdlib/$(PACKAGE)-$(VERSION).tar.gz && \ - cp -af $(PACKAGE)-$(VERSION)/* . && \ +define unpack-distcheck-release + rm -rf $(PACKAGE)-$(VERSION)/ && \ + tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cp -a -f $(PACKAGE)-$(VERSION)/* . && \ rm -rf $(PACKAGE)-$(VERSION)/ && \ - git add . && git ci -m "Release v$(VERSION)" && \ - git tag -a -m "Full source release tag" release-v$(VERSION) && \ - git push && git push --tags + echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ + echo './configure && make all rockspecs' && \ + ./configure --version && ./configure && \ + $(MAKE) all rockspecs +endef + +check-in-release: distcheck + current_branch=`$(GIT) symbolic-ref HEAD`; \ + { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ + { $(GIT) pull origin release || true; } && \ + $(unpack-distcheck-release) && \ + $(GIT) add . && \ + $(GIT) commit -a -m "Release v$(VERSION)" && \ + $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ + $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` + +GIT_PUBLISH ?= $(GIT) release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ + $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - woger lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" + $(WOGER) lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/aclocal.m4 b/aclocal.m4 index e995adf..e0d6b76 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,8 +1,7 @@ -# generated automatically by aclocal 1.11.6 -*- Autoconf -*- +# generated automatically by aclocal 1.13.1 -*- Autoconf -*- + +# Copyright (C) 1996-2012 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, -# Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -12,33 +11,31 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' +[am__api_version='1.13' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.6], [], +m4_if([$1], [1.13.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -54,24 +51,22 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.6])dnl +[AM_AUTOMAKE_VERSION([1.13.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -90,7 +85,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you +# harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -116,15 +111,12 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 16 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -140,7 +132,7 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -169,31 +161,40 @@ AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -204,28 +205,32 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], @@ -253,15 +258,12 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, -# Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -275,16 +277,14 @@ if test x"${install_sh}" != xset; then install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST(install_sh)]) +AC_SUBST([install_sh])]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -300,15 +300,12 @@ AC_SUBST([am__leading_dot])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -316,11 +313,10 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -333,54 +329,22 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) + AC_MSG_WARN(['missing' script is too old or missing]) fi ]) -# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, -# Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 1 - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -390,7 +354,7 @@ AC_DEFUN([_AM_MANGLE_OPTION], # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ @@ -406,22 +370,16 @@ AC_DEFUN([_AM_IF_OPTION], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -432,32 +390,40 @@ case `pwd` in esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$[2]" = conftest.file ) then @@ -467,31 +433,50 @@ else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT(yes)]) +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) -# Copyright (C) 2009, 2011 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT -# (`yes' being less verbose, `no' or empty being verbose). +# ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], -[ --enable-silent-rules less verbose build output (undo: `make V=1') - --disable-silent-rules verbose build output (undo: `make V=0')]) -case $enable_silent_rules in -yes) AM_DEFAULT_VERBOSITY=0;; -no) AM_DEFAULT_VERBOSITY=1;; -*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl -dnl A few `make' implementations (e.g., NonStop OS and NextStep) +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} @@ -509,7 +494,7 @@ else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then - dnl Using `$V' instead of `$(V)' breaks IRIX make. + dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else @@ -526,44 +511,40 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 1 - # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor `install' (even GNU) is that you can't +# One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize +# always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -577,18 +558,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -611,7 +590,7 @@ AC_MSG_CHECKING([how to create a $1 tar archive]) _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. +# Solaris sh will not grok spaces in the rhs of '-'. for _am_tool in $_am_tools do case $_am_tool in diff --git a/build-aux/install-sh b/build-aux/install-sh index a9244eb..377bb86 100755 --- a/build-aux/install-sh +++ b/build-aux/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-01-19.21; # UTC +scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2011-01-19.21; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,7 +156,7 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -190,7 +190,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac @@ -202,7 +202,7 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi @@ -240,7 +240,7 @@ fi for src do - # Protect names problematic for `test' and other utilities. + # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac @@ -354,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in diff --git a/build-aux/missing b/build-aux/missing index 86a8fc3..cdea514 100755 --- a/build-aux/missing +++ b/build-aux/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2012-01-06.13; # UTC +scriptversion=2012-06-26.16; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,68 +25,40 @@ scriptversion=2012-01-06.13; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi +case $1 in -msg="missing on your system" + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." exit $? @@ -99,228 +70,141 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG=\${$#} - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'automa4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" ;; -esac - -exit 0 + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/configure b/configure index 2f9f8d5..2f3430f 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 31. +# Generated by GNU Autoconf 2.69 for stdlib 32. # # Report bugs to . # @@ -578,8 +578,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='31' -PACKAGE_STRING='stdlib 31' +PACKAGE_VERSION='32' +PACKAGE_STRING='stdlib 32' PACKAGE_BUGREPORT='rrt@sc3d.org' PACKAGE_URL='' @@ -1213,7 +1213,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 31 to adapt to many kinds of systems. +\`configure' configures stdlib 32 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1279,7 +1279,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 31:";; + short | recursive ) echo "Configuration of stdlib 32:";; esac cat <<\_ACEOF @@ -1287,8 +1287,8 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: `make V=1') - --disable-silent-rules verbose build output (undo: `make V=0') + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1365,7 +1365,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 31 +stdlib configure 32 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1382,7 +1382,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 31, which was +It was created by stdlib $as_me 32, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1759,7 +1759,7 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -am__api_version='1.11' +am__api_version='1.13' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -1856,9 +1856,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -1869,32 +1866,40 @@ case `pwd` in esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi - + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$2" = conftest.file ) then @@ -1906,6 +1911,16 @@ Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -1928,12 +1943,12 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -1945,10 +1960,10 @@ if test x"${install_sh}" != xset; then esac fi -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. +# will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -2087,12 +2102,6 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -2175,6 +2184,45 @@ else fi rmdir .tst 2>/dev/null +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -2197,7 +2245,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='31' + VERSION='32' cat >>confdefs.h <<_ACEOF @@ -2225,6 +2273,12 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used @@ -2242,10 +2296,10 @@ if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi -case $enable_silent_rules in -yes) AM_DEFAULT_VERBOSITY=0;; -no) AM_DEFAULT_VERBOSITY=1;; -*) AM_DEFAULT_VERBOSITY=0;; +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 @@ -2964,6 +3018,14 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } : "${CONFIG_STATUS=./config.status}" @@ -3362,7 +3424,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 31, which was +This file was extended by stdlib $as_me 32, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3415,7 +3477,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 31 +stdlib config.status 32 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index a765abd..1ad200f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake -AC_INIT(stdlib, 31, rrt@sc3d.org) +AC_INIT(stdlib, 32, rrt@sc3d.org) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) AM_SILENT_RULES([yes]) diff --git a/specs/lib/specl.lua b/specs/lib/specl.lua new file mode 100644 index 0000000..60cc8ea --- /dev/null +++ b/specs/lib/specl.lua @@ -0,0 +1,329 @@ +-- Specification testing framework. +-- +-- Copyright (c) 2013 Free Software Foundation, Inc. +-- Written by Gary V. Vaughan, 2013 +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3, or (at your option) +-- any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; see the file COPYING. If not, write to the +-- Free Software Foundation, Fifth Floor, 51 Franklin Street, Boston, +-- MA 02111-1301, USA. + +require "std" + + + +--[[ ================================= ]]-- +--[[ Compatibility between 5.1 and 5.2 ]]-- +--[[ ================================= ]]-- + + +-- From http://lua-users.org/lists/lua-l/2010-06/msg00313.html +setfenv = setfenv or function(f, t) + local name + local up = 0 + repeat + up = up + 1 + name = debug.getupvalue (f, up) + until name == '_ENV' or name == nil + if name then + debug.upvaluejoin (f, up, function () return name end, 1) + debug.setupvalue (f, up, t) + end + return f +end + + + +--[[ =========== ]]-- +--[[ Formatters. ]]-- +--[[ =========== ]]-- + + +local report = { + header = function () + end, + + spec = function (spec) + print (spec) + end, + + example = function (example) + print (example) + end, + + expectations = function (expectations, indent) + indent = indent or "" + for i, expectation in ipairs (expectations) do + if expectation.status ~= true then + print (indent .. "- FAILED expectation " .. i .. ": " .. + expectation.message:gsub ("\n", "%0" .. indent .. " ")) + end + end + end, + + footer = function (stats) + local total = stats.pass + stats.fail + local percent = 100 * stats.pass / total + + print () + print (string.format ("Met %.2f%% of %d expectations.", percent, total)) + print (stats.pass .. " passed, and " .. + stats.fail .. " failed in " .. + (os.clock () - stats.starttime) .. " seconds.") + end, +} + + +local progress = { + header = function () + io.write (">") + io.flush () + end, + + spec = function (spec) + end, + + example = function (example) + end, + + expectations = function (expectations, indent) + io.write ("\08") + for i, expectation in ipairs (expectations) do + if expectation.status == true then + io.write (".") + else + io.write ("F") + end + end + io.write (">") + io.flush () + end, + + footer = function (stats) + io.write ("\08 \n") + + if stats.fail == 0 then + io.write ("All expectations met, ") + else + io.write (stats.pass .. " passed, and " .. stats.fail .. " failed ") + end + io.write ("in " .. (os.clock () - stats.starttime) .. " seconds.\n") + end, +} + + +-- Use the simple progress formatter by default. Can be changed by run(). +local formatter = progress + + + +--[[ ========= ]]-- +--[[ Matchers. ]]-- +--[[ ========= ]]-- + + +local function objcmp (o1, o2) + local type1, type2 = type (o1), type (o2) + if type1 ~= type2 then return false end + if type1 ~= "table" or type2 ~= "table" then return o1 == o2 end + + for k, v in pairs (o1) do + if o2[k] == nil or not objcmp (v, o2[k]) then return false end + end + -- any keys in o2, not already compared above denote a mismatch! + for k, _ in pairs (o2) do + if o1[k] == nil then return false end + end + return true +end + + +-- Quote strings nicely, and coerce non-strings into strings. +local function q (obj) + if type (obj) == "string" then + return '"' .. obj:gsub ('[\\"]', "\\%0") .. '"' + end + return tostring (obj) +end + + +local matchers = { + -- Deep comparison, matches if VALUE and EXPECTED share the same + -- structure. + equal = function (value, expected) + local m = "expecting " .. q(expected) .. ", but got ".. q(value) + return (objcmp (value, expected) == true), m + end, + + -- Identity, only match if VALUE and EXPECTED are the same object. + be = function (value, expected) + local m = "expecting exactly " .. q(expected) .. ", but got " .. q(value) + return (value == expected), m + end, + + -- Matches if FUNC raises any error. + ["error"] = function (expected, ...) + local ok, err = pcall (...) + if not ok then -- "not ok" means an error occurred + local pattern = ".*" .. expected:gsub ("%W", "%%%0") .. ".*" + ok = not err:match (pattern) + end + return not ok, "expecting an error containing " .. q(expected) .. ", and got\n" .. q(err) + end, + + -- Matches if VALUE matches regular expression PATTERN. + match = function (target, pattern) + if type (target) ~= 'string' then + error ("type error, 'match' matcher expecting target as string") + end + local m = "expecting string matching " .. q(pattern) .. ", but got " .. q(value) + return (string.match (value, pattern) == true), m + end, + + -- Matches if VALUE contains the string EXPECTED. + contain = function (value, expected) + if type (target) ~= 'string' then + error ("type error, 'contain' matcher expecting target as string") + end + local m = "expecting string containing " .. q(expected) .. ", but got " .. q(value) + local pattern = ".*" .. expected:gsub ("%W", "%%%0") .. ".*" + return (string.match (value, pattern)), m + end, +} + + +-- Wrap TARGET in metatable that dynamically looks up an appropriate +-- matcher from the table above for comparison with the following +-- parameter. Matcher names containing '_not_' invert their results +-- before returning. +-- +-- For example: expect ({}).should_not_be {} + +_G.expectations = {} +_G.stats = { pass = 0, fail = 0, starttime = os.clock () } + +local function expect (target) + return setmetatable ({}, { + __index = function(_, matcher) + local inverse = false + if matcher:match ("^should_not_") then + inverse, matcher = true, matcher:sub (12) + else + matcher = matcher:sub (8) + end + return function(...) + local success, message = matchers[matcher](target, ...) + + if inverse then + success = not success + message = message and ("not " .. message) + end + + if success ~= true then + _G.stats.fail = _G.stats.fail + 1 + else + _G.stats.pass = _G.stats.pass + 1 + end + table.insert (_G.expectations, { status = success, message = message }) + end + end + }) +end + + + +--[[ ============= ]]-- +--[[ Spec' Runner. ]]-- +--[[ ============= ]]-- + + +local nop, run_specs, run_examples + + +-- Always call before and after unconditionally. +function nop () end + + +function run_specs (specs, indent, env) + indent = indent or "" + for _, detail in ipairs (specs) do + for description, examples in pairs (detail) do + formatter.spec (indent .. description:gsub ("^%w+%s+", "", 1)) + run_examples (examples, indent .. " ", env) + end + end +end + + +function run_examples (examples, indent, env) + env = env or _G + + local before, after = examples.before or nop, examples.after or nop + local block = function (example, blockenv) + before () + + -- There is only one, otherwise we can't maintain example order. + local description, definition = next (example) + + if type (definition) == "table" then + -- A nested context, revert back to run_specs. + run_specs ({ example }, indent, env) + + elseif type (definition) == "function" then + -- An example, execute it in a clean new sub-environment. + local fenv = { expect = expect } + formatter.example (indent .. description:gsub ("^%w+%s+", "", 1)) + setfenv (definition, setmetatable (fenv, { __index = blockenv })) + + _G.expectations = {} -- each example may have several expectations + definition () + formatter.expectations (_G.expectations, " " .. indent) + + else + -- Oh dear, most likely your nesting is not quite right! + error ("malformed spec in " .. tostring (description), 2) + end + + after () + end + + for _, example in ipairs (examples) do + -- Also, run every block in a sub-environment, so that before() and + -- after() calls from one block don't affect any other. + local fenv = setmetatable ({}, { __index = env }) + setfenv (block, fenv) + block (example, fenv) + end +end + + +local function run (spec, format) + formatter = format or formatter + formatter.header (stats) + run_specs (spec) + formatter.footer (stats) +end + + +--[[ ----------------- ]]-- +--[[ Public Interface. ]]-- +--[[ ----------------- ]]-- + +local M = { + matchers = matchers, + progress = progress, + report = report, + run = run, +} + +return M diff --git a/specs/package_ext_spec.lua b/specs/package_ext_spec.lua new file mode 100644 index 0000000..c94930f --- /dev/null +++ b/specs/package_ext_spec.lua @@ -0,0 +1,34 @@ +{["specify package_ext"] = { + before = function () + unextended = require "package_ext" + end, + + {["context when requiring the module"] = { + before = function () + -- don't try to check all the entries in unextended package, + -- because they naturally change as modules are loaded. + apis = { "config", "cpath", "loaders", "loadlib", "preload", + "searchers", "searchpath", "seeall" } + end, + + {["it returns the unextended package table"] = function () + expect (unextended.config).should_be (package.config) + expect (unextended.dirsep).should_be (nil) + expect (unextended.pathsep).should_be (nil) + expect (unextended.path_mark).should_be (nil) + expect (unextended.execdir).should_be (nil) + expect (unextended.igmark).should_be (nil) + end}, + {["it splits package.config up"] = function () + expect (string.format ("%s\n%s\n%s\n%s\n%s\n", + package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark) + ).should_be (package.config) + end}, + {["it doesn't override any other module access points"] = function () + + for _, api in ipairs (apis) do + expect (package[api]).should_be (unextended[api]) + end + end}, + }}, +}} diff --git a/specs/specl b/specs/specl new file mode 100755 index 0000000..3dbcfa1 --- /dev/null +++ b/specs/specl @@ -0,0 +1,86 @@ +#! /usr/bin/env lua + +-- Specification testing framework. +-- +-- Copyright (c) 2013 Free Software Foundation, Inc. +-- Written by Gary V. Vaughan, 2013 +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3, or (at your option) +-- any later version. +-- +-- This program is distributed in the hope that it will be useful, but +-- WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-- General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; see the file COPYING. If not, write to the +-- Free Software Foundation, Fifth Floor, 51 Franklin Street, Boston, +-- MA 02111-1301, USA. + +require "std" + +package.path = "specs/lib/?.lua;src/?.lua;" .. package.path + +local specl = require "specl" + +-- TODO: remove fake specs +-- TODO: write some specs for specl! +-- TODO: make sure it really works with 5.1 +-- TODO: Environment sharing between before/example/after is not right :( + +prog = { + name = arg[0]:gsub ("^.*/", ""), + banner = "Specl 0.1 by Gary V. Vaughan ", + purpose = "A specification testing framework.", + notes = "Copyright (c) 2013 Gary V. Vaughan\n" .. + "Specl comes with ABSOLUTELY NO WARRANTY.\n" .. + "You may redistribute copies of Specl under the terms of the GNU\n" .. + "General Public License; either version 3, or any later version.\n" .. + "Report bugs at http://github.com/gvvaughan/specl/issues." +} + +options = { + Option {{"verbose", "v"}, "verbose mode"}, +} + + +-- Called by io.processFiles() to concatenate a comma separated list of +-- specifications in each FILENAME. +local spec = {} +function slurp (filename) + local s, errmsg = io.slurp () + if errmsg ~= nil then + io.stderr:write (errmsg .. "\n") + os.exit (1) + end + + -- Remove leading comment lines, carefully preserving line numbers for + -- error messages from 'load', and then inject the 'return' keyword at + -- the start of the first non-blank line. + s = s:gsub ("^%s*%-%-[^\r\n]+i(\r*\n)%s*", "%1" + ):gsub ("[^\r\n]", "return %0", 1) + local f, errmsg = load (s, filename) + + -- Execute the function from 'load', and save the value returned, or + -- report any error right away. + local t + if f ~= nil then + t, errmsg = f () + end + if errmsg ~= nil then + error (errmsg) + end + + -- Append to the specification list, which specl will run on completion. + table.insert (spec, t) +end + + +getopt.processArgs () +io.processFiles (slurp) +specl.run (spec, getopt.opt.verbose and specl.report) + +os.exit (0) diff --git a/specs/table_ext_spec.lua b/specs/table_ext_spec.lua new file mode 100644 index 0000000..f331431 --- /dev/null +++ b/specs/table_ext_spec.lua @@ -0,0 +1,326 @@ +{["specify table_ext"] = { + before = function () + unextended = require "table_ext" + end, + + + {["describe table.clone ()"] = { + before = function () + subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + f = table.clone + end, + + {["it does not just return the subject"] = function () + expect (f (subject)).should_not_be (subject) + end}, + {["it does copy the subject"] = function () + expect (f (subject)).should_equal (subject) + end}, + {["it only makes a shallow copy"] = function () + expect (f (subject).k1).should_be (subject.k1) + end}, + {["the original subject is not perturbed"] = function () + target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } + copy = f (subject) + expect (subject).should_equal (target) + expect (subject).should_be (subject) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + end}, + }}, + + + {["describe table.clone_rename()"] = { + before = function () + subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + f = table.clone_rename + end, + + {["it does not just return the subject"] = function () + expect (f ({}, subject)).should_not_be (subject) + end}, + {["it copies the subject"] = function () + expect (f ({}, subject)).should_equal (subject) + end}, + {["it only makes a shallow copy"] = function () + expect (f ({}, subject).k2).should_be (subject.k2) + end}, + {["context when renaming some keys"] = { + before = function () + target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } + end, + + {["it renames during cloning"] = function () + expect (f ({k1 = "newkey"}, subject)).should_equal (target) + end}, + {["it does not perturb the value in the renamed key field"] = function () + expect (f ({k1 = "newkey"}, subject).newkey).should_be (subject.k1) + end}, + }}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, {}, nil) + expect ("table expected").should_error (f, {}, "foo") + end}, + }}, + + + {["describe table.empty ()"] = { + before = function () + f = table.empty + end, + + {["it returns true for an empty table"] = function () + expect (f {}).should_be (true) + expect (f {nil}).should_be (true) + end}, + {["it returns false for a non-empty table"] = function () + expect (f {"stuff"}).should_be (false) + expect (f {{}}).should_be (false) + expect (f {false}).should_be (false) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + end}, + }}, + + + {["describe table.invert ()"] = { + before = function () + subject = { k1 = 1, k2 = 2, k3 = 3 } + f = table.invert + end, + + {["it returns a new table"] = function () + expect (f (subject)).should_not_be (subject) + end}, + {["it inverts keys and values in the returned table"] = function () + expect (f (subject)).should_equal { "k1", "k2", "k3" } + end}, + {["it is reversible"] = function () + expect (f (f (subject))).should_equal (subject) + end}, + {["it seems to copy a list of 1..n numbers"] = function () + subject = { 1, 2, 3 } + expect (f (subject)).should_equal (subject) + expect (f (subject)).should_not_be (subject) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + end}, + }}, + + + {["describe table.keys ()"] = { + before = function () + subject = { k1 = 1, k2 = 2, k3 = 3 } + f = table.keys + end, + + {["it returns an empty list when subject is empty"] = function () + expect (f {}).should_equal {} + end}, + {["it makes a list of table keys"] = function () + cmp = function (a, b) return a < b end + expect (table.sort (f (subject), cmp)).should_equal {"k1", "k2", "k3"} + end}, + {["it does not guarantee stable ordering"] = function () + subject = {} + -- is this a good test? there's a vanishingly small possibility the + -- returned table will have all 10000 keys in the same order... + for i = 10000, 1, -1 do table.insert (subject, i) end + expect (f (subject)).should_not_equal (subject) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + end}, + }}, + + + {["describe table.merge ()"] = { + before = function () + -- Additional merge keys which are moderately unusual + t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } + t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } + f = table.merge + + target = {} + for k, v in pairs (t1) do target[k] = v end + for k, v in pairs (t2) do target[k] = v end + end, + + {["it doesn't create a whole new table"] = function () + expect (f (t1, t2)).should_be (t1) + end}, + {["it doesn't change t1, if t2 is empty"] = function () + expect (f (t1, {})).should_be (t1) + end}, + {["it copies t2, if t1 is empty"] = function () + expect (f ({}, t1)).should_not_be (t1) + expect (f ({}, t1)).should_equal (t1) + end}, + {["it merges keys from t2 into t1"] = function () + expect (f (t1, t2)).should_equal (target) + end}, + {["it gives precedence to values from t2"] = function () + original = table.clone (t1) + m = f (t1, t2) -- Merge is destructive, do it once only. + expect (m.k3).should_be (t2.k3) + expect (m.k3).should_not_be (original.k3) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil, nil) + expect ("table expected").should_error (f, "foo", "bar") + end}, + }}, + + + {["describe table.new ()"] = { + before = function () + f = table.new + end, + + {["context when not setting a default "] = { + before = function () + default = nil + end, + + {["it returns a new table when nil is passed"] = function () + expect (f (default, nil)).should_equal {} + end}, + {["it returns any table passed in"] = function () + t = { "unique table" } + expect (f (default, t)).should_be (t) + end}, + }}, + {["context when setting a default "] = { + before = function () + default = "default" + end, + + {["it returns a new table when nil is passed"] = function () + expect (f (default, nil)).should_equal {} + end}, + {["it returns any table passed in"] = function () + t = { "unique table" } + expect (f (default, t)).should_be (t) + end}, + }}, + {["it returns the stored value for existing keys"] = function () + t = f ("default") + v = { "unique value" } + t[1] = v + expect (t[1]).should_be (v) + end}, + {["it returns the constructor default for unset keys"] = function () + t = f ("default") + expect (t[1]).should_be "default" + end}, + {["it returns the actual default object"] = function () + default = { "unique object" } + t = f (default) + expect (t[1]).should_be (default) + end}, + {["it diagnoses non-tables/non-nil in the second argument"] = function () + expect ("table expected").should_error (f, nil, "foo") + end}, + }}, + + + {["describe table.size ()"] = { + before = function () + -- - 1 - --------- 2 ---------- -- 3 -- + subject = { "one", { { "two" }, "three" }, four = 5 } + f = table.size + end, + + {["it counts the number of keys in a table"] = function () + expect (f (subject)).should_be (3) + end}, + {["it counts no keys in an empty table"] = function () + expect (f {}).should_be (0) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + end}, + }}, + + + {["describe table.sort ()"] = { + before = function () + subject = { 5, 2, 4, 1, 0, 3 } + target = { 0, 1, 2, 3, 4, 5 } + cmp = function (a, b) return a < b end + f = table.sort + end, + + {["it sorts elements in place"] = function () + f (subject, cmp) + expect (subject).should_equal (target) + end}, + {["it returns the sorted table"] = function () + expect (f (subject, cmp)).should_equal (target) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, nil) + end}, + }}, + + + {["describe table.values ()"] = { + before = function () + subject = { k1 = {1}, k2 = {2}, k3 = {3} } + f = table.values + end, + + {["it returns an empty list when subject is empty"] = function () + expect (f {}).should_equal {} + end}, + {["it makes a list of table values"] = function () + cmp = function (a, b) return a[1] < b[1] end + expect (table.sort (f (subject), cmp)).should_equal {{1}, {2}, {3}} + end}, + {["it does guarantee stable ordering"] = function () + subject = {} + -- is this a good test? or just requiring an implementation quirk? + for i = 10000, 1, -1 do table.insert (subject, i) end + expect (f (subject)).should_equal (subject) + end}, + {["it diagnoses non-table arguments"] = function () + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + end}, + }}, + + + {["context when requiring the module"] = { + before = function () + extensions = { "clone", "clone_rename", "empty", "invert", "keys", + "merge", "new", "size", "sort", "values" } + end, + + {["it returns the unextended module table"] = function () + for _, api in ipairs (extensions) do + if api ~= "sort" then + expect (unextended[api]).should_be (nil) + end + end + end}, + {["it injects an enhanced sort function"] = function () + expect (unextended.sort).should_not_be (table.sort) + end}, + {["it doesn't override any other module access points"] = function () + for api in pairs (unextended) do + if api ~= "sort" then + expect (table[api]).should_be (unextended[api]) + end + end + end}, + }}, +}} diff --git a/src/getopt.lua b/src/getopt.lua index 78734df..78962cf 100644 --- a/src/getopt.lua +++ b/src/getopt.lua @@ -202,11 +202,16 @@ end -- -help/-h automatically; -- stops program if there was an error, or if -help or -- -version was used. +local M = { + opt = {}, +} + local function processArgs () local totArgs = #arg options = makeOptions (options) local errors - _G.arg, opt, errors = getopt.getOpt (arg, options) + _G.arg, M.opt, errors = getopt.getOpt (arg, options) + local opt = M.opt if (opt.version or opt.help) and prog.banner then io.writelines (prog.banner) end @@ -272,11 +277,9 @@ if type (_DEBUG) == "table" and _DEBUG.std then end -- Public interface -local M = { +return table.merge (M, { getOpt = getOpt, processArgs = processArgs, usage = usage, usageInfo = usageInfo, -} - -return M +}) diff --git a/src/index.html b/src/index.html index a6f44be..f94edd1 100644 --- a/src/index.html +++ b/src/index.html @@ -50,18 +50,10 @@

    Modules

    math -
  • - package -
  • -
  • string
  • -
  • - table -
  • - @@ -200,21 +192,11 @@

    Modules

    Additions to the math module. - - package - - - string Additions to the string module TODO: Pretty printing (use in getopt); see source for details. - - table - - - diff --git a/src/io_ext.lua b/src/io_ext.lua index d867f51..1696ba4 100644 --- a/src/io_ext.lua +++ b/src/io_ext.lua @@ -2,7 +2,7 @@ module ("io", package.seeall) require "base" -require "package_ext" +local package_unext = require "package_ext" -- Get file handle metatable diff --git a/src/package_ext.lua b/src/package_ext.lua index 974139a..01e61db 100644 --- a/src/package_ext.lua +++ b/src/package_ext.lua @@ -1,6 +1,9 @@ -- Additions to the package module. -module ("package", package.seeall) +local table_unext = require "table_ext" + +-- Save original unextended table. +local unextended = table.clone (package) --- Make named constants for package.config (undocumented -- in 5.1; see luaconf.h for C equivalents). @@ -11,5 +14,7 @@ module ("package", package.seeall) -- @field path_mark string that marks substitution points in a path template -- @field execdir (Windows only) replaced by the executable's directory in a path -- @field igmark Mark to ignore all before it when building luaopen_ function name. -dirsep, pathsep, path_mark, execdir, igmark = +package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark = string.match (package.config, "^([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)") + +return unextended diff --git a/src/std.lua b/src/std.lua index 8b4feae..047ffac 100644 --- a/src/std.lua +++ b/src/std.lua @@ -7,7 +7,7 @@ -- this also helps to check module dependencies. --
  • TODO: pre-compile.
  • -- -local version = "General Lua libraries / 30" +local version = "General Lua libraries / 32" for _, m in ipairs (require "modules") do _G[m] = require (m) diff --git a/src/table_ext.lua b/src/table_ext.lua index c2eb4ad..6f63bd5 100644 --- a/src/table_ext.lua +++ b/src/table_ext.lua @@ -1,15 +1,14 @@ -- Extensions to the table module -module ("table", package.seeall) --local list = require "list" FIXME: allow require loops -local _sort = sort +local _sort = table.sort --- Make table.sort return its result. -- @param t table -- @param c comparator function -- @return sorted table -function sort (t, c) +local function sort (t, c) _sort (t, c) return t end @@ -17,14 +16,14 @@ end --- Return whether table is empty. -- @param t table -- @return true if empty or false otherwise -function empty (t) +local function empty (t) return not next (t) end --- Find the number of elements in a table. -- @param t table -- @return number of elements in t -function size (t) +local function size (t) local n = 0 for _ in pairs (t) do n = n + 1 @@ -35,10 +34,10 @@ end --- Make the list of keys of a table. -- @param t table -- @return list of keys -function keys (t) +local function keys (t) local u = {} for i, v in pairs (t) do - insert (u, i) + table.insert (u, i) end return u end @@ -46,10 +45,10 @@ end --- Make the list of values of a table. -- @param t table -- @return list of values -function values (t) +local function values (t) local u = {} for i, v in pairs (t) do - insert (u, v) + table.insert (u, v) end return u end @@ -57,7 +56,7 @@ end --- Invert a table. -- @param t table {i=v, ...} -- @return inverted table {v=i, ...} -function invert (t) +local function invert (t) local u = {} for i, v in pairs (t) do u[v] = i @@ -70,7 +69,7 @@ end -- @param t table -- @param nometa if non-nil don't copy metatable -- @return copy of table -function clone (t, nometa) +local function clone (t, nometa) local u = {} if not nometa then setmetatable (u, getmetatable (t)) @@ -85,7 +84,7 @@ end -- @param map table {old_key=new_key, ...} -- @param t table to copy -- @return copy of table -function clone_rename (map, t) +local function clone_rename (map, t) local r = clone (t) for i, v in pairs (map) do r[v] = t[i] @@ -98,7 +97,7 @@ end -- @param t first table -- @param u second table -- @return first table -function merge (t, u) +local function merge (t, u) for i, v in pairs (u) do t[i] = v end @@ -109,9 +108,30 @@ end -- @param x default entry value (default: nil) -- @param t initial table (default: {}) -- @return table whose unset elements are x -function new (x, t) +local function new (x, t) return setmetatable (t or {}, {__index = function (t, i) return x end}) end + +-- Save original unextended table. +local unextended = clone (table) + +local M = { + clone = clone, + clone_rename = clone_rename, + empty = empty, + invert = invert, + keys = keys, + merge = merge, + new = new, + size = size, + sort = sort, + values = values, +} + +-- Inject stdlib extensions directly into the table package. +_G.table = merge (table, M) + +return unextended diff --git a/stdlib-30-1.rockspec b/stdlib-32-1.rockspec similarity index 94% rename from stdlib-30-1.rockspec rename to stdlib-32-1.rockspec index 9aa02ff..2c9f6c0 100644 --- a/stdlib-30-1.rockspec +++ b/stdlib-32-1.rockspec @@ -1,25 +1,25 @@ description = { license = "MIT/X11", - summary = "General Lua libraries", homepage = "http://github.com/rrthomas/lua-stdlib/", detailed = " stdlib is a library of modules for common programming tasks,\ including list, table and functional operations, regexps, objects,\ pickling, pretty-printing and getopt.\ ", + summary = "General Lua libraries", } build = { type = "command", - build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", copy_directories = { }, + build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", install_command = "make install", } -version = "30-1" dependencies = { "lua >= 5.1", } package = "stdlib" source = { - branch = "release-v30", + branch = "release-v32", url = "git://github.com/rrthomas/lua-stdlib.git", } +version = "32-1" diff --git a/stdlib-git-1.rockspec b/stdlib-git-1.rockspec index 2a0b19f..55b1f3d 100644 --- a/stdlib-git-1.rockspec +++ b/stdlib-git-1.rockspec @@ -1,24 +1,24 @@ version = "git-1" package = "stdlib" -dependencies = { - "lua >= 5.1", +description = { + detailed = " stdlib is a library of modules for common programming tasks,\ + including list, table and functional operations, regexps, objects,\ + pickling, pretty-printing and getopt.\ + ", + summary = "General Lua libraries", + license = "MIT/X11", + homepage = "http://github.com/rrthomas/lua-stdlib/", } build = { - install_command = "make install", - build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", type = "command", copy_directories = { }, + build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + install_command = "make install", +} +dependencies = { + "lua >= 5.1", } source = { url = "git://github.com/rrthomas/lua-stdlib.git", } -description = { - license = "MIT/X11", - detailed = " stdlib is a library of modules for common programming tasks,\ - including list, table and functional operations, regexps, objects,\ - pickling, pretty-printing and getopt.\ - ", - homepage = "http://github.com/rrthomas/lua-stdlib/", - summary = "General Lua libraries", -} From a919fece24acd8bcd04a6918fbec0bb57caaee42 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 28 Feb 2013 03:23:45 +0700 Subject: [PATCH 09/34] Release v33 --- Makefile | 47 +- Makefile.am | 42 +- Makefile.in | 39 +- configure | 20 +- configure.ac | 2 +- specs/getopt_spec.lua | 83 +++ specs/lib/specl.lua | 43 +- specs/specl | 33 +- specs/string_ext_spec.lua | 522 +++++++++++++++++++ specs/table_ext_spec.yaml | 262 ++++++++++ src/files/base.html | 12 - src/files/bin.html | 12 - src/files/debug_ext.html | 12 - src/files/debug_init.html | 12 - src/files/fstable.html | 12 - src/files/getopt.html | 54 +- src/files/io_ext.html | 12 - src/files/lcs.html | 12 - src/files/list.html | 12 - src/files/math_ext.html | 12 - src/files/mbox.html | 12 - src/files/modules.html | 12 - src/files/object.html | 12 - src/files/package_ext.html | 14 - src/files/parser.html | 12 - src/files/set.html | 12 - src/files/std.html | 12 - src/files/strbuf.html | 12 - src/files/strict.html | 12 - src/files/string_ext.html | 30 +- src/files/table_ext.html | 14 - src/files/tree.html | 12 - src/files/xml.html | 12 - src/getopt.lua | 176 ++++--- src/index.html | 9 - src/io_ext.lua | 2 - src/modules/base.html | 12 - src/modules/debug.html | 12 - src/modules/io.html | 12 - src/modules/math.html | 12 - src/std.lua | 2 +- src/string_ext.lua | 144 +++-- stdlib-32-1.rockspec => stdlib-33-1.rockspec | 26 +- stdlib-git-1.rockspec | 24 +- 44 files changed, 1178 insertions(+), 686 deletions(-) create mode 100644 specs/getopt_spec.lua create mode 100644 specs/string_ext_spec.lua create mode 100644 specs/table_ext_spec.yaml rename stdlib-32-1.rockspec => stdlib-33-1.rockspec (94%) diff --git a/Makefile b/Makefile index 1c83fbd..f8e21fc 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ AUTOHEADER = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing AUTOMAKE = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing automake-1.13 AWK = awk CYGPATH_W = echo -DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"32\" -DPACKAGE_STRING=\"stdlib\ 32\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"32\" +DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"33\" -DPACKAGE_STRING=\"stdlib\ 33\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"33\" ECHO_C = \c ECHO_N = ECHO_T = @@ -187,15 +187,15 @@ MKDIR_P = build-aux/install-sh -c -d PACKAGE = stdlib PACKAGE_BUGREPORT = rrt@sc3d.org PACKAGE_NAME = stdlib -PACKAGE_STRING = stdlib 32 +PACKAGE_STRING = stdlib 33 PACKAGE_TARNAME = stdlib PACKAGE_URL = -PACKAGE_VERSION = 32 +PACKAGE_VERSION = 33 PATH_SEPARATOR = : SET_MAKE = SHELL = /bin/sh STRIP = -VERSION = 32 +VERSION = 33 abs_builddir = /Volumes/Home/Devo/lua-stdlib--master--0 abs_srcdir = /Volumes/Home/Devo/lua-stdlib--master--0 abs_top_builddir = /Volumes/Home/Devo/lua-stdlib--master--0 @@ -272,7 +272,9 @@ SOURCES = \ $(NOTHING_ELSE) SPECS = \ + specs/getopt_spec.lua \ specs/package_ext_spec.lua \ + specs/string_ext_spec.lua \ specs/table_ext_spec.lua \ $(NOTHING_ELSE) @@ -783,43 +785,6 @@ rockspecs: check-local: $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua -GIT ?= git -LN_S ?= ln -sf - -tag-release: - $(GIT) diff --exit-code && \ - $(GIT) tag -f -a -m "Release tag" v$(VERSION) - -define unpack-distcheck-release - rm -rf $(PACKAGE)-$(VERSION)/ && \ - tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ - cp -a -f $(PACKAGE)-$(VERSION)/* . && \ - rm -rf $(PACKAGE)-$(VERSION)/ && \ - echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ - echo './configure && make all rockspecs' && \ - ./configure --version && ./configure && \ - $(MAKE) all rockspecs -endef - -check-in-release: distcheck - current_branch=`$(GIT) symbolic-ref HEAD`; \ - { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ - { $(GIT) pull origin release || true; } && \ - $(unpack-distcheck-release) && \ - $(GIT) add . && \ - $(GIT) commit -a -m "Release v$(VERSION)" && \ - $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ - $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` - -GIT_PUBLISH ?= $(GIT) - -release: rockspecs - $(MAKE) tag-release && \ - $(MAKE) check-in-release && \ - $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ - LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - $(WOGER) lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/Makefile.am b/Makefile.am index bb7e73e..c4f89ad 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,7 +38,9 @@ SOURCES = \ $(NOTHING_ELSE) SPECS = \ + specs/getopt_spec.lua \ specs/package_ext_spec.lua \ + specs/string_ext_spec.lua \ specs/table_ext_spec.lua \ $(NOTHING_ELSE) @@ -78,43 +80,3 @@ rockspecs: check-local: $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua - -GIT ?= git -LN_S ?= ln -sf - -tag-release: - $(GIT) diff --exit-code && \ - $(GIT) tag -f -a -m "Release tag" v$(VERSION) - -define unpack-distcheck-release - rm -rf $(PACKAGE)-$(VERSION)/ && \ - tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ - cp -a -f $(PACKAGE)-$(VERSION)/* . && \ - rm -rf $(PACKAGE)-$(VERSION)/ && \ - echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ - echo './configure && make all rockspecs' && \ - ./configure --version && ./configure && \ - $(MAKE) all rockspecs -endef - -check-in-release: distcheck - current_branch=`$(GIT) symbolic-ref HEAD`; \ - { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ - { $(GIT) pull origin release || true; } && \ - $(unpack-distcheck-release) && \ - $(GIT) add . && \ - $(GIT) commit -a -m "Release v$(VERSION)" && \ - $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ - $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` - - -## To test the release process without publishing upstream, use: -## make release WOGER=: GIT_PUBLISH=: -GIT_PUBLISH ?= $(GIT) - -release: rockspecs - $(MAKE) tag-release && \ - $(MAKE) check-in-release && \ - $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ - LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - $(WOGER) lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" diff --git a/Makefile.in b/Makefile.in index af94d5b..77907a9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -272,7 +272,9 @@ SOURCES = \ $(NOTHING_ELSE) SPECS = \ + specs/getopt_spec.lua \ specs/package_ext_spec.lua \ + specs/string_ext_spec.lua \ specs/table_ext_spec.lua \ $(NOTHING_ELSE) @@ -783,43 +785,6 @@ rockspecs: check-local: $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua -GIT ?= git -LN_S ?= ln -sf - -tag-release: - $(GIT) diff --exit-code && \ - $(GIT) tag -f -a -m "Release tag" v$(VERSION) - -define unpack-distcheck-release - rm -rf $(PACKAGE)-$(VERSION)/ && \ - tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ - cp -a -f $(PACKAGE)-$(VERSION)/* . && \ - rm -rf $(PACKAGE)-$(VERSION)/ && \ - echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ - echo './configure && make all rockspecs' && \ - ./configure --version && ./configure && \ - $(MAKE) all rockspecs -endef - -check-in-release: distcheck - current_branch=`$(GIT) symbolic-ref HEAD`; \ - { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ - { $(GIT) pull origin release || true; } && \ - $(unpack-distcheck-release) && \ - $(GIT) add . && \ - $(GIT) commit -a -m "Release v$(VERSION)" && \ - $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ - $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` - -GIT_PUBLISH ?= $(GIT) - -release: rockspecs - $(MAKE) tag-release && \ - $(MAKE) check-in-release && \ - $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ - LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - $(WOGER) lua package=$(PACKAGE) package_name=$(PACKAGE_NAME) version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) home="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' $(LUA) -l$(PACKAGE) -e 'print (description.homepage)'`" - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/configure b/configure index 2f3430f..9506b39 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 32. +# Generated by GNU Autoconf 2.69 for stdlib 33. # # Report bugs to . # @@ -578,8 +578,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='32' -PACKAGE_STRING='stdlib 32' +PACKAGE_VERSION='33' +PACKAGE_STRING='stdlib 33' PACKAGE_BUGREPORT='rrt@sc3d.org' PACKAGE_URL='' @@ -1213,7 +1213,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 32 to adapt to many kinds of systems. +\`configure' configures stdlib 33 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1279,7 +1279,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 32:";; + short | recursive ) echo "Configuration of stdlib 33:";; esac cat <<\_ACEOF @@ -1365,7 +1365,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 32 +stdlib configure 33 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1382,7 +1382,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 32, which was +It was created by stdlib $as_me 33, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2245,7 +2245,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='32' + VERSION='33' cat >>confdefs.h <<_ACEOF @@ -3424,7 +3424,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 32, which was +This file was extended by stdlib $as_me 33, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3477,7 +3477,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 32 +stdlib config.status 33 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 1ad200f..62e4f2a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake -AC_INIT(stdlib, 32, rrt@sc3d.org) +AC_INIT(stdlib, 33, rrt@sc3d.org) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) AM_SILENT_RULES([yes]) diff --git a/specs/getopt_spec.lua b/specs/getopt_spec.lua new file mode 100644 index 0000000..7c77ddf --- /dev/null +++ b/specs/getopt_spec.lua @@ -0,0 +1,83 @@ +{["specify getopt"] = { + before = function () + getopt = require "getopt" + Option = getopt.Option + end, + + + {["describe getopt.getOpt ()"] = { + before = function () + prog = { + name = "getopt_spec.lua", + options = { Option {{"verbose", "v"}, "verbosely list files"}, + Option {{"output", "o"}, "dump to FILE", "Opt", "FILE"}, + Option {{"name", "n"}, + "only dump USER's files", "Req", "USER"}, + } + } + + function test (cmdLine) + local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options) + if #errors == 0 then + return { options = opts, args = nonOpts } + else + return errors + end + end + + getopt.processArgs (prog) + end, + + {["it recognizes a user defined option"] = function () + expect (test {"foo", "-v"}).should_equal ( + { options = { verbose = {1}}, args = { "foo" } }) + end}, + {["it treats -- as the end of the option list"] = function () + expect (test {"foo", "--", "-v"}).should_equal ( + { options = {}, args = { "foo", "-v" } }) + end}, + {["it captures a list of repeated option arguments"] = function () + expect (test {"-o", "-V", "-name", "bar", "--name=baz"}).should_equal ( + { options = { name = {"bar", "baz"}, version = {1}, output = {1}}, + args = {} }) + end}, + {["it diagnoses unrecognized options"] = function () + expect (test {"-foo"}).should_contain "unrecognized option `-foo'" + end}, + }}, + + + {["describe getopt.usageInfo ()"] = { + {["context when specifying options"] = { + before = function () + helppatt = "%-h, %-%-help%s+print this help, then exit" + versionpatt = "%-V, %-%-version%s+print version information, then exit" + prog = { name = "getopt_spec.lua", options = {} } + options = { Option {{"help", "?"}, "display this help"}, + Option {{"version"}, "display version number"} } + f = getopt.usageInfo + end, + + {["it provides a default version option"] = function () + getopt.processArgs (prog) + expect (f ("", prog.options)).should_match (versionpatt) + end}, + {["it allows the user to override the version option"] = function () + prog.options = options + getopt.processArgs (prog) + expect (f ("", prog.options)).should_not_match (versionpatt) + expect (f ("", prog.options)).should_match (" %-%-version%s+display") + end}, + {["it provides a default help option"] = function () + getopt.processArgs (prog) + expect (f ("", prog.options)).should_match (helppatt) + end}, + {["it allows the user to override the help option"] = function () + prog.options = options + getopt.processArgs (prog) + expect (f ("", prog.options)).should_not_match (helppatt) + expect (f ("", prog.options)).should_match ("%-%?, %-%-help%s+display") + end}, + }}, + }}, +}} diff --git a/specs/lib/specl.lua b/specs/lib/specl.lua index 60cc8ea..44cbda1 100644 --- a/specs/lib/specl.lua +++ b/specs/lib/specl.lua @@ -182,22 +182,32 @@ local matchers = { end, -- Matches if VALUE matches regular expression PATTERN. - match = function (target, pattern) - if type (target) ~= 'string' then - error ("type error, 'match' matcher expecting target as string") + match = function (value, pattern) + if type (value) ~= "string" then + error ("'match' matcher: string expected, but got " .. type (value)) end local m = "expecting string matching " .. q(pattern) .. ", but got " .. q(value) - return (string.match (value, pattern) == true), m + return (value:match (pattern) ~= nil), m end, - -- Matches if VALUE contains the string EXPECTED. + -- Matches if VALUE contains EXPECTED. contain = function (value, expected) - if type (target) ~= 'string' then - error ("type error, 'contain' matcher expecting target as string") + if type (value) == "string" and type (expected) == "string" then + -- Look for a substring if VALUE is a string. + local pattern = expected:gsub ("%W", "%%%0") + local m = "expecting string containing " .. q(expected) .. ", but got " .. q(value) + return (value:match (pattern) ~= nil), m + elseif type (value) == "table" then + -- Do deep comparison against keys and values of the table. + local m = "expecting table containing " .. q(expected) .. ", but got " .. q(value) + for k, v in pairs (value) do + if objcmp (k, expected) or objcmp (v, expected) then + return true, m + end + end + return false, m end - local m = "expecting string containing " .. q(expected) .. ", but got " .. q(value) - local pattern = ".*" .. expected:gsub ("%W", "%%%0") .. ".*" - return (string.match (value, pattern)), m + error ("'contain' matcher: string or table expected, but got " .. type (value)) end, } @@ -309,9 +319,10 @@ end local function run (spec, format) formatter = format or formatter - formatter.header (stats) + formatter.header (_G.stats) run_specs (spec) - formatter.footer (stats) + formatter.footer (_G.stats) + return _G.stats.fail == 0 end @@ -320,10 +331,18 @@ end --[[ ----------------- ]]-- local M = { + _VERSION = "0.1", + matchers = matchers, progress = progress, report = report, run = run, } + +if _G._SPEC then + -- Give specs access to some additional private access points. + M = table.merge (M, { _expect = expect }) +end + return M diff --git a/specs/specl b/specs/specl index 3dbcfa1..434ca8c 100755 --- a/specs/specl +++ b/specs/specl @@ -26,24 +26,25 @@ package.path = "specs/lib/?.lua;src/?.lua;" .. package.path local specl = require "specl" --- TODO: remove fake specs --- TODO: write some specs for specl! -- TODO: make sure it really works with 5.1 --- TODO: Environment sharing between before/example/after is not right :( prog = { - name = arg[0]:gsub ("^.*/", ""), - banner = "Specl 0.1 by Gary V. Vaughan ", - purpose = "A specification testing framework.", - notes = "Copyright (c) 2013 Gary V. Vaughan\n" .. + name = arg[0]:gsub ("^.*/", ""), + version = "Specl 0.1\nWritten by Gary V. Vaughan , 2013", + purpose = "A specification testing framework.", + description = "Execute specifications from FILEs or standard input, " .. + "reporting results on standard output.\nIf no FILE is listed, or w" .. + "here '-' is given as a FILE, read from standard input.", + copyright = "Copyright (c) 2013 Gary V. Vaughan\n" .. "Specl comes with ABSOLUTELY NO WARRANTY.\n" .. "You may redistribute copies of Specl under the terms of the GNU\n" .. - "General Public License; either version 3, or any later version.\n" .. - "Report bugs at http://github.com/gvvaughan/specl/issues." -} - -options = { - Option {{"verbose", "v"}, "verbose mode"}, + "General Public License; either version 3, or any later version.", + notes = "Report bugs at http://github.com/gvvaughan/specl/issues.", + options = { + getopt.Option {{"help"}, "print this help, then exit"}, + getopt.Option {{"version"}, "print version number, then exit"}, + getopt.Option {{"verbose", "v"}, "verbose mode"}, + } } @@ -79,8 +80,6 @@ function slurp (filename) end -getopt.processArgs () +getopt.processArgs (prog) io.processFiles (slurp) -specl.run (spec, getopt.opt.verbose and specl.report) - -os.exit (0) +os.exit (specl.run (spec, getopt.opt.verbose and specl.report) and 0 or 1) diff --git a/specs/string_ext_spec.lua b/specs/string_ext_spec.lua new file mode 100644 index 0000000..600880e --- /dev/null +++ b/specs/string_ext_spec.lua @@ -0,0 +1,522 @@ +{["specify string_ext"] = { + before = function () + unextended = require "string_ext" + + subject = "a string \n\n" + end, + + + {["describe .. operator"] = { + {["it concatenates string arguments"] = function () + target = "a string \n\n another string" + expect (subject .. " another string").should_be (target) + end}, + {["it stringifies non-string arguments"] = function () + argument = { "a table" } + expect (subject .. argument).should_be (string.format ("%s%s", subject, tostring (argument))) + end}, + {["it stringifies nil arguments"] = function () + argument = nil + expect (subject .. argument).should_be (string.format ("%s%s", subject, tostring (argument))) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = subject .. " concatenate something" + expect (subject).should_be (original) + end}, + }}, + + + {["describe string.caps ()"] = { + before = function () + f = string.caps + end, + + {["it capitalises words of a string"] = function () + target = "A String \n\n" + expect (f (subject)).should_be (target) + end}, + {["it changes only the first letter of each word"] = function () + expect (f "a stRiNg").should_be "A StRiNg" + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject) + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.chomp ()"] = { + before = function () + f = string.chomp + end, + + {["it removes a single trailing newline from a string"] = function () + target = "a string \n" + expect (f (subject)).should_be (target) + end}, + {["it doesn't change a string with no trailing newline"] = function () + subject = "a string " + expect (f (subject)).should_be (subject) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject) + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.escape_pattern ()"] = { + before = function () + f = string.escape_pattern + end, + + {["it inserts a % before any non-alphanumeric in a string"] = function () + subject, target = "", "" + for c = 32, 126 do + s = string.char (c) + subject = subject .. s + if s:match ("%W") then target = target .. "%" end + target = target .. s + end + expect (f (subject)).should_be (target) + end}, + {["legacy escapePattern call is the same function"] = function () + expect (string.escapePattern).should_be (f) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject) + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.escape_shell ()"] = { + before = function () + f = string.escape_shell + end, + + {["it inserts a \\ before any shell metacharacters"] = function () + subject, target = "", "" + for c = 32, 126 do + s = string.char (c) + subject = subject .. s + if s:match ("[][ ()\\\"']") then target = target .. "\\" end + target = target .. s + end + expect (f (subject)).should_be (target) + end}, + {["legacy escapeShell call is the same function"] = function () + expect (string.escapeShell).should_be (f) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject) + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.finds ()"] = { + before = function () + subject = "abcd" + f = string.finds + end, + + {["it creates a list of pattern captures"] = function () + target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } + expect ({f (subject, "(.)(.)")}).should_equal ({ target }) + end}, + {["it creates an empty list where no captures are matched "] = function () + target = {} + expect ({f (subject, "(x)")}).should_equal ({ target }) + end}, + {["it creates an empty list for a pattern without captures"] = function () + target = { { 1, 1; capt = {} } } + expect ({f (subject, "a")}).should_equal ({ target }) + end}, + {["it starts the search at a specified index into the subject"] = function () + target = { { 8, 9; capt = { "a", "b" } }, { 10, 11; capt = { "c", "d" } } } + expect ({f ("garbage" .. subject, "(.)(.)", 8)}).should_equal ({ target }) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, "...") + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + -- FIXME: This looks like a misfeature to me, let's remove it! + {["describe string.format ()"] = { + before = function () + subject = "string: %s, number: %d" + f = string.format + end, + + {["it returns a single argument without attempting formatting"] = function () + expect (f (subject)).should_be (subject) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject) + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil, "arg") + expect ("string expected").should_error (f, { "a table" }, "arg") + end}, + }}, + + + {["describe string.ltrim ()"] = { + before = function () + subject = " \t\r\n a short string \t\r\n " + f = string.ltrim + end, + + {["it removes whitespace from the start of a string"] = function () + target = "a short string \t\r\n " + expect (f (subject)).should_equal (target) + end}, + {["it supports custom removal patterns"] = function () + target = "\r\n a short string \t\r\n " + expect (f (subject, "[ \t\n]+")).should_equal (target) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, "%W") + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.numbertosi ()"] = { + before = function () + f = string.numbertosi + end, + + {["it returns a number using SI suffixes"] = function () + target = {"1e-9", "1y", "1z", "1a", "1f", "1p", "1n", "1mu", "1m", "1", + "1k", "1M", "1G", "1T", "1P", "1E", "1Z", "1Y", "1e9"} + subject = {} + for n = -28, 28, 3 do + m = 10 * (10 ^ n) + table.insert (subject, f (m)) + end + expect (subject).should_equal (target) + end}, + {["it coerces string arguments to a number"] = function () + expect (f "1000").should_be "1k" + end}, + {["it diagnoses non-numeric arguments"] = function () + expect ("attempt to perform arithmetic").should_error (f, nil) + expect ("number expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.ordinal_suffix ()"] = { + before = function () + f = string.ordinal_suffix + end, + + {["it returns the English suffix for a number"] = function () + subject, target = {}, {} + for n = -120, 120 do + suffix = "th" + m = math.abs (n) % 10 + if m == 1 and math.abs (n) % 100 ~= 11 then suffix = "st" + elseif m == 2 and math.abs (n) % 100 ~= 12 then suffix = "nd" + elseif m == 3 and math.abs (n) % 100 ~= 13 then suffix = "rd" + end + table.insert (target, n .. suffix) + table.insert (subject, n .. f (n)) + end + expect (subject).should_equal (target) + end}, + {["legacy ordinalSuffix call is the same function"] = function () + expect (string.ordinalSuffix).should_be (f) + end}, + {["it coerces string arguments to a number"] = function () + expect (f "-91").should_be "st" + end}, + {["it diagnoses non-numeric arguments"] = function () + expect ("number expected").should_error (f, nil) + expect ("number expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.pad ()"] = { + before = function () + width = 20 + f = string.pad + end, + + {["context when string is shorter than given width"] = { + before = function () + subject = "short string" + end, + + {["it right pads a string with spaces, to the given width"] = function () + target = "short string " + expect (f (subject, width)).should_be (target) + end}, + {["it left pads a string with spaces, given a negative width"] = function () + width = -width + target = " short string" + expect (f (subject, width)).should_be (target) + end}, + }}, + {["context when string is longer than given width"] = { + before = function () + subject = "a string that's longer than twenty characters" + end, + + {["it truncates a string to the given width"] = function () + target = "a string that's long" + expect (f (subject, width)).should_be (target) + end}, + {["it left pads a string to given width with spaces"] = function () + width = -width + target = "an twenty characters" + expect (f (subject, width)).should_be (target) + end}, + }}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, width) + expect (subject).should_be (original) + end}, + {["it coerces non-string arguments to a string"] = function () + expect (f ({ "a table" }, width)).should_contain "a table" + end}, + {["it diagnoses non-numeric width arguments"] = function () + expect ("number expected").should_error (f, subject, nil) + expect ("number expected").should_error (f, subject, { "a table" }) + end}, + }}, + + + {["describe string.rtrim ()"] = { + before = function () + subject = " \t\r\n a short string \t\r\n " + f = string.rtrim + end, + + {["it removes whitespace from the end of a string"] = function () + target = " \t\r\n a short string" + expect (f (subject)).should_equal (target) + end}, + {["it supports custom removal patterns"] = function () + target = " \t\r\n a short string \t\r" + expect (f (subject, "[ \t\n]+")).should_equal (target) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, "%W") + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.split ()"] = { + before = function () + target = { "first", "the second one", "final entry" } + subject = table.concat (target, ", ") + f = string.split + end, + + {["it makes a table of substrings delimitied by a separator"] = function () + expect (f (subject, ", ")).should_equal (target) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, "e") + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, "a string", nil) + expect ("string expected").should_error (f, nil, ",") + expect ("string expected").should_error (f, { "a table" }, ",") + end}, + }}, + + + {["describe string.tfind ()"] = { + before = function () + subject = "abc" + f = string.tfind + end, + + {["it creates a list of pattern captures"] = function () + target = { 1, 3, { "a", "b", "c" } } + expect ({f (subject, "(.)(.)(.)")}).should_equal (target) + end}, + {["it creates an empty list where no captures are matched "] = function () + target = { nil, nil, {} } + expect ({f (subject, "(x)(y)(z)")}).should_equal (target) + end}, + {["it creates an empty list for a pattern without captures"] = function () + target = { 1, 1, {} } + expect ({f (subject, "a")}).should_equal (target) + end}, + {["it starts the search at a specified index into the subject"] = function () + target = { 8, 10, { "a", "b", "c" } } + expect ({f ("garbage" .. subject, "(.)(.)(.)", 8)}).should_equal (target) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, "...") + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.trim ()"] = { + before = function () + subject = " \t\r\n a short string \t\r\n " + f = string.trim + end, + + {["it removes whitespace from each end of a string"] = function () + target = "a short string" + expect (f (subject)).should_equal (target) + end}, + {["it supports custom removal patterns"] = function () + target = "\r\n a short string \t\r" + expect (f (subject, "[ \t\n]+")).should_equal (target) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, "%W") + expect (subject).should_be (original) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["describe string.wrap ()"] = { + before = function () + subject = "This is a collection of Lua libraries for Lua 5.1 " .. + "and 5.2. The libraries are copyright by their authors 2000" .. + "-2013 (see the AUTHORS file for details), and released und" .. + "er the MIT license (the same license as Lua itself). There" .. + " is no warranty." + f = string.wrap + end, + + {["it inserts newlines to wrap a string"] = function () + target = "This is a collection of Lua libraries for Lua 5.1 a" .. + "nd 5.2. The libraries are\ncopyright by their authors 2000" .. + "-2013 (see the AUTHORS file for details), and\nreleased un" .. + "der the MIT license (the same license as Lua itself). Ther" .. + "e is no\nwarranty." + expect (f (subject)).should_be (target) + end}, + {["it honours a column width parameter"] = function () + target = "This is a collection of Lua libraries for Lua 5.1 a" .. + "nd 5.2. The libraries\nare copyright by their authors 2000" .. + "-2013 (see the AUTHORS file for\ndetails), and released un" .. + "der the MIT license (the same license as Lua\nitself). The" .. + "re is no warranty." + expect (f (subject, 72)).should_be (target) + end}, + {["it supports indenting by a fixed number of columns"] = function () + target = " This is a collection of Lua libraries for L" .. + "ua 5.1 and 5.2. The\n libraries are copyright by th" .. + "eir authors 2000-2013 (see the\n AUTHORS file for d" .. + "etails), and released under the MIT license\n (the " .. + "same license as Lua itself). There is no warranty." + expect (f (subject, 72, 8)).should_be (target) + end}, + {["it can indent the first line differently"] = function () + target = " This is a collection of Lua libraries for Lua 5" .. + ".1 and 5.2.\n The libraries are copyright by their author" .. + "s 2000-2013 (see\n the AUTHORS file for details), and rel" .. + "eased under the MIT\n license (the same license as Lua it" .. + "self). There is no\n warranty." + expect (f (subject, 64, 2, 4)).should_be (target) + end}, + {["the original subject is not perturbed"] = function () + original = subject + newstring = f (subject, 55, 5) + expect (subject).should_be (original) + end}, + {["it diagnoses indent greater than line width"] = function () + expect ("less than the line width").should_error (f, subject, 10, 12) + expect ("less than the line width").should_error (f, subject, 99, 99) + end}, + {["it diagnoses non-string arguments"] = function () + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + end}, + }}, + + + {["context when requiring the module"] = { + before = function () + extensions = { "caps", "chomp", "escape_pattern", "escape_shell", + "finds", "format", "ltrim", "numbertosi", + "ordinal_suffix", "pad", "rtrim", "split", "tfind", + "trim", "wrap" } + end, + + {["it returns the unextended module table"] = function () + for _, api in ipairs (extensions) do + if api ~= "format" then + expect (unextended[api]).should_be (nil) + end + end + end}, + {["it injects an enhanced format function"] = function () + expect (unextended.format).should_not_be (table.format) + end}, + {["it doesn't override any other module access points"] = function () + for api in pairs (unextended) do + if api ~= "format" then + expect (string[api]).should_be (unextended[api]) + end + end + end}, + }}, +}} diff --git a/specs/table_ext_spec.yaml b/specs/table_ext_spec.yaml new file mode 100644 index 0000000..456f22f --- /dev/null +++ b/specs/table_ext_spec.yaml @@ -0,0 +1,262 @@ +module table_ext: +- before: | + unextended = require "table_ext" + table_ext = table + + +- shared examples: + - before: | + object = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + + - describe a table operation: + - it diagnoses non-table arguments: | + expect ("table expected").should_error (subject, nil) + expect ("table expected").should_error (subject, 42) + expect ("table expected").should_error (subject, "foo") + + - describe a destructive operation: + - it operates on the object in place: | + original = object + expect (subject (object)).should_be (original) + + - "describe a non-destructive operation": + - it returns a new object: | + expect (subject (object)).should_not_be (object) + + - describe a reversible operation: + - it is returns the original object when applied twice: | + expect (subject (subject (object))).should_equal (object) + + - describe a stable table operation: + - it behaves like: a table operation + - it behaves like: a not-destructive operation + + - it returns an empty list when object is empty: | + expect (subject {}).should_equal {} + + # is this a good test? or just requiring an implementation quirk? + - it does guarantee stable ordering: | + object = {} + for i = 10000, 1, -1 do table.insert (object, i) end + expect (subject (object)).should_equal (object) + + - describe an unstable table operation: + - it behaves like: a table operation + - it behaves like: a not-destructive operation + + - it returns an empty list when object is empty: | + expect (subject {}).should_equal {} + + # is this a good example? there's a vanishingly small possibility + # the returned table will have all 10000 keys in the same order... + - it does not guarantee stable ordering: | + object = {} + for i = 10000, 1, -1 do table.insert (object, i) end + expect (subject (object)).should_not_equal (object) + + - describe a table copying operation: + - it behaves like: a table operation + - it behaves like: a non-destructive operation + + - it does copy the object: | + expect (subject (object)).should_equal (object) + + - the original object is not perturbed: | + target = { k1 = object.k1, k2 = object.k2, k3 = object.k3 } + copy = subject (object) + expect (object).should_equal (target) + expect (object).should_be (object) + + +- new: + - "it diagnoses non-tables/non-nil in the second argument": | + expect ("table expected").should_error (subject, nil, "foo") + + - context when not setting a default: + - before: | + default = nil + + - it returns a new table when nil is passed: | + expect (subject (default, nil)).should_equal {} + + - it returns any table passed in: | + t = { "unique table" } + expect (subject (default, t)).should_be (t) + + - context when setting a default: + - before: | + default = "default" + + - it returns a new table when nil is passed: | + expect (subject (default, nil)).should_equal {} + + - it returns any table passed in: | + t = { "unique table" } + expect (subject (default, t)).should_be (t) + + - it returns the stored value for existing keys: | + t = subject ("default") + v = { "unique value" } + t[1] = v + expect (t[1]).should_be (v) + + - it returns the constructor default for unset keys: | + t = subject ("default") + expect (t[1]).should_be "default" + + - it returns the actual default object: | + default = { "unique object" } + t = subject (default) + expect (t[1]).should_be (default) + + +- empty: + - it behaves like: a table operation + - it behaves like: a non-destructive operation + + - it returns true for an empty table: | + expect (subject {}).should_be (true) + expect (subject {nil}).should_be (true) + + - it returns false for a non-empty table: | + expect (subject {"stuff"}).should_be (false) + expect (subject {{}}).should_be (false) + expect (subject {false}).should_be (false) + + +- size: + - it behaves like: a table operation + - it behaves like: a non-destructive operation + + - it counts no keys in an empty table: | + expect (subject {}).should_be (0) + + - it counts the number of keys in a table: | + # - 1 - --------- 2 ---------- -- 3 -- + object = { "one", { { "two" }, "three" }, four = 5 } + expect (subject (object)).should_be (3) + + +- sort: + - it behaves like: a table operation + - it behaves like: a destructive operation + + - it returns the sorted object: | + object = { 5, 2, 4, 1, 0, 3 } + target = { 0, 1, 2, 3, 4, 5 } + expect (subject (object)).should_equal (target) + + +- keys: + - it behaves like: an unstable table operation + + - it makes a list of table keys: | + object = { k1 = "v1", k2 = "v2", k3 = "v3" } + expect (table.sort (subject (object))).should_equal {"k1", "k2", "k3"} + + +- values: + - it behaves like: a stable table operation + + - it makes a list of table values: | + object = { k1 = "v1", k2 = "v2", k3 = "v3" } + expect (table.sort (subject (object))).should_equal {"v1", "v2", "v3"} + + +- clone: + - it behaves like: a table copying operation + + - it only makes a shallow copy: | + expect (subject (object)). should_have (#object).members + for k in pairs (object) do + expect (subject (object)[k]).should_be (object[k]) + end + + +- clone_rename: + - before: | + subject = function (t) return table.clone_rename ({}, t) end + + - it behaves like: clone + + - context when renaming some keys: + - before: | + subject = table.clone_rename + rename = { k1 = "renamed" } + target = { newkey = object.k1, k2 = object.k2, k3 = object.k3 } + + - it renames some keys during cloning: | + expect (subject (rename, object)).should_equal (target) + + - it does not perturb the value in the renamed key field: | + expect (subject (renames, object).renamed).should_be (object.k1) + + +- invert: + - it behaves like: a table operation + - it behaves like: a non-destructive operation + - it behaves like: a reversible operation + + - it inverts keys and values in the returned table: | + object = { k1 = 1, k2 = 2, k3 = 3 } + expect (subject (object)).should_equal { "k1", "k2", "k3" } + + - it seems to copy a list of 1..n numbers: | + object = { 1, 2, 3 } + expect (subject (object)).should_equal (object) + expect (subject (object)).should_not_be (object) + + +- merge: + - before: | + # Additional merge keys which are moderately unusual + t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } + t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } + + target = {} + for k, v in pairs (t1) do target[k] = v end + for k, v in pairs (t2) do target[k] = v end + + - it behaves like: a table operation + - it behaves like: a destructive operation + + - it does not create a whole new table: | + expect (subject (t1, t2)).should_be (t1) + + - "it does not change t1, if t2 is empty": | + expect (subject (t1, {})).should_be (t1) + + - "it copies t2, if t1 is empty": | + expect (subject ({}, t1)).should_not_be (t1) + expect (subject ({}, t1)).should_equal (t1) + + - it merges keys from t2 into t1: | + expect (subject (t1, t2)).should_equal (target) + + - it gives precedence to values from t2: | + original = table.clone (t1) + m = subject (t1, t2) # Merge is destructive, do it once only. + expect (m.k3).should_be (t2.k3) + expect (m.k3).should_not_be (original.k3) + + +- context when requiring the module: + - it returns the unextended module table: | + extensions = { "clone", "clone_rename", "empty", "invert", "keys", + "merge", "new", "size", "sort", "values" } + + for _, api in ipairs (extensions) do + if api ~= "sort" then + expect (unextended[api]).should_be (nil) + end + end + + - it injects an enhanced sort function: | + expect (unextended.sort).should_not_be (table.sort) + + - "it doesn't override any other module access points": | + for api in pairs (unextended) do + if api ~= "sort" then + expect (table[api]).should_be (unextended[api]) + end + end diff --git a/src/files/base.html b/src/files/base.html index cedeb6c..8e08905 100644 --- a/src/files/base.html +++ b/src/files/base.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/bin.html b/src/files/bin.html index 1894154..e42ef70 100644 --- a/src/files/bin.html +++ b/src/files/bin.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/debug_ext.html b/src/files/debug_ext.html index 5822edf..a73f8c6 100644 --- a/src/files/debug_ext.html +++ b/src/files/debug_ext.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/debug_init.html b/src/files/debug_init.html index 2b246b1..7ff4514 100644 --- a/src/files/debug_init.html +++ b/src/files/debug_init.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/fstable.html b/src/files/fstable.html index abb491b..fd53984 100644 --- a/src/files/fstable.html +++ b/src/files/fstable.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/getopt.html b/src/files/getopt.html index d090970..5598161 100644 --- a/src/files/getopt.html +++ b/src/files/getopt.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - @@ -194,12 +182,12 @@

    Functions

    - processArgs () + processArgs (prog) Simple getOpt wrapper. - usage () + usage (prog) Emit a usage message. @@ -217,8 +205,8 @@

    Tables

    - - + +
    _G.OptionOptions table type.OptionObject that defines a single Option entry.
    @@ -303,11 +291,20 @@

    Parameters

    -
    processArgs ()
    +
    processArgs (prog)
    -Simple getOpt wrapper. Adds -version/-V and -help/-h automatically; stops program if there was an error, or if -help or -version was used. +Simple getOpt wrapper. If the caller didn't supply their own already, adds --version/-V and --help/-h options automatically; stops program if there was an error, or if --help or --version was used. +

    Parameters

    +
      + +
    • + prog: table of named parameters +
    • + +
    + @@ -320,11 +317,20 @@

    Parameters

    -
    usage ()
    +
    usage (prog)
    Emit a usage message. +

    Parameters

    +
      + +
    • + prog: table of named parameters +
    • + +
    + @@ -380,15 +386,15 @@

    Return value:

    Tables

    -
    _G.Option
    -
    Options table type. +
    Option
    +
    Object that defines a single Option entry. Fields
    • - name: list of names + name: list of option names
    • @@ -396,11 +402,11 @@

      Tables

    • - type: type of argument (if any): Req(uired), Opt(ional) + type: type of option argument (if any): Req(uired), Opt(ional)
    • - var: descriptive name for the argument + var: descriptive name for the option argument
    diff --git a/src/files/io_ext.html b/src/files/io_ext.html index a2506bd..f8de140 100644 --- a/src/files/io_ext.html +++ b/src/files/io_ext.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/lcs.html b/src/files/lcs.html index 0a0191a..48c4809 100644 --- a/src/files/lcs.html +++ b/src/files/lcs.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/list.html b/src/files/list.html index 60705a9..f0071a5 100644 --- a/src/files/list.html +++ b/src/files/list.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/math_ext.html b/src/files/math_ext.html index 17e3378..2c4e978 100644 --- a/src/files/math_ext.html +++ b/src/files/math_ext.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/mbox.html b/src/files/mbox.html index 3694004..4021740 100644 --- a/src/files/mbox.html +++ b/src/files/mbox.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/modules.html b/src/files/modules.html index cf0d7f1..8bfa7b5 100644 --- a/src/files/modules.html +++ b/src/files/modules.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/object.html b/src/files/object.html index c970961..bd86c9d 100644 --- a/src/files/object.html +++ b/src/files/object.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/package_ext.html b/src/files/package_ext.html index f0b45a3..edca151 100644 --- a/src/files/package_ext.html +++ b/src/files/package_ext.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - @@ -175,8 +163,6 @@

    Files

    File package_ext.lua

    -

    Make named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents).

    - diff --git a/src/files/parser.html b/src/files/parser.html index 988f51a..1da5a07 100644 --- a/src/files/parser.html +++ b/src/files/parser.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/set.html b/src/files/set.html index 7fdcf8a..7f684e9 100644 --- a/src/files/set.html +++ b/src/files/set.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/std.html b/src/files/std.html index faee4a3..92fdc30 100644 --- a/src/files/std.html +++ b/src/files/std.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/strbuf.html b/src/files/strbuf.html index b509c5f..7075e99 100644 --- a/src/files/strbuf.html +++ b/src/files/strbuf.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/strict.html b/src/files/strict.html index ac6c47b..208054b 100644 --- a/src/files/strict.html +++ b/src/files/strict.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/string_ext.html b/src/files/string_ext.html index 125bc36..daa78d7 100644 --- a/src/files/string_ext.html +++ b/src/files/string_ext.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - @@ -175,8 +163,6 @@

    Files

    File string_ext.lua

    -

    Additions to the string module TODO: Pretty printing (use in getopt); see source for details.

    - @@ -196,7 +182,7 @@

    Functions

    - escapePattern (s) + escape_pattern (s) Escape a string to be used as a pattern @@ -216,7 +202,7 @@

    Functions

    - ordinalSuffix (n) + ordinal_suffix (n) Return the English suffix for an ordinal. @@ -326,7 +312,7 @@

    Return value:

    -
    escapePattern (s)
    +
    escape_pattern (s)
    Escape a string to be used as a pattern @@ -406,7 +392,7 @@

    Parameters

  • - r: leading regex (default: "%s+") + r: leading pattern (default: "%s+")
  • @@ -455,7 +441,7 @@

    Return value:

    -
    ordinalSuffix (n)
    +
    ordinal_suffix (n)
    Return the English suffix for an ordinal. @@ -534,7 +520,7 @@

    Parameters

  • - r: trailing regex (default: "%s+") + r: trailing pattern (default: "%s+")
  • @@ -567,7 +553,7 @@

    Parameters

  • - sep: separator regex + sep: separator pattern
  • @@ -641,7 +627,7 @@

    Parameters

  • - r: leading/trailing regex (default: "%s+") + r: leading/trailing pattern (default: "%s+")
  • diff --git a/src/files/table_ext.html b/src/files/table_ext.html index a16d3d6..df59014 100644 --- a/src/files/table_ext.html +++ b/src/files/table_ext.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - @@ -175,8 +163,6 @@

    Files

    File table_ext.lua

    -

    Make table.sort return its result.

    - diff --git a/src/files/tree.html b/src/files/tree.html index 38bb30b..6f71ec7 100644 --- a/src/files/tree.html +++ b/src/files/tree.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/files/xml.html b/src/files/xml.html index 10f9ab0..9bbda48 100644 --- a/src/files/xml.html +++ b/src/files/xml.html @@ -50,18 +50,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/getopt.lua b/src/getopt.lua index 78962cf..7d91706 100644 --- a/src/getopt.lua +++ b/src/getopt.lua @@ -1,9 +1,18 @@ --- Simplified getopt, based on Svenne Panne's Haskell GetOpt.
    -- Usage: --
      ---
    • options = {Option {...}, ...}
      --- getopt.processArgs ()
    • ---
    • Assumes prog = {name[, banner] [, purpose] [, notes] [, usage]}
    • +--
    • prog = {< +-- name = , +-- [usage = ,] +-- [options = { +-- {Option {}, , [,] [var]}, +-- ... +-- },] +-- [banner = ,] +-- [purpose = ,] +-- [notes = ] +-- }
    • +--
    • getopt.processArgs (prog)
    • --
    • Options take a single dash, but may have a double dash.
    • --
    • Arguments may be given as -opt=arg or -opt arg.
    • --
    • If an option taking an argument is given multiple times, only the @@ -13,8 +22,6 @@ -- below, and the example at the end). Set _DEBUG.std to a non-nil -- value to run the example. --
        ---
      • TODO: Sort out the packaging. getopt.Option is tedious to type, but --- surely Option shouldn't be in the root namespace?
      • --
      • TODO: Wrap all messages; do all wrapping in processArgs, not -- usageInfo; use sdoc-like library (see string.format todos).
      • --
      • TODO: Don't require name to be repeated in banner.
      • @@ -26,6 +33,10 @@ local list = require "list" require "string_ext" local Object = require "object" +local M = { + opt = {}, +} + --- Perform argument processing -- @param argIn list of command-line args @@ -83,35 +94,42 @@ local function getOpt (argIn, options) end ---- Options table type. +--- Object that defines a single Option entry. -- @class table --- @name _G.Option --- @field name list of names +-- @name Option +-- @field name list of option names -- @field desc description of this option --- @field type type of argument (if any): Req(uired), +-- @field type type of option argument (if any): Req(uired), -- Opt(ional) --- @field var descriptive name for the argument -_G.Option = Object {_init = {"name", "desc", "type", "var"}} +-- @field var descriptive name for the option argument +local Option = Object {_init = {"name", "desc", "type", "var"}} --- Options table constructor: adds lookup tables for the option names local function makeOptions (t) - t = list.concat (t or {}, - {Option {{"version", "V"}, - "output version information and exit"}, - Option {{"help", "h"}, - "display this help and exit"}} - ) - local name = {} - for v in list.elems (t) do - for j, s in pairs (v.name) do + local options, name = {}, {} + local function appendOpt (v, nodupes) + local dupe = false + for s in list.elems (v.name) do if name[s] then - warn ("duplicate option '%s'", s) + dupe = true end name[s] = v end + if not dupe or nodupes ~= true then + if dupe then warn ("duplicate option '%s'", s) end + for s in list.elems (v.name) do name[s] = v end + options = list.concat (options, {v}) + end + end + for v in list.elems (t or {}) do + appendOpt (v) end - t.name = name - return t + -- Unless they were supplied already, add version and help options + appendOpt (Option {{"version", "V"}, "print version information, then exit"}, + true) + appendOpt (Option {{"help", "h"}, "print this help, then exit"}, true) + options.name = name + return options end @@ -128,7 +146,7 @@ local function usageInfo (header, optDesc, pageWidth) -- @return description local function fmtOpt (opt) local function fmtName (o) - return "-" .. o + return (#o > 1 and "--" or "-") .. o end local function fmtArg () if opt.type == nil then @@ -141,7 +159,11 @@ local function usageInfo (header, optDesc, pageWidth) end local textName = list.reverse (list.map (fmtName, opt.name)) textName[#textName] = textName[#textName] .. fmtArg () - return {table.concat ({table.concat (textName, ", ")}, ", "), + local indent = "" + if #opt.name == 1 and #opt.name[1] > 1 then + indent = " " + end + return {indent .. table.concat ({table.concat (textName, ", ")}, ", "), opt.desc} end local function sameLen (xs) @@ -175,13 +197,21 @@ local function usageInfo (header, optDesc, pageWidth) end --- Emit a usage message. -local function usage () - local usage, purpose, notes = "[OPTION]... [FILE]...", "", "" +-- @param prog table of named parameters +local function usage (prog) + local usage = "[OPTION]... [FILE]..." + local purpose, description, notes = "", "", "" if prog.usage then usage = prog.usage end + usage = "Usage: " .. prog.name .. " " .. usage if prog.purpose then - purpose = "\n" .. prog.purpose + purpose = "\n\n" .. prog.purpose + end + if prog.description then + for para in list.elems (string.split (prog.description, "\n")) do + description = description .. "\n\n" .. string.wrap (para) + end end if prog.notes then notes = "\n\n" @@ -191,94 +221,62 @@ local function usage () notes = notes .. prog.notes end end - io.writelines (usageInfo ("Usage: " .. prog.name .. " " .. usage .. purpose, - options) - .. notes) + local header = usage .. purpose .. description + io.writelines (usageInfo (header, prog.options) .. notes) end ---- Simple getOpt wrapper. --- Adds -version/-V and --- -help/-h automatically; --- stops program if there was an error, or if -help or --- -version was used. -local M = { - opt = {}, -} +local function version (prog) + local version = prog.version or prog.name or "unknown version!" + if prog.copyright then + version = version .. "\n\n" .. prog.copyright + end + io.writelines (version) +end + -local function processArgs () + +--- Simple getOpt wrapper. +-- If the caller didn't supply their own already, +-- adds --version/-V and +-- --help/-h options automatically; +-- stops program if there was an error, or if --help or +-- --version was used. +-- @param prog table of named parameters +local function processArgs (prog) local totArgs = #arg - options = makeOptions (options) local errors - _G.arg, M.opt, errors = getopt.getOpt (arg, options) + prog.options = makeOptions (prog.options) + _G.arg, M.opt, errors = getopt.getOpt (arg, prog.options) local opt = M.opt if (opt.version or opt.help) and prog.banner then io.writelines (prog.banner) end - if #errors > 0 or opt.help then + if #errors > 0 then local name = prog.name prog.name = nil if #errors > 0 then - warn (table.concat (errors, "\n") .. "\n") + warn (name .. ": " .. table.concat (errors, "\n")) + warn (name .. ": Try '" .. (arg[0] or name) .. " --help' for more help") end - prog.name = name - usage () if #errors > 0 then error () end + elseif opt.version then + version (prog) + elseif opt.help then + usage (prog) end if opt.version or opt.help then os.exit () end end -_G.options = nil - - --- A small and hopefully enlightening example: -if type (_DEBUG) == "table" and _DEBUG.std then - - options = makeOptions ({ - Option {{"verbose", "v"}, "verbosely list files"}, - Option {{"output", "o"}, "dump to FILE", "Opt", "FILE"}, - Option {{"name", "n"}, "only dump USER's files", "Req", "USER"}, - }) - function test (cmdLine) - local nonOpts, opts, errors = getopt.getOpt (cmdLine, options) - if #errors == 0 then - print ("options=" .. tostring (opts) .. - " args=" .. tostring (nonOpts) .. "\n") - else - print (table.concat (errors, "\n") .. "\n" .. - usageInfo ("Usage: foobar [OPTION...] FILE...", - options)) - end - end - - -- FIXME: Turn the following documentation into unit tests - prog = {name = "foobar"} -- for errors - -- Example runs: - test {"foo", "-v"} - -- options={verbose={1}} args={1=foo} - test {"foo", "--", "-v"} - -- options={} args={1=foo,2=-v} - test {"-o", "-V", "-name", "bar", "--name=baz"} - -- options={name={"baz"},version={1},output={1}} args={} - test {"-foo"} - -- unrecognized option `-foo' - -- Usage: foobar [OPTION]... [FILE]... - -- - -- -v, -verbose verbosely list files - -- -o, -output[=FILE] dump to FILE - -- -n, -name=USER only dump USER's files - -- -V, -version output version information and exit - -- -h, -help display this help and exit - -end -- Public interface return table.merge (M, { getOpt = getOpt, + Option = Option, processArgs = processArgs, usage = usage, usageInfo = usageInfo, diff --git a/src/index.html b/src/index.html index f94edd1..c92cf55 100644 --- a/src/index.html +++ b/src/index.html @@ -50,10 +50,6 @@

        Modules

        math -
      • - string -
      • -
      @@ -192,11 +188,6 @@

      Modules

      Additions to the math module. - - string - Additions to the string module TODO: Pretty printing (use in getopt); see source for details. - - diff --git a/src/io_ext.lua b/src/io_ext.lua index 1696ba4..7a57ca2 100644 --- a/src/io_ext.lua +++ b/src/io_ext.lua @@ -108,8 +108,6 @@ function processFiles (f) else io.input (v) end - prog.file = v f (v, i) end - prog.file = nil end diff --git a/src/modules/base.html b/src/modules/base.html index 92deccd..8f85c51 100644 --- a/src/modules/base.html +++ b/src/modules/base.html @@ -48,18 +48,6 @@

      Modules

      math
    • -
    • - package -
    • - -
    • - string -
    • - -
    • - table -
    • -
    diff --git a/src/modules/debug.html b/src/modules/debug.html index e375478..502ef24 100644 --- a/src/modules/debug.html +++ b/src/modules/debug.html @@ -48,18 +48,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/modules/io.html b/src/modules/io.html index 686b7bb..8f7f7b4 100644 --- a/src/modules/io.html +++ b/src/modules/io.html @@ -48,18 +48,6 @@

    Modules

    math -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/modules/math.html b/src/modules/math.html index de5d037..019911f 100644 --- a/src/modules/math.html +++ b/src/modules/math.html @@ -48,18 +48,6 @@

    Modules

  • math
  • -
  • - package -
  • - -
  • - string -
  • - -
  • - table -
  • - diff --git a/src/std.lua b/src/std.lua index 047ffac..99efbe1 100644 --- a/src/std.lua +++ b/src/std.lua @@ -7,7 +7,7 @@ -- this also helps to check module dependencies. --
  • TODO: pre-compile.
  • -- -local version = "General Lua libraries / 32" +local version = "General Lua libraries / 33" for _, m in ipairs (require "modules") do _G[m] = require (m) diff --git a/src/string_ext.lua b/src/string_ext.lua index a24c9f4..1cc2331 100644 --- a/src/string_ext.lua +++ b/src/string_ext.lua @@ -1,7 +1,8 @@ --- Additions to the string module -- TODO: Pretty printing (use in getopt); see source for details. -module ("string", package.seeall) +require "table_ext" +require "strbuf" -- Write pretty-printing based on: -- @@ -36,7 +37,7 @@ module ("string", package.seeall) local old__index = getmetatable ("").__index getmetatable ("").__index = function (s, i) if type (i) == "number" then - return sub (s, i, i) + return s:sub (i, i) -- Fall back to old metamethods elseif type (old__index) == "function" then return old__index (s, i) @@ -64,26 +65,26 @@ end --- Capitalise each word in a string. -- @param s string -- @return capitalised string -function caps (s) - return (gsub (s, "(%w)([%w]*)", - function (l, ls) - return upper (l) .. ls - end)) +local function caps (s) + return (string.gsub (s, "(%w)([%w]*)", + function (l, ls) + return string.upper (l) .. ls + end)) end --- Remove any final newline from a string. -- @param s string to process -- @return processed string -function chomp (s) - return (gsub (s, "\n$", "")) +local function chomp (s) + return (string.gsub (s, "\n$", "")) end --- Escape a string to be used as a pattern -- @param s string to process -- @return -- @param s_: processed string -function escapePattern (s) - return (gsub (s, "(%W)", "%%%1")) +local function escape_pattern (s) + return (string.gsub (s, "(%W)", "%%%1")) end -- Escape a string to be used as a shell token. @@ -91,16 +92,16 @@ end -- whitespace. -- @param s string to process -- @return processed string -function escapeShell (s) - return (gsub (s, "([ %(%)%\\%[%]\"'])", "\\%1")) +local function escape_shell (s) + return (string.gsub (s, "([ %(%)%\\%[%]\"'])", "\\%1")) end --- Return the English suffix for an ordinal. -- @param n number of the day -- @return suffix -function ordinalSuffix (n) - n = math.mod (n, 100) - local d = math.mod (n, 10) +local function ordinal_suffix (n) + n = math.abs (n) % 100 + local d = n % 10 if d == 1 and n ~= 11 then return "st" elseif d == 2 and n ~= 12 then @@ -117,8 +118,8 @@ end -- @param f format -- @param ... arguments to format -- @return formatted string -local _format = format -function format (f, arg1, ...) +local _format = string.format +local function format (f, arg1, ...) if arg1 == nil then return f else @@ -134,12 +135,12 @@ end -- left-justify) -- @param p string to pad with (default: " ") -- @return justified string -function pad (s, w, p) - p = rep (p or " ", math.abs (w)) +local function pad (s, w, p) + p = string.rep (p or " ", math.abs (w)) if w < 0 then - return sub (p .. s, w) + return string.sub (p .. s, w) end - return sub (s .. p, 1, w) + return string.sub (s .. p, 1, w) end --- Wrap a string into a paragraph. @@ -148,37 +149,40 @@ end -- @param ind indent (default: 0) -- @param ind1 indent of first line (default: ind) -- @return wrapped paragraph -function wrap (s, w, ind, ind1) +local function wrap (s, w, ind, ind1) w = w or 78 ind = ind or 0 ind1 = ind1 or ind assert (ind1 < w and ind < w, "the indents must be less than the line width") - s = rep (" ", ind1) .. s - local lstart, len = 1, len (s) - while len - lstart > w - ind do - local i = lstart + w - ind - while i > lstart and sub (s, i, i) ~= " " do - i = i - 1 + assert (type (s) == "string", + "bad argument #1 to 'wrap' (string expected, got " .. type (s) .. ")") + local r = strbuf.new ():concat (string.rep (" ", ind1)) + local i, lstart, len = 1, ind1, #s + while i <= #s do + local j = i + w - lstart + while #s[j] > 0 and s[j] ~= " " and j > i do + j = j - 1 end - local j = i - while j > lstart and sub (s, j, j) == " " do + local ni = j + 1 + while s[j] == " " do j = j - 1 end - s = sub (s, 1, j) .. "\n" .. rep (" ", ind) .. - sub (s, i + 1, -1) - local change = ind + 1 - (i - j) - lstart = j + change - len = len + change + r:concat (s:sub (i, j)) + i = ni + if i < #s then + r:concat ("\n" .. string.rep (" ", ind)) + lstart = ind + end end - return s + return r:tostring () end --- Write a number using SI suffixes. -- The number is always written to 3 s.f. -- @param n number -- @return string -function numbertosi (n) +local function numbertosi (n) local SIprefix = { [-8] = "y", [-7] = "z", [-6] = "a", [-5] = "f", [-4] = "p", [-3] = "n", [-2] = "mu", [-1] = "m", @@ -186,7 +190,7 @@ function numbertosi (n) [4] = "T", [5] = "P", [6] = "E", [7] = "Z", [8] = "Y" } - local t = format("% #.2e", n) + local t = string.format("% #.2e", n) local _, _, m, e = t:find(".(.%...)e(.+)") local man, exp = tonumber (m), tonumber (e) local siexp = math.floor (exp / 3) @@ -202,7 +206,11 @@ end -- @param init start position (default: 1) -- @param plain inhibit magic characters (default: nil) -- @return start of match, end of match, table of captures -function tfind (s, p, init, plain) +local function tfind (s, p, init, plain) + assert (type (s) == "string", + "bad argument #1 to 'tfind' (string expected, got " .. type (s) .. ")") + assert (type (p) == "string", + "bad argument #2 to 'tfind' (string expected, got " .. type (p) .. ")") local function pack (from, to, ...) return from, to, {...} end @@ -215,7 +223,7 @@ end -- @param init start position (default: 1) -- @param plain inhibit magic characters (default: nil) -- @return list of {from, to; capt = {captures}} -function finds (s, p, init, plain) +local function finds (s, p, init, plain) init = init or 1 local l = {} local from, to, r @@ -232,9 +240,9 @@ end --- Split a string at a given separator. -- FIXME: Consider Perl and Python versions. -- @param s string to split --- @param sep separator regex +-- @param sep separator pattern -- @return list of strings -function split (s, sep) +local function split (s, sep) -- finds gets a list of {from, to, capt = {}} lists; we then -- flatten the result, discarding the captures, and prepend 0 (1 -- before the first character) and append 0 (1 after the last @@ -242,33 +250,65 @@ function split (s, sep) local pairs = list.concat ({0}, list.flatten (finds (s, sep)), {0}) local l = {} for i = 1, #pairs, 2 do - table.insert (l, sub (s, pairs[i] + 1, pairs[i + 1] - 1)) + table.insert (l, string.sub (s, pairs[i] + 1, pairs[i + 1] - 1)) end return l end --- Remove leading matter from a string. -- @param s string --- @param r leading regex (default: "%s+") +-- @param r leading pattern (default: "%s+") -- @return string without leading r -function ltrim (s, r) +local function ltrim (s, r) r = r or "%s+" - return (gsub (s, "^" .. r, "")) + return (string.gsub (s, "^" .. r, "")) end --- Remove trailing matter from a string. -- @param s string --- @param r trailing regex (default: "%s+") +-- @param r trailing pattern (default: "%s+") -- @return string without trailing r -function rtrim (s, r) +local function rtrim (s, r) r = r or "%s+" - return (gsub (s, r .. "$", "")) + return (string.gsub (s, r .. "$", "")) end --- Remove leading and trailing matter from a string. -- @param s string --- @param r leading/trailing regex (default: "%s+") +-- @param r leading/trailing pattern (default: "%s+") -- @return string without leading/trailing r -function trim (s, r) +local function trim (s, r) return rtrim (ltrim (s, r), r) end + +-- Save original unextended table. +local unextended = table.clone (string) + +local M = { + __index = old__index, + caps = caps, + chomp = chomp, + escape_pattern = escape_pattern, + escape_shell = escape_shell, + finds = finds, + format = format, + ltrim = ltrim, + numbertosi = numbertosi, + ordinal_suffix = ordinal_suffix, + pad = pad, + rtrim = rtrim, + split = split, + tfind = tfind, + trim = trim, + wrap = wrap, + + -- camelCase compatibility: + escapePattern = escape_pattern, + escapeShell = escape_shell, + ordinalSuffix = ordinal_suffix, +} + +-- Inject stdlib extensions directly into the string package. +_G.string = table.merge (string, M) + +return unextended diff --git a/stdlib-32-1.rockspec b/stdlib-33-1.rockspec similarity index 94% rename from stdlib-32-1.rockspec rename to stdlib-33-1.rockspec index 2c9f6c0..06e9b0f 100644 --- a/stdlib-32-1.rockspec +++ b/stdlib-33-1.rockspec @@ -1,25 +1,25 @@ -description = { - license = "MIT/X11", - homepage = "http://github.com/rrthomas/lua-stdlib/", - detailed = " stdlib is a library of modules for common programming tasks,\ - including list, table and functional operations, regexps, objects,\ - pickling, pretty-printing and getopt.\ - ", - summary = "General Lua libraries", -} build = { - type = "command", + build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", copy_directories = { }, - build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", install_command = "make install", + type = "command", } dependencies = { "lua >= 5.1", } +version = "33-1" +description = { + summary = "General Lua libraries", + license = "MIT/X11", + detailed = " stdlib is a library of modules for common programming tasks,\ + including list, table and functional operations, regexps, objects,\ + pickling, pretty-printing and getopt.\ + ", + homepage = "http://github.com/rrthomas/lua-stdlib/", +} package = "stdlib" source = { - branch = "release-v32", + branch = "release-v33", url = "git://github.com/rrthomas/lua-stdlib.git", } -version = "32-1" diff --git a/stdlib-git-1.rockspec b/stdlib-git-1.rockspec index 55b1f3d..c08f7f3 100644 --- a/stdlib-git-1.rockspec +++ b/stdlib-git-1.rockspec @@ -1,24 +1,24 @@ -version = "git-1" package = "stdlib" -description = { - detailed = " stdlib is a library of modules for common programming tasks,\ - including list, table and functional operations, regexps, objects,\ - pickling, pretty-printing and getopt.\ - ", - summary = "General Lua libraries", - license = "MIT/X11", - homepage = "http://github.com/rrthomas/lua-stdlib/", -} build = { + build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + install_command = "make install", type = "command", copy_directories = { }, - build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - install_command = "make install", } dependencies = { "lua >= 5.1", } +version = "git-1" source = { url = "git://github.com/rrthomas/lua-stdlib.git", } +description = { + license = "MIT/X11", + detailed = " stdlib is a library of modules for common programming tasks,\ + including list, table and functional operations, regexps, objects,\ + pickling, pretty-printing and getopt.\ + ", + summary = "General Lua libraries", + homepage = "http://github.com/rrthomas/lua-stdlib/", +} From 82d8ddfc608e77650f4e3c849df09258d9c33924 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 28 Feb 2013 04:19:30 +0700 Subject: [PATCH 10/34] Release v33 --- GNUmakefile | 83 +++++++++++++++++++++++++++++++++++++++++++ Makefile | 16 +++------ Makefile.am | 6 +--- Makefile.in | 16 +++------ configure | 3 +- configure.ac | 2 +- stdlib-33-1.rockspec | 26 +++++++------- stdlib-git-1.rockspec | 24 ++++++------- 8 files changed, 121 insertions(+), 55 deletions(-) create mode 100644 GNUmakefile diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..985e548 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,83 @@ +## maintainer rules. + +dont-forget-to-bootstrap = $(wildcard Makefile) + +ifeq ($(dont-forget-to-bootstrap),) + +Makefile: Makefile.in + ./configure + $(MAKE) + +Makefile.in: + autoreconf --force --verbose --install + +else + +include Makefile + +MKROCKSPECS = $(ROCKSPEC_ENV) $(LUA) $(srcdir)/mkrockspecs.lua +ROCKSPEC_TEMPLATE = $(srcdir)/$(PACKAGE)-rockspec.lua + +luarocks-config.lua: + $(AM_V_GEN){ \ + echo 'rocks_trees = {'; \ + echo ' "$(abs_srcdir)/luarocks"'; \ + echo '}'; \ + } > '$@' + +rockspecs: luarocks-config.lua + rm -f *.rockspec + $(MKROCKSPECS) $(PACKAGE) $(VERSION) $(ROCKSPEC_TEMPLATE) + $(MKROCKSPECS) $(PACKAGE) git $(ROCKSPEC_TEMPLATE) + +GIT ?= git + +tag-release: + $(GIT) diff --exit-code && \ + $(GIT) tag -f -a -m "Release tag" v$(VERSION) + +define unpack-distcheck-release + rm -rf $(PACKAGE)-$(VERSION)/ && \ + tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + cp -a -f $(PACKAGE)-$(VERSION)/* . && \ + rm -rf $(PACKAGE)-$(VERSION)/ && \ + echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ + echo './configure && make all rockspecs' && \ + ./configure --version && ./configure && \ + $(MAKE) all rockspecs +endef + +check-in-release: distcheck + current_branch=`$(GIT) symbolic-ref HEAD`; \ + { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ + { $(GIT) pull origin release || true; } && \ + $(unpack-distcheck-release) && \ + $(GIT) add . && \ + $(GIT) commit -a -m "Release v$(VERSION)" && \ + $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ + $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` + + +## To test the release process without publishing upstream, use: +## make release WOGER=: GIT_PUBLISH=: +GIT_PUBLISH ?= $(GIT) +WOGER ?= woger + +WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' +WOGER_OUT = $(WOGER_ENV) $(LUA) -l$(PACKAGE) -e + +release: rockspecs + $(MAKE) tag-release && \ + $(MAKE) check-in-release && \ + $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ + LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks \ + --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ + $(WOGER) lua \ + package=$(PACKAGE) \ + package_name=$(PACKAGE_NAME) \ + version=$(VERSION) \ + notes=release-notes-$(VERSION) \ + home="`$(WOGER_OUT) 'print (description.homepage)'`" \ + description="`$(WOGER_OUT) 'print (description.summary)'`" + +endif diff --git a/Makefile b/Makefile index f8e21fc..a3ee2d1 100644 --- a/Makefile +++ b/Makefile @@ -51,9 +51,9 @@ POST_UNINSTALL = : subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/luarocks-config.lua.in $(dist_data_DATA) \ - $(dist_doc_DATA) $(dist_files_DATA) $(dist_modules_DATA) \ - AUTHORS INSTALL README build-aux/install-sh build-aux/missing \ + $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ + $(dist_modules_DATA) AUTHORS INSTALL README \ + build-aux/install-sh build-aux/missing \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -65,7 +65,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = luarocks-config.lua +CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) @@ -291,6 +291,7 @@ EXTRA_DIST = \ specs/specl \ specs/lib/specl.lua \ src/std.lua.in \ + GNUmakefile \ $(SPECS) \ $(NOTHING_ELSE) @@ -332,8 +333,6 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): -luarocks-config.lua: $(top_builddir)/config.status $(srcdir)/luarocks-config.lua.in - cd $(top_builddir) && $(SHELL) ./config.status $@ install-dist_dataDATA: $(dist_data_DATA) @$(NORMAL_INSTALL) @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ @@ -777,11 +776,6 @@ src/std.lua: src/std.lua.in $(dist_doc_DATA): $(SOURCES) cd src && $(LUADOC) *.lua -rockspecs: - rm -f *.rockspec - $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) - $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git - check-local: $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua diff --git a/Makefile.am b/Makefile.am index c4f89ad..4f25b03 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,6 +58,7 @@ EXTRA_DIST = \ specs/specl \ specs/lib/specl.lua \ src/std.lua.in \ + GNUmakefile \ $(SPECS) \ $(NOTHING_ELSE) @@ -73,10 +74,5 @@ src/std.lua: src/std.lua.in $(dist_doc_DATA): $(SOURCES) cd src && $(LUADOC) *.lua -rockspecs: - rm -f *.rockspec - $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) - $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git - check-local: $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua diff --git a/Makefile.in b/Makefile.in index 77907a9..ef160b1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -51,9 +51,9 @@ POST_UNINSTALL = : subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ - $(srcdir)/luarocks-config.lua.in $(dist_data_DATA) \ - $(dist_doc_DATA) $(dist_files_DATA) $(dist_modules_DATA) \ - AUTHORS INSTALL README build-aux/install-sh build-aux/missing \ + $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ + $(dist_modules_DATA) AUTHORS INSTALL README \ + build-aux/install-sh build-aux/missing \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -65,7 +65,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = luarocks-config.lua +CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -291,6 +291,7 @@ EXTRA_DIST = \ specs/specl \ specs/lib/specl.lua \ src/std.lua.in \ + GNUmakefile \ $(SPECS) \ $(NOTHING_ELSE) @@ -332,8 +333,6 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): -luarocks-config.lua: $(top_builddir)/config.status $(srcdir)/luarocks-config.lua.in - cd $(top_builddir) && $(SHELL) ./config.status $@ install-dist_dataDATA: $(dist_data_DATA) @$(NORMAL_INSTALL) @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ @@ -777,11 +776,6 @@ src/std.lua: src/std.lua.in $(dist_doc_DATA): $(SOURCES) cd src && $(LUADOC) *.lua -rockspecs: - rm -f *.rockspec - $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) $(VERSION) - $(LUA_ENV) $(LUA) mkrockspecs.lua $(PACKAGE) git - check-local: $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua diff --git a/configure b/configure index 9506b39..7d7ef22 100755 --- a/configure +++ b/configure @@ -2871,7 +2871,7 @@ fi -ac_config_files="$ac_config_files Makefile luarocks-config.lua" +ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -3591,7 +3591,6 @@ for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "luarocks-config.lua") CONFIG_FILES="$CONFIG_FILES luarocks-config.lua" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index 62e4f2a..4fdb41b 100644 --- a/configure.ac +++ b/configure.ac @@ -14,5 +14,5 @@ AX_WITH_PROG([LUADOC], [luadoc], [:]) dnl Generate output files AC_CONFIG_MACRO_DIR(m4) -AC_CONFIG_FILES([Makefile luarocks-config.lua]) +AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/stdlib-33-1.rockspec b/stdlib-33-1.rockspec index 06e9b0f..484025d 100644 --- a/stdlib-33-1.rockspec +++ b/stdlib-33-1.rockspec @@ -1,25 +1,25 @@ -build = { - build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - copy_directories = { - }, - install_command = "make install", - type = "command", +version = "33-1" +source = { + url = "git://github.com/rrthomas/lua-stdlib.git", + branch = "release-v33", } dependencies = { "lua >= 5.1", } -version = "33-1" +package = "stdlib" +build = { + install_command = "make install", + type = "command", + copy_directories = { + }, + build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", +} description = { - summary = "General Lua libraries", license = "MIT/X11", + summary = "General Lua libraries", detailed = " stdlib is a library of modules for common programming tasks,\ including list, table and functional operations, regexps, objects,\ pickling, pretty-printing and getopt.\ ", homepage = "http://github.com/rrthomas/lua-stdlib/", } -package = "stdlib" -source = { - branch = "release-v33", - url = "git://github.com/rrthomas/lua-stdlib.git", -} diff --git a/stdlib-git-1.rockspec b/stdlib-git-1.rockspec index c08f7f3..7616f7d 100644 --- a/stdlib-git-1.rockspec +++ b/stdlib-git-1.rockspec @@ -1,24 +1,24 @@ -package = "stdlib" -build = { - build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - install_command = "make install", - type = "command", - copy_directories = { - }, +version = "git-1" +source = { + url = "git://github.com/rrthomas/lua-stdlib.git", } dependencies = { "lua >= 5.1", } -version = "git-1" -source = { - url = "git://github.com/rrthomas/lua-stdlib.git", +build = { + type = "command", + install_command = "make install", + build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + copy_directories = { + }, } description = { license = "MIT/X11", + homepage = "http://github.com/rrthomas/lua-stdlib/", + summary = "General Lua libraries", detailed = " stdlib is a library of modules for common programming tasks,\ including list, table and functional operations, regexps, objects,\ pickling, pretty-printing and getopt.\ ", - summary = "General Lua libraries", - homepage = "http://github.com/rrthomas/lua-stdlib/", } +package = "stdlib" From 7e2f00655e6e10af13c87011bb761e7afb62c4b5 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 28 Feb 2013 04:28:46 +0700 Subject: [PATCH 11/34] Release v33 --- GNUmakefile | 6 +++--- stdlib-33-1.rockspec | 22 +++++++++++----------- stdlib-git-1.rockspec | 24 ++++++++++++------------ 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 985e548..d8cad3c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -48,14 +48,12 @@ define unpack-distcheck-release endef check-in-release: distcheck - current_branch=`$(GIT) symbolic-ref HEAD`; \ { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ { $(GIT) pull origin release || true; } && \ $(unpack-distcheck-release) && \ $(GIT) add . && \ $(GIT) commit -a -m "Release v$(VERSION)" && \ - $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION); \ - $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` + $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION) ## To test the release process without publishing upstream, use: @@ -67,6 +65,7 @@ WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' WOGER_OUT = $(WOGER_ENV) $(LUA) -l$(PACKAGE) -e release: rockspecs + current_branch=`$(GIT) symbolic-ref HEAD`; \ $(MAKE) tag-release && \ $(MAKE) check-in-release && \ $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ @@ -79,5 +78,6 @@ release: rockspecs notes=release-notes-$(VERSION) \ home="`$(WOGER_OUT) 'print (description.homepage)'`" \ description="`$(WOGER_OUT) 'print (description.summary)'`" + $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` endif diff --git a/stdlib-33-1.rockspec b/stdlib-33-1.rockspec index 484025d..1e91314 100644 --- a/stdlib-33-1.rockspec +++ b/stdlib-33-1.rockspec @@ -1,25 +1,25 @@ -version = "33-1" -source = { - url = "git://github.com/rrthomas/lua-stdlib.git", - branch = "release-v33", -} -dependencies = { - "lua >= 5.1", -} -package = "stdlib" build = { - install_command = "make install", type = "command", copy_directories = { }, build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + install_command = "make install", +} +source = { + branch = "release-v33", + url = "git://github.com/rrthomas/lua-stdlib.git", +} +version = "33-1" +package = "stdlib" +dependencies = { + "lua >= 5.1", } description = { - license = "MIT/X11", summary = "General Lua libraries", detailed = " stdlib is a library of modules for common programming tasks,\ including list, table and functional operations, regexps, objects,\ pickling, pretty-printing and getopt.\ ", + license = "MIT/X11", homepage = "http://github.com/rrthomas/lua-stdlib/", } diff --git a/stdlib-git-1.rockspec b/stdlib-git-1.rockspec index 7616f7d..cde167f 100644 --- a/stdlib-git-1.rockspec +++ b/stdlib-git-1.rockspec @@ -1,24 +1,24 @@ -version = "git-1" -source = { - url = "git://github.com/rrthomas/lua-stdlib.git", -} -dependencies = { - "lua >= 5.1", -} +package = "stdlib" build = { type = "command", - install_command = "make install", build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + install_command = "make install", copy_directories = { }, } +version = "git-1" +source = { + url = "git://github.com/rrthomas/lua-stdlib.git", +} description = { - license = "MIT/X11", - homepage = "http://github.com/rrthomas/lua-stdlib/", - summary = "General Lua libraries", detailed = " stdlib is a library of modules for common programming tasks,\ including list, table and functional operations, regexps, objects,\ pickling, pretty-printing and getopt.\ ", + homepage = "http://github.com/rrthomas/lua-stdlib/", + license = "MIT/X11", + summary = "General Lua libraries", +} +dependencies = { + "lua >= 5.1", } -package = "stdlib" From 819b8f90af77897ea8fe0132bb37419aead99e55 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Mon, 25 Mar 2013 21:21:47 +0700 Subject: [PATCH 12/34] Release v34 --- GNUmakefile | 14 +- Makefile | 61 +-- Makefile.am | 26 +- Makefile.in | 23 +- README | 4 +- configure | 20 +- configure.ac | 2 +- specs/getopt_spec.yaml | 67 +++ specs/package_ext_spec.yaml | 25 ++ specs/string_ext_spec.yaml | 391 ++++++++++++++++ specs/table_ext_spec.yaml | 446 +++++++++---------- src/files/getopt.html | 60 +-- src/getopt.lua | 33 +- src/list.lua | 26 +- src/std.lua | 2 +- src/string_ext.lua | 3 +- stdlib-33-1.rockspec => stdlib-34-1.rockspec | 22 +- stdlib-git-1.rockspec | 26 +- 18 files changed, 845 insertions(+), 406 deletions(-) create mode 100644 specs/getopt_spec.yaml create mode 100644 specs/package_ext_spec.yaml create mode 100644 specs/string_ext_spec.yaml rename stdlib-33-1.rockspec => stdlib-34-1.rockspec (94%) diff --git a/GNUmakefile b/GNUmakefile index d8cad3c..bcdc6e7 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,6 +13,13 @@ Makefile.in: else +# Use 'make check V=1' for verbose output, or set SPECL_OPTS to +# pass alternative options to specl command. +SPECL_OPTS ?= $(specl_verbose_$(V)) +specl_verbose_ = $(specl_verbose_$(AM_DEFAULT_VERBOSITY)) +specl_verbose_0 = +specl_verbose_1 = --verbose --formatter=report + include Makefile MKROCKSPECS = $(ROCKSPEC_ENV) $(LUA) $(srcdir)/mkrockspecs.lua @@ -38,7 +45,7 @@ tag-release: define unpack-distcheck-release rm -rf $(PACKAGE)-$(VERSION)/ && \ - tar zxf $(PACKAGE)-$(VERSION).tar.gz && \ + tar zxf ../$(PACKAGE)/$(PACKAGE)-$(VERSION).tar.gz && \ cp -a -f $(PACKAGE)-$(VERSION)/* . && \ rm -rf $(PACKAGE)-$(VERSION)/ && \ echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ @@ -48,8 +55,7 @@ define unpack-distcheck-release endef check-in-release: distcheck - { $(GIT) checkout -b release 2>/dev/null || $(GIT) checkout release; } && \ - { $(GIT) pull origin release || true; } && \ + cd ../$(PACKAGE)-release && \ $(unpack-distcheck-release) && \ $(GIT) add . && \ $(GIT) commit -a -m "Release v$(VERSION)" && \ @@ -65,7 +71,6 @@ WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' WOGER_OUT = $(WOGER_ENV) $(LUA) -l$(PACKAGE) -e release: rockspecs - current_branch=`$(GIT) symbolic-ref HEAD`; \ $(MAKE) tag-release && \ $(MAKE) check-in-release && \ $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ @@ -78,6 +83,5 @@ release: rockspecs notes=release-notes-$(VERSION) \ home="`$(WOGER_OUT) 'print (description.homepage)'`" \ description="`$(WOGER_OUT) 'print (description.summary)'`" - $(GIT) checkout `echo "$$current_branch" | sed 's,.*/,,g'` endif diff --git a/Makefile b/Makefile index a3ee2d1..71118e6 100644 --- a/Makefile +++ b/Makefile @@ -154,15 +154,15 @@ distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print -ACLOCAL = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing aclocal-1.13 +ACLOCAL = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing aclocal-1.13 AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 0 -AUTOCONF = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing autoconf -AUTOHEADER = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing autoheader -AUTOMAKE = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing automake-1.13 -AWK = awk +AUTOCONF = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing autoconf +AUTOHEADER = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing autoheader +AUTOMAKE = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing automake-1.13 +AWK = gawk CYGPATH_W = echo -DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"33\" -DPACKAGE_STRING=\"stdlib\ 33\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"33\" +DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"34\" -DPACKAGE_STRING=\"stdlib\ 34\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"34\" ECHO_C = \c ECHO_N = ECHO_T = @@ -180,26 +180,26 @@ LUA_EXEC_PREFIX = ${exec_prefix} LUA_MIN_VERSION = 5.1 LUA_PLATFORM = unknown LUA_PREFIX = ${prefix} -LUA_SHORT_VERSION = 52 -LUA_VERSION = 5.2 -MAKEINFO = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/missing makeinfo +LUA_SHORT_VERSION = 51 +LUA_VERSION = 5.1 +MAKEINFO = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing makeinfo MKDIR_P = build-aux/install-sh -c -d PACKAGE = stdlib PACKAGE_BUGREPORT = rrt@sc3d.org PACKAGE_NAME = stdlib -PACKAGE_STRING = stdlib 33 +PACKAGE_STRING = stdlib 34 PACKAGE_TARNAME = stdlib PACKAGE_URL = -PACKAGE_VERSION = 33 +PACKAGE_VERSION = 34 PATH_SEPARATOR = : SET_MAKE = SHELL = /bin/sh STRIP = -VERSION = 33 -abs_builddir = /Volumes/Home/Devo/lua-stdlib--master--0 -abs_srcdir = /Volumes/Home/Devo/lua-stdlib--master--0 -abs_top_builddir = /Volumes/Home/Devo/lua-stdlib--master--0 -abs_top_srcdir = /Volumes/Home/Devo/lua-stdlib--master--0 +VERSION = 34 +abs_builddir = /Users/gary/Devo/stdlib-release +abs_srcdir = /Users/gary/Devo/stdlib-release +abs_top_builddir = /Users/gary/Devo/stdlib-release +abs_top_srcdir = /Users/gary/Devo/stdlib-release am__leading_dot = . am__tar = $${TAR-tar} chof - "$$tardir" am__untar = $${TAR-tar} xf - @@ -215,13 +215,13 @@ host_alias = htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info -install_sh = ${SHELL} /Volumes/Home/Devo/lua-stdlib--master--0/build-aux/install-sh +install_sh = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var -luadir = ${prefix}/share/lua/5.2 -luaexecdir = ${exec_prefix}/lib/lua/5.2 +luadir = ${prefix}/share/lua/5.1 +luaexecdir = ${exec_prefix}/lib/lua/5.1 mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include @@ -241,9 +241,9 @@ top_builddir = . top_srcdir = . ACLOCAL_AMFLAGS = -I m4 src_spec = $(abs_srcdir)/src/?.lua -lib_spec = $(abs_srcdir)/specs/lib/?.lua LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPEC_ENV = LUA_PATH="$(lib_spec);$(src_spec);$(LUA_PATH)" +SPEC_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" +SPECL_MIN = 3 NOTHING_ELSE = SOURCES = \ src/base.lua \ @@ -272,10 +272,10 @@ SOURCES = \ $(NOTHING_ELSE) SPECS = \ - specs/getopt_spec.lua \ - specs/package_ext_spec.lua \ - specs/string_ext_spec.lua \ - specs/table_ext_spec.lua \ + $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/package_ext_spec.yaml \ + $(srcdir)/specs/string_ext_spec.yaml \ + $(srcdir)/specs/table_ext_spec.yaml \ $(NOTHING_ELSE) dist_data_DATA = $(SOURCES) @@ -288,8 +288,6 @@ dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ - specs/specl \ - specs/lib/specl.lua \ src/std.lua.in \ GNUmakefile \ $(SPECS) \ @@ -777,7 +775,14 @@ $(dist_doc_DATA): $(SOURCES) cd src && $(LUADOC) *.lua check-local: - $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua + @v=`specl --version | sed -e 's|^.* ||' -e 1q`; \ + if test "$$v" -lt "$(SPECL_MIN)"; then \ + echo "ERROR: Specl version $$v is too old, please upgrade to at least version $(SPECL_MIN),";\ + echo "ERROR: and rerun \`make check\`"; \ + exit 1; \ + else \ + $(SPEC_ENV) specl $(SPECL_OPTS) $(SPECS); \ + fi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/Makefile.am b/Makefile.am index 4f25b03..e3c07a3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,11 +3,12 @@ ACLOCAL_AMFLAGS = -I m4 src_spec = $(abs_srcdir)/src/?.lua -lib_spec = $(abs_srcdir)/specs/lib/?.lua LUA_PATH ?= ; LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPEC_ENV = LUA_PATH="$(lib_spec);$(src_spec);$(LUA_PATH)" +SPEC_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" + +SPECL_MIN = 3 NOTHING_ELSE = @@ -37,11 +38,11 @@ SOURCES = \ src/xml.lua \ $(NOTHING_ELSE) -SPECS = \ - specs/getopt_spec.lua \ - specs/package_ext_spec.lua \ - specs/string_ext_spec.lua \ - specs/table_ext_spec.lua \ +SPECS = \ + $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/package_ext_spec.yaml \ + $(srcdir)/specs/string_ext_spec.yaml \ + $(srcdir)/specs/table_ext_spec.yaml \ $(NOTHING_ELSE) dist_data_DATA = $(SOURCES) @@ -55,8 +56,6 @@ modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ - specs/specl \ - specs/lib/specl.lua \ src/std.lua.in \ GNUmakefile \ $(SPECS) \ @@ -75,4 +74,11 @@ $(dist_doc_DATA): $(SOURCES) cd src && $(LUADOC) *.lua check-local: - $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua + @v=`specl --version | sed -e 's|^.* ||' -e 1q`; \ + if test "$$v" -lt "$(SPECL_MIN)"; then \ + echo "ERROR: Specl version $$v is too old, please upgrade to at least version $(SPECL_MIN),";\ + echo "ERROR: and rerun \`make check\`"; \ + exit 1; \ + else \ + $(SPEC_ENV) specl $(SPECL_OPTS) $(SPECS); \ + fi diff --git a/Makefile.in b/Makefile.in index ef160b1..24b9991 100644 --- a/Makefile.in +++ b/Makefile.in @@ -241,9 +241,9 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 src_spec = $(abs_srcdir)/src/?.lua -lib_spec = $(abs_srcdir)/specs/lib/?.lua LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPEC_ENV = LUA_PATH="$(lib_spec);$(src_spec);$(LUA_PATH)" +SPEC_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" +SPECL_MIN = 3 NOTHING_ELSE = SOURCES = \ src/base.lua \ @@ -272,10 +272,10 @@ SOURCES = \ $(NOTHING_ELSE) SPECS = \ - specs/getopt_spec.lua \ - specs/package_ext_spec.lua \ - specs/string_ext_spec.lua \ - specs/table_ext_spec.lua \ + $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/package_ext_spec.yaml \ + $(srcdir)/specs/string_ext_spec.yaml \ + $(srcdir)/specs/table_ext_spec.yaml \ $(NOTHING_ELSE) dist_data_DATA = $(SOURCES) @@ -288,8 +288,6 @@ dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ - specs/specl \ - specs/lib/specl.lua \ src/std.lua.in \ GNUmakefile \ $(SPECS) \ @@ -777,7 +775,14 @@ $(dist_doc_DATA): $(SOURCES) cd src && $(LUADOC) *.lua check-local: - $(AM_V_at)$(SPEC_ENV) $(LUA) $(srcdir)/specs/specl $(srcdir)/specs/*_spec.lua + @v=`specl --version | sed -e 's|^.* ||' -e 1q`; \ + if test "$$v" -lt "$(SPECL_MIN)"; then \ + echo "ERROR: Specl version $$v is too old, please upgrade to at least version $(SPECL_MIN),";\ + echo "ERROR: and rerun \`make check\`"; \ + exit 1; \ + else \ + $(SPEC_ENV) specl $(SPECL_OPTS) $(SPECS); \ + fi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/README b/README index 41d1ff2..a8185b1 100644 --- a/README +++ b/README @@ -12,7 +12,7 @@ license as Lua itself). There is no warranty. The standard subset of stdlib has no prerequisites beyond a standard Lua system. The following modules have extra dependencies: - fstable: Lua 5.2 + fstable: Lua 5.2, lfs, luaposix Installation @@ -21,7 +21,7 @@ Installation The simplest way to install stdlib is with LuaRocks (http://www.luarocks.org/ ): -luarocks install stdlib + luarocks install stdlib Use diff --git a/configure b/configure index 7d7ef22..9874456 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 33. +# Generated by GNU Autoconf 2.69 for stdlib 34. # # Report bugs to . # @@ -578,8 +578,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='33' -PACKAGE_STRING='stdlib 33' +PACKAGE_VERSION='34' +PACKAGE_STRING='stdlib 34' PACKAGE_BUGREPORT='rrt@sc3d.org' PACKAGE_URL='' @@ -1213,7 +1213,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 33 to adapt to many kinds of systems. +\`configure' configures stdlib 34 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1279,7 +1279,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 33:";; + short | recursive ) echo "Configuration of stdlib 34:";; esac cat <<\_ACEOF @@ -1365,7 +1365,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 33 +stdlib configure 34 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1382,7 +1382,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 33, which was +It was created by stdlib $as_me 34, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2245,7 +2245,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='33' + VERSION='34' cat >>confdefs.h <<_ACEOF @@ -3424,7 +3424,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 33, which was +This file was extended by stdlib $as_me 34, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3477,7 +3477,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 33 +stdlib config.status 34 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4fdb41b..966b5d6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake -AC_INIT(stdlib, 33, rrt@sc3d.org) +AC_INIT(stdlib, 34, rrt@sc3d.org) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) AM_SILENT_RULES([yes]) diff --git a/specs/getopt_spec.yaml b/specs/getopt_spec.yaml new file mode 100644 index 0000000..006d9cd --- /dev/null +++ b/specs/getopt_spec.yaml @@ -0,0 +1,67 @@ +specify getopt: +- before: + getopt = require "getopt" + +- "describe getopt.getOpt": + - before: | + prog = { + name = "getopt_spec.lua", + options = { {{"verbose", "v"}, "verbosely list files"}, + {{"output", "o"}, "dump to FILE", "Opt", "FILE"}, + {{"name", "n"}, "only dump USER's files", "Req", "USER"}, + } + } + + function test (cmdLine, undefined_opts) + local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options, undefined_opts) + if #errors == 0 then + return { options = opts, args = nonOpts } + else + return errors + end + end + + getopt.processArgs (prog) + + - it recognizes a user defined option: + expect (test {"foo", "-v"}).should_equal ( + { options = { verbose = {1}}, args = { "foo" } }) + - "it treats -- as the end of the option list": + expect (test {"foo", "--", "-v"}).should_equal ( + { options = {}, args = { "foo", "-v" } }) + - it captures a list of repeated option arguments: + expect (test {"-o", "-V", "-name", "bar", "--name=baz"}).should_equal ( + { options = { name = {"bar", "baz"}, version = {1}, output = {1}}, + args = {} }) + - it diagnoses unrecognized options: + expect (test {"-foo"}).should_contain "unrecognized option `-foo'" + - it allows unrecognized options if told to: + expect (test ({"-foo"}, true)).should_equal ( + { options = { foo = {1}}, args = {} }) + +- "describe getopt.usageInfo": + - context when specifying options: + - before: + helppatt = "%-h, %-%-help%s+print this help, then exit" + versionpatt = "%-V, %-%-version%s+print version information, then exit" + prog = { name = "getopt_spec.lua", options = {} } + options = { {{"help", "?"}, "display this help"}, + {{"version"}, "display version number"} } + f = getopt.usageInfo + + - it provides a default version option: + getopt.processArgs (prog) + expect (f ("", prog.options)).should_match (versionpatt) + - it allows the user to override the version option: + prog.options = options + getopt.processArgs (prog) + expect (f ("", prog.options)).should_not_match (versionpatt) + expect (f ("", prog.options)).should_match (" %-%-version%s+display") + - it provides a default help option: + getopt.processArgs (prog) + expect (f ("", prog.options)).should_match (helppatt) + - it allows the user to override the help option: + prog.options = options + getopt.processArgs (prog) + expect (f ("", prog.options)).should_not_match (helppatt) + expect (f ("", prog.options)).should_match ("%-%?, %-%-help%s+display") diff --git a/specs/package_ext_spec.yaml b/specs/package_ext_spec.yaml new file mode 100644 index 0000000..2fe09f8 --- /dev/null +++ b/specs/package_ext_spec.yaml @@ -0,0 +1,25 @@ +specify package_ext: +- before: + unextended = require "package_ext" +- context when requiring the module: + - before: | + -- do not try to check all the entries in unextended package, + -- because they naturally change as modules are loaded. + apis = { "config", "cpath", "loaders", "loadlib", "preload", + "searchers", "searchpath", "seeall" } + + - it returns the unextended package table: + expect (unextended.config).should_be (package.config) + expect (unextended.dirsep).should_be (nil) + expect (unextended.pathsep).should_be (nil) + expect (unextended.path_mark).should_be (nil) + expect (unextended.execdir).should_be (nil) + expect (unextended.igmark).should_be (nil) + - "it splits package.config up": + expect (string.format ("%s\n%s\n%s\n%s\n%s\n", + package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark) + ).should_contain (package.config) + - it does not override any other module access points: + for _, api in ipairs (apis) do + expect (package[api]).should_be (unextended[api]) + end diff --git a/specs/string_ext_spec.yaml b/specs/string_ext_spec.yaml new file mode 100644 index 0000000..bbcb91c --- /dev/null +++ b/specs/string_ext_spec.yaml @@ -0,0 +1,391 @@ +specify string_ext: +- before: + unextended = require "string_ext" + subject = "a string \n\n" + +- "describe .. operator": + - it concatenates string arguments: + target = "a string \n\n another string" + expect (subject .. " another string").should_be (target) + - "it stringifies non-string arguments": + argument = { "a table" } + expect (subject .. argument).should_match (string.format ("%s{1=a table}", subject)) + - it stringifies nil arguments: + argument = nil + expect (subject .. argument).should_be (string.format ("%s%s", subject, tostring (argument))) + - the original subject is not perturbed: + original = subject + newstring = subject .. " concatenate something" + expect (subject).should_be (original) + +- "describe string.caps ()": + - before: + f = string.caps + - it capitalises words of a string: + target = "A String \n\n" + expect (f (subject)).should_be (target) + - it changes only the first letter of each word: + expect (f "a stRiNg").should_be "A StRiNg" + - the original subject is not perturbed: + original = subject + newstring = f (subject) + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.chomp ()": + - before: + f = string.chomp + - it removes a single trailing newline from a string: + target = "a string \n" + expect (f (subject)).should_be (target) + - it does not change a string with no trailing newline: + subject = "a string " + expect (f (subject)).should_be (subject) + - the original subject is not perturbed: + original = subject + newstring = f (subject) + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.escape_pattern ()": + - before: + f = string.escape_pattern + - "it inserts a % before any non-alphanumeric in a string": + subject, target = "", "" + for c = 32, 126 do + s = string.char (c) + subject = subject .. s + if s:match ("%W") then target = target .. "%" end + target = target .. s + end + expect (f (subject)).should_be (target) + - legacy escapePattern call is the same function: + expect (string.escapePattern).should_be (f) + - the original subject is not perturbed: + original = subject + newstring = f (subject) + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.escape_shell ()": + - before: + f = string.escape_shell + - "it inserts a \\ before any shell metacharacters": + subject, target = "", "" + for c = 32, 126 do + s = string.char (c) + subject = subject .. s + if s:match ("[][ ()\\\"']") then target = target .. "\\" end + target = target .. s + end + expect (f (subject)).should_be (target) + - legacy escapeShell call is the same function: + expect (string.escapeShell).should_be (f) + - the original subject is not perturbed: + original = subject + newstring = f (subject) + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.finds ()": + - before: + subject = "abcd" + f = string.finds + - it creates a list of pattern captures: + target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } + expect ({f (subject, "(.)(.)")}).should_equal ({ target }) + - it creates an empty list where no captures are matched: + target = {} + expect ({f (subject, "(x)")}).should_equal ({ target }) + - it creates an empty list for a pattern without captures: + target = { { 1, 1; capt = {} } } + expect ({f (subject, "a")}).should_equal ({ target }) + - it starts the search at a specified index into the subject: + target = { { 8, 9; capt = { "a", "b" } }, { 10, 11; capt = { "c", "d" } } } + expect ({f ("garbage" .. subject, "(.)(.)", 8)}).should_equal ({ target }) + - the original subject is not perturbed: + original = subject + newstring = f (subject, "...") + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +# FIXME: This looks like a misfeature to me, let's remove it! +- "describe string.format ()": + - before: | + subject = "string: %s, number: %d" + f = string.format + - it returns a single argument without attempting formatting: + expect (f (subject)).should_be (subject) + - the original subject is not perturbed: + original = subject + newstring = f (subject) + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil, "arg") + expect ("string expected").should_error (f, { "a table" }, "arg") + + +- "describe string.ltrim ()": + - before: + subject = " \t\r\n a short string \t\r\n " + f = string.ltrim + - it removes whitespace from the start of a string: + target = "a short string \t\r\n " + expect (f (subject)).should_equal (target) + - it supports custom removal patterns: + target = "\r\n a short string \t\r\n " + expect (f (subject, "[ \t\n]+")).should_equal (target) + - the original subject is not perturbed: + original = subject + newstring = f (subject, "%W") + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.numbertosi ()": + - before: + f = string.numbertosi + - it returns a number using SI suffixes: + target = {"1e-9", "1y", "1z", "1a", "1f", "1p", "1n", "1mu", "1m", "1", + "1k", "1M", "1G", "1T", "1P", "1E", "1Z", "1Y", "1e9"} + subject = {} + for n = -28, 28, 3 do + m = 10 * (10 ^ n) + table.insert (subject, f (m)) + end + expect (subject).should_equal (target) + - it coerces string arguments to a number: + expect (f "1000").should_be "1k" + - "it diagnoses non-numeric arguments": + expect ("attempt to perform arithmetic").should_error (f, nil) + expect ("number expected").should_error (f, { "a table" }) + + +- "describe string.ordinal_suffix ()": + - before: + f = string.ordinal_suffix + - it returns the English suffix for a number: + subject, target = {}, {} + for n = -120, 120 do + suffix = "th" + m = math.abs (n) % 10 + if m == 1 and math.abs (n) % 100 ~= 11 then suffix = "st" + elseif m == 2 and math.abs (n) % 100 ~= 12 then suffix = "nd" + elseif m == 3 and math.abs (n) % 100 ~= 13 then suffix = "rd" + end + table.insert (target, n .. suffix) + table.insert (subject, n .. f (n)) + end + expect (subject).should_equal (target) + - legacy ordinalSuffix call is the same function: + expect (string.ordinalSuffix).should_be (f) + - it coerces string arguments to a number: + expect (f "-91").should_be "st" + - "it diagnoses non-numeric arguments": + expect ("number expected").should_error (f, nil) + expect ("number expected").should_error (f, { "a table" }) + + +- "describe string.pad ()": + - before: + width = 20 + f = string.pad + + - context when string is shorter than given width: + - before: + subject = "short string" + - it right pads a string to the given width with spaces: + target = "short string " + expect (f (subject, width)).should_be (target) + - it left pads a string to the given negative width with spaces: + width = -width + target = " short string" + expect (f (subject, width)).should_be (target) + + - context when string is longer than given width: + - before: + subject = "a string that's longer than twenty characters" + - it truncates a string to the given width: + target = "a string that's long" + expect (f (subject, width)).should_be (target) + - it left pads a string to given width with spaces: + width = -width + target = "an twenty characters" + expect (f (subject, width)).should_be (target) + + - the original subject is not perturbed: + original = subject + newstring = f (subject, width) + expect (subject).should_be (original) + - "it coerces non-string arguments to a string": + expect (f ({ "a table" }, width)).should_contain "a table" + - "it diagnoses non-numeric width arguments": + expect ("number expected").should_error (f, subject, nil) + expect ("number expected").should_error (f, subject, { "a table" }) + + +- "describe string.rtrim ()": + - before: + subject = " \t\r\n a short string \t\r\n " + f = string.rtrim + - it removes whitespace from the end of a string: + target = " \t\r\n a short string" + expect (f (subject)).should_equal (target) + - it supports custom removal patterns: + target = " \t\r\n a short string \t\r" + expect (f (subject, "[ \t\n]+")).should_equal (target) + - the original subject is not perturbed: + original = subject + newstring = f (subject, "%W") + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.split ()": + - before: + target = { "first", "the second one", "final entry" } + subject = table.concat (target, ", ") + f = string.split + - it makes a table of substrings delimitied by a separator: + expect (f (subject, ", ")).should_equal (target) + - the original subject is not perturbed: + original = subject + newstring = f (subject, "e") + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, "a string", nil) + expect ("string expected").should_error (f, nil, ",") + expect ("string expected").should_error (f, { "a table" }, ",") + + +- "describe string.tfind ()": + - before: + subject = "abc" + f = string.tfind + - it creates a list of pattern captures: + target = { 1, 3, { "a", "b", "c" } } + expect ({f (subject, "(.)(.)(.)")}).should_equal (target) + - it creates an empty list where no captures are matched: + target = { nil, nil, {} } + expect ({f (subject, "(x)(y)(z)")}).should_equal (target) + - it creates an empty list for a pattern without captures: + target = { 1, 1, {} } + expect ({f (subject, "a")}).should_equal (target) + - it starts the search at a specified index into the subject: + target = { 8, 10, { "a", "b", "c" } } + expect ({f ("garbage" .. subject, "(.)(.)(.)", 8)}).should_equal (target) + - the original subject is not perturbed: + original = subject + newstring = f (subject, "...") + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.trim ()": + - before: + subject = " \t\r\n a short string \t\r\n " + f = string.trim + - it removes whitespace from each end of a string: + target = "a short string" + expect (f (subject)).should_equal (target) + - it supports custom removal patterns: + target = "\r\n a short string \t\r" + expect (f (subject, "[ \t\n]+")).should_equal (target) + - the original subject is not perturbed: + original = subject + newstring = f (subject, "%W") + expect (subject).should_be (original) + - "it diagnoses non-string arguments": + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- "describe string.wrap ()": + - before: + subject = "This is a collection of Lua libraries for Lua 5.1 " .. + "and 5.2. The libraries are copyright by their authors 2000" .. + "-2013 (see the AUTHORS file for details), and released und" .. + "er the MIT license (the same license as Lua itself). There" .. + " is no warranty." + f = string.wrap + - it inserts newlines to wrap a string: + target = "This is a collection of Lua libraries for Lua 5.1 a" .. + "nd 5.2. The libraries are\ncopyright by their authors 2000" .. + "-2013 (see the AUTHORS file for details), and\nreleased un" .. + "der the MIT license (the same license as Lua itself). Ther" .. + "e is no\nwarranty." + expect (f (subject)).should_be (target) + - it honours a column width parameter: + target = "This is a collection of Lua libraries for Lua 5.1 a" .. + "nd 5.2. The libraries\nare copyright by their authors 2000" .. + "-2013 (see the AUTHORS file for\ndetails), and released un" .. + "der the MIT license (the same license as Lua\nitself). The" .. + "re is no warranty." + expect (f (subject, 72)).should_be (target) + - it supports indenting by a fixed number of columns: + target = " This is a collection of Lua libraries for L" .. + "ua 5.1 and 5.2. The\n libraries are copyright by th" .. + "eir authors 2000-2013 (see the\n AUTHORS file for d" .. + "etails), and released under the MIT license\n (the " .. + "same license as Lua itself). There is no warranty." + expect (f (subject, 72, 8)).should_be (target) + - it can indent the first line differently: + target = " This is a collection of Lua libraries for Lua 5" .. + ".1 and 5.2.\n The libraries are copyright by their author" .. + "s 2000-2013 (see\n the AUTHORS file for details), and rel" .. + "eased under the MIT\n license (the same license as Lua it" .. + "self). There is no\n warranty." + expect (f (subject, 64, 2, 4)).should_be (target) + - the original subject is not perturbed: + original = subject + newstring = f (subject, 55, 5) + expect (subject).should_be (original) + - it diagnoses indent greater than line width: + expect ("less than the line width").should_error (f, subject, 10, 12) + expect ("less than the line width").should_error (f, subject, 99, 99) + - it diagnoses non-string arguments: + expect ("string expected").should_error (f, nil) + expect ("string expected").should_error (f, { "a table" }) + + +- context when requiring the module: + - before: + extensions = { "caps", "chomp", "escape_pattern", "escape_shell", + "finds", "format", "ltrim", "numbertosi", + "ordinal_suffix", "pad", "rtrim", "split", "tfind", + "trim", "wrap" } + - it returns the unextended module table: + for _, api in ipairs (extensions) do + if api ~= "format" then + expect (unextended[api]).should_be (nil) + end + end + - it injects an enhanced format function: + expect (unextended.format).should_not_be (table.format) + - it does not override any other module access points: + for api in pairs (unextended) do + if api ~= "format" then + expect (string[api]).should_be (unextended[api]) + end + end diff --git a/specs/table_ext_spec.yaml b/specs/table_ext_spec.yaml index 456f22f..a391faf 100644 --- a/specs/table_ext_spec.yaml +++ b/specs/table_ext_spec.yaml @@ -1,260 +1,232 @@ -module table_ext: -- before: | - unextended = require "table_ext" - table_ext = table - - -- shared examples: - - before: | - object = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } - - - describe a table operation: - - it diagnoses non-table arguments: | - expect ("table expected").should_error (subject, nil) - expect ("table expected").should_error (subject, 42) - expect ("table expected").should_error (subject, "foo") - - - describe a destructive operation: - - it operates on the object in place: | - original = object - expect (subject (object)).should_be (original) - - - "describe a non-destructive operation": - - it returns a new object: | - expect (subject (object)).should_not_be (object) - - - describe a reversible operation: - - it is returns the original object when applied twice: | - expect (subject (subject (object))).should_equal (object) - - - describe a stable table operation: - - it behaves like: a table operation - - it behaves like: a not-destructive operation - - - it returns an empty list when object is empty: | - expect (subject {}).should_equal {} - - # is this a good test? or just requiring an implementation quirk? - - it does guarantee stable ordering: | - object = {} - for i = 10000, 1, -1 do table.insert (object, i) end - expect (subject (object)).should_equal (object) - - - describe an unstable table operation: - - it behaves like: a table operation - - it behaves like: a not-destructive operation - - - it returns an empty list when object is empty: | - expect (subject {}).should_equal {} - - # is this a good example? there's a vanishingly small possibility - # the returned table will have all 10000 keys in the same order... - - it does not guarantee stable ordering: | - object = {} - for i = 10000, 1, -1 do table.insert (object, i) end - expect (subject (object)).should_not_equal (object) - - - describe a table copying operation: - - it behaves like: a table operation - - it behaves like: a non-destructive operation - - - it does copy the object: | - expect (subject (object)).should_equal (object) - - - the original object is not perturbed: | - target = { k1 = object.k1, k2 = object.k2, k3 = object.k3 } - copy = subject (object) - expect (object).should_equal (target) - expect (object).should_be (object) - - -- new: - - "it diagnoses non-tables/non-nil in the second argument": | - expect ("table expected").should_error (subject, nil, "foo") - - - context when not setting a default: - - before: | - default = nil - - - it returns a new table when nil is passed: | - expect (subject (default, nil)).should_equal {} - - - it returns any table passed in: | - t = { "unique table" } - expect (subject (default, t)).should_be (t) - - - context when setting a default: - - before: | - default = "default" - - - it returns a new table when nil is passed: | - expect (subject (default, nil)).should_equal {} - - - it returns any table passed in: | - t = { "unique table" } - expect (subject (default, t)).should_be (t) - - - it returns the stored value for existing keys: | - t = subject ("default") - v = { "unique value" } - t[1] = v - expect (t[1]).should_be (v) - - - it returns the constructor default for unset keys: | - t = subject ("default") - expect (t[1]).should_be "default" - - - it returns the actual default object: | - default = { "unique object" } - t = subject (default) - expect (t[1]).should_be (default) - - -- empty: - - it behaves like: a table operation - - it behaves like: a non-destructive operation - - - it returns true for an empty table: | - expect (subject {}).should_be (true) - expect (subject {nil}).should_be (true) - - - it returns false for a non-empty table: | - expect (subject {"stuff"}).should_be (false) - expect (subject {{}}).should_be (false) - expect (subject {false}).should_be (false) - - -- size: - - it behaves like: a table operation - - it behaves like: a non-destructive operation - - - it counts no keys in an empty table: | - expect (subject {}).should_be (0) - - - it counts the number of keys in a table: | - # - 1 - --------- 2 ---------- -- 3 -- - object = { "one", { { "two" }, "three" }, four = 5 } - expect (subject (object)).should_be (3) - - -- sort: - - it behaves like: a table operation - - it behaves like: a destructive operation - - - it returns the sorted object: | - object = { 5, 2, 4, 1, 0, 3 } - target = { 0, 1, 2, 3, 4, 5 } - expect (subject (object)).should_equal (target) - - -- keys: - - it behaves like: an unstable table operation - - - it makes a list of table keys: | - object = { k1 = "v1", k2 = "v2", k3 = "v3" } - expect (table.sort (subject (object))).should_equal {"k1", "k2", "k3"} - - -- values: - - it behaves like: a stable table operation - - - it makes a list of table values: | - object = { k1 = "v1", k2 = "v2", k3 = "v3" } - expect (table.sort (subject (object))).should_equal {"v1", "v2", "v3"} - - -- clone: - - it behaves like: a table copying operation - - - it only makes a shallow copy: | - expect (subject (object)). should_have (#object).members - for k in pairs (object) do - expect (subject (object)[k]).should_be (object[k]) - end - - -- clone_rename: - - before: | - subject = function (t) return table.clone_rename ({}, t) end - - - it behaves like: clone - - - context when renaming some keys: - - before: | - subject = table.clone_rename - rename = { k1 = "renamed" } - target = { newkey = object.k1, k2 = object.k2, k3 = object.k3 } - - - it renames some keys during cloning: | - expect (subject (rename, object)).should_equal (target) - - - it does not perturb the value in the renamed key field: | - expect (subject (renames, object).renamed).should_be (object.k1) - - -- invert: - - it behaves like: a table operation - - it behaves like: a non-destructive operation - - it behaves like: a reversible operation - - - it inverts keys and values in the returned table: | - object = { k1 = 1, k2 = 2, k3 = 3 } - expect (subject (object)).should_equal { "k1", "k2", "k3" } - - - it seems to copy a list of 1..n numbers: | - object = { 1, 2, 3 } - expect (subject (object)).should_equal (object) - expect (subject (object)).should_not_be (object) - - -- merge: - - before: | - # Additional merge keys which are moderately unusual +specify table_ext: +- before: + unextended = require "table_ext" +- "describe table.clone ()": + - before: + subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + f = table.clone + - it does not just return the subject: + expect (f (subject)).should_not_be (subject) + - it does copy the subject: + expect (f (subject)).should_equal (subject) + - it only makes a shallow copy: + expect (f (subject).k1).should_be (subject.k1) + - the original subject is not perturbed: + target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } + copy = f (subject) + expect (subject).should_equal (target) + expect (subject).should_be (subject) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + + +- "describe table.clone_rename()": + - before: + subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + f = table.clone_rename + - it does not just return the subject: + expect (f ({}, subject)).should_not_be (subject) + - it copies the subject: + expect (f ({}, subject)).should_equal (subject) + - it only makes a shallow copy: + expect (f ({}, subject).k2).should_be (subject.k2) + + - context when renaming some keys: + - before: + target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } + - it renames during cloning: + expect (f ({k1 = "newkey"}, subject)).should_equal (target) + - it does not perturb the value in the renamed key field: + expect (f ({k1 = "newkey"}, subject).newkey).should_be (subject.k1) + + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, {}, nil) + expect ("table expected").should_error (f, {}, "foo") + + +- "describe table.empty ()": + - before: + f = table.empty + - it returns true for an empty table: + expect (f {}).should_be (true) + expect (f {nil}).should_be (true) + - "it returns false for a non-empty table": + expect (f {"stuff"}).should_be (false) + expect (f {{}}).should_be (false) + expect (f {false}).should_be (false) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + + +- "describe table.invert ()": + - before: + subject = { k1 = 1, k2 = 2, k3 = 3 } + f = table.invert + - it returns a new table: + expect (f (subject)).should_not_be (subject) + - it inverts keys and values in the returned table: + expect (f (subject)).should_equal { "k1", "k2", "k3" } + - it is reversible: + expect (f (f (subject))).should_equal (subject) + - "it seems to copy a list of 1..n numbers": + subject = { 1, 2, 3 } + expect (f (subject)).should_equal (subject) + expect (f (subject)).should_not_be (subject) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + + +- "describe table.keys ()": + - before: + subject = { k1 = 1, k2 = 2, k3 = 3 } + f = table.keys + - it returns an empty list when subject is empty: + expect (f {}).should_equal {} + - it makes a list of table keys: + cmp = function (a, b) return a < b end + expect (table.sort (f (subject), cmp)).should_equal {"k1", "k2", "k3"} + - it does not guarantee stable ordering: + subject = {} + -- is this a good test? there is a vanishingly small possibility the + -- returned table will have all 10000 keys in the same order... + for i = 10000, 1, -1 do table.insert (subject, i) end + expect (f (subject)).should_not_equal (subject) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + + +- "describe table.merge ()": + - before: | + -- Additional merge keys which are moderately unusual t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } + f = table.merge target = {} for k, v in pairs (t1) do target[k] = v end for k, v in pairs (t2) do target[k] = v end - - - it behaves like: a table operation - - it behaves like: a destructive operation - - - it does not create a whole new table: | - expect (subject (t1, t2)).should_be (t1) - - - "it does not change t1, if t2 is empty": | - expect (subject (t1, {})).should_be (t1) - - - "it copies t2, if t1 is empty": | - expect (subject ({}, t1)).should_not_be (t1) - expect (subject ({}, t1)).should_equal (t1) - - - it merges keys from t2 into t1: | - expect (subject (t1, t2)).should_equal (target) - - - it gives precedence to values from t2: | + - it does not create a whole new table: + expect (f (t1, t2)).should_be (t1) + - it does not change t1 when t2 is empty: + expect (f (t1, {})).should_be (t1) + - it copies t2 when t1 is empty: + expect (f ({}, t1)).should_not_be (t1) + expect (f ({}, t1)).should_equal (t1) + - it merges keys from t2 into t1: + expect (f (t1, t2)).should_equal (target) + - it gives precedence to values from t2: original = table.clone (t1) - m = subject (t1, t2) # Merge is destructive, do it once only. + m = f (t1, t2) -- Merge is destructive, do it once only. expect (m.k3).should_be (t2.k3) expect (m.k3).should_not_be (original.k3) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil, nil) + expect ("table expected").should_error (f, "foo", "bar") + + +- "describe table.new ()": + - before: + f = table.new + + - context when not setting a default: + - before: default = nil + - it returns a new table when nil is passed: + expect (f (default, nil)).should_equal {} + - it returns any table passed in: + t = { "unique table" } + expect (f (default, t)).should_be (t) + + - context when setting a default: + - before: + default = "default" + - it returns a new table when nil is passed: + expect (f (default, nil)).should_equal {} + - it returns any table passed in: + t = { "unique table" } + expect (f (default, t)).should_be (t) + + - it returns the stored value for existing keys: + t = f ("default") + v = { "unique value" } + t[1] = v + expect (t[1]).should_be (v) + - it returns the constructor default for unset keys: + t = f ("default") + expect (t[1]).should_be "default" + - it returns the actual default object: + default = { "unique object" } + t = f (default) + expect (t[1]).should_be (default) + - "it diagnoses non-tables/non-nil in the second argument": + expect ("table expected").should_error (f, nil, "foo") + + +- "describe table.size ()": + - before: | + -- - 1 - --------- 2 ---------- -- 3 -- + subject = { "one", { { "two" }, "three" }, four = 5 } + f = table.size + - it counts the number of keys in a table: + expect (f (subject)).should_be (3) + - it counts no keys in an empty table: + expect (f {}).should_be (0) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") + + +- "describe table.sort ()": + - before: + subject = { 5, 2, 4, 1, 0, 3 } + target = { 0, 1, 2, 3, 4, 5 } + cmp = function (a, b) return a < b end + f = table.sort + - it sorts elements in place: + f (subject, cmp) + expect (subject).should_equal (target) + - it returns the sorted table: + expect (f (subject, cmp)).should_equal (target) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, nil) + + +- "describe table.values ()": + - before: + subject = { k1 = {1}, k2 = {2}, k3 = {3} } + f = table.values + - it returns an empty list when subject is empty: + expect (f {}).should_equal {} + - it makes a list of table values: + cmp = function (a, b) return a[1] < b[1] end + expect (table.sort (f (subject), cmp)).should_equal {{1}, {2}, {3}} + - it does guarantee stable ordering: + subject = {} + -- is this a good test? or just requiring an implementation quirk? + for i = 10000, 1, -1 do table.insert (subject, i) end + expect (f (subject)).should_equal (subject) + - "it diagnoses non-table arguments": + expect ("table expected").should_error (f, nil) + expect ("table expected").should_error (f, "foo") - context when requiring the module: - - it returns the unextended module table: | + - before: extensions = { "clone", "clone_rename", "empty", "invert", "keys", "merge", "new", "size", "sort", "values" } - + - it returns the unextended module table: for _, api in ipairs (extensions) do if api ~= "sort" then expect (unextended[api]).should_be (nil) end end - - - it injects an enhanced sort function: | + - it injects an enhanced sort function: expect (unextended.sort).should_not_be (table.sort) - - - "it doesn't override any other module access points": | + - it does not override any other module access points: for api in pairs (unextended) do if api ~= "sort" then expect (table[api]).should_be (unextended[api]) diff --git a/src/files/getopt.html b/src/files/getopt.html index 5598161..fa614fa 100644 --- a/src/files/getopt.html +++ b/src/files/getopt.html @@ -172,7 +172,7 @@

    Functions

    - + @@ -182,7 +182,7 @@

    Functions

    - + @@ -201,16 +201,6 @@

    Functions

    -

    Tables

    -
    getOpt (argIn, options)getOpt (argIn, options, undefined_options) Perform argument processing
    processArgs (prog)processArgs (prog, undefined_opts) Simple getOpt wrapper.
    - - - - - - -
    OptionObject that defines a single Option entry.
    -
    @@ -224,7 +214,7 @@

    Functions

    -
    getOpt (argIn, options)
    +
    getOpt (argIn, options, undefined_options)
    Perform argument processing @@ -240,6 +230,10 @@

    Parameters

    options: options table +
  • + undefined_options: if true, allow and collect undefined options +
  • + @@ -291,7 +285,7 @@

    Parameters

    -
    processArgs (prog)
    +
    processArgs (prog, undefined_opts)
    Simple getOpt wrapper. If the caller didn't supply their own already, adds --version/-V and --help/-h options automatically; stops program if there was an error, or if --help or --version was used. @@ -303,6 +297,10 @@

    Parameters

    prog: table of named parameters +
  • + undefined_opts: if true, allow and collect undefined options +
  • + @@ -383,40 +381,6 @@

    Return value:

    -

    Tables

    -
    - -
    Option
    -
    Object that defines a single Option entry. - - -Fields -
      - -
    • - name: list of option names -
    • - -
    • - desc: description of this option -
    • - -
    • - type: type of option argument (if any): Req(uired), Opt(ional) -
    • - -
    • - var: descriptive name for the option argument -
    • - -
    - - -
    - - -
    - diff --git a/src/getopt.lua b/src/getopt.lua index 7d91706..2042f15 100644 --- a/src/getopt.lua +++ b/src/getopt.lua @@ -5,13 +5,16 @@ -- name = , -- [usage = ,] -- [options = { --- {Option {}, , [,] [var]}, +-- {{[, ...]}, , [ [, ]]}, -- ... -- },] -- [banner = ,] -- [purpose = ,] -- [notes = ] -- } +--
  • The type of option argument is one of Req(uired), +-- Opt(ional)
  • +--
  • The varis a descriptive name for the option argument.
  • --
  • getopt.processArgs (prog)
  • --
  • Options take a single dash, but may have a double dash.
  • --
  • Arguments may be given as -opt=arg or -opt arg.
  • @@ -41,10 +44,11 @@ local M = { --- Perform argument processing -- @param argIn list of command-line args -- @param options options table +-- @param undefined_options if true, allow and collect undefined options -- @return table of remaining non-options -- @return table of option key-value list pairs -- @return table of error messages -local function getOpt (argIn, options) +local function getOpt (argIn, options, undefined_options) local noProcess = nil local argOut, optOut, errors = {[0] = argIn[0]}, {}, {} -- get an argument for option opt @@ -70,7 +74,8 @@ local function getOpt (argIn, options) local function parseOpt (opt, arg) local o = options.name[opt] - if o ~= nil then + if undefined_options or o ~= nil then + o = o or {name = {opt}} optOut[o.name[1]] = optOut[o.name[1]] or {} table.insert (optOut[o.name[1]], getArg (o, opt, arg, optOut[o.name[1]])) else @@ -94,14 +99,7 @@ local function getOpt (argIn, options) end ---- Object that defines a single Option entry. --- @class table --- @name Option --- @field name list of option names --- @field desc description of this option --- @field type type of option argument (if any): Req(uired), --- Opt(ional) --- @field var descriptive name for the option argument +-- Object that defines a single Option entry. local Option = Object {_init = {"name", "desc", "type", "var"}} --- Options table constructor: adds lookup tables for the option names @@ -109,6 +107,7 @@ local function makeOptions (t) local options, name = {}, {} local function appendOpt (v, nodupes) local dupe = false + v = Option (v) for s in list.elems (v.name) do if name[s] then dupe = true @@ -125,9 +124,9 @@ local function makeOptions (t) appendOpt (v) end -- Unless they were supplied already, add version and help options - appendOpt (Option {{"version", "V"}, "print version information, then exit"}, + appendOpt ({{"version", "V"}, "print version information, then exit"}, true) - appendOpt (Option {{"help", "h"}, "print this help, then exit"}, true) + appendOpt ({{"help", "h"}, "print this help, then exit"}, true) options.name = name return options end @@ -141,7 +140,7 @@ end local function usageInfo (header, optDesc, pageWidth) pageWidth = pageWidth or 78 -- Format the usage info for a single option - -- @param opt the Option table + -- @param opt the option table -- @return options -- @return description local function fmtOpt (opt) @@ -243,11 +242,12 @@ end -- stops program if there was an error, or if --help or -- --version was used. -- @param prog table of named parameters -local function processArgs (prog) +-- @param undefined_opts if true, allow and collect undefined options +local function processArgs (prog, undefined_opts) local totArgs = #arg local errors prog.options = makeOptions (prog.options) - _G.arg, M.opt, errors = getopt.getOpt (arg, prog.options) + _G.arg, M.opt, errors = getOpt (arg, prog.options, undefined_opts) local opt = M.opt if (opt.version or opt.help) and prog.banner then io.writelines (prog.banner) @@ -276,7 +276,6 @@ end -- Public interface return table.merge (M, { getOpt = getOpt, - Option = Option, processArgs = processArgs, usage = usage, usageInfo = usageInfo, diff --git a/src/list.lua b/src/list.lua index 213cf3e..87cf336 100644 --- a/src/list.lua +++ b/src/list.lua @@ -1,7 +1,7 @@ --- Tables as lists. require "base" -require "table_ext" +local new -- forward declaration --- An iterator over the elements of a list. -- @param l list to iterate over @@ -67,7 +67,7 @@ end -- @param to end of range (default: #l) -- @return {l[from], ..., l[to]} local function sub (l, from, to) - local r = list.new () + local r = new () local len = #l from = from or 1 to = to or len @@ -133,7 +133,7 @@ end -- l1[#l1], ..., ln[1], ..., -- ln[#ln]} local function concat (...) - local r = list.new () + local r = new () for l in elems ({...}) do for v in elems (l) do table.insert (r, v) @@ -147,7 +147,7 @@ end -- @param n number of times to repeat -- @return n copies of l appended together local function rep (l, n) - local r = list.new () + local r = new () for i = 1, n do r = concat (r, l) end @@ -158,7 +158,7 @@ end -- @param l list -- @return list {l[#l], ..., l[1]} local function reverse (l) - local r = list.new () + local r = new () for i = #l, 1, -1 do table.insert (r, l[i]) end @@ -173,9 +173,9 @@ end -- @return {{l1,1, ..., lr,1}, ..., -- {l1,c, ..., lr,c}} local function transpose (ls) - local rs, len = list.new (), #ls + local rs, len = new (), #ls for i = 1, math.max (unpack (map (function (l) return #l end, ls))) do - rs[i] = list.new () + rs[i] = new () for j = 1, len do rs[i][j] = ls[j][i] end @@ -207,7 +207,7 @@ end -- @return list {{i1, v1}, ..., -- {in, vn}} local function enpair (t) - local ls = list.new () + local ls = new () for i, v in pairs (t) do table.insert (ls, {i, v}) end @@ -232,7 +232,7 @@ end -- @param l list to flatten -- @return flattened list local function flatten (l) - local r = list.new () + local r = new () for v in ileaves (l) do table.insert (r, v) end @@ -281,7 +281,7 @@ local function shape (s, l) if d > #s then return l[i], i + 1 else - local r = list.new () + local r = new () for j = 1, s[d] do local e e, i = fill (i, d + 1) @@ -300,7 +300,7 @@ end -- @return index {t1[f]=1, ..., -- tn[f]=n} local function indexKey (f, l) - local r = list.new () + local r = new () for i, v in ipairs (l) do local k = v[f] if k then @@ -317,7 +317,7 @@ end -- @return index {t1[f]=t1, ..., -- tn[f]=tn} local function indexValue (f, l) - local r = list.new () + local r = new () for i, v in ipairs (l) do local k = v[f] if k then @@ -393,7 +393,7 @@ local metatable = { -- Needed in order to use metamethods. -- @param t list (as a table), or nil for empty list -- @return list (with list metamethods) -local function new (l) +function new (l) return setmetatable (l or {}, metatable) end diff --git a/src/std.lua b/src/std.lua index 99efbe1..a9cad69 100644 --- a/src/std.lua +++ b/src/std.lua @@ -7,7 +7,7 @@ -- this also helps to check module dependencies. --
  • TODO: pre-compile.
  • -- -local version = "General Lua libraries / 33" +local version = "General Lua libraries / 34" for _, m in ipairs (require "modules") do _G[m] = require (m) diff --git a/src/string_ext.lua b/src/string_ext.lua index 1cc2331..8b7de39 100644 --- a/src/string_ext.lua +++ b/src/string_ext.lua @@ -2,7 +2,8 @@ -- TODO: Pretty printing (use in getopt); see source for details. require "table_ext" -require "strbuf" +local list = require "list" +local strbuf = require "strbuf" -- Write pretty-printing based on: -- diff --git a/stdlib-33-1.rockspec b/stdlib-34-1.rockspec similarity index 94% rename from stdlib-33-1.rockspec rename to stdlib-34-1.rockspec index 1e91314..8978100 100644 --- a/stdlib-33-1.rockspec +++ b/stdlib-34-1.rockspec @@ -1,25 +1,25 @@ -build = { - type = "command", - copy_directories = { - }, - build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - install_command = "make install", -} +version = "34-1" source = { - branch = "release-v33", + branch = "release-v34", url = "git://github.com/rrthomas/lua-stdlib.git", } -version = "33-1" package = "stdlib" dependencies = { "lua >= 5.1", } description = { + homepage = "http://github.com/rrthomas/lua-stdlib/", + license = "MIT/X11", summary = "General Lua libraries", detailed = " stdlib is a library of modules for common programming tasks,\ including list, table and functional operations, regexps, objects,\ pickling, pretty-printing and getopt.\ ", - license = "MIT/X11", - homepage = "http://github.com/rrthomas/lua-stdlib/", +} +build = { + build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + type = "command", + copy_directories = { + }, + install_command = "make install", } diff --git a/stdlib-git-1.rockspec b/stdlib-git-1.rockspec index cde167f..50d9b70 100644 --- a/stdlib-git-1.rockspec +++ b/stdlib-git-1.rockspec @@ -1,24 +1,24 @@ -package = "stdlib" -build = { - type = "command", - build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - install_command = "make install", - copy_directories = { - }, -} version = "git-1" source = { url = "git://github.com/rrthomas/lua-stdlib.git", } +package = "stdlib" +dependencies = { + "lua >= 5.1", +} description = { + homepage = "http://github.com/rrthomas/lua-stdlib/", + license = "MIT/X11", + summary = "General Lua libraries", detailed = " stdlib is a library of modules for common programming tasks,\ including list, table and functional operations, regexps, objects,\ pickling, pretty-printing and getopt.\ ", - homepage = "http://github.com/rrthomas/lua-stdlib/", - license = "MIT/X11", - summary = "General Lua libraries", } -dependencies = { - "lua >= 5.1", +build = { + build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", + type = "command", + copy_directories = { + }, + install_command = "make install", } From f311a9982add212cf0412c25c0eb18b7081528f7 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Fri, 29 Mar 2013 12:11:54 +0700 Subject: [PATCH 13/34] Release v34-2 --- GNUmakefile | 13 ++++++------ Makefile | 2 +- mkrockspecs.lua | 2 +- rockspecs.lua | 2 +- specs/getopt_spec.yaml | 10 ++++----- src/files/getopt.html | 12 +++++------ src/getopt.lua | 21 +++++++++++-------- stdlib-34-1.rockspec => stdlib-34-2.rockspec | 2 +- ...ib-git-1.rockspec => stdlib-git-2.rockspec | 2 +- stdlib.rockspec.in | 2 +- 10 files changed, 36 insertions(+), 32 deletions(-) rename stdlib-34-1.rockspec => stdlib-34-2.rockspec (97%) rename stdlib-git-1.rockspec => stdlib-git-2.rockspec (97%) diff --git a/GNUmakefile b/GNUmakefile index bcdc6e7..2198036 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -22,7 +22,8 @@ specl_verbose_1 = --verbose --formatter=report include Makefile -MKROCKSPECS = $(ROCKSPEC_ENV) $(LUA) $(srcdir)/mkrockspecs.lua +ROCKSPEC_ENV = $(LUA_ENV) +MKROCKSPECS = $(ROCKSPEC_ENV) $(LUA) $(srcdir)/mkrockspecs.lua ROCKSPEC_TEMPLATE = $(srcdir)/$(PACKAGE)-rockspec.lua luarocks-config.lua: @@ -41,7 +42,7 @@ GIT ?= git tag-release: $(GIT) diff --exit-code && \ - $(GIT) tag -f -a -m "Release tag" v$(VERSION) + $(GIT) tag -f -a -m "Release tag" v$(VERSION)-2 define unpack-distcheck-release rm -rf $(PACKAGE)-$(VERSION)/ && \ @@ -58,8 +59,8 @@ check-in-release: distcheck cd ../$(PACKAGE)-release && \ $(unpack-distcheck-release) && \ $(GIT) add . && \ - $(GIT) commit -a -m "Release v$(VERSION)" && \ - $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION) + $(GIT) commit -a -m "Release v$(VERSION)-2" && \ + $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION)-2 ## To test the release process without publishing upstream, use: @@ -67,7 +68,7 @@ check-in-release: distcheck GIT_PUBLISH ?= $(GIT) WOGER ?= woger -WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' +WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-2.rockspec' WOGER_OUT = $(WOGER_ENV) $(LUA) -l$(PACKAGE) -e release: rockspecs @@ -75,7 +76,7 @@ release: rockspecs $(MAKE) check-in-release && \ $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks \ - --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ + --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-2.rockspec && \ $(WOGER) lua \ package=$(PACKAGE) \ package_name=$(PACKAGE_NAME) \ diff --git a/Makefile b/Makefile index 71118e6..bc6d63d 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ AM_DEFAULT_VERBOSITY = 0 AUTOCONF = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing autoconf AUTOHEADER = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing autoheader AUTOMAKE = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing automake-1.13 -AWK = gawk +AWK = awk CYGPATH_W = echo DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"34\" -DPACKAGE_STRING=\"stdlib\ 34\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"34\" ECHO_C = \c diff --git a/mkrockspecs.lua b/mkrockspecs.lua index ee3e80b..b2a77ae 100644 --- a/mkrockspecs.lua +++ b/mkrockspecs.lua @@ -32,7 +32,7 @@ end for f, spec in pairs (loadfile ("rockspecs.lua") ()) do if f ~= "default" then - local specfile = package_name.."-"..(f ~= "" and f:lower ().."-" or "")..version.."-1.rockspec" + local specfile = package_name.."-"..(f ~= "" and f:lower ().."-" or "")..version.."-2.rockspec" h = io.open (specfile, "w") assert (h) flavour = f -- a global, visible in loadfile diff --git a/rockspecs.lua b/rockspecs.lua index 002dbf5..cfa3c8e 100644 --- a/rockspecs.lua +++ b/rockspecs.lua @@ -10,7 +10,7 @@ local version_dashed = version:gsub ("%.", "-") local default = { package = package_name, - version = version.."-1", + version = version.."-2", source = { url = "git://github.com/rrthomas/lua-stdlib.git", }, diff --git a/specs/getopt_spec.yaml b/specs/getopt_spec.yaml index 006d9cd..94bfe5c 100644 --- a/specs/getopt_spec.yaml +++ b/specs/getopt_spec.yaml @@ -12,8 +12,8 @@ specify getopt: } } - function test (cmdLine, undefined_opts) - local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options, undefined_opts) + function test (cmdLine, stop_at_nonopt) + local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options, stop_at_nonopt) if #errors == 0 then return { options = opts, args = nonOpts } else @@ -35,9 +35,9 @@ specify getopt: args = {} }) - it diagnoses unrecognized options: expect (test {"-foo"}).should_contain "unrecognized option `-foo'" - - it allows unrecognized options if told to: - expect (test ({"-foo"}, true)).should_equal ( - { options = { foo = {1}}, args = {} }) + - it stops option parsing at the first non-option if told to: + expect (test ({"foo", "-bar"}, true)).should_equal ( + { options = {}, args = {"foo", "-bar"} }) - "describe getopt.usageInfo": - context when specifying options: diff --git a/src/files/getopt.html b/src/files/getopt.html index fa614fa..707082b 100644 --- a/src/files/getopt.html +++ b/src/files/getopt.html @@ -172,7 +172,7 @@

    Functions

    - + @@ -182,7 +182,7 @@

    Functions

    - + @@ -214,7 +214,7 @@

    Functions

    -
    getOpt (argIn, options, undefined_options)
    +
    getOpt (argIn, options, stop_at_nonopt)
    Perform argument processing @@ -231,7 +231,7 @@

    Parameters

  • - undefined_options: if true, allow and collect undefined options + stop_at_nonopt: if true, stop option processing at first non-option
  • @@ -285,7 +285,7 @@

    Parameters

    -
    processArgs (prog, undefined_opts)
    +
    processArgs (prog, ...)
    Simple getOpt wrapper. If the caller didn't supply their own already, adds --version/-V and --help/-h options automatically; stops program if there was an error, or if --help or --version was used. @@ -298,7 +298,7 @@

    Parameters

  • - undefined_opts: if true, allow and collect undefined options + ...: extra arguments for getOpt
  • diff --git a/src/getopt.lua b/src/getopt.lua index 2042f15..d67c8a2 100644 --- a/src/getopt.lua +++ b/src/getopt.lua @@ -44,11 +44,11 @@ local M = { --- Perform argument processing -- @param argIn list of command-line args -- @param options options table --- @param undefined_options if true, allow and collect undefined options +-- @param stop_at_nonopt if true, stop option processing at first non-option -- @return table of remaining non-options -- @return table of option key-value list pairs -- @return table of error messages -local function getOpt (argIn, options, undefined_options) +local function getOpt (argIn, options, stop_at_nonopt) local noProcess = nil local argOut, optOut, errors = {[0] = argIn[0]}, {}, {} -- get an argument for option opt @@ -74,7 +74,7 @@ local function getOpt (argIn, options, undefined_options) local function parseOpt (opt, arg) local o = options.name[opt] - if undefined_options or o ~= nil then + if o ~= nil then o = o or {name = {opt}} optOut[o.name[1]] = optOut[o.name[1]] or {} table.insert (optOut[o.name[1]], getArg (o, opt, arg, optOut[o.name[1]])) @@ -87,9 +87,12 @@ local function getOpt (argIn, options, undefined_options) table.remove (argIn, 1) local _, _, dash, opt = string.find (v, "^(%-%-?)([^=-][^=]*)") local _, _, arg = string.find (v, "=(.*)$") + if not dash and stop_at_nonopt then + noProcess = true + end if v == "--" then - noProcess = 1 - elseif dash == nil or noProcess then -- non-option + noProcess = true + elseif not dash or noProcess then -- non-option table.insert (argOut, v) else -- option parseOpt (opt, arg) @@ -242,12 +245,12 @@ end -- stops program if there was an error, or if --help or -- --version was used. -- @param prog table of named parameters --- @param undefined_opts if true, allow and collect undefined options -local function processArgs (prog, undefined_opts) - local totArgs = #arg +-- @param ... extra arguments for getOpt +local function processArgs (prog, ...) + local totArgs = #_G.arg local errors prog.options = makeOptions (prog.options) - _G.arg, M.opt, errors = getOpt (arg, prog.options, undefined_opts) + _G.arg, M.opt, errors = getOpt (_G.arg, prog.options, ...) local opt = M.opt if (opt.version or opt.help) and prog.banner then io.writelines (prog.banner) diff --git a/stdlib-34-1.rockspec b/stdlib-34-2.rockspec similarity index 97% rename from stdlib-34-1.rockspec rename to stdlib-34-2.rockspec index 8978100..842cf9e 100644 --- a/stdlib-34-1.rockspec +++ b/stdlib-34-2.rockspec @@ -1,4 +1,4 @@ -version = "34-1" +version = "34-2" source = { branch = "release-v34", url = "git://github.com/rrthomas/lua-stdlib.git", diff --git a/stdlib-git-1.rockspec b/stdlib-git-2.rockspec similarity index 97% rename from stdlib-git-1.rockspec rename to stdlib-git-2.rockspec index 50d9b70..130a74d 100644 --- a/stdlib-git-1.rockspec +++ b/stdlib-git-2.rockspec @@ -1,4 +1,4 @@ -version = "git-1" +version = "git-2" source = { url = "git://github.com/rrthomas/lua-stdlib.git", } diff --git a/stdlib.rockspec.in b/stdlib.rockspec.in index bc69d01..e08c434 100644 --- a/stdlib.rockspec.in +++ b/stdlib.rockspec.in @@ -1,5 +1,5 @@ package="stdlib" -version="@VERSION@-1" +version="@VERSION@-2" source = { url = "git://github.com/rrthomas/lua-stdlib.git", branch = "release-v@VERSION@", From bf5d6ec5d87a1cd6317a9904d6f364f02a5fca32 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Mon, 1 Apr 2013 15:09:26 +0700 Subject: [PATCH 14/34] Release v34.1 --- GNUmakefile | 10 +++++----- Makefile | 8 ++++---- configure | 20 +++++++++---------- configure.ac | 2 +- src/std.lua | 2 +- ...ib-git-2.rockspec => stdilb-git-1.rockspec | 0 ...ib-34-2.rockspec => stdlib-34.1-1.rockspec | 4 ++-- 7 files changed, 23 insertions(+), 23 deletions(-) rename stdlib-git-2.rockspec => stdilb-git-1.rockspec (100%) rename stdlib-34-2.rockspec => stdlib-34.1-1.rockspec (93%) diff --git a/GNUmakefile b/GNUmakefile index 2198036..25122be 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -42,7 +42,7 @@ GIT ?= git tag-release: $(GIT) diff --exit-code && \ - $(GIT) tag -f -a -m "Release tag" v$(VERSION)-2 + $(GIT) tag -f -a -m "Release tag" v$(VERSION) define unpack-distcheck-release rm -rf $(PACKAGE)-$(VERSION)/ && \ @@ -59,8 +59,8 @@ check-in-release: distcheck cd ../$(PACKAGE)-release && \ $(unpack-distcheck-release) && \ $(GIT) add . && \ - $(GIT) commit -a -m "Release v$(VERSION)-2" && \ - $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION)-2 + $(GIT) commit -a -m "Release v$(VERSION)" && \ + $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION) ## To test the release process without publishing upstream, use: @@ -68,7 +68,7 @@ check-in-release: distcheck GIT_PUBLISH ?= $(GIT) WOGER ?= woger -WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-2.rockspec' +WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' WOGER_OUT = $(WOGER_ENV) $(LUA) -l$(PACKAGE) -e release: rockspecs @@ -76,7 +76,7 @@ release: rockspecs $(MAKE) check-in-release && \ $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks \ - --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-2.rockspec && \ + --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ $(WOGER) lua \ package=$(PACKAGE) \ package_name=$(PACKAGE_NAME) \ diff --git a/Makefile b/Makefile index bc6d63d..59f4b80 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ AUTOHEADER = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing autohead AUTOMAKE = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing automake-1.13 AWK = awk CYGPATH_W = echo -DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"34\" -DPACKAGE_STRING=\"stdlib\ 34\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"34\" +DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"34.1\" -DPACKAGE_STRING=\"stdlib\ 34.1\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"34.1\" ECHO_C = \c ECHO_N = ECHO_T = @@ -187,15 +187,15 @@ MKDIR_P = build-aux/install-sh -c -d PACKAGE = stdlib PACKAGE_BUGREPORT = rrt@sc3d.org PACKAGE_NAME = stdlib -PACKAGE_STRING = stdlib 34 +PACKAGE_STRING = stdlib 34.1 PACKAGE_TARNAME = stdlib PACKAGE_URL = -PACKAGE_VERSION = 34 +PACKAGE_VERSION = 34.1 PATH_SEPARATOR = : SET_MAKE = SHELL = /bin/sh STRIP = -VERSION = 34 +VERSION = 34.1 abs_builddir = /Users/gary/Devo/stdlib-release abs_srcdir = /Users/gary/Devo/stdlib-release abs_top_builddir = /Users/gary/Devo/stdlib-release diff --git a/configure b/configure index 9874456..3733e23 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 34. +# Generated by GNU Autoconf 2.69 for stdlib 34.1. # # Report bugs to . # @@ -578,8 +578,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='34' -PACKAGE_STRING='stdlib 34' +PACKAGE_VERSION='34.1' +PACKAGE_STRING='stdlib 34.1' PACKAGE_BUGREPORT='rrt@sc3d.org' PACKAGE_URL='' @@ -1213,7 +1213,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 34 to adapt to many kinds of systems. +\`configure' configures stdlib 34.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1279,7 +1279,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 34:";; + short | recursive ) echo "Configuration of stdlib 34.1:";; esac cat <<\_ACEOF @@ -1365,7 +1365,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 34 +stdlib configure 34.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1382,7 +1382,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 34, which was +It was created by stdlib $as_me 34.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2245,7 +2245,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='34' + VERSION='34.1' cat >>confdefs.h <<_ACEOF @@ -3424,7 +3424,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 34, which was +This file was extended by stdlib $as_me 34.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3477,7 +3477,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 34 +stdlib config.status 34.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 966b5d6..86de659 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake -AC_INIT(stdlib, 34, rrt@sc3d.org) +AC_INIT(stdlib, 34.1, rrt@sc3d.org) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) AM_SILENT_RULES([yes]) diff --git a/src/std.lua b/src/std.lua index a9cad69..a6822ab 100644 --- a/src/std.lua +++ b/src/std.lua @@ -7,7 +7,7 @@ -- this also helps to check module dependencies. --
  • TODO: pre-compile.
  • -- -local version = "General Lua libraries / 34" +local version = "General Lua libraries / 34.1" for _, m in ipairs (require "modules") do _G[m] = require (m) diff --git a/stdlib-git-2.rockspec b/stdilb-git-1.rockspec similarity index 100% rename from stdlib-git-2.rockspec rename to stdilb-git-1.rockspec diff --git a/stdlib-34-2.rockspec b/stdlib-34.1-1.rockspec similarity index 93% rename from stdlib-34-2.rockspec rename to stdlib-34.1-1.rockspec index 842cf9e..28e3ffa 100644 --- a/stdlib-34-2.rockspec +++ b/stdlib-34.1-1.rockspec @@ -1,6 +1,6 @@ -version = "34-2" +version = "34.1-1" source = { - branch = "release-v34", + branch = "release-v34.1", url = "git://github.com/rrthomas/lua-stdlib.git", } package = "stdlib" From 6f9107878c0028188648d095025fbbf970b42dbb Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Sun, 7 Apr 2013 12:42:46 +0700 Subject: [PATCH 15/34] maint: support Travis CI builds from release branch. * .travis.yml: New file. Copied from master. --- .travis.yml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a506e15 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,46 @@ +# Lua is not officially supported, but an erlang environment will do. +language: erlang + +env: + matrix: + - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 + - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 + - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 + global: + - LUAROCKS_CONFIG=luarocks-config.lua + - LUAROCKS_BASE=luarocks-2.0.12 + - LUAROCKS="$LUA $HOME/bin/luarocks" + +# Tool setup. +install: + # Temporarily for specl-v4, which spuriously regenerates specl.1.in :( + - sudo apt-get install help2man + - sudo apt-get install luajit + - sudo apt-get install libluajit-5.1-dev + - sudo apt-get install lua5.1 + - sudo apt-get install liblua5.1-dev + - sudo apt-get install lua5.2 + - sudo apt-get install liblua5.2-dev + # Temporarily for luadoc, which only works with Lua 5.1 :( + - sudo apt-get install luarocks + - sudo luarocks install luadoc + # Temporarily until Travis VMs make a Lua 5.2 compatible Luarocks available :( + - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz + - tar zxvpf $LUAROCKS_BASE.tar.gz + - cd $LUAROCKS_BASE + - ./configure --prefix=$HOME --lua-version=5.1 --lua-suffix=5.1 --with-lua-include="/usr/include/lua5.1" + - make all install + - cd .. + +# Configure, build and test. +script: + - autoreconf --force --verbose --install + - ./configure LUA="$LUA" + # Temporarily use Lua 5.1 with system luarocks until luadoc works with Lua 5.2 :( + - sed 's|^exec "[^"]*"|exec lua5.1|' `which luadoc` > luadoc + - make LUA=lua5.1 LUADOC="$SHELL `pwd`/luadoc" all V=1 + - make LUA_INCDIR="$LUA_INCDIR" "$LUAROCKS_CONFIG" std/std.lua V=1 + - eval `$LUAROCKS path`; $LUAROCKS install specl + - make rockspecs V=1 + - $LUAROCKS make stdlib-git-1.rockspec + - eval `$LUAROCKS path`; make SPECL=luarocks/bin/specl check V=1 From 468d845e8513e247bba45b23a6bb54f3621c0ec7 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Mon, 6 May 2013 08:31:52 +0700 Subject: [PATCH 16/34] Release v35. Signed-off-by: Gary V. Vaughan --- .autom4te.cfg | 4 + .gitignore | 8 - .travis.yml | 54 +- ChangeLog | 2594 +++++++++++++++ GNUmakefile | 94 +- INSTALL | 1 - Makefile | 789 ----- Makefile.am | 139 +- Makefile.in | 562 ++-- NEWS | 398 +++ README | 51 - README.md | 72 + aclocal.m4 | 2 +- bootstrap | 4764 +++++++++++++++++++++++++++ bootstrap.conf | 100 + bootstrap.slingshot | 277 ++ build-aux/gitlog-to-changelog | 432 +++ build-aux/mkrockspecs | 274 ++ build-aux/release.mk | 377 +++ build-aux/rockspecs.mk | 112 + build-aux/sanity.mk | 1112 +++++++ build-aux/specl.mk | 56 + configure | 368 ++- configure.ac | 23 +- local.mk | 30 + lua-stdlib-35-1.rockspec | 22 + luarocks-config.lua.in | 3 - m4/ax_with_prog.m4 | 70 - m4/slingshot.m4 | 51 + mkrockspecs.lua | 49 - rockspec.conf | 16 + rockspecs.lua | 44 - slingshot | 1 + specs/debug_ext_spec.yaml | 69 + specs/getopt_spec.lua | 83 - specs/getopt_spec.yaml | 2 +- specs/io_ext_spec.yaml | 88 + specs/lib/specl.lua | 348 -- specs/math_ext_spec.yaml | 64 + specs/package_ext_spec.lua | 34 - specs/package_ext_spec.yaml | 84 +- specs/specl | 85 - specs/specs.mk | 25 + specs/string_ext_spec.lua | 522 --- specs/string_ext_spec.yaml | 349 +- specs/table_ext_spec.lua | 326 -- specs/table_ext_spec.yaml | 167 +- src/base.lua | 537 --- src/bin.lua | 26 - src/debug_init.lua | 2 - src/files/bin.html | 270 -- src/files/fstable.html | 246 -- src/files/lcs.html | 250 -- src/files/mbox.html | 242 -- src/files/parser.html | 284 -- src/files/std.html | 198 -- src/files/xml.html | 247 -- src/fstable.lua | 123 - src/lcs.lua | 61 - src/mbox.lua | 59 - src/modules.lua | 16 - src/modules/bin.html | 328 -- src/modules/debug.html | 343 -- src/modules/fstable.html | 304 -- src/modules/getopt.html | 473 --- src/modules/io.html | 476 --- src/modules/lcs.html | 308 -- src/modules/list.html | 1212 ------- src/modules/math.html | 282 -- src/modules/mbox.html | 300 -- src/modules/object.html | 292 -- src/modules/package.html | 256 -- src/modules/parser.html | 342 -- src/modules/set.html | 640 ---- src/modules/std.html | 256 -- src/modules/strbuf.html | 338 -- src/modules/string.html | 717 ---- src/modules/table.html | 578 ---- src/modules/tree.html | 415 --- src/parser.lua | 267 -- src/std.lua | 20 - src/std.lua.in | 20 - src/xml.lua | 75 - std/base.lua | 291 ++ {src => std}/debug_ext.lua | 59 +- std/debug_init.lua | 10 + {src => std}/files/base.html | 600 ---- {src => std}/files/debug_ext.html | 42 - {src => std}/files/debug_init.html | 40 - {src => std}/files/getopt.html | 40 - {src => std}/files/io_ext.html | 46 +- {src => std}/files/list.html | 120 +- {src => std}/files/math_ext.html | 42 - {src => std}/files/modules.html | 40 - {src => std}/files/object.html | 40 - {src => std}/files/package_ext.html | 40 - {src => std}/files/set.html | 40 - {src => std}/files/strbuf.html | 40 - {src => std}/files/strict.html | 40 - {src => std}/files/string_ext.html | 478 ++- {src => std}/files/table_ext.html | 40 - {src => std}/files/tree.html | 40 - {src => std}/getopt.lua | 10 +- {src => std}/index.html | 90 - {src => std}/io_ext.lua | 56 +- {src => std}/list.lua | 36 +- {src => std}/luadoc.css | 0 {src => std}/math_ext.lua | 23 +- std/modules.lua | 16 + {src => std}/modules/base.html | 600 ---- {src => std}/object.lua | 2 +- {src => std}/package_ext.lua | 13 +- {src => std}/set.lua | 2 +- std/std.lua | 48 + std/std.lua.in | 48 + std/std.mk | 62 + {src => std}/strbuf.lua | 0 {src => std}/strict.lua | 0 {src => std}/string_ext.lua | 400 ++- {src => std}/table_ext.lua | 16 +- {src => std}/tree.lua | 10 +- stdilb-git-1.rockspec | 24 - stdlib-34.1-1.rockspec | 25 - stdlib.rockspec.in | 25 - template.lua | 33 - travis.yml.in | 60 + 126 files changed, 13621 insertions(+), 16064 deletions(-) create mode 100644 .autom4te.cfg delete mode 100644 .gitignore create mode 100644 ChangeLog delete mode 100644 Makefile create mode 100644 NEWS delete mode 100644 README create mode 100644 README.md create mode 100755 bootstrap create mode 100644 bootstrap.conf create mode 100644 bootstrap.slingshot create mode 100755 build-aux/gitlog-to-changelog create mode 100755 build-aux/mkrockspecs create mode 100644 build-aux/release.mk create mode 100644 build-aux/rockspecs.mk create mode 100644 build-aux/sanity.mk create mode 100644 build-aux/specl.mk create mode 100644 local.mk create mode 100644 lua-stdlib-35-1.rockspec delete mode 100644 luarocks-config.lua.in delete mode 100644 m4/ax_with_prog.m4 create mode 100644 m4/slingshot.m4 delete mode 100644 mkrockspecs.lua create mode 100644 rockspec.conf delete mode 100644 rockspecs.lua create mode 160000 slingshot create mode 100644 specs/debug_ext_spec.yaml delete mode 100644 specs/getopt_spec.lua create mode 100644 specs/io_ext_spec.yaml delete mode 100644 specs/lib/specl.lua create mode 100644 specs/math_ext_spec.yaml delete mode 100644 specs/package_ext_spec.lua delete mode 100755 specs/specl create mode 100644 specs/specs.mk delete mode 100644 specs/string_ext_spec.lua delete mode 100644 specs/table_ext_spec.lua delete mode 100644 src/base.lua delete mode 100644 src/bin.lua delete mode 100644 src/debug_init.lua delete mode 100644 src/files/bin.html delete mode 100644 src/files/fstable.html delete mode 100644 src/files/lcs.html delete mode 100644 src/files/mbox.html delete mode 100644 src/files/parser.html delete mode 100644 src/files/std.html delete mode 100644 src/files/xml.html delete mode 100644 src/fstable.lua delete mode 100644 src/lcs.lua delete mode 100644 src/mbox.lua delete mode 100644 src/modules.lua delete mode 100644 src/modules/bin.html delete mode 100644 src/modules/debug.html delete mode 100644 src/modules/fstable.html delete mode 100644 src/modules/getopt.html delete mode 100644 src/modules/io.html delete mode 100644 src/modules/lcs.html delete mode 100644 src/modules/list.html delete mode 100644 src/modules/math.html delete mode 100644 src/modules/mbox.html delete mode 100644 src/modules/object.html delete mode 100644 src/modules/package.html delete mode 100644 src/modules/parser.html delete mode 100644 src/modules/set.html delete mode 100644 src/modules/std.html delete mode 100644 src/modules/strbuf.html delete mode 100644 src/modules/string.html delete mode 100644 src/modules/table.html delete mode 100644 src/modules/tree.html delete mode 100644 src/parser.lua delete mode 100644 src/std.lua delete mode 100644 src/std.lua.in delete mode 100644 src/xml.lua create mode 100644 std/base.lua rename {src => std}/debug_ext.lua (71%) create mode 100644 std/debug_init.lua rename {src => std}/files/base.html (58%) rename {src => std}/files/debug_ext.html (87%) rename {src => std}/files/debug_init.html (79%) rename {src => std}/files/getopt.html (89%) rename {src => std}/files/io_ext.html (88%) rename {src => std}/files/list.html (94%) rename {src => std}/files/math_ext.html (84%) rename {src => std}/files/modules.html (79%) rename {src => std}/files/object.html (82%) rename {src => std}/files/package_ext.html (84%) rename {src => std}/files/set.html (92%) rename {src => std}/files/strbuf.html (84%) rename {src => std}/files/strict.html (79%) rename {src => std}/files/string_ext.html (60%) rename {src => std}/files/table_ext.html (91%) rename {src => std}/files/tree.html (89%) rename {src => std}/getopt.lua (97%) rename {src => std}/index.html (71%) rename {src => std}/io_ext.lua (75%) rename {src => std}/list.lua (93%) rename {src => std}/luadoc.css (100%) rename {src => std}/math_ext.lua (71%) create mode 100644 std/modules.lua rename {src => std}/modules/base.html (58%) rename {src => std}/object.lua (98%) rename {src => std}/package_ext.lua (73%) rename {src => std}/set.lua (99%) create mode 100644 std/std.lua create mode 100644 std/std.lua.in create mode 100644 std/std.mk rename {src => std}/strbuf.lua (100%) rename {src => std}/strict.lua (100%) rename {src => std}/string_ext.lua (56%) rename {src => std}/table_ext.lua (92%) rename {src => std}/tree.lua (94%) delete mode 100644 stdilb-git-1.rockspec delete mode 100644 stdlib-34.1-1.rockspec delete mode 100644 stdlib.rockspec.in delete mode 100644 template.lua create mode 100644 travis.yml.in diff --git a/.autom4te.cfg b/.autom4te.cfg new file mode 100644 index 0000000..f47eaee --- /dev/null +++ b/.autom4te.cfg @@ -0,0 +1,4 @@ +# Disable the autom4te.cache directory. +begin-language: "Autoconf-without-aclocal-m4" +args: --no-cache +end-language: "Autoconf-without-aclocal-m4" diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0be030c..0000000 --- a/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/autom4te.cache -/config.log -/config.status -/luarocks -/luarocks-config.lua -/release-notes-* -/stdlib-*.tar.gz -/stdlib-*/ diff --git a/.travis.yml b/.travis.yml index a506e15..8103f11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,18 +2,21 @@ language: erlang env: + global: + - PACKAGE=lua-stdlib + - ROCKSPEC=$PACKAGE-git-1.rockspec + - LUAROCKS_CONFIG=build-aux/luarocks-config.lua + - LUAROCKS_BASE=luarocks-2.0.13 + - LUAROCKS="$LUA $HOME/bin/luarocks" + - LUADOC=luarocks/bin/luadoc + - SPECL=bin/specl matrix: - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 - global: - - LUAROCKS_CONFIG=luarocks-config.lua - - LUAROCKS_BASE=luarocks-2.0.12 - - LUAROCKS="$LUA $HOME/bin/luarocks" # Tool setup. install: - # Temporarily for specl-v4, which spuriously regenerates specl.1.in :( - sudo apt-get install help2man - sudo apt-get install luajit - sudo apt-get install libluajit-5.1-dev @@ -21,26 +24,37 @@ install: - sudo apt-get install liblua5.1-dev - sudo apt-get install lua5.2 - sudo apt-get install liblua5.2-dev - # Temporarily for luadoc, which only works with Lua 5.1 :( - - sudo apt-get install luarocks - - sudo luarocks install luadoc - # Temporarily until Travis VMs make a Lua 5.2 compatible Luarocks available :( + # Install a recent luarocks release locally. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz - cd $LUAROCKS_BASE - - ./configure --prefix=$HOME --lua-version=5.1 --lua-suffix=5.1 --with-lua-include="/usr/include/lua5.1" + - ./configure + --prefix=$HOME --lua-version=5.1 --lua-suffix=5.1 + --with-lua-include="/usr/include/lua5.1" - make all install - cd .. + # Luadoc has to be installed separately while it is Lua 5.1 only. + - sudo apt-get install luarocks + - sudo luarocks install luadoc + - mkdir -p luarocks/bin + - sed 's|^exec "[^"]*"|exec lua5.1|' `which luadoc` > $LUADOC + - chmod a+rx $LUADOC -# Configure, build and test. +# Configure and build. script: - - autoreconf --force --verbose --install + - ./bootstrap - ./configure LUA="$LUA" - # Temporarily use Lua 5.1 with system luarocks until luadoc works with Lua 5.2 :( - - sed 's|^exec "[^"]*"|exec lua5.1|' `which luadoc` > luadoc - - make LUA=lua5.1 LUADOC="$SHELL `pwd`/luadoc" all V=1 - - make LUA_INCDIR="$LUA_INCDIR" "$LUAROCKS_CONFIG" std/std.lua V=1 - - eval `$LUAROCKS path`; $LUAROCKS install specl - - make rockspecs V=1 - - $LUAROCKS make stdlib-git-1.rockspec - - eval `$LUAROCKS path`; make SPECL=luarocks/bin/specl check V=1 + - make $LUAROCKS_CONFIG + LUA="$LUA" LUA_INCDIR="$LUA_INCDIR" V=1 + || cat $LUAROCKS_CONFIG config.log + # Set Lua and Shell paths up for local luarocks tree. + - eval `$LUAROCKS path` + - export PATH=`pwd`/luarocks/bin:$PATH + - $LUAROCKS install lyaml; $LUAROCKS install specl; + - make rockspecs LUAROCKS="$LUAROCKS" V=1 + || { $LUAROCKS path; cat $ROCKSPEC; } + # LuaRocks make will fail if dependencies are missing. + - $LUAROCKS make $ROCKSPEC + # Use bin/specl if we built it, or else the specl rock we just installed. + - test -f "$SPECL" || SPECL=luarocks/bin/specl; + make check SPECL="$SPECL" V=1 diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..43bcae0 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,2594 @@ +2013-05-06 Gary V. Vaughan + + Release version 35 + * NEWS: Record release date. + + slingshot: sync with upstream. + * .gitmodules: Remove. Slingshot regenerates on demand. + * .gitignore: Ignore .gitmodules. + * slingshot: Update. + * bootstrap.slingshot: Copied from slingshot, for clean checkout + bootstrapping before slingshot subproject is populated. + * bootstrap.conf: Adjust. + + maint: collect previous release notes into NEWS. + * NEWS: new file, required for the Slingshot release process. + * local.mk (old_NEWS_hash): Update. + + formatting: fix whitespace errors flagged by slingshot syntax-check. + * INSTALL, specs/debug_ext_spec.yaml: Remove trailing blank lines. + * specs/io_ext_spec.yaml, specs/match_ext_spec.yaml, + specs/table_ext_spec.yaml: Remove trailing spaces. + * std/std.mk: Remove SPACE-TAB sequence. + + configury: adopt slingshot release mechanism. + * GNUmakefile, Makefile.am, build-aux/mkrockspecs, + m4/ax_compare_version.m4, m4/ax_lua.m4, m4/ax_with_prog.m4: + Remove. These files are handled by slingshot now. + * bootstrap: New file. Copied from slingshot subproject. + * bootstrap.conf (stdlib_copy_slingshot): Install missing slingshot + files. + * configure.ac: Adjust to drive slingshot processes. + * local.mk: New file. Project local make rules. + * rockspec.conf: New file. Slingshot rockspec template. + * specs/specs.mk: Simplified. + * .gitignore: Update. + * .travis.yml: Regenerate. + +2013-05-05 Gary V. Vaughan + + slingshot: add slingshot as a git submodule. + * .gitmodules: New file. + * slingshot: New submodule. + +2013-04-30 Gary V. Vaughan + + configury: there is no distinct top_srcdir with non-recursive make. + * std/std.mk (dist_doc_DATA, dist_files_DATA, dist_modules_DATA): + Use plain $(srcdir). + + std: don't overwrite lua library tables. + Overwriting a global library table causes hard-to-debug problems + when the C part of Lua is holding references to the original + (overwritten) table. + * std/std.lua.in: When injecting new entry points into a core + library, do it an entry at a time to avoid breaking references to + the original address in the core. This fixes a problem with the + `package.path` and `package.cpath` being lost when set from + LUA_INIT, among many other potential issues. + +2013-04-14 Reuben Thomas + + Remove non-core modules, which go into separate lua-rrtlib for ad-hoc modules + +2013-04-11 Gary V. Vaughan + + specs: upgrade to Specl 5. + * specs/string_ext_spec.yaml, specs/table_ext_spec.yaml: Update + all 'should_error' matchers to saner Specl 5 ordering. + * specs/specs.mk (SPECL_MIN): Bump to 5. + + getopt: also requires io_ext module to be loaded. + * std/getopt.lua: Load io_ext into a local table. + +2013-04-10 Gary V. Vaughan + + configury: install correctly with configure or luarocks. + For the classic './configure; make; make install' to work we need + to install to '$luadir' as discovered by ax_lua.m4. But we also + need to install directly to luarocks '$(LUADIR)' otherwise the + stdlib source files are not copied onto the LUA_PATH properly by + 'luarocks make stdlib-*-1.rockspec'. + * mkrockspecs.lua: Move from here... + * build-aux/mkrockspecs: ...to here. + * GNUmakefile (rockspecs): Adjust accordingly. + * build-aux/mkrockspecs: Synchronise with the version that loads + a template, interpolates the variables and writes out the result. + * rockspecs.lua (build.install_command): Pass luadir to ensure + installation to the correct directory for luarocks. + * stdlib.rockspec.in: Remove. + * bootstrap: New script to call autoreconf for compatibility with + new build-aux/mkrockspecs. + * GNUmakefile (Makefile.in): Use it. + +2013-04-08 Gary V. Vaughan + + docs: point to github pages documentation. + * README.md (Documentation): Point to github pages documentation. + + docs: fix stupid typo. + * README.md (Installation): That would be luarOCKS not luarCOKS :-$ + + maint: correct git master installation instructions. + * README.md (Installation): Provide working instructions for + installing git master with Luarocks. + Liberal use of additional useful links. + +2013-04-08 Reuben Thomas + + README.md: simplify installation instructions, and other minor tweaks + +2013-04-07 Gary V. Vaughan + + maint: remove spurious LUA override in Travis CI build. + * .travis.yml (script): No need to force Lua 5.1 when running + initial make now that we fixed up luadocs. + + docs: we need to autoreconf a master branch github checkout. + * README.md (Installation): Show missing autoreconf invocation. + +2013-04-07 Gary V. Vaughan + + Revert "maint: support rerunning check-local in multiple lua environments." + This reverts commit e052c045cfc5b837e2dcb36db2e1cd34791a3c69. + + Conflicts: + Makefile.am + +2013-04-07 Gary V. Vaughan + + docs: rename README to README.md for github display goodness. + * README: Move from here... + * README.md: ...to here. + * Makefile.am (EXTRA_DIST): Add README.md. + + maint: tweak luadoc wrapper to work with Travis CI. + * .travis.yml (script): luadoc is a shell wrapper that calls the + wrong lua, so make a copy, patch it to call a compatible lua binary, + and run that instead. + + maint: run luadoc in a Lua 5.1 environment for Travis CI. + * .travis.yml (script): luadoc only works with Lua 5.1, so set the + execution environment up carefully for it to run correctly. + + maint: make luadoc available to Travis CI. + * .travis.yml (install): Install a system luarocks, and a luadoc + binary that uses it. + + maint: don't forget to make std/std.lua for Travis CI. + * .travis.yml (script): Run a full make to ensure std.lua is + generated in time for running mkrockspecs.lua! + + configury: don't hardcode specl, use $(SPECL) everywhere. + * specs/specs.mk (specs-check-local): Use $(SPECL), because bare + specl may not be on PATH, or otherwise correctly enabled. + * .travis.yml (script): Always call make with V=1 for better + logging. + + maint: install help2man for Travis CI specl build. + * .travis.yml (script): specl-v4 build currently fails when trying + to regenerate specl.1.in, so install help2man until that bug is + fixed. + + maint: set LUA_PATH for specl build with Travis CI. + * .travis.yml (script): Make sure local specl install can find + ansicolors and lyaml in local luarocks tree. + + maint: remove unnecessary manual ansicolors installation for Travis CI. + * .travis.yml: The previous error was caused by a bug in specl + release 3, not a lack of ansicolors. Remove the bogus ansicolors + installation now that specl-v4 is released. + + maint: make sure ansicolors is installed for Travis CI. + * .travis.yml (script): Install ansicolors to local luarocks tree. + + maint: make sure specl is installed for Travis CI. + * .travis.yml (script): Install specl, and use it for make check. + + configury: respect `make V=0` in rockspecs rule. + * GNUmakefile (rockspecs): Be quieter by default. + + std: strip leading "std." from global namespaces. + * std/std.lua.in: Before injecting symbols into the global + namespace, strip off the leading "std." added by std.modules.lua. + + configury: use uninstalled stdlib again. Again. (issue #24) + * specs/specs.mk (std_path): Move from here... + * Makefile.am (std_path): ...to here. + (LUA_ENV): Make sure to set this so that mkrockspecs rule uses + uninstalled stdlib again. + * specs/specs.mk (SPECL_ENV): Simplify accordingly. + + configury: fix a typo in luarocks-config.lua generation. + * GNUmakefile (luarocks-config.lua): Only one e in 'echo'. + + maint: integration with Travis CI system. + * .travis.yml: configure, build and test with each of Lua 5.1, + Lua 5.2 and luajit. + * GNUmakefile (luarocks-config.lua): Set interpreter environment + variables for luarocks invocations. + * mkrockspecs.lua: Invoke luarocks via user LUAROCKS setting. + * stdlib.rockspec.in (build.build_command): Pass LUA as a + configure precious variable so that recent ax-lua.m4 uses it as + passed instead of running the hardcoded search for a lua binary. + * README: Add travis build status badge markup. Plus some + indentation corrections for correct markdown code rendering. + +2013-04-02 Gary V. Vaughan + + docs: improved installation instructions. + * README: improve installation instructions. + +2013-04-01 Gary V. Vaughan + + maint: The Grand Renaming™ - use `require "std.list"` etc. + * Makefile.am (SPEC_ENV, SPECL, SPECL_MIN, SPECS, MULTICHECK) + (check-local, src_spec): Split out from here... + * specs/specs.mk (SPECL_ENV, SPECL, SPECL_MIN, specl_SPECS) + (MULTICHECK, specs-check-local, std_path): New file. ...to here. + * Makefile.am (SOURCES, dist_data_DATA, dist_doc_DATA) + (dist_files_DATA, dist_modules_DATA): Split out from here... + * std/std.mk (nobase_dist_lua_DATA, dist_lua_DATA, std/std.lua) + (dist_doc_DATA, dist_files_DATA, dist_modules_DATA): New file. + ...to here. + * specs/debug_ext_spec.yaml, specs/getopt_spec.yaml, + specs/io_ext_spec.yaml, specs/math_ext_spec.yaml, + specs/package_ext_spec.yaml, specs/string_ext_spec.yaml, + specs/table_ext_spec.yaml: Adjust require calls. + * src/base.lua, src/bin.lua, src/debug_ext.lua, src/debug_init.lua, + src/fstable.lua, src/getopt.lua, src/io_ext.lua, src/lcs.lua, + src/list.lua, src/math_ext.lua, src/mbox.lua, src/modules.lua, + src/object.lua, src/package_ext.lua, src/parser.lua, src/set.lua, + src/std.lua.in, src/strbuf.lua, src/strict.lua, src/string_ext.lua, + src/table_ext.lua, src/tree.lua, src/xml.lua: Move from here... + * std/base.lua, std/bin.lua, std/debug_ext.lua, std/debug_init.lua, + std/fstable.lua, std/getopt.lua, std/io_ext.lua, std/lcs.lua, + std/list.lua, std/math_ext.lua, std/mbox.lua, std/modules.lua, + std/object.lua, std/package_ext.lua, std/parser.lua, std/set.lua, + std/std.lua.in, std/strbuf.lua, std/strict.lua, std/string_ext.lua, + std/table_ext.lua, std/tree.lua, std/xml.lua: ...to here. Adjust + require calls. + * std/modules.lua: Add "std." prefix. + * std/std.lua.in: Strip "std." prefix before injecting required + symbols into global namespace. + +2013-03-29 Gary V. Vaughan + + maint: support rerunning check-local in multiple lua environments. + * .luamultienv: Example multienv runner. + * Makefile.am (SPECL): Allow overriding. + (MULTICHECK): Location of multicheck script. + (check-local): Run multicheck without looping, if present. + + getopt: ensure we find _G.arg from Specl nested setfenv environments. (issue #27) + Although only necessary for Lua 5.1, this fix is harmless for Lua + 5.2, and we support both! + * src/getopt.lua (processArgs): Use only fully qualified _G.arg + references, for Lua 5.1 Specl compatibility. + Fixes issue #27. + +2013-03-29 Reuben Thomas + + getopt: instead of parsing undefined options, stop at first non-option + This is a configurable behaviour in C getopt, and does what I actually + wanted in the first place. If the other behaviour has a use case, it + can be reinstated later. + +2013-03-26 Gary V. Vaughan + + string_ext: propagate string metamethods correctly. (issue #26) + * specs/string_ext_spec.yaml (describe caps, describe chomp) + (describe escape_pattern, describe escape_shell, describe finds) + (describe format, describe ltrim, describe pad, describe rtrim) + (describe split, describe tfind, describe trim, describe wrap): + Add new specifications for metamethods. + * src/string_ext.lua (M): Declare at the beginning, and then + copy function references in at the end. + (__index metamethod): Delegate to M for unknown metamethods, now + that it carries all string functions too. + Fixes issue #26. + + refactor: eliminate forward declarations by reordering string_ext.lua. + * src/string_ext.lua (split): Move above require_version, the + earliest caller. Declare as a local. Rewove forward declaration. + (finds): Move above split, the earliest caller. + (tfind): Move above finds, the earliest caller. + (format): Move above assert, the earliest caller. Declare as + local. Remove forward declaration. + + refactor: don't over simplify specs/string_ext_spec.yaml. + * specs/string_ext_spec.yaml (context by name): Add back + accidentally deleted line. + + refactor: simplify specs/string_ext_spec.yaml. + * specs/string_ext_spec.yaml (context by name): Unroll a function. + (it adds extension apis to the global table): Remove debug code. + + std: propagate methods into global environment correctly. (issue #25) + * specs/string_ext_spec.yaml (keywords): List of methods that + should propagate into the global environment. + (it propagates keywords to the global environment): New + specification. + * src/std.lua.in: Propagate global methods correctly. + Fixes issue #25. + + configury: mkrockspecs uses uninstalled stdlib again. (issue #24) + * GNUmakefile (ROCKSPEC_ENV): Default to same value as LUA_ENV. + (MKROCKSPECS): Now uses lua-stdlib from the build tree, not the + previously installed version. + +2013-03-25 Gary V. Vaughan + + debug_ext: don't perturb the global environment by default. + For backwards compatibility, `require "std"` will still write + symbols into the global environment, but when loaded directly be + much more hygienic and return everything in a table, like most + other modules: + * src/debug_ext.lua (M): Return a table of previous debug_ext + globals. + * src/debug_init.lua: Wrap _DEBUG in a returned table, but + initialize from _G._DEBUG when first loaded. + * specs/debug_ext_spec.yaml: New specs. Specify behaviour of + loading just debug_ext, or indirectly via `require "std"`. + Add pending examples for remaining debug_ext APIs. + * Makefile.am (SPECS): Add specs/debug_ext_spec.yaml. + + math_ext: don't perturb the global environment by default. + For backwards compatibility, `require "std"` will still write + symbols into the global environment, but when loaded directly be + much more hygienic and return everything in a table, like most + other modules: + * src/math_ext.lua (M): Return a table of previous math_ext + globals. + * specs/math_ext_spec.yaml: New specs. Specify behaviour of + loading just math_ext, or indirectly via `require "std"`. + Add pending examples for remaining math_ext APIs. + + io_ext: don't perturb the global environment by default. + For backwards compatibility, `require "std"` will still write + symbols into the global environment, but when loaded directly be + much more hygienic and return everything in a table, like most + other modules: + * src/io_ext.lua (M): Return a table of previous io_ext globals. + (file_metatable): Move from here... + * src/std.lua.in: ...to here. + * specs/io_ext_spec.yaml: New specs. Specify behaviour of loading + just io_ext, or indirectly via `require "std"`. + Add pending examples for remaining io_ext APIs. + + refactor: move leaves and ileaves from base to list. + Break another dependency loop. + * src/base.lua (_leaves, _G.ileaves, _G.leaves): Move from here... + * src/list.lua (_leaves, ileaves, leaves): ...to here. + (M): Adjust. + * src/io_ext.lua: For ileaves, `require "list"` instead of "base". + (writelines): Adjust. + * src/tree.lua (M): Re-export list.ileaves and list.leaves as + tree.ileaves and tree.leaves. + * src/std.lua (_G): Re-export list.ileaves and list.leaves to the + global environment. + + string_ext: don't perturb the global environment by default. + For backwards compatibility, `require "std"` will still write + symbols into the global namespace, but when loaded directly be + much more hygienic and return everything in a table, like most + other modules: + * src/base.lua: Don't depend on list or string_ext modules to + break a depndency loop. + (_G.require_version, _G.render, _G.tostring, _G._tostring) + (_G.prettytostring, _G.pickle, _G.assert): Move these "stringy" + functions from here... + * src/string_ext.lua: ...to here, breaking another dependency + loop. + (M): Define module symbols in this table and return it. + * specs/string_ext_spec.yaml: Add pending examples for the + relocated APIs. + * src/std.lua.in: Inject string_ext module symbols into global + string namespace, and newly relocated base functions directly + into _G. + * src/debug_ext.lua, src/getopt.lua, src/xml.lua: Use required + string_ext return value from a local table. + * specs/string_ext_spec.yaml: Specify new behaviour, being + careful about `require "std"` side-effects. + + table_ext: don't perturb the global environment by default. + For backwards compatibility, `require "std"` will still write + symbols into the global namespace, but when loaded directly be + much more hygienic and return everything in a table, like most + other modules: + * src/table_ext.lua (unextended): Remove. + (M): Include core lua table.sort function as M._sort, and + return M. + * src/std.lua.in: Inject table_ext module symbols into global + namespace. + * specs/table_ext_spec.yaml: Specify new behaviour, being + careful about `require "std"` side-effects in global namespace.. + * src/base.lua, src/fstable.lua, src/getopt.lua, src/object.lua, + src/string_ext.lua: Save "table_ext" import into a local table and + call APIs directly from there. + + package_ext: don't perturb the global environment by default. + For backwards compatibility, `require "std"` will still write + symbols into the global namespace, but when loaded directly be + much more hygienic and return everything in a table, like most + other modules: + * src/package_ext.lua (M): Define module symbols in this table + and return it. + * src/std.lua.in: Inject package_ext module symbols into global + namespace. + * specs/package_ext_spec.yaml: Specify new behaviour, being + careful about `require "std"` side-effects. + + configury: bump release number to 35. + * configure.ac (AC_INIT): Bump release number to 35. + +2013-03-24 Gary V. Vaughan + + configury: warn if `make check` needs a newer Specl. + * Makefile.am (SPECL_MIN): Oldest release capable of running our + spec files. + (check-local): If actual Specl version is older than SPECL_MIN + show a diagnostic rather than try to run the specs. + + maint: move GNU make only rules to GNUmakefile. + * Makefile.am (SPECL_OPTS, specl_verbose_, specl_verbose_0) + (specl_verbose_1): Move from here... + * GNUmakefile: ...to here. + (specl_verbose_1): Now that Specl-3 passes --verbose on to the + selected formatter to handle, explicitly request the long-form + report formatter for `make check V=1`. + + maint: revert premature merge of pull request #23. + Reverse apply 5508adb. + +2013-03-23 Reuben Thomas + + README: make formatting consistent + + GNUmakefile: change to using a separate checkout for release branch + +2013-03-15 Reuben Thomas + + Merge pull request #23 from rrthomas/gary/ext-hygiene + package_ext: don't perturb the global environment by default. + +2013-03-15 Gary V. Vaughan + + package_ext: don't perturb the global environment by default. + For backwards compatibility, `require "std"` will still write + symbols into the global namespace, but when loaded directly be + much more hygienic and return everything in a table, like most + other modules: + * src/package_ext.lua (M): Define module symbols in this table + and return it. + * src/std.lua.in: Inject package_ext module symbols into global + namespace. + * specs/package_ext_spec.yaml: Specify new behaviour, being + careful about `require "std"` side-effects. + + string_ext: fix a bad assumption in a spec example. + Running string.format in the expectation `should` uses the core + Lua string.format which doesn't prettify tables, but we're + comparing it to the string_ext `..` operator which uses the std + enhanced string.format, and that *does* prettify tables. + * specs/string_ext_spec.yaml (stringifies non-string arguments): + Manually expand the the stringified table in should to match the + std prettified table stringification. + + list: fix standalone loading of string_ext module. + This fix reenables simple 'require "string_ext"' without an additional + 'require "std"'. + * src/string_ext.lua: Load the list module, which is used in split(). + Store APIs from `require "strbuf"`. + +2013-03-14 Gary V. Vaughan + + list: fix standalone loading of list module. + This fix reenables simple 'require "getopt"' without an additional + 'require "std"'. + * src/list.lua (new): Add a forward declaration. + (sub, concat, rep, reverse, transpose, enpair, flatten, shape) + (indexKey, indexValue): Use new, rather than list.new. + * src/getopt.lua (processArgs): Call local 'getOpt' function. Global + getopt.getOpt may never exist! + +2013-03-10 Reuben Thomas + + README: mention all extra dependencies of fstable + + getopt: remove the need for ugly getopt.Option constructor + +2013-03-09 Gary V. Vaughan + + maint: support 'make check V=1' and 'SPECL_OPTS=-v make check'. + * Makefile.am (SPECL_OPTS): Unless set in the environment already, + pass -v to specl according to whether or not V=1 was given to make. + (check-local): Use it. + +2013-03-09 Reuben Thomas + + getopt: allow parsing of undefined options; useful for programs which wrap other programs + +2013-03-07 Gary V. Vaughan + + specs: update to cleaner Specl-2 YAML spec format. + * specs/getopt_spec.lua, specs/package_ext_spec.lua, + specs/string_ext_spec.lua, specs/table_ext_spec.lua: Rename from + these... + * specs/getopt_spec.yaml, specs/package_ext_spec.yaml, + specs/string_ext_spec.yaml, specs/table_ext_spec.yaml: ...to + these. Reformat as YAML. + * Makeflie.am (SPECS): Remove old _spec.lua filenames, and add + new _spec.yaml filenames. + +2013-03-06 Gary V. Vaughan + + specs: allow for package.config differences in Lua 5.1. + * specs/package_ext_spec.lua (it splits package.config up): Allow + for optional trailing \n present in 5.2 but not 5.1. + +2013-02-28 Gary V. Vaughan + + configury: bump release number to 34. + * configure.ac (AC_INIT): Bump release number to 34. + + specs: rely on installed specl rather than shipping our own. + * specs/specl, specs/lib/specl.lua: Remove. + * Makefile.am (EXTRA_DIST): Adjust accordingly. + (lib_spec): Remove. + (SPEC_ENV): Adjust accordingly. + (SPECS): Add $(srcdir) prefix for distcheck. + (check-local): Run listed SPECS using installed specl. + + maint: don't checkout master again before running woger. + * GNUmakefile (check-in-release): Move current_branch save and + restore from here... + (release): ...to here. + + maint: mkrockspecs simplifications. + * luarocks-config.lua.in: Remove. + * configure.ac (AC_CONFIG_FILES): Remove luarocks-config.lua. + * GNUmakefile (luarocks-config.lua): Make on demand. + * Makefile.am (rockspecs): Move from here... + * GNUmakefile (rockspecs): ...to here. + (WOGER_ENV, WOGER_OUT): Factored out of release rule. + (release): Simplify accordingly. + + maint: don't forget to distribute GNUmakefile. + * Makeflie.am (EXTRA_DIST): Add GNUmakefile. + +2013-02-25 Gary V. Vaughan + + io_ext: remove spurious access to global 'prog' variable. + * src/io_ext.lua (processFiles): The supplied function receives + a copy of each file name, so no need to make assumptions about + global variables in here. + +2013-02-23 Gary V. Vaughan + + specs: add a skeleton specl spec for getopt module. + * src/getopt.lua (test): Remove. + * specs/getopt_spec.lua: Reimplement as specs. + * Makefile.am (SPECS): Add spects/getopt_spec.lua. + * specs/getopt_spec.lua): More specs for default option overrides. + * src/getopt.lua (processArgs): Fix a small scoping bug uncovered + by the new specs. + + getopt: don't display the full help for option errors. + * src/getopt.lua (processArgs): Show the error and a short help + message for option errors, and save the full blown help screens + for '--help'. + (usage): Simplify concatenations slightly. + + getopt: support GNU style --help and --version output. + * src/getopt.lua (usage): Take arguments from the prog parameter + instead of inspecting global variables. + If present, wrap paragraphs from prog.description and display + between purpose and option table. + (version): New function. Display version info according to prog. + version and prog.copyright. + (processArgs): Use it. + * template.lua: Update. + * specs/specl: Update. + + getopt: insert a blank line between usage and purpose. + + getopt: move options and prog out of the global namespace. + * src/getopt.lua (usage): Require prog as a parameter with options + inside it. + (processArgs): Likewise. + * template.lua: Update. + + getopt: only add default help and version when user supplied none. + * src/getopt.lua (makeOptions): Make two passes through the option + list. The first to collect all option declarations, and the second + to make an index. + (appendOpt): Factor out, and add a nodupes parameter to prevent + addition option specs being added when any of the option letters + they use have been claimed already. + Use it to only add default help and version options when the user + didn't specify their own already. + + getopt: format long and short options properly. + * src/getopt.lua (fmtOpt): Display two leading dashes for long + options. + (usageInfo): Indent past the short option column where only a + long option is being displayed. + + getopt: move Option out of the global namespace. + * src/getopt.lua (_G.Option): Rename from this... + (Option): ...to this local declaration. + (M): Export Option as a new public interface. + Remove TODO. + * template.lua, specs/specl: Update. + +2013-02-23 Reuben Thomas + + Fix some spec failures in string.wrap, and one error in a spec. + + string_ext.lua: fix a reference to string.sub. + +2013-02-22 Gary V. Vaughan + + string_ext: prefer snake_case to camelCase APIs. + * src/string_ext.lua (escapePattern, escapeShell, ordinalSuffix): + Rename from these... + (escape_pattern, escape_shell, ordinal_suffix): ...to these. + (M): Continue to support camelCase calls for backwards compatibility. + * specs/string_ext_spec.lua: Update. + Add specs to ensure camelCase APIs continue to work. + + maint: update string_ext to use Lua 5.2 style modules. + * src/string_ext.lua: Save unextended string table, returning + that after injecting stdlib extensions. + * specs/string_ext_spec.lua (context when requiring the module): A + few new specifications for requiring string_ext. + + specs: add missing specs for string.finds and string.tfind. + * specs/string_ext_spec.lua (describe string.finds (), describe + string.tfind ()): New specs for these APIs. + + specl: ensure that failing to meet specs kills make distcheck. + * specs/lib/specl.lua (run): Return true unless there are + expectation failures. + * specs/specl: Exit with non-zero status for with expectation + failures. + + string_ext: bail out early with fatal type mismatch errors. + * src/string_ext.lua (wrap): Rather than letting the guts of wrap + choke unpredictably later on, assert the required types at the + outset. + (tfind): Likewise. These currently bubble up to finds and split + as well. + + specl: update ordinalSuffix () error specs to match the new error messages. + * specs/string_ext_spec.lua (describe string.ordinalSuffix): Make the + expectations match reality. + +2013-02-22 Reuben Thomas + + Fix ordinalSuffix for negative arguments (issue #20). + + string_ext.lua: use Lua terminology "pattern" rather than "regex" + +2013-02-22 Gary V. Vaughan + + specs: add specl specification for string_ext module. + * specs/string_ext_spec.lua: New file. Specl specs for + string_ext. + * Makefile.am (SPECS): Add specs/string_ext_spec.lua. + + specl: sync from upstream. + * specs/lib/specl.lua: Upgrade to the latest upstream, where the + contain and match matchers are not broken! + + string_ext: don't use math.mod, which doesn't exist in Lua 5.2. + * string_ext.lua (ordinalSuffix): Use '%' operator instead of + math.mod, which is compatible with Lua 5.1 and 5.2. + + maint: move maintainer rules into GNUmakefile. + * Makefile.am: Move maintainer rules from here... + * GNUmakefile.am: New file. ...to here. + Automatically autoreconf the directory if configure is missing. + + configury: make sure WOGER has a default value. + * Makefile.am (WOGER): Set it to 'woger' by default. + + configury: bump release number to 33. + * configure.ac (AC_INIT): Bump release number to 33. + + configury: make the release rules more robust. + * Makefile.am (GIT, GIT_REMOTE, LN_S): Set as macros that can be + overridden during testing. + Adjust all callers. + (tag-release, check-in-release): Move the push commands that + publish changes upstream from here... + (release): ...to here. + (check-in-release): Rather than rely on having a parallel checkout + in a particular sibling directory, just switch branches from here + temorarily. + (unpack-distcheck-release): Once in the relase branch, overwrite + the previous release with the tarball from distcheck. + + configury: bump release number to 32. + * configure.ac (AC_INIT): Bump release number to 32. + +2013-02-21 Gary V. Vaughan + + specs: add specl specification for package_ext module. + * specs/package_ext_spec.lua: New file. Specl specs for + package_ext. + * Makefile.am (SPECS): Add specs/package_ext_spec.lua. + + maint: update package_ext to use Lua 5.2 style modules. + * src/package_ext.lua: Save unextended package table, returning + that after injecting stdlib extensions. + + specs: specify return of the unextended module from table_ext. + * specs/table_ext_spec.lua (context when requiring the module): A + few new specifications for requiring table_ext. + + maint: update table_ext.lua to use Lua 5.2 style modules. + * src/table_ext.lua: Save unextended package table, returning that + after injecting stdlib extensions. + Declare everything locally. + (M): Public interface. + + specl: new specification testing framework. + * specs/lib/specl.lua: New file for specification testing. + * specs/specl: New file. Command line wrapper for specl.lua. + * specs/table_ext_spec.lua: New file. Specl tests for + src/table_ext.lua. + * Makefile.am (src_spec, lib_spec): Lua search path strings for + directories in the source tree. + (LUA_ENV): Adjust. + (SPEC_ENV): New macro. Set Lua environment for calling specl. + (SPECS): New macro. A list of specs/*_spec.lua files. + (EXTRA_DIST): Add new specification testing files. + (check-local): Hook the specl tests into the Automake test + framework. + + bugfix: make sure getopt.opt is updated in the module table. + Fix a bug preventing visibility of getopt.opt after port to Lua + 5.2 style modues. + * src/getopt.lua (M): Add opt table. Move declaration above... + (processArgs): ...here, and update M.opt instead of undeclared + opt variable. + Merge other public entry points into M table before returning. + + configury: use static list of SOURCES instead of $(filter)ing. + * Makefile.am (SOURCES): Remove the GNU Make extensions used to + dynamically build the list, and just list each file statically. + +2013-02-21 Reuben Thomas + + Makefile.am: bump version to 31. + + list.lua: rename slice to sub, for compatibility with strings. + + list.lua: add list methods. + + Makefile.am: re-add explicit setting for release notes file, which we can once more prepare ahead of time + + Makefile.am: no longer need to re-bootstrap after checking in release files. + +2013-02-19 Reuben Thomas + + m4/ax_lua.m4: get latest version; no code changes, but some pleasing spelling corrections. + + list.lua: allow list.new to take no arguments to create an empty list. + The previous commit relied on this behaviour; oops. + + list.lua: make all methods that return lists make them with list.new, not {}. + Also rename result variables consistently to r, not, in some cases, m. + +2013-02-18 Reuben Thomas + + Makefile.am: checking out release branch in same directory doesn't work; use another directory. + + Makefile.am: since git clean deletes release notes file, don't supply it to woger (which will prompt for release notes). + + Makefile.am: need to git clean directories too. + + Makefile.am: run git clean to ensure we can check out the release branch. + + Makefile.am: only supply std.lua once (fixes make distcheck in some setups) + +2013-02-16 Reuben Thomas + + Makefile.am: copy a couple of fixes from luaposix. + + rockspecs.lua: add luarocks include path to configure command. + + Makefile.am: remove reference to defunct stdlib.rockspec.in + + rockspecs.lua: remove lrexlib-specific comment + +2013-02-12 Gary V. Vaughan + + maint: bump version to 30. + * configure.ac (AC_INIT): Bump version to 30. + +2013-02-12 Gary V. Vaughan + + Merge pull request #14 from gvvaughan/pull-request/move-to-lua52-module-style + Pull request/move to lua52 module style + +2013-02-12 Gary V. Vaughan + + configury: make sure we build std.lua when necessary. + Using wildcard for SOURCES before std.lua has been built now that + configure no longer makes it for us, means standard make or + luarocks install after building from a fresh checkout results in + std.lua not being built or installed. + * Makefile.am (SOURCES): Add src/std.lua. + +2013-02-12 Gary V. Vaughan + + Merge pull request #12 from gvvaughan/pull-request/fix-luadocs-hard-dependency + configury: fix hard dependency on luadocs. + + Merge pull request #11 from gvvaughan/pull-request/use-uninstalled-stdlib + configury: load local std modules as expected by mkrockspecs.lua. + +2013-02-12 Reuben Thomas + + parser.lua: update to current stdlib and Lua 5.2, fixing a couple of small bugs + Remove a debugging line accidentally left in before. + + base.lua: fix die; previously produced rubbish! + +2013-02-12 Gary V. Vaughan + + maint: update parser to use lua 5.2 style modules. + * src/parser.lua: Simply return the Parser object. + + maint: update object to use lua 5.2 style modules. + * src/object.lua: Simply return the callable Object table. + Adjust all callers. + + maint: update setbuf to use lua 5.2 style modules. + * src/strbuf.lua: Declare everything locally, and return a table + of interfaces, per lua 5.2 module style. + Adjust all callers. + +2013-02-11 Gary V. Vaughan + + maint: update mbox to use lua 5.2 style modules. + * src/mbox.lua: Declare parse locally, and return a table with a + reference, per lua 5.2 module style. + + maint: update lcs to use lua 5.2 style modules. + * src/lcs.lua: Declare longestCommonSubseq locally, and return a + table containing a reference to it, per lua 5.2 module style. + + maint: update getopt to use lua 5.2 style modules. + * src/getopt.lua: Declare everything locally, and return a table + of interfaces, per lua 5.2 module style. + + maint: update fstable to use lua 5.2 style modules. + * src/fstable.lua: Declare everything locally, and return a table + of interfaces, per lua 5.2 module style. + + maint: update bin to use lua 5.2 style modules. + * src/bin.lua: Declare everything locally, and return a table of + interfaces, per lua 5.2 module style. + + maint: update trees to lua 5.2 style modules. + * src/tree.lua: Declare everything locally, and return a table of + interfaces, per lua 5.2 module style. + + maint: update lists to use lua 5.2 style modules. + * src/list.lua: Declare everything locally, and return a table of + interfaces, per lua 5.2 module style. + Adjust all callers. + + maint: update sets to use lua 5.2 style modules. + This is backwards compatible with lua 5.1, and allows use of sets + with the strict module loaded, which raised a bogus error before. + * src/std.lua.in (version): Return this in the module namespace. + Require the bundle of "std" modules into the global namespace. + * src/set.lua: Declare everything locally, and return a table + of interfaces, per lua 5.2 module style. + + configury: fix hard dependency on luadocs. + * m4/ax_with_prog.m4: New file. + * configure.ac (AX_WITH_PROG): Use it to find a luadocs binary. + * Makefile.am ($(dist_doc_DATA)): Use the substituted binary. + * rockspecs.lua: Remove insertion of luadocs dependency. + + * configury: load local std modules as expected by mkrockspecs.lua. + Rather than having to manually update the installed lua-stdlib + behind luarocks' back, let the mkrockspecs.lua script find the + modules it was written for in the source tree. + * Makefile.am (LUA_PATH): Default to compiled-in search path. + (LUA_ENV): Load modules from the source tree instead of potentially + outdated versions from the lua installation. + (rockspecs): Run lua with LUA_ENV set. + +2013-02-09 Reuben Thomas + + rockspecs.lua: add luadoc as a dependency for git rockspec. + + rockspecs.lua: fix build command for building from git. + + mkrockspecs.lua: whitespace fix. + + Add a rockspec for building from git, and machinery for building variant rockspecs. + + tree.lua: add tree.merge. + +2013-02-08 Reuben Thomas + + set.lua: fix broken elems iterator (issue #10) + + strict.lua: tweak formatting to match other modules + + base.lua: note availability of original tostring as _tostring. + +2013-02-07 Reuben Thomas + + set.lua: add missing dependency on list.lua + + Avoid rebuilding documentation in distributed sources, so users don't need luadoc installed. + + Makefile.am: some more fixups to release-by-git. + + .gitignore: we have reverted from zip to tgz tarballs. + + Makefile.am: don't try to rebuild documentation if not necessary (doesn't work in VPATH build, so breaks distcheck). + + Makefile.am: distcheck is really a dependency of check-in-release, not of release. + + stdlib.rockspec.in: correct name of git tag to source release tag. + + Makefile.am: check in sources before trying to check them out for test build. + + Fix issue #8: members with the same names as class methods cause problems. + + Bump version to 29. + + Makefile.am: add check-in-release to push release files to git. + + Makefile.am: enable building of documentation from git checkout. + +2013-02-06 Reuben Thomas + + Change to building (with LuaRocks) direct from git, not releasing a zip. + + README: update installation instructions and mention GitHub, not LuaForge. + + Update to latest ax_lua.m4. + +2013-02-05 Reuben Thomas + + README: Make Lua 5.2 compatibility definite, and update copyright years. + +2012-12-24 Reuben Thomas + + stdlib.rockspec.in: remove redundant dir setting + +2012-10-30 Reuben Thomas + + .gitignore: add luarocks directory + +2012-10-29 Reuben Thomas + + Add testing of luarock against uploaded archive before mailing announcement + + base.lua: user simpler default require_version pattern that works in more cases + +2012-10-29 Reuben Thomas + + Generate Lua version in rockspec from that in configure.ac + Bump version to 28 + + Use newer ax_lua.m4 + + Tweak pattern used to substitute MD5 sum into rockspec to be + compatible with gnulib syntax checks, should we ever use them. + +2012-10-29 Reuben Thomas + + Bump version to 28, and simplify slightly, requiring automake 1.11 + +2012-10-15 Reuben Thomas + + base.lua: move a documentation stanza to a more apt location + +2012-10-04 Reuben Thomas + + release: fix call to woger to generate correct URLs + + rockspec: fix homepage URL + + Makefile.am: really distribute all docs + + rockspec: fix download URL (thanks, Hisham Muhammad) + +2012-10-02 Reuben Thomas + + base.lua: add require_version + +2012-09-26 Reuben Thomas + + Make build_command in rockspec more robust. + + Install documentation with 'make install' and from luarocks. + +2012-09-23 Reuben Thomas + + Rename table.indices to table.keys, and use term 'keys' more. + +2012-09-21 Reuben Thomas + + getopt.lua: output usage information to stdout, not stderr + + configure.ac: bump version to 27 + + configure.ac: accept Lua 5.2 + +2012-09-18 Reuben Thomas + + getopt.lua: remove func member of Option; simply gather all option values into a list + + getopt.lua: improve some comments and remove a redundant require + + set.lua: fix last commit: elements should be elems + + base.lua: remove a spurious blank line + + set.lua: revert elements iterator to being pairs; leaves is wrong! + +2012-09-12 Reuben Thomas + + Turn on debugging by default and tweak what the global debug function does. + +2012-09-12 Reuben Thomas + + I misunderstood what finds did, and didn't spot that it was needed for split! + Revert "string_ext: remove finds; map should be used with string.find instead" + + This reverts commit 5a62e3ee7ad2514b681ff6f348c43b797088b089. + +2012-09-11 Reuben Thomas + + string_ext: remove finds; map should be used with string.find instead + +2012-09-06 Reuben Thomas + + Remove string.gsubs: the order of substitutions was undefined, and map can be used just as well. + +2012-07-06 Reuben Thomas + + build: Check MD5 sum of rockspec against tarball before releasing + +2012-05-31 Reuben Thomas + + object: fix an incorrect simplification in the previous commit. + + object: add the ability to have a constructor function. + +2012-05-31 Reuben Thomas + + Tweak a couple of table functions. + Rename table.rearrange to the more descriptive table.clone_rename, and + clarify the documentation. + + Make table.merge not clone its left-hand argument, but modify it, as + the user has reason to expect. + +2012-05-31 Reuben Thomas + + parser.lua: fix call to renamed method. + +2012-05-29 Reuben Thomas + + object.lua: fix inconsistency and missing HTML close tag in doc comments. + +2012-02-23 Reuben Thomas + + base.lua: Fix minor formatting variation. + + Merge pull request #5 from gvvaughan/pull-request/for-fame-and-glory + AUTHORS: Add myself. + +2012-02-23 Gary V. Vaughan + + base.lua: new memoize function. + * src/base.lua (memoize): Memoize a single result function by + wrapping it in a functable. + +2012-02-23 Reuben Thomas + + Update URL to point to github. + + Reformat some code to make lua-mode happier (most of the time, sigh). + +2012-02-22 Gary V. Vaughan + + AUTHORS: Add myself. + * AUTHORS: List the few small contributions I've made. + +2012-02-19 Reuben Thomas + + Update rockspec for github. + + Makefile.am: Update call to woger. + + Makefile.am: Update call to woger. + + Makefile.am: Update call to woger. + + Makefile.am: Update call to woger. + + Makefile.am: Update call to woger. + + Makefile.am: Update call to woger. + + Makefile.am: Update call to woger. + + Rename set.elements to set.elems for consistency with list.elems. + +2012-01-21 Reuben Thomas + + base.lua: add missing require of strbuf. + + strict.lua: improve error message. + +2012-01-20 Reuben Thomas + + Add leaves, ileaves and inodes tree iterators; simplify nodes slightly. + Use ileaves to simplify flatten. + + Rename io.writeline to io.writelines and allow it to flatten table + arguments. + + Use list.elems instead of ipairs in several places. + + Fix FIXME in set: use leaves as elements to return only the key. + +2012-01-19 Reuben Thomas + + src/io_ext.lua: Improve docstring for readlines. + +2012-01-18 Reuben Thomas + + string_ext: fix new string.__concat metamethod to run tostring on both args, thus avoiding infinite recursion. + +2012-01-17 Reuben Thomas + + string_ext: add __concat metamethod for strings which runs tostring. + Reformat some code to please lua-mode and add some missing quotes in a + comment. + +2012-01-09 Reuben Thomas + + io_ext: Add slurp; use it in various places. + +2011-12-17 Reuben Thomas + + Bump version to 26. + +2011-12-16 Reuben Thomas + + Merge pull request #1 from gvvaughan/patch-1 + tree: fix bugs when using a list of tables as keys + + Thanks for this. I don't currently have another use case than Zile to test with. + +2011-12-16 Gary V. Vaughan + + tree: fix bugs when using a list of tables as keys + To be fully general, tree should allow table keys so that it's + possible to write: + $ lua -lstd + > t, k1, k2 = tree.new(), {key='a'}, {key='b'} + > t[{"k1", "k2"}] = "string keys"; t[{k1, k2}] = "table keys" + > = t[{"k1", "k2"}], t[{k1, k2}] + string keys table keys + This patch fixes 3 bugs that prevent that from working. + * src/tree.lua (metatable.__newindex): Detect subtrees correctly + by comparing against the tree metatable, rather than assuming any + "table" type is a correct match. + Use rawset to insert a new node without triggering the __index + metamethod. + (metatable.__index): Don't recurse into table key members, only + the list entries to be folded, by checking whether the table has + a length first - for t[{k1, k2}], {k1, k2} is a list (with length) + and should be folded, but k1 (k1 = {key='a'}) is not a list and + should not. + +2011-10-01 Reuben Thomas + + io_ext: unset prog.file at the end of io.processFiles + +2011-09-27 Reuben Thomas + + getopt: improve output and conformance to best practice + Make the short option for -version be -V, not -v. + + Remove short option -? for -help. + + In help, show short options first, so that display is easier to read. + + Remove publicly Options constructor, as it’s not needed externally. + +2011-09-20 Reuben Thomas + + Makefile.am: tweak rockspec's deps. + + src/.gitignore: add std.lua. + + Bump version to 25. + + std.lua: add a version string to the std module + + list: add list.compare, and __le and __lt metamethods. + + Makefile.am: make release message shorter and more precise. + + Makefile.am: distribute rockspec source. + + .gitignore: ignore correct zip name. + +2011-09-19 Reuben Thomas + + configury: rename project to stdlib for consistency and to make luarocks happy. + + Make rockspec on release. + + Bump version to 24. + + string_ext.lua: fix old call of findl (is now called tfind). + +2011-09-17 Reuben Thomas + + Makefile.am: fix getting summary description, and reminder message output by make release. + + rockspec: Keep old name (stdlib) for the rock. + Also fix LuaForge URL, which of course hasn’t changed. + + .gitignore: Add Makefile. + + Build system: autotoolize and generate rockspec. + +2011-09-11 Reuben Thomas + + Rename findl to tfind to conform to lrexlib. + Also fix a bug in the LuaDoc documentation of the return values. + +2011-09-07 Reuben Thomas + + Remove posix_ext module (is going in luaposix instead). + Update documentation about LuaDoc. + + Add posix.creat. + +2011-09-02 Reuben Thomas + + Fix typo. + + Add a new module with some binary to number/string conversion routines. + + Add simple string buffers and use them for default table tostring. + + Fix mode on .gitignore. + + Remove some non-LuaDoc markup. + +2011-08-20 Reuben Thomas + + Fixup. + + Add some more LuaDoc stuff. + + Partial conversion of documentation to LuaDoc. + +2011-06-06 Reuben Thomas + + Push tags, but don’t tag until we’ve successfully released. + + Update woger call to new keyword style. + + Add fstable module for storing tables as file trees. + + Replace reference to ldoc with one to LuaDoc. + + Convert documentation to LuaDoc, and retire ldoc. + + Add index.html. + +2011-05-22 Reuben Thomas + + Fix faulty ldoc tags. + + Fix return code on --help to be 0. + Make dieWithUsage into plain usage, and don’t exit at end. + +2011-05-20 Reuben Thomas + + Add some missing param tags. + +2011-05-04 Reuben Thomas + + Comment out strict from default set to make co-existence with other code easier. + + Fix calls to writeLine to be to writeline. + +2011-05-02 Reuben Thomas + + Add readlines and writeline to file handle metatable. + + Fix capitalization of readlines and writeline in docstrings. + +2011-04-16 David Favro + + Fixed bug: ldoc used writeLine() rather than writeline(). + +2011-04-12 Reuben Thomas + + Always return nil on error, not -1. + +2011-04-04 Reuben Thomas + + Rename readLines to readlines and writeLine to writeline. + +2011-03-24 Reuben Thomas + + Only set _DEBUG to false if it’s not already initialised. + +2011-03-19 Reuben Thomas + + Fix splitdir. + +2011-03-12 Reuben Thomas + + Initialise _DEBUG early so that it can be overridden by app and still be strict.lua-compatible. + + Shorten a TODO. + +2011-03-09 Reuben Thomas + + Restore modules.lua as holding standard list, to un-break std.lua. + + Allow mk1file to generate customized sets of modules, with the standard set as the default. + + Remove unnecessary posix. prefix. + + Correct name of package_ext. + + Remove redundant comments. + + Update documentation of standard set, and add prerequisites. + + Merge branch 'origin' of github.com:rrthomas/lua-stdlib into origin + +2011-03-08 Reuben Thomas + + Remove posix_ext and object from standard set. + + Remove posix prefix from function calls. + + Add euidaccess. + + Improve a comment. + + Merge branch 'origin' of github.com:rrthomas/lua-stdlib into origin + + Add __index method to allow OO syntax use of methods. + Add delete method. + +2011-03-01 Reuben Thomas + + Reverse order of list methods for convenient OO use. + + Merge from HEAD. + +2011-02-27 Reuben Thomas + + In future, make zip distros. + + Fix message. + + Use package.dirsep once more. + + Put package.config reflexion into a new package_ext module. + + Make message clearer. + + Leave dist tarball in source dir, not above. + + Add tarball to .gitignore. + + Add sensible access to package.config. + + Bump copyright year. + + Bump copyright year. + + Use undocumented package.config to get platform’s directory separator. + +2011-02-09 Reuben Thomas + + Improve release target to tag releases. + +2011-02-07 Reuben Thomas + + Fix missing math. prefix, and swap incorrect sign in sub. Thanks to Bob Chapman. + +2010-12-15 Reuben Thomas + + Speed up math.floor for case where p is 0 or absent (thanks, Lukáš Procházka). + +2010-12-09 Reuben Thomas + + Change rules from using CVS to using git. + + Reinstate string __index metamethod fallback so that OO uses of strings work. + Switch argument order of ltrim, rtrim and trim so they work in OO + syntax. + + Point to tree.clone for deep copies. + +2010-10-12 Reuben Thomas + + Restore 'dubious' but used string metamethod fallback. + +2010-10-09 Reuben Thomas + + Move .cvsignore's to .gitignore's. + +2010-10-08 Reuben Thomas + + Fix typo in io.catfile. + + Add commit that seems to be missing from import from CVS. + + Add new posix_ext module. + + Add posix_ext to list. + + Remove spurious full stop. + + Add catfile and fix catdir to return `/' when necessary. + +2010-10-07 Reuben Thomas + + Fix permissions. + +2010-06-21 rrt + + Remove dubious metamethod fallback for string.__index. + +2010-06-14 rrt + + Fix and simplify tree.__newindex: there was a variable name typo, and sub-tables should also be initialised to trees, as otherwise the relevant metamethods are not called. + + Fix an incompatibility with strict.lua. + +2010-06-11 rrt + + Simplify nodes iterator and make it more efficient; thanks to Alistair Turnbull for the hint. + + Simplify, generalise and rename (from treeIter to nodes) tree iterator. + + Whitespace correction. + + Simplify implementation of empty, using next as per manual. + +2010-06-09 rrt + + Rename table.subscript to op["[]"], and move table.deepclone and table.lookup into a new module, tree, as the clone method and __index metamethod respectively. The tree module also has a constructor, new, and a __newindex metamethod. + Rename table.newDefault to table.new. + + Fix writeLine and add an explanatory comment. + + Make the set metatable a local variable. + + Add Lua distribution’s strict.lua to standard modules. + + Have a single list of modules in modules.lua and use it to load them in std.lua and generate the single-file version in mk1file, which latter is now a Lua script. + +2010-06-08 rrt + + Fix list.foldl, list.foldr, and the fold iterator combinator. + Simplify the op table functions to be exactly the primitive operators, + not list versions thereof. + + (Possibly) improve the commented-out simpler version of treeIter. + +2010-06-08 rrt + + Remove table.subscripts function: it’s easily replaced by subscript plus string.split, as in its definition. + +2010-06-07 rrt + + Initialise _DEBUG to nil so stdlib works with strict.lua. + Rename debug.traceCall to debug.trace (more Lua-ish). + + Use math.max rather than just (incorrectly) max. + + Improve some documentation. + +2010-06-03 rrt + + Remove redundant redefinition of print (it already calls tostring). + Fix op table so that base can require list without breaking; fixes + FIXME. + + Remove lcs module from std set. + Update FIXME about autogeneration of mk1file to make it more precise. + + Bump copyright year to 2010. + +2010-03-19 rrt + + Add missing dependency on list. + +2009-09-14 rrt + + Improve formatting slightly. + +2009-09-07 rrt + + Avoid using removed function io.changeSuffix. + + Remove rex module altogether. + + Don’t need pcre_rex any more. + Remove FIXME about external dependencies as we no longer have any, nor + intend to. + + Remove need for rex_pcre in xml. + Remove xml, rex, parser and mbox from standard list of libraries. + + Remove dependency on lposix; in the process remove addSuffix and changeSuffix, as they reliedon basename and dirname, and it wasn't worth reimplementing them as they're not used. + + Add explanatory comment. + +2009-09-01 rrt + + Add requirement of posix and copyright notice to output. + + Add lua-posix to list of dependencies. + +2009-08-24 rrt + + Fix basename and dirname calls + + Remove basename and dirname as they are now implemented in lposix. + Rename pathConcat to catdir and pathSplitDir to splitdir and make them + behave like the corresponding Perl functions. + + Add FIXME. + +2009-03-20 rrt + + Use the original _floor in round rather than chaining via floor for a bit of extra speed; thanks to David Kantowitz. + +2009-03-16 rrt + + Update 'usage' message. + + Make 'make release' do 'make dist' + + Simplify assert. + + Simplify string.format. + + Remove string.join, which is the same as table.concat. Thanks to David Kantowitz for spotting it. + +2009-03-14 rrt + + Add support for not cloning metatables. + +2009-03-13 rrt + + Check no outstanding changes and tag release. + + Fix typo. + + Update copyright year. + + Fix variable substitution in release target. + + Ignore release-notes-* + + Add release target, and exclude release notes from tarball. + + Copy metatables in deepclone, so that it does what it says. Patch from David Kantowitz. + +2009-02-19 rrt + + Add final newline for neatness. + + In the single file, make the special "require" function local so that other files can be required after the single-file std. + + Update object module to correspond with Lua Gems version. + +2008-09-04 rrt + + Fix Diego Nehab's name. Sorry Diego! Thanks to Shmuel Zeigerman for pointing out my error. + +2008-09-04 rrt + + Fix set.difference. + Add set.symmetric_difference. + + Make s * t do intersection for sets, and s / t do symmetric + difference, as in Modula 3 and (at least for *) "Programming in Lua". + +2008-09-04 rrt + + Fix equal. Thanks to report from Jiutian Yanling. + +2008-07-28 niklas + + Cope with nil values in map. + +2008-07-27 niklas + + Fix elems and relems + + Fix make dist; $REL -> ${REL}, add --exclude for .#*, and no longer exclude template-rrt.lua, which no longer lives in the tree. + +2008-06-21 niklas + + Add collect, from Patrick Walton, to run an iterator and collect the results in a table. + As a result, rewrite all the table functionals to be iterator + functionals (in base) and reimplement the list functionals in terms of + them. Add two iterators for lists, elems and relems, that return only + the elements and not the indices, in order to implement the list + functionals. + + A couple of old fixes where the Lua 5.1 table count is used (#). + + Simplify ripairs slightly. + + Fix a comment typo. + +2008-03-28 rrt + + Add some TODOs to make the prog structure a bit more sensible. + +2008-03-05 rrt + + Make a note to compare pathSplit and pathConcat with Perl equivalents. + +2008-03-04 rrt + + Add TODO to use LuaDoc instead. + + Add Makefile with dist target + + Fix typo in comment. + + No dependency on LFS. + + No longer have any sort of dependency on bitlib. + + Remove _INTEGER_BITS and unneeded dependency + +2008-03-03 rrt + + Update date and prerequisites. + +2008-03-02 rrt + + Require external deps before neutering "require". + + We may add bit to stdlib, but it's not currently there, nor is it actually used by anything in stdlib. + + rex is not an external dependency + + Simplify length function. + + Use LFS for length() function. + +2008-01-20 niklas + + Add pathSplit and pathConcat from nancy. + +2008-01-13 rrt + + Make calls to find and gsub get the function from the pattern, meaning that in theory they could work with other regex engines than Lua's. + + Remove pointless object notation on a string. + +2007-11-20 rrt + + Now that INTEGER_BITS is added to the math namespace, no need to prefix it with _. + + Note that bitlib is needed. + +2007-10-07 rrt + + Rename 'permute' to the more accurate 'rearrange' + + Update some comments to match changes in the Lua Gem about this code. + +2007-10-06 rrt + + Fix from Roberto Ierusalimschy. + +2007-05-12 rrt + + Fix up single-file stdlib + + Clarify TODO. + +2007-04-26 rrt + + Tidy length slightly. + + Clarify documentation a little further + + Ignore built docs + + Format prerequisites to allow for more than one! + Explain ldoc better. + + Revert to plain implementation of length to avoid using POSIX library which is currently unmaintained. + + Clear up uses of old vararg "arg" syntax (thanks Matt). + +2007-03-02 rrt + + Add list.rep + + Add FIXME for commented-out require + +2007-03-01 rrt + + Make join cope with empty lists. + + Remove default separator in string.split, and hence a TODO. + Add string.join. + +2007-02-26 rrt + + Mention the dependency on lrexlib. + +2007-02-25 rrt + + Use __append metamethod, not __concat, which was wrong + + Add __append metamethod and constructor for LCS + + Add __append metamethod for LCS + + Set had been left rather broken; fix it up. + + Remove no-longer-needed LCS method. Thanks to Enrico Tassi for noticing it. + +2007-02-22 rrt + + Cosmetic changes to finds (comments and a variable rename) for clarity. + Use list.flatten (l) instead of list.concat (unpack (l)) in split to + avoid overflowing the parameter stack (with the unpack) when splitting + large strings. Clarify the comment for this code. + + Fix indexKey and indexValue: the function passed to table.process wasn't returning the accumulator as it should have. + +2007-02-21 rrt + + Make a note to find better names for enpair and depair, which are useful but confusing. Something like pairsToTable and tableToPairs? + +2007-01-26 rrt + + Add missing dirname and basename + +2007-01-06 rrt + + Sync with reality. + +2007-01-05 rrt + + Document. + Set rex = rex_pcre, so that we actually have the functions we expect + under "rex". + +2007-01-04 rrt + + Now that lrexlib no longer has a Lua component or a default library, add a library to load it (currently just require rex_pcre). + +2006-12-07 rrt + + Remove TODOs that apply to lrexlib. + +2006-11-28 rrt + + Use non-list-capable math.max correctly + +2006-11-21 rrt + + Fix from Jerôme Vuarand to string subscription that deals with oldmetas that are functions. + +2006-11-08 rrt + + Stop string subscription operator from hiding other methods. + +2006-11-06 rrt + + Note that rex is now an external dependency. + + Note problem with external dependencies. + +2006-11-05 rrt + + Sort out adding to module metatables. + + Add a FIXME + + As 5.1 has all the metamethods we need, rewrite LCS to use them. Hence, no need for wrapper string.lcs. + Remove named string concat, need for which is mostly obviated by + concat metamethod. + + Remove @module from list of tags to add, as we already have it. + + Clarify Reuben's role. + + Remove rex.lua, now imported from lrexlib + + No longer need to lift std modules into global environment as they are already there. + + Remove std/ prefix for module files, and no longer include std.lua, which does nothing. + + Remove std directory, having all modules at the root, and with root names (no "std." prefix), so that stdlib can rely on external libraries, and the namespace is simplified. + + file.lua is no more + + Rewrite io.length using posix.stat and move it to io.lua. + + Move TODO from rex.lua + +2006-11-03 rrt + + No longer mention defunct bit.lua. + + Remove listable and listabled functions. This wasn't really that useful, and could confuse. + +2006-11-02 rrt + + Correct @function to @func + + Really cope with multiple params under a single @param. + + Add template for std-using scripts. + + Clarify gmatch metamethod + + Cope with multiple params under a single @param, by insisting on the : at the end. + +2006-10-30 rrt + + Fix list.concat (thanks to Avi Yagodnick for reporting the bug). + +2006-10-29 niklas + + Remove require loops by commenting out looping requires. This needs fixing properly (by permitting them). + Where possible without further change, remove the "std" prefix from + module declarations. + + Where possible, remove module prefixes from function definitions. + + Use ... in more places. + + Move pathSubscript to table.lua. + + Move assert.lua's contents to base.lua (we can't have a module called + assert, and this is in the base library in any case). + + Move function forms of operators to base.lua. + + Make headings of modules consistent (add @module lines). + + Remove io.exists, as it's dodgy, and posix.stat is much better. + Lighterweight environments are probably going to roll their own + anyway. + + Remove "zip" and "unzip" aliases for list.transpose. Add a note to the + documentation instead. + + In io.lua, remove some io. prefixes (that don't make the code less + clear) as we're already in io, and instead prefix type with _G (oops, + that's ugly). + + Improve changeSuffix, and make it use posix.dirname and + posix.basename. + + Add two functions to list module: flatten and shape, to flatten and + reshape arbitrarily nested lists. + + Add a paragraph of documentation to the top of the rex module in + preparation for lrexlib 1.20 (rex.lua will leave stdlib and move to + lrexlib). + + Add rex.gmatch (as well as adding a metatable method for rex objects). + + Update set.lua to current practices, including the (still + commented-out) metamethods. + + Probable bug-fixing in string module obscured by removal of string. + prefix from function definitions and calls. + + Make redefinitions of existing functions more consistent, and fix some + faulty ones. + + Add deepclone to table from Jamie Webb's code. + +2006-10-08 rrt + + Update to match stdlib. Remove revision history as it's in CVS, and replace version number with CVS Revision tag. + + table.getn --> # + +2006-10-01 rrt + + Remove io.readDir, as it is replaced by posix.dir. + + Remove io.dirname, as it is replaced by posix.dirname. + + Fix changeSuffix to work with paths containing dots by only operating on basename, not the whole file name. + +2006-09-18 rrt + + Fix ordering of deps + +2006-07-14 rrt + + Escape quotes and apostrophes in string.escapeShell. + + Escape square brackets too in string.escapeShell. + +2006-04-26 rrt + + Prepend redefinition of require to the output. + +2006-04-25 rrt + + Use string methods rather than functions so that the functions here work on regexs as well. Add a note to make the whole API work properly with regexs as well as Lua patterns. + + Add TODO + + Reformat and improve comments. + +2006-04-24 rrt + + Simplify assignment of retry. + + Correct name of table.filterItem (was table.mapItem). + +2006-04-15 rrt + + Reformat. + + Use variadic bit.or. + + Add table.filter and table.filterItem. Add list.filterItem and implement list.filter in terms of it. + + Fix more bugs, patch from Shmuel Zeigerman. + Call rex:flags() to inject flags into rex table. + + Remove unnecessary local line from gmatch, and initialise st to 1, not 0 (thanks to Shmuel Zeigerman). + +2006-04-10 rrt + + Reorganise libraries with simpler names + + Move all modules out of string + + Reflect simplified structure + + Move all modules out of io + + Rename io.getopt to getopt + + Rename string.xml to xml + + Add utility to make a single file stdlib + + Use env to run script and reverse Changelog order + + Rename algorithm.lcs to lcs + +2006-04-10 rrt + + Rewrite string.split to be regex-system-neutral. + Change string.findl to return from and to in list form, not {from = f, + to = t}. + + Update string.regex to Lua 5.1 vararg syntax. + + Make io.exists use stat if available. + + Add io.dirname. + +2006-04-09 rrt + + Update Lua code from Shmuel's version and write gmatch in Lua. + + Update concat to Lua 5.1 vararg syntax. + Remove flatten alias for concat, as concat doesn't flatten. + + Update to 5.1 vararg syntax + +2006-03-30 rrt + + string.gfind is now string.gmatch. + + Reactivate tests, but make them conditional on running in debug mode. + + Improve installation instructions. + + Fix mailing list address. + + Update to match reality. + + Fix handling of global arg table. + + Use new form of message-less error. + +2006-03-29 rrt + + Deal with C modules like Lua modules. + + Don't mention require for Lua 4 any more. + + Rename modules *-ext to *_ext to avoid problem with version number parser in require. + + Simplify adding functions to global table. + +2006-03-28 rrt + + Add module calls everywhere, and do some necessary renaming to avoid clashes + +2006-03-23 rrt + + Use module and require in properly 5.1-compatible way, and change module names to work better with 5.1. + This should all still work fine with 5.0 using compat-5.1.lua. + +2006-02-03 rrt + + More fixes and tests from Shmuel Zeigerman. + +2006-01-29 rrt + + Add tests from Shmuel Zeigerman, reorganised somewhat. They are run when the module is loaded. + + Rename sub to cap for clarity (Shmuel Zeigerman). + +2006-01-26 rrt + + More fixes from Shmuel to mimic string.gsub better. + +2006-01-25 rrt + + Fix endless loop when pattern is .* (bug reported by Shmuel Zeigerman). + +2006-01-24 rrt + + Cope with capture being false (Shmuel Zeigerman). + + Fix bug when n == 0 (thanks Shmuel Zeigerman), and tidy up. + +2006-01-23 rrt + + Fix from Shmuel Zeigerman to match string.gsub better: when the pattern contains no captures, pass the entire match to the replacement function. + +2006-01-22 rrt + + More bug fixes; thanks to Shmuel Zeigerman for reporting the bugs and in one case giving the fix. + +2006-01-21 rrt + + Fix bugs with %n replacements in rex.gsub + + Make rex.gsub a full gsub for rex. + +2006-01-20 rrt + + Don't escape & in entities + + Improve rex.gsub + +2006-01-17 rrt + + Escape <, > and & in XML output. + +2005-11-24 rrt + + Replace deepipairs with treeIter to iterate properly over trees. + +2005-11-23 rrt + + Remove table.filterItem, as it really only works for lists. Inline the function in list.filter. + Add table.map. + +2005-11-22 rrt + + Add XML output, assuming Lua tables created by luaexpat. + +2005-11-21 rrt + + Add generic printing framework, and use it to add prettytostring. + +2005-11-19 rrt + + Use table.process to implement list processing functions. + + Add generic table-processing function table.process and action functions for map, filter &c. + + Add two iterators: ripairs which is like ipairs, but in reverse, and deepipairs, which recurses into nested tables. + +2005-11-09 rrt + + Remove import. + + Update year to 2005. + + import has been removed. + + Fix bogus version in history + + Remove import, and instead use 5.1-style require (tested with compat-5.1.lua). + Assume a LUA_DIR of "/", hence rename files accordingly. + +2005-09-04 rrt + + Fix string.ltrim and string.rtrim to return only the advertised return value. + Fix string.trim to do what it says on the tin; it was completely + broken. + +2004-09-08 rrt + + Fix assert when called with only one argument: arg has the value {n=0} when there are no variadic arguments, not nil as I assumed. + +2004-02-17 rrt + + Comment the constructor. + + Check error return when loading file, so that if file is not found we don't abort immediately so that all LUA_PATH entries are checked. + +2004-02-05 rrt + + Tidy up abstract syntax rules: there's now only one per production. + Keep action functions for more complex rules. Looks as though we only + ever have one or the other (because simple rules don't take into + account any housekeeping info) so perhaps simplify this again. + + Make lists not have a ty field, but just be lists of whatever they + contain. + + Return false instead of nil for empty parse trees, so as not to upset + ipairs iterations over lists. + +2004-02-05 rrt + + Tidy up the code, mostly by shortening the names of frequently-used variables. + + Allow import to report errors during importing. + +2004-02-04 rrt + + Added Diego Nahab for his mbox parser. + + Added Diego Nahab's mbox parser. + +2004-02-04 rrt + + Rework the API: now has a single method exposed, parse, and the other methods have been moved inside parse as local functions. The constructor no longer takes a token list. + Also, provide support for producing an abstract parse tree rather than + the (default) concrete one. + + Full details in the all-new documentation. + +2004-02-04 rrt + + Clarify note about import and add TODO about markup tags. + +2004-02-02 rrt + + Massacre the object implementation, reverting to implementing sets as simple tables, which seems to be better for general use. A lot of the code in this file is now non-functional; I'll be making it work later, integrating it with Jamie Webb's code. The module may get folded back into table. + + Make list.map and list.filter work on lists that have nil elements. + + Fix __call metamethod. + + writeLine -> io.writeLine + + Fix io.writeLine (somehow two lines had become swapped). + + writeLine -> io.writeLine + + Various modifications prompted by Jamie Webb's submission of his own standard library. So far I have assimilated improvements that map directly on to existing code, and also removed some functions that didn't seem to be that useful. Looking at the code again provoked other miscellaneous improvements. + +2004-02-01 rrt + + In the previous commit, which had a bogus log message, I fixed io.readDir: split --> string.split. + In this one, I improved the formatting of io.readDir slightly. + + Improve spacing of comments. + + If -version is given and no command-line args, then terminate after showing the version message. + + Explain that although import is used internally, users should use require (as in README) and why. + + Removed bit._INTEGER_BITS, because it's the same as math._INTEGER_BITS. I suspect I meant to do this ages ago. + + Added a few more people I thought of. + + Formalise the README: this project is no longer just mine. + Add a list of AUTHORS: the first contributions have arrived. + + This script was trivial and wrong. + + Added math.floor and math.round, based on code from Johann Hibschman. + + Add math.floor and math.round, based on code from Johann Hibschman. + +2004-01-31 rrt + + Fix pickle: format->string.format (thanks to Johann Hibschman). + +2004-01-29 rrt + + Default the from and to parameters of list.slice to the start and end of the list respectively. + + Add primitive way to cope with missing non-standard C libraries, and a TODO to deal with missing C libraries properly. + + Fix table.newDefault to use correct name for __index metamethod. + + Improve module description in first line. + + Fix tostring to work on self-referential tables. + +2004-01-27 rrt + + Corrected misnaming of functions and added documentation. + +2004-01-26 rrt + + Add string.format extension to make it not try to format if there is only one argument. + +2004-01-25 rrt + + Update to Lua 5. This is an old change which I forgot to check in; ldoc is *not* the way forward for stdlib documentation. This checkin is just for completeness. + +2004-01-10 rrt + + *** empty log message *** + +2004-01-10 rrt + + Change "returns" lines to "@returns" for better LuaDoc-ness. + Add string.tonumbersi. + + Minor corrections and LuaDocification of some other comments. + +2003-10-22 rrt + + More Lua 5 tweaks, and a couple of minor bugfixes. + +2003-10-21 rrt + + Oops; added file with incorrect name; re-add with correct name. + + Add "import" from LTN 11 to overcome require's problem with circular dependencies. + Remove string.next, as string.gfind provides an equivalent iterator. + +2003-10-20 rrt + + More renaming for consistency, and move more code around. This introduced the first cyclic dependency between modules since I moved to Lua 5, and I've had to cure this with a C include-style trick, since Lua 5 require just overflows the stack when there's a recursive call of require. + + Add an iterator for the values in a set, and use it; methods are now organised into those that access the data structure and those that call other methods. + + Objectify the implementation, and add LuaDoc-style markup to the comments. + + Write methods outside object prototype (i.e. in more consistent form for stdlib). + +2003-10-18 rrt + + Rename std.data.logic to std.bit, as it extends the C bit library. + + Make a namespace for list routines. + + Fix bug in curry properly. + + Finish renaming in io.io. Update TODO for getopt in std.lua. + + Re-add mistakenly removed logic (I confused the ability to take multiple args with the ability to take lists). + + assert lives again! math added to hold math function extensions. + + Remove logic (no longer needed; _INTEGER_BITS moved to math, band &c. already work on lists). Various other movements and renaming of modules. + + Routines moves to std.list and std.base. + + More renaming. Remove boolean routines for when bitlib is not present. There's no excuse in Lua 5! + + Use ipairs instead of table.getn loops. + + Use pairs () instead of deprecated for "i, v in t" form. + + Rename table routines. Simplify compose. + + Renamed some libraries for Lua 5-ification reasons. + + Fix a minor bug and remove some debugging code. + +2003-10-18 rrt + + A new module (and family): algorithm, with first member algorithm.lcs, which implements the longest common subsequence algorithm needed for diff. + std.object has been reworked, and now fits much better with Lua 5, + although the interface to it is pretty much the same as before. + + Some other Lua 5-isation has been done, but not much; there's still a + lot left to do in std.data in particular. + +2003-10-13 rrt + + Fix call to writeLine (now io.writeLine). + +2003-09-28 rrt + + More Lua 5-ification changes, mostly to the io modules this time. + +2003-09-26 uid30086 + + Another round of changes for Lua 5-ification. This completes the changes to the string library (used to be the text library), and adds std.rex (complements my C rex library). Other changes are mostly to accomodate this; a few extras have snuck in. + +2003-09-25 rrt + + First set of changes moving to Lua 5-like naming conventions for the libraries. + +2003-09-15 rrt + + Use math.mod rather than bit.mod for wider compatibility. + + Wrap notes field of prog structure before output. + +2003-09-12 rrt + + More changes to update to Lua 5.0. Nearly there now, I think, as I have several scripts working! + +2003-09-11 rrt + + Another few search-and-replace function names to update to Lua 5. Mostly string functions this time. + +2003-09-10 rrt + + More search-and-replace and wholesale code removal (notably POSIX getopt) for Lua 5. + + Another swathe of Lua 5 updates. Now my little script that I'm testing nearly works, which means that quite a lot of the code in the libraries is at least vaguely correct! + +2003-09-09 rrt + + A slew of updates in the march to Lua-5-ify the libraries. I've just been working on a particular small script and changing things "on demand", and I've not even managed to make the script work yet, so there's almost certainly a lot of work still to go. + +2003-06-04 rrt + + Convert to Lua 5.0, and some slight tidying. + + Do TODOs for Lua 5 (use "le" tagmethod -- will have to become a metamethod) and ability to force a function to return only one result. + + Update std.patch40 to std.patch50 for Lua 5. Now none of the other modules need it. + + Make readDir return an unsorted list of files. Unfortunately, -U isn't supported by ls on all platforms. + +2003-03-14 rrt + + Update to match new directory structure (rather overdue!). + +2003-01-06 rrt + + Use endOfLine in chomp and wrap. + +2002-10-18 rrt + + Removed std.logic; now folded into std.data.logic + + std.logic now merged into std.data.logic. + + Merge the two logic modules. + +2002-09-28 rrt + + Add tabulate function to use tabulator methods, and use it. + +2002-09-10 rrt + + Sigh. New bnot didn't work. Next time I'll think and test rather better before straying from the path of righteousness. + + I was being very dim about bnot. Oops. Roberto pointed it out. I hang my head in shame. + + Revert to previous version to avoid losing precision (specifically, LSB). + + Shorter implementation of bxor, and bnot thanks to a remark by Paul Hsieh on lual (Message-Id: <0H26009OMQ9J59@mta5.snfc21.pbi.net>). + Kept band (as the primitive to make bxor) and bor (because de + Morganising it would involve a call to bnot and two to band, hence + making it three times slower). + +2002-09-09 rrt + + Poor man's logic functions (for those who can't use bitlib). Also calculate the number of bits in the word. + + Add std.logic + +2002-09-06 rrt + + Improve layout of usage message when no command line options (don't have trailing blank line). + +2002-09-05 rrt + + Add withFileOrHandle, which takes a filename, handle or uses a default handle, opens the file if appropriate, and passes the handle to a given function. + Use it to generalise readLines and readFile. + + It's tempting to generalise writeLine too, but writeLine ("foo", "bar") is + ambiguous: do we want to write "foo" and "bar" to _OUTPUT, or "bar" to + file "foo"? + +2002-09-05 rrt + + Make patches work with any version that starts with "Lua 4.0", to cope with 4.0.1 and any future point releases. + Replace unpack with a recursive version (based on code from John + Belmonte) that copes with any number of values. + + Change "key" to "index" everywhere for consistency. + + Improve comments for tinvert + + Change intersect tag method to division, and add TODO to implement proper subset tagmethod in Lua 5.0. + + Rename intersect to setintersect for consistency, and define setunion (= merge). + +2002-08-28 rrt + + Allow stringifier methods again, but they are now only used by tostring. Allows more cosmetic stringification, while not stopping pickling from working. + +2002-08-27 rrt + + Don't need stringify and pickler tables any more, and tostring and pickle can be simplified. They both use tabulator where necessary. + + Remove interaction between pickle and tostring, which is no longer needed, as they both now use tabulator methods where necessary. + + Add tabulator method table for turning arbitrary objects (typically tagged userdata) into tables. Use this to finally fix tostring and pickle. Oh, yes. + +2002-08-23 rrt + + A last gamble. Then I'll have to sit down and work it out again. + + Another desperate attempt. + + Fix up. I hope. This is starting to drive me insane. + + Typo. + + Fix default case for pickling. + + Fix typo. + + More fixes. + + More fixes to pickling. I got in a pickle with this one. + + Make pickling work properly on numbers and nil by having a "self" parameter for stringifier and pickler functions. They're more like classes now. + + Fix buglet (can't concat to nil). + + Make pickle work for numbers and nil. + + Add tinvert, and update some comments to LDoc format. + +2002-08-22 rrt + + Correct call of warn to expand arg list. + +2002-08-15 rrt + + Add utility for making zip dist of stdlib. + + Add empty to test whether a table is. + + Fix paths for new directory structure and get rid of one or two gremlins. + + Finish editing std.cfg into new form (configuration file with require implementation tacked on the end) and rename it. + + Update some TODOs. + + Rename std->modules and remove stray std.lua + + Standardize code style, and make changes (mostly to the comments) to prepare for renaming to std.config, as per John's suggestion. This file will only secondarily contain require, and will typically be built into the Lua system anyway. When we move to Lua 5.0, require will disappear, anyway. + + John Belmonte's replacement require implementation (5.0-compatible). + + Reorganise directory structure to a flat directory, to cope with Lua 5.0 require patterns (so that the libraries can be loaded without making assumptions about directory separators). + +2002-08-13 rrt + + Add the format library to text. + + Fix buglet in warn. + + Move some functions to format.lua to avoid dependency loop text<->assert and to make way for the new pretty printing functions described in a big TODO in format.lua. + Override format in text, so that if it's only passed one argument, it + just returns it. + + Use capability of warn to take format arguments. + +2002-08-13 rrt + + Rename affirm to assert, and pass its arguments to the new format function. + Remove the *f functions (which called format); these were unused. Now + warn, die and assert can all take format arguments. + + affirm->assert in file.lua + +2002-08-13 rrt + + Correct punctuation. + + Fix a typo loading pickle.lua in text.lua + Make pickle escape characters in strings that need it + + Restructure stringifying so that functions in stringifier can produce either a string or a table of stringified index = stringified value pairs. + Use this to write a simple pickle function that can pickle anything + that tostring can stringify. pickle and tostring are now effectively + just different renderers for the functions in stringifier. + + Fix spacing in comments. + +2002-08-12 rrt + + Allow new tostring methods to be registered. + + *** empty log message *** + + Debug defaultTable so it uses the initial value given rather than always creating an empty table. + + Add defaultTable to macro. + Move lookup to macro, reimplement it in terms of foldl and subscript, + and reimplement pathSubscript in terms of it. + + Add a logic module to extend band, bor and bxor to lists (just listable them). + + Comment list.lua in ldoc format. The other modules will probably follow. + + Include the new macro module. + + Move pathSubscript out of table.lua to avoid a circular dependency, into the new macro.lua module, which also includes some material moved from global.lua. + +2002-08-01 rrt + + Move print from assert to debug. This not only makes sense, but breaks a recursive dependency between assert and text/text. + +2002-07-31 rrt + + Remove require for now-defunct time.lua, and tidy up the TODOs. + + Correct endofLine -> endOfLine again; this must have crept back in with the last diff. Using CVS everywhere rather than manual copying will be a Good Thing in this respect! + +2002-07-30 rrt + + Generalised daySuffix to ordinalSuffix. Still English-specific :-( + +2002-07-27 rrt + + Improve comment for mapIter + +2002-07-26 rrt + + Add constant, a constant function generator. + + Use pathSubscript in methodify to allow more convenient macroization of tables. + + A simple documentation extracter, relying completely on specially formatted comments. There's no documentation at the moment except the patterns in the program, which should be obvious! I'll ldocify all the code shortly and check in instructions with it. + This tool is provisional, and subject to improvement. The TODOs in the + file indicate some of my first thoughts in that direction. + +2002-07-24 rrt + + Move methodify to table.lua where it belongs (it has nothing to do with lists!) + + Allow scripts to have no arguments. If you want to display help when just the script is run with no arguments, you'll have to do it manually. + + Throw away stderr from shell commands (we don't expect the output to clutter up the screen; it's always possible to capture it by adding a redirection to the command, which will override the one we add). + + Add subscript, which exposes [] as a function. + +2002-06-22 rrt + + Correct endofLine -> endOfLine + + Initial revision diff --git a/GNUmakefile b/GNUmakefile index 25122be..492ce1e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,88 +1,38 @@ ## maintainer rules. -dont-forget-to-bootstrap = $(wildcard Makefile) +ME = GNUmakefile -ifeq ($(dont-forget-to-bootstrap),) +# If the user runs GNU make but didn't ./configure yet, do it for them. +dont-forget-to-bootstrap = $(wildcard Makefile.in) -Makefile: Makefile.in - ./configure - $(MAKE) +ifeq ($(dont-forget-to-bootstrap),) -Makefile.in: - autoreconf --force --verbose --install +%:: + @echo '$(ME): rebootstrap' + @test -f Makefile.in || ./bootstrap + @test -f Makefile || ./configure + $(MAKE) $@ else -# Use 'make check V=1' for verbose output, or set SPECL_OPTS to -# pass alternative options to specl command. -SPECL_OPTS ?= $(specl_verbose_$(V)) -specl_verbose_ = $(specl_verbose_$(AM_DEFAULT_VERBOSITY)) -specl_verbose_0 = -specl_verbose_1 = --verbose --formatter=report - -include Makefile - -ROCKSPEC_ENV = $(LUA_ENV) -MKROCKSPECS = $(ROCKSPEC_ENV) $(LUA) $(srcdir)/mkrockspecs.lua -ROCKSPEC_TEMPLATE = $(srcdir)/$(PACKAGE)-rockspec.lua -luarocks-config.lua: - $(AM_V_GEN){ \ - echo 'rocks_trees = {'; \ - echo ' "$(abs_srcdir)/luarocks"'; \ - echo '}'; \ - } > '$@' +include build-aux/release.mk +include build-aux/sanity.mk -rockspecs: luarocks-config.lua - rm -f *.rockspec - $(MKROCKSPECS) $(PACKAGE) $(VERSION) $(ROCKSPEC_TEMPLATE) - $(MKROCKSPECS) $(PACKAGE) git $(ROCKSPEC_TEMPLATE) +# Run sanity checks as part of distcheck. +distcheck: $(local-check) -GIT ?= git +## ------ ## +## Specl. ## +## ------ ## -tag-release: - $(GIT) diff --exit-code && \ - $(GIT) tag -f -a -m "Release tag" v$(VERSION) - -define unpack-distcheck-release - rm -rf $(PACKAGE)-$(VERSION)/ && \ - tar zxf ../$(PACKAGE)/$(PACKAGE)-$(VERSION).tar.gz && \ - cp -a -f $(PACKAGE)-$(VERSION)/* . && \ - rm -rf $(PACKAGE)-$(VERSION)/ && \ - echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ - echo './configure && make all rockspecs' && \ - ./configure --version && ./configure && \ - $(MAKE) all rockspecs -endef - -check-in-release: distcheck - cd ../$(PACKAGE)-release && \ - $(unpack-distcheck-release) && \ - $(GIT) add . && \ - $(GIT) commit -a -m "Release v$(VERSION)" && \ - $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION) - - -## To test the release process without publishing upstream, use: -## make release WOGER=: GIT_PUBLISH=: -GIT_PUBLISH ?= $(GIT) -WOGER ?= woger +# Use 'make check V=1' for verbose output, or set SPECL_OPTS to +# pass alternative options to specl command. -WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' -WOGER_OUT = $(WOGER_ENV) $(LUA) -l$(PACKAGE) -e +SPECL_OPTS ?= $(specl_verbose_$(V)) +specl_verbose_ = $(specl_verbose_$(AM_DEFAULT_VERBOSITY)) +specl_verbose_0 = +specl_verbose_1 = --verbose --formatter=report -release: rockspecs - $(MAKE) tag-release && \ - $(MAKE) check-in-release && \ - $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ - LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks \ - --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-1.rockspec && \ - $(WOGER) lua \ - package=$(PACKAGE) \ - package_name=$(PACKAGE_NAME) \ - version=$(VERSION) \ - notes=release-notes-$(VERSION) \ - home="`$(WOGER_OUT) 'print (description.homepage)'`" \ - description="`$(WOGER_OUT) 'print (description.summary)'`" endif diff --git a/INSTALL b/INSTALL index 7d1c323..64c6937 100644 --- a/INSTALL +++ b/INSTALL @@ -362,4 +362,3 @@ operates. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. - diff --git a/Makefile b/Makefile deleted file mode 100644 index 59f4b80..0000000 --- a/Makefile +++ /dev/null @@ -1,789 +0,0 @@ -# Makefile.in generated by automake 1.13.1 from Makefile.am. -# Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994-2012 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - - -am__make_dryrun = \ - { \ - am__dry=no; \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ - esac; \ - test $$am__dry = yes; \ - } -pkgdatadir = $(datadir)/stdlib -pkgincludedir = $(includedir)/stdlib -pkglibdir = $(libdir)/stdlib -pkglibexecdir = $(libexecdir)/stdlib -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = . -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) \ - $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ - $(dist_modules_DATA) AUTHORS INSTALL README \ - build-aux/install-sh build-aux/missing \ - $(top_srcdir)/build-aux/install-sh \ - $(top_srcdir)/build-aux/missing -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ - $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/m4/ax_with_prog.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_$(V)) -am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -am__v_at_1 = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" \ - "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)" -DATA = $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ - $(dist_modules_DATA) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing aclocal-1.13 -AMTAR = $${TAR-tar} -AM_DEFAULT_VERBOSITY = 0 -AUTOCONF = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing autoconf -AUTOHEADER = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing autoheader -AUTOMAKE = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing automake-1.13 -AWK = awk -CYGPATH_W = echo -DEFS = -DPACKAGE_NAME=\"stdlib\" -DPACKAGE_TARNAME=\"stdlib\" -DPACKAGE_VERSION=\"34.1\" -DPACKAGE_STRING=\"stdlib\ 34.1\" -DPACKAGE_BUGREPORT=\"rrt@sc3d.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"stdlib\" -DVERSION=\"34.1\" -ECHO_C = \c -ECHO_N = -ECHO_T = -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -LIBOBJS = -LIBS = -LTLIBOBJS = -LUA = /usr/local/bin/lua -LUADOC = /usr/local/bin/luadoc -LUA_EXEC_PREFIX = ${exec_prefix} -LUA_MIN_VERSION = 5.1 -LUA_PLATFORM = unknown -LUA_PREFIX = ${prefix} -LUA_SHORT_VERSION = 51 -LUA_VERSION = 5.1 -MAKEINFO = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/missing makeinfo -MKDIR_P = build-aux/install-sh -c -d -PACKAGE = stdlib -PACKAGE_BUGREPORT = rrt@sc3d.org -PACKAGE_NAME = stdlib -PACKAGE_STRING = stdlib 34.1 -PACKAGE_TARNAME = stdlib -PACKAGE_URL = -PACKAGE_VERSION = 34.1 -PATH_SEPARATOR = : -SET_MAKE = -SHELL = /bin/sh -STRIP = -VERSION = 34.1 -abs_builddir = /Users/gary/Devo/stdlib-release -abs_srcdir = /Users/gary/Devo/stdlib-release -abs_top_builddir = /Users/gary/Devo/stdlib-release -abs_top_srcdir = /Users/gary/Devo/stdlib-release -am__leading_dot = . -am__tar = $${TAR-tar} chof - "$$tardir" -am__untar = $${TAR-tar} xf - -bindir = ${exec_prefix}/bin -build_alias = -builddir = . -datadir = ${datarootdir} -datarootdir = ${prefix}/share -docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} -dvidir = ${docdir} -exec_prefix = ${prefix} -host_alias = -htmldir = ${docdir} -includedir = ${prefix}/include -infodir = ${datarootdir}/info -install_sh = ${SHELL} /Users/gary/Devo/stdlib-release/build-aux/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localedir = ${datarootdir}/locale -localstatedir = ${prefix}/var -luadir = ${prefix}/share/lua/5.1 -luaexecdir = ${exec_prefix}/lib/lua/5.1 -mandir = ${datarootdir}/man -mkdir_p = $(MKDIR_P) -oldincludedir = /usr/include -pdfdir = ${docdir} -pkgluadir = ${luadir}/stdlib -pkgluaexecdir = ${luaexecdir}/stdlib -prefix = /usr/local -program_transform_name = s,x,x, -psdir = ${docdir} -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -srcdir = . -sysconfdir = ${prefix}/etc -target_alias = -top_build_prefix = -top_builddir = . -top_srcdir = . -ACLOCAL_AMFLAGS = -I m4 -src_spec = $(abs_srcdir)/src/?.lua -LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPEC_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPECL_MIN = 3 -NOTHING_ELSE = -SOURCES = \ - src/base.lua \ - src/bin.lua \ - src/debug_ext.lua \ - src/debug_init.lua \ - src/fstable.lua \ - src/getopt.lua \ - src/io_ext.lua \ - src/lcs.lua \ - src/list.lua \ - src/math_ext.lua \ - src/mbox.lua \ - src/modules.lua \ - src/object.lua \ - src/package_ext.lua \ - src/parser.lua \ - src/set.lua \ - src/std.lua \ - src/strbuf.lua \ - src/strict.lua \ - src/string_ext.lua \ - src/table_ext.lua \ - src/tree.lua \ - src/xml.lua \ - $(NOTHING_ELSE) - -SPECS = \ - $(srcdir)/specs/getopt_spec.yaml \ - $(srcdir)/specs/package_ext_spec.yaml \ - $(srcdir)/specs/string_ext_spec.yaml \ - $(srcdir)/specs/table_ext_spec.yaml \ - $(NOTHING_ELSE) - -dist_data_DATA = $(SOURCES) -dist_doc_DATA = \ - $(top_srcdir)/src/index.html \ - $(top_srcdir)/src/luadoc.css - -filesdir = $(docdir)/files -dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) -modulesdir = $(docdir)/modules -dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) -EXTRA_DIST = \ - src/std.lua.in \ - GNUmakefile \ - $(SPECS) \ - $(NOTHING_ELSE) - -DISTCLEANFILES = $(PACKAGE).rockspec -all: all-am - -.SUFFIXES: -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): -install-dist_dataDATA: $(dist_data_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(datadir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(datadir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(datadir)" || exit $$?; \ - done - -uninstall-dist_dataDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(datadir)'; $(am__uninstall_files_from_dir) -install-dist_docDATA: $(dist_doc_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ - done - -uninstall-dist_docDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) -install-dist_filesDATA: $(dist_files_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(filesdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(filesdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(filesdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(filesdir)" || exit $$?; \ - done - -uninstall-dist_filesDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(filesdir)'; $(am__uninstall_files_from_dir) -install-dist_modulesDATA: $(dist_modules_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(modulesdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(modulesdir)" || exit $$?; \ - done - -uninstall-dist_modulesDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local -check: check-am -all-am: Makefile $(DATA) -installdirs: - for dir in "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-dist_dataDATA install-dist_docDATA \ - install-dist_filesDATA install-dist_modulesDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ - uninstall-dist_filesDATA uninstall-dist_modulesDATA - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am \ - check-local clean clean-cscope clean-generic cscope \ - cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-generic distclean-tags \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dist_dataDATA install-dist_docDATA \ - install-dist_filesDATA install-dist_modulesDATA install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-dist_dataDATA uninstall-dist_docDATA \ - uninstall-dist_filesDATA uninstall-dist_modulesDATA - - -LUA_PATH ?= ; - -# In order to avoid regenerating std.lua at configure time, which -# causes the documentation to be rebuilt and hence requires users to -# have luadoc installed, put src/std.lua in as a Makefile dependency. -# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) -src/std.lua: src/std.lua.in - ./config.status --file=$@ - -$(dist_doc_DATA): $(SOURCES) - cd src && $(LUADOC) *.lua - -check-local: - @v=`specl --version | sed -e 's|^.* ||' -e 1q`; \ - if test "$$v" -lt "$(SPECL_MIN)"; then \ - echo "ERROR: Specl version $$v is too old, please upgrade to at least version $(SPECL_MIN),";\ - echo "ERROR: and rerun \`make check\`"; \ - exit 1; \ - else \ - $(SPEC_ENV) specl $(SPECL_OPTS) $(SPECS); \ - fi - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/Makefile.am b/Makefile.am index e3c07a3..96dccbb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,84 +1,73 @@ -## Process this file with automake to produce Makefile.in +# Non-recursive Make rules. +# +# Copyright (C) 2013 Gary V. Vaughan +# Written by Gary V. Vaughan, 2013 +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . -ACLOCAL_AMFLAGS = -I m4 -src_spec = $(abs_srcdir)/src/?.lua +## ------------ ## +## Environment. ## +## ------------ ## LUA_PATH ?= ; -LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPEC_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" - -SPECL_MIN = 3 - -NOTHING_ELSE = - -SOURCES = \ - src/base.lua \ - src/bin.lua \ - src/debug_ext.lua \ - src/debug_init.lua \ - src/fstable.lua \ - src/getopt.lua \ - src/io_ext.lua \ - src/lcs.lua \ - src/list.lua \ - src/math_ext.lua \ - src/mbox.lua \ - src/modules.lua \ - src/object.lua \ - src/package_ext.lua \ - src/parser.lua \ - src/set.lua \ - src/std.lua \ - src/strbuf.lua \ - src/strict.lua \ - src/string_ext.lua \ - src/table_ext.lua \ - src/tree.lua \ - src/xml.lua \ - $(NOTHING_ELSE) -SPECS = \ - $(srcdir)/specs/getopt_spec.yaml \ - $(srcdir)/specs/package_ext_spec.yaml \ - $(srcdir)/specs/string_ext_spec.yaml \ - $(srcdir)/specs/table_ext_spec.yaml \ - $(NOTHING_ELSE) -dist_data_DATA = $(SOURCES) +## ---------- ## +## Bootstrap. ## +## ---------- ## -dist_doc_DATA = \ - $(top_srcdir)/src/index.html \ - $(top_srcdir)/src/luadoc.css -filesdir = $(docdir)/files -dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) -modulesdir = $(docdir)/modules -dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) +ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = \ - src/std.lua.in \ - GNUmakefile \ - $(SPECS) \ - $(NOTHING_ELSE) -DISTCLEANFILES = $(PACKAGE).rockspec - -# In order to avoid regenerating std.lua at configure time, which -# causes the documentation to be rebuilt and hence requires users to -# have luadoc installed, put src/std.lua in as a Makefile dependency. -# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) -src/std.lua: src/std.lua.in - ./config.status --file=$@ - -$(dist_doc_DATA): $(SOURCES) - cd src && $(LUADOC) *.lua - -check-local: - @v=`specl --version | sed -e 's|^.* ||' -e 1q`; \ - if test "$$v" -lt "$(SPECL_MIN)"; then \ - echo "ERROR: Specl version $$v is too old, please upgrade to at least version $(SPECL_MIN),";\ - echo "ERROR: and rerun \`make check\`"; \ - exit 1; \ - else \ - $(SPEC_ENV) specl $(SPECL_OPTS) $(SPECS); \ - fi +## ------------- ## +## Declarations. ## +## ------------- ## + +EXTRA_DIST = +CLEANFILES = +DISTCLEANFILES = +MAINTAINERCLEANFILES = +NOTHING_ELSE = + +bin_SCRIPTS = +check_local = +install_exec_hooks = +man_MANS = + +include local.mk +include build-aux/rockspecs.mk + + +## ------------ ## +## Local Tests. ## +## ------------ ## + +check-local: $(check_local) + + +## ------------- ## +## Installation. ## +## ------------- ## + +install-exec-hook: $(install_exec_hooks) + + +## ------------- ## +## Distribution. ## +## ------------- ## + +EXTRA_DIST += \ + README.md \ + $(NOTHING_ELSE) diff --git a/Makefile.in b/Makefile.in index 24b9991..2e81a3f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,6 +14,95 @@ @SET_MAKE@ +# Non-recursive Make rules. +# +# Copyright (C) 2013 Gary V. Vaughan +# Written by Gary V. Vaughan, 2013 +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Local Make rules. + +# lua-stdlib make rules. + +# Specl specs make rules. + +# Slingshot specl rules for make. + +# This file is distributed with Slingshot, and licensed under the +# terms of the MIT license reproduced below. + +# ==================================================================== # +# Copyright (C) 2013 Gary V. Vaughan # +# # +# Permission is hereby granted, free of charge, to any person # +# obtaining a copy of this software and associated documentation # +# files (the "Software"), to deal in the Software without restriction, # +# including without limitation the rights to use, copy, modify, merge, # +# publish, distribute, sublicense, and/or sell copies of the Software, # +# and to permit persons to whom the Software is furnished to do so, # +# subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be # +# included in all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # +# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # +# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +# ==================================================================== # + +# To use this file create a list of your spec files in specl_SPECS +# and then include this make fragment. + +# Slingshot rockspec rules for make. + +# This file is distributed with Slingshot, and licensed under the +# terms of the MIT license reproduced below. + +# ==================================================================== # +# Copyright (C) 2013 Reuben Thomas and Gary V. Vaughan # +# # +# Permission is hereby granted, free of charge, to any person # +# obtaining a copy of this software and associated documentation # +# files (the "Software"), to deal in the Software without restriction, # +# including without limitation the rights to use, copy, modify, merge, # +# publish, distribute, sublicense, and/or sell copies of the Software, # +# and to permit persons to whom the Software is furnished to do so, # +# subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be # +# included in all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # +# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # +# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +# ==================================================================== # + +# This file is suitable for use from a portable Makefile, you might +# include it into the top-level Makefile.am with: +# +# include build-aux/rockspecs.mk + + VPATH = @srcdir@ am__make_dryrun = \ { \ @@ -48,43 +137,28 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -subdir = . -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/configure $(am__configure_deps) \ - $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ - $(dist_modules_DATA) AUTHORS INSTALL README \ +DIST_COMMON = $(srcdir)/local.mk $(srcdir)/std/std.mk \ + $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk \ + $(srcdir)/build-aux/rockspecs.mk $(srcdir)/Makefile.in \ + $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(srcdir)/travis.yml.in $(dist_doc_DATA) \ + $(dist_files_DATA) $(dist_lua_DATA) $(dist_modules_DATA) \ + $(nobase_dist_lua_DATA) AUTHORS ChangeLog INSTALL NEWS \ build-aux/install-sh build-aux/missing \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/missing +subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ - $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/m4/ax_with_prog.m4 \ + $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/m4/slingshot.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = +CONFIG_CLEAN_FILES = .travis.yml CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -112,31 +186,32 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" \ - "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)" -DATA = $(dist_data_DATA) $(dist_doc_DATA) $(dist_files_DATA) \ - $(dist_modules_DATA) +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(luadir)" \ + "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(luadir)" +SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(dist_doc_DATA) $(dist_files_DATA) $(dist_lua_DATA) \ + $(dist_modules_DATA) $(nobase_dist_lua_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -166,6 +241,9 @@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXTRA_ROCKS = @EXTRA_ROCKS@ +GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -176,8 +254,8 @@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ LUA = @LUA@ LUADOC = @LUADOC@ +LUADOC_FALSE = @LUADOC_FALSE@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ -LUA_MIN_VERSION = @LUA_MIN_VERSION@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ @@ -192,8 +270,11 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SPECL = @SPECL@ +SPECL_MIN = @SPECL_MIN@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ @@ -240,66 +321,87 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 -src_spec = $(abs_srcdir)/src/?.lua -LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPEC_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" -SPECL_MIN = 3 +EXTRA_DIST = std/std.lua.in $(NOTHING_ELSE) $(specl_SPECS) \ + $(NOTHING_ELSE) $(mkrockspecs) $(package_rockspec) \ + $(rockspec_conf) $(NOTHING_ELSE) README.md $(NOTHING_ELSE) +CLEANFILES = +DISTCLEANFILES = $(luarocks_config) $(NOTHING_ELSE) +MAINTAINERCLEANFILES = NOTHING_ELSE = -SOURCES = \ - src/base.lua \ - src/bin.lua \ - src/debug_ext.lua \ - src/debug_init.lua \ - src/fstable.lua \ - src/getopt.lua \ - src/io_ext.lua \ - src/lcs.lua \ - src/list.lua \ - src/math_ext.lua \ - src/mbox.lua \ - src/modules.lua \ - src/object.lua \ - src/package_ext.lua \ - src/parser.lua \ - src/set.lua \ - src/std.lua \ - src/strbuf.lua \ - src/strict.lua \ - src/string_ext.lua \ - src/table_ext.lua \ - src/tree.lua \ - src/xml.lua \ +bin_SCRIPTS = +check_local = specl-check-local +install_exec_hooks = +man_MANS = +std_path = $(abs_srcdir)/?.lua;$(abs_srcdir)/std/?.lua +LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" +old_NEWS_hash = dfde3c0c6163db72d47538ad8711607c +filesdir = $(docdir)/files +modulesdir = $(docdir)/modules +dist_doc_DATA = $(srcdir)/std/index.html $(srcdir)/std/luadoc.css +dist_files_DATA = $(wildcard $(srcdir)/std/files/*.html) +dist_modules_DATA = $(wildcard $(srcdir)/std/modules/*.html) +nobase_dist_lua_DATA = \ + std/base.lua \ + std/debug_ext.lua \ + std/debug_init.lua \ + std/getopt.lua \ + std/io_ext.lua \ + std/list.lua \ + std/math_ext.lua \ + std/modules.lua \ + std/object.lua \ + std/package_ext.lua \ + std/set.lua \ + std/strbuf.lua \ + std/strict.lua \ + std/string_ext.lua \ + std/table_ext.lua \ + std/tree.lua \ + $(NOTHING_ELSE) + +dist_lua_DATA = \ + std/std.lua \ $(NOTHING_ELSE) -SPECS = \ +SPECL_ENV = $(LUA_ENV) +specl_SPECS = \ + $(srcdir)/specs/debug_ext_spec.yaml \ $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/io_ext_spec.yaml \ + $(srcdir)/specs/math_ext_spec.yaml \ $(srcdir)/specs/package_ext_spec.yaml \ $(srcdir)/specs/string_ext_spec.yaml \ $(srcdir)/specs/table_ext_spec.yaml \ $(NOTHING_ELSE) -dist_data_DATA = $(SOURCES) -dist_doc_DATA = \ - $(top_srcdir)/src/index.html \ - $(top_srcdir)/src/luadoc.css - -filesdir = $(docdir)/files -dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) -modulesdir = $(docdir)/modules -dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) -EXTRA_DIST = \ - src/std.lua.in \ - GNUmakefile \ - $(SPECS) \ +luarocks_config = build-aux/luarocks-config.lua +rockspec_conf = $(srcdir)/rockspec.conf +mkrockspecs = $(srcdir)/build-aux/mkrockspecs +package_rockspec = $(srcdir)/$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec +scm_rockspec = $(PACKAGE)-git-$(rockspec_revision).rockspec + +# If you need a different rockspec revision, override this on the make +# command line: +# +# make rockspecs rockspec_revision=2 +rockspec_revision = 1 +LUAROCKS = luarocks +MKROCKSPECS = $(MKROCKSPECS_ENV) $(LUA) $(mkrockspecs) +ROCKSPECS_DEPS = \ + $(luarocks_config) \ + $(mkrockspecs) \ + $(rockspec_conf) \ $(NOTHING_ELSE) -DISTCLEANFILES = $(PACKAGE).rockspec +set_LUA_BINDIR = LUA_BINDIR=`which $(LUA) |$(SED) 's|/[^/]*$$||'` +LUA_INCDIR = `cd $$LUA_BINDIR/../include && pwd` +LUA_LIBDIR = `cd $$LUA_BINDIR/../lib && pwd` all: all-am .SUFFIXES: am--refresh: Makefile @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/local.mk $(srcdir)/std/std.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -322,6 +424,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; +$(srcdir)/local.mk $(srcdir)/std/std.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk: $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck @@ -331,27 +434,43 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): -install-dist_dataDATA: $(dist_data_DATA) +.travis.yml: $(top_builddir)/config.status $(srcdir)/travis.yml.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) - @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(datadir)" || exit 1; \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(datadir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(datadir)" || exit $$?; \ - done - -uninstall-dist_dataDATA: + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) - @list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(datadir)'; $(am__uninstall_files_from_dir) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ @@ -394,6 +513,27 @@ uninstall-dist_filesDATA: @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(filesdir)'; $(am__uninstall_files_from_dir) +install-dist_luaDATA: $(dist_lua_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_lua_DATA)'; test -n "$(luadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(luadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(luadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(luadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(luadir)" || exit $$?; \ + done + +uninstall-dist_luaDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_lua_DATA)'; test -n "$(luadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(luadir)'; $(am__uninstall_files_from_dir) install-dist_modulesDATA: $(dist_modules_DATA) @$(NORMAL_INSTALL) @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ @@ -415,65 +555,36 @@ uninstall-dist_modulesDATA: @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) +install-nobase_dist_luaDATA: $(nobase_dist_lua_DATA) + @$(NORMAL_INSTALL) + @list='$(nobase_dist_lua_DATA)'; test -n "$(luadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(luadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(luadir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(luadir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(luadir)/$$dir"; }; \ + echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(luadir)/$$dir'"; \ + $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(luadir)/$$dir" || exit $$?; }; \ + done -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files +uninstall-nobase_dist_luaDATA: + @$(NORMAL_UNINSTALL) + @list='$(nobase_dist_lua_DATA)'; test -n "$(luadir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(luadir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) @@ -634,9 +745,9 @@ distcleancheck: distclean check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am -all-am: Makefile $(DATA) +all-am: Makefile $(SCRIPTS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(datadir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(modulesdir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(luadir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -661,6 +772,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -670,6 +782,7 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am @@ -677,7 +790,7 @@ clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags +distclean-am: clean-am distclean-generic dvi: dvi-am @@ -691,15 +804,17 @@ info: info-am info-am: -install-data-am: install-dist_dataDATA install-dist_docDATA \ - install-dist_filesDATA install-dist_modulesDATA +install-data-am: install-dist_docDATA install-dist_filesDATA \ + install-dist_luaDATA install-dist_modulesDATA \ + install-nobase_dist_luaDATA install-dvi: install-dvi-am install-dvi-am: -install-exec-am: - +install-exec-am: install-binSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: @@ -738,52 +853,89 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dist_dataDATA uninstall-dist_docDATA \ - uninstall-dist_filesDATA uninstall-dist_modulesDATA +uninstall-am: uninstall-binSCRIPTS uninstall-dist_docDATA \ + uninstall-dist_filesDATA uninstall-dist_luaDATA \ + uninstall-dist_modulesDATA uninstall-nobase_dist_luaDATA -.MAKE: check-am install-am install-strip +.MAKE: check-am install-am install-exec-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am \ - check-local clean clean-cscope clean-generic cscope \ - cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ +.PHONY: all all-am am--refresh check check-am check-local clean \ + clean-generic cscopelist-am ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-generic distclean-tags \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dist_dataDATA install-dist_docDATA \ - install-dist_filesDATA install-dist_modulesDATA install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-dist_dataDATA uninstall-dist_docDATA \ - uninstall-dist_filesDATA uninstall-dist_modulesDATA + distcheck distclean distclean-generic distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binSCRIPTS install-data \ + install-data-am install-dist_docDATA install-dist_filesDATA \ + install-dist_luaDATA install-dist_modulesDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-hook \ + install-html install-html-am install-info install-info-am \ + install-man install-nobase_dist_luaDATA install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-binSCRIPTS uninstall-dist_docDATA \ + uninstall-dist_filesDATA uninstall-dist_luaDATA \ + uninstall-dist_modulesDATA uninstall-nobase_dist_luaDATA LUA_PATH ?= ; # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to -# have luadoc installed, put src/std.lua in as a Makefile dependency. +# have luadoc installed, put std/std.lua in as a Makefile dependency. # (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) -src/std.lua: src/std.lua.in +std/std.lua: std/std.lua.in ./config.status --file=$@ -$(dist_doc_DATA): $(SOURCES) - cd src && $(LUADOC) *.lua - -check-local: - @v=`specl --version | sed -e 's|^.* ||' -e 1q`; \ - if test "$$v" -lt "$(SPECL_MIN)"; then \ - echo "ERROR: Specl version $$v is too old, please upgrade to at least version $(SPECL_MIN),";\ - echo "ERROR: and rerun \`make check\`"; \ - exit 1; \ - else \ - $(SPEC_ENV) specl $(SPECL_OPTS) $(SPECS); \ +$(dist_doc_DATA): $(nobase_dist_lua_DATA) + cd $(srcdir)/std && $(LUADOC) *.lua +specl-check-local: $(specl_SPECS) + @v=`$(SPECL) --version | sed -e 's|^.* ||' -e 1q`; \ + if test "$$v" -lt "$(SPECL_MIN)"; then \ + printf "%s%s\n%s\n" \ + "ERROR: Specl version $$v is too old," \ + " please upgrade to at least version $(SPECL_MIN)," \ + "ERROR: and rerun \`make check\`"; \ + exit 1; \ + else \ + $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS); \ fi +$(luarocks_config): Makefile.am + @test -d build-aux || mkdir build-aux + $(AM_V_GEN){ \ + $(set_LUA_BINDIR); \ + echo 'rocks_trees = { "$(abs_srcdir)/luarocks" }'; \ + echo 'variables = {'; \ + echo ' LUA = "$(LUA)",'; \ + echo ' LUA_BINDIR = "'$$LUA_BINDIR'",'; \ + echo ' LUA_INCDIR = "'$(LUA_INCDIR)'",'; \ + echo ' LUA_LIBDIR = "'$(LUA_LIBDIR)'",'; \ + echo '}'; \ + } > '$@' + +$(package_rockspec): $(ROCKSPECS_DEPS) + $(AM_V_at)rm -f '$@' 2>/dev/null || : + $(AM_V_GEN)test -f '$@' || \ + $(MKROCKSPECS) $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' + $(AM_V_at)$(LUAROCKS) lint '$@' + +$(scm_rockspec): $(ROCKSPECS_DEPS) + $(AM_V_at)rm '$@' 2>/dev/null || : + $(AM_V_GEN)test -f '$@' || \ + $(MKROCKSPECS) $(PACKAGE) git 1 > '$@' + $(AM_V_at)$(LUAROCKS) lint '$@' + +.PHONY: rockspecs +rockspecs: + $(AM_V_at)rm -f *.rockspec + $(AM_V_at)$(MAKE) $(package_rockspec) $(scm_rockspec) + +check-local: $(check_local) + +install-exec-hook: $(install_exec_hooks) + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..6420c32 --- /dev/null +++ b/NEWS @@ -0,0 +1,398 @@ +Stdlib NEWS - User visible changes + +* Noteworthy changes in release 35 (2013-05-06) [stable] + +** New features: + + - Move to the Slingshot release system. + - Continuous integration from Travis automatically builds stdilb + with Lua 5.1, Lua 5.2 and luajit-2.0 with every commit, which + should help prevent future release breaking compatibility with + one or another of those interpreters. + +** Bug fixes: + + - `std.package_ext` no longer overwrites the core `package` table, + leaving the core holding on to memory that Lua code could no + longer access. + +** Incompatible changes: + + - The Grand Renaming™ - everything now installs to $luaprefix/std/, + except `std.lua` itself. Importing individual modules now involves: + + local list = require "std.list" + + If you want to have all the symbols previously available from the + global and core module namespaces, you will need to put them there + yourself, or import everything with: + + require "std" + + which still behaves per previous releases. + + Not all of the modules work correctly when imported individually + right now, until we figure out how to break some circular dependencies. + + +* Noteworthy changes in release 34.1 (2013-04-01) [stable] + +** This is a maintenance release to quickly fix a breakage in getopt + from release v34. Getopt no longer parses non-options, but stops + on the first non-option... if a use case for the other method + comes up, we can always add it back in. + + +* Noteworthy changes in release 34 (2013-03-25) [stable] + + - stdlib is moving towards supporting separate requirement of individual + modules, without scribbling on the global environment; the work is not + yet complete, but we're collecting tests along the way to ensure that + once it is all working, it will carry on working; + - there are some requirement loops between modules, so not everything can + be required independently just now; + - `require "std"` will continue to inject std symbols into the system + tables for backwards compatibility; + - stdlib no longer ships a copy of Specl, which you will need to install + separately if you want to run the bundled tests; + - getopt supports parsing of undefined options; useful for programs that + wrap other programs; + - getopt.Option constructor is no longer used, pass a plain Lua table of + options, and getopt will do the rest; + + +* Noteworthy changes in release 33 (2013-07-27) [stable] + +** This release improves stability where Specl has helped locate some + corner cases that are now fixed. + - `string_ext.wrap` and `string_ext.tfind` now diagnose invalid arguments. + +** Specl code coverage is improving. + +** OrdinalSuffix improvements. + - Use '%' instead of math.mod, as the latter does not exist in Lua 5.2. + - Accept negative arguments. + + +* Noteworthy changes in release 32 (2013-02-22) [stable] + +** This release fixes a critical bug preventing getopt from returning + anything in getopt.opt. Gary V. Vaughan is now a co-maintainer, currently + reworking the sources to use (Lua 5.1 compatible) Lua 5.2 style module + packaging, which requires you to assign the return values from your imports: + + getopt = require "getopt" + +** Extension modules, table_ext, package_ext etc. return the unextended module + table before injecting additional package methods, so you can ignore those + return values or save them for programatically backing out the changes: + + table_unextended = require "table_ext" + +** Additionally, Specl (see http://github.com/gvvaughan/specl/) specifications + are being written for stdlib modules to help us stop accidentally breaking + things between releases. + + +* Noteworthy changes in release 31 (2013-02-20) [stable] + +** This release improves the list module: lists now have methods, list.slice + is renamed to list.sub (the old name is provided as an alias for backwards + compatibility), and all functions that construct a new list return a proper + list, not a table. As a result, it is now often possible to write code that + works on both lists and strings. + + +* Noteworthy changes in release 30 (2013-02-17) [stable] + +** This release changes some modules to be written in a Lua 5.2 style (but + not the way they work with 5.1). Some fixes and improvements were made to + the build system. Bugs in the die function, the parser module, and a nasty + bug in the set module introduced in the last release (29) were fixed. + + +* Noteworthy changes in release 29 (2013-02-06) [stable] + +** This release overhauls the build system to have LuaRocks install releases + directly from git rather than from tarballs, and fixes a bug in set (issue + #8). + + +* Noteworthy changes in release 28 (2012-10-28) [stable] + +** This release improves the documentation and build system, and improves + require_version to work by default with more libraries. + + +* Noteworthy changes in release 27 (2012-10-03) [stable] + +** This release changes getopt to return all arguments in a list, rather than + optionally processing them with a function, fixes an incorrect definition + of set.elems introduced in release 26, turns on debugging by default, + removes the not-very-useful string.gsubs, adds constructor functions for + objects, renames table.rearrange to the more descriptive table.clone_rename + and table.indices to table.keys, and makes table.merge not clone but modify + its left-hand argument. A function require_version has been added to allow + version constraints on a module being required. Gary Vaughan has + contributed a memoize function, and minor documentation and build system + improvements have been made. Usage information is now output to stdout, not + stderr. The build system has been fixed to accept Lua 5.2. The luarock now + installs documentation, and the build command used is now more robust + against previous builds in the same tree. + + +* Noteworthy changes in release 26 (2012-02-18) [stable] + +** This release improves getoptâs output messages and conformance to + standard practice for default options. io.processFiles now unsets prog.file + when it finishes, so that a program can tell when itâs no longer + processing a file. Three new tree iterators, inodes, leaves and ileaves, + have been added; the set iterator set.elements (renamed to set.elems for + consistency with list.elems) is now leaves rather than pairs. tree indexing + has been made to work in more circumstances (thanks, Gary Vaughan). + io.writeline is renamed io.writelines for consistency with io.readlines and + its function. A slurping function, io.slurp, has been added. Strings now + have a __concat metamethod. + + +* Noteworthy changes in release 25 (2011-09-19) [stable] + +** This release adds a version string to the std module and fixes a buglet in + the build system. + + +* Noteworthy changes in release 24 (2011-09-19) [stable] + +** This release fixes a rename missing from release 23, and makes a couple of + fixes to the new build system, also from release 23. + + +* Noteworthy changes in release 23 (2011-09-17) [stable] + +** This release removes the posix_ext module, which is now part of luaposix, + renames string.findl to string.tfind to be the same as lrexlib, and + autotoolizes the build system, as well as providing a rockspec file. + + +* Noteworthy changes in release 22 (2011-09-02) [stable] + +** This release adds two new modules: strbuf, a trivial string buffers + implementation, which is used to speed up the stdlib tostring method for + tables, and bin, which contains a couple of routines for converting binary + data into numbers and strings. Some small documentation and build system + fixes have been made. + + +* Noteworthy changes in release 21 (2011-06-06) [stable] + +** This release converts the documentation of stdlib to LuaDoc, adds an + experimental Lua 5.2 module "fstable", for storing tables directly on + disk as files and directories, and fixes a few minor bugs (with help from + David Favro). + +** This release has been tested lightly on Lua 5.2 alpha, but is not + guaranteed to work fully. + + +* Noteworthy changes in release 20 (2011-04-14) [stable] + +** This release fixes a conflict between the global _DEBUG setting and the use + of strict.lua, changes the argument order of some list functions to favour + OO-style use, adds posix.euidaccess, and adds OO-style use to set. mk1file + can now produce a single-file version of a user-supplied list of modules, + not just the standard set. + + +* Noteworthy changes in release 19 (2011-02-26) [stable] + +** This release puts the package.config reflection in a new package_ext + module, where it belongs. Thanks to David Manura for this point, and for a + small improvement to the code. + + +* Noteworthy changes in release 18 (2011-02-26) [stable] + +** This release provides named access to the contents of package.config, which + is undocumented in Lua 5.1. See luaconf.h and the Lua 5.2 manual for more + details. + + +* Noteworthy changes in release 17 (2011-02-07) [stable] + +** This release fixes two bugs in string.pad (thanks to Bob Chapman for the + fixes). + + +* Noteworthy changes in release 16 (2010-12-09) [stable] + +** Adds posix module, using luaposix, and makes various other small fixes and + improvements. + + +* Noteworthy changes in release 15 (2010-06-14) [stable] + +** This release fixes list.foldl, list.foldr, the fold iterator combinator and + io.writeLine. It also simplifies the op table, which now merely sugars the + built-in operators rather than extending them. It adds a new tree module, + which subsumes the old table.deepclone and table.lookup functions. + table.subscript has become op["[]"], and table.subscripts has been removed; + the old treeIter iterator has been simplified and generalised, and renamed + to nodes. The mk1file script and std.lua library loader have had the module + list factored out into modules.lua. strict.lua from the Lua distribution is + now included in stdlib, which has been fixed to work with it. Some minor + documentation and other code improvements and fixes have been made. + + +* Noteworthy changes in release 14 (2010-06-07) [stable] + +** This release makes stdlib compatible with strict.lua, which required a + small change to the debug_ext module. Some other minor changes have also + been made to that module. The table.subscripts function has been removed + from the table_ext.lua. + + +* Noteworthy changes in release 13 (2010-06-02) [stable] + +** This release removes the lcs module from the standard set loaded by + "std", removes an unnecessary definition of print, and tidies up the + implementation of the "op" table of functional versions of the infix + operators and logical operators. + + +* Noteworthy changes in release 12 (2009-09-07) [stable] + +** This release removes io.basename and io.dirname, which are now available in + lposix, and the little-used functions addSuffix and changeSuffix which + dependend on them. io.pathConcat is renamed to io.catdir and io.pathSplit + to io.splitdir, making them behave the same as the corresponding Perl + functions. The dependency on lrexlib has been removed along with the rex + wrapper module. Some of the more esoteric and special-purpose modules + (mbox, xml, parser) are no longer loaded by 'require "std"'. + + This leaves stdlib with no external dependencies, and a rather more + coherent set of basic modules. + + +* Noteworthy changes in release 11 (2009-03-15) [stable] + +** This release fixes a bug in string.format, removes the redundant + string.join (it's the same as table.concat), and adds to table.clone and + table.deepclone the ability to copy without metatables. Thanks to David + Kantowitz for pointing out the various deficiencies. + + +* Noteworthy changes in release 10 (2009-03-13) [stable] + +** This release fixes table.deepclone to copy metatables, as it should. + Thanks to David Kantowitz for the fix. + + +* Noteworthy changes in release 9 (2009-02-19) [stable] + +** This release updates the object module to be the same as that published + in "Lua Gems", and fixes a bug in the utility mk1file which makes a + one-file version of the library, to stop it permanently redefining require. + + +* Noteworthy changes in release 8 (2008-09-04) [stable] + +** This release features fixes and improvements to the set module; thanks to + Jiutian Yanling for a bug report and suggestion which led to this work. + + +* Noteworthy changes in release 7 (2008-09-04) [stable] + +** just a bug fix + + +* Noteworthy changes in release 6 (2008-07-28) [stable] + +** This release rewrites the iterators in a more Lua-ish 5.1 style. + + +* Noteworthy changes in release 5 (2008-03-04) [stable] + +** I'm happy to announce a new release of my standard Lua libraries. It's been + nearly a year since the last release, and I'm happy to say that since then + only one bug has been found (thanks Roberto!). Two functions have been + added in this release, to deal with file paths, and one removed (io.length, + which is handled by lfs.attributes) along with one constant (INTEGER_BITS, + handled by bitlib's bit.bits). + +** For those not familiar with stdlib, it's a pure-Lua library of mostly + fundamental data structures and algorithms, in particular support for + functional and object-oriented programming, string and regex operations and + extensible pretty printing of data structures. More specific modules + include a getopt implementation, a generalised least common subsequences + (i.e. diff algorithm) implementation, a recursive-descent parser generator, + and an mbox parser. + +** It's quite a mixed bag, but almost all written for real projects. It's + written in a doc-string-ish style with the supplied very simple ldoc tool. + +** I am happy with this code base, but there are various things it could use: + + 0. Tests. Tests. Tests. The code has no unit tests. It so needs them. + + 1. More code. Nothing too specialised (unless it's too small to be released + on its own, although very little seems "too small" in the Lua + community). Anything that either has widespread applicability (like + getopt) or is very general (data structures, algorithms, design + patterns) is good. + + 2. Refactoring. The code is not ideally factored. At the moment it is + divided into modules that extend existing libraries, and new modules + constructed along similar lines, but I think that some of the divisions + are confusing. For example, the functional programming support is spread + between the list and base modules, and would probably be better in its + own module, as those who aren't interested in the functional style won't + want the functional list support or the higher-order functions support, + and those who want one will probably want the other. + + 3. Documentation work. There's not a long wrong with the existing + documentation, but it would be nice, now that there is a stable LuaDoc, + to use that instead of the built-in ldoc, which I'm happy to discard now + that LuaDoc is stable. ldoc was always designed as a minimal LuaDoc + substitute in any case. + + 4. Maintenance and advocacy. For a while I have been reducing my work on + Lua, and am also now reducing my work in Lua. If anyone would like to + take on stdlib, please talk to me. It fills a much-needed function: I + suspect a lot of Lua programmers have invented the wheels with which it + is filled over and over again. In particular, many programmers could + benefit from the simplicity of its simple and well-designed functional, + string and regex capabilities, and others will love its comprehensive + getopt. + + +* Noteworthy changes in release 4 (2007-04-26) [beta] + +** This release removes the dependency on the currently unmaintained lposix + library, includes pre-built HTML documentation, and fixes some 5.0-style + uses of variadic arguments. + + Thanks to Matt for pointing out all these problems. stdlib is very much + user-driven at the moment, since it already does everything I need, and I + don't have much time to work on it, so do please contact me if you find + bugs or problems or simply don't understand it, as the one thing I *do* + want to do is make it useful and accessible! + + +* Noteworthy changes in release 3 (2007-02-25) [beta] + +** This release fixes the "set" and "lcs" (longest common subsequence, or + "grep") libraries, which were broken, and adds one or two other bug and + design fixes. Thanks are due to Enrico Tassi for pointing out some of the + problems. + + +* Noteworthy changes in release 2 (2007-01-05) [beta] + +** This release includes some bug fixes, and compatibility with lrexlib 2.0. + + +* Noteworthy changes in release 1 (2011-09-02) [beta] + +** It's just a snapshot of CVS, but it's pretty stable at the moment; stdlib, + until such time as greater interest or participation enables (or forces!) + formal releases will be in permanent beta, and tracking CVS is recommended. diff --git a/README b/README deleted file mode 100644 index a8185b1..0000000 --- a/README +++ /dev/null @@ -1,51 +0,0 @@ - Standard Lua libraries - ---------------------- - - by the stdlib project (http://github.com/rrthomas/lua-stdlib/) - - -This is a collection of Lua libraries for Lua 5.1 and 5.2. The -libraries are copyright by their authors 2000-2013 (see the AUTHORS -file for details), and released under the MIT license (the same -license as Lua itself). There is no warranty. - -The standard subset of stdlib has no prerequisites beyond a standard -Lua system. The following modules have extra dependencies: - - fstable: Lua 5.2, lfs, luaposix - - -Installation ------------- - -The simplest way to install stdlib is with LuaRocks -(http://www.luarocks.org/ ): - - luarocks install stdlib - - -Use ---- - -As well as requiring individual libraries, you can load the standard -set with - - require "std" - -Modules not in the standard set may be removed from future versions of -stdlib. - - -Documentation -------------- - -The libraries are documented in LuaDoc. Pre-built HTML files are -included. - - -Bug reports and code contributions ----------------------------------- - -These libraries are maintained and extended by their users. Please -make bug report and suggestions on GitHub (see URL at top of file). -Pull requests are especially appreciated. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a7bb94 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +Standard Lua libraries +====================== + +by the [stdlib project][github] + +[github]: http://github.com/rrthomas/lua-stdlib/ "Github repository" + +[![travis-ci status](https://secure.travis-ci.org/rrthomas/lua-stdlib.png?branch=master)](http://travis-ci.org/rrthomas/lua-stdlib/builds) + + +This is a collection of Lua libraries for Lua 5.1 and 5.2. The +libraries are copyright by their authors 2000-2013 (see the AUTHORS +file for details), and released under the MIT license (the same +license as Lua itself). There is no warranty. + +Stdlib has no prerequisites beyond a standard Lua system. + + +Installation +------------ + +The simplest way to install stdlib is with [LuaRocks][]. To install the +latest release (recommended): + + luarocks install stdlib + +To install current git master (for testing): + + luarocks install https://raw.github.com/rrthomas/lua-stdlib/release/stdlib-git-1.rockspec + +To install without LuaRocks, check out the sources from the +[repository][github], and then run the following commands: the +dependencies are listed in the dependencies entry of the file +`stdlib-rockspec.lua`. You will also need autoconf and automake. + + cd lua-stdlib + autoreconf --force --version --install + ./configure --prefix=INSTALLATION-ROOT-DIRECTORY + make all check install + +See [INSTALL][] for instructions for `configure`. + +[luarocks]: http://www.luarocks.org "LuaRocks Project" +[install]: https://raw.github.com/rrthomas/lua-stdlib/master/INSTALL + +Use +--- + +As well as requiring individual libraries, you can load the standard +set with + + require "std" + +Modules not in the standard set may be removed from future versions of +stdlib. + + +Documentation +------------- + +The libraries are [documented in LuaDoc][github.io]. Pre-built HTML +files are included. + +[github.io]: http://rrthomas.github.io/lua-stdlib + + +Bug reports and code contributions +---------------------------------- + +These libraries are written and maintained by their users. Please make +bug report and suggestions on GitHub (see URL at top of file). Pull +requests are especially appreciated. diff --git a/aclocal.m4 b/aclocal.m4 index e0d6b76..73b9204 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -653,4 +653,4 @@ AC_SUBST([am__untar]) m4_include([m4/ax_compare_version.m4]) m4_include([m4/ax_lua.m4]) -m4_include([m4/ax_with_prog.m4]) +m4_include([m4/slingshot.m4]) diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..c230e82 --- /dev/null +++ b/bootstrap @@ -0,0 +1,4764 @@ +#! /bin/sh + +# Bootstrap an Autotooled package from checked-out sources. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# Source required external libraries: +# Set a version string for this script. +scriptversion=2012-10-21.11; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS=" $sp$nl" + +# There are still modern systems that have problems with 'echo' mis- +# handling backslashes, among others, so make sure $bs_echo is set to a +# command that correctly interprets backslashes. +# (this code from Autoconf 2.68) + +# Printing a long string crashes Solaris 7 /usr/bin/printf. +bs_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo +bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $bs_echo`" = "X$bs_echo") 2>/dev/null; then + bs_echo='print -r --' + bs_echo_n='print -rn --' +elif (test "X`printf %s $bs_echo`" = "X$bs_echo") 2>/dev/null; then + bs_echo='printf %s\n' + bs_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $bs_echo) 2>/dev/null`" = "X-n $bs_echo"; then + bs_echo_body='eval /usr/ucb/echo -n "$1$nl"' + bs_echo_n='/usr/ucb/echo -n' + else + bs_echo_body='eval expr "X$1" : "X\\(.*\\)"' + bs_echo_n_body='eval + arg=$1; + case $arg in #( + *"$nl"*) + expr "X$arg" : "X\\(.*\\)$nl"; + arg=`expr "X$arg" : ".*$nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$nl" + ' + export bs_echo_n_body + bs_echo_n='sh -c $bs_echo_n_body bs_echo' + fi + export bs_echo_body + bs_echo='sh -c $bs_echo_body bs_echo' +fi + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="$bs_echo"} +: ${EGREP="grep -E"} +: ${FGREP="grep -F"} +: ${GREP="grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$bs_echo "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$bs_echo "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$bs_echo $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $bs_echo "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$bs_echo "$_G_tc" | sed "$sed_make_literal_regex"` + _G_indent=`$bs_echo "$_G_indent" | sed "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | sed 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $bs_echo "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has just all characters which are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2012-10-21.11; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$bs_echo "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ------------------## +## Helper functions. ## +## ------------------## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$bs_echo \""Usage: $usage"\" + eval \$bs_echo \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $bs_echo "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $bs_echo "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$bs_echo \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$bs_echo \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n '/^##/q + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Extract macro arguments from autotools input with GNU M4. +# Written by Gary V. Vaughan, 2010 +# +# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# Make sure we've evaluated scripts we depend on. +test -z "$progpath" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/funclib.sh +test extract-trace = "$progname" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/options-parser + +# Set a version string. +scriptversion=2012-10-07.10; # UTC + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './extract-trace --help' for help with using this script from the +# command line. +# +# Or source first 'options-parser' and then this file into your own +# scripts in order to make use of the function and variable framework +# they define, and also to avoid the overhead of forking to run this +# script in its own process on every call. + + + +## ------------------## +## Helper functions. ## +## ------------------## + +# This section contains the helper functions used by the rest of +# 'extract-trace'. + + +# func_autoconf_configure MAYBE-CONFIGURE-FILE +# -------------------------------------------- +# Ensure that MAYBE-CONFIGURE-FILE is the name of a file in the current +# directory which contains an uncommented call to AC_INIT. +func_autoconf_configure () +{ + $debug_cmd + + _G_sed_no_comment=' + s|#.*$|| + s|^dnl .*$|| + s| dnl .*$||' + _G_ac_init= + + # If we were passed a genuine file, make sure it calls AC_INIT. + test -f "$1" \ + && _G_ac_init=`$SED "$_G_sed_no_comment" "$1" |grep AC_INIT` + + # Otherwise it is not a genuine Autoconf input file. + test -n "$_G_ac_init" + _G_status=$? + + test 0 -ne "$_G_status" \ + && func_verbose "'$1' not using Autoconf" + + (exit $_G_status) +} + + +# func_find_tool ENVVAR NAMES... +# ------------------------------ +# Search for a required program. Use the value of ENVVAR, if set, +# otherwise find the first of the NAMES that can be run (i.e., +# supports --version). If found, set ENVVAR to the program name, +# die otherwise. +func_find_tool () +{ + $debug_cmd + + _G_find_tool_envvar=$1 + shift + _G_find_tool_names=$@ + eval "_G_find_tool_res=\$$_G_find_tool_envvar" + if test -n "$_G_find_tool_res"; then + _G_find_tool_error_prefix="\$$find_tool_envvar: " + else + for _G_prog + do + if func_tool_version_output $_G_prog >/dev/null; then + _G_find_tool_res=$_G_prog + break + fi + done + fi + if test -n "$_G_find_tool_res"; then + func_tool_version_output >/dev/null $_G_find_tool_res "\ +${_G_find_tool_error_prefix}Cannot run '$_G_find_tool_res --version'" + + # Make sure the result is exported to the environment for children + # to use. + eval "$_G_find_tool_envvar=\$_G_find_tool_res" + eval "export $_G_find_tool_envvar" + else + func_error "\ +One of these is required: + $_G_find_tool_names" + fi +} + + +# func_tool_version_output CMD [FATAL-ERROR-MSG] +# ---------------------------------------------- +# Attempt to run 'CMD --version', discarding errors. The output can be +# ignored by redirecting stdout, and this function used simply to test +# whether the command exists and exits normally when passed a +# '--version' argument. +# When FATAL-ERROR-MSG is given, then this function will display the +# message and exit if running 'CMD --version' returns a non-zero exit +# status. +func_tool_version_output () +{ + $debug_cmd + + _G_cmd=$1 + _G_fatal_error_msg=$2 + + # Some tools, like 'git2cl' produce thousands of lines of output + # unless stdin is /dev/null - in that case we want to return + # successfully without saving all of that output. Other tools, + # such as 'help2man' exit with a non-zero status when stdin comes + # from /dev/null, so we re-execute without /dev/null if that + # happens. This means that occasionally, the output from both calls + # ends up in the result, but the alternative would be to discard the + # output from one call, and hope the other produces something useful. + { $_G_cmd --version /dev/null + _G_status=$? + + test 0 -ne "$_G_status" && test -n "$_G_fatal_error_msg" \ + && func_fatal_error "$_G_fatal_error_msg" + + (exit $_G_status) +} + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Where a variable already has a non- +# empty value (as set by the package's 'bootstrap.conf'), that value is +# used in preference to deriving the default. Call them using their +# associated 'require_*' variable to ensure that they are executed, at +# most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_configure_ac +# -------------------- +# Ensure that there is a 'configure.ac' or 'configure.in' file in the +# current directory which contains an uncommented call to AC_INIT, and +# that '$configure_ac' contains its name. +require_configure_ac=func_require_configure_ac +func_require_configure_ac () +{ + $debug_cmd + + test -z "$configure_ac" \ + && func_autoconf_configure configure.ac && configure_ac=configure.ac + test -z "$configure_ac" \ + && func_autoconf_configure configure.in && configure_ac=configure.in + test -z "$configure_ac" \ + || func_verbose "found '$configure_ac'" + + require_configure_ac=: +} + + +# require_gnu_m4 +# -------------- +# Search for GNU M4, and export it in $M4. +require_gnu_m4=func_require_gnu_m4 +func_require_gnu_m4 () +{ + $debug_cmd + + test -n "$M4" || { + # Find the first m4 binary that responds to --version. + func_find_tool M4 gm4 gnum4 m4 + } + + test -n "$M4" || func_fatal_error "\ +Please install GNU M4, or 'export M4=/path/to/gnu/m4'." + + func_verbose "export M4='$M4'" + + # Make sure the search result is visible to subshells + export M4 + + require_gnu_m4=: +} + + +## --------------- ## +## Core functions. ## +## --------------- ## + +# This section contains the high level functions used when calling this +# file as a script. 'func_extract_trace' is probably the only one that you +# won't want to replace if you source this file into your own script. + + +# func_extract_trace MACRO_NAMES [FILENAME]... +# -------------------------------------------- +# set '$func_extract_trace_result' to a colon delimited list of arguments +# to any of the comma separated list of MACRO_NAMES in FILENAME. If no +# FILENAME is given, then '$configure_ac' is assumed. +func_extract_trace () +{ + $debug_cmd + + $require_configure_ac + $require_gnu_m4 + + _G_m4_traces=`$bs_echo "--trace=$1" |$SED 's%,% --trace=%g'` + _G_re_macros=`$bs_echo "($1)" |$SED 's%,%|%g'` + _G_macros="$1"; shift + test $# -gt 0 || { + set dummy $configure_ac + shift + } + + # Generate an error if the first file is missing + <"$1" + + # Sadly, we can't use 'autom4te' tracing to extract macro arguments, + # because it complains about things we want to ignore at bootstrap + # time - like missing m4_include files; AC_PREREQ being newer than + # the installed autoconf; and returns nothing when tracing + # 'AM_INIT_AUTOMAKE' when aclocal hasn't been generated yet. + # + # The following tries to emulate a less persnickety version of (and + # due to not having to wait for Perl startup on every invocation, + # it's probably faster too): + # + # autom4te --language=Autoconf --trace=$my_macro:\$% "$@" + # + # First we give a minimal set of macro declarations to M4 to prime + # it for reading Autoconf macros, while still providing some of the + # functionality generally used at m4-time to supply dynamic + # arguments to Autocof functions, but without following + # 'm4_s?include' files. + _G_mini=' + # Initialisation. + m4_changequote([,]) + m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))]) + m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])]) + + # Disable these macros. + m4_undefine([m4_dnl]) + m4_undefine([m4_include]) + m4_undefine([m4_m4exit]) + m4_undefine([m4_m4wrap]) + m4_undefine([m4_maketemp]) + + # Copy and rename macros not handled by "m4 --prefix". + m4_define([dnl], [m4_builtin([dnl])]) + m4_copy([m4_define], [m4_defun]) + m4_rename([m4_ifelse], [m4_if]) + m4_ifdef([m4_mkstemp], [m4_undefine([m4_mkstemp])]) + m4_rename([m4_patsubst], [m4_bpatsubst]) + m4_rename([m4_regexp], [m4_bregexp]) + + # "m4sugar.mini" - useful m4-time macros for dynamic arguments. + # If we discover packages that need more m4 macros defined in + # order to bootstrap correctly, add them here: + m4_define([m4_bmatch], + [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2], + [m4_if(m4_bregexp([$1], [$2]), -1, + [$0([$1], m4_shift3($@))], [$3])])]) + m4_define([m4_ifndef], [m4_ifdef([$1], [$3], [$2])]) + m4_define([m4_ifset], + [m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])]) + m4_define([m4_require], [$1]) + m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))]) + + # "autoconf.mini" - things from autoconf macros we care about. + m4_copy([m4_defun], [AC_DEFUN]) + + # Dummy definitions for the macros we want to trace. + # AM_INIT_AUTOMAKE at least produces no trace without this. + ' + + _G_save=$IFS + IFS=, + for _G_macro in $_G_macros; do + IFS=$_G_save + func_append _G_mini "AC_DEFUN([$_G_macro])$nl" + done + IFS=$_G_save + + # We discard M4's stdout, but the M4 trace output from reading our + # "autoconf.mini" followed by any other files passed to this + # function is then scanned by sed to transform it into a colon + # delimited argument list assigned to a shell variable. + _G_transform='s|#.*$||; s|^dnl .*$||; s| dnl .*$||;' + + # Unfortunately, alternation in regexp addresses doesn't work in at + # least BSD (and hence Mac OS X) sed, so we have to append a capture + # and print block for each traced macro to the sed transform script. + _G_save=$IFS + IFS=, + for _G_macro in $_G_macros; do + IFS=$_G_save + func_append _G_transform ' + /^m4trace: -1- '"$_G_macro"'/ { + s|^m4trace: -1- '"$_G_macro"'[([]*|| + s|], [[]|:|g + s|[])]*$|:| + s|\(.\):$|\1| + p + }' + done + IFS=$_G_save + + # Save the command pipeline results for further use by callers of + # this function. + func_extract_trace_result=`$bs_echo "$_G_mini" \ + |$M4 -daq --prefix $_G_m4_traces - "$@" 2>&1 1>/dev/null \ + |$SED -n -e "$_G_transform"` +} + + +# func_extract_trace_first MACRO_NAMES [FILENAME]... +# -------------------------------------------------- +# Exactly like func_extract_trace, except that only the first argument +# to the first invocation of one of the comma separated MACRO_NAMES is +# returned in '$func_extract_trace_first_result'. +func_extract_trace_first () +{ + $debug_cmd + + func_extract_trace ${1+"$@"} + func_extract_trace_first_result=`$bs_echo "$func_extract_trace_result" \ + |$SED -e 's|:.*$||g' -e 1q` +} + + +# func_main [ARG]... +# ------------------ +func_main () +{ + $debug_cmd + + # Configuration. + usage='$progname MACRO_NAME FILE [...]' + + long_help_message=' +The first argument to this program is the name of an autotools macro +whose arguments you want to extract by examining the files listed in the +remaining arguments using the same tool that Autoconf and Automake use, +GNU M4. + +The arguments are returned separated by colons, with each traced call +on a separate line.' + + # Option processing. + func_options "$@" + eval set dummy "$func_options_result"; shift + + # Validate remaining non-option arguments. + test $# -gt 1 \ + || func_fatal_help "not enough arguments" + + # Pass non-option arguments to extraction function. + func_extract_trace "$@" + + # Display results. + test -n "$func_extract_trace_result" \ + && $bs_echo "$func_extract_trace_result" + + # The End. + exit $EXIT_SUCCESS +} + + +## --------------------------- ## +## Actually perform the trace. ## +## --------------------------- ## + +# Only call 'func_main' if this script was called directly. +test extract-trace = "$progname" && func_main "$@" + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string for *this* script. +scriptversion=2013-01-20.16; # UTC + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Originally written by Paul Eggert. The canonical version of this +# script is maintained as build-aux/bootstrap in gnulib, however, to +# be useful to your project, you should place a copy of it under +# version control in the top-level directory of your project. The +# intent is that all customization can be done with a bootstrap.conf +# file also maintained in your version control; gnulib comes with a +# template build-aux/bootstrap.conf to get you started. + +# Please report bugs or propose patches to bug-gnulib@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Most GNUish projects do not keep all of the generated Autotool +# files under version control, but running all of the right tools +# with the right arguments, in the correct order to regenerate +# all of those files in readiness for configuration and building +# can be surprisingly involved! Many projects have a 'bootstrap' +# script under version control to invoke Autotools and perform +# other assorted book-keeping with version numbers and the like. +# +# This bootstrap script aims to probe the configure.ac and top +# Makefile.am of your project to automatically determine what +# the correct ordering and arguments are and then run the tools for +# you. In order to use it, you can generate an initial standalone +# script with: +# +# gl/build-aux/inline-source gl/build-aux/bootstrap.in > bootstrap +# +# You should then store than script in version control for other +# developers in you project. It will give you instructions about +# how to keep it up to date if the sources change. +# +# See gl/doc/bootstrap.texi for documentation on how to write +# a bootstrap.conf to customize it for your project's +# idiosyncracies. + + +## ================================================================== ## +## ## +## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ## +## ## +## ================================================================== ## + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase denotes values stored in the environment. These +# variables should generally be overridden by the user - however, we do +# set them to 'true' in some parts of this script to prevent them being +# called at the wrong time by other tools that we call ('autoreconf', +# for example). +# +# We also allow 'LIBTOOLIZE', 'M4', 'SHA1SUM' and some others to be +# overridden, and export the result for child processes, but they are +# handled by the function 'func_find_tool' and not defaulted in this +# section. + +: ${ACLOCAL="aclocal"} +: ${AUTOCONF="autoconf"} +: ${AUTOHEADER="autoheader"} +: ${AUTOM4TE="autom4te"} +: ${AUTOHEADER="autoheader"} +: ${AUTOMAKE="automake"} +: ${AUTOPOINT="autopoint"} +: ${AUTORECONF="autoreconf"} +: ${CMP="cmp"} +: ${CONFIG_SHELL="/bin/sh"} +: ${DIFF="diff"} +: ${EGREP="grep -E"} +: ${FGREP="grep -F"} +: ${GIT="git"} +: ${GREP="grep"} +: ${LN_S="ln -s"} +: ${RM="rm"} +: ${SED="sed"} + +export ACLOCAL +export AUTOCONF +export AUTOHEADER +export AUTOM4TE +export AUTOHEADER +export AUTOMAKE +export AUTOPOINT +export AUTORECONF +export CONFIG_SHELL + + +## -------------- ## +## Configuration. ## +## -------------- ## + +# A newline delimited list of triples of programs (that respond to +# --version), the minimum version numbers required (or just '-' in the +# version field if any version will be sufficient) and homepage URLs +# to help locate missing packages. +buildreq= + +# Name of a file containing instructions on installing missing packages +# required in 'buildreq'. +buildreq_readme=README-hacking + +# These are extracted from AC_INIT in configure.ac, though you can +# override those values in 'bootstrap.conf' if you prefer. +build_aux= +macro_dir= +package= +package_name= +package_version= +package_bugreport= + +# These are extracted from 'gnulib-cache.m4', or else fall-back +# automatically on the gnulib defaults; unless you set the values +# manually in 'bootstrap.conf'. +doc_base= +gnulib_mk= +gnulib_name= +local_gl_dir= +source_base= +tests_base= + +# The list of gnulib modules required at 'gnulib-tool' time. If you +# check 'gnulib-cache.m4' into your repository, then this list will be +# extracted automatically. +gnulib_modules= + +# Extra gnulib files that are not in modules, which override files of +# the same name installed by other bootstrap tools. +gnulib_non_module_files=" + build-aux/compile + build-aux/install-sh + build-aux/mdate-sh + build-aux/texinfo.tex + build-aux/depcomp + build-aux/config.guess + build-aux/config.sub + doc/INSTALL +" + +# Relative path to the local gnulib submodule, and url to the upstream +# git repository. If you have a gnulib entry in your .gitmodules file, +# these values are ignored. +gnulib_path= +gnulib_url= + +# Additional gnulib-tool options to use. +gnulib_tool_options=" + --no-changelog +" + +# bootstrap removes any macro-files that are not included by aclocal.m4, +# except for files listed in this variable which are always kept. +gnulib_precious=" + gnulib-tool.m4 +" + +# When truncating long commands for display, always allow at least this +# many characters before truncating. +min_cmd_len=160 + +# The command to download all .po files for a specified domain into +# a specified directory. Fill in the first %s is the domain name, and +# the second with the destination directory. Use rsync's -L and -r +# options because the latest/%s directory and the .po files within are +# all symlinks. +po_download_command_format=\ +"rsync --delete --exclude '*.s1' -Lrtvz \ +'translationproject.org::tp/latest/%s/' '%s'" + +# Other locale categories that need message catalogs. +extra_locale_categories= + +# Additional xgettext options to use. Gnulib might provide you with an +# extensive list of additional options to append to this, but gettext +# 0.16.1 and newer appends them automaticaly, so you can safely ignore +# the complaints from 'gnulib-tool' if your $configure_ac states: +# +# AM_GNU_GETTEXT_VERSION([0.16.1]) +xgettext_options=" + --flag=_:1:pass-c-format + --flag=N_:1:pass-c-format +" + +# Package copyright holder for gettext files. Defaults to FSF if unset. +copyright_holder= + +# File that should exist in the top directory of a checked out hierarchy, +# but not in a distribution tarball. +checkout_only_file= + +# Whether to use copies instead of symlinks by default (if set to true, +# the --copy option has no effect). +copy=false + +# Set this to ".cvsignore .gitignore" in 'bootstrap.conf' if you want +# those files to be generated in directories like 'lib/', 'm4/', and 'po/', +# or set it to "auto" to make this script select which to use based +# on which version control system (if any) is used in the source directory. +# Or set it to "none" to ignore VCS ignore files entirely. Default is +# "auto". +vc_ignore= + + +## ------------------- ## +## Hookable functions. ## +## ------------------- ## + +# After 'bootstrap.conf' has been sourced, execution proceeds by calling +# 'func_bootstrap'. Wherever a function is decorated with +# 'func_hookable func_name', you will find a matching 'func_run_hooks +# func_name' which executes all functions added with 'func_add_hook +# func_name my_func'. +# +# You might notice that many of these functions begin with a series of +# '$require_foo' lines. See the docu-comments at the start of the +# 'Resource management' section for a description of what these are. + + +# func_bootstrap [ARG]... +# ----------------------- +# All the functions called inside func_bootstrap are hookable. See the +# the individual implementations for details. +func_bootstrap () +{ + $debug_cmd + + # Save the current positional parameters to prevent them being + # corrupted by calls to 'set' in 'func_init'. + func_quote_for_eval ${1+"$@"} + _G_saved_positional_parameters=$func_quote_for_eval_result + + # Initialisation. + func_init + + # Option processing. + eval func_options "$_G_saved_positional_parameters" + + # Post-option preparation. + func_prep + + # Ensure ChangeLog presence. + func_ifcontains "$gnulib_modules" gitlog-to-changelog \ + func_ensure_changelog + + # Reconfigure the package. + func_reconfigure + + # Ensure .version is up-to-date. + func_update_dotversion + + # Finalisation. + func_fini +} + + +# func_init +# --------- +# Any early initialisations can be hooked to this function. Consider +# whether you can hook onto 'func_prep' instead, because if you hook +# any slow to execute code in here, it will also add to the time before +# './bootstrap --version' can respond. +func_hookable func_init +func_init () +{ + $debug_cmd + + func_run_hooks func_init +} + + +# func_prep +# --------- +# Function to perform preparation for remaining bootstrap process. If +# your hooked code relies on the outcome of 'func_options' hook it here +# rather than to 'func_init'. +# +# All the functions called inside func_prep are hookable. See the +# individual implementations for details. +func_hookable func_prep +func_prep () +{ + $debug_cmd + + $require_buildtools_uptodate + $require_checkout_only_file + + $require_gnulib_merge_changelog + + # fetch update files from the translation project + func_update_translations + + func_run_hooks func_prep +} + + +# func_update_translations +# ------------------------ +# Update package po files and translations. +func_hookable func_update_translations +func_update_translations () +{ + $debug_cmd + + $opt_skip_po || { + test -d po && { + $require_package + + func_update_po_files po $package || exit $? + } + + func_run_hooks func_update_translations + } +} + + +# func_reconfigure +# ---------------- +# Reconfigure the current package by running the appropriate autotools in a +# suitable order. +func_hookable func_reconfigure +func_reconfigure () +{ + $debug_cmd + + # Released 'autopoint' has the tendency to install macros that have + # been obsoleted in current 'gnulib., so run this before 'gnulib-tool'. + func_autopoint + + # Autoreconf runs 'aclocal' before 'libtoolize', which causes spurious + # warnings if the initial 'aclocal' is confused by the libtoolized + # (or worse: out-of-date) macro directory. + func_libtoolize + + # If you need to do anything after 'gnulib-tool' is done, but before + # 'autoreconf' runs, you don't need to override this whole function, + # because 'func_gnulib_tool' is hookable. + func_gnulib_tool + + func_autoreconf + + func_run_hooks func_reconfigure +} + + +# func_gnulib_tool +# ---------------- +# Run 'gnulib-tool' to fetch gnulib modules into the current package. +# +# It's assumed that since you are using gnulib's 'bootstrap' script, +# you're also using gnulib elsewhere in your package. If not, then +# you can preset 'gnulib_tool=true' in your 'bootstrap.conf' to force +# this function to return immediately. +func_hookable func_gnulib_tool +func_gnulib_tool () +{ + $debug_cmd + + $require_gnulib_tool + $require_libtoolize + + test true = "$gnulib_tool" || { + if test -n "$gnulib_modules"; then + $require_gnulib_cache + $require_gnulib_tool_base_options + + gnulib_mode=--import + + # Try not to pick up any stale values from 'gnulib-cache.m4'. + rm -f "$gnulib_cache" + + gnulib_tool_all_options=$gnulib_tool_options + test -n "$gnulib_tool_base_options" \ + && func_append_uniq gnulib_tool_all_options " $gnulib_tool_base_options" + test -n "$gnulib_mk" \ + && func_append_uniq gnulib_tool_all_options " --makefile-name=$gnulib_mk" + test -n "$tests_base" && { + func_append_uniq gnulib_tool_all_options " --tests-base=$tests_base" + func_append_uniq gnulib_tool_all_options " --with-tests" + } + else + + # 'gnulib_modules' and others are cached in 'gnulib-cache.m4': + # Use 'gnulib --update' to fetch gnulib modules. + gnulib_mode=--update + + gnulib_tool_all_options=$gnulib_tool_options + fi + + # Add a sensible default libtool option to gnulib_tool_options. + # The embedded echo is to squash whitespace before globbing. + case `echo " "$gnulib_tool_all_options" "` in + *" --no-libtool "*|*" --libtool "*) ;; + *) if test true = "$LIBTOOLIZE"; then + func_append_uniq gnulib_tool_all_options " --no-libtool" + else + func_append_uniq gnulib_tool_all_options " --libtool" + fi + ;; + esac + + $opt_copy || func_append_uniq gnulib_tool_all_options " --symlink" + + func_append_uniq gnulib_tool_all_options " $gnulib_mode" + func_append gnulib_tool_all_options " $gnulib_modules" + + # The embedded echo is to squash whitespace before display. + gnulib_cmd=`echo $gnulib_tool $gnulib_tool_all_options` + + func_show_eval "$gnulib_cmd" 'exit $?' + + # Use 'gnulib-tool --copy-file' to install non-module files. + func_install_gnulib_non_module_files + } + + func_run_hooks func_gnulib_tool +} + + +# func_fini +# --------- +# Function to perform all finalisation for the bootstrap process. +func_hookable func_fini +func_fini () +{ + $debug_cmd + + func_gettext_configuration + func_clean_dangling_symlinks + func_clean_unused_macros + func_skip_po_recommendation + + func_run_hooks func_fini + + $require_bootstrap_uptodate + + func_echo "Done. Now you can run './configure'." +} + + +# func_gettext_configuration +# -------------------------- +# Edit configuration values into po/Makevars. +func_hookable func_gettext_configuration +func_gettext_configuration () +{ + $debug_cmd + + $require_autopoint + + test true = "$AUTOPOINT" || { + $require_copyright_holder + $require_extra_locale_categories + $require_package_bugreport + + # Escape xgettext options for sed Makevars generation below. + # We have to delete blank lines in a separate script so that we don't + # append \\\ to the penultimate line, and then delete the last empty + # line, which messes up the variable substitution later in this + # function. Note that adding a literal \\\ requires double escaping + # here, once for the execution subshell, and again for the assignment, + # which is why there are actually 12 (!!) backslashes in the script. + _G_xgettext_options=`echo "$xgettext_options$nl" |$SED '/^$/d' |$SED ' + $b + s|$| \\\\\\\\\\\\|'` + + # Create gettext configuration. + func_echo "Creating po/Makevars from po/Makevars.template ..." + $RM -f po/Makevars + $SED ' + /^EXTRA_LOCALE_CATEGORIES *=/s|=.*|= '"$extra_locale_categories"'| + /^COPYRIGHT_HOLDER *=/s|=.*|= '"$copyright_holder"'| + /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$package_bugreport"'| + /^XGETTEXT_OPTIONS *=/{ + s|$| \\| + a\ + '"$_G_xgettext_options"' \\\ + $${end_of_xgettext_options+} + } + ' po/Makevars.template >po/Makevars || exit 1 + } + + func_run_hooks func_gettext_configuration +} + + + +## --------------- ## +## Core functions. ## +## --------------- ## + +# This section contains the main functions called from the 'Hookable +# functions' (shown above), and are the ones you're most likely +# to want to replace with your own implementations in 'bootstrap.conf'. + + +# func_autopoint +# -------------- +# If this package uses gettext, then run 'autopoint'. +func_autopoint () +{ + $debug_cmd + + $require_autopoint + + test true = "$AUTOPOINT" \ + || func_show_eval "$AUTOPOINT --force" 'exit $?' +} + + +# func_libtoolize +# --------------- +# If this package uses libtool, then run 'libtoolize'. +func_libtoolize () +{ + $debug_cmd + + $require_libtoolize + + test true = "$LIBTOOLIZE" || { + _G_libtoolize_options= + $opt_copy && func_append _G_libtoolize_options " --copy" + $opt_force && func_append _G_libtoolize_options " --force" + $opt_verbose || func_append _G_libtoolize_options " --quiet" + func_show_eval "$LIBTOOLIZE$_G_libtoolize_options" 'exit $?' + } +} + + +# func_gnulib_tool_copy_file SRC DEST +# ----------------------------------- +# Copy SRC, a path relative to the gnulib sub-tree, to DEST, a path +# relative to the top-level source directory using gnulib-tool so that +# any patches or replacements in $local_gl_dir are applied. +func_gnulib_tool_copy_file () +{ + $debug_cmd + + $require_gnulib_path + $require_gnulib_tool + $require_patch + + gnulib_copy_cmd="$gnulib_tool --copy-file" + $opt_copy || func_append gnulib_copy_cmd " --symlink" + + if test true = "$gnulib_tool"; then + # If gnulib-tool is not available (e.g. bootstrapping in a + # distribution tarball), make sure that at least we have some + # version of the required file already in place. + test -f "$2" || func_fatal_error "\ +Can't find, copy or download '$2', a required +gnulib supplied file, please provide the location of a +complete 'gnulib' tree by setting 'gnulib_path' in your +'bootstrap.conf' or with the '--gnulib-srcdir' option - +or else specify the location of your 'git' binary by +setting 'GIT' in the environment so that a fresh +'gnulib' submodule can be cloned." + else + test -f "$gnulib_path/$1" || { + func_error "'$gnulib_path/$1' does not exist" + return 1 + } + + $gnulib_copy_cmd $1 $2 + fi +} + + +# func_install_gnulib_non_module_files +# ------------------------------------ +# Get additional non-module files from gnulib, overriding existing files. +func_install_gnulib_non_module_files () +{ + $debug_cmd + + $require_build_aux + $require_gnulib_tool + + test -n "$gnulib_non_module_files" && { + maybe_exit_cmd=: + + for file in $gnulib_non_module_files; do + case $file in + */COPYING*) dest=COPYING;; + */INSTALL) dest=INSTALL;; + build-aux/missing) dest= + func_warning settings "\ +Please remove build-aux/missing from gnulib_module_files in +'bootstrap.conf', as it may clash with Automake's version." + ;; + build-aux/*) dest=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;; + *) dest=$file;; + esac + + # Be sure to show all copying errors before bailing out + test -z "$dest" \ + || func_gnulib_tool_copy_file "$file" "$dest" \ + || maybe_exit_cmd="exit $EXIT_FAILURE" + done + + $maybe_exit_cmd + } +} + + +# func_ensure_changelog +# --------------------- +# Even with 'gitlog-to-changelog' generated ChangeLogs, automake +# will not run to completion with no ChangeLog file. +func_ensure_changelog () +{ + $debug_cmd + + test -f ChangeLog && mv -f ChangeLog ChangeLog~ + + cat >ChangeLog <<'EOT' +## ---------------------- ## +## DO NOT EDIT THIS FILE! ## +## ---------------------- ## + +ChangeLog is generated by gitlog-to-changelog. +EOT + + _G_message="creating dummy 'ChangeLog'" + test -f ChangeLog~ \ + && func_append _G_message ' (backup in ChangeLog~)' + func_verbose "$_G_message" + + return 0 +} + + +# func_autoreconf +# --------------- +# Being careful not to re-run 'autopoint' or 'libtoolize', and not to +# try to run 'autopoint', 'libtoolize' or 'autoheader' on packages that +# don't use them, defer to 'autoreconf' for execution of the remaining +# autotools to bootstrap this package. +func_autoreconf () +{ + $debug_cmd + + $require_autoheader + $require_build_aux # automake and others put files in here + $require_macro_dir # aclocal and others put files in here + + # We ran these manually already, and autoreconf won't exec ':' + save_AUTOPOINT=$AUTOPOINT; AUTOPOINT=true + save_LIBTOOLIZE=$LIBTOOLIZE; LIBTOOLIZE=true + + _G_autoreconf_options= + $opt_copy || func_append _G_autoreconf_options " --symlink" + $opt_force && func_append _G_autoreconf_options " --force" + $opt_verbose && func_append _G_autoreconf_options " --verbose" + func_show_eval "$AUTORECONF$_G_autoreconf_options --install" 'exit $?' + + AUTOPOINT=$save_AUTOPOINT + LIBTOOLIZE=$save_LIBTOOLIZE +} + + +# func_check_configuration VARNAME [CONFIGURE_MACRO] +# -------------------------------------------------- +# Exit with a suitable diagnostic for an important configuration change +# that needs to be made before bootstrap can run correctly. +func_check_configuration () +{ + $debug_cmd + + $require_configure_ac + + eval 'test -n "$'$1'"' || { + _G_error_msg="please set '$1' in 'bootstrap.conf'" + if test -n "$configure_ac" && test -n "$2"; then + func_append _G_error_msg " +or add the following (or similar) to your '$configure_ac': +$2" + fi + + func_fatal_error "$_G_error_msg" + } +} + + +# func_clean_dangling_symlinks +# ---------------------------- +# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some +# gnulib-populated directories. Such .m4 files would cause aclocal to +# fail. The following requires GNU find 4.2.3 or newer. Considering +# the usual portability constraints of this script, that may seem a very +# demanding requirement, but it should be ok. Ignore any failure, +# which is fine, since this is only a convenience to help developers +# avoid the relatively unusual case in which a symlinked-to .m4 file is +# git-removed from gnulib between successive runs of this script. +func_clean_dangling_symlinks () +{ + $debug_cmd + + $require_macro_dir + $require_source_base + + func_verbose "cleaning dangling symlinks" + + find "$macro_dir" "$source_base" \ + -depth \( -name '*.m4' -o -name '*.[ch]' \) \ + -type l -xtype l -delete > /dev/null 2>&1 +} + + +# func_clean_unused_macros +# ------------------------ +# Autopoint can result in over-zealously adding macros into $macro_dir +# even though they are not actually used, for example tests to help +# build the 'intl' directory even though you have specified +# 'AM_GNU_GETTEXT([external])' in your configure.ac. This function +# looks removes any macro files that can be found in gnulib, but +# are not 'm4_include'd by 'aclocal.m4'. +func_clean_unused_macros () +{ + $debug_cmd + + test true = "$gnulib_tool" || { + $require_gnulib_path + $require_macro_dir + + test -n "$gnulib_path" && test -f aclocal.m4 && { + aclocal_m4s=`find . -name aclocal.m4 -print` + + # We use 'ls|grep' instead of 'ls *.m4' to avoid exceeding + # command line length limits in some shells. + for file in `cd "$macro_dir" && ls -1 |grep '\.m4$'`; do + + # Remove a macro file when aclocal.m4 does not m4_include it... + func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \ + || test ! -f "$gnulib_path/m4/$file" || { + + # ...and there is an identical file in gnulib... + if func_cmp_s "$gnulib_path/m4/$file" "$macro_dir/$file"; then + + # ...and it's not in the precious list ('echo' is needed + # here to squash whitespace for the match expression). + case " "`echo $gnulib_precious`" " in + *" $file "*) ;; + *) rm -f "$macro_dir/$file" + func_verbose \ + "removing unused gnulib file '$macro_dir/$file'" + esac + fi + } + done + } + } +} + + +# func_skip_po_recommendation +# --------------------------- +# If there is a po directory, and '--skip-po' wasn't passed, let the +# user know that they can use '--skip-po' on subsequent invocations. +func_skip_po_recommendation () +{ + $debug_cmd + + test ! -d po \ + || $opt_skip_po \ + || func_warning recommend "\ +If your pofiles are up-to-date, you can rerun bootstrap +as '$progname --skip-po' to avoid redownloading." +} + + +# func_update_dotversion +# ---------------------- +# Even with 'gitlog-to-changelog' generated ChangeLogs, automake +# will not run to completion with no ChangeLog file. +func_update_dotversion () +{ + $debug_cmd + + test -f "$build_aux/git-version-gen" && { + _G_message="updating .version" + test -f .version && { + mv .version .version~ + func_append _G_message " (backup in .version~)" + } + func_verbose "updating .version" + + $build_aux/git-version-gen dummy-arg > .version + } +} + + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Where a variable already has a non- +# empty value (as set by the package's 'bootstrap.conf'), that value is +# used in preference to deriving the default. Call them using their +# associated 'require_*' variable to ensure that they are executed, at +# most, once. + + +# require_checkout_only_file +# -------------------------- +# Bail out if this package only bootstraps properly from a repository +# checkout. +require_checkout_only_file=func_require_checkout_only_file +func_require_checkout_only_file () +{ + $debug_cmd + + $opt_force || { + test -n "$checkout_only_file" && test ! -f "$checkout_only_file" \ + && func_fatal_error "\ +Bootstrapping from a non-checked-out distribution is risky. +If you wish to bootstrap anyway, use the '--force' option." + } + + require_checkout_only_file=: +} + + +# require_aclocal_amflags +# ----------------------- +# Ensure '$aclocal_amflags' has a sensible default, extracted from +# 'Makefile.am' if necessary. +require_aclocal_amflags=func_require_aclocal_amflags +func_require_aclocal_amflags () +{ + $debug_cmd + + $require_makefile_am + + _G_sed_extract_aclocal_amflags='s|#.*$|| + /^[ ]*ACLOCAL_AMFLAGS[ ]*=/ { + s|^.*=[ ]*\(.*\)|aclocal_amflags="\1"| + p + }' + + _G_aclocal_flags_cmd=`$SED -n "$_G_sed_extract_aclocal_amflags" \ + "$makefile_am"` + eval "$_G_aclocal_flags_cmd" + + func_verbose "ACLOCAL_AMFLAGS='$aclocal_amflags'" + + require_aclocal_amflags=: +} + + +# require_autoheader +# ------------------ +# Skip autoheader if it's not needed. +require_autoheader=func_require_autoheader +func_require_autoheader () +{ + $debug_cmd + + test true = "$AUTOHEADER" || { + func_extract_trace AC_CONFIG_HEADERS + test -n "$func_extract_trace_result" \ + || func_extract_trace AC_CONFIG_HEADER + + test -n "$func_extract_trace_result" || { + AUTOHEADER=true + + func_verbose "export AUTOHEADER='$AUTOHEADER'" + + # Make sure the search result is visible to subshells + export AUTOHEADER + } + } + + require_autoheader=: +} + + +# require_autopoint +# ----------------- +# Skip autopoint if it's not needed. +require_autopoint=func_require_autopoint +func_require_autopoint () +{ + $debug_cmd + + test true = "$AUTOPOINT" || { + func_extract_trace AM_GNU_GETTEXT_VERSION + + test -n "$func_extract_trace_result" || { + AUTOPOINT=true + + func_verbose "export AUTOPOINT='$AUTOPOINT'" + + # Make sure the search result is visible to subshells + export AUTOPOINT + } + } + + require_autopoint=: +} + + +# require_bootstrap_uptodate +# -------------------------- +# Complain if the version of bootstrap in the gnulib directory differs +# from the one we are running. +require_bootstrap_uptodate=func_require_bootstrap_uptodate +func_require_bootstrap_uptodate () +{ + $debug_cmd + + $require_build_aux + + _G_bootstrap_sources=" + $build_aux/bootstrap.in + $build_aux/extract-trace + $build_aux/funclib.sh + $build_aux/options-parser + " + + _G_missing_bootstrap_sources=false + for _G_src in $_G_bootstrap_sources; do + test -f "$_G_src" || _G_missing_bootstrap_sources=: + done + + if $_G_missing_bootstrap_sources; then + func_warning upgrade "\ +Please add bootstrap to your gnulib_modules list in +'bootstrap.conf', so that I can tell you when there are +updates available." + else + $build_aux/inline-source $build_aux/bootstrap.in > bootstrap.new + + if func_cmp_s "$progpath" bootstrap.new; then + rm -f bootstrap.new + func_verbose "bootstrap script up to date" + else + func_warning upgrade "\ +An updated bootstrap script has been generated for you in +'bootstrap.new'. After you've verified that you want +the changes, you can update with: + cat bootstrap.new > $progname + ./$progname + +Or you can disable this check permanently by adding the +following to 'bootstrap.conf': + require_bootstrap_uptodate=:" + fi + fi + + require_bootstrap_uptodate=: +} + + +# require_build_aux +# ----------------- +# Ensure that '$build_aux' is set, and if it doesn't already point to an +# existing directory, create one. +require_build_aux=func_require_build_aux +func_require_build_aux () +{ + $debug_cmd + + test -n "$build_aux" || { + func_extract_trace_first AC_CONFIG_AUX_DIR + build_aux=$func_extract_trace_first_result + func_check_configuration build_aux \ + "AC_CONFIG_AUX_DIR([name of a directory for build scripts])" + + func_verbose "build_aux='$build_aux'" + } + + $require_vc_ignore_files + + # If the build_aux directory doesn't exist, create it now, and mark it + # as ignored for the VCS. + if test ! -d "$build_aux"; then + func_show_eval "mkdir '$build_aux'" + + test -n "$vc_ignore_files" \ + || func_insert_if_absent "$build_aux" $vc_ignore_files + fi + + require_build_aux=: +} + + +# require_buildreq_autobuild +# -------------------------- +# Try to find whether the bootstrap requires autobuild. +require_buildreq_autobuild=func_require_buildreq_autobuild +func_require_buildreq_autobuild () +{ + $debug_cmd + + $require_macro_dir + + test -f "$macro_dir/autobuild.m4" \ + || printf '%s\n' "$buildreq" |func_grep_q '^[ ]*autobuild' \ + || { + func_extract_trace AB_INIT + test -n "$func_extract_trace_result" && { + func_append buildreq 'autobuild - http://josefsson.org/autobuild/ +' + func_verbose "auto-adding 'autobuild' to build requirements" + } + } + + require_buildreq_autobuild=: +} + + +# require_buildreq_autoconf +# require_buildreq_autopoint +# require_buildreq_libtoolize +# --------------------------- +# Try to find the minimum compatible version of autoconf/libtool +# required to bootstrap successfully, and add it to '$buildreq'. +for tool in autoconf libtoolize autopoint; do + b=$tool + v=require_buildreq_${tool} + f=func_$v + case $tool in + autoconf) m=AC_PREREQ ;; + libtoolize) m=LT_PREREQ; b=libtool ;; + autopoint) m=AM_GNU_GETTEXT_VERSION b=gettext ;; + esac + + eval $v'='$f' + '$f' () + { + $debug_cmd + + # The following is ignored if undefined, but might be necessary + # in order for `func_find_tool` to run. + ${require_'$tool'-:} + + printf '\''%s\n'\'' "$buildreq" |func_grep_q '\''^[ ]*'$tool\'' || { + func_extract_trace '$m' + _G_version=$func_extract_trace_result + test -n "$_G_version" && { + func_append buildreq "\ + '$tool' $_G_version http://www.gnu.org/s/'$b' +" + func_verbose \ + "auto-adding '\'$tool'-'$_G_version\'' to build requirements" + } + } + + '$v'=: + } +' +done + + +# require_buildreq_automake +# ------------------------- +# Try to find the minimum compatible version of automake required to +# bootstrap successfully, and add it to '$buildreq'. +require_buildreq_automake=func_require_buildreq_automake +func_require_buildreq_automake () +{ + $debug_cmd + + # if automake is not already listed in $buildreq... + printf '%s\n' "$buildreq" |func_grep_q automake || { + func_extract_trace AM_INIT_AUTOMAKE + + # ...and AM_INIT_AUTOMAKE is declared... + test -n "$func_extract_trace_result" && { + automake_version=`$bs_echo "$func_extract_trace_result" \ + |$SED -e 's|[^0-9]*||' -e 's| .*$||'` + test -n "$automake_version" || automake_version=- + + func_append buildreq "\ + automake $automake_version http://www.gnu.org/s/automake +" + func_verbose \ + "auto-adding 'automake-$automake_version' to build requirements" + } + } + + require_buildreq_automake=: +} + + +# require_buildreq_patch +# ---------------------- +# Automatically add a patch build-requirement if there are diff files +# in $local_gl_dir. +require_buildreq_patch=func_require_buildreq_patch +func_require_buildreq_patch () +{ + $debug_cmd + + # This ensures PATCH is set appropriately by the time + # func_check_versions enforces $buildreq. + $require_patch + + # If patch is not already listed in $buildreq... + printf '%s\n' "$buildreq" |func_grep_q '^[ ]*patch' || { + # The ugly find invocation is necessary to exit with non-zero + # status for old find binaries that don't support -exec fully. + if test ! -d "$local_gl_dir" \ + || find "$local_gl_dir" -name *.diff -exec false {} \; ; then : + else + func_append buildreq 'patch - http://www.gnu.org/s/patch +' + fi + } + + require_buildreq_patch=: +} + + +# require_buildtools_uptodate +# --------------------------- +# Ensure all the packages listed in BUILDREQS are available on the build +# machine at the minimum versions or better. +require_buildtools_uptodate=func_require_buildtools_uptodate +func_require_buildtools_uptodate () +{ + $debug_cmd + + $require_buildreq_autobuild + $require_buildreq_autoconf + $require_buildreq_automake + $require_buildreq_libtoolize + $require_buildreq_autopoint + $require_buildreq_patch + + test -n "$buildreq" && { + _G_error_hdr= + + func_check_versions $buildreq + $func_check_versions_result || { + test -n "$buildreq_readme" \ + && test -f "$buildreq_readme" \ + && _G_error_hdr="\ +$buildreq_readme explains how to obtain these prerequisite programs: +" + func_strtable 0 11 12 36 \ + "Program" "Min_version" "Homepage" $buildreq + func_fatal_error "$_G_error_hdr$func_strtable_result" + } + } + + require_buildtools_uptodate=: +} + + +# require_copyright_holder +# ------------------------ +# Ensure there is a sensible non-empty default value in '$copyright_holder'. +require_copyright_holder=func_require_copyright_holder +func_require_copyright_holder () +{ + $debug_cmd + + test -n "$copyright_holder" || { + copyright_holder='Free Software Foundation, Inc.' + func_warning settings "\ +Please set copyright_holder explicitly in 'bootstrap.conf'; +defaulting to '$copyright_holder'." + } + + require_copyright_holder=: +} + + +# require_dotgitmodules +# --------------------- +# Ensure we have a '.gitmodules' file, with appropriate 'gnulib' settings. +require_dotgitmodules=func_require_dotgitmodules +func_require_dotgitmodules () +{ + $debug_cmd + + $require_git + + test true = "$GIT" || { + # A gnulib entry in .gitmodules always takes precedence. + _G_path=`$GIT config --file .gitmodules submodule.gnulib.path 2>/dev/null` + + test -n "$_G_path" || { + $require_vc_ignore_files + + func_verbose "creating '.gitmodules'" + + # If the .gitmodules file doesn't exist, create it now, and mark + # it as ignored for the VCS. + test -n "$gnulib_path" || gnulib_path=gnulib + test -n "$gnulib_url" || gnulib_url=git://git.sv.gnu.org/gnulib + + { + echo '[submodule "gnulib"]' + echo " path = $gnulib_path" + echo " url = $gnulib_url" + } >> .gitmodules + + test -n "$vc_ignore_files" \ + || func_insert_if_absent ".gitmodules" $vc_ignore_files + } + } + + require_dotgitmodules=: +} + + +# require_extra_locale_categories +# ------------------------------- +# Ensure there is a default value in '$extra_locale_categories' +require_extra_locale_categories=func_require_extra_locale_categories +func_require_extra_locale_categories () +{ + $debug_cmd + + # Defaults to empty, so run with whatever value may have been set in + # 'bootstrap.conf'. + require_extra_locale_categories=: +} + + +# require_git +# ----------- +# Ignore git if it's not available, or we're not in a git checkout tree. +require_git=func_require_git +func_require_git () +{ + $debug_cmd + + $opt_skip_git && GIT=true + + test true = "$GIT" || { + if test -f .gitignore && ($GIT --version) >/dev/null 2>&1; then :; else + GIT=true + fi + } + + func_verbose "GIT='$GIT'" + + require_git=: +} + + +# require_gnulib_cache +# -------------------- +# Ensure there is a non-empty default for '$gnulib_cache', and that it +# names an existing file. +require_gnulib_cache=func_require_gnulib_cache +func_require_gnulib_cache () +{ + $debug_cmd + + $require_macro_dir + + test -n "$gnulib_cache" \ + || gnulib_cache=$macro_dir/gnulib-cache.m4 + + func_verbose "found '$gnulib_cache'" + + require_gnulib_cache=: +} + + +# require_gnulib_merge_changelog +# ------------------------------ +# See if we can use gnulib's git-merge-changelog merge driver. +require_gnulib_merge_changelog=func_require_gnulib_merge_changelog +func_require_gnulib_merge_changelog () +{ + $debug_cmd + + test -f ChangeLog && { + $require_git + + func_grep_q '^\(/\|\)ChangeLog$' .gitignore || test true = "$GIT" || { + if $GIT config merge.merge-changelog.driver >/dev/null; then + : + elif (git-merge-changelog --version) >/dev/null 2>&1; then + func_echo "initializing git-merge-changelog driver" + $GIT config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' + $GIT config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' + else + func_warning recommend \ + "Consider installing git-merge-changelog from gnulib." + fi + } + } + + require_gnulib_merge_changelog=: +} + + +# require_gnulib_mk +# ----------------- +# Ensure gnulib_mk has a sensible value, extracted from 'gnulib-cache.m4' +# if possible, otherwise letting 'gnulib-tool' pick a default. +require_gnulib_mk=func_require_gnulib_mk +func_require_gnulib_mk () +{ + $debug_cmd + + test -f "$gnulib_cache" && test -z "$gnulib_mk" && { + $require_gnulib_cache + $require_macro_dir + + func_extract_trace_first "gl_MAKEFILE_NAME" "$gnulib_cache" + gnulib_mk=$func_extract_trace_first_result + + test -n "$gnulib_mk" && func_verbose "gnulib_mk='$gnulib_mk'" + } + + require_gnulib_mk=: +} + + +# require_gnulib_path +# require_gnulib_url +# ------------------- +# Ensure 'gnulib_path' and 'gnulib_url' are set. +require_gnulib_path=func_require_dotgitmodules_parameters +require_gnulib_url=func_require_dotgitmodules_parameters +func_require_dotgitmodules_parameters () +{ + $debug_cmd + + $require_git + + test true = "$GIT" && { + # If we can't find git (or if the user specified '--skip-git'), + # then use an existing gnulib directory specified with + # '--gnulib-srcdir' if possible. + test -n "$gnulib_path" \ + || test ! -x "$opt_gnulib_srcdir/gnulib-tool" \ + || gnulib_path=$opt_gnulib_srcdir + } + + + $require_dotgitmodules + + test -f .gitmodules && { + # Extract the parameters with sed, since git may be missing + test -n "$gnulib_path" \ + || gnulib_path=`$SED -e '/^.submodule "gnulib".$/,${ + /[ ]*path *= */{ + s|[ ]*||g;s|^[^=]*=||;p + } + } + d' .gitmodules |$SED 1q` + test -n "$gnulib_url" \ + || gnulib_url=`$SED -e '/^.submodule "gnulib".$/,${ + /[ ]*url *= */{ + s|[ ]*||g;s|^[^=]*=||;p + } + } + d' .gitmodules |$SED 1q` + + func_verbose "gnulib_path='$gnulib_path'" + func_verbose "gnulib_url='$gnulib_url'" + } + + require_gnulib_path=: + require_gnulib_url=: +} + + +# require_gnulib_submodule +# ------------------------ +# Ensure that there is a current gnulib submodule at '$gnulib_path'. +require_gnulib_submodule=func_require_gnulib_submodule +func_require_gnulib_submodule () +{ + $debug_cmd + + $require_git + + if test true = "$GIT"; then + func_warning recommend \ + "No 'git' found; imported gnulib modules may be outdated." + else + $require_gnulib_path + $require_gnulib_url + + if test -f .gitmodules && test -f "$gnulib_path/gnulib-tool"; then + : All present and correct. + + elif test -n "$opt_gnulib_srcdir"; then + # Older git can't clone into an empty directory. + rmdir "$gnulib_path" 2>/dev/null + func_show_eval "$GIT clone --reference '$opt_gnulib_srcdir' \ + '$gnulib_url' '$gnulib_path'" \ + || func_fatal_error "Unable to fetch gnulib submodule." + + # Without --gnulib-srcdir, and no existing checked out submodule, we + # create a new shallow clone of the remote gnulib repository. + else + trap func_cleanup_gnulib 1 2 13 15 + + shallow= + $GIT clone -h 2>&1 |func_grep_q -- --depth \ + && shallow='--depth 365' + + func_show_eval "$GIT clone $shallow '$gnulib_url' '$gnulib_path'" \ + func_cleanup_gnulib + + # FIXME: Solaris /bin/sh will try to execute '-' if any of + # these signals are caught after this. + trap - 1 2 13 15 + fi + + # Make sure we've checked out the correct revision of gnulib. + func_show_eval "$GIT submodule init" \ + && func_show_eval "$GIT submodule update" \ + || func_fatal_error "Unable to update gnulib submodule." + fi + + require_gnulib_submodule=: +} + + +# require_gnulib_tool +# ------------------- +# Ensure that '$gnulib_tool' is set, and points to an executable file, +# or else fall back to using the binary 'true' if the main gnulib +# files appear to have been imported already. +require_gnulib_tool=func_require_gnulib_tool +func_require_gnulib_tool () +{ + $debug_cmd + + test -n "$GNULIB_TOOL" && gnulib_tool=$GNULIB_TOOL + + test true = "$gnulib_tool" || { + $require_gnulib_submodule + $require_gnulib_path + + test -n "$gnulib_tool" \ + || gnulib_tool=$gnulib_path/gnulib-tool + + test -x "$gnulib_tool" || { + gnulib_tool=true + func_warning recommend \ + "No 'gnulib-tool' found; gnulib modules may be missing." + } + + test true = "$gnulib_tool" \ + || func_verbose "found '$gnulib_tool'" + } + + require_gnulib_tool=: +} + + +# require_gnulib_tool_base_options +# -------------------------------- +# Ensure that '$gnulib_tool_base_options' contains all the base options +# required according to user configuration from bootstrap.conf. +require_gnulib_tool_base_options=func_require_gnulib_tool_base_options +func_require_gnulib_tool_base_options () +{ + $debug_cmd + + $require_gnulib_tool + + gnulib_tool_base_options= + + test true = "$gnulib_tool" || { + $require_build_aux + $require_macro_dir + + # 'gnulib_modules' and others are maintained in 'bootstrap.conf': + # Use 'gnulib --import' to fetch gnulib modules. + test -n "$build_aux" \ + && func_append_uniq gnulib_tool_base_options " --aux-dir=$build_aux" + test -n "$macro_dir" \ + && func_append_uniq gnulib_tool_base_options " --m4-base=$macro_dir" + test -n "$doc_base" \ + && func_append_uniq gnulib_tool_base_options " --doc-base=$doc_base" + test -n "$gnulib_name" \ + && func_append_uniq gnulib_tool_base_options " --lib=$gnulib_name" + test -n "$local_gl_dir" \ + && func_append_uniq gnulib_tool_base_options " --local-dir=$local_gl_dir" + test -n "$source_base" \ + && func_append_uniq gnulib_tool_base_options " --source-base=$source_base" + } + + require_gnulib_tool_base_options=: +} + + +# require_libtoolize +# ------------------ +# Skip libtoolize if it's not needed. +require_libtoolize=func_require_libtoolize +func_require_libtoolize () +{ + $debug_cmd + + # Unless we're not searching for libtool use by this package, set + # LIBTOOLIZE to true if none of 'LT_INIT', 'AC_PROG_LIBTOOL' and + # 'AM_PROG_LIBTOOL' are used in configure. + test true = "$LIBTOOLIZE" || { + func_extract_trace LT_INIT + test -n "$func_extract_trace_result" || func_extract_trace AC_PROG_LIBTOOL + test -n "$func_extract_trace_result" || func_extract_trace AM_PROG_LIBTOOL + test -n "$func_extract_trace_result" || LIBTOOLIZE=true + } + + test -n "$LIBTOOLIZE" || { + # Find libtoolize, named glibtoolize in Mac Ports, but prefer + # user-installed libtoolize to ancient glibtoolize shipped by + # Apple with Mac OS X when Mac Ports is not installed. + func_find_tool LIBTOOLIZE libtoolize glibtoolize + } + + func_verbose "export LIBTOOLIZE='$LIBTOOLIZE'" + + # Make sure the search result is visible to subshells + export LIBTOOLIZE + + require_libtoolize=: +} + + +# require_macro_dir +# ----------------- +# Ensure that '$macro_dir' is set, and if it doesn't already point to an +# existing directory, create one. +require_macro_dir=func_require_macro_dir +func_require_macro_dir () +{ + $debug_cmd + + # Sometimes this is stored in 'configure.ac'. + test -n "$macro_dir" || { + # AC_CONFIG_MACRO_DIRS takes a space delimited list of directories, + # but we only care about the first one in bootstrap. + func_extract_trace_first AC_CONFIG_MACRO_DIRS + macro_dir=`expr "x$func_extract_trace_first_result" : 'x\([^ ]*\)'` + } + test -n "$macro_dir" || { + func_extract_trace_first AC_CONFIG_MACRO_DIR + macro_dir=$func_extract_trace_first_result + } + + # Otherwise we might find it in 'Makefile.am'. + test -n "$macro_dir" || { + $require_aclocal_amflags + + # Take the argument following the first '-I', if any. + _G_minus_I_seen=false + for _G_arg in $aclocal_amflags; do + case $_G_minus_I_seen,$_G_arg in + :,*) macro_dir=$_G_arg; break ;; + *,-I) _G_minus_I_seen=: ;; + *,-I*) macro_dir=`expr x$_G_arg : 'x-I\(.*\)$'`; break ;; + esac + done + } + + func_verbose "macro_dir='$macro_dir'" + + func_check_configuration macro_dir \ + "AC_CONFIG_MACRO_DIRS([name of a directory for configure m4 files])" + + $require_vc_ignore_files + + # If the macro_dir directory doesn't exist, create it now, and mark it + # as ignored for the VCS. + if test ! -d "$macro_dir"; then + mkdir "$macro_dir" || func_permissions_error "$macro_dir" + + test -n "$vc_ignore_files" \ + || func_insert_if_absent "$macro_dir" $vc_ignore_files + fi + + require_macro_dir=: +} + + +# require_makefile_am +# ------------------- +# Ensure there is a 'Makefile.am' in the current directory. +# names an existing file. +require_makefile_am=func_require_makefile_am +func_require_makefile_am () +{ + $debug_cmd + + test -n "$makefile_am" \ + || makefile_am=Makefile.am + + <"$makefile_am" + + func_verbose "found '$makefile_am'" + + require_makefile_am=: +} + + +# require_package +# --------------- +# Ensure that '$package' contains a sensible default value. +require_package=func_require_package +func_require_package () +{ + $debug_cmd + + test -n "$package" || { + $require_package_name + + package=`echo "$package_name" \ + |$SED -e 's/GNU //' \ + -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + } + + func_verbose "package='$package'" + + require_package=: +} + + +# require_package_bugreport +# ------------------------- +# Ensure that this has a sensible value, extracted from 'configure.ac' +# if appropriate (and possible!). +require_package_bugreport=func_require_package_bugreport +func_require_package_bugreport () +{ + $debug_cmd + + func_extract_trace AC_INIT + + save_ifs=$IFS + IFS=: + set dummy $func_extract_trace_result + IFS=$save_ifs + shift + + test -n "$package_bugreport" || package_bugreport=$3 + func_check_configuration package_bugreport \ + "AC_INIT([$package_name], [$package_version], [bug-$package@gnu.org])" + func_verbose "package_bugreport='$package_bugreport'" + + require_package_bugreport=: +} + + +# require_package_name +# -------------------- +# Ensure that this has a sensible value, extracted from 'configure.ac' +# if appropriate (and possible!). +require_package_name=func_require_package_name +func_require_package_name () +{ + $debug_cmd + + func_extract_trace AC_INIT + + save_ifs=$IFS + IFS=: + set dummy $func_extract_trace_result + IFS=$save_ifs + shift + + test -n "$package_name" || package_name=$1 + func_check_configuration package_name \ + "AC_INIT([name of your package], [package version number])" + func_verbose "package_name='$package_name'" + + require_package_name=: +} + + +# require_package_version +# ----------------------- +# Ensure that this has a sensible value, extracted from 'configure.ac' +# if appropriate (and possible!). While we might have set all the +# parameters extracted from AC_INIT at once, 'package_version' in +# particular is not necessarily available as early as the others, since +# 'git-version-gen' is often involved, and until then we can't rely on +# getting a correct version number from an AC_INIT extraction. +require_package_version=func_require_package_version +func_require_package_version () +{ + $debug_cmd + + func_extract_trace AC_INIT + + save_ifs=$IFS + IFS=: + set dummy $func_extract_trace_result + IFS=$save_ifs + shift + + test -n "$package_version" || package_version=$2 + test -n "$package_version" || { + # The embedded echo is to squash whitespace before globbing. + case " "`echo $gnulib_modules`" " in + *" git-version-gen "*) + func_fatal_error "\ +cannot \$require_package_version in bootstrap.conf before +func_gnulib_tool has installed the 'git-version-gen' script." + ;; + *) + func_check_configuration package_version \ + "AC_INIT([name of your package], [package version number])" + ;; + esac + } + func_verbose "package_version='$package_version'" + + require_package_version=: +} + + +# require_patch +# ------------- +# Find patch, according to the PATCH environment variable, or else +# searching the user's PATH. +require_patch=func_require_patch +func_require_patch () +{ + $debug_cmd + + test -n "$PATCH" || { + # Find a patch program, preferring gpatch which is usually better + # than the vendor patch. + func_find_tool PATCH gpatch patch + } + + func_verbose "export PATCH='$PATCH'" + + # Make sure the search result is visible to subshells + export PATCH + + require_patch=: +} + + +# require_source_base +# ------------------- +# Ensure that source_base has a sensible value, extracted from +# 'gnulib-cache.m4' if possible. +require_source_base=func_require_source_base +func_require_source_base () +{ + $debug_cmd + + $require_gnulib_cache + + test -f "$gnulib_cache" && test -z "$source_base" && { + $require_macro_dir + + func_extract_trace_first "gl_SOURCE_BASE" "$gnulib_cache" + + source_base=$func_extract_trace_first_result + + func_verbose "source_base='$source_base'" + } + + require_source_base=: +} + + +# require_vc_ignore_files +# ----------------------- +# Ensure that '$vc_ignore' has been processed to list VCS ignore files +# in '$vc_ignore_files' +require_vc_ignore_files=func_require_vc_ignore_files +func_require_vc_ignore_files () +{ + $debug_cmd + + test -n "$vc_ignore" || vc_ignore=auto + + if test auto = "$vc_ignore" && test -z "$vc_ignore_files"; then + vc_ignore_files= + test -d .git && vc_ignore_files=.gitignore + test -d CVS && vc_ignore_files="$vc_ignore_files .cvsignore" + else + vc_ignore_files=$vc_ignore + fi + + func_verbose "vc_ignore_files='$vc_ignore_files'" + + require_vc_ignore_files=: +} + + +## ------------------## +## Helper functions. ## +## ------------------## + +# This section contains the helper functions used by the rest of 'bootstrap'. + +# func_len STRING +# --------------- +# STRING may not start with a hyphen. +if (eval 'x=123; test x${#x} = "x3"') 2>/dev/null +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo 0` + } +fi + + +# func_unset VAR +# -------------- +# Portably unset VAR. +# In some shells, an 'unset VAR' statement leaves a non-zero return +# status if VAR is already unset, which might be problematic if the +# statement is used at the end of a function (thus poisoning its return +# value) or when 'set -e' is active (causing even a spurious abort of +# the script in this case). +func_unset () +{ + { eval $1=; unset $1; } +} +unset=func_unset + + +# func_cmp_s FILE1 FILE2 +# ---------------------- +# Return non-zero exit status unless FILE1 and FILE2 are identical, without +# any output at all, even error messages. +func_cmp_s () +{ + $debug_cmd + + # This function relies on non-zero exit status, which will cause the + # program to exit when running in 'set -e' mode. + $CMP "$@" >/dev/null 2>&1 +} + + +# func_grep_q EXPRESSION [FILENAME..] +# ----------------------------------- +# Check whether EXPRESSION matches any line of any listed FILENAME, +# without any output at all, even error messages. +func_grep_q () +{ + $debug_cmd + + # This function relies on non-zero exit status, which will cause the + # program to exit when running in 'set -e' mode. + $GREP "$@" >/dev/null 2>&1 +} + + +# func_ifcontains LIST MEMBER YES-CMD [NO-CMD] +# -------------------------------------------- +# If whitespace-separated LIST contains MEMBER then execute YES-CMD, +# otherwise if NO-CMD was give, execute that. +func_ifcontains () +{ + $debug_cmd + + # The embedded echo is to squash whitespace before globbing. + _G_wslist=`$bs_echo " "$1" "` + _G_member=$2 + _G_yes_cmd=$3 + _G_no_cmd=${4-":"} + + case $_G_wslist in + *" $_G_member "*) + eval "$_G_yes_cmd" + _G_status=$? + ;; + *) + eval "$_G_no_cmd" + _G_status=$? + ;; + esac + + test 0 -eq "$_G_status" || exit $_G_status +} + + +# func_strpad STR WIDTH CHAR +# -------------------------- +# Trim STR, or pad with CHAR to force a total length of WIDTH. +func_strpad () +{ + $debug_cmd + + _G_width=`expr "$2" - 1` + func_strpad_result=`$bs_echo "$1" |$SED ' + :a + s|^.\{0,'"$_G_width"'\}$|&'"$3"'| + ta + '` +} + + +# func_strrpad STR WIDTH CHAR +# --------------------------- +# Trim STR, or right-justify-pad with CHAR to force a total length of +# WIDTH. +func_strrpad () +{ + $debug_cmd + + _G_width=`expr "$2" - 1` + func_strrpad_result=`$bs_echo "$1" |$SED ' + :a + s|^.\{0,'"$_G_width"'\}$|'"$3"'&| + ta + '` +} + + +# func_strrow INDENT FIELD WIDTH [FIELDn WIDTHn]... +# ------------------------------------------------- +# Return a string containing each FIELD left justified to WIDTH, with +# the whole thing indented by INDENT spaces. This function is used to +# render one row of aligned columns for a table by func_strtable(). +func_strrow () +{ + $debug_cmd + + func_strrow_linelen=$1; shift + + _G_row= + while test $# -gt 0; do + func_strrow_linelen=`expr $func_strrow_linelen + $2` + func_strpad "$1" $2 " " + func_append _G_row "$func_strpad_result" + shift; shift + done + + func_strrpad "$_G_row" $func_strrow_linelen " " + func_strrow_result=$func_strrpad_result +} + + +# func_strtable INDENT WIDTH1...WIDTHn HEADER1...HEADERn FIELD1...FIELDn +# ---------------------------------------------------------------------- +# Generate a string of newline-separated rows arranged in lined-up +# columns of the given WIDTHs, with the entire table indented by INDENT +# spaces. The number of columns is determined by the number of integer +# valued WIDTH arguments following INDENT. The next set (i.e. a number +# of arguments equal to the number of WIDTH arguments) of fields are +# treated as the table's column HEADERs, and are separated from the +# remainder of the table by an indented row of '-' characters. Remaining +# arguments are each aligned below the next available header, wrapping +# to a new row as necessary. Finally another row of '-' characters is +# added to mark the end of the table. +# +# For example an unindented 3 column table with 2 rows of data would be +# generated by this call: +# +# func_strtable 3 20 10 25 \ +# Header1 Header2 Header3 \ +# Row1Col1 Row1Col2 Row1Col3 \ +# Row2Col1 Row2Col2 Row2Col3 +# +# returning the following string: +# +# " Header1 Header2 Header3 +# ------------------------------------------------------- +# Row1Col1 Row1Col2 Row1Col3 +# Row2Col1 Row2Col2 Row2Col3 +# -------------------------------------------------------" +func_strtable () +{ + $debug_cmd + + # Save the indent value, we'll need it for each row we render. + _G_indent=$1; shift + + # Collect remaining numeric args into a list for reuse between + # members of each row when we call func_strrow later. + _G_widths=$1; shift + while test 0 -lt `expr "$1" : '[1-9][0-9]*$'`; do + func_append _G_widths " $1"; shift + done + + # Extract the same number of positional parameters as there are + # width elements - we'll do the header rows separately so that + # we can insert a divider line. + _G_header=$_G_indent + for _G_width in $_G_widths; do + func_append _G_header " $1 $_G_width"; shift + done + func_strrow $_G_header + + # Strip off the indent, and make a divider with '-' chars, then + # reindent. + _G_divider=`$bs_echo "$func_strrow_result" \ + |$SED 's|[^ ]|-|g + :a + s|- |--|g + ta + '` + + # Append the header and divider to the running result. + func_append func_strtable_result "\ +$func_strrow_result +$_G_divider +" + + # The remaining rows are zipped between the width values we + # unwound earlier just like the header row above. + while test $# -gt 0; do + _G_row=$_G_indent + for _G_width in $_G_widths; do + func_append _G_row " $1 $_G_width"; shift + done + func_strrow $_G_row + func_append func_strtable_result "\ +$func_strrow_result +" + done + + # Mark the end of the table with a final divider line. + func_append func_strtable_result "$_G_divider" +} + + +# func_internal_error ARG... +# -------------------------- +# Echo program name prefixed message to standard error, and exit. +func_internal_error () +{ + func_fatal_error "\ +INTERNAL: " ${1+"$@"} " + Please report this bug to 'bug-gnulib@gnu.org' + in as much detail as possible." +} + + +# func_permissions_error FILE-OR-DIRECTORY +# ---------------------------------------- +# Echo program name prefixed permissions error message to standard +# error, and exit. +func_permissions_error () +{ + $debug_cmd + + func_fatal_error "Failed to create '$1', check permissions." +} + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + $require_term_colors + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + ${opt_silent-'false'} || { + func_quote_for_eval $_G_cmd + eval func_truncate_cmd $func_quote_for_eval_result + func_echo "running: $tc_bold$func_truncate_cmd_result$tc_reset" + } + + ${opt_dry_run-'false'} || { + eval "$_G_cmd" + _G_status=$? + test 0 -eq "$_G_status" || eval "(exit $_G_status); $_G_fail_exp" + } +} + + +# func_truncate_cmd CMD [ARG]... +# ------------------------------ +# For unreasonably long commands (such as a gnulib-tool invocation with +# the full module list for import), truncate CMD after the second non- +# option ARG. +func_truncate_cmd () +{ + $debug_cmd + + _G_last_arg_opt_p=false + func_truncate_cmd_result= + + set dummy "$@"; shift + + while test $# -gt 0; do + _G_opt=$1; shift + + test -n "$func_truncate_cmd_result" \ + && func_append func_truncate_cmd_result ' ' + func_append func_truncate_cmd_result "$_G_opt" + + func_len "x$func_truncate_cmd_result" + + case $_G_opt in + -*) _G_last_arg_opt_p=: ;; + *) $_G_last_arg_opt_p \ + || test "$min_cmd_len" -gt "$func_len_result" \ + || break + _G_last_arg_opt_p=false + ;; + esac + done + + test $# -gt 0 && func_append func_truncate_cmd_result "..." +} + + +# func_gitignore_entries FILE... +# ------------------------------ +# Strip blank and comment lines to leave significant entries. +func_gitignore_entries () +{ + $debug_cmd + + sed -e '/^#/d' -e '/^$/d' "$@" +} + + +# func_insert_if_absent STR FILE... +# --------------------------------- +# If $STR is not already on a line by itself in $FILE, insert it, at the +# start. Entries are inserted at the start of the ignore list to ensure +# existing entries starting with ! are not overridden. Such entries +# support whilelisting exceptions after a more generic blacklist pattern. +# sorting the new contents of the file and replacing $FILE with the result. +func_insert_if_absent () +{ + $debug_cmd + + str=$1 + shift + + for file + do + test -f "$file" || touch "$file" + + duplicate_entries=`func_gitignore_entries "$file" |sort |uniq -d` + test -n "$duplicate_entries" \ + && func_error "duplicate entries in $file: " $duplicate_entries + + func_grep_q "^$str\$" "$file" \ + || func_verbose "inserting '$str' into '$file'" + + linesold=`func_gitignore_entries "$file" |wc -l` + linesnew=`$bs_echo "$str" \ + |func_gitignore_entries - "$file" |sort -u |wc -l` + test "$linesold" -eq "$linesnew" \ + || { sed "1i\\$nl$str$nl" "$file" >"$file"T && mv "$file"T "$file"; } \ + || func_permissions_error "$file" + done +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + ver1=$1 + ver2=$2 + + # Split on '.' and compare each component. + i=1 + while :; do + p1=`echo "$ver1" |cut -d. -f$i` + p2=`echo "$ver2" |cut -d. -f$i` + if test ! "$p1"; then + echo "$1 $2" + break + elif test ! "$p2"; then + echo "$2 $1" + break + elif test ! "$p1" = "$p2"; then + if test "$p1" -gt "$p2" 2>/dev/null; then # numeric comparison + echo "$2 $1" + elif test "$p2" -gt "$p1" 2>/dev/null; then # numeric comparison + echo "$1 $2" + else # numeric, then lexicographic comparison + lp=`printf "$p1\n$p2\n" |sort -n |tail -n1` + if test "$lp" = "$p2"; then + echo "$1 $2" + else + echo "$2 $1" + fi + fi + break + fi + i=`expr $i + 1` + done +} + + +# func_get_version APP +# -------------------- +# echo the version number (if any) of APP, which is looked up along your +# PATH. +func_get_version () +{ + $debug_cmd + + _G_app=$1 + + # Rather than uncomment the sed script in-situ, strip the comments + # programatically before passing the result to $SED for evaluation. + sed_get_version=`$bs_echo '# extract version within line + s|.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| + t done + + # extract version at start of line + s|^\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| + t done + + d + + :done + # the following essentially does s|5.005|5.5| + s|\.0*\([1-9]\)|.\1|g + p + q' \ + |$SED '/^[ ]*#.*$/d'` + + func_tool_version_output $_G_app >/dev/null + _G_status=$? + + test 0 -ne "$_G_status" \ + || $_G_app --version 2>&1 |$SED -n "$sed_get_version" + + (exit $_G_status) +} + + +# func_check_versions APP1 VER1 URL1 ...[APPN VERN URLN] +# ------------------------------------------------------ +func_check_versions () +{ + $debug_cmd + + func_check_versions_result=: + + while test $# -gt 0; do + _G_app=$1; shift + _G_reqver=$1; shift + _G_url=$1; shift + + # Honor $APP variables ($TAR, $AUTOCONF, etc.) + _G_appvar=`echo $_G_app |tr '[a-z]' '[A-Z]'` + test TAR = "$_G_appvar" && _G_appvar=AMTAR + eval "_G_app=\${$_G_appvar-$_G_app}" + _G_instver=`func_get_version $_G_app` + + test -z "$_G_instver" \ + || func_verbose "found '$_G_app' version $_G_instver." + + # Fail if --version didn't work. + if test -z "$_G_instver"; then + func_error "Prerequisite '$_G_app' not found. Please install it, or +'export $_G_appvar=/path/to/$_G_app'." + func_check_versions_result=false + + # Fail if a new version than what we have is required. + elif test x- != "x$_G_reqver"; then + _G_newer=`func_sort_ver $_G_reqver $_G_instver |cut -d' ' -f2` + test "$_G_newer" != "$_G_instver" && { + func_error "\ +'$_G_app' version == $_G_instver is too old +'$_G_app' version >= $_G_reqver is required" + func_check_versions_result=false + } + fi + done +} + + +# func_cleanup_gnulib +# ------------------- +# Recursively delete everything below the path in the global variable +# GNULIB_PATH. +func_cleanup_gnulib () +{ + $debug_cmd + + _G_status=$? + $RM -fr "$gnulib_path" + exit $_G_status +} + + +# func_download_po_files SUBDIR DOMAIN +# ------------------------------------ +func_download_po_files () +{ + $debug_cmd + + func_echo "getting translations into $1 for $2..." + _G_cmd=`printf "$po_download_command_format" "$2" "$1"` + eval "$_G_cmd" +} + + +# func_update_po_files PO_DIR DOMAIN +# ---------------------------------- +# Mirror .po files to $po_dir/.reference and copy only the new +# or modified ones into $po_dir. Also update $po_dir/LINGUAS. +# Note po files that exist locally only are left in $po_dir but will +# not be included in LINGUAS and hence will not be distributed. +func_update_po_files () +{ + $debug_cmd + + # Directory containing primary .po files. + # Overwrite them only when we're sure a .po file is new. + _G_po_dir=$1 + _G_domain=$2 + + # Mirror *.po files into this dir. + # Usually contains *.s1 checksum files. + _G_ref_po_dir=$_G_po_dir/.reference + + test -d "$_G_ref_po_dir" || mkdir $_G_ref_po_dir || return + func_download_po_files $_G_ref_po_dir $_G_domain \ + && ls "$_G_ref_po_dir"/*.po 2>/dev/null \ + |$SED -e 's|.*/||' -e 's|\.po$||' > "$_G_po_dir/LINGUAS" || return + + # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6+. + func_find_tool SHA1SUM sha1sum gsha1sum shasum + + _G_langs=`cd $_G_ref_po_dir && echo *.po|$SED 's|\.po||g'` + test '*' = "$_G_langs" && _G_langs=x + for _G_po in $_G_langs; do + case $_G_po in x) continue;; esac + _G_new_po=$_G_ref_po_dir/$_G_po.po + _G_cksum_file=$_G_ref_po_dir/$_G_po.s1 + if ! test -f "$_G_cksum_file" || + ! test -f "$_G_po_dir/$_G_po.po" || + ! $SHA1SUM -c --status "$_G_cksum_file" \ + < "$_G_new_po" > /dev/null; then + echo "updated $_G_po_dir/$_G_po.po..." + cp "$_G_new_po" "$_G_po_dir/$_G_po.po" \ + && $SHA1SUM < "$_G_new_po" > "$_G_cksum_file" + fi + done +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]...' + +# Short help message in response to '-h'. Add to this in 'bootstrap.conf' +# if you accept any additional options. +usage_message="Common Bootstrap Options: + -c, --copy copy files instead of creating symbolic links. + --debug enable verbose shell tracing + -n, --dry-run print commands rather than running them + -f, --force attempt to bootstrap even if the sources seem not + to have been checked out. + --gnulib-srcdir=DIRNAME + specify a local directory where gnulib sources + reside. Use this if you already have the gnulib + sources on your machine, and don't want to waste + your bandwidth downloading them again. Defaults to + \$GNULIB_SRCDIR. + --no-warnings equivalent to '-Wnone' + --skip-git do not fetch files from remote repositories + --skip-po do not download po files. + -v, --verbose verbosely report processing + --version print version information and exit + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=$long_help_message" + 'recommend' show warnings about missing recommended packages + 'settings' show warnings about missing '$progname.conf' settings + 'upgrade' show warnings about out-dated files + +If the file '$progname.conf' exists in the same directory as this +script, its contents are read as shell variables to configure the +bootstrap. + +For build prerequisites, environment variables like \$AUTOCONF and +\$AMTAR are honored. + +Running without arguments will suffice in most cases. +" + +# Warning categories used by 'bootstrap', append others if you use them +# in your 'bootstrap.conf'. +warning_categories='recommend settings upgrade' + + +# bootstrap_options_prep [ARG]... +# ------------------------------- +# Preparation for options parsed by Bootstrap. +bootstrap_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_copy=${copy-'false'} + opt_dry_run=false + opt_force=false + opt_gnulib_srcdir=$GNULIB_SRCDIR + opt_skip_git=false + opt_skip_po=false + + # Pass back the list of options we consumed. + func_quote_for_eval ${1+"$@"} + bootstrap_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep bootstrap_options_prep + + +# bootstrap_parse_options [ARG]... +# -------------------------------- +# Provide handling for Bootstrap specific options. +bootstrap_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: ;; + --copy|-c) opt_copy=: ;; + --force|-f) opt_force=: ;; + + --gnulib-srcdir) + test $# = 0 && func_missing_arg $_G_opt && break + opt_gnulib_srcdir=$1 + shift + ;; + + --skip-git) opt_skip_git=: ;; + --skip-po) opt_skip_po=: ;; + + # Separate non-argument short options: + -c*|-f*|-n*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + bootstrap_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options bootstrap_parse_options + + +# bootstrap_validate_options [ARG]... +# ----------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +bootstrap_validate_options () +{ + $debug_cmd + + # Validate options. + test $# -gt 0 \ + && func_fatal_help "too many arguments" + + # Pass back the (empty) list of unconsumed options. + func_quote_for_eval ${1+"$@"} + bootstrap_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options bootstrap_validate_options + + +## -------------------------------------------------- ## +## Source package customisations in 'bootstrap.conf'. ## +## -------------------------------------------------- ## + +# Override the default configuration, if necessary. +# Make sure that bootstrap.conf is sourced from the current directory +# if we were invoked as "sh bootstrap". +case $0 in + */*) test -r "$0.conf" && . "$0.conf" ;; + *) test -r "$0.conf" && . ./"$0.conf" ;; +esac + + +## ------------------------------- ## +## Actually perform the bootstrap. ## +## ------------------------------- ## + +func_bootstrap ${1+"$@"} + +# The End. +exit ${exit_status-$EXIT_SUCCESS} + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "20/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: diff --git a/bootstrap.conf b/bootstrap.conf new file mode 100644 index 0000000..65cfaab --- /dev/null +++ b/bootstrap.conf @@ -0,0 +1,100 @@ +# bootstrap.conf (Stdlib) version 2013-05-06 +# +# Copyright (C) 2013 Gary V. Vaughan +# Written by Gary V. Vaughan, 2013 + +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +## -------------- ## +## Configuration. ## +## -------------- ## + +# List of programs, minimum versions, and software urls required to +# bootstrap, maintain and release GNU Zile. + +# Build prerequisites +buildreq=' + git 1.5.5 http://git-scm.com +' + +# List of slingshot files to link into stdlib tree before autotooling. +slingshot_files=' + .autom4te.cfg + GNUmakefile + Makefile.am + build-aux/do-release-commit-and-tag + build-aux/gitlog-to-changelog + build-aux/mkrockspecs + build-aux/release.mk + build-aux/rockspecs.mk + build-aux/sanity.mk + build-aux/specl.mk + m4/ax_compare_version.m4 + m4/ax_lua.m4 + m4/slingshot.m4 + travis.yml.in +' + +# No need to do any gnulib-tooling here. +gnulib_tool=true + +# The not-synced with gnulib warning is bogus until upstream adopts +# the saner bootstrap script. +require_bootstrap_uptodate=: + + +## -------------------------------- ## +## Source Slingshot customisations. ## +## -------------------------------- ## + +# Integrate the Slingshot submodule bootstrap. +# Make sure that bootstrap.slingshot is sourced from the current +# directory if we were invoked with "sh bootstrap". +case $0 in + */*) . "$0.slingshot" ;; + *) . ./"$0.slingshot" ;; +esac + + +## --------------- ## +## Hook functions. ## +## --------------- ## + +# stdlib_force_changelog +# ---------------------- +# Automake requires that ChangeLog exist. +stdlib_force_changelog () +{ + $debug_cmd + + echo "Autogenerated by 'make dist'" > ChangeLog || exit 1 +} +func_add_hook func_gnulib_tool stdlib_force_changelog + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "# bootstrap.conf (Stdlib) version " +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "$" +# End: diff --git a/bootstrap.slingshot b/bootstrap.slingshot new file mode 100644 index 0000000..ad7476f --- /dev/null +++ b/bootstrap.slingshot @@ -0,0 +1,277 @@ +# bootstrap.slingshot (Slingshot) version 2013-05-06 +# +# Copyright (C) 2013 Gary V. Vaughan +# Written by Gary V. Vaughan, 2013 + +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# For your project to work with subproject slingshot out of the box, you'll +# need to commit this file to your project's repository and source it from +# bootstrap.conf. +# +# case $0 in +# */*) . "$0.slingshot" ;; +# *) . ./"$0.slingshot" ;; +# esac + + +## -------------- ## +## Configuration. ## +## -------------- ## + +# Relative path to the local slingshot submodule, and url to the upsream +# git repository. If you have a slingshot entry in your .gitmodules file, +# these values are ignored. +slingshot_path= +slingshot_url= + + +## ------------------ ## +## Utility functions. ## +## ------------------ ## + +# slingshot_copy FILENAME SRCDIR DESTDIR +# -------------------------------------- +# If option '--copy' was specified, or soft-linking SRCFILE to DESTFILE +# fails, then try to copy SRCFILE to DESTFILE (making sure to update the +# timestamp so that a series of files with dependencies can be copied +# in the right order that their timestamps won't trigger rebuilds). +slingshot_copy () +{ + $debug_cmd + + slingshot_srcfile=`echo "$2/$1" |sed -e 's|/\./|/|g'` + slingshot_destfile=`echo "$3/$1" |sed -e 's|/\./|/|g'` + + $opt_force || { + # Nothing to do if the files are already identical. + if func_cmp_s "$slingshot_srcfile" "$slingshot_destfile"; then + func_verbose "'$slingshot_destfile' is up to date." + return 0 + fi + } + + # Require --force to remove existing $slingshot_destfile. + $opt_force && $RM "$slingshot_destfile" + test -f "$slingshot_destfile" && { + func_warn_and_continue "'$slingshot_destfile' exists: use '--force' to overwrite" + return 0 + } + + # Be careful to support 'func_copy dir/target srcbase destbase'. + func_dirname "$slingshot_destfile" + func_mkdir_p "$func_dirname_result" + + # Copy or link according to '--copy' option. + if $opt_copy; then + slingshot_copycmd=$CP + slingshot_copy_type=copying + else + slingshot_copycmd=$LN_S + slingshot_copy_type=linking + + func_relative_path "$3" "$2" + slingshot_srcfile=$func_relative_path_result/$1 + fi + slingshot_copy_msg="$slingshot_copy_type file '$slingshot_destfile'" + $opt_verbose && \ + slingshot_copy_msg="$slingshot_copy_type $slingshot_srcfile $3" + + if $opt_dry_run || { + ( umask 0 + $slingshot_copycmd "$slingshot_srcfile" "$slingshot_destfile" + ) >/dev/null 2>&1 + } + then + echo "$slingshot_copy_msg" + else + func_error "$slingshot_copy_type '$2/$1' to '$3/' failed" + return 1 + fi +} + + +## --------------- ## +## Hook functions. ## +## --------------- ## + +# slingshot_copy_files +# -------------------- +# Update files from slingshot subproject. +slingshot_copy_files () +{ + $debug_cmd + + $require_slingshot_submodule + + # Make sure we have the latest mkrockspecs + make -C slingshot build-aux/mkrockspecs + + # Update in-tree links. + for file in $slingshot_files; do + func_dirname_and_basename "./$file" + slingshot_copy "$func_basename_result" \ + "slingshot/$func_dirname_result" "$func_dirname_result" + done +} +func_add_hook func_prep slingshot_copy_files + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# require_slingshot_dotgitmodules +# ------------------------------- +# Ensure we have a '.gitmodules' file, with appropriate 'slingshot' settings. +require_slingshot_dotgitmodules=slingshot_require_slingshot_dotgitmodules +slingshot_require_slingshot_dotgitmodules () +{ + $debug_cmd + + $require_git + + test true = "$GIT" || { + # A slingshot entry in .gitmodules always takes precedence. + _G_path=`$GIT config --file .gitmodules submodule.slingshot.path 2>/dev/null` + + test -n "$_G_path" || { + $require_vc_ignore_files + + func_verbose "adding slingshot entries to '.gitmodules'" + + test -n "$slingshot_path" || slingshot_path=slingshot + test -n "$slingshot_url" || slingshot_url=git://github.com/gvvaughan/slingshot.git + + { + echo '[submodule "slingshot"]' + echo " path=$slingshot_path" + echo " url=$slingshot_url" + } >> .gitmodules + + test -n "$vc_ignore_files" \ + || func_insert_if_absent ".gitmodules" $vc_ignore_files + } + } + + require_slingshot_dotgitmodules=: +} + + +# require_slingshot_path +# require_slingshot_url +# ---------------------- +# Ensure 'slingshot_path' and 'slingshot_url' are set. +require_slingshot_path=slingshot_require_slingshot_dotgitmodules_parameters +require_slingshot_url=slingshot_require_slingshot_dotgitmodules_parameters +slingshot_require_slingshot_dotgitmodules_parameters () +{ + $debug_cmd + + $require_git + $require_slingshot_dotgitmodules + + test -f .gitmodules \ + || func_fatal_error "Unable to update '.gitmodules' with slingshot submodule" + + test true = "$GIT" || { + slingshot_path=`$GIT config --file=.gitmodules --get submodule.slingshot.path` + slingshot_url=`$GIT config --file=.gitmodules --get submodule.slingshot.url` + + func_verbose "slingshot_path='$slingshot_path'" + func_verbose "slingshot_url='$slingshot_url'" + } + + require_slingshot_path=: + require_slingshot_url=: +} + + +# require_slingshot_submodule +# --------------------------- +# Ensure that there is a current slingshot submodule. +require_slingshot_submodule=slingshot_require_slingshot_submodule +slingshot_require_slingshot_submodule () +{ + $debug_cmd + + $require_git + + if test true = "$GIT"; then + func_warning recommend \ + "No 'git' found; imported slingshot modules may be missing." + else + $require_slingshot_dotgitmodules + + if test -f .gitmodules && test -f "slingshot/build-aux/mkrockspecs.in" + then + : All present and correct. + + else + $require_slingshot_path + $require_slingshot_url + + trap slingshot_cleanup 1 2 13 15 + + shallow= + $GIT clone -h 2>&1 |func_grep_q -- --depth \ + && shallow='--depth 365' + + func_show_eval "$GIT clone $shallow '$slingshot_url' '$slingshot_path'" \ + slingshot_cleanup + + # FIXME: Solaris /bin/sh will try to execute '-' if any of + # these signals are caught after this. + trap - 1 2 13 15 + + # Make sure we've checked out the correct revision of slingshot. + func_show_eval "$GIT submodule init" \ + && func_show_eval "$GIT submodule update" \ + || func_fatal_error "Unable to update slingshot submodule." + fi + fi + + require_slingshot_submodule=: +} + + +# slingshot_cleanup +# ----------------- +# Recursively delete everything at $slingshot_path. +slingshot_cleanup () +{ + $debug_cmd + + $require_slingshot_path + + _G_status=$? + $RM -fr $slingshot_path + exit $_G_status +} + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "# bootstrap.slingshot (Slingshot) version " +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "$" +# End: diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog new file mode 100755 index 0000000..e02d34c --- /dev/null +++ b/build-aux/gitlog-to-changelog @@ -0,0 +1,432 @@ +eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' + & eval 'exec perl -wS "$0" $argv:q' + if 0; +# Convert git log output to ChangeLog format. + +my $VERSION = '2012-07-29 06:11'; # UTC +# The definition above must lie within the first 8 lines in order +# for the Emacs time-stamp write hook (at end) to update it. +# If you change this file with Emacs, please let the write hook +# do its job. Otherwise, update this string manually. + +# Copyright (C) 2008-2013 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Written by Jim Meyering + +use strict; +use warnings; +use Getopt::Long; +use POSIX qw(strftime); + +(my $ME = $0) =~ s|.*/||; + +# use File::Coda; # http://meyering.net/code/Coda/ +END { + defined fileno STDOUT or return; + close STDOUT and return; + warn "$ME: failed to close standard output: $!\n"; + $? ||= 1; +} + +sub usage ($) +{ + my ($exit_code) = @_; + my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); + if ($exit_code != 0) + { + print $STREAM "Try '$ME --help' for more information.\n"; + } + else + { + print $STREAM < ChangeLog + $ME -- -n 5 foo > last-5-commits-to-branch-foo + +SPECIAL SYNTAX: + +The following types of strings are interpreted specially when they appear +at the beginning of a log message line. They are not copied to the output. + + Copyright-paperwork-exempt: Yes + Append the "(tiny change)" notation to the usual "date name email" + ChangeLog header to mark a change that does not require a copyright + assignment. + Co-authored-by: Joe User + List the specified name and email address on a second + ChangeLog header, denoting a co-author. + Signed-off-by: Joe User + These lines are simply elided. + +In a FILE specified via --amend, comment lines (starting with "#") are ignored. +FILE must consist of pairs where SHA is a 40-byte SHA1 (alone on +a line) referring to a commit in the current project, and CODE refers to one +or more consecutive lines of Perl code. Pairs must be separated by one or +more blank line. + +Here is sample input for use with --amend=FILE, from coreutils: + +3a169f4c5d9159283548178668d2fae6fced3030 +# fix typo in title: +s/all tile types/all file types/ + +1379ed974f1fa39b12e2ffab18b3f7a607082202 +# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself. +# Change the author to be Paul. Note the escaped "@": +s,Jim .*>,Paul Eggert , + +EOF + } + exit $exit_code; +} + +# If the string $S is a well-behaved file name, simply return it. +# If it contains white space, quotes, etc., quote it, and return the new string. +sub shell_quote($) +{ + my ($s) = @_; + if ($s =~ m![^\w+/.,-]!) + { + # Convert each single quote to '\'' + $s =~ s/\'/\'\\\'\'/g; + # Then single quote the string. + $s = "'$s'"; + } + return $s; +} + +sub quoted_cmd(@) +{ + return join (' ', map {shell_quote $_} @_); +} + +# Parse file F. +# Comment lines (starting with "#") are ignored. +# F must consist of pairs where SHA is a 40-byte SHA1 +# (alone on a line) referring to a commit in the current project, and +# CODE refers to one or more consecutive lines of Perl code. +# Pairs must be separated by one or more blank line. +sub parse_amend_file($) +{ + my ($f) = @_; + + open F, '<', $f + or die "$ME: $f: failed to open for reading: $!\n"; + + my $fail; + my $h = {}; + my $in_code = 0; + my $sha; + while (defined (my $line = )) + { + $line =~ /^\#/ + and next; + chomp $line; + $line eq '' + and $in_code = 0, next; + + if (!$in_code) + { + $line =~ /^([0-9a-fA-F]{40})$/ + or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"), + $fail = 1, next; + $sha = lc $1; + $in_code = 1; + exists $h->{$sha} + and (warn "$ME: $f:$.: duplicate SHA1\n"), + $fail = 1, next; + } + else + { + $h->{$sha} ||= ''; + $h->{$sha} .= "$line\n"; + } + } + close F; + + $fail + and exit 1; + + return $h; +} + +# git_dir_option $SRCDIR +# +# From $SRCDIR, the --git-dir option to pass to git (none if $SRCDIR +# is undef). Return as a list (0 or 1 element). +sub git_dir_option($) +{ + my ($srcdir) = @_; + my @res = (); + if (defined $srcdir) + { + my $qdir = shell_quote $srcdir; + my $cmd = "cd $qdir && git rev-parse --show-toplevel"; + my $qcmd = shell_quote $cmd; + my $git_dir = qx($cmd); + defined $git_dir + or die "$ME: cannot run $qcmd: $!\n"; + $? == 0 + or die "$ME: $qcmd had unexpected exit code or signal ($?)\n"; + chomp $git_dir; + push @res, "--git-dir=$git_dir/.git"; + } + @res; +} + +{ + my $since_date; + my $format_string = '%s%n%b%n'; + my $amend_file; + my $append_dot = 0; + my $cluster = 1; + my $strip_tab = 0; + my $strip_cherry_pick = 0; + my $srcdir; + GetOptions + ( + help => sub { usage 0 }, + version => sub { print "$ME version $VERSION\n"; exit }, + 'since=s' => \$since_date, + 'format=s' => \$format_string, + 'amend=s' => \$amend_file, + 'append-dot' => \$append_dot, + 'cluster!' => \$cluster, + 'strip-tab' => \$strip_tab, + 'strip-cherry-pick' => \$strip_cherry_pick, + 'srcdir=s' => \$srcdir, + ) or usage 1; + + defined $since_date + and unshift @ARGV, "--since=$since_date"; + + # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/) + # that makes a correction in the log or attribution of that commit. + my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {}; + + my @cmd = ('git', + git_dir_option $srcdir, + qw(log --log-size), + '--pretty=format:%H:%ct %an <%ae>%n%n'.$format_string, @ARGV); + open PIPE, '-|', @cmd + or die ("$ME: failed to run '". quoted_cmd (@cmd) ."': $!\n" + . "(Is your Git too old? Version 1.5.1 or later is required.)\n"); + + my $prev_multi_paragraph; + my $prev_date_line = ''; + my @prev_coauthors = (); + while (1) + { + defined (my $in = ) + or last; + $in =~ /^log size (\d+)$/ + or die "$ME:$.: Invalid line (expected log size):\n$in"; + my $log_nbytes = $1; + + my $log; + my $n_read = read PIPE, $log, $log_nbytes; + $n_read == $log_nbytes + or die "$ME:$.: unexpected EOF\n"; + + # Extract leading hash. + my ($sha, $rest) = split ':', $log, 2; + defined $sha + or die "$ME:$.: malformed log entry\n"; + $sha =~ /^[0-9a-fA-F]{40}$/ + or die "$ME:$.: invalid SHA1: $sha\n"; + + # If this commit's log requires any transformation, do it now. + my $code = $amend_code->{$sha}; + if (defined $code) + { + eval 'use Safe'; + my $s = new Safe; + # Put the unpreprocessed entry into "$_". + $_ = $rest; + + # Let $code operate on it, safely. + my $r = $s->reval("$code") + or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n"; + + # Note that we've used this entry. + delete $amend_code->{$sha}; + + # Update $rest upon success. + $rest = $_; + } + + # Remove lines inserted by "git cherry-pick". + if ($strip_cherry_pick) + { + $rest =~ s/^\s*Conflicts:\n.*//sm; + $rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m; + } + + my @line = split "\n", $rest; + my $author_line = shift @line; + defined $author_line + or die "$ME:$.: unexpected EOF\n"; + $author_line =~ /^(\d+) (.*>)$/ + or die "$ME:$.: Invalid line " + . "(expected date/author/email):\n$author_line\n"; + + # Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog + # `(tiny change)' annotation. + my $tiny = (grep (/^Copyright-paperwork-exempt:\s+[Yy]es$/, @line) + ? ' (tiny change)' : ''); + + my $date_line = sprintf "%s %s$tiny\n", + strftime ("%F", localtime ($1)), $2; + + my @coauthors = grep /^Co-authored-by:.*$/, @line; + # Omit meta-data lines we've already interpreted. + @line = grep !/^(?:Signed-off-by:[ ].*>$ + |Co-authored-by:[ ] + |Copyright-paperwork-exempt:[ ] + )/x, @line; + + # Remove leading and trailing blank lines. + if (@line) + { + while ($line[0] =~ /^\s*$/) { shift @line; } + while ($line[$#line] =~ /^\s*$/) { pop @line; } + } + + # Record whether there are two or more paragraphs. + my $multi_paragraph = grep /^\s*$/, @line; + + # Format 'Co-authored-by: A U Thor ' lines in + # standard multi-author ChangeLog format. + for (@coauthors) + { + s/^Co-authored-by:\s*/\t /; + s/\s*/ + or warn "$ME: warning: missing email address for " + . substr ($_, 5) . "\n"; + } + + # If clustering of commit messages has been disabled, if this header + # would be different from the previous date/name/email/coauthors header, + # or if this or the previous entry consists of two or more paragraphs, + # then print the header. + if ( ! $cluster + || $date_line ne $prev_date_line + || "@coauthors" ne "@prev_coauthors" + || $multi_paragraph + || $prev_multi_paragraph) + { + $prev_date_line eq '' + or print "\n"; + print $date_line; + @coauthors + and print join ("\n", @coauthors), "\n"; + } + $prev_date_line = $date_line; + @prev_coauthors = @coauthors; + $prev_multi_paragraph = $multi_paragraph; + + # If there were any lines + if (@line == 0) + { + warn "$ME: warning: empty commit message:\n $date_line\n"; + } + else + { + if ($append_dot) + { + # If the first line of the message has enough room, then + if (length $line[0] < 72) + { + # append a dot if there is no other punctuation or blank + # at the end. + $line[0] =~ /[[:punct:]\s]$/ + or $line[0] .= '.'; + } + } + + # Remove one additional leading TAB from each line. + $strip_tab + and map { s/^\t// } @line; + + # Prefix each non-empty line with a TAB. + @line = map { length $_ ? "\t$_" : '' } @line; + + print "\n", join ("\n", @line), "\n"; + } + + defined ($in = ) + or last; + $in ne "\n" + and die "$ME:$.: unexpected line:\n$in"; + } + + close PIPE + or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; + # FIXME-someday: include $PROCESS_STATUS in the diagnostic + + # Complain about any unused entry in the --amend=F specified file. + my $fail = 0; + foreach my $sha (keys %$amend_code) + { + warn "$ME:$amend_file: unused entry: $sha\n"; + $fail = 1; + } + + exit $fail; +} + +# Local Variables: +# mode: perl +# indent-tabs-mode: nil +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "my $VERSION = '" +# time-stamp-format: "%:y-%02m-%02d %02H:%02M" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "'; # UTC" +# End: diff --git a/build-aux/mkrockspecs b/build-aux/mkrockspecs new file mode 100755 index 0000000..c3cac7a --- /dev/null +++ b/build-aux/mkrockspecs @@ -0,0 +1,274 @@ +#!/bin/sh +A=--[[ exec lua "$0" "$@" # -* mode: lua; -*s ]]A +-- +-- Slingshot rockspec generator. +-- +-- This file is distributed with Slingshot, and licensed under the +-- terms of the MIT license reproduced below. + +--[[ + +# ==================================================================== # +# Copyright (C) 2013 Gary V. Vaughan # +# # +# Permission is hereby granted, free of charge, to any person # +# obtaining a copy of this software and associated documentation # +# files (the "Software"), to deal in the Software without restriction, # +# including without limitation the rights to use, copy, modify, merge, # +# publish, distribute, sublicense, and/or sell copies of the Software, # +# and to permit persons to whom the Software is furnished to do so, # +# subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be # +# included in all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # +# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # +# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +# ==================================================================== # + +]] + + +--[[ ============== ]]-- +--[[ Parse options. ]]-- +--[[ ============== ]]-- + +local usage = 'Usage: mkrockspecs [OPTIONS] PACKAGE VERSION [REVISION]\n' + +local prog = { + _VERSION = "1", + + name = arg[0] and arg[0]:gsub (".*/", "") or "mkrockspecs", + + ["--help"] = function () + print (usage .. [[ + +Convert a YAML configuration file into a full rockspec. + +If there is a 'rockspec.conf' in the current directory, load it as the +base configuration, otherwise wait for input on stdin. + +PACKAGE and VERSION are the package name and version number as defined +by 'configure.ac' or similar. REVISION is only required for a revised +rockspec if the default "-1" revision was released with errors. + + --help print this help, then exit + --version print version number, then exit + +Report bugs to http://github.com/gvvaughan/slingshot/issues.]]) + os.exit (0) + end, + + ["--version"] = function () + print [[mkrockspecs (slingshot) 2 +Written by Gary V. Vaughan , 2013 + +Copyright (C) 2013, Gary V. Vaughan +Slingshot comes with ABSOLUTELY NO WARRANTY. +See source files for individual license conditions.]] + os.exit (0) + end, +} + +-- Print an argument processing error message, and return non-zero exit +-- status. +local function warn (msg) + io.stderr:write (usage) + io.stderr:write (prog.name .. ": error: " .. msg .. ".\n") + io.stderr:write (prog.name .. ": Try '" .. prog.name .. " --help' for help,\n") + return 2 +end + +local nonopts +local status = 0 +for _, opt in ipairs (arg) do + + -- Collect non-option arguments to save back into _G.arg later. + if type (nonopts) == "table" then + table.insert (nonopts, opt) + + -- Run prog.option handler. + elseif opt:sub (1,1) == "-" and type (prog[opt]) == "function" then + prog[opt] () + + -- End of option arguments. + elseif opt == "--" then + nonopts = {} + + -- Diagnose unknow command line options. + elseif opt:sub (1, 1) == "-" then + status = warn ("unrecognized option '" .. opt .. "'") + + -- First non-option argument marks the end of options. + else + nonopts = { opt } + end +end + +-- Don't exit until all warnings issued. +if status ~= 0 then os.exit (status) end + +-- put non-option args back into global arg table. +nonopts = nonopts or {} +nonopts[0] = arg[0] +_G.arg = nonopts + +if select ("#", ...) < 2 then + io.stderr:write "Usage: mkrockspecs PACKAGE VERSION [REVISION]\n" + os.exit () +end + +local package = arg[1] +local version = arg[2] +local revision = arg[3] or "1" + + +--[[ =================== ]]-- +--[[ Load configuration. ]]-- +--[[ =================== ]]-- + +local yaml = require "lyaml" +local conf = "rockspec.conf" + +-- Slurp io.input (). +local function slurp () + h = io.input () + if h then + local s = h:read "*a" + h:close () + return s + end +end + +local h = io.open (conf) +if h then + io.input (conf) + h:close () +else + io.input (io.stdin) +end + +local spec = yaml.load (slurp ()) +local default = { source = {} } + +-- url needn't be given if it is identical to homepage. +local url +if spec.source ~= nil then + url = spec.source.url +elseif spec.description ~= nil then + url = spec.description.homepage +end +url = url:gsub ("^[a-z]*://", ""):gsub ("%.git$", "") + +-- Interpolate default values. +default.package = package +default.version = version .. "-" .. revision + +configure_flags = "" +if type (spec.external_dependencies) == "table" then + CPPFLAGS, LDFLAGS = "", "" + for name, vars in pairs (spec.external_dependencies) do + if vars.library then + CPPFLAGS = CPPFLAGS .. " -I$(" .. name .. "_INCDIR)" + LDFLAGS = LDFLAGS .. " -L$(" .. name .. "_LIBDIR)" + end + end + + if string.len (CPPFLAGS) > 0 then + configure_flags = configure_flags .. + "CPPFLAGS='" .. CPPFLAGS:gsub ("^%s", "") .. "'" .. + " LDFLAGS='" .. LDFLAGS:gsub ("^%s", "") .. "'" .. + " " + end +end + +default.build = { + type = "command", + build_command = "./configure " .. + "LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' " .. configure_flags .. + "--prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' " .. + "&& make clean all", + install_command = "make install luadir='$(LUADIR)'", + copy_directories = {}, +} + +-- Additional spec-type dependenent values. +spec.source = spec.source or {} +if version ~= "scm" and version ~= "git" then + spec.source.url = "http://" .. url .. "/archive/release-v" .. version .. ".zip" + spec.source.dir = package .. "-release-v" .. version +else + spec.source.url = "git://" .. url .. ".git" + default.build.build_command = "./bootstrap && " .. default.build.build_command +end + +-- Recursive merge, settings from spec take precedence. Elements of src +-- overwrite equivalent keys in dest. +local function merge (dest, src) + for k, v in pairs (src) do + if type (v) == "table" then + dest[k] = merge (dest[k] or {}, src[k]) + else + dest[k] = src[k] + end + end + return dest +end + +spec = merge (default, spec) + + +--[[ ======= ]]-- +--[[ Output. ]]-- +--[[ ======= ]]-- + +-- Recursively format X, with pretty printing. +local function format (x, indent) + indent = indent or "" + if type (x) == "table" then + if next (x) == nil then + return "{}" + else + local s = "{\n" + for i, v in pairs (x) do + if type (i) ~= "number" then + s = s..indent..i.." = "..format (v, indent.." ")..",\n" + end + end + for i, v in ipairs (x) do + s = s..indent..format (v, indent.." ")..",\n" + end + return s..indent:sub (1, -3).."}" + end + elseif type (x) == "string" then + return string.format ("%q", x) + else + return tostring (x) + end +end + +-- Use the standard order for known keys. +for _, k in ipairs { + "package", + "version", + "description", + "source", + "dependencies", + "external_dependencies", + "build", +} do + print (k .. " = " .. format (spec[k], " ")) + spec[k] = nil +end + +-- Output anything left in the table at the end. +for i, v in pairs (spec) do + print (i .. " = " .. format (v, " ")) +end + +os.exit (0) diff --git a/build-aux/release.mk b/build-aux/release.mk new file mode 100644 index 0000000..00019ef --- /dev/null +++ b/build-aux/release.mk @@ -0,0 +1,377 @@ +# Slingshot release rules for GNU Make. + +# ====================================================================== +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Originally by Jim Meyering, Simon Josefsson, Eric Blake, +# Akim Demaille, Gary V. Vaughan, and others. +# This version by Gary V. Vaughan, 2013. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# ====================================================================== + +NOTHING_ELSE ?= + + +## --------------- ## +## GNU Make magic. ## +## --------------- ## + +# This file uses GNU Make extensions. Include it from GNUmakefile with: +# +# include build-aux/release.mk + +# Make tar archive easier to reproduce. +export TAR_OPTIONS = --owner=0 --group=0 --numeric-owner + +# Helper variables. +_empty = +_sp = $(_empty) $(_empty) + +# member-check,VARIABLE,VALID-VALUES +# ---------------------------------- +# Check that $(VARIABLE) is in the space-separated list of VALID-VALUES, and +# return it. Die otherwise. +member-check = \ + $(strip \ + $(if $($(1)), \ + $(if $(findstring $(_sp),$($(1))), \ + $(error invalid $(1): '$($(1))', expected $(2)), \ + $(or $(findstring $(_sp)$($(1))$(_sp),$(_sp)$(2)$(_sp)), \ + $(error invalid $(1): '$($(1))', expected $(2)))), \ + $(error $(1) undefined))) + +include Makefile + +## --------- ## +## Defaults. ## +## --------- ## + +GIT ?= git +LUA ?= lua +TAR ?= tar + +# Override this in cfg.mk if you are using a different format in your +# NEWS file. +today ?= $(shell date +%Y-%m-%d) + +# Old releases are stored here. +release_archive_dir ?= ../release + +# Override this in cfg.mk if you follow different procedures. +release-prep-hook ?= release-prep + +_build-aux ?= build-aux +my_distdir ?= $(PACKAGE)-$(VERSION) +prev_version_file ?= $(srcdir)/.prev-version +old_NEWS_hash-file ?= $(srcdir)/local.mk +gl_noteworthy_news_ = * Noteworthy changes in release ?.? (????-??-??) [?] + +PREV_VERSION = $(shell cat $(prev_version_file) 2>/dev/null) +VERSION_REGEXP = $(subst .,\.,$(VERSION)) +PREV_VERSION_REGEXP = $(subst .,\.,$(PREV_VERSION)) + + +## ------------- ## +## Distribution. ## +## ------------- ## + +gitlog_to_changelog = $(srcdir)/build-aux/gitlog-to-changelog + +dist-hook: ChangeLog +.PHONY: ChangeLog +ChangeLog: + $(AM_V_GEN)if test -d '$(srcdir)/.git'; then \ + $(gitlog_to_changelog) > '$@T'; \ + rm -f '$@'; mv '$@T' '$@'; \ + fi + +# Override this in GNUmakefile if you don't want to automatically +# redistribute all the maintainer support files (take care that +# Travis CI is finicky about this, and will likely need tweaking +# to cope with missing any of these if you decide to omit them). +release_extra_dist ?= \ + .autom4te.cfg \ + .travis.yml \ + GNUmakefile \ + bootstrap \ + bootstrap.conf \ + bootstrap.slingshot \ + local.mk \ + travis.yml.in \ + $(NOTHING_ELSE) + +EXTRA_DIST += \ + $(_build-aux)/release.mk \ + $(gitlog_to_changelog) \ + $(release_extra_dist) \ + $(NOTHING_ELSE) + +all-am: .travis.yml + + +## -------- ## +## Release. ## +## -------- ## + +# The vast majority of what follows is preparation -in the form +# of early bail-out if something is not right yet- for the final +# check-in-release-branch rule that makes the tip of the release +# branch match the contents of a 'make distcheck' tarball. + +# Validate and return $(RELEASE_TYPE), or die. +RELEASE_TYPES = alpha beta stable +release-type = $(call member-check,RELEASE_TYPE,$(RELEASE_TYPES)) + +# This will actually make the release, including sending release +# announcements, and pushing changes back to the origin. +# Use it like this, eg: +# make RELEASE_TYPE=beta +.PHONY: release +release: + $(AM_V_GEN)$(MAKE) $(release-type) + $(AM_V_GEN)$(MAKE) push + $(AM_V_GEN)$(MAKE) mail + +submodule-checks ?= no-submodule-changes public-submodule-commit + +.PHONY: no-submodule-changes +no-submodule-changes: + $(AM_V_GEN)if test -d $(srcdir)/.git \ + && git --version >/dev/null 2>&1; then \ + diff=$$(cd $(srcdir) && git submodule -q foreach \ + git diff-index --name-only HEAD) \ + || exit 1; \ + case $$diff in '') ;; \ + *) echo '$(ME): submodule files are locally modified:'; \ + echo "$$diff"; exit 1;; esac; \ + else \ + : ; \ + fi + +# Ensure that each sub-module commit we're using is public. +# Without this, it is too easy to tag and release code that +# cannot be built from a fresh clone. +.PHONY: public-submodule-commit +public-submodule-commit: + $(AM_V_GEN)if test -d $(srcdir)/.git \ + && git --version >/dev/null 2>&1; then \ + cd $(srcdir) && \ + git submodule --quiet foreach \ + test '"$$(git rev-parse "$$sha1")"' \ + = '"$$(git merge-base origin "$$sha1")"' \ + || { echo '$(ME): found non-public submodule commit' >&2; \ + exit 1; }; \ + else \ + : ; \ + fi +# This rule has a high enough utility/cost ratio that it should be a +# dependent of "check" by default. However, some of us do occasionally +# commit a temporary change that deliberately points to a non-public +# submodule commit, and want to be able to use rules like "make check". +# In that case, run e.g., "make check gl_public_submodule_commit=" +# to disable this test. +gl_public_submodule_commit ?= public-submodule-commit +check: $(gl_public_submodule_commit) + +# These targets do all the file shuffling necessary for a release, but +# purely locally, so you can rewind and redo before pushing anything +# to origin or sending release announcements. Use it like this, eg: +# +# make beta +.PHONY: alpha beta stable +alpha beta stable: $(submodule-checks) + $(AM_V_GEN)test $@ = stable && \ + { echo $(VERSION) |$(EGREP) '^[0-9]+(\.[0-9]+)*$$' >/dev/null \ + || { echo "invalid version string: $(VERSION)" 1>&2; exit 1;};}\ + || : + $(AM_V_at)$(MAKE) prev-version-check + $(AM_V_at)$(MAKE) vc-diff-check + $(AM_V_at)$(MAKE) release-commit RELEASE_TYPE=$@ + $(AM_V_at)$(MAKE) news-check + $(AM_V_at)$(MAKE) distcheck + $(AM_V_at)$(MAKE) check + $(AM_V_at)$(MAKE) $(release-prep-hook) RELEASE_TYPE=$@ + $(AM_V_at)$(MAKE) check-in-release-branch + +prev-version-check: + $(AM_V_at)if test -z "`$(GIT) ls-files $(prev_version_file)`"; \ + then \ + echo "error: checked in $(prev_version_file) required." >&2; \ + exit 1; \ + fi + +# Abort the release if there are unchecked in changes remaining. +vc-diff-check: + $(AM_V_at)if ! $(GIT) diff --exit-code; then \ + $(GIT) diff >/dev/null; \ + echo "error: Some files are locally modified" >&2; \ + exit 1; \ + fi + +# Select which lines of NEWS are searched for $(news-check-regexp). +# This is a sed line number spec. The default says that we search +# only line 3 of NEWS for $(news-check-regexp), to match the behaviour +# of '$(_build-aux)/do-release-commit-and-tag'. +# If you want to search only lines 1-10, use "1,10". +news-check-lines-spec ?= 3 +news-check-regexp ?= '^\*.* $(VERSION_REGEXP) \($(today)\)' + +news-check: NEWS + $(AM_V_GEN)if $(SED) -n $(news-check-lines-spec)p $< \ + | $(EGREP) $(news-check-regexp) >/dev/null; then \ + :; \ + else \ + echo 'NEWS: $$(news-check-regexp) failed to match' 1>&2; \ + exit 1; \ + fi + +.PHONY: release-commit +release-commit: + $(AM_V_GEN)cd $(srcdir) \ + && $(_build-aux)/do-release-commit-and-tag \ + -C $(abs_builddir) $(VERSION) $(RELEASE_TYPE) + +define emit-commit-log + printf '%s\n' 'maint: post-release administrivia.' '' \ + '* NEWS: Add header line for next release.' \ + '* .prev-version: Record previous version.' \ + '* $(old_NEWS_hash-file) (old_NEWS_hash): Auto-update.' +endef + +.PHONY: release-prep +release-prep: $(scm_rockspec) + $(AM_V_GEN)$(MAKE) --no-print-directory -s announcement \ + > ~/announce-$(my_distdir) + $(AM_V_at)if test -d $(release_archive_dir); then \ + ln $(rel-files) $(release_archive_dir); \ + chmod a-w $(rel-files); \ + fi + $(AM_V_at)echo $(VERSION) > $(prev_version_file) + $(AM_V_at)$(MAKE) update-old-NEWS-hash + $(AM_V_at)perl -pi \ + -e '$$. == 3 and print "$(gl_noteworthy_news_)\n\n\n"' \ + $(srcdir)/NEWS + $(AM_V_at)msg=$$($(emit-commit-log)) || exit 1; \ + cd $(srcdir) && $(GIT) commit -s -m "$$msg" -a + @echo '**** Release announcement in ~/announce-$(my_distdir)' + +# Strip out copyright messages with years, so that changing those (e.g. +# with 'make update-copyight') doesn't change the old_NEWS_hash. +NEWS_hash = \ + $$(sed -n '/^\*.* $(PREV_VERSION_REGEXP) ([0-9-]*)/,$$p' \ + $(srcdir)/NEWS \ + | perl -0777 -pe 's/^Copyright.+?[12][0-9]{3}.+?\n//ms' \ + | md5sum - \ + | sed 's/ .*//') + +# Update the hash stored above. Do this after each release and +# for any corrections to old entries. + +old-NEWS-regexp = '^old_NEWS_hash[ \t]+?=[ \t]+' +update-old-NEWS-hash: NEWS + $(AM_V_GEN)if $(EGREP) $(old-NEWS-regexp) $(old_NEWS_hash-file); then \ + perl -pi -e 's/^(old_NEWS_hash[ \t]+:?=[ \t]+).*/$${1}'"$(NEWS_hash)/" \ + $(old_NEWS_hash-file); \ + else \ + printf '%s\n' '' "old_NEWS_hash = $(NEWS_hash)" \ + >> $(old_NEWS_hash-file); \ + fi + +ANNOUNCE_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' +ANNOUNCE_PRINT = $(ANNOUNCE_ENV) $(LUA) -l$(PACKAGE) -e + +_PRE = " http://raw." +_POST = "/release-v$(VERSION)/$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec" +GITHUB_ROCKSPEC = (source.url:gsub ("^git://", $(_PRE)):gsub ("%.git$$", $(_POST))) + +announcement: NEWS +# Not $(AM_V_GEN) since the output of this command serves as +# announcement message: else, it would start with " GEN announcement". + $(AM_V_at)$(ANNOUNCE_PRINT) 'print (description.summary)' + $(AM_V_at)printf '%s\n' '' \ + 'I am happy to announce the release of $(PACKAGE_NAME) release $(VERSION).' \ + '' + $(AM_V_at)$(ANNOUNCE_PRINT) \ + 'print ("$(PACKAGE_NAME)'\''s home page is at " .. description.homepage)' + $(AM_V_at)printf '\n' + $(AM_V_at)$(SED) -n \ + -e '/^\* Noteworthy changes in release $(PREV_VERSION)/q' \ + -e p NEWS |$(SED) -e 1,2d + $(AM_V_at)printf '%s\n' \ + 'Install it with LuaRocks, using:' '' \ + ' luarocks install $(PACKAGE)-$(VERSION)' '' \ + 'Until the rocks are available from the official repository in a few days,' \ + 'you can install directly from the $(PACKAGE) release branch, with:' \ + '' ' $$ luarocks install \' + $(AM_V_at)$(ANNOUNCE_PRINT) 'print ($(GITHUB_ROCKSPEC))' + + +branch = $(shell $(GIT) branch |$(SED) -ne '/^\* /{s///;p;q;}') +GCO = $(GIT) checkout +release-tarball = $(my_distdir).tar.gz + +# Anything in $(_save-files) is not removed after switching to the +# release branch, and is thus "in the release". Add addtional partial +# filenames to save in save_release_files, for example: +# save_release_files = RELEASE-NOTES- +_save-files = \ + $(release-tarball) \ + $(save_release_files) \ + $(NOTHING_ELSE) + + +list-to-rexp = $(SED) -e 's|^|(|' -e 's/|$$/)/' +git-clean-files = `printf -- '-e %s ' $(_save-files)` +grep-clean-files = `printf -- '%s|' $(_save-files) |$(list-to-rexp)` + +# Switch to (or create) 'release' branch, remove all files, except the +# newly generated dist tarball, then unpack the dist tarball and check +# in all the files it creates, and tag that as the next release. +# Github creates automatic zipballs of tagged git revisions, so we can +# safely use this tag in the rockspecs we distribute. +.PHONY: check-in-release-branch +check-in-release-branch: + $(AM_V_GEN)$(GCO) -b release v1 2>/dev/null || $(GCO) release + $(AM_V_at)$(GIT) pull origin release 2>/dev/null || true + $(AM_V_at)$(GIT) clean -dfx $(git-clean-files) + $(AM_V_at)remove_re=$(grep-clean-files); \ + $(GIT) rm -f `$(GIT) ls-files |$(EGREP) -v "$$remove_re"` + $(AM_V_at)ln -s . '$(my_distdir)' + $(AM_V_at)$(TAR) zxf '$(release-tarball)' + $(AM_V_at)rm -f '$(my_distdir)' '$(release-tarball)' + $(AM_V_at)$(GIT) add . + $(AM_V_at)$(GIT) commit -s -a -m "Release v$(VERSION)." + $(AM_V_at)$(GIT) tag -s -a -m "Full source $(VERSION) release" release-v$(VERSION) + $(AM_V_at)$(GCO) $(branch) + +.PHONY: push +push: + $(AM_V_at)$(GIT) push origin master + $(AM_V_at)$(GIT) push origin release + $(AM_V_at)$(GIT) push origin v$(VERSION) + $(AM_V_at)$(GIT) push origin release-v$(VERSION) + +announce_emails ?= lua-l@lists.lua.org +rockspec_emails ?= luarocks-developers@lists.sourceforge.net + +.PHONY: mail +mail: + $(AM_V_at)cat ~/announce-$(my_distdir) \ + | mail -s '[ANN] $(PACKAGE) $(VERSION) released' -- \ + $(announce_emails) + $(AM_V_at)printf '%s\n' \ + 'Rockspec for $(PACKAGE) version $(VERSION) at:' \ + `$(ANNOUNCE_PRINT) 'print ($(GITHUB_ROCKSPEC))'` \ + | mail -s '[ANN] $(PACKAGE) $(VERSION) released; rockspec url included' -- \ + $(rockspec_emails) diff --git a/build-aux/rockspecs.mk b/build-aux/rockspecs.mk new file mode 100644 index 0000000..1271c36 --- /dev/null +++ b/build-aux/rockspecs.mk @@ -0,0 +1,112 @@ +# Slingshot rockspec rules for make. + +# This file is distributed with Slingshot, and licensed under the +# terms of the MIT license reproduced below. + +# ==================================================================== # +# Copyright (C) 2013 Reuben Thomas and Gary V. Vaughan # +# # +# Permission is hereby granted, free of charge, to any person # +# obtaining a copy of this software and associated documentation # +# files (the "Software"), to deal in the Software without restriction, # +# including without limitation the rights to use, copy, modify, merge, # +# publish, distribute, sublicense, and/or sell copies of the Software, # +# and to permit persons to whom the Software is furnished to do so, # +# subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be # +# included in all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # +# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # +# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +# ==================================================================== # + + +## --------- ## +## LuaRocks. ## +## --------- ## + +# This file is suitable for use from a portable Makefile, you might +# include it into the top-level Makefile.am with: +# +# include build-aux/rockspecs.mk + +luarocks_config = build-aux/luarocks-config.lua +rockspec_conf = $(srcdir)/rockspec.conf +mkrockspecs = $(srcdir)/build-aux/mkrockspecs +package_rockspec = $(srcdir)/$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec +scm_rockspec = $(PACKAGE)-git-$(rockspec_revision).rockspec + +# If you need a different rockspec revision, override this on the make +# command line: +# +# make rockspecs rockspec_revision=2 +rockspec_revision = 1 + +LUAROCKS = luarocks +MKROCKSPECS = $(MKROCKSPECS_ENV) $(LUA) $(mkrockspecs) + +ROCKSPECS_DEPS = \ + $(luarocks_config) \ + $(mkrockspecs) \ + $(rockspec_conf) \ + $(NOTHING_ELSE) + +set_LUA_BINDIR = LUA_BINDIR=`which $(LUA) |$(SED) 's|/[^/]*$$||'` +LUA_INCDIR = `cd $$LUA_BINDIR/../include && pwd` +LUA_LIBDIR = `cd $$LUA_BINDIR/../lib && pwd` + +$(luarocks_config): Makefile.am + @test -d build-aux || mkdir build-aux + $(AM_V_GEN){ \ + $(set_LUA_BINDIR); \ + echo 'rocks_trees = { "$(abs_srcdir)/luarocks" }'; \ + echo 'variables = {'; \ + echo ' LUA = "$(LUA)",'; \ + echo ' LUA_BINDIR = "'$$LUA_BINDIR'",'; \ + echo ' LUA_INCDIR = "'$(LUA_INCDIR)'",'; \ + echo ' LUA_LIBDIR = "'$(LUA_LIBDIR)'",'; \ + echo '}'; \ + } > '$@' + +$(package_rockspec): $(ROCKSPECS_DEPS) + $(AM_V_at)rm -f '$@' 2>/dev/null || : + $(AM_V_GEN)test -f '$@' || \ + $(MKROCKSPECS) $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' + $(AM_V_at)$(LUAROCKS) lint '$@' + +$(scm_rockspec): $(ROCKSPECS_DEPS) + $(AM_V_at)rm '$@' 2>/dev/null || : + $(AM_V_GEN)test -f '$@' || \ + $(MKROCKSPECS) $(PACKAGE) git 1 > '$@' + $(AM_V_at)$(LUAROCKS) lint '$@' + +.PHONY: rockspecs +rockspecs: + $(AM_V_at)rm -f *.rockspec + $(AM_V_at)$(MAKE) $(package_rockspec) $(scm_rockspec) + + +## ------------- ## +## Distribution. ## +## ------------- ## + +EXTRA_DIST += \ + $(mkrockspecs) \ + $(package_rockspec) \ + $(rockspec_conf) \ + $(NOTHING_ELSE) + + +## ------------ ## +## Maintenance. ## +## ------------ ## + +DISTCLEANFILES += \ + $(luarocks_config) \ + $(NOTHING_ELSE) diff --git a/build-aux/sanity.mk b/build-aux/sanity.mk new file mode 100644 index 0000000..f2f43bd --- /dev/null +++ b/build-aux/sanity.mk @@ -0,0 +1,1112 @@ +# Slingshot sanity checking rules for GNU Make. + +# ====================================================================== +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Originally by Jim Meyering, Simon Josefsson, Eric Blake, +# Akim Demaille, Gary V. Vaughan, and others. +# This version by Gary V. Vaughan, 2013. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# ====================================================================== + +VC_LIST = $(GIT) ls-files + +# You can override this variable in cfg.mk to set your own regexp +# matching files to ignore. +VC_LIST_ALWAYS_EXCLUDE_REGEX ?= ^$$ + +# This is to preprocess robustly the output of $(VC_LIST), so that even +# when $(srcdir) is a pathological name like "....", the leading sed command +# removes only the intended prefix. +_dot_escaped_srcdir = $(subst .,\.,$(srcdir)) + +# Post-process $(VC_LIST) output, prepending $(srcdir)/, but only +# when $(srcdir) is not ".". +ifeq ($(srcdir),.) + _prepend_srcdir_prefix = +else + _prepend_srcdir_prefix = | sed 's|^|$(srcdir)/|' +endif + +# In order to be able to consistently filter "."-relative names, +# (i.e., with no $(srcdir) prefix), this definition is careful to +# remove any $(srcdir) prefix, and to restore what it removes. +_sc_excl = \ + $(or $(exclude_file_name_regexp--$@),^build-aux/sanity.mk$$) +VC_LIST_EXCEPT = \ + $(VC_LIST) | sed 's|^$(_dot_escaped_srcdir)/||' \ + | if test -f $(srcdir)/.x-$@; then grep -vEf $(srcdir)/.x-$@; \ + else grep -Ev -e "$${VC_LIST_EXCEPT_DEFAULT-ChangeLog}"; fi \ + | grep -Ev -e '($(VC_LIST_ALWAYS_EXCLUDE_REGEX)|$(_sc_excl))' \ + $(_prepend_srcdir_prefix) + + +## --------------- ## +## Sanity checks. ## +## --------------- ## + +_cfg_mk := $(wildcard $(srcdir)/cfg.mk) + +# Collect the names of rules starting with 'sc_'. +syntax-check-rules := $(sort $(shell sed -n 's/^\(sc_[a-zA-Z0-9_-]*\):.*/\1/p' \ + $(srcdir)/$(ME) $(_cfg_mk) $(srcdir)/$(_build-aux)/*.mk)) +.PHONY: $(syntax-check-rules) + +ifeq ($(shell $(VC_LIST) >/dev/null 2>&1; echo $$?),0) + local-checks-available += $(syntax-check-rules) +else + local-checks-available += no-vc-detected +no-vc-detected: + @echo "No version control files detected; skipping syntax check" +endif +.PHONY: $(local-checks-available) + +# Arrange to print the name of each syntax-checking rule just before running it. +$(syntax-check-rules): %: %.m +sc_m_rules_ = $(patsubst %, %.m, $(syntax-check-rules)) +.PHONY: $(sc_m_rules_) +$(sc_m_rules_): + @echo $(patsubst sc_%.m, %, $@) + @date +%s.%N > .sc-start-$(basename $@) + +# Compute and print the elapsed time for each syntax-check rule. +sc_z_rules_ = $(patsubst %, %.z, $(syntax-check-rules)) +.PHONY: $(sc_z_rules_) +$(sc_z_rules_): %.z: % + @end=$$(date +%s.%N); \ + start=$$(cat .sc-start-$*); \ + rm -f .sc-start-$*; \ + awk -v s=$$start -v e=$$end \ + 'END {printf "%.2f $(patsubst sc_%,%,$*)\n", e - s}' < /dev/null + +# The patsubst here is to replace each sc_% rule with its sc_%.z wrapper +# that computes and prints elapsed time. +local-check := \ + $(patsubst sc_%, sc_%.z, \ + $(filter-out $(local-checks-to-skip), $(local-checks-available))) + +syntax-check: $(local-check) + +# _sc_search_regexp +# +# This macro searches for a given construct in the selected files and +# then takes some action. +# +# Parameters (shell variables): +# +# prohibit | require +# +# Regular expression (ERE) denoting either a forbidden construct +# or a required construct. Those arguments are exclusive. +# +# exclude +# +# Regular expression (ERE) denoting lines to ignore that matched +# a prohibit construct. For example, this can be used to exclude +# comments that mention why the nearby code uses an alternative +# construct instead of the simpler prohibited construct. +# +# in_vc_files | in_files +# +# grep-E-style regexp selecting the files to check. For in_vc_files, +# the regexp is used to select matching files from the list of all +# version-controlled files; for in_files, it's from the names printed +# by "find $(srcdir)". When neither is specified, use all files that +# are under version control. +# +# containing | non_containing +# +# Select the files (non) containing strings matching this regexp. +# If both arguments are specified then CONTAINING takes +# precedence. +# +# with_grep_options +# +# Extra options for grep. +# +# ignore_case +# +# Ignore case. +# +# halt +# +# Message to display before to halting execution. +# +# Finally, you may exempt files based on an ERE matching file names. +# For example, to exempt from the sc_space_tab check all files with the +# .diff suffix, set this Make variable: +# +# exclude_file_name_regexp--sc_space_tab = \.diff$ +# +# Note that while this functionality is mostly inherited via VC_LIST_EXCEPT, +# when filtering by name via in_files, we explicitly filter out matching +# names here as well. + +# Initialize each, so that envvar settings cannot interfere. +export require = +export prohibit = +export exclude = +export in_vc_files = +export in_files = +export containing = +export non_containing = +export halt = +export with_grep_options = + +# By default, _sc_search_regexp does not ignore case. +export ignore_case = +_ignore_case = $$(test -n "$$ignore_case" && printf %s -i || :) + +define _sc_say_and_exit + dummy=; : so we do not need a semicolon before each use; \ + { printf '%s\n' "$(ME): $$msg" 1>&2; exit 1; }; +endef + +define _sc_search_regexp + dummy=; : so we do not need a semicolon before each use; \ + \ + : Check arguments; \ + test -n "$$prohibit" && test -n "$$require" \ + && { msg='Cannot specify both prohibit and require' \ + $(_sc_say_and_exit) } || :; \ + test -z "$$prohibit" && test -z "$$require" \ + && { msg='Should specify either prohibit or require' \ + $(_sc_say_and_exit) } || :; \ + test -z "$$prohibit" && test -n "$$exclude" \ + && { msg='Use of exclude requires a prohibit pattern' \ + $(_sc_say_and_exit) } || :; \ + test -n "$$in_vc_files" && test -n "$$in_files" \ + && { msg='Cannot specify both in_vc_files and in_files' \ + $(_sc_say_and_exit) } || :; \ + test "x$$halt" != x \ + || { msg='halt not defined' $(_sc_say_and_exit) }; \ + \ + : Filter by file name; \ + if test -n "$$in_files"; then \ + files=$$(find $(srcdir) | grep -E "$$in_files" \ + | grep -Ev '$(_sc_excl)'); \ + else \ + files=$$($(VC_LIST_EXCEPT)); \ + if test -n "$$in_vc_files"; then \ + files=$$(echo "$$files" | grep -E "$$in_vc_files"); \ + fi; \ + fi; \ + \ + : Filter by content; \ + test -n "$$files" && test -n "$$containing" \ + && { files=$$(grep -l "$$containing" $$files); } || :; \ + test -n "$$files" && test -n "$$non_containing" \ + && { files=$$(grep -vl "$$non_containing" $$files); } || :; \ + \ + : Check for the construct; \ + if test -n "$$files"; then \ + if test -n "$$prohibit"; then \ + grep $$with_grep_options $(_ignore_case) -nE "$$prohibit" $$files \ + | grep -vE "$${exclude:-^$$}" \ + && { msg="$$halt" $(_sc_say_and_exit) } || :; \ + else \ + grep $$with_grep_options $(_ignore_case) -LE "$$require" $$files \ + | grep . \ + && { msg="$$halt" $(_sc_say_and_exit) } || :; \ + fi \ + else :; \ + fi || :; +endef + +sc_avoid_if_before_free: + @test -f $(srcdir)/$(_build-aux)/useless-if-before-free && \ + $(srcdir)/$(_build-aux)/useless-if-before-free \ + $(useless_free_options) \ + $$($(VC_LIST_EXCEPT) | grep -v useless-if-before-free) && \ + { echo '$(ME): found useless "if" before "free" above' 1>&2; \ + exit 1; } || : + +sc_cast_of_argument_to_free: + @prohibit='\&2; \ + exit 1; } || : + +# Error messages should not start with a capital letter +sc_error_message_uppercase: + @grep -nEA2 '[^rp]error *\(' $$($(VC_LIST_EXCEPT)) \ + | grep -E '"[A-Z]' \ + | grep -vE '"FATAL|"WARNING|"Java|"C#|PRIuMAX' && \ + { echo '$(ME): found capitalized error message' 1>&2; \ + exit 1; } || : + +# Error messages should not end with a period +sc_error_message_period: + @grep -nEA2 '[^rp]error *\(' $$($(VC_LIST_EXCEPT)) \ + | grep -E '[^."]\."' && \ + { echo '$(ME): found error message ending in period' 1>&2; \ + exit 1; } || : + +sc_file_system: + @prohibit=file''system \ + ignore_case=1 \ + halt='found use of "file''system"; spell it "file system"' \ + $(_sc_search_regexp) + +sc_makefile: + @prohibit=make''flie \ + ignore_case=1 \ + halt='found misspelled "make''flie"; use "makefile" instead' \ + $(_sc_search_regexp) + +# Don't use cpp tests of this symbol. All code assumes config.h is included. +sc_prohibit_have_config_h: + @prohibit='^# *if.*HAVE''_CONFIG_H' \ + halt='found use of HAVE''_CONFIG_H; remove' \ + $(_sc_search_regexp) + +# Nearly all .c files must include . However, we also permit this +# via inclusion of a package-specific header, if cfg.mk specified one. +# config_h_header must be suitable for grep -E. +config_h_header ?= +sc_require_config_h: + @require='^# *include $(config_h_header)' \ + in_vc_files='\.c$$' \ + halt='the above files do not include ' \ + $(_sc_search_regexp) + +# You must include before including any other header file. +# This can possibly be via a package-specific header, if given by cfg.mk. +sc_require_config_h_first: + @if $(VC_LIST_EXCEPT) | grep -l '\.c$$' > /dev/null; then \ + fail=0; \ + for i in $$($(VC_LIST_EXCEPT) | grep '\.c$$'); do \ + grep '^# *include\>' $$i | sed 1q \ + | grep -E '^# *include $(config_h_header)' > /dev/null \ + || { echo $$i; fail=1; }; \ + done; \ + test $$fail = 1 && \ + { echo '$(ME): the above files include some other header' \ + 'before ' 1>&2; exit 1; } || :; \ + else :; \ + fi + +sc_prohibit_HAVE_MBRTOWC: + @prohibit='\bHAVE_MBRTOWC\b' \ + halt="do not use $$prohibit; it is always defined" \ + $(_sc_search_regexp) + +# To use this "command" macro, you must first define two shell variables: +# h: the header name, with no enclosing <> or "" +# re: a regular expression that matches IFF something provided by $h is used. +define _sc_header_without_use + dummy=; : so we do not need a semicolon before each use; \ + h_esc=`echo '[<"]'"$$h"'[">]'|sed 's/\./\\\\./g'`; \ + if $(VC_LIST_EXCEPT) | grep -l '\.c$$' > /dev/null; then \ + files=$$(grep -l '^# *include '"$$h_esc" \ + $$($(VC_LIST_EXCEPT) | grep '\.c$$')) && \ + grep -LE "$$re" $$files | grep . && \ + { echo "$(ME): the above files include $$h but don't use it" \ + 1>&2; exit 1; } || :; \ + else :; \ + fi +endef + +# Prohibit the inclusion of assert.h without an actual use of assert. +sc_prohibit_assert_without_use: + @h='assert.h' re='\new(file => "/dev/stdin")->as_string'|sed 's/\?://g' +# Note this was produced by the above: +# _xa1 = \ +#x(((2n?)?re|c(har)?|n(re|m)|z)alloc|alloc_(oversized|die)|m(alloc|emdup)|strdup) +# But we can do better, in at least two ways: +# 1) take advantage of two "dup"-suffixed strings: +# x(((2n?)?re|c(har)?|n(re|m)|[mz])alloc|alloc_(oversized|die)|(mem|str)dup) +# 2) notice that "c(har)?|[mz]" is equivalent to the shorter and more readable +# "char|[cmz]" +# x(((2n?)?re|char|n(re|m)|[cmz])alloc|alloc_(oversized|die)|(mem|str)dup) +_xa1 = x(((2n?)?re|char|n(re|m)|[cmz])alloc|alloc_(oversized|die)|(mem|str)dup) +_xa2 = X([CZ]|N?M)ALLOC +sc_prohibit_xalloc_without_use: + @h='xalloc.h' \ + re='\<($(_xa1)|$(_xa2)) *\('\ + $(_sc_header_without_use) + +# Extract function names: +# perl -lne '/^(?:extern )?(?:void|char) \*?(\w+) *\(/ and print $1' lib/hash.h +_hash_re = \ +clear|delete|free|get_(first|next)|insert|lookup|print_statistics|reset_tuning +_hash_fn = \<($(_hash_re)) *\( +_hash_struct = (struct )?\<[Hh]ash_(table|tuning)\> +sc_prohibit_hash_without_use: + @h='hash.h' \ + re='$(_hash_fn)|$(_hash_struct)'\ + $(_sc_header_without_use) + +sc_prohibit_cloexec_without_use: + @h='cloexec.h' re='\<(set_cloexec_flag|dup_cloexec) *\(' \ + $(_sc_header_without_use) + +sc_prohibit_posixver_without_use: + @h='posixver.h' re='\' \ + halt='do not use HAVE''_FCNTL_H or O'_NDELAY \ + $(_sc_search_regexp) + +# FIXME: warn about definitions of EXIT_FAILURE, EXIT_SUCCESS, STREQ + +# Each nonempty ChangeLog line must start with a year number, or a TAB. +sc_changelog: + @prohibit='^[^12 ]' \ + in_vc_files='^ChangeLog$$' \ + halt='found unexpected prefix in a ChangeLog' \ + $(_sc_search_regexp) + +# Ensure that each .c file containing a "main" function also +# calls set_program_name. +sc_program_name: + @require='set_program_name *\(m?argv\[0\]\);' \ + in_vc_files='\.c$$' \ + containing='\
    /dev/null \ + && : || { die=1; echo $$i; } \ + done; \ + test $$die = 1 && \ + { echo 1>&2 '$(ME): the final line in each of the above is not:'; \ + echo 1>&2 'Exit something'; \ + exit 1; } || :; \ + fi + +sc_trailing_blank: + @prohibit='[ ]$$' \ + halt='found trailing blank(s)' \ + exclude='^Binary file .* matches$$' \ + $(_sc_search_regexp) + +# Match lines like the following, but where there is only one space +# between the options and the description: +# -D, --all-repeated[=delimit-method] print all duplicate lines\n +longopt_re = --[a-z][0-9A-Za-z-]*(\[?=[0-9A-Za-z-]*\]?)? +sc_two_space_separator_in_usage: + @prohibit='^ *(-[A-Za-z],)? $(longopt_re) [^ ].*\\$$' \ + halt='help2man requires at least two spaces between an option and its description'\ + $(_sc_search_regexp) + +# A regexp matching function names like "error_" that may be used +# to emit translatable messages. +_gl_translatable_diag_func_re ?= error_ + +# Look for diagnostics that aren't marked for translation. +# This won't find any for which error's format string is on a separate line. +sc_unmarked_diagnostics: + @prohibit='\<$(_gl_translatable_diag_func_re) *\([^"]*"[^"]*[a-z]{3}' \ + exclude='(_|ngettext ?)\(' \ + halt='found unmarked diagnostic(s)' \ + $(_sc_search_regexp) + +# Avoid useless parentheses like those in this example: +# #if defined (SYMBOL) || defined (SYM2) +sc_useless_cpp_parens: + @prohibit='^# *if .*defined *\(' \ + halt='found useless parentheses in cpp directive' \ + $(_sc_search_regexp) + +# List headers for which HAVE_HEADER_H is always true, assuming you are +# using the appropriate gnulib module. CAUTION: for each "unnecessary" +# #if HAVE_HEADER_H that you remove, be sure that your project explicitly +# requires the gnulib module that guarantees the usability of that header. +gl_assured_headers_ = \ + cd $(gnulib_dir)/lib && echo *.in.h|sed 's/\.in\.h//g' + +# Convert the list of names to upper case, and replace each space with "|". +az_ = abcdefghijklmnopqrstuvwxyz +AZ_ = ABCDEFGHIJKLMNOPQRSTUVWXYZ +gl_header_upper_case_or_ = \ + $$($(gl_assured_headers_) \ + | tr $(az_)/.- $(AZ_)___ \ + | tr -s ' ' '|' \ + ) +sc_prohibit_always_true_header_tests: + @or=$(gl_header_upper_case_or_); \ + re="HAVE_($$or)_H"; \ + prohibit='\<'"$$re"'\>' \ + halt=$$(printf '%s\n' \ + 'do not test the above HAVE_
    _H symbol(s);' \ + ' with the corresponding gnulib module, they are always true') \ + $(_sc_search_regexp) + +sc_prohibit_defined_have_decl_tests: + @prohibit='#[ ]*if(n?def|.*\[ (]+HAVE_DECL_' \ + halt='HAVE_DECL macros are always defined' \ + $(_sc_search_regexp) + +# ================================================================== +gl_other_headers_ ?= \ + intprops.h \ + openat.h \ + stat-macros.h + +# Perl -lne code to extract "significant" cpp-defined symbols from a +# gnulib header file, eliminating a few common false-positives. +# The exempted names below are defined only conditionally in gnulib, +# and hence sometimes must/may be defined in application code. +gl_extract_significant_defines_ = \ + /^\# *define ([^_ (][^ (]*)(\s*\(|\s+\w+)/\ + && $$2 !~ /(?:rpl_|_used_without_)/\ + && $$1 !~ /^(?:NSIG|ENODATA)$$/\ + && $$1 !~ /^(?:SA_RESETHAND|SA_RESTART)$$/\ + and print $$1 + +# Create a list of regular expressions matching the names +# of macros that are guaranteed to be defined by parts of gnulib. +define def_sym_regex + gen_h=$(gl_generated_headers_); \ + (cd $(gnulib_dir)/lib; \ + for f in *.in.h $(gl_other_headers_); do \ + test -f $$f \ + && perl -lne '$(gl_extract_significant_defines_)' $$f; \ + done; \ + ) | sort -u \ + | sed 's/^/^ *# *(define|undef) */;s/$$/\\>/' +endef + +# Don't define macros that we already get from gnulib header files. +sc_prohibit_always-defined_macros: + @if test -d $(gnulib_dir); then \ + case $$(echo all: | grep -l -f - Makefile) in Makefile);; *) \ + echo '$(ME): skipping $@: you lack GNU grep' 1>&2; exit 0;; \ + esac; \ + $(def_sym_regex) | grep -E -f - $$($(VC_LIST_EXCEPT)) \ + && { echo '$(ME): define the above via some gnulib .h file' \ + 1>&2; exit 1; } || :; \ + fi +# ================================================================== + +# Prohibit checked in backup files. +sc_prohibit_backup_files: + @$(VC_LIST) | grep '~$$' && \ + { echo '$(ME): found version controlled backup file' 1>&2; \ + exit 1; } || : + +# Require the latest GPL. +sc_GPL_version: + @prohibit='either ''version [^3]' \ + halt='GPL vN, N!=3' \ + $(_sc_search_regexp) + +# Require the latest GFDL. Two regexp, since some .texi files end up +# line wrapping between 'Free Documentation License,' and 'Version'. +_GFDL_regexp = (Free ''Documentation.*Version 1\.[^3]|Version 1\.[^3] or any) +sc_GFDL_version: + @prohibit='$(_GFDL_regexp)' \ + halt='GFDL vN, N!=3' \ + $(_sc_search_regexp) + +# Don't use Texinfo's @acronym{}. +# http://lists.gnu.org/archive/html/bug-gnulib/2010-03/msg00321.html +texinfo_suffix_re_ ?= \.(txi|texi(nfo)?)$$ +sc_texinfo_acronym: + @prohibit='@acronym\{' \ + in_vc_files='$(texinfo_suffix_re_)' \ + halt='found use of Texinfo @acronym{}' \ + $(_sc_search_regexp) + +cvs_keywords = \ + Author|Date|Header|Id|Name|Locker|Log|RCSfile|Revision|Source|State + +sc_prohibit_cvs_keyword: + @prohibit='\$$($(cvs_keywords))\$$' \ + halt='do not use CVS keyword expansion' \ + $(_sc_search_regexp) + +# This Perl code is slightly obfuscated. Not only is each "$" doubled +# because it's in a Makefile, but the $$c's are comments; we cannot +# use "#" due to the way the script ends up concatenated onto one line. +# It would be much more concise, and would produce better output (including +# counts) if written as: +# perl -ln -0777 -e '/\n(\n+)$/ and print "$ARGV: ".length $1' ... +# but that would be far less efficient, reading the entire contents +# of each file, rather than just the last two bytes of each. +# In addition, while the code below detects both blank lines and a missing +# newline at EOF, the above detects only the former. +# +# This is a perl script that is expected to be the single-quoted argument +# to a command-line "-le". The remaining arguments are file names. +# Print the name of each file that does not end in exactly one newline byte. +# I.e., warn if there are blank lines (2 or more newlines), or if the +# last byte is not a newline. However, currently we don't complain +# about any file that contains exactly one byte. +# Exit nonzero if at least one such file is found, otherwise, exit 0. +# Warn about, but otherwise ignore open failure. Ignore seek/read failure. +# +# Use this if you want to remove trailing empty lines from selected files: +# perl -pi -0777 -e 's/\n\n+$/\n/' files... +# +require_exactly_one_NL_at_EOF_ = \ + foreach my $$f (@ARGV) \ + { \ + open F, "<", $$f or (warn "failed to open $$f: $$!\n"), next; \ + my $$p = sysseek (F, -2, 2); \ + my $$c = "seek failure probably means file has < 2 bytes; ignore"; \ + my $$last_two_bytes; \ + defined $$p and $$p = sysread F, $$last_two_bytes, 2; \ + close F; \ + $$c = "ignore read failure"; \ + $$p && ($$last_two_bytes eq "\n\n" \ + || substr ($$last_two_bytes,1) ne "\n") \ + and (print $$f), $$fail=1; \ + } \ + END { exit defined $$fail } +sc_prohibit_empty_lines_at_EOF: + @perl -le '$(require_exactly_one_NL_at_EOF_)' $$($(VC_LIST_EXCEPT)) \ + || { echo '$(ME): empty line(s) or no newline at EOF' \ + 1>&2; exit 1; } || : + +# Make sure we don't use st_blocks. Use ST_NBLOCKS instead. +# This is a bit of a kludge, since it prevents use of the string +# even in comments, but for now it does the job with no false positives. +sc_prohibit_stat_st_blocks: + @prohibit='[.>]st_blocks' \ + halt='do not use st_blocks; use ST_NBLOCKS' \ + $(_sc_search_regexp) + +# Make sure we don't define any S_IS* macros in src/*.c files. +# They're already defined via gnulib's sys/stat.h replacement. +sc_prohibit_S_IS_definition: + @prohibit='^ *# *define *S_IS' \ + halt='do not define S_IS* macros; include ' \ + $(_sc_search_regexp) + +# Perl block to convert a match to FILE_NAME:LINENO:TEST, +# that is shared by two definitions below. +perl_filename_lineno_text_ = \ + -e ' {' \ + -e ' $$n = ($$` =~ tr/\n/\n/ + 1);' \ + -e ' ($$v = $$&) =~ s/\n/\\n/g;' \ + -e ' print "$$ARGV:$$n:$$v\n";' \ + -e ' }' + +prohibit_doubled_word_RE_ ?= \ + /\b(then?|[iao]n|i[fst]|but|f?or|at|and|[dt]o)\s+\1\b/gims +prohibit_doubled_word_ = \ + -e 'while ($(prohibit_doubled_word_RE_))' \ + $(perl_filename_lineno_text_) + +# Define this to a regular expression that matches +# any filename:dd:match lines you want to ignore. +# The default is to ignore no matches. +ignore_doubled_word_match_RE_ ?= ^$$ + +sc_prohibit_doubled_word: + @perl -n -0777 $(prohibit_doubled_word_) $$($(VC_LIST_EXCEPT)) \ + | grep -vE '$(ignore_doubled_word_match_RE_)' \ + | grep . && { echo '$(ME): doubled words' 1>&2; exit 1; } || : + +# A regular expression matching undesirable combinations of words like +# "can not"; this matches them even when the two words appear on different +# lines, but not when there is an intervening delimiter like "#" or "*". +# Similarly undesirable, "See @xref{...}", since an @xref should start +# a sentence. Explicitly prohibit any prefix of "see" or "also". +# Also prohibit a prefix matching "\w+ +". +# @pxref gets the same see/also treatment and should be parenthesized; +# presume it must *not* start a sentence. +bad_xref_re_ ?= (?:[\w,:;] +|(?:see|also)\s+)\@xref\{ +bad_pxref_re_ ?= (?:[.!?]|(?:see|also))\s+\@pxref\{ +prohibit_undesirable_word_seq_RE_ ?= \ + /(?:\bcan\s+not\b|$(bad_xref_re_)|$(bad_pxref_re_))/gims +prohibit_undesirable_word_seq_ = \ + -e 'while ($(prohibit_undesirable_word_seq_RE_))' \ + $(perl_filename_lineno_text_) +# Define this to a regular expression that matches +# any filename:dd:match lines you want to ignore. +# The default is to ignore no matches. +ignore_undesirable_word_sequence_RE_ ?= ^$$ + +sc_prohibit_undesirable_word_seq: + @perl -n -0777 $(prohibit_undesirable_word_seq_) \ + $$($(VC_LIST_EXCEPT)) \ + | grep -vE '$(ignore_undesirable_word_sequence_RE_)' | grep . \ + && { echo '$(ME): undesirable word sequence' >&2; exit 1; } || : + +_ptm1 = use "test C1 && test C2", not "test C1 -''a C2" +_ptm2 = use "test C1 || test C2", not "test C1 -''o C2" +# Using test's -a and -o operators is not portable. +# We prefer test over [, since the latter is spelled [[ in configure.ac. +sc_prohibit_test_minus_ao: + @prohibit='(\ /dev/null \ + || { fail=1; echo 1>&2 "$(ME): $$p uses proper_name_utf8"; }; \ + done; \ + test $$fail = 1 && \ + { echo 1>&2 '$(ME): the above do not link with any ICONV library'; \ + exit 1; } || :; \ + fi + +# Warn about "c0nst struct Foo const foo[]", +# but not about "char const *const foo" or "#define const const". +sc_redundant_const: + @prohibit='\bconst\b[[:space:][:alnum:]]{2,}\bconst\b' \ + halt='redundant "const" in declarations' \ + $(_sc_search_regexp) + +sc_const_long_option: + @prohibit='^ *static.*struct option ' \ + exclude='const struct option|struct option const' \ + halt='add "const" to the above declarations' \ + $(_sc_search_regexp) + +# Ensure that we don't accidentally insert an entry into an old NEWS block. +sc_immutable_NEWS: + @if test -f $(srcdir)/NEWS; then \ + test "$(NEWS_hash)" = '$(old_NEWS_hash)' && : || \ + { echo '$(ME): you have modified old NEWS' 1>&2; exit 1; }; \ + fi + +# Ensure that we use only the standard $(VAR) notation, +# not @...@ in Makefile.am, now that we can rely on automake +# to emit a definition for each substituted variable. +# However, there is still one case in which @VAR@ use is not just +# legitimate, but actually required: when augmenting an automake-defined +# variable with a prefix. For example, gettext uses this: +# MAKEINFO = env LANG= LC_MESSAGES= LC_ALL= LANGUAGE= @MAKEINFO@ +# otherwise, makeinfo would put German or French (current locale) +# navigation hints in the otherwise-English documentation. +# +# Allow the package to add exceptions via a hook in cfg.mk; +# for example, @PRAGMA_SYSTEM_HEADER@ can be permitted by +# setting this to ' && !/PRAGMA_SYSTEM_HEADER/'. +_makefile_at_at_check_exceptions ?= +sc_makefile_at_at_check: + @perl -ne '/\@\w+\@/' \ + -e ' && !/(\w+)\s+=.*\@\1\@$$/' \ + -e ''$(_makefile_at_at_check_exceptions) \ + -e 'and (print "$$ARGV:$$.: $$_"), $$m=1; END {exit !$$m}' \ + $$($(VC_LIST_EXCEPT) | grep -E '(^|/)(Makefile\.am|[^/]+\.mk)$$') \ + && { echo '$(ME): use $$(...), not @...@' 1>&2; exit 1; } || : + +sc_makefile_TAB_only_indentation: + @prohibit='^ [ ]{8}' \ + in_vc_files='akefile|\.mk$$' \ + halt='found TAB-8-space indentation' \ + $(_sc_search_regexp) + +sc_m4_quote_check: + @prohibit='(AC_DEFINE(_UNQUOTED)?|AC_DEFUN)\([^[]' \ + in_vc_files='(^configure\.ac|\.m4)$$' \ + halt='quote the first arg to AC_DEF*' \ + $(_sc_search_regexp) + +fix_po_file_diag = \ +'you have changed the set of files with translatable diagnostics;\n\ +apply the above patch\n' + +# Verify that all source files using _() (more specifically, files that +# match $(_gl_translatable_string_re)) are listed in po/POTFILES.in. +po_file ?= $(srcdir)/po/POTFILES.in +generated_files ?= $(srcdir)/lib/*.[ch] +_gl_translatable_string_re ?= \b(N?_|gettext *)\([^)"]*("|$$) +sc_po_check: + @if test -f $(po_file); then \ + grep -E -v '^(#|$$)' $(po_file) \ + | grep -v '^src/false\.c$$' | sort > $@-1; \ + files=; \ + for file in $$($(VC_LIST_EXCEPT)) $(generated_files); do \ + test -r $$file || continue; \ + case $$file in \ + *.m4|*.mk) continue ;; \ + *.?|*.??) ;; \ + *) continue;; \ + esac; \ + case $$file in \ + *.[ch]) \ + base=`expr " $$file" : ' \(.*\)\..'`; \ + { test -f $$base.l || test -f $$base.y; } && continue;; \ + esac; \ + files="$$files $$file"; \ + done; \ + grep -E -l '$(_gl_translatable_string_re)' $$files \ + | sed 's|^$(_dot_escaped_srcdir)/||' | sort -u > $@-2; \ + diff -u -L $(po_file) -L $(po_file) $@-1 $@-2 \ + || { printf '$(ME): '$(fix_po_file_diag) 1>&2; exit 1; }; \ + rm -f $@-1 $@-2; \ + fi + +# Sometimes it is useful to change the PATH environment variable +# in Makefiles. When doing so, it's better not to use the Unix-centric +# path separator of ':', but rather the automake-provided '$(PATH_SEPARATOR)'. +msg = 'Do not use ":" above; use $$(PATH_SEPARATOR) instead' +sc_makefile_path_separator_check: + @prohibit='PATH[=].*:' \ + in_vc_files='akefile|\.mk$$' \ + halt=$(msg) \ + $(_sc_search_regexp) + +v_etc_file = $(gnulib_dir)/lib/version-etc.c +sample-test = tests/sample-test +texi = doc/$(PACKAGE).texi +# Make sure that the copyright date in $(v_etc_file) is up to date. +# Do the same for the $(sample-test) and the main doc/.texi file. +sc_copyright_check: + @require='enum { COPYRIGHT_YEAR = '$$(date +%Y)' };' \ + in_files=$(v_etc_file) \ + halt='out of date copyright in $(v_etc_file); update it' \ + $(_sc_search_regexp) + @require='# Copyright \(C\) '$$(date +%Y)' Free' \ + in_vc_files=$(sample-test) \ + halt='out of date copyright in $(sample-test); update it' \ + $(_sc_search_regexp) + @require='Copyright @copyright\{\} .*'$$(date +%Y)' Free' \ + in_vc_files=$(texi) \ + halt='out of date copyright in $(texi); update it' \ + $(_sc_search_regexp) + +# #if HAVE_... will evaluate to false for any non numeric string. +# That would be flagged by using -Wundef, however gnulib currently +# tests many undefined macros, and so we can't enable that option. +# So at least preclude common boolean strings as macro values. +sc_Wundef_boolean: + @prohibit='^#define.*(yes|no|true|false)$$' \ + in_files='$(CONFIG_INCLUDE)' \ + halt='Use 0 or 1 for macro values' \ + $(_sc_search_regexp) + +# Even if you use pathmax.h to guarantee that PATH_MAX is defined, it might +# not be constant, or might overflow a stack. In general, use PATH_MAX as +# a limit, not an array or alloca size. +sc_prohibit_path_max_allocation: + @prohibit='(\balloca *\([^)]*|\[[^]]*)\bPATH_MAX' \ + halt='Avoid stack allocations of size PATH_MAX' \ + $(_sc_search_regexp) + +sc_vulnerable_makefile_CVE-2009-4029: + @prohibit='perm -777 -exec chmod a\+rwx|chmod 777 \$$\(distdir\)' \ + in_files='(^|/)Makefile\.in$$' \ + halt=$$(printf '%s\n' \ + 'the above files are vulnerable; beware of running' \ + ' "make dist*" rules, and upgrade to fixed automake' \ + ' see http://bugzilla.redhat.com/542609 for details') \ + $(_sc_search_regexp) + +sc_vulnerable_makefile_CVE-2012-3386: + @prohibit='chmod a\+w \$$\(distdir\)' \ + in_files='(^|/)Makefile\.in$$' \ + halt=$$(printf '%s\n' \ + 'the above files are vulnerable; beware of running' \ + ' "make distcheck", and upgrade to fixed automake' \ + ' see http://bugzilla.redhat.com/CVE-2012-3386 for details') \ + $(_sc_search_regexp) + + +## ------------- ## +## Distribution. ## +## ------------- ## + +EXTRA_DIST += \ + $(_build-aux)/sanity.mk \ + $(NOTHING_ELSE) diff --git a/build-aux/specl.mk b/build-aux/specl.mk new file mode 100644 index 0000000..c84a860 --- /dev/null +++ b/build-aux/specl.mk @@ -0,0 +1,56 @@ +# Slingshot specl rules for make. + +# This file is distributed with Slingshot, and licensed under the +# terms of the MIT license reproduced below. + +# ==================================================================== # +# Copyright (C) 2013 Gary V. Vaughan # +# # +# Permission is hereby granted, free of charge, to any person # +# obtaining a copy of this software and associated documentation # +# files (the "Software"), to deal in the Software without restriction, # +# including without limitation the rights to use, copy, modify, merge, # +# publish, distribute, sublicense, and/or sell copies of the Software, # +# and to permit persons to whom the Software is furnished to do so, # +# subject to the following conditions: # +# # +# The above copyright notice and this permission notice shall be # +# included in all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # +# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # +# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +# ==================================================================== # + +# To use this file create a list of your spec files in specl_SPECS +# and then include this make fragment. + +## ------ ## +## Specl. ## +## ------ ## + +check_local += specl-check-local +specl-check-local: $(specl_SPECS) + @v=`$(SPECL) --version | sed -e 's|^.* ||' -e 1q`; \ + if test "$$v" -lt "$(SPECL_MIN)"; then \ + printf "%s%s\n%s\n" \ + "ERROR: Specl version $$v is too old," \ + " please upgrade to at least version $(SPECL_MIN)," \ + "ERROR: and rerun \`make check\`"; \ + exit 1; \ + else \ + $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS); \ + fi + + +## ------------- ## +## Distribution. ## +## ------------- ## + +EXTRA_DIST += \ + $(specl_SPECS) \ + $(NOTHING_ELSE) diff --git a/configure b/configure index 3733e23..954fda1 100755 --- a/configure +++ b/configure @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 34.1. +# Generated by GNU Autoconf 2.69 for lua-stdlib 35. # -# Report bugs to . +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -197,7 +197,8 @@ test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else @@ -265,10 +266,11 @@ fi $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and rrt@sc3d.org about -$0: your system, including any error possibly output before -$0: this message. Then install a modern shell, or manually -$0: run the script under such a shell if you do have one." + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: http://github.com/rrthomas/lua-stdlib/issues about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -576,15 +578,22 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='stdlib' -PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='34.1' -PACKAGE_STRING='stdlib 34.1' -PACKAGE_BUGREPORT='rrt@sc3d.org' +PACKAGE_NAME='lua-stdlib' +PACKAGE_TARNAME='lua-stdlib' +PACKAGE_VERSION='35' +PACKAGE_STRING='lua-stdlib 35' +PACKAGE_BUGREPORT='http://github.com/rrthomas/lua-stdlib/issues' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS +EXTRA_ROCKS +SPECL_MIN +LUADOC_FALSE +SED +EGREP +GREP +SPECL LUADOC pkgluaexecdir luaexecdir @@ -596,7 +605,6 @@ LUA_PLATFORM LUA_SHORT_VERSION LUA_VERSION LUA -LUA_MIN_VERSION AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V @@ -666,13 +674,11 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules -with_luadoc ' ac_precious_vars='build_alias host_alias target_alias -LUA -LUADOC' +LUA' # Initialize some variables set by options. @@ -1213,7 +1219,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 34.1 to adapt to many kinds of systems. +\`configure' configures lua-stdlib 35 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1261,7 +1267,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/stdlib] + --docdir=DIR documentation root [DATAROOTDIR/doc/lua-stdlib] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1279,7 +1285,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 34.1:";; + short | recursive ) echo "Configuration of lua-stdlib 35:";; esac cat <<\_ACEOF @@ -1290,19 +1296,13 @@ Optional Features: --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-luadoc=[PATH] absolute path to luadoc executable - Some influential environment variables: LUA The Lua interpreter, e.g. /usr/bin/lua5.1 - LUADOC Absolute path to luadoc executable Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to . +Report bugs to . _ACEOF ac_status=$? fi @@ -1365,7 +1365,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 34.1 +lua-stdlib configure 35 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1382,7 +1382,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 34.1, which was +It was created by lua-stdlib $as_me 35, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1759,6 +1759,13 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +$as_echo "## ------------------------- ## +## Configuring lua-stdlib 35 ## +## ------------------------- ##" +echo + am__api_version='1.13' # Find a good install program. We prefer a C program (faster), @@ -2244,8 +2251,8 @@ fi # Define the identity of the package. - PACKAGE='stdlib' - VERSION='34.1' + PACKAGE='lua-stdlib' + VERSION='35' cat >>confdefs.h <<_ACEOF @@ -2331,8 +2338,6 @@ fi AM_BACKSLASH='\' -LUA_MIN_VERSION=5.1 - @@ -2352,7 +2357,7 @@ $as_echo "no" >&6; } fi - _ax_check_text="whether $LUA version >= $LUA_MIN_VERSION, < 5.3" + _ax_check_text="whether $LUA version >= 5.1, < 5.3" { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 $as_echo_n "checking $_ax_check_text... " >&6; } @@ -2380,7 +2385,7 @@ fi -e 's/[^0-9]//g'` - ax_compare_version_B=`echo "$LUA_MIN_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + ax_compare_version_B=`echo "5.1" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ @@ -2446,7 +2451,7 @@ fi ax_display_LUA=$LUA else - _ax_check_text="for a Lua interpreter with version >= $LUA_MIN_VERSION, < 5.3" + _ax_check_text="for a Lua interpreter with version >= 5.1, < 5.3" { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 $as_echo_n "checking $_ax_check_text... " >&6; } if ${ax_cv_pathless_LUA+:} false; then : @@ -2486,7 +2491,7 @@ fi -e 's/[^0-9]//g'` - ax_compare_version_B=`echo "$LUA_MIN_VERSION" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ + ax_compare_version_B=`echo "5.1" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ @@ -2735,39 +2740,7 @@ $as_echo "$ax_cv_lua_luaexecdir" >&6; } fi - - - - - - - - - - - - if test -z "$LUADOC"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether luadoc executable path has been provided" >&5 -$as_echo_n "checking whether luadoc executable path has been provided... " >&6; } - -# Check whether --with-luadoc was given. -if test "${with_luadoc+set}" = set; then : - withval=$with_luadoc; - if test "$withval" != yes && test "$withval" != no; then : - - LUADOC="$withval" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LUADOC" >&5 -$as_echo "$LUADOC" >&6; } - -else - - LUADOC="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - if test "$withval" != no; then : - - # Extract the first word of "luadoc", so it can be a program name with args. +# Extract the first word of "luadoc", so it can be a program name with args. set dummy luadoc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } @@ -2808,25 +2781,16 @@ $as_echo "no" >&6; } fi - -fi - -fi - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - # Extract the first word of "luadoc", so it can be a program name with args. -set dummy luadoc; ac_word=$2 +# Extract the first word of "specl", so it can be a program name with args. +set dummy specl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LUADOC+:} false; then : +if ${ac_cv_path_SPECL+:} false; then : $as_echo_n "(cached) " >&6 else - case $LUADOC in + case $SPECL in [\\/]* | ?:[\\/]*) - ac_cv_path_LUADOC="$LUADOC" # Let the user override the test with a path. + ac_cv_path_SPECL="$SPECL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2836,7 +2800,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LUADOC="$as_dir/$ac_word$ac_exec_ext" + ac_cv_path_SPECL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2844,31 +2808,250 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_path_LUADOC" && ac_cv_path_LUADOC=":" + test -z "$ac_cv_path_SPECL" && ac_cv_path_SPECL=":" ;; esac fi -LUADOC=$ac_cv_path_LUADOC -if test -n "$LUADOC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LUADOC" >&5 -$as_echo "$LUADOC" >&6; } +SPECL=$ac_cv_path_SPECL +if test -n "$SPECL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPECL" >&5 +$as_echo "$SPECL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +SPECL_MIN=5 + # Luadoc only works with Lua 5.1, so must be installed with care. + LUADOC_FALSE=# + SPECL_MIN=${SPECL_MIN-"5"} + # luarocks requires a separate invocation per luarock, and lyaml + # is required by all slingshot clients for mkrockspecs. + EXTRA_ROCKS=- + for _ss_rock in lyaml luadoc specl; do + # Enable associated .travis sections for special rocks. + case $_ss_rock in + luadoc) + LUADOC_FALSE=- + continue + ;; + esac + + case $EXTRA_ROCKS in + *" $_ss_rock;"*) ;; # ignore duplicates + *) + EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" + ;; + esac + done + + ac_config_files="$ac_config_files .travis.yml:travis.yml.in" ac_config_files="$ac_config_files Makefile" @@ -3424,7 +3607,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 34.1, which was +This file was extended by lua-stdlib $as_me 35, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3471,13 +3654,13 @@ Usage: $0 [OPTION]... [TAG]... Configuration files: $config_files -Report bugs to ." +Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 34.1 +lua-stdlib config.status 35 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -3590,6 +3773,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in + ".travis.yml") CONFIG_FILES="$CONFIG_FILES .travis.yml:travis.yml.in" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; diff --git a/configure.ac b/configure.ac index 86de659..f035512 100644 --- a/configure.ac +++ b/configure.ac @@ -1,18 +1,25 @@ dnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake -AC_INIT(stdlib, 34.1, rrt@sc3d.org) +AC_INIT([lua-stdlib], [35], [http://github.com/rrthomas/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) -AM_INIT_AUTOMAKE([foreign]) -AM_SILENT_RULES([yes]) +AC_CONFIG_MACRO_DIR([m4]) -dnl Lua -AC_SUBST([LUA_MIN_VERSION], [5.1]) -AX_PROG_LUA([$LUA_MIN_VERSION], [5.3]) +AS_BOX([Configuring AC_PACKAGE_TARNAME AC_PACKAGE_VERSION]) +echo -AX_WITH_PROG([LUADOC], [luadoc], [:]) +AM_INIT_AUTOMAKE([-Wall foreign]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +dnl Check for programs +AX_PROG_LUA([5.1], [5.3]) +AC_PATH_PROG([LUADOC], [luadoc], [:]) +AC_PATH_PROG([SPECL], [specl], [:]) +AC_PROG_EGREP +AC_PROG_SED dnl Generate output files -AC_CONFIG_MACRO_DIR(m4) +SPECL_MIN=5 +SS_CONFIG_TRAVIS([luadoc specl]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/local.mk b/local.mk new file mode 100644 index 0000000..030de92 --- /dev/null +++ b/local.mk @@ -0,0 +1,30 @@ +# Local Make rules. + +## ------------ ## +## Environment. ## +## ------------ ## + +std_path = $(abs_srcdir)/?.lua;$(abs_srcdir)/std/?.lua +LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" + + +## ---------- ## +## Bootstrap. ## +## ---------- ## + +old_NEWS_hash = dfde3c0c6163db72d47538ad8711607c + + +## ------------- ## +## Declarations. ## +## ------------- ## + +filesdir = $(docdir)/files +modulesdir = $(docdir)/modules + +dist_doc_DATA = +dist_files_DATA = +dist_modules_DATA = + +include std/std.mk +include specs/specs.mk diff --git a/lua-stdlib-35-1.rockspec b/lua-stdlib-35-1.rockspec new file mode 100644 index 0000000..32620c5 --- /dev/null +++ b/lua-stdlib-35-1.rockspec @@ -0,0 +1,22 @@ +package = "lua-stdlib" +version = "35-1" +description = { + homepage = "http://rrthomas.github.io/lua-stdlib", + license = "MIT/X11", + summary = "General Lua Libraries", + detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt.", +} +source = { + url = "http://github.com/rrthomas/lua-stdlib/archive/release-v35.zip", + dir = "lua-stdlib-release-v35", +} +dependencies = { + "lua >= 5.1", +} +external_dependencies = nil +build = { + build_command = "./configure LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' --prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' && make clean all", + type = "command", + copy_directories = {}, + install_command = "make install luadir='$(LUADIR)'", +} diff --git a/luarocks-config.lua.in b/luarocks-config.lua.in deleted file mode 100644 index 412b3ed..0000000 --- a/luarocks-config.lua.in +++ /dev/null @@ -1,3 +0,0 @@ -rocks_trees = { - "@abs_srcdir@/luarocks" -} diff --git a/m4/ax_with_prog.m4 b/m4/ax_with_prog.m4 deleted file mode 100644 index f337c05..0000000 --- a/m4/ax_with_prog.m4 +++ /dev/null @@ -1,70 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_with_prog.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_WITH_PROG([VARIABLE],[program],[VALUE-IF-NOT-FOUND],[PATH]) -# -# DESCRIPTION -# -# Locates an installed program binary, placing the result in the precious -# variable VARIABLE. Accepts a present VARIABLE, then --with-program, and -# failing that searches for program in the given path (which defaults to -# the system path). If program is found, VARIABLE is set to the full path -# of the binary; if it is not found VARIABLE is set to VALUE-IF-NOT-FOUND -# if provided, unchanged otherwise. -# -# A typical example could be the following one: -# -# AX_WITH_PROG(PERL,perl) -# -# NOTE: This macro is based upon the original AX_WITH_PYTHON macro from -# Dustin J. Mitchell . -# -# LICENSE -# -# Copyright (c) 2008 Francesco Salvestrini -# Copyright (c) 2008 Dustin J. Mitchell -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 16 - -AC_DEFUN([AX_WITH_PROG],[ - AC_PREREQ([2.61]) - - pushdef([VARIABLE],$1) - pushdef([EXECUTABLE],$2) - pushdef([VALUE_IF_NOT_FOUND],$3) - pushdef([PATH_PROG],$4) - - AC_ARG_VAR(VARIABLE,Absolute path to EXECUTABLE executable) - - AS_IF(test -z "$VARIABLE",[ - AC_MSG_CHECKING(whether EXECUTABLE executable path has been provided) - AC_ARG_WITH(EXECUTABLE,AS_HELP_STRING([--with-EXECUTABLE=[[[PATH]]]],absolute path to EXECUTABLE executable), [ - AS_IF([test "$withval" != yes && test "$withval" != no],[ - VARIABLE="$withval" - AC_MSG_RESULT($VARIABLE) - ],[ - VARIABLE="" - AC_MSG_RESULT([no]) - AS_IF([test "$withval" != no], [ - AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) - ]) - ]) - ],[ - AC_MSG_RESULT([no]) - AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) - ]) - ]) - - popdef([PATH_PROG]) - popdef([VALUE_IF_NOT_FOUND]) - popdef([EXECUTABLE]) - popdef([VARIABLE]) -]) diff --git a/m4/slingshot.m4 b/m4/slingshot.m4 new file mode 100644 index 0000000..9e7acc6 --- /dev/null +++ b/m4/slingshot.m4 @@ -0,0 +1,51 @@ +dnl slingshot.m4 +dnl +dnl Copyright (c) 2013 Free Software Foundation, Inc. +dnl Written by Gary V. Vaughan, 2013 +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published +dnl by the Free Software Foundation; either version 3, or (at your +dnl option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see . + +# SS_CONFIG_TRAVIS(LUAROCKS) +# -------------------------- +# Generate .travis.yml, ensuring LUAROCKS are installed. +AC_DEFUN([SS_CONFIG_TRAVIS], [ + # Luadoc only works with Lua 5.1, so must be installed with care. + LUADOC_FALSE=# + AC_SUBST(LUADOC_FALSE) + + SPECL_MIN=${SPECL_MIN-"5"} + AC_SUBST([SPECL_MIN]) + + # luarocks requires a separate invocation per luarock, and lyaml + # is required by all slingshot clients for mkrockspecs. + EXTRA_ROCKS=- + for _ss_rock in lyaml $1; do + # Enable associated .travis sections for special rocks. + case $_ss_rock in + luadoc) + LUADOC_FALSE=- + continue + ;; + esac + + case $EXTRA_ROCKS in + *" $_ss_rock;"*) ;; # ignore duplicates + *) + EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" + ;; + esac + done + AC_SUBST([EXTRA_ROCKS]) + AC_CONFIG_FILES([.travis.yml:travis.yml.in]) +]) diff --git a/mkrockspecs.lua b/mkrockspecs.lua deleted file mode 100644 index b2a77ae..0000000 --- a/mkrockspecs.lua +++ /dev/null @@ -1,49 +0,0 @@ --- Generate rockspecs from a prototype with variants - -require "std" - -if select ("#", ...) < 2 then - io.stderr:write "Usage: mkrockspecs PACKAGE VERSION\n" - os.exit () -end - -package_name = select (1, ...) -version = select (2, ...) - -function format (x, indent) - indent = indent or "" - if type (x) == "table" then - local s = "{\n" - for i, v in pairs (x) do - if type (i) ~= "number" then - s = s..indent..i.." = "..format (v, indent.." ")..",\n" - end - end - for i, v in ipairs (x) do - s = s..indent..format (v, indent.." ")..",\n" - end - return s..indent:sub (1, -3).."}" - elseif type (x) == "string" then - return string.format ("%q", x) - else - return tostring (x) - end -end - -for f, spec in pairs (loadfile ("rockspecs.lua") ()) do - if f ~= "default" then - local specfile = package_name.."-"..(f ~= "" and f:lower ().."-" or "")..version.."-2.rockspec" - h = io.open (specfile, "w") - assert (h) - flavour = f -- a global, visible in loadfile - local specs = loadfile ("rockspecs.lua") () -- reload to get current flavour interpolated - local spec = tree.merge (tree.new (specs.default), tree.new (specs[f])) - local s = "" - for i, v in pairs (spec) do - s = s..i.." = "..format (v, " ").."\n" - end - h:write (s) - h:close () - os.execute ("luarocks lint " .. specfile) - end -end diff --git a/rockspec.conf b/rockspec.conf new file mode 100644 index 0000000..c7813c7 --- /dev/null +++ b/rockspec.conf @@ -0,0 +1,16 @@ +# stdlib rockspec configuration. + +description: + homepage: http://rrthomas.github.io/lua-stdlib + license: MIT/X11 + summary: General Lua Libraries + detailed: + stdlib is a library of modules for common programming tasks, + including list, table and functional operations, regexps, objects, + pickling, pretty-printing and getopt. + +dependencies: +- lua >= 5.1 + +source: + url: git://github.com/rrthomas/lua-stdlib.git diff --git a/rockspecs.lua b/rockspecs.lua deleted file mode 100644 index cfa3c8e..0000000 --- a/rockspecs.lua +++ /dev/null @@ -1,44 +0,0 @@ --- Rockspec data - --- Variables to be interpolated: --- --- flavour: regex library --- package --- version - -local version_dashed = version:gsub ("%.", "-") - -local default = { - package = package_name, - version = version.."-2", - source = { - url = "git://github.com/rrthomas/lua-stdlib.git", - }, - description = { - summary = "General Lua libraries", - detailed = [[ - stdlib is a library of modules for common programming tasks, - including list, table and functional operations, regexps, objects, - pickling, pretty-printing and getopt. - ]], - homepage = "http://github.com/rrthomas/lua-stdlib/", - license = "MIT/X11", - }, - dependencies = { - "lua >= 5.1", - }, - build = { - type = "command", - build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - install_command = "make install", - copy_directories = {}, - }, -} - -if version ~= "git" then - default.source.branch = "release-v"..version_dashed -else - default.build.build_command = "autoreconf -i && " .. default.build.build_command -end - -return {default=default, [""]={}} diff --git a/slingshot b/slingshot new file mode 160000 index 0000000..f5e4b13 --- /dev/null +++ b/slingshot @@ -0,0 +1 @@ +Subproject commit f5e4b135266d2d959b998f8e420ecd57cd2395f1 diff --git a/specs/debug_ext_spec.yaml b/specs/debug_ext_spec.yaml new file mode 100644 index 0000000..e83eb9b --- /dev/null +++ b/specs/debug_ext_spec.yaml @@ -0,0 +1,69 @@ +specify debug_ext: +- before: | + M = require "std.debug_ext" + + extends = debug + enhancements = {} + extensions = { "say", "trace" } + +- context when required: + - before: + enhanced = {} + for _, api in ipairs (enhancements) do enhanced[api] = true end + + - context by name: + - before: | + function restore (g, m) + for _, api in ipairs (enhancements) do + g[api], g["_" .. api] = m[api], m["_" .. api] + end + for _, api in ipairs (extensions) do g[api] = m[api] end + end + + for _, api in ipairs (enhancements) do + extends[api] = M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = nil end + - after: + restore (extends, M) + - it does not perturb the global table: + for _, api in ipairs (extensions) do + expect (extends[api]).should_be (nil) + end + for _, api in ipairs (enhancements) do + expect (extends[api]).should_be (M["_" .. api]) + end + - it contains all global access points: + for api in pairs (extends) do + if enhanced[api] then + expect (M[api]).should_not_be (extends[api]) + else + expect (M[api]).should_be (extends[api]) + end + end + + - context via the std module: + - before: + require "std" + - it adds extension apis to the global table: + for api in pairs (M) do + expect (extends[api]).should_be (M[api]) + end + - it does not add any other global access points: + for api in pairs (extends) do + if not enhanced[api] then + expect (M[api]).should_be (extends[api]) + end + end + + +- describe _DEBUG: + + +- describe debug: + + +- describe say: + + +- describe trace: diff --git a/specs/getopt_spec.lua b/specs/getopt_spec.lua deleted file mode 100644 index 7c77ddf..0000000 --- a/specs/getopt_spec.lua +++ /dev/null @@ -1,83 +0,0 @@ -{["specify getopt"] = { - before = function () - getopt = require "getopt" - Option = getopt.Option - end, - - - {["describe getopt.getOpt ()"] = { - before = function () - prog = { - name = "getopt_spec.lua", - options = { Option {{"verbose", "v"}, "verbosely list files"}, - Option {{"output", "o"}, "dump to FILE", "Opt", "FILE"}, - Option {{"name", "n"}, - "only dump USER's files", "Req", "USER"}, - } - } - - function test (cmdLine) - local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options) - if #errors == 0 then - return { options = opts, args = nonOpts } - else - return errors - end - end - - getopt.processArgs (prog) - end, - - {["it recognizes a user defined option"] = function () - expect (test {"foo", "-v"}).should_equal ( - { options = { verbose = {1}}, args = { "foo" } }) - end}, - {["it treats -- as the end of the option list"] = function () - expect (test {"foo", "--", "-v"}).should_equal ( - { options = {}, args = { "foo", "-v" } }) - end}, - {["it captures a list of repeated option arguments"] = function () - expect (test {"-o", "-V", "-name", "bar", "--name=baz"}).should_equal ( - { options = { name = {"bar", "baz"}, version = {1}, output = {1}}, - args = {} }) - end}, - {["it diagnoses unrecognized options"] = function () - expect (test {"-foo"}).should_contain "unrecognized option `-foo'" - end}, - }}, - - - {["describe getopt.usageInfo ()"] = { - {["context when specifying options"] = { - before = function () - helppatt = "%-h, %-%-help%s+print this help, then exit" - versionpatt = "%-V, %-%-version%s+print version information, then exit" - prog = { name = "getopt_spec.lua", options = {} } - options = { Option {{"help", "?"}, "display this help"}, - Option {{"version"}, "display version number"} } - f = getopt.usageInfo - end, - - {["it provides a default version option"] = function () - getopt.processArgs (prog) - expect (f ("", prog.options)).should_match (versionpatt) - end}, - {["it allows the user to override the version option"] = function () - prog.options = options - getopt.processArgs (prog) - expect (f ("", prog.options)).should_not_match (versionpatt) - expect (f ("", prog.options)).should_match (" %-%-version%s+display") - end}, - {["it provides a default help option"] = function () - getopt.processArgs (prog) - expect (f ("", prog.options)).should_match (helppatt) - end}, - {["it allows the user to override the help option"] = function () - prog.options = options - getopt.processArgs (prog) - expect (f ("", prog.options)).should_not_match (helppatt) - expect (f ("", prog.options)).should_match ("%-%?, %-%-help%s+display") - end}, - }}, - }}, -}} diff --git a/specs/getopt_spec.yaml b/specs/getopt_spec.yaml index 94bfe5c..c36c7d0 100644 --- a/specs/getopt_spec.yaml +++ b/specs/getopt_spec.yaml @@ -1,6 +1,6 @@ specify getopt: - before: - getopt = require "getopt" + getopt = require "std.getopt" - "describe getopt.getOpt": - before: | diff --git a/specs/io_ext_spec.yaml b/specs/io_ext_spec.yaml new file mode 100644 index 0000000..aa5f37d --- /dev/null +++ b/specs/io_ext_spec.yaml @@ -0,0 +1,88 @@ +specify io_ext: +- before: | + M = require "std.io_ext" + + extends = io + enhancements = {} + extensions = { "catdir", "catfile", "process_files", "readlines", + "shell", "slurp", "splitdir", "writelines", + -- camelCase compatibility: + "processFiles" } + +- context when required: + - before: + enhanced = {} + for _, api in ipairs (enhancements) do enhanced[api] = true end + + - context by name: + - before: | + function restore (g, m) + for _, api in ipairs (enhancements) do + g[api], g["_" .. api] = m[api], m["_" .. api] + end + for _, api in ipairs (extensions) do g[api] = m[api] end + end + + for _, api in ipairs (enhancements) do + extends[api] = M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = nil end + - after: + restore (extends, M) + - it does not perturb the global table: + for _, api in ipairs (extensions) do + expect (extends[api]).should_be (nil) + end + for _, api in ipairs (enhancements) do + expect (extends[api]).should_be (M["_" .. api]) + end + - it contains all global access points: + for api in pairs (extends) do + if enhanced[api] then + expect (M[api]).should_not_be (extends[api]) + else + expect (M[api]).should_be (extends[api]) + end + end + + - context via the std module: + - before: + require "std" + - it adds extension apis to the global table: + for api in pairs (M) do + expect (extends[api]).should_be (M[api]) + end + - it does not add any other global access points: + for api in pairs (extends) do + if not enhanced[api] then + expect (M[api]).should_be (extends[api]) + end + end + + +- describe catdir: + + +- describe catfile: + + +- describe process_files: + - before: + subject = M.process_files + - it is the same function as legacy processFiles call: + expect (io.processFiles).should_be (subject) + + +- describe readlines: + + +- describe shell: + + +- describe slurp: + + +- describe splitdir: + + +- describe writelines: diff --git a/specs/lib/specl.lua b/specs/lib/specl.lua deleted file mode 100644 index 44cbda1..0000000 --- a/specs/lib/specl.lua +++ /dev/null @@ -1,348 +0,0 @@ --- Specification testing framework. --- --- Copyright (c) 2013 Free Software Foundation, Inc. --- Written by Gary V. Vaughan, 2013 --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 3, or (at your option) --- any later version. --- --- This program is distributed in the hope that it will be useful, but --- WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; see the file COPYING. If not, write to the --- Free Software Foundation, Fifth Floor, 51 Franklin Street, Boston, --- MA 02111-1301, USA. - -require "std" - - - ---[[ ================================= ]]-- ---[[ Compatibility between 5.1 and 5.2 ]]-- ---[[ ================================= ]]-- - - --- From http://lua-users.org/lists/lua-l/2010-06/msg00313.html -setfenv = setfenv or function(f, t) - local name - local up = 0 - repeat - up = up + 1 - name = debug.getupvalue (f, up) - until name == '_ENV' or name == nil - if name then - debug.upvaluejoin (f, up, function () return name end, 1) - debug.setupvalue (f, up, t) - end - return f -end - - - ---[[ =========== ]]-- ---[[ Formatters. ]]-- ---[[ =========== ]]-- - - -local report = { - header = function () - end, - - spec = function (spec) - print (spec) - end, - - example = function (example) - print (example) - end, - - expectations = function (expectations, indent) - indent = indent or "" - for i, expectation in ipairs (expectations) do - if expectation.status ~= true then - print (indent .. "- FAILED expectation " .. i .. ": " .. - expectation.message:gsub ("\n", "%0" .. indent .. " ")) - end - end - end, - - footer = function (stats) - local total = stats.pass + stats.fail - local percent = 100 * stats.pass / total - - print () - print (string.format ("Met %.2f%% of %d expectations.", percent, total)) - print (stats.pass .. " passed, and " .. - stats.fail .. " failed in " .. - (os.clock () - stats.starttime) .. " seconds.") - end, -} - - -local progress = { - header = function () - io.write (">") - io.flush () - end, - - spec = function (spec) - end, - - example = function (example) - end, - - expectations = function (expectations, indent) - io.write ("\08") - for i, expectation in ipairs (expectations) do - if expectation.status == true then - io.write (".") - else - io.write ("F") - end - end - io.write (">") - io.flush () - end, - - footer = function (stats) - io.write ("\08 \n") - - if stats.fail == 0 then - io.write ("All expectations met, ") - else - io.write (stats.pass .. " passed, and " .. stats.fail .. " failed ") - end - io.write ("in " .. (os.clock () - stats.starttime) .. " seconds.\n") - end, -} - - --- Use the simple progress formatter by default. Can be changed by run(). -local formatter = progress - - - ---[[ ========= ]]-- ---[[ Matchers. ]]-- ---[[ ========= ]]-- - - -local function objcmp (o1, o2) - local type1, type2 = type (o1), type (o2) - if type1 ~= type2 then return false end - if type1 ~= "table" or type2 ~= "table" then return o1 == o2 end - - for k, v in pairs (o1) do - if o2[k] == nil or not objcmp (v, o2[k]) then return false end - end - -- any keys in o2, not already compared above denote a mismatch! - for k, _ in pairs (o2) do - if o1[k] == nil then return false end - end - return true -end - - --- Quote strings nicely, and coerce non-strings into strings. -local function q (obj) - if type (obj) == "string" then - return '"' .. obj:gsub ('[\\"]', "\\%0") .. '"' - end - return tostring (obj) -end - - -local matchers = { - -- Deep comparison, matches if VALUE and EXPECTED share the same - -- structure. - equal = function (value, expected) - local m = "expecting " .. q(expected) .. ", but got ".. q(value) - return (objcmp (value, expected) == true), m - end, - - -- Identity, only match if VALUE and EXPECTED are the same object. - be = function (value, expected) - local m = "expecting exactly " .. q(expected) .. ", but got " .. q(value) - return (value == expected), m - end, - - -- Matches if FUNC raises any error. - ["error"] = function (expected, ...) - local ok, err = pcall (...) - if not ok then -- "not ok" means an error occurred - local pattern = ".*" .. expected:gsub ("%W", "%%%0") .. ".*" - ok = not err:match (pattern) - end - return not ok, "expecting an error containing " .. q(expected) .. ", and got\n" .. q(err) - end, - - -- Matches if VALUE matches regular expression PATTERN. - match = function (value, pattern) - if type (value) ~= "string" then - error ("'match' matcher: string expected, but got " .. type (value)) - end - local m = "expecting string matching " .. q(pattern) .. ", but got " .. q(value) - return (value:match (pattern) ~= nil), m - end, - - -- Matches if VALUE contains EXPECTED. - contain = function (value, expected) - if type (value) == "string" and type (expected) == "string" then - -- Look for a substring if VALUE is a string. - local pattern = expected:gsub ("%W", "%%%0") - local m = "expecting string containing " .. q(expected) .. ", but got " .. q(value) - return (value:match (pattern) ~= nil), m - elseif type (value) == "table" then - -- Do deep comparison against keys and values of the table. - local m = "expecting table containing " .. q(expected) .. ", but got " .. q(value) - for k, v in pairs (value) do - if objcmp (k, expected) or objcmp (v, expected) then - return true, m - end - end - return false, m - end - error ("'contain' matcher: string or table expected, but got " .. type (value)) - end, -} - - --- Wrap TARGET in metatable that dynamically looks up an appropriate --- matcher from the table above for comparison with the following --- parameter. Matcher names containing '_not_' invert their results --- before returning. --- --- For example: expect ({}).should_not_be {} - -_G.expectations = {} -_G.stats = { pass = 0, fail = 0, starttime = os.clock () } - -local function expect (target) - return setmetatable ({}, { - __index = function(_, matcher) - local inverse = false - if matcher:match ("^should_not_") then - inverse, matcher = true, matcher:sub (12) - else - matcher = matcher:sub (8) - end - return function(...) - local success, message = matchers[matcher](target, ...) - - if inverse then - success = not success - message = message and ("not " .. message) - end - - if success ~= true then - _G.stats.fail = _G.stats.fail + 1 - else - _G.stats.pass = _G.stats.pass + 1 - end - table.insert (_G.expectations, { status = success, message = message }) - end - end - }) -end - - - ---[[ ============= ]]-- ---[[ Spec' Runner. ]]-- ---[[ ============= ]]-- - - -local nop, run_specs, run_examples - - --- Always call before and after unconditionally. -function nop () end - - -function run_specs (specs, indent, env) - indent = indent or "" - for _, detail in ipairs (specs) do - for description, examples in pairs (detail) do - formatter.spec (indent .. description:gsub ("^%w+%s+", "", 1)) - run_examples (examples, indent .. " ", env) - end - end -end - - -function run_examples (examples, indent, env) - env = env or _G - - local before, after = examples.before or nop, examples.after or nop - local block = function (example, blockenv) - before () - - -- There is only one, otherwise we can't maintain example order. - local description, definition = next (example) - - if type (definition) == "table" then - -- A nested context, revert back to run_specs. - run_specs ({ example }, indent, env) - - elseif type (definition) == "function" then - -- An example, execute it in a clean new sub-environment. - local fenv = { expect = expect } - formatter.example (indent .. description:gsub ("^%w+%s+", "", 1)) - setfenv (definition, setmetatable (fenv, { __index = blockenv })) - - _G.expectations = {} -- each example may have several expectations - definition () - formatter.expectations (_G.expectations, " " .. indent) - - else - -- Oh dear, most likely your nesting is not quite right! - error ("malformed spec in " .. tostring (description), 2) - end - - after () - end - - for _, example in ipairs (examples) do - -- Also, run every block in a sub-environment, so that before() and - -- after() calls from one block don't affect any other. - local fenv = setmetatable ({}, { __index = env }) - setfenv (block, fenv) - block (example, fenv) - end -end - - -local function run (spec, format) - formatter = format or formatter - formatter.header (_G.stats) - run_specs (spec) - formatter.footer (_G.stats) - return _G.stats.fail == 0 -end - - ---[[ ----------------- ]]-- ---[[ Public Interface. ]]-- ---[[ ----------------- ]]-- - -local M = { - _VERSION = "0.1", - - matchers = matchers, - progress = progress, - report = report, - run = run, -} - - -if _G._SPEC then - -- Give specs access to some additional private access points. - M = table.merge (M, { _expect = expect }) -end - -return M diff --git a/specs/math_ext_spec.yaml b/specs/math_ext_spec.yaml new file mode 100644 index 0000000..eba26ee --- /dev/null +++ b/specs/math_ext_spec.yaml @@ -0,0 +1,64 @@ +specify math_ext: +- before: | + M = require "std.math_ext" + + extends = math + enhancements = { "floor" } + extensions = { "round" } + + +- context when required: + - before: + enhanced = {} + for _, api in ipairs (enhancements) do enhanced[api] = true end + + - context by name: + - before: | + function restore (g, m) + for _, api in ipairs (enhancements) do + g[api], g["_" .. api] = m[api], m["_" .. api] + end + for _, api in ipairs (extensions) do g[api] = m[api] end + end + + for _, api in ipairs (enhancements) do + extends[api] = M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = nil end + - after: + restore (extends, M) + - it does not perturb the global table: + for _, api in ipairs (extensions) do + expect (extends[api]).should_be (nil) + end + for _, api in ipairs (enhancements) do + expect (extends[api]).should_be (M["_" .. api]) + end + - it contains all global access points: + for api in pairs (extends) do + if enhanced[api] then + expect (M[api]).should_not_be (extends[api]) + else + expect (M[api]).should_be (extends[api]) + end + end + + - context via the std module: + - before: + require "std" + - it adds extension apis to the global table: + for api in pairs (M) do + expect (extends[api]).should_be (M[api]) + end + - it does not add any other global access points: + for api in pairs (extends) do + if not enhanced[api] then + expect (M[api]).should_be (extends[api]) + end + end + + +- describe floor: + + +- describe round: diff --git a/specs/package_ext_spec.lua b/specs/package_ext_spec.lua deleted file mode 100644 index c94930f..0000000 --- a/specs/package_ext_spec.lua +++ /dev/null @@ -1,34 +0,0 @@ -{["specify package_ext"] = { - before = function () - unextended = require "package_ext" - end, - - {["context when requiring the module"] = { - before = function () - -- don't try to check all the entries in unextended package, - -- because they naturally change as modules are loaded. - apis = { "config", "cpath", "loaders", "loadlib", "preload", - "searchers", "searchpath", "seeall" } - end, - - {["it returns the unextended package table"] = function () - expect (unextended.config).should_be (package.config) - expect (unextended.dirsep).should_be (nil) - expect (unextended.pathsep).should_be (nil) - expect (unextended.path_mark).should_be (nil) - expect (unextended.execdir).should_be (nil) - expect (unextended.igmark).should_be (nil) - end}, - {["it splits package.config up"] = function () - expect (string.format ("%s\n%s\n%s\n%s\n%s\n", - package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark) - ).should_be (package.config) - end}, - {["it doesn't override any other module access points"] = function () - - for _, api in ipairs (apis) do - expect (package[api]).should_be (unextended[api]) - end - end}, - }}, -}} diff --git a/specs/package_ext_spec.yaml b/specs/package_ext_spec.yaml index 2fe09f8..42be71b 100644 --- a/specs/package_ext_spec.yaml +++ b/specs/package_ext_spec.yaml @@ -1,25 +1,63 @@ specify package_ext: -- before: - unextended = require "package_ext" -- context when requiring the module: - - before: | - -- do not try to check all the entries in unextended package, - -- because they naturally change as modules are loaded. - apis = { "config", "cpath", "loaders", "loadlib", "preload", - "searchers", "searchpath", "seeall" } +- before: | + M = require "std.package_ext" - - it returns the unextended package table: - expect (unextended.config).should_be (package.config) - expect (unextended.dirsep).should_be (nil) - expect (unextended.pathsep).should_be (nil) - expect (unextended.path_mark).should_be (nil) - expect (unextended.execdir).should_be (nil) - expect (unextended.igmark).should_be (nil) - - "it splits package.config up": - expect (string.format ("%s\n%s\n%s\n%s\n%s\n", - package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark) - ).should_contain (package.config) - - it does not override any other module access points: - for _, api in ipairs (apis) do - expect (package[api]).should_be (unextended[api]) - end + extends = package + extensions = { "dirsep", "pathsep", "path_mark", "execdir", "igmark" } + enhancements = {} + + -- Do not try to check all the entries in unextended package, + -- because they naturally change as modules are loaded. + coreapis = { "config", "cpath", "loaders", "loadlib", "preload", + "searchers", "searchpath", "seeall" } + +- context when required: + - before: + enhanced = {} + for _, api in ipairs (enhancements) do enhanced[api] = true end + + - context by name: + - before: + for _, api in ipairs (enhancements) do + extends[api] = M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = nil end + - after: + for _, api in ipairs (enhancements) do + extends[api], extends["_" .. api] = M[api], M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = M[api] end + - it does not perturb the global table: + for _, api in ipairs (extensions) do + expect (extends[api]).should_be (nil) + end + for _, api in ipairs (enhancements) do + expect (extends[api]).should_be (M["_" .. api]) + end + - it contains all global access points: + for _, api in ipairs (coreapis) do + if enhanced[api] then + expect (M[api]).should_not_be (extends[api]) + else + expect (M[api]).should_be (extends[api]) + end + end + + - context via the std module: + - before: + require "std" + - it adds extension apis to the global table: + for _, api in ipairs (extensions) do + expect (extends[api]).should_be (M[api]) + end + - it does not add any other global access points: + for _, api in ipairs (coreapis) do + if not enhanced[api] then + expect (M[api]).should_be (extends[api]) + end + end + +- "it splits package.config up": + expect (string.format ("%s\n%s\n%s\n%s\n%s\n", + M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark) + ).should_contain (package.config) diff --git a/specs/specl b/specs/specl deleted file mode 100755 index 434ca8c..0000000 --- a/specs/specl +++ /dev/null @@ -1,85 +0,0 @@ -#! /usr/bin/env lua - --- Specification testing framework. --- --- Copyright (c) 2013 Free Software Foundation, Inc. --- Written by Gary V. Vaughan, 2013 --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 3, or (at your option) --- any later version. --- --- This program is distributed in the hope that it will be useful, but --- WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; see the file COPYING. If not, write to the --- Free Software Foundation, Fifth Floor, 51 Franklin Street, Boston, --- MA 02111-1301, USA. - -require "std" - -package.path = "specs/lib/?.lua;src/?.lua;" .. package.path - -local specl = require "specl" - --- TODO: make sure it really works with 5.1 - -prog = { - name = arg[0]:gsub ("^.*/", ""), - version = "Specl 0.1\nWritten by Gary V. Vaughan , 2013", - purpose = "A specification testing framework.", - description = "Execute specifications from FILEs or standard input, " .. - "reporting results on standard output.\nIf no FILE is listed, or w" .. - "here '-' is given as a FILE, read from standard input.", - copyright = "Copyright (c) 2013 Gary V. Vaughan\n" .. - "Specl comes with ABSOLUTELY NO WARRANTY.\n" .. - "You may redistribute copies of Specl under the terms of the GNU\n" .. - "General Public License; either version 3, or any later version.", - notes = "Report bugs at http://github.com/gvvaughan/specl/issues.", - options = { - getopt.Option {{"help"}, "print this help, then exit"}, - getopt.Option {{"version"}, "print version number, then exit"}, - getopt.Option {{"verbose", "v"}, "verbose mode"}, - } -} - - --- Called by io.processFiles() to concatenate a comma separated list of --- specifications in each FILENAME. -local spec = {} -function slurp (filename) - local s, errmsg = io.slurp () - if errmsg ~= nil then - io.stderr:write (errmsg .. "\n") - os.exit (1) - end - - -- Remove leading comment lines, carefully preserving line numbers for - -- error messages from 'load', and then inject the 'return' keyword at - -- the start of the first non-blank line. - s = s:gsub ("^%s*%-%-[^\r\n]+i(\r*\n)%s*", "%1" - ):gsub ("[^\r\n]", "return %0", 1) - local f, errmsg = load (s, filename) - - -- Execute the function from 'load', and save the value returned, or - -- report any error right away. - local t - if f ~= nil then - t, errmsg = f () - end - if errmsg ~= nil then - error (errmsg) - end - - -- Append to the specification list, which specl will run on completion. - table.insert (spec, t) -end - - -getopt.processArgs (prog) -io.processFiles (slurp) -os.exit (specl.run (spec, getopt.opt.verbose and specl.report) and 0 or 1) diff --git a/specs/specs.mk b/specs/specs.mk new file mode 100644 index 0000000..d0b2ae2 --- /dev/null +++ b/specs/specs.mk @@ -0,0 +1,25 @@ +# Specl specs make rules. + + +## ------------ ## +## Environment. ## +## ------------ ## + +SPECL_ENV = $(LUA_ENV) + + +## ------ ## +## Specs. ## +## ------ ## + +specl_SPECS = \ + $(srcdir)/specs/debug_ext_spec.yaml \ + $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/io_ext_spec.yaml \ + $(srcdir)/specs/math_ext_spec.yaml \ + $(srcdir)/specs/package_ext_spec.yaml \ + $(srcdir)/specs/string_ext_spec.yaml \ + $(srcdir)/specs/table_ext_spec.yaml \ + $(NOTHING_ELSE) + +include build-aux/specl.mk diff --git a/specs/string_ext_spec.lua b/specs/string_ext_spec.lua deleted file mode 100644 index 600880e..0000000 --- a/specs/string_ext_spec.lua +++ /dev/null @@ -1,522 +0,0 @@ -{["specify string_ext"] = { - before = function () - unextended = require "string_ext" - - subject = "a string \n\n" - end, - - - {["describe .. operator"] = { - {["it concatenates string arguments"] = function () - target = "a string \n\n another string" - expect (subject .. " another string").should_be (target) - end}, - {["it stringifies non-string arguments"] = function () - argument = { "a table" } - expect (subject .. argument).should_be (string.format ("%s%s", subject, tostring (argument))) - end}, - {["it stringifies nil arguments"] = function () - argument = nil - expect (subject .. argument).should_be (string.format ("%s%s", subject, tostring (argument))) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = subject .. " concatenate something" - expect (subject).should_be (original) - end}, - }}, - - - {["describe string.caps ()"] = { - before = function () - f = string.caps - end, - - {["it capitalises words of a string"] = function () - target = "A String \n\n" - expect (f (subject)).should_be (target) - end}, - {["it changes only the first letter of each word"] = function () - expect (f "a stRiNg").should_be "A StRiNg" - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject) - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.chomp ()"] = { - before = function () - f = string.chomp - end, - - {["it removes a single trailing newline from a string"] = function () - target = "a string \n" - expect (f (subject)).should_be (target) - end}, - {["it doesn't change a string with no trailing newline"] = function () - subject = "a string " - expect (f (subject)).should_be (subject) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject) - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.escape_pattern ()"] = { - before = function () - f = string.escape_pattern - end, - - {["it inserts a % before any non-alphanumeric in a string"] = function () - subject, target = "", "" - for c = 32, 126 do - s = string.char (c) - subject = subject .. s - if s:match ("%W") then target = target .. "%" end - target = target .. s - end - expect (f (subject)).should_be (target) - end}, - {["legacy escapePattern call is the same function"] = function () - expect (string.escapePattern).should_be (f) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject) - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.escape_shell ()"] = { - before = function () - f = string.escape_shell - end, - - {["it inserts a \\ before any shell metacharacters"] = function () - subject, target = "", "" - for c = 32, 126 do - s = string.char (c) - subject = subject .. s - if s:match ("[][ ()\\\"']") then target = target .. "\\" end - target = target .. s - end - expect (f (subject)).should_be (target) - end}, - {["legacy escapeShell call is the same function"] = function () - expect (string.escapeShell).should_be (f) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject) - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.finds ()"] = { - before = function () - subject = "abcd" - f = string.finds - end, - - {["it creates a list of pattern captures"] = function () - target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } - expect ({f (subject, "(.)(.)")}).should_equal ({ target }) - end}, - {["it creates an empty list where no captures are matched "] = function () - target = {} - expect ({f (subject, "(x)")}).should_equal ({ target }) - end}, - {["it creates an empty list for a pattern without captures"] = function () - target = { { 1, 1; capt = {} } } - expect ({f (subject, "a")}).should_equal ({ target }) - end}, - {["it starts the search at a specified index into the subject"] = function () - target = { { 8, 9; capt = { "a", "b" } }, { 10, 11; capt = { "c", "d" } } } - expect ({f ("garbage" .. subject, "(.)(.)", 8)}).should_equal ({ target }) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, "...") - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - -- FIXME: This looks like a misfeature to me, let's remove it! - {["describe string.format ()"] = { - before = function () - subject = "string: %s, number: %d" - f = string.format - end, - - {["it returns a single argument without attempting formatting"] = function () - expect (f (subject)).should_be (subject) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject) - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil, "arg") - expect ("string expected").should_error (f, { "a table" }, "arg") - end}, - }}, - - - {["describe string.ltrim ()"] = { - before = function () - subject = " \t\r\n a short string \t\r\n " - f = string.ltrim - end, - - {["it removes whitespace from the start of a string"] = function () - target = "a short string \t\r\n " - expect (f (subject)).should_equal (target) - end}, - {["it supports custom removal patterns"] = function () - target = "\r\n a short string \t\r\n " - expect (f (subject, "[ \t\n]+")).should_equal (target) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, "%W") - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.numbertosi ()"] = { - before = function () - f = string.numbertosi - end, - - {["it returns a number using SI suffixes"] = function () - target = {"1e-9", "1y", "1z", "1a", "1f", "1p", "1n", "1mu", "1m", "1", - "1k", "1M", "1G", "1T", "1P", "1E", "1Z", "1Y", "1e9"} - subject = {} - for n = -28, 28, 3 do - m = 10 * (10 ^ n) - table.insert (subject, f (m)) - end - expect (subject).should_equal (target) - end}, - {["it coerces string arguments to a number"] = function () - expect (f "1000").should_be "1k" - end}, - {["it diagnoses non-numeric arguments"] = function () - expect ("attempt to perform arithmetic").should_error (f, nil) - expect ("number expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.ordinal_suffix ()"] = { - before = function () - f = string.ordinal_suffix - end, - - {["it returns the English suffix for a number"] = function () - subject, target = {}, {} - for n = -120, 120 do - suffix = "th" - m = math.abs (n) % 10 - if m == 1 and math.abs (n) % 100 ~= 11 then suffix = "st" - elseif m == 2 and math.abs (n) % 100 ~= 12 then suffix = "nd" - elseif m == 3 and math.abs (n) % 100 ~= 13 then suffix = "rd" - end - table.insert (target, n .. suffix) - table.insert (subject, n .. f (n)) - end - expect (subject).should_equal (target) - end}, - {["legacy ordinalSuffix call is the same function"] = function () - expect (string.ordinalSuffix).should_be (f) - end}, - {["it coerces string arguments to a number"] = function () - expect (f "-91").should_be "st" - end}, - {["it diagnoses non-numeric arguments"] = function () - expect ("number expected").should_error (f, nil) - expect ("number expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.pad ()"] = { - before = function () - width = 20 - f = string.pad - end, - - {["context when string is shorter than given width"] = { - before = function () - subject = "short string" - end, - - {["it right pads a string with spaces, to the given width"] = function () - target = "short string " - expect (f (subject, width)).should_be (target) - end}, - {["it left pads a string with spaces, given a negative width"] = function () - width = -width - target = " short string" - expect (f (subject, width)).should_be (target) - end}, - }}, - {["context when string is longer than given width"] = { - before = function () - subject = "a string that's longer than twenty characters" - end, - - {["it truncates a string to the given width"] = function () - target = "a string that's long" - expect (f (subject, width)).should_be (target) - end}, - {["it left pads a string to given width with spaces"] = function () - width = -width - target = "an twenty characters" - expect (f (subject, width)).should_be (target) - end}, - }}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, width) - expect (subject).should_be (original) - end}, - {["it coerces non-string arguments to a string"] = function () - expect (f ({ "a table" }, width)).should_contain "a table" - end}, - {["it diagnoses non-numeric width arguments"] = function () - expect ("number expected").should_error (f, subject, nil) - expect ("number expected").should_error (f, subject, { "a table" }) - end}, - }}, - - - {["describe string.rtrim ()"] = { - before = function () - subject = " \t\r\n a short string \t\r\n " - f = string.rtrim - end, - - {["it removes whitespace from the end of a string"] = function () - target = " \t\r\n a short string" - expect (f (subject)).should_equal (target) - end}, - {["it supports custom removal patterns"] = function () - target = " \t\r\n a short string \t\r" - expect (f (subject, "[ \t\n]+")).should_equal (target) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, "%W") - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.split ()"] = { - before = function () - target = { "first", "the second one", "final entry" } - subject = table.concat (target, ", ") - f = string.split - end, - - {["it makes a table of substrings delimitied by a separator"] = function () - expect (f (subject, ", ")).should_equal (target) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, "e") - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, "a string", nil) - expect ("string expected").should_error (f, nil, ",") - expect ("string expected").should_error (f, { "a table" }, ",") - end}, - }}, - - - {["describe string.tfind ()"] = { - before = function () - subject = "abc" - f = string.tfind - end, - - {["it creates a list of pattern captures"] = function () - target = { 1, 3, { "a", "b", "c" } } - expect ({f (subject, "(.)(.)(.)")}).should_equal (target) - end}, - {["it creates an empty list where no captures are matched "] = function () - target = { nil, nil, {} } - expect ({f (subject, "(x)(y)(z)")}).should_equal (target) - end}, - {["it creates an empty list for a pattern without captures"] = function () - target = { 1, 1, {} } - expect ({f (subject, "a")}).should_equal (target) - end}, - {["it starts the search at a specified index into the subject"] = function () - target = { 8, 10, { "a", "b", "c" } } - expect ({f ("garbage" .. subject, "(.)(.)(.)", 8)}).should_equal (target) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, "...") - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.trim ()"] = { - before = function () - subject = " \t\r\n a short string \t\r\n " - f = string.trim - end, - - {["it removes whitespace from each end of a string"] = function () - target = "a short string" - expect (f (subject)).should_equal (target) - end}, - {["it supports custom removal patterns"] = function () - target = "\r\n a short string \t\r" - expect (f (subject, "[ \t\n]+")).should_equal (target) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, "%W") - expect (subject).should_be (original) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["describe string.wrap ()"] = { - before = function () - subject = "This is a collection of Lua libraries for Lua 5.1 " .. - "and 5.2. The libraries are copyright by their authors 2000" .. - "-2013 (see the AUTHORS file for details), and released und" .. - "er the MIT license (the same license as Lua itself). There" .. - " is no warranty." - f = string.wrap - end, - - {["it inserts newlines to wrap a string"] = function () - target = "This is a collection of Lua libraries for Lua 5.1 a" .. - "nd 5.2. The libraries are\ncopyright by their authors 2000" .. - "-2013 (see the AUTHORS file for details), and\nreleased un" .. - "der the MIT license (the same license as Lua itself). Ther" .. - "e is no\nwarranty." - expect (f (subject)).should_be (target) - end}, - {["it honours a column width parameter"] = function () - target = "This is a collection of Lua libraries for Lua 5.1 a" .. - "nd 5.2. The libraries\nare copyright by their authors 2000" .. - "-2013 (see the AUTHORS file for\ndetails), and released un" .. - "der the MIT license (the same license as Lua\nitself). The" .. - "re is no warranty." - expect (f (subject, 72)).should_be (target) - end}, - {["it supports indenting by a fixed number of columns"] = function () - target = " This is a collection of Lua libraries for L" .. - "ua 5.1 and 5.2. The\n libraries are copyright by th" .. - "eir authors 2000-2013 (see the\n AUTHORS file for d" .. - "etails), and released under the MIT license\n (the " .. - "same license as Lua itself). There is no warranty." - expect (f (subject, 72, 8)).should_be (target) - end}, - {["it can indent the first line differently"] = function () - target = " This is a collection of Lua libraries for Lua 5" .. - ".1 and 5.2.\n The libraries are copyright by their author" .. - "s 2000-2013 (see\n the AUTHORS file for details), and rel" .. - "eased under the MIT\n license (the same license as Lua it" .. - "self). There is no\n warranty." - expect (f (subject, 64, 2, 4)).should_be (target) - end}, - {["the original subject is not perturbed"] = function () - original = subject - newstring = f (subject, 55, 5) - expect (subject).should_be (original) - end}, - {["it diagnoses indent greater than line width"] = function () - expect ("less than the line width").should_error (f, subject, 10, 12) - expect ("less than the line width").should_error (f, subject, 99, 99) - end}, - {["it diagnoses non-string arguments"] = function () - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - end}, - }}, - - - {["context when requiring the module"] = { - before = function () - extensions = { "caps", "chomp", "escape_pattern", "escape_shell", - "finds", "format", "ltrim", "numbertosi", - "ordinal_suffix", "pad", "rtrim", "split", "tfind", - "trim", "wrap" } - end, - - {["it returns the unextended module table"] = function () - for _, api in ipairs (extensions) do - if api ~= "format" then - expect (unextended[api]).should_be (nil) - end - end - end}, - {["it injects an enhanced format function"] = function () - expect (unextended.format).should_not_be (table.format) - end}, - {["it doesn't override any other module access points"] = function () - for api in pairs (unextended) do - if api ~= "format" then - expect (string[api]).should_be (unextended[api]) - end - end - end}, - }}, -}} diff --git a/specs/string_ext_spec.yaml b/specs/string_ext_spec.yaml index bbcb91c..d00d71d 100644 --- a/specs/string_ext_spec.yaml +++ b/specs/string_ext_spec.yaml @@ -1,9 +1,76 @@ specify string_ext: -- before: - unextended = require "string_ext" +- before: | + M = require "std.string_ext" + + extends = string + enhancements = { "format" } + extensions = { "assert", "caps", "chomp", "escape_pattern", + "escape_shell", "finds", "ltrim", "numbertosi", + "ordinal_suffix", "pad", "pickle", "prettytostring", + "render", "require_version", "rtrim", "split", + "tostring", "tfind", "trim", "wrap", + -- make these available after require "std" + "__index", "_tostring", + -- camelCase compatibility: + "escapePattern", "escapeShell", "ordinalSuffix" } + keywords = { "assert", "pickle", "prettytostring", "render", + "require_version", "tostring" } + subject = "a string \n\n" -- "describe .. operator": + +- context when required: + - before: + enhanced = {} + for _, api in ipairs (enhancements) do enhanced[api] = true end + + - context by name: + - before: | + for _, api in ipairs (enhancements) do + extends[api] = M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = nil end + - after: + for _, api in ipairs (enhancements) do + extends[api], extends["_" .. api] = M[api], M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = M[api] end + - it does not perturb the global table: + for _, api in ipairs (extensions) do + expect (extends[api]).should_be (nil) + end + for _, api in ipairs (enhancements) do + expect (extends[api]).should_be (M["_" .. api]) + end + - it contains all global access points: + for api in pairs (extends) do + if enhanced[api] then + expect (M[api]).should_not_be (extends[api]) + else + expect (M[api]).should_be (extends[api]) + end + end + + - context via the std module: + - before: + require "std" + - it adds extension apis to the global table: + for api in pairs (M) do + expect (extends[api]).should_be (M[api]) + end + - it propagates keywords to the global environment: + for _, api in ipairs (keywords) do + expect (_G[api]).should_be (M[api]) + end + - it does not add any other global access points: + for api in pairs (extends) do + if not enhanced[api] then + expect (M[api]).should_be (extends[api]) + end + end + + +- "describe ..": - it concatenates string arguments: target = "a string \n\n another string" expect (subject .. " another string").should_be (target) @@ -18,94 +85,114 @@ specify string_ext: newstring = subject .. " concatenate something" expect (subject).should_be (original) -- "describe string.caps ()": + +- describe assert: + + +- describe caps: - before: - f = string.caps + f = M.caps - it capitalises words of a string: target = "A String \n\n" expect (f (subject)).should_be (target) - it changes only the first letter of each word: expect (f "a stRiNg").should_be "A StRiNg" + - it is available as a string metamethod: + expect (("a stRiNg"):caps ()).should_be "A StRiNg" - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") -- "describe string.chomp ()": +- describe chomp: - before: - f = string.chomp - - it removes a single trailing newline from a string: + f = M.chomp target = "a string \n" + - it removes a single trailing newline from a string: expect (f (subject)).should_be (target) - it does not change a string with no trailing newline: subject = "a string " expect (f (subject)).should_be (subject) + - it is available as a string metamethod: + expect (subject:chomp ()).should_be (target) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") -- "describe string.escape_pattern ()": +- describe escape_pattern: - before: - f = string.escape_pattern - - "it inserts a % before any non-alphanumeric in a string": - subject, target = "", "" - for c = 32, 126 do - s = string.char (c) - subject = subject .. s - if s:match ("%W") then target = target .. "%" end - target = target .. s - end - expect (f (subject)).should_be (target) + f = M.escape_pattern + - context with each printable ASCII char: + - before: + subject, target = "", "" + for c = 32, 126 do + s = string.char (c) + subject = subject .. s + if s:match ("%W") then target = target .. "%" end + target = target .. s + end + - "it inserts a % before any non-alphanumeric in a string": + expect (f (subject)).should_be (target) + - it is available as a string metamethod: + expect (subject:escape_pattern ()).should_be (target) - legacy escapePattern call is the same function: - expect (string.escapePattern).should_be (f) + expect (M.escapePattern).should_be (f) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") -- "describe string.escape_shell ()": +- describe escape_shell: - before: - f = string.escape_shell - - "it inserts a \\ before any shell metacharacters": - subject, target = "", "" - for c = 32, 126 do - s = string.char (c) - subject = subject .. s - if s:match ("[][ ()\\\"']") then target = target .. "\\" end - target = target .. s - end - expect (f (subject)).should_be (target) + f = M.escape_shell + - context with each printable ASCII char: + - before: + subject, target = "", "" + for c = 32, 126 do + s = string.char (c) + subject = subject .. s + if s:match ("[][ ()\\\"']") then target = target .. "\\" end + target = target .. s + end + - "it inserts a \\ before any shell metacharacters": + expect (f (subject)).should_be (target) + - it is available as a string metamethod: + expect (subject:escape_shell ()).should_be (target) - legacy escapeShell call is the same function: - expect (string.escapeShell).should_be (f) + expect (M.escapeShell).should_be (f) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") -- "describe string.finds ()": +- describe finds: - before: subject = "abcd" - f = string.finds - - it creates a list of pattern captures: - target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } - expect ({f (subject, "(.)(.)")}).should_equal ({ target }) + f = M.finds + - context given a complex nested list: + - before: + target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } + - it creates a list of pattern captures: + expect ({f (subject, "(.)(.)")}).should_equal ({ target }) + - it is available as a string metamethod: + expect ({subject:finds ("(.)(.)")}).should_equal ({ target }) - it creates an empty list where no captures are matched: target = {} expect ({f (subject, "(x)")}).should_equal ({ target }) @@ -120,48 +207,53 @@ specify string_ext: newstring = f (subject, "...") expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") # FIXME: This looks like a misfeature to me, let's remove it! -- "describe string.format ()": +- describe format: - before: | subject = "string: %s, number: %d" - f = string.format + f = M.format - it returns a single argument without attempting formatting: expect (f (subject)).should_be (subject) + - it is available as a string metamethod: + expect (subject:format ()).should_be (subject) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil, "arg") - expect ("string expected").should_error (f, { "a table" }, "arg") + expect (f (nil, "arg")).should_error ("string expected") + expect (f ({"a table"}, "arg")).should_error ("string expected") -- "describe string.ltrim ()": +- describe ltrim: - before: subject = " \t\r\n a short string \t\r\n " - f = string.ltrim + f = M.ltrim - it removes whitespace from the start of a string: target = "a short string \t\r\n " expect (f (subject)).should_equal (target) - it supports custom removal patterns: target = "\r\n a short string \t\r\n " expect (f (subject, "[ \t\n]+")).should_equal (target) + - it is available as a string metamethod: + target = "\r\n a short string \t\r\n " + expect (subject:ltrim ("[ \t\n]+")).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") -- "describe string.numbertosi ()": +- describe numbertosi: - before: - f = string.numbertosi + f = M.numbertosi - it returns a number using SI suffixes: target = {"1e-9", "1y", "1z", "1a", "1f", "1p", "1n", "1mu", "1m", "1", "1k", "1M", "1G", "1T", "1P", "1E", "1Z", "1Y", "1e9"} @@ -174,13 +266,13 @@ specify string_ext: - it coerces string arguments to a number: expect (f "1000").should_be "1k" - "it diagnoses non-numeric arguments": - expect ("attempt to perform arithmetic").should_error (f, nil) - expect ("number expected").should_error (f, { "a table" }) + expect (f ()).should_error ("attempt to perform arithmetic") + expect (f {"a table"}).should_error ("number expected") -- "describe string.ordinal_suffix ()": +- describe ordinal_suffix: - before: - f = string.ordinal_suffix + f = M.ordinal_suffix - it returns the English suffix for a number: subject, target = {}, {} for n = -120, 120 do @@ -195,18 +287,18 @@ specify string_ext: end expect (subject).should_equal (target) - legacy ordinalSuffix call is the same function: - expect (string.ordinalSuffix).should_be (f) + expect (M.ordinalSuffix).should_be (f) - it coerces string arguments to a number: expect (f "-91").should_be "st" - "it diagnoses non-numeric arguments": - expect ("number expected").should_error (f, nil) - expect ("number expected").should_error (f, { "a table" }) + expect (f ()).should_error ("number expected") + expect (f {"a table"}).should_error ("number expected") -- "describe string.pad ()": +- describe pad: - before: width = 20 - f = string.pad + f = M.pad - context when string is shorter than given width: - before: @@ -218,6 +310,9 @@ specify string_ext: width = -width target = " short string" expect (f (subject, width)).should_be (target) + - it is available as a string metamethod: + target = "short string " + expect (subject:pad (width)).should_be (target) - context when string is longer than given width: - before: @@ -229,6 +324,9 @@ specify string_ext: width = -width target = "an twenty characters" expect (f (subject, width)).should_be (target) + - it is available as a string metamethod: + target = "a string that's long" + expect (subject:pad (width)).should_be (target) - the original subject is not perturbed: original = subject @@ -237,50 +335,68 @@ specify string_ext: - "it coerces non-string arguments to a string": expect (f ({ "a table" }, width)).should_contain "a table" - "it diagnoses non-numeric width arguments": - expect ("number expected").should_error (f, subject, nil) - expect ("number expected").should_error (f, subject, { "a table" }) + expect (f (subject, nil)).should_error ("number expected") + expect (f (subject, {"a table"})).should_error ("number expected") + + +- describe pickle: + + +- describe prettytostring: + + +- describe render: + + +- describe require_version: -- "describe string.rtrim ()": +- describe rtrim: - before: subject = " \t\r\n a short string \t\r\n " - f = string.rtrim + f = M.rtrim - it removes whitespace from the end of a string: target = " \t\r\n a short string" expect (f (subject)).should_equal (target) - it supports custom removal patterns: target = " \t\r\n a short string \t\r" expect (f (subject, "[ \t\n]+")).should_equal (target) + - it is available as a string metamethod: + target = " \t\r\n a short string \t\r" + expect (subject:rtrim ("[ \t\n]+")).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") -- "describe string.split ()": +- describe split: - before: target = { "first", "the second one", "final entry" } subject = table.concat (target, ", ") - f = string.split - - it makes a table of substrings delimitied by a separator: + f = M.split + - it makes a table of substrings delimited by a separator: expect (f (subject, ", ")).should_equal (target) + - it is available as a string metamethod: + expect (subject:split ", ").should_equal (target) + expect (("/foo/bar/baz.quux"):split "/").should_equal {"", "foo", "bar", "baz.quux"} - the original subject is not perturbed: original = subject newstring = f (subject, "e") expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, "a string", nil) - expect ("string expected").should_error (f, nil, ",") - expect ("string expected").should_error (f, { "a table" }, ",") + expect (f ("a string")).should_error ("string expected") + expect (f (nil, ",")).should_error ("string expected") + expect (f ({"a table"}, ",")).should_error ("string expected") -- "describe string.tfind ()": +- describe tfind: - before: subject = "abc" - f = string.tfind + f = M.tfind - it creates a list of pattern captures: target = { 1, 3, { "a", "b", "c" } } expect ({f (subject, "(.)(.)(.)")}).should_equal (target) @@ -293,42 +409,51 @@ specify string_ext: - it starts the search at a specified index into the subject: target = { 8, 10, { "a", "b", "c" } } expect ({f ("garbage" .. subject, "(.)(.)(.)", 8)}).should_equal (target) + - it is available as a string metamethod: + target = { 8, 10, { "a", "b", "c" } } + expect ({("garbage" .. subject):tfind ("(.)(.)(.)", 8)}).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "...") expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") + + +- describe tostring: -- "describe string.trim ()": +- describe trim: - before: subject = " \t\r\n a short string \t\r\n " - f = string.trim + f = M.trim - it removes whitespace from each end of a string: target = "a short string" expect (f (subject)).should_equal (target) - it supports custom removal patterns: target = "\r\n a short string \t\r" expect (f (subject, "[ \t\n]+")).should_equal (target) + - it is available as a string metamethod: + target = "\r\n a short string \t\r" + expect (subject:trim ("[ \t\n]+")).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") expect (subject).should_be (original) - "it diagnoses non-string arguments": - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") -- "describe string.wrap ()": +- describe wrap: - before: subject = "This is a collection of Lua libraries for Lua 5.1 " .. "and 5.2. The libraries are copyright by their authors 2000" .. "-2013 (see the AUTHORS file for details), and released und" .. "er the MIT license (the same license as Lua itself). There" .. " is no warranty." - f = string.wrap + f = M.wrap - it inserts newlines to wrap a string: target = "This is a collection of Lua libraries for Lua 5.1 a" .. "nd 5.2. The libraries are\ncopyright by their authors 2000" .. @@ -350,42 +475,24 @@ specify string_ext: "etails), and released under the MIT license\n (the " .. "same license as Lua itself). There is no warranty." expect (f (subject, 72, 8)).should_be (target) - - it can indent the first line differently: - target = " This is a collection of Lua libraries for Lua 5" .. - ".1 and 5.2.\n The libraries are copyright by their author" .. - "s 2000-2013 (see\n the AUTHORS file for details), and rel" .. - "eased under the MIT\n license (the same license as Lua it" .. - "self). There is no\n warranty." - expect (f (subject, 64, 2, 4)).should_be (target) + - context given a long unwrapped string: + - before: + target = " This is a collection of Lua libraries for Lua 5" .. + ".1 and 5.2.\n The libraries are copyright by their author" .. + "s 2000-2013 (see\n the AUTHORS file for details), and rel" .. + "eased under the MIT\n license (the same license as Lua it" .. + "self). There is no\n warranty." + - it can indent the first line differently: + expect (f (subject, 64, 2, 4)).should_be (target) + - it is available as a string metamethod: + expect (subject:wrap (64, 2, 4)).should_be (target) - the original subject is not perturbed: original = subject newstring = f (subject, 55, 5) expect (subject).should_be (original) - it diagnoses indent greater than line width: - expect ("less than the line width").should_error (f, subject, 10, 12) - expect ("less than the line width").should_error (f, subject, 99, 99) + expect (f (subject, 10, 12)).should_error ("less than the line width") + expect (f (subject, 99, 99)).should_error ("less than the line width") - it diagnoses non-string arguments: - expect ("string expected").should_error (f, nil) - expect ("string expected").should_error (f, { "a table" }) - - -- context when requiring the module: - - before: - extensions = { "caps", "chomp", "escape_pattern", "escape_shell", - "finds", "format", "ltrim", "numbertosi", - "ordinal_suffix", "pad", "rtrim", "split", "tfind", - "trim", "wrap" } - - it returns the unextended module table: - for _, api in ipairs (extensions) do - if api ~= "format" then - expect (unextended[api]).should_be (nil) - end - end - - it injects an enhanced format function: - expect (unextended.format).should_not_be (table.format) - - it does not override any other module access points: - for api in pairs (unextended) do - if api ~= "format" then - expect (string[api]).should_be (unextended[api]) - end - end + expect (f ()).should_error ("string expected") + expect (f {"a table"}).should_error ("string expected") diff --git a/specs/table_ext_spec.lua b/specs/table_ext_spec.lua deleted file mode 100644 index f331431..0000000 --- a/specs/table_ext_spec.lua +++ /dev/null @@ -1,326 +0,0 @@ -{["specify table_ext"] = { - before = function () - unextended = require "table_ext" - end, - - - {["describe table.clone ()"] = { - before = function () - subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } - f = table.clone - end, - - {["it does not just return the subject"] = function () - expect (f (subject)).should_not_be (subject) - end}, - {["it does copy the subject"] = function () - expect (f (subject)).should_equal (subject) - end}, - {["it only makes a shallow copy"] = function () - expect (f (subject).k1).should_be (subject.k1) - end}, - {["the original subject is not perturbed"] = function () - target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } - copy = f (subject) - expect (subject).should_equal (target) - expect (subject).should_be (subject) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") - end}, - }}, - - - {["describe table.clone_rename()"] = { - before = function () - subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } - f = table.clone_rename - end, - - {["it does not just return the subject"] = function () - expect (f ({}, subject)).should_not_be (subject) - end}, - {["it copies the subject"] = function () - expect (f ({}, subject)).should_equal (subject) - end}, - {["it only makes a shallow copy"] = function () - expect (f ({}, subject).k2).should_be (subject.k2) - end}, - {["context when renaming some keys"] = { - before = function () - target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } - end, - - {["it renames during cloning"] = function () - expect (f ({k1 = "newkey"}, subject)).should_equal (target) - end}, - {["it does not perturb the value in the renamed key field"] = function () - expect (f ({k1 = "newkey"}, subject).newkey).should_be (subject.k1) - end}, - }}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, {}, nil) - expect ("table expected").should_error (f, {}, "foo") - end}, - }}, - - - {["describe table.empty ()"] = { - before = function () - f = table.empty - end, - - {["it returns true for an empty table"] = function () - expect (f {}).should_be (true) - expect (f {nil}).should_be (true) - end}, - {["it returns false for a non-empty table"] = function () - expect (f {"stuff"}).should_be (false) - expect (f {{}}).should_be (false) - expect (f {false}).should_be (false) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") - end}, - }}, - - - {["describe table.invert ()"] = { - before = function () - subject = { k1 = 1, k2 = 2, k3 = 3 } - f = table.invert - end, - - {["it returns a new table"] = function () - expect (f (subject)).should_not_be (subject) - end}, - {["it inverts keys and values in the returned table"] = function () - expect (f (subject)).should_equal { "k1", "k2", "k3" } - end}, - {["it is reversible"] = function () - expect (f (f (subject))).should_equal (subject) - end}, - {["it seems to copy a list of 1..n numbers"] = function () - subject = { 1, 2, 3 } - expect (f (subject)).should_equal (subject) - expect (f (subject)).should_not_be (subject) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") - end}, - }}, - - - {["describe table.keys ()"] = { - before = function () - subject = { k1 = 1, k2 = 2, k3 = 3 } - f = table.keys - end, - - {["it returns an empty list when subject is empty"] = function () - expect (f {}).should_equal {} - end}, - {["it makes a list of table keys"] = function () - cmp = function (a, b) return a < b end - expect (table.sort (f (subject), cmp)).should_equal {"k1", "k2", "k3"} - end}, - {["it does not guarantee stable ordering"] = function () - subject = {} - -- is this a good test? there's a vanishingly small possibility the - -- returned table will have all 10000 keys in the same order... - for i = 10000, 1, -1 do table.insert (subject, i) end - expect (f (subject)).should_not_equal (subject) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") - end}, - }}, - - - {["describe table.merge ()"] = { - before = function () - -- Additional merge keys which are moderately unusual - t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } - t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } - f = table.merge - - target = {} - for k, v in pairs (t1) do target[k] = v end - for k, v in pairs (t2) do target[k] = v end - end, - - {["it doesn't create a whole new table"] = function () - expect (f (t1, t2)).should_be (t1) - end}, - {["it doesn't change t1, if t2 is empty"] = function () - expect (f (t1, {})).should_be (t1) - end}, - {["it copies t2, if t1 is empty"] = function () - expect (f ({}, t1)).should_not_be (t1) - expect (f ({}, t1)).should_equal (t1) - end}, - {["it merges keys from t2 into t1"] = function () - expect (f (t1, t2)).should_equal (target) - end}, - {["it gives precedence to values from t2"] = function () - original = table.clone (t1) - m = f (t1, t2) -- Merge is destructive, do it once only. - expect (m.k3).should_be (t2.k3) - expect (m.k3).should_not_be (original.k3) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil, nil) - expect ("table expected").should_error (f, "foo", "bar") - end}, - }}, - - - {["describe table.new ()"] = { - before = function () - f = table.new - end, - - {["context when not setting a default "] = { - before = function () - default = nil - end, - - {["it returns a new table when nil is passed"] = function () - expect (f (default, nil)).should_equal {} - end}, - {["it returns any table passed in"] = function () - t = { "unique table" } - expect (f (default, t)).should_be (t) - end}, - }}, - {["context when setting a default "] = { - before = function () - default = "default" - end, - - {["it returns a new table when nil is passed"] = function () - expect (f (default, nil)).should_equal {} - end}, - {["it returns any table passed in"] = function () - t = { "unique table" } - expect (f (default, t)).should_be (t) - end}, - }}, - {["it returns the stored value for existing keys"] = function () - t = f ("default") - v = { "unique value" } - t[1] = v - expect (t[1]).should_be (v) - end}, - {["it returns the constructor default for unset keys"] = function () - t = f ("default") - expect (t[1]).should_be "default" - end}, - {["it returns the actual default object"] = function () - default = { "unique object" } - t = f (default) - expect (t[1]).should_be (default) - end}, - {["it diagnoses non-tables/non-nil in the second argument"] = function () - expect ("table expected").should_error (f, nil, "foo") - end}, - }}, - - - {["describe table.size ()"] = { - before = function () - -- - 1 - --------- 2 ---------- -- 3 -- - subject = { "one", { { "two" }, "three" }, four = 5 } - f = table.size - end, - - {["it counts the number of keys in a table"] = function () - expect (f (subject)).should_be (3) - end}, - {["it counts no keys in an empty table"] = function () - expect (f {}).should_be (0) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") - end}, - }}, - - - {["describe table.sort ()"] = { - before = function () - subject = { 5, 2, 4, 1, 0, 3 } - target = { 0, 1, 2, 3, 4, 5 } - cmp = function (a, b) return a < b end - f = table.sort - end, - - {["it sorts elements in place"] = function () - f (subject, cmp) - expect (subject).should_equal (target) - end}, - {["it returns the sorted table"] = function () - expect (f (subject, cmp)).should_equal (target) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, nil) - end}, - }}, - - - {["describe table.values ()"] = { - before = function () - subject = { k1 = {1}, k2 = {2}, k3 = {3} } - f = table.values - end, - - {["it returns an empty list when subject is empty"] = function () - expect (f {}).should_equal {} - end}, - {["it makes a list of table values"] = function () - cmp = function (a, b) return a[1] < b[1] end - expect (table.sort (f (subject), cmp)).should_equal {{1}, {2}, {3}} - end}, - {["it does guarantee stable ordering"] = function () - subject = {} - -- is this a good test? or just requiring an implementation quirk? - for i = 10000, 1, -1 do table.insert (subject, i) end - expect (f (subject)).should_equal (subject) - end}, - {["it diagnoses non-table arguments"] = function () - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") - end}, - }}, - - - {["context when requiring the module"] = { - before = function () - extensions = { "clone", "clone_rename", "empty", "invert", "keys", - "merge", "new", "size", "sort", "values" } - end, - - {["it returns the unextended module table"] = function () - for _, api in ipairs (extensions) do - if api ~= "sort" then - expect (unextended[api]).should_be (nil) - end - end - end}, - {["it injects an enhanced sort function"] = function () - expect (unextended.sort).should_not_be (table.sort) - end}, - {["it doesn't override any other module access points"] = function () - for api in pairs (unextended) do - if api ~= "sort" then - expect (table[api]).should_be (unextended[api]) - end - end - end}, - }}, -}} diff --git a/specs/table_ext_spec.yaml b/specs/table_ext_spec.yaml index a391faf..3f3fc20 100644 --- a/specs/table_ext_spec.yaml +++ b/specs/table_ext_spec.yaml @@ -1,10 +1,67 @@ specify table_ext: -- before: - unextended = require "table_ext" -- "describe table.clone ()": +- before: | + M = require "std.table_ext" + + extends = table + enhancements = { "sort" } + extensions = { "clone", "clone_rename", "empty", "invert", "keys", + "merge", "new", "size", "values" } + +- context when required: + - before: + enhanced = {} + for _, api in ipairs (enhancements) do enhanced[api] = true end + + - context by name: + - before: | + function restore (g, m) + for _, api in ipairs (enhancements) do + g[api], g["_" .. api] = m[api], m["_" .. api] + end + for _, api in ipairs (extensions) do g[api] = m[api] end + end + + for _, api in ipairs (enhancements) do + extends[api] = M["_" .. api] + end + for _, api in ipairs (extensions) do extends[api] = nil end + - after: + restore (extends, M) + - it does not perturb the global table: + for _, api in ipairs (extensions) do + expect (extends[api]).should_be (nil) + end + for _, api in ipairs (enhancements) do + expect (extends[api]).should_be (M["_" .. api]) + end + - it contains all global access points: + for api in pairs (extends) do + if enhanced[api] then + expect (M[api]).should_not_be (extends[api]) + else + expect (M[api]).should_be (extends[api]) + end + end + + - context via the std module: + - before: + require "std" + - it adds extension apis to the global table: + for api in pairs (M) do + expect (extends[api]).should_be (M[api]) + end + - it does not add any other global access points: + for api in pairs (extends) do + if not enhanced[api] then + expect (M[api]).should_be (extends[api]) + end + end + + +- describe clone: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } - f = table.clone + f = M.clone - it does not just return the subject: expect (f (subject)).should_not_be (subject) - it does copy the subject: @@ -17,14 +74,14 @@ specify table_ext: expect (subject).should_equal (target) expect (subject).should_be (subject) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") -- "describe table.clone_rename()": +- describe clone_rename: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } - f = table.clone_rename + f = M.clone_rename - it does not just return the subject: expect (f ({}, subject)).should_not_be (subject) - it copies the subject: @@ -41,13 +98,13 @@ specify table_ext: expect (f ({k1 = "newkey"}, subject).newkey).should_be (subject.k1) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, {}, nil) - expect ("table expected").should_error (f, {}, "foo") + expect (f {}).should_error ("table expected") + expect (f ({}, "foo")).should_error ("table expected") -- "describe table.empty ()": +- describe empty: - before: - f = table.empty + f = M.empty - it returns true for an empty table: expect (f {}).should_be (true) expect (f {nil}).should_be (true) @@ -56,14 +113,14 @@ specify table_ext: expect (f {{}}).should_be (false) expect (f {false}).should_be (false) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") -- "describe table.invert ()": +- describe invert: - before: subject = { k1 = 1, k2 = 2, k3 = 3 } - f = table.invert + f = M.invert - it returns a new table: expect (f (subject)).should_not_be (subject) - it inverts keys and values in the returned table: @@ -75,19 +132,19 @@ specify table_ext: expect (f (subject)).should_equal (subject) expect (f (subject)).should_not_be (subject) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") -- "describe table.keys ()": +- describe keys: - before: subject = { k1 = 1, k2 = 2, k3 = 3 } - f = table.keys + f = M.keys - it returns an empty list when subject is empty: expect (f {}).should_equal {} - it makes a list of table keys: cmp = function (a, b) return a < b end - expect (table.sort (f (subject), cmp)).should_equal {"k1", "k2", "k3"} + expect (M.sort (f (subject), cmp)).should_equal {"k1", "k2", "k3"} - it does not guarantee stable ordering: subject = {} -- is this a good test? there is a vanishingly small possibility the @@ -95,16 +152,16 @@ specify table_ext: for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).should_not_equal (subject) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") -- "describe table.merge ()": +- describe merge: - before: | -- Additional merge keys which are moderately unusual t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } - f = table.merge + f = M.merge target = {} for k, v in pairs (t1) do target[k] = v end @@ -119,18 +176,18 @@ specify table_ext: - it merges keys from t2 into t1: expect (f (t1, t2)).should_equal (target) - it gives precedence to values from t2: - original = table.clone (t1) + original = M.clone (t1) m = f (t1, t2) -- Merge is destructive, do it once only. expect (m.k3).should_be (t2.k3) expect (m.k3).should_not_be (original.k3) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil, nil) - expect ("table expected").should_error (f, "foo", "bar") + expect (f ()).should_error ("table expected") + expect (f ("foo", "bar")).should_error ("table expected") -- "describe table.new ()": +- describe new: - before: - f = table.new + f = M.new - context when not setting a default: - before: default = nil @@ -162,73 +219,53 @@ specify table_ext: t = f (default) expect (t[1]).should_be (default) - "it diagnoses non-tables/non-nil in the second argument": - expect ("table expected").should_error (f, nil, "foo") + expect (f (nil, "foo")).should_error ("table expected") -- "describe table.size ()": +- describe size: - before: | -- - 1 - --------- 2 ---------- -- 3 -- subject = { "one", { { "two" }, "three" }, four = 5 } - f = table.size + f = M.size - it counts the number of keys in a table: expect (f (subject)).should_be (3) - it counts no keys in an empty table: expect (f {}).should_be (0) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") -- "describe table.sort ()": +- describe sort: - before: subject = { 5, 2, 4, 1, 0, 3 } target = { 0, 1, 2, 3, 4, 5 } cmp = function (a, b) return a < b end - f = table.sort + f = M.sort - it sorts elements in place: f (subject, cmp) expect (subject).should_equal (target) - it returns the sorted table: expect (f (subject, cmp)).should_equal (target) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, nil) + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") + - -- "describe table.values ()": +- describe values: - before: subject = { k1 = {1}, k2 = {2}, k3 = {3} } - f = table.values + f = M.values - it returns an empty list when subject is empty: expect (f {}).should_equal {} - it makes a list of table values: cmp = function (a, b) return a[1] < b[1] end - expect (table.sort (f (subject), cmp)).should_equal {{1}, {2}, {3}} + expect (M.sort (f (subject), cmp)).should_equal {{1}, {2}, {3}} - it does guarantee stable ordering: subject = {} -- is this a good test? or just requiring an implementation quirk? for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).should_equal (subject) - "it diagnoses non-table arguments": - expect ("table expected").should_error (f, nil) - expect ("table expected").should_error (f, "foo") - - -- context when requiring the module: - - before: - extensions = { "clone", "clone_rename", "empty", "invert", "keys", - "merge", "new", "size", "sort", "values" } - - it returns the unextended module table: - for _, api in ipairs (extensions) do - if api ~= "sort" then - expect (unextended[api]).should_be (nil) - end - end - - it injects an enhanced sort function: - expect (unextended.sort).should_not_be (table.sort) - - it does not override any other module access points: - for api in pairs (unextended) do - if api ~= "sort" then - expect (table[api]).should_be (unextended[api]) - end - end + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") diff --git a/src/base.lua b/src/base.lua deleted file mode 100644 index 3ec219d..0000000 --- a/src/base.lua +++ /dev/null @@ -1,537 +0,0 @@ ---- Adds to the existing global functions -module ("base", package.seeall) - ---- Functional forms of infix operators. --- Defined here so that other modules can write to it. --- @class table --- @name _G.op -_G.op = {} - -require "table_ext" -local list = require "list" -require "string_ext" ---require "io_ext" FIXME: allow loops -local strbuf = require "strbuf" - - ---- Require a module with a particular version --- @param module module to require --- @param min lowest acceptable version (default: any) --- @param too_big lowest version that is too big (default: none) --- @pattern pattern to match version in module.version or --- module.VERSION (default: ".*[%.%d]+" -function _G.require_version (module, min, too_big, pattern) - local function version_to_list (v) - return list.new (string.split (v, "%.")) - end - local function module_version (module, pattern) - return version_to_list (string.match (module.version or module._VERSION, - pattern or ".*[%.%d]+")) - end - local m = require (module) - if min then - assert (module_version (m, pattern) >= version_to_list (min)) - end - if too_big then - assert (module_version (m, pattern) < version_to_list (too_big)) - end - return m -end - ---- Return given metamethod, if any, or nil. --- @param x object to get metamethod of --- @param n name of metamethod to get --- @return metamethod function or nil if no metamethod or not a --- function -function _G.metamethod (x, n) - local _, m = pcall (function (x) - return getmetatable (x)[n] - end, - x) - if type (m) ~= "function" then - m = nil - end - return m -end - ---- Turn tables into strings with recursion detection. --- N.B. Functions calling render should not recurse, or recursion --- detection will not work. --- @see render_OpenRenderer, render_CloseRenderer --- @see render_ElementRenderer, render_PairRenderer --- @see render_SeparatorRenderer --- @param x object to convert to string --- @param open open table renderer --- @param close close table renderer --- @param elem element renderer --- @param pair pair renderer --- @param sep separator renderer --- @return string representation -function _G.render (x, open, close, elem, pair, sep, roots) - local function stop_roots (x) - return roots[x] or render (x, open, close, elem, pair, sep, table.clone (roots)) - end - roots = roots or {} - if type (x) ~= "table" or metamethod (x, "__tostring") then - return elem (x) - else - local s = strbuf.new () - s = s .. open (x) - roots[x] = elem (x) - local i, v = nil, nil - for j, w in pairs (x) do - s = s .. sep (x, i, v, j, w) .. pair (x, j, w, stop_roots (j), stop_roots (w)) - i, v = j, w - end - s = s .. sep(x, i, v, nil, nil) .. close (x) - return s:tostring () - end -end - ---- --- @class function --- @name render_OpenRenderer --- @param t table --- @return open table string - ---- --- @class function --- @name render_CloseRenderer --- @param t table --- @return close table string - ---- --- @class function --- @name render_ElementRenderer --- @param e element --- @return element string - ---- --- @class function --- @name render_PairRenderer --- N.B. the function should not try to render i and v, or treat --- them recursively. --- @param t table --- @param i index --- @param v value --- @param is index string --- @param vs value string --- @return element string - ---- --- @class function --- @name render_SeparatorRenderer --- @param t table --- @param i preceding index (nil on first call) --- @param v preceding value (nil on first call) --- @param j following index (nil on last call) --- @param w following value (nil on last call) --- @return separator string - ---- Extend tostring to work better on tables. --- The original tostring is available as _tostring. --- @class function --- @name _G.tostring --- @param x object to convert to string --- @return string representation -_G._tostring = tostring -- make original tostring available -local _tostring = tostring -function _G.tostring (x) - return render (x, - function () return "{" end, - function () return "}" end, - _tostring, - function (t, _, _, i, v) - return i .. "=" .. v - end, - function (_, i, _, j) - if i and j then - return "," - end - return "" - end) -end - ---- Pretty-print a table. --- @param t table to print --- @param indent indent between levels ["\t"] --- @param spacing space before every line --- @return pretty-printed string -function _G.prettytostring (t, indent, spacing) - indent = indent or "\t" - spacing = spacing or "" - return render (t, - function () - local s = spacing .. "{" - spacing = spacing .. indent - return s - end, - function () - spacing = string.gsub (spacing, indent .. "$", "") - return spacing .. "}" - end, - function (x) - if type (x) == "string" then - return string.format ("%q", x) - else - return tostring (x) - end - end, - function (x, i, v, is, vs) - local s = spacing .. "[" - if type (i) == "table" then - s = s .. "\n" - end - s = s .. is - if type (i) == "table" then - s = s .. "\n" - end - s = s .. "] =" - if type (v) == "table" then - s = s .. "\n" - else - s = s .. " " - end - s = s .. vs - return s - end, - function (_, i) - local s = "\n" - if i then - s = "," .. s - end - return s - end) -end - ---- Turn an object into a table according to __totable metamethod. --- @param x object to turn into a table --- @return table or nil -function _G.totable (x) - local m = metamethod (x, "__totable") - if m then - return m (x) - elseif type (x) == "table" then - return x - else - return nil - end -end - ---- Convert a value to a string. --- The string can be passed to dostring to retrieve the value. ---
    TODO: Make it work for recursive tables. --- @param x object to pickle --- @return string such that eval (s) is the same value as x -function _G.pickle (x) - if type (x) == "string" then - return string.format ("%q", x) - elseif type (x) == "number" or type (x) == "boolean" or - type (x) == "nil" then - return tostring (x) - else - x = totable (x) or x - if type (x) == "table" then - local s, sep = "{", "" - for i, v in pairs (x) do - s = s .. sep .. "[" .. pickle (i) .. "]=" .. pickle (v) - sep = "," - end - s = s .. "}" - return s - else - die ("cannot pickle " .. tostring (x)) - end - end -end - ---- Identity function. --- @param ... --- @return the arguments passed to the function -function _G.id (...) - return ... -end - ---- Turn a tuple into a list. --- @param ... tuple --- @return list -function _G.pack (...) - return {...} -end - ---- Partially apply a function. --- @param f function to apply partially --- @param ... arguments to bind --- @return function with ai already bound -function _G.bind (f, ...) - local fix = {...} - return function (...) - return f (unpack (list.concat (fix, {...}))) - end -end - ---- Curry a function. --- @param f function to curry --- @param n number of arguments --- @return curried version of f -function _G.curry (f, n) - if n <= 1 then - return f - else - return function (x) - return curry (bind (f, x), n - 1) - end - end -end - ---- Compose functions. --- @param f1...fn functions to compose --- @return composition of f1 ... fn -function _G.compose (...) - local arg = {...} - local fns, n = arg, #arg - return function (...) - local arg = {...} - for i = n, 1, -1 do - arg = {fns[i] (unpack (arg))} - end - return unpack (arg) - end -end - ---- Memoize a function, by wrapping it in a functable. --- @param fn function that returns a single result --- @return memoized function -function _G.memoize (fn) - return setmetatable ({}, { - __call = function (self, ...) - local k = tostring ({...}) - local v = self[k] - if v == nil then - v = fn (...) - self[k] = v - end - return v - end - }) -end - ---- Evaluate a string. --- @param s string --- @return value of string -function _G.eval (s) - return loadstring ("return " .. s)() -end - ---- An iterator like ipairs, but in reverse. --- @param t table to iterate over --- @return iterator function --- @return the table, as above --- @return #t + 1 -function _G.ripairs (t) - return function (t, n) - n = n - 1 - if n > 0 then - return n, t[n] - end - end, - t, #t + 1 -end - ---- --- @class function --- @name tree_Iterator --- @param n current node --- @return type ("leaf", "branch" (pre-order) or "join" (post-order)) --- @return path to node ({i1...ik}) --- @return node -local function _nodes (it, tr) - local p = {} - local function visit (n) - if type (n) == "table" then - coroutine.yield ("branch", p, n) - for i, v in it (n) do - table.insert (p, i) - visit (v) - table.remove (p) - end - coroutine.yield ("join", p, n) - else - coroutine.yield ("leaf", p, n) - end - end - return coroutine.wrap (visit), tr -end - ---- Tree iterator. --- @see tree_Iterator --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -function _G.nodes (tr) - return _nodes (pairs, tr) -end - ---- Tree iterator over numbered nodes, in order. --- @see tree_Iterator --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -function _G.inodes (tr) - return _nodes (ipairs, tr) -end - -local function _leaves (it, tr) - local function visit (n) - if type (n) == "table" then - for _, v in it (n) do - visit (v) - end - else - coroutine.yield (n) - end - end - return coroutine.wrap (visit), tr -end - ---- Tree iterator which returns just numbered leaves, in order. --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -function _G.ileaves (tr) - return _leaves (ipairs, tr) -end - ---- Tree iterator which returns just leaves. --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -function _G.leaves (tr) - return _leaves (pairs, tr) -end - ---- Collect the results of an iterator. --- @param i iterator --- @return results of running the iterator on its arguments -function _G.collect (i, ...) - local t = {} - for e in i (...) do - table.insert (t, e) - end - return t -end - ---- Map a function over an iterator. --- @param f function --- @param i iterator --- @return result table -function _G.map (f, i, ...) - local t = {} - for e in i (...) do - local r = f (e) - if r then - table.insert (t, r) - end - end - return t -end - ---- Filter an iterator with a predicate. --- @param p predicate --- @param i iterator --- @return result table containing elements e for which p (e) -function _G.filter (p, i, ...) - local t = {} - for e in i (...) do - if p (e) then - table.insert (t, e) - end - end - return t -end - ---- Fold a binary function into an iterator. --- @param f function --- @param d initial first argument --- @param i iterator --- @return result -function _G.fold (f, d, i, ...) - local r = d - for e in i (...) do - r = f (r, e) - end - return r -end - ---- Extend to allow formatted arguments. --- @param v value to assert --- @param f format --- @param ... arguments to format --- @return value -function _G.assert (v, f, ...) - if not v then - if f == nil then - f = "" - end - error (string.format (f, ...)) - end - return v -end - ---- Give warning with the name of program and file (if any). --- @param ... arguments for format -function _G.warn (...) - if prog.name then - io.stderr:write (prog.name .. ":") - end - if prog.file then - io.stderr:write (prog.file .. ":") - end - if prog.line then - io.stderr:write (tostring (prog.line) .. ":") - end - if prog.name or prog.file or prog.line then - io.stderr:write (" ") - end - io.writelines (io.stderr, string.format (...)) -end - ---- Die with error. --- @param ... arguments for format -function _G.die (...) - warn (...) - error () -end - --- Function forms of operators. --- FIXME: Make these visible in LuaDoc (also list.concat in list) -_G.op["[]"] = function (t, s) - return t[s] -end -_G.op["+"] = function (a, b) - return a + b -end -_G.op["-"] = function (a, b) - return a - b -end -_G.op["*"] = function (a, b) - return a * b -end -_G.op["/"] = function (a, b) - return a / b -end -_G.op["and"] = function (a, b) - return a and b -end -_G.op["or"] = function (a, b) - return a or b -end -_G.op["not"] = function (a) - return not a -end -_G.op["=="] = function (a, b) - return a == b -end -_G.op["~="] = function (a, b) - return a ~= b -end diff --git a/src/bin.lua b/src/bin.lua deleted file mode 100644 index 46375dc..0000000 --- a/src/bin.lua +++ /dev/null @@ -1,26 +0,0 @@ ---- Binary data utilities - ---- Turn a little-endian word into a number -local function le_to_number (s) - local res = 0 - for i = #s, 1, -1 do - res = res * 256 + string.byte (s, i) - end - return res -end - ---- Turn a little-endian word into a hex string -local function le_to_hex (s) - local res = "" - for i = 1, #s do - res = res .. string.format ("%.2x", string.byte (s, i)) - end - return res -end - -local M = { - le_to_number = le_to_number, - le_to_hex = le_to_hex, -} - -return M diff --git a/src/debug_init.lua b/src/debug_init.lua deleted file mode 100644 index 37ab532..0000000 --- a/src/debug_init.lua +++ /dev/null @@ -1,2 +0,0 @@ --- Debugging is on by default -_G._DEBUG = true diff --git a/src/files/bin.html b/src/files/bin.html deleted file mode 100644 index e42ef70..0000000 --- a/src/files/bin.html +++ /dev/null @@ -1,270 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File bin.lua

    - - - - - - - -

    Functions

    -
    getOpt (argIn, options, undefined_options)getOpt (argIn, options, stop_at_nonopt) Perform argument processing
    processArgs (prog, undefined_opts)processArgs (prog, ...) Simple getOpt wrapper.
    - - - - - - - - - - - -
    le_to_hex (s)Turn a little-endian word into a hex string
    le_to_number (s)Turn a little-endian word into a number
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    le_to_hex (s)
    -
    -Turn a little-endian word into a hex string - - -

    Parameters

    -
      - -
    • - s: -
    • - -
    - - - - - - - - -
    - - - - -
    le_to_number (s)
    -
    -Turn a little-endian word into a number - - -

    Parameters

    -
      - -
    • - s: -
    • - -
    - - - - - - - - -
    - - -
    - - - - - - - - - - - -
    -

    Valid XHTML 1.0!

    -
    - - - - diff --git a/src/files/fstable.html b/src/files/fstable.html deleted file mode 100644 index fd53984..0000000 --- a/src/files/fstable.html +++ /dev/null @@ -1,246 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File fstable.lua

    - - - - - - - -

    Functions

    - - - - - - - -
    new (path, t)Bind a directory to a table
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    new (path, t)
    -
    -Bind a directory to a table - - -

    Parameters

    -
      - -
    • - path: directory path -
    • - -
    • - t: table to merge with directory -
    • - -
    - - - - - - -

    Return value:

    -table bound to directory - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/files/lcs.html b/src/files/lcs.html deleted file mode 100644 index 48c4809..0000000 --- a/src/files/lcs.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File lcs.lua

    - - - - - - - -

    Functions

    - - - - - - - -
    longestCommonSubseq (a, b, s)Find the longest common subsequence of two sequences.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    longestCommonSubseq (a, b, s)
    -
    -Find the longest common subsequence of two sequences. The sequence objects must have an __append metamethod. This is provided by string_ext for strings, and by list for lists. - - -

    Parameters

    -
      - -
    • - a: first sequence -
    • - -
    • - b: second sequence -
    • - -
    • - s: an empty sequence of the same type, to hold the result -
    • - -
    - - - - - - -

    Return value:

    -the LCS of a and b - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/files/mbox.html b/src/files/mbox.html deleted file mode 100644 index 4021740..0000000 --- a/src/files/mbox.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File mbox.lua

    - - - - - - - -

    Functions

    - - - - - - - -
    parse (s)Parse a mailbox into messages.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    parse (s)
    -
    -Parse a mailbox into messages. - - -

    Parameters

    -
      - -
    • - s: mailbox as a string -
    • - -
    - - - - - - -

    Return value:

    -list of messages, each of form {header = {...}, body = "..."} - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/files/parser.html b/src/files/parser.html deleted file mode 100644 index 1da5a07..0000000 --- a/src/files/parser.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File parser.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - -
    Parser:_init (grammar)Parser constructor
    Parser:parse (start, token, from)Parse a token list.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    Parser:_init (grammar)
    -
    -Parser constructor - - -

    Parameters

    -
      - -
    • - grammar: parser grammar -
    • - -
    - - - - - - -

    Return value:

    -parser - - - -
    - - - - -
    Parser:parse (start, token, from)
    -
    -Parse a token list. - - -

    Parameters

    -
      - -
    • - start: the token at which to start -
    • - -
    • - token: the list of tokens -
    • - -
    • - from: the index of the token to start from (default: 1) -
    • - -
    - - - - - - -

    Return value:

    -parse tree - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/files/std.html b/src/files/std.html deleted file mode 100644 index 92fdc30..0000000 --- a/src/files/std.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File std.lua

    - - - - - - - - - - - - -
    -
    - - - - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/files/xml.html b/src/files/xml.html deleted file mode 100644 index 9bbda48..0000000 --- a/src/files/xml.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File xml.lua

    - - - - - - - -

    Functions

    - - - - - - - -
    string.writeXML (t, indent, spacing)Write a table as XML.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    string.writeXML (t, indent, spacing)
    -
    -Write a table as XML. The input format is assumed to be that output by luaexpat. - - -

    Parameters

    -
      - -
    • - t: table to print. In each element, tag is its name, attr is the table of attributes, and the sub-elements are held in the integer keys -
    • - -
    • - indent: indent between levels (default: "\t") -
    • - -
    • - spacing: space before every line -
    • - -
    - - - - - - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/fstable.lua b/src/fstable.lua deleted file mode 100644 index 7e6574c..0000000 --- a/src/fstable.lua +++ /dev/null @@ -1,123 +0,0 @@ ---- Tables mapped to the filing system --- Only string keys are permitted; package.dirsep characters are --- converted to underscores. --- Values are stored as strings (converted by tostring). --- As with disk operations, a table's elements must be set to nil --- (deleted) before the table itself can be set to nil. - -require "io_ext" -require "table_ext" - -require "io_ext" -require "lfs" -require "posix" - -local new - -local function fsnext (dir) - local f - repeat - f = dir:next () - until f ~= "." and f ~= ".." - return f -end - --- Metamethods for persistent tables -local metatable = {} - -metatable.__index = -function (t, k) - local path = io.catfile (getmetatable (t).directory, k) - local attrs = lfs.attributes (path) - if attrs then - if attrs.mode == "file" then - return io.slurp (path) - elseif attrs.mode == "directory" then - return new (path) - end - end - return attrs -end - -metatable.__newindex = -function (t, k, v) - local ty = type (v) - if ty == "thread" or ty == "function" or ty == "userdata" then - error ("cannot persist a " .. ty .. "") - elseif type (k) ~= "string" then - error ("keys of persistent tables must be of type string") - else - k = string.gsub (k, package.dirsep, "_") - local path = io.catfile (getmetatable (t).directory, k) - local vm = getmetatable (v) - if v == nil then - os.remove (path) - elseif type (v) ~= "table" then - local h = io.open (path, "w") - h:write (tostring (v)) - h:close () - elseif type (vm) == "table" and vm.metatable == metatable then - -- To match Lua semantics we'd hardlink, but that's not allowed for directories - local ok, errmsg = posix.link (vm.directory, path, true) - else - local ok, errmsg = lfs.mkdir (path) - if not ok then - error (errmsg) - end - new (path, v) - end - end -end - -metatable.__pairs = -function (t) - local _, dir = lfs.dir (getmetatable (t).directory) - return function (dir) - local f = fsnext (dir) - if f then - return f, t[f] - end - end, - dir -end - -metatable.__ipairs = -function (t) - local _, dir = lfs.dir (getmetatable (t).directory) - return function (dir, i) - local f = fsnext (dir) - if f then - return i + 1, f - end - end, - dir, 0 -end - ---- Bind a directory to a table --- @param path directory path --- @param t table to merge with directory --- @return table bound to directory -function new (path, t) - if not path:find ("^" .. package.dirsep) then - path = io.catfile (lfs.currentdir (), path) - end - if lfs.attributes (path, "mode") ~= "directory" then - error ("`" .. path .. "' does not exist or is not a directory") - end - local m = table.clone (metatable) - m.directory = path - m.metatable = metatable - local d = setmetatable ({}, m) - if t then - for i, v in pairs (t) do - d[i] = v - end - end - return d -end - -local M = { - new = new, -} - -return M diff --git a/src/lcs.lua b/src/lcs.lua deleted file mode 100644 index aab9920..0000000 --- a/src/lcs.lua +++ /dev/null @@ -1,61 +0,0 @@ ---- Longest Common Subsequence algorithm. --- After pseudo-code in lecture --- notes by David Eppstein. - - --- Find common subsequences. --- @param a first sequence --- @param b second sequence --- @return list of common subsequences --- @return the length of a --- @return the length of b -local function commonSubseqs (a, b) - local l, m, n = {}, #a, #b - for i = m + 1, 1, -1 do - l[i] = {} - for j = n + 1, 1, -1 do - if i > m or j > n then - l[i][j] = 0 - elseif a[i] == b[j] then - l[i][j] = 1 + l[i + 1][j + 1] - else - l[i][j] = math.max (l[i + 1][j], l[i][j + 1]) - end - end - end - return l, m, n -end - ---- Find the longest common subsequence of two sequences. --- The sequence objects must have an __append metamethod. --- This is provided by string_ext for strings, and by --- list for lists. --- @param a first sequence --- @param b second sequence --- @param s an empty sequence of the same type, to hold the result --- @return the LCS of a and b -local function longestCommonSubseq (a, b, s) - local l, m, n = commonSubseqs (a, b) - local i, j = 1, 1 - local f = getmetatable (s).__append - while i <= m and j <= n do - if a[i] == b[j] then - s = f (s, a[i]) - i = i + 1 - j = j + 1 - elseif l[i + 1][j] >= l[i][j + 1] then - i = i + 1 - else - j = j + 1 - end - end - return s -end - --- Public interface -local M = { - longestCommonSubseq = longestCommonSubseq, -} - -return M diff --git a/src/mbox.lua b/src/mbox.lua deleted file mode 100644 index 996adb0..0000000 --- a/src/mbox.lua +++ /dev/null @@ -1,59 +0,0 @@ ---- mbox parser. --- Based on code by Diego Nahab. - -local function headers (s) - local header = {} - s = "\n" .. s .. "$$$:\n" - local i, j = 1, 1 - while true do - j = string.find (s, "\n%S-:", i + 1) - if not j then - break - end - local _, _, name, val = string.find (string.sub (s, i + 1, j - 1), - "(%S-):(.*)") - val = string.gsub (val or "", "\r\n", "\n") - val = string.gsub (val, "\n%s*", " ") - name = string.lower (name) - if header[name] then - header[name] = header[name] .. ", " .. val - else - header[name] = val - end - i, j = j, i - end - header["$$$"] = nil - return header -end - -local function message (s) - s = string.gsub (s, "^.-\n", "") - local _, s, body - _, _, s, body = string.find(s, "^(.-\n)\n(.*)") - return {header = headers (s or ""), body = body or ""} -end - ---- Parse a mailbox into messages. --- @param s mailbox as a string --- @return list of messages, each of form {header = {...}, body = "..."} -local function parse (s) - local mbox = {} - s = "\n" .. s .. "\nFrom " - local i, j = 1, 1 - while true do - j = string.find (s, "\nFrom ", i + 1) - if not j then - break - end - table.insert (mbox, message (string.sub (s, i + 1, j - 1))) - i, j = j, i - end - return mbox -end - --- Public interface -local M = { - parse = parse, -} - -return M diff --git a/src/modules.lua b/src/modules.lua deleted file mode 100644 index 1ca0556..0000000 --- a/src/modules.lua +++ /dev/null @@ -1,16 +0,0 @@ -return { - "debug_init", - --"strict", - "base", - "package_ext", - "debug_ext", - "table_ext", - "list", - "tree", - "string_ext", - "math_ext", - "io_ext", - "getopt", - "set", - "strbuf", -} diff --git a/src/modules/bin.html b/src/modules/bin.html deleted file mode 100644 index 3491814..0000000 --- a/src/modules/bin.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module bin

    - -

    Binary data utilities

    - - - - - -

    Functions

    - - - - - - - - - - - - -
    le_to_hex (s)Turn a little-endian word into a hex string
    le_to_number (s)Turn a little-endian word into a number
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    le_to_hex (s)
    -
    -Turn a little-endian word into a hex string - - -

    Parameters

    -
      - -
    • - s: -
    • - -
    - - - - - - - - -
    - - - - -
    le_to_number (s)
    -
    -Turn a little-endian word into a number - - -

    Parameters

    -
      - -
    • - s: -
    • - -
    - - - - - - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/debug.html b/src/modules/debug.html deleted file mode 100644 index 502ef24..0000000 --- a/src/modules/debug.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module debug

    - -

    Additions to the debug module

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - -
    debug ()The global function debug is an abbreviation for debug.say (1, ...)
    say (n, ...)Print a debugging message
    trace (event)Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set.
    - - - - -

    Tables

    - - - - - - - -
    _DEBUGTo activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below.
    - - - -
    -
    - - - -

    Functions

    -
    - - - -
    debug ()
    -
    -The global function debug is an abbreviation for debug.say (1, ...) - - - - - - - - - -

    See also:

    - - -
    - - - - -
    say (n, ...)
    -
    -Print a debugging message - - -

    Parameters

    -
      - -
    • - n: debugging level, defaults to 1 -
    • - -
    • - ...: objects to print (as for print) -
    • - -
    - - - - - - - - -
    - - - - -
    trace (event)
    -
    -Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set. Based on test/trace-calls.lua from the Lua distribution. - - -

    Parameters

    -
      - -
    • - event: event causing the call -
    • - -
    - - - - - - - - -
    - - -
    - - - - -

    Tables

    -
    - -
    _DEBUG
    -
    To activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below. - - -Fields -
      - -
    • - level: debugging level -
    • - -
    • - call: do call trace debugging -
    • - -
    • - std: do standard library debugging (run examples & test code) -
    • - -
    - - -
    - - -
    - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/fstable.html b/src/modules/fstable.html deleted file mode 100644 index f998230..0000000 --- a/src/modules/fstable.html +++ /dev/null @@ -1,304 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module fstable

    - -

    Tables mapped to the filing system Only string keys are permitted; package.dirsep characters are converted to underscores. Values are stored as strings (converted by tostring). As with disk operations, a table's elements must be set to nil (deleted) before the table itself can be set to nil.

    - - - - - -

    Functions

    - - - - - - - -
    new (path, t)Bind a directory to a table
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    new (path, t)
    -
    -Bind a directory to a table - - -

    Parameters

    -
      - -
    • - path: directory path -
    • - -
    • - t: table to merge with directory -
    • - -
    - - - - - - -

    Return value:

    -table bound to directory - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/getopt.html b/src/modules/getopt.html deleted file mode 100644 index 0a6f18f..0000000 --- a/src/modules/getopt.html +++ /dev/null @@ -1,473 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module getopt

    - -

    Simplified getopt, based on Svenne Panne's Haskell GetOpt.
    Usage:

    • options = {Option {...}, ...}
      getopt.processArgs ()
    • Assumes prog = {name[, banner] [, purpose] [, notes] [, usage]}
    • Options take a single dash, but may have a double dash.
    • Arguments may be given as -opt=arg or -opt arg.
    • If an option taking an argument is given multiple times, only the last value is returned; missing arguments are returned as 1.
    getOpt, usageInfo and usage can be called directly (see below, and the example at the end). Set _DEBUG.std to a non-nil value to run the example.
    • TODO: Sort out the packaging. getopt.Option is tedious to type, but surely Option shouldn't be in the root namespace?
    • TODO: Wrap all messages; do all wrapping in processArgs, not usageInfo; use sdoc-like library (see string.format todos).
    • TODO: Don't require name to be repeated in banner.
    • TODO: Store version separately (construct banner?).

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    getOpt (argIn, options)Perform argument processing
    makeOptions (t)Options table constructor: adds lookup tables for the option names
    processArgs ()Simple getOpt wrapper.
    usage ()Emit a usage message.
    usageInfo (header, optDesc, pageWidth)Produce usage info for the given options
    - - - - -

    Tables

    - - - - - - - -
    _G.OptionOptions table type.
    - - - -
    -
    - - - -

    Functions

    -
    - - - -
    getOpt (argIn, options)
    -
    -Perform argument processing - - -

    Parameters

    -
      - -
    • - argIn: list of command-line args -
    • - -
    • - options: options table -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. table of remaining non-options - -
    2. table of option key-value list pairs - -
    3. table of error messages - -
    - - - -
    - - - - -
    makeOptions (t)
    -
    -Options table constructor: adds lookup tables for the option names - - -

    Parameters

    -
      - -
    • - t: -
    • - -
    - - - - - - - - -
    - - - - -
    processArgs ()
    -
    -Simple getOpt wrapper. Adds -version/-V and -help/-h automatically; stops program if there was an error, or if -help or -version was used. - - - - - - - - - -
    - - - - -
    usage ()
    -
    -Emit a usage message. - - - - - - - - - -
    - - - - -
    usageInfo (header, optDesc, pageWidth)
    -
    -Produce usage info for the given options - - -

    Parameters

    -
      - -
    • - header: header string -
    • - -
    • - optDesc: option descriptors -
    • - -
    • - pageWidth: width to format to [78] -
    • - -
    - - - - - - -

    Return value:

    -formatted string - - - -
    - - -
    - - - - -

    Tables

    -
    - -
    _G.Option
    -
    Options table type. - - -Fields -
      - -
    • - name: list of names -
    • - -
    • - desc: description of this option -
    • - -
    • - type: type of argument (if any): Req(uired), Opt(ional) -
    • - -
    • - var: descriptive name for the argument -
    • - -
    - - -
    - - -
    - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/io.html b/src/modules/io.html deleted file mode 100644 index 8f7f7b4..0000000 --- a/src/modules/io.html +++ /dev/null @@ -1,476 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module io

    - -

    Additions to the io module

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    catdir (...)Concatenate two or more directories into a path, removing the trailing slash.
    catfile (...)Concatenate one or more directories and a filename into a path.
    processFiles (f)Process files specified on the command-line.
    readlines (h)Read a file or file handle into a list of lines.
    shell (c)Perform a shell command and return its output.
    slurp (h)Slurp a file handle.
    splitdir (path)Split a directory path into components.
    writelines (h, ...)Write values adding a newline after each.
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    catdir (...)
    -
    -Concatenate two or more directories into a path, removing the trailing slash. - - -

    Parameters

    -
      - -
    • - ...: path components -
    • - -
    - - - - - - -

    Return value:

    -path - - - -
    - - - - -
    catfile (...)
    -
    -Concatenate one or more directories and a filename into a path. - - -

    Parameters

    -
      - -
    • - ...: path components -
    • - -
    - - - - - - -

    Return value:

    -path - - - -
    - - - - -
    processFiles (f)
    -
    -Process files specified on the command-line. If no files given, process io.stdin; in list of files, - means io.stdin.
    FIXME: Make the file list an argument to the function. - - -

    Parameters

    -
      - -
    • - f: function to process files with, which is passed (name, arg_no) -
    • - -
    - - - - - - - - -
    - - - - -
    readlines (h)
    -
    -Read a file or file handle into a list of lines. - - -

    Parameters

    -
      - -
    • - h: file handle or name (default: io.input ()); if h is a handle, the file is closed after reading -
    • - -
    - - - - - - -

    Return value:

    -list of lines - - - -
    - - - - -
    shell (c)
    -
    -Perform a shell command and return its output. - - -

    Parameters

    -
      - -
    • - c: command -
    • - -
    - - - - - - -

    Return value:

    -output, or nil if error - - - -
    - - - - -
    slurp (h)
    -
    -Slurp a file handle. - - -

    Parameters

    -
      - -
    • - h: file handle or name (default: io.input ()) -
    • - -
    - - - - - - -

    Return value:

    -contents of file or handle, or nil if error - - - -
    - - - - -
    splitdir (path)
    -
    -Split a directory path into components. Empty components are retained: the root directory becomes {"", ""}. - - -

    Parameters

    -
      - -
    • - path: path -
    • - -
    - - - - - - -

    Return value:

    -list of path components - - - -
    - - - - -
    writelines (h, ...)
    -
    -Write values adding a newline after each. - - -

    Parameters

    -
      - -
    • - h: file handle (default: io.output () -
    • - -
    • - ...: values to write (as for write) -
    • - -
    - - - - - - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/lcs.html b/src/modules/lcs.html deleted file mode 100644 index 7dc03d2..0000000 --- a/src/modules/lcs.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module lcs

    - -

    Longest Common Subsequence algorithm. After pseudo-code in lecture notes by David Eppstein.

    - - - - - -

    Functions

    - - - - - - - -
    longestCommonSubseq (a, b, s)Find the longest common subsequence of two sequences.
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    longestCommonSubseq (a, b, s)
    -
    -Find the longest common subsequence of two sequences. The sequence objects must have an __append metamethod. This is provided by string_ext for strings, and by list for lists. - - -

    Parameters

    -
      - -
    • - a: first sequence -
    • - -
    • - b: second sequence -
    • - -
    • - s: an empty sequence of the same type, to hold the result -
    • - -
    - - - - - - -

    Return value:

    -the LCS of a and b - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/list.html b/src/modules/list.html deleted file mode 100644 index 002336a..0000000 --- a/src/modules/list.html +++ /dev/null @@ -1,1212 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module list

    - -

    Tables as lists.

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    append (l, x)Append an item to a list.
    compare (l, m)Compare two lists element by element left-to-right
    concat (...)Concatenate lists.
    cons (l, x)Prepend an item to a list.
    depair (ls)Turn a list of pairs into a table.
    elems (l)An iterator over the elements of a list.
    enpair (t)Turn a table into a list of pairs.
    filter (p, l)Filter a list according to a predicate.
    flatten (l)Flatten a list.
    foldl (f, e, l)Fold a binary function through a list left associatively.
    foldr (f, e, l)Fold a binary function through a list right associatively.
    indexKey (f, l)Make an index of a list of tables on a given field
    indexValue (f, l)Copy a list of tables, indexed on a given field
    map (f, l)Map a function over a list.
    mapWith (f, l, ls)Map a function over a list of lists.
    new (l, t)List constructor.
    project (f, l)Project a list of fields from a list of tables.
    relems (l)An iterator over the elements of a list, in reverse.
    rep (l, n)Repeat a list.
    reverse (l)Reverse a list.
    shape (s, l)Shape a list according to a list of dimensions.
    slice (l, from, to)Return a slice of a list.
    tail (l)Return a list with its first element removed.
    transpose (ls)Transpose a list of lists.
    zipWith (f, ls)Zip lists together with a function.
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    append (l, x)
    -
    -Append an item to a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - x: item -
    • - -
    - - - - - - -

    Return value:

    -{l[1], ..., l[#l], x} - - - -
    - - - - -
    compare (l, m)
    -
    -Compare two lists element by element left-to-right - - -

    Parameters

    -
      - -
    • - l: first list -
    • - -
    • - m: second list -
    • - -
    - - - - - - -

    Return value:

    --1 if l is less than m, 0 if they are the same, and 1 if l is greater than m - - - -
    - - - - -
    concat (...)
    -
    -Concatenate lists. - - -

    Parameters

    -
      - -
    • - ...: lists -
    • - -
    - - - - - - -

    Return value:

    -{l1[1], ..., l1[#l1], ..., ln[1], ..., ln[#ln]} - - - -
    - - - - -
    cons (l, x)
    -
    -Prepend an item to a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - x: item -
    • - -
    - - - - - - -

    Return value:

    -{x, unpack (l)} - - - -
    - - - - -
    depair (ls)
    -
    -Turn a list of pairs into a table.
    FIXME: Find a better name. - - -

    Parameters

    -
      - -
    • - ls: list {{i1, v1}, ..., {in, vn}} -
    • - -
    - - - - - - -

    Return value:

    -table {i1=v1, ..., in=vn} - - - -
    - - - - -
    elems (l)
    -
    -An iterator over the elements of a list. - - -

    Parameters

    -
      - -
    • - l: list to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function which returns successive elements of the list - -
    2. the list l as above - -
    3. true - -
    - - - -
    - - - - -
    enpair (t)
    -
    -Turn a table into a list of pairs.
    FIXME: Find a better name. - - -

    Parameters

    -
      - -
    • - t: table {i1=v1, ..., in=vn} -
    • - -
    - - - - - - -

    Return value:

    -list {{i1, v1}, ..., {in, vn}} - - - -
    - - - - -
    filter (p, l)
    -
    -Filter a list according to a predicate. - - -

    Parameters

    -
      - -
    • - p: predicate (function of one argument returning a boolean) -
    • - -
    • - l: list of lists -
    • - -
    - - - - - - -

    Return value:

    -result list containing elements e of l for which p (e) is true - - - -
    - - - - -
    flatten (l)
    -
    -Flatten a list. - - -

    Parameters

    -
      - -
    • - l: list to flatten -
    • - -
    - - - - - - -

    Return value:

    -flattened list - - - -
    - - - - -
    foldl (f, e, l)
    -
    -Fold a binary function through a list left associatively. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - e: element to place in left-most position -
    • - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -result - - - -
    - - - - -
    foldr (f, e, l)
    -
    -Fold a binary function through a list right associatively. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - e: element to place in right-most position -
    • - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -result - - - -
    - - - - -
    indexKey (f, l)
    -
    -Make an index of a list of tables on a given field - - -

    Parameters

    -
      - -
    • - f: field -
    • - -
    • - l: list of tables {t1, ..., tn} -
    • - -
    - - - - - - -

    Return value:

    -index {t1[f]=1, ..., tn[f]=n} - - - -
    - - - - -
    indexValue (f, l)
    -
    -Copy a list of tables, indexed on a given field - - -

    Parameters

    -
      - -
    • - f: field whose value should be used as index -
    • - -
    • - l: list of tables {i1=t1, ..., in=tn} -
    • - -
    - - - - - - -

    Return value:

    -index {t1[f]=t1, ..., tn[f]=tn} - - - -
    - - - - -
    map (f, l)
    -
    -Map a function over a list. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -result list {f (l[1]), ..., f (l[#l])} - - - -
    - - - - -
    mapWith (f, l, ls)
    -
    -Map a function over a list of lists. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - l: -
    • - -
    • - ls: list of lists -
    • - -
    - - - - - - -

    Return value:

    -result list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} - - - -
    - - - - -
    new (l, t)
    -
    -List constructor. Needed in order to use metamethods. - - -

    Parameters

    -
      - -
    • - l: -
    • - -
    • - t: list (as a table) -
    • - -
    - - - - - - -

    Return value:

    -list (with list metamethods) - - - -
    - - - - -
    project (f, l)
    -
    -Project a list of fields from a list of tables. - - -

    Parameters

    -
      - -
    • - f: field to project -
    • - -
    • - l: list of tables -
    • - -
    - - - - - - -

    Return value:

    -list of f fields - - - -
    - - - - -
    relems (l)
    -
    -An iterator over the elements of a list, in reverse. - - -

    Parameters

    -
      - -
    • - l: list to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function which returns precessive elements of the list - -
    2. the list l as above - -
    3. true - -
    - - - -
    - - - - -
    rep (l, n)
    -
    -Repeat a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - n: number of times to repeat -
    • - -
    - - - - - - -

    Return value:

    -n copies of l appended together - - - -
    - - - - -
    reverse (l)
    -
    -Reverse a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -list {l[#l], ..., l[1]} - - - -
    - - - - -
    shape (s, l)
    -
    -Shape a list according to a list of dimensions. Dimensions are given outermost first and items from the original list are distributed breadth first; there may be one 0 indicating an indefinite number. Hence, {0} is a flat list, {1} is a singleton, {2, 0} is a list of two lists, and {0, 2} is a list of pairs.
    Algorithm: turn shape into all positive numbers, calculating the zero if necessary and making sure there is at most one; recursively walk the shape, adding empty tables until the bottom level is reached at which point add table items instead, using a counter to walk the flattened original list.
    - - -

    Parameters

    -
      - -
    • - s: {d1, ..., dn} -
    • - -
    • - l: list to reshape -
    • - -
    - - - - - - -

    Return value:

    -reshaped list FIXME: Use ileaves instead of flatten (needs a while instead of a for in fill function) - - - -
    - - - - -
    slice (l, from, to)
    -
    -Return a slice of a list. (Negative list indices count from the end of the list.) - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - from: start of slice (default: 1) -
    • - -
    • - to: end of slice (default: #l) -
    • - -
    - - - - - - -

    Return value:

    -{l[from], ..., l[to]} - - - -
    - - - - -
    tail (l)
    -
    -Return a list with its first element removed. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -{l[2], ..., l[#l]} - - - -
    - - - - -
    transpose (ls)
    -
    -Transpose a list of lists. This function in Lua is equivalent to zip and unzip in more strongly typed languages. - - -

    Parameters

    -
      - -
    • - ls: {{l1,1, ..., l1,c}, ..., {lr,1, ..., lr,c}} -
    • - -
    - - - - - - -

    Return value:

    -{{l1,1, ..., lr,1}, ..., {l1,c, ..., lr,c}} - - - -
    - - - - -
    zipWith (f, ls)
    -
    -Zip lists together with a function. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - ls: list of lists -
    • - -
    - - - - - - -

    Return value:

    -{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) where N = max {map (function (l) return #l end, ls)} - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/math.html b/src/modules/math.html deleted file mode 100644 index 019911f..0000000 --- a/src/modules/math.html +++ /dev/null @@ -1,282 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module math

    - -

    Additions to the math module.

    - - - - - -

    Functions

    - - - - - - - - - - - - -
    floor (n, p)Extend math.floor to take the number of decimal places.
    round (n, p)Round a number to a given number of decimal places
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    floor (n, p)
    -
    -Extend math.floor to take the number of decimal places. - - -

    Parameters

    -
      - -
    • - n: number -
    • - -
    • - p: number of decimal places to truncate to (default: 0) -
    • - -
    - - - - - - -

    Return value:

    -n truncated to p decimal places - - - -
    - - - - -
    round (n, p)
    -
    -Round a number to a given number of decimal places - - -

    Parameters

    -
      - -
    • - n: number -
    • - -
    • - p: number of decimal places to round to (default: 0) -
    • - -
    - - - - - - -

    Return value:

    -n rounded to p decimal places - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/mbox.html b/src/modules/mbox.html deleted file mode 100644 index 4e5d5ed..0000000 --- a/src/modules/mbox.html +++ /dev/null @@ -1,300 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module mbox

    - -

    mbox parser. Based on code by Diego Nahab.

    - - - - - -

    Functions

    - - - - - - - -
    parse (s)Parse a mailbox into messages.
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    parse (s)
    -
    -Parse a mailbox into messages. - - -

    Parameters

    -
      - -
    • - s: mailbox as a string -
    • - -
    - - - - - - -

    Return value:

    -list of messages, each of form {header = {...}, body = "..."} - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/object.html b/src/modules/object.html deleted file mode 100644 index 6522980..0000000 --- a/src/modules/object.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module object

    - -

    Prototype-based objects

    • Create an object/class:
      • Either, if the _init field is a list:
        • object/Class = prototype {value, ...; field = value, ...}
        • Named values are assigned to the corresponding fields, and unnamed values to the fields given by _init.
      • Or, if the _init field is a function:
        • object/Class = prototype (value, ...)
        • The given values are passed as arguments to the _init function.
      • An object's metatable is itself.
      • Private fields and methods start with "_".
    • Access an object field: object.field
    • Call an object method: object:method (...)
    • Call a class method: Class.method (object, ...)
    • Add a field: object.field = x
    • Add a method: function object:method (...) ... end
    • - - - - - - - - -

      Tables

      - - - - - - - -
      ObjectRoot object
      - - - -
      -
      - - - - - - -

      Tables

      -
      - -
      Object
      -
      Root object - - -Fields -
        - -
      • - _init: constructor method or list of fields to be initialised by the constructor -
      • - -
      • - _clone: object constructor which provides the behaviour for _init documented above -
      • - -
      - - -
      - - -
      - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/package.html b/src/modules/package.html deleted file mode 100644 index ce97e71..0000000 --- a/src/modules/package.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module package

    - -

    - - - - - - - - -

    Tables

    - - - - - - - -
    packageMake named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents).
    - - - -
    -
    - - - - - - -

    Tables

    -
    - -
    package
    -
    Make named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents). - - -Fields -
      - -
    • - dirsep: directory separator -
    • - -
    • - pathsep: path separator -
    • - -
    • - path_mark: string that marks substitution points in a path template -
    • - -
    • - execdir: (Windows only) replaced by the executable's directory in a path -
    • - -
    • - igmark: Mark to ignore all before it when building luaopen_ function name. -
    • - -
    - - -
    - - -
    - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/parser.html b/src/modules/parser.html deleted file mode 100644 index 9c6c08e..0000000 --- a/src/modules/parser.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module parser

    - -

    Parser generator.

    A parser is created by

    p = Parser {grammar}

    and called with

    result = p:parse (start_token, token_list[, from])

    where start_token is the non-terminal at which to start parsing in the grammar, token_list is a list of tokens of the form

    {ty = "token_type", tok = "token_text"}

    and from is the token in the list from which to start (the default value is 1).

    The output of the parser is a tree, each of whose nodes is of the form:

    {ty = symbol, node1 = tree1, node2 = tree2, ... [, list]}

    where each nodei is a symbolic name, and list is the list of trees returned if the corresponding token was a list token.

    A grammar is a table of rules of the form

    non-terminal = {production1, production2, ...}

    plus a special item

    lexemes = Set {"class1", "class2", ...}

    Each production gives a form that a non-terminal may take. A production has the form

    production = {"token1", "token2", ..., [action][,abstract]}

    A production

    • must not start with the non-terminal being defined (it must not be left-recursive)
    • must not be a prefix of a later production in the same non-terminal

    Each token may be

    • a non-terminal, i.e. a token defined by the grammar
      • an optional symbol is indicated by the suffix _opt
      • a list is indicated by the suffix _list, and may be followed by _≤separator-symbol> (default is no separator)
    • a lexeme class
    • a string to match literally

    The parse tree for a literal string or lexeme class is the string that was matched. The parse tree for a non-terminal is a table of the form

    {ty = "non_terminal_name", tree1, tree2, ...}

    where the treei are the parse trees for the corresponding terminals and non-terminals.

    An action is of the form

    action = function (tree, token, pos) ... return tree_ end

    It is passed the parse tree for the current node, the token list, and the current position in the token list, and returns a new parse tree.

    An abstract syntax rule is of the form

    name = {i1, i2, ...}

    where i1, i2, ... are numbers. This results in a parse tree of the form

    {ty = "name"; treei1, treei2, ...}

    If a production has no abstract syntax rule, the result is the parse node for the current node.

    FIXME: Give lexemes as an extra argument to Parser?
    FIXME: Rename second argument to parse method to "tokens"?
    FIXME: Make start_token an optional argument to parse? (swap with token list) and have it default to the first non-terminal?

    - - - - - -

    Functions

    - - - - - - - - - - - - -
    Parser:_init (grammar)Parser constructor
    Parser:parse (start, token, from)Parse a token list.
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    Parser:_init (grammar)
    -
    -Parser constructor - - -

    Parameters

    -
      - -
    • - grammar: parser grammar -
    • - -
    - - - - - - -

    Return value:

    -parser - - - -
    - - - - -
    Parser:parse (start, token, from)
    -
    -Parse a token list. - - -

    Parameters

    -
      - -
    • - start: the token at which to start -
    • - -
    • - token: the list of tokens -
    • - -
    • - from: the index of the token to start from (default: 1) -
    • - -
    - - - - - - -

    Return value:

    -parse tree - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/set.html b/src/modules/set.html deleted file mode 100644 index 90cd4e8..0000000 --- a/src/modules/set.html +++ /dev/null @@ -1,640 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module set

    - -

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    delete (s, e)Delete an element from a set
    difference (s, t)Find the difference of two sets
    equal (s, t)Find whether two sets are equal
    insert (s, e)Insert an element into a set
    intersection (s, t)Find the intersection of two sets
    member (s, e)Say whether an element is in a set
    propersubset (s, t)Find whether one set is a proper subset of another
    subset (s, t)Find whether one set is a subset of another
    symmetric_difference (s, t)Find the symmetric difference of two sets
    union (s, t)Find the union of two sets
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    delete (s, e)
    -
    -Delete an element from a set - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - e: element -
    • - -
    - - - - - - - - -
    - - - - -
    difference (s, t)
    -
    -Find the difference of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -s with elements of t removed - - - -
    - - - - -
    equal (s, t)
    -
    -Find whether two sets are equal - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -true if sets are equal, false otherwise - - - -
    - - - - -
    insert (s, e)
    -
    -Insert an element into a set - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - e: element -
    • - -
    - - - - - - - - -
    - - - - -
    intersection (s, t)
    -
    -Find the intersection of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -set intersection of s and t - - - -
    - - - - -
    member (s, e)
    -
    -Say whether an element is in a set - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - e: element -
    • - -
    - - - - - - -

    Return value:

    -true if e is in set, false otherwise - - - -
    - - - - -
    propersubset (s, t)
    -
    -Find whether one set is a proper subset of another - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -true if s is a proper subset of t, false otherwise - - - -
    - - - - -
    subset (s, t)
    -
    -Find whether one set is a subset of another - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -true if s is a subset of t, false otherwise - - - -
    - - - - -
    symmetric_difference (s, t)
    -
    -Find the symmetric difference of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -elements of s and t that are in s or t but not both - - - -
    - - - - -
    union (s, t)
    -
    -Find the union of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -set union of s and t - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/std.html b/src/modules/std.html deleted file mode 100644 index 907beef..0000000 --- a/src/modules/std.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module std

    - -

    Lua standard library

    • TODO: Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call error, not die; OO vs non-OO (a thorny problem).
    • TODO: Add tests for each function immediately after the function; this also helps to check module dependencies.
    • TODO: pre-compile.

    - - - - - - - - - - -
    -
    - - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/strbuf.html b/src/modules/strbuf.html deleted file mode 100644 index e6b6aca..0000000 --- a/src/modules/strbuf.html +++ /dev/null @@ -1,338 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module strbuf

    - -

    String buffers

    - - - - - -

    Functions

    - - - - - - - - - - - - -
    concat (b, s)Add a string to a buffer
    tostring (b)Convert a buffer to a string
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    concat (b, s)
    -
    -Add a string to a buffer - - -

    Parameters

    -
      - -
    • - b: buffer -
    • - -
    • - s: string to add -
    • - -
    - - - - - - -

    Return value:

    -buffer - - - -
    - - - - -
    tostring (b)
    -
    -Convert a buffer to a string - - -

    Parameters

    -
      - -
    • - b: buffer -
    • - -
    - - - - - - -

    Return value:

    -string - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/string.html b/src/modules/string.html deleted file mode 100644 index 12ebe16..0000000 --- a/src/modules/string.html +++ /dev/null @@ -1,717 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module string

    - -

    Additions to the string module TODO: Pretty printing (use in getopt); see source for details.

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    caps (s)Capitalise each word in a string.
    chomp (s)Remove any final newline from a string.
    escapePattern (s)Escape a string to be used as a pattern
    finds (s, p, init, plain)Do multiple finds on a string.
    ltrim (s, r)Remove leading matter from a string.
    numbertosi (n)Write a number using SI suffixes.
    ordinalSuffix (n)Return the English suffix for an ordinal.
    pad (s, w, p)Justify a string.
    rtrim (s, r)Remove trailing matter from a string.
    split (s, sep)Split a string at a given separator.
    tfind (s, p, init, plain)Do find, returning captures as a list.
    trim (s, r)Remove leading and trailing matter from a string.
    wrap (s, w, ind, ind1)Wrap a string into a paragraph.
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    caps (s)
    -
    -Capitalise each word in a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    - - - - - - -

    Return value:

    -capitalised string - - - -
    - - - - -
    chomp (s)
    -
    -Remove any final newline from a string. - - -

    Parameters

    -
      - -
    • - s: string to process -
    • - -
    - - - - - - -

    Return value:

    -processed string - - - -
    - - - - -
    escapePattern (s)
    -
    -Escape a string to be used as a pattern - - -

    Parameters

    -
      - -
    • - s: string to process @return -
    • - -
    - - - - - - - - -
    - - - - -
    finds (s, p, init, plain)
    -
    -Do multiple finds on a string. - - -

    Parameters

    -
      - -
    • - s: target string -
    • - -
    • - p: pattern -
    • - -
    • - init: start position (default: 1) -
    • - -
    • - plain: inhibit magic characters (default: nil) -
    • - -
    - - - - - - -

    Return value:

    -list of {from, to; capt = {captures}} - - - -
    - - - - -
    ltrim (s, r)
    -
    -Remove leading matter from a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    • - r: leading regex (default: "%s+") -
    • - -
    - - - - - - -

    Return value:

    -string without leading r - - - -
    - - - - -
    numbertosi (n)
    -
    -Write a number using SI suffixes. The number is always written to 3 s.f. - - -

    Parameters

    -
      - -
    • - n: number -
    • - -
    - - - - - - -

    Return value:

    -string - - - -
    - - - - -
    ordinalSuffix (n)
    -
    -Return the English suffix for an ordinal. - - -

    Parameters

    -
      - -
    • - n: number of the day -
    • - -
    - - - - - - -

    Return value:

    -suffix - - - -
    - - - - -
    pad (s, w, p)
    -
    -Justify a string. When the string is longer than w, it is truncated (left or right according to the sign of w). - - -

    Parameters

    -
      - -
    • - s: string to justify -
    • - -
    • - w: width to justify to (-ve means right-justify; +ve means left-justify) -
    • - -
    • - p: string to pad with (default: " ") -
    • - -
    - - - - - - -

    Return value:

    -justified string - - - -
    - - - - -
    rtrim (s, r)
    -
    -Remove trailing matter from a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    • - r: trailing regex (default: "%s+") -
    • - -
    - - - - - - -

    Return value:

    -string without trailing r - - - -
    - - - - -
    split (s, sep)
    -
    -Split a string at a given separator. FIXME: Consider Perl and Python versions. - - -

    Parameters

    -
      - -
    • - s: string to split -
    • - -
    • - sep: separator regex -
    • - -
    - - - - - - -

    Return value:

    -list of strings - - - -
    - - - - -
    tfind (s, p, init, plain)
    -
    -Do find, returning captures as a list. - - -

    Parameters

    -
      - -
    • - s: target string -
    • - -
    • - p: pattern -
    • - -
    • - init: start position (default: 1) -
    • - -
    • - plain: inhibit magic characters (default: nil) -
    • - -
    - - - - - - -

    Return value:

    -start of match, end of match, table of captures - - - -
    - - - - -
    trim (s, r)
    -
    -Remove leading and trailing matter from a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    • - r: leading/trailing regex (default: "%s+") -
    • - -
    - - - - - - -

    Return value:

    -string without leading/trailing r - - - -
    - - - - -
    wrap (s, w, ind, ind1)
    -
    -Wrap a string into a paragraph. - - -

    Parameters

    -
      - -
    • - s: string to wrap -
    • - -
    • - w: width to wrap to (default: 78) -
    • - -
    • - ind: indent (default: 0) -
    • - -
    • - ind1: indent of first line (default: ind) -
    • - -
    - - - - - - -

    Return value:

    -wrapped paragraph - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/table.html b/src/modules/table.html deleted file mode 100644 index f83fba0..0000000 --- a/src/modules/table.html +++ /dev/null @@ -1,578 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module table

    - -

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    clone (t, nometa)Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone).
    clone_rename (map, t)Clone a table, renaming some keys.
    empty (t)Return whether table is empty.
    invert (t)Invert a table.
    keys (t)Make the list of keys of a table.
    merge (t, u)Merge one table into another.
    new (x, t)Make a table with a default value for unset keys.
    size (t)Find the number of elements in a table.
    sort (t, c)Make table.sort return its result.
    values (t)Make the list of values of a table.
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    clone (t, nometa)
    -
    -Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone). - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - nometa: if non-nil don't copy metatable -
    • - -
    - - - - - - -

    Return value:

    -copy of table - - - -
    - - - - -
    clone_rename (map, t)
    -
    -Clone a table, renaming some keys. - - -

    Parameters

    -
      - -
    • - map: table {old_key=new_key, ...} -
    • - -
    • - t: table to copy -
    • - -
    - - - - - - -

    Return value:

    -copy of table - - - -
    - - - - -
    empty (t)
    -
    -Return whether table is empty. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -true if empty or false otherwise - - - -
    - - - - -
    invert (t)
    -
    -Invert a table. - - -

    Parameters

    -
      - -
    • - t: table {i=v, ...} -
    • - -
    - - - - - - -

    Return value:

    -inverted table {v=i, ...} - - - -
    - - - - -
    keys (t)
    -
    -Make the list of keys of a table. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -list of keys - - - -
    - - - - -
    merge (t, u)
    -
    -Merge one table into another. u is merged into t. - - -

    Parameters

    -
      - -
    • - t: first table -
    • - -
    • - u: second table -
    • - -
    - - - - - - -

    Return value:

    -first table - - - -
    - - - - -
    new (x, t)
    -
    -Make a table with a default value for unset keys. - - -

    Parameters

    -
      - -
    • - x: default entry value (default: nil) -
    • - -
    • - t: initial table (default: {}) -
    • - -
    - - - - - - -

    Return value:

    -table whose unset elements are x - - - -
    - - - - -
    size (t)
    -
    -Find the number of elements in a table. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -number of elements in t - - - -
    - - - - -
    sort (t, c)
    -
    -Make table.sort return its result. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - c: comparator function -
    • - -
    - - - - - - -

    Return value:

    -sorted table - - - -
    - - - - -
    values (t)
    -
    -Make the list of values of a table. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -list of values - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/modules/tree.html b/src/modules/tree.html deleted file mode 100644 index 543f3b6..0000000 --- a/src/modules/tree.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module tree

    - -

    Tables as trees.

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - -
    clone (t, nometa)Make a deep copy of a tree, including any metatables
    metatable.__index (tr, i)Tree __index metamethod.
    metatable.__newindex (tr, i, v)Tree __newindex metamethod.
    new (t)Make a table into a tree
    - - - - - - -
    -
    - - - -

    Functions

    -
    - - - -
    clone (t, nometa)
    -
    -Make a deep copy of a tree, including any metatables - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - nometa: if non-nil don't copy metatables -
    • - -
    - - - - - - -

    Return value:

    -copy of table - - - -
    - - - - -
    metatable.__index (tr, i)
    -
    -Tree __index metamethod. - - -

    Parameters

    -
      - -
    • - tr: tree -
    • - -
    • - i: non-table, or list of keys {i1 ... in} -
    • - -
    - - - - - - -

    Return value:

    -tr[i]...[in] if i is a table, or tr[i] otherwise - - - -
    - - - - -
    metatable.__newindex (tr, i, v)
    -
    -Tree __newindex metamethod. Sets tr[i1]...[in] = v if i is a table, or tr[i] = v otherwise - - -

    Parameters

    -
      - -
    • - tr: tree -
    • - -
    • - i: non-table, or list of keys {i1 ... in} -
    • - -
    • - v: value -
    • - -
    - - - - - - - - -
    - - - - -
    new (t)
    -
    -Make a table into a tree - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -tree - - - -
    - - -
    - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/src/parser.lua b/src/parser.lua deleted file mode 100644 index d93afb4..0000000 --- a/src/parser.lua +++ /dev/null @@ -1,267 +0,0 @@ ---- Parser generator. ---

    A parser is created by

    ---
    ---

    p = Parser {grammar}

    ---
    ---

    and called with

    ---
    ---

    result = p:parse (start_token, token_list[, --- from])

    ---
    ---

    where start_token is the non-terminal at which to start parsing --- in the grammar, token_list is a list of tokens of the form

    ---
    ---

    {ty = "token_type", tok = "token_text"}

    ---
    ---

    and from is the token in the list from which to start (the --- default value is 1).

    ---

    The output of the parser is a tree, each of whose --- nodes is of the form:

    ---
    ---

    {ty = symbol, node1 = tree1, --- node2 = tree2, ... [, list]}

    ---
    ---

    where each nodei is a symbolic name, and --- list is the list of trees returned if the corresponding token was a --- list token.

    ---

    A grammar is a table of rules of the form

    ---
    ---

    non-terminal = {production1, --- production2, ...}

    ---
    ---

    plus a special item

    ---
    ---

    lexemes = set.new {"class1", "class2", --- ...}

    ---
    ---

    Each production gives a form that a non-terminal may take. A --- production has the form

    ---
    ---

    production = {"token1", "token2", --- ..., [action][,abstract]}

    ---
    ---

    A production

    ---
      ---
    • must not start with the non-terminal being defined (it must not --- be left-recursive)
    • ---
    • must not be a prefix of a later production in the same --- non-terminal
    • ---
    ---

    Each token may be

    ---
      ---
    • a non-terminal, i.e. a token defined by the grammar
    • ---
        ---
      • an optional symbol is indicated by the suffix _opt
      • ---
      • a list is indicated by the suffix _list, and may be --- followed by _≤separator-symbol> (default is no separator)
      • ---
      ---
    • a lexeme class
    • ---
    • a string to match literally
    • ---
    ---

    The parse tree for a literal string or lexeme class is the string --- that was matched. The parse tree for a non-terminal is a table of --- the form

    ---
    ---

    {ty = "non_terminal_name", tree1, --- tree2, ...}

    ---
    ---

    where the treei are the parse trees for the --- corresponding terminals and non-terminals.

    ---

    An action is of the form

    ---
    ---

    action = function (tree, token, pos) ... return tree_ --- end

    ---
    ---

    It is passed the parse tree for the current node, the token list, --- and the current position in the token list, and returns a new parse --- tree.

    ---

    An abstract syntax rule is of the form

    ---
    ---

    name = {i1, i2, ...}

    ---
    ---

    where i1, i2, --- ... are numbers. This results in a parse tree of the form

    ---
    ---

    {ty = "name"; treei1, --- treei2, ...}

    ---
    ---

    If a production has no abstract syntax rule, the result is the --- parse node for the current node.

    ---

    FIXME: Give lexemes as an extra argument to Parser? ---
    FIXME: Rename second argument to parse method to "tokens"? ---
    FIXME: Make start_token an optional argument to parse? (swap with --- token list) and have it default to the first non-terminal?

    - -local Object = require "object" - - -local Parser = Object {_init = {"grammar"}} - - ---- Parser constructor --- @param grammar parser grammar --- @return parser -function Parser:_init (grammar) - local init = table.clone_rename ({"grammar"}, grammar) - -- Reformat the abstract syntax rules - for rname, rule in pairs (init.grammar) do - if name ~= "lexemes" then - for pnum, prod in ipairs (rule) do - local abstract - for i, v in pairs (prod) do - if type (i) == "string" and i ~= "action" then - if abstract then - die ("more than one abstract rule for " .. rname .. "." - .. tostring (pnum)) - else - if type (v) ~= "table" then - die ("bad abstract syntax rule of type " .. type (v)) - end - abstract = {ty = i, template = v} - prod[i] = nil - end - end - end - if abstract then - prod.abstract = abstract - end - end - end - end - return table.merge (self, init) -end - ---- Parse a token list. --- @param start the token at which to start --- @param token the list of tokens --- @param from the index of the token to start from (default: 1) --- @return parse tree -function Parser:parse (start, token, from) - - local grammar = self.grammar -- for consistency and brevity - local rule, symbol -- functions called before they are defined - - -- Try to parse an optional symbol. - -- @param sym the symbol being tried - -- @param from the index of the token to start from - -- @return the resulting parse tree, or false if empty - -- @return the index of the first unused token, or false to - -- indicate failure - local function optional (sym, from) - local tree, to = symbol (sym, from) - if to then - return tree, to - else - return false, from - end - end - - -- Try to parse a list of symbols. - -- @param sym the symbol being tried - -- @param sep the list separator - -- @param from the index of the token to start from - -- @return the resulting parse tree, or false if empty - -- @return the index of the first unused token, or false to - -- indicate failure - local function list (sym, sep, from) - local tree, to - tree, from = symbol (sym, from) - local list = {tree} - if from == false then - return list, false - end - to = from - repeat - if sep ~= "" then - tree, from = symbol (sep, from) - end - if from then - tree, from = symbol (sym, from) - if from then - table.insert (list, tree) - to = from - end - end - until from == false - return list, to - end - - -- Try to parse a given symbol. - -- @param sym the symbol being tried - -- @param from the index of the token to start from - -- @return tree the resulting parse tree, or false if empty - -- @return the index of the first unused token, or false to - -- indicate failure - symbol = function (sym, from) -- declared at the top - if string.sub (sym, -4, -1) == "_opt" then -- optional symbol - return optional (string.sub (sym, 1, -5), from) - elseif string.find (sym, "_list.-$") then -- list - local _, _, subsym, sep = string.find (sym, "^(.*)_list_?(.-)$") - return list (subsym, sep, from) - elseif grammar[sym] then -- non-terminal - return rule (sym, from) - elseif token[from] and -- not end of token list - ((grammar.lexemes:member (sym) and sym == token[from].ty) or -- lexeme - sym == token[from].tok) -- literal terminal - then - return token[from].tok, from + 1 -- advance to next token - else - return false, false - end - end - - -- Try a production. - -- @param name the name of the current rule - -- @param prod the production (list of symbols) being tried - -- @param from the index of the token to start from - -- @return the parse tree (incomplete if to is false) - -- @return the index of the first unused token, or false to - -- indicate failure - local function production (name, prod, from) - local tree = {ty = name} - local to = from - for prod in _G.list.elems (prod) do - local sym - sym, to = symbol (prod, to) - if to then - table.insert (tree, sym) - else - return tree, false - end - end - if prod.action then - tree = prod.action (tree, token, to) - end - if prod.abstract then - local ntree = {} - ntree.ty = prod.abstract.ty - for i, n in pairs (prod.abstract.template) do - ntree[i] = tree[n] - end - tree = ntree - end - return tree, to - end - - -- Parse according to a particular rule. - -- @param name the name of the rule to try - -- @param from the index of the token to start from - -- @return parse tree - -- @return the index of the first unused token, or false to - -- indicate failure - rule = function (name, from) -- declared at the top - local alt = grammar[name] - local tree, to - for alt in _G.list.elems (alt) do - tree, to = production (name, alt, from) - if to then - return tree, to - end - end - return tree, false - end - - return rule (start, 1, from or 1) -end - -return Parser diff --git a/src/std.lua b/src/std.lua deleted file mode 100644 index a6822ab..0000000 --- a/src/std.lua +++ /dev/null @@ -1,20 +0,0 @@ ---- Lua standard library ---
      ---
    • TODO: Write a style guide (indenting/wrapping, capitalisation, --- function and variable names); library functions should call --- error, not die; OO vs non-OO (a thorny problem).
    • ---
    • TODO: Add tests for each function immediately after the function; --- this also helps to check module dependencies.
    • ---
    • TODO: pre-compile.
    • ---
    -local version = "General Lua libraries / 34.1" - -for _, m in ipairs (require "modules") do - _G[m] = require (m) -end - -local M = { - version = version, -} - -return M diff --git a/src/std.lua.in b/src/std.lua.in deleted file mode 100644 index 312bce9..0000000 --- a/src/std.lua.in +++ /dev/null @@ -1,20 +0,0 @@ ---- Lua standard library ---
      ---
    • TODO: Write a style guide (indenting/wrapping, capitalisation, --- function and variable names); library functions should call --- error, not die; OO vs non-OO (a thorny problem).
    • ---
    • TODO: Add tests for each function immediately after the function; --- this also helps to check module dependencies.
    • ---
    • TODO: pre-compile.
    • ---
    -local version = "General Lua libraries / @VERSION@" - -for _, m in ipairs (require "modules") do - _G[m] = require (m) -end - -local M = { - version = version, -} - -return M diff --git a/src/xml.lua b/src/xml.lua deleted file mode 100644 index 14a2203..0000000 --- a/src/xml.lua +++ /dev/null @@ -1,75 +0,0 @@ --- XML extensions to string module. --- @class module --- @name xml - -require "base" -require "string_ext" - - ---- Write a table as XML. --- The input format is assumed to be that output by luaexpat. --- @param t table to print. --- In each element, tag is its name, attr is the table of attributes, --- and the sub-elements are held in the integer keys --- @param indent indent between levels (default: "\t") --- @param spacing space before every line --- @returns XML string -function string.writeXML (t, indent, spacing) - indent = indent or "\t" - spacing = spacing or "" - return render (t, - function (x) - spacing = spacing .. indent - if x.tag then - local s = "<" .. x.tag - if type (x.attr) == "table" then - for i, v in pairs (x.attr) do - if type (i) ~= "number" then - -- luaexpat gives names of attributes in list elements - s = s .. " " .. tostring (i) .. "=" .. string.format ("%q", tostring (v)) - end - end - end - if #x == 0 then - s = s .. " /" - end - s = s .. ">" - return s - end - return "" - end, - function (x) - spacing = string.gsub (spacing, indent .. "$", "") - if x.tag and #x > 0 then - return spacing .. "" - end - return "" - end, - function (s) - s = tostring (s) - s = string.gsub (s, "&([%S]+)", - function (s) - if not string.match (s, "^#?%w+;") then - return "&" .. s - else - return "&" .. s - end - end) - s = string.gsub (s, "<", "<") - s = string.gsub (s, ">", ">") - return s - end, - function (x, i, v, is, vs) - local s = "" - if type (i) == "number" then - s = spacing .. vs - end - return s - end, - function (_, i, _, j) - if type (i) == "number" or type (j) == "number" then - return "\n" - end - return "" - end) -end diff --git a/std/base.lua b/std/base.lua new file mode 100644 index 0000000..d8a4a15 --- /dev/null +++ b/std/base.lua @@ -0,0 +1,291 @@ +--- Adds to the existing global functions +module ("base", package.seeall) + +--- Functional forms of infix operators. +-- Defined here so that other modules can write to it. +-- @class table +-- @name _G.op +_G.op = {} + +local table = require "std.table_ext" +--local list = require "std.list" +--require "std.io_ext" FIXME: allow loops +local strbuf = require "std.strbuf" + + +--- Return given metamethod, if any, or nil. +-- @param x object to get metamethod of +-- @param n name of metamethod to get +-- @return metamethod function or nil if no metamethod or not a +-- function +function _G.metamethod (x, n) + local _, m = pcall (function (x) + return getmetatable (x)[n] + end, + x) + if type (m) ~= "function" then + m = nil + end + return m +end + +--- Turn an object into a table according to __totable metamethod. +-- @param x object to turn into a table +-- @return table or nil +function _G.totable (x) + local m = metamethod (x, "__totable") + if m then + return m (x) + elseif type (x) == "table" then + return x + else + return nil + end +end + +--- Identity function. +-- @param ... +-- @return the arguments passed to the function +function _G.id (...) + return ... +end + +--- Turn a tuple into a list. +-- @param ... tuple +-- @return list +function _G.pack (...) + return {...} +end + +--- Partially apply a function. +-- @param f function to apply partially +-- @param ... arguments to bind +-- @return function with ai already bound +function _G.bind (f, ...) + local fix = {...} + return function (...) + return f (unpack (list.concat (fix, {...}))) + end +end + +--- Curry a function. +-- @param f function to curry +-- @param n number of arguments +-- @return curried version of f +function _G.curry (f, n) + if n <= 1 then + return f + else + return function (x) + return curry (bind (f, x), n - 1) + end + end +end + +--- Compose functions. +-- @param f1...fn functions to compose +-- @return composition of f1 ... fn +function _G.compose (...) + local arg = {...} + local fns, n = arg, #arg + return function (...) + local arg = {...} + for i = n, 1, -1 do + arg = {fns[i] (unpack (arg))} + end + return unpack (arg) + end +end + +--- Memoize a function, by wrapping it in a functable. +-- @param fn function that returns a single result +-- @return memoized function +function _G.memoize (fn) + return setmetatable ({}, { + __call = function (self, ...) + local k = tostring ({...}) + local v = self[k] + if v == nil then + v = fn (...) + self[k] = v + end + return v + end + }) +end + +--- Evaluate a string. +-- @param s string +-- @return value of string +function _G.eval (s) + return loadstring ("return " .. s)() +end + +--- An iterator like ipairs, but in reverse. +-- @param t table to iterate over +-- @return iterator function +-- @return the table, as above +-- @return #t + 1 +function _G.ripairs (t) + return function (t, n) + n = n - 1 + if n > 0 then + return n, t[n] + end + end, + t, #t + 1 +end + +--- +-- @class function +-- @name tree_Iterator +-- @param n current node +-- @return type ("leaf", "branch" (pre-order) or "join" (post-order)) +-- @return path to node ({i1...ik}) +-- @return node +local function _nodes (it, tr) + local p = {} + local function visit (n) + if type (n) == "table" then + coroutine.yield ("branch", p, n) + for i, v in it (n) do + table.insert (p, i) + visit (v) + table.remove (p) + end + coroutine.yield ("join", p, n) + else + coroutine.yield ("leaf", p, n) + end + end + return coroutine.wrap (visit), tr +end + +--- Tree iterator. +-- @see tree_Iterator +-- @param tr tree to iterate over +-- @return iterator function +-- @return the tree, as above +function _G.nodes (tr) + return _nodes (pairs, tr) +end + +--- Tree iterator over numbered nodes, in order. +-- @see tree_Iterator +-- @param tr tree to iterate over +-- @return iterator function +-- @return the tree, as above +function _G.inodes (tr) + return _nodes (ipairs, tr) +end + +--- Collect the results of an iterator. +-- @param i iterator +-- @return results of running the iterator on its arguments +function _G.collect (i, ...) + local t = {} + for e in i (...) do + table.insert (t, e) + end + return t +end + +--- Map a function over an iterator. +-- @param f function +-- @param i iterator +-- @return result table +function _G.map (f, i, ...) + local t = {} + for e in i (...) do + local r = f (e) + if r then + table.insert (t, r) + end + end + return t +end + +--- Filter an iterator with a predicate. +-- @param p predicate +-- @param i iterator +-- @return result table containing elements e for which p (e) +function _G.filter (p, i, ...) + local t = {} + for e in i (...) do + if p (e) then + table.insert (t, e) + end + end + return t +end + +--- Fold a binary function into an iterator. +-- @param f function +-- @param d initial first argument +-- @param i iterator +-- @return result +function _G.fold (f, d, i, ...) + local r = d + for e in i (...) do + r = f (r, e) + end + return r +end + +--- Give warning with the name of program and file (if any). +-- @param ... arguments for format +function _G.warn (...) + if prog.name then + io.stderr:write (prog.name .. ":") + end + if prog.file then + io.stderr:write (prog.file .. ":") + end + if prog.line then + io.stderr:write (tostring (prog.line) .. ":") + end + if prog.name or prog.file or prog.line then + io.stderr:write (" ") + end + io.writelines (io.stderr, string.format (...)) +end + +--- Die with error. +-- @param ... arguments for format +function _G.die (...) + warn (...) + error () +end + +-- Function forms of operators. +-- FIXME: Make these visible in LuaDoc (also list.concat in list) +_G.op["[]"] = function (t, s) + return t[s] +end +_G.op["+"] = function (a, b) + return a + b +end +_G.op["-"] = function (a, b) + return a - b +end +_G.op["*"] = function (a, b) + return a * b +end +_G.op["/"] = function (a, b) + return a / b +end +_G.op["and"] = function (a, b) + return a and b +end +_G.op["or"] = function (a, b) + return a or b +end +_G.op["not"] = function (a) + return not a +end +_G.op["=="] = function (a, b) + return a == b +end +_G.op["~="] = function (a, b) + return a ~= b +end diff --git a/src/debug_ext.lua b/std/debug_ext.lua similarity index 71% rename from src/debug_ext.lua rename to std/debug_ext.lua index c2d5dfd..9b20f24 100644 --- a/src/debug_ext.lua +++ b/std/debug_ext.lua @@ -1,9 +1,8 @@ --- Additions to the debug module -module ("debug", package.seeall) -require "debug_init" -require "io_ext" -require "string_ext" +local init = require "std.debug_init" +local io = require "std.io_ext" +local string = require "std.string_ext" --- To activate debugging set _DEBUG either to any true value -- (equivalent to {level = 1}), or as documented below. @@ -17,32 +16,21 @@ require "string_ext" --- Print a debugging message -- @param n debugging level, defaults to 1 -- @param ... objects to print (as for print) -function say (n, ...) +local function say (n, ...) local level = 1 local arg = {n, ...} if type (arg[1]) == "number" then level = arg[1] table.remove (arg, 1) end - if _DEBUG and - ((type (_DEBUG) == "table" and type (_DEBUG.level) == "number" and - _DEBUG.level >= level) + if init._DEBUG and + ((type (init._DEBUG) == "table" and type (init._DEBUG.level) == "number" and + init._DEBUG.level >= level) or level <= 1) then io.writelines (io.stderr, table.concat (list.map (tostring, arg), "\t")) end end ---- --- The global function debug is an abbreviation for --- debug.say (1, ...) --- @class function --- @name debug --- @see say -getmetatable (_M).__call = - function (self, ...) - say (1, ...) - end - --- Trace function calls -- Use as debug.sethook (trace, "cr"), which is done automatically -- when _DEBUG.call is set. @@ -51,8 +39,8 @@ getmetatable (_M).__call = -- @name trace -- @param event event causing the call local level = 0 -function trace (event) - local t = getinfo (3) +local function trace (event) + local t = debug.getinfo (3) local s = " >>> " .. string.rep (" ", level) if t ~= nil and t.currentline >= 0 then s = s .. t.short_src .. ":" .. t.currentline .. " " @@ -78,7 +66,30 @@ function trace (event) io.writelines (io.stderr, s) end --- Set hooks according to _DEBUG -if type (_DEBUG) == "table" and _DEBUG.call then - sethook (trace, "cr") +-- Set hooks according to init._DEBUG +if type (init._DEBUG) == "table" and init._DEBUG.call then + debug.sethook (trace, "cr") +end + +local M = { + say = say, + trace = trace, +} + +for k, v in pairs (debug) do + M[k] = M[k] or v end + +--- +-- The global function debug is an abbreviation for +-- debug.say (1, ...) +-- @class function +-- @name debug +-- @see say +local metatable = { + __call = function (self, ...) + say (1, ...) + end, +} + +return setmetatable (M, metatable) diff --git a/std/debug_init.lua b/std/debug_init.lua new file mode 100644 index 0000000..f008777 --- /dev/null +++ b/std/debug_init.lua @@ -0,0 +1,10 @@ +-- Debugging is on by default +local M = { + _DEBUG = true, +} + +if _G._DEBUG ~= nil then + M._DEBUG = _G._DEBUG +end + +return M diff --git a/src/files/base.html b/std/files/base.html similarity index 58% rename from src/files/base.html rename to std/files/base.html index 8e08905..13c0317 100644 --- a/src/files/base.html +++ b/std/files/base.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -61,10 +49,6 @@

    Files

  • base.lua
  • -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -73,10 +57,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -85,10 +65,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -97,10 +73,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -173,11 +133,6 @@

    File base.lua

    Functions

    - - - - - @@ -223,21 +178,11 @@

    Functions

    - - - - - - - - - - @@ -263,36 +208,11 @@

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - @@ -303,31 +223,6 @@

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - @@ -361,43 +256,6 @@

    Functions

    -
    _G.assert (v, f, ...)
    -
    -Extend to allow formatted arguments. - - -

    Parameters

    -
      - -
    • - v: value to assert -
    • - -
    • - f: format -
    • - -
    • - ...: arguments to format -
    • - -
    - - - - - - -

    Return value:

    -value - - - -
    - - - -
    _G.bind (f, ...)
    Partially apply a function. @@ -692,41 +550,6 @@

    Return value:

    -
    _G.ileaves (tr)
    -
    -Tree iterator which returns just numbered leaves, in order. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -
    - - - -
    _G.inodes (tr)
    Tree iterator over numbered nodes, in order. @@ -771,41 +594,6 @@

    See also:

    -
    _G.leaves (tr)
    -
    -Tree iterator which returns just leaves. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -
    - - - -
    _G.map (f, i, ...)
    Map a function over an iterator. @@ -973,188 +761,6 @@

    Return value:

    -
    - - - - -
    _G.pickle (x)
    -
    -Convert a value to a string. The string can be passed to dostring to retrieve the value.
    TODO: Make it work for recursive tables. - - -

    Parameters

    -
      - -
    • - x: object to pickle -
    • - -
    - - - - - - -

    Return value:

    -string such that eval (s) is the same value as x - - - -
    - - - - -
    _G.prettytostring (t, indent, spacing)
    -
    -Pretty-print a table. - - -

    Parameters

    -
      - -
    • - t: table to print -
    • - -
    • - indent: indent between levels ["\t"] -
    • - -
    • - spacing: space before every line -
    • - -
    - - - - - - -

    Return value:

    -pretty-printed string - - - -
    - - - - -
    _G.render (x, open, close, elem, pair, sep, roots)
    -
    -Turn tables into strings with recursion detection. N.B. Functions calling render should not recurse, or recursion detection will not work. - - -

    Parameters

    -
      - -
    • - x: object to convert to string -
    • - -
    • - open: open table renderer -
    • - -
    • - close: close table renderer -
    • - -
    • - elem: element renderer -
    • - -
    • - pair: pair renderer -
    • - -
    • - sep: separator renderer -
    • - -
    • - roots: -
    • - -
    - - - - - - -

    Return value:

    -string representation - - - -

    See also:

    - - -
    - - - - -
    _G.require_version (module, min, too_big, pattern)
    -
    -Require a module with a particular version - - -

    Parameters

    -
      - -
    • - module: module to require -
    • - -
    • - min: lowest acceptable version (default: any) -
    • - -
    • - too_big: lowest version that is too big (default: none) -
    • - -
    • - pattern: -
    • - -
    - - - - - - - -
    @@ -1197,35 +803,6 @@

    Return values:

    -
    _G.tostring (x)
    -
    -Extend tostring to work better on tables. The original tostring is available as _tostring. - - -

    Parameters

    -
      - -
    • - x: object to convert to string -
    • - -
    - - - - - - -

    Return value:

    -string representation - - - -
    - - - -
    _G.totable (x)
    Turn an object into a table according to __totable metamethod. @@ -1276,183 +853,6 @@

    Parameters

    -
    - - - - -
    render_CloseRenderer (t)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -close table string - - - -
    - - - - -
    render_ElementRenderer (e)
    -
    - - - -

    Parameters

    -
      - -
    • - e: element -
    • - -
    - - - - - - -

    Return value:

    -element string - - - -
    - - - - -
    render_OpenRenderer (t)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -open table string - - - -
    - - - - -
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - i: index -
    • - -
    • - v: value -
    • - -
    • - is: index string -
    • - -
    • - vs: value string -
    • - -
    - - - - - - -

    Return value:

    -element string - - - -
    - - - - -
    render_SeparatorRenderer (t, i, v, j, w)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - i: preceding index (nil on first call) -
    • - -
    • - v: preceding value (nil on first call) -
    • - -
    • - j: following index (nil on last call) -
    • - -
    • - w: following value (nil on last call) -
    • - -
    - - - - - - -

    Return value:

    -separator string - - -
    diff --git a/src/files/debug_ext.html b/std/files/debug_ext.html similarity index 87% rename from src/files/debug_ext.html rename to std/files/debug_ext.html index a73f8c6..d1860db 100644 --- a/src/files/debug_ext.html +++ b/std/files/debug_ext.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,20 +51,12 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • debug_init.lua
  • -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -85,10 +65,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -97,10 +73,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -163,8 +123,6 @@

    Files

    File debug_ext.lua

    -

    Additions to the debug module

    - diff --git a/src/files/debug_init.html b/std/files/debug_init.html similarity index 79% rename from src/files/debug_init.html rename to std/files/debug_init.html index 7ff4514..be1fb79 100644 --- a/src/files/debug_init.html +++ b/std/files/debug_init.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,20 +51,12 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • debug_init.lua
  • -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -85,10 +65,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -97,10 +73,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/getopt.html b/std/files/getopt.html similarity index 89% rename from src/files/getopt.html rename to std/files/getopt.html index 707082b..aa320fc 100644 --- a/src/files/getopt.html +++ b/std/files/getopt.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,20 +59,12 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • io_ext.lua
  • -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -97,10 +73,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/io_ext.html b/std/files/io_ext.html similarity index 88% rename from src/files/io_ext.html rename to std/files/io_ext.html index f8de140..0b66749 100644 --- a/src/files/io_ext.html +++ b/std/files/io_ext.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,20 +59,12 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • io_ext.lua
  • -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -97,10 +73,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -163,8 +123,6 @@

    Files

    File io_ext.lua

    -

    Additions to the io module

    - @@ -184,7 +142,7 @@

    Functions

    - + @@ -289,7 +247,7 @@

    Return value:

    -
    processFiles (f)
    +
    process_files (f)
    Process files specified on the command-line. If no files given, process io.stdin; in list of files, - means io.stdin.
    FIXME: Make the file list an argument to the function. diff --git a/src/files/list.html b/std/files/list.html similarity index 94% rename from src/files/list.html rename to std/files/list.html index f0071a5..19c78c8 100644 --- a/src/files/list.html +++ b/std/files/list.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,20 +67,12 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • math_ext.lua
  • -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -226,6 +186,11 @@

    Functions

    + + + + + @@ -236,6 +201,11 @@

    Functions

    + + + + + @@ -673,6 +643,41 @@

    Return value:

    +
    ileaves (tr)
    +
    +Tree iterator which returns just numbered leaves, in order. + + +

    Parameters

    +
      + +
    • + tr: tree to iterate over +
    • + +
    + + + + + + +

    Return values:

    +
      + +
    1. iterator function + +
    2. the tree, as above + +
    + + + +
    + + + +
    indexKey (f, l)
    Make an index of a list of tables on a given field @@ -739,6 +744,41 @@

    Return value:

    +
    leaves (tr)
    +
    +Tree iterator which returns just leaves. + + +

    Parameters

    +
      + +
    • + tr: tree to iterate over +
    • + +
    + + + + + + +

    Return values:

    +
      + +
    1. iterator function + +
    2. the tree, as above + +
    + + + +
    + + + +
    map (f, l)
    Map a function over a list. diff --git a/src/files/math_ext.html b/std/files/math_ext.html similarity index 84% rename from src/files/math_ext.html rename to std/files/math_ext.html index 2c4e978..2a36550 100644 --- a/src/files/math_ext.html +++ b/std/files/math_ext.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,20 +67,12 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • math_ext.lua
  • -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -163,8 +123,6 @@

    Files

    File math_ext.lua

    -

    Additions to the math module.

    - diff --git a/src/files/modules.html b/std/files/modules.html similarity index 79% rename from src/files/modules.html rename to std/files/modules.html index 8bfa7b5..2c2d73e 100644 --- a/src/files/modules.html +++ b/std/files/modules.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua
  • -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/object.html b/std/files/object.html similarity index 82% rename from src/files/object.html rename to std/files/object.html index bd86c9d..fd5c9a1 100644 --- a/src/files/object.html +++ b/std/files/object.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/package_ext.html b/std/files/package_ext.html similarity index 84% rename from src/files/package_ext.html rename to std/files/package_ext.html index edca151..31f307e 100644 --- a/src/files/package_ext.html +++ b/std/files/package_ext.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

  • package_ext.lua
  • -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/set.html b/std/files/set.html similarity index 92% rename from src/files/set.html rename to std/files/set.html index 7f684e9..e9f4c08 100644 --- a/src/files/set.html +++ b/std/files/set.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -115,16 +87,8 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/strbuf.html b/std/files/strbuf.html similarity index 84% rename from src/files/strbuf.html rename to std/files/strbuf.html index 7075e99..6affbaf 100644 --- a/src/files/strbuf.html +++ b/std/files/strbuf.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -115,18 +87,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua
  • -
  • - xml.lua -
  • - diff --git a/src/files/strict.html b/std/files/strict.html similarity index 79% rename from src/files/strict.html rename to std/files/strict.html index 208054b..9550e95 100644 --- a/src/files/strict.html +++ b/std/files/strict.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -115,18 +87,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/string_ext.html b/std/files/string_ext.html similarity index 60% rename from src/files/string_ext.html rename to std/files/string_ext.html index daa78d7..570fb18 100644 --- a/src/files/string_ext.html +++ b/std/files/string_ext.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -115,18 +87,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -211,6 +171,51 @@

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -226,6 +231,11 @@

    Functions

    + + + + + @@ -502,6 +512,365 @@

    Return value:

    + + + + + +
    pickle (x)
    +
    +Convert a value to a string. The string can be passed to dostring to retrieve the value.
    TODO: Make it work for recursive tables. + + +

    Parameters

    +
      + +
    • + x: object to pickle +
    • + +
    + + + + + + +

    Return value:

    +string such that eval (s) is the same value as x + + + +
    + + + + +
    prettytostring (t, indent, spacing)
    +
    +Pretty-print a table. + + +

    Parameters

    +
      + +
    • + t: table to print +
    • + +
    • + indent: indent between levels ["\t"] +
    • + +
    • + spacing: space before every line +
    • + +
    + + + + + + +

    Return value:

    +pretty-printed string + + + +
    + + + + +
    render (x, open, close, elem, pair, sep, roots)
    +
    +Turn tables into strings with recursion detection. N.B. Functions calling render should not recurse, or recursion detection will not work. + + +

    Parameters

    +
      + +
    • + x: object to convert to string +
    • + +
    • + open: open table renderer +
    • + +
    • + close: close table renderer +
    • + +
    • + elem: element renderer +
    • + +
    • + pair: pair renderer +
    • + +
    • + sep: separator renderer +
    • + +
    • + roots: +
    • + +
    + + + + + + +

    Return value:

    +string representation + + + +

    See also:

    + + +
    + + + + +
    render_CloseRenderer (t)
    +
    + + + +

    Parameters

    +
      + +
    • + t: table +
    • + +
    + + + + + + +

    Return value:

    +close table string + + + +
    + + + + +
    render_ElementRenderer (e)
    +
    + + + +

    Parameters

    +
      + +
    • + e: element +
    • + +
    + + + + + + +

    Return value:

    +element string + + + +
    + + + + +
    render_OpenRenderer (t)
    +
    + + + +

    Parameters

    +
      + +
    • + t: table +
    • + +
    + + + + + + +

    Return value:

    +open table string + + + +
    + + + + +
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    +
    + + + +

    Parameters

    +
      + +
    • + t: table +
    • + +
    • + i: index +
    • + +
    • + v: value +
    • + +
    • + is: index string +
    • + +
    • + vs: value string +
    • + +
    + + + + + + +

    Return value:

    +element string + + + +
    + + + + +
    render_SeparatorRenderer (t, i, v, j, w)
    +
    + + + +

    Parameters

    +
      + +
    • + t: table +
    • + +
    • + i: preceding index (nil on first call) +
    • + +
    • + v: preceding value (nil on first call) +
    • + +
    • + j: following index (nil on last call) +
    • + +
    • + w: following value (nil on last call) +
    • + +
    + + + + + + +

    Return value:

    +separator string + + + +
    + + + + +
    require_version (module, min, too_big, pattern)
    +
    +Require a module with a particular version + + +

    Parameters

    +
      + +
    • + module: module to require +
    • + +
    • + min: lowest acceptable version (default: any) +
    • + +
    • + too_big: lowest version that is too big (default: none) +
    • + +
    • + pattern: +
    • + +
    + + + + + + + +
    @@ -614,6 +983,35 @@

    Return value:

    +
    tostring (x)
    +
    +Extend tostring to work better on tables. + + +

    Parameters

    +
      + +
    • + x: object to convert to string +
    • + +
    + + + + + + +

    Return value:

    +string representation + + + +
    + + + +
    trim (s, r)
    Remove leading and trailing matter from a string. diff --git a/src/files/table_ext.html b/std/files/table_ext.html similarity index 91% rename from src/files/table_ext.html rename to std/files/table_ext.html index df59014..b0ecf02 100644 --- a/src/files/table_ext.html +++ b/std/files/table_ext.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -115,18 +87,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - diff --git a/src/files/tree.html b/std/files/tree.html similarity index 89% rename from src/files/tree.html rename to std/files/tree.html index 6f71ec7..82b7934 100644 --- a/src/files/tree.html +++ b/std/files/tree.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -115,18 +87,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

  • tree.lua
  • -
  • - xml.lua -
  • - diff --git a/src/getopt.lua b/std/getopt.lua similarity index 97% rename from src/getopt.lua rename to std/getopt.lua index d67c8a2..5db8487 100644 --- a/src/getopt.lua +++ b/std/getopt.lua @@ -31,10 +31,12 @@ --
  • TODO: Store version separately (construct banner?).
  • -- -require "base" -local list = require "list" -require "string_ext" -local Object = require "object" +require "std.base" +local io = require "std.io_ext" +local list = require "std.list" +local Object = require "std.object" +local string = require "std.string_ext" +local table = require "std.table_ext" local M = { opt = {}, diff --git a/src/index.html b/std/index.html similarity index 71% rename from src/index.html rename to std/index.html index c92cf55..c5814e7 100644 --- a/src/index.html +++ b/std/index.html @@ -38,18 +38,6 @@

    Modules

    base -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -63,10 +51,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -75,10 +59,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -87,10 +67,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -99,10 +75,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -115,18 +87,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -147,10 +111,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -173,21 +133,6 @@

    Modules

    - - - - - - - - - - - - - - -
    _G.assert (v, f, ...)Extend to allow formatted arguments.
    _G.bind (f, ...) Partially apply a function. Identity function.
    _G.ileaves (tr)Tree iterator which returns just numbered leaves, in order.
    _G.inodes (tr) Tree iterator over numbered nodes, in order.
    _G.leaves (tr)Tree iterator which returns just leaves.
    _G.map (f, i, ...) Map a function over an iterator. Turn a tuple into a list.
    _G.pickle (x)Convert a value to a string.
    _G.prettytostring (t, indent, spacing)Pretty-print a table.
    _G.render (x, open, close, elem, pair, sep, roots)Turn tables into strings with recursion detection.
    _G.require_version (module, min, too_big, pattern)Require a module with a particular version
    _G.ripairs (t) An iterator like ipairs, but in reverse.
    _G.tostring (x)Extend tostring to work better on tables.
    _G.totable (x) Turn an object into a table according to __totable metamethod. Give warning with the name of program and file (if any).
    render_CloseRenderer (t)
    render_ElementRenderer (e)
    render_OpenRenderer (t)
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    render_SeparatorRenderer (t, i, v, j, w)
    tree_Iterator (it, tr, n)
    processFiles (f)process_files (f) Process files specified on the command-line.
    Fold a binary function through a list right associatively.
    ileaves (tr)Tree iterator which returns just numbered leaves, in order.
    indexKey (f, l) Make an index of a list of tables on a given field Copy a list of tables, indexed on a given field
    leaves (tr)Tree iterator which returns just leaves.
    map (f, l) Map a function over a list. Justify a string.
    pickle (x)Convert a value to a string.
    prettytostring (t, indent, spacing)Pretty-print a table.
    render (x, open, close, elem, pair, sep, roots)Turn tables into strings with recursion detection.
    render_CloseRenderer (t)
    render_ElementRenderer (e)
    render_OpenRenderer (t)
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    render_SeparatorRenderer (t, i, v, j, w)
    require_version (module, min, too_big, pattern)Require a module with a particular version
    rtrim (s, r) Remove trailing matter from a string. Do find, returning captures as a list.
    tostring (x)Extend tostring to work better on tables.
    trim (s, r) Remove leading and trailing matter from a string. Adds to the existing global functions
    debugAdditions to the debug module
    ioAdditions to the io module
    mathAdditions to the math module.
    @@ -203,11 +148,6 @@

    Files

    - - bin.lua - - - debug_ext.lua @@ -218,11 +158,6 @@

    Files

    - - fstable.lua - - - getopt.lua @@ -233,11 +168,6 @@

    Files

    - - lcs.lua - - - list.lua @@ -248,11 +178,6 @@

    Files

    - - mbox.lua - - - modules.lua @@ -268,21 +193,11 @@

    Files

    - - parser.lua - - - set.lua - - std.lua - - - strbuf.lua @@ -308,11 +223,6 @@

    Files

    - - xml.lua - - - diff --git a/src/io_ext.lua b/std/io_ext.lua similarity index 75% rename from src/io_ext.lua rename to std/io_ext.lua index 7a57ca2..ff85d75 100644 --- a/src/io_ext.lua +++ b/std/io_ext.lua @@ -1,12 +1,7 @@ --- Additions to the io module -module ("io", package.seeall) -require "base" -local package_unext = require "package_ext" - - --- Get file handle metatable -local file_metatable = getmetatable (io.stdin) +local list = require "std.list" +local package = require "std.package_ext" -- Get an input file handle. @@ -14,8 +9,8 @@ local file_metatable = getmetatable (io.stdin) -- @return file handle, or nil on error local function input_handle (h) if h == nil then - h = input () - elseif _G.type (h) == "string" then + h = io.input () + elseif type (h) == "string" then h = io.open (h) end return h @@ -24,7 +19,7 @@ end --- Slurp a file handle. -- @param h file handle or name (default: io.input ()) -- @return contents of file or handle, or nil if error -function slurp (h) +local function slurp (h) h = input_handle (h) if h then local s = h:read ("*a") @@ -37,7 +32,7 @@ end -- @param h file handle or name (default: io.input ()); -- if h is a handle, the file is closed after reading -- @return list of lines -function readlines (h) +local function readlines (h) h = input_handle (h) local l = {} for line in h:lines () do @@ -46,49 +41,47 @@ function readlines (h) h:close () return l end -file_metatable.readlines = readlines --- Write values adding a newline after each. -- @param h file handle (default: io.output () -- @param ... values to write (as for write) -function writelines (h, ...) +local function writelines (h, ...) if io.type (h) ~= "file" then io.write (h, "\n") h = io.output () end - for v in ileaves ({...}) do + for v in list.ileaves ({...}) do h:write (v, "\n") end end -file_metatable.writelines = writelines --- Split a directory path into components. -- Empty components are retained: the root directory becomes {"", ""}. -- @param path path -- @return list of path components -function splitdir (path) +local function splitdir (path) return string.split (path, package.dirsep) end --- Concatenate one or more directories and a filename into a path. -- @param ... path components -- @return path -function catfile (...) +local function catfile (...) return table.concat ({...}, package.dirsep) end --- Concatenate two or more directories into a path, removing the trailing slash. -- @param ... path components -- @return path -function catdir (...) +local function catdir (...) return (string.gsub (catfile (...), "^$", package.dirsep)) end --- Perform a shell command and return its output. -- @param c command -- @return output, or nil if error -function shell (c) - return io.slurp (io.popen (c)) +local function shell (c) + return slurp (io.popen (c)) end --- Process files specified on the command-line. @@ -97,7 +90,7 @@ end --
    FIXME: Make the file list an argument to the function. -- @param f function to process files with, which is passed -- (name, arg_no) -function processFiles (f) +local function process_files (f) -- N.B. "arg" below refers to the global array of command-line args if #arg == 0 then table.insert (arg, "-") @@ -111,3 +104,24 @@ function processFiles (f) f (v, i) end end + + +local M = { + catdir = catdir, + catfile = catfile, + process_files = process_files, + readlines = readlines, + shell = shell, + slurp = slurp, + splitdir = splitdir, + writelines = writelines, + + -- camelCase compatibility, + processFiles = process_files, +} + +for k, v in pairs (io) do + M[k] = M[k] or v +end + +return M diff --git a/src/list.lua b/std/list.lua similarity index 93% rename from src/list.lua rename to std/list.lua index 87cf336..6b614d9 100644 --- a/src/list.lua +++ b/std/list.lua @@ -1,5 +1,5 @@ --- Tables as lists. -require "base" +require "std.base" local new -- forward declaration @@ -228,6 +228,36 @@ local function depair (ls) return t end + +local function _leaves (it, tr) + local function visit (n) + if type (n) == "table" then + for _, v in it (n) do + visit (v) + end + else + coroutine.yield (n) + end + end + return coroutine.wrap (visit), tr +end + +--- Tree iterator which returns just numbered leaves, in order. +-- @param tr tree to iterate over +-- @return iterator function +-- @return the tree, as above +local function ileaves (tr) + return _leaves (ipairs, tr) +end + +--- Tree iterator which returns just leaves. +-- @param tr tree to iterate over +-- @return iterator function +-- @return the tree, as above +local function leaves (tr) + return _leaves (pairs, tr) +end + --- Flatten a list. -- @param l list to flatten -- @return flattened list @@ -428,6 +458,10 @@ local M = { tail = tail, transpose = transpose, zipWith = zipWith, + + -- APIs that used to be in "base". + ileaves = ileaves, + leaves = leaves, } return M diff --git a/src/luadoc.css b/std/luadoc.css similarity index 100% rename from src/luadoc.css rename to std/luadoc.css diff --git a/src/math_ext.lua b/std/math_ext.lua similarity index 71% rename from src/math_ext.lua rename to std/math_ext.lua index f328105..3a3f9ae 100644 --- a/src/math_ext.lua +++ b/std/math_ext.lua @@ -1,14 +1,12 @@ --- Additions to the math module. -module ("math", package.seeall) - -local _floor = floor +local _floor = math.floor --- Extend math.floor to take the number of decimal places. -- @param n number -- @param p number of decimal places to truncate to (default: 0) -- @return n truncated to p decimal places -function floor (n, p) +local function floor (n, p) if p and p ~= 0 then local e = 10 ^ p return _floor (n * e) / e @@ -21,7 +19,22 @@ end -- @param n number -- @param p number of decimal places to round to (default: 0) -- @return n rounded to p decimal places -function round (n, p) +local function round (n, p) local e = 10 ^ (p or 0) return _floor (n * e + 0.5) / e end + + +local M = { + floor = floor, + round = round, + + -- Core Lua function implementations. + _floor = _floor, +} + +for k, v in pairs (math) do + M[k] = M[k] or v +end + +return M diff --git a/std/modules.lua b/std/modules.lua new file mode 100644 index 0000000..acee187 --- /dev/null +++ b/std/modules.lua @@ -0,0 +1,16 @@ +return { + "std.debug_init", + --"std.strict", + "std.base", + "std.package_ext", + "std.debug_ext", + "std.table_ext", + "std.list", + "std.tree", + "std.string_ext", + "std.math_ext", + "std.io_ext", + "std.getopt", + "std.set", + "std.strbuf", +} diff --git a/src/modules/base.html b/std/modules/base.html similarity index 58% rename from src/modules/base.html rename to std/modules/base.html index 8f85c51..8382c1e 100644 --- a/src/modules/base.html +++ b/std/modules/base.html @@ -36,18 +36,6 @@

    Modules

  • base
  • -
  • - debug -
  • - -
  • - io -
  • - -
  • - math -
  • - @@ -61,10 +49,6 @@

    Files

    base.lua -
  • - bin.lua -
  • -
  • debug_ext.lua
  • @@ -73,10 +57,6 @@

    Files

    debug_init.lua -
  • - fstable.lua -
  • -
  • getopt.lua
  • @@ -85,10 +65,6 @@

    Files

    io_ext.lua -
  • - lcs.lua -
  • -
  • list.lua
  • @@ -97,10 +73,6 @@

    Files

    math_ext.lua -
  • - mbox.lua -
  • -
  • modules.lua
  • @@ -113,18 +85,10 @@

    Files

    package_ext.lua -
  • - parser.lua -
  • -
  • set.lua
  • -
  • - std.lua -
  • -
  • strbuf.lua
  • @@ -145,10 +109,6 @@

    Files

    tree.lua -
  • - xml.lua -
  • - @@ -171,11 +131,6 @@

    Module base

    Functions

    - - - - - @@ -221,21 +176,11 @@

    Functions

    - - - - - - - - - - @@ -261,36 +206,11 @@

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - @@ -301,31 +221,6 @@

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - @@ -358,43 +253,6 @@

    Functions

    -
    _G.assert (v, f, ...)
    -
    -Extend to allow formatted arguments. - - -

    Parameters

    -
      - -
    • - v: value to assert -
    • - -
    • - f: format -
    • - -
    • - ...: arguments to format -
    • - -
    - - - - - - -

    Return value:

    -value - - - -
    - - - -
    _G.bind (f, ...)
    Partially apply a function. @@ -689,41 +547,6 @@

    Return value:

    -
    _G.ileaves (tr)
    -
    -Tree iterator which returns just numbered leaves, in order. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -
    - - - -
    _G.inodes (tr)
    Tree iterator over numbered nodes, in order. @@ -768,41 +591,6 @@

    See also:

    -
    _G.leaves (tr)
    -
    -Tree iterator which returns just leaves. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -
    - - - -
    _G.map (f, i, ...)
    Map a function over an iterator. @@ -970,188 +758,6 @@

    Return value:

    -
    - - - - -
    _G.pickle (x)
    -
    -Convert a value to a string. The string can be passed to dostring to retrieve the value.
    TODO: Make it work for recursive tables. - - -

    Parameters

    -
      - -
    • - x: object to pickle -
    • - -
    - - - - - - -

    Return value:

    -string such that eval (s) is the same value as x - - - -
    - - - - -
    _G.prettytostring (t, indent, spacing)
    -
    -Pretty-print a table. - - -

    Parameters

    -
      - -
    • - t: table to print -
    • - -
    • - indent: indent between levels ["\t"] -
    • - -
    • - spacing: space before every line -
    • - -
    - - - - - - -

    Return value:

    -pretty-printed string - - - -
    - - - - -
    _G.render (x, open, close, elem, pair, sep, roots)
    -
    -Turn tables into strings with recursion detection. N.B. Functions calling render should not recurse, or recursion detection will not work. - - -

    Parameters

    -
      - -
    • - x: object to convert to string -
    • - -
    • - open: open table renderer -
    • - -
    • - close: close table renderer -
    • - -
    • - elem: element renderer -
    • - -
    • - pair: pair renderer -
    • - -
    • - sep: separator renderer -
    • - -
    • - roots: -
    • - -
    - - - - - - -

    Return value:

    -string representation - - - -

    See also:

    - - -
    - - - - -
    _G.require_version (module, min, too_big, pattern)
    -
    -Require a module with a particular version - - -

    Parameters

    -
      - -
    • - module: module to require -
    • - -
    • - min: lowest acceptable version (default: any) -
    • - -
    • - too_big: lowest version that is too big (default: none) -
    • - -
    • - pattern: -
    • - -
    - - - - - - - -
    @@ -1194,35 +800,6 @@

    Return values:

    -
    _G.tostring (x)
    -
    -Extend tostring to work better on tables. The original tostring is available as _tostring. - - -

    Parameters

    -
      - -
    • - x: object to convert to string -
    • - -
    - - - - - - -

    Return value:

    -string representation - - - -
    - - - -
    _G.totable (x)
    Turn an object into a table according to __totable metamethod. @@ -1273,183 +850,6 @@

    Parameters

    -
    - - - - -
    render_CloseRenderer (t)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -close table string - - - -
    - - - - -
    render_ElementRenderer (e)
    -
    - - - -

    Parameters

    -
      - -
    • - e: element -
    • - -
    - - - - - - -

    Return value:

    -element string - - - -
    - - - - -
    render_OpenRenderer (t)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -open table string - - - -
    - - - - -
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - i: index -
    • - -
    • - v: value -
    • - -
    • - is: index string -
    • - -
    • - vs: value string -
    • - -
    - - - - - - -

    Return value:

    -element string - - - -
    - - - - -
    render_SeparatorRenderer (t, i, v, j, w)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - i: preceding index (nil on first call) -
    • - -
    • - v: preceding value (nil on first call) -
    • - -
    • - j: following index (nil on last call) -
    • - -
    • - w: following value (nil on last call) -
    • - -
    - - - - - - -

    Return value:

    -separator string - - -
    diff --git a/src/object.lua b/std/object.lua similarity index 98% rename from src/object.lua rename to std/object.lua index a52f321..e9c5927 100644 --- a/src/object.lua +++ b/std/object.lua @@ -23,7 +23,7 @@ --
  • Add a method: function object:method (...) ... end
  • -- -require "table_ext" +local table = require "std.table_ext" --- Root object diff --git a/src/package_ext.lua b/std/package_ext.lua similarity index 73% rename from src/package_ext.lua rename to std/package_ext.lua index 01e61db..7f32eaa 100644 --- a/src/package_ext.lua +++ b/std/package_ext.lua @@ -1,9 +1,6 @@ -- Additions to the package module. -local table_unext = require "table_ext" - --- Save original unextended table. -local unextended = table.clone (package) +local M = {} --- Make named constants for package.config (undocumented -- in 5.1; see luaconf.h for C equivalents). @@ -14,7 +11,11 @@ local unextended = table.clone (package) -- @field path_mark string that marks substitution points in a path template -- @field execdir (Windows only) replaced by the executable's directory in a path -- @field igmark Mark to ignore all before it when building luaopen_ function name. -package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark = +M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark = string.match (package.config, "^([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)") -return unextended +for k, v in pairs (package) do + M[k] = M[k] or v +end + +return M diff --git a/src/set.lua b/std/set.lua similarity index 99% rename from src/set.lua rename to std/set.lua index 763759e..0e6251a 100644 --- a/src/set.lua +++ b/std/set.lua @@ -1,4 +1,4 @@ -local list = require "list" +local list = require "std.list" -- Primitive methods (know about representation) diff --git a/std/std.lua b/std/std.lua new file mode 100644 index 0000000..ecac189 --- /dev/null +++ b/std/std.lua @@ -0,0 +1,48 @@ +--- Lua standard library +--
      +--
    • TODO: Write a style guide (indenting/wrapping, capitalisation, +-- function and variable names); library functions should call +-- error, not die; OO vs non-OO (a thorny problem).
    • +--
    • TODO: Add tests for each function immediately after the function; +-- this also helps to check module dependencies.
    • +--
    • TODO: pre-compile.
    • +--
    +local version = "General Lua libraries / 35" + +for _, m in ipairs (require "std.modules") do + if m:match "_ext$" ~= nil then + -- Inject stdlib extensions directly into global package namespaces. + local t = m:match "std%.(.*)_ext$" + for k, v in pairs (require (m)) do + _G[t][k] = v + end + else + _G[m:match "std%.(.*)$"] = require (m) + end +end + +-- Add io functions to the file handle metatable. +local file_metatable = getmetatable (io.stdin) +file_metatable.readlines = io.readlines +file_metatable.writelines = io.writelines + +-- Maintain old global interface access points. +for _, api in ipairs { + "assert", + "ileaves", + "leaves", + "pickle", + "prettytostring", + "render", + "require_version", + "tostring", +} do + _G[api] = list[api] or _G[api] + _G[api] = string[api] or _G[api] +end + +local M = { + version = version, +} + +return M diff --git a/std/std.lua.in b/std/std.lua.in new file mode 100644 index 0000000..0b4b504 --- /dev/null +++ b/std/std.lua.in @@ -0,0 +1,48 @@ +--- Lua standard library +--
      +--
    • TODO: Write a style guide (indenting/wrapping, capitalisation, +-- function and variable names); library functions should call +-- error, not die; OO vs non-OO (a thorny problem).
    • +--
    • TODO: Add tests for each function immediately after the function; +-- this also helps to check module dependencies.
    • +--
    • TODO: pre-compile.
    • +--
    +local version = "General Lua libraries / @VERSION@" + +for _, m in ipairs (require "std.modules") do + if m:match "_ext$" ~= nil then + -- Inject stdlib extensions directly into global package namespaces. + local t = m:match "std%.(.*)_ext$" + for k, v in pairs (require (m)) do + _G[t][k] = v + end + else + _G[m:match "std%.(.*)$"] = require (m) + end +end + +-- Add io functions to the file handle metatable. +local file_metatable = getmetatable (io.stdin) +file_metatable.readlines = io.readlines +file_metatable.writelines = io.writelines + +-- Maintain old global interface access points. +for _, api in ipairs { + "assert", + "ileaves", + "leaves", + "pickle", + "prettytostring", + "render", + "require_version", + "tostring", +} do + _G[api] = list[api] or _G[api] + _G[api] = string[api] or _G[api] +end + +local M = { + version = version, +} + +return M diff --git a/std/std.mk b/std/std.mk new file mode 100644 index 0000000..6dce04b --- /dev/null +++ b/std/std.mk @@ -0,0 +1,62 @@ +# lua-stdlib make rules. + + +## ------ ## +## Build. ## +## ------ ## + +## Use, e.g. `require "std.list"` for individual modules. +nobase_dist_lua_DATA = \ + std/base.lua \ + std/debug_ext.lua \ + std/debug_init.lua \ + std/getopt.lua \ + std/io_ext.lua \ + std/list.lua \ + std/math_ext.lua \ + std/modules.lua \ + std/object.lua \ + std/package_ext.lua \ + std/set.lua \ + std/strbuf.lua \ + std/strict.lua \ + std/string_ext.lua \ + std/table_ext.lua \ + std/tree.lua \ + $(NOTHING_ELSE) + +## But, `require "std"` for core module. +dist_lua_DATA = \ + std/std.lua \ + $(NOTHING_ELSE) + +# In order to avoid regenerating std.lua at configure time, which +# causes the documentation to be rebuilt and hence requires users to +# have luadoc installed, put std/std.lua in as a Makefile dependency. +# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) +std/std.lua: std/std.lua.in + ./config.status --file=$@ + + +## ------------- ## +## Distribution. ## +## ------------- ## + +EXTRA_DIST += \ + std/std.lua.in \ + $(NOTHING_ELSE) + + +## -------------- ## +## Documentation. ## +## -------------- ## + +dist_doc_DATA += \ + $(srcdir)/std/index.html \ + $(srcdir)/std/luadoc.css + +dist_files_DATA += $(wildcard $(srcdir)/std/files/*.html) +dist_modules_DATA += $(wildcard $(srcdir)/std/modules/*.html) + +$(dist_doc_DATA): $(nobase_dist_lua_DATA) + cd $(srcdir)/std && $(LUADOC) *.lua diff --git a/src/strbuf.lua b/std/strbuf.lua similarity index 100% rename from src/strbuf.lua rename to std/strbuf.lua diff --git a/src/strict.lua b/std/strict.lua similarity index 100% rename from src/strict.lua rename to std/strict.lua diff --git a/src/string_ext.lua b/std/string_ext.lua similarity index 56% rename from src/string_ext.lua rename to std/string_ext.lua index 8b7de39..fc37a29 100644 --- a/src/string_ext.lua +++ b/std/string_ext.lua @@ -1,9 +1,121 @@ --- Additions to the string module -- TODO: Pretty printing (use in getopt); see source for details. -require "table_ext" -local list = require "list" -local strbuf = require "strbuf" +local list = require "std.list" +local strbuf = require "std.strbuf" +local table = require "std.table_ext" + +local M = {} + +--- Extend to work better with one argument. +-- If only one argument is passed, no formatting is attempted. +-- @param f format +-- @param ... arguments to format +-- @return formatted string +local _format = string.format +local function format (f, arg1, ...) + if arg1 == nil then + return f + else + return _format (f, arg1, ...) + end +end + +--- Extend to allow formatted arguments. +-- @param v value to assert +-- @param f format +-- @param ... arguments to format +-- @return value +local _assert = assert +local function assert (v, f, ...) + if not v then + if f == nil then + f = "" + end + error (format (f, ...)) + end + return v +end + +--- Do find, returning captures as a list. +-- @param s target string +-- @param p pattern +-- @param init start position (default: 1) +-- @param plain inhibit magic characters (default: nil) +-- @return start of match, end of match, table of captures +local function tfind (s, p, init, plain) + assert (type (s) == "string", + "bad argument #1 to 'tfind' (string expected, got " .. type (s) .. ")") + assert (type (p) == "string", + "bad argument #2 to 'tfind' (string expected, got " .. type (p) .. ")") + local function pack (from, to, ...) + return from, to, {...} + end + return pack (p.find (s, p, init, plain)) +end + +--- Do multiple finds on a string. +-- @param s target string +-- @param p pattern +-- @param init start position (default: 1) +-- @param plain inhibit magic characters (default: nil) +-- @return list of {from, to; capt = {captures}} +local function finds (s, p, init, plain) + init = init or 1 + local l = {} + local from, to, r + repeat + from, to, r = tfind (s, p, init, plain) + if from ~= nil then + table.insert (l, {from, to, capt = r}) + init = to + 1 + end + until not from + return l +end + +--- Split a string at a given separator. +-- FIXME: Consider Perl and Python versions. +-- @param s string to split +-- @param sep separator pattern +-- @return list of strings +local function split (s, sep) + -- finds gets a list of {from, to, capt = {}} lists; we then + -- flatten the result, discarding the captures, and prepend 0 (1 + -- before the first character) and append 0 (1 after the last + -- character), and then read off the result in pairs. + local pairs = list.concat ({0}, list.flatten (finds (s, sep)), {0}) + local l = {} + for i = 1, #pairs, 2 do + table.insert (l, string.sub (s, pairs[i] + 1, pairs[i + 1] - 1)) + end + return l +end + +--- Require a module with a particular version +-- @param module module to require +-- @param min lowest acceptable version (default: any) +-- @param too_big lowest version that is too big (default: none) +-- @pattern pattern to match version in module.version or +-- module.VERSION (default: ".*[%.%d]+" +local function require_version (module, min, too_big, pattern) + local function version_to_list (v) + return list.new (split (v, "%.")) + end + local function module_version (module, pattern) + return version_to_list (string.match (module.version or module._VERSION, + pattern or ".*[%.%d]+")) + end + local m = require (module) + if min then + assert (module_version (m, pattern) >= version_to_list (min)) + end + if too_big then + assert (module_version (m, pattern) < version_to_list (too_big)) + end + return m +end + -- Write pretty-printing based on: -- @@ -30,6 +142,184 @@ local strbuf = require "strbuf" -- -> a Result +--- Turn tables into strings with recursion detection. +-- N.B. Functions calling render should not recurse, or recursion +-- detection will not work. +-- @see render_OpenRenderer, render_CloseRenderer +-- @see render_ElementRenderer, render_PairRenderer +-- @see render_SeparatorRenderer +-- @param x object to convert to string +-- @param open open table renderer +-- @param close close table renderer +-- @param elem element renderer +-- @param pair pair renderer +-- @param sep separator renderer +-- @return string representation +local function render (x, open, close, elem, pair, sep, roots) + local function stop_roots (x) + return roots[x] or render (x, open, close, elem, pair, sep, table.clone (roots)) + end + roots = roots or {} + if type (x) ~= "table" or metamethod (x, "__tostring") then + return elem (x) + else + local s = strbuf.new () + s = s .. open (x) + roots[x] = elem (x) + local i, v = nil, nil + for j, w in pairs (x) do + s = s .. sep (x, i, v, j, w) .. pair (x, j, w, stop_roots (j), stop_roots (w)) + i, v = j, w + end + s = s .. sep (x, i, v, nil, nil) .. close (x) + return s:tostring () + end +end + +--- +-- @class function +-- @name render_OpenRenderer +-- @param t table +-- @return open table string + +--- +-- @class function +-- @name render_CloseRenderer +-- @param t table +-- @return close table string + +--- +-- @class function +-- @name render_ElementRenderer +-- @param e element +-- @return element string + +--- +-- @class function +-- @name render_PairRenderer +-- N.B. the function should not try to render i and v, or treat +-- them recursively. +-- @param t table +-- @param i index +-- @param v value +-- @param is index string +-- @param vs value string +-- @return element string + +--- +-- @class function +-- @name render_SeparatorRenderer +-- @param t table +-- @param i preceding index (nil on first call) +-- @param v preceding value (nil on first call) +-- @param j following index (nil on last call) +-- @param w following value (nil on last call) +-- @return separator string + +--- Extend tostring to work better on tables. +-- @class function +-- @name tostring +-- @param x object to convert to string +-- @return string representation +local _tostring = tostring +local function tostring (x) + return render (x, + function () return "{" end, + function () return "}" end, + _tostring, + function (t, _, _, i, v) + return i .. "=" .. v + end, + function (_, i, _, j) + if i and j then + return "," + end + return "" + end) +end + + +--- Pretty-print a table. +-- @param t table to print +-- @param indent indent between levels ["\t"] +-- @param spacing space before every line +-- @return pretty-printed string +local function prettytostring (t, indent, spacing) + indent = indent or "\t" + spacing = spacing or "" + return render (t, + function () + local s = spacing .. "{" + spacing = spacing .. indent + return s + end, + function () + spacing = string.gsub (spacing, indent .. "$", "") + return spacing .. "}" + end, + function (x) + if type (x) == "string" then + return format ("%q", x) + else + return tostring (x) + end + end, + function (x, i, v, is, vs) + local s = spacing .. "[" + if type (i) == "table" then + s = s .. "\n" + end + s = s .. is + if type (i) == "table" then + s = s .. "\n" + end + s = s .. "] =" + if type (v) == "table" then + s = s .. "\n" + else + s = s .. " " + end + s = s .. vs + return s + end, + function (_, i) + local s = "\n" + if i then + s = "," .. s + end + return s + end) +end + + +--- Convert a value to a string. +-- The string can be passed to dostring to retrieve the value. +--
    TODO: Make it work for recursive tables. +-- @param x object to pickle +-- @return string such that eval (s) is the same value as x +local function pickle (x) + if type (x) == "string" then + return format ("%q", x) + elseif type (x) == "number" or type (x) == "boolean" or + type (x) == "nil" then + return tostring (x) + else + x = totable (x) or x + if type (x) == "table" then + local s, sep = "{", "" + for i, v in pairs (x) do + s = s .. sep .. "[" .. pickle (i) .. "]=" .. pickle (v) + sep = "," + end + s = s .. "}" + return s + else + die ("cannot pickle " .. tostring (x)) + end + end +end + + --- Give strings a subscription operator. -- @param s string -- @param i index @@ -39,11 +329,9 @@ local old__index = getmetatable ("").__index getmetatable ("").__index = function (s, i) if type (i) == "number" then return s:sub (i, i) - -- Fall back to old metamethods - elseif type (old__index) == "function" then - return old__index (s, i) + -- Fall back to module metamethods else - return old__index[i] + return M[i] end end @@ -114,20 +402,6 @@ local function ordinal_suffix (n) end end ---- Extend to work better with one argument. --- If only one argument is passed, no formatting is attempted. --- @param f format --- @param ... arguments to format --- @return formatted string -local _format = string.format -local function format (f, arg1, ...) - if arg1 == nil then - return f - else - return _format (f, arg1, ...) - end -end - --- Justify a string. -- When the string is longer than w, it is truncated (left or right -- according to the sign of w). @@ -191,7 +465,7 @@ local function numbertosi (n) [4] = "T", [5] = "P", [6] = "E", [7] = "Z", [8] = "Y" } - local t = string.format("% #.2e", n) + local t = format("% #.2e", n) local _, _, m, e = t:find(".(.%...)e(.+)") local man, exp = tonumber (m), tonumber (e) local siexp = math.floor (exp / 3) @@ -201,61 +475,6 @@ local function numbertosi (n) return tostring (man) .. s end ---- Do find, returning captures as a list. --- @param s target string --- @param p pattern --- @param init start position (default: 1) --- @param plain inhibit magic characters (default: nil) --- @return start of match, end of match, table of captures -local function tfind (s, p, init, plain) - assert (type (s) == "string", - "bad argument #1 to 'tfind' (string expected, got " .. type (s) .. ")") - assert (type (p) == "string", - "bad argument #2 to 'tfind' (string expected, got " .. type (p) .. ")") - local function pack (from, to, ...) - return from, to, {...} - end - return pack (p.find (s, p, init, plain)) -end - ---- Do multiple finds on a string. --- @param s target string --- @param p pattern --- @param init start position (default: 1) --- @param plain inhibit magic characters (default: nil) --- @return list of {from, to; capt = {captures}} -local function finds (s, p, init, plain) - init = init or 1 - local l = {} - local from, to, r - repeat - from, to, r = tfind (s, p, init, plain) - if from ~= nil then - table.insert (l, {from, to, capt = r}) - init = to + 1 - end - until not from - return l -end - ---- Split a string at a given separator. --- FIXME: Consider Perl and Python versions. --- @param s string to split --- @param sep separator pattern --- @return list of strings -local function split (s, sep) - -- finds gets a list of {from, to, capt = {}} lists; we then - -- flatten the result, discarding the captures, and prepend 0 (1 - -- before the first character) and append 0 (1 after the last - -- character), and then read off the result in pairs. - local pairs = list.concat ({0}, list.flatten (finds (s, sep)), {0}) - local l = {} - for i = 1, #pairs, 2 do - table.insert (l, string.sub (s, pairs[i] + 1, pairs[i + 1] - 1)) - end - return l -end - --- Remove leading matter from a string. -- @param s string -- @param r leading pattern (default: "%s+") @@ -282,10 +501,8 @@ local function trim (s, r) return rtrim (ltrim (s, r), r) end --- Save original unextended table. -local unextended = table.clone (string) -local M = { +for k, v in pairs { __index = old__index, caps = caps, chomp = chomp, @@ -303,13 +520,28 @@ local M = { trim = trim, wrap = wrap, + -- APIs that used to be in "base". + assert = assert, + pickle = pickle, + prettytostring = prettytostring, + render = render, + require_version = require_version, + tostring = tostring, + -- camelCase compatibility: escapePattern = escape_pattern, escapeShell = escape_shell, ordinalSuffix = ordinal_suffix, -} --- Inject stdlib extensions directly into the string package. -_G.string = table.merge (string, M) + -- Core Lua function implementations. + _format = _format, + _tostring = _tostring, +} do + M[k] = v +end + +for k, v in pairs (string) do + M[k] = M[k] or v +end -return unextended +return M diff --git a/src/table_ext.lua b/std/table_ext.lua similarity index 92% rename from src/table_ext.lua rename to std/table_ext.lua index 6f63bd5..0278c77 100644 --- a/src/table_ext.lua +++ b/std/table_ext.lua @@ -1,8 +1,5 @@ -- Extensions to the table module ---local list = require "list" FIXME: allow require loops - - local _sort = table.sort --- Make table.sort return its result. -- @param t table @@ -115,9 +112,6 @@ local function new (x, t) end}) end --- Save original unextended table. -local unextended = clone (table) - local M = { clone = clone, clone_rename = clone_rename, @@ -129,9 +123,13 @@ local M = { size = size, sort = sort, values = values, + + -- Core Lua table.sort function. + _sort = _sort, } --- Inject stdlib extensions directly into the table package. -_G.table = merge (table, M) +for k, v in pairs (table) do + M[k] = M[k] or v +end -return unextended +return M diff --git a/src/tree.lua b/std/tree.lua similarity index 94% rename from src/tree.lua rename to std/tree.lua index 1f1159b..156ec9f 100644 --- a/src/tree.lua +++ b/std/tree.lua @@ -1,5 +1,5 @@ --- Tables as trees. -local list = require "list" +local list = require "std.list" local metatable = {} @@ -94,9 +94,11 @@ end -- Public interface local M = { - clone = clone, - merge = merge, - new = new, + clone = clone, + ileaves = list.ileaves, + leaves = list.leaves, + merge = merge, + new = new, } return M diff --git a/stdilb-git-1.rockspec b/stdilb-git-1.rockspec deleted file mode 100644 index 130a74d..0000000 --- a/stdilb-git-1.rockspec +++ /dev/null @@ -1,24 +0,0 @@ -version = "git-2" -source = { - url = "git://github.com/rrthomas/lua-stdlib.git", -} -package = "stdlib" -dependencies = { - "lua >= 5.1", -} -description = { - homepage = "http://github.com/rrthomas/lua-stdlib/", - license = "MIT/X11", - summary = "General Lua libraries", - detailed = " stdlib is a library of modules for common programming tasks,\ - including list, table and functional operations, regexps, objects,\ - pickling, pretty-printing and getopt.\ - ", -} -build = { - build_command = "autoreconf -i && LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - type = "command", - copy_directories = { - }, - install_command = "make install", -} diff --git a/stdlib-34.1-1.rockspec b/stdlib-34.1-1.rockspec deleted file mode 100644 index 28e3ffa..0000000 --- a/stdlib-34.1-1.rockspec +++ /dev/null @@ -1,25 +0,0 @@ -version = "34.1-1" -source = { - branch = "release-v34.1", - url = "git://github.com/rrthomas/lua-stdlib.git", -} -package = "stdlib" -dependencies = { - "lua >= 5.1", -} -description = { - homepage = "http://github.com/rrthomas/lua-stdlib/", - license = "MIT/X11", - summary = "General Lua libraries", - detailed = " stdlib is a library of modules for common programming tasks,\ - including list, table and functional operations, regexps, objects,\ - pickling, pretty-printing and getopt.\ - ", -} -build = { - build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - type = "command", - copy_directories = { - }, - install_command = "make install", -} diff --git a/stdlib.rockspec.in b/stdlib.rockspec.in deleted file mode 100644 index e08c434..0000000 --- a/stdlib.rockspec.in +++ /dev/null @@ -1,25 +0,0 @@ -package="stdlib" -version="@VERSION@-2" -source = { - url = "git://github.com/rrthomas/lua-stdlib.git", - branch = "release-v@VERSION@", -} -description = { - summary = "General Lua libraries", - detailed = [[ - stdlib is a library of modules for common programming tasks, - including list, table and functional operations, regexps, objects, - pickling, pretty-printing and getopt. - ]], - homepage = "http://github.com/rrthomas/lua-stdlib/", - license = "MIT/X11" -} -dependencies = { - "lua >= @LUA_MIN_VERSION@" -} -build = { - type = "command", - build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", - install_command = "make install", - copy_directories = {} -} diff --git a/template.lua b/template.lua deleted file mode 100644 index 1d2abe7..0000000 --- a/template.lua +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env lua -prog = { - name = "", - banner = " VERSION (DATE) by AUTHOR )", - purpose = "", -} - - -require "std" - - --- Process a file -function main (file, number) -end - - --- Command-line options -options = { - Option {{"test", "t"}, - "test option"}, -} - --- Main routine -getopt.processArgs () -if table.getn (arg) == 0 then - getopt.dieWithUsage () -end -io.processFiles (main) - - --- Changelog - --- 0.1 Program started diff --git a/travis.yml.in b/travis.yml.in new file mode 100644 index 0000000..09fc7ca --- /dev/null +++ b/travis.yml.in @@ -0,0 +1,60 @@ +# Lua is not officially supported, but an erlang environment will do. +language: erlang + +env: + global: + - PACKAGE=@PACKAGE@ + - ROCKSPEC=$PACKAGE-git-1.rockspec + - LUAROCKS_CONFIG=build-aux/luarocks-config.lua + - LUAROCKS_BASE=luarocks-2.0.13 + - LUAROCKS="$LUA $HOME/bin/luarocks" + - LUADOC=luarocks/bin/luadoc + - SPECL=bin/specl + matrix: + - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 + - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 + - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 + +# Tool setup. +install: + - sudo apt-get install help2man + - sudo apt-get install luajit + - sudo apt-get install libluajit-5.1-dev + - sudo apt-get install lua5.1 + - sudo apt-get install liblua5.1-dev + - sudo apt-get install lua5.2 + - sudo apt-get install liblua5.2-dev + # Install a recent luarocks release locally. + - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz + - tar zxvpf $LUAROCKS_BASE.tar.gz + - cd $LUAROCKS_BASE + - ./configure + --prefix=$HOME --lua-version=5.1 --lua-suffix=5.1 + --with-lua-include="/usr/include/lua5.1" + - make all install + - cd .. + # Luadoc has to be installed separately while it is Lua 5.1 only. + @LUADOC_FALSE@ sudo apt-get install luarocks + @LUADOC_FALSE@ sudo luarocks install luadoc + @LUADOC_FALSE@ mkdir -p luarocks/bin + @LUADOC_FALSE@ sed 's|^exec "[^"]*"|exec lua5.1|' `which luadoc` > $LUADOC + @LUADOC_FALSE@ chmod a+rx $LUADOC + +# Configure and build. +script: + - ./bootstrap + - ./configure LUA="$LUA" + - make $LUAROCKS_CONFIG + LUA="$LUA" LUA_INCDIR="$LUA_INCDIR" V=1 + || cat $LUAROCKS_CONFIG config.log + # Set Lua and Shell paths up for local luarocks tree. + - eval `$LUAROCKS path` + - export PATH=`pwd`/luarocks/bin:$PATH + @EXTRA_ROCKS@ + - make rockspecs LUAROCKS="$LUAROCKS" V=1 + || { $LUAROCKS path; cat $ROCKSPEC; } + # LuaRocks make will fail if dependencies are missing. + - $LUAROCKS make $ROCKSPEC + # Use bin/specl if we built it, or else the specl rock we just installed. + - test -f "$SPECL" || SPECL=luarocks/bin/specl; + make check SPECL="$SPECL" V=1 From 2e0a7080f2114c6de15bf5367ea1bcf67a8ccd54 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Sun, 19 May 2013 16:29:03 +0700 Subject: [PATCH 17/34] slingshot: remove from release branch. * slingshot. Remove. This is not in relase tarballs, and should not be on the release branch. Signed-off-by: Gary V. Vaughan --- slingshot | 1 - 1 file changed, 1 deletion(-) delete mode 160000 slingshot diff --git a/slingshot b/slingshot deleted file mode 160000 index f5e4b13..0000000 --- a/slingshot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f5e4b135266d2d959b998f8e420ecd57cd2395f1 From 34eb7bf1cea5d01632a2c7e1982fba8e89a0ba53 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 16 Jan 2014 10:48:49 +1300 Subject: [PATCH 18/34] Release v36. Signed-off-by: Gary V. Vaughan --- .travis.yml | 59 +- COPYING | 27 + ChangeLog | 1024 ++++++++-- GNUmakefile | 50 +- INSTALL | 18 +- Makefile.am | 22 +- Makefile.in | 490 +++-- NEWS | 94 + README.md => README | 2 +- aclocal.m4 | 222 ++- bootstrap | 1771 ++++++++++++----- bootstrap.conf | 40 +- bootstrap.slingshot | 277 --- build-aux/missing | 4 +- build-aux/mkrockspecs | 332 ++- build-aux/release.mk | 37 +- build-aux/rockspecs.mk | 10 +- build-aux/sanity.mk | 6 +- build-aux/specl.mk | 13 +- configure | 141 +- configure.ac | 28 +- doc/classes/std.container.html | 278 +++ doc/classes/std.list.html | 1082 ++++++++++ doc/classes/std.object.html | 392 ++++ doc/classes/std.set.html | 767 +++++++ doc/classes/std.strbuf.html | 245 +++ doc/classes/std.tree.html | 461 +++++ doc/config.ld | 29 + doc/index.html | 140 ++ doc/ldoc.css | 302 +++ doc/modules/std.debug.html | 208 ++ doc/modules/std.functional.html | 501 +++++ doc/modules/std.getopt.html | 248 +++ doc/modules/std.html | 723 +++++++ doc/modules/std.io.html | 371 ++++ doc/modules/std.math.html | 157 ++ doc/modules/std.package.html | 131 ++ doc/modules/std.strict.html | 130 ++ doc/modules/std.string.html | 1076 ++++++++++ doc/modules/std.table.html | 518 +++++ lib/std.lua | 196 ++ lib/std.lua.in | 196 ++ lib/std/base.lua | 157 ++ lib/std/container.lua | 233 +++ std/debug_ext.lua => lib/std/debug.lua | 24 +- {std => lib/std}/debug_init.lua | 0 lib/std/functional.lua | 202 ++ {std => lib/std}/getopt.lua | 158 +- std/io_ext.lua => lib/std/io.lua | 64 +- lib/std/list.lua | 436 ++++ std/math_ext.lua => lib/std/math.lua | 21 +- lib/std/modules.lua | 19 + lib/std/object.lua | 153 ++ std/package_ext.lua => lib/std/package.lua | 14 +- lib/std/set.lua | 287 +++ lib/std/strbuf.lua | 56 + {std => lib/std}/strict.lua | 21 +- std/string_ext.lua => lib/std/string.lua | 165 +- lib/std/table.lua | 184 ++ lib/std/tree.lua | 237 +++ local.mk | 121 +- m4/ax_lua.m4 | 5 +- m4/slingshot.m4 | 29 +- specs/container_spec.yaml | 108 + .../{debug_ext_spec.yaml => debug_spec.yaml} | 4 +- specs/{io_ext_spec.yaml => io_spec.yaml} | 9 +- specs/list_spec.yaml | 441 ++++ specs/{math_ext_spec.yaml => math_spec.yaml} | 4 +- specs/object_spec.yaml | 301 +++ ...ackage_ext_spec.yaml => package_spec.yaml} | 4 +- specs/set_spec.yaml | 328 +++ specs/spec_helper.lua | 29 + specs/specs.mk | 22 +- specs/strbuf_spec.yaml | 79 + ...{string_ext_spec.yaml => string_spec.yaml} | 68 +- .../{table_ext_spec.yaml => table_spec.yaml} | 16 +- specs/tree_spec.yaml | 398 ++++ std/base.lua | 291 --- std/files/base.html | 935 --------- std/files/debug_ext.html | 305 --- std/files/debug_init.html | 158 -- std/files/getopt.html | 357 ---- std/files/io_ext.html | 438 ---- std/files/list.html | 1194 ----------- std/files/math_ext.html | 244 --- std/files/modules.html | 158 -- std/files/object.html | 194 -- std/files/package_ext.html | 206 -- std/files/set.html | 573 ------ std/files/strbuf.html | 240 --- std/files/strict.html | 158 -- std/files/string_ext.html | 1105 ---------- std/files/table_ext.html | 528 ----- std/files/tree.html | 355 ---- std/index.html | 239 --- std/list.lua | 467 ----- std/luadoc.css | 286 --- std/modules.lua | 16 - std/modules/base.html | 931 --------- std/object.lua | 57 - std/set.lua | 167 -- std/std.lua | 48 - std/std.lua.in | 48 - std/std.mk | 62 - std/strbuf.lua | 41 - std/table_ext.lua | 135 -- std/tree.lua | 104 - stdlib-36-1.rockspec | 40 + ...lib-35-1.rockspec => stdlib-git-1.rockspec | 13 +- travis.yml.in | 55 +- 110 files changed, 15700 insertions(+), 11663 deletions(-) create mode 100644 COPYING rename README.md => README (96%) delete mode 100644 bootstrap.slingshot create mode 100644 doc/classes/std.container.html create mode 100644 doc/classes/std.list.html create mode 100644 doc/classes/std.object.html create mode 100644 doc/classes/std.set.html create mode 100644 doc/classes/std.strbuf.html create mode 100644 doc/classes/std.tree.html create mode 100644 doc/config.ld create mode 100644 doc/index.html create mode 100644 doc/ldoc.css create mode 100644 doc/modules/std.debug.html create mode 100644 doc/modules/std.functional.html create mode 100644 doc/modules/std.getopt.html create mode 100644 doc/modules/std.html create mode 100644 doc/modules/std.io.html create mode 100644 doc/modules/std.math.html create mode 100644 doc/modules/std.package.html create mode 100644 doc/modules/std.strict.html create mode 100644 doc/modules/std.string.html create mode 100644 doc/modules/std.table.html create mode 100644 lib/std.lua create mode 100644 lib/std.lua.in create mode 100644 lib/std/base.lua create mode 100644 lib/std/container.lua rename std/debug_ext.lua => lib/std/debug.lua (83%) rename {std => lib/std}/debug_init.lua (100%) create mode 100644 lib/std/functional.lua rename {std => lib/std}/getopt.lua (63%) rename std/io_ext.lua => lib/std/io.lua (64%) create mode 100644 lib/std/list.lua rename std/math_ext.lua => lib/std/math.lua (66%) create mode 100644 lib/std/modules.lua create mode 100644 lib/std/object.lua rename std/package_ext.lua => lib/std/package.lua (61%) create mode 100644 lib/std/set.lua create mode 100644 lib/std/strbuf.lua rename {std => lib/std}/strict.lua (61%) rename std/string_ext.lua => lib/std/string.lua (81%) create mode 100644 lib/std/table.lua create mode 100644 lib/std/tree.lua create mode 100644 specs/container_spec.yaml rename specs/{debug_ext_spec.yaml => debug_spec.yaml} (97%) rename specs/{io_ext_spec.yaml => io_spec.yaml} (90%) create mode 100644 specs/list_spec.yaml rename specs/{math_ext_spec.yaml => math_spec.yaml} (97%) create mode 100644 specs/object_spec.yaml rename specs/{package_ext_spec.yaml => package_spec.yaml} (97%) create mode 100644 specs/set_spec.yaml create mode 100644 specs/spec_helper.lua create mode 100644 specs/strbuf_spec.yaml rename specs/{string_ext_spec.yaml => string_spec.yaml} (89%) rename specs/{table_ext_spec.yaml => table_spec.yaml} (97%) create mode 100644 specs/tree_spec.yaml delete mode 100644 std/base.lua delete mode 100644 std/files/base.html delete mode 100644 std/files/debug_ext.html delete mode 100644 std/files/debug_init.html delete mode 100644 std/files/getopt.html delete mode 100644 std/files/io_ext.html delete mode 100644 std/files/list.html delete mode 100644 std/files/math_ext.html delete mode 100644 std/files/modules.html delete mode 100644 std/files/object.html delete mode 100644 std/files/package_ext.html delete mode 100644 std/files/set.html delete mode 100644 std/files/strbuf.html delete mode 100644 std/files/strict.html delete mode 100644 std/files/string_ext.html delete mode 100644 std/files/table_ext.html delete mode 100644 std/files/tree.html delete mode 100644 std/index.html delete mode 100644 std/list.lua delete mode 100644 std/luadoc.css delete mode 100644 std/modules.lua delete mode 100644 std/modules/base.html delete mode 100644 std/object.lua delete mode 100644 std/set.lua delete mode 100644 std/std.lua delete mode 100644 std/std.lua.in delete mode 100644 std/std.mk delete mode 100644 std/strbuf.lua delete mode 100644 std/table_ext.lua delete mode 100644 std/tree.lua create mode 100644 stdlib-36-1.rockspec rename lua-stdlib-35-1.rockspec => stdlib-git-1.rockspec (62%) diff --git a/.travis.yml b/.travis.yml index 8103f11..6f3f7be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,20 +3,22 @@ language: erlang env: global: - - PACKAGE=lua-stdlib + - PACKAGE=stdlib - ROCKSPEC=$PACKAGE-git-1.rockspec - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - - LUAROCKS_BASE=luarocks-2.0.13 + - LUAROCKS_BASE=luarocks-2.1.1 - LUAROCKS="$LUA $HOME/bin/luarocks" - - LUADOC=luarocks/bin/luadoc - - SPECL=bin/specl matrix: - - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 - - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 - - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 + - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 + - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 LUA_SUFFIX=5.2 + - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 LUA_SUFFIX=5.1 # Tool setup. install: + # Put back the links for libyaml, which are missing on recent Travis VMs + - test -f /usr/lib/libyaml.so || + sudo find /usr/lib -name 'libyaml*' -exec ln -s {} /usr/lib \; + - sudo apt-get install help2man - sudo apt-get install luajit - sudo apt-get install libluajit-5.1-dev @@ -24,37 +26,50 @@ install: - sudo apt-get install liblua5.1-dev - sudo apt-get install lua5.2 - sudo apt-get install liblua5.2-dev - # Install a recent luarocks release locally. + # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz - cd $LUAROCKS_BASE - ./configure - --prefix=$HOME --lua-version=5.1 --lua-suffix=5.1 - --with-lua-include="/usr/include/lua5.1" + --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX + --with-lua-include=$LUA_INCDIR - make all install - cd .. - # Luadoc has to be installed separately while it is Lua 5.1 only. - - sudo apt-get install luarocks - - sudo luarocks install luadoc - - mkdir -p luarocks/bin - - sed 's|^exec "[^"]*"|exec lua5.1|' `which luadoc` > $LUADOC - - chmod a+rx $LUADOC # Configure and build. script: - - ./bootstrap + # Initial bootstrap to build luarocks-config.lua, before we've + # installed our rocks. + - ./bootstrap --skip-rock-checks - ./configure LUA="$LUA" - make $LUAROCKS_CONFIG LUA="$LUA" LUA_INCDIR="$LUA_INCDIR" V=1 || cat $LUAROCKS_CONFIG config.log + # Set Lua and Shell paths up for local luarocks tree. + # this package depends on will be installed. - eval `$LUAROCKS path` - export PATH=`pwd`/luarocks/bin:$PATH + + # Install extra rocks into $LUAROCKS_CONFIG rocks tree. - $LUAROCKS install lyaml; $LUAROCKS install specl; + # LDoc 1.4.0 is not in luarocks yet, and LDoc master has no rockspec :( + - $LUAROCKS install http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec + + # Make git rockspec for this package. - make rockspecs LUAROCKS="$LUAROCKS" V=1 || { $LUAROCKS path; cat $ROCKSPEC; } - # LuaRocks make will fail if dependencies are missing. - - $LUAROCKS make $ROCKSPEC - # Use bin/specl if we built it, or else the specl rock we just installed. - - test -f "$SPECL" || SPECL=luarocks/bin/specl; - make check SPECL="$SPECL" V=1 + + # The git rockspec will rerun bootstrap, and check any rock versions + # in bootstrap.conf:buildreq this time. + - $LUAROCKS make $ROCKSPEC LUA="$LUA" + + # Run self-tests in the `luarocks make` build tree. + # Use bin/specl if present, or else the specl rock from EXTRA_ROCKS + # above. + - if test -f luarocks/bin/specl; then export SPECL=luarocks/bin/specl; + elif test -f bin/specl; then export SPECL=bin/specl; fi + - export LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" + - export LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" + - export LUA_INIT=; export LUA_INIT_5_2= + - make check SPECL="$SPECL" V=1 diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..8aecd8e --- /dev/null +++ b/COPYING @@ -0,0 +1,27 @@ +This software comprises files that are copyright their respective +authors (see the AUTHORS file for details), and distributed under +the terms of the MIT license (the same license as Lua itself), +unless noted otherwise in the body of that file. + +==================================================================== +Copyright (C) 2002-2014 stdlib authors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- +MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +==================================================================== diff --git a/ChangeLog b/ChangeLog index 43bcae0..341c8ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,785 @@ +2014-01-16 Gary V. Vaughan + + Release version 36 + * NEWS: Record release date. + +2014-01-13 Gary V. Vaughan + + configury: use explicit lists instead of $(wildcard ...). + * local.mk (dist_classes_DATA, dist_modules_DATA): Only GNU make + supports $(wildcard ...) expressions, and Automake complains + every time it sees one. List files explicitly. + ($(dist_doc_DATA)): Add $(dist_classes_DATA) and + $(dist_modules_DATA) to LHS of this rule so that make knows it + has to run LDoc to create those files. + + slingshot: resync for subdirectory bootstrap fix. + * slingshot: Sync with upstream. + + slingshot: sync with upstream, for rockspecs in $buildreq. + * slingshot: Sync with upstream. + * bootstrap: Sync with slingshot. + * configure.ac (SPECL_MIN): Remove. + * bootstrap.conf (buildreq): Add ldoc and specl rockspecs. + * .travis.yml: Regenerate, but manually splice in the LDoc-1.4.0 + luarocks install while waiting for a luarocks release. + +2014-01-05 Gary V. Vaughan + + slingshot: sync with upstream. + Fix the annoying contest.sed file dropping bug. + * slingshot: Sync with upstream. + * bootstrap: Sync with slingshot. + + doc: distribute ldoc classes and modules documentation. + * local.mk (filesdir, dist_files_DATA): Rename from these... + (classesdir, dist_classes_DATA): ...to these. + (dist_classes_DATA, dist_modules_DATA): Use correct paths in + gmake wildcard expression. + +2014-01-04 Gary V. Vaughan + + maint: update copyright notices to include 2014. + * .x-update-copyright: New file. Exclude files not owned by this + project from update-copyright rules. + * boootstrap.conf, configure.ac, local.mk: Bump copyright year. + + travis: horrid workaround for crashy LDoc master vs apt-get luarocks. + * slingshot: Sync for Travis fixes. + * .travis.yml: Temporary code to fetch a custom stable version of + LDoc that doesn't crash on stdlib doc-comments. + + maint: fix copyright attribution in COPYING. + * COPYING: Correct year and authors in copyright statement. + + slingshot: sync with upstream and simplify accordingly. + * slingshot: Sync with upstream. + * bootstrap: Update from slingshot. + * configure.ac (AM_INIT_AUTOMAKE): Remove 'foreign'. Slingshot + now handles missing README automatically. + * bootstrap.slingshot: Remove. No longer required. + * bootstrap.conf: Remove bootstrap.slingshot source boilerplate. + (stdlib_force_changelog): Remove. Automated by slingshot now. + * INSTALL: Remove. Autotools copies in the canonical version + automatically. + * COPYING: New file, with MIT License, to avoid Autotools + copying over a standard GPLv3 COPYING boilerplate. + * .gitignore: Update. + + slingshot: sync with upstream, and update copyright years. + * slingshot: Update, particularly for update-copyright support. + * bootstrap, bootstrap.slingshot: Update from slingshot. + +2014-01-01 Gary V. Vaughan + + slingshot: sync with upstream. + * slingshot: Sync with latest upstream, particularly for Travis fixes. + * .travis.yml: Regenerate. Plus temporary patch to run gvvaughan/next + branch of LDoc during integration until stevedonovan/master is fixed. + +2013-12-11 Gary V. Vaughan + + tree: derive from std.container. + * specs/tree_spec.yaml: Replace object methods with module + functions throughout. + Add specs for inheritted functionality. + * lib/std/tree.lua: Rewrite as a derivative of std.container. + Change object methods to Container style module functions. + * NEWS: Update. + + doc: update object constructor _function documentation. + * lib/std/container.lua: Update module doc-comment to reflect + simplification of passing module functions in _functions table. + (std.container): Update _function description. + * lib/std/object.lua (std.object): Likewise. + * lib/std/set.lua (std.set): Likewise. + + specs: improve expectation description. + * specs/set_spec.yaml: Write "shows the type name" instead of + "contains the type". + + refactor: automatically fill method functions form _functions table. + * lib/std/container.lua (metatable.__call): Copy entries from + newly passed _functions table to object. + * lib/std/set.lua (Set): Delete manual copy of method functions. + + set: derive from std.container, keys no longer clash with method names. + * specs/set_spec.yaml: Replace object methods with prototype + functions through out. + Check that set elements with the same name as a prototype + function behave properly. + * lib/std/set.lua: Rewrite as a derivative of std.container. + Change object methods to Container style prototype functions. + * NEWS: Update. + +2013-12-10 Gary V. Vaughan + + list: remove trailing whitespace. + * lib/std/list.lua: Remove trailing whitespace. + + container: new module for objects that use [] to access contents. + * specs/container_spec.yaml: Specify behaviour of Container + objects. + * specs/specs.mk (specl_SPECS): Add specs/container_spec.yaml. + * specs/object_spec.yaml: Remove duplicate tests. + * doc/config.ld (file), local.mk (dist_luastd_DATA): Add + lib/std/container.lua. + * lib/std/container.lua: New file. Implement Container objects. + They have no methods, so that __index can be used for accessing + contents instead. + * lib/std/object.lua: Vastly improved doc-comments. + Simplify drastically in light of Container implementation. + * NEWS: Update. + +2013-12-09 Gary V. Vaughan + + Revert "maint: move lua extension sources to $top_srcdir/ext." + This reverts commit 4d51ca63a1eedd3759201db8b3df850a658856e6. + + I have no idea why I thought moving Lua libraries from the lib + tree to the Lua C extensions ext tree seemed like a good idea. + Undo the damage. + * ext/: Rename back to lib/. + * local.mk (std_path, dist_lua_DATA, dist_luastd_DATA) + (mkrockspecs_args, EXTRA_DIST, dist_files_DATA) + (dist_modules_DATA): Adjust. + * doc/config.ld (file): Adjust. + * .gitignore: Update. + +2013-12-09 Gary V. Vaughan + + table: add string support to totable function. + * ext/std/table.lua (totable): When passed a string, return a + table of each character in the string. + * NEWS: Update. + + specs: simplify the tree merge specs. + * specs/tree_spec.yaml (tree merge): comparing non-leaf nodes + is not a fair test, better to set k3 to a different string + that can be tested before and after the merge without worrying + about whether a table node is coerced to a tree node. + +2013-11-28 Gary V. Vaughan + + specs: don't assume in order traversal by tree.nodes. + * specs/tree_spec.yaml (node): Use `should_contain.all_of` + in place of `should_equal` to avoid enforcing a particular + traversal order. + + tree: fix broken tests, and improve doc-comments (Fixes #40) + * specs/tree_spec.yaml (inodes, nodes): Be sure to clone iterator + returned paths before storing. Some corrections to the expected + results. + Remove pending "see issue #40" instances. + (merge): Fix tests. Remove pending "see issue #40" instances. + * ext/std/tree.lua (nodes): Much improved doc-comment. + (merge): Assert the arguments are actual tree nodes, because + raw tables do not work! + + doc: update doc-comments for latest LDoc master. + * doc/config.ld (metamethod): Delete. Metamethods are now + separated out automatically. + * ext/std/list.lua: Describe use of object methods as module + functions. + Update doc-comments. + * ext/std/object.lua, ext/std/set.lua, ext/std/strbuf.lua, + ext/std/strict.lua, ext/std/tree.lua: Update doc-comments. + + tree: add specl specs, and fix simple API inconsistencies. + * specs/tree_spec.yaml: New file. Examples of how tree APIs + should behave. + * specs/specs.mk (specl_SPECS): Add specs/tree_spec.yaml. + * ext/std/base.lua (ileaves, leaves): Report non-table arguments. + * ext/std/tree.lua (clone, inodes, nodes, merge): Likewise. + +2013-11-27 Gary V. Vaughan + + string: report assert failures from assert caller level. + * ext/std/string.lua (assert): Call error with level 2, to report + errors from the assert caller not assert itself. + + tree: fix argument order for list.foldl call. + The argument order for list.foldl changed in 9fe27bb, but one + call site wasn't updated to match. + * ext/std/tree.lua (metatable.__index): Use new argument order + for list.foldl call. + +2013-11-27 Reuben Thomas + + Remove some spurious comment markers in docstrings. + These were introduced by commit 31b314c835 converting doc-comments to + LDoc 1.4. + +2013-11-26 Gary V. Vaughan + + travis: replace recently missing links for libyaml + Rerunning previously passing integration test shows that the + multilibbed libyaml libraries are no longer available from + /usr/lib alongside other libs - maybe an OS upgrade, or an + upstream packaging error? + * .travis.yml (install): Remove libyaml-dev reinstall. + Run a shell find command to link the multilib libyaml libs + back into /usr/lib. If this command starts failing in future + then it should mean libyaml has moved back to the proper place + and we're failing to relink it manually, so this workaround + can be removed. + + maint: install libyaml-dev for Travis. + Seems recent tests have been failing because libyaml-dev is no + longer installed by default. + * .travis.yml (install): Add libyaml-dev which pulls in libyaml. + + doc: distinguish object and class methods in object doc-comments. + * ext/std/object.lua (clone): Rename first argument to self, and + remove associated @param as a hint to LDoc. + (stringify, totable): Likewise. + (metatable): Document important fields. + (metatable.__call): Add documentation. + + doc: use a more topographical ordering for document sidebar. + Now that the latest LDoc doesn't enforce strict alphabetical + ordering, reorder the documentation into a more topographical + order for easier reading. + * doc/config.ld (file): Reorder for clarity. + + doc: separate camelCaseCompat methods to avoid LDoc warnings. + Using the @export feature of LDoc provides the flexibility to + change the exported functions from a single table, but we also + have to be careful not to sweep up undocumented access points + in the same table, otherwise LDoc correctly warns us that those + functions have no doc-comments. + * ext/std/getopt.lua (getOpt, processArgs, usageInfo): Move + to a separate table, and merge back into the module table before + return. + * ext/std/io.lua (processFiles): Likewise. + * ext/std/list.lua (indexKey, indexValue, mapWith, zipWith): + Likewise. + * ext/std/string.lua (escapePattern, escapeShell, ordinalSuffix): + Likewise. + + doc: markup std.string.escape_string correctly for LDoc. + * ext/std/string.lua (escape_string): Add missing leading hyphen. + + doc: LDoc master now handles local references differently. + * .travis.yml (install): Switch to github master rockspec. + * ext/std/list.lua (enpair, depair, __concat, __add): Adjust + @see argument. + * ext/std/object.lua (__totable, __tostring): Likewise. + * ext/std/set.lua (__add, __sub, __mul, __div, __le, __lt): + Likewise. + * ext/std/strbuf.lua (__concat, __tostring): Likewise. + +2013-11-18 Gary V. Vaughan + + doc: point to updated online LDoc documentation. + * README.md (Documentation): Refer to latest LDoc docs. + + maint: remove last references to luadoc. + * local.mk (dist_doc_DATA): Remove luadoc.css. Add ldoc.css. + + travis: use unofficial ldoc 1.4.0 release candidate. + We're using features from the release candidate already, so + temporarily point the travis installer to that rockspec while + waiting for an official release. + * .travis.yml: Adjust ldoc rockspec location. + + list: fix broken specs. + * ext/std/list.lua (depair): Needs to be the inverse operation of + enpair, which requires returning a bare table, and not a List + object. + + .gitignore: ignore ldoc output, not luadoc output. + * .gitignore: Remove /doc/luadoc.css. Add /doc/ldoc.css. + + getopt: revert an accidental comment deletion. + * ext/std/getopt.lua (makeOptions): Revert accidental deletion. + + doc: convert doc-comments to LDoc 1.4. + * doc/config.ld: New file. Configuration for LDoc. + * local.mk (EXTRA_DIST): Add it. + (dist_doc_DATA): Remove Luadoc files. Add LDoc files. + ($(dist_doc_DATA)): Invoke LDoc. + * configure.ac (SS_CONFIG_TRAVIS): Request ldoc instead of luadoc. + * .travis.yml: Regenerate. + * .gitignore: Adjust. + * ext/std.lua.in, ext/std/base.lua, ext/std/debug.lua, + ext/std/functional.lua, ext/std/getopt.lua, ext/std/io.lua, + ext/std/list.lua, ext/std/math.lua, ext/std/modules.lua, + ext/std/object.lua, ext/std/package.lua, ext/std/set.lua, + ext/std/strbuf.lua, ext/std/strict.lua, ext/std/string.lua, + ext/std/table.lua, ext/std/tree.lua: Convert doc-comment syntax to + richer LDoc 1.4 format. + +2013-11-15 Gary V. Vaughan + + maint: move lua extension sources to $top_srcdir/ext. + For consistency with other Lua projects I maintain, rename the + lib directory to ext. + * lib/: Rename to ext/. + * local.mk (std_path, dist_lua_DATA, dist_luastd_DATA) + (mkrockspecs_args, EXTRA_DIST, dist_doc_DATA, dist_files_DATA) + (dist_modules_DATA): Adjust. + * .gitignore: Update. + + bootstrap: drop 'lua-' prefix from project name. + * configure.ac (AC_INIT): Set name to 'stdlib'. + * .travis.yml: Regenerate. + +2013-09-15 Gary V. Vaughan + + slingshot: sync with upstream. + * slingshot: Update to latest revision, particularly to get the + fix for release announcement content. + * bootstrap: Upgrade from latest slingshot. + * .travis.yml: Regenerate. + +2013-06-27 Gary V. Vaughan + + list: std.list returns the List prototype object. + Removing the separation between List prototype and the module + table that used to wrap it, for consistency with the other + Object specialisations. We break backwards compatibilitf here + though because the argument ordering used to be different for + several functions depending on whether they were called through + the module table, or as List methods. The List method ordering + (i.e. list argument first) wins out here, because that is a + prerequisite of being able to call object methods with the Lua + : syntax. + * specs/list_spec.yaml: Remove examples of constructing a List + from the module table, and with the `new` command. + * lib/std/list.lua: Much simplified by removal of the module + table. + (filter, foldl, foldr, index_key, index_value, map, map_with) + (project, shape, zip_with): The list operand is always first + now, whether called with a `.' or a `:'. + Adjust all callers. + (new): Remove. Adjust all callers. + * NEWS: Update. + + strbuf: std.strbuf returns the strbuf prototype object. + Fix some latent bugs caused by the artificial separation between + the metatable of strbuf and strbuf.StrBuf, by removing the + distinction between the two. `require "std.strbuf"` returns the + actual StrBuf object, ready to go! + * specs/strbuf_spec.yaml: Remove examples of constructing a StrBuf + from the module table, and with the `new` command. + * lib/std/strbuf.lua: No need to wrap the StrBuf prototype in an + additional layer of abstraction to return a module table containing + the StrBuf prototype. Just return StrBuf directly. + (strbuf.new): Remove. + Adjust all callers. + + set: std.set returns the Set prototype object. + Fix some latent bugs caused by the artificial separation between + the metatable of set and set.Set, by removing the distinction + between the two. `require "std.set" returns the actual Set object, + ready to go! + * specs/set_spec.yaml: remove examples of constructing a set from + the module table, and with the `new` command. + * lib/std/set.lua: No need to wrap the Set prototype in an + additional layer of abstraction to return a module table containing + the Set prototype. Just return Set directly. + (set.new): Remove. + Adjust all callers. + + object: std.object returns the root object. + Fix some latent bugs caused by the artificial separation between + the metatable of object and object.Object, by removing the + distinction between the two. `require "std.object"` returns the + actual root object, ready to go! + * specs/object_spec.yaml: Remove examples of constructing an + object from the object module table and the `new` method. + * lib/std/object.lua: No need to wrap the root object in an + additional layer of abstraction to return a module table containing + the root object. Just return the root object directly. + (object.new): Remove. + Adjust all callers. + * NEWS: Update. + + object: don't assume object metatable __index is always a table. + * lib/std/object.lua (clone): Only merge new object metatable + methods when both metatables have a table type __index entry. + (metatable:__call): Let Lua do the lookup for an object clone + function, incase __index is a function. + + object: be consistent with various object constructors. + * specs/object_spec.yaml: Specify behaviour for Object:clone {} + and object.new () constructors, with single table initialiser and + parameter list respectively, plus the Object {} and object () + syntactic sugars for each. + * specs/list_spec.yaml, specs/set_spec.yaml, + specs/strbuf_spec.yaml: Likewise for other objects to make sure + all are consistent. + * lib/std/list.lua, lib/std/set.lua, lib/std/strbuf.lua: Implement + the specified behaviours. + + object: fix __lt and __le support with shared metatables. + * specs/object_spec.yaml: Specify desired behaviour with new + examples for metatable sharing. + * lib/std/object.lua (metaentry): New helper function. + (object_type, clone, stringify, totable): Factor out of root + object initialiser. + (clone): Maintain separation between "_" prefixed fields, kept + in the new object metatable, and everything else in the object. + If the newly instantiated object requires a new metatable to + support the additional "_" prefixed keys, create it, otherwise + share the prototype's metatable. + Additionally, when creating a new metatable, be sure to merge + in __index methods from the prototype metatable. + (Object): Much simplified! + (metatable): Set type, methods and metamethods for root object. + * lib/std/list.lua (methods, metalist, new): Refactored from + these... + (List, new): ...to these, also simplifed accordingly. + * lib/std/set.lua (M, metaset, new): Refactored from these... + (M, new): ...to this, much simplified. + * specs/list_spec.yaml, specs/set_spec.yaml: Add more examples + to specify metatable propagation behaviour, and refactor for + clarity and consistency. + * NEWS: Update. + + set: share metatable so that __le and __lt work. + * specs/set_spec.yaml: Many more examples, in particular to check + behaviour of __le and __lt comprehensively. + * lib/std/set.lua (metaset): New metatable shared by all sets. + (new): Adjust. + * NEWS: Update. + + travis: regenerate .travis.yml. + * .travis.yml: specl-8 is out, so don't try to work around it + any more! + + specs: update spec_helper for Grand Renaming II™. + * specs/spec_helper.lua: Fix table_ext reference for name change + to straight table. + +2013-05-30 Gary V. Vaughan + + object: __tostring should call __totable metamethod, not method. + * lib/std/object.lua (new.__tostring): Because we have to set a + separate metatable for objects that have __lt or __le metamethods, + self:__totable () is not always the same as getmetatable (self). + __totable (self). Use the longhand so that __tostring calls the + right function in both cases. + +2013-05-23 Gary V. Vaughan + + travis: use specl from git until specl 8 is released. + * .travis.yml: Fetch the rockspec from github. Install it. + + list: derive from `std.object`. + * specs/list_spec.yaml: Describe expected behaviour of list as an + Object. + * specs/specs.mk (specl_SPECS): Add specs/list_spec.yaml. + * lib/std/list.lua (metalist): __lt and __le metamethods only + work if both objects share the same metatable... this one for + list objects. + (new): Return a new Object, with metalist as the metatable, + and _clone doctored to propagate the metalist metatable. + (M): Return a callable table that forwards module calls to the + `new` function. + * NEWS: Update. + + object: be sure to run tostring on array elements before table.concat. + * lib/std/object.lua (new.__tostring): table.concat requires that + all elements already be strings, so call tostring on the array + part of the object table before passing to table.concat. + +2013-05-22 Gary V. Vaughan + + object: respond to tostring() with stringified table of non-hidden fields. + Rather than add individual __tostring metamethods to every object + type, implement a general stringification algorithm in the base + object, to return the type followed by the array part of the object, + and then the dictionary part of the object. + * specs/object_spec.yaml (__tostring): Describe desired behaviour. + * specs/set_spec.yaml (__tostring): Likewise. + * lib/std/object.lua: Don't overwrite core table functions with + std.base. Adjust all callers. + (new.__tostring): return stringification of non-hidden fields. + * lib/std/set.lua (new.__tostring): Remove. Inheritted base object + metamethod is equivalent. + + configury: specl 8 required for stdlib compatible objects. + * configure.ac (SPECL_MIN): Bump to Specl 8. Earlier versions use + an incompatible object system, which crash when fed recently + enhanced stdlib objects. + + string: prettyprint valid symbol keys without spurious quoting. + * specs/string_spec.yaml (prettytostring): Remove quoting from + examples with valid symbols as keys. Add an example with some + invalid symbol names as table keys. + * lib/std/string.lua (prettytostring): Skip the key quoting + code unless a key is not a string, or contains any non-word + character. + + string: display prettyprinted table keys in table.sort order. + When comparing actual and expected output in unit tests, or with + Specl matchers, it's quite difficult to write robust examples when + the output of prettyprint is randomised for tables. This commit + ensures that table keys are always output in the same order. + * specs/string_spec.yaml (prettytostring): Examples of desired + behaviour for string.prettytostring. + * lib/std/string.lua (render): Use a sorted list of keys to + determine the order in which they are output. + * NEWS: Update. + + object: __totable and __index support. + Provide object.type, analagously to io.type. + * specs/object_spec.yaml (__totable): Specify desired + behaviour. + * specs/set_spec.yaml (__totable): Likewise. + * specs/strbuf_spec.yaml (__totable): Likewise. + * lib/std/object.lua (typeof): Rename from this... + (M.type): ...to this, to support e.g. object:type (). + (new.__totable): Return a table of non `_` prefixed object + elements. + (new.__index): Defer to methods in M, when the object itself has + none. + * lib/std/getopt.lua (argtype): Set of valid argtype keys. + (getopt): Comparing an Option's type field to nil doesn't work, + because of the Object:type () method it shadows. Instead check + for a value not in the argtype set. + (usageinfo): Reorder type tests to avoid the same Object:type() + problem. + * lib/std/set.lua: Use object.type instead of object.typeof. + * specs/object_spec.yaml, specs/set_spec.yaml, + specs/strbuf_spec.yaml: Adjust. + * NEWS: Update. + + maint: The Grand Renaming II™ - use `require "std.string"` etc. + Now that individual modules are loaded from the std subdirectory, + remove the spurious "_ext" suffix so that `require "std.io_ext"` + is not needed any more. + * lib/std/debug_ext.lua, specs/debug_ext_spec.yaml, + lib/std/io_ext.lua, specs/io_ext_spec.yaml, + lib/std/math_ext.lua, specs/math_ext_spec.yaml, + lib/std/package_ext.lua, specs/package_ext_spec.yaml, + lib/std/string_ext.lua, specs/string_ext_spec.yaml, + lib/std/table_ext.lua, specs/table_ext_spec.yaml: Rename from + these... + * lib/std/debug.lua, specs/debug_spec.yaml, lib/std/io.lua, + specs/io_spec.yaml, lib/std/math.lua, specs/math_spec.yaml, + lib/std/package.lua, specs/package_spec.yaml, lib/std/string.lua, + specs/string_spec.yaml, lib/std/table.lua, specs/table_spec.yaml: + ...to these. Adjust all require calls. + * specs/io_spec.yaml, specs/string_spec.yaml, specs/table_spec.yaml + (extensions): Add some missing apis. + * lib/std.lua.in, lib/std/modules.lua: Adjust and simplify. + * specs/specs.mk (specl_SPECS): Adjust. + * local.mk (dist_luastd_DATA): Adjust. + * NEWS: Update. + + object: don't trigger table metamethods for type lookup. + * lib/std/object.lua (typeof): When looking up the type of an + object table with no _type field, don't use __index metamethod. + +2013-05-19 Gary V. Vaughan + + configury: support non-autotool LuaRocks installation. + * slingshot: Sync with upstream. + * local.mk (mkrockspecs_args): Add --module-dir so that latest + mkrockspecs will use the LuaRocks builtin build.type. + * std/std.lua.in, std/base.lua, std/debug_ext.lua, + std/debug_init.lua, std/functional.lua, std/getopt.lua, + std/io_ext.lua, std/list.lua, std/math_ext.lua, std/modules.lua, + std/oject.lua, std/package_ext.lua, std/set.lua, + std/strbuf.lua, std/strict.lua, std/string_ext.lua, + std/table_ext.lua, std/tree.lua: Move from here... + * lib/std.lua.in, lib/std/base.lua, lib/std/debug_ext.lua, + lib/std/debug_init.lua, lib/std/functional.lua, lib/std/getopt.lua, + lib/std/io_ext.lua, lib/std/list.lua, lib/std/math_ext.lua, + lib/std/modules.lua, lib/std/oject.lua, lib/std/package_ext.lua, + lib/std/set.lua, lib/std/strbuf.lua, lib/std/strict.lua, + lib/std/string_ext.lua, lib/std/table_ext.lua, lib/std/tree.lua: + ...to here. + * local.mk (std_path): Adjust. + * std/.gitignore: Remove. Consolidate into... + * .gitignore: ...here. + * std/std.mk: Remove. Consolidate into... + * local.mk: ...hore. + * NEWS: Update. + +2013-05-16 Gary V. Vaughan + + NEWS: fix poor grammar in set to object entry. + * NEWS: Fix poor grammar in set to object entry. + + object: rename object.Object to object.new for consistency. + * std/object.lua (Object): Rename from this... + (new): ...to this. Adjust all callers. + * specs/object_spec.yaml: Adjust. + * NEWS: Update. + + set: derive from `std.object.Object`. + * specs/set_spec.yaml: Describe expected behaviour of set as an + Object. + * specs/spec_helper.lua (have_member): New custom Specl matcher. + * specs/specs.mk (specl_SPECS): Add specs/set_spec.yaml. + (EXTRA_DIST): Add specs/spec_helper.lua. + * std/set.lua (delete, insert): Return the modified set. + (difference, intersection, propersubset, subset) + (symmetric_difference, union): Coerce a table in argument 2 to a + set. + (new): Return a new Object, with metamethods rolled in. + (M): Return a callable table that forwards module calls to the + `new` function. + * NEWS: Update. + +2013-05-15 Gary V. Vaughan + + strbuf: derive from `std.object.Object`. + * specs/strbuf_spec.yaml: Describe expected behaviour of strbuf as + an Object. + * specs/specs.mk (specl_SPECS): Add specs/strbuf_spec.yaml. + * std/strbuf.lua (new): Return a new Object, with metamethods and + object methods rolled in. + (M): Return a callable table that forwards module calls to the + `new` function. + * NEWS: Update. + + object: bake in inherited object type names. + * specs/object_spec.yaml: New file. Examples of how typed objects + should behave. + * specs/specs.mk (specl_SPECS): Add specs/object_spec.yaml. + * std/table_ext.lua (clone, clone_rename, merge): Move from here... + * std/base.lua (clone, clone_rename, merge): ...to here. + * std/table_ext.lua (M.clone, M.clone_rename, M.merge): Re-export + implementations from `std.base`. + * std/object.lua (Object._type): Name the `type` of this object. + (typeof): Insepet the type of an object, falling back on system + type for non-objectes. + Return the public interface table, with a `__call`able metatable + that delegates to Object for instantiation. + +2013-05-14 Gary V. Vaughan + + configury: bump minimum specl version to release 7. + Specl 6 has a bug in `should_contain` matcher that makes the + package_ext checks fail spuriously. + * configure.ac (SPECL_MIN): Bump to 7. + +2013-05-13 Gary V. Vaughan + + string_ext: make escape_pattern compatible with Lua 5.2. + Lua 5.2 complains of an illegal character if a non-pattern meta + character is preceded by a '%'. + * std/string_ext.lua (escape_pattern): Escape only meta-chars. + * specs/string_ext_spec.yaml (escape_pattern): Adjust example + code to match. + * NEWS: Update. + +2013-05-12 Gary V. Vaughan + + refactor: move base.lua methods to more appropriate modules. + Move things around to remove more trampling of _G, and break the + remaining dependency loops, so that modules can all be required + independently. + * std/list.lua (M.append, M.compare, M.concat, M.elems, M.ileaves) + (M.leaves, M.new): Move from here... + * std/base.lua (M.append, M.compare, M.concat, M.elems, M.ileaves) + (M.leaves, M.new): ..to here, for breaking remaining dependency loops. + * std/list.lua (M.append, M.compare, M.concat, M.elems, M.new): + Import from base, and reexport. + * std/base.lua (_G.inodes, _G.nodes): Move from here... + * std/tree.lua (M.inodes, M.nodes): ...to here. + (M.leaves, M.ileaves): Import from base, and reexport. + * std/base.lua (_G.pack, _G.ripairs, _G.totable): Move from here... + * std/table_ext.lua (M.pack, M.ripairs, M.totable): ...to here. + * specs/table_ext_spec.yaml (pack, ripairs, totable): Add pending + example descriptions. + * std/base.lua (_G.metamethod, _G.id, _G.bind, _G.curry, _G.compose) + (_G.memoize, _G.eval, _G.collect, _G.map, _G.filter, _G.fold, _G.op): + Move from here... + * std/functional.lua (M.metamethod, M.id, M.bind, M.curry, M.compose) + (M.memoize, M.eval, M.collect, M.map, M.filter, M.fold, M.op): + New new module. ...to here. + * std/modules.lua: Add std.functional. + * std/std.mk (nobase_dist_lua_DATA): Add std/functional.lua. + * std/base.lua (_G.die, _G.warn): Move from here... + * std/io_ext.lua (M.die, M.warn): ...to here. + * std/std.lua.in: Reexport all recently modularized APIs into _G. + * std/getopt.lua: Explicitly import used modules. + * std/set.lua, std/strbuf.lua: Rearrange definitions to match other + modules. + * std/string_ext.lua: Require std.functional for metamethod(). + (_tostring): Be explicit when saving a handle for _G.tostring. + * NEWS: Update. + + debug_ext: use correct require dependencies. + * std/debug_ext.lua (say): Be explicit about the use of enhanced + string.tostring. + Be sure to require "list" before using its methods. + +2013-05-11 Gary V. Vaughan + + configury: bump release number to 36. + * configure.ac (AC_INIT): Bump release number to 36. + + maint: no need to gitignore files we no longer generate. + * .gitignore: Remove luarocks-config.lua and release-notes-* from + ignore list. + 2013-05-06 Gary V. Vaughan + slingshot: Update. + * slingshot: Update. + * configure.ac (AC_INIT): Package name has to match gnulib repo- + name for generated rockspecs to find the tag zipballs. + * .gitignore: Move /stdlib-*.tar.gz to /lua-stdlib-*.tar.gz. + * .travis.yml: Regenerate. + + travis: make the lua5.1 hacked luadoc executable. + * slingshot: Upgrade. + * .travis.yml: Regenerate. + + travis: don't install luadocs twice. + * slingshot: Update. + * .travis.yml: Regenerate. + + travis: update slingshot, for better luadoc handling. + * slingshot: Update. + * configure.ac: Adjust. + * .travis.yml: Regenerate. + + Revert "travis: force luadoc to run only using Lua 5.1." + This reverts commit d54819f8b58988b10f8a298746abc28ce30b41c8. + + travis: force luadoc to run only using Lua 5.1. + * slingshot: Update. + * configure.ac (EXTRA_ROCKS): Ugly hack to inject the interpreter + substitution without requiring a locally modified travis.yml.in. + * .travis.yml: Regenerate. + + slingshot: update. + * slingshot: Update. + * bootstrap.slingshot: Manually update. + * bootstrap.conf (slingshot_files): Add m4/slingshot.m4. + * configure.ac: Adjust. + * .travis.yml: Regenerate. + + travis: install luadoc before running luarocks make. + * configure.ac (EXTRA_ROCKS): Add luadoc. + * .travis.yml: Regenerate. + + slingshot: update. + + travis: regenerate .travis.yml. + * .travis.yml: Regenerate. + + travis: specify EXTRA_ROCKS correctly. + * configure.ac (EXTRA_ROCKS): Add lyaml rock. + * .travis.yml: Regenerate. + + slingshot: use the public slingshot url. + * slingshot: Update. + * bootstrap.slingshot: Sync from upstream. + + maint: post-release administrivia. + * NEWS: Add header line for next release. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + Release version 35 * NEWS: Record release date. @@ -35,8 +815,6 @@ * .gitignore: Update. * .travis.yml: Regenerate. -2013-05-05 Gary V. Vaughan - slingshot: add slingshot as a git submodule. * .gitmodules: New file. * slingshot: New submodule. @@ -61,18 +839,18 @@ Remove non-core modules, which go into separate lua-rrtlib for ad-hoc modules -2013-04-11 Gary V. Vaughan +2013-04-12 Gary V. Vaughan specs: upgrade to Specl 5. * specs/string_ext_spec.yaml, specs/table_ext_spec.yaml: Update all 'should_error' matchers to saner Specl 5 ordering. * specs/specs.mk (SPECL_MIN): Bump to 5. +2013-04-11 Gary V. Vaughan + getopt: also requires io_ext module to be loaded. * std/getopt.lua: Load io_ext into a local table. -2013-04-10 Gary V. Vaughan - configury: install correctly with configure or luarocks. For the classic './configure; make; make install' to work we need to install to '$luadir' as discovered by ax_lua.m4. But we also @@ -242,7 +1020,7 @@ * std/std.lua.in: Strip "std." prefix before injecting required symbols into global namespace. -2013-03-29 Gary V. Vaughan +2013-03-30 Gary V. Vaughan maint: support rerunning check-local in multiple lua environments. * .luamultienv: Example multienv runner. @@ -250,6 +1028,8 @@ (MULTICHECK): Location of multicheck script. (check-local): Run multicheck without looping, if present. +2013-03-29 Gary V. Vaughan + getopt: ensure we find _G.arg from Specl nested setfenv environments. (issue #27) Although only necessary for Lua 5.1, this fix is harmless for Lua 5.2, and we support both! @@ -307,8 +1087,6 @@ (MKROCKSPECS): Now uses lua-stdlib from the build tree, not the previously installed version. -2013-03-25 Gary V. Vaughan - debug_ext: don't perturb the global environment by default. For backwards compatibility, `require "std"` will still write symbols into the global environment, but when loaded directly be @@ -412,7 +1190,7 @@ configury: bump release number to 35. * configure.ac (AC_INIT): Bump release number to 35. -2013-03-24 Gary V. Vaughan +2013-03-25 Gary V. Vaughan configury: warn if `make check` needs a newer Specl. * Makefile.am (SPECL_MIN): Oldest release capable of running our @@ -431,18 +1209,18 @@ maint: revert premature merge of pull request #23. Reverse apply 5508adb. -2013-03-23 Reuben Thomas +2013-03-24 Reuben Thomas README: make formatting consistent GNUmakefile: change to using a separate checkout for release branch -2013-03-15 Reuben Thomas +2013-03-16 Reuben Thomas Merge pull request #23 from rrthomas/gary/ext-hygiene package_ext: don't perturb the global environment by default. -2013-03-15 Gary V. Vaughan +2013-03-16 Gary V. Vaughan package_ext: don't perturb the global environment by default. For backwards compatibility, `require "std"` will still write @@ -456,6 +1234,8 @@ * specs/package_ext_spec.yaml: Specify new behaviour, being careful about `require "std"` side-effects. +2013-03-15 Gary V. Vaughan + string_ext: fix a bad assumption in a spec example. Running string.format in the expectation `should` uses the core Lua string.format which doesn't prettify tables, but we're @@ -511,8 +1291,6 @@ * Makeflie.am (SPECS): Remove old _spec.lua filenames, and add new _spec.yaml filenames. -2013-03-06 Gary V. Vaughan - specs: allow for package.config differences in Lua 5.1. * specs/package_ext_spec.lua (it splits package.config up): Allow for optional trailing \n present in 5.2 but not 5.1. @@ -554,7 +1332,7 @@ a copy of each file name, so no need to make assumptions about global variables in here. -2013-02-23 Gary V. Vaughan +2013-02-24 Gary V. Vaughan specs: add a skeleton specl spec for getopt module. * src/getopt.lua (test): Remove. @@ -618,7 +1396,7 @@ string_ext.lua: fix a reference to string.sub. -2013-02-22 Gary V. Vaughan +2013-02-23 Gary V. Vaughan string_ext: prefer snake_case to camelCase APIs. * src/string_ext.lua (escapePattern, escapeShell, ordinalSuffix): @@ -655,13 +1433,13 @@ * specs/string_ext_spec.lua (describe string.ordinalSuffix): Make the expectations match reality. -2013-02-22 Reuben Thomas +2013-02-23 Reuben Thomas Fix ordinalSuffix for negative arguments (issue #20). string_ext.lua: use Lua terminology "pattern" rather than "regex" -2013-02-22 Gary V. Vaughan +2013-02-23 Gary V. Vaughan specs: add specl specification for string_ext module. * specs/string_ext_spec.lua: New file. Specl specs for @@ -676,6 +1454,8 @@ * string_ext.lua (ordinalSuffix): Use '%' operator instead of math.mod, which is compatible with Lua 5.1 and 5.2. +2013-02-22 Gary V. Vaughan + maint: move maintainer rules into GNUmakefile. * Makefile.am: Move maintainer rules from here... * GNUmakefile.am: New file. ...to here. @@ -703,8 +1483,6 @@ configury: bump release number to 32. * configure.ac (AC_INIT): Bump release number to 32. -2013-02-21 Gary V. Vaughan - specs: add specl specification for package_ext module. * specs/package_ext_spec.lua: New file. Specl specs for package_ext. @@ -842,8 +1620,6 @@ of interfaces, per lua 5.2 module style. Adjust all callers. -2013-02-11 Gary V. Vaughan - maint: update mbox to use lua 5.2 style modules. * src/mbox.lua: Declare parse locally, and return a table with a reference, per lua 5.2 module style. @@ -881,6 +1657,8 @@ * src/set.lua: Declare everything locally, and return a table of interfaces, per lua 5.2 module style. +2013-02-11 Gary V. Vaughan + configury: fix hard dependency on luadocs. * m4/ax_with_prog.m4: New file. * configure.ac (AX_WITH_PROG): Use it to find a luadocs binary. @@ -896,10 +1674,12 @@ outdated versions from the lua installation. (rockspecs): Run lua with LUA_ENV set. -2013-02-09 Reuben Thomas +2013-02-10 Reuben Thomas rockspecs.lua: add luadoc as a dependency for git rockspec. +2013-02-09 Reuben Thomas + rockspecs.lua: fix build command for building from git. mkrockspecs.lua: whitespace fix. @@ -908,20 +1688,20 @@ tree.lua: add tree.merge. -2013-02-08 Reuben Thomas - set.lua: fix broken elems iterator (issue #10) strict.lua: tweak formatting to match other modules base.lua: note availability of original tostring as _tostring. -2013-02-07 Reuben Thomas +2013-02-08 Reuben Thomas set.lua: add missing dependency on list.lua Avoid rebuilding documentation in distributed sources, so users don't need luadoc installed. +2013-02-07 Reuben Thomas + Makefile.am: some more fixups to release-by-git. .gitignore: we have reverted from zip to tgz tarballs. @@ -942,15 +1722,13 @@ Makefile.am: enable building of documentation from git checkout. -2013-02-06 Reuben Thomas - Change to building (with LuaRocks) direct from git, not releasing a zip. README: update installation instructions and mention GitHub, not LuaForge. Update to latest ax_lua.m4. -2013-02-05 Reuben Thomas +2013-02-06 Reuben Thomas README: Make Lua 5.2 compatibility definite, and update copyright years. @@ -958,7 +1736,7 @@ stdlib.rockspec.in: remove redundant dir setting -2012-10-30 Reuben Thomas +2012-10-31 Reuben Thomas .gitignore: add luarocks directory @@ -982,7 +1760,7 @@ Bump version to 28, and simplify slightly, requiring automake 1.11 -2012-10-15 Reuben Thomas +2012-10-16 Reuben Thomas base.lua: move a documentation stanza to a more apt location @@ -1030,30 +1808,30 @@ set.lua: revert elements iterator to being pairs; leaves is wrong! -2012-09-12 Reuben Thomas +2012-09-13 Reuben Thomas Turn on debugging by default and tweak what the global debug function does. -2012-09-12 Reuben Thomas +2012-09-13 Reuben Thomas I misunderstood what finds did, and didn't spot that it was needed for split! Revert "string_ext: remove finds; map should be used with string.find instead" This reverts commit 5a62e3ee7ad2514b681ff6f348c43b797088b089. -2012-09-11 Reuben Thomas +2012-09-12 Reuben Thomas string_ext: remove finds; map should be used with string.find instead -2012-09-06 Reuben Thomas +2012-09-07 Reuben Thomas Remove string.gsubs: the order of substitutions was undefined, and map can be used just as well. -2012-07-06 Reuben Thomas +2012-07-07 Reuben Thomas build: Check MD5 sum of rockspec against tarball before releasing -2012-05-31 Reuben Thomas +2012-06-01 Reuben Thomas object: fix an incorrect simplification in the previous commit. @@ -1072,7 +1850,7 @@ parser.lua: fix call to renamed method. -2012-05-29 Reuben Thomas +2012-05-30 Reuben Thomas object.lua: fix inconsistency and missing HTML close tag in doc comments. @@ -1095,7 +1873,7 @@ Reformat some code to make lua-mode happier (most of the time, sigh). -2012-02-22 Gary V. Vaughan +2012-02-23 Gary V. Vaughan AUTHORS: Add myself. * AUTHORS: List the few small contributions I've made. @@ -1146,13 +1924,11 @@ string_ext: fix new string.__concat metamethod to run tostring on both args, thus avoiding infinite recursion. -2012-01-17 Reuben Thomas - string_ext: add __concat metamethod for strings which runs tostring. Reformat some code to please lua-mode and add some missing quotes in a comment. -2012-01-09 Reuben Thomas +2012-01-10 Reuben Thomas io_ext: Add slurp; use it in various places. @@ -1160,7 +1936,7 @@ Bump version to 26. -2011-12-16 Reuben Thomas +2011-12-17 Reuben Thomas Merge pull request #1 from gvvaughan/patch-1 tree: fix bugs when using a list of tables as keys @@ -1193,7 +1969,7 @@ io_ext: unset prog.file at the end of io.processFiles -2011-09-27 Reuben Thomas +2011-09-28 Reuben Thomas getopt: improve output and conformance to best practice Make the short option for -version be -V, not -v. @@ -1222,8 +1998,6 @@ .gitignore: ignore correct zip name. -2011-09-19 Reuben Thomas - configury: rename project to stdlib for consistency and to make luarocks happy. Make rockspec on release. @@ -1232,7 +2006,7 @@ string_ext.lua: fix old call of findl (is now called tfind). -2011-09-17 Reuben Thomas +2011-09-18 Reuben Thomas Makefile.am: fix getting summary description, and reminder message output by make release. @@ -1243,19 +2017,19 @@ Build system: autotoolize and generate rockspec. -2011-09-11 Reuben Thomas +2011-09-12 Reuben Thomas Rename findl to tfind to conform to lrexlib. Also fix a bug in the LuaDoc documentation of the return values. -2011-09-07 Reuben Thomas +2011-09-08 Reuben Thomas Remove posix_ext module (is going in luaposix instead). Update documentation about LuaDoc. Add posix.creat. -2011-09-02 Reuben Thomas +2011-09-03 Reuben Thomas Fix typo. @@ -1306,7 +2080,7 @@ Fix calls to writeLine to be to writeline. -2011-05-02 Reuben Thomas +2011-05-03 Reuben Thomas Add readlines and writeline to file handle metatable. @@ -1316,7 +2090,7 @@ Fixed bug: ldoc used writeLine() rather than writeline(). -2011-04-12 Reuben Thomas +2011-04-13 Reuben Thomas Always return nil on error, not -1. @@ -1328,7 +2102,7 @@ Only set _DEBUG to false if it’s not already initialised. -2011-03-19 Reuben Thomas +2011-03-20 Reuben Thomas Fix splitdir. @@ -1338,12 +2112,14 @@ Shorten a TODO. -2011-03-09 Reuben Thomas +2011-03-10 Reuben Thomas Restore modules.lua as holding standard list, to un-break std.lua. Allow mk1file to generate customized sets of modules, with the standard set as the default. +2011-03-09 Reuben Thomas + Remove unnecessary posix. prefix. Correct name of package_ext. @@ -1354,10 +2130,10 @@ Merge branch 'origin' of github.com:rrthomas/lua-stdlib into origin -2011-03-08 Reuben Thomas - Remove posix_ext and object from standard set. +2011-03-08 Reuben Thomas + Remove posix prefix from function calls. Add euidaccess. @@ -1369,7 +2145,7 @@ Add __index method to allow OO syntax use of methods. Add delete method. -2011-03-01 Reuben Thomas +2011-03-02 Reuben Thomas Reverse order of list methods for convenient OO use. @@ -1403,7 +2179,7 @@ Improve release target to tag releases. -2011-02-07 Reuben Thomas +2011-02-08 Reuben Thomas Fix missing math. prefix, and swap incorrect sign in sub. Thanks to Bob Chapman. @@ -1411,7 +2187,7 @@ Speed up math.floor for case where p is 0 or absent (thanks, Lukáš Procházka). -2010-12-09 Reuben Thomas +2010-12-10 Reuben Thomas Change rules from using CVS to using git. @@ -1421,7 +2197,7 @@ Point to tree.clone for deep copies. -2010-10-12 Reuben Thomas +2010-10-13 Reuben Thomas Restore 'dubious' but used string metamethod fallback. @@ -1429,8 +2205,6 @@ Move .cvsignore's to .gitignore's. -2010-10-08 Reuben Thomas - Fix typo in io.catfile. Add commit that seems to be missing from import from CVS. @@ -1441,6 +2215,8 @@ Remove spurious full stop. +2010-10-08 Reuben Thomas + Add catfile and fix catdir to return `/' when necessary. 2010-10-07 Reuben Thomas @@ -1457,12 +2233,14 @@ Fix an incompatibility with strict.lua. -2010-06-11 rrt +2010-06-12 rrt Simplify nodes iterator and make it more efficient; thanks to Alistair Turnbull for the hint. Simplify, generalise and rename (from treeIter to nodes) tree iterator. +2010-06-11 rrt + Whitespace correction. Simplify implementation of empty, using next as per manual. @@ -1492,7 +2270,7 @@ Remove table.subscripts function: it’s easily replaced by subscript plus string.split, as in its definition. -2010-06-07 rrt +2010-06-08 rrt Initialise _DEBUG to nil so stdlib works with strict.lua. Rename debug.traceCall to debug.trace (more Lua-ish). @@ -1516,11 +2294,11 @@ Add missing dependency on list. -2009-09-14 rrt +2009-09-15 rrt Improve formatting slightly. -2009-09-07 rrt +2009-09-08 rrt Avoid using removed function io.changeSuffix. @@ -1573,8 +2351,6 @@ Add support for not cloning metatables. -2009-03-13 rrt - Check no outstanding changes and tag release. Fix typo. @@ -1597,7 +2373,7 @@ Update object module to correspond with Lua Gems version. -2008-09-04 rrt +2008-09-05 rrt Fix Diego Nehab's name. Sorry Diego! Thanks to Shmuel Zeigerman for pointing out my error. @@ -1617,10 +2393,10 @@ Cope with nil values in map. -2008-07-27 niklas - Fix elems and relems +2008-07-27 niklas + Fix make dist; $REL -> ${REL}, add --exclude for .#*, and no longer exclude template-rrt.lua, which no longer lives in the tree. 2008-06-21 niklas @@ -1638,7 +2414,7 @@ Fix a comment typo. -2008-03-28 rrt +2008-03-29 rrt Add some TODOs to make the prog structure a bit more sensible. @@ -1660,8 +2436,6 @@ Remove _INTEGER_BITS and unneeded dependency -2008-03-03 rrt - Update date and prerequisites. 2008-03-02 rrt @@ -1708,7 +2482,7 @@ Clarify TODO. -2007-04-26 rrt +2007-04-27 rrt Tidy length slightly. @@ -1721,6 +2495,8 @@ Revert to plain implementation of length to avoid using POSIX library which is currently unmaintained. +2007-04-26 rrt + Clear up uses of old vararg "arg" syntax (thanks Matt). 2007-03-02 rrt @@ -1729,10 +2505,10 @@ Add FIXME for commented-out require -2007-03-01 rrt - Make join cope with empty lists. +2007-03-01 rrt + Remove default separator in string.split, and hence a TODO. Add string.join. @@ -1765,7 +2541,7 @@ Make a note to find better names for enpair and depair, which are useful but confusing. Something like pairsToTable and tableToPairs? -2007-01-26 rrt +2007-01-27 rrt Add missing dirname and basename @@ -1805,8 +2581,6 @@ Note problem with external dependencies. -2006-11-05 rrt - Sort out adding to module metatables. Add a FIXME @@ -1817,6 +2591,8 @@ Remove @module from list of tags to add, as we already have it. +2006-11-05 rrt + Clarify Reuben's role. Remove rex.lua, now imported from lrexlib @@ -1908,10 +2684,12 @@ Add deepclone to table from Jamie Webb's code. -2006-10-08 rrt +2006-10-09 rrt Update to match stdlib. Remove revision history as it's in CVS, and replace version number with CVS Revision tag. +2006-10-08 rrt + table.getn --> # 2006-10-01 rrt @@ -1926,7 +2704,7 @@ Fix ordering of deps -2006-07-14 rrt +2006-07-15 rrt Escape quotes and apostrophes in string.escapeShell. @@ -1936,21 +2714,19 @@ Prepend redefinition of require to the output. -2006-04-25 rrt - Use string methods rather than functions so that the functions here work on regexs as well. Add a note to make the whole API work properly with regexs as well as Lua patterns. Add TODO Reformat and improve comments. -2006-04-24 rrt +2006-04-25 rrt Simplify assignment of retry. Correct name of table.filterItem (was table.mapItem). -2006-04-15 rrt +2006-04-16 rrt Reformat. @@ -1958,6 +2734,8 @@ Add table.filter and table.filterItem. Add list.filterItem and implement list.filter in terms of it. +2006-04-15 rrt + Fix more bugs, patch from Shmuel Zeigerman. Call rex:flags() to inject flags into rex table. @@ -1995,7 +2773,7 @@ Add io.dirname. -2006-04-09 rrt +2006-04-10 rrt Update Lua code from Shmuel's version and write gmatch in Lua. @@ -2004,7 +2782,7 @@ Update to 5.1 vararg syntax -2006-03-30 rrt +2006-03-31 rrt string.gfind is now string.gmatch. @@ -2016,6 +2794,8 @@ Update to match reality. +2006-03-30 rrt + Fix handling of global arg table. Use new form of message-less error. @@ -2030,8 +2810,6 @@ Simplify adding functions to global table. -2006-03-28 rrt - Add module calls everywhere, and do some necessary renaming to avoid clashes 2006-03-23 rrt @@ -2049,7 +2827,7 @@ Rename sub to cap for clarity (Shmuel Zeigerman). -2006-01-26 rrt +2006-01-27 rrt More fixes from Shmuel to mimic string.gsub better. @@ -2057,10 +2835,10 @@ Fix endless loop when pattern is .* (bug reported by Shmuel Zeigerman). -2006-01-24 rrt - Cope with capture being false (Shmuel Zeigerman). +2006-01-24 rrt + Fix bug when n == 0 (thanks Shmuel Zeigerman), and tidy up. 2006-01-23 rrt @@ -2071,10 +2849,10 @@ More bug fixes; thanks to Shmuel Zeigerman for reporting the bugs and in one case giving the fix. -2006-01-21 rrt - Fix bugs with %n replacements in rex.gsub +2006-01-21 rrt + Make rex.gsub a full gsub for rex. 2006-01-20 rrt @@ -2096,11 +2874,9 @@ Remove table.filterItem, as it really only works for lists. Inline the function in list.filter. Add table.map. -2005-11-22 rrt - Add XML output, assuming Lua tables created by luaexpat. -2005-11-21 rrt +2005-11-22 rrt Add generic printing framework, and use it to add prettytostring. @@ -2112,7 +2888,7 @@ Add two iterators: ripairs which is like ipairs, but in reverse, and deepipairs, which recurses into nested tables. -2005-11-09 rrt +2005-11-10 rrt Remove import. @@ -2234,15 +3010,15 @@ Fix tostring to work on self-referential tables. -2004-01-27 rrt +2004-01-28 rrt Corrected misnaming of functions and added documentation. -2004-01-26 rrt +2004-01-27 rrt Add string.format extension to make it not try to format if there is only one argument. -2004-01-25 rrt +2004-01-26 rrt Update to Lua 5. This is an old change which I forgot to check in; ldoc is *not* the way forward for stdlib documentation. This checkin is just for completeness. @@ -2268,17 +3044,17 @@ Add "import" from LTN 11 to overcome require's problem with circular dependencies. Remove string.next, as string.gfind provides an equivalent iterator. -2003-10-20 rrt - More renaming for consistency, and move more code around. This introduced the first cyclic dependency between modules since I moved to Lua 5, and I've had to cure this with a C include-style trick, since Lua 5 require just overflows the stack when there's a recursive call of require. +2003-10-20 rrt + Add an iterator for the values in a set, and use it; methods are now organised into those that access the data structure and those that call other methods. Objectify the implementation, and add LuaDoc-style markup to the comments. Write methods outside object prototype (i.e. in more consistent form for stdlib). -2003-10-18 rrt +2003-10-19 rrt Rename std.data.logic to std.bit, as it extends the C bit library. @@ -2286,6 +3062,8 @@ Fix bug in curry properly. +2003-10-18 rrt + Finish renaming in io.io. Update TODO for getopt in std.lua. Re-add mistakenly removed logic (I confused the ability to take multiple args with the ability to take lists). @@ -2317,7 +3095,7 @@ Some other Lua 5-isation has been done, but not much; there's still a lot left to do in std.data in particular. -2003-10-13 rrt +2003-10-14 rrt Fix call to writeLine (now io.writeLine). @@ -2343,8 +3121,6 @@ More changes to update to Lua 5.0. Nearly there now, I think, as I have several scripts working! -2003-09-11 rrt - Another few search-and-replace function names to update to Lua 5. Mostly string functions this time. 2003-09-10 rrt @@ -2383,16 +3159,18 @@ Merge the two logic modules. -2002-09-28 rrt +2002-09-29 rrt Add tabulate function to use tabulator methods, and use it. -2002-09-10 rrt +2002-09-11 rrt Sigh. New bnot didn't work. Next time I'll think and test rather better before straying from the path of righteousness. I was being very dim about bnot. Oops. Roberto pointed it out. I hang my head in shame. +2002-09-10 rrt + Revert to previous version to avoid losing precision (specifically, LSB). Shorter implementation of bxor, and bnot thanks to a remark by Paul Hsieh on lual (Message-Id: <0H26009OMQ9J59@mta5.snfc21.pbi.net>). @@ -2410,7 +3188,7 @@ Improve layout of usage message when no command line options (don't have trailing blank line). -2002-09-05 rrt +2002-09-06 rrt Add withFileOrHandle, which takes a filename, handle or uses a default handle, opens the file if appropriate, and passes the handle to a given function. Use it to generalise readLines and readFile. @@ -2419,12 +3197,14 @@ ambiguous: do we want to write "foo" and "bar" to _OUTPUT, or "bar" to file "foo"? -2002-09-05 rrt +2002-09-06 rrt Make patches work with any version that starts with "Lua 4.0", to cope with 4.0.1 and any future point releases. Replace unpack with a recursive version (based on code from John Belmonte) that copes with any number of values. +2002-09-05 rrt + Change "key" to "index" everywhere for consistency. Improve comments for tinvert @@ -2433,19 +3213,21 @@ Rename intersect to setintersect for consistency, and define setunion (= merge). -2002-08-28 rrt +2002-08-29 rrt Allow stringifier methods again, but they are now only used by tostring. Allows more cosmetic stringification, while not stopping pickling from working. -2002-08-27 rrt +2002-08-28 rrt Don't need stringify and pickler tables any more, and tostring and pickle can be simplified. They both use tabulator where necessary. +2002-08-27 rrt + Remove interaction between pickle and tostring, which is no longer needed, as they both now use tabulator methods where necessary. Add tabulator method table for turning arbitrary objects (typically tagged userdata) into tables. Use this to finally fix tostring and pickle. Oh, yes. -2002-08-23 rrt +2002-08-24 rrt A last gamble. Then I'll have to sit down and work it out again. @@ -2469,13 +3251,15 @@ Make pickle work for numbers and nil. +2002-08-23 rrt + Add tinvert, and update some comments to LDoc format. 2002-08-22 rrt Correct call of warn to expand arg list. -2002-08-15 rrt +2002-08-16 rrt Add utility for making zip dist of stdlib. @@ -2483,6 +3267,8 @@ Fix paths for new directory structure and get rid of one or two gremlins. +2002-08-15 rrt + Finish editing std.cfg into new form (configuration file with require implementation tacked on the end) and rename it. Update some TODOs. @@ -2529,8 +3315,6 @@ Fix spacing in comments. -2002-08-12 rrt - Allow new tostring methods to be registered. *** empty log message *** @@ -2563,7 +3347,7 @@ Generalised daySuffix to ordinalSuffix. Still English-specific :-( -2002-07-27 rrt +2002-07-28 rrt Improve comment for mapIter @@ -2577,7 +3361,7 @@ This tool is provisional, and subject to improvement. The TODOs in the file indicate some of my first thoughts in that direction. -2002-07-24 rrt +2002-07-25 rrt Move methodify to table.lua where it belongs (it has nothing to do with lists!) diff --git a/GNUmakefile b/GNUmakefile index 492ce1e..307d9a6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,20 @@ -## maintainer rules. +# Maintainer rules. +# +# Copyright (C) 2013-2014 Gary V. Vaughan +# Written by Gary V. Vaughan, 2013 +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . ME = GNUmakefile @@ -7,9 +23,12 @@ dont-forget-to-bootstrap = $(wildcard Makefile.in) ifeq ($(dont-forget-to-bootstrap),) +## Don't redo any pedantic rock version checks, incase they derail +## a subdirectory bootstrap of slingshot. + %:: @echo '$(ME): rebootstrap' - @test -f Makefile.in || ./bootstrap + @test -f Makefile.in || ./bootstrap --skip-rock-checks @test -f Makefile || ./configure $(MAKE) $@ @@ -22,6 +41,30 @@ include build-aux/sanity.mk # Run sanity checks as part of distcheck. distcheck: $(local-check) + +## ------------------------- ## +## Copyright Notice Updates. ## +## ------------------------- ## + +# If you want to set UPDATE_COPYRIGHT_* environment variables, +# for the build-aux/update-copyright script: set the assignments +# in this variable in local.mk. +update_copyright_env ?= + +# Run this rule once per year (usually early in January) +# to update all FSF copyright year lists in your project. +# If you have an additional project-specific rule, +# add it in local.mk along with a line 'update-copyright: prereq'. +# By default, exclude all variants of COPYING; you can also +# add exemptions (such as ChangeLog..* for rotated change logs) +# in the file .x-update-copyright. +.PHONY: update-copyright +update-copyright: + $(AM_V_GEN)grep -l -w Copyright \ + $$(export VC_LIST_EXCEPT_DEFAULT=COPYING && $(VC_LIST_EXCEPT)) \ + | $(update_copyright_env) xargs $(srcdir)/build-aux/$@ + + ## ------ ## ## Specl. ## ## ------ ## @@ -29,7 +72,8 @@ distcheck: $(local-check) # Use 'make check V=1' for verbose output, or set SPECL_OPTS to # pass alternative options to specl command. -SPECL_OPTS ?= $(specl_verbose_$(V)) +SPECL_OPTS ?= +SPECL_OPTS += $(specl_verbose_$(V)) specl_verbose_ = $(specl_verbose_$(AM_DEFAULT_VERBOSITY)) specl_verbose_0 = specl_verbose_1 = --verbose --formatter=report diff --git a/INSTALL b/INSTALL index 64c6937..2099840 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, +Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -12,8 +12,8 @@ without warranty of any kind. Basic Installation ================== - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following + Briefly, the shell command `./configure && make && make install' +should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented @@ -226,6 +226,11 @@ order to use an ANSI C compiler: and if that doesn't work, install pre-built binaries of GCC for HP-UX. + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended @@ -304,9 +309,10 @@ causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== diff --git a/Makefile.am b/Makefile.am index 96dccbb..d707341 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # Non-recursive Make rules. # -# Copyright (C) 2013 Gary V. Vaughan +# Copyright (C) 2013-2014 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # # This program is free software; you can redistribute it and/or modify it @@ -21,7 +21,8 @@ ## Environment. ## ## ------------ ## -LUA_PATH ?= ; +LUA_PATH ?= ; +LUA_CPATH ?= ; ## ---------- ## @@ -30,12 +31,15 @@ LUA_PATH ?= ; ACLOCAL_AMFLAGS = -I m4 +AM_CPPFLAGS = $(LUA_INCLUDE) + ## ------------- ## ## Declarations. ## ## ------------- ## EXTRA_DIST = +EXTRA_LTLIBRARIES = CLEANFILES = DISTCLEANFILES = MAINTAINERCLEANFILES = @@ -43,8 +47,13 @@ NOTHING_ELSE = bin_SCRIPTS = check_local = +dist_bin_SCRIPTS = +dist_lua_DATA = +doc_DATA = install_exec_hooks = +lib_LTLIBRARIES = man_MANS = +save_release_files = include local.mk include build-aux/rockspecs.mk @@ -62,12 +71,3 @@ check-local: $(check_local) ## ------------- ## install-exec-hook: $(install_exec_hooks) - - -## ------------- ## -## Distribution. ## -## ------------- ## - -EXTRA_DIST += \ - README.md \ - $(NOTHING_ELSE) diff --git a/Makefile.in b/Makefile.in index 2e81a3f..307409a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.1 from Makefile.am. +# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -16,7 +16,7 @@ # Non-recursive Make rules. # -# Copyright (C) 2013 Gary V. Vaughan +# Copyright (C) 2013-2014 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # # This program is free software; you can redistribute it and/or modify it @@ -33,8 +33,22 @@ # along with this program. If not, see . # Local Make rules. - -# lua-stdlib make rules. +# +# Copyright (C) 2013-2014 Gary V. Vaughan +# Written by Gary V. Vaughan, 2013 +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . # Specl specs make rules. @@ -44,7 +58,7 @@ # terms of the MIT license reproduced below. # ==================================================================== # -# Copyright (C) 2013 Gary V. Vaughan # +# Copyright (C) 2013-2014 Gary V. Vaughan # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation # @@ -75,7 +89,7 @@ # terms of the MIT license reproduced below. # ==================================================================== # -# Copyright (C) 2013 Reuben Thomas and Gary V. Vaughan # +# Copyright (C) 2013-2014 Reuben Thomas and Gary V. Vaughan # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation # @@ -103,24 +117,53 @@ # include build-aux/rockspecs.mk + VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -137,14 +180,14 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -DIST_COMMON = $(srcdir)/local.mk $(srcdir)/std/std.mk \ - $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk \ - $(srcdir)/build-aux/rockspecs.mk $(srcdir)/Makefile.in \ +DIST_COMMON = $(srcdir)/local.mk $(srcdir)/specs/specs.mk \ + $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk \ + INSTALL NEWS README AUTHORS ChangeLog $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(srcdir)/travis.yml.in $(dist_doc_DATA) \ - $(dist_files_DATA) $(dist_lua_DATA) $(dist_modules_DATA) \ - $(nobase_dist_lua_DATA) AUTHORS ChangeLog INSTALL NEWS \ - build-aux/install-sh build-aux/missing \ + $(am__configure_deps) $(srcdir)/travis.yml.in \ + $(dist_bin_SCRIPTS) $(dist_classes_DATA) $(dist_doc_DATA) \ + $(dist_lua_DATA) $(dist_luastd_DATA) $(dist_modules_DATA) \ + COPYING build-aux/install-sh build-aux/missing \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/missing subdir = . @@ -186,10 +229,13 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" \ - "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(luadir)" \ - "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(luadir)" -SCRIPTS = $(bin_SCRIPTS) +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" \ + "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" \ + "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(modulesdir)" \ + "$(DESTDIR)$(docdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +SCRIPTS = $(bin_SCRIPTS) $(dist_bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -209,8 +255,8 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -DATA = $(dist_doc_DATA) $(dist_files_DATA) $(dist_lua_DATA) \ - $(dist_modules_DATA) $(nobase_dist_lua_DATA) +DATA = $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ + $(dist_luastd_DATA) $(dist_modules_DATA) $(doc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -249,12 +295,11 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDOC = @LDOC@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ LUA = @LUA@ -LUADOC = @LUADOC@ -LUADOC_FALSE = @LUADOC_FALSE@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ @@ -274,7 +319,6 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPECL = @SPECL@ -SPECL_MIN = @SPECL_MIN@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ @@ -321,59 +365,93 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = std/std.lua.in $(NOTHING_ELSE) $(specl_SPECS) \ +AM_CPPFLAGS = $(LUA_INCLUDE) +EXTRA_DIST = $(srcdir)/specs/spec_helper.lua $(NOTHING_ELSE) \ + $(specl_SPECS) $(NOTHING_ELSE) doc/config.ld lib/std.lua.in \ $(NOTHING_ELSE) $(mkrockspecs) $(package_rockspec) \ - $(rockspec_conf) $(NOTHING_ELSE) README.md $(NOTHING_ELSE) + $(rockspec_conf) $(NOTHING_ELSE) +EXTRA_LTLIBRARIES = CLEANFILES = DISTCLEANFILES = $(luarocks_config) $(NOTHING_ELSE) MAINTAINERCLEANFILES = NOTHING_ELSE = bin_SCRIPTS = check_local = specl-check-local +dist_bin_SCRIPTS = +dist_lua_DATA = lib/std.lua $(NOTHING_ELSE) +doc_DATA = install_exec_hooks = +lib_LTLIBRARIES = man_MANS = -std_path = $(abs_srcdir)/?.lua;$(abs_srcdir)/std/?.lua +save_release_files = $(scm_rockspec) +std_path = $(abs_srcdir)/lib/?.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = dfde3c0c6163db72d47538ad8711607c -filesdir = $(docdir)/files -modulesdir = $(docdir)/modules -dist_doc_DATA = $(srcdir)/std/index.html $(srcdir)/std/luadoc.css -dist_files_DATA = $(wildcard $(srcdir)/std/files/*.html) -dist_modules_DATA = $(wildcard $(srcdir)/std/modules/*.html) -nobase_dist_lua_DATA = \ - std/base.lua \ - std/debug_ext.lua \ - std/debug_init.lua \ - std/getopt.lua \ - std/io_ext.lua \ - std/list.lua \ - std/math_ext.lua \ - std/modules.lua \ - std/object.lua \ - std/package_ext.lua \ - std/set.lua \ - std/strbuf.lua \ - std/strict.lua \ - std/string_ext.lua \ - std/table_ext.lua \ - std/tree.lua \ - $(NOTHING_ELSE) - -dist_lua_DATA = \ - std/std.lua \ - $(NOTHING_ELSE) +old_NEWS_hash = 7ef01dfb840329db3d8db218bfe9d075 +update_copyright_env = \ + UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ + UPDATE_COPYRIGHT_USE_INTERVALS=1 \ + UPDATE_COPYRIGHT_FORCE=1 +classesdir = $(docdir)/classes +modulesdir = $(docdir)/modules +dist_doc_DATA = $(srcdir)/doc/index.html $(srcdir)/doc/ldoc.css +dist_classes_DATA = $(srcdir)/doc/classes/std.container.html \ + $(srcdir)/doc/classes/std.list.html \ + $(srcdir)/doc/classes/std.object.html \ + $(srcdir)/doc/classes/std.set.html \ + $(srcdir)/doc/classes/std.strbuf.html \ + $(srcdir)/doc/classes/std.tree.html $(NOTHING_ELSE) +dist_modules_DATA = $(srcdir)/doc/modules/std.html \ + $(srcdir)/doc/modules/std.debug.html \ + $(srcdir)/doc/modules/std.functional.html \ + $(srcdir)/doc/modules/std.getopt.html \ + $(srcdir)/doc/modules/std.io.html \ + $(srcdir)/doc/modules/std.math.html \ + $(srcdir)/doc/modules/std.package.html \ + $(srcdir)/doc/modules/std.strict.html \ + $(srcdir)/doc/modules/std.string.html \ + $(srcdir)/doc/modules/std.table.html $(NOTHING_ELSE) SPECL_ENV = $(LUA_ENV) specl_SPECS = \ - $(srcdir)/specs/debug_ext_spec.yaml \ + $(srcdir)/specs/container_spec.yaml \ + $(srcdir)/specs/debug_spec.yaml \ $(srcdir)/specs/getopt_spec.yaml \ - $(srcdir)/specs/io_ext_spec.yaml \ - $(srcdir)/specs/math_ext_spec.yaml \ - $(srcdir)/specs/package_ext_spec.yaml \ - $(srcdir)/specs/string_ext_spec.yaml \ - $(srcdir)/specs/table_ext_spec.yaml \ + $(srcdir)/specs/io_spec.yaml \ + $(srcdir)/specs/list_spec.yaml \ + $(srcdir)/specs/math_spec.yaml \ + $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/package_spec.yaml \ + $(srcdir)/specs/set_spec.yaml \ + $(srcdir)/specs/strbuf_spec.yaml \ + $(srcdir)/specs/string_spec.yaml \ + $(srcdir)/specs/table_spec.yaml \ + $(srcdir)/specs/tree_spec.yaml \ + $(NOTHING_ELSE) + +luastddir = $(luadir)/std +dist_luastd_DATA = \ + lib/std/base.lua \ + lib/std/container.lua \ + lib/std/debug.lua \ + lib/std/debug_init.lua \ + lib/std/functional.lua \ + lib/std/getopt.lua \ + lib/std/io.lua \ + lib/std/list.lua \ + lib/std/math.lua \ + lib/std/modules.lua \ + lib/std/object.lua \ + lib/std/package.lua \ + lib/std/set.lua \ + lib/std/strbuf.lua \ + lib/std/strict.lua \ + lib/std/string.lua \ + lib/std/table.lua \ + lib/std/tree.lua \ $(NOTHING_ELSE) +mkrockspecs_args = --module-dir $(srcdir)/lib +ldoc_DEPS = $(dist_lua_DATA) $(dist_luastd_DATA) luarocks_config = build-aux/luarocks-config.lua rockspec_conf = $(srcdir)/rockspec.conf mkrockspecs = $(srcdir)/build-aux/mkrockspecs @@ -401,19 +479,19 @@ all: all-am .SUFFIXES: am--refresh: Makefile @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/local.mk $(srcdir)/std/std.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk $(am__configure_deps) +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/local.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile + $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -424,7 +502,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; -$(srcdir)/local.mk $(srcdir)/std/std.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk: +$(srcdir)/local.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk: $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck @@ -436,6 +514,41 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): .travis.yml: $(top_builddir)/config.status $(srcdir)/travis.yml.in cd $(top_builddir) && $(SHELL) ./config.status $@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(INSTALL) $(INSTALL_STRIP_FLAG) $$list '$(DESTDIR)$(libdir)'"; \ + $(INSTALL) $(INSTALL_STRIP_FLAG) $$list "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ @@ -471,48 +584,83 @@ uninstall-binSCRIPTS: files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) -install-dist_docDATA: $(dist_doc_DATA) +install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) @$(NORMAL_INSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-dist_binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) +install-dist_classesDATA: $(dist_classes_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_classes_DATA)'; test -n "$(classesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(classesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(classesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(classesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(classesdir)" || exit $$?; \ done -uninstall-dist_docDATA: +uninstall-dist_classesDATA: @$(NORMAL_UNINSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + @list='$(dist_classes_DATA)'; test -n "$(classesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) -install-dist_filesDATA: $(dist_files_DATA) + dir='$(DESTDIR)$(classesdir)'; $(am__uninstall_files_from_dir) +install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) - @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(filesdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(filesdir)" || exit 1; \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(filesdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(filesdir)" || exit $$?; \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done -uninstall-dist_filesDATA: +uninstall-dist_docDATA: @$(NORMAL_UNINSTALL) - @list='$(dist_files_DATA)'; test -n "$(filesdir)" || list=; \ + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(filesdir)'; $(am__uninstall_files_from_dir) + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-dist_luaDATA: $(dist_lua_DATA) @$(NORMAL_INSTALL) @list='$(dist_lua_DATA)'; test -n "$(luadir)" || list=; \ @@ -534,6 +682,27 @@ uninstall-dist_luaDATA: @list='$(dist_lua_DATA)'; test -n "$(luadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(luadir)'; $(am__uninstall_files_from_dir) +install-dist_luastdDATA: $(dist_luastd_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_luastd_DATA)'; test -n "$(luastddir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(luastddir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(luastddir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(luastddir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(luastddir)" || exit $$?; \ + done + +uninstall-dist_luastdDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_luastd_DATA)'; test -n "$(luastddir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(luastddir)'; $(am__uninstall_files_from_dir) install-dist_modulesDATA: $(dist_modules_DATA) @$(NORMAL_INSTALL) @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ @@ -555,30 +724,27 @@ uninstall-dist_modulesDATA: @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) -install-nobase_dist_luaDATA: $(nobase_dist_lua_DATA) +install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) - @list='$(nobase_dist_lua_DATA)'; test -n "$(luadir)" || list=; \ + @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(luadir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(luadir)" || exit 1; \ + echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ - $(am__nobase_list) | while read dir files; do \ - xfiles=; for file in $$files; do \ - if test -f "$$file"; then xfiles="$$xfiles $$file"; \ - else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ - test -z "$$xfiles" || { \ - test "x$$dir" = x. || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(luadir)/$$dir'"; \ - $(MKDIR_P) "$(DESTDIR)$(luadir)/$$dir"; }; \ - echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(luadir)/$$dir'"; \ - $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(luadir)/$$dir" || exit $$?; }; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done -uninstall-nobase_dist_luaDATA: +uninstall-docDATA: @$(NORMAL_UNINSTALL) - @list='$(nobase_dist_lua_DATA)'; test -n "$(luadir)" || list=; \ - $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ - dir='$(DESTDIR)$(luadir)'; $(am__uninstall_files_from_dir) + @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: @@ -642,10 +808,16 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) @@ -687,9 +859,10 @@ distcheck: dist && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -745,9 +918,9 @@ distcleancheck: distclean check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-am -all-am: Makefile $(SCRIPTS) $(DATA) +all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(filesdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(luadir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -785,7 +958,7 @@ maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am -clean-am: clean-generic mostlyclean-am +clean-am: clean-generic clean-libLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -804,15 +977,16 @@ info: info-am info-am: -install-data-am: install-dist_docDATA install-dist_filesDATA \ - install-dist_luaDATA install-dist_modulesDATA \ - install-nobase_dist_luaDATA +install-data-am: install-dist_classesDATA install-dist_docDATA \ + install-dist_luaDATA install-dist_luastdDATA \ + install-dist_modulesDATA install-docDATA install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-binSCRIPTS +install-exec-am: install-binSCRIPTS install-dist_binSCRIPTS \ + install-libLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am @@ -853,54 +1027,52 @@ ps: ps-am ps-am: -uninstall-am: uninstall-binSCRIPTS uninstall-dist_docDATA \ - uninstall-dist_filesDATA uninstall-dist_luaDATA \ - uninstall-dist_modulesDATA uninstall-nobase_dist_luaDATA +uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ + uninstall-dist_classesDATA uninstall-dist_docDATA \ + uninstall-dist_luaDATA uninstall-dist_luastdDATA \ + uninstall-dist_modulesDATA uninstall-docDATA \ + uninstall-libLTLIBRARIES .MAKE: check-am install-am install-exec-am install-strip .PHONY: all all-am am--refresh check check-am check-local clean \ - clean-generic cscopelist-am ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-generic distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-binSCRIPTS install-data \ - install-data-am install-dist_docDATA install-dist_filesDATA \ - install-dist_luaDATA install-dist_modulesDATA install-dvi \ + clean-generic clean-libLTLIBRARIES cscopelist-am ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-binSCRIPTS \ + install-data install-data-am install-dist_binSCRIPTS \ + install-dist_classesDATA install-dist_docDATA \ + install-dist_luaDATA install-dist_luastdDATA \ + install-dist_modulesDATA install-docDATA install-dvi \ install-dvi-am install-exec install-exec-am install-exec-hook \ install-html install-html-am install-info install-info-am \ - install-man install-nobase_dist_luaDATA install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ - uninstall-binSCRIPTS uninstall-dist_docDATA \ - uninstall-dist_filesDATA uninstall-dist_luaDATA \ - uninstall-dist_modulesDATA uninstall-nobase_dist_luaDATA + uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ + uninstall-dist_classesDATA uninstall-dist_docDATA \ + uninstall-dist_luaDATA uninstall-dist_luastdDATA \ + uninstall-dist_modulesDATA uninstall-docDATA \ + uninstall-libLTLIBRARIES -LUA_PATH ?= ; +LUA_PATH ?= ; +LUA_CPATH ?= ; +specl-check-local: $(specl_SPECS) + $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to -# have luadoc installed, put std/std.lua in as a Makefile dependency. +# have ldoc installed, put std/std.lua in as a Makefile dependency. # (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) -std/std.lua: std/std.lua.in +lib/std.lua: lib/std.lua.in ./config.status --file=$@ -$(dist_doc_DATA): $(nobase_dist_lua_DATA) - cd $(srcdir)/std && $(LUADOC) *.lua -specl-check-local: $(specl_SPECS) - @v=`$(SPECL) --version | sed -e 's|^.* ||' -e 1q`; \ - if test "$$v" -lt "$(SPECL_MIN)"; then \ - printf "%s%s\n%s\n" \ - "ERROR: Specl version $$v is too old," \ - " please upgrade to at least version $(SPECL_MIN)," \ - "ERROR: and rerun \`make check\`"; \ - exit 1; \ - else \ - $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS); \ - fi +$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(ldoc_DEPS) + cd $(srcdir) && $(LDOC) -c doc/config.ld . $(luarocks_config): Makefile.am @test -d build-aux || mkdir build-aux @@ -918,13 +1090,15 @@ $(luarocks_config): Makefile.am $(package_rockspec): $(ROCKSPECS_DEPS) $(AM_V_at)rm -f '$@' 2>/dev/null || : $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' + $(MKROCKSPECS) $(mkrockspecs_args) \ + $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' $(AM_V_at)$(LUAROCKS) lint '$@' $(scm_rockspec): $(ROCKSPECS_DEPS) $(AM_V_at)rm '$@' 2>/dev/null || : $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(PACKAGE) git 1 > '$@' + $(MKROCKSPECS) $(mkrockspecs_args) \ + $(PACKAGE) git 1 > '$@' $(AM_V_at)$(LUAROCKS) lint '$@' .PHONY: rockspecs diff --git a/NEWS b/NEWS index 6420c32..b3fd9f0 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,99 @@ Stdlib NEWS - User visible changes +* Noteworthy changes in release 36 (2014-01-16) [stable] + +** New features: + + - Modules have been refactored so that they can be safely + required individually, and without loading themselves or any + dependencies on other std modules into the global namespace. + + - Objects derived from the `std.object` prototype have a new + :prototype () method that returns the contents of the + new internal `_type` field. This can be overridden during cloning + with, e.g.: + + local Object = require "std.object" + Prototype = Object { _type = "Prototype", } + + - Objects derived from the `std.object` prototype return a new table + with a shallow copy of all non-private fields (keys that do not + begin with "_") when passed to `table.totable` - unless overridden + in the derived object's __totable field. + + - list and strbuf are now derived from `std.object`, which means that + they respond to `object.prototype` with appropriate type names ("List", + "StrBuf", etc.) and can be used as prototypes for further derived + objects or clones; support object:prototype (); respond to totable etc. + + - A new Container module at `std.container` makes separation between + container objects (which are free to use __index as a "[]" access + metamethod, but) which have no object methods, and regular objects + (which do have object methods, but) which cannot use the __index + metamethod for "[]" access to object contents. + + - set and tree are now derived from `std.container`, so there are no + object methods. Instead there are a full complement of equivalent + module functions. Metamethods continue to work as before. + + - `string.prettytostring` always displays table elements in the same + order, as provided by `table.sort`. + + - `table.totable` now accepts a string, and returns a list of the + characters that comprise the string. + + - Can now be installed directly from a release tarball by `luarocks`. + No need to run `./configure` or `make`, unless you want to install to + a custom location, or do not use LuaRocks. + +** Bug fixes: + + - string.escape_pattern is now Lua 5.2 compatible. + + - all objects now reuse prototype metatables, as required for __le and + __lt metamethods to work as documented. + +** Deprecations: + + - To avoid confusion between the builtin Lua `type` function and the + method for finding the object prototype names, `std.object.type` is + deprecated in favour of `std.object.prototype`. `std.object.type` + continues to work for now, but might be removed from a future + release. + + local prototype = (require 'std.object').prototype + + ...makes for more readable code, rather than confusion between the + different flavours of `type`. + +** Incompatible changes: + + - Following on from the Grand Renaming™ change in the last release, + `std.debug_ext`, `std.io_ext`, `std.math_ext`, `std.package_ext`, + `std.string_ext` and `std.table_ext` no longer have the spurious + `_ext` suffix. Instead, you must now use, e.g.: + + local string = require "std.string" + + These names are now stable, and will be available from here for + future releases. + + - The `std.list` module, as a consequence of returning a List object + prototype rather than a table of functions including a constructor, + now always has the list operand as the first argument, whether that + function is called with `.` syntax or `:` syntax. Functions which + previously had the list operand in a different position when called + with `.` syntax were: list.filter, list.foldl, list.foldr, + list.index_key, list.index_value, list.map, list.map_with, + list.project, list.shape and list.zip_with. Calls made as object + methods using `:` calling syntax are unchanged. + + - The `std.set` module is a `std.container` with no object methods, + and now uses prototype functions instead: + + local union = Set.union (set1, set2) + + * Noteworthy changes in release 35 (2013-05-06) [stable] ** New features: diff --git a/README.md b/README similarity index 96% rename from README.md rename to README index 0a7bb94..a076bf0 100644 --- a/README.md +++ b/README @@ -58,7 +58,7 @@ stdlib. Documentation ------------- -The libraries are [documented in LuaDoc][github.io]. Pre-built HTML +The libraries are [documented in LDoc][github.io]. Pre-built HTML files are included. [github.io]: http://rrthomas.github.io/lua-stdlib diff --git a/aclocal.m4 b/aclocal.m4 index 73b9204..05b078f 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.13.1 -*- Autoconf -*- +# generated automatically by aclocal 1.14.1 -*- Autoconf -*- -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.13' +[am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.13.1], [], +m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,7 +51,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.13.1])dnl +[AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) @@ -120,6 +120,12 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -228,7 +234,48 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further @@ -236,7 +283,6 @@ dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -577,76 +623,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of '-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR diff --git a/bootstrap b/bootstrap index c230e82..82ee636 100755 --- a/bootstrap +++ b/bootstrap @@ -1,20 +1,260 @@ #! /bin/sh +## DO NOT EDIT - This file generated from build-aux/bootstrap.in +## by inline-source v2014-01-03.01 # Bootstrap an Autotooled package from checked-out sources. # Written by Gary V. Vaughan, 2010 -# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# Copyright (C) 2010-2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Originally written by Paul Eggert. The canonical version of this +# script is maintained as build-aux/bootstrap in gnulib, however, to +# be useful to your project, you should place a copy of it under +# version control in the top-level directory of your project. The +# intent is that all customization can be done with a bootstrap.conf +# file also maintained in your version control; gnulib comes with a +# template build-aux/bootstrap.conf to get you started. + +# Please report bugs or propose patches to bug-gnulib@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Most GNUish projects do not keep all of the generated Autotool +# files under version control, but running all of the right tools +# with the right arguments, in the correct order to regenerate +# all of those files in readiness for configuration and building +# can be surprisingly involved! Many projects have a 'bootstrap' +# script under version control to invoke Autotools and perform +# other assorted book-keeping with version numbers and the like. +# +# This bootstrap script aims to probe the configure.ac and top +# Makefile.am of your project to automatically determine what +# the correct ordering and arguments are and then run the tools for +# you. In order to use it, you can generate an initial standalone +# script with: +# +# gl/build-aux/inline-source gl/build-aux/bootstrap.in > bootstrap +# +# You should then store than script in version control for other +# developers in you project. It will give you instructions about +# how to keep it up to date if the sources change. +# +# See gl/doc/bootstrap.texi for documentation on how to write +# a bootstrap.conf to customize it for your project's +# idiosyncracies. + + +## ================================================================== ## +## ## +## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ## +## ## +## ================================================================== ## + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase denotes values stored in the environment. These +# variables should generally be overridden by the user - however, we do +# set them to 'true' in some parts of this script to prevent them being +# called at the wrong time by other tools that we call ('autoreconf', +# for example). +# +# We also allow 'LIBTOOLIZE', 'M4', 'SHA1SUM' and some others to be +# overridden, and export the result for child processes, but they are +# handled by the function 'func_find_tool' and not defaulted in this +# section. + +: ${ACLOCAL="aclocal"} +: ${AUTOCONF="autoconf"} +: ${AUTOHEADER="autoheader"} +: ${AUTOM4TE="autom4te"} +: ${AUTOHEADER="autoheader"} +: ${AUTOMAKE="automake"} +: ${AUTOPOINT="autopoint"} +: ${AUTORECONF="autoreconf"} +: ${CMP="cmp"} +: ${CONFIG_SHELL="/bin/sh"} +: ${DIFF="diff"} +: ${GIT="git"} +: ${LN_S="ln -s"} +: ${RM="rm"} + +export ACLOCAL +export AUTOCONF +export AUTOHEADER +export AUTOM4TE +export AUTOHEADER +export AUTOMAKE +export AUTOPOINT +export AUTORECONF +export CONFIG_SHELL + + +: ${LUAROCKS="luarocks"} + +export LUAROCKS + + +## -------------- ## +## Configuration. ## +## -------------- ## + +# A newline delimited list of triples of programs (that respond to +# --version), the minimum version numbers required (or just '-' in the +# version field if any version will be sufficient) and homepage URLs +# to help locate missing packages. +buildreq= + +# Name of a file containing instructions on installing missing packages +# required in 'buildreq'. +buildreq_readme=README-hacking + +# These are extracted from AC_INIT in configure.ac, though you can +# override those values in 'bootstrap.conf' if you prefer. +build_aux= +macro_dir= +package= +package_name= +package_version= +package_bugreport= + +# These are extracted from 'gnulib-cache.m4', or else fall-back +# automatically on the gnulib defaults; unless you set the values +# manually in 'bootstrap.conf'. +doc_base= +gnulib_mk= +gnulib_name= +local_gl_dir= +source_base= +tests_base= + +# The list of gnulib modules required at 'gnulib-tool' time. If you +# check 'gnulib-cache.m4' into your repository, then this list will be +# extracted automatically. +gnulib_modules= + +# Extra gnulib files that are not in modules, which override files of +# the same name installed by other bootstrap tools. +gnulib_non_module_files=" + build-aux/compile + build-aux/install-sh + build-aux/mdate-sh + build-aux/texinfo.tex + build-aux/depcomp + build-aux/config.guess + build-aux/config.sub + doc/INSTALL +" + +# Relative path to the local gnulib submodule, and url to the upstream +# git repository. If you have a gnulib entry in your .gitmodules file, +# these values are ignored. +gnulib_path= +gnulib_url= + +# Additional gnulib-tool options to use. +gnulib_tool_options=" + --no-changelog +" + +# bootstrap removes any macro-files that are not included by aclocal.m4, +# except for files listed in this variable that are always kept. +gnulib_precious=" + gnulib-tool.m4 +" + +# When truncating long commands for display, always allow at least this +# many characters before truncating. +min_cmd_len=160 + +# The command to download all .po files for a specified domain into +# a specified directory. Fill in the first %s is the domain name, and +# the second with the destination directory. Use rsync's -L and -r +# options because the latest/%s directory and the .po files within are +# all symlinks. +po_download_command_format=\ +"rsync --delete --exclude '*.s1' -Lrtvz \ +'translationproject.org::tp/latest/%s/' '%s'" + +# Other locale categories that need message catalogs. +extra_locale_categories= + +# Additional xgettext options to use. Gnulib might provide you with an +# extensive list of additional options to append to this, but gettext +# 0.16.1 and newer appends them automaticaly, so you can safely ignore +# the complaints from 'gnulib-tool' if your $configure_ac states: +# +# AM_GNU_GETTEXT_VERSION([0.16.1]) +xgettext_options=" + --flag=_:1:pass-c-format + --flag=N_:1:pass-c-format +" + +# Package copyright holder for gettext files. Defaults to FSF if unset. +copyright_holder= + +# File that should exist in the top directory of a checked out hierarchy, +# but not in a distribution tarball. +checkout_only_file= + +# Whether to use copies instead of symlinks by default (if set to true, +# the --copy option has no effect). +copy=false + +# Set this to ".cvsignore .gitignore" in 'bootstrap.conf' if you want +# those files to be generated in directories like 'lib/', 'm4/', and 'po/', +# or set it to "auto" to make this script select what to use based +# on what version control system (if any) is used in the source directory. +# Or set it to "none" to ignore VCS ignore files entirely. Default is +# "auto". +vc_ignore= + + +# List of slingshot files to link into stdlib tree before autotooling. +slingshot_files=$slingshot_files + +# Relative path to the local slingshot submodule, and url to the upsream +# git repository. If you have a slingshot entry in your .gitmodules file, +# these values are ignored. +slingshot_path=$slingshot_path +slingshot_url=$slingshot_url + +# NOTE: slingshot bootstrap will check rockspecs listed in $buildreq, +# according to the URL part of a specification triple ending in +# `.rockspec`. + + +## ------------------- ## +## External Libraries. ## +## ------------------- ## + # Source required external libraries: # Set a version string for this script. -scriptversion=2012-10-21.11; # UTC +scriptversion=2014-01-03.01; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 -# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -92,49 +332,159 @@ done sp=' ' nl=' ' -IFS=" $sp$nl" - -# There are still modern systems that have problems with 'echo' mis- -# handling backslashes, among others, so make sure $bs_echo is set to a -# command that correctly interprets backslashes. -# (this code from Autoconf 2.68) - -# Printing a long string crashes Solaris 7 /usr/bin/printf. -bs_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo -bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $bs_echo`" = "X$bs_echo") 2>/dev/null; then - bs_echo='print -r --' - bs_echo_n='print -rn --' -elif (test "X`printf %s $bs_echo`" = "X$bs_echo") 2>/dev/null; then - bs_echo='printf %s\n' - bs_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $bs_echo) 2>/dev/null`" = "X-n $bs_echo"; then - bs_echo_body='eval /usr/ucb/echo -n "$1$nl"' - bs_echo_n='/usr/ucb/echo -n' - else - bs_echo_body='eval expr "X$1" : "X\\(.*\\)"' - bs_echo_n_body='eval - arg=$1; - case $arg in #( - *"$nl"*) - expr "X$arg" : "X\\(.*\\)$nl"; - arg=`expr "X$arg" : ".*$nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$nl" - ' - export bs_echo_n_body - bs_echo_n='sh -c $bs_echo_n_body bs_echo' - fi - export bs_echo_body - bs_echo='sh -c $bs_echo_body bs_echo' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } fi + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=$PATH_SEPARATOR + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## @@ -145,16 +495,14 @@ fi # in the command search PATH. : ${CP="cp -f"} -: ${ECHO="$bs_echo"} -: ${EGREP="grep -E"} -: ${FGREP="grep -F"} -: ${GREP="grep"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} -: ${SED="sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} @@ -177,7 +525,7 @@ sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains +# that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' @@ -245,13 +593,13 @@ exit_status=$EXIT_SUCCESS progpath=$0 # The name of this program. -progname=`$bs_echo "$progpath" |$SED "$sed_basename"` +progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) - progdir=`$bs_echo "$progpath" |$SED "$sed_dirname"` + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; @@ -352,6 +700,173 @@ func_require_term_colors () } +# require_rockspecs_req +# --------------------- +# Remove rockspecs from $buildreq, and add them to $rockspecs_req. +require_rockspecs_req=slingshot_require_rockspecs_req +slingshot_require_rockspecs_req () +{ + $debug_cmd + + test -n "$rockspecs_req" || { + _G_non_rockspecs= + + set dummy $buildreq; shift + + while test $# -gt 2; do + case $3 in + *.rockspec) + func_append rockspecs_req " $1 $2 $3" + ;; + [a-z]*://*) + func_append _G_non_rockspecs " $1 $2 $3" + ;; + *) func_fatal_error "\ +'$3' from the buildreq table in +'bootstrap.conf' does not look like the URL for downloading +$1. Please ensure that buildreq is a strict newline +delimited list of triples; 'program min-version url'." + ;; + esac + shift; shift; shift + done + + buildreq=$_G_non_rockspecs + } + + require_rockspecs_req=: +} + + +# require_slingshot_dotgitmodules +# ------------------------------- +# Ensure we have a '.gitmodules' file, with appropriate 'slingshot' settings. +require_slingshot_dotgitmodules=slingshot_require_slingshot_dotgitmodules +slingshot_require_slingshot_dotgitmodules () +{ + $debug_cmd + + $require_git + + test true = "$GIT" || { + # A slingshot entry in .gitmodules always takes precedence. + _G_path=`$GIT config --file .gitmodules submodule.slingshot.path 2>/dev/null` + + test -n "$_G_path" || { + $require_vc_ignore_files + + func_verbose "adding slingshot entries to '.gitmodules'" + + test -n "$slingshot_path" || slingshot_path=slingshot + test -n "$slingshot_url" || slingshot_url=git://github.com/gvvaughan/slingshot.git + + { + echo '[submodule "slingshot"]' + echo " path=$slingshot_path" + echo " url=$slingshot_url" + } >> .gitmodules + + test -n "$vc_ignore_files" \ + || func_insert_if_absent ".gitmodules" $vc_ignore_files + } + } + + require_slingshot_dotgitmodules=: +} + + +# require_slingshot_path +# require_slingshot_url +# ---------------------- +# Ensure 'slingshot_path' and 'slingshot_url' are set. +require_slingshot_path=slingshot_require_slingshot_dotgitmodules_parameters +require_slingshot_url=slingshot_require_slingshot_dotgitmodules_parameters +slingshot_require_slingshot_dotgitmodules_parameters () +{ + $debug_cmd + + $require_git + $require_slingshot_dotgitmodules + + test -f .gitmodules \ + || func_fatal_error "Unable to update '.gitmodules' with slingshot submodule" + + test true = "$GIT" || { + slingshot_path=`$GIT config --file=.gitmodules --get submodule.slingshot.path` + slingshot_url=`$GIT config --file=.gitmodules --get submodule.slingshot.url` + + func_verbose "slingshot_path='$slingshot_path'" + func_verbose "slingshot_url='$slingshot_url'" + } + + require_slingshot_path=: + require_slingshot_url=: +} + + +# require_slingshot_submodule +# --------------------------- +# Ensure that there is a current slingshot submodule. +require_slingshot_submodule=slingshot_require_slingshot_submodule +slingshot_require_slingshot_submodule () +{ + $debug_cmd + + $require_git + + if test true = "$GIT"; then + func_warning recommend \ + "No 'git' found; imported slingshot modules may be missing." + else + $require_slingshot_dotgitmodules + + if test -f .gitmodules && test -f "slingshot/src/mkrockspecs.in" + then + : All present and correct. + + else + $require_slingshot_path + $require_slingshot_url + + trap slingshot_cleanup 1 2 13 15 + + shallow= + $GIT clone -h 2>&1 |func_grep_q -- --depth \ + && shallow='--depth 365' + + func_show_eval "$GIT clone $shallow '$slingshot_url' '$slingshot_path'" \ + slingshot_cleanup + + # FIXME: Solaris /bin/sh will try to execute '-' if any of + # these signals are caught after this. + trap - 1 2 13 15 + + # Make sure we've checked out the correct revision of slingshot. + func_show_eval "$GIT submodule init" \ + && func_show_eval "$GIT submodule update" \ + || func_fatal_error "Unable to update slingshot submodule." + fi + fi + + require_slingshot_submodule=: +} + + +# slingshot_cleanup +# ----------------- +# Recursively delete everything at $slingshot_path. +slingshot_cleanup () +{ + $debug_cmd + + $require_slingshot_path + + _G_status=$? + $RM -fr $slingshot_path + exit $_G_status +} + + ## ----------------- ## ## Function library. ## ## ----------------- ## @@ -445,7 +960,7 @@ func_append_uniq () { $debug_cmd - eval _G_current_value='`$bs_echo $'$1'`' + eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in @@ -558,7 +1073,7 @@ func_echo () IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS - $bs_echo "$progname: $_G_line" + $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } @@ -592,17 +1107,17 @@ func_echo_infix_1 () for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { - _G_esc_tc=`$bs_echo "$_G_tc" | sed "$sed_make_literal_regex"` - _G_indent=`$bs_echo "$_G_indent" | sed "s|$_G_esc_tc||g"` + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done - _G_indent="$progname: "`echo "$_G_indent" | sed 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS - $bs_echo "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS @@ -935,7 +1450,7 @@ func_relative_path () # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result -# has just all characters which are still active within double +# has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { @@ -1166,22 +1681,53 @@ func_warning () } +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + # Local variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. -scriptversion=2012-10-21.11; # UTC +scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 -# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# Copyright (C) 2010-2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -1321,7 +1867,7 @@ func_remove_hook () { $debug_cmd - eval ${1}_hooks='`$bs_echo "\$'$1'_hooks" |$SED "s| '$2'||"`' + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } @@ -1589,18 +2135,101 @@ func_validate_options () func_run_hooks func_validate_options ${1+"$@"} - # Bail if the options were screwed! - $exit_cmd $EXIT_FAILURE + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + + +# slingshot_options_prep +# ---------------------- +# Preparation for additional slingshot option parsing. +slingshot_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_skip_rock_checks=false + # opt_luarocks_tree default in *unset*! + + # Extend the existing usage message. + usage_message=$usage_message' +Slingshot Options: + + --luarocks-tree=DIR + check a non-default tree for prerequisite rocks + --skip-rock-checks + ignore Lua rocks in bootstrap.conf:buidreq' + + func_quote_for_eval ${1+"$@"} + slingshot_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep slingshot_options_prep + + +# slingshot_parse_options OPT... +# ------------------------------ +# Called at the end of each main option parse loop to process any +# additional slingshot options. +slingshot_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --luarocks-tree) + test $# = 0 && func_missing_arg $_G_opt && break + opt_luarocks_tree=$1 + shift + ;; + + --skip-rock-checks) + opt_skip_rock_checks=: + ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result + func_quote_for_eval ${1+"$@"} + slingshot_parse_options_result=$func_quote_for_eval_result } +func_add_hook func_parse_options slingshot_parse_options + + +# slingshot_option_validation +# --------------------------- +# Flag any inconsistencies in users' selection of slingshot options. +slingshot_option_validation () +{ + $debug_cmd + test -z "$opt_luarocks_tree" \ + || test -d "$opt_luarocks_tree" \ + || func_fatal_help "$opt_luarocks_tree: not a directory" +} +func_add_hook func_validate_options slingshot_option_validation -## ------------------## +## ----------------- ## ## Helper functions. ## -## ------------------## +## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. @@ -1614,8 +2243,8 @@ func_fatal_help () { $debug_cmd - eval \$bs_echo \""Usage: $usage"\" - eval \$bs_echo \""$fatal_help"\" + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } @@ -1629,7 +2258,7 @@ func_help () $debug_cmd func_usage_message - $bs_echo "$long_help_message" + $ECHO "$long_help_message" exit 0 } @@ -1716,7 +2345,7 @@ func_usage () $debug_cmd func_usage_message - $bs_echo "Run '$progname --help |${PAGER-more}' for full usage" + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } @@ -1728,7 +2357,7 @@ func_usage_message () { $debug_cmd - eval \$bs_echo \""Usage: $usage"\" + eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ @@ -1737,7 +2366,7 @@ func_usage_message () h /^Written by/q' < "$progpath" echo - eval \$bs_echo \""$usage_message"\" + eval \$ECHO \""$usage_message"\" } @@ -1749,7 +2378,7 @@ func_version () $debug_cmd printf '%s\n' "$progname $scriptversion" - $SED -n '/^##/q + $SED -n ' /(C)/!b go :more /\./!{ @@ -1777,7 +2406,7 @@ func_version () # Local variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: @@ -1786,7 +2415,7 @@ func_version () # Extract macro arguments from autotools input with GNU M4. # Written by Gary V. Vaughan, 2010 # -# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# Copyright (C) 2010-2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -1795,7 +2424,7 @@ test -z "$progpath" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/funclib.sh test extract-trace = "$progname" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/options-parser # Set a version string. -scriptversion=2012-10-07.10; # UTC +scriptversion=2014-01-04.01; # UTC # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -1813,6 +2442,82 @@ scriptversion=2012-10-07.10; # UTC # Please report bugs or propose patches to gary@gnu.org. +# slingshot_copy FILENAME SRCDIR DESTDIR +# -------------------------------------- +# If option '--copy' was specified, or soft-linking SRCFILE to DESTFILE +# fails, then try to copy SRCFILE to DESTFILE (making sure to update the +# timestamp so that a series of files with dependencies can be copied +# in the right order that their timestamps won't trigger rebuilds). +slingshot_copy () +{ + $debug_cmd + + slingshot_srcfile=`echo "$2/$1" |sed -e 's|/\./|/|g'` + slingshot_destfile=`echo "$3/$1" |sed -e 's|/\./|/|g'` + + $opt_force || { + # Nothing to do if the files are already identical. + if func_cmp_s "$slingshot_srcfile" "$slingshot_destfile"; then + func_verbose "'$slingshot_destfile' is up to date." + return 0 + fi + } + + # Require --force to remove existing $slingshot_destfile. + $opt_force && $RM "$slingshot_destfile" + test -f "$slingshot_destfile" && { + func_warn_and_continue "'$slingshot_destfile' exists: use '--force' to overwrite" + return 0 + } + + # Be careful to support 'func_copy dir/target srcbase destbase'. + func_dirname "$slingshot_destfile" + func_mkdir_p "$func_dirname_result" + + # Copy or link according to '--copy' option. + if $opt_copy; then + slingshot_copycmd=$CP + slingshot_copy_type=copying + else + slingshot_copycmd=$LN_S + slingshot_copy_type=linking + + func_relative_path "$3" "$2" + slingshot_srcfile=$func_relative_path_result/$1 + fi + slingshot_copy_msg="$slingshot_copy_type file '$slingshot_destfile'" + $opt_verbose && \ + slingshot_copy_msg="$slingshot_copy_type $slingshot_srcfile $3" + + if $opt_dry_run || { + ( umask 0 + $slingshot_copycmd "$slingshot_srcfile" "$slingshot_destfile" + ) >/dev/null 2>&1 + } + then + echo "$slingshot_copy_msg" + else + func_error "$slingshot_copy_type '$2/$1' to '$3/' failed" + return 1 + fi +} + + +# slingshot_rockspec_error +# ------------------------ +# Called by zile_check_rockspecs for missing rocks. +slingshot_rockspec_error () +{ + $debug_cmd + + _G_strippedver=`expr "$_G_reqver" : '=*\(.*\)'` + func_error "\ +Prerequisite LuaRock '$_G_rock $_G_strippedver' not found. Please install it." + + rockspecs_uptodate_result=false +} + + ## ------ ## ## Usage. ## ## ------ ## @@ -1827,9 +2532,9 @@ scriptversion=2012-10-07.10; # UTC -## ------------------## +## ----------------- ## ## Helper functions. ## -## ------------------## +## ----------------- ## # This section contains the helper functions used by the rest of # 'extract-trace'. @@ -1838,7 +2543,7 @@ scriptversion=2012-10-07.10; # UTC # func_autoconf_configure MAYBE-CONFIGURE-FILE # -------------------------------------------- # Ensure that MAYBE-CONFIGURE-FILE is the name of a file in the current -# directory which contains an uncommented call to AC_INIT. +# directory that contains an uncommented call to AC_INIT. func_autoconf_configure () { $debug_cmd @@ -1851,7 +2556,7 @@ func_autoconf_configure () # If we were passed a genuine file, make sure it calls AC_INIT. test -f "$1" \ - && _G_ac_init=`$SED "$_G_sed_no_comment" "$1" |grep AC_INIT` + && _G_ac_init=`$SED "$_G_sed_no_comment" "$1" |$GREP AC_INIT` # Otherwise it is not a genuine Autoconf input file. test -n "$_G_ac_init" @@ -1961,7 +2666,7 @@ func_tool_version_output () # require_configure_ac # -------------------- # Ensure that there is a 'configure.ac' or 'configure.in' file in the -# current directory which contains an uncommented call to AC_INIT, and +# current directory that contains an uncommented call to AC_INIT, and # that '$configure_ac' contains its name. require_configure_ac=func_require_configure_ac func_require_configure_ac () @@ -2025,8 +2730,8 @@ func_extract_trace () $require_configure_ac $require_gnu_m4 - _G_m4_traces=`$bs_echo "--trace=$1" |$SED 's%,% --trace=%g'` - _G_re_macros=`$bs_echo "($1)" |$SED 's%,%|%g'` + _G_m4_traces=`$ECHO "--trace=$1" |$SED 's%,% --trace=%g'` + _G_re_macros=`$ECHO "($1)" |$SED 's%,%|%g'` _G_macros="$1"; shift test $# -gt 0 || { set dummy $configure_ac @@ -2128,7 +2833,7 @@ func_extract_trace () # Save the command pipeline results for further use by callers of # this function. - func_extract_trace_result=`$bs_echo "$_G_mini" \ + func_extract_trace_result=`$ECHO "$_G_mini" \ |$M4 -daq --prefix $_G_m4_traces - "$@" 2>&1 1>/dev/null \ |$SED -n -e "$_G_transform"` } @@ -2144,7 +2849,7 @@ func_extract_trace_first () $debug_cmd func_extract_trace ${1+"$@"} - func_extract_trace_first_result=`$bs_echo "$func_extract_trace_result" \ + func_extract_trace_first_result=`$ECHO "$func_extract_trace_result" \ |$SED -e 's|:.*$||g' -e 1q` } @@ -2180,7 +2885,7 @@ on a separate line.' # Display results. test -n "$func_extract_trace_result" \ - && $bs_echo "$func_extract_trace_result" + && $ECHO "$func_extract_trace_result" # The End. exit $EXIT_SUCCESS @@ -2197,231 +2902,13 @@ test extract-trace = "$progname" && func_main "$@" # Local variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "20/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: -# Set a version string for *this* script. -scriptversion=2013-01-20.16; # UTC - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Originally written by Paul Eggert. The canonical version of this -# script is maintained as build-aux/bootstrap in gnulib, however, to -# be useful to your project, you should place a copy of it under -# version control in the top-level directory of your project. The -# intent is that all customization can be done with a bootstrap.conf -# file also maintained in your version control; gnulib comes with a -# template build-aux/bootstrap.conf to get you started. - -# Please report bugs or propose patches to bug-gnulib@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# Most GNUish projects do not keep all of the generated Autotool -# files under version control, but running all of the right tools -# with the right arguments, in the correct order to regenerate -# all of those files in readiness for configuration and building -# can be surprisingly involved! Many projects have a 'bootstrap' -# script under version control to invoke Autotools and perform -# other assorted book-keeping with version numbers and the like. -# -# This bootstrap script aims to probe the configure.ac and top -# Makefile.am of your project to automatically determine what -# the correct ordering and arguments are and then run the tools for -# you. In order to use it, you can generate an initial standalone -# script with: -# -# gl/build-aux/inline-source gl/build-aux/bootstrap.in > bootstrap -# -# You should then store than script in version control for other -# developers in you project. It will give you instructions about -# how to keep it up to date if the sources change. -# -# See gl/doc/bootstrap.texi for documentation on how to write -# a bootstrap.conf to customize it for your project's -# idiosyncracies. - - -## ================================================================== ## -## ## -## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ## -## ## -## ================================================================== ## - -## ------------------------------- ## -## User overridable command paths. ## -## ------------------------------- ## - -# All uppercase denotes values stored in the environment. These -# variables should generally be overridden by the user - however, we do -# set them to 'true' in some parts of this script to prevent them being -# called at the wrong time by other tools that we call ('autoreconf', -# for example). -# -# We also allow 'LIBTOOLIZE', 'M4', 'SHA1SUM' and some others to be -# overridden, and export the result for child processes, but they are -# handled by the function 'func_find_tool' and not defaulted in this -# section. - -: ${ACLOCAL="aclocal"} -: ${AUTOCONF="autoconf"} -: ${AUTOHEADER="autoheader"} -: ${AUTOM4TE="autom4te"} -: ${AUTOHEADER="autoheader"} -: ${AUTOMAKE="automake"} -: ${AUTOPOINT="autopoint"} -: ${AUTORECONF="autoreconf"} -: ${CMP="cmp"} -: ${CONFIG_SHELL="/bin/sh"} -: ${DIFF="diff"} -: ${EGREP="grep -E"} -: ${FGREP="grep -F"} -: ${GIT="git"} -: ${GREP="grep"} -: ${LN_S="ln -s"} -: ${RM="rm"} -: ${SED="sed"} - -export ACLOCAL -export AUTOCONF -export AUTOHEADER -export AUTOM4TE -export AUTOHEADER -export AUTOMAKE -export AUTOPOINT -export AUTORECONF -export CONFIG_SHELL - - -## -------------- ## -## Configuration. ## -## -------------- ## - -# A newline delimited list of triples of programs (that respond to -# --version), the minimum version numbers required (or just '-' in the -# version field if any version will be sufficient) and homepage URLs -# to help locate missing packages. -buildreq= - -# Name of a file containing instructions on installing missing packages -# required in 'buildreq'. -buildreq_readme=README-hacking - -# These are extracted from AC_INIT in configure.ac, though you can -# override those values in 'bootstrap.conf' if you prefer. -build_aux= -macro_dir= -package= -package_name= -package_version= -package_bugreport= - -# These are extracted from 'gnulib-cache.m4', or else fall-back -# automatically on the gnulib defaults; unless you set the values -# manually in 'bootstrap.conf'. -doc_base= -gnulib_mk= -gnulib_name= -local_gl_dir= -source_base= -tests_base= - -# The list of gnulib modules required at 'gnulib-tool' time. If you -# check 'gnulib-cache.m4' into your repository, then this list will be -# extracted automatically. -gnulib_modules= - -# Extra gnulib files that are not in modules, which override files of -# the same name installed by other bootstrap tools. -gnulib_non_module_files=" - build-aux/compile - build-aux/install-sh - build-aux/mdate-sh - build-aux/texinfo.tex - build-aux/depcomp - build-aux/config.guess - build-aux/config.sub - doc/INSTALL -" - -# Relative path to the local gnulib submodule, and url to the upstream -# git repository. If you have a gnulib entry in your .gitmodules file, -# these values are ignored. -gnulib_path= -gnulib_url= - -# Additional gnulib-tool options to use. -gnulib_tool_options=" - --no-changelog -" - -# bootstrap removes any macro-files that are not included by aclocal.m4, -# except for files listed in this variable which are always kept. -gnulib_precious=" - gnulib-tool.m4 -" - -# When truncating long commands for display, always allow at least this -# many characters before truncating. -min_cmd_len=160 - -# The command to download all .po files for a specified domain into -# a specified directory. Fill in the first %s is the domain name, and -# the second with the destination directory. Use rsync's -L and -r -# options because the latest/%s directory and the .po files within are -# all symlinks. -po_download_command_format=\ -"rsync --delete --exclude '*.s1' -Lrtvz \ -'translationproject.org::tp/latest/%s/' '%s'" - -# Other locale categories that need message catalogs. -extra_locale_categories= - -# Additional xgettext options to use. Gnulib might provide you with an -# extensive list of additional options to append to this, but gettext -# 0.16.1 and newer appends them automaticaly, so you can safely ignore -# the complaints from 'gnulib-tool' if your $configure_ac states: -# -# AM_GNU_GETTEXT_VERSION([0.16.1]) -xgettext_options=" - --flag=_:1:pass-c-format - --flag=N_:1:pass-c-format -" - -# Package copyright holder for gettext files. Defaults to FSF if unset. -copyright_holder= - -# File that should exist in the top directory of a checked out hierarchy, -# but not in a distribution tarball. -checkout_only_file= - -# Whether to use copies instead of symlinks by default (if set to true, -# the --copy option has no effect). -copy=false - -# Set this to ".cvsignore .gitignore" in 'bootstrap.conf' if you want -# those files to be generated in directories like 'lib/', 'm4/', and 'po/', -# or set it to "auto" to make this script select which to use based -# on which version control system (if any) is used in the source directory. -# Or set it to "none" to ignore VCS ignore files entirely. Default is -# "auto". -vc_ignore= +# Set a version string for *this* script. +scriptversion=2014-01-04.01; # UTC ## ------------------- ## @@ -2431,7 +2918,7 @@ vc_ignore= # After 'bootstrap.conf' has been sourced, execution proceeds by calling # 'func_bootstrap'. Wherever a function is decorated with # 'func_hookable func_name', you will find a matching 'func_run_hooks -# func_name' which executes all functions added with 'func_add_hook +# func_name', which executes all functions added with 'func_add_hook # func_name my_func'. # # You might notice that many of these functions begin with a series of @@ -2461,10 +2948,6 @@ func_bootstrap () # Post-option preparation. func_prep - # Ensure ChangeLog presence. - func_ifcontains "$gnulib_modules" gitlog-to-changelog \ - func_ensure_changelog - # Reconfigure the package. func_reconfigure @@ -2509,6 +2992,10 @@ func_prep () $require_gnulib_merge_changelog + # Report the results of SED and GREP searches from funclib.sh. + func_verbose "GREP='$GREP'" + func_verbose "SED='$SED'" + # fetch update files from the translation project func_update_translations @@ -2545,8 +3032,29 @@ func_reconfigure () { $debug_cmd + $require_automake_options + + # Automake (without 'foreign' option) requires that README exists. + case " $automake_options " in + " foreign ") ;; + *) func_ensure_README ;; + esac + + # Ensure ChangeLog presence. + if test -n "$gnulib_modules"; then + func_ifcontains "$gnulib_modules" gitlog-to-changelog \ + func_ensure_changelog + else + $require_gnulib_cache + if $SED -n '/^gl_MODULES(\[/,/^])$/p' $gnulib_cache 2>/dev/null | + func_grep_q gitlog-to-changelog + then + func_ensure_changelog + fi + fi + # Released 'autopoint' has the tendency to install macros that have - # been obsoleted in current 'gnulib., so run this before 'gnulib-tool'. + # been obsoleted in current 'gnulib', so run this before 'gnulib-tool'. func_autopoint # Autoreconf runs 'aclocal' before 'libtoolize', which causes spurious @@ -2571,8 +3079,12 @@ func_reconfigure () # # It's assumed that since you are using gnulib's 'bootstrap' script, # you're also using gnulib elsewhere in your package. If not, then -# you can preset 'gnulib_tool=true' in your 'bootstrap.conf' to force -# this function to return immediately. +# you can replace this function in 'bootstrap.conf' with: +# +# func_gnulib_tool () { :; } +# +# (although the function returns immediately if $gnulib_tool is set to +# true in any case). func_hookable func_gnulib_tool func_gnulib_tool () { @@ -2582,6 +3094,13 @@ func_gnulib_tool () $require_libtoolize test true = "$gnulib_tool" || { + # bootstrap.conf written for gnulib bootstrap expects + # gnulib_tool_option_extras to which --no-changelog is appended, + # but libtool bootstrap expects you to append to gnulib_tool_options + # so that you can override the --no-changelog default: make sure we + # support both styles so users can migrate between them easily. + gnulib_tool_all_options="$gnulib_tool_options $gnulib_tool_option_extras" + if test -n "$gnulib_modules"; then $require_gnulib_cache $require_gnulib_tool_base_options @@ -2591,7 +3110,6 @@ func_gnulib_tool () # Try not to pick up any stale values from 'gnulib-cache.m4'. rm -f "$gnulib_cache" - gnulib_tool_all_options=$gnulib_tool_options test -n "$gnulib_tool_base_options" \ && func_append_uniq gnulib_tool_all_options " $gnulib_tool_base_options" test -n "$gnulib_mk" \ @@ -2605,8 +3123,6 @@ func_gnulib_tool () # 'gnulib_modules' and others are cached in 'gnulib-cache.m4': # Use 'gnulib --update' to fetch gnulib modules. gnulib_mode=--update - - gnulib_tool_all_options=$gnulib_tool_options fi # Add a sensible default libtool option to gnulib_tool_options. @@ -2707,6 +3223,169 @@ func_gettext_configuration () +## The section title above is chosen for what section of bootstrap +## these functions will be merged to, so that the invocations of +## `func_add_hook` are guaranteed not to be executed until after +## the hook management functions are defined. + + +# slingshot_split_buildreq +# ------------------------ +# For convenience, let the user add rockspec requirements to $buildreq. +# Note that this is for *build-time* requirements (e.g. ldoc), so that +# make can complete without error. You should add *run-time* rockspec +# requirements (e.g. stdlib) to rockspec.conf. +slingshot_split_buildreq () +{ + $debug_cmd + + $require_rockspecs_req +} +func_add_hook func_init slingshot_split_buildreq + + +# slingshot_check_rockspecs +# ------------------------- +# Check build-time rockspecs from $buildreq are uptodate. +# It would be nice if we could rely on luarock binaries to respond to +# `--version` like GNU apps, but there is no reliable consensus, so we +# have to check installed luarock versions directly, and warn the user +# if the apps we're checking for are not somewhere along PATH. +slingshot_check_rockspecs () +{ + $debug_cmd + + $opt_skip_rock_checks && return + + $require_rockspecs_req + + _G_req= + rockspecs_uptodate_result=: + + set dummy $rockspecs_req; shift + while test $# -gt 0; do + _G_rock=$1; shift + _G_reqver=$1; shift + _G_url=$1; shift + + func_append _G_req " $_G_rock $_G_url" + + # Honor $APP variables ($LDOC, $SPECL, etc.) + _G_appvar=`echo $_G_rock |tr '[a-z]' '[A-Z]'` + eval "_G_rock=\${$_G_appvar-$_G_rock}" + + # Trust the user will ensure the binaries will arive at the + # specified location before they are needed if they set these. + if eval 'test -n "${'$_G_appvar'+set}"'; then + eval test -f '"${'$_G_appvar'}"' \ + || eval 'func_warning settings "\ +not checking whether $'$_G_appvar' has version $_G_reqver; +configure or make may fail because you set $_G_appvar, but +$'$_G_appvar' does not yet exist!"' + else + _G_instver=`$LUAROCKS ${opt_luarocks_tree+--tree=$opt_luarocks_tree} \ + show $_G_rock 2>/dev/null \ + |sed -n '/^'"$_G_rock"' .* - /{s/^'"$_G_rock"' \(.*\) - .*$/\1/p;}'` + + if test -z "$_G_instver"; then + slingshot_rockspec_error + else + func_verbose "found '$_G_rock' version $_G_instver." + + case $_G_reqver in + =*) + test "x$_G_reqver" = "x=$_G_instver" || slingshot_rockspec_error + ;; + *) + func_lt_ver "$_G_reqver" "$_G_instver" || slingshot_rockspec_error + ;; + esac + fi + fi + done + + $rockspecs_uptodate_result || { + func_strtable 0 10 48 \ + "Program" "Rockspec_URL" $_G_req + func_fatal_error "Missing rocks: +$func_strtable_result +Install missing rockspecs with: + $LUAROCKS ${opt_luarocks_tree+--tree=$opt_luarocks_tree }install \$Rockspec_URL +and then rerun bootstrap with the --luarocks-tree option set +appropriately, or if you're sure that the missing rocks will +be installed before running make by exporting: + APPNAME=/path/to/app. +" + } +} +func_add_hook func_prep slingshot_check_rockspecs + + +# slingshot_copy_files +# -------------------- +# Update files from slingshot subproject. +slingshot_copy_files () +{ + $debug_cmd + + $require_package + + test slingshot = "$package" || { + func_check_configuration slingshot_files + + $require_slingshot_submodule + + # Make sure we have the latest mkrockspecs + make -C slingshot build-aux/mkrockspecs + + # Update in-tree links. + for file in $slingshot_files; do + func_dirname_and_basename "./$file" + slingshot_copy "$func_basename_result" \ + "slingshot/$func_dirname_result" "$func_dirname_result" + done + } +} +func_add_hook func_prep slingshot_copy_files + + +# slingshot_ensure_changelog +# -------------------------- +# Slingshot project probably won't have a gnulib_modules list. +# So we redo the ChangeLog check against slingshot_files. +slingshot_ensure_changelog () +{ + $debug_cmd + + if test -n "$slingshot_files"; then + func_ifcontains "$slingshot_files" build-aux/gitlog-to-changelog \ + func_ensure_changelog + fi + + return 0 +} +func_add_hook func_prep slingshot_ensure_changelog + + +# slingshot_check_rockstree_path +# ------------------------------ +# Show a warning at the end of bootstrap if --luarocks-tree was passed +# set, but $opt_luarocks_tree/bin is not in the command PATH. +slingshot_check_rockstree_path () +{ + $debug_cmd + + test -z "$rockspecs_req" || { + case :$PATH: in + *:$opt_luarocks_tree/bin:*) ;; + *) func_warning recommend \ + "If configure or make fail, try adding $opt_luarocks_tree/bin to PATH" ;; + esac + } +} +func_add_hook func_fini slingshot_check_rockstree_path + + ## --------------- ## ## Core functions. ## ## --------------- ## @@ -2758,13 +3437,9 @@ func_gnulib_tool_copy_file () { $debug_cmd - $require_gnulib_path $require_gnulib_tool $require_patch - gnulib_copy_cmd="$gnulib_tool --copy-file" - $opt_copy || func_append gnulib_copy_cmd " --symlink" - if test true = "$gnulib_tool"; then # If gnulib-tool is not available (e.g. bootstrapping in a # distribution tarball), make sure that at least we have some @@ -2778,12 +3453,14 @@ or else specify the location of your 'git' binary by setting 'GIT' in the environment so that a fresh 'gnulib' submodule can be cloned." else - test -f "$gnulib_path/$1" || { + $require_gnulib_copy_cmd + + $gnulib_copy_cmd $1 $2 2>/dev/null || { + $require_gnulib_path + func_error "'$gnulib_path/$1' does not exist" return 1 } - - $gnulib_copy_cmd $1 $2 fi } @@ -2852,12 +3529,44 @@ EOT } -# func_autoreconf -# --------------- +# func_ensure_README +# ------------------ +# Without AM_INIT_AUTOMAKE([foreign]), automake will not run to +# completion with no README file, even though README.md or README.txt +# is often preferable. +func_ensure_README () +{ + $debug_cmd + + test -f README || { + _G_README= + for _G_readme in README.txt README.md README.rst; do + test -f "$_G_readme" && break + done + + test -f "$_G_readme" && $LN_S $_G_readme README + func_verbose "$LN_S $_G_readme README" + } + + return 0 +} + + +# func_autoreconf [SUBDIR] +# ------------------------ # Being careful not to re-run 'autopoint' or 'libtoolize', and not to # try to run 'autopoint', 'libtoolize' or 'autoheader' on packages that # don't use them, defer to 'autoreconf' for execution of the remaining # autotools to bootstrap this package. +# +# Projects with multiple trees to reconfigure can hook another call to +# this function onto func_reconfigure: +# +# my_autoreconf_foo () +# { +# func_autoreconf foo +# } +# func_add_hook func_reconfigure my_autoreconf_foo func_autoreconf () { $debug_cmd @@ -2874,7 +3583,7 @@ func_autoreconf () $opt_copy || func_append _G_autoreconf_options " --symlink" $opt_force && func_append _G_autoreconf_options " --force" $opt_verbose && func_append _G_autoreconf_options " --verbose" - func_show_eval "$AUTORECONF$_G_autoreconf_options --install" 'exit $?' + func_show_eval "$AUTORECONF$_G_autoreconf_options --install${1+ $1}" 'exit $?' AUTOPOINT=$save_AUTOPOINT LIBTOOLIZE=$save_LIBTOOLIZE @@ -2912,7 +3621,7 @@ $2" # the usual portability constraints of this script, that may seem a very # demanding requirement, but it should be ok. Ignore any failure, # which is fine, since this is only a convenience to help developers -# avoid the relatively unusual case in which a symlinked-to .m4 file is +# avoid the relatively unusual case where a symlinked-to .m4 file is # git-removed from gnulib between successive runs of this script. func_clean_dangling_symlinks () { @@ -2941,36 +3650,34 @@ func_clean_unused_macros () { $debug_cmd - test true = "$gnulib_tool" || { - $require_gnulib_path - $require_macro_dir + $require_gnulib_path + $require_macro_dir - test -n "$gnulib_path" && test -f aclocal.m4 && { - aclocal_m4s=`find . -name aclocal.m4 -print` - - # We use 'ls|grep' instead of 'ls *.m4' to avoid exceeding - # command line length limits in some shells. - for file in `cd "$macro_dir" && ls -1 |grep '\.m4$'`; do - - # Remove a macro file when aclocal.m4 does not m4_include it... - func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \ - || test ! -f "$gnulib_path/m4/$file" || { - - # ...and there is an identical file in gnulib... - if func_cmp_s "$gnulib_path/m4/$file" "$macro_dir/$file"; then - - # ...and it's not in the precious list ('echo' is needed - # here to squash whitespace for the match expression). - case " "`echo $gnulib_precious`" " in - *" $file "*) ;; - *) rm -f "$macro_dir/$file" - func_verbose \ - "removing unused gnulib file '$macro_dir/$file'" - esac - fi - } - done - } + test -n "$gnulib_path" && test -f aclocal.m4 && { + aclocal_m4s=`find . -name aclocal.m4 -print` + + # We use 'ls|grep' instead of 'ls *.m4' to avoid exceeding + # command line length limits in some shells. + for file in `cd "$macro_dir" && ls -1 |$GREP '\.m4$'`; do + + # Remove a macro file when aclocal.m4 does not m4_include it... + func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \ + || test ! -f "$gnulib_path/m4/$file" || { + + # ...and there is an identical file in gnulib... + if func_cmp_s "$gnulib_path/m4/$file" "$macro_dir/$file"; then + + # ...and it's not in the precious list ('echo' is needed + # here to squash whitespace for the match expression). + case " "`echo $gnulib_precious`" " in + *" $file "*) ;; + *) rm -f "$macro_dir/$file" + func_verbose \ + "removing unused gnulib file '$macro_dir/$file'" + esac + fi + } + done } } @@ -3101,6 +3808,21 @@ func_require_autoheader () } +# require_automake_options +# ------------------------ +# Extract options from AM_AUTOMAKE_INIT. +require_automake_options=func_require_automake_options +func_require_automake_options () +{ + $debug_cmd + + func_extract_trace AM_INIT_AUTOMAKE + automake_options=$func_extract_trace_result + + require_automake_options=: +} + + # require_autopoint # ----------------- # Skip autopoint if it's not needed. @@ -3155,17 +3877,19 @@ Please add bootstrap to your gnulib_modules list in 'bootstrap.conf', so that I can tell you when there are updates available." else + rm -f bootstrap.new $build_aux/inline-source $build_aux/bootstrap.in > bootstrap.new if func_cmp_s "$progpath" bootstrap.new; then rm -f bootstrap.new func_verbose "bootstrap script up to date" else + chmod 555 bootstrap.new func_warning upgrade "\ An updated bootstrap script has been generated for you in 'bootstrap.new'. After you've verified that you want the changes, you can update with: - cat bootstrap.new > $progname + mv -f bootstrap.new $progname ./$progname Or you can disable this check permanently by adding the @@ -3269,7 +3993,7 @@ for tool in autoconf libtoolize autopoint; do '$tool' $_G_version http://www.gnu.org/s/'$b' " func_verbose \ - "auto-adding '\'$tool'-'$_G_version\'' to build requirements" + "auto-adding '\'$tool'-$_G_version'\'' to build requirements" } } @@ -3294,7 +4018,7 @@ func_require_buildreq_automake () # ...and AM_INIT_AUTOMAKE is declared... test -n "$func_extract_trace_result" && { - automake_version=`$bs_echo "$func_extract_trace_result" \ + automake_version=`$ECHO "$func_extract_trace_result" \ |$SED -e 's|[^0-9]*||' -e 's| .*$||'` test -n "$automake_version" || automake_version=- @@ -3319,6 +4043,8 @@ func_require_buildreq_patch () { $debug_cmd + $require_local_gl_dir + # This ensures PATCH is set appropriately by the time # func_check_versions enforces $buildreq. $require_patch @@ -3394,6 +4120,28 @@ defaulting to '$copyright_holder'." } +# require_doc_base +# ---------------- +# Ensure doc_base has a sensible value, extracted from 'gnulib-cache.m4' +# if possible, otherwise letting 'gnulib-tool' pick a default. +require_doc_base=func_require_doc_base +func_require_doc_base () +{ + $debug_cmd + + $require_gnulib_cache + + test -f "$gnulib_cache" && test -z "$doc_base" && { + func_extract_trace_first "gl_DOC_BASE" "$gnulib_cache" + doc_base=$func_extract_trace_first_result + + test -n "$doc_base" && func_verbose "doc_base='$doc_base'" + } + + require_doc_base=: +} + + # require_dotgitmodules # --------------------- # Ensure we have a '.gitmodules' file, with appropriate 'gnulib' settings. @@ -3489,6 +4237,25 @@ func_require_gnulib_cache () } +# require_gnulib_copy_cmd +# ----------------------- +# Only calculate the options for copying files with gnulib once. +require_gnulib_copy_cmd=func_require_gnulib_copy_cmd +func_require_gnulib_copy_cmd () +{ + $debug_cmd + + $require_gnulib_tool + $require_gnulib_tool_base_options + + gnulib_copy_cmd="$gnulib_tool $gnulib_tool_base_options --copy-file" + $opt_copy || func_append gnulib_copy_cmd " --symlink" + $opt_quiet || func_append gnulib_copy_cmd " --verbose" + + require_gnulib_copy_cmd=: +} + + # require_gnulib_merge_changelog # ------------------------------ # See if we can use gnulib's git-merge-changelog merge driver. @@ -3527,10 +4294,9 @@ func_require_gnulib_mk () { $debug_cmd - test -f "$gnulib_cache" && test -z "$gnulib_mk" && { - $require_gnulib_cache - $require_macro_dir + $require_gnulib_cache + test -f "$gnulib_cache" && test -z "$gnulib_mk" && { func_extract_trace_first "gl_MAKEFILE_NAME" "$gnulib_cache" gnulib_mk=$func_extract_trace_first_result @@ -3541,6 +4307,28 @@ func_require_gnulib_mk () } +# require_gnulib_name +# ------------------- +# Ensure gnulib_name has a sensible value, extracted from 'gnulib-cache.m4' +# if possible, otherwise letting 'gnulib-tool' pick a default. +require_gnulib_name=func_require_gnulib_name +func_require_gnulib_name () +{ + $debug_cmd + + $require_gnulib_cache + + test -f "$gnulib_cache" && test -z "$gnulib_name" && { + func_extract_trace_first "gl_LIB" "$gnulib_cache" + gnulib_name=$func_extract_trace_first_result + + test -n "$gnulib_name" && func_verbose "gnulib_name='$gnulib_name'" + } + + require_gnulib_name=: +} + + # require_gnulib_path # require_gnulib_url # ------------------- @@ -3655,8 +4443,6 @@ func_require_gnulib_tool () { $debug_cmd - test -n "$GNULIB_TOOL" && gnulib_tool=$GNULIB_TOOL - test true = "$gnulib_tool" || { $require_gnulib_submodule $require_gnulib_path @@ -3692,21 +4478,24 @@ func_require_gnulib_tool_base_options () gnulib_tool_base_options= test true = "$gnulib_tool" || { - $require_build_aux - $require_macro_dir - # 'gnulib_modules' and others are maintained in 'bootstrap.conf': # Use 'gnulib --import' to fetch gnulib modules. + $require_build_aux test -n "$build_aux" \ && func_append_uniq gnulib_tool_base_options " --aux-dir=$build_aux" + $require_macro_dir test -n "$macro_dir" \ && func_append_uniq gnulib_tool_base_options " --m4-base=$macro_dir" + $require_doc_base test -n "$doc_base" \ && func_append_uniq gnulib_tool_base_options " --doc-base=$doc_base" + $require_gnulib_name test -n "$gnulib_name" \ && func_append_uniq gnulib_tool_base_options " --lib=$gnulib_name" + $require_local_gl_dir test -n "$local_gl_dir" \ && func_append_uniq gnulib_tool_base_options " --local-dir=$local_gl_dir" + $require_source_base test -n "$source_base" \ && func_append_uniq gnulib_tool_base_options " --source-base=$source_base" } @@ -3749,6 +4538,28 @@ func_require_libtoolize () } +# require_local_gl_dir +# -------------------- +# Ensure local_gl_dir has a sensible value, extracted from 'gnulib-cache.m4' +# if possible, otherwise letting 'gnulib-tool' pick a default. +require_local_gl_dir=func_require_local_gl_dir +func_require_local_gl_dir () +{ + $debug_cmd + + $require_gnulib_cache + + test -f "$gnulib_cache" && test -z "$local_gl_dir" && { + func_extract_trace_first "gl_LOCAL_DIR" "$gnulib_cache" + local_gl_dir=$func_extract_trace_first_result + + test -n "$local_gl_dir" && func_verbose "local_gl_dir='$local_gl_dir'" + } + + require_local_gl_dir=: +} + + # require_macro_dir # ----------------- # Ensure that '$macro_dir' is set, and if it doesn't already point to an @@ -3808,7 +4619,6 @@ func_require_macro_dir () # require_makefile_am # ------------------- # Ensure there is a 'Makefile.am' in the current directory. -# names an existing file. require_makefile_am=func_require_makefile_am func_require_makefile_am () { @@ -3951,7 +4761,7 @@ func_require_patch () $debug_cmd test -n "$PATCH" || { - # Find a patch program, preferring gpatch which is usually better + # Find a patch program, preferring gpatch, which is usually better # than the vendor patch. func_find_tool PATCH gpatch patch } @@ -3977,8 +4787,6 @@ func_require_source_base () $require_gnulib_cache test -f "$gnulib_cache" && test -z "$source_base" && { - $require_macro_dir - func_extract_trace_first "gl_SOURCE_BASE" "$gnulib_cache" source_base=$func_extract_trace_first_result @@ -4015,9 +4823,9 @@ func_require_vc_ignore_files () } -## ------------------## +## ----------------- ## ## Helper functions. ## -## ------------------## +## ----------------- ## # This section contains the helper functions used by the rest of 'bootstrap'. @@ -4090,27 +4898,30 @@ func_grep_q () # func_ifcontains LIST MEMBER YES-CMD [NO-CMD] # -------------------------------------------- # If whitespace-separated LIST contains MEMBER then execute YES-CMD, -# otherwise if NO-CMD was give, execute that. +# otherwise if NO-CMD was given, execute that. func_ifcontains () { $debug_cmd - # The embedded echo is to squash whitespace before globbing. - _G_wslist=`$bs_echo " "$1" "` + _G_wslist=$1 _G_member=$2 _G_yes_cmd=$3 _G_no_cmd=${4-":"} - case $_G_wslist in - *" $_G_member "*) - eval "$_G_yes_cmd" - _G_status=$? - ;; - *) - eval "$_G_no_cmd" - _G_status=$? - ;; - esac + _G_found=false + for _G_item in $_G_wslist; do + test "x$_G_item" = "x$_G_member" && { + _G_found=: + break + } + done + if $_G_found; then + eval "$_G_yes_cmd" + _G_status=$? + else + eval "$_G_no_cmd" + _G_status=$? + fi test 0 -eq "$_G_status" || exit $_G_status } @@ -4124,7 +4935,7 @@ func_strpad () $debug_cmd _G_width=`expr "$2" - 1` - func_strpad_result=`$bs_echo "$1" |$SED ' + func_strpad_result=`$ECHO "$1" |$SED ' :a s|^.\{0,'"$_G_width"'\}$|&'"$3"'| ta @@ -4141,7 +4952,7 @@ func_strrpad () $debug_cmd _G_width=`expr "$2" - 1` - func_strrpad_result=`$bs_echo "$1" |$SED ' + func_strrpad_result=`$ECHO "$1" |$SED ' :a s|^.\{0,'"$_G_width"'\}$|'"$3"'&| ta @@ -4226,7 +5037,7 @@ func_strtable () # Strip off the indent, and make a divider with '-' chars, then # reindent. - _G_divider=`$bs_echo "$func_strrow_result" \ + _G_divider=`$ECHO "$func_strrow_result" \ |$SED 's|[^ ]|-|g :a s|- |--|g @@ -4353,7 +5164,7 @@ func_gitignore_entries () { $debug_cmd - sed -e '/^#/d' -e '/^$/d' "$@" + $SED -e '/^#/d' -e '/^$/d' "$@" } @@ -4383,62 +5194,15 @@ func_insert_if_absent () || func_verbose "inserting '$str' into '$file'" linesold=`func_gitignore_entries "$file" |wc -l` - linesnew=`$bs_echo "$str" \ - |func_gitignore_entries - "$file" |sort -u |wc -l` + linesnew=`{ $ECHO "$str"; cat "$file"; } \ + |func_gitignore_entries |sort -u |wc -l` test "$linesold" -eq "$linesnew" \ - || { sed "1i\\$nl$str$nl" "$file" >"$file"T && mv "$file"T "$file"; } \ + || { $SED "1i\\$nl$str$nl" "$file" >"$file"T && mv "$file"T "$file"; } \ || func_permissions_error "$file" done } -# func_sort_ver VER1 VER2 -# ----------------------- -# 'sort -V' is not generally available. -# Note this deviates from the version comparison in automake -# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a -# but this should suffice as we won't be specifying old -# version formats or redundant trailing .0 in bootstrap.conf. -# If we did want full compatibility then we should probably -# use m4_version_compare from autoconf. -func_sort_ver () -{ - $debug_cmd - - ver1=$1 - ver2=$2 - - # Split on '.' and compare each component. - i=1 - while :; do - p1=`echo "$ver1" |cut -d. -f$i` - p2=`echo "$ver2" |cut -d. -f$i` - if test ! "$p1"; then - echo "$1 $2" - break - elif test ! "$p2"; then - echo "$2 $1" - break - elif test ! "$p1" = "$p2"; then - if test "$p1" -gt "$p2" 2>/dev/null; then # numeric comparison - echo "$2 $1" - elif test "$p2" -gt "$p1" 2>/dev/null; then # numeric comparison - echo "$1 $2" - else # numeric, then lexicographic comparison - lp=`printf "$p1\n$p2\n" |sort -n |tail -n1` - if test "$lp" = "$p2"; then - echo "$1 $2" - else - echo "$2 $1" - fi - fi - break - fi - i=`expr $i + 1` - done -} - - # func_get_version APP # -------------------- # echo the version number (if any) of APP, which is looked up along your @@ -4451,7 +5215,7 @@ func_get_version () # Rather than uncomment the sed script in-situ, strip the comments # programatically before passing the result to $SED for evaluation. - sed_get_version=`$bs_echo '# extract version within line + sed_get_version=`$ECHO '# extract version within line s|.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| t done @@ -4478,6 +5242,35 @@ func_get_version () } +# func_check_tool APP +# ------------------- +# Search PATH for an executable at APP. +func_check_tool () +{ + $debug_cmd + + func_check_tool_result= + + case $1 in + *[\\/]*) + test -x "$1" && func_check_tool_result=$1 + ;; + *) + save_IFS=$IFS + IFS=: + for _G_check_tool_path in $PATH; do + IFS=$save_IFS + if test -x "$_G_check_tool_path/$1"; then + func_check_tool_result=$_G_check_tool_path/$1 + break + fi + done + IFS=$save_IFS + ;; + esac +} + + # func_check_versions APP1 VER1 URL1 ...[APPN VERN URLN] # ------------------------------------------------------ func_check_versions () @@ -4491,30 +5284,67 @@ func_check_versions () _G_reqver=$1; shift _G_url=$1; shift + # Diagnose bad buildreq formatting. + case $_G_url in + [a-z]*://*) ;; # looks like a url + *) func_fatal_error "\ +'$_G_url' from the buildreq table in +'bootstrap.conf' does not look like the URL for downloading +$_G_app. Please ensure that buildreq is a strict newline +delimited list of triples; 'program min-version url'." + ;; + esac + # Honor $APP variables ($TAR, $AUTOCONF, etc.) _G_appvar=`echo $_G_app |tr '[a-z]' '[A-Z]'` test TAR = "$_G_appvar" && _G_appvar=AMTAR eval "_G_app=\${$_G_appvar-$_G_app}" - _G_instver=`func_get_version $_G_app` - test -z "$_G_instver" \ - || func_verbose "found '$_G_app' version $_G_instver." + # Fail if no version specified, but the program can't be found. + if test x- = "x$_G_reqver"; then + func_check_tool $_G_app + if test -z "$func_check_tool_result"; then + func_error "Prerequisite '$_G_app' not not found. Please install it, or +'export $_G_appvar=/path/to/$_G_app'." + func_check_versions_result=false + else + func_verbose "found '$func_check_tool_result' for $_G_appvar." + fi + else + _G_instver=`func_get_version $_G_app` - # Fail if --version didn't work. - if test -z "$_G_instver"; then - func_error "Prerequisite '$_G_app' not found. Please install it, or + # Fail if --version didn't work. + if test -z "$_G_instver"; then + func_error "Prerequisite '$_G_app' not found. Please install it, or 'export $_G_appvar=/path/to/$_G_app'." - func_check_versions_result=false - - # Fail if a new version than what we have is required. - elif test x- != "x$_G_reqver"; then - _G_newer=`func_sort_ver $_G_reqver $_G_instver |cut -d' ' -f2` - test "$_G_newer" != "$_G_instver" && { - func_error "\ -'$_G_app' version == $_G_instver is too old -'$_G_app' version >= $_G_reqver is required" func_check_versions_result=false - } + + # Fail if a newer version than what we have is required. + else + func_verbose "found '$_G_app' version $_G_instver." + + case $_G_reqver in + =*) + # If $buildreq version starts with '=', version must + # match the installed program exactly. + test "x$_G_reqver" = "x=$_G_instver" || { + func_error "\ + '$_G_app' version == $_G_instver is too old + 'exactly $_G_app-$_G_reqver is required" + func_check_versions_result=false + } + ;; + *) + # Otherwise, anything that is not older is a match. + func_lt_ver "$_G_reqver" "$_G_instver" || { + func_error "\ + '$_G_app' version == $_G_instver is too old + '$_G_app' version >= $_G_reqver is required" + func_check_versions_result=false + } + ;; + esac + fi fi done } @@ -4571,7 +5401,7 @@ func_update_po_files () |$SED -e 's|.*/||' -e 's|\.po$||' > "$_G_po_dir/LINGUAS" || return # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6+. - func_find_tool SHA1SUM sha1sum gsha1sum shasum + func_find_tool SHA1SUM sha1sum gsha1sum shasum sha1 _G_langs=`cd $_G_ref_po_dir && echo *.po|$SED 's|\.po||g'` test '*' = "$_G_langs" && _G_langs=x @@ -4581,11 +5411,11 @@ func_update_po_files () _G_cksum_file=$_G_ref_po_dir/$_G_po.s1 if ! test -f "$_G_cksum_file" || ! test -f "$_G_po_dir/$_G_po.po" || - ! $SHA1SUM -c --status "$_G_cksum_file" \ + ! $SHA1SUM -c "$_G_cksum_file" \ < "$_G_new_po" > /dev/null; then echo "updated $_G_po_dir/$_G_po.po..." cp "$_G_new_po" "$_G_po_dir/$_G_po.po" \ - && $SHA1SUM < "$_G_new_po" > "$_G_cksum_file" + && $SHA1SUM < "$_G_new_po" > "$_G_cksum_file" || return fi done } @@ -4692,8 +5522,13 @@ bootstrap_parse_options () shift ;; - --skip-git) opt_skip_git=: ;; - --skip-po) opt_skip_po=: ;; + --skip-git|--no-git) + opt_skip_git=: + ;; + + --skip-po|--no-po) + opt_skip_po=: + ;; # Separate non-argument short options: -c*|-f*|-n*) @@ -4758,7 +5593,7 @@ exit ${exit_status-$EXIT_SUCCESS} # Local variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-pattern: "20/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "500/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: diff --git a/bootstrap.conf b/bootstrap.conf index 65cfaab..d9b0e91 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -1,6 +1,6 @@ -# bootstrap.conf (Stdlib) version 2013-05-06 +# bootstrap.conf (Stdlib) version 2014-01-04 # -# Copyright (C) 2013 Gary V. Vaughan +# Copyright (C) 2013-2014 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # This is free software; see the source for copying conditions. There is NO @@ -32,7 +32,9 @@ # Build prerequisites buildreq=' - git 1.5.5 http://git-scm.com + git 1.5.5 http://git-scm.com + ldoc =next-1 http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec + specl 8 http://luarocks.org/repositories/rocks/specl-9-1.rockspec ' # List of slingshot files to link into stdlib tree before autotooling. @@ -47,6 +49,7 @@ slingshot_files=' build-aux/rockspecs.mk build-aux/sanity.mk build-aux/specl.mk + build-aux/update-copyright m4/ax_compare_version.m4 m4/ax_lua.m4 m4/slingshot.m4 @@ -61,39 +64,10 @@ gnulib_tool=true require_bootstrap_uptodate=: -## -------------------------------- ## -## Source Slingshot customisations. ## -## -------------------------------- ## - -# Integrate the Slingshot submodule bootstrap. -# Make sure that bootstrap.slingshot is sourced from the current -# directory if we were invoked with "sh bootstrap". -case $0 in - */*) . "$0.slingshot" ;; - *) . ./"$0.slingshot" ;; -esac - - -## --------------- ## -## Hook functions. ## -## --------------- ## - -# stdlib_force_changelog -# ---------------------- -# Automake requires that ChangeLog exist. -stdlib_force_changelog () -{ - $debug_cmd - - echo "Autogenerated by 'make dist'" > ChangeLog || exit 1 -} -func_add_hook func_gnulib_tool stdlib_force_changelog - - # Local variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "# bootstrap.conf (Stdlib) version " # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "$" diff --git a/bootstrap.slingshot b/bootstrap.slingshot deleted file mode 100644 index ad7476f..0000000 --- a/bootstrap.slingshot +++ /dev/null @@ -1,277 +0,0 @@ -# bootstrap.slingshot (Slingshot) version 2013-05-06 -# -# Copyright (C) 2013 Gary V. Vaughan -# Written by Gary V. Vaughan, 2013 - -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# For your project to work with subproject slingshot out of the box, you'll -# need to commit this file to your project's repository and source it from -# bootstrap.conf. -# -# case $0 in -# */*) . "$0.slingshot" ;; -# *) . ./"$0.slingshot" ;; -# esac - - -## -------------- ## -## Configuration. ## -## -------------- ## - -# Relative path to the local slingshot submodule, and url to the upsream -# git repository. If you have a slingshot entry in your .gitmodules file, -# these values are ignored. -slingshot_path= -slingshot_url= - - -## ------------------ ## -## Utility functions. ## -## ------------------ ## - -# slingshot_copy FILENAME SRCDIR DESTDIR -# -------------------------------------- -# If option '--copy' was specified, or soft-linking SRCFILE to DESTFILE -# fails, then try to copy SRCFILE to DESTFILE (making sure to update the -# timestamp so that a series of files with dependencies can be copied -# in the right order that their timestamps won't trigger rebuilds). -slingshot_copy () -{ - $debug_cmd - - slingshot_srcfile=`echo "$2/$1" |sed -e 's|/\./|/|g'` - slingshot_destfile=`echo "$3/$1" |sed -e 's|/\./|/|g'` - - $opt_force || { - # Nothing to do if the files are already identical. - if func_cmp_s "$slingshot_srcfile" "$slingshot_destfile"; then - func_verbose "'$slingshot_destfile' is up to date." - return 0 - fi - } - - # Require --force to remove existing $slingshot_destfile. - $opt_force && $RM "$slingshot_destfile" - test -f "$slingshot_destfile" && { - func_warn_and_continue "'$slingshot_destfile' exists: use '--force' to overwrite" - return 0 - } - - # Be careful to support 'func_copy dir/target srcbase destbase'. - func_dirname "$slingshot_destfile" - func_mkdir_p "$func_dirname_result" - - # Copy or link according to '--copy' option. - if $opt_copy; then - slingshot_copycmd=$CP - slingshot_copy_type=copying - else - slingshot_copycmd=$LN_S - slingshot_copy_type=linking - - func_relative_path "$3" "$2" - slingshot_srcfile=$func_relative_path_result/$1 - fi - slingshot_copy_msg="$slingshot_copy_type file '$slingshot_destfile'" - $opt_verbose && \ - slingshot_copy_msg="$slingshot_copy_type $slingshot_srcfile $3" - - if $opt_dry_run || { - ( umask 0 - $slingshot_copycmd "$slingshot_srcfile" "$slingshot_destfile" - ) >/dev/null 2>&1 - } - then - echo "$slingshot_copy_msg" - else - func_error "$slingshot_copy_type '$2/$1' to '$3/' failed" - return 1 - fi -} - - -## --------------- ## -## Hook functions. ## -## --------------- ## - -# slingshot_copy_files -# -------------------- -# Update files from slingshot subproject. -slingshot_copy_files () -{ - $debug_cmd - - $require_slingshot_submodule - - # Make sure we have the latest mkrockspecs - make -C slingshot build-aux/mkrockspecs - - # Update in-tree links. - for file in $slingshot_files; do - func_dirname_and_basename "./$file" - slingshot_copy "$func_basename_result" \ - "slingshot/$func_dirname_result" "$func_dirname_result" - done -} -func_add_hook func_prep slingshot_copy_files - - -## -------------------- ## -## Resource management. ## -## -------------------- ## - -# require_slingshot_dotgitmodules -# ------------------------------- -# Ensure we have a '.gitmodules' file, with appropriate 'slingshot' settings. -require_slingshot_dotgitmodules=slingshot_require_slingshot_dotgitmodules -slingshot_require_slingshot_dotgitmodules () -{ - $debug_cmd - - $require_git - - test true = "$GIT" || { - # A slingshot entry in .gitmodules always takes precedence. - _G_path=`$GIT config --file .gitmodules submodule.slingshot.path 2>/dev/null` - - test -n "$_G_path" || { - $require_vc_ignore_files - - func_verbose "adding slingshot entries to '.gitmodules'" - - test -n "$slingshot_path" || slingshot_path=slingshot - test -n "$slingshot_url" || slingshot_url=git://github.com/gvvaughan/slingshot.git - - { - echo '[submodule "slingshot"]' - echo " path=$slingshot_path" - echo " url=$slingshot_url" - } >> .gitmodules - - test -n "$vc_ignore_files" \ - || func_insert_if_absent ".gitmodules" $vc_ignore_files - } - } - - require_slingshot_dotgitmodules=: -} - - -# require_slingshot_path -# require_slingshot_url -# ---------------------- -# Ensure 'slingshot_path' and 'slingshot_url' are set. -require_slingshot_path=slingshot_require_slingshot_dotgitmodules_parameters -require_slingshot_url=slingshot_require_slingshot_dotgitmodules_parameters -slingshot_require_slingshot_dotgitmodules_parameters () -{ - $debug_cmd - - $require_git - $require_slingshot_dotgitmodules - - test -f .gitmodules \ - || func_fatal_error "Unable to update '.gitmodules' with slingshot submodule" - - test true = "$GIT" || { - slingshot_path=`$GIT config --file=.gitmodules --get submodule.slingshot.path` - slingshot_url=`$GIT config --file=.gitmodules --get submodule.slingshot.url` - - func_verbose "slingshot_path='$slingshot_path'" - func_verbose "slingshot_url='$slingshot_url'" - } - - require_slingshot_path=: - require_slingshot_url=: -} - - -# require_slingshot_submodule -# --------------------------- -# Ensure that there is a current slingshot submodule. -require_slingshot_submodule=slingshot_require_slingshot_submodule -slingshot_require_slingshot_submodule () -{ - $debug_cmd - - $require_git - - if test true = "$GIT"; then - func_warning recommend \ - "No 'git' found; imported slingshot modules may be missing." - else - $require_slingshot_dotgitmodules - - if test -f .gitmodules && test -f "slingshot/build-aux/mkrockspecs.in" - then - : All present and correct. - - else - $require_slingshot_path - $require_slingshot_url - - trap slingshot_cleanup 1 2 13 15 - - shallow= - $GIT clone -h 2>&1 |func_grep_q -- --depth \ - && shallow='--depth 365' - - func_show_eval "$GIT clone $shallow '$slingshot_url' '$slingshot_path'" \ - slingshot_cleanup - - # FIXME: Solaris /bin/sh will try to execute '-' if any of - # these signals are caught after this. - trap - 1 2 13 15 - - # Make sure we've checked out the correct revision of slingshot. - func_show_eval "$GIT submodule init" \ - && func_show_eval "$GIT submodule update" \ - || func_fatal_error "Unable to update slingshot submodule." - fi - fi - - require_slingshot_submodule=: -} - - -# slingshot_cleanup -# ----------------- -# Recursively delete everything at $slingshot_path. -slingshot_cleanup () -{ - $debug_cmd - - $require_slingshot_path - - _G_status=$? - $RM -fr $slingshot_path - exit $_G_status -} - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "# bootstrap.slingshot (Slingshot) version " -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "$" -# End: diff --git a/build-aux/missing b/build-aux/missing index cdea514..db98974 100755 --- a/build-aux/missing +++ b/build-aux/missing @@ -1,7 +1,7 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2012-06-26.16; # UTC +scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. @@ -160,7 +160,7 @@ give_advice () ;; autom4te*) echo "You might have modified some maintainer files that require" - echo "the 'automa4te' program to be rebuilt." + echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) diff --git a/build-aux/mkrockspecs b/build-aux/mkrockspecs index c3cac7a..9fd26fc 100755 --- a/build-aux/mkrockspecs +++ b/build-aux/mkrockspecs @@ -1,108 +1,191 @@ #!/bin/sh -A=--[[ exec lua "$0" "$@" # -* mode: lua; -*s ]]A --- --- Slingshot rockspec generator. --- --- This file is distributed with Slingshot, and licensed under the --- terms of the MIT license reproduced below. - ---[[ - -# ==================================================================== # -# Copyright (C) 2013 Gary V. Vaughan # -# # -# Permission is hereby granted, free of charge, to any person # -# obtaining a copy of this software and associated documentation # -# files (the "Software"), to deal in the Software without restriction, # -# including without limitation the rights to use, copy, modify, merge, # -# publish, distribute, sublicense, and/or sell copies of the Software, # -# and to permit persons to whom the Software is furnished to do so, # -# subject to the following conditions: # -# # -# The above copyright notice and this permission notice shall be # -# included in all copies or substantial portions of the Software. # -# # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # -# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # -# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # -# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -# ==================================================================== # - -]] +SH=--[[ # -*- mode: lua; -*- +## Slingshot rockspec generator. +## +## This file is distributed with Slingshot, and licensed under the +## terms of the MIT license reproduced below. + +## ==================================================================== +## Copyright (C) 2013-2014 Gary V. Vaughan +## +## Permission is hereby granted, free of charge, to any person +## obtaining a copy of this software and associated documentation +## files (the "Software"), to deal in the Software without restriction, +## including without limitation the rights to use, copy, modify, merge, +## publish, distribute, sublicense, and/or sell copies of the Software, +## and to permit persons to whom the Software is furnished to do so, +## subject to the following conditions: +## +## The above copyright notice and this permission notice shall be +## included in all copies or substantial portions of the Software. +## +## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- +## MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +## FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +## CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +## WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +## ==================================================================== + + +_lua_version_re='"Lua 5."[12]*' +_lua_binaries='lua lua5.2 lua52 lua5.1 lua51' + +export LUA_INIT +export LUA_INIT_5_2 +export LUA_PATH +export LUA_CPATH + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi + +# If LUA is not set, search PATH for something suitable. +test -n "$LUA" || { + # Check that the supplied binary is executable and returns a compatible + # Lua version number. + func_vercheck () + { + test -x "$1" && { + eval 'case `'$1' -e "print (_VERSION)" 2>/dev/null` in + '"$_lua_version_re"') LUA='$1' ;; + esac' + } + } + + progname=`echo "$0" |${SED-sed} 's|.*/||'` + + save_IFS="$IFS" + LUA= + for x in $_lua_binaries; do + IFS=: + for dir in $PATH; do + IFS="$save_IFS" + func_vercheck "$dir/$x" + test -n "$LUA" && break + done + IFS="$save_IFS" + test -n "$LUA" && break + e="${e+$e\n}$progname: command not found on PATH: $x" + done +} + +test -n "$LUA" || { + printf "${e+$e\n}$progname: retry after 'export LUA=/path/to/lua'\n" >&2 + exit 1 +} + +LUA_INIT= +LUA_INIT_5_2= + +# Reexecute using the interpreter suppiled in LUA, or found above. +exec "$LUA" "$0" "$@" +]]SH --[[ ============== ]]-- --[[ Parse options. ]]-- --[[ ============== ]]-- -local usage = 'Usage: mkrockspecs [OPTIONS] PACKAGE VERSION [REVISION]\n' - -local prog = { - _VERSION = "1", +local usage = 'Usage: mkrockspecs [OPTIONS] PACKAGE VERSION [REVISION] [FILE]\n' +prog = { name = arg[0] and arg[0]:gsub (".*/", "") or "mkrockspecs", - ["--help"] = function () - print (usage .. [[ + opts = {}, +} + +-- Print an argument processing error message, and return non-zero exit +-- status. +local function opterr (msg) + io.stderr:write (usage) + io.stderr:write (prog.name .. ": error: " .. msg .. ".\n") + io.stderr:write (prog.name .. ": Try '" .. prog.name .. " --help' for help,\n") + os.exit (2) +end + +local function die (msg) + msg:gsub ("([^\n]+)\n?", + function () + io.stderr:write (prog.name .. ": error: " .. msg.. "\n") + end) + os.exit (1) +end + +prog["--help"] = function () + print (usage .. [[ Convert a YAML configuration file into a full rockspec. -If there is a 'rockspec.conf' in the current directory, load it as the -base configuration, otherwise wait for input on stdin. +If FILE is provided, load it as the base configuration, otherwise if +there is a 'rockspec.conf' in the current directory use that, or else +wait for input on stdin. If FILE is '-', force reading base config- +uration from stdin. PACKAGE and VERSION are the package name and version number as defined by 'configure.ac' or similar. REVISION is only required for a revised rockspec if the default "-1" revision was released with errors. - --help print this help, then exit - --version print version number, then exit + --help print this help, then exit + --version print version number, then exit + -m, --module-dir=ROOT directory of lua-files for builtin build type Report bugs to http://github.com/gvvaughan/slingshot/issues.]]) os.exit (0) - end, +end - ["--version"] = function () - print [[mkrockspecs (slingshot) 2 +prog["--version"] = function () + print [[mkrockspecs (slingshot) 6 Written by Gary V. Vaughan , 2013 Copyright (C) 2013, Gary V. Vaughan Slingshot comes with ABSOLUTELY NO WARRANTY. See source files for individual license conditions.]] - os.exit (0) - end, -} + os.exit (0) +end --- Print an argument processing error message, and return non-zero exit --- status. -local function warn (msg) - io.stderr:write (usage) - io.stderr:write (prog.name .. ": error: " .. msg .. ".\n") - io.stderr:write (prog.name .. ": Try '" .. prog.name .. " --help' for help,\n") - return 2 +prog["--module-dir"] = function (arglist, i) + local opt = arglist[i] + if i + 1 > #arglist then + opterr ("option '" .. opt .. "' requires an argument") + end + + prog.opts.module_root = arglist[i + 1] + return i + 1 end +prog["-m"] = prog["--module-dir"] + local nonopts -local status = 0 -for _, opt in ipairs (arg) do +local i = 0 +while i < #arg do + i = i + 1 + local opt = arg[i] - -- Collect non-option arguments to save back into _G.arg later. + -- Collect remaining arguments not nonopts to save back into _G.arg later. if type (nonopts) == "table" then table.insert (nonopts, opt) -- Run prog.option handler. elseif opt:sub (1,1) == "-" and type (prog[opt]) == "function" then - prog[opt] () + i = prog[opt] (arg, i) -- End of option arguments. elseif opt == "--" then nonopts = {} - -- Diagnose unknow command line options. + -- Diagnose unknown command line options. elseif opt:sub (1, 1) == "-" then - status = warn ("unrecognized option '" .. opt .. "'") + opterr ("unrecognized option '" .. opt .. "'") -- First non-option argument marks the end of options. else @@ -110,22 +193,75 @@ for _, opt in ipairs (arg) do end end --- Don't exit until all warnings issued. -if status ~= 0 then os.exit (status) end - -- put non-option args back into global arg table. nonopts = nonopts or {} nonopts[0] = arg[0] _G.arg = nonopts if select ("#", ...) < 2 then - io.stderr:write "Usage: mkrockspecs PACKAGE VERSION [REVISION]\n" - os.exit () + opterr ("only " .. select ("#", ...) .. " arguments provided") end local package = arg[1] local version = arg[2] local revision = arg[3] or "1" +local conf = arg[4] or "rockspec.conf" + + +--[[ ================= ]]-- +--[[ Helper functions. ]]-- +--[[ ================= ]]-- + +local ok, posix = pcall (require, "posix") + +files = {} + +if ok then + -- faster version if luaposix is available + function tree (root) + for f in posix.files (root) do + local path = root .. "/" .. f + if f:match ("%.lua$") then + table.insert (files, path) + elseif f == "." or f == ".." then + -- don't go into a loop + elseif posix.stat (path, "type") == "directory" then + tree (path) + end + end + end +else + -- fallback version that executes ls in subshells + function tree (root) + local p = io.popen ("ls -1 " .. root .. " 2>/dev/null") + + if p ~= nil then + local f = p:read "*l" + while f ~= nil do + if f:match ("%.lua$") then + table.insert (files, root .. "/" .. f) + else + tree (root .. "/" .. f) + end + f = p:read "*l" + end + end + end +end + +local function escape_pattern (s) + return (string.gsub (s, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")) +end + +local function loadmap (root) + local map = {} + tree (root) + for _, f in ipairs (files) do + local m = f:match ("^" .. escape_pattern (root) .. "/(.*)%.lua") + map [m:gsub ("/", ".")] = f:gsub ("^%./", "") + end + return map +end --[[ =================== ]]-- @@ -133,7 +269,6 @@ local revision = arg[3] or "1" --[[ =================== ]]-- local yaml = require "lyaml" -local conf = "rockspec.conf" -- Slurp io.input (). local function slurp () @@ -145,12 +280,16 @@ local function slurp () end end -local h = io.open (conf) -if h then - io.input (conf) - h:close () -else +if conf == "-" then io.input (io.stdin) +else + local h = io.open (conf) + if h then + io.input (conf) + h:close () + else + io.input (io.stdin) + end end local spec = yaml.load (slurp ()) @@ -162,6 +301,8 @@ if spec.source ~= nil then url = spec.source.url elseif spec.description ~= nil then url = spec.description.homepage +else + die (conf .. ": could not find source.url or description.homepage") end url = url:gsub ("^[a-z]*://", ""):gsub ("%.git$", "") @@ -183,11 +324,23 @@ if type (spec.external_dependencies) == "table" then configure_flags = configure_flags .. "CPPFLAGS='" .. CPPFLAGS:gsub ("^%s", "") .. "'" .. " LDFLAGS='" .. LDFLAGS:gsub ("^%s", "") .. "'" .. - " " + " " end end -default.build = { +-- If we have a module root, use the luarocks "builtin" type. +if version ~= "scm" and version ~= "git" then + if prog.opts.module_root ~= nil then + default.build = { + type = "builtin", + modules = loadmap (prog.opts.module_root), + } + elseif spec.build ~= nil and spec.build.modules ~= nil then + default.build = { type = "builtin" } + end +end + +default.build = default.build or { type = "command", build_command = "./configure " .. "LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' " .. configure_flags .. @@ -197,16 +350,19 @@ default.build = { copy_directories = {}, } --- Additional spec-type dependenent values. +-- Additional spec-type dependent values. spec.source = spec.source or {} +spec.build = spec.build or {} if version ~= "scm" and version ~= "git" then spec.source.url = "http://" .. url .. "/archive/release-v" .. version .. ".zip" spec.source.dir = package .. "-release-v" .. version else spec.source.url = "git://" .. url .. ".git" default.build.build_command = "./bootstrap && " .. default.build.build_command + spec.build.modules = nil end + -- Recursive merge, settings from spec take precedence. Elements of src -- overwrite equivalent keys in dest. local function merge (dest, src) @@ -235,13 +391,29 @@ local function format (x, indent) return "{}" else local s = "{\n" - for i, v in pairs (x) do - if type (i) ~= "number" then - s = s..indent..i.." = "..format (v, indent.." ")..",\n" + + -- Collect and sort non-numeric keys first. + keys = {} + for k in pairs (x) do + if type (k) ~= "number" then table.insert (keys, k) end + end + table.sort (keys, function (a, b) return tostring (a) < tostring (b) end) + + -- Display non-numeric key pairs in sort order. + for _, k in ipairs (keys) do + s = s .. indent + if k:match ("[^_%w]") then + -- wrap keys with non-%w chars in square brackets + s = s .. '["' .. k .. '"]' + else + s = s .. k end + s = s .. " = " .. format (x[k], indent .. " ") .. ",\n" end + + -- And numeric key pairs last. for i, v in ipairs (x) do - s = s..indent..format (v, indent.." ")..",\n" + s = s .. indent .. format (v, indent .. " ") .. ",\n" end return s..indent:sub (1, -3).."}" end diff --git a/build-aux/release.mk b/build-aux/release.mk index 00019ef..6941603 100644 --- a/build-aux/release.mk +++ b/build-aux/release.mk @@ -1,7 +1,7 @@ # Slingshot release rules for GNU Make. # ====================================================================== -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # Originally by Jim Meyering, Simon Josefsson, Eric Blake, # Akim Demaille, Gary V. Vaughan, and others. # This version by Gary V. Vaughan, 2013. @@ -91,24 +91,25 @@ gitlog_to_changelog = $(srcdir)/build-aux/gitlog-to-changelog dist-hook: ChangeLog .PHONY: ChangeLog ChangeLog: - $(AM_V_GEN)if test -d '$(srcdir)/.git'; then \ - $(gitlog_to_changelog) > '$@T'; \ - rm -f '$@'; mv '$@T' '$@'; \ + $(AM_V_GEN)if test -d '$(srcdir)/.git'; then \ + $(gitlog_to_changelog) $(gitlog_args) > '$@T'; \ + rm -f '$@'; mv '$@T' '$@'; \ fi # Override this in GNUmakefile if you don't want to automatically # redistribute all the maintainer support files (take care that # Travis CI is finicky about this, and will likely need tweaking # to cope with missing any of these if you decide to omit them). + +_travis_yml ?= .travis.yml travis.yml.in + release_extra_dist ?= \ .autom4te.cfg \ - .travis.yml \ GNUmakefile \ bootstrap \ bootstrap.conf \ - bootstrap.slingshot \ local.mk \ - travis.yml.in \ + $(_travis_yml) \ $(NOTHING_ELSE) EXTRA_DIST += \ @@ -117,7 +118,7 @@ EXTRA_DIST += \ $(release_extra_dist) \ $(NOTHING_ELSE) -all-am: .travis.yml +all-am: $(_travis_yml) ## -------- ## @@ -150,8 +151,7 @@ no-submodule-changes: $(AM_V_GEN)if test -d $(srcdir)/.git \ && git --version >/dev/null 2>&1; then \ diff=$$(cd $(srcdir) && git submodule -q foreach \ - git diff-index --name-only HEAD) \ - || exit 1; \ + git diff-index --name-only HEAD); \ case $$diff in '') ;; \ *) echo '$(ME): submodule files are locally modified:'; \ echo "$$diff"; exit 1;; esac; \ @@ -300,7 +300,7 @@ announcement: NEWS # announcement message: else, it would start with " GEN announcement". $(AM_V_at)$(ANNOUNCE_PRINT) 'print (description.summary)' $(AM_V_at)printf '%s\n' '' \ - 'I am happy to announce the release of $(PACKAGE_NAME) release $(VERSION).' \ + 'I am happy to announce release $(VERSION) of $(PACKAGE_NAME).' \ '' $(AM_V_at)$(ANNOUNCE_PRINT) \ 'print ("$(PACKAGE_NAME)'\''s home page is at " .. description.homepage)' @@ -310,10 +310,10 @@ announcement: NEWS -e p NEWS |$(SED) -e 1,2d $(AM_V_at)printf '%s\n' \ 'Install it with LuaRocks, using:' '' \ - ' luarocks install $(PACKAGE)-$(VERSION)' '' \ + ' luarocks install $(PACKAGE) $(VERSION)' '' \ 'Until the rocks are available from the official repository in a few days,' \ 'you can install directly from the $(PACKAGE) release branch, with:' \ - '' ' $$ luarocks install \' + '' ' $$ luarocks install '\\ $(AM_V_at)$(ANNOUNCE_PRINT) 'print ($(GITHUB_ROCKSPEC))' @@ -340,10 +340,17 @@ grep-clean-files = `printf -- '%s|' $(_save-files) |$(list-to-rexp)` # in all the files it creates, and tag that as the next release. # Github creates automatic zipballs of tagged git revisions, so we can # safely use this tag in the rockspecs we distribute. +submodule-regexp ?= '^\[submodule "' +submodule-extract-spec ?= 's|^.*"\([^"]*\)".*$$|\1|' + .PHONY: check-in-release-branch check-in-release-branch: - $(AM_V_GEN)$(GCO) -b release v1 2>/dev/null || $(GCO) release + $(AM_V_GEN)$(GCO) -b release v$(VERSION) 2>/dev/null || $(GCO) release $(AM_V_at)$(GIT) pull origin release 2>/dev/null || true + $(AM_V_at)if $(EGREP) $(submodule-regexp) .gitmodules >/dev/null 2>&1; then \ + $(EGREP) $(submodule-regexp) .gitmodules \ + | $(SED) $(submodule-extract-spec) | xargs rm -rf; \ + fi $(AM_V_at)$(GIT) clean -dfx $(git-clean-files) $(AM_V_at)remove_re=$(grep-clean-files); \ $(GIT) rm -f `$(GIT) ls-files |$(EGREP) -v "$$remove_re"` @@ -366,7 +373,7 @@ announce_emails ?= lua-l@lists.lua.org rockspec_emails ?= luarocks-developers@lists.sourceforge.net .PHONY: mail -mail: +mail: rockspecs $(AM_V_at)cat ~/announce-$(my_distdir) \ | mail -s '[ANN] $(PACKAGE) $(VERSION) released' -- \ $(announce_emails) diff --git a/build-aux/rockspecs.mk b/build-aux/rockspecs.mk index 1271c36..dc8859b 100644 --- a/build-aux/rockspecs.mk +++ b/build-aux/rockspecs.mk @@ -4,7 +4,7 @@ # terms of the MIT license reproduced below. # ==================================================================== # -# Copyright (C) 2013 Reuben Thomas and Gary V. Vaughan # +# Copyright (C) 2013-2014 Reuben Thomas and Gary V. Vaughan # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation # @@ -77,13 +77,15 @@ $(luarocks_config): Makefile.am $(package_rockspec): $(ROCKSPECS_DEPS) $(AM_V_at)rm -f '$@' 2>/dev/null || : $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' + $(MKROCKSPECS) $(mkrockspecs_args) \ + $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' $(AM_V_at)$(LUAROCKS) lint '$@' $(scm_rockspec): $(ROCKSPECS_DEPS) $(AM_V_at)rm '$@' 2>/dev/null || : $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(PACKAGE) git 1 > '$@' + $(MKROCKSPECS) $(mkrockspecs_args) \ + $(PACKAGE) git 1 > '$@' $(AM_V_at)$(LUAROCKS) lint '$@' .PHONY: rockspecs @@ -102,6 +104,8 @@ EXTRA_DIST += \ $(rockspec_conf) \ $(NOTHING_ELSE) +save_release_files += $(scm_rockspec) + ## ------------ ## ## Maintenance. ## diff --git a/build-aux/sanity.mk b/build-aux/sanity.mk index f2f43bd..78bb125 100644 --- a/build-aux/sanity.mk +++ b/build-aux/sanity.mk @@ -43,7 +43,7 @@ endif # (i.e., with no $(srcdir) prefix), this definition is careful to # remove any $(srcdir) prefix, and to restore what it removes. _sc_excl = \ - $(or $(exclude_file_name_regexp--$@),^build-aux/sanity.mk$$) + $(or $(exclude_file_name_regexp--$@),^build-aux/sanity.mk$$|gnulib$$|^slingshot$$) VC_LIST_EXCEPT = \ $(VC_LIST) | sed 's|^$(_dot_escaped_srcdir)/||' \ | if test -f $(srcdir)/.x-$@; then grep -vEf $(srcdir)/.x-$@; \ @@ -56,6 +56,8 @@ VC_LIST_EXCEPT = \ ## Sanity checks. ## ## --------------- ## +-include $(srcdir)/$(_build-aux)/sanity-cfg.mk + _cfg_mk := $(wildcard $(srcdir)/cfg.mk) # Collect the names of rules starting with 'sc_'. @@ -271,7 +273,7 @@ sc_prohibit_strcmp: # It may fail to NUL-terminate the destination, # and always NUL-pads out to the specified length. sc_prohibit_strncpy: - @prohibit='\. # @@ -578,23 +578,21 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='lua-stdlib' -PACKAGE_TARNAME='lua-stdlib' -PACKAGE_VERSION='35' -PACKAGE_STRING='lua-stdlib 35' +PACKAGE_NAME='stdlib' +PACKAGE_TARNAME='stdlib' +PACKAGE_VERSION='36' +PACKAGE_STRING='stdlib 36' PACKAGE_BUGREPORT='http://github.com/rrthomas/lua-stdlib/issues' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS EXTRA_ROCKS -SPECL_MIN -LUADOC_FALSE SED EGREP GREP SPECL -LUADOC +LDOC pkgluaexecdir luaexecdir pkgluadir @@ -1219,7 +1217,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures lua-stdlib 35 to adapt to many kinds of systems. +\`configure' configures stdlib 36 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1267,7 +1265,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/lua-stdlib] + --docdir=DIR documentation root [DATAROOTDIR/doc/stdlib] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1285,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of lua-stdlib 35:";; + short | recursive ) echo "Configuration of stdlib 36:";; esac cat <<\_ACEOF @@ -1365,7 +1363,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -lua-stdlib configure 35 +stdlib configure 36 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1382,7 +1380,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by lua-stdlib $as_me 35, which was +It was created by stdlib $as_me 36, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1761,12 +1759,12 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -$as_echo "## ------------------------- ## -## Configuring lua-stdlib 35 ## -## ------------------------- ##" +$as_echo "## --------------------- ## +## Configuring stdlib 36 ## +## --------------------- ##" echo -am__api_version='1.13' +am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2251,8 +2249,8 @@ fi # Define the identity of the package. - PACKAGE='lua-stdlib' - VERSION='35' + PACKAGE='stdlib' + VERSION='36' cat >>confdefs.h <<_ACEOF @@ -2292,12 +2290,58 @@ mkdir_p='$(MKDIR_P)' # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; @@ -2740,16 +2784,16 @@ $as_echo "$ax_cv_lua_luaexecdir" >&6; } fi -# Extract the first word of "luadoc", so it can be a program name with args. -set dummy luadoc; ac_word=$2 +# Extract the first word of "ldoc", so it can be a program name with args. +set dummy ldoc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LUADOC+:} false; then : +if ${ac_cv_path_LDOC+:} false; then : $as_echo_n "(cached) " >&6 else - case $LUADOC in + case $LDOC in [\\/]* | ?:[\\/]*) - ac_cv_path_LUADOC="$LUADOC" # Let the user override the test with a path. + ac_cv_path_LDOC="$LDOC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2759,7 +2803,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LUADOC="$as_dir/$ac_word$ac_exec_ext" + ac_cv_path_LDOC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2767,14 +2811,14 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_path_LUADOC" && ac_cv_path_LUADOC=":" + test -z "$ac_cv_path_LDOC" && ac_cv_path_LDOC=":" ;; esac fi -LUADOC=$ac_cv_path_LUADOC -if test -n "$LUADOC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LUADOC" >&5 -$as_echo "$LUADOC" >&6; } +LDOC=$ac_cv_path_LDOC +if test -n "$LDOC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDOC" >&5 +$as_echo "$LDOC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -3022,35 +3066,23 @@ $as_echo "$ac_cv_path_SED" >&6; } rm -f conftest.sed -SPECL_MIN=5 - # Luadoc only works with Lua 5.1, so must be installed with care. - LUADOC_FALSE=# - - - SPECL_MIN=${SPECL_MIN-"5"} - - - # luarocks requires a separate invocation per luarock, and lyaml # is required by all slingshot clients for mkrockspecs. EXTRA_ROCKS=- - for _ss_rock in lyaml luadoc specl; do - # Enable associated .travis sections for special rocks. - case $_ss_rock in - luadoc) - LUADOC_FALSE=- - continue - ;; - esac - + for _ss_rock in lyaml ldoc specl; do case $EXTRA_ROCKS in *" $_ss_rock;"*) ;; # ignore duplicates *) - EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" + test "x$PACKAGE_NAME" != "x$_ss_rock" \ + && EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" ;; esac done + # Avoid empty travis commands. + test "x$EXTRA_ROCKS" != "x-" || EXTRA_ROCKS='# No extra rocks needed here;' + + ac_config_files="$ac_config_files .travis.yml:travis.yml.in" @@ -3607,7 +3639,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by lua-stdlib $as_me 35, which was +This file was extended by stdlib $as_me 36, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3660,7 +3692,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -lua-stdlib config.status 35 +stdlib config.status 36 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -4199,6 +4231,13 @@ which seems to be undefined. Please make sure it is defined" >&2;} esac + + case $ac_file$ac_mode in + ".travis.yml":F) + # Remove trailing blanks so as not to trip sc_trailing_blank in syntax check + sed 's| *$||' < .travis.yml > ss_tmp && mv ss_tmp .travis.yml; rm -f ss_tmp ;; + + esac done # for ac_tag diff --git a/configure.ac b/configure.ac index f035512..60a4f26 100644 --- a/configure.ac +++ b/configure.ac @@ -1,25 +1,41 @@ -dnl Process this file with autoconf to produce a configure script +dnl configure.ac +dnl +dnl Copyright (c) 2012-2014 Free Software Foundation, Inc. +dnl Written by Gary V. Vaughan, 2012 +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published +dnl by the Free Software Foundation; either version 3, or (at your +dnl option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see . + dnl Initialise autoconf and automake -AC_INIT([lua-stdlib], [35], [http://github.com/rrthomas/lua-stdlib/issues]) +AC_INIT([stdlib], [36], [http://github.com/rrthomas/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AS_BOX([Configuring AC_PACKAGE_TARNAME AC_PACKAGE_VERSION]) echo -AM_INIT_AUTOMAKE([-Wall foreign]) +AM_INIT_AUTOMAKE([-Wall]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) dnl Check for programs AX_PROG_LUA([5.1], [5.3]) -AC_PATH_PROG([LUADOC], [luadoc], [:]) +AC_PATH_PROG([LDOC], [ldoc], [:]) AC_PATH_PROG([SPECL], [specl], [:]) AC_PROG_EGREP AC_PROG_SED dnl Generate output files -SPECL_MIN=5 -SS_CONFIG_TRAVIS([luadoc specl]) +SS_CONFIG_TRAVIS([ldoc specl]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html new file mode 100644 index 0000000..8fdd62f --- /dev/null +++ b/doc/classes/std.container.html @@ -0,0 +1,278 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Class std.container

    +

    Container object.

    +

    A container is a std.object with no methods. It's functionality is + instead defined by its metamethods.

    + +

    Where an Object uses the __index metatable entry to hold object + methods, a Container stores its contents using __index, preventing + it from having methods in there too.

    + +

    Although there are no actual methods, Containers are free to use + metamethods (__index, __sub, etc) and, like Objects, can supply + module functions by listing them in _functions. Also, since a + std.container is a std.object, it can be passed to the + std.object module functions, or anywhere else a std.object is + expected.

    + +

    Container derived objects returned directly from a require statement + may also provide module functions, which can be called only from the + initial prototype object returned by require , but are not passed + on to derived objects during cloning:

    + +
      > Container = require "std.container"
    +  > x = Container {}
    +  > = Container.prototype (x)
    +  Object
    +  > = x.prototype (o)
    +  stdin:1: attempt to call field 'prototype' (a nil value)
    +  ...
    +
    + +

    To add functions like this to your own prototype objects, pass a table + of the module functions in the _functions private field before + cloning, and those functions will not be inherited by clones.

    + +
      > Container = require "std.container"
    +  > Graph = Container {
    +  >>   _type = "Graph",
    +  >>   _functions = {
    +  >>     nodes = function (graph)
    +  >>       local n = 0
    +  >>       for _ in pairs (graph) do n = n + 1 end
    +  >>       return n
    +  >>     end,
    +  >>   },
    +  >> }
    +  > g = Graph { "node1", "node2" }
    +  > = Graph.nodes (g)
    +  2
    +  > = g.nodes
    +  nil
    +
    + +

    When making your own prototypes, start from std.container if you + want to access the contents of your objects with the [] operator, or + std.object if you want to access the functionality of your objects + with named object methods.

    + + +

    Tables

    +
    _G.assert (v, f, ...)Extend to allow formatted arguments.
    _G.bind (f, ...) Partially apply a function. Identity function.
    _G.ileaves (tr)Tree iterator which returns just numbered leaves, in order.
    _G.inodes (tr) Tree iterator over numbered nodes, in order.
    _G.leaves (tr)Tree iterator which returns just leaves.
    _G.map (f, i, ...) Map a function over an iterator. Turn a tuple into a list.
    _G.pickle (x)Convert a value to a string.
    _G.prettytostring (t, indent, spacing)Pretty-print a table.
    _G.render (x, open, close, elem, pair, sep, roots)Turn tables into strings with recursion detection.
    _G.require_version (module, min, too_big, pattern)Require a module with a particular version
    _G.ripairs (t) An iterator like ipairs, but in reverse.
    _G.tostring (x)Extend tostring to work better on tables.
    _G.totable (x) Turn an object into a table according to __totable metamethod. Give warning with the name of program and file (if any).
    render_CloseRenderer (t)
    render_ElementRenderer (e)
    render_OpenRenderer (t)
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    render_SeparatorRenderer (t, i, v, j, w)
    tree_Iterator (it, tr, n)
    + + + + +
    std.containerContainer prototype.
    +

    Metamethods

    + + + + + + + + + + + + + +
    std.container:__call (...)Return a clone of this container.
    std.container:__tostring ()Return a string representation of this container.
    std.container:__totable ()Return a table representation of this container.
    + +
    +
    + + +

    Tables

    +
    +
    + + std.container +
    +
    + Container prototype. + + +

    Fields:

    +
      +
    • _init + table or function + a table of field names, or + initialisation function, used by __call +
    • +
    • _functions + nil or table + a table of module functions not copied + by std.object.__call +
    • +
    • _type + string + type of Container, returned by + std.object.prototype + (default "Container") +
    • +
    + + + + + +
    +
    +

    Metamethods

    +
    +
    + + std.container:__call (...) +
    +
    + Return a clone of this container. + + +

    Parameters:

    +
      +
    • ... + arguments for _init +
    • +
    + +

    Returns:

    +
      + + std.container + a clone of the called container. +
    + + +

    See also:

    + + + +
    +
    + + std.container:__tostring () +
    +
    + Return a string representation of this container. + + + +

    Returns:

    +
      + + string + stringified container representation +
    + + +

    See also:

    + + + +
    +
    + + std.container:__totable () +
    +
    + Return a table representation of this container. + + + +

    Returns:

    +
      + + table + a shallow copy of non-private container fields +
    + + +

    See also:

    + + + +
    +
    + + + + +
    +generated by LDoc 1.4.0 +
    + + + diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html new file mode 100644 index 0000000..561ad08 --- /dev/null +++ b/doc/classes/std.list.html @@ -0,0 +1,1082 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Class std.list

    +

    Tables as lists.

    +

    + + +

    Every list is also an object, and thus inherits all of the std.object + methods, particularly use of object cloning for making new list objects.

    + +

    In addition to calling methods on list objects in OO style...

    + +
     local List = require "std.list"
    + local l = List {1, 2, 3}
    + for e in l:relems () do print (e) end
    +   => 3
    +   => 2
    +   => 1
    +
    + +

    ...they can also be called as module functions with an explicit argument:

    + +
     local List = require "std.list"
    + local l = List {1, 2, 3}
    + for e in List.relems (l) do print (e) end
    +   => 3
    +   => 2
    +   => 1
    +
    + +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    std.list.depair (ls)Turn a list of pairs into a table.
    std.list.enpair (t)Turn a table into a list of pairs.
    std.list.index_key (l, f)Make an index of a list of tables on a given field
    std.list.index_value (l, f)Copy a list of tables, indexed on a given field
    std.list.map_with (ls, f)Map a function over a list of lists.
    std.list.transpose (ls)Transpose a list of lists.
    std.list.zip_with (ls, f)Zip a list of lists together with a function.
    +

    Metamethods

    + + + + + + + + + + + + + + + + + +
    std.list:__add (list, element)Append element to list.
    std.list:__concat (list, table)Concatenate lists.
    std.list:__le (list1, list2)List equality or order operator.
    std.list:__lt (list1, list2)List order operator.
    +

    Methods

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    std.list:append (x)Append an item to a list.
    std.list:compare (l)Compare two lists element-by-element, from left-to-right.
    std.list:concat (...)Concatenate arguments into a list.
    std.list:cons (x)Prepend an item to a list.
    std.list:elems ()An iterator over the elements of a list.
    std.list:filter (p)Filter a list according to a predicate.
    std.list:flatten (self)Flatten a list.
    std.list:foldl (f, e)Fold a binary function through a list left associatively.
    std.list:foldr (f, e)Fold a binary function through a list right associatively.
    std.list:map (f)Map a function over a list.
    std.list:project (f)Project a list of fields from a list of tables.
    std.list:relems (self)An iterator over the elements of a list, in reverse.
    std.list:rep (n)Repeat a list.
    std.list:reverse (self)Reverse a list.
    std.list:shape (s)Shape a list according to a list of dimensions.
    std.list:sub (from, to)Return a sub-range of a list.
    std.list:tail (self)Return a list with its first element removed.
    + +
    +
    + + +

    Functions

    +
    +
    + + std.list.depair (ls) +
    +
    + Turn a list of pairs into a table. + + +

    Parameters:

    +
      +
    • ls + table + list of lists {{i1, v1}, ..., {in, vn}} +
    • +
    + +

    Returns:

    +
      + + table + a new list containing table {i1=v1, ..., in=vn} +
    + + +

    See also:

    + + + +
    +
    + + std.list.enpair (t) +
    +
    + Turn a table into a list of pairs. + + +

    Parameters:

    +
      +
    • t + table + a table {i1=v1, ..., in=vn} +
    • +
    + +

    Returns:

    +
      + + std.list + a new list containing {{i1, v1}, ..., {in, vn}} +
    + + +

    See also:

    + + + +
    +
    + + std.list.index_key (l, f) +
    +
    + Make an index of a list of tables on a given field + + +

    Parameters:

    +
      +
    • l + table + list of tables {t1, ..., tn} +
    • +
    • f + field +
    • +
    + +

    Returns:

    +
      + + std.list + index {t1[f]=1, ..., tn[f]=n} +
    + + + + +
    +
    + + std.list.index_value (l, f) +
    +
    + Copy a list of tables, indexed on a given field + + +

    Parameters:

    +
      +
    • l + table + list of tables {i1=t1, ..., in=tn} +
    • +
    • f + field whose value should be used as index +
    • +
    + +

    Returns:

    +
      + + std.list + index {t1[f]=t1, ..., tn[f]=tn} +
    + + + + +
    +
    + + std.list.map_with (ls, f) +
    +
    + Map a function over a list of lists. + + +

    Parameters:

    +
      +
    • ls + table + a list of lists +
    • +
    • f + function + map function +
    • +
    + +

    Returns:

    +
      + + std.list + new list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} +
    + + + + +
    +
    + + std.list.transpose (ls) +
    +
    + Transpose a list of lists. + This function in Lua is equivalent to zip and unzip in more strongly + typed languages. + + +

    Parameters:

    +
      +
    • ls + table + {{ls<1,1>, ..., ls<1,c>}, ..., {ls<r,1>, ..., ls<r,c>}} +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing + {{ls<1,1>, ..., ls<r,1>}, ..., {ls<1,c>, ..., ls<r,c>}} +
    + + + + +
    +
    + + std.list.zip_with (ls, f) +
    +
    + Zip a list of lists together with a function. + + +

    Parameters:

    +
      +
    • ls + table + list of lists +
    • +
    • f + function + function +
    • +
    + +

    Returns:

    +
      + + std.list + +
      a new list containing
      +
      +

      {f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) + where N = max {map (function (l) return #l end, ls)}

      + +
    + + + + +
    +
    +

    Metamethods

    +
    +
    + + std.list:__add (list, element) +
    +
    + +

    Append element to list.

    +
     list = list + element
    +
    + + + +

    Parameters:

    +
      +
    • list + std.list + a list +
    • +
    • element + element to append +
    • +
    + + + +

    See also:

    + + + +
    +
    + + std.list:__concat (list, table) +
    +
    + +

    Concatenate lists.

    +
     new = list .. table
    +
    + + + +

    Parameters:

    +
      +
    • list + std.list + a list +
    • +
    • table + table + another list, hash part is ignored +
    • +
    + + + +

    See also:

    + + + +
    +
    + + std.list:__le (list1, list2) +
    +
    + +

    List equality or order operator.

    +
     min = list1 <= list2 and list1 or list2
    +
    + + + +

    Parameters:

    + + + + +

    See also:

    + + + +
    +
    + + std.list:__lt (list1, list2) +
    +
    + +

    List order operator.

    +
     max = list1 > list2 and list1 or list2
    +
    + + + +

    Parameters:

    + + + + +

    See also:

    + + + +
    +
    +

    Methods

    +
    +
    + + std.list:append (x) +
    +
    + Append an item to a list. + + +

    Parameters:

    +
      +
    • x + item +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing {self[1], ..., self[#self], x} +
    + + + + +
    +
    + + std.list:compare (l) +
    +
    + +

    Compare two lists element-by-element, from left-to-right.

    + +
     if a_list:compare (another_list) == 0 then print "same" end
    +
    + + + +

    Parameters:

    +
      +
    • l + table + another list +
    • +
    + +

    Returns:

    +
      + + -1 if self is less than l, 0 if they are the same, and 1 + if self is greater than l +
    + + + + +
    +
    + + std.list:concat (...) +
    +
    + Concatenate arguments into a list. + + +

    Parameters:

    +
      +
    • ... + tuple of lists +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing + {self[1], ..., self[#self], l_1[1], ..., l_1[#l_1], ..., l_n[1], ..., l_n[#l_n]} +
    + + + + +
    +
    + + std.list:cons (x) +
    +
    + Prepend an item to a list. + + +

    Parameters:

    +
      +
    • x + item +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing {x, unpack (self)} +
    + + + + +
    +
    + + std.list:elems () +
    +
    + An iterator over the elements of a list. + + + +

    Returns:

    +
      +
    1. + function + iterator function which returns successive elements of self
    2. +
    3. + table + list
    4. +
    5. + true
    6. +
    + + + + +
    +
    + + std.list:filter (p) +
    +
    + Filter a list according to a predicate. + + +

    Parameters:

    +
      +
    • p + function + predicate function, of one argument returning a boolean +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing elements e of self for which p (e) is true +
    + + + + +
    +
    + + std.list:flatten (self) +
    +
    + Flatten a list. + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    + +

    Returns:

    +
      + + std.list + flattened list +
    + + + + +
    +
    + + std.list:foldl (f, e) +
    +
    + Fold a binary function through a list left associatively. + + +

    Parameters:

    +
      +
    • f + function + binary function +
    • +
    • e + element to place in left-most position +
    • +
    + +

    Returns:

    +
      + + result +
    + + + + +
    +
    + + std.list:foldr (f, e) +
    +
    + Fold a binary function through a list right associatively. + + +

    Parameters:

    +
      +
    • f + function + binary function +
    • +
    • e + element to place in right-most position +
    • +
    + +

    Returns:

    +
      + + result +
    + + + + +
    +
    + + std.list:map (f) +
    +
    + Map a function over a list. + + +

    Parameters:

    +
      +
    • f + function + map function +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing {f (self[1]), ..., f (self[#self])} +
    + + + + +
    +
    + + std.list:project (f) +
    +
    + Project a list of fields from a list of tables. + + +

    Parameters:

    +
      +
    • f + field to project +
    • +
    + +

    Returns:

    +
      + + std.list + list of f fields +
    + + + + +
    +
    + + std.list:relems (self) +
    +
    + An iterator over the elements of a list, in reverse. + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    + +

    Returns:

    +
      +
    1. + function + iterator function which returns precessive elements of the self
    2. +
    3. + std.list + self
    4. +
    5. + true
    6. +
    + + + + +
    +
    + + std.list:rep (n) +
    +
    + Repeat a list. + + +

    Parameters:

    +
      +
    • n + number + number of times to repeat +
    • +
    + +

    Returns:

    +
      + + std.list + n copies of self appended together +
    + + + + +
    +
    + + std.list:reverse (self) +
    +
    + Reverse a list. + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing {self[#self], ..., self[1]} +
    + + + + +
    +
    + + std.list:shape (s) +
    +
    + Shape a list according to a list of dimensions.

    + +

    Dimensions are given outermost first and items from the original + list are distributed breadth first; there may be one 0 indicating + an indefinite number. Hence, {0} is a flat list, + {1} is a singleton, {2, 0} is a list of + two lists, and {0, 2} is a list of pairs.

    + +

    Algorithm: turn shape into all positive numbers, calculating + the zero if necessary and making sure there is at most one; + recursively walk the shape, adding empty tables until the bottom + level is reached at which point add table items instead, using a + counter to walk the flattened original list. + + +

    Parameters:

    +
      +
    • s + table + {d1, ..., dn} +
    • +
    + +

    Returns:

    +
      + + reshaped list +
    + + + + +
    +
    + + std.list:sub (from, to) +
    +
    + Return a sub-range of a list. + (The equivalent of string.sub on strings; negative list indices + count from the end of the list.) + + +

    Parameters:

    +
      +
    • from + number + start of range (default: 1) +
    • +
    • to + number + end of range (default: #self) +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing {self[from], ..., self[to]} +
    + + + + +
    +
    + + std.list:tail (self) +
    +
    + Return a list with its first element removed. + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    + +

    Returns:

    +
      + + std.list + new list containing {self[2], ..., self[#self]} +
    + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html new file mode 100644 index 0000000..82f840c --- /dev/null +++ b/doc/classes/std.object.html @@ -0,0 +1,392 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Class std.object

    +

    Prototype-based objects.

    +

    This module creates the root prototype object from which every other + object is descended. There are no classes as such, rather new objects + are created by cloning an existing object, and then changing or adding + to the clone. Further objects can then be made by cloning the changed + object, and so on.

    + +

    Objects are cloned by simply calling an existing object, which then + serves as a prototype from which the new object is copied.

    + +

    All valid objects contain a field _init, which determines the syntax + required to execute the cloning process:

    + +
      +
    1. _init can be a list of keys; then the unnamed init_1 through + init_m values from the argument table are assigned to the + corresponding keys in new_object;

      + +
       new_object = proto_object {
      +   init_1, ..., init_m;
      +   field_1 = value_1,
      +   ...
      +   field_n = value_n,
      + }
      +
    2. +
    3. Or it can be a function, in which the arguments passed to the + prototype during cloning are simply handed to the _init function:

      + +
      new_object = proto_object (arg, ...)
      +
    4. +
    + +

    Objects, then, are essentially tables of field_n = value_n pairs:

    + +
      > o = Object {
    +  >>  field_1 = "value_1",
    +  >>  method_1 = function (self) return self.field_1 end,
    +  >> }
    +  > = o.field_1
    +  value_1
    +  > o.field_2 = 2
    +  > function o:method_2 (n) return self.field_2 + n end
    +  > = o:method_2 (2)
    +  4
    +
    + +

    Normally new_object automatically shares a metatable with + proto_object. However, field names beginning with "_" are private, + and moved into the object metatable during cloning. So, adding new + private fields to an object during cloning will result in a new + metatable for new_object that also contains a copy of all the entries + in the proto_object metatable.

    + +

    Note that Object methods are stored in the __index field of their + metatable, and so cannot also use __index to lookup references with + square brackets. See std.container objects if you want to do that.

    + + +

    Tables

    + + + + + +
    std.objectRoot object.
    +

    Metamethods

    + + + + + + + + + + + + + +
    std.object:__call (...)Return a clone of this object, and its metatable.
    std.object:__tostring ()Return a string representation of this object.
    std.object:__totable ()Return a shallow copy of non-private object fields.
    +

    Methods

    + + + + + + + + + +
    std.object:clone (o, ...)Clone this Object.
    std.object:prototype (x)Type of an object, or primitive.
    + +
    +
    + + +

    Tables

    +
    +
    + + std.object +
    +
    + Root object.

    + +

    Changing the values of these fields in a new object will change the + corresponding behaviour. + + +

    Fields:

    +
      +
    • _init + table or function + a table of field names, or + initialisation function, used by clone +
    • +
    • _functions + nil or table + a table of module functions not copied + by std.object.__call +
    • +
    • _type + string + type of Object, returned by prototype + (default "Object") +
    • +
    + + + + + +
    +
    +

    Metamethods

    +
    +
    + + std.object:__call (...) +
    +
    + Return a clone of this object, and its metatable.

    + +

    Private fields are stored in the metatable. + + +

    Parameters:

    +
      +
    • ... + arguments for _init +
    • +
    + +

    Returns:

    +
      + + std.object + a clone of the this object. +
    + + +

    See also:

    + + + +
    +
    + + std.object:__tostring () +
    +
    + Return a string representation of this object.

    + +

    First the object type, and then between { and } a list of the + array part of the object table (without numeric keys) followed + by the remaining key-value pairs.

    + +

    This function doesn't recurse explicity, but relies upon suitable + __tostring metamethods in field values. + + + +

    Returns:

    +
      + + string + stringified container representation +
    + + +

    See also:

    + + + +
    +
    + + std.object:__totable () +
    +
    + Return a shallow copy of non-private object fields.

    + +

    Used by clone to get the base contents of the new object. Can + be overridden in other objects for greater control of which fields + are considered non-private. + + + +

    Returns:

    +
      + + table + a shallow copy of non-private object fields +
    + + +

    See also:

    + + + +
    +
    +

    Methods

    +
    +
    + + std.object:clone (o, ...) +
    +
    + Clone this Object. + + +

    Parameters:

    +
      +
    • o + std.object + an object +
    • +
    • ... + a list of arguments if o._init is a function, or a + single table if o._init is a table. +
    • +
    + +

    Returns:

    +
      + + std.object + a clone of o +
    + + +

    See also:

    + + + +
    +
    + + std.object:prototype (x) +
    +
    + +

    Type of an object, or primitive.

    + +

    It's conventional to organise similar objects according to a + string valued _type field, which can then be queried using this + function.

    + +
     Stack = Object {
    +   _type = "Stack",
    +
    +   __tostring = function (self) ... end,
    +
    +   __index = {
    +     push = function (self) ... end,
    +     pop  = function (self) ... end,
    +   },
    + }
    + stack = Stack {}
    +
    + stack:prototype () --> "Stack"
    +
    + + + + +

    Parameters:

    +
      +
    • x + anything +
    • +
    + +

    Returns:

    +
      + + string + type of x +
    + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html new file mode 100644 index 0000000..b1b8754 --- /dev/null +++ b/doc/classes/std.set.html @@ -0,0 +1,767 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Class std.set

    +

    Set container.

    +

    Derived from std.container, and inherits Container's metamethods.

    + +

    Note that Functions listed below are available only available from the + Set prototype returned by requiring this module, because Container + objects cannot have object methods.

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    std.set.delete (set, e)Delete an element from a set.
    std.set.difference (set1, set2)Find the difference of two sets.
    std.set.elems (set)Iterator for sets.
    std.set.equal (set1, set2)Find whether two sets are equal.
    std.set.insert (set, e)Insert an element into a set.
    std.set.intersection (set1, set2)Find the intersection of two sets.
    std.set.member (set, e)Say whether an element is in a set.
    std.set.proper_subset (set1, set2)Find whether one set is a proper subset of another.
    std.set.subset (set1, set2)Find whether one set is a subset of another.
    std.set.symmetric_difference (set1, set2)Find the symmetric difference of two sets.
    std.set.union (set1, set2)Find the union of two sets.
    +

    Tables

    + + + + + +
    std.setSet prototype object.
    +

    Metamethods

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    std.set.__add (set, table)Union operator.
    std.set.__div (set, table)Symmetric difference operator.
    std.set.__le (set, table)Subset operator.
    std.set.__lt (set, table)Proper subset operator.
    std.set.__mul (set, table)Intersection operator.
    std.set.__sub (set, table)Difference operator.
    + +
    +
    + + +

    Functions

    +
    +
    + + std.set.delete (set, e) +
    +
    + Delete an element from a set. + + +

    Parameters:

    +
      +
    • set + set + a set +
    • +
    • e + element +
    • +
    + +

    Returns:

    +
      + + the modified set +
    + + + + +
    +
    + + std.set.difference (set1, set2) +
    +
    + Find the difference of two sets. + + +

    Parameters:

    +
      +
    • set1 + set + a set +
    • +
    • set2 + table or set + another set, or table +
    • +
    + +

    Returns:

    +
      + + set1 with elements of s removed +
    + + + + +
    +
    + + std.set.elems (set) +
    +
    + Iterator for sets. + + +

    Parameters:

    +
      +
    • set + set + a set +
    • +
    + + + + + +
    +
    + + std.set.equal (set1, set2) +
    +
    + Find whether two sets are equal. + + +

    Parameters:

    +
      +
    • set1 + set + a set +
    • +
    • set2 + table or set + another set, or table +
    • +
    + +

    Returns:

    +
      + + true if set1 and set2 are equal, false otherwise +
    + + + + +
    +
    + + std.set.insert (set, e) +
    +
    + Insert an element into a set. + + +

    Parameters:

    +
      +
    • set + set + a set +
    • +
    • e + element +
    • +
    + +

    Returns:

    +
      + + the modified set +
    + + + + +
    +
    + + std.set.intersection (set1, set2) +
    +
    + Find the intersection of two sets. + + +

    Parameters:

    +
      +
    • set1 + set + a set +
    • +
    • set2 + table or set + another set, or table +
    • +
    + +

    Returns:

    +
      + + set intersection of set1 and set2 +
    + + + + +
    +
    + + std.set.member (set, e) +
    +
    + Say whether an element is in a set. + + +

    Parameters:

    +
      +
    • set + set + a set +
    • +
    • e + element +
    • +
    + +

    Returns:

    +
      + + true if e is in set , otherwise false + otherwise +
    + + + + +
    +
    + + std.set.proper_subset (set1, set2) +
    +
    + Find whether one set is a proper subset of another. + + +

    Parameters:

    +
      +
    • set1 + set + a set +
    • +
    • set2 + table or set + another set, or table +
    • +
    + +

    Returns:

    +
      + + true if set1 is a proper subset of set2, false otherwise +
    + + + + +
    +
    + + std.set.subset (set1, set2) +
    +
    + Find whether one set is a subset of another. + + +

    Parameters:

    +
      +
    • set1 + set + a set +
    • +
    • set2 + table or set + another set, or table +
    • +
    + +

    Returns:

    +
      + + true if set1 is a subset of set2, false otherwise +
    + + + + +
    +
    + + std.set.symmetric_difference (set1, set2) +
    +
    + Find the symmetric difference of two sets. + + +

    Parameters:

    +
      +
    • set1 + set + a set +
    • +
    • set2 + table or set + another set, or table +
    • +
    + +

    Returns:

    +
      + + elements of set1 and set2 that are in set1 or set2 but not both +
    + + + + +
    +
    + + std.set.union (set1, set2) +
    +
    + Find the union of two sets. + + +

    Parameters:

    +
      +
    • set1 + set + a set +
    • +
    • set2 + table or set + another set, or table +
    • +
    + +

    Returns:

    +
      + + set union of set1 and set2 +
    + + + + +
    +
    +

    Tables

    +
    +
    + + std.set +
    +
    + Set prototype object. + + +

    Fields:

    + + + + + + +
    +
    +

    Metamethods

    +
    +
    + + std.set.__add (set, table) +
    +
    + +

    Union operator.

    +
     union = set + table
    +
    + + + +

    Parameters:

    +
      +
    • set + set + set +
    • +
    • table + table or set + another set or table +
    • +
    + +

    Returns:

    +
      + + set + union +
    + + +

    See also:

    + + + +
    +
    + + std.set.__div (set, table) +
    +
    + +

    Symmetric difference operator.

    +
     symmetric_difference = set / table
    +
    + + + +

    Parameters:

    +
      +
    • set + set + set +
    • +
    • table + table or set + another set or table +
    • +
    + +

    Returns:

    +
      + + set + symmetric_difference +
    + + +

    See also:

    + + + +
    +
    + + std.set.__le (set, table) +
    +
    + +

    Subset operator.

    +
     set = set <= table
    +
    + + + +

    Parameters:

    +
      +
    • set + set + set +
    • +
    • table + table or set + another set or table +
    • +
    + +

    Returns:

    +
      + + set + subset +
    + + +

    See also:

    + + + +
    +
    + + std.set.__lt (set, table) +
    +
    + +

    Proper subset operator.

    +
     proper_subset = set < table
    +
    + + + +

    Parameters:

    +
      +
    • set + set + set +
    • +
    • table + table or set + another set or table +
    • +
    + +

    Returns:

    +
      + + set + proper_subset +
    + + +

    See also:

    + + + +
    +
    + + std.set.__mul (set, table) +
    +
    + +

    Intersection operator.

    +
     intersection = set * table
    +
    + + + +

    Parameters:

    +
      +
    • set + set + set +
    • +
    • table + table or set + another set or table +
    • +
    + +

    Returns:

    +
      + + set + intersection +
    + + +

    See also:

    + + + +
    +
    + + std.set.__sub (set, table) +
    +
    + +

    Difference operator.

    +
     difference = set - table
    +
    + + + +

    Parameters:

    +
      +
    • set + set + set +
    • +
    • table + table or set + another set or table +
    • +
    + +

    Returns:

    +
      + + set + difference +
    + + +

    See also:

    + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html new file mode 100644 index 0000000..a5ec6be --- /dev/null +++ b/doc/classes/std.strbuf.html @@ -0,0 +1,245 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Class std.strbuf

    +

    String buffers.

    +

    + +

    + + +

    Metamethods

    + + + + + + + + + +
    std.strbuf:__concat (buffer, str)Support concatenation of StrBuf objects.
    std.strbuf:__tostring (buffer)Support fast conversion to Lua string.
    +

    Methods

    + + + + + + + + + +
    std.strbuf:concat (s)Add a string to a buffer.
    std.strbuf:tostring (self)Convert a buffer to a string.
    + +
    +
    + + +

    Metamethods

    +
    +
    + + std.strbuf:__concat (buffer, str) +
    +
    + +

    Support concatenation of StrBuf objects.

    +
     buffer = buffer .. str
    +
    + + + +

    Parameters:

    +
      +
    • buffer + std.strbuf + StrBuf object +
    • +
    • str + string + a string or string-like object +
    • +
    + +

    Returns:

    +
      + + std.strbuf + modified buffer +
    + + +

    See also:

    + + + +
    +
    + + std.strbuf:__tostring (buffer) +
    +
    + +

    Support fast conversion to Lua string.

    +
     str = tostring (buffer)
    +
    + + + +

    Parameters:

    + + +

    Returns:

    +
      + + string + concatenation of buffer contents +
    + + +

    See also:

    + + + +
    +
    +

    Methods

    +
    +
    + + std.strbuf:concat (s) +
    +
    + Add a string to a buffer. + + +

    Parameters:

    +
      +
    • s + string + string to add +
    • +
    + +

    Returns:

    +
      + + std.strbuf + modified buffer +
    + + + + +
    +
    + + std.strbuf:tostring (self) +
    +
    + Convert a buffer to a string. + + +

    Parameters:

    +
      +
    • self + + + +
    • +
    + +

    Returns:

    +
      + + string + stringified self +
    + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html new file mode 100644 index 0000000..261ecad --- /dev/null +++ b/doc/classes/std.tree.html @@ -0,0 +1,461 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Class std.tree

    +

    Tree container.

    +

    Derived from std.container, and inherits Container's metamethods.

    + +

    Note that Functions listed below are only available from the Tree + prototype return by requiring this module, because Container objects + cannot have object methods.

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    std.tree.clone (t, nometa)Make a deep copy of a tree, including any metatables.
    std.tree.ileaves (tr)Tree iterator which returns just numbered leaves, in order.
    std.tree.inodes (tr)Tree iterator over numbered nodes, in order.
    std.tree.leaves (tr)Tree iterator which returns just leaves.
    std.tree.merge (t, u)Destructively deep-merge one tree into another.
    std.tree.nodes (tr)Tree iterator over all nodes.
    +

    Tables

    + + + + + +
    std.treeTree prototype object.
    +

    Metamethods

    + + + + + + + + + +
    std.tree:__index (i)Tree __index metamethod.
    std.tree:__newindex (i, v)Tree __newindex metamethod.
    + +
    +
    + + +

    Functions

    +
    +
    + + std.tree.clone (t, nometa) +
    +
    + Make a deep copy of a tree, including any metatables.

    + +

    To make fast shallow copies, use std.table.clone. + + +

    Parameters:

    +
      +
    • t + table or tree + table or tree to be cloned +
    • +
    • nometa + boolean + if non-nil don't copy metatables +
    • +
    + +

    Returns:

    +
      + + table or tree + a deep copy of t +
    + + + + +
    +
    + + std.tree.ileaves (tr) +
    +
    + Tree iterator which returns just numbered leaves, in order. + + +

    Parameters:

    +
      +
    • tr + tree or table + tree or tree-like table +
    • +
    + +

    Returns:

    +
      +
    1. + function + iterator function
    2. +
    3. + tree or table + the tree tr
    4. +
    + + + + +
    +
    + + std.tree.inodes (tr) +
    +
    + Tree iterator over numbered nodes, in order.

    + +

    The iterator function behaves like nodes, but only traverses the + array part of the nodes of tr, ignoring any others. + + +

    Parameters:

    +
      +
    • tr + tree or table + tree to iterate over +
    • +
    + +

    Returns:

    +
      +
    1. + function + iterator function
    2. +
    3. + tree or table + the tree, tr
    4. +
    + + +

    See also:

    + + + +
    +
    + + std.tree.leaves (tr) +
    +
    + Tree iterator which returns just leaves. + + +

    Parameters:

    +
      +
    • tr + tree or table + tree or tree-like table +
    • +
    + +

    Returns:

    +
      +
    1. + function + iterator function
    2. +
    3. + tree or table + the tree, tr
    4. +
    + + + + +
    +
    + + std.tree.merge (t, u) +
    +
    + Destructively deep-merge one tree into another. + + +

    Parameters:

    +
      +
    • t + tree or table + destination tree or table +
    • +
    • u + tree or table + tree or table with nodes to merge +
    • +
    + +

    Returns:

    +
      + + tree or table + t with nodes from u merged in +
    + + +

    See also:

    + + + +
    +
    + + std.tree.nodes (tr) +
    +
    + Tree iterator over all nodes.

    + +

    The returned iterator function performs a depth-first traversal of + tr, and at each node it returns {node-type, tree-path, tree-node} + where node-type is branch, join or leaf; tree-path is a + list of keys used to reach this node, and tree-node is the current + node.

    + +

    Given a tree to represent:

    + +
     + root
    +    +-- node1
    +    |    +-- leaf1
    +    |    '-- leaf2
    +    '-- leaf 3
    +
    + tree = std.tree { std.tree { "leaf1", "leaf2"}, "leaf3" }
    +
    + +

    A series of calls to tree.nodes will return:

    + +
     "branch", {},    {{"leaf1", "leaf2"}, "leaf3"}
    + "branch", {1},   {"leaf1", "leaf"2")
    + "leaf",   {1,1}, "leaf1"
    + "leaf",   {1,2}, "leaf2"
    + "join",   {1},   {"leaf1", "leaf2"}
    + "leaf",   {2},   "leaf3"
    + "join",   {},    {{"leaf1", "leaf2"}, "leaf3"}
    +
    + +

    Note that the tree-path reuses the same table on each iteration, so + you must table.clone a copy if you want to take a snap-shot of the + current state of the tree-path list before the next iteration + changes it. + + +

    Parameters:

    +
      +
    • tr + tree or table + tree or tree-like table to iterate over +
    • +
    + +

    Returns:

    +
      +
    1. + function + iterator function
    2. +
    3. + tree or table + the tree, tr
    4. +
    + + +

    See also:

    + + + +
    +
    +

    Tables

    +
    +
    + + std.tree +
    +
    + Tree prototype object. + + +

    Fields:

    + + + + + + +
    +
    +

    Metamethods

    +
    +
    + + std.tree:__index (i) +
    +
    + Tree __index metamethod. + + +

    Parameters:

    +
      +
    • i + non-table, or list of keys {i_1 ... i_n} +
    • +
    + +

    Returns:

    +
      + + self[i]...[i_n] if i is a table, or self[i] otherwise +
    + + + + +
    +
    + + std.tree:__newindex (i, v) +
    +
    + Tree __newindex metamethod.

    + +

    Sets self[i_1]...[i_n] = v if i is a table, or self[i] = v otherwise + + +

    Parameters:

    +
      +
    • i + non-table, or list of keys {i_1 ... i_n} +
    • +
    • v + value +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/config.ld b/doc/config.ld new file mode 100644 index 0000000..fb5c297 --- /dev/null +++ b/doc/config.ld @@ -0,0 +1,29 @@ +-- -*- lua -*- +project = "stdlib" +description = "Standard Lua Libraries" +dir = "." + +file = { + -- Modules + "../lib/std.lua", + "../lib/std/debug.lua", + "../lib/std/functional.lua", + "../lib/std/getopt.lua", + "../lib/std/io.lua", + "../lib/std/math.lua", + "../lib/std/package.lua", + "../lib/std/strict.lua", + "../lib/std/string.lua", + "../lib/std/table.lua", + "../lib/std/tree.lua", + + -- Classes + "../lib/std/container.lua", + "../lib/std/object.lua", + "../lib/std/list.lua", + "../lib/std/set.lua", + "../lib/std/strbuf.lua", +} + +format = "markdown" +sort = true diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..954c2bd --- /dev/null +++ b/doc/index.html @@ -0,0 +1,140 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + + +

    Standard Lua Libraries

    + +

    Modules

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    stdGlobal namespace scribbler.
    std.debugAdditions to the debug module
    std.functionalFunctional programming.
    std.getoptSimplified getopt, based on Svenne Panne's Haskell GetOpt.
    std.ioAdditions to the io module.
    std.mathAdditions to the math module.
    std.packageAdditions to the package module.
    std.strictChecks uses of undeclared global variables.
    std.stringAdditions to the string module.
    std.tableExtensions to the table module.
    +

    Classes

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    std.treeTree container.
    std.containerContainer object.
    std.objectPrototype-based objects.
    std.listTables as lists.
    std.setSet container.
    std.strbufString buffers.
    + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/ldoc.css b/doc/ldoc.css new file mode 100644 index 0000000..765c710 --- /dev/null +++ b/doc/ldoc.css @@ -0,0 +1,302 @@ +/* BEGIN RESET + +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.8.2r1 +*/ +html { + color: #000; + background: #FFF; +} +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { + margin: 0; + padding: 0; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +fieldset,img { + border: 0; +} +address,caption,cite,code,dfn,em,strong,th,var,optgroup { + font-style: inherit; + font-weight: inherit; +} +del,ins { + text-decoration: none; +} +li { + list-style: disc; + margin-left: 20px; +} +caption,th { + text-align: left; +} +h1,h2,h3,h4,h5,h6 { + font-size: 100%; + font-weight: bold; +} +q:before,q:after { + content: ''; +} +abbr,acronym { + border: 0; + font-variant: normal; +} +sup { + vertical-align: baseline; +} +sub { + vertical-align: baseline; +} +legend { + color: #000; +} +input,button,textarea,select,optgroup,option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; +} +input,button,textarea,select {*font-size:100%; +} +/* END RESET */ + +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color: #ffffff; margin: 0px; +} + +code, tt { font-family: monospace; } +span.parameter { font-family:monospace; } +span.parameter:after { content:":"; } +span.types:before { content:"("; } +span.types:after { content:")"; } +.type { font-weight: bold; font-style:italic } + +body, p, td, th { font-size: .95em; line-height: 1.2em;} + +p, ul { margin: 10px 0 0 0px;} + +strong { font-weight: bold;} + +em { font-style: italic;} + +h1 { + font-size: 1.5em; + margin: 0 0 20px 0; +} +h2, h3, h4 { margin: 15px 0 10px 0; } +h2 { font-size: 1.25em; } +h3 { font-size: 1.15em; } +h4 { font-size: 1.06em; } + +a:link { font-weight: bold; color: #004080; text-decoration: none; } +a:visited { font-weight: bold; color: #006699; text-decoration: none; } +a:link:hover { text-decoration: underline; } + +hr { + color:#cccccc; + background: #00007f; + height: 1px; +} + +blockquote { margin-left: 3em; } + +ul { list-style-type: disc; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; +} + +pre.example { + background-color: rgb(245, 245, 245); + border: 1px solid silver; + padding: 10px; + margin: 10px 0 10px 0; + font-family: "Andale Mono", monospace; + font-size: .85em; +} + +pre { + background-color: rgb(245, 245, 245); + border: 1px solid silver; + padding: 10px; + margin: 10px 0 10px 0; + overflow: auto; + font-family: "Andale Mono", monospace; +} + + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } + +#container { + margin-left: 1em; + margin-right: 1em; + background-color: #f0f0f0; +} + +#product { + text-align: center; + border-bottom: 1px solid #cccccc; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#main { + background-color: #f0f0f0; + border-left: 2px solid #cccccc; +} + +#navigation { + float: left; + width: 18em; + vertical-align: top; + background-color: #f0f0f0; + overflow: visible; +} + +#navigation h2 { + background-color:#e7e7e7; + font-size:1.1em; + color:#000000; + text-align: left; + padding:0.2em; + border-top:1px solid #dddddd; + border-bottom:1px solid #dddddd; +} + +#navigation ul +{ + font-size:1em; + list-style-type: none; + margin: 1px 1px 10px 1px; +} + +#navigation li { + text-indent: -1em; + display: block; + margin: 3px 0px 0px 22px; +} + +#navigation li li a { + margin: 0px 3px 0px -1em; +} + +#content { + margin-left: 18em; + padding: 1em; + width: 700px; + border-left: 2px solid #cccccc; + border-right: 2px solid #cccccc; + background-color: #ffffff; +} + +#about { + clear: both; + padding: 5px; + border-top: 2px solid #cccccc; + background-color: #ffffff; +} + +@media print { + body { + font: 12pt "Times New Roman", "TimeNR", Times, serif; + } + a { font-weight: bold; color: #004080; text-decoration: underline; } + + #main { + background-color: #ffffff; + border-left: 0px; + } + + #container { + margin-left: 2%; + margin-right: 2%; + background-color: #ffffff; + } + + #content { + padding: 1em; + background-color: #ffffff; + } + + #navigation { + display: none; + } + pre.example { + font-family: "Andale Mono", monospace; + font-size: 10pt; + page-break-inside: avoid; + } +} + +table.module_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.module_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.module_list td.name { background-color: #f0f0f0; min-width: 200px; } +table.module_list td.summary { width: 100%; } + + +table.function_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.function_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.function_list td.name { background-color: #f0f0f0; min-width: 200px; } +table.function_list td.summary { width: 100%; } + +ul.nowrap { + overflow:auto; + white-space:nowrap; +} + +dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} +dl.table h3, dl.function h3 {font-size: .95em;} + +/* stop sublists from having initial vertical space */ +ul ul { margin-top: 0px; } +ol ul { margin-top: 0px; } +ol ol { margin-top: 0px; } +ul ol { margin-top: 0px; } + +/* styles for prettification of source */ +pre .comment { color: #558817; } +pre .constant { color: #a8660d; } +pre .escape { color: #844631; } +pre .keyword { color: #2239a8; font-weight: bold; } +pre .library { color: #0e7c6b; } +pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } +pre .string { color: #a8660d; } +pre .number { color: #f8660d; } +pre .operator { color: #2239a8; font-weight: bold; } +pre .preprocessor, pre .prepro { color: #a33243; } +pre .global { color: #800080; } +pre .prompt { color: #558817; } +pre .url { color: #272fc2; text-decoration: underline; } diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html new file mode 100644 index 0000000..e919d11 --- /dev/null +++ b/doc/modules/std.debug.html @@ -0,0 +1,208 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.debug

    +

    Additions to the debug module

    +

    + +

    + + +

    Functions

    + + + + + + + + + + + + + +
    debug ()The global function debug is an abbreviation for debug.say (1, ...)
    say (n, ...)Print a debugging message.
    trace (event)Trace function calls.
    +

    Tables

    + + + + + +
    _DEBUGTo activate debugging set _DEBUG either to any true value + (equivalent to {level = 1}), or as documented below.
    + +
    +
    + + +

    Functions

    +
    +
    + + debug () +
    +
    + The global function debug is an abbreviation for debug.say (1, ...) + + + + + +

    See also:

    + + + +
    +
    + + say (n, ...) +
    +
    + Print a debugging message. + + +

    Parameters:

    +
      +
    • n + debugging level, defaults to 1 +
    • +
    • ... + objects to print (as for print) +
    • +
    + + + + + +
    +
    + + trace (event) +
    +
    + Trace function calls. + Use as debug.sethook (trace, "cr"), which is done automatically + when _DEBUG.call is set. + Based on test/trace-calls.lua from the Lua distribution. + + +

    Parameters:

    +
      +
    • event + event causing the call +
    • +
    + + + + + +
    +
    +

    Tables

    +
    +
    + + _DEBUG +
    +
    + To activate debugging set _DEBUG either to any true value + (equivalent to {level = 1}), or as documented below. + + +

    Fields:

    +
      +
    • level + debugging level +
    • +
    • call + do call trace debugging +
    • +
    • std + do standard library debugging (run examples & test code) +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html new file mode 100644 index 0000000..c3bf40b --- /dev/null +++ b/doc/modules/std.functional.html @@ -0,0 +1,501 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.functional

    +

    Functional programming.

    +

    + +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    bind (f, ...)Partially apply a function.
    collect (i)Collect the results of an iterator.
    compose ()Compose functions.
    curry (f, n)Curry a function.
    eval (s)Evaluate a string.
    filter (p, i)Filter an iterator with a predicate.
    fold (f, d, i)Fold a binary function into an iterator.
    id (...)Identity function.
    map (f, i)Map a function over an iterator.
    memoize (fn)Memoize a function, by wrapping it in a functable.
    metamethod (x, n)Return given metamethod, if any, or nil.
    +

    Tables

    + + + + + +
    opFunctional forms of infix operators.
    + +
    +
    + + +

    Functions

    +
    +
    + + bind (f, ...) +
    +
    + Partially apply a function. + + +

    Parameters:

    +
      +
    • f + function to apply partially +
    • +
    • ... + arguments to bind +
    • +
    + +

    Returns:

    +
      + + function with ai already bound +
    + + + + +
    +
    + + collect (i) +
    +
    + Collect the results of an iterator. + + +

    Parameters:

    +
      +
    • i + iterator +
    • +
    + +

    Returns:

    +
      + + results of running the iterator on its arguments +
    + + + + +
    +
    + + compose () +
    +
    + Compose functions. + + + +

    Returns:

    +
      + + composition of f1 ... fn +
    + + + + +
    +
    + + curry (f, n) +
    +
    + Curry a function. + + +

    Parameters:

    +
      +
    • f + function to curry +
    • +
    • n + number of arguments +
    • +
    + +

    Returns:

    +
      + + curried version of f +
    + + + + +
    +
    + + eval (s) +
    +
    + Evaluate a string. + + +

    Parameters:

    +
      +
    • s + string +
    • +
    + +

    Returns:

    +
      + + value of string +
    + + + + +
    +
    + + filter (p, i) +
    +
    + Filter an iterator with a predicate. + + +

    Parameters:

    +
      +
    • p + predicate +
    • +
    • i + iterator +
    • +
    + +

    Returns:

    +
      + + result table containing elements e for which p (e) +
    + + + + +
    +
    + + fold (f, d, i) +
    +
    + Fold a binary function into an iterator. + + +

    Parameters:

    +
      +
    • f + function +
    • +
    • d + initial first argument +
    • +
    • i + iterator +
    • +
    + +

    Returns:

    +
      + + result +
    + + + + +
    +
    + + id (...) +
    +
    + Identity function. + + +

    Parameters:

    +
      +
    • ... + + + +
    • +
    + +

    Returns:

    +
      + + the arguments passed to the function +
    + + + + +
    +
    + + map (f, i) +
    +
    + Map a function over an iterator. + + +

    Parameters:

    +
      +
    • f + function +
    • +
    • i + iterator +
    • +
    + +

    Returns:

    +
      + + result table +
    + + + + +
    +
    + + memoize (fn) +
    +
    + Memoize a function, by wrapping it in a functable. + + +

    Parameters:

    +
      +
    • fn + function that returns a single result +
    • +
    + +

    Returns:

    +
      + + memoized function +
    + + + + +
    +
    + + metamethod (x, n) +
    +
    + Return given metamethod, if any, or nil. + + +

    Parameters:

    +
      +
    • x + object to get metamethod of +
    • +
    • n + name of metamethod to get +
    • +
    + +

    Returns:

    +
      + + metamethod function or nil if no metamethod or not a + function +
    + + + + +
    +
    +

    Tables

    +
    +
    + + op +
    +
    + Functional forms of infix operators. + Defined here so that other modules can write to it. + + +

    Fields:

    +
      +
    • dereference + table index +
    • +
    • addition + + + +
    • +
    • subtraction + + + +
    • +
    • multiplication + + + +
    • +
    • division + + + +
    • +
    • and + logical and +
    • +
    • or + logical or +
    • +
    • not + logical not +
    • +
    • equality + + + +
    • +
    • inequality + + + +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.getopt.html b/doc/modules/std.getopt.html new file mode 100644 index 0000000..5a915a0 --- /dev/null +++ b/doc/modules/std.getopt.html @@ -0,0 +1,248 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.getopt

    +

    Simplified getopt, based on Svenne Panne's Haskell GetOpt.

    +

    Usage:

    + +
     prog = {<
    +   name = <progname>,
    +   [usage = <usage line>,]
    +   [options = {
    +     {{<name>[, ...]}, <desc>, [<type> [, <var>]]},
    +     ...
    +   },]
    +   [banner = <banner string>,]
    +   [purpose = <purpose string>,]
    +   [notes = <additional notes>]
    + }
    +
    + +
      +
    • The type of option argument is one of Req(uired), + Opt(ional)
    • +
    • The varis a descriptive name for the option argument.
    • +
    • getopt.processargs (prog)
    • +
    • Options take a single dash, but may have a double dash.
    • +
    • Arguments may be given as -opt=arg or -opt arg.
    • +
    • If an option taking an argument is given multiple times, only the + last value is returned; missing arguments are returned as 1.
    • +
    + +

    getOpt, usageinfo and usage can be called directly (see + below, and the example at the end). Set _DEBUG.std to a non-nil + value to run the example.

    + + +

    Functions

    + + + + + + + + + + + + + + + + + +
    getopt (argIn, options, stop_at_nonopt)Perform argument processing
    processargs (prog, ...)Simple getopt wrapper.
    usage (prog)Emit a usage message.
    usageinfo (header, optDesc, pageWidth)Produce usage info for the given options.
    + +
    +
    + + +

    Functions

    +
    +
    + + getopt (argIn, options, stop_at_nonopt) +
    +
    + Perform argument processing + + +

    Parameters:

    +
      +
    • argIn + list of command-line args +
    • +
    • options + options table +
    • +
    • stop_at_nonopt + if true, stop option processing at first non-option +
    • +
    + +

    Returns:

    +
      +
    1. + table of remaining non-options
    2. +
    3. + table of option key-value list pairs
    4. +
    5. + table of error messages
    6. +
    + + + + +
    +
    + + processargs (prog, ...) +
    +
    + Simple getopt wrapper. + If the caller didn't supply their own already, adds --version/-V + and --help/-h options automatically; + stops program if there was an error, or if --help or --version was + used. + + +

    Parameters:

    +
      +
    • prog + table of named parameters +
    • +
    • ... + extra arguments for getopt +
    • +
    + + + + + +
    +
    + + usage (prog) +
    +
    + Emit a usage message. + + +

    Parameters:

    +
      +
    • prog + table of named parameters +
    • +
    + + + + + +
    +
    + + usageinfo (header, optDesc, pageWidth) +
    +
    + Produce usage info for the given options. + + +

    Parameters:

    +
      +
    • header + header string +
    • +
    • optDesc + option descriptors +
    • +
    • pageWidth + width to format to [78] +
    • +
    + +

    Returns:

    +
      + + formatted string +
    + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.html b/doc/modules/std.html new file mode 100644 index 0000000..1ab8ea2 --- /dev/null +++ b/doc/modules/std.html @@ -0,0 +1,723 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std

    +

    Global namespace scribbler.

    +

    For backwards compatibility with older releases, require "std" + will inject the same functions into the global namespace as it + has done previously, even though it is now deprecated.

    + +

    For new code, much better than scribbling all over the global + namespace, it's more hygienic to explicitly assign the results of + requiring just the submodules you actually use to a local variable, + and access its functions via that table.

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    _G.assert ()Extend to allow formatted arguments.
    _G.bind ()Partially apply a function.
    _G.collect ()Collect the results of an iterator.
    _G.compose ()Compose functions.
    _G.curry ()Curry a function.
    _G.die ()Die with an error.
    _G.eval ()Evaluate a string.
    _G.filter ()Filter an iterator with a predicate.
    _G.fold ()Fold a binary function into an iterator.
    _G.id ()Identity function.
    _G.ileaves ()Tree iterator which returns just numbered leaves, in order.
    _G.inodes ()Tree iterator over numbered nodes, in order.
    _G.leaves ()Tree iterator which returns just leaves.
    _G.map ()Map a function over an iterator.
    _G.memoize ()Memoize a function, by wrapping it in a functable.
    _G.metamethod ()Return given metamethod, if any, else nil.
    _G.nodes ()Tree iterator.
    _G.pack ()Turn a tuple into a list.
    _G.pickle ()Convert a value to a string.
    _G.prettytostring ()Pretty-print a table.
    _G.render ()Turn tables into strings with recursion detection.
    _G.require_version ()Require a module with a particular version.
    _G.ripairs ()An iterator like ipairs, but in reverse.
    _G.tostring ()Extend tostring to work better on tables.
    _G.totable ()Turn an object into a table, according to __totable metamethod.
    _G.warn ()Give a warning with the name of program and file (if any).
    +

    Tables

    + + + + + + + + + +
    _G.opFunctional forms of infix operators.
    stdModule table.
    + +
    +
    + + +

    Functions

    +
    +
    + + _G.assert () +
    +
    + Extend to allow formatted arguments. + + + + + +

    See also:

    + + + +
    +
    + + _G.bind () +
    +
    + Partially apply a function. + + + + + +

    See also:

    + + + +
    +
    + + _G.collect () +
    +
    + Collect the results of an iterator. + + + + + +

    See also:

    + + + +
    +
    + + _G.compose () +
    +
    + Compose functions. + + + + + +

    See also:

    + + + +
    +
    + + _G.curry () +
    +
    + Curry a function. + + + + + +

    See also:

    + + + +
    +
    + + _G.die () +
    +
    + Die with an error. + + + + + +

    See also:

    + + + +
    +
    + + _G.eval () +
    +
    + Evaluate a string. + + + + + +

    See also:

    + + + +
    +
    + + _G.filter () +
    +
    + Filter an iterator with a predicate. + + + + + +

    See also:

    + + + +
    +
    + + _G.fold () +
    +
    + Fold a binary function into an iterator. + + + + + +

    See also:

    + + + +
    +
    + + _G.id () +
    +
    + Identity function. + + + + + +

    See also:

    + + + +
    +
    + + _G.ileaves () +
    +
    + Tree iterator which returns just numbered leaves, in order. + + + + + +

    See also:

    + + + +
    +
    + + _G.inodes () +
    +
    + Tree iterator over numbered nodes, in order. + + + + + +

    See also:

    + + + +
    +
    + + _G.leaves () +
    +
    + Tree iterator which returns just leaves. + + + + + +

    See also:

    + + + +
    +
    + + _G.map () +
    +
    + Map a function over an iterator. + + + + + +

    See also:

    + + + +
    +
    + + _G.memoize () +
    +
    + Memoize a function, by wrapping it in a functable. + + + + + +

    See also:

    + + + +
    +
    + + _G.metamethod () +
    +
    + Return given metamethod, if any, else nil. + + + + + +

    See also:

    + + + +
    +
    + + _G.nodes () +
    +
    + Tree iterator. + + + + + +

    See also:

    + + + +
    +
    + + _G.pack () +
    +
    + Turn a tuple into a list. + + + + + +

    See also:

    + + + +
    +
    + + _G.pickle () +
    +
    + Convert a value to a string. + + + + + +

    See also:

    + + + +
    +
    + + _G.prettytostring () +
    +
    + Pretty-print a table. + + + + + +

    See also:

    + + + +
    +
    + + _G.render () +
    +
    + Turn tables into strings with recursion detection. + + + + + +

    See also:

    + + + +
    +
    + + _G.require_version () +
    +
    + Require a module with a particular version. + + + + + +

    See also:

    + + + +
    +
    + + _G.ripairs () +
    +
    + An iterator like ipairs, but in reverse. + + + + + +

    See also:

    + + + +
    +
    + + _G.tostring () +
    +
    + Extend tostring to work better on tables. + + + + + +

    See also:

    + + + +
    +
    + + _G.totable () +
    +
    + Turn an object into a table, according to __totable metamethod. + + + + + +

    See also:

    + + + +
    +
    + + _G.warn () +
    +
    + Give a warning with the name of program and file (if any). + + + + + +

    See also:

    + + + +
    +
    +

    Tables

    +
    +
    + + _G.op +
    +
    + Functional forms of infix operators. + + + + + +

    See also:

    + + + +
    +
    + + std +
    +
    + Module table. + + +

    Fields:

    +
      +
    • version + release version string +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html new file mode 100644 index 0000000..812381e --- /dev/null +++ b/doc/modules/std.io.html @@ -0,0 +1,371 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.io

    +

    Additions to the io module.

    +

    + +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    catdir (...)Concatenate two or more directories into a path, removing the trailing slash.
    catfile (...)Concatenate one or more directories and a filename into a path.
    die (...)Die with error.
    process_files (f)Process files specified on the command-line.
    readlines (h)Read a file or file handle into a list of lines.
    shell (c)Perform a shell command and return its output.
    slurp (h)Slurp a file handle.
    splitdir (path)Split a directory path into components.
    warn (...)Give warning with the name of program and file (if any).
    writelines (h, ...)Write values adding a newline after each.
    + +
    +
    + + +

    Functions

    +
    +
    + + catdir (...) +
    +
    + Concatenate two or more directories into a path, removing the trailing slash. + + +

    Parameters:

    +
      +
    • ... + path components +
    • +
    + +

    Returns:

    +
      + + path +
    + + + + +
    +
    + + catfile (...) +
    +
    + Concatenate one or more directories and a filename into a path. + + +

    Parameters:

    +
      +
    • ... + path components +
    • +
    + +

    Returns:

    +
      + + path +
    + + + + +
    +
    + + die (...) +
    +
    + Die with error. + + +

    Parameters:

    +
      +
    • ... + arguments for format +
    • +
    + + + + + +
    +
    + + process_files (f) +
    +
    + Process files specified on the command-line. + If no files given, process io.stdin; in list of files, + - means io.stdin. + + +

    Parameters:

    +
      +
    • f + function to process files with, which is passed + (name, arg_no) +
    • +
    + + + + + +
    +
    + + readlines (h) +
    +
    + Read a file or file handle into a list of lines. + + +

    Parameters:

    +
      +
    • h + file handle or name (default: io.input ()); + if h is a handle, the file is closed after reading +
    • +
    + +

    Returns:

    +
      + + list of lines +
    + + + + +
    +
    + + shell (c) +
    +
    + Perform a shell command and return its output. + + +

    Parameters:

    +
      +
    • c + command +
    • +
    + +

    Returns:

    +
      + + output, or nil if error +
    + + + + +
    +
    + + slurp (h) +
    +
    + Slurp a file handle. + + +

    Parameters:

    +
      +
    • h + file handle or name (default: io.input ()) +
    • +
    + +

    Returns:

    +
      + + contents of file or handle, or nil if error +
    + + + + +
    +
    + + splitdir (path) +
    +
    + Split a directory path into components. + Empty components are retained: the root directory becomes {"", ""}. + + +

    Parameters:

    +
      +
    • path + path +
    • +
    + +

    Returns:

    +
      + + list of path components +
    + + + + +
    +
    + + warn (...) +
    +
    + Give warning with the name of program and file (if any). + + +

    Parameters:

    +
      +
    • ... + arguments for format +
    • +
    + + + + + +
    +
    + + writelines (h, ...) +
    +
    + Write values adding a newline after each. + + +

    Parameters:

    +
      +
    • h + file handle (default: io.output () +
    • +
    • ... + values to write (as for write) +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html new file mode 100644 index 0000000..1d26c3b --- /dev/null +++ b/doc/modules/std.math.html @@ -0,0 +1,157 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.math

    +

    Additions to the math module.

    +

    + +

    + + +

    Functions

    + + + + + + + + + +
    floor (n, p)Extend math.floor to take the number of decimal places.
    round (n, p)Round a number to a given number of decimal places
    + +
    +
    + + +

    Functions

    +
    +
    + + floor (n, p) +
    +
    + Extend math.floor to take the number of decimal places. + + +

    Parameters:

    +
      +
    • n + number +
    • +
    • p + number of decimal places to truncate to (default: 0) +
    • +
    + +

    Returns:

    +
      + + n truncated to p decimal places +
    + + + + +
    +
    + + round (n, p) +
    +
    + Round a number to a given number of decimal places + + +

    Parameters:

    +
      +
    • n + number +
    • +
    • p + number of decimal places to round to (default: 0) +
    • +
    + +

    Returns:

    +
      + + n rounded to p decimal places +
    + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html new file mode 100644 index 0000000..3285807 --- /dev/null +++ b/doc/modules/std.package.html @@ -0,0 +1,131 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.package

    +

    Additions to the package module.

    +

    + +

    + + +

    Tables

    + + + + + +
    packageMake named constants for package.config + (undocumented in 5.1; see luaconf.h for C equivalents).
    + +
    +
    + + +

    Tables

    +
    +
    + + package +
    +
    + Make named constants for package.config + (undocumented in 5.1; see luaconf.h for C equivalents). + + +

    Fields:

    +
      +
    • dirsep + directory separator +
    • +
    • pathsep + path separator +
    • +
    • path_mark + string that marks substitution points in a path template +
    • +
    • execdir + (Windows only) replaced by the executable's directory in a path +
    • +
    • igmark + Mark to ignore all before it when building luaopen_ function name. +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html new file mode 100644 index 0000000..c0184a7 --- /dev/null +++ b/doc/modules/std.strict.html @@ -0,0 +1,130 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.strict

    +

    Checks uses of undeclared global variables.

    +

    All global variables must be 'declared' through a regular + assignment (even assigning nil will do) in a top-level + chunk before being used anywhere or assigned to inside a function. + From Lua distribution (etc/strict.lua).

    + + +

    Functions

    + + + + + + + + + +
    __index ()Detect derefrence of undeclared global.
    __newindex ()Detect assignment to undeclared global.
    + +
    +
    + + +

    Functions

    +
    +
    + + __index () +
    +
    + Detect derefrence of undeclared global. + + + + + + + +
    +
    + + __newindex () +
    +
    + Detect assignment to undeclared global. + + + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html new file mode 100644 index 0000000..c3f1211 --- /dev/null +++ b/doc/modules/std.string.html @@ -0,0 +1,1076 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.string

    +

    Additions to the string module.

    +

    + +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    assert (v, f, ...)Extend to allow formatted arguments.
    caps (s)Capitalise each word in a string.
    chomp (s)Remove any final newline from a string.
    escape_pattern (s)Escape a string to be used as a pattern.
    escape_shell (s)Escape a string to be used as a shell token.
    finds (s, p, init, plain)Do multiple finds on a string.
    format (f, arg1, ...)Extend to work better with one argument.
    ltrim (s, r)Remove leading matter from a string.
    numbertosi (n)Write a number using SI suffixes.
    ordinal_suffix (n)Return the English suffix for an ordinal.
    pad (s, w, p)Justify a string.
    pickle (x)Convert a value to a string.
    prettytostring (t, indent, spacing)Pretty-print a table.
    render (x, open, close, elem, pair, sep, roots)Turn tables into strings with recursion detection.
    render_CloseRenderer (t) + +
    render_ElementRenderer (e) + +
    render_OpenRenderer (t) + +
    render_PairRenderer (t, i, v, is, vs)NB.
    render_SeparatorRenderer (t, i, v, j, w) + +
    require_version (module, min, too_big, pattern)Require a module with a particular version.
    rtrim (s, r)Remove trailing matter from a string.
    split (s, sep)Split a string at a given separator.
    tfind (s, p, init, plain)Do find, returning captures as a list.
    tostring (x)Extend tostring to work better on tables.
    trim (s, r)Remove leading and trailing matter from a string.
    wrap (s, w, ind, ind1)Wrap a string into a paragraph.
    +

    Fields

    + + + + + + + + + + + + + +
    sGive strings a subscription operator.
    sGive strings an append metamethod.
    sGive strings a concat metamethod.
    + +
    +
    + + +

    Functions

    +
    +
    + + assert (v, f, ...) +
    +
    + Extend to allow formatted arguments. + + +

    Parameters:

    +
      +
    • v + value to assert +
    • +
    • f + format +
    • +
    • ... + arguments to format +
    • +
    + +

    Returns:

    +
      + + value +
    + + + + +
    +
    + + caps (s) +
    +
    + Capitalise each word in a string. + + +

    Parameters:

    +
      +
    • s + string +
    • +
    + +

    Returns:

    +
      + + capitalised string +
    + + + + +
    +
    + + chomp (s) +
    +
    + Remove any final newline from a string. + + +

    Parameters:

    +
      +
    • s + string to process +
    • +
    + +

    Returns:

    +
      + + processed string +
    + + + + +
    +
    + + escape_pattern (s) +
    +
    + Escape a string to be used as a pattern. + + +

    Parameters:

    +
      +
    • s + string to process +
    • +
    + +

    Returns:

    +
      + + processed string +
    + + + + +
    +
    + + escape_shell (s) +
    +
    + Escape a string to be used as a shell token. + Quotes spaces, parentheses, brackets, quotes, apostrophes and + whitespace. + + +

    Parameters:

    +
      +
    • s + string to process +
    • +
    + +

    Returns:

    +
      + + processed string +
    + + + + +
    +
    + + finds (s, p, init, plain) +
    +
    + Do multiple finds on a string. + + +

    Parameters:

    +
      +
    • s + target string +
    • +
    • p + pattern +
    • +
    • init + start position (default: 1) +
    • +
    • plain + inhibit magic characters (default: nil) +
    • +
    + +

    Returns:

    +
      + + list of {from, to; capt = {captures}} +
    + + + + +
    +
    + + format (f, arg1, ...) +
    +
    + Extend to work better with one argument. + If only one argument is passed, no formatting is attempted. + + +

    Parameters:

    +
      +
    • f + format +
    • +
    • arg1 + first argument to format +
    • +
    • ... + arguments to format +
    • +
    + +

    Returns:

    +
      + + formatted string +
    + + + + +
    +
    + + ltrim (s, r) +
    +
    + Remove leading matter from a string. + + +

    Parameters:

    +
      +
    • s + string +
    • +
    • r + leading pattern (default: "%s+") +
    • +
    + +

    Returns:

    +
      + + string without leading r +
    + + + + +
    +
    + + numbertosi (n) +
    +
    + Write a number using SI suffixes. + The number is always written to 3 s.f. + + +

    Parameters:

    +
      +
    • n + number +
    • +
    + +

    Returns:

    +
      + + string +
    + + + + +
    +
    + + ordinal_suffix (n) +
    +
    + Return the English suffix for an ordinal. + + +

    Parameters:

    +
      +
    • n + number of the day +
    • +
    + +

    Returns:

    +
      + + suffix +
    + + + + +
    +
    + + pad (s, w, p) +
    +
    + Justify a string. + When the string is longer than w, it is truncated (left or right + according to the sign of w). + + +

    Parameters:

    +
      +
    • s + string to justify +
    • +
    • w + width to justify to (-ve means right-justify; +ve means + left-justify) +
    • +
    • p + string to pad with (default: " ") +
    • +
    + +

    Returns:

    +
      + + justified string +
    + + + + +
    +
    + + pickle (x) +
    +
    + Convert a value to a string. + The string can be passed to dostring to retrieve the value. + + +

    Parameters:

    +
      +
    • x + object to pickle +
    • +
    + +

    Returns:

    +
      + + string such that eval (s) is the same value as x +
    + + + + +
    +
    + + prettytostring (t, indent, spacing) +
    +
    + Pretty-print a table. + + +

    Parameters:

    +
      +
    • t + table to print +
    • +
    • indent + indent between levels ["\t"] +
    • +
    • spacing + space before every line +
    • +
    + +

    Returns:

    +
      + + pretty-printed string +
    + + + + +
    +
    + + render (x, open, close, elem, pair, sep, roots) +
    +
    + Turn tables into strings with recursion detection. + N.B. Functions calling render should not recurse, or recursion + detection will not work. + + +

    Parameters:

    +
      +
    • x + object to convert to string +
    • +
    • open + open table renderer +
    • +
    • close + close table renderer +
    • +
    • elem + element renderer +
    • +
    • pair + pair renderer +
    • +
    • sep + separator renderer +
    • +
    • roots + accumulates table references to detect recursion +
    • +
    + +

    Returns:

    +
      +
    1. + string representation
    2. +
    3. + open table string
    4. +
    + + +

    See also:

    + + + +
    +
    + + render_CloseRenderer (t) +
    +
    + + + +

    Parameters:

    +
      +
    • t + table +
    • +
    + +

    Returns:

    +
      +
    1. + close table string
    2. +
    3. + element string
    4. +
    + + + + +
    +
    + + render_ElementRenderer (e) +
    +
    + + + +

    Parameters:

    +
      +
    • e + element +
    • +
    + +

    Returns:

    +
      + + element string +
    + + + + +
    +
    + + render_OpenRenderer (t) +
    +
    + + + +

    Parameters:

    +
      +
    • t + table +
    • +
    + +

    Returns:

    +
      +
    1. + open table string
    2. +
    3. + close table string
    4. +
    + + + + +
    +
    + + render_PairRenderer (t, i, v, is, vs) +
    +
    + NB. the function should not try to render i and v, or treat them recursively. + + +

    Parameters:

    +
      +
    • t + table +
    • +
    • i + index +
    • +
    • v + value +
    • +
    • is + index string +
    • +
    • vs + value string +
    • +
    + +

    Returns:

    +
      +
    1. + element string
    2. +
    3. + separator string
    4. +
    + + + + +
    +
    + + render_SeparatorRenderer (t, i, v, j, w) +
    +
    + + + +

    Parameters:

    +
      +
    • t + table +
    • +
    • i + preceding index (nil on first call) +
    • +
    • v + preceding value (nil on first call) +
    • +
    • j + following index (nil on last call) +
    • +
    • w + following value (nil on last call) +
    • +
    + +

    Returns:

    +
      + + separator string +
    + + + + +
    +
    + + require_version (module, min, too_big, pattern) +
    +
    + Require a module with a particular version. + + +

    Parameters:

    +
      +
    • module + module to require +
    • +
    • min + lowest acceptable version (default: any) +
    • +
    • too_big + lowest version that is too big (default: none) +
    • +
    • pattern + to match version in module.version or + module.VERSION (default: ".*[%.%d]+" +
    • +
    + + + + + +
    +
    + + rtrim (s, r) +
    +
    + Remove trailing matter from a string. + + +

    Parameters:

    +
      +
    • s + string +
    • +
    • r + trailing pattern (default: "%s+") +
    • +
    + +

    Returns:

    +
      + + string without trailing r +
    + + + + +
    +
    + + split (s, sep) +
    +
    + Split a string at a given separator. + + +

    Parameters:

    +
      +
    • s + string to split +
    • +
    • sep + separator pattern +
    • +
    + +

    Returns:

    +
      + + list of strings +
    + + + + +
    +
    + + tfind (s, p, init, plain) +
    +
    + Do find, returning captures as a list. + + +

    Parameters:

    +
      +
    • s + target string +
    • +
    • p + pattern +
    • +
    • init + start position (default: 1) +
    • +
    • plain + inhibit magic characters (default: nil) +
    • +
    + +

    Returns:

    +
      + + start of match, end of match, table of captures +
    + + + + +
    +
    + + tostring (x) +
    +
    + Extend tostring to work better on tables. + + +

    Parameters:

    +
      +
    • x + object to convert to string +
    • +
    + +

    Returns:

    +
      + + string representation +
    + + + + +
    +
    + + trim (s, r) +
    +
    + Remove leading and trailing matter from a string. + + +

    Parameters:

    +
      +
    • s + string +
    • +
    • r + leading/trailing pattern (default: "%s+") +
    • +
    + +

    Returns:

    +
      + + string without leading/trailing r +
    + + + + +
    +
    + + wrap (s, w, ind, ind1) +
    +
    + Wrap a string into a paragraph. + + +

    Parameters:

    +
      +
    • s + string to wrap +
    • +
    • w + width to wrap to (default: 78) +
    • +
    • ind + indent (default: 0) +
    • +
    • ind1 + indent of first line (default: ind) +
    • +
    + +

    Returns:

    +
      + + wrapped paragraph +
    + + + + +
    +
    +

    Fields

    +
    +
    + + s +
    +
    + Give strings a subscription operator. + + +
      +
    • s + string +
    • +
    • i + index +
    • +
    + + + + + +
    +
    + + s +
    +
    + Give strings an append metamethod. + + +
      +
    • s + string +
    • +
    • c + character (1-character string) +
    • +
    + + + + + +
    +
    + + s +
    +
    + Give strings a concat metamethod. + + +
      +
    • s + string +
    • +
    • o + object +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html new file mode 100644 index 0000000..05cb962 --- /dev/null +++ b/doc/modules/std.table.html @@ -0,0 +1,518 @@ + + + + + Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.table

    +

    Extensions to the table module.

    +

    + +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    clone (t, nometa)Make a shallow copy of a table, including any metatable.
    clone_rename (t, map)Clone a table, renaming some keys.
    empty (t)Return whether table is empty.
    invert (t)Invert a table.
    keys (t)Make the list of keys in table.
    merge (t, u)Destructively merge another table's fields into table.
    new (x, t)Make a table with a default value for unset keys.
    pack (...)Turn a tuple into a list.
    ripairs (t)An iterator like ipairs, but in reverse.
    size (t)Find the number of elements in a table.
    sort (t, c)Make table.sort return its result.
    totable (x)Turn an object into a table according to __totable metamethod.
    values (t)Make the list of values of a table.
    + +
    +
    + + +

    Functions

    +
    +
    + + clone (t, nometa) +
    +
    + Make a shallow copy of a table, including any metatable.

    + +

    To make deep copies, use std.tree.clone. + + +

    Parameters:

    +
      +
    • t + table + +
        source table
      +
      + +
    • +
    • nometa + boolean + if non-nil don't copy metatable +
    • +
    + +

    Returns:

    +
      + + copy of table +
    + + + + +
    +
    + + clone_rename (t, map) +
    +
    + Clone a table, renaming some keys. + + +

    Parameters:

    +
      +
    • t + table + source table +
    • +
    • map + table + table {oldkey=newkey, ...} +
    • +
    + +

    Returns:

    +
      + + copy of table +
    + + + + +
    +
    + + empty (t) +
    +
    + Return whether table is empty. + + +

    Parameters:

    +
      +
    • t + table + any table +
    • +
    + +

    Returns:

    +
      + + true if t is empty, otherwise false +
    + + + + +
    +
    + + invert (t) +
    +
    + Invert a table. + + +

    Parameters:

    +
      +
    • t + table + a table with {k=v, ...} +
    • +
    + +

    Returns:

    +
      + + table + inverted table {v=k, ...} +
    + + + + +
    +
    + + keys (t) +
    +
    + Make the list of keys in table. + + +

    Parameters:

    +
      +
    • t + table + any table +
    • +
    + +

    Returns:

    +
      + + table + list of keys +
    + + + + +
    +
    + + merge (t, u) +
    +
    + Destructively merge another table's fields into table. + + +

    Parameters:

    +
      +
    • t + table + destination table +
    • +
    • u + table + table with fields to merge +
    • +
    + +

    Returns:

    +
      + + table t with fields from u merged in +
    + + + + +
    +
    + + new (x, t) +
    +
    + Make a table with a default value for unset keys. + + +

    Parameters:

    +
      +
    • x + default entry value (default: nil) +
    • +
    • t + table + initial table (default: {}) +
    • +
    + +

    Returns:

    +
      + + table + table whose unset elements are x +
    + + + + +
    +
    + + pack (...) +
    +
    + Turn a tuple into a list. + + +

    Parameters:

    +
      +
    • ... + tuple +
    • +
    + +

    Returns:

    +
      + + list +
    + + + + +
    +
    + + ripairs (t) +
    +
    + An iterator like ipairs, but in reverse. + + +

    Parameters:

    +
      +
    • t + table + any table +
    • +
    + +

    Returns:

    +
      +
    1. + function + iterator function
    2. +
    3. + table + the table, t
    4. +
    5. + number + #t + 1
    6. +
    + + + + +
    +
    + + size (t) +
    +
    + Find the number of elements in a table. + + +

    Parameters:

    +
      +
    • t + table + any table +
    • +
    + +

    Returns:

    +
      + + number of non-nil values in t +
    + + + + +
    +
    + + sort (t, c) +
    +
    + Make table.sort return its result. + + +

    Parameters:

    +
      +
    • t + table + unsorted table +
    • +
    • c + function + comparator function +
    • +
    + +

    Returns:

    +
      + + t with keys sorted accordind to c +
    + + + + +
    +
    + + totable (x) +
    +
    + Turn an object into a table according to __totable metamethod. + + +

    Parameters:

    +
      +
    • x + std.object + object to turn into a table +
    • +
    + +

    Returns:

    +
      + + table + resulting table or nil +
    + + + + +
    +
    + + values (t) +
    +
    + Make the list of values of a table. + + +

    Parameters:

    +
      +
    • t + table + any table +
    • +
    + +

    Returns:

    +
      + + table + list of values +
    + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.0 +
    +
    + + diff --git a/lib/std.lua b/lib/std.lua new file mode 100644 index 0000000..0a17601 --- /dev/null +++ b/lib/std.lua @@ -0,0 +1,196 @@ +--[[-- + Global namespace scribbler. + + For backwards compatibility with older releases, `require "std"` + will inject the same functions into the global namespace as it + has done previously, even though it is now deprecated. + + For new code, much better than scribbling all over the global + namespace, it's more hygienic to explicitly assign the results of + requiring just the submodules you actually use to a local variable, + and access its functions via that table. + + @todo Write a style guide (indenting/wrapping, capitalisation, + function and variable names); library functions should call + error, not die; OO vs non-OO (a thorny problem). + @todo Add tests for each function immediately after the function; + this also helps to check module dependencies. + @todo pre-compile. + @module std +]] + +--- Module table. +-- @table std +-- @field version release version string +local version = "General Lua libraries / 36" + +for m, globally in pairs (require "std.modules") do + if globally == true then + -- Inject stdlib extensions directly into global package namespaces. + for k, v in pairs (require ("std." .. m)) do + _G[m][k] = v + end + else + _G[m] = require ("std." .. m) + end +end + +-- Add io functions to the file handle metatable. +local file_metatable = getmetatable (io.stdin) +file_metatable.readlines = io.readlines +file_metatable.writelines = io.writelines + +-- Maintain old global interface access points. +for _, api in ipairs { + --- Partially apply a function. + -- @function _G.bind + -- @see std.functional.bind + "functional.bind", + + --- Collect the results of an iterator. + -- @function _G.collect + -- @see std.functional.collect + "functional.collect", + + --- Compose functions. + -- @function _G.compose + -- @see std.functional.compose + "functional.compose", + + --- Curry a function. + -- @function _G.curry + -- @see std.functional.curry + "functional.curry", + + --- Evaluate a string. + -- @function _G.eval + -- @see std.functional.eval + "functional.eval", + + --- Filter an iterator with a predicate. + -- @function _G.filter + -- @see std.functional.filter + "functional.filter", + + --- Fold a binary function into an iterator. + -- @function _G.fold + -- @see std.functional.fold + "functional.fold", + + --- Identity function. + -- @function _G.id + -- @see std.functional.id + "functional.id", + + --- Map a function over an iterator. + -- @function _G.map + -- @see std.functional.map + "functional.map", + + --- Memoize a function, by wrapping it in a functable. + -- @function _G.memoize + -- @see std.functional.memoize + "functional.memoize", + + --- Return given metamethod, if any, else nil. + -- @function _G.metamethod + -- @see std.functional.metamethod + "functional.metamethod", + + --- Functional forms of infix operators. + -- @table _G.op + -- @see std.functional.op + "functional.op", + + + + --- Die with an error. + -- @function _G.die + -- @see std.io.die + "io.die", + + --- Give a warning with the name of program and file (if any). + -- @function _G.warn + -- @see std.io.warn + "io.warn", + + + + --- Extend to allow formatted arguments. + -- @function _G.assert + -- @see std.string.assert + "string.assert", + + --- Convert a value to a string. + -- @function _G.pickle + -- @see std.string.pickle + "string.pickle", + + --- Pretty-print a table. + -- @function _G.prettytostring + -- @see std.string.prettytostring + "string.prettytostring", + + --- Turn tables into strings with recursion detection. + -- @function _G.render + -- @see std.string.render + "string.render", + + --- Require a module with a particular version. + -- @function _G.require_version + -- @see std.string.require_version + "string.require_version", + + --- Extend `tostring` to work better on tables. + -- @function _G.tostring + -- @see std.string.tostring + "string.tostring", + + + + --- Turn a tuple into a list. + -- @function _G.pack + -- @see std.table.pack + "table.pack", + + --- An iterator like ipairs, but in reverse. + -- @function _G.ripairs + -- @see std.table.ripairs + "table.ripairs", + + --- Turn an object into a table, according to `__totable` metamethod. + -- @function _G.totable + -- @see std.table.totable + "table.totable", + + + + --- Tree iterator which returns just numbered leaves, in order. + -- @function _G.ileaves + -- @see std.tree.ileaves + "tree.ileaves", + + --- Tree iterator over numbered nodes, in order. + -- @function _G.inodes + -- @see std.tree.inodes + "tree.inodes", + + --- Tree iterator which returns just leaves. + -- @function _G.leaves + -- @see std.tree.leaves + "tree.leaves", + + --- Tree iterator. + -- @function _G.nodes + -- @see std.tree.nodes + "tree.nodes", +} do + local module, method = api:match "^(.*)%.(.-)$" + _G[method] = _G[module][method] +end + +local M = { + version = version, +} + +return M diff --git a/lib/std.lua.in b/lib/std.lua.in new file mode 100644 index 0000000..508f0b3 --- /dev/null +++ b/lib/std.lua.in @@ -0,0 +1,196 @@ +--[[-- + Global namespace scribbler. + + For backwards compatibility with older releases, `require "std"` + will inject the same functions into the global namespace as it + has done previously, even though it is now deprecated. + + For new code, much better than scribbling all over the global + namespace, it's more hygienic to explicitly assign the results of + requiring just the submodules you actually use to a local variable, + and access its functions via that table. + + @todo Write a style guide (indenting/wrapping, capitalisation, + function and variable names); library functions should call + error, not die; OO vs non-OO (a thorny problem). + @todo Add tests for each function immediately after the function; + this also helps to check module dependencies. + @todo pre-compile. + @module std +]] + +--- Module table. +-- @table std +-- @field version release version string +local version = "General Lua libraries / @VERSION@" + +for m, globally in pairs (require "std.modules") do + if globally == true then + -- Inject stdlib extensions directly into global package namespaces. + for k, v in pairs (require ("std." .. m)) do + _G[m][k] = v + end + else + _G[m] = require ("std." .. m) + end +end + +-- Add io functions to the file handle metatable. +local file_metatable = getmetatable (io.stdin) +file_metatable.readlines = io.readlines +file_metatable.writelines = io.writelines + +-- Maintain old global interface access points. +for _, api in ipairs { + --- Partially apply a function. + -- @function _G.bind + -- @see std.functional.bind + "functional.bind", + + --- Collect the results of an iterator. + -- @function _G.collect + -- @see std.functional.collect + "functional.collect", + + --- Compose functions. + -- @function _G.compose + -- @see std.functional.compose + "functional.compose", + + --- Curry a function. + -- @function _G.curry + -- @see std.functional.curry + "functional.curry", + + --- Evaluate a string. + -- @function _G.eval + -- @see std.functional.eval + "functional.eval", + + --- Filter an iterator with a predicate. + -- @function _G.filter + -- @see std.functional.filter + "functional.filter", + + --- Fold a binary function into an iterator. + -- @function _G.fold + -- @see std.functional.fold + "functional.fold", + + --- Identity function. + -- @function _G.id + -- @see std.functional.id + "functional.id", + + --- Map a function over an iterator. + -- @function _G.map + -- @see std.functional.map + "functional.map", + + --- Memoize a function, by wrapping it in a functable. + -- @function _G.memoize + -- @see std.functional.memoize + "functional.memoize", + + --- Return given metamethod, if any, else nil. + -- @function _G.metamethod + -- @see std.functional.metamethod + "functional.metamethod", + + --- Functional forms of infix operators. + -- @table _G.op + -- @see std.functional.op + "functional.op", + + + + --- Die with an error. + -- @function _G.die + -- @see std.io.die + "io.die", + + --- Give a warning with the name of program and file (if any). + -- @function _G.warn + -- @see std.io.warn + "io.warn", + + + + --- Extend to allow formatted arguments. + -- @function _G.assert + -- @see std.string.assert + "string.assert", + + --- Convert a value to a string. + -- @function _G.pickle + -- @see std.string.pickle + "string.pickle", + + --- Pretty-print a table. + -- @function _G.prettytostring + -- @see std.string.prettytostring + "string.prettytostring", + + --- Turn tables into strings with recursion detection. + -- @function _G.render + -- @see std.string.render + "string.render", + + --- Require a module with a particular version. + -- @function _G.require_version + -- @see std.string.require_version + "string.require_version", + + --- Extend `tostring` to work better on tables. + -- @function _G.tostring + -- @see std.string.tostring + "string.tostring", + + + + --- Turn a tuple into a list. + -- @function _G.pack + -- @see std.table.pack + "table.pack", + + --- An iterator like ipairs, but in reverse. + -- @function _G.ripairs + -- @see std.table.ripairs + "table.ripairs", + + --- Turn an object into a table, according to `__totable` metamethod. + -- @function _G.totable + -- @see std.table.totable + "table.totable", + + + + --- Tree iterator which returns just numbered leaves, in order. + -- @function _G.ileaves + -- @see std.tree.ileaves + "tree.ileaves", + + --- Tree iterator over numbered nodes, in order. + -- @function _G.inodes + -- @see std.tree.inodes + "tree.inodes", + + --- Tree iterator which returns just leaves. + -- @function _G.leaves + -- @see std.tree.leaves + "tree.leaves", + + --- Tree iterator. + -- @function _G.nodes + -- @see std.tree.nodes + "tree.nodes", +} do + local module, method = api:match "^(.*)%.(.-)$" + _G[method] = _G[module][method] +end + +local M = { + version = version, +} + +return M diff --git a/lib/std/base.lua b/lib/std/base.lua new file mode 100644 index 0000000..bc26f82 --- /dev/null +++ b/lib/std/base.lua @@ -0,0 +1,157 @@ +------ +-- @module std.base + +-- Doc-commented in table.lua... +local function clone (t, nometa) + local u = {} + if not nometa then + setmetatable (u, getmetatable (t)) + end + for i, v in pairs (t) do + u[i] = v + end + return u +end + +-- Doc-commented in table.lua... +local function clone_rename (map, t) + local r = clone (t) + for i, v in pairs (map) do + r[v] = t[i] + r[i] = nil + end + return r +end + +-- Doc-commented in table.lua... +local function merge (t, u) + for i, v in pairs (u) do + t[i] = v + end + return t +end + +-- Doc-commented in list.lua... +local function append (l, x) + local r = {unpack (l)} + table.insert (r, x) + return r +end + +-- Doc-commented in list.lua... +local function compare (l, m) + for i = 1, math.min (#l, #m) do + if l[i] < m[i] then + return -1 + elseif l[i] > m[i] then + return 1 + end + end + if #l < #m then + return -1 + elseif #l > #m then + return 1 + end + return 0 +end + +-- Doc-commented in list.lua... +local function elems (l) + local n = 0 + return function (l) + n = n + 1 + if n <= #l then + return l[n] + end + end, + l, true +end + +--- Concatenate lists. +-- @param ... lists +-- @return `{l1[1], ..., +-- l1[#l1], ..., ln[1], ..., +-- ln[#ln]}` +local function concat (...) + local r = new () + for l in elems ({...}) do + for v in elems (l) do + table.insert (r, v) + end + end + return r +end + +local function _leaves (it, tr) + local function visit (n) + if type (n) == "table" then + for _, v in it (n) do + visit (v) + end + else + coroutine.yield (n) + end + end + return coroutine.wrap (visit), tr +end + +-- Metamethods for lists +-- It would be nice to define this in `list.lua`, but then we +-- couldn't keep `new` here, and other modules that really only +-- need `list.new` (as opposed to the entire `std.list` API) get +-- caught in a dependency loop. +local metatable = { + -- list .. table = list.concat + __concat = concat, + + -- list == list retains its referential meaning + -- + -- list < list = list.compare returns < 0 + __lt = function (l, m) return compare (l, m) < 0 end, + + -- list <= list = list.compare returns <= 0 + __le = function (l, m) return compare (l, m) <= 0 end, + + __append = append, +} + +--- List constructor. +-- Needed in order to use metamethods. +-- @param t list (as a table), or nil for empty list +-- @return list (with list metamethods) +function new (t) + return setmetatable (t or {}, metatable) +end + + +-- Doc-commented in tree.lua... +local function ileaves (tr) + assert (type (tr) == "table", + "bad argument #1 to 'ileaves' (table expected, got " .. type (tr) .. ")") + return _leaves (ipairs, tr) +end + +-- Doc-commented in tree.lua... +local function leaves (tr) + assert (type (tr) == "table", + "bad argument #1 to 'leaves' (table expected, got " .. type (tr) .. ")") + return _leaves (pairs, tr) +end + +local M = { + append = append, + clone = clone, + clone_rename = clone_rename, + compare = compare, + concat = concat, + elems = elems, + ileaves = ileaves, + leaves = leaves, + merge = merge, + new = new, + + -- list metatable + _list_mt = metatable, +} + +return M diff --git a/lib/std/container.lua b/lib/std/container.lua new file mode 100644 index 0000000..5104569 --- /dev/null +++ b/lib/std/container.lua @@ -0,0 +1,233 @@ +--[[-- + Container object. + + A container is a @{std.object} with no methods. It's functionality is + instead defined by its *meta*methods. + + Where an Object uses the `\_\_index` metatable entry to hold object + methods, a Container stores its contents using `\_\_index`, preventing + it from having methods in there too. + + Although there are no actual methods, Containers are free to use + metamethods (`\_\_index`, `\_\_sub`, etc) and, like Objects, can supply + module functions by listing them in `\_functions`. Also, since a + @{std.container} is a @{std.object}, it can be passed to the + @{std.object} module functions, or anywhere else a @{std.object} is + expected. + + Container derived objects returned directly from a `require` statement + may also provide module functions, which can be called only from the + initial prototype object returned by `require`, but are **not** passed + on to derived objects during cloning: + + > Container = require "std.container" + > x = Container {} + > = Container.prototype (x) + Object + > = x.prototype (o) + stdin:1: attempt to call field 'prototype' (a nil value) + ... + + To add functions like this to your own prototype objects, pass a table + of the module functions in the `_functions` private field before + cloning, and those functions will not be inherited by clones. + + > Container = require "std.container" + > Graph = Container { + >> _type = "Graph", + >> _functions = { + >> nodes = function (graph) + >> local n = 0 + >> for _ in pairs (graph) do n = n + 1 end + >> return n + >> end, + >> }, + >> } + > g = Graph { "node1", "node2" } + > = Graph.nodes (g) + 2 + > = g.nodes + nil + + When making your own prototypes, start from @{std.container} if you + want to access the contents of your objects with the `[]` operator, or + @{std.object} if you want to access the functionality of your objects + with named object methods. + + @classmod std.container +]] + + +local base = require "std.base" +local func = require "std.functional" + + +--- Return the named entry from x's metatable. +-- @param x anything +-- @tparam string n name of entry +-- @return value associate with `n` in `x`'s metatable, else nil +local function metaentry (x, n) + local ok, f = pcall (function (x) + return getmetatable (x)[n] + end, + x) + if not ok then f = nil end + return f +end + + +--- Filter a table with a function. +-- @tparam table t source table +-- @tparam function f a function that takes key and value arguments +-- from calling `pairs` on `t`, and returns non-`nil` for elements +-- that should be in the returned table +-- @treturn table a shallow copy of `t`, with elements removed according +-- to `f` +local function filter (t, f) + local r = {} + for k, v in pairs (t) do + if f (k, v) then + r[k] = v + end + end + return r +end + + +local functions = { + -- Type of this container. + -- @static + -- @tparam std.container o an container + -- @treturn string type of the container + -- @see std.object.prototype + prototype = function (o) + local _type = metaentry (o, "_type") + if type (o) == "table" and _type ~= nil then + return _type + end + return type (o) + end, +} + + +--- Container prototype. +-- @table std.container +-- @string[opt="Container"] _type type of Container, returned by +-- @{std.object.prototype} +-- @tfield table|function _init a table of field names, or +-- initialisation function, used by @{__call} +-- @tfield nil|table _functions a table of module functions not copied +-- by @{std.object.__call} +local metatable = { + _type = "Container", + _init = {}, + _functions = functions, + + + --- Return a clone of this container. + -- @function __call + -- @param ... arguments for `_init` + -- @treturn std.container a clone of the called container. + -- @see std.object:__call + __call = function (self, ...) + local mt = getmetatable (self) + + -- Make a shallow copy of prototype, skipping metatable + -- _functions. + local fn = mt._functions or {} + local obj = filter (self, function (e) return not fn[e] end) + + -- Map arguments according to _init metamethod. + local _init = metaentry (self, "_init") + if type (_init) == "table" then + base.merge (obj, base.clone_rename (_init, ...)) + else + obj = _init (obj, ...) + end + + -- Extract any new fields beginning with "_". + local obj_mt = {} + for k, v in pairs (obj) do + if type (k) == "string" and k:sub (1, 1) == "_" then + obj_mt[k], obj[k] = v, nil + end + end + + -- However, newly passed _functions from _init arguments are + -- copied as prototype functions into the object. + func.map (function (k) obj[k] = obj_mt._functions[k] end, + pairs, obj_mt._functions or {}) + + -- _functions is not propagated from prototype to clone. + if next (obj_mt) == nil and mt._functions == nil then + -- Reuse metatable if possible + obj_mt = getmetatable (self) + else + + -- Otherwise copy the prototype metatable... + local t = filter (mt, function (e) return e ~= "_functions" end) + -- ...but give preference to "_" prefixed keys from init table + obj_mt = base.merge (t, obj_mt) + + -- ...and merge container methods from prototype too. + if mt then + if type (obj_mt.__index) == "table" and type (mt.__index) == "table" then + local methods = base.clone (obj_mt.__index) + for k, v in pairs (mt.__index) do + methods[k] = methods[k] or v + end + obj_mt.__index = methods + end + end + end + + return setmetatable (obj, obj_mt) + end, + + + --- Return a string representation of this container. + -- @function __tostring + -- @treturn string stringified container representation + -- @see std.object.__tostring + __tostring = function (self) + local totable = getmetatable (self).__totable + local array = base.clone (totable (self), "nometa") + local other = base.clone (array, "nometa") + local s = "" + if #other > 0 then + for i in ipairs (other) do other[i] = nil end + end + for k in pairs (other) do array[k] = nil end + for i, v in ipairs (array) do array[i] = tostring (v) end + + local keys, dict = {}, {} + for k in pairs (other) do table.insert (keys, k) end + table.sort (keys, function (a, b) return tostring (a) < tostring (b) end) + for _, k in ipairs (keys) do + table.insert (dict, tostring (k) .. "=" .. tostring (other[k])) + end + + if #array > 0 then + s = s .. table.concat (array, ", ") + if next (dict) ~= nil then s = s .. "; " end + end + if #dict > 0 then + s = s .. table.concat (dict, ", ") + end + + return metaentry (self, "_type") .. " {" .. s .. "}" + end, + + + --- Return a table representation of this container. + -- @function __totable + -- @treturn table a shallow copy of non-private container fields + -- @see std.object:__totable + __totable = function (self) + return filter (self, function (e) + return type (e) ~= "string" or e:sub (1, 1) ~= "_" + end) + end, +} + +return setmetatable (functions, metatable) diff --git a/std/debug_ext.lua b/lib/std/debug.lua similarity index 83% rename from std/debug_ext.lua rename to lib/std/debug.lua index 9b20f24..555d09a 100644 --- a/std/debug_ext.lua +++ b/lib/std/debug.lua @@ -1,8 +1,12 @@ ---- Additions to the debug module +--[[-- + Additions to the debug module + @module std.debug +]] local init = require "std.debug_init" -local io = require "std.io_ext" -local string = require "std.string_ext" +local io = require "std.io" +local list = require "std.list" +local string = require "std.string" --- To activate debugging set _DEBUG either to any true value -- (equivalent to {level = 1}), or as documented below. @@ -13,7 +17,7 @@ local string = require "std.string_ext" -- @field std do standard library debugging (run examples & test code) ---- Print a debugging message +--- Print a debugging message. -- @param n debugging level, defaults to 1 -- @param ... objects to print (as for print) local function say (n, ...) @@ -27,11 +31,11 @@ local function say (n, ...) ((type (init._DEBUG) == "table" and type (init._DEBUG.level) == "number" and init._DEBUG.level >= level) or level <= 1) then - io.writelines (io.stderr, table.concat (list.map (tostring, arg), "\t")) + io.writelines (io.stderr, table.concat (list.map (string.tostring, arg), "\t")) end end ---- Trace function calls +--- Trace function calls. -- Use as debug.sethook (trace, "cr"), which is done automatically -- when _DEBUG.call is set. -- Based on test/trace-calls.lua from the Lua distribution. @@ -71,6 +75,7 @@ if type (init._DEBUG) == "table" and init._DEBUG.call then debug.sethook (trace, "cr") end +--- @export local M = { say = say, trace = trace, @@ -80,11 +85,8 @@ for k, v in pairs (debug) do M[k] = M[k] or v end ---- --- The global function debug is an abbreviation for --- debug.say (1, ...) --- @class function --- @name debug +--- The global function `debug` is an abbreviation for `debug.say (1, ...)` +-- @function debug -- @see say local metatable = { __call = function (self, ...) diff --git a/std/debug_init.lua b/lib/std/debug_init.lua similarity index 100% rename from std/debug_init.lua rename to lib/std/debug_init.lua diff --git a/lib/std/functional.lua b/lib/std/functional.lua new file mode 100644 index 0000000..a151ab8 --- /dev/null +++ b/lib/std/functional.lua @@ -0,0 +1,202 @@ +--[[-- + Functional programming. + @module std.functional +]] + +local list = require "std.base" + +local functional -- forward declaration + + +--- Return given metamethod, if any, or nil. +-- @param x object to get metamethod of +-- @param n name of metamethod to get +-- @return metamethod function or nil if no metamethod or not a +-- function +local function metamethod (x, n) + local _, m = pcall (function (x) + return getmetatable (x)[n] + end, + x) + if type (m) ~= "function" then + m = nil + end + return m +end + + +--- Identity function. +-- @param ... +-- @return the arguments passed to the function +local function id (...) + return ... +end + + +--- Partially apply a function. +-- @param f function to apply partially +-- @param ... arguments to bind +-- @return function with ai already bound +local function bind (f, ...) + local fix = {...} + return function (...) + return f (unpack (list.concat (fix, {...}))) + end +end + + +--- Curry a function. +-- @param f function to curry +-- @param n number of arguments +-- @return curried version of f +local function curry (f, n) + if n <= 1 then + return f + else + return function (x) + return curry (bind (f, x), n - 1) + end + end +end + + +--- Compose functions. +-- @param f1...fn functions to compose +-- @return composition of f1 ... fn +local function compose (...) + local arg = {...} + local fns, n = arg, #arg + return function (...) + local arg = {...} + for i = n, 1, -1 do + arg = {fns[i] (unpack (arg))} + end + return unpack (arg) + end +end + + +--- Memoize a function, by wrapping it in a functable. +-- @param fn function that returns a single result +-- @return memoized function +local function memoize (fn) + return setmetatable ({}, { + __call = function (self, ...) + local k = tostring ({...}) + local v = self[k] + if v == nil then + v = fn (...) + self[k] = v + end + return v + end + }) +end + + +--- Evaluate a string. +-- @param s string +-- @return value of string +local function eval (s) + return loadstring ("return " .. s)() +end + + +--- Collect the results of an iterator. +-- @param i iterator +-- @return results of running the iterator on its arguments +local function collect (i, ...) + local t = {} + for e in i (...) do + table.insert (t, e) + end + return t +end + + +--- Map a function over an iterator. +-- @param f function +-- @param i iterator +-- @return result table +local function map (f, i, ...) + local t = {} + for e in i (...) do + local r = f (e) + if r then + table.insert (t, r) + end + end + return t +end + + +--- Filter an iterator with a predicate. +-- @param p predicate +-- @param i iterator +-- @return result table containing elements e for which p (e) +local function filter (p, i, ...) + local t = {} + for e in i (...) do + if p (e) then + table.insert (t, e) + end + end + return t +end + + +--- Fold a binary function into an iterator. +-- @param f function +-- @param d initial first argument +-- @param i iterator +-- @return result +local function fold (f, d, i, ...) + local r = d + for e in i (...) do + r = f (r, e) + end + return r +end + +--- @export +functional = { + bind = bind, + collect = collect, + compose = compose, + curry = curry, + eval = eval, + filter = filter, + fold = fold, + id = id, + map = map, + memoize = memoize, + metamethod = metamethod, +} + +--- Functional forms of infix operators. +-- Defined here so that other modules can write to it. +-- @table op +-- @field [] dereference table index +-- @field + addition +-- @field - subtraction +-- @field * multiplication +-- @field / division +-- @field and logical and +-- @field or logical or +-- @field not logical not +-- @field == equality +-- @field ~= inequality +functional.op = { + ["[]"] = function (t, s) return t[s] end, + ["+"] = function (a, b) return a + b end, + ["-"] = function (a, b) return a - b end, + ["*"] = function (a, b) return a * b end, + ["/"] = function (a, b) return a / b end, + ["and"] = function (a, b) return a and b end, + ["or"] = function (a, b) return a or b end, + ["not"] = function (a) return not a end, + ["=="] = function (a, b) return a == b end, + ["~="] = function (a, b) return a ~= b end, +} + +return functional diff --git a/std/getopt.lua b/lib/std/getopt.lua similarity index 63% rename from std/getopt.lua rename to lib/std/getopt.lua index 5db8487..f57fb10 100644 --- a/std/getopt.lua +++ b/lib/std/getopt.lua @@ -1,47 +1,51 @@ ---- Simplified getopt, based on Svenne Panne's Haskell GetOpt.
    +--- Simplified getopt, based on Svenne Panne's Haskell GetOpt. +-- -- Usage: ---
      ---
    • prog = {< --- name = , --- [usage = ,] --- [options = { --- {{[, ...]}, , [ [, ]]}, --- ... --- },] --- [banner = ,] --- [purpose = ,] --- [notes = ] --- }
    • ---
    • The type of option argument is one of Req(uired), --- Opt(ional)
    • ---
    • The varis a descriptive name for the option argument.
    • ---
    • getopt.processArgs (prog)
    • ---
    • Options take a single dash, but may have a double dash.
    • ---
    • Arguments may be given as -opt=arg or -opt arg.
    • ---
    • If an option taking an argument is given multiple times, only the --- last value is returned; missing arguments are returned as 1.
    • ---
    --- getOpt, usageInfo and usage can be called directly (see +-- +-- prog = {< +-- name = , +-- [usage = ,] +-- [options = { +-- {{[, ...]}, , [ [, ]]}, +-- ... +-- },] +-- [banner = ,] +-- [purpose = ,] +-- [notes = ] +-- } +-- +-- * The `type` of option argument is one of `Req`(uired), +-- `Opt`(ional) +-- * The `var`is a descriptive name for the option argument. +-- * `getopt.processargs (prog)` +-- * Options take a single dash, but may have a double dash. +-- * Arguments may be given as `-opt=arg` or `-opt arg`. +-- * If an option taking an argument is given multiple times, only the +-- last value is returned; missing arguments are returned as 1. +-- +-- getOpt, usageinfo and usage can be called directly (see -- below, and the example at the end). Set _DEBUG.std to a non-nil -- value to run the example. ---
      ---
    • TODO: Wrap all messages; do all wrapping in processArgs, not --- usageInfo; use sdoc-like library (see string.format todos).
    • ---
    • TODO: Don't require name to be repeated in banner.
    • ---
    • TODO: Store version separately (construct banner?).
    • ---
    +-- +-- @todo Wrap all messages; do all wrapping in processargs, not +-- usageinfo; use sdoc-like library (see string.format todos). +-- @todo Don't require name to be repeated in banner. +-- @todo Store version separately (construct banner?). +-- +-- @module std.getopt -require "std.base" -local io = require "std.io_ext" -local list = require "std.list" +local io = require "std.io" +local List = require "std.list" local Object = require "std.object" -local string = require "std.string_ext" -local table = require "std.table_ext" +local string = require "std.string" +local table = require "std.table" local M = { opt = {}, } +local argtype = { Opt = true, Req = true } + --- Perform argument processing -- @param argIn list of command-line args @@ -50,12 +54,12 @@ local M = { -- @return table of remaining non-options -- @return table of option key-value list pairs -- @return table of error messages -local function getOpt (argIn, options, stop_at_nonopt) +local function getopt (argIn, options, stop_at_nonopt) local noProcess = nil local argOut, optOut, errors = {[0] = argIn[0]}, {}, {} -- get an argument for option opt local function getArg (o, opt, arg, oldarg) - if o.type == nil then + if not argtype[o.type] then if arg ~= nil then table.insert (errors, "option `" .. opt .. "' doesn't take an argument") end @@ -107,25 +111,25 @@ end -- Object that defines a single Option entry. local Option = Object {_init = {"name", "desc", "type", "var"}} ---- Options table constructor: adds lookup tables for the option names +--- Options table constructor: adds lookup tables for the option names. local function makeOptions (t) local options, name = {}, {} local function appendOpt (v, nodupes) local dupe = false v = Option (v) - for s in list.elems (v.name) do + for s in List.elems (v.name) do if name[s] then dupe = true end name[s] = v end if not dupe or nodupes ~= true then - if dupe then warn ("duplicate option '%s'", s) end - for s in list.elems (v.name) do name[s] = v end - options = list.concat (options, {v}) + if dupe then io.warn ("duplicate option '%s'", s) end + for s in List.elems (v.name) do name[s] = v end + options = List.concat (options, {v}) end end - for v in list.elems (t or {}) do + for v in List.elems (t or {}) do appendOpt (v) end -- Unless they were supplied already, add version and help options @@ -137,12 +141,12 @@ local function makeOptions (t) end ---- Produce usage info for the given options +--- Produce usage info for the given options. -- @param header header string -- @param optDesc option descriptors -- @param pageWidth width to format to [78] -- @return formatted string -local function usageInfo (header, optDesc, pageWidth) +local function usageinfo (header, optDesc, pageWidth) pageWidth = pageWidth or 78 -- Format the usage info for a single option -- @param opt the option table @@ -153,15 +157,15 @@ local function usageInfo (header, optDesc, pageWidth) return (#o > 1 and "--" or "-") .. o end local function fmtArg () - if opt.type == nil then - return "" - elseif opt.type == "Req" then + if opt.type == "Req" then return "=" .. opt.var - else + elseif opt.type == "Opt" then return "[=" .. opt.var .. "]" + else + return "" end end - local textName = list.reverse (list.map (fmtName, opt.name)) + local textName = List.reverse (List.map (opt.name, fmtName)) textName[#textName] = textName[#textName] .. fmtArg () local indent = "" if #opt.name == 1 and #opt.name[1] > 1 then @@ -171,7 +175,7 @@ local function usageInfo (header, optDesc, pageWidth) opt.desc} end local function sameLen (xs) - local n = math.max (unpack (list.map (string.len, xs))) + local n = math.max (unpack (List.map (xs, string.len))) for i, v in pairs (xs) do xs[i] = string.sub (v .. string.rep (" ", n), 1, n) end @@ -187,14 +191,14 @@ local function usageInfo (header, optDesc, pageWidth) end local optText = "" if #optDesc > 0 then - local cols = list.transpose (list.map (fmtOpt, optDesc)) + local cols = List.transpose (List.map (optDesc, fmtOpt)) local width cols[1], width = sameLen (cols[1]) - cols[2] = list.map (wrapper (pageWidth, width + 4), cols[2]) + cols[2] = List.map (cols[2], wrapper (pageWidth, width + 4)) optText = "\n\n" .. - table.concat (list.mapWith (paste, - list.transpose ({sameLen (cols[1]), - cols[2]})), + table.concat (List.map_with (List.transpose ({sameLen (cols[1]), + cols[2]}), + paste), "\n") end return header .. optText @@ -213,7 +217,7 @@ local function usage (prog) purpose = "\n\n" .. prog.purpose end if prog.description then - for para in list.elems (string.split (prog.description, "\n")) do + for para in List.elems (string.split (prog.description, "\n")) do description = description .. "\n\n" .. string.wrap (para) end end @@ -226,7 +230,7 @@ local function usage (prog) end end local header = usage .. purpose .. description - io.writelines (usageInfo (header, prog.options) .. notes) + io.writelines (usageinfo (header, prog.options) .. notes) end @@ -240,19 +244,18 @@ end ---- Simple getOpt wrapper. --- If the caller didn't supply their own already, --- adds --version/-V and --- --help/-h options automatically; --- stops program if there was an error, or if --help or --- --version was used. +--- Simple getopt wrapper. +-- If the caller didn't supply their own already, adds `--version`/`-V` +-- and `--help`/`-h` options automatically; +-- stops program if there was an error, or if `--help` or `--version` was +-- used. -- @param prog table of named parameters --- @param ... extra arguments for getOpt -local function processArgs (prog, ...) +-- @param ... extra arguments for getopt +local function processargs (prog, ...) local totArgs = #_G.arg local errors prog.options = makeOptions (prog.options) - _G.arg, M.opt, errors = getOpt (_G.arg, prog.options, ...) + _G.arg, M.opt, errors = getopt (_G.arg, prog.options, ...) local opt = M.opt if (opt.version or opt.help) and prog.banner then io.writelines (prog.banner) @@ -261,8 +264,8 @@ local function processArgs (prog, ...) local name = prog.name prog.name = nil if #errors > 0 then - warn (name .. ": " .. table.concat (errors, "\n")) - warn (name .. ": Try '" .. (arg[0] or name) .. " --help' for more help") + io.warn (name .. ": " .. table.concat (errors, "\n")) + io.warn (name .. ": Try '" .. (arg[0] or name) .. " --help' for more help") end if #errors > 0 then error () @@ -278,10 +281,19 @@ local function processArgs (prog, ...) end --- Public interface -return table.merge (M, { - getOpt = getOpt, - processArgs = processArgs, +--- @export +local Getopt = { + getopt = getopt, + processargs = processargs, usage = usage, - usageInfo = usageInfo, + usageinfo = usageinfo, +} + +-- camelCase compatibility. +Getopt = table.merge (Getopt, { + getOpt = getopt, + processArgs = processargs, + usageInfo = usageinfo, }) + +return table.merge (M, Getopt) diff --git a/std/io_ext.lua b/lib/std/io.lua similarity index 64% rename from std/io_ext.lua rename to lib/std/io.lua index ff85d75..d72883d 100644 --- a/std/io_ext.lua +++ b/lib/std/io.lua @@ -1,11 +1,15 @@ ---- Additions to the io module +--[[-- + Additions to the io module. + @module std.io +]] -local list = require "std.list" -local package = require "std.package_ext" +local package = require "std.package" +local string = require "std.string" +local tree = require "std.tree" -- Get an input file handle. --- @param h file handle or name (default: io.input ()) +-- @param h file handle or name (default: `io.input ()`) -- @return file handle, or nil on error local function input_handle (h) if h == nil then @@ -17,7 +21,7 @@ local function input_handle (h) end --- Slurp a file handle. --- @param h file handle or name (default: io.input ()) +-- @param h file handle or name (default: `io.input ()`) -- @return contents of file or handle, or nil if error local function slurp (h) h = input_handle (h) @@ -29,7 +33,7 @@ local function slurp (h) end --- Read a file or file handle into a list of lines. --- @param h file handle or name (default: io.input ()); +-- @param h file handle or name (default: `io.input ()`); -- if h is a handle, the file is closed after reading -- @return list of lines local function readlines (h) @@ -43,20 +47,20 @@ local function readlines (h) end --- Write values adding a newline after each. --- @param h file handle (default: io.output () +-- @param h file handle (default: `io.output ()` -- @param ... values to write (as for write) local function writelines (h, ...) if io.type (h) ~= "file" then io.write (h, "\n") h = io.output () end - for v in list.ileaves ({...}) do + for v in tree.ileaves ({...}) do h:write (v, "\n") end end --- Split a directory path into components. --- Empty components are retained: the root directory becomes {"", ""}. +-- Empty components are retained: the root directory becomes `{"", ""}`. -- @param path path -- @return list of path components local function splitdir (path) @@ -85,11 +89,11 @@ local function shell (c) end --- Process files specified on the command-line. --- If no files given, process io.stdin; in list of files, --- - means io.stdin. ---
    FIXME: Make the file list an argument to the function. +-- If no files given, process `io.stdin`; in list of files, +-- `-` means `io.stdin`. +-- @todo Make the file list an argument to the function. -- @param f function to process files with, which is passed --- (name, arg_no) +-- `(name, arg_no)` local function process_files (f) -- N.B. "arg" below refers to the global array of command-line args if #arg == 0 then @@ -105,21 +109,49 @@ local function process_files (f) end end +--- Give warning with the name of program and file (if any). +-- @param ... arguments for format +local function warn (...) + if prog.name then + io.stderr:write (prog.name .. ":") + end + if prog.file then + io.stderr:write (prog.file .. ":") + end + if prog.line then + io.stderr:write (tostring (prog.line) .. ":") + end + if prog.name or prog.file or prog.line then + io.stderr:write (" ") + end + writelines (io.stderr, string.format (...)) +end +--- Die with error. +-- @param ... arguments for format +local function die (...) + warn (...) + error () +end + + +--- @export local M = { catdir = catdir, catfile = catfile, + die = die, process_files = process_files, readlines = readlines, shell = shell, slurp = slurp, splitdir = splitdir, + warn = warn, writelines = writelines, - - -- camelCase compatibility, - processFiles = process_files, } +-- camelCase compatibility. +M.processFiles = process_files + for k, v in pairs (io) do M[k] = M[k] or v end diff --git a/lib/std/list.lua b/lib/std/list.lua new file mode 100644 index 0000000..5cb0ea8 --- /dev/null +++ b/lib/std/list.lua @@ -0,0 +1,436 @@ +--[[-- + Tables as lists. + + Every list is also an object, and thus inherits all of the `std.object` + methods, particularly use of object cloning for making new list objects. + + In addition to calling methods on list objects in OO style... + + local List = require "std.list" + local l = List {1, 2, 3} + for e in l:relems () do print (e) end + => 3 + => 2 + => 1 + + ...they can also be called as module functions with an explicit argument: + + local List = require "std.list" + local l = List {1, 2, 3} + for e in List.relems (l) do print (e) end + => 3 + => 2 + => 1 + + @classmod std.list +]] + +local base = require "std.base" +local func = require "std.functional" +local Object = require "std.object" + + +--- Compare two lists element-by-element, from left-to-right. +-- +-- if a_list:compare (another_list) == 0 then print "same" end +-- @function compare +-- @tparam table l another list +-- @return -1 if `self` is less than `l`, 0 if they are the same, and 1 +-- if `self` is greater than `l` +local compare = base.compare + + +--- An iterator over the elements of a list. +-- @function elems +-- @treturn function iterator function which returns successive elements of `self` +-- @treturn table *list* +-- @return `true` +local elems = base.elems + + +local List -- list prototype object forward declaration + + +--- Append an item to a list. +-- @param x item +-- @treturn std.list new list containing `{self[1], ..., self[#self], x}` +local function append (self, x) + return List (base.append (self, x)) +end + + +--- Concatenate arguments into a list. +-- @param ... tuple of lists +-- @treturn std.list new list containing +-- `{self[1], ..., self[#self], l\_1[1], ..., l\_1[#l\_1], ..., l\_n[1], ..., l\_n[#l\_n]}` +local function concat (self, ...) + return List (base.concat (self, ...)) +end + + +--- An iterator over the elements of a list, in reverse. +-- @treturn function iterator function which returns precessive elements of the `self` +-- @treturn std.list `self` +-- @return `true` +local function relems (self) + local n = #self + 1 + return function (self) + n = n - 1 + if n > 0 then + return self[n] + end + end, + self, true +end + + +--- Map a function over a list. +-- @tparam function f map function +-- @treturn std.list new list containing `{f (self[1]), ..., f (self[#self])}` +local function map (self, f) + return List (func.map (f, elems, self)) +end + + +--- Map a function over a list of lists. +-- @tparam table ls a list of lists +-- @tparam function f map function +-- @treturn std.list new list `{f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))}` +local function map_with (ls, f) + return List (func.map (func.compose (f, unpack), elems, ls)) +end + + +--- Filter a list according to a predicate. +-- @tparam function p predicate function, of one argument returning a boolean +-- @treturn std.list new list containing elements `e` of `self` for which `p (e)` is true +local function filter (self, p) + return List (func.filter (p, elems, self)) +end + + +--- Return a sub-range of a list. +-- (The equivalent of `string.sub` on strings; negative list indices +-- count from the end of the list.) +-- @tparam number from start of range (default: 1) +-- @tparam number to end of range (default: `#self`) +-- @treturn std.list new list containing `{self[from], ..., self[to]}` +local function sub (self, from, to) + local r = List {} + local len = #self + from = from or 1 + to = to or len + if from < 0 then + from = from + len + 1 + end + if to < 0 then + to = to + len + 1 + end + for i = from, to do + table.insert (r, self[i]) + end + return r +end + + +--- Return a list with its first element removed. +-- @treturn std.list new list containing `{self[2], ..., self[#self]}` +local function tail (self) + return sub (self, 2) +end + + +--- Fold a binary function through a list left associatively. +-- @tparam function f binary function +-- @param e element to place in left-most position +-- @return result +local function foldl (self, f, e) + return func.fold (f, e, elems, self) +end + + +--- Fold a binary function through a list right associatively. +-- @tparam function f binary function +-- @param e element to place in right-most position +-- @return result +local function foldr (self, f, e) + return List (func.fold (function (x, y) return f (y, x) end, + e, relems, self)) +end + + +--- Prepend an item to a list. +-- @param x item +-- @treturn std.list new list containing `{x, unpack (self)}` +local function cons (self, x) + return List {x, unpack (self)} +end + + +--- Repeat a list. +-- @tparam number n number of times to repeat +-- @treturn std.list `n` copies of `self` appended together +local function rep (self, n) + local r = List {} + for i = 1, n do + r = concat (r, self) + end + return r +end + + +--- Reverse a list. +-- @treturn std.list new list containing `{self[#self], ..., self[1]}` +local function reverse (self) + local r = List {} + for i = #self, 1, -1 do + table.insert (r, self[i]) + end + return r +end + + +--- Transpose a list of lists. +-- This function in Lua is equivalent to zip and unzip in more strongly +-- typed languages. +-- @tparam table ls +-- `{{ls<1,1>, ..., ls<1,c>}, ..., {ls<r,1>, ..., ls<r,c>}}` +-- @treturn std.list new list containing +-- `{{ls<1,1>, ..., ls<r,1>}, ..., {ls<1,c>, ..., ls<r,c>}}` +local function transpose (ls) + local rs, len = List {}, #ls + for i = 1, math.max (unpack (map (ls, function (l) return #l end))) do + rs[i] = List {} + for j = 1, len do + rs[i][j] = ls[j][i] + end + end + return rs +end + + +--- Zip a list of lists together with a function. +-- @tparam table ls list of lists +-- @tparam function f function +-- @treturn std.list a new list containing +-- `{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N])` +-- where `N = max {map (function (l) return #l end, ls)}` +local function zip_with (ls, f) + return map_with (transpose (ls), f) +end + + +--- Project a list of fields from a list of tables. +-- @param f field to project +-- @treturn std.list list of `f` fields +local function project (self, f) + return map (self, function (t) return t[f] end) +end + + +--- Turn a table into a list of pairs. +-- @todo Find a better name. +-- @tparam table t a table `{i1=v1, ..., in=vn}` +-- @treturn std.list a new list containing `{{i1, v1}, ..., {in, vn}}` +-- @see depair +local function enpair (t) + local ls = List {} + for i, v in pairs (t) do + table.insert (ls, List {i, v}) + end + return ls +end + + +--- Turn a list of pairs into a table. +-- @todo Find a better name. +-- @tparam table ls list of lists `{{i1, v1}, ..., {in, vn}}` +-- @treturn table a new list containing table `{i1=v1, ..., in=vn}` +-- @see enpair +local function depair (ls) + local t = {} + for v in elems (ls) do + t[v[1]] = v[2] + end + return t +end + + +--- Flatten a list. +-- @treturn std.list flattened list +local function flatten (self) + local r = List {} + for v in base.ileaves (self) do + table.insert (r, v) + end + return r +end + + +--- Shape a list according to a list of dimensions. +-- +-- Dimensions are given outermost first and items from the original +-- list are distributed breadth first; there may be one 0 indicating +-- an indefinite number. Hence, `{0}` is a flat list, +-- `{1}` is a singleton, `{2, 0}` is a list of +-- two lists, and `{0, 2}` is a list of pairs. +-- +-- Algorithm: turn shape into all positive numbers, calculating +-- the zero if necessary and making sure there is at most one; +-- recursively walk the shape, adding empty tables until the bottom +-- level is reached at which point add table items instead, using a +-- counter to walk the flattened original list. +-- +-- @todo Use ileaves instead of flatten (needs a while instead of a +-- for in fill function) +-- @tparam table s `{d1, ..., dn}` +-- @return reshaped list +local function shape (self, s) + self = flatten (self) + -- Check the shape and calculate the size of the zero, if any + local size = 1 + local zero + for i, v in ipairs (s) do + if v == 0 then + if zero then -- bad shape: two zeros + return nil + else + zero = i + end + else + size = size * v + end + end + if zero then + s[zero] = math.ceil (#self / size) + end + local function fill (i, d) + if d > #s then + return self[i], i + 1 + else + local r = List {} + for j = 1, s[d] do + local e + e, i = fill (i, d + 1) + table.insert (r, e) + end + return r, i + end + end + return (fill (1, 1)) +end + + +--- Make an index of a list of tables on a given field +-- @tparam table l list of tables `{t1, ..., tn}` +-- @param f field +-- @treturn std.list index `{t1[f]=1, ..., tn[f]=n}` +local function index_key (l, f) + local r = List {} + for i, v in ipairs (l) do + local k = v[f] + if k then + r[k] = i + end + end + return r +end + + +--- Copy a list of tables, indexed on a given field +-- @tparam table l list of tables `{i1=t1, ..., in=tn}` +-- @param f field whose value should be used as index +-- @treturn std.list index `{t1[f]=t1, ..., tn[f]=tn}` +local function index_value (l, f) + local r = List {} + for i, v in ipairs (l) do + local k = v[f] + if k then + r[k] = v + end + end + return r +end + + +--- @export +local metamethods = { + append = append, + compare = compare, + concat = concat, + cons = cons, + depair = depair, + elems = elems, + enpair = enpair, + filter = filter, + flatten = flatten, + foldl = foldl, + foldr = foldr, + index_key = index_key, + index_value = index_value, + map = map, + map_with = map_with, + project = project, + relems = relems, + rep = rep, + reverse = reverse, + shape = shape, + sub = sub, + tail = tail, + transpose = transpose, + zip_with = zip_with, +} + + +List = Object { + -- Derived object type. + _type = "List", + + ------ + -- Concatenate lists. + -- new = list .. table + -- @function __concat + -- @tparam std.list list a list + -- @tparam table table another list, hash part is ignored + -- @see concat + __concat = concat, + + ------ + -- Append element to list. + -- list = list + element + -- @function __add + -- @tparam std.list list a list + -- @param element element to append + -- @see append + __add = append, + + ------ + -- List order operator. + -- max = list1 > list2 and list1 or list2 + -- @tparam std.list list1 a list + -- @tparam std.list list2 another list + -- @see std.list:compare + __lt = function (list1, list2) return compare (list1, list2) < 0 end, + + ------ + -- List equality or order operator. + -- min = list1 <= list2 and list1 or list2 + -- @tparam std.list list1 a list + -- @tparam std.list list2 another list + -- @see std.list:compare + __le = function (list1, list2) return compare (list1, list2) <= 0 end, + + __index = base.merge (metamethods, { + -- camelCase compatibility. + indexKey = index_key, + indexValue = index_value, + mapWith = map_with, + zipWith = zip_with, + }), +} + + +-- Function forms of operators +func.op[".."] = concat + +return List diff --git a/std/math_ext.lua b/lib/std/math.lua similarity index 66% rename from std/math_ext.lua rename to lib/std/math.lua index 3a3f9ae..a50859f 100644 --- a/std/math_ext.lua +++ b/lib/std/math.lua @@ -1,11 +1,16 @@ ---- Additions to the math module. +--[[-- + Additions to the math module. + @module std.math +]] local _floor = math.floor ---- Extend math.floor to take the number of decimal places. + +--- Extend `math.floor` to take the number of decimal places. +-- @function floor -- @param n number -- @param p number of decimal places to truncate to (default: 0) --- @return n truncated to p decimal places +-- @return `n` truncated to `p` decimal places local function floor (n, p) if p and p ~= 0 then local e = 10 ^ p @@ -15,17 +20,19 @@ local function floor (n, p) end end + --- Round a number to a given number of decimal places +-- @function round -- @param n number -- @param p number of decimal places to round to (default: 0) --- @return n rounded to p decimal places +-- @return `n` rounded to `p` decimal places local function round (n, p) local e = 10 ^ (p or 0) return _floor (n * e + 0.5) / e end -local M = { +local Math = { floor = floor, round = round, @@ -34,7 +41,7 @@ local M = { } for k, v in pairs (math) do - M[k] = M[k] or v + Math[k] = Math[k] or v end -return M +return Math diff --git a/lib/std/modules.lua b/lib/std/modules.lua new file mode 100644 index 0000000..2beaf18 --- /dev/null +++ b/lib/std/modules.lua @@ -0,0 +1,19 @@ +-- Set of imported modules. + +return { + -- true => module symbols injected into equivalent core namespace + -- with `require 'std'`: + debug = true, + debug_init = false, + functional = false, + getopt = false, + io = true, + list = false, + math = true, + package = true, + set = false, + strbuf = false, + string = true, + table = true, + tree = false, +} diff --git a/lib/std/object.lua b/lib/std/object.lua new file mode 100644 index 0000000..355f2b7 --- /dev/null +++ b/lib/std/object.lua @@ -0,0 +1,153 @@ +--[[-- + Prototype-based objects. + + This module creates the root prototype object from which every other + object is descended. There are no classes as such, rather new objects + are created by cloning an existing object, and then changing or adding + to the clone. Further objects can then be made by cloning the changed + object, and so on. + + Objects are cloned by simply calling an existing object, which then + serves as a prototype from which the new object is copied. + + All valid objects contain a field `_init`, which determines the syntax + required to execute the cloning process: + + 1. `_init` can be a list of keys; then the unnamed `init_1` through + `init_m` values from the argument table are assigned to the + corresponding keys in `new_object`; + + new_object = proto_object { + init_1, ..., init_m; + field_1 = value_1, + ... + field_n = value_n, + } + + 2. Or it can be a function, in which the arguments passed to the + prototype during cloning are simply handed to the `_init` function: + + new_object = proto_object (arg, ...) + + Objects, then, are essentially tables of `field\_n = value\_n` pairs: + + > o = Object { + >> field_1 = "value_1", + >> method_1 = function (self) return self.field_1 end, + >> } + > = o.field_1 + value_1 + > o.field_2 = 2 + > function o:method_2 (n) return self.field_2 + n end + > = o:method_2 (2) + 4 + + Normally `new_object` automatically shares a metatable with + `proto_object`. However, field names beginning with "_" are *private*, + and moved into the object metatable during cloning. So, adding new + private fields to an object during cloning will result in a new + metatable for `new_object` that also contains a copy of all the entries + in the `proto_object` metatable. + + Note that Object methods are stored in the `\_\_index` field of their + metatable, and so cannot also use `\_\_index` to lookup references with + square brackets. See @{std.container} objects if you want to do that. + + @classmod std.object +]] + + +local Container = require "std.container" +local metamethod = (require "std.functional").metamethod + + +--- Root object. +-- +-- Changing the values of these fields in a new object will change the +-- corresponding behaviour. +-- @table std.object +-- @string[opt="Object"] _type type of Object, returned by @{prototype} +-- @tfield table|function _init a table of field names, or +-- initialisation function, used by @{clone} +-- @tfield nil|table _functions a table of module functions not copied +-- by @{std.object.__call} +return Container { + _type = "Object", + + -- No need for explicit module functions here, because calls to, e.g. + -- `Object.prototype` will automatically fall back metamethods in + -- `\_\_index`. + + __index = { + --- Clone this Object. + -- @function clone + -- @tparam std.object o an object + -- @param ... a list of arguments if `o._init` is a function, or a + -- single table if `o._init` is a table. + -- @treturn std.object a clone of `o` + -- @see __call + clone = metamethod (Container, "__call"), + + + --- Type of an object, or primitive. + -- + -- It's conventional to organise similar objects according to a + -- string valued `_type` field, which can then be queried using this + -- function. + -- + -- Stack = Object { + -- _type = "Stack", + -- + -- __tostring = function (self) ... end, + -- + -- __index = { + -- push = function (self) ... end, + -- pop = function (self) ... end, + -- }, + -- } + -- stack = Stack {} + -- + -- stack:prototype () --> "Stack" + -- + -- @function prototype + -- @param x anything + -- @treturn string type of `x` + prototype = Container.prototype, + + + -- Backwards compatibility: + type = Container.prototype, + }, + + + --- Return a @{clone} of this object, and its metatable. + -- + -- Private fields are stored in the metatable. + -- @function __call + -- @param ... arguments for `\_init` + -- @treturn std.object a clone of the this object. + -- @see clone + + + --- Return a string representation of this object. + -- + -- First the object type, and then between { and } a list of the + -- array part of the object table (without numeric keys) followed + -- by the remaining key-value pairs. + -- + -- This function doesn't recurse explicity, but relies upon suitable + -- `__tostring` metamethods in field values. + -- @function __tostring + -- @treturn string stringified container representation + -- @see tostring + + + --- Return a shallow copy of non-private object fields. + -- + -- Used by @{clone} to get the base contents of the new object. Can + -- be overridden in other objects for greater control of which fields + -- are considered non-private. + -- @function __totable + -- @treturn table a shallow copy of non-private object fields + -- @see std.table.totable +} diff --git a/std/package_ext.lua b/lib/std/package.lua similarity index 61% rename from std/package_ext.lua rename to lib/std/package.lua index 7f32eaa..ab791b5 100644 --- a/std/package_ext.lua +++ b/lib/std/package.lua @@ -1,16 +1,18 @@ --- Additions to the package module. +--[[-- + Additions to the package module. + @module std.package +]] local M = {} ---- Make named constants for package.config (undocumented --- in 5.1; see luaconf.h for C equivalents). --- @class table --- @name package +--- Make named constants for `package.config` +-- (undocumented in 5.1; see luaconf.h for C equivalents). +-- @table package -- @field dirsep directory separator -- @field pathsep path separator -- @field path_mark string that marks substitution points in a path template -- @field execdir (Windows only) replaced by the executable's directory in a path --- @field igmark Mark to ignore all before it when building luaopen_ function name. +-- @field igmark Mark to ignore all before it when building `luaopen_` function name. M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark = string.match (package.config, "^([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)") diff --git a/lib/std/set.lua b/lib/std/set.lua new file mode 100644 index 0000000..2eb032c --- /dev/null +++ b/lib/std/set.lua @@ -0,0 +1,287 @@ +--[[-- + Set container. + + Derived from @{std.container}, and inherits Container's metamethods. + + Note that Functions listed below are available only available from the + Set prototype returned by requiring this module, because Container + objects cannot have object methods. + + @classmod std.set + @see std.container + ]] + +local base = require "std.base" +local Container = require "std.container" +local prototype = (require "std.object").prototype + + +local Set -- forward declaration + +-- Primitive methods (know about representation) +-- The representation is a table whose tags are the elements, and +-- whose values are true. + + +--- Say whether an element is in a set. +-- @tparam set set a set +-- @param e element +-- @return `true` if `e` is in `set`, otherwise `false` +-- otherwise +local function member (set, e) + return rawget (set, e) == true +end + + +--- Insert an element into a set. +-- @tparam set set a set +-- @param e element +-- @return the modified set +local function insert (set, e) + rawset (set, e, true) + return set +end + + +--- Delete an element from a set. +-- @tparam set set a set +-- @param e element +-- @return the modified set +local function delete (set, e) + rawset (set, e, nil) + return set +end + + +--- Iterator for sets. +-- @tparam set set a set +-- @todo Make the iterator return only the key +local function elems (set) + return pairs (set) +end + + +-- High level methods (representation-independent) + +local difference, symmetric_difference, intersection, union, subset, equal + + +--- Find the difference of two sets. +-- @tparam set set1 a set +-- @tparam table|set set2 another set, or table +-- @return `set1` with elements of s removed +function difference (set1, set2) + if prototype (set2) == "table" then + set2 = Set (set2) + end + local t = Set {} + for e in elems (set1) do + if not member (set2, e) then + insert (t, e) + end + end + return t +end + + +--- Find the symmetric difference of two sets. +-- @tparam set set1 a set +-- @tparam table|set set2 another set, or table +-- @return elements of `set1` and `set2` that are in `set1` or `set2` but not both +function symmetric_difference (set1, set2) + if prototype (set2) == "table" then + set2 = Set (set2) + end + return difference (union (set1, set2), intersection (set2, set1)) +end + + +--- Find the intersection of two sets. +-- @tparam set set1 a set +-- @tparam table|set set2 another set, or table +-- @return set intersection of `set1` and `set2` +function intersection (set1, set2) + if prototype (set2) == "table" then + set2 = Set (set2) + end + local t = Set {} + for e in elems (set1) do + if member (set2, e) then + insert (t, e) + end + end + return t +end + + +--- Find the union of two sets. +-- @tparam set set1 a set +-- @tparam table|set set2 another set, or table +-- @return set union of `set1` and `set2` +function union (set1, set2) + if prototype (set2) == "table" then + set2 = Set (set2) + end + local t = Set {} + for e in elems (set1) do + insert (t, e) + end + for e in elems (set2) do + insert (t, e) + end + return t +end + + +--- Find whether one set is a subset of another. +-- @tparam set set1 a set +-- @tparam table|set set2 another set, or table +-- @return `true` if `set1` is a subset of `set2`, `false` otherwise +function subset (set1, set2) + if prototype (set2) == "table" then + set2 = Set (set2) + end + for e in elems (set1) do + if not member (set2, e) then + return false + end + end + return true +end + + +--- Find whether one set is a proper subset of another. +-- @tparam set set1 a set +-- @tparam table|set set2 another set, or table +-- @return `true` if `set1` is a proper subset of `set2`, `false` otherwise +function proper_subset (set1, set2) + if prototype (set2) == "table" then + t = Set (set2) + end + return subset (set1, set2) and not subset (set2, set1) +end + + +--- Find whether two sets are equal. +-- @tparam set set1 a set +-- @tparam table|set set2 another set, or table +-- @return `true` if `set1` and `set2` are equal, `false` otherwise +function equal (set1, set2) + return subset (set1, set2) and subset (set2, set1) +end + +--- Set prototype object. +-- @table std.set +-- @string[opt="Set"] _type type of Set, returned by +-- @{std.object.prototype} +-- @tfield table|function _init a table of field names, or +-- initialisation function, see @{std.object.__call} +-- @tfield nil|table _functions a table of module functions not copied +-- by @{std.object.__call} +Set = Container { + _type = "Set", + + _init = function (self, t) + for e in base.elems (t) do + insert (self, e) + end + return self + end, + + + --- Union operator. + -- union = set + table + -- @function __add + -- @static + -- @tparam set set set + -- @tparam table|set table another set or table + -- @treturn set union + -- @see union + __add = union, + + + --- Difference operator. + -- difference = set - table + -- @function __sub + -- @static + -- @tparam set set set + -- @tparam table|set table another set or table + -- @treturn set difference + -- @see difference + __sub = difference, + + + --- Intersection operator. + -- intersection = set * table + -- @function __mul + -- @static + -- @tparam set set set + -- @tparam table|set table another set or table + -- @treturn set intersection + -- @see intersection + __mul = intersection, + + + --- Symmetric difference operator. + -- symmetric_difference = set / table + -- @function __div + -- @static + -- @tparam set set set + -- @tparam table|set table another set or table + -- @treturn set symmetric_difference + -- @see symmetric_difference + __div = symmetric_difference, + + + --- Subset operator. + -- set = set <= table + -- @function __le + -- @static + -- @tparam set set set + -- @tparam table|set table another set or table + -- @treturn set subset + -- @see subset + __le = subset, + + + --- Proper subset operator. + -- proper_subset = set < table + -- @function __lt + -- @static + -- @tparam set set set + -- @tparam table|set table another set or table + -- @treturn set proper_subset + -- @see proper_subset + __lt = proper_subset, + + + -- Set to table conversion. + -- @treturn table table representation of a set. + -- @see std.table.totable + __totable = function (self) + local t = {} + for e in elems (self) do + table.insert (t, e) + end + table.sort (t) + return t + end, + + + --- @export + _functions = { + delete = delete, + difference = difference, + elems = elems, + equal = equal, + insert = insert, + intersection = intersection, + member = member, + proper_subset = proper_subset, + subset = subset, + symmetric_difference = symmetric_difference, + union = union, + }, +} + +return Set diff --git a/lib/std/strbuf.lua b/lib/std/strbuf.lua new file mode 100644 index 0000000..77ed1bb --- /dev/null +++ b/lib/std/strbuf.lua @@ -0,0 +1,56 @@ +--[[-- + String buffers. + @classmod std.strbuf +]] + + +local Object = require "std.object" + + +--- Add a string to a buffer. +-- @tparam string s string to add +-- @treturn std.strbuf modified buffer +local function concat (self, s) + table.insert (self, s) + return self +end + + +--- Convert a buffer to a string. +-- @treturn string stringified `self` +local function tostring (self) + return table.concat (self) +end + + +return Object { + -- Derived object type. + _type = "StrBuf", + + ------ + -- Support concatenation of StrBuf objects. + -- buffer = buffer .. str + -- @function __concat + -- @tparam std.strbuf buffer StrBuf object + -- @tparam string str a string or string-like object + -- @treturn std.strbuf modified `buffer` + -- @see concat + __concat = concat, + + + ------ + -- Support fast conversion to Lua string. + -- str = tostring (buffer) + -- @function __tostring + -- @tparam std.strbuf buffer Strbuf object + -- @treturn string concatenation of buffer contents + -- @see tostring + __tostring = tostring, + + + --- @export + __index = { + concat = concat, + tostring = tostring, + }, +} diff --git a/std/strict.lua b/lib/std/strict.lua similarity index 61% rename from std/strict.lua rename to lib/std/strict.lua index 1eb22c7..5c06551 100644 --- a/std/strict.lua +++ b/lib/std/strict.lua @@ -1,10 +1,13 @@ ---- Checks uses of undeclared global variables. --- All global variables must be 'declared' through a regular --- assignment (even assigning nil will do) in a top-level --- chunk before being used anywhere or assigned to inside a function. --- From Lua distribution (etc/strict.lua). --- @class module --- @name strict +--[[-- + Checks uses of undeclared global variables. + + All global variables must be 'declared' through a regular + assignment (even assigning `nil` will do) in a top-level + chunk before being used anywhere or assigned to inside a function. + From Lua distribution (`etc/strict.lua`). + + @module std.strict +]] local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget @@ -21,6 +24,8 @@ local function what () return d and d.what or "C" end +--- Detect assignment to undeclared global. +-- @function __newindex mt.__newindex = function (t, n, v) if not mt.__declared[n] then local w = what () @@ -32,6 +37,8 @@ mt.__newindex = function (t, n, v) rawset (t, n, v) end +--- Detect derefrence of undeclared global. +-- @function __index mt.__index = function (t, n) if not mt.__declared[n] and what () ~= "C" then error ("variable '" .. n .. "' is not declared", 2) diff --git a/std/string_ext.lua b/lib/std/string.lua similarity index 81% rename from std/string_ext.lua rename to lib/std/string.lua index fc37a29..c4008e8 100644 --- a/std/string_ext.lua +++ b/lib/std/string.lua @@ -1,18 +1,26 @@ ---- Additions to the string module --- TODO: Pretty printing (use in getopt); see source for details. +--[[-- + Additions to the string module. + @module std.string +]] +local func = require "std.functional" local list = require "std.list" -local strbuf = require "std.strbuf" -local table = require "std.table_ext" +local StrBuf = require "std.strbuf" +local table = require "std.table" + +local _assert = _G.assert +local _format = string.format +local _tostring = _G.tostring +local old__index = getmetatable ("").__index local M = {} --- Extend to work better with one argument. -- If only one argument is passed, no formatting is attempted. -- @param f format +-- @param arg1 first argument to format -- @param ... arguments to format -- @return formatted string -local _format = string.format local function format (f, arg1, ...) if arg1 == nil then return f @@ -26,13 +34,12 @@ end -- @param f format -- @param ... arguments to format -- @return value -local _assert = assert local function assert (v, f, ...) if not v then if f == nil then f = "" end - error (format (f, ...)) + error (format (f, ...), 2) end return v end @@ -54,12 +61,12 @@ local function tfind (s, p, init, plain) return pack (p.find (s, p, init, plain)) end ---- Do multiple finds on a string. +--- Do multiple `find`s on a string. -- @param s target string -- @param p pattern -- @param init start position (default: 1) -- @param plain inhibit magic characters (default: nil) --- @return list of {from, to; capt = {captures}} +-- @return list of `{from, to; capt = {captures}}` local function finds (s, p, init, plain) init = init or 1 local l = {} @@ -75,7 +82,7 @@ local function finds (s, p, init, plain) end --- Split a string at a given separator. --- FIXME: Consider Perl and Python versions. +-- @todo Consider Perl and Python versions. -- @param s string to split -- @param sep separator pattern -- @return list of strings @@ -92,12 +99,12 @@ local function split (s, sep) return l end ---- Require a module with a particular version +--- Require a module with a particular version. -- @param module module to require -- @param min lowest acceptable version (default: any) -- @param too_big lowest version that is too big (default: none) --- @pattern pattern to match version in module.version or --- module.VERSION (default: ".*[%.%d]+" +-- @param pattern to match version in `module.version` or +-- `module.VERSION` (default: `".*[%.%d]+"` local function require_version (module, min, too_big, pattern) local function version_to_list (v) return list.new (split (v, "%.")) @@ -154,20 +161,29 @@ end -- @param elem element renderer -- @param pair pair renderer -- @param sep separator renderer +-- @param roots accumulates table references to detect recursion -- @return string representation local function render (x, open, close, elem, pair, sep, roots) local function stop_roots (x) return roots[x] or render (x, open, close, elem, pair, sep, table.clone (roots)) end roots = roots or {} - if type (x) ~= "table" or metamethod (x, "__tostring") then + if type (x) ~= "table" or func.metamethod (x, "__tostring") then return elem (x) else - local s = strbuf.new () + local s = StrBuf {} s = s .. open (x) roots[x] = elem (x) + + -- create a sorted list of keys + local ord = {} + for k, _ in pairs (x) do table.insert (ord, k) end + table.sort (ord, function (a, b) return tostring (a) < tostring (b) end) + + -- render x elements in order local i, v = nil, nil - for j, w in pairs (x) do + for _, j in ipairs (ord) do + local w = x[j] s = s .. sep (x, i, v, j, w) .. pair (x, j, w, stop_roots (j), stop_roots (w)) i, v = j, w end @@ -177,28 +193,22 @@ local function render (x, open, close, elem, pair, sep, roots) end --- --- @class function --- @name render_OpenRenderer +-- @function render_OpenRenderer -- @param t table -- @return open table string --- --- @class function --- @name render_CloseRenderer +-- @function render_CloseRenderer -- @param t table -- @return close table string --- --- @class function --- @name render_ElementRenderer +-- @function render_ElementRenderer -- @param e element -- @return element string ---- --- @class function --- @name render_PairRenderer --- N.B. the function should not try to render i and v, or treat --- them recursively. +--- NB. the function should not try to render i and v, or treat them recursively. +-- @function render_PairRenderer -- @param t table -- @param i index -- @param v value @@ -207,8 +217,7 @@ end -- @return element string --- --- @class function --- @name render_SeparatorRenderer +-- @function render_SeparatorRenderer -- @param t table -- @param i preceding index (nil on first call) -- @param v preceding value (nil on first call) @@ -216,12 +225,10 @@ end -- @param w following value (nil on last call) -- @return separator string ---- Extend tostring to work better on tables. --- @class function --- @name tostring +--- Extend `tostring` to work better on tables. +-- @function tostring -- @param x object to convert to string -- @return string representation -local _tostring = tostring local function tostring (x) return render (x, function () return "{" end, @@ -265,15 +272,21 @@ local function prettytostring (t, indent, spacing) end end, function (x, i, v, is, vs) - local s = spacing .. "[" - if type (i) == "table" then - s = s .. "\n" - end - s = s .. is - if type (i) == "table" then - s = s .. "\n" - end - s = s .. "] =" + local s = spacing + if type (i) ~= "string" or i:match "[^%w_]" then + s = s .. "[" + if type (i) == "table" then + s = s .. "\n" + end + s = s .. is + if type (i) == "table" then + s = s .. "\n" + end + s = s .. "]" + else + s = s .. i + end + s = s .. " =" if type (v) == "table" then s = s .. "\n" else @@ -294,7 +307,7 @@ end --- Convert a value to a string. -- The string can be passed to dostring to retrieve the value. ---
    TODO: Make it work for recursive tables. +-- @todo Make it work for recursive tables. -- @param x object to pickle -- @return string such that eval (s) is the same value as x local function pickle (x) @@ -323,9 +336,8 @@ end --- Give strings a subscription operator. -- @param s string -- @param i index --- @return string.sub (s, i, i) if i is a number, or +-- @return `string.sub (s, i, i)` if i is a number, or -- falls back to any previous metamethod (by default, string methods) -local old__index = getmetatable ("").__index getmetatable ("").__index = function (s, i) if type (i) == "number" then return s:sub (i, i) @@ -338,7 +350,7 @@ end --- Give strings an append metamethod. -- @param s string -- @param c character (1-character string) --- @return s .. c +-- @return `s .. c` getmetatable ("").__append = function (s, c) return s .. c end @@ -368,15 +380,14 @@ local function chomp (s) return (string.gsub (s, "\n$", "")) end ---- Escape a string to be used as a pattern +--- Escape a string to be used as a pattern. -- @param s string to process --- @return --- @param s_: processed string +-- @return processed string local function escape_pattern (s) - return (string.gsub (s, "(%W)", "%%%1")) + return (string.gsub (s, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")) end --- Escape a string to be used as a shell token. +--- Escape a string to be used as a shell token. -- Quotes spaces, parentheses, brackets, quotes, apostrophes and -- whitespace. -- @param s string to process @@ -408,7 +419,7 @@ end -- @param s string to justify -- @param w width to justify to (-ve means right-justify; +ve means -- left-justify) --- @param p string to pad with (default: " ") +-- @param p string to pad with (default: `" "`) -- @return justified string local function pad (s, w, p) p = string.rep (p or " ", math.abs (w)) @@ -432,7 +443,7 @@ local function wrap (s, w, ind, ind1) "the indents must be less than the line width") assert (type (s) == "string", "bad argument #1 to 'wrap' (string expected, got " .. type (s) .. ")") - local r = strbuf.new ():concat (string.rep (" ", ind1)) + local r = StrBuf { string.rep (" ", ind1) } local i, lstart, len = 1, ind1, #s while i <= #s do local j = i + w - lstart @@ -477,7 +488,7 @@ end --- Remove leading matter from a string. -- @param s string --- @param r leading pattern (default: "%s+") +-- @param r leading pattern (default: `"%s+"`) -- @return string without leading r local function ltrim (s, r) r = r or "%s+" @@ -486,7 +497,7 @@ end --- Remove trailing matter from a string. -- @param s string --- @param r trailing pattern (default: "%s+") +-- @param r trailing pattern (default: `"%s+"`) -- @return string without trailing r local function rtrim (s, r) r = r or "%s+" @@ -495,39 +506,41 @@ end --- Remove leading and trailing matter from a string. -- @param s string --- @param r leading/trailing pattern (default: "%s+") +-- @param r leading/trailing pattern (default: `"%s+"`) -- @return string without leading/trailing r local function trim (s, r) return rtrim (ltrim (s, r), r) end -for k, v in pairs { - __index = old__index, - caps = caps, - chomp = chomp, - escape_pattern = escape_pattern, - escape_shell = escape_shell, - finds = finds, - format = format, - ltrim = ltrim, - numbertosi = numbertosi, - ordinal_suffix = ordinal_suffix, - pad = pad, - rtrim = rtrim, - split = split, - tfind = tfind, - trim = trim, - wrap = wrap, - - -- APIs that used to be in "base". +--- @export +local String = { + __index = old__index, assert = assert, + caps = caps, + chomp = chomp, + escape_pattern = escape_pattern, + escape_shell = escape_shell, + finds = finds, + format = format, + ltrim = ltrim, + numbertosi = numbertosi, + ordinal_suffix = ordinal_suffix, + pad = pad, pickle = pickle, prettytostring = prettytostring, render = render, require_version = require_version, + rtrim = rtrim, + split = split, + tfind = tfind, tostring = tostring, + trim = trim, + wrap = wrap, +} +-- Merge non-@export functions: +for k,v in pairs (table.merge (String, { -- camelCase compatibility: escapePattern = escape_pattern, escapeShell = escape_shell, @@ -536,7 +549,7 @@ for k, v in pairs { -- Core Lua function implementations. _format = _format, _tostring = _tostring, -} do +})) do M[k] = v end diff --git a/lib/std/table.lua b/lib/std/table.lua new file mode 100644 index 0000000..f4261b5 --- /dev/null +++ b/lib/std/table.lua @@ -0,0 +1,184 @@ +--[[-- + Extensions to the table module. + @module std.table +]] + +local base = require "std.base" +local func = require "std.functional" + + +--- Make a shallow copy of a table, including any metatable. +-- +-- To make deep copies, use @{std.tree.clone}. +-- @function clone +-- @tparam table t source table +-- @tparam boolean nometa if non-nil don't copy metatable +-- @return copy of *table* +local clone = base.clone + + +--- Clone a table, renaming some keys. +-- @function clone_rename +-- @tparam table t source table +-- @tparam table map table `{old_key=new_key, ...}` +-- @return copy of *table* +local clone_rename = base.clone_rename + + +--- Destructively merge another table's fields into *table*. +-- @function merge +-- @tparam table t destination table +-- @tparam table u table with fields to merge +-- @return table `t` with fields from `u` merged in +local merge = base.merge + + +-- Preserve core table sort function. +local _sort = table.sort + +--- Make table.sort return its result. +-- @tparam table t unsorted table +-- @tparam function c comparator function +-- @return `t` with keys sorted accordind to `c` +local function sort (t, c) + _sort (t, c) + return t +end + + +--- Return whether table is empty. +-- @tparam table t any table +-- @return `true` if `t` is empty, otherwise `false` +local function empty (t) + return not next (t) +end + + +--- Turn a tuple into a list. +-- @param ... tuple +-- @return list +local function pack (...) + return {...} +end + + +--- Find the number of elements in a table. +-- @tparam table t any table +-- @return number of non-nil values in `t` +local function size (t) + local n = 0 + for _ in pairs (t) do + n = n + 1 + end + return n +end + + +--- Make the list of keys in table. +-- @tparam table t any table +-- @treturn table list of keys +local function keys (t) + local l = {} + for k, _ in pairs (t) do + table.insert (l, k) + end + return l +end + + +--- Make the list of values of a table. +-- @tparam table t any table +-- @treturn table list of values +local function values (t) + local l = {} + for _, v in pairs (t) do + table.insert (l, v) + end + return l +end + + +--- Invert a table. +-- @tparam table t a table with `{k=v, ...}` +-- @treturn table inverted table `{v=k, ...}` +local function invert (t) + local i = {} + for k, v in pairs (t) do + i[v] = k + end + return i +end + + +--- An iterator like ipairs, but in reverse. +-- @tparam table t any table +-- @treturn function iterator function +-- @treturn table the table, `t` +-- @treturn number `#t + 1` +local function ripairs (t) + return function (t, n) + n = n - 1 + if n > 0 then + return n, t[n] + end + end, + t, #t + 1 +end + + +--- Turn an object into a table according to __totable metamethod. +-- @tparam std.object x object to turn into a table +-- @treturn table resulting table or `nil` +local function totable (x) + local m = func.metamethod (x, "__totable") + if m then + return m (x) + elseif type (x) == "table" then + return x + elseif type (x) == "string" then + local t = {} + x:gsub (".", function (c) t[#t + 1] = c end) + return t + else + return nil + end +end + + +--- Make a table with a default value for unset keys. +-- @param x default entry value (default: `nil`) +-- @tparam table t initial table (default: `{}`) +-- @treturn table table whose unset elements are x +local function new (x, t) + return setmetatable (t or {}, + {__index = function (t, i) + return x + end}) +end + + +--- @export +local Table = { + clone = clone, + clone_rename = clone_rename, + empty = empty, + invert = invert, + keys = keys, + merge = merge, + new = new, + pack = pack, + ripairs = ripairs, + size = size, + sort = sort, + totable = totable, + values = values, + + -- Core Lua table.sort function + _sort = _sort, +} + +for k, v in pairs (table) do + Table[k] = Table[k] or v +end + +return Table diff --git a/lib/std/tree.lua b/lib/std/tree.lua new file mode 100644 index 0000000..f1c2d28 --- /dev/null +++ b/lib/std/tree.lua @@ -0,0 +1,237 @@ +--[[-- + Tree container. + + Derived from @{std.container}, and inherits Container's metamethods. + + Note that Functions listed below are only available from the Tree + prototype return by requiring this module, because Container objects + cannot have object methods. + + @classmod std.tree + @see std.container +]] + +local base = require "std.base" +local Container = require "std.container" +local list = require "std.list" +local func = require "std.functional" + +local prototype = (require "std.object").prototype + +local Tree -- forward declaration + + +--- Tree iterator which returns just numbered leaves, in order. +-- @function ileaves +-- @static +-- @tparam tree|table tr tree or tree-like table +-- @treturn function iterator function +-- @treturn tree|table the tree `tr` +local ileaves = base.ileaves + + +--- Tree iterator which returns just leaves. +-- @function leaves +-- @static +-- @tparam tree|table tr tree or tree-like table +-- @treturn function iterator function +-- @treturn tree|table the tree, `tr` +local leaves = base.leaves + + +--- Make a deep copy of a tree, including any metatables. +-- +-- To make fast shallow copies, use @{std.table.clone}. +-- @tparam table|tree t table or tree to be cloned +-- @tparam boolean nometa if non-nil don't copy metatables +-- @treturn table|tree a deep copy of `t` +local function clone (t, nometa) + assert (type (t) == "table", + "bad argument #1 to 'clone' (table expected, got " .. type (t) .. ")") + local r = {} + if not nometa then + setmetatable (r, getmetatable (t)) + end + local d = {[t] = r} + local function copy (o, x) + for i, v in pairs (x) do + if type (v) == "table" then + if not d[v] then + d[v] = {} + if not nometa then + setmetatable (d[v], getmetatable (v)) + end + o[i] = copy (d[v], v) + else + o[i] = d[v] + end + else + o[i] = v + end + end + return o + end + return copy (r, t) +end + + +--- Tree iterator. +-- @tparam function it iterator function +-- @tparam tree|table tr tree or tree-like table +-- @treturn string type ("leaf", "branch" (pre-order) or "join" (post-order)) +-- @treturn table path to node ({i\_1...i\_k}) +-- @return node +local function _nodes (it, tr) + local p = {} + local function visit (n) + if type (n) == "table" then + coroutine.yield ("branch", p, n) + for i, v in it (n) do + table.insert (p, i) + visit (v) + table.remove (p) + end + coroutine.yield ("join", p, n) + else + coroutine.yield ("leaf", p, n) + end + end + return coroutine.wrap (visit), tr +end + + +--- Tree iterator over all nodes. +-- +-- The returned iterator function performs a depth-first traversal of +-- `tr`, and at each node it returns `{node-type, tree-path, tree-node}` +-- where `node-type` is `branch`, `join` or `leaf`; `tree-path` is a +-- list of keys used to reach this node, and `tree-node` is the current +-- node. +-- +-- Given a `tree` to represent: +-- +-- + root +-- +-- node1 +-- | +-- leaf1 +-- | '-- leaf2 +-- '-- leaf 3 +-- +-- tree = std.tree { std.tree { "leaf1", "leaf2"}, "leaf3" } +-- +-- A series of calls to `tree.nodes` will return: +-- +-- "branch", {}, {{"leaf1", "leaf2"}, "leaf3"} +-- "branch", {1}, {"leaf1", "leaf"2") +-- "leaf", {1,1}, "leaf1" +-- "leaf", {1,2}, "leaf2" +-- "join", {1}, {"leaf1", "leaf2"} +-- "leaf", {2}, "leaf3" +-- "join", {}, {{"leaf1", "leaf2"}, "leaf3"} +-- +-- Note that the `tree-path` reuses the same table on each iteration, so +-- you must `table.clone` a copy if you want to take a snap-shot of the +-- current state of the `tree-path` list before the next iteration +-- changes it. +-- @tparam tree|table tr tree or tree-like table to iterate over +-- @treturn function iterator function +-- @treturn tree|table the tree, `tr` +-- @see inodes +local function nodes (tr) + assert (type (tr) == "table", + "bad argument #1 to 'nodes' (table expected, got " .. type (tr) .. ")") + return _nodes (pairs, tr) +end + + +--- Tree iterator over numbered nodes, in order. +-- +-- The iterator function behaves like @{nodes}, but only traverses the +-- array part of the nodes of `tr`, ignoring any others. +-- @tparam tree|table tr tree to iterate over +-- @treturn function iterator function +-- @treturn tree|table the tree, `tr` +-- @see nodes +local function inodes (tr) + assert (type (tr) == "table", + "bad argument #1 to 'inodes' (table expected, got " .. type (tr) .. ")") + return _nodes (ipairs, tr) +end + + +--- Destructively deep-merge one tree into another. +-- @tparam tree|table t destination tree or table +-- @tparam tree|table u tree or table with nodes to merge +-- @treturn tree|table `t` with nodes from `u` merged in +-- @see std.table.merge +local function merge (t, u) + assert (type (t) == "table", + "bad argument #1 to 'merge' (table expected, got " .. type (t) .. ")") + assert (type (u) == "table", + "bad argument #2 to 'merge' (table expected, got " .. type (u) .. ")") + for ty, p, n in nodes (u) do + if ty == "leaf" then + t[p] = n + end + end + return t +end + + +--- Tree prototype object. +-- @table std.tree +-- @string[opt="Tree"] _type type of Tree, returned by +-- @{std.object.prototype} +-- @tfield[opt={}] table|function _init a table of field names, or +-- initialisation function, see @{std.object.__call} +-- @tfield nil|table _functions a table of module functions not copied +-- by @{std.object.__call} +Tree = Container { + -- Derived object type. + _type = "Tree", + + --- Tree `__index` metamethod. + -- @function __index + -- @param i non-table, or list of keys `{i\_1 ... i\_n}` + -- @return `self[i]...[i\_n]` if i is a table, or `self[i]` otherwise + -- @todo the following doesn't treat list keys correctly + -- e.g. self[{{1, 2}, {3, 4}}], maybe flatten first? + __index = function (self, i) + if type (i) == "table" and #i > 0 then + return list.foldl (i, func.op["[]"], self) + else + return rawget (self, i) + end + end, + + --- Tree `__newindex` metamethod. + -- + -- Sets `self[i\_1]...[i\_n] = v` if i is a table, or `self[i] = v` otherwise + -- @function __newindex + -- @param i non-table, or list of keys `{i\_1 ... i\_n}` + -- @param v value + __newindex = function (self, i, v) + if type (i) == "table" then + for n = 1, #i - 1 do + if prototype (self[i[n]]) ~= "Tree" then + rawset (self, i[n], Tree {}) + end + self = self[i[n]] + end + rawset (self, i[#i], v) + else + rawset (self, i, v) + end + end, + + --- @export + _functions = { + clone = clone, + ileaves = ileaves, + inodes = inodes, + leaves = leaves, + merge = merge, + nodes = nodes, + }, +} + +return Tree diff --git a/local.mk b/local.mk index 030de92..23c0ad0 100644 --- a/local.mk +++ b/local.mk @@ -1,10 +1,27 @@ # Local Make rules. +# +# Copyright (C) 2013-2014 Gary V. Vaughan +# Written by Gary V. Vaughan, 2013 +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + ## ------------ ## ## Environment. ## ## ------------ ## -std_path = $(abs_srcdir)/?.lua;$(abs_srcdir)/std/?.lua +std_path = $(abs_srcdir)/lib/?.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" @@ -12,19 +29,113 @@ LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" ## Bootstrap. ## ## ---------- ## -old_NEWS_hash = dfde3c0c6163db72d47538ad8711607c +old_NEWS_hash = 7ef01dfb840329db3d8db218bfe9d075 + +update_copyright_env = \ + UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ + UPDATE_COPYRIGHT_USE_INTERVALS=1 \ + UPDATE_COPYRIGHT_FORCE=1 ## ------------- ## ## Declarations. ## ## ------------- ## -filesdir = $(docdir)/files +classesdir = $(docdir)/classes modulesdir = $(docdir)/modules dist_doc_DATA = -dist_files_DATA = +dist_classes_DATA = dist_modules_DATA = -include std/std.mk include specs/specs.mk + + +## ------ ## +## Build. ## +## ------ ## + +dist_lua_DATA += \ + lib/std.lua \ + $(NOTHING_ELSE) + +luastddir = $(luadir)/std + +dist_luastd_DATA = \ + lib/std/base.lua \ + lib/std/container.lua \ + lib/std/debug.lua \ + lib/std/debug_init.lua \ + lib/std/functional.lua \ + lib/std/getopt.lua \ + lib/std/io.lua \ + lib/std/list.lua \ + lib/std/math.lua \ + lib/std/modules.lua \ + lib/std/object.lua \ + lib/std/package.lua \ + lib/std/set.lua \ + lib/std/strbuf.lua \ + lib/std/strict.lua \ + lib/std/string.lua \ + lib/std/table.lua \ + lib/std/tree.lua \ + $(NOTHING_ELSE) + +# In order to avoid regenerating std.lua at configure time, which +# causes the documentation to be rebuilt and hence requires users to +# have ldoc installed, put std/std.lua in as a Makefile dependency. +# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) +lib/std.lua: lib/std.lua.in + ./config.status --file=$@ + + +## Use a builtin rockspec build with root at $(srcdir)/lib +mkrockspecs_args = --module-dir $(srcdir)/lib + + +## ------------- ## +## Distribution. ## +## ------------- ## + +EXTRA_DIST += \ + doc/config.ld \ + lib/std.lua.in \ + $(NOTHING_ELSE) + + +## -------------- ## +## Documentation. ## +## -------------- ## + + +dist_doc_DATA += \ + $(srcdir)/doc/index.html \ + $(srcdir)/doc/ldoc.css + +dist_classes_DATA += \ + $(srcdir)/doc/classes/std.container.html \ + $(srcdir)/doc/classes/std.list.html \ + $(srcdir)/doc/classes/std.object.html \ + $(srcdir)/doc/classes/std.set.html \ + $(srcdir)/doc/classes/std.strbuf.html \ + $(srcdir)/doc/classes/std.tree.html \ + $(NOTHING_ELSE) + +dist_modules_DATA += \ + $(srcdir)/doc/modules/std.html \ + $(srcdir)/doc/modules/std.debug.html \ + $(srcdir)/doc/modules/std.functional.html \ + $(srcdir)/doc/modules/std.getopt.html \ + $(srcdir)/doc/modules/std.io.html \ + $(srcdir)/doc/modules/std.math.html \ + $(srcdir)/doc/modules/std.package.html \ + $(srcdir)/doc/modules/std.strict.html \ + $(srcdir)/doc/modules/std.string.html \ + $(srcdir)/doc/modules/std.table.html \ + $(NOTHING_ELSE) + +ldoc_DEPS = $(dist_lua_DATA) $(dist_luastd_DATA) + +$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(ldoc_DEPS) + cd $(srcdir) && $(LDOC) -c doc/config.ld . diff --git a/m4/ax_lua.m4 b/m4/ax_lua.m4 index c6f5974..f158253 100644 --- a/m4/ax_lua.m4 +++ b/m4/ax_lua.m4 @@ -468,7 +468,7 @@ AC_DEFUN([AX_LUA_HEADERS], done ]) - AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], + AS_IF([test "x$ac_cv_header_lua_h" = 'xyes' && test "x$cross_compiling" != 'xyes'], [ dnl Make a program to print LUA_VERSION defined in the header. dnl TODO This probably shouldn't be a runtime test. @@ -505,6 +505,9 @@ int main(int argc, char ** argv) [ AC_MSG_RESULT([no]) ax_header_version_match='no' ]) + ], + [ + ax_header_version_match='yes' ]) dnl Was LUA_INCLUDE specified? diff --git a/m4/slingshot.m4 b/m4/slingshot.m4 index 9e7acc6..541f8f5 100644 --- a/m4/slingshot.m4 +++ b/m4/slingshot.m4 @@ -1,6 +1,6 @@ dnl slingshot.m4 dnl -dnl Copyright (c) 2013 Free Software Foundation, Inc. +dnl Copyright (c) 2013-2014 Free Software Foundation, Inc. dnl Written by Gary V. Vaughan, 2013 dnl dnl This program is free software; you can redistribute it and/or modify @@ -20,32 +20,23 @@ dnl along with this program. If not, see . # -------------------------- # Generate .travis.yml, ensuring LUAROCKS are installed. AC_DEFUN([SS_CONFIG_TRAVIS], [ - # Luadoc only works with Lua 5.1, so must be installed with care. - LUADOC_FALSE=# - AC_SUBST(LUADOC_FALSE) - - SPECL_MIN=${SPECL_MIN-"5"} - AC_SUBST([SPECL_MIN]) - - # luarocks requires a separate invocation per luarock, and lyaml # is required by all slingshot clients for mkrockspecs. EXTRA_ROCKS=- for _ss_rock in lyaml $1; do - # Enable associated .travis sections for special rocks. - case $_ss_rock in - luadoc) - LUADOC_FALSE=- - continue - ;; - esac - case $EXTRA_ROCKS in *" $_ss_rock;"*) ;; # ignore duplicates *) - EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" + test "x$PACKAGE_NAME" != "x$_ss_rock" \ + && EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" ;; esac done + + # Avoid empty travis commands. + test "x$EXTRA_ROCKS" != "x-" || EXTRA_ROCKS='# No extra rocks needed here;' + AC_SUBST([EXTRA_ROCKS]) - AC_CONFIG_FILES([.travis.yml:travis.yml.in]) + AC_CONFIG_FILES([.travis.yml:travis.yml.in], [ + # Remove trailing blanks so as not to trip sc_trailing_blank in syntax check + sed 's| *$||' < .travis.yml > ss_tmp && mv ss_tmp .travis.yml; rm -f ss_tmp]) ]) diff --git a/specs/container_spec.yaml b/specs/container_spec.yaml new file mode 100644 index 0000000..34a8ef0 --- /dev/null +++ b/specs/container_spec.yaml @@ -0,0 +1,108 @@ +before: + Container = require "std.container" + prototype = (require "std.object").prototype + +specify Container: +- describe construction: + - context from Container prototype: + - before: + things = Container {"foo", "bar", baz="quux"} + - it constructs a new container: + expect (things).should_not_be (Container) + expect (type (things)).should_be "table" + expect (prototype (things)).should_be "Container" + - it reuses the container metatable: + o, p = things {"o"}, things {"p"} + expect (getmetatable (o)).should_be (getmetatable (p)) + - it sets container fields from arguments: + o = Container {"foo", "bar", baz="quux"} + expect (o).should_equal (things) + - it serves as a prototype for new instances: + o = things {} + expect (prototype (o)).should_be "Container" + expect (o).should_not_be (things) + expect (o).should_equal (things) + expect (getmetatable (o)).should_be (getmetatable (things)) + - it separates '_' prefixed fields: + expect (Container {foo="bar", _baz="quux"}). + should_equal (Container {foo="bar"}) + - it puts '_' prefixed fields in a new metatable: + things = Container {foo="bar", _baz="quux"} + expect (getmetatable (things)).should_not_be (getmetatable (Container)) + expect (getmetatable (things)._baz).should_be "quux" + - context with module functions: + - before: + fold = (require "std.functional").fold + functions = { + count = function (bag) + return fold (function (r, k) return r + bag[k] end, 0, pairs, bag) + end, + } + Bag = Container { + _type = "Bag", _functions = functions, count = functions.count, + } + - it does not propagate _functions: + things = Bag {} + expect (things.count).should_be (nil) + - it does not provide object methods: | + things = Bag {} + expect (things:count ()).should_error "attempt to call method 'count'" + - it does retain module functions: + things = Bag { apples = 1, oranges = 3 } + expect (Bag.count (things)).should_be (4) + - it does allow elements named after module functions: + things = Bag { count = 1337 } + expect (Bag.count (things)).should_be (1337) + + +- describe field access: + - before: + things = Container {"foo", "bar", baz="quux"} + - context with bracket notation: + - it provides access to existing contents: + expect (things[1]).should_be "foo" + expect (things["baz"]).should_be "quux" + - it assigns new contents: + things["new"] = "value" + expect (things["new"]).should_be "value" + - context with dot notation: + - it provides access to existing contents: + expect (things.baz).should_be "quux" + - it assigns new contents: + things.new = "value" + expect (things.new).should_be "value" + + +- describe stringification: + - before: + things = Container {_type = "Derived", "one", "two", "three"} + - it returns a string: + expect (type (tostring (things))).should_be "string" + - it contains the type: + expect (tostring (Container {})).should_contain "Container" + expect (tostring (things)).should_contain (prototype (things)) + - it contains the ordered array part elements: + expect (tostring (things)).should_contain "one, two, three" + - it contains the ordered dictionary part elements: + expect (tostring (Container {one = true, two = true, three = true})). + should_contain "one=true, three=true, two=true" + expect (tostring (things {one = true, two = true, three = true})). + should_contain "one=true, three=true, two=true" + - it contains a ';' separator only when container has array and dictionary parts: + expect (tostring (things)).should_not_contain ";" + expect (tostring (Container {one = true, two = true, three = true})). + should_not_contain ";" + expect (tostring (things {one = true, two = true, three = true})). + should_contain ";" + + +- describe tablification: + - before: + totable = (require "std.table").totable + Derived = Container {_type = "Derived", "one", "two", three = true} + - it returns a table: + expect (prototype (totable (Derived))).should_be "table" + - it contains all non-hidden fields of container: + expect (totable (Derived)).should_contain.all_of {"one", "two", "three"} + - it does not contain any hidden fields of container: + expect (totable (Derived)).should_equal {"one", "two", three = true} diff --git a/specs/debug_ext_spec.yaml b/specs/debug_spec.yaml similarity index 97% rename from specs/debug_ext_spec.yaml rename to specs/debug_spec.yaml index e83eb9b..6ba7acc 100644 --- a/specs/debug_ext_spec.yaml +++ b/specs/debug_spec.yaml @@ -1,6 +1,6 @@ -specify debug_ext: +specify debug: - before: | - M = require "std.debug_ext" + M = require "std.debug" extends = debug enhancements = {} diff --git a/specs/io_ext_spec.yaml b/specs/io_spec.yaml similarity index 90% rename from specs/io_ext_spec.yaml rename to specs/io_spec.yaml index aa5f37d..758060a 100644 --- a/specs/io_ext_spec.yaml +++ b/specs/io_spec.yaml @@ -1,11 +1,12 @@ -specify io_ext: +specify io: - before: | - M = require "std.io_ext" + M = require "std.io" extends = io enhancements = {} - extensions = { "catdir", "catfile", "process_files", "readlines", - "shell", "slurp", "splitdir", "writelines", + extensions = { "catdir", "catfile", "die", "process_files", + "readlines", "shell", "slurp", "splitdir", "warn", + "writelines", -- camelCase compatibility: "processFiles" } diff --git a/specs/list_spec.yaml b/specs/list_spec.yaml new file mode 100644 index 0000000..a80749a --- /dev/null +++ b/specs/list_spec.yaml @@ -0,0 +1,441 @@ +before: + require "spec_helper" + Object = require "std.object" + List = require "std.list" + l = List {"foo", "bar", "baz"} + + +specify List: +- describe construction: + - context from List clone method: + - it constructs a new list: + l = List:clone {} + expect (l).should_not_be (List) + expect (Object.type (l)).should_be "List" + - it reuses the List metatable: + l, m = List:clone {"l"}, List:clone {"m"} + expect (getmetatable (l)).should_be (getmetatable (m)) + - it initialises list with constructor parameters: + m = List:clone {"foo", "bar", "baz"} + expect (m).should_equal (l) + - it serves as a prototype for new instances: + obj = l:clone {} + expect (Object.type (obj)).should_be "List" + expect (obj).should_equal (l) + expect (getmetatable (obj)).should_be (getmetatable (l)) + + # List {args} is just syntactic sugar for List:clone {args} + - context from List object prototype: + - it constructs a new list: + l = List {} + expect (l).should_not_be (List) + expect (Object.type (l)).should_be "List" + - it reuses the List metatable: + l, m = List {"l"}, List {"m"} + expect (getmetatable (l)).should_be (getmetatable (m)) + - it initialises list with constructor parameters: + m = List {"foo", "bar", "baz"} + expect (m).should_equal (l) + - it serves as a prototype for new instances: + obj = l {} + expect (Object.type (obj)).should_be "List" + expect (obj).should_equal (l) + expect (getmetatable (obj)).should_be (getmetatable (l)) + + +- describe metatable propagation: + - it reuses the metatable for List constructed objects: + obj = List {"foo", "bar"} + expect (getmetatable (obj)).should_be (getmetatable (l)) + + +- describe append: + - context when called as a list object method: + - it returns a list object: + l = l:append ("quux") + expect (Object.type (l)).should_be "List" + - it works for an empty list: + l = List {} + expect (l:append ("quux")).should_equal (List {"quux"}) + - it appends an item to a list: + expect (l:append ("quux")). + should_equal (List {"foo", "bar", "baz", "quux"}) + - context when called as a list metamethod: + - it returns a list object: + l = l + "quux" + expect (Object.type (l)).should_be "List" + - it works for an empty list: + l = List {} + expect (l + "quux").should_equal (List {"quux"}) + - it appends an item to a list: + expect (l + "quux"). + should_equal (List {"foo", "bar", "baz", "quux"}) + + +- describe compare: + - before: + a, b = List {"foo", "bar"}, List {"foo", "baz"} + - context when called as a list object method: + - it returns -1 when the first list is less than the second: | + expect (a:compare {"foo", "baz"}).should_be (-1) + expect (a:compare (List {"foo", "baz"})).should_be (-1) + - it returns -1 when the second list has additional elements: | + b = List {"foo"} + expect (b:compare {"foo", "bar"}).should_be (-1) + expect (List {"foo"}:compare (List {"foo", "bar"})).should_be (-1) + - it returns 0 when two lists are the same: | + expect (a:compare {"foo", "bar"}).should_be (0) + expect (a:compare (List {"foo", "bar"})).should_be (0) + - it returns +1 when the first list is greater than the second: | + expect (a:compare {"baz", "quux"}).should_be (1) + expect (a:compare (List {"baz", "quux"})).should_be (1) + - it returns +1 when the first list has additional elements: | + expect (a:compare {"foo"}).should_be (1) + expect (a:compare (List {"foo"})).should_be (1) + - context when called as a '<' list metamethod: + - it succeeds when the first list is less than the second: + expect (a < b).should_be (true) + - it fails when the first list is not less than the second: + expect (a < a).should_be (false) + expect (b < a).should_be (false) + - context when called as a '>' list metamethod: + - it succeeds when the first list is greater than the second: + expect (b > a).should_be (true) + - it fails when the first list is not greater than the second: + expect (b > b).should_be (false) + expect (a > b).should_be (false) + - context when called as a '<=' list metamethod: + - it succeeds when the first list is less than or equal to the second: + expect (a <= b).should_be (true) + expect (a <= a).should_be (true) + - it fails when the first list is not less than or equal to the second: + expect (b <= a).should_be (false) + - context when called as a '>=' list metamethod: + - it succeeds when the first list is greater than or equal to the second: + expect (b >= a).should_be (true) + expect (b >= b).should_be (true) + - it fails when the first list is not greater than or equal to the second: + expect (a >= b).should_be (false) + + +- describe concat: + - before: l = List {"foo", "bar"} + + - context when called as a list object method: + - it returns a list object: + l = l:concat (List {"baz"}) + expect (Object.type (l)).should_be "List" + - it works for an empty list: + l = List {} + expect (l:concat (List {"baz"})).should_equal (List {"baz"}) + - it concatenates lists: + expect (l:concat (List {"baz", "quux"})). + should_equal (List {"foo", "bar", "baz", "quux"}) + expect (l:concat (List {"baz"}, List {"quux"})). + should_equal (List {"foo", "bar", "baz", "quux"}) + - context whne called as a list metamethod: + - it returns a list object: + l = l .. List {"baz"} + expect (Object.type (l)).should_be "List" + - it works for an empty list: + l = List {} + expect (l .. List {"baz"}).should_equal (List {"baz"}) + - it concatenates lists: + expect (l .. List {"baz", "quux"}). + should_equal (List {"foo", "bar", "baz", "quux"}) + expect (l .. List {"baz"} .. List {"quux"}). + should_equal (List {"foo", "bar", "baz", "quux"}) + + +- describe cons: + - context when called as a list object method: + - it returns a list object: + l = l:cons "quux" + expect (Object.type (l)).should_be "List" + - it works for empty lists: + l = List {} + expect (l:cons "quux").should_equal (List {"quux"}) + - it prepends an item to a list: + expect (l:cons "quux"). + should_equal (List {"quux", "foo", "bar", "baz"}) + + +- describe depair: + - before: + t = {"first", "second", third = 4} + l = List.enpair (t) + + - it diagnoses an argument that is not a list of lists: + - context when called as a list object method: + - it returns a primitive table: + expect (Object.type (l:depair ())).should_be "table" + - it works with an empty list: + l = List {} + expect (l:depair ()).should_equal {} + - it is the inverse of enpair: + expect (l:depair ()).should_equal (t) + + +- describe elems: + - it is an iterator over list members: + t = {} + for e in List.elems (l) do table.insert (t, e) end + expect (t).should_equal {"foo", "bar", "baz"} + - it works for an empty list: + t = {} + for e in List.elems (List {}) do table.insert (t, e) end + expect (t).should_equal {} + - it can be called from the list module: + t = {} + for e in List.elems (l) do table.insert (t, e) end + expect (t).should_equal {"foo", "bar", "baz"} + - it can be called as a list object method: + t = {} + for e in l:elems () do table.insert (t, e) end + expect (t).should_equal {"foo", "bar", "baz"} + + +- describe enpair: + - before: + t = {"first", "second", third = 4} + + - it diagnoses a missing argument: + - it diagnoses a non-table argument: + - it returns a list object: + expect (Object.type (List.enpair (t))).should_be "List" + - it works for an empty table: + expect (List.enpair {}).should_equal (List {}) + - it turns a table into a list of pairs: + expect (List.enpair (t)). + should_equal (List {List {1, "first"}, List {2, "second"}, List {"third", 4}}) + + +- describe filter: + - before: + l = List {"foo", "bar", "baz", "quux"} + p = function (e) return (e:match "a" ~= nil) end + + - context when called as a list object method: + - it returns a list object: + m = l:filter (p) + expect (Object.type (m)).should_be "List" + - it works for an empty list: + l = List {} + expect (l:filter (p)).should_equal (List {}) + - it filters a list according to a predicate: + expect (l:filter (p)).should_equal (List {"bar", "baz"}) + + +- describe flatten: + - before: + l = List {List {List {"one"}}, "two", List {List {"three"}, "four"}} + + - context when called as a list object method: + - it returns a list object: + m = List.flatten (l) + expect (Object.type (m)).should_be "List" + - it works for an empty list: + l = List {} + expect (l:flatten ()).should_equal (List {}) + - it flattens a list: + expect (l:flatten ()). + should_equal (List {"one", "two", "three", "four"}) + + +- describe foldl: + - before: + op = (require "std.functional").op + l = List {1, 10, 100} + + - context when called as a list object method: + - it works with an empty list: + l = List {} + expect (l:foldl (op["+"], 10000)).should_be (10000) + - it folds a binary function through a list: + expect (l:foldl (op["+"], 10000)).should_be (10111) + + +- describe foldr: + - before: + op = (require "std.functional").op + l = List {1, 10, 100} + + - context when called as a list object method: + - it works with an empty list: + l = List {} + expect (l:foldl (op["/"], 1)).should_be (1) + - it folds a binary function through a list: + expect (l:foldl (op["/"], 10000)).should_be (10) + + +- describe index_key: + + +- describe index_value: + + +- describe map: + - before: + l = List {1, 2, 3, 4, 5} + f = function (n) return n * n end + + - context when called as a list object method: + - it returns a list object: + m = l:map (f) + expect (Object.type (m)).should_be "List" + - it works for an empty list: + l = List {} + expect (l:map (f)).should_equal (List {}) + - it creates a new list: + o = l + m = l:map (f) + expect (l).should_equal (o) + expect (m).should_not_equal (o) + expect (l).should_equal (List {1, 2, 3, 4, 5}) + - it maps a function over a list: + expect (l:map (f)).should_equal (List {1, 4, 9, 16, 25}) + + +- describe map_with: + - before: + l = List {List {1, 2, 3}, List {4, 5}} + f = function (...) return select ("#", ...) end + + - it diagnoses an argument that is not a list of lists: + - context when called as a list object method: + - it returns a list object: + m = l:map_with (f) + expect (Object.type (m)).should_be "List" + - it works for an empty list: + l = List {} + expect (l:map_with (f)).should_equal (List {}) + - it creates a new list: + o = l + m = l:map_with (f) + expect (l).should_equal (o) + expect (m).should_not_equal (o) + expect (l).should_equal (List {List {1, 2, 3}, List {4, 5}}) + - it maps a function over a list: + expect (l:map_with (f)).should_equal (List {3, 2}) + + +- describe project: + - before: + l = List { + {first = false, second = true, third = true}, + {first = 1, second = 2, third = 3}, + {first = "1st", second = "2nd", third = "3rd"}, + } + + - it diagnoses an argument that is not a list of tables: + - context when called as a list object method: + - it returns a list object: + p = l:project ("third") + expect (Object.type (p)).should_be "List" + - it works with an empty list: + l = List {} + expect (l:project ("third")).should_equal (List {}) + - it projects a list of fields from a list of tables: + expect (l:project ("third")). + should_equal (List {true, 3, "3rd"}) + - it projects fields with a falsey value correctly: | + pending "see issue #34" + expect (l:project ("first")). + should_equal (List {false, 1, "1st"}) + + +- describe relems: + - it is a reverse iterator over list members: + t = {} + for e in List.relems (l) do table.insert (t, e) end + expect (t).should_equal {"baz", "bar", "foo"} + - it works for an empty list: + t = {} + for e in List.relems (List {}) do table.insert (t, e) end + expect (t).should_equal {} + - it can be called from the list module: + t = {} + for e in List.relems (l) do table.insert (t, e) end + expect (t).should_equal {"baz", "bar", "foo"} + - it can be called as a list object method: + t = {} + for e in l:relems () do table.insert (t, e) end + expect (t).should_equal {"baz", "bar", "foo"} + + +- describe rep: + - before: l = List {"foo", "bar"} + + - context when called as a list object method: + - it returns a list object: + expect (Object.type (l:rep (3))).should_be "List" + - it works for an empty list: + l = List {} + expect (l:rep (99)).should_equal (List {}) + - it repeats the contents of a list: + expect (l:rep (3)). + should_equal (List {"foo", "bar", "foo", "bar", "foo", "bar"}) + + +- describe reverse: + - before: l = List {"foo", "bar", "baz", "quux"} + + - context when called as a list object method: + - it returns a list object: + expect (Object.type (l:reverse ())).should_be "List" + - it works for an empty list: + l = List {} + expect (l:reverse ()).should_equal (List {}) + - it makes a new reversed list: + m = l + expect (l:reverse ()). + should_equal (List {"quux", "baz", "bar", "foo"}) + expect (l).should_equal (List {"foo", "bar", "baz", "quux"}) + expect (l).should_be (m) + + +- describe shape: + + +- describe sub: + - before: l = List {1, 2, 3, 4, 5, 6, 7} + + - context when called as a list object method: + - it returns a list object: | + expect (Object.type (l:sub (1, 1))).should_be "List" + - it makes a list from a subrange of another list: | + expect (l:sub (2, 5)).should_equal (List {2, 3, 4, 5}) + - it truncates the result if 'to' argument is too large: | + expect (l:sub (5, 10)).should_equal (List {5, 6, 7}) + - it defaults 'to' to the end of the list: | + expect (l:sub (5)).should_equal (List {5, 6, 7}) + - it defaults 'from' to the beginning of the list: | + expect (l:sub ()).should_equal (l) + - it returns an empty list when 'from' is greater than 'to': | + expect (l:sub (2, 1)).should_equal (List {}) + - it counts from the end of the list for a negative 'from' argument: | + expect (l:sub (-3)).should_equal (List {5, 6, 7}) + - it counts from the end of the list for a negative 'to' argument: | + expect (l:sub (-5, -2)).should_equal (List {3, 4, 5, 6}) + + +- describe tail: + - before: l = List {1, 2, 3, 4, 5, 6, 7} + + - context when called as a list object method: + - it returns a list object: | + expect (Object.type (l:tail ())).should_be "List" + - it makes a new list with the first element removed: | + expect (l:tail ()).should_equal (List {2, 3, 4, 5, 6, 7}) + - it works for an empty list: | + l = List {} + expect (l:tail ()).should_equal (List {}) + - it returns an empty list when passed a list with one element: | + l = List {1} + expect (l:tail ()).should_equal (List {}) + + +- describe transpose: + + +- describe zip_with: diff --git a/specs/math_ext_spec.yaml b/specs/math_spec.yaml similarity index 97% rename from specs/math_ext_spec.yaml rename to specs/math_spec.yaml index eba26ee..d812d4a 100644 --- a/specs/math_ext_spec.yaml +++ b/specs/math_spec.yaml @@ -1,6 +1,6 @@ -specify math_ext: +specify math: - before: | - M = require "std.math_ext" + M = require "std.math" extends = math enhancements = { "floor" } diff --git a/specs/object_spec.yaml b/specs/object_spec.yaml new file mode 100644 index 0000000..2a07af2 --- /dev/null +++ b/specs/object_spec.yaml @@ -0,0 +1,301 @@ +before: + Object = require "std.object" + obj = Object {"foo", "bar", baz="quux"} + prototype = Object.prototype + +specify Object: +- describe construction: + - context from Object clone method: + - it constructs a new object: + obj = Object:clone {} + expect (obj).should_not_be (Object) + expect (type (obj)).should_be "table" + expect (prototype (obj)).should_be "Object" + - it reuses the Object metatable: + o = obj:clone {"o"} + p = o:clone {"p"} + expect (p).should_not_be (o) + expect (getmetatable (o)).should_be (getmetatable (p)) + - it sets object fields from arguments: + o = obj:clone {} + expect (o).should_not_be (obj) + expect (o).should_equal (obj) + - it serves as a prototype for new instances: + o = obj:clone {} + expect (prototype (o)).should_be "Object" + expect (o).should_not_be (obj) + expect (o).should_equal (obj) + expect (getmetatable (o)).should_be (getmetatable (obj)) + - it separates '_' prefixed fields: + expect (Object:clone {foo="bar", _baz="quux"}). + should_equal (Object:clone {foo="bar"}) + - it puts '_' prefixed fields in a new metatable: + obj = Object:clone {foo="bar", _baz="quux"} + expect (getmetatable (obj)).should_not_be (getmetatable (Object)) + expect (getmetatable (obj)._baz).should_be "quux" + +- describe prototype: + - before: o = Object {} + + - context when called from the object module: + - it reports the prototype stored in the object's metatable: + expect (prototype (o)).should_be "Object" + - it reports the type of a cloned object: + expect (prototype (o {})).should_be "Object" + - it reports the type of a derived object: + Example = Object {_type = "Example"} + expect (prototype (Example)).should_be "Example" + - it reports the type of a cloned derived object: + Portal = Object {_type = "Demon"} + p = Portal {} + expect (prototype (p)).should_be "Demon" + expect (prototype (p {})).should_be "Demon" + - context when called as an object method: + - it reports the type stored in the object's metatable: + expect (o:prototype ()).should_be "Object" + - it reports the type of a cloned object: + expect ((o {}):prototype ()).should_be "Object" + - it reports the type of a subclassed object: + Example = Object {_type = "Example"} + expect (Example:prototype ()).should_be "Example" + - it reports the type of a cloned subclassed object: + Portal = Object {_type = "Demon"} + p = Portal {} + expect (p:prototype ()).should_be "Demon" + expect ((p {}):prototype ()).should_be "Demon" + - context backwards compatibility: + - it reports the prototype stored in the object's metatable: + expect (Object.type (o)).should_be "Object" + - it reports the type stored in the object's metatable: + expect (o:type ()).should_be "Object" + + +- describe instantiation from a prototype: + - before: + totable = (require "std.table").totable + + - context when _init is nil: + - before: + Array = Object { + _type = "Array", + "foo", "bar", "baz", + } + Array._init = nil + - it contains user-defined fields: + expect (totable (Array)). + should_equal {"foo", "bar", "baz"} + - it sets array part of instance object from positional parameters: + array = Array {"first", "second", "third"} + expect (totable (array)). + should_equal {"first", "second", "third"} + - it uses prototype values for missing positional parameters: + array = Array {"first", "second"} + expect (totable (array)). + should_equal {"first", "second", "baz"} + - it merges surplas positional parameters: + array = Array {"first", "second", "third", "fourth"} + expect (totable (array)). + should_equal {"first", "second", "third", "fourth"} + + - context when _init is an empty table: + - before: + Prototype = Object { + _type = "Prototype"; + _init = {}, + "first", "second", "third", + } + - it contains user-defined fields: + expect (totable (Prototype)). + should_equal {"first", "second", "third"} + - it ignores positional parameters: | + instance = Prototype {"foo", "bar"} + expect (instance).should_not_be (Prototype) + pending "see issue #35" + expect (instance).should_equal (Prototype) + + - context when _init is a table of field names: + - before: + Process = Object { + _type = "Process", + _init = {"status", "output", "errout"}, + status = -1, + output = "empty", + errout = "no errors", + } + - it contains user-defined fields: + expect (totable (Process)). + should_equal {status = -1, output = "empty", errout = "no errors"} + - it sets user-defined fields from positional parameters: + proc = Process {0, "output", "diagnostics"} + expect (totable (proc)). + should_equal {status = 0, output = "output", errout = "diagnostics"} + - it uses prototype values for missing positional parameters: + proc = Process {0, "output"} + expect (totable (proc)). + should_equal {status = 0, output = "output", errout = "no errors"} + - it merges surplus positional parameters into array part of new object: | + proc = Process {0, "output", "diagnostics", "garbage"} + pending "see issue #35" + expect (totable (proc)). + should_equal { status = 0, output = "output", errout = "diagnostics" } + + - context when _init is a function: + - before: + Prototype = Object { + _type = "Prototype", + f1 = "proto1", f2 = "proto2", + _init = function (self, ...) + self.args = unpack {...} + return self + end, + } + - it passes user defined fields to custom _init function: + instance = Prototype {"param1", "param2"} + expect ({instance.f1, instance.f2, instance.args}). + should_equal {"proto1", "proto2", {"param1", "param2"}} + +- describe field access: + - before: + Prototype = Object { + _type = "Prototype", + _init = { "field", "method"}, + field = "in prototype", + method = function (self, ...) + return prototype (self) .. " class, " .. + table.concat ({...}, ", ") + end, + } + instance = Prototype {"in object", function (self, ...) + return prototype (self) .. " instance, " .. + table.concat ({...}, ", ") + end, + } + + - it provides object field access with dot notation: + expect (instance.field).should_be "in object" + - it provides class field acces with dot notation: + expect (Prototype.field).should_be "in prototype" + - it provides object method acces with colon notation: + expect (instance:method "object method call"). + should_be "Prototype instance, object method call" + - it provides class method access with class dot notation: + expect (Prototype.method (instance, "class method call")). + should_be "Prototype class, class method call" + - it allows new instance fields to be added: + instance.newfield = "new" + expect (instance.newfield).should_be "new" + - it allows new instance methods to be added: + instance.newmethod = function (self) + return prototype (self) .. ", new instance method" + end + expect (instance:newmethod ()).should_be "Prototype, new instance method" + - it allows new class methods to be added: + Prototype.newmethod = function (self) + return prototype (self) .. ", new class method" + end + expect (Prototype.newmethod (instance)). + should_be "Prototype, new class method" + + +- describe object method propagation: + - context with no custom instance methods: + # :prototype is a method defined by the root object + - it inherits prototype object methods: + instance = Object {} + expect (instance:prototype ()).should_be "Object" + - it propagates prototype methods to derived instances: + Derived = Object {_type = "Derived"} + instance = Derived {} + expect (instance:prototype ()).should_be "Derived" + - context with custom object methods: + - before: + bag = Object { + _type = "bag", + __index = { + add = function (self, item) + self[item] = (self[item] or 0) + 1 + return self + end, + }, + } + # :prototype is a method defined by the root object + - it inherits prototype object methods: + expect (bag:prototype ()).should_be "bag" + - it propagates prototype methods to derived instances: + instance = bag {} + expect (instance:prototype ()).should_be "bag" + - it supports method calls: + expect (bag:add "foo").should_be (bag) + expect (bag.foo).should_be (1) + + +# Metatable propagation is an important property of Object cloning, +# because Lua will only call __lt and __le metamethods when both +# arguments share the same metatable - i.e. the previous behaviour +# of making each object its own metatable precluded ever being able +# to use __lt and __le! +- describe object metatable propagation: + - before: root_mt = getmetatable (Object) + + - context with no custom metamethods: + - it inherits prototype object metatable: + instance = Object {} + expect (getmetatable (instance)).should_be (root_mt) + - it propagates prototype metatable to derived instances: + Derived = Object {_type = "Derived"} + instance = Derived {} + expect (getmetatable (Derived)).should_not_be (root_mt) + expect (getmetatable (instance)).should_be (getmetatable (Derived)) + - context with custom metamethods: + - before: + base = require "std.base" + bag = Object { + _type = "bag", + __lt = function (a, b) return base.compare (a, b) < 0 end, + } + - it has it's own metatable: + expect (getmetatable (bag)).should_not_be (root_mt) + - it propagates prototype metatable to derived instances: + instance = bag {} + expect (getmetatable (instance)).should_be (getmetatable (bag)) + - it supports __lt calls: + a, b = bag {"a"}, bag {"b"} + expect (a < b).should_be (true) + expect (a < a).should_be (false) + expect (a > b).should_be (false) + + +- describe __totable: + - before: + totable = (require "std.table").totable + Derived = Object {_type = "Derived", "one", "two", three = true} + + - it returns a table: + expect (prototype (totable (Derived))).should_be "table" + - it contains all non-hidden fields of object: + expect (totable (Derived)).should_contain.all_of {"one", "two", "three"} + - it does not contain any hidden fields of object: + expect (totable (Derived)).should_equal {"one", "two", three = true} + + +- describe __tostring: + - before: + obj = Object {_type = "Derived", "one", "two", "three"} + - it returns a string: + expect (type (tostring (obj))).should_be "string" + - it contains the type: + expect (tostring (Object {})).should_contain "Object" + expect (tostring (obj)).should_contain (prototype (obj)) + - it contains the ordered array part elements: + expect (tostring (obj)).should_contain "one, two, three" + - it contains the ordered dictionary part elements: + expect (tostring (Object {one = true, two = true, three = true})). + should_contain "one=true, three=true, two=true" + expect (tostring (obj {one = true, two = true, three = true})). + should_contain "one=true, three=true, two=true" + - it contains a ';' separator only when object has array and dictionary parts: + expect (tostring (obj)).should_not_contain ";" + expect (tostring (Object {one = true, two = true, three = true})). + should_not_contain ";" + expect (tostring (obj {one = true, two = true, three = true})). + should_contain ";" diff --git a/specs/package_ext_spec.yaml b/specs/package_spec.yaml similarity index 97% rename from specs/package_ext_spec.yaml rename to specs/package_spec.yaml index 42be71b..c7b4bbd 100644 --- a/specs/package_ext_spec.yaml +++ b/specs/package_spec.yaml @@ -1,6 +1,6 @@ -specify package_ext: +specify package: - before: | - M = require "std.package_ext" + M = require "std.package" extends = package extensions = { "dirsep", "pathsep", "path_mark", "execdir", "igmark" } diff --git a/specs/set_spec.yaml b/specs/set_spec.yaml new file mode 100644 index 0000000..4e7f931 --- /dev/null +++ b/specs/set_spec.yaml @@ -0,0 +1,328 @@ +before: + require "spec_helper" + Set = require "std.set" + prototype = (require "std.object").prototype + totable = (require "std.table").totable + s = Set {"foo", "bar", "bar"} + +specify Set: +- describe construction: + - it constructs a new set: + s = Set {} + expect (s).should_not_be (Set) + expect (prototype (s)).should_be "Set" + - it initialises set with constructor parameters: + t = Set {"foo", "bar", "bar"} + expect (t).should_equal (s) + - it serves as a prototype for new instances: + obj = s {} + expect (prototype (obj)).should_be "Set" + expect (obj).should_equal (s) + expect (getmetatable (obj)).should_be (getmetatable (s)) + + +- describe delete: + - context when called as a Set module function: + - before: + s = Set {"foo", "bar", "baz"} + - it returns a set object: + expect (prototype (Set.delete (s, "foo"))).should_be "Set" + - it is destructive: + Set.delete (s, "bar") + expect (s).should_not_have_member "bar" + - it returns the modified set: + expect (Set.delete (s, "baz")).should_not_have_member "baz" + - it ignores removal of non-members: | + clone = s {} + expect (Set.delete (s, "quux")).should_equal (clone) + - it deletes a member from the set: + expect (s).should_have_member "bar" + Set.delete (s, "bar") + expect (s).should_not_have_member "bar" + - it works with an empty set: + expect (Set.delete (Set {}, "quux")).should_equal (Set {}) + + +- describe difference: + - before: + r = Set {"foo", "bar", "baz"} + s = Set {"bar", "baz", "quux"} + + - context when called as a Set module function: + - it returns a set object: + expect (prototype (Set.difference (r, s))).should_be "Set" + - it is non-destructive: + Set.difference (r, s) + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members of the first that are not in the second: + expect (Set.difference (r, s)).should_equal (Set {"foo"}) + - it coerces a table argument to a set: + expect (Set.difference (r, {"bar"})).should_equal (Set {"baz", "foo"}) + - context when called as a set metamethod: + - it returns a set object: + expect (prototype (r - s)).should_be "Set" + - it is non-destructive: + q = r - s + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members of the first that are not in the second: + expect (r - s).should_equal (Set {"foo"}) + - it coerces a table argument to a set: + expect (r - {"bar"}).should_equal (Set {"baz", "foo"}) + + +- describe elems: + - before: + s = Set {"foo", "bar", "baz"} + + - context when called as a Set module function: + - it is an iterator over set members: + t = {} + for e in Set.elems (s) do table.insert (t, e) end + table.sort (t) + expect (t).should_equal {"bar", "baz", "foo"} + - it works for an empty set: + t = {} + for e in Set.elems (Set {}) do table.insert (t, e) end + expect (t).should_equal {} + + +- describe insert: + - context when called as a Set module function: + - before: + s = Set {"foo"} + - it returns a set object: + expect (prototype (Set.insert (s, "bar"))).should_be "Set" + - it is destructive: + Set.insert (s, "bar") + expect (s).should_have_member "bar" + - it returns the modified set: + expect (Set.insert (s, "baz")).should_have_member "baz" + - it ignores insertion of existing members: + expect (Set.insert (s, "foo")).should_equal (Set {"foo"}) + - it inserts a new member into the set: + expect (s).should_not_have_member "bar" + Set.insert (s, "bar") + expect (s).should_have_member "bar" + - it works with an empty set: + expect (Set.insert (Set {}, "foo")).should_equal (s) + - context when called as a set metamethod: + - before: + s = Set {"foo"} + - it returns a set object: + s["bar"] = true + expect (prototype (s)).should_be "Set" + - it is destructive: + s["bar"] = true + expect (s).should_have_member "bar" + - it ignores insertion of existing members: + s["foo"] = true + expect (s).should_equal (Set {"foo"}) + - it inserts a new member into the set: + expect (s).should_not_have_member "bar" + s["bar"] = true + expect (s).should_have_member "bar" + - it works with an empty set: + s = Set {} + s.foo = true + expect (s).should_equal (s) + + +- describe intersection: + - before: + r = Set {"foo", "bar", "baz"} + s = Set {"bar", "baz", "quux"} + + - context when called as a Set module function: + - it returns a set object: + expect (prototype (Set.intersection (r, s))).should_be "Set" + - it is non-destructive: + Set.intersection (r, s) + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members common to both arguments: + expect (Set.intersection (r, s)). + should_equal (Set {"bar", "baz"}) + - it coerces a table argument to a set: + expect (Set.intersection (r, {"bar", "quux"})). + should_equal (Set {"bar"}) + - context when called as a set metamethod: + - it returns a set object: + q = r * s + expect (prototype (q)).should_be "Set" + - it is non-destructive: + q = r * s + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members common to both arguments: + expect (r * s).should_equal (Set {"bar", "baz"}) + - it coerces a table argument to a set: + expect (r * {"bar", "quux"}).should_equal (Set {"bar"}) + + +- describe member: + - before: s = Set {"foo", "bar"} + + - context when called as a Set module function: + - it succeeds when set contains the given member: + expect (Set.member (s, "foo")).should_be (true) + - it fails when set does not contain the given member: + expect (Set.member (s, "baz")).should_not_be (true) + - it works with the empty set: + s = Set {} + expect (Set.member (s, "foo")).should_not_be (true) + - context when called as a set metamethod: + - it succeeds when set contains the given member: + expect (s["foo"]).should_be (true) + - it fails when set does not contain the given member: + expect (s["baz"]).should_not_be (true) + - it works with the empty set: + s = Set {} + expect (s["foo"]).should_not_be (true) + + +- describe proper_subset: + - before: + r = Set {"foo", "bar", "baz"} + s = Set {"bar", "baz"} + + - context when called as a Set module function: + - it succeeds when set contains all elements of another: + expect (Set.proper_subset (s, r)).should_be (true) + - it fails when two sets are equal: + r = s {} + expect (Set.proper_subset (s, r)).should_be (false) + - it fails when set does not contain all elements of another: + s = s + Set {"quux"} + expect (Set.proper_subset (r, s)).should_be (false) + - it coerces a table argument to a set: + expect (Set.proper_subset (s, {"foo", "bar", "baz"})).should_be (true) + expect (Set.proper_subset (s, {"foo"})).should_be (false) + - context when called as a set metamethod: + - it succeeds when set contains all elements of another: + expect (s < r).should_be (true) + - it fails when two sets are equal: + r = s {} + expect (s < r).should_be (false) + - it fails when set does not contain all elements of another: + s = s + Set {"quux"} + expect (r < s).should_be (false) + + +- describe subset: + - before: + r = Set {"foo", "bar", "baz"} + s = Set {"bar", "baz"} + + - context when called as a Set module function: + - it succeeds when set contains all elements of another: + expect (Set.subset (s, r)).should_be (true) + - it succeeds when two sets are equal: + r = s {} + expect (Set.subset (s, r)).should_be (true) + - it fails when set does not contain all elements of another: + s = s + Set {"quux"} + expect (Set.subset (r, s)).should_be (false) + - it coerces a table argument to a set: + expect (Set.subset (s, {"foo", "bar", "baz"})).should_be (true) + expect (Set.subset (s, {"foo"})).should_be (false) + - context when called as a set metamethod: + - it succeeds when set contains all elements of another: + expect (s <= r).should_be (true) + - it succeeds when two sets are equal: + r = s {} + expect (s <= r).should_be (true) + - it fails when set does not contain all elements of another: + s = s + Set {"quux"} + expect (r <= s).should_be (false) + + +- describe symmetric_difference: + - before: + r = Set {"foo", "bar", "baz"} + s = Set {"bar", "baz", "quux"} + + - context when called as a Set module function: + - it returns a set object: + expect (prototype (Set.symmetric_difference (r, s))). + should_be "Set" + - it is non-destructive: + Set.symmetric_difference (r, s) + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members in only one argument set: + expect (Set.symmetric_difference (r, s)). + should_equal (Set {"foo", "quux"}) + - it coerces a table argument to a set: + expect (Set.symmetric_difference (r, {"bar"})). + should_equal (Set {"baz", "foo"}) + - context when called as a set metamethod: + - it returns a set object: + expect (prototype (r / s)).should_be "Set" + - it is non-destructive: + q = r / s + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members in only one argument set: + expect (r / s).should_equal (Set {"foo", "quux"}) + - it coerces a table argument to a set: + expect (r / {"bar"}).should_equal (Set {"baz", "foo"}) + + +- describe union: + - before: + r = Set {"foo", "bar", "baz"} + s = Set {"bar", "baz", "quux"} + + - context when called as a Set module function: + - it returns a set object: + expect (prototype (Set.union (r, s))).should_be "Set" + - it is non-destructive: + Set.union (r, s) + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members in only one argument set: + expect (Set.union (r, s)). + should_equal (Set {"foo", "bar", "baz", "quux"}) + - it coerces a table argument to a set: + expect (Set.union (r, {"quux"})). + should_equal (Set {"foo", "bar", "baz", "quux"}) + - context when called as a set metamethod: + - it returns a set object: + expect (prototype (r + s)).should_be "Set" + - it is non-destructive: + q = r + s + expect (r).should_equal (Set {"foo", "bar", "baz"}) + expect (s).should_equal (Set {"bar", "baz", "quux"}) + - it returns a set containing members in only one argument set: + expect (r + s).should_equal (Set {"foo", "bar", "baz", "quux"}) + - it coerces a table argument to a set: + expect (r + {"quux"}). + should_equal (Set {"foo", "bar", "baz", "quux"}) + + +- describe __totable: + - before: + s = Set {"foo", "bar", "baz"} + + - it returns a table: + expect (prototype (totable (s))).should_be "table" + - it contains all non-hidden fields of object: + expect (totable (s)).should_contain.all_of {"foo", "bar", "baz"} + - it contains fields of set in order: + expect (totable (s)).should_equal {"bar", "baz", "foo"} + - it does not contain any hidden fields of object: + expect (totable (s)).should_equal {"bar", "baz", "foo"} + + +- describe __tostring: + - before: + s = Set {"foo", "bar", "baz"} + + - it returns a string: + expect (type (tostring (s))).should_be "string" + - it shows the type name: + expect (tostring (s)).should_contain "Set" + - it contains the ordered set elements: + expect (tostring (s)).should_contain "bar, baz, foo" diff --git a/specs/spec_helper.lua b/specs/spec_helper.lua new file mode 100644 index 0000000..2480cc1 --- /dev/null +++ b/specs/spec_helper.lua @@ -0,0 +1,29 @@ +-- Not local, so that it is available in spec examples. +totable = (require "std.table").totable + + +-- Custom matcher for set membership. + +local set = require "std.set" +local util = require "specl.util" +local matchers = require "specl.matchers" + +local Matcher, matchers, q = + matchers.Matcher, matchers.matchers, matchers.stringify + +matchers.have_member = Matcher { + function (actual, expect) + return set.member (actual, expect) + end, + + actual = "set", + + format_expect = function (expect) + return " a set containing " .. q (expect) .. ", " + end, + + format_any_of = function (alternatives) + return " a set containing any of " .. + util.concat (alternatives, util.QUOTED) .. ", " + end, +} diff --git a/specs/specs.mk b/specs/specs.mk index d0b2ae2..99ae87a 100644 --- a/specs/specs.mk +++ b/specs/specs.mk @@ -13,13 +13,23 @@ SPECL_ENV = $(LUA_ENV) ## ------ ## specl_SPECS = \ - $(srcdir)/specs/debug_ext_spec.yaml \ + $(srcdir)/specs/container_spec.yaml \ + $(srcdir)/specs/debug_spec.yaml \ $(srcdir)/specs/getopt_spec.yaml \ - $(srcdir)/specs/io_ext_spec.yaml \ - $(srcdir)/specs/math_ext_spec.yaml \ - $(srcdir)/specs/package_ext_spec.yaml \ - $(srcdir)/specs/string_ext_spec.yaml \ - $(srcdir)/specs/table_ext_spec.yaml \ + $(srcdir)/specs/io_spec.yaml \ + $(srcdir)/specs/list_spec.yaml \ + $(srcdir)/specs/math_spec.yaml \ + $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/package_spec.yaml \ + $(srcdir)/specs/set_spec.yaml \ + $(srcdir)/specs/strbuf_spec.yaml \ + $(srcdir)/specs/string_spec.yaml \ + $(srcdir)/specs/table_spec.yaml \ + $(srcdir)/specs/tree_spec.yaml \ + $(NOTHING_ELSE) + +EXTRA_DIST += \ + $(srcdir)/specs/spec_helper.lua \ $(NOTHING_ELSE) include build-aux/specl.mk diff --git a/specs/strbuf_spec.yaml b/specs/strbuf_spec.yaml new file mode 100644 index 0000000..11bdc9a --- /dev/null +++ b/specs/strbuf_spec.yaml @@ -0,0 +1,79 @@ +before: + object = require "std.object" + StrBuf = require "std.strbuf" + b = StrBuf {"foo", "bar"} + +specify StrBuf: +- describe construction: + - context from StrBuf clone method: + - it constructs a new strbuf: + b = StrBuf:clone {} + expect (b).should_not_be (StrBuf) + expect (object.type (b)).should_be "StrBuf" + - it reuses the StrBuf metatable: + a, b = StrBuf:clone {"a"}, StrBuf:clone {"b"} + expect (getmetatable (a)).should_be (getmetatable (b)) + - it initialises strbuf with constructor parameters: + a = StrBuf:clone {"foo", "bar"} + expect (a).should_equal (b) + - it serves as a prototype for new instances: + obj = b:clone {} + expect (object.type (obj)).should_be "StrBuf" + expect (obj).should_equal (b) + expect (getmetatable (obj)).should_be (getmetatable (b)) + + # StrBuf {args} is just syntactic sugar for StrBuf:clone {args} + - context from StrBuf object prototype: + - it constructs a new strbuf: + b = StrBuf {} + expect (b).should_not_be (StrBuf) + expect (object.type (b)).should_be "StrBuf" + - it reuses the StrBuf metatable: + a, b = StrBuf {"a"}, StrBuf {"b"} + expect (getmetatable (a)).should_be (getmetatable (b)) + - it initialises strbuf with constructor parameters: + a = StrBuf:clone {"foo", "bar"} + expect (a).should_equal (b) + - it serves as a prototype for new instances: + obj = b {} + expect (object.type (obj)).should_be "StrBuf" + expect (obj).should_equal (b) + expect (getmetatable (obj)).should_be (getmetatable (b)) + + +- describe tostring: + - it can be called from strbuf module: + expect (StrBuf.tostring (b)).should_be "foobar" + - it can be called as a strbuf object method: + expect (b:tostring ()).should_be "foobar" + - it can be called as a strbuf metabethod: + expect (tostring (b)).should_be "foobar" + + +- describe concat: + - before: + b = StrBuf {"foo", "bar"} + - it can be called from strbuf module: + b = StrBuf.concat (b, "baz") + expect (object.type (b)).should_be "StrBuf" + expect (StrBuf.tostring (b)).should_be "foobarbaz" + - it can be called as a strbuf object method: + b:concat "baz" + expect (object.type (b)).should_be "StrBuf" + expect (b:tostring()).should_be "foobarbaz" + - it can be called as a strbuf metamethod: + b = b .. "baz" + expect (object.type (b)).should_be "StrBuf" + expect (tostring (b)).should_be "foobarbaz" + + +- describe __totable: + - before: + totable = (require "std.table").totable + + - it returns a table: + expect (object.type (totable (b))).should_be "table" + - it contains all non-hidden fields of object: + expect (totable (b)).should_contain.all_of {"foo", "bar"} + - it does not contain any hidden fields of object: + expect (totable (b)).should_equal {"foo", "bar"} diff --git a/specs/string_ext_spec.yaml b/specs/string_spec.yaml similarity index 89% rename from specs/string_ext_spec.yaml rename to specs/string_spec.yaml index d00d71d..d4de247 100644 --- a/specs/string_ext_spec.yaml +++ b/specs/string_spec.yaml @@ -1,20 +1,18 @@ -specify string_ext: +specify string: - before: | - M = require "std.string_ext" + M = require "std.string" extends = string - enhancements = { "format" } - extensions = { "assert", "caps", "chomp", "escape_pattern", - "escape_shell", "finds", "ltrim", "numbertosi", - "ordinal_suffix", "pad", "pickle", "prettytostring", - "render", "require_version", "rtrim", "split", - "tostring", "tfind", "trim", "wrap", + enhancements = { "assert", "format", "tostring" } + extensions = { "caps", "chomp", "escape_pattern", "escape_shell", + "finds", "ltrim", "numbertosi", "ordinal_suffix", + "pad", "pickle", "prettytostring", "render", + "require_version", "rtrim", "split", "tfind", + "trim", "wrap", -- make these available after require "std" - "__index", "_tostring", + "__index", "_format", "_tostring", -- camelCase compatibility: "escapePattern", "escapeShell", "ordinalSuffix" } - keywords = { "assert", "pickle", "prettytostring", "render", - "require_version", "tostring" } subject = "a string \n\n" @@ -58,10 +56,6 @@ specify string_ext: for api in pairs (M) do expect (extends[api]).should_be (M[api]) end - - it propagates keywords to the global environment: - for _, api in ipairs (keywords) do - expect (_G[api]).should_be (M[api]) - end - it does not add any other global access points: for api in pairs (extends) do if not enhanced[api] then @@ -129,15 +123,22 @@ specify string_ext: - describe escape_pattern: - - before: + - before: | f = M.escape_pattern + + magic = {} + meta = "^$()%.[]*+-?" + for i = 1, string.len (meta) do + magic[meta:sub (i, i)] = true + end + - context with each printable ASCII char: - before: subject, target = "", "" for c = 32, 126 do s = string.char (c) subject = subject .. s - if s:match ("%W") then target = target .. "%" end + if magic[s] then target = target .. "%" end target = target .. s end - "it inserts a % before any non-alphanumeric in a string": @@ -343,6 +344,39 @@ specify string_ext: - describe prettytostring: + - before: + f = M.prettytostring + - it renders nil exactly like system tostring: + expect (f (nil)).should_be (tostring (nil)) + - it renders booleans exactly like system tostring: + expect (f (true)).should_be (tostring (true)) + expect (f (false)).should_be (tostring (false)) + - it renders numbers exactly like system tostring: + n = 8723643 + expect (f (n)).should_be (tostring (n)) + - it renders functions exactly like system tostring: + expect (f (f)).should_be (tostring (f)) + - it renders strings with format "%q" styling: + s = "a string" + expect (f (s)).should_be (string.format ("%q", s)) + - it renders empty tables as a pair of braces: + expect (f {}).should_be ("{\n}") + - it renders an array prettily: + a = {"one", "two", "three"} + expect (f (a, "")). + should_be '{\n[1] = "one",\n[2] = "two",\n[3] = "three",\n}' + - it renders a table prettily: + t = { one = true, two = 2, three = {3}} + expect (f (t, "")). + should_be '{\none = true,\nthree =\n{\n[1] = 3,\n},\ntwo = 2,\n}' + - it renders table keys in table.sort order: + t = { one = 3, two = 5, three = 4, four = 2, five = 1 } + expect (f (t, "")). + should_be '{\nfive = 1,\nfour = 2,\none = 3,\nthree = 4,\ntwo = 5,\n}' + - it renders keys with invalid symbol names in long hand: + t = { _ = 0, word = 0, ["?"] = 1, ["a-key"] = 1, ["[]"] = 1 } + expect (f (t, "")). + should_be '{\n["?"] = 1,\n["[]"] = 1,\n_ = 0,\n["a-key"] = 1,\nword = 0,\n}' - describe render: diff --git a/specs/table_ext_spec.yaml b/specs/table_spec.yaml similarity index 97% rename from specs/table_ext_spec.yaml rename to specs/table_spec.yaml index 3f3fc20..2620d5c 100644 --- a/specs/table_ext_spec.yaml +++ b/specs/table_spec.yaml @@ -1,11 +1,12 @@ -specify table_ext: +specify table: - before: | - M = require "std.table_ext" + M = require "std.table" extends = table enhancements = { "sort" } extensions = { "clone", "clone_rename", "empty", "invert", "keys", - "merge", "new", "size", "values" } + "merge", "new", "pack", "ripairs", "size", "totable", + "values" } - context when required: - before: @@ -222,6 +223,12 @@ specify table_ext: expect (f (nil, "foo")).should_error ("table expected") +- describe pack: + + +- describe ripairs: + + - describe size: - before: | -- - 1 - --------- 2 ---------- -- 3 -- @@ -252,6 +259,9 @@ specify table_ext: expect (f "foo").should_error ("table expected") +- describe totable: + + - describe values: - before: subject = { k1 = {1}, k2 = {2}, k3 = {3} } diff --git a/specs/tree_spec.yaml b/specs/tree_spec.yaml new file mode 100644 index 0000000..c0520da --- /dev/null +++ b/specs/tree_spec.yaml @@ -0,0 +1,398 @@ +before: + Tree = require "std.tree" + prototype = (require "std.object").prototype + totable = (require "std.table").totable + t = {foo="foo", fnord={branch={bar="bar", baz="baz"}}, quux="quux"} + tr = Tree (t) + +specify tree: +- describe construction: + - it constructs a new tree: + tr = Tree {} + expect (tr).should_not_be (Tree) + expect (prototype (tr)).should_be "Tree" + - it turns a table argument into a tree: + expect (prototype (Tree (tr))).should_be "Tree" + - it does not turn table argument values into sub-Trees: + expect (prototype (tr["fnord"])).should_be "table" + - it understands branched nodes: + expect (tr).should_equal (Tree (t)) + expect (tr[{"fnord"}]).should_equal (t.fnord) + expect (tr[{"fnord", "branch", "bar"}]).should_equal (t.fnord.branch.bar) + - it serves as a prototype for new instances: + obj = tr {} + expect (prototype (obj)).should_be "Tree" + expect (obj).should_equal (tr) + expect (getmetatable (obj)).should_be (getmetatable (tr)) + + +- describe clone: + - before: + subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + f = Tree.clone + - it does not just return the subject: + expect (f (subject)).should_not_be (subject) + - it does copy the subject: + expect (f (subject)).should_equal (subject) + - it makes a deep copy: + expect (f (subject).k1).should_not_be (subject.k1) + - it does not perturb the original subject: + target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } + copy = f (subject) + expect (subject).should_equal (target) + expect (subject).should_be (subject) + - it diagnoses non-table arguments: + expect (f ()).should_error ("table expected") + expect (f "foo").should_error ("table expected") + + +- describe ileaves: + - before: + f = Tree.ileaves + l = {} + - it iterates over array part of a table argument: + for v in f {"first", "second", "3rd"} do l[1+#l]=v end + expect (l).should_equal {"first", "second", "3rd"} + - it iterates over array parts of nested table argument: + for v in f {{"one", {"two"}, {{"three"}, "four"}}, "five"} do + l[1+#l]=v + end + expect (l).should_equal {"one", "two", "three", "four", "five"} + - it skips hash part of a table argument: + for v in f {"first", "second"; third = "2rd"} do l[1+#l]=v end + expect (l).should_equal {"first", "second"} + - it skips hash parts of nested table argument: + for v in f {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} do + l[1+#l]=v + end + expect (l).should_equal {"one", "three", "five"} + - it works on trees too: + for v in f (Tree {Tree {"one", + Tree {two=2}, + Tree {Tree {"three"}, four=4} + }, + foo="bar", "five"}) + do + l[1+#l]=v + end + expect (l).should_equal {"one", "three", "five"} + - it diagnoses non-table arguments: + expect (f ()).should_error ("table expected") + expect (f "string").should_error ("table expected") + + +- describe inodes: + - before: | + f = Tree.inodes + local tostring = (require "std.string").tostring + + function traverse (subject) + l = {} + for ty, p, n in f (subject) do + l[1+#l]={ty, Tree.clone (p), n} + end + return l + end + - it iterates over array part of a table argument: | + subject = {"first", "second", "3rd"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"leaf", {3}, subject[3]}, -- 3rd, + {"join", {}, subject}} -- } + - it iterates over array parts of nested table argument: | + subject = {{"one", {"two"}, {{"three"}, "four"}}, "five"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,1}, subject[1][2][1]}, -- two, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,2}, subject[1][3][2]}, -- four, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } + - it skips hash part of a table argument: | + subject = {"first", "second"; third = "3rd"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"join", {}, subject}} -- } + - it skips hash parts of nested table argument: | + subject = {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } + - it works on trees too: | + subject = Tree {Tree {"one", + Tree {two=2}, + Tree {Tree {"three"}, four=4}}, + foo="bar", + "five"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } + - it diagnoses non-table arguments: + expect (f ()).should_error ("table expected") + expect (f "string").should_error ("table expected") + + +- describe leaves: + - before: + f = Tree.leaves + l = {} + - it iterates over elements of a table argument: + for v in f {"first", "second", "3rd"} do l[1+#l]=v end + expect (l).should_equal {"first", "second", "3rd"} + - it iterates over elements of a nested table argument: + for v in f {{"one", {"two"}, {{"three"}, "four"}}, "five"} do + l[1+#l]=v + end + expect (l).should_equal {"one", "two", "three", "four", "five"} + - it includes the hash part of a table argument: + for v in f {"first", "second"; third = "3rd"} do l[1+#l]=v end + expect (l).should_equal {"first", "second", "3rd"} + - it includes hash parts of a nested table argument: + for v in f {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} do + l[1+#l]=v + end + expect (l).should_contain.all_of {"one", 2, "three", 4, "bar", "five"} + - it works on trees too: + for v in f (Tree {Tree {"one", + Tree {two=2}, + Tree {Tree {"three"}, four=4} + }, + foo="bar", "five"}) + do + l[1+#l]=v + end + expect (l).should_contain.all_of {"one", 2, "three", 4, "bar", "five"} + - it diagnoses non-table arguments: + expect (f ()).should_error ("table expected") + expect (f "string").should_error ("table expected") + + +- describe merge: + - before: | + f = Tree.merge + + -- Additional merge keys which are moderately unusual + t1 = Tree { k1 = "v1", k2 = "if", k3 = Tree {"?"} } + t2 = Tree { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = "v2" } + + target = Tree.clone (t1) + for ty, p, n in Tree.nodes (t2) do + if ty == "leaf" then target[p] = n end + end + - it does not create a whole new table: + expect (f (t1, t2)).should_be (t1) + - it does not change t1 when t2 is empty: + expect (f (t1, Tree {})).should_be (t1) + - it copies t2 when t1 is empty: | + expect (f (Tree {}, t1)).should_not_be (t1) + expect (f (Tree {}, t1)).should_equal (t1) + - it merges keys from t2 into t1: | + expect (f (t1, t2)).should_equal (target) + - it gives precedence to values from t2: + original = Tree.clone (t1) + m = f (t1, t2) -- Merge is destructive, do it once only. + expect (m.k3).should_be (t2.k3) + expect (m.k3).should_not_be (original.k3) + - it diagnoses non-table arguments: + expect (f (nil, {})).should_error ("table expected") + expect (f ({}, nil)).should_error ("table expected") + + +- describe nodes: + - before: + f = Tree.nodes + + function traverse (subject) + l = {} + for ty, p, n in f (subject) do l[1+#l]={ty, Tree.clone (p), n} end + return l + end + - it iterates over the elements of a table argument: | + subject = {"first", "second", "3rd"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"leaf", {3}, subject[3]}, -- 3rd, + {"join", {}, subject}} -- } + - it iterates over the elements of nested a table argument: | + subject = {{"one", {"two"}, {{"three"}, "four"}}, "five"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,1}, subject[1][2][1]}, -- two, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,2}, subject[1][3][2]}, -- four, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } + - it includes the hash part of a table argument: | + -- like `pairs`, `nodes` can visit elements in any order, so we cannot + -- guarantee the array part is always visited before the hash part, or + -- even that the array elements are visited in order! + subject = {"first", "second"; third = "3rd"} + expect (traverse (subject)).should_contain. + all_of {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"leaf", {"third"}, subject["third"]}, -- 3rd + {"join", {}, subject}} -- } + - it includes hash parts of a nested table argument: | + -- like `pairs`, `nodes` can visit elements in any order, so we cannot + -- guarantee the array part is always visited before the hash part, or + -- even that the array elements are visited in order! + subject = {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} + expect (traverse (subject)).should_contain. + all_of {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,"two"}, subject[1][2]["two"]}, -- 2, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,"four"}, subject[1][3]["four"]}, -- 4, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"leaf", {"foo"}, subject["foo"]}, -- bar, + {"join", {}, subject}} -- } + - it works on trees too: | + -- like `pairs`, `nodes` can visit elements in any order, so we cannot + -- guarantee the array part is always visited before the hash part, or + -- even that the array elements are visited in order! + subject = Tree {Tree {"one", + Tree {two=2}, + Tree {Tree {"three"}, four=4}}, + foo="bar", + "five"} + expect (traverse (subject)).should_contain. + all_of {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,"two"}, subject[1][2]["two"]}, -- 2, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,"four"}, subject[1][3]["four"]}, -- 4, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"leaf", {"foo"}, subject["foo"]}, -- bar, + {"join", {}, subject}} -- } + - it generates path key-lists that are valid __index arguments: | + pending "std.tree.__index handling empty list keys" + subject = Tree {"first", Tree {"second"}, "3rd"} + expect (traverse (subject)). + should_equal {{"branch", {}, subject[{}]}, -- { + {"leaf", {1}, subject[{1}]}, -- first, + {"branch", {2}, subject[{2}]}, -- { + {"leaf", {2,1}, subject[{2,1}]}, -- second + {"join", {2}, subject[{2}]}, -- } + {"leaf", {3}, subject[{3}]}, -- 3rd, + {"join", {}, subject[{}]}} -- } + - it diagnoses non-table arguments: + expect (f ()).should_error ("table expected") + expect (f "string").should_error ("table expected") + + +- describe __index: + - it returns nil for a missing key: + expect (tr["no such key"]).should_be (nil) + - it returns nil for missing single element key lists: + expect (tr[{"no such key"}]).should_be (nil) + - it returns nil for missing multi-element key lists: | + expect (tr[{"fnord", "foo"}]).should_be (nil) + pending "see issue #39" + expect (tr[{"no", "such", "key"}]).should_be (nil) + - it returns a value for the given key: + expect (tr["foo"]).should_be "foo" + expect (tr["quux"]).should_be "quux" + - it returns values for single element key lists: + expect (tr[{"foo"}]).should_be "foo" + expect (tr[{"quux"}]).should_be "quux" + - it returns values for multi-element key lists: + expect (tr[{"fnord", "branch", "bar"}]).should_be "bar" + expect (tr[{"fnord", "branch", "baz"}]).should_be "baz" + + +- describe __newindex: + - before: + tr = Tree {} + - it stores values for simple keys: + tr["foo"] = "foo" + expect (tr).should_equal (Tree {foo="foo"}) + - it stores values for single element key lists: + tr[{"foo"}] = "foo" + expect (tr).should_equal (Tree {foo="foo"}) + - it stores values for multi-element key lists: + tr[{"foo", "bar"}] = "baz" + expect (tr).should_equal (Tree {foo=Tree {bar="baz"}}) + - it separates branches for diverging key lists: + tr[{"foo", "branch", "bar"}] = "leaf1" + tr[{"foo", "branch", "baz"}] = "leaf2" + expect (tr).should_equal (Tree {foo=Tree {branch=Tree {bar="leaf1", baz="leaf2"}}}) + +- describe __totable: + - it returns a table: + expect (prototype (totable (tr))).should_be "table" + - it contains all non-hidden fields of object: + expect (totable (tr)).should_contain. + all_of {"foo", branch={bar="bar", baz="baz"}, "quux"} + +- describe __tostring: + - it returns a string: + expect (prototype (tostring (tr))).should_be "string" + - it shows the type name: + expect (tostring (tr)).should_contain "Tree" + - it shows the contents in order: | + pending "see issue #44" + expect (tostring (tr)). + should_contain 'fnord={branch={bar=bar, baz=baz}}, foo=foo, quux=quux' diff --git a/std/base.lua b/std/base.lua deleted file mode 100644 index d8a4a15..0000000 --- a/std/base.lua +++ /dev/null @@ -1,291 +0,0 @@ ---- Adds to the existing global functions -module ("base", package.seeall) - ---- Functional forms of infix operators. --- Defined here so that other modules can write to it. --- @class table --- @name _G.op -_G.op = {} - -local table = require "std.table_ext" ---local list = require "std.list" ---require "std.io_ext" FIXME: allow loops -local strbuf = require "std.strbuf" - - ---- Return given metamethod, if any, or nil. --- @param x object to get metamethod of --- @param n name of metamethod to get --- @return metamethod function or nil if no metamethod or not a --- function -function _G.metamethod (x, n) - local _, m = pcall (function (x) - return getmetatable (x)[n] - end, - x) - if type (m) ~= "function" then - m = nil - end - return m -end - ---- Turn an object into a table according to __totable metamethod. --- @param x object to turn into a table --- @return table or nil -function _G.totable (x) - local m = metamethod (x, "__totable") - if m then - return m (x) - elseif type (x) == "table" then - return x - else - return nil - end -end - ---- Identity function. --- @param ... --- @return the arguments passed to the function -function _G.id (...) - return ... -end - ---- Turn a tuple into a list. --- @param ... tuple --- @return list -function _G.pack (...) - return {...} -end - ---- Partially apply a function. --- @param f function to apply partially --- @param ... arguments to bind --- @return function with ai already bound -function _G.bind (f, ...) - local fix = {...} - return function (...) - return f (unpack (list.concat (fix, {...}))) - end -end - ---- Curry a function. --- @param f function to curry --- @param n number of arguments --- @return curried version of f -function _G.curry (f, n) - if n <= 1 then - return f - else - return function (x) - return curry (bind (f, x), n - 1) - end - end -end - ---- Compose functions. --- @param f1...fn functions to compose --- @return composition of f1 ... fn -function _G.compose (...) - local arg = {...} - local fns, n = arg, #arg - return function (...) - local arg = {...} - for i = n, 1, -1 do - arg = {fns[i] (unpack (arg))} - end - return unpack (arg) - end -end - ---- Memoize a function, by wrapping it in a functable. --- @param fn function that returns a single result --- @return memoized function -function _G.memoize (fn) - return setmetatable ({}, { - __call = function (self, ...) - local k = tostring ({...}) - local v = self[k] - if v == nil then - v = fn (...) - self[k] = v - end - return v - end - }) -end - ---- Evaluate a string. --- @param s string --- @return value of string -function _G.eval (s) - return loadstring ("return " .. s)() -end - ---- An iterator like ipairs, but in reverse. --- @param t table to iterate over --- @return iterator function --- @return the table, as above --- @return #t + 1 -function _G.ripairs (t) - return function (t, n) - n = n - 1 - if n > 0 then - return n, t[n] - end - end, - t, #t + 1 -end - ---- --- @class function --- @name tree_Iterator --- @param n current node --- @return type ("leaf", "branch" (pre-order) or "join" (post-order)) --- @return path to node ({i1...ik}) --- @return node -local function _nodes (it, tr) - local p = {} - local function visit (n) - if type (n) == "table" then - coroutine.yield ("branch", p, n) - for i, v in it (n) do - table.insert (p, i) - visit (v) - table.remove (p) - end - coroutine.yield ("join", p, n) - else - coroutine.yield ("leaf", p, n) - end - end - return coroutine.wrap (visit), tr -end - ---- Tree iterator. --- @see tree_Iterator --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -function _G.nodes (tr) - return _nodes (pairs, tr) -end - ---- Tree iterator over numbered nodes, in order. --- @see tree_Iterator --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -function _G.inodes (tr) - return _nodes (ipairs, tr) -end - ---- Collect the results of an iterator. --- @param i iterator --- @return results of running the iterator on its arguments -function _G.collect (i, ...) - local t = {} - for e in i (...) do - table.insert (t, e) - end - return t -end - ---- Map a function over an iterator. --- @param f function --- @param i iterator --- @return result table -function _G.map (f, i, ...) - local t = {} - for e in i (...) do - local r = f (e) - if r then - table.insert (t, r) - end - end - return t -end - ---- Filter an iterator with a predicate. --- @param p predicate --- @param i iterator --- @return result table containing elements e for which p (e) -function _G.filter (p, i, ...) - local t = {} - for e in i (...) do - if p (e) then - table.insert (t, e) - end - end - return t -end - ---- Fold a binary function into an iterator. --- @param f function --- @param d initial first argument --- @param i iterator --- @return result -function _G.fold (f, d, i, ...) - local r = d - for e in i (...) do - r = f (r, e) - end - return r -end - ---- Give warning with the name of program and file (if any). --- @param ... arguments for format -function _G.warn (...) - if prog.name then - io.stderr:write (prog.name .. ":") - end - if prog.file then - io.stderr:write (prog.file .. ":") - end - if prog.line then - io.stderr:write (tostring (prog.line) .. ":") - end - if prog.name or prog.file or prog.line then - io.stderr:write (" ") - end - io.writelines (io.stderr, string.format (...)) -end - ---- Die with error. --- @param ... arguments for format -function _G.die (...) - warn (...) - error () -end - --- Function forms of operators. --- FIXME: Make these visible in LuaDoc (also list.concat in list) -_G.op["[]"] = function (t, s) - return t[s] -end -_G.op["+"] = function (a, b) - return a + b -end -_G.op["-"] = function (a, b) - return a - b -end -_G.op["*"] = function (a, b) - return a * b -end -_G.op["/"] = function (a, b) - return a / b -end -_G.op["and"] = function (a, b) - return a and b -end -_G.op["or"] = function (a, b) - return a or b -end -_G.op["not"] = function (a) - return not a -end -_G.op["=="] = function (a, b) - return a == b -end -_G.op["~="] = function (a, b) - return a ~= b -end diff --git a/std/files/base.html b/std/files/base.html deleted file mode 100644 index 13c0317..0000000 --- a/std/files/base.html +++ /dev/null @@ -1,935 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File base.lua

    - - -

    Adds to the existing global functions

    - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    _G.bind (f, ...)Partially apply a function.
    _G.collect (i, ...)Collect the results of an iterator.
    _G.compose (..., f1...fn)Compose functions.
    _G.curry (f, n)Curry a function.
    _G.die (...)Die with error.
    _G.eval (s)Evaluate a string.
    _G.filter (p, i, ...)Filter an iterator with a predicate.
    _G.fold (f, d, i, ...)Fold a binary function into an iterator.
    _G.id (...)Identity function.
    _G.inodes (tr)Tree iterator over numbered nodes, in order.
    _G.map (f, i, ...)Map a function over an iterator.
    _G.memoize (fn)Memoize a function, by wrapping it in a functable.
    _G.metamethod (x, n)Return given metamethod, if any, or nil.
    _G.nodes (tr)Tree iterator.
    _G.pack (...)Turn a tuple into a list.
    _G.ripairs (t)An iterator like ipairs, but in reverse.
    _G.totable (x)Turn an object into a table according to __totable metamethod.
    _G.warn (...)Give warning with the name of program and file (if any).
    tree_Iterator (it, tr, n)
    - - - - -

    Tables

    - - - - - - - -
    _G.opFunctional forms of infix operators.
    - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    _G.bind (f, ...)
    -
    -Partially apply a function. - - -

    Parameters

    -
      - -
    • - f: function to apply partially -
    • - -
    • - ...: arguments to bind -
    • - -
    - - - - - - -

    Return value:

    -function with ai already bound - - - -
    - - - - -
    _G.collect (i, ...)
    -
    -Collect the results of an iterator. - - -

    Parameters

    -
      - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -results of running the iterator on its arguments - - - -
    - - - - -
    _G.compose (..., f1...fn)
    -
    -Compose functions. - - -

    Parameters

    -
      - -
    • - ...: -
    • - -
    • - f1...fn: functions to compose -
    • - -
    - - - - - - -

    Return value:

    -composition of f1 ... fn - - - -
    - - - - -
    _G.curry (f, n)
    -
    -Curry a function. - - -

    Parameters

    -
      - -
    • - f: function to curry -
    • - -
    • - n: number of arguments -
    • - -
    - - - - - - -

    Return value:

    -curried version of f - - - -
    - - - - -
    _G.die (...)
    -
    -Die with error. - - -

    Parameters

    -
      - -
    • - ...: arguments for format -
    • - -
    - - - - - - - - -
    - - - - -
    _G.eval (s)
    -
    -Evaluate a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    - - - - - - -

    Return value:

    -value of string - - - -
    - - - - -
    _G.filter (p, i, ...)
    -
    -Filter an iterator with a predicate. - - -

    Parameters

    -
      - -
    • - p: predicate -
    • - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -result table containing elements e for which p (e) - - - -
    - - - - -
    _G.fold (f, d, i, ...)
    -
    -Fold a binary function into an iterator. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - d: initial first argument -
    • - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -result - - - -
    - - - - -
    _G.id (...)
    -
    -Identity function. - - -

    Parameters

    -
      - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -the arguments passed to the function - - - -
    - - - - -
    _G.inodes (tr)
    -
    -Tree iterator over numbered nodes, in order. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -

    See also:

    - - -
    - - - - -
    _G.map (f, i, ...)
    -
    -Map a function over an iterator. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -result table - - - -
    - - - - -
    _G.memoize (fn)
    -
    -Memoize a function, by wrapping it in a functable. - - -

    Parameters

    -
      - -
    • - fn: function that returns a single result -
    • - -
    - - - - - - -

    Return value:

    -memoized function - - - -
    - - - - -
    _G.metamethod (x, n)
    -
    -Return given metamethod, if any, or nil. - - -

    Parameters

    -
      - -
    • - x: object to get metamethod of -
    • - -
    • - n: name of metamethod to get -
    • - -
    - - - - - - -

    Return value:

    -metamethod function or nil if no metamethod or not a function - - - -
    - - - - -
    _G.nodes (tr)
    -
    -Tree iterator. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -

    See also:

    - - -
    - - - - -
    _G.pack (...)
    -
    -Turn a tuple into a list. - - -

    Parameters

    -
      - -
    • - ...: tuple -
    • - -
    - - - - - - -

    Return value:

    -list - - - -
    - - - - -
    _G.ripairs (t)
    -
    -An iterator like ipairs, but in reverse. - - -

    Parameters

    -
      - -
    • - t: table to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the table, as above - -
    3. #t + 1 - -
    - - - -
    - - - - -
    _G.totable (x)
    -
    -Turn an object into a table according to __totable metamethod. - - -

    Parameters

    -
      - -
    • - x: object to turn into a table -
    • - -
    - - - - - - -

    Return value:

    -table or nil - - - -
    - - - - -
    _G.warn (...)
    -
    -Give warning with the name of program and file (if any). - - -

    Parameters

    -
      - -
    • - ...: arguments for format -
    • - -
    - - - - - - - - -
    - - - - -
    tree_Iterator (it, tr, n)
    -
    - - - -

    Parameters

    -
      - -
    • - it: -
    • - -
    • - tr: -
    • - -
    • - n: current node -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. type ("leaf", "branch" (pre-order) or "join" (post-order)) - -
    2. path to node ({i1...ik}) - -
    3. node - -
    - - - -
    - - -
    - - - - -

    Tables

    -
    - -
    _G.op
    -
    Functional forms of infix operators. Defined here so that other modules can write to it. - - - -
    - - -
    - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/debug_ext.html b/std/files/debug_ext.html deleted file mode 100644 index d1860db..0000000 --- a/std/files/debug_ext.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File debug_ext.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - -
    debug ()The global function debug is an abbreviation for debug.say (1, ...)
    say (n, ...)Print a debugging message
    trace (event)Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set.
    - - - - -

    Tables

    - - - - - - - -
    _DEBUGTo activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below.
    - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    debug ()
    -
    -The global function debug is an abbreviation for debug.say (1, ...) - - - - - - - - - -

    See also:

    - - -
    - - - - -
    say (n, ...)
    -
    -Print a debugging message - - -

    Parameters

    -
      - -
    • - n: debugging level, defaults to 1 -
    • - -
    • - ...: objects to print (as for print) -
    • - -
    - - - - - - - - -
    - - - - -
    trace (event)
    -
    -Trace function calls Use as debug.sethook (trace, "cr"), which is done automatically when _DEBUG.call is set. Based on test/trace-calls.lua from the Lua distribution. - - -

    Parameters

    -
      - -
    • - event: event causing the call -
    • - -
    - - - - - - - - -
    - - -
    - - - - -

    Tables

    -
    - -
    _DEBUG
    -
    To activate debugging set _DEBUG either to any true value (equivalent to {level = 1}), or as documented below. - - -Fields -
      - -
    • - level: debugging level -
    • - -
    • - call: do call trace debugging -
    • - -
    • - std: do standard library debugging (run examples & test code) -
    • - -
    - - -
    - - -
    - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/debug_init.html b/std/files/debug_init.html deleted file mode 100644 index be1fb79..0000000 --- a/std/files/debug_init.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File debug_init.lua

    - - - - - - - - - - - - -
    -
    - - - - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/getopt.html b/std/files/getopt.html deleted file mode 100644 index aa320fc..0000000 --- a/std/files/getopt.html +++ /dev/null @@ -1,357 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File getopt.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    getOpt (argIn, options, stop_at_nonopt)Perform argument processing
    makeOptions (t)Options table constructor: adds lookup tables for the option names
    processArgs (prog, ...)Simple getOpt wrapper.
    usage (prog)Emit a usage message.
    usageInfo (header, optDesc, pageWidth)Produce usage info for the given options
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    getOpt (argIn, options, stop_at_nonopt)
    -
    -Perform argument processing - - -

    Parameters

    -
      - -
    • - argIn: list of command-line args -
    • - -
    • - options: options table -
    • - -
    • - stop_at_nonopt: if true, stop option processing at first non-option -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. table of remaining non-options - -
    2. table of option key-value list pairs - -
    3. table of error messages - -
    - - - -
    - - - - -
    makeOptions (t)
    -
    -Options table constructor: adds lookup tables for the option names - - -

    Parameters

    -
      - -
    • - t: -
    • - -
    - - - - - - - - -
    - - - - -
    processArgs (prog, ...)
    -
    -Simple getOpt wrapper. If the caller didn't supply their own already, adds --version/-V and --help/-h options automatically; stops program if there was an error, or if --help or --version was used. - - -

    Parameters

    -
      - -
    • - prog: table of named parameters -
    • - -
    • - ...: extra arguments for getOpt -
    • - -
    - - - - - - - - -
    - - - - -
    usage (prog)
    -
    -Emit a usage message. - - -

    Parameters

    -
      - -
    • - prog: table of named parameters -
    • - -
    - - - - - - - - -
    - - - - -
    usageInfo (header, optDesc, pageWidth)
    -
    -Produce usage info for the given options - - -

    Parameters

    -
      - -
    • - header: header string -
    • - -
    • - optDesc: option descriptors -
    • - -
    • - pageWidth: width to format to [78] -
    • - -
    - - - - - - -

    Return value:

    -formatted string - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/io_ext.html b/std/files/io_ext.html deleted file mode 100644 index 0b66749..0000000 --- a/std/files/io_ext.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File io_ext.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    catdir (...)Concatenate two or more directories into a path, removing the trailing slash.
    catfile (...)Concatenate one or more directories and a filename into a path.
    process_files (f)Process files specified on the command-line.
    readlines (h)Read a file or file handle into a list of lines.
    shell (c)Perform a shell command and return its output.
    slurp (h)Slurp a file handle.
    splitdir (path)Split a directory path into components.
    writelines (h, ...)Write values adding a newline after each.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    catdir (...)
    -
    -Concatenate two or more directories into a path, removing the trailing slash. - - -

    Parameters

    -
      - -
    • - ...: path components -
    • - -
    - - - - - - -

    Return value:

    -path - - - -
    - - - - -
    catfile (...)
    -
    -Concatenate one or more directories and a filename into a path. - - -

    Parameters

    -
      - -
    • - ...: path components -
    • - -
    - - - - - - -

    Return value:

    -path - - - -
    - - - - -
    process_files (f)
    -
    -Process files specified on the command-line. If no files given, process io.stdin; in list of files, - means io.stdin.
    FIXME: Make the file list an argument to the function. - - -

    Parameters

    -
      - -
    • - f: function to process files with, which is passed (name, arg_no) -
    • - -
    - - - - - - - - -
    - - - - -
    readlines (h)
    -
    -Read a file or file handle into a list of lines. - - -

    Parameters

    -
      - -
    • - h: file handle or name (default: io.input ()); if h is a handle, the file is closed after reading -
    • - -
    - - - - - - -

    Return value:

    -list of lines - - - -
    - - - - -
    shell (c)
    -
    -Perform a shell command and return its output. - - -

    Parameters

    -
      - -
    • - c: command -
    • - -
    - - - - - - -

    Return value:

    -output, or nil if error - - - -
    - - - - -
    slurp (h)
    -
    -Slurp a file handle. - - -

    Parameters

    -
      - -
    • - h: file handle or name (default: io.input ()) -
    • - -
    - - - - - - -

    Return value:

    -contents of file or handle, or nil if error - - - -
    - - - - -
    splitdir (path)
    -
    -Split a directory path into components. Empty components are retained: the root directory becomes {"", ""}. - - -

    Parameters

    -
      - -
    • - path: path -
    • - -
    - - - - - - -

    Return value:

    -list of path components - - - -
    - - - - -
    writelines (h, ...)
    -
    -Write values adding a newline after each. - - -

    Parameters

    -
      - -
    • - h: file handle (default: io.output () -
    • - -
    • - ...: values to write (as for write) -
    • - -
    - - - - - - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/list.html b/std/files/list.html deleted file mode 100644 index 19c78c8..0000000 --- a/std/files/list.html +++ /dev/null @@ -1,1194 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File list.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    append (l, x)Append an item to a list.
    compare (l, m)Compare two lists element by element left-to-right
    concat (...)Concatenate lists.
    cons (l, x)Prepend an item to a list.
    depair (ls)Turn a list of pairs into a table.
    elems (l)An iterator over the elements of a list.
    enpair (t)Turn a table into a list of pairs.
    filter (p, l)Filter a list according to a predicate.
    flatten (l)Flatten a list.
    foldl (f, e, l)Fold a binary function through a list left associatively.
    foldr (f, e, l)Fold a binary function through a list right associatively.
    ileaves (tr)Tree iterator which returns just numbered leaves, in order.
    indexKey (f, l)Make an index of a list of tables on a given field
    indexValue (f, l)Copy a list of tables, indexed on a given field
    leaves (tr)Tree iterator which returns just leaves.
    map (f, l)Map a function over a list.
    mapWith (f, l, ls)Map a function over a list of lists.
    new (l, t)List constructor.
    project (f, l)Project a list of fields from a list of tables.
    relems (l)An iterator over the elements of a list, in reverse.
    rep (l, n)Repeat a list.
    reverse (l)Reverse a list.
    shape (s, l)Shape a list according to a list of dimensions.
    sub (l, from, to)Return a sub-range of a list.
    tail (l)Return a list with its first element removed.
    transpose (ls)Transpose a list of lists.
    zipWith (f, ls)Zip lists together with a function.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    append (l, x)
    -
    -Append an item to a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - x: item -
    • - -
    - - - - - - -

    Return value:

    -{l[1], ..., l[#l], x} - - - -
    - - - - -
    compare (l, m)
    -
    -Compare two lists element by element left-to-right - - -

    Parameters

    -
      - -
    • - l: first list -
    • - -
    • - m: second list -
    • - -
    - - - - - - -

    Return value:

    --1 if l is less than m, 0 if they are the same, and 1 if l is greater than m - - - -
    - - - - -
    concat (...)
    -
    -Concatenate lists. - - -

    Parameters

    -
      - -
    • - ...: lists -
    • - -
    - - - - - - -

    Return value:

    -{l1[1], ..., l1[#l1], ..., ln[1], ..., ln[#ln]} - - - -
    - - - - -
    cons (l, x)
    -
    -Prepend an item to a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - x: item -
    • - -
    - - - - - - -

    Return value:

    -{x, unpack (l)} - - - -
    - - - - -
    depair (ls)
    -
    -Turn a list of pairs into a table.
    FIXME: Find a better name. - - -

    Parameters

    -
      - -
    • - ls: list {{i1, v1}, ..., {in, vn}} -
    • - -
    - - - - - - -

    Return value:

    -table {i1=v1, ..., in=vn} - - - -
    - - - - -
    elems (l)
    -
    -An iterator over the elements of a list. - - -

    Parameters

    -
      - -
    • - l: list to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function which returns successive elements of the list - -
    2. the list l as above - -
    3. true - -
    - - - -
    - - - - -
    enpair (t)
    -
    -Turn a table into a list of pairs.
    FIXME: Find a better name. - - -

    Parameters

    -
      - -
    • - t: table {i1=v1, ..., in=vn} -
    • - -
    - - - - - - -

    Return value:

    -list {{i1, v1}, ..., {in, vn}} - - - -
    - - - - -
    filter (p, l)
    -
    -Filter a list according to a predicate. - - -

    Parameters

    -
      - -
    • - p: predicate (function of one argument returning a boolean) -
    • - -
    • - l: list of lists -
    • - -
    - - - - - - -

    Return value:

    -result list containing elements e of l for which p (e) is true - - - -
    - - - - -
    flatten (l)
    -
    -Flatten a list. - - -

    Parameters

    -
      - -
    • - l: list to flatten -
    • - -
    - - - - - - -

    Return value:

    -flattened list - - - -
    - - - - -
    foldl (f, e, l)
    -
    -Fold a binary function through a list left associatively. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - e: element to place in left-most position -
    • - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -result - - - -
    - - - - -
    foldr (f, e, l)
    -
    -Fold a binary function through a list right associatively. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - e: element to place in right-most position -
    • - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -result - - - -
    - - - - -
    ileaves (tr)
    -
    -Tree iterator which returns just numbered leaves, in order. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -
    - - - - -
    indexKey (f, l)
    -
    -Make an index of a list of tables on a given field - - -

    Parameters

    -
      - -
    • - f: field -
    • - -
    • - l: list of tables {t1, ..., tn} -
    • - -
    - - - - - - -

    Return value:

    -index {t1[f]=1, ..., tn[f]=n} - - - -
    - - - - -
    indexValue (f, l)
    -
    -Copy a list of tables, indexed on a given field - - -

    Parameters

    -
      - -
    • - f: field whose value should be used as index -
    • - -
    • - l: list of tables {i1=t1, ..., in=tn} -
    • - -
    - - - - - - -

    Return value:

    -index {t1[f]=t1, ..., tn[f]=tn} - - - -
    - - - - -
    leaves (tr)
    -
    -Tree iterator which returns just leaves. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -
    - - - - -
    map (f, l)
    -
    -Map a function over a list. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -result list {f (l[1]), ..., f (l[#l])} - - - -
    - - - - -
    mapWith (f, l, ls)
    -
    -Map a function over a list of lists. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - l: -
    • - -
    • - ls: list of lists -
    • - -
    - - - - - - -

    Return value:

    -result list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} - - - -
    - - - - -
    new (l, t)
    -
    -List constructor. Needed in order to use metamethods. - - -

    Parameters

    -
      - -
    • - l: -
    • - -
    • - t: list (as a table), or nil for empty list -
    • - -
    - - - - - - -

    Return value:

    -list (with list metamethods) - - - -
    - - - - -
    project (f, l)
    -
    -Project a list of fields from a list of tables. - - -

    Parameters

    -
      - -
    • - f: field to project -
    • - -
    • - l: list of tables -
    • - -
    - - - - - - -

    Return value:

    -list of f fields - - - -
    - - - - -
    relems (l)
    -
    -An iterator over the elements of a list, in reverse. - - -

    Parameters

    -
      - -
    • - l: list to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function which returns precessive elements of the list - -
    2. the list l as above - -
    3. true - -
    - - - -
    - - - - -
    rep (l, n)
    -
    -Repeat a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - n: number of times to repeat -
    • - -
    - - - - - - -

    Return value:

    -n copies of l appended together - - - -
    - - - - -
    reverse (l)
    -
    -Reverse a list. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -list {l[#l], ..., l[1]} - - - -
    - - - - -
    shape (s, l)
    -
    -Shape a list according to a list of dimensions. Dimensions are given outermost first and items from the original list are distributed breadth first; there may be one 0 indicating an indefinite number. Hence, {0} is a flat list, {1} is a singleton, {2, 0} is a list of two lists, and {0, 2} is a list of pairs.
    Algorithm: turn shape into all positive numbers, calculating the zero if necessary and making sure there is at most one; recursively walk the shape, adding empty tables until the bottom level is reached at which point add table items instead, using a counter to walk the flattened original list.
    - - -

    Parameters

    -
      - -
    • - s: {d1, ..., dn} -
    • - -
    • - l: list to reshape -
    • - -
    - - - - - - -

    Return value:

    -reshaped list FIXME: Use ileaves instead of flatten (needs a while instead of a for in fill function) - - - -
    - - - - -
    sub (l, from, to)
    -
    -Return a sub-range of a list. (The equivalent of string.sub on strings; negative list indices count from the end of the list.) - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    • - from: start of range (default: 1) -
    • - -
    • - to: end of range (default: #l) -
    • - -
    - - - - - - -

    Return value:

    -{l[from], ..., l[to]} - - - -
    - - - - -
    tail (l)
    -
    -Return a list with its first element removed. - - -

    Parameters

    -
      - -
    • - l: list -
    • - -
    - - - - - - -

    Return value:

    -{l[2], ..., l[#l]} - - - -
    - - - - -
    transpose (ls)
    -
    -Transpose a list of lists. This function in Lua is equivalent to zip and unzip in more strongly typed languages. - - -

    Parameters

    -
      - -
    • - ls: {{l1,1, ..., l1,c}, ..., {lr,1, ..., lr,c}} -
    • - -
    - - - - - - -

    Return value:

    -{{l1,1, ..., lr,1}, ..., {l1,c, ..., lr,c}} - - - -
    - - - - -
    zipWith (f, ls)
    -
    -Zip lists together with a function. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - ls: list of lists -
    • - -
    - - - - - - -

    Return value:

    -{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) where N = max {map (function (l) return #l end, ls)} - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/math_ext.html b/std/files/math_ext.html deleted file mode 100644 index 2a36550..0000000 --- a/std/files/math_ext.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File math_ext.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - -
    floor (n, p)Extend math.floor to take the number of decimal places.
    round (n, p)Round a number to a given number of decimal places
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    floor (n, p)
    -
    -Extend math.floor to take the number of decimal places. - - -

    Parameters

    -
      - -
    • - n: number -
    • - -
    • - p: number of decimal places to truncate to (default: 0) -
    • - -
    - - - - - - -

    Return value:

    -n truncated to p decimal places - - - -
    - - - - -
    round (n, p)
    -
    -Round a number to a given number of decimal places - - -

    Parameters

    -
      - -
    • - n: number -
    • - -
    • - p: number of decimal places to round to (default: 0) -
    • - -
    - - - - - - -

    Return value:

    -n rounded to p decimal places - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/modules.html b/std/files/modules.html deleted file mode 100644 index 2c2d73e..0000000 --- a/std/files/modules.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File modules.lua

    - - - - - - - - - - - - -
    -
    - - - - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/object.html b/std/files/object.html deleted file mode 100644 index fd5c9a1..0000000 --- a/std/files/object.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File object.lua

    - - - - - - - - - - -

    Tables

    - - - - - - - -
    ObjectRoot object
    - - - -
    -
    - - - - - - - -

    Tables

    -
    - -
    Object
    -
    Root object - - -Fields -
      - -
    • - _init: constructor method or list of fields to be initialised by the constructor -
    • - -
    • - _clone: object constructor which provides the behaviour for _init documented above -
    • - -
    - - -
    - - -
    - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/package_ext.html b/std/files/package_ext.html deleted file mode 100644 index 31f307e..0000000 --- a/std/files/package_ext.html +++ /dev/null @@ -1,206 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File package_ext.lua

    - - - - - - - - - - -

    Tables

    - - - - - - - -
    packageMake named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents).
    - - - -
    -
    - - - - - - - -

    Tables

    -
    - -
    package
    -
    Make named constants for package.config (undocumented in 5.1; see luaconf.h for C equivalents). - - -Fields -
      - -
    • - dirsep: directory separator -
    • - -
    • - pathsep: path separator -
    • - -
    • - path_mark: string that marks substitution points in a path template -
    • - -
    • - execdir: (Windows only) replaced by the executable's directory in a path -
    • - -
    • - igmark: Mark to ignore all before it when building luaopen_ function name. -
    • - -
    - - -
    - - -
    - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/set.html b/std/files/set.html deleted file mode 100644 index e9f4c08..0000000 --- a/std/files/set.html +++ /dev/null @@ -1,573 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File set.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    delete (s, e)Delete an element from a set
    difference (s, t)Find the difference of two sets
    elems (s)Iterator for sets TODO: Make the iterator return only the key
    equal (s, t)Find whether two sets are equal
    insert (s, e)Insert an element into a set
    intersection (s, t)Find the intersection of two sets
    member (s, e)Say whether an element is in a set
    propersubset (s, t)Find whether one set is a proper subset of another
    subset (s, t)Find whether one set is a subset of another
    symmetric_difference (s, t)Find the symmetric difference of two sets
    union (s, t)Find the union of two sets
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    delete (s, e)
    -
    -Delete an element from a set - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - e: element -
    • - -
    - - - - - - - - -
    - - - - -
    difference (s, t)
    -
    -Find the difference of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -s with elements of t removed - - - -
    - - - - -
    elems (s)
    -
    -Iterator for sets TODO: Make the iterator return only the key - - -

    Parameters

    -
      - -
    • - s: -
    • - -
    - - - - - - - - -
    - - - - -
    equal (s, t)
    -
    -Find whether two sets are equal - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -true if sets are equal, false otherwise - - - -
    - - - - -
    insert (s, e)
    -
    -Insert an element into a set - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - e: element -
    • - -
    - - - - - - - - -
    - - - - -
    intersection (s, t)
    -
    -Find the intersection of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -set intersection of s and t - - - -
    - - - - -
    member (s, e)
    -
    -Say whether an element is in a set - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - e: element -
    • - -
    - - - - - - -

    Return value:

    -true if e is in set, false otherwise - - - -
    - - - - -
    propersubset (s, t)
    -
    -Find whether one set is a proper subset of another - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -true if s is a proper subset of t, false otherwise - - - -
    - - - - -
    subset (s, t)
    -
    -Find whether one set is a subset of another - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -true if s is a subset of t, false otherwise - - - -
    - - - - -
    symmetric_difference (s, t)
    -
    -Find the symmetric difference of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -elements of s and t that are in s or t but not both - - - -
    - - - - -
    union (s, t)
    -
    -Find the union of two sets - - -

    Parameters

    -
      - -
    • - s: set -
    • - -
    • - t: set -
    • - -
    - - - - - - -

    Return value:

    -set union of s and t - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/strbuf.html b/std/files/strbuf.html deleted file mode 100644 index 6affbaf..0000000 --- a/std/files/strbuf.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File strbuf.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - -
    concat (b, s)Add a string to a buffer
    tostring (b)Convert a buffer to a string
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    concat (b, s)
    -
    -Add a string to a buffer - - -

    Parameters

    -
      - -
    • - b: buffer -
    • - -
    • - s: string to add -
    • - -
    - - - - - - -

    Return value:

    -buffer - - - -
    - - - - -
    tostring (b)
    -
    -Convert a buffer to a string - - -

    Parameters

    -
      - -
    • - b: buffer -
    • - -
    - - - - - - -

    Return value:

    -string - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/strict.html b/std/files/strict.html deleted file mode 100644 index 9550e95..0000000 --- a/std/files/strict.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File strict.lua

    - - - - - - - - - - - - -
    -
    - - - - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/string_ext.html b/std/files/string_ext.html deleted file mode 100644 index 570fb18..0000000 --- a/std/files/string_ext.html +++ /dev/null @@ -1,1105 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File string_ext.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    caps (s)Capitalise each word in a string.
    chomp (s)Remove any final newline from a string.
    escape_pattern (s)Escape a string to be used as a pattern
    finds (s, p, init, plain)Do multiple finds on a string.
    ltrim (s, r)Remove leading matter from a string.
    numbertosi (n)Write a number using SI suffixes.
    ordinal_suffix (n)Return the English suffix for an ordinal.
    pad (s, w, p)Justify a string.
    pickle (x)Convert a value to a string.
    prettytostring (t, indent, spacing)Pretty-print a table.
    render (x, open, close, elem, pair, sep, roots)Turn tables into strings with recursion detection.
    render_CloseRenderer (t)
    render_ElementRenderer (e)
    render_OpenRenderer (t)
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    render_SeparatorRenderer (t, i, v, j, w)
    require_version (module, min, too_big, pattern)Require a module with a particular version
    rtrim (s, r)Remove trailing matter from a string.
    split (s, sep)Split a string at a given separator.
    tfind (s, p, init, plain)Do find, returning captures as a list.
    tostring (x)Extend tostring to work better on tables.
    trim (s, r)Remove leading and trailing matter from a string.
    wrap (s, w, ind, ind1)Wrap a string into a paragraph.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    caps (s)
    -
    -Capitalise each word in a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    - - - - - - -

    Return value:

    -capitalised string - - - -
    - - - - -
    chomp (s)
    -
    -Remove any final newline from a string. - - -

    Parameters

    -
      - -
    • - s: string to process -
    • - -
    - - - - - - -

    Return value:

    -processed string - - - -
    - - - - -
    escape_pattern (s)
    -
    -Escape a string to be used as a pattern - - -

    Parameters

    -
      - -
    • - s: string to process @return -
    • - -
    - - - - - - - - -
    - - - - -
    finds (s, p, init, plain)
    -
    -Do multiple finds on a string. - - -

    Parameters

    -
      - -
    • - s: target string -
    • - -
    • - p: pattern -
    • - -
    • - init: start position (default: 1) -
    • - -
    • - plain: inhibit magic characters (default: nil) -
    • - -
    - - - - - - -

    Return value:

    -list of {from, to; capt = {captures}} - - - -
    - - - - -
    ltrim (s, r)
    -
    -Remove leading matter from a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    • - r: leading pattern (default: "%s+") -
    • - -
    - - - - - - -

    Return value:

    -string without leading r - - - -
    - - - - -
    numbertosi (n)
    -
    -Write a number using SI suffixes. The number is always written to 3 s.f. - - -

    Parameters

    -
      - -
    • - n: number -
    • - -
    - - - - - - -

    Return value:

    -string - - - -
    - - - - -
    ordinal_suffix (n)
    -
    -Return the English suffix for an ordinal. - - -

    Parameters

    -
      - -
    • - n: number of the day -
    • - -
    - - - - - - -

    Return value:

    -suffix - - - -
    - - - - -
    pad (s, w, p)
    -
    -Justify a string. When the string is longer than w, it is truncated (left or right according to the sign of w). - - -

    Parameters

    -
      - -
    • - s: string to justify -
    • - -
    • - w: width to justify to (-ve means right-justify; +ve means left-justify) -
    • - -
    • - p: string to pad with (default: " ") -
    • - -
    - - - - - - -

    Return value:

    -justified string - - - -
    - - - - -
    pickle (x)
    -
    -Convert a value to a string. The string can be passed to dostring to retrieve the value.
    TODO: Make it work for recursive tables. - - -

    Parameters

    -
      - -
    • - x: object to pickle -
    • - -
    - - - - - - -

    Return value:

    -string such that eval (s) is the same value as x - - - -
    - - - - -
    prettytostring (t, indent, spacing)
    -
    -Pretty-print a table. - - -

    Parameters

    -
      - -
    • - t: table to print -
    • - -
    • - indent: indent between levels ["\t"] -
    • - -
    • - spacing: space before every line -
    • - -
    - - - - - - -

    Return value:

    -pretty-printed string - - - -
    - - - - -
    render (x, open, close, elem, pair, sep, roots)
    -
    -Turn tables into strings with recursion detection. N.B. Functions calling render should not recurse, or recursion detection will not work. - - -

    Parameters

    -
      - -
    • - x: object to convert to string -
    • - -
    • - open: open table renderer -
    • - -
    • - close: close table renderer -
    • - -
    • - elem: element renderer -
    • - -
    • - pair: pair renderer -
    • - -
    • - sep: separator renderer -
    • - -
    • - roots: -
    • - -
    - - - - - - -

    Return value:

    -string representation - - - -

    See also:

    - - -
    - - - - -
    render_CloseRenderer (t)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -close table string - - - -
    - - - - -
    render_ElementRenderer (e)
    -
    - - - -

    Parameters

    -
      - -
    • - e: element -
    • - -
    - - - - - - -

    Return value:

    -element string - - - -
    - - - - -
    render_OpenRenderer (t)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -open table string - - - -
    - - - - -
    render_PairRenderer N.B. the function should not try to render i and v, or treat them recursively. (t, i, v, is, vs)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - i: index -
    • - -
    • - v: value -
    • - -
    • - is: index string -
    • - -
    • - vs: value string -
    • - -
    - - - - - - -

    Return value:

    -element string - - - -
    - - - - -
    render_SeparatorRenderer (t, i, v, j, w)
    -
    - - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - i: preceding index (nil on first call) -
    • - -
    • - v: preceding value (nil on first call) -
    • - -
    • - j: following index (nil on last call) -
    • - -
    • - w: following value (nil on last call) -
    • - -
    - - - - - - -

    Return value:

    -separator string - - - -
    - - - - -
    require_version (module, min, too_big, pattern)
    -
    -Require a module with a particular version - - -

    Parameters

    -
      - -
    • - module: module to require -
    • - -
    • - min: lowest acceptable version (default: any) -
    • - -
    • - too_big: lowest version that is too big (default: none) -
    • - -
    • - pattern: -
    • - -
    - - - - - - - - -
    - - - - -
    rtrim (s, r)
    -
    -Remove trailing matter from a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    • - r: trailing pattern (default: "%s+") -
    • - -
    - - - - - - -

    Return value:

    -string without trailing r - - - -
    - - - - -
    split (s, sep)
    -
    -Split a string at a given separator. FIXME: Consider Perl and Python versions. - - -

    Parameters

    -
      - -
    • - s: string to split -
    • - -
    • - sep: separator pattern -
    • - -
    - - - - - - -

    Return value:

    -list of strings - - - -
    - - - - -
    tfind (s, p, init, plain)
    -
    -Do find, returning captures as a list. - - -

    Parameters

    -
      - -
    • - s: target string -
    • - -
    • - p: pattern -
    • - -
    • - init: start position (default: 1) -
    • - -
    • - plain: inhibit magic characters (default: nil) -
    • - -
    - - - - - - -

    Return value:

    -start of match, end of match, table of captures - - - -
    - - - - -
    tostring (x)
    -
    -Extend tostring to work better on tables. - - -

    Parameters

    -
      - -
    • - x: object to convert to string -
    • - -
    - - - - - - -

    Return value:

    -string representation - - - -
    - - - - -
    trim (s, r)
    -
    -Remove leading and trailing matter from a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    • - r: leading/trailing pattern (default: "%s+") -
    • - -
    - - - - - - -

    Return value:

    -string without leading/trailing r - - - -
    - - - - -
    wrap (s, w, ind, ind1)
    -
    -Wrap a string into a paragraph. - - -

    Parameters

    -
      - -
    • - s: string to wrap -
    • - -
    • - w: width to wrap to (default: 78) -
    • - -
    • - ind: indent (default: 0) -
    • - -
    • - ind1: indent of first line (default: ind) -
    • - -
    - - - - - - -

    Return value:

    -wrapped paragraph - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/table_ext.html b/std/files/table_ext.html deleted file mode 100644 index b0ecf02..0000000 --- a/std/files/table_ext.html +++ /dev/null @@ -1,528 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File table_ext.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    clone (t, nometa)Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone).
    clone_rename (map, t)Clone a table, renaming some keys.
    empty (t)Return whether table is empty.
    invert (t)Invert a table.
    keys (t)Make the list of keys of a table.
    merge (t, u)Merge one table into another.
    new (x, t)Make a table with a default value for unset keys.
    size (t)Find the number of elements in a table.
    sort (t, c)Make table.sort return its result.
    values (t)Make the list of values of a table.
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    clone (t, nometa)
    -
    -Make a shallow copy of a table, including any metatable (for a deep copy, use tree.clone). - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - nometa: if non-nil don't copy metatable -
    • - -
    - - - - - - -

    Return value:

    -copy of table - - - -
    - - - - -
    clone_rename (map, t)
    -
    -Clone a table, renaming some keys. - - -

    Parameters

    -
      - -
    • - map: table {old_key=new_key, ...} -
    • - -
    • - t: table to copy -
    • - -
    - - - - - - -

    Return value:

    -copy of table - - - -
    - - - - -
    empty (t)
    -
    -Return whether table is empty. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -true if empty or false otherwise - - - -
    - - - - -
    invert (t)
    -
    -Invert a table. - - -

    Parameters

    -
      - -
    • - t: table {i=v, ...} -
    • - -
    - - - - - - -

    Return value:

    -inverted table {v=i, ...} - - - -
    - - - - -
    keys (t)
    -
    -Make the list of keys of a table. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -list of keys - - - -
    - - - - -
    merge (t, u)
    -
    -Merge one table into another. u is merged into t. - - -

    Parameters

    -
      - -
    • - t: first table -
    • - -
    • - u: second table -
    • - -
    - - - - - - -

    Return value:

    -first table - - - -
    - - - - -
    new (x, t)
    -
    -Make a table with a default value for unset keys. - - -

    Parameters

    -
      - -
    • - x: default entry value (default: nil) -
    • - -
    • - t: initial table (default: {}) -
    • - -
    - - - - - - -

    Return value:

    -table whose unset elements are x - - - -
    - - - - -
    size (t)
    -
    -Find the number of elements in a table. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -number of elements in t - - - -
    - - - - -
    sort (t, c)
    -
    -Make table.sort return its result. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - c: comparator function -
    • - -
    - - - - - - -

    Return value:

    -sorted table - - - -
    - - - - -
    values (t)
    -
    -Make the list of values of a table. - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -list of values - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/files/tree.html b/std/files/tree.html deleted file mode 100644 index 82b7934..0000000 --- a/std/files/tree.html +++ /dev/null @@ -1,355 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    File tree.lua

    - - - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    clone (t, nometa)Make a deep copy of a tree, including any metatables
    merge (t, u)Deep-merge one tree into another.
    metatable.__index (tr, i)Tree __index metamethod.
    metatable.__newindex (tr, i, v)Tree __newindex metamethod.
    new (t)Make a table into a tree
    - - - - - - -
    -
    - - - - -

    Functions

    -
    - - - -
    clone (t, nometa)
    -
    -Make a deep copy of a tree, including any metatables - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    • - nometa: if non-nil don't copy metatables -
    • - -
    - - - - - - -

    Return value:

    -copy of table - - - -
    - - - - -
    merge (t, u)
    -
    -Deep-merge one tree into another. u is merged into t. - - -

    Parameters

    -
      - -
    • - t: first tree -
    • - -
    • - u: second tree -
    • - -
    - - - - - - -

    Return value:

    -first tree - - - -
    - - - - -
    metatable.__index (tr, i)
    -
    -Tree __index metamethod. - - -

    Parameters

    -
      - -
    • - tr: tree -
    • - -
    • - i: non-table, or list of keys {i1 ... in} -
    • - -
    - - - - - - -

    Return value:

    -tr[i]...[in] if i is a table, or tr[i] otherwise - - - -
    - - - - -
    metatable.__newindex (tr, i, v)
    -
    -Tree __newindex metamethod. Sets tr[i1]...[in] = v if i is a table, or tr[i] = v otherwise - - -

    Parameters

    -
      - -
    • - tr: tree -
    • - -
    • - i: non-table, or list of keys {i1 ... in} -
    • - -
    • - v: value -
    • - -
    - - - - - - - - -
    - - - - -
    new (t)
    -
    -Make a table into a tree - - -

    Parameters

    -
      - -
    • - t: table -
    • - -
    - - - - - - -

    Return value:

    -tree - - - -
    - - -
    - - - - - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/index.html b/std/index.html deleted file mode 100644 index c5814e7..0000000 --- a/std/index.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - - - -

    Modules

    - - - - - - - - -
    baseAdds to the existing global functions
    - - - - - -

    Files

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    base.lua
    debug_ext.lua
    debug_init.lua
    getopt.lua
    io_ext.lua
    list.lua
    math_ext.lua
    modules.lua
    object.lua
    package_ext.lua
    set.lua
    strbuf.lua
    strict.lua
    string_ext.lua
    table_ext.lua
    tree.lua
    - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/list.lua b/std/list.lua deleted file mode 100644 index 6b614d9..0000000 --- a/std/list.lua +++ /dev/null @@ -1,467 +0,0 @@ ---- Tables as lists. -require "std.base" - -local new -- forward declaration - ---- An iterator over the elements of a list. --- @param l list to iterate over --- @return iterator function which returns successive elements of the list --- @return the list l as above --- @return true -local function elems (l) - local n = 0 - return function (l) - n = n + 1 - if n <= #l then - return l[n] - end - end, - l, true -end - ---- An iterator over the elements of a list, in reverse. --- @param l list to iterate over --- @return iterator function which returns precessive elements of the list --- @return the list l as above --- @return true -local function relems (l) - local n = #l + 1 - return function (l) - n = n - 1 - if n > 0 then - return l[n] - end - end, - l, true -end - ---- Map a function over a list. --- @param f function --- @param l list --- @return result list {f (l[1]), ..., f (l[#l])} -local function map (f, l) - return _G.map (f, elems, l) -end - ---- Map a function over a list of lists. --- @param f function --- @param ls list of lists --- @return result list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} -local function mapWith (f, l) - return _G.map (compose (f, unpack), elems, l) -end - ---- Filter a list according to a predicate. --- @param p predicate (function of one argument returning a boolean) --- @param l list of lists --- @return result list containing elements e of --- l for which p (e) is true -local function filter (p, l) - return _G.filter (p, elems, l) -end - ---- Return a sub-range of a list. (The equivalent of string.sub --- on strings; negative list indices count from the end of the list.) --- @param l list --- @param from start of range (default: 1) --- @param to end of range (default: #l) --- @return {l[from], ..., l[to]} -local function sub (l, from, to) - local r = new () - local len = #l - from = from or 1 - to = to or len - if from < 0 then - from = from + len + 1 - end - if to < 0 then - to = to + len + 1 - end - for i = from, to do - table.insert (r, l[i]) - end - return r -end - ---- Return a list with its first element removed. --- @param l list --- @return {l[2], ..., l[#l]} -local function tail (l) - return sub (l, 2) -end - ---- Fold a binary function through a list left associatively. --- @param f function --- @param e element to place in left-most position --- @param l list --- @return result -local function foldl (f, e, l) - return fold (f, e, elems, l) -end - ---- Fold a binary function through a list right associatively. --- @param f function --- @param e element to place in right-most position --- @param l list --- @return result -local function foldr (f, e, l) - return fold (function (x, y) return f (y, x) end, - e, relems, l) -end - ---- Prepend an item to a list. --- @param l list --- @param x item --- @return {x, unpack (l)} -local function cons (l, x) - return {x, unpack (l)} -end - ---- Append an item to a list. --- @param l list --- @param x item --- @return {l[1], ..., l[#l], x} -local function append (l, x) - local r = {unpack (l)} - table.insert (r, x) - return r -end - ---- Concatenate lists. --- @param ... lists --- @return {l1[1], ..., --- l1[#l1], ..., ln[1], ..., --- ln[#ln]} -local function concat (...) - local r = new () - for l in elems ({...}) do - for v in elems (l) do - table.insert (r, v) - end - end - return r -end - ---- Repeat a list. --- @param l list --- @param n number of times to repeat --- @return n copies of l appended together -local function rep (l, n) - local r = new () - for i = 1, n do - r = concat (r, l) - end - return r -end - ---- Reverse a list. --- @param l list --- @return list {l[#l], ..., l[1]} -local function reverse (l) - local r = new () - for i = #l, 1, -1 do - table.insert (r, l[i]) - end - return r -end - ---- Transpose a list of lists. --- This function in Lua is equivalent to zip and unzip in more --- strongly typed languages. --- @param ls {{l1,1, ..., l1,c}, ..., --- {lr,1, ..., lr,c}} --- @return {{l1,1, ..., lr,1}, ..., --- {l1,c, ..., lr,c}} -local function transpose (ls) - local rs, len = new (), #ls - for i = 1, math.max (unpack (map (function (l) return #l end, ls))) do - rs[i] = new () - for j = 1, len do - rs[i][j] = ls[j][i] - end - end - return rs -end - ---- Zip lists together with a function. --- @param f function --- @param ls list of lists --- @return {f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) --- where N = max {map (function (l) return #l end, ls)} -local function zipWith (f, ls) - return mapWith (f, transpose (ls)) -end - ---- Project a list of fields from a list of tables. --- @param f field to project --- @param l list of tables --- @return list of f fields -local function project (f, l) - return map (function (t) return t[f] end, l) -end - ---- Turn a table into a list of pairs. ---
    FIXME: Find a better name. --- @param t table {i1=v1, ..., --- in=vn} --- @return list {{i1, v1}, ..., --- {in, vn}} -local function enpair (t) - local ls = new () - for i, v in pairs (t) do - table.insert (ls, {i, v}) - end - return ls -end - ---- Turn a list of pairs into a table. ---
    FIXME: Find a better name. --- @param ls list {{i1, v1}, ..., --- {in, vn}} --- @return table {i1=v1, ..., --- in=vn} -local function depair (ls) - local t = {} - for v in elems (ls) do - t[v[1]] = v[2] - end - return t -end - - -local function _leaves (it, tr) - local function visit (n) - if type (n) == "table" then - for _, v in it (n) do - visit (v) - end - else - coroutine.yield (n) - end - end - return coroutine.wrap (visit), tr -end - ---- Tree iterator which returns just numbered leaves, in order. --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -local function ileaves (tr) - return _leaves (ipairs, tr) -end - ---- Tree iterator which returns just leaves. --- @param tr tree to iterate over --- @return iterator function --- @return the tree, as above -local function leaves (tr) - return _leaves (pairs, tr) -end - ---- Flatten a list. --- @param l list to flatten --- @return flattened list -local function flatten (l) - local r = new () - for v in ileaves (l) do - table.insert (r, v) - end - return r -end - ---- Shape a list according to a list of dimensions. --- --- Dimensions are given outermost first and items from the original --- list are distributed breadth first; there may be one 0 indicating --- an indefinite number. Hence, {0} is a flat list, --- {1} is a singleton, {2, 0} is a list of --- two lists, and {0, 2} is a list of pairs. ---
    --- Algorithm: turn shape into all positive numbers, calculating --- the zero if necessary and making sure there is at most one; --- recursively walk the shape, adding empty tables until the bottom --- level is reached at which point add table items instead, using a --- counter to walk the flattened original list. ---
    --- @param s {d1, ..., dn} --- @param l list to reshape --- @return reshaped list --- FIXME: Use ileaves instead of flatten (needs a while instead of a --- for in fill function) -local function shape (s, l) - l = flatten (l) - -- Check the shape and calculate the size of the zero, if any - local size = 1 - local zero - for i, v in ipairs (s) do - if v == 0 then - if zero then -- bad shape: two zeros - return nil - else - zero = i - end - else - size = size * v - end - end - if zero then - s[zero] = math.ceil (#l / size) - end - local function fill (i, d) - if d > #s then - return l[i], i + 1 - else - local r = new () - for j = 1, s[d] do - local e - e, i = fill (i, d + 1) - table.insert (r, e) - end - return r, i - end - end - return (fill (1, 1)) -end - ---- Make an index of a list of tables on a given field --- @param f field --- @param l list of tables {t1, ..., --- tn} --- @return index {t1[f]=1, ..., --- tn[f]=n} -local function indexKey (f, l) - local r = new () - for i, v in ipairs (l) do - local k = v[f] - if k then - r[k] = i - end - end - return r -end - ---- Copy a list of tables, indexed on a given field --- @param f field whose value should be used as index --- @param l list of tables {i1=t1, ..., --- in=tn} --- @return index {t1[f]=t1, ..., --- tn[f]=tn} -local function indexValue (f, l) - local r = new () - for i, v in ipairs (l) do - local k = v[f] - if k then - r[k] = v - end - end - return r -end -permuteOn = indexValue - ---- Compare two lists element by element left-to-right --- @param l first list --- @param m second list --- @return -1 if l is less than m, 0 if they --- are the same, and 1 if l is greater than m -local function compare (l, m) - for i = 1, math.min (#l, #m) do - if l[i] < m[i] then - return -1 - elseif l[i] > m[i] then - return 1 - end - end - if #l < #m then - return -1 - elseif #l > #m then - return 1 - end - return 0 -end - --- Methods for lists -local methods = { - append = append, - compare = compare, - concat = concat, - cons = cons, - depair = depair, - elems = elems, - filter = function (self, p) return filter (p, self) end, - flatten = flatten, - foldl = function (self, f, e) return foldl (f, e, self) end, - foldr = function (self, f, e) return foldr (f, e, self) end, - indexKey = function (self, f) return indexKey (self, f) end, - indexValue = function (self, f) return indexValue (self, f) end, - map = function (self, f) return map (f, self) end, - mapWith = function (self, f) return mapWith (f, self) end, - project = function (self, f) return project (f, self) end, - relems = relems, - rep = rep, - reverse = reverse, - shape = function (self, s) return shape (s, self) end, - sub = sub, - tail = tail, - transpose = transpose, - zipWith = function (self, f) return zipWith (f, self) end, -} - --- Metamethods for lists -local metatable = { - -- list .. table = list.concat - __concat = concat, - -- list == list retains its referential meaning - -- list < list = list.compare returns < 0 - __lt = function (l, m) return compare (l, m) < 0 end, - -- list <= list = list.compare returns <= 0 - __le = function (l, m) return compare (l, m) <= 0 end, - __append = append, - __index = methods, -} - ---- List constructor. --- Needed in order to use metamethods. --- @param t list (as a table), or nil for empty list --- @return list (with list metamethods) -function new (l) - return setmetatable (l or {}, metatable) -end - --- Function forms of operators -_G.op[".."] = concat - --- Public interface -local M = { - append = append, - compare = compare, - concat = concat, - cons = cons, - depair = depair, - elems = elems, - enpair = enpair, - filter = filter, - flatten = flatten, - foldl = foldl, - foldr = foldr, - indexKey = indexKey, - indexValue = indexValue, - new = new, - map = map, - mapWith = mapWith, - project = project, - relems = relems, - rep = rep, - reverse = reverse, - shape = shape, - slice = sub, -- backwards compatibility - sub = sub, - tail = tail, - transpose = transpose, - zipWith = zipWith, - - -- APIs that used to be in "base". - ileaves = ileaves, - leaves = leaves, -} - -return M diff --git a/std/luadoc.css b/std/luadoc.css deleted file mode 100644 index bc0f98a..0000000 --- a/std/luadoc.css +++ /dev/null @@ -1,286 +0,0 @@ -body { - margin-left: 1em; - margin-right: 1em; - font-family: arial, helvetica, geneva, sans-serif; - background-color:#ffffff; margin:0px; -} - -code { - font-family: "Andale Mono", monospace; -} - -tt { - font-family: "Andale Mono", monospace; -} - -body, td, th { font-size: 11pt; } - -h1, h2, h3, h4 { margin-left: 0em; } - -textarea, pre, tt { font-size:10pt; } -body, td, th { color:#000000; } -small { font-size:0.85em; } -h1 { font-size:1.5em; } -h2 { font-size:1.25em; } -h3 { font-size:1.15em; } -h4 { font-size:1.06em; } - -a:link { font-weight:bold; color: #004080; text-decoration: none; } -a:visited { font-weight:bold; color: #006699; text-decoration: none; } -a:link:hover { text-decoration:underline; } -hr { color:#cccccc } -img { border-width: 0px; } - - -h3 { padding-top: 1em; } - -p { margin-left: 1em; } - -p.name { - font-family: "Andale Mono", monospace; - padding-top: 1em; - margin-left: 0em; -} - -blockquote { margin-left: 3em; } - -pre.example { - background-color: rgb(245, 245, 245); - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-style: solid; - border-right-style: solid; - border-bottom-style: solid; - border-left-style: solid; - border-top-color: silver; - border-right-color: silver; - border-bottom-color: silver; - border-left-color: silver; - padding: 1em; - margin-left: 1em; - margin-right: 1em; - font-family: "Andale Mono", monospace; - font-size: smaller; -} - - -hr { - margin-left: 0em; - background: #00007f; - border: 0px; - height: 1px; -} - -ul { list-style-type: disc; } - -table.index { border: 1px #00007f; } -table.index td { text-align: left; vertical-align: top; } -table.index ul { padding-top: 0em; margin-top: 0em; } - -table { - border: 1px solid black; - border-collapse: collapse; - margin-left: auto; - margin-right: auto; -} -th { - border: 1px solid black; - padding: 0.5em; -} -td { - border: 1px solid black; - padding: 0.5em; -} -div.header, div.footer { margin-left: 0em; } - -#container -{ - margin-left: 1em; - margin-right: 1em; - background-color: #f0f0f0; -} - -#product -{ - text-align: center; - border-bottom: 1px solid #cccccc; - background-color: #ffffff; -} - -#product big { - font-size: 2em; -} - -#product_logo -{ -} - -#product_name -{ -} - -#product_description -{ -} - -#main -{ - background-color: #f0f0f0; - border-left: 2px solid #cccccc; -} - -#navigation -{ - float: left; - width: 18em; - margin: 0; - vertical-align: top; - background-color: #f0f0f0; - overflow:visible; -} - -#navigation h1 { - background-color:#e7e7e7; - font-size:1.1em; - color:#000000; - text-align:left; - margin:0px; - padding:0.2em; - border-top:1px solid #dddddd; - border-bottom:1px solid #dddddd; -} - -#navigation ul -{ - font-size:1em; - list-style-type: none; - padding: 0; - margin: 1px; -} - -#navigation li -{ - text-indent: -1em; - margin: 0em 0em 0em 0.5em; - display: block; - padding: 3px 0px 0px 12px; -} - -#navigation li li a -{ - padding: 0px 3px 0px -1em; -} - -#content -{ - margin-left: 18em; - padding: 1em; - border-left: 2px solid #cccccc; - border-right: 2px solid #cccccc; - background-color: #ffffff; -} - -#about -{ - clear: both; - margin: 0; - padding: 5px; - border-top: 2px solid #cccccc; - background-color: #ffffff; -} - -@media print { - body { - font: 12pt "Times New Roman", "TimeNR", Times, serif; - } - a { font-weight:bold; color: #004080; text-decoration: underline; } - - #main { background-color: #ffffff; border-left: 0px; } - #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } - - #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } - - #navigation { display: none; - } - pre.example { - font-family: "Andale Mono", monospace; - font-size: 10pt; - page-break-inside: avoid; - } -} - -table.module_list td -{ - border-width: 1px; - padding: 3px; - border-style: solid; - border-color: #cccccc; -} -table.module_list td.name { background-color: #f0f0f0; } -table.module_list td.summary { width: 100%; } - -table.file_list -{ - border-width: 1px; - border-style: solid; - border-color: #cccccc; - border-collapse: collapse; -} -table.file_list td -{ - border-width: 1px; - padding: 3px; - border-style: solid; - border-color: #cccccc; -} -table.file_list td.name { background-color: #f0f0f0; } -table.file_list td.summary { width: 100%; } - - -table.function_list -{ - border-width: 1px; - border-style: solid; - border-color: #cccccc; - border-collapse: collapse; -} -table.function_list td -{ - border-width: 1px; - padding: 3px; - border-style: solid; - border-color: #cccccc; -} -table.function_list td.name { background-color: #f0f0f0; } -table.function_list td.summary { width: 100%; } - - -table.table_list -{ - border-width: 1px; - border-style: solid; - border-color: #cccccc; - border-collapse: collapse; -} -table.table_list td -{ - border-width: 1px; - padding: 3px; - border-style: solid; - border-color: #cccccc; -} -table.table_list td.name { background-color: #f0f0f0; } -table.table_list td.summary { width: 100%; } - -dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} -dl.function dd {padding-bottom: 1em;} -dl.function h3 {padding: 0; margin: 0; font-size: medium;} - -dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;} -dl.table dd {padding-bottom: 1em;} -dl.table h3 {padding: 0; margin: 0; font-size: medium;} - -#TODO: make module_list, file_list, function_list, table_list inherit from a list - diff --git a/std/modules.lua b/std/modules.lua deleted file mode 100644 index acee187..0000000 --- a/std/modules.lua +++ /dev/null @@ -1,16 +0,0 @@ -return { - "std.debug_init", - --"std.strict", - "std.base", - "std.package_ext", - "std.debug_ext", - "std.table_ext", - "std.list", - "std.tree", - "std.string_ext", - "std.math_ext", - "std.io_ext", - "std.getopt", - "std.set", - "std.strbuf", -} diff --git a/std/modules/base.html b/std/modules/base.html deleted file mode 100644 index 8382c1e..0000000 --- a/std/modules/base.html +++ /dev/null @@ -1,931 +0,0 @@ - - - - Reference - - - - - -
    - -
    - -
    -
    -
    - -
    - - - -
    - -

    Module base

    - -

    Adds to the existing global functions

    - - - - - -

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    _G.bind (f, ...)Partially apply a function.
    _G.collect (i, ...)Collect the results of an iterator.
    _G.compose (..., f1...fn)Compose functions.
    _G.curry (f, n)Curry a function.
    _G.die (...)Die with error.
    _G.eval (s)Evaluate a string.
    _G.filter (p, i, ...)Filter an iterator with a predicate.
    _G.fold (f, d, i, ...)Fold a binary function into an iterator.
    _G.id (...)Identity function.
    _G.inodes (tr)Tree iterator over numbered nodes, in order.
    _G.map (f, i, ...)Map a function over an iterator.
    _G.memoize (fn)Memoize a function, by wrapping it in a functable.
    _G.metamethod (x, n)Return given metamethod, if any, or nil.
    _G.nodes (tr)Tree iterator.
    _G.pack (...)Turn a tuple into a list.
    _G.ripairs (t)An iterator like ipairs, but in reverse.
    _G.totable (x)Turn an object into a table according to __totable metamethod.
    _G.warn (...)Give warning with the name of program and file (if any).
    tree_Iterator (it, tr, n)
    - - - - -

    Tables

    - - - - - - - -
    _G.opFunctional forms of infix operators.
    - - - -
    -
    - - - -

    Functions

    -
    - - - -
    _G.bind (f, ...)
    -
    -Partially apply a function. - - -

    Parameters

    -
      - -
    • - f: function to apply partially -
    • - -
    • - ...: arguments to bind -
    • - -
    - - - - - - -

    Return value:

    -function with ai already bound - - - -
    - - - - -
    _G.collect (i, ...)
    -
    -Collect the results of an iterator. - - -

    Parameters

    -
      - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -results of running the iterator on its arguments - - - -
    - - - - -
    _G.compose (..., f1...fn)
    -
    -Compose functions. - - -

    Parameters

    -
      - -
    • - ...: -
    • - -
    • - f1...fn: functions to compose -
    • - -
    - - - - - - -

    Return value:

    -composition of f1 ... fn - - - -
    - - - - -
    _G.curry (f, n)
    -
    -Curry a function. - - -

    Parameters

    -
      - -
    • - f: function to curry -
    • - -
    • - n: number of arguments -
    • - -
    - - - - - - -

    Return value:

    -curried version of f - - - -
    - - - - -
    _G.die (...)
    -
    -Die with error. - - -

    Parameters

    -
      - -
    • - ...: arguments for format -
    • - -
    - - - - - - - - -
    - - - - -
    _G.eval (s)
    -
    -Evaluate a string. - - -

    Parameters

    -
      - -
    • - s: string -
    • - -
    - - - - - - -

    Return value:

    -value of string - - - -
    - - - - -
    _G.filter (p, i, ...)
    -
    -Filter an iterator with a predicate. - - -

    Parameters

    -
      - -
    • - p: predicate -
    • - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -result table containing elements e for which p (e) - - - -
    - - - - -
    _G.fold (f, d, i, ...)
    -
    -Fold a binary function into an iterator. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - d: initial first argument -
    • - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -result - - - -
    - - - - -
    _G.id (...)
    -
    -Identity function. - - -

    Parameters

    -
      - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -the arguments passed to the function - - - -
    - - - - -
    _G.inodes (tr)
    -
    -Tree iterator over numbered nodes, in order. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -

    See also:

    - - -
    - - - - -
    _G.map (f, i, ...)
    -
    -Map a function over an iterator. - - -

    Parameters

    -
      - -
    • - f: function -
    • - -
    • - i: iterator -
    • - -
    • - ...: -
    • - -
    - - - - - - -

    Return value:

    -result table - - - -
    - - - - -
    _G.memoize (fn)
    -
    -Memoize a function, by wrapping it in a functable. - - -

    Parameters

    -
      - -
    • - fn: function that returns a single result -
    • - -
    - - - - - - -

    Return value:

    -memoized function - - - -
    - - - - -
    _G.metamethod (x, n)
    -
    -Return given metamethod, if any, or nil. - - -

    Parameters

    -
      - -
    • - x: object to get metamethod of -
    • - -
    • - n: name of metamethod to get -
    • - -
    - - - - - - -

    Return value:

    -metamethod function or nil if no metamethod or not a function - - - -
    - - - - -
    _G.nodes (tr)
    -
    -Tree iterator. - - -

    Parameters

    -
      - -
    • - tr: tree to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the tree, as above - -
    - - - -

    See also:

    - - -
    - - - - -
    _G.pack (...)
    -
    -Turn a tuple into a list. - - -

    Parameters

    -
      - -
    • - ...: tuple -
    • - -
    - - - - - - -

    Return value:

    -list - - - -
    - - - - -
    _G.ripairs (t)
    -
    -An iterator like ipairs, but in reverse. - - -

    Parameters

    -
      - -
    • - t: table to iterate over -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. iterator function - -
    2. the table, as above - -
    3. #t + 1 - -
    - - - -
    - - - - -
    _G.totable (x)
    -
    -Turn an object into a table according to __totable metamethod. - - -

    Parameters

    -
      - -
    • - x: object to turn into a table -
    • - -
    - - - - - - -

    Return value:

    -table or nil - - - -
    - - - - -
    _G.warn (...)
    -
    -Give warning with the name of program and file (if any). - - -

    Parameters

    -
      - -
    • - ...: arguments for format -
    • - -
    - - - - - - - - -
    - - - - -
    tree_Iterator (it, tr, n)
    -
    - - - -

    Parameters

    -
      - -
    • - it: -
    • - -
    • - tr: -
    • - -
    • - n: current node -
    • - -
    - - - - - - -

    Return values:

    -
      - -
    1. type ("leaf", "branch" (pre-order) or "join" (post-order)) - -
    2. path to node ({i1...ik}) - -
    3. node - -
    - - - -
    - - -
    - - - - -

    Tables

    -
    - -
    _G.op
    -
    Functional forms of infix operators. Defined here so that other modules can write to it. - - - -
    - - -
    - - - -
    - -
    - -
    -

    Valid XHTML 1.0!

    -
    - -
    - - diff --git a/std/object.lua b/std/object.lua deleted file mode 100644 index e9c5927..0000000 --- a/std/object.lua +++ /dev/null @@ -1,57 +0,0 @@ ---- Prototype-based objects ---
      ---
    • Create an object/class:
    • ---
        ---
      • Either, if the _init field is a list: ---
          ---
        • object/Class = prototype {value, ...; field = value, ...}
        • ---
        • Named values are assigned to the corresponding fields, and unnamed values --- to the fields given by _init.
        • ---
        ---
      • Or, if the _init field is a function: ---
          ---
        • object/Class = prototype (value, ...)
        • ---
        • The given values are passed as arguments to the _init function.
        • ---
        ---
      • An object's metatable is itself.
      • ---
      • Private fields and methods start with "_".
      • ---
      ---
    • Access an object field: object.field
    • ---
    • Call an object method: object:method (...)
    • ---
    • Call a class method: Class.method (object, ...)
    • ---
    • Add a field: object.field = x
    • ---
    • Add a method: function object:method (...) ... end
    • --- - -local table = require "std.table_ext" - - ---- Root object --- @class table --- @name Object --- @field _init constructor method or list of fields to be initialised by the --- constructor --- @field _clone object constructor which provides the behaviour for _init --- documented above -local Object = { - _init = {}, - - _clone = function (self, ...) - local object = table.clone (self) - if type (self._init) == "table" then - table.merge (object, table.clone_rename (self._init, ...)) - else - object = self._init (object, ...) - end - return setmetatable (object, object) - end, - - -- Sugar instance creation - __call = function (...) - -- First (...) gets first element of list - return (...)._clone (...) - end, -} -setmetatable (Object, Object) - -return Object diff --git a/std/set.lua b/std/set.lua deleted file mode 100644 index 0e6251a..0000000 --- a/std/set.lua +++ /dev/null @@ -1,167 +0,0 @@ -local list = require "std.list" - - --- Primitive methods (know about representation) --- The representation is a table whose tags are the elements, and --- whose values are true. - ---- Say whether an element is in a set --- @param s set --- @param e element --- @return true if e is in set, false --- otherwise -local function member (s, e) - return rawget (s.contents, e) == true -end - ---- Insert an element into a set --- @param s set --- @param e element -local function insert (s, e) - rawset (s.contents, e, true) -end - ---- Delete an element from a set --- @param s set --- @param e element -local function delete (s, e) - rawset (s.contents, e, nil) -end - ---- Make a list into a set --- @param l list --- @return set -local metatable = {} -local function new (l) - local s = setmetatable ({contents={}}, metatable) - for e in list.elems (l) do - insert (s, e) - end - return s -end - ---- Iterator for sets --- TODO: Make the iterator return only the key -local function elems (s) - return pairs (s.contents) -end - - --- High level methods (representation-independent) - -local difference, symmetric_difference, intersection, union, subset, equal - ---- Find the difference of two sets --- @param s set --- @param t set --- @return s with elements of t removed -function difference (s, t) - local r = new {} - for e in elems (s) do - if not member (t, e) then - insert (r, e) - end - end - return r -end - ---- Find the symmetric difference of two sets --- @param s set --- @param t set --- @return elements of s and t that are in s or t but not both -function symmetric_difference (s, t) - return difference (union (s, t), intersection (t, s)) -end - ---- Find the intersection of two sets --- @param s set --- @param t set --- @return set intersection of s and t -function intersection (s, t) - local r = new {} - for e in elems (s) do - if member (t, e) then - insert (r, e) - end - end - return r -end - ---- Find the union of two sets --- @param s set --- @param t set --- @return set union of s and t -function union (s, t) - local r = new {} - for e in elems (s) do - insert (r, e) - end - for e in elems (t) do - insert (r, e) - end - return r -end - ---- Find whether one set is a subset of another --- @param s set --- @param t set --- @return true if s is a subset of t, false --- otherwise -function subset (s, t) - for e in elems (s) do - if not member (t, e) then - return false - end - end - return true -end - ---- Find whether one set is a proper subset of another --- @param s set --- @param t set --- @return true if s is a proper subset of t, false otherwise -function propersubset (s, t) - return subset (s, t) and not subset (t, s) -end - ---- Find whether two sets are equal --- @param s set --- @param t set --- @return true if sets are equal, false --- otherwise -function equal (s, t) - return subset (s, t) and subset (t, s) -end - --- Public interface -local M = { - delete = delete, - difference = difference, - elems = elems, - equal = equal, - insert = insert, - intersection = intersection, - member = member, - new = new, - subset = subset, - symmetric_difference = symmetric_difference, - union = union, -} - ---- Metamethods for sets --- set:method () -metatable.__index = M --- set + table = union -metatable.__add = union --- set - table = set difference -metatable.__sub = difference --- set * table = intersection -metatable.__mul = intersection --- set / table = symmetric difference -metatable.__div = symmetric_difference --- set <= table = subset -metatable.__le = subset --- set < table = proper subset -metatable.__lt = propersubset - -return M diff --git a/std/std.lua b/std/std.lua deleted file mode 100644 index ecac189..0000000 --- a/std/std.lua +++ /dev/null @@ -1,48 +0,0 @@ ---- Lua standard library ---
        ---
      • TODO: Write a style guide (indenting/wrapping, capitalisation, --- function and variable names); library functions should call --- error, not die; OO vs non-OO (a thorny problem).
      • ---
      • TODO: Add tests for each function immediately after the function; --- this also helps to check module dependencies.
      • ---
      • TODO: pre-compile.
      • ---
      -local version = "General Lua libraries / 35" - -for _, m in ipairs (require "std.modules") do - if m:match "_ext$" ~= nil then - -- Inject stdlib extensions directly into global package namespaces. - local t = m:match "std%.(.*)_ext$" - for k, v in pairs (require (m)) do - _G[t][k] = v - end - else - _G[m:match "std%.(.*)$"] = require (m) - end -end - --- Add io functions to the file handle metatable. -local file_metatable = getmetatable (io.stdin) -file_metatable.readlines = io.readlines -file_metatable.writelines = io.writelines - --- Maintain old global interface access points. -for _, api in ipairs { - "assert", - "ileaves", - "leaves", - "pickle", - "prettytostring", - "render", - "require_version", - "tostring", -} do - _G[api] = list[api] or _G[api] - _G[api] = string[api] or _G[api] -end - -local M = { - version = version, -} - -return M diff --git a/std/std.lua.in b/std/std.lua.in deleted file mode 100644 index 0b4b504..0000000 --- a/std/std.lua.in +++ /dev/null @@ -1,48 +0,0 @@ ---- Lua standard library ---
        ---
      • TODO: Write a style guide (indenting/wrapping, capitalisation, --- function and variable names); library functions should call --- error, not die; OO vs non-OO (a thorny problem).
      • ---
      • TODO: Add tests for each function immediately after the function; --- this also helps to check module dependencies.
      • ---
      • TODO: pre-compile.
      • ---
      -local version = "General Lua libraries / @VERSION@" - -for _, m in ipairs (require "std.modules") do - if m:match "_ext$" ~= nil then - -- Inject stdlib extensions directly into global package namespaces. - local t = m:match "std%.(.*)_ext$" - for k, v in pairs (require (m)) do - _G[t][k] = v - end - else - _G[m:match "std%.(.*)$"] = require (m) - end -end - --- Add io functions to the file handle metatable. -local file_metatable = getmetatable (io.stdin) -file_metatable.readlines = io.readlines -file_metatable.writelines = io.writelines - --- Maintain old global interface access points. -for _, api in ipairs { - "assert", - "ileaves", - "leaves", - "pickle", - "prettytostring", - "render", - "require_version", - "tostring", -} do - _G[api] = list[api] or _G[api] - _G[api] = string[api] or _G[api] -end - -local M = { - version = version, -} - -return M diff --git a/std/std.mk b/std/std.mk deleted file mode 100644 index 6dce04b..0000000 --- a/std/std.mk +++ /dev/null @@ -1,62 +0,0 @@ -# lua-stdlib make rules. - - -## ------ ## -## Build. ## -## ------ ## - -## Use, e.g. `require "std.list"` for individual modules. -nobase_dist_lua_DATA = \ - std/base.lua \ - std/debug_ext.lua \ - std/debug_init.lua \ - std/getopt.lua \ - std/io_ext.lua \ - std/list.lua \ - std/math_ext.lua \ - std/modules.lua \ - std/object.lua \ - std/package_ext.lua \ - std/set.lua \ - std/strbuf.lua \ - std/strict.lua \ - std/string_ext.lua \ - std/table_ext.lua \ - std/tree.lua \ - $(NOTHING_ELSE) - -## But, `require "std"` for core module. -dist_lua_DATA = \ - std/std.lua \ - $(NOTHING_ELSE) - -# In order to avoid regenerating std.lua at configure time, which -# causes the documentation to be rebuilt and hence requires users to -# have luadoc installed, put std/std.lua in as a Makefile dependency. -# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) -std/std.lua: std/std.lua.in - ./config.status --file=$@ - - -## ------------- ## -## Distribution. ## -## ------------- ## - -EXTRA_DIST += \ - std/std.lua.in \ - $(NOTHING_ELSE) - - -## -------------- ## -## Documentation. ## -## -------------- ## - -dist_doc_DATA += \ - $(srcdir)/std/index.html \ - $(srcdir)/std/luadoc.css - -dist_files_DATA += $(wildcard $(srcdir)/std/files/*.html) -dist_modules_DATA += $(wildcard $(srcdir)/std/modules/*.html) - -$(dist_doc_DATA): $(nobase_dist_lua_DATA) - cd $(srcdir)/std && $(LUADOC) *.lua diff --git a/std/strbuf.lua b/std/strbuf.lua deleted file mode 100644 index 66d77cf..0000000 --- a/std/strbuf.lua +++ /dev/null @@ -1,41 +0,0 @@ ---- String buffers - ---- Create a new string buffer -local metatable = {} -local function new () - return setmetatable ({}, metatable) -end - ---- Add a string to a buffer --- @param b buffer --- @param s string to add --- @return buffer -local function concat (b, s) - table.insert (b, s) - return b -end - ---- Convert a buffer to a string --- @param b buffer --- @return string -local function tostring (b) - return table.concat (b) -end - - --- Public interface -local M = { - concat = concat, - new = new, - tostring = tostring, -} - ---- Metamethods for string buffers --- buffer:method () -metatable.__index = M --- buffer .. string -metatable.__concat = concat --- tostring -metatable.__tostring = tostring - -return M diff --git a/std/table_ext.lua b/std/table_ext.lua deleted file mode 100644 index 0278c77..0000000 --- a/std/table_ext.lua +++ /dev/null @@ -1,135 +0,0 @@ --- Extensions to the table module - -local _sort = table.sort ---- Make table.sort return its result. --- @param t table --- @param c comparator function --- @return sorted table -local function sort (t, c) - _sort (t, c) - return t -end - ---- Return whether table is empty. --- @param t table --- @return true if empty or false otherwise -local function empty (t) - return not next (t) -end - ---- Find the number of elements in a table. --- @param t table --- @return number of elements in t -local function size (t) - local n = 0 - for _ in pairs (t) do - n = n + 1 - end - return n -end - ---- Make the list of keys of a table. --- @param t table --- @return list of keys -local function keys (t) - local u = {} - for i, v in pairs (t) do - table.insert (u, i) - end - return u -end - ---- Make the list of values of a table. --- @param t table --- @return list of values -local function values (t) - local u = {} - for i, v in pairs (t) do - table.insert (u, v) - end - return u -end - ---- Invert a table. --- @param t table {i=v, ...} --- @return inverted table {v=i, ...} -local function invert (t) - local u = {} - for i, v in pairs (t) do - u[v] = i - end - return u -end - ---- Make a shallow copy of a table, including any metatable (for a --- deep copy, use tree.clone). --- @param t table --- @param nometa if non-nil don't copy metatable --- @return copy of table -local function clone (t, nometa) - local u = {} - if not nometa then - setmetatable (u, getmetatable (t)) - end - for i, v in pairs (t) do - u[i] = v - end - return u -end - ---- Clone a table, renaming some keys. --- @param map table {old_key=new_key, ...} --- @param t table to copy --- @return copy of table -local function clone_rename (map, t) - local r = clone (t) - for i, v in pairs (map) do - r[v] = t[i] - r[i] = nil - end - return r -end - ---- Merge one table into another. u is merged into t. --- @param t first table --- @param u second table --- @return first table -local function merge (t, u) - for i, v in pairs (u) do - t[i] = v - end - return t -end - ---- Make a table with a default value for unset keys. --- @param x default entry value (default: nil) --- @param t initial table (default: {}) --- @return table whose unset elements are x -local function new (x, t) - return setmetatable (t or {}, - {__index = function (t, i) - return x - end}) -end - -local M = { - clone = clone, - clone_rename = clone_rename, - empty = empty, - invert = invert, - keys = keys, - merge = merge, - new = new, - size = size, - sort = sort, - values = values, - - -- Core Lua table.sort function. - _sort = _sort, -} - -for k, v in pairs (table) do - M[k] = M[k] or v -end - -return M diff --git a/std/tree.lua b/std/tree.lua deleted file mode 100644 index 156ec9f..0000000 --- a/std/tree.lua +++ /dev/null @@ -1,104 +0,0 @@ ---- Tables as trees. -local list = require "std.list" - - -local metatable = {} ---- Make a table into a tree --- @param t table --- @return tree -local function new (t) - return setmetatable (t or {}, metatable) -end - ---- Tree __index metamethod. --- @param tr tree --- @param i non-table, or list of keys {i1 ... --- in} --- @return tr[i]...[in] if i is a table, or --- tr[i] otherwise -function metatable.__index (tr, i) - -- FIXME: the following doesn't treat list keys correctly - -- e.g. tr[{{1, 2}, {3, 4}}], maybe flatten first? - if type (i) == "table" and #i > 0 then - return list.foldl (op["[]"], tr, i) - else - return rawget (tr, i) - end -end - ---- Tree __newindex metamethod. --- Sets tr[i1]...[in] = v if i is a --- table, or tr[i] = v otherwise --- @param tr tree --- @param i non-table, or list of keys {i1 ... --- in} --- @param v value -function metatable.__newindex (tr, i, v) - if type (i) == "table" then - for n = 1, #i - 1 do - if getmetatable (tr[i[n]]) ~= metatable then - rawset (tr, i[n], new ()) - end - tr = tr[i[n]] - end - rawset (tr, i[#i], v) - else - rawset (tr, i, v) - end -end - ---- Make a deep copy of a tree, including any metatables --- @param t table --- @param nometa if non-nil don't copy metatables --- @return copy of table -local function clone (t, nometa) - local r = {} - if not nometa then - setmetatable (r, getmetatable (t)) - end - local d = {[t] = r} - local function copy (o, x) - for i, v in pairs (x) do - if type (v) == "table" then - if not d[v] then - d[v] = {} - if not nometa then - setmetatable (d[v], getmetatable (v)) - end - o[i] = copy (d[v], v) - else - o[i] = d[v] - end - else - o[i] = v - end - end - return o - end - return copy (r, t) -end - ---- Deep-merge one tree into another. u is merged into ---- t. --- @param t first tree --- @param u second tree --- @return first tree -local function merge (t, u) - for ty, p, n in nodes (u) do - if ty == "leaf" then - t[p] = n - end - end - return t -end - --- Public interface -local M = { - clone = clone, - ileaves = list.ileaves, - leaves = list.leaves, - merge = merge, - new = new, -} - -return M diff --git a/stdlib-36-1.rockspec b/stdlib-36-1.rockspec new file mode 100644 index 0000000..0b24e86 --- /dev/null +++ b/stdlib-36-1.rockspec @@ -0,0 +1,40 @@ +package = "stdlib" +version = "36-1" +description = { + detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt.", + homepage = "http://rrthomas.github.io/lua-stdlib", + license = "MIT/X11", + summary = "General Lua Libraries", +} +source = { + dir = "stdlib-release-v36", + url = "http://github.com/rrthomas/lua-stdlib/archive/release-v36.zip", +} +dependencies = { + "lua >= 5.1", +} +external_dependencies = nil +build = { + modules = { + std = "lib/std.lua", + ["std.base"] = "lib/std/base.lua", + ["std.container"] = "lib/std/container.lua", + ["std.debug"] = "lib/std/debug.lua", + ["std.debug_init"] = "lib/std/debug_init.lua", + ["std.functional"] = "lib/std/functional.lua", + ["std.getopt"] = "lib/std/getopt.lua", + ["std.io"] = "lib/std/io.lua", + ["std.list"] = "lib/std/list.lua", + ["std.math"] = "lib/std/math.lua", + ["std.modules"] = "lib/std/modules.lua", + ["std.object"] = "lib/std/object.lua", + ["std.package"] = "lib/std/package.lua", + ["std.set"] = "lib/std/set.lua", + ["std.strbuf"] = "lib/std/strbuf.lua", + ["std.strict"] = "lib/std/strict.lua", + ["std.string"] = "lib/std/string.lua", + ["std.table"] = "lib/std/table.lua", + ["std.tree"] = "lib/std/tree.lua", + }, + type = "builtin", +} diff --git a/lua-stdlib-35-1.rockspec b/stdlib-git-1.rockspec similarity index 62% rename from lua-stdlib-35-1.rockspec rename to stdlib-git-1.rockspec index 32620c5..161f21f 100644 --- a/lua-stdlib-35-1.rockspec +++ b/stdlib-git-1.rockspec @@ -1,22 +1,21 @@ -package = "lua-stdlib" -version = "35-1" +package = "stdlib" +version = "git-1" description = { + detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt.", homepage = "http://rrthomas.github.io/lua-stdlib", license = "MIT/X11", summary = "General Lua Libraries", - detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt.", } source = { - url = "http://github.com/rrthomas/lua-stdlib/archive/release-v35.zip", - dir = "lua-stdlib-release-v35", + url = "git://github.com/rrthomas/lua-stdlib.git", } dependencies = { "lua >= 5.1", } external_dependencies = nil build = { - build_command = "./configure LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' --prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' && make clean all", - type = "command", + build_command = "./bootstrap && ./configure LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' --prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' && make clean all", copy_directories = {}, install_command = "make install luadir='$(LUADIR)'", + type = "command", } diff --git a/travis.yml.in b/travis.yml.in index 09fc7ca..1d4be12 100644 --- a/travis.yml.in +++ b/travis.yml.in @@ -6,17 +6,19 @@ env: - PACKAGE=@PACKAGE@ - ROCKSPEC=$PACKAGE-git-1.rockspec - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - - LUAROCKS_BASE=luarocks-2.0.13 + - LUAROCKS_BASE=luarocks-2.1.1 - LUAROCKS="$LUA $HOME/bin/luarocks" - - LUADOC=luarocks/bin/luadoc - - SPECL=bin/specl matrix: - - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 - - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 - - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 + - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 + - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 LUA_SUFFIX=5.2 + - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 LUA_SUFFIX=5.1 # Tool setup. install: + # Put back the links for libyaml, which are missing on recent Travis VMs + - test -f /usr/lib/libyaml.so || + sudo find /usr/lib -name 'libyaml*' -exec ln -s {} /usr/lib \; + - sudo apt-get install help2man - sudo apt-get install luajit - sudo apt-get install libluajit-5.1-dev @@ -24,37 +26,48 @@ install: - sudo apt-get install liblua5.1-dev - sudo apt-get install lua5.2 - sudo apt-get install liblua5.2-dev - # Install a recent luarocks release locally. + # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz - cd $LUAROCKS_BASE - ./configure - --prefix=$HOME --lua-version=5.1 --lua-suffix=5.1 - --with-lua-include="/usr/include/lua5.1" + --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX + --with-lua-include=$LUA_INCDIR - make all install - cd .. - # Luadoc has to be installed separately while it is Lua 5.1 only. - @LUADOC_FALSE@ sudo apt-get install luarocks - @LUADOC_FALSE@ sudo luarocks install luadoc - @LUADOC_FALSE@ mkdir -p luarocks/bin - @LUADOC_FALSE@ sed 's|^exec "[^"]*"|exec lua5.1|' `which luadoc` > $LUADOC - @LUADOC_FALSE@ chmod a+rx $LUADOC # Configure and build. script: - - ./bootstrap + # Initial bootstrap to build luarocks-config.lua, before we've + # installed our rocks. + - ./bootstrap --skip-rock-checks - ./configure LUA="$LUA" - make $LUAROCKS_CONFIG LUA="$LUA" LUA_INCDIR="$LUA_INCDIR" V=1 || cat $LUAROCKS_CONFIG config.log + # Set Lua and Shell paths up for local luarocks tree. + # this package depends on will be installed. - eval `$LUAROCKS path` - export PATH=`pwd`/luarocks/bin:$PATH + + # Install extra rocks into $LUAROCKS_CONFIG rocks tree. @EXTRA_ROCKS@ + + # Make git rockspec for this package. - make rockspecs LUAROCKS="$LUAROCKS" V=1 || { $LUAROCKS path; cat $ROCKSPEC; } - # LuaRocks make will fail if dependencies are missing. - - $LUAROCKS make $ROCKSPEC - # Use bin/specl if we built it, or else the specl rock we just installed. - - test -f "$SPECL" || SPECL=luarocks/bin/specl; - make check SPECL="$SPECL" V=1 + + # The git rockspec will rerun bootstrap, and check any rock versions + # in bootstrap.conf:buildreq this time. + - $LUAROCKS make $ROCKSPEC LUA="$LUA" + + # Run self-tests in the `luarocks make` build tree. + # Use bin/specl if present, or else the specl rock from EXTRA_ROCKS + # above. + - if test -f luarocks/bin/specl; then export SPECL=luarocks/bin/specl; + elif test -f bin/specl; then export SPECL=bin/specl; fi + - export LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" + - export LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" + - export LUA_INIT=; export LUA_INIT_5_2= + - make check SPECL="$SPECL" V=1 From 51ef05f503cade231952e4f95f43ca3543b25a66 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 16 Jan 2014 11:53:21 +1300 Subject: [PATCH 19/34] rockspec: fix source.dir for mismatched project and rockspec name. * stdlib-36-1.rockspec (source.dir): Add `lua-` prefix to match the contents of the zipball from github Signed-off-by: Gary V. Vaughan --- stdlib-36-1.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib-36-1.rockspec b/stdlib-36-1.rockspec index 0b24e86..7e9574e 100644 --- a/stdlib-36-1.rockspec +++ b/stdlib-36-1.rockspec @@ -7,7 +7,7 @@ description = { summary = "General Lua Libraries", } source = { - dir = "stdlib-release-v36", + dir = "lua-stdlib-release-v36", url = "http://github.com/rrthomas/lua-stdlib/archive/release-v36.zip", } dependencies = { From c7eba233c64e6e9cbb8ca6a39e1c2be7595dffeb Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 16 Jan 2014 12:03:56 +1300 Subject: [PATCH 20/34] bootstrap: update bootstrap script. * bootstrap: Sync with slingshot. Signed-off-by: Gary V. Vaughan --- bootstrap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap b/bootstrap index 82ee636..82dcf5c 100755 --- a/bootstrap +++ b/bootstrap @@ -4206,8 +4206,8 @@ func_require_git () $opt_skip_git && GIT=true test true = "$GIT" || { - if test -f .gitignore && ($GIT --version) >/dev/null 2>&1; then :; else - GIT=true + if test -f .git; then + ($GIT --version) >/dev/null 2>&1 || GIT=true fi } From 9d9a5cfbc2df15fc07cb9bdcdaa0e09bb1b13312 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Sat, 18 Jan 2014 12:00:06 +1300 Subject: [PATCH 21/34] Release v37. Signed-off-by: Gary V. Vaughan --- .travis.yml | 28 +- ChangeLog | 115 +++ Makefile.in | 108 ++- NEWS | 26 + build-aux/mkrockspecs | 42 +- build-aux/sanity-cfg.mk | 3 + build-aux/specl.mk | 2 +- configure | 26 +- configure.ac | 4 +- doc/classes/std.container.html | 4 +- doc/classes/std.list.html | 4 +- doc/classes/std.object.html | 4 +- doc/classes/std.optparse.html | 742 ++++++++++++++++++ doc/classes/std.set.html | 4 +- doc/classes/std.strbuf.html | 4 +- doc/classes/std.tree.html | 4 +- doc/config.ld | 3 +- doc/config.ld.in | 30 + doc/index.html | 12 +- doc/modules/std.debug.html | 4 +- doc/modules/std.functional.html | 4 +- doc/modules/std.getopt.html | 248 ------ doc/modules/std.html | 55 +- doc/modules/std.io.html | 4 +- doc/modules/std.math.html | 4 +- doc/modules/std.package.html | 4 +- doc/modules/std.strict.html | 4 +- doc/modules/std.string.html | 6 +- doc/modules/std.table.html | 4 +- lib/std.lua | 33 +- lib/std.lua.in | 31 +- lib/std/base.lua | 2 + .../{debug_init.lua => debug_init/init.lua} | 0 lib/std/getopt.lua | 299 ------- lib/std/modules.lua | 2 +- lib/std/optparse.lua | 533 +++++++++++++ lib/std/set.lua | 3 +- lib/std/string.lua | 2 +- local.mk | 25 +- rockspec.conf | 4 +- specs/container_spec.yaml | 9 +- specs/debug_spec.yaml | 71 +- specs/functional_spec.yaml | 55 ++ specs/getopt_spec.yaml | 67 -- specs/io_spec.yaml | 105 ++- specs/list_spec.yaml | 8 +- specs/math_spec.yaml | 81 +- specs/object_spec.yaml | 9 +- specs/optparse_spec.yaml | 370 +++++++++ specs/package_spec.yaml | 79 +- specs/set_spec.yaml | 8 +- specs/spec_helper.lua | 29 - specs/spec_helper.lua.in | 145 ++++ specs/specs.mk | 16 +- specs/std_spec.yaml | 12 + specs/strbuf_spec.yaml | 9 +- specs/string_spec.yaml | 125 +-- specs/table_spec.yaml | 106 ++- specs/tree_spec.yaml | 33 +- stdlib-36-1.rockspec => stdlib-37-1.rockspec | 12 +- travis.yml.in | 25 +- 61 files changed, 2670 insertions(+), 1140 deletions(-) create mode 100644 build-aux/sanity-cfg.mk create mode 100644 doc/classes/std.optparse.html create mode 100644 doc/config.ld.in delete mode 100644 doc/modules/std.getopt.html rename lib/std/{debug_init.lua => debug_init/init.lua} (100%) delete mode 100644 lib/std/getopt.lua create mode 100644 lib/std/optparse.lua create mode 100644 specs/functional_spec.yaml delete mode 100644 specs/getopt_spec.yaml create mode 100644 specs/optparse_spec.yaml delete mode 100644 specs/spec_helper.lua create mode 100644 specs/spec_helper.lua.in create mode 100644 specs/std_spec.yaml rename stdlib-36-1.rockspec => stdlib-37-1.rockspec (78%) diff --git a/.travis.yml b/.travis.yml index 6f3f7be..cead315 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - LUAROCKS_BASE=luarocks-2.1.1 - LUAROCKS="$LUA $HOME/bin/luarocks" + - LDOC_ROCKSPEC=http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec matrix: - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 LUA_SUFFIX=5.2 @@ -29,12 +30,11 @@ install: # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz - - cd $LUAROCKS_BASE - - ./configure - --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX - --with-lua-include=$LUA_INCDIR - - make all install - - cd .. + - ( cd $LUAROCKS_BASE; + ./configure + --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX + --with-lua-include=$LUA_INCDIR; + make all install; ) # Configure and build. script: @@ -54,9 +54,9 @@ script: # Install extra rocks into $LUAROCKS_CONFIG rocks tree. - $LUAROCKS install lyaml; $LUAROCKS install specl; # LDoc 1.4.0 is not in luarocks yet, and LDoc master has no rockspec :( - - $LUAROCKS install http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec + - $LUAROCKS install $LDOC_ROCKSPEC - # Make git rockspec for this package. + # Make git rockspec for this stdlib - make rockspecs LUAROCKS="$LUAROCKS" V=1 || { $LUAROCKS path; cat $ROCKSPEC; } @@ -65,11 +65,7 @@ script: - $LUAROCKS make $ROCKSPEC LUA="$LUA" # Run self-tests in the `luarocks make` build tree. - # Use bin/specl if present, or else the specl rock from EXTRA_ROCKS - # above. - - if test -f luarocks/bin/specl; then export SPECL=luarocks/bin/specl; - elif test -f bin/specl; then export SPECL=bin/specl; fi - - export LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" - - export LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" - - export LUA_INIT=; export LUA_INIT_5_2= - - make check SPECL="$SPECL" V=1 + - LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" + LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" + LUA_INIT= LUA_INIT_5_2= + make check V=1 diff --git a/ChangeLog b/ChangeLog index 341c8ff..7ab60a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,120 @@ +2014-01-18 Gary V. Vaughan + + Release version 37 + * NEWS: Record release date. + + specs: make sure hell.spawn uses the same Lua as Specl examples. + * slingshot: Sync with upstream, for build-aux/specs.mk fix. + * configure.ac (AC_CONFIG_FILES): Add specs/spec_helper.lua. + * specs/spec_helper.lua: Move from here... + * specs/spec_helper.lua.in: ...to here. + * .gitignore: Add spec_helper.lua. + * specs/specs.mk (SPECL_ENV): Add $builddir/specs to LUA_PATH + for generated spec_helper.lua. + * specs/spec_helper.lua.in (LUA): Don't dig through `_G.arg`, + wait for configure substitution. + + specs: remove duplicate examples. + * specs/math_spec.yaml: forgot to remove the old namespace + corruption tests from this file when adding new check in 3507e84. + + specs: compatibility with Specl < 11. + * specs/specs.mk (specl_SPECS): Move std_spec.yaml to the end of + the list, where symbol leaks don't affect subsequent examples. + +2014-01-17 Gary V. Vaughan + + specs: compensate for table.pack differences between Lua 5.1/5.2. + * specs/table_spec (before): Make sure `extend_base` and + `enhance_base` reflect whether core table library has a `pack` + entry. + + std: lazy load submodules on demand. + * specs/std_spec.yaml: New specifications for lazy loading. + * specs/specs.mk (specl_SPECS): Add specs/std_spec.yaml. + * lib/std.lua.in (std.__index): Implement it. + * NEWS: Update. + + doc: add the package name and version to html doc page titles. + * doc/config.ld: Move from here... + * doc/config.ld.in: ...to here. Add a title setting incorporating + @PACKAGE@ and @VERSION@. + * configure.ac (AC_CONFIG_FILES): Add doc/config.ld. + * .gitignore: Add doc/config.ld. + Suggested by Dirk Laurie + + maint: plug symbol leaks with working specifications. + * specs/spec_helper.lua (show_apis): New function. Compare table + entries in a sub-process, to support tracking namespace changes + when requiring modules by various means. + * specs/functional_spec.yaml: New file. Use it to ensure + "std.functional" doesn't leak symbols. + * specs/debug_spec.yaml, specs/functional_spec.yaml, + specs/io_spec.yaml, specs/list_spec.yaml, specs/math_spec.yaml, + specs/object_spec.yaml, specs/optparse_spec.yaml, + specs/package_spec.yaml, specs/set_spec.yaml, + specs/spec_helper.lua, specs/specs.mk, specs/strbuf_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml, + specs/tree_spec.yaml: Rewrite specs that check symbol leaks + using show_apis(). + * lib/std/base.lua (new): Don't forget the forward declaration. + * lib/std/set.lua (proper_subset): Likewise. + * NEWS: Update. + Reported by Dirk Laurie + + rockspecs: update detailed description text. + * rockspec.conf (description.detailed): Remove mention of regexps + and getopt. Add mention of civilised option parsing. + + maint: cosmetic fix to imported module list. + * lib/std/modules.lua: Replace `getopt` with `optparse`. + + maint: workaround a luarocks bug handling debug_init.lua. + LuaRocks misinstalls build.modules entries ending in `init.lua`, + so rearrange the source tree and Automake rules so that + `require "std.debug_init"` still works as before even though + the file ends up in the wrong directory after installation. + * lib/std/debug_init.lua: Move from here... + * lib/std/debug_init/init.lua: ...to here. + * slingshot: upgrade for `.../init.lua` handling in mkrockspecs. + * local.mk (dist_luastd_DATA): Remove lib/std/debug_init.lua. + (dist_luastddebug_DATA): New installation dir. Add + lib/std/debug_init/init.lua. + + optparse: replace getopt with an easier to use option parser. + * specs/optparse_spec.yaml: Specify behaviour for a civilised + option parsing API. + * lib/std/optparse.lua: New module. + * lib/std/getopt.lua: Remove. + * doc/config.ld (file), local.mk (dist_luastd_DATA): Adjust. + * specs/getopt_spec.yaml: Remove. + * local.mk (dist_modules_DATA, dist_classes_DATA): Adjust. + * specs/specs.mk (specl_SPECS): Likewise. + * build-aux/sanity-cfg.mk: New file. Don't fail sanity checks on + account of 'OptionParser' in optparse.lua error message. + * NEWS: Update. + +2014-01-17 Reuben Thomas + + string.lua: fix a missing close paren in a docstring + 2014-01-16 Gary V. Vaughan + slingshot: resync for `mkrockspecs --repository` support. + * slingshot: Sync with upstream. + * local.mk (mkrockspecs_args): Add `--repository lua-stdlib`. + * .travis.yml: Regenerate. + + slingshot: sync with upstream, for bootstrap git detection fix. + * slingshot: Sync with upstream. + * bootstrap: Sync with slingshot. + + maint: post-release administrivia. + * NEWS: Add header line for next release. + * configure.ac: Bump version number to 37. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + Release version 36 * NEWS: Record release date. diff --git a/Makefile.in b/Makefile.in index 307409a..269b227 100644 --- a/Makefile.in +++ b/Makefile.in @@ -185,10 +185,12 @@ DIST_COMMON = $(srcdir)/local.mk $(srcdir)/specs/specs.mk \ INSTALL NEWS README AUTHORS ChangeLog $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(srcdir)/travis.yml.in \ - $(dist_bin_SCRIPTS) $(dist_classes_DATA) $(dist_doc_DATA) \ - $(dist_lua_DATA) $(dist_luastd_DATA) $(dist_modules_DATA) \ - COPYING build-aux/install-sh build-aux/missing \ - $(top_srcdir)/build-aux/install-sh \ + $(top_srcdir)/doc/config.ld.in \ + $(top_srcdir)/specs/spec_helper.lua.in $(dist_bin_SCRIPTS) \ + $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ + $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ + $(dist_modules_DATA) COPYING build-aux/install-sh \ + build-aux/missing $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -200,7 +202,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = .travis.yml +CONFIG_CLEAN_FILES = .travis.yml doc/config.ld specs/spec_helper.lua CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -232,8 +234,8 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" \ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" \ - "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(modulesdir)" \ - "$(DESTDIR)$(docdir)" + "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" \ + "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)" LTLIBRARIES = $(lib_LTLIBRARIES) SCRIPTS = $(bin_SCRIPTS) $(dist_bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) @@ -256,7 +258,8 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ - $(dist_luastd_DATA) $(dist_modules_DATA) $(doc_DATA) + $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ + $(dist_modules_DATA) $(doc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -366,7 +369,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 AM_CPPFLAGS = $(LUA_INCLUDE) -EXTRA_DIST = $(srcdir)/specs/spec_helper.lua $(NOTHING_ELSE) \ +EXTRA_DIST = $(srcdir)/specs/spec_helper.lua.in $(NOTHING_ELSE) \ $(specl_SPECS) $(NOTHING_ELSE) doc/config.ld lib/std.lua.in \ $(NOTHING_ELSE) $(mkrockspecs) $(package_rockspec) \ $(rockspec_conf) $(NOTHING_ELSE) @@ -386,7 +389,7 @@ man_MANS = save_release_files = $(scm_rockspec) std_path = $(abs_srcdir)/lib/?.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = 7ef01dfb840329db3d8db218bfe9d075 +old_NEWS_hash = 7a7647cb5b2d5d886a18070e1f4ac5fd update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ UPDATE_COPYRIGHT_USE_INTERVALS=1 \ @@ -398,34 +401,38 @@ dist_doc_DATA = $(srcdir)/doc/index.html $(srcdir)/doc/ldoc.css dist_classes_DATA = $(srcdir)/doc/classes/std.container.html \ $(srcdir)/doc/classes/std.list.html \ $(srcdir)/doc/classes/std.object.html \ + $(srcdir)/doc/classes/std.optparse.html \ $(srcdir)/doc/classes/std.set.html \ $(srcdir)/doc/classes/std.strbuf.html \ $(srcdir)/doc/classes/std.tree.html $(NOTHING_ELSE) dist_modules_DATA = $(srcdir)/doc/modules/std.html \ $(srcdir)/doc/modules/std.debug.html \ $(srcdir)/doc/modules/std.functional.html \ - $(srcdir)/doc/modules/std.getopt.html \ $(srcdir)/doc/modules/std.io.html \ $(srcdir)/doc/modules/std.math.html \ $(srcdir)/doc/modules/std.package.html \ $(srcdir)/doc/modules/std.strict.html \ $(srcdir)/doc/modules/std.string.html \ $(srcdir)/doc/modules/std.table.html $(NOTHING_ELSE) -SPECL_ENV = $(LUA_ENV) +specs_path = $(abs_builddir)/specs/?.lua +SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" +SPECL_OPTS = --unicode specl_SPECS = \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ - $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/functional_spec.yaml \ $(srcdir)/specs/io_spec.yaml \ $(srcdir)/specs/list_spec.yaml \ $(srcdir)/specs/math_spec.yaml \ $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/optparse_spec.yaml \ $(srcdir)/specs/package_spec.yaml \ $(srcdir)/specs/set_spec.yaml \ $(srcdir)/specs/strbuf_spec.yaml \ $(srcdir)/specs/string_spec.yaml \ $(srcdir)/specs/table_spec.yaml \ $(srcdir)/specs/tree_spec.yaml \ + $(srcdir)/specs/std_spec.yaml \ $(NOTHING_ELSE) luastddir = $(luadir)/std @@ -433,14 +440,13 @@ dist_luastd_DATA = \ lib/std/base.lua \ lib/std/container.lua \ lib/std/debug.lua \ - lib/std/debug_init.lua \ lib/std/functional.lua \ - lib/std/getopt.lua \ lib/std/io.lua \ lib/std/list.lua \ lib/std/math.lua \ lib/std/modules.lua \ lib/std/object.lua \ + lib/std/optparse.lua \ lib/std/package.lua \ lib/std/set.lua \ lib/std/strbuf.lua \ @@ -450,7 +456,18 @@ dist_luastd_DATA = \ lib/std/tree.lua \ $(NOTHING_ELSE) -mkrockspecs_args = --module-dir $(srcdir)/lib + +# For bugwards compatibility with LuaRocks 2.1, while ensuring that +# `require "std.debug_init"` continues to work, we have to install +# the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. +# When everyone has upgraded to a LuaRocks that works, move this +# file back to dist_luastd_DATA above and rename to debug_init.lua. +luastddebugdir = $(luastddir)/debug_init +dist_luastddebug_DATA = \ + lib/std/debug_init/init.lua \ + $(NOTHING_ELSE) + +mkrockspecs_args = --module-dir $(srcdir)/lib --repository lua-stdlib ldoc_DEPS = $(dist_lua_DATA) $(dist_luastd_DATA) luarocks_config = build-aux/luarocks-config.lua rockspec_conf = $(srcdir)/rockspec.conf @@ -514,6 +531,10 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): .travis.yml: $(top_builddir)/config.status $(srcdir)/travis.yml.in cd $(top_builddir) && $(SHELL) ./config.status $@ +doc/config.ld: $(top_builddir)/config.status $(top_srcdir)/doc/config.ld.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +specs/spec_helper.lua: $(top_builddir)/config.status $(top_srcdir)/specs/spec_helper.lua.in + cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @@ -703,6 +724,27 @@ uninstall-dist_luastdDATA: @list='$(dist_luastd_DATA)'; test -n "$(luastddir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(luastddir)'; $(am__uninstall_files_from_dir) +install-dist_luastddebugDATA: $(dist_luastddebug_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_luastddebug_DATA)'; test -n "$(luastddebugdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(luastddebugdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(luastddebugdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(luastddebugdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(luastddebugdir)" || exit $$?; \ + done + +uninstall-dist_luastddebugDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_luastddebug_DATA)'; test -n "$(luastddebugdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(luastddebugdir)'; $(am__uninstall_files_from_dir) install-dist_modulesDATA: $(dist_modules_DATA) @$(NORMAL_INSTALL) @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ @@ -920,7 +962,7 @@ check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -979,7 +1021,8 @@ info-am: install-data-am: install-dist_classesDATA install-dist_docDATA \ install-dist_luaDATA install-dist_luastdDATA \ - install-dist_modulesDATA install-docDATA + install-dist_luastddebugDATA install-dist_modulesDATA \ + install-docDATA install-dvi: install-dvi-am @@ -1030,8 +1073,8 @@ ps-am: uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ uninstall-dist_classesDATA uninstall-dist_docDATA \ uninstall-dist_luaDATA uninstall-dist_luastdDATA \ - uninstall-dist_modulesDATA uninstall-docDATA \ - uninstall-libLTLIBRARIES + uninstall-dist_luastddebugDATA uninstall-dist_modulesDATA \ + uninstall-docDATA uninstall-libLTLIBRARIES .MAKE: check-am install-am install-exec-am install-strip @@ -1044,17 +1087,18 @@ uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ install-data install-data-am install-dist_binSCRIPTS \ install-dist_classesDATA install-dist_docDATA \ install-dist_luaDATA install-dist_luastdDATA \ - install-dist_modulesDATA install-docDATA install-dvi \ - install-dvi-am install-exec install-exec-am install-exec-hook \ - install-html install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags-am uninstall uninstall-am \ - uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ - uninstall-dist_classesDATA uninstall-dist_docDATA \ - uninstall-dist_luaDATA uninstall-dist_luastdDATA \ + install-dist_luastddebugDATA install-dist_modulesDATA \ + install-docDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ + uninstall uninstall-am uninstall-binSCRIPTS \ + uninstall-dist_binSCRIPTS uninstall-dist_classesDATA \ + uninstall-dist_docDATA uninstall-dist_luaDATA \ + uninstall-dist_luastdDATA uninstall-dist_luastddebugDATA \ uninstall-dist_modulesDATA uninstall-docDATA \ uninstall-libLTLIBRARIES @@ -1062,7 +1106,7 @@ uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ LUA_PATH ?= ; LUA_CPATH ?= ; specl-check-local: $(specl_SPECS) - $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) + $(SPECL_ENV) LUA=$(LUA) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to diff --git a/NEWS b/NEWS index b3fd9f0..cc9d78b 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,31 @@ Stdlib NEWS - User visible changes +* Noteworthy changes in release 37 (2014-01-18) [stable] + +** New features: + + - Lazy loading of submodules into `std` on first reference. On initial + load, `std` has the usual single `version` entry, but the `__index` + metatable will automatically require submodules on first reference: + + local std = require "std" + local prototype = std.container.prototype + + - New `std.optparse` module: A civilised option parser. + (L)Documentation distributed in doc/classes/std.optparse.html. + +** Bug fixes: + + - Modules no longer leak `new' and `proper_subset' into the global + table. + +** Incompatible changes: + + - `std.getopt` is no more. It appears to have no users, though if there + is a great outcry, it should be easy to make a compatibility api over + `std.optparse` in the next release. + + * Noteworthy changes in release 36 (2014-01-16) [stable] ** New features: diff --git a/build-aux/mkrockspecs b/build-aux/mkrockspecs index 9fd26fc..63386bd 100755 --- a/build-aux/mkrockspecs +++ b/build-aux/mkrockspecs @@ -113,6 +113,15 @@ local function opterr (msg) os.exit (2) end +local function setopt (optname, arglist, i) + local opt = arglist[i] + if i + 1 > #arglist then + opterr ("option '" .. opt .. "' requires an argument") + end + prog.opts[optname] = arglist[i + 1] + return i + 1 +end + local function die (msg) msg:gsub ("([^\n]+)\n?", function () @@ -135,16 +144,18 @@ PACKAGE and VERSION are the package name and version number as defined by 'configure.ac' or similar. REVISION is only required for a revised rockspec if the default "-1" revision was released with errors. + -b, --branch=BRANCH make git rockspec use BRANCH + -m, --module-dir=ROOT directory of lua-files for builtin build type + -r, --repository=REPO set the repository name (default=PACKAGE) --help print this help, then exit --version print version number, then exit - -m, --module-dir=ROOT directory of lua-files for builtin build type Report bugs to http://github.com/gvvaughan/slingshot/issues.]]) os.exit (0) end prog["--version"] = function () - print [[mkrockspecs (slingshot) 6 + print [[mkrockspecs (slingshot) 7 Written by Gary V. Vaughan , 2013 Copyright (C) 2013, Gary V. Vaughan @@ -153,17 +164,14 @@ See source files for individual license conditions.]] os.exit (0) end -prog["--module-dir"] = function (arglist, i) - local opt = arglist[i] - if i + 1 > #arglist then - opterr ("option '" .. opt .. "' requires an argument") - end +prog["-b"] = function (argl, i) return setopt ("branch", argl, i) end +prog["--branch"] = prog["-b"] - prog.opts.module_root = arglist[i + 1] - return i + 1 -end +prog["-m"] = function (argl, i) return setopt ("module_root", argl, i) end +prog["--module-dir"] = prog["-m"] -prog["-m"] = prog["--module-dir"] +prog["-r"] = function (argl, i) return setopt ("repository", argl, i) end +prog["--repository"] = prog["-r"] local nonopts local i = 0 @@ -207,6 +215,11 @@ local version = arg[2] local revision = arg[3] or "1" local conf = arg[4] or "rockspec.conf" +-- Unless set explicity, assume the repo is named after the package. +if prog.opts.repository == nil then + prog.opts.repository = package +end + --[[ ================= ]]-- --[[ Helper functions. ]]-- @@ -258,7 +271,7 @@ local function loadmap (root) tree (root) for _, f in ipairs (files) do local m = f:match ("^" .. escape_pattern (root) .. "/(.*)%.lua") - map [m:gsub ("/", ".")] = f:gsub ("^%./", "") + map [m:gsub ("/", "."):gsub ("%.init$", "")] = f:gsub ("^%./", "") end return map end @@ -355,11 +368,12 @@ spec.source = spec.source or {} spec.build = spec.build or {} if version ~= "scm" and version ~= "git" then spec.source.url = "http://" .. url .. "/archive/release-v" .. version .. ".zip" - spec.source.dir = package .. "-release-v" .. version + spec.source.dir = prog.opts.repository .. "-release-v" .. version else spec.source.url = "git://" .. url .. ".git" - default.build.build_command = "./bootstrap && " .. default.build.build_command + spec.source.branch = prog.opts.branch spec.build.modules = nil + default.build.build_command = "./bootstrap && " .. default.build.build_command end diff --git a/build-aux/sanity-cfg.mk b/build-aux/sanity-cfg.mk new file mode 100644 index 0000000..693103f --- /dev/null +++ b/build-aux/sanity-cfg.mk @@ -0,0 +1,3 @@ +exclude_file_name_regexp--sc_error_message_uppercase = ^lib/std/optparse.lua$$ + +EXTRA_DIST += build-aux/sanity-cfg.mk diff --git a/build-aux/specl.mk b/build-aux/specl.mk index f5ec9fc..6cee599 100644 --- a/build-aux/specl.mk +++ b/build-aux/specl.mk @@ -35,7 +35,7 @@ check_local += specl-check-local specl-check-local: $(specl_SPECS) - $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) + $(SPECL_ENV) LUA=$(LUA) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) ## ------------- ## diff --git a/configure b/configure index efe5681..fa259fe 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 36. +# Generated by GNU Autoconf 2.69 for stdlib 37. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='36' -PACKAGE_STRING='stdlib 36' +PACKAGE_VERSION='37' +PACKAGE_STRING='stdlib 37' PACKAGE_BUGREPORT='http://github.com/rrthomas/lua-stdlib/issues' PACKAGE_URL='' @@ -1217,7 +1217,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 36 to adapt to many kinds of systems. +\`configure' configures stdlib 37 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1283,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 36:";; + short | recursive ) echo "Configuration of stdlib 37:";; esac cat <<\_ACEOF @@ -1363,7 +1363,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 36 +stdlib configure 37 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1380,7 +1380,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 36, which was +It was created by stdlib $as_me 37, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1760,7 +1760,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. $as_echo "## --------------------- ## -## Configuring stdlib 36 ## +## Configuring stdlib 37 ## ## --------------------- ##" echo @@ -2250,7 +2250,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='36' + VERSION='37' cat >>confdefs.h <<_ACEOF @@ -3086,7 +3086,7 @@ $as_echo "$ac_cv_path_SED" >&6; } ac_config_files="$ac_config_files .travis.yml:travis.yml.in" -ac_config_files="$ac_config_files Makefile" +ac_config_files="$ac_config_files Makefile doc/config.ld specs/spec_helper.lua" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -3639,7 +3639,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 36, which was +This file was extended by stdlib $as_me 37, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3692,7 +3692,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 36 +stdlib config.status 37 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -3807,6 +3807,8 @@ do case $ac_config_target in ".travis.yml") CONFIG_FILES="$CONFIG_FILES .travis.yml:travis.yml.in" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "doc/config.ld") CONFIG_FILES="$CONFIG_FILES doc/config.ld" ;; + "specs/spec_helper.lua") CONFIG_FILES="$CONFIG_FILES specs/spec_helper.lua" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index 60a4f26..24c91cd 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [36], [http://github.com/rrthomas/lua-stdlib/issues]) +AC_INIT([stdlib], [37], [http://github.com/rrthomas/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) @@ -37,5 +37,5 @@ AC_PROG_SED dnl Generate output files SS_CONFIG_TRAVIS([ldoc specl]) -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([Makefile doc/config.ld specs/spec_helper.lua]) AC_OUTPUT diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 8fdd62f..07d98db 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,6 +42,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -51,7 +52,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 561ad08..78f2dac 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -43,6 +43,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -52,7 +53,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index 82f840c..28373a2 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -43,6 +43,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -52,7 +53,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html new file mode 100644 index 0000000..704bec4 --- /dev/null +++ b/doc/classes/std.optparse.html @@ -0,0 +1,742 @@ + + + + + stdlib 37 Reference + + + + +
      + +
      + +
      +
      +
      + + +
      + + + + + + +
      + +

      Class std.optparse

      +

      Parse and process command line options.

      +

      + + +

       local OptionParser = require "std.optparse"
      + local parser = OptionParser (spec)
      + _G.arg, opts = parser:parse (_G.arg)
      +
      + +

      The string spec passed to OptionParser must be a specially formatted + help text, of the form:

      + +
       any text VERSION
      + Additional lines of text to show when the --version
      + option is passed.
      +
      + Several lines or paragraphs are permitted.
      +
      + Usage: PROGNAME
      +
      + Banner text.
      +
      + Optional long description text to show when the --help
      + option is passed.
      +
      + Several lines or paragraphs of long description are permitted.
      +
      + Options:
      +
      +   -h, --help               display this help, then exit
      +       --version            display version information, then exit
      +   -b                       a short option with no long option
      +       --long               a long option with no short option
      +       --another-long       a long option with internal hypen
      +       --true               a Lua keyword as an option name
      +   -v, --verbose            a combined short and long option
      +   -n, --dryrun, --dry-run  several spellings of the same option
      +   -u, --name=USER          require an argument
      +   -o, --output=[FILE]      accept an optional argument
      +   --                       end of options
      +
      +Footer text.  Several lines or paragraphs are permitted.
      +
      +Please report bugs at bug-list@yourhost.com
      +
      + +

      Most often, everything else is handled automatically. After calling + parser:parse as shown above, _G.arg will contain unparsed arguments, + usually filenames or similar, and opts will be a table of parsed + option values. The keys to the table are the long-options with leading + hyphens stripped, and non-word characters turned to _. For example + if --another-long had been found in _G.arg then opts would + have a key named another_long. If there is no long option name, then + the short option is used, e.g. opts.b will be set. The values saved + in those keys are controlled by the option handler, usually just true + or the option argument string as appropriate.

      + +

      On those occasions where more complex processing is required, handlers + can be replaced or added using parser:on.

      + +

      + + +

      Functions

      + + + + + +
      std.optparse.OptionParser (spec)Instantiate a new parser.
      +

      Tables

      + + + + + + + + + + + + + +
      std.optparse.boolvalsMap various option strings to equivalent Lua boolean values.
      std.optparse.optsParsed options table, with a key for each encountered option, each + with value set by that option's on_handler.
      std.optparse.parserCustomized parser for your options.
      +

      Methods

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      std.optparse:boolean (opt[, optarg="1"])Return a Lua boolean equivalent of various optarg strings.
      std.optparse:file (opt, optarg)Report an option parse error unless optarg names an + existing file.
      std.optparse:finished (arglist, i)Finish option processing + Usually indicated by -- at arglist[i].
      std.optparse:flag (arglist, i[, value])Option at arglist[i] is a boolean switch.
      std.optparse:help ()Option should display help text, then exit.
      std.optparse:normalise (arglist)Normalise an argument list.
      std.optparse:on (name, handler, value)Add an option handler.
      std.optparse:on_handler (arglist, i[, value=nil])Function signature of an option handler for on.
      std.optparse:opterr (msg)Report an option parse error, then exit with status 2.
      std.optparse:optional (arglist, i[, value=true])Option at arglist[i] can take an argument.
      std.optparse:parse (arglist)Parse arglist.
      std.optparse:required (arglist, i[, value])Option at arglist[i} requires an argument.
      std.optparse:set (opt, value)Store value with opt.
      std.optparse:version ()Option should display version text, then exit.
      + +
      +
      + + +

      Functions

      +
      +
      + + std.optparse.OptionParser (spec) +
      +
      + Instantiate a new parser. + Read the documented options from spec and return a new parser that + can be passed to parse for parsing those options from an argument + list. + + +

      Parameters:

      +
        +
      • spec + string + option parsing specification +
      • +
      + +

      Returns:

      +
        + + parser + a parser for options described by spec +
      + + + + +
      +
      +

      Tables

      +
      +
      + + std.optparse.boolvals +
      +
      + Map various option strings to equivalent Lua boolean values. + + +

      Fields:

      +
        +
      • false + false +
      • +
      • 0 + false +
      • +
      • no + false +
      • +
      • n + false +
      • +
      • true + true +
      • +
      • 1 + true +
      • +
      • yes + true +
      • +
      • y + true +
      • +
      + + + + + +
      +
      + + std.optparse.opts +
      +
      + Parsed options table, with a key for each encountered option, each + with value set by that option's on_handler. + + + + + + + +
      +
      + + std.optparse.parser +
      +
      + Customized parser for your options. + + + + + + + +
      +
      +

      Methods

      +
      +
      + + std.optparse:boolean (opt[, optarg="1"]) +
      +
      + Return a Lua boolean equivalent of various optarg strings. + Report an option parse error if optarg is not recognised. + + +

      Parameters:

      +
        +
      • opt + string + option name +
      • +
      • optarg + string + option argument, must be a key in boolvals + (default "1") +
      • +
      + +

      Returns:

      +
        + + bool + true or false +
      + + + + +
      +
      + + std.optparse:file (opt, optarg) +
      +
      + Report an option parse error unless optarg names an + existing file. + + +

      Parameters:

      +
        +
      • opt + string + option name +
      • +
      • optarg + string + option argument, must be an existing file +
      • +
      + +

      Returns:

      +
        + + `optarg` + + + +
      + + + + +
      +
      + + std.optparse:finished (arglist, i) +
      +
      + Finish option processing + Usually indicated by -- at arglist[i]. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:flag (arglist, i[, value]) +
      +
      + Option at arglist[i] is a boolean switch. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + either a function to process the option argument, + or a value to store when this flag is encountered +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:help () +
      +
      + Option should display help text, then exit. + + + + + + + +
      +
      + + std.optparse:normalise (arglist) +
      +
      + Normalise an argument list. + Separate short options, remove = separators from + --long-option=optarg etc. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments to normalise +
      • +
      + +

      Returns:

      +
        + + table + normalised argument list +
      + + + + +
      +
      + + std.optparse:on (name, handler, value) +
      +
      + Add an option handler. + + +

      Parameters:

      +
        +
      • name + opts + of the option, or list of option names +
      • +
      • handler + on_handler + function to call when any of opts is + encountered +
      • +
      • value + additional value passed to on_handler +
      • +
      + + + + + +
      +
      + + std.optparse:on_handler (arglist, i[, value=nil]) +
      +
      + Function signature of an option handler for on. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + additional value registered with on + (default nil) +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:opterr (msg) +
      +
      + Report an option parse error, then exit with status 2. + + +

      Parameters:

      +
        +
      • msg + string + error message +
      • +
      + + + + + +
      +
      + + std.optparse:optional (arglist, i[, value=true]) +
      +
      + Option at arglist[i] can take an argument. + Argument is accepted only if there is a following entry that does not + begin with a '-'. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + either a function to process the option + argument, or a default value if encountered without an optarg + (default true) +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:parse (arglist) +
      +
      + Parse arglist. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      + +

      Returns:

      +
        +
      1. + table + a list of unrecognised arglist elements
      2. +
      3. + opts + parsing results
      4. +
      + + + + +
      +
      + + std.optparse:required (arglist, i[, value]) +
      +
      + Option at arglist[i} requires an argument. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + either a function to process the option argument, + or a forced value to replace the user's option argument. +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:set (opt, value) +
      +
      + Store value with opt. + + +

      Parameters:

      +
        +
      • opt + string + option name +
      • +
      • value + option argument value +
      • +
      + + + + + +
      +
      + + std.optparse:version () +
      +
      + Option should display version text, then exit. + + + + + + + +
      +
      + + +
      +
      +
      +generated by LDoc 1.4.0 +
      +
      + + diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index b1b8754..b291a94 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -43,6 +43,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -52,7 +53,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index a5ec6be..cefb45c 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,6 +42,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -51,7 +52,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index 261ecad..f6ffff8 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -43,6 +43,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -52,7 +53,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/config.ld b/doc/config.ld index fb5c297..1cd763c 100644 --- a/doc/config.ld +++ b/doc/config.ld @@ -1,4 +1,5 @@ -- -*- lua -*- +title = "stdlib 37 Reference" project = "stdlib" description = "Standard Lua Libraries" dir = "." @@ -8,7 +9,6 @@ file = { "../lib/std.lua", "../lib/std/debug.lua", "../lib/std/functional.lua", - "../lib/std/getopt.lua", "../lib/std/io.lua", "../lib/std/math.lua", "../lib/std/package.lua", @@ -21,6 +21,7 @@ file = { "../lib/std/container.lua", "../lib/std/object.lua", "../lib/std/list.lua", + "../lib/std/optparse.lua", "../lib/std/set.lua", "../lib/std/strbuf.lua", } diff --git a/doc/config.ld.in b/doc/config.ld.in new file mode 100644 index 0000000..fb4576f --- /dev/null +++ b/doc/config.ld.in @@ -0,0 +1,30 @@ +-- -*- lua -*- +title = "@PACKAGE@ @VERSION@ Reference" +project = "stdlib" +description = "Standard Lua Libraries" +dir = "." + +file = { + -- Modules + "../lib/std.lua", + "../lib/std/debug.lua", + "../lib/std/functional.lua", + "../lib/std/io.lua", + "../lib/std/math.lua", + "../lib/std/package.lua", + "../lib/std/strict.lua", + "../lib/std/string.lua", + "../lib/std/table.lua", + "../lib/std/tree.lua", + + -- Classes + "../lib/std/container.lua", + "../lib/std/object.lua", + "../lib/std/list.lua", + "../lib/std/optparse.lua", + "../lib/std/set.lua", + "../lib/std/strbuf.lua", +} + +format = "markdown" +sort = true diff --git a/doc/index.html b/doc/index.html index 954c2bd..12a01ee 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -34,7 +34,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • @@ -48,6 +47,7 @@

      Classes

    • std.container
    • std.object
    • std.list
    • +
    • std.optparse
    • std.set
    • std.strbuf
    @@ -73,10 +73,6 @@

    Modules

    std.functional Functional programming. - - std.getopt - Simplified getopt, based on Svenne Panne's Haskell GetOpt. - std.io Additions to the io module. @@ -120,6 +116,10 @@

    Classes

    std.list Tables as lists. + + std.optparse + Parse and process command line options. + std.set Set container. diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html index e919d11..615896c 100644 --- a/doc/modules/std.debug.html +++ b/doc/modules/std.debug.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,7 +42,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +55,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index c3bf40b..b9730a2 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,7 +42,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +55,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.getopt.html b/doc/modules/std.getopt.html deleted file mode 100644 index 5a915a0..0000000 --- a/doc/modules/std.getopt.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Reference - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module std.getopt

    -

    Simplified getopt, based on Svenne Panne's Haskell GetOpt.

    -

    Usage:

    - -
     prog = {<
    -   name = <progname>,
    -   [usage = <usage line>,]
    -   [options = {
    -     {{<name>[, ...]}, <desc>, [<type> [, <var>]]},
    -     ...
    -   },]
    -   [banner = <banner string>,]
    -   [purpose = <purpose string>,]
    -   [notes = <additional notes>]
    - }
    -
    - -
      -
    • The type of option argument is one of Req(uired), - Opt(ional)
    • -
    • The varis a descriptive name for the option argument.
    • -
    • getopt.processargs (prog)
    • -
    • Options take a single dash, but may have a double dash.
    • -
    • Arguments may be given as -opt=arg or -opt arg.
    • -
    • If an option taking an argument is given multiple times, only the - last value is returned; missing arguments are returned as 1.
    • -
    - -

    getOpt, usageinfo and usage can be called directly (see - below, and the example at the end). Set _DEBUG.std to a non-nil - value to run the example.

    - - -

    Functions

    - - - - - - - - - - - - - - - - - -
    getopt (argIn, options, stop_at_nonopt)Perform argument processing
    processargs (prog, ...)Simple getopt wrapper.
    usage (prog)Emit a usage message.
    usageinfo (header, optDesc, pageWidth)Produce usage info for the given options.
    - -
    -
    - - -

    Functions

    -
    -
    - - getopt (argIn, options, stop_at_nonopt) -
    -
    - Perform argument processing - - -

    Parameters:

    -
      -
    • argIn - list of command-line args -
    • -
    • options - options table -
    • -
    • stop_at_nonopt - if true, stop option processing at first non-option -
    • -
    - -

    Returns:

    -
      -
    1. - table of remaining non-options
    2. -
    3. - table of option key-value list pairs
    4. -
    5. - table of error messages
    6. -
    - - - - -
    -
    - - processargs (prog, ...) -
    -
    - Simple getopt wrapper. - If the caller didn't supply their own already, adds --version/-V - and --help/-h options automatically; - stops program if there was an error, or if --help or --version was - used. - - -

    Parameters:

    -
      -
    • prog - table of named parameters -
    • -
    • ... - extra arguments for getopt -
    • -
    - - - - - -
    -
    - - usage (prog) -
    -
    - Emit a usage message. - - -

    Parameters:

    -
      -
    • prog - table of named parameters -
    • -
    - - - - - -
    -
    - - usageinfo (header, optDesc, pageWidth) -
    -
    - Produce usage info for the given options. - - -

    Parameters:

    -
      -
    • header - header string -
    • -
    • optDesc - option descriptors -
    • -
    • pageWidth - width to format to [78] -
    • -
    - -

    Returns:

    -
      - - formatted string -
    - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.0 -
    -
    - - diff --git a/doc/modules/std.html b/doc/modules/std.html index 1ab8ea2..b5efcff 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -34,6 +34,7 @@

    Contents

    @@ -42,7 +43,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +56,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • @@ -194,6 +195,13 @@

    Tables

    Module table. +

    Metamethods

    + + + + + +
    __index (name)Lazy loading of stdlib modules.


    @@ -695,7 +703,16 @@

    See also:

    std
    - Module table. + +

    Module table. + Lazy load submodules into std on first reference. On initial + load, std has the usual single version entry, but the __index + metatable will automatically require submodules on first reference:

    + +
     local std = require "std"
    + local prototype = std.container.prototype
    +
    +

    Fields:

    @@ -709,6 +726,38 @@

    Fields:

    +
    +
    +

    Metamethods

    + +
    +
    + + __index (name) +
    +
    + Lazy loading of stdlib modules. + Don't load everything on initial startup, wait until first attempt + to access a submodule, and then load it on demand. + + +

    Parameters:

    +
      +
    • name + string + submodule name +
    • +
    + +

    Returns:

    +
      + + the submodule that was loaded to satisfy the missing name +
    + + + +
    diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index 812381e..c1109d9 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index 1d26c3b..eb857ed 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index 3285807..7c0b2eb 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index c0184a7..cfdc552 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index c3f1211..f99a396 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,7 +42,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +55,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • @@ -808,7 +808,7 @@

    Parameters:

  • pattern to match version in module.version or - module.VERSION (default: ".*[%.%d]+" + module.VERSION (default: ".*[%.%d]+")
  • diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index 05cb962..96ebab2 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/lib/std.lua b/lib/std.lua index 0a17601..af93195 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -19,12 +19,21 @@ @module std ]] + --- Module table. +-- Lazy load submodules into `std` on first reference. On initial +-- load, `std` has the usual single `version` entry, but the `__index` +-- metatable will automatically require submodules on first reference: +-- +-- local std = require "std" +-- local prototype = std.container.prototype -- @table std -- @field version release version string -local version = "General Lua libraries / 36" +local version = "General Lua libraries / 37" + +local modules = require "std.modules" -for m, globally in pairs (require "std.modules") do +for m, globally in pairs (modules) do if globally == true then -- Inject stdlib extensions directly into global package namespaces. for k, v in pairs (require ("std." .. m)) do @@ -193,4 +202,22 @@ local M = { version = version, } -return M + +--- Metamethods +-- @section Metamethods + +return setmetatable (M, { + --- Lazy loading of stdlib modules. + -- Don't load everything on initial startup, wait until first attempt + -- to access a submodule, and then load it on demand. + -- @function __index + -- @string name submodule name + -- @return the submodule that was loaded to satisfy the missing `name` + __index = function (self, name) + local ok, t = pcall (require, "std." .. name) + if ok then + rawset (self, name, t) + return t + end + end, +}) diff --git a/lib/std.lua.in b/lib/std.lua.in index 508f0b3..da0fb77 100644 --- a/lib/std.lua.in +++ b/lib/std.lua.in @@ -19,12 +19,21 @@ @module std ]] + --- Module table. +-- Lazy load submodules into `std` on first reference. On initial +-- load, `std` has the usual single `version` entry, but the `__index` +-- metatable will automatically require submodules on first reference: +-- +-- local std = require "std" +-- local prototype = std.container.prototype -- @table std -- @field version release version string local version = "General Lua libraries / @VERSION@" -for m, globally in pairs (require "std.modules") do +local modules = require "std.modules" + +for m, globally in pairs (modules) do if globally == true then -- Inject stdlib extensions directly into global package namespaces. for k, v in pairs (require ("std." .. m)) do @@ -193,4 +202,22 @@ local M = { version = version, } -return M + +--- Metamethods +-- @section Metamethods + +return setmetatable (M, { + --- Lazy loading of stdlib modules. + -- Don't load everything on initial startup, wait until first attempt + -- to access a submodule, and then load it on demand. + -- @function __index + -- @string name submodule name + -- @return the submodule that was loaded to satisfy the missing `name` + __index = function (self, name) + local ok, t = pcall (require, "std." .. name) + if ok then + rawset (self, name, t) + return t + end + end, +}) diff --git a/lib/std/base.lua b/lib/std/base.lua index bc26f82..0ac5aad 100644 --- a/lib/std/base.lua +++ b/lib/std/base.lua @@ -31,6 +31,8 @@ local function merge (t, u) return t end +local new -- forward declaration + -- Doc-commented in list.lua... local function append (l, x) local r = {unpack (l)} diff --git a/lib/std/debug_init.lua b/lib/std/debug_init/init.lua similarity index 100% rename from lib/std/debug_init.lua rename to lib/std/debug_init/init.lua diff --git a/lib/std/getopt.lua b/lib/std/getopt.lua deleted file mode 100644 index f57fb10..0000000 --- a/lib/std/getopt.lua +++ /dev/null @@ -1,299 +0,0 @@ ---- Simplified getopt, based on Svenne Panne's Haskell GetOpt. --- --- Usage: --- --- prog = {< --- name = , --- [usage = ,] --- [options = { --- {{[, ...]}, , [ [, ]]}, --- ... --- },] --- [banner = ,] --- [purpose = ,] --- [notes = ] --- } --- --- * The `type` of option argument is one of `Req`(uired), --- `Opt`(ional) --- * The `var`is a descriptive name for the option argument. --- * `getopt.processargs (prog)` --- * Options take a single dash, but may have a double dash. --- * Arguments may be given as `-opt=arg` or `-opt arg`. --- * If an option taking an argument is given multiple times, only the --- last value is returned; missing arguments are returned as 1. --- --- getOpt, usageinfo and usage can be called directly (see --- below, and the example at the end). Set _DEBUG.std to a non-nil --- value to run the example. --- --- @todo Wrap all messages; do all wrapping in processargs, not --- usageinfo; use sdoc-like library (see string.format todos). --- @todo Don't require name to be repeated in banner. --- @todo Store version separately (construct banner?). --- --- @module std.getopt - -local io = require "std.io" -local List = require "std.list" -local Object = require "std.object" -local string = require "std.string" -local table = require "std.table" - -local M = { - opt = {}, -} - -local argtype = { Opt = true, Req = true } - - ---- Perform argument processing --- @param argIn list of command-line args --- @param options options table --- @param stop_at_nonopt if true, stop option processing at first non-option --- @return table of remaining non-options --- @return table of option key-value list pairs --- @return table of error messages -local function getopt (argIn, options, stop_at_nonopt) - local noProcess = nil - local argOut, optOut, errors = {[0] = argIn[0]}, {}, {} - -- get an argument for option opt - local function getArg (o, opt, arg, oldarg) - if not argtype[o.type] then - if arg ~= nil then - table.insert (errors, "option `" .. opt .. "' doesn't take an argument") - end - else - if arg == nil and argIn[1] and - string.sub (argIn[1], 1, 1) ~= "-" then - arg = argIn[1] - table.remove (argIn, 1) - end - if arg == nil and o.type == "Req" then - table.insert (errors, "option `" .. opt .. - "' requires an argument `" .. o.var .. "'") - return nil - end - end - return arg or 1 -- make sure arg has a value - end - - local function parseOpt (opt, arg) - local o = options.name[opt] - if o ~= nil then - o = o or {name = {opt}} - optOut[o.name[1]] = optOut[o.name[1]] or {} - table.insert (optOut[o.name[1]], getArg (o, opt, arg, optOut[o.name[1]])) - else - table.insert (errors, "unrecognized option `-" .. opt .. "'") - end - end - while argIn[1] do - local v = argIn[1] - table.remove (argIn, 1) - local _, _, dash, opt = string.find (v, "^(%-%-?)([^=-][^=]*)") - local _, _, arg = string.find (v, "=(.*)$") - if not dash and stop_at_nonopt then - noProcess = true - end - if v == "--" then - noProcess = true - elseif not dash or noProcess then -- non-option - table.insert (argOut, v) - else -- option - parseOpt (opt, arg) - end - end - return argOut, optOut, errors -end - - --- Object that defines a single Option entry. -local Option = Object {_init = {"name", "desc", "type", "var"}} - ---- Options table constructor: adds lookup tables for the option names. -local function makeOptions (t) - local options, name = {}, {} - local function appendOpt (v, nodupes) - local dupe = false - v = Option (v) - for s in List.elems (v.name) do - if name[s] then - dupe = true - end - name[s] = v - end - if not dupe or nodupes ~= true then - if dupe then io.warn ("duplicate option '%s'", s) end - for s in List.elems (v.name) do name[s] = v end - options = List.concat (options, {v}) - end - end - for v in List.elems (t or {}) do - appendOpt (v) - end - -- Unless they were supplied already, add version and help options - appendOpt ({{"version", "V"}, "print version information, then exit"}, - true) - appendOpt ({{"help", "h"}, "print this help, then exit"}, true) - options.name = name - return options -end - - ---- Produce usage info for the given options. --- @param header header string --- @param optDesc option descriptors --- @param pageWidth width to format to [78] --- @return formatted string -local function usageinfo (header, optDesc, pageWidth) - pageWidth = pageWidth or 78 - -- Format the usage info for a single option - -- @param opt the option table - -- @return options - -- @return description - local function fmtOpt (opt) - local function fmtName (o) - return (#o > 1 and "--" or "-") .. o - end - local function fmtArg () - if opt.type == "Req" then - return "=" .. opt.var - elseif opt.type == "Opt" then - return "[=" .. opt.var .. "]" - else - return "" - end - end - local textName = List.reverse (List.map (opt.name, fmtName)) - textName[#textName] = textName[#textName] .. fmtArg () - local indent = "" - if #opt.name == 1 and #opt.name[1] > 1 then - indent = " " - end - return {indent .. table.concat ({table.concat (textName, ", ")}, ", "), - opt.desc} - end - local function sameLen (xs) - local n = math.max (unpack (List.map (xs, string.len))) - for i, v in pairs (xs) do - xs[i] = string.sub (v .. string.rep (" ", n), 1, n) - end - return xs, n - end - local function paste (x, y) - return " " .. x .. " " .. y - end - local function wrapper (w, i) - return function (s) - return string.wrap (s, w, i, 0) - end - end - local optText = "" - if #optDesc > 0 then - local cols = List.transpose (List.map (optDesc, fmtOpt)) - local width - cols[1], width = sameLen (cols[1]) - cols[2] = List.map (cols[2], wrapper (pageWidth, width + 4)) - optText = "\n\n" .. - table.concat (List.map_with (List.transpose ({sameLen (cols[1]), - cols[2]}), - paste), - "\n") - end - return header .. optText -end - ---- Emit a usage message. --- @param prog table of named parameters -local function usage (prog) - local usage = "[OPTION]... [FILE]..." - local purpose, description, notes = "", "", "" - if prog.usage then - usage = prog.usage - end - usage = "Usage: " .. prog.name .. " " .. usage - if prog.purpose then - purpose = "\n\n" .. prog.purpose - end - if prog.description then - for para in List.elems (string.split (prog.description, "\n")) do - description = description .. "\n\n" .. string.wrap (para) - end - end - if prog.notes then - notes = "\n\n" - if not string.find (prog.notes, "\n") then - notes = notes .. string.wrap (prog.notes) - else - notes = notes .. prog.notes - end - end - local header = usage .. purpose .. description - io.writelines (usageinfo (header, prog.options) .. notes) -end - - -local function version (prog) - local version = prog.version or prog.name or "unknown version!" - if prog.copyright then - version = version .. "\n\n" .. prog.copyright - end - io.writelines (version) -end - - - ---- Simple getopt wrapper. --- If the caller didn't supply their own already, adds `--version`/`-V` --- and `--help`/`-h` options automatically; --- stops program if there was an error, or if `--help` or `--version` was --- used. --- @param prog table of named parameters --- @param ... extra arguments for getopt -local function processargs (prog, ...) - local totArgs = #_G.arg - local errors - prog.options = makeOptions (prog.options) - _G.arg, M.opt, errors = getopt (_G.arg, prog.options, ...) - local opt = M.opt - if (opt.version or opt.help) and prog.banner then - io.writelines (prog.banner) - end - if #errors > 0 then - local name = prog.name - prog.name = nil - if #errors > 0 then - io.warn (name .. ": " .. table.concat (errors, "\n")) - io.warn (name .. ": Try '" .. (arg[0] or name) .. " --help' for more help") - end - if #errors > 0 then - error () - end - elseif opt.version then - version (prog) - elseif opt.help then - usage (prog) - end - if opt.version or opt.help then - os.exit () - end -end - - ---- @export -local Getopt = { - getopt = getopt, - processargs = processargs, - usage = usage, - usageinfo = usageinfo, -} - --- camelCase compatibility. -Getopt = table.merge (Getopt, { - getOpt = getopt, - processArgs = processargs, - usageInfo = usageinfo, -}) - -return table.merge (M, Getopt) diff --git a/lib/std/modules.lua b/lib/std/modules.lua index 2beaf18..d023b1b 100644 --- a/lib/std/modules.lua +++ b/lib/std/modules.lua @@ -6,10 +6,10 @@ return { debug = true, debug_init = false, functional = false, - getopt = false, io = true, list = false, math = true, + optparse = false, package = true, set = false, strbuf = false, diff --git a/lib/std/optparse.lua b/lib/std/optparse.lua new file mode 100644 index 0000000..7bf0ee5 --- /dev/null +++ b/lib/std/optparse.lua @@ -0,0 +1,533 @@ +--[[-- + Parse and process command line options. + + local OptionParser = require "std.optparse" + local parser = OptionParser (spec) + _G.arg, opts = parser:parse (_G.arg) + + The string `spec` passed to `OptionParser` must be a specially formatted + help text, of the form: + + any text VERSION + Additional lines of text to show when the --version + option is passed. + + Several lines or paragraphs are permitted. + + Usage: PROGNAME + + Banner text. + + Optional long description text to show when the --help + option is passed. + + Several lines or paragraphs of long description are permitted. + + Options: + + -h, --help display this help, then exit + --version display version information, then exit + -b a short option with no long option + --long a long option with no short option + --another-long a long option with internal hypen + --true a Lua keyword as an option name + -v, --verbose a combined short and long option + -n, --dryrun, --dry-run several spellings of the same option + -u, --name=USER require an argument + -o, --output=[FILE] accept an optional argument + -- end of options + + Footer text. Several lines or paragraphs are permitted. + + Please report bugs at bug-list@yourhost.com + + Most often, everything else is handled automatically. After calling + `parser:parse` as shown above, `_G.arg` will contain unparsed arguments, + usually filenames or similar, and `opts` will be a table of parsed + option values. The keys to the table are the long-options with leading + hyphens stripped, and non-word characters turned to `_`. For example + if `--another-long` had been found in `_G.arg` then `opts` would + have a key named `another_long`. If there is no long option name, then + the short option is used, e.g. `opts.b` will be set. The values saved + in those keys are controlled by the option handler, usually just `true` + or the option argument string as appropriate. + + On those occasions where more complex processing is required, handlers + can be replaced or added using parser:@{on}. + + @classmod std.optparse +]] + + +local OptionParser -- forward declaration + + +------ +-- Customized parser for your options. +-- @table parser + + +--[[ ----------------- ]]-- +--[[ Helper Functions. ]]-- +--[[ ----------------- ]]-- + + +local optional, required + + +--- Normalise an argument list. +-- Separate short options, remove `=` separators from +-- `--long-option=optarg` etc. +-- @function normalise +-- @tparam table arglist list of arguments to normalise +-- @treturn table normalised argument list +local function normalise (self, arglist) + -- First pass: Normalise to long option names, without '=' separators. + local normal = {} + local i = 0 + while i < #arglist do + i = i + 1 + local opt = arglist[i] + + -- Split '--long-option=option-argument'. + if opt:sub (1, 2) == "--" then + local x = opt:find ("=", 3, true) + if x then + table.insert (normal, opt:sub (1, x - 1)) + table.insert (normal, opt:sub (x + 1)) + else + table.insert (normal, opt) + end + + elseif opt:sub (1, 1) == "-" and string.len (opt) > 2 then + local rest + repeat + opt, rest = opt:sub (1, 2), opt:sub (3) + + table.insert (normal, opt) + + -- Split '-xyz' into '-x -yz', and reiterate for '-yz' + if self[opt].handler ~= optional and + self[opt].handler ~= required then + if string.len (rest) > 0 then + opt = "-" .. rest + else + opt = nil + end + + -- Split '-xshortargument' into '-x shortargument'. + else + table.insert (normal, rest) + opt = nil + end + until opt == nil + else + table.insert (normal, opt) + end + end + + normal[-1], normal[0] = arglist[-1], arglist[0] + return normal +end + + +--- Store `value` with `opt`. +-- @function set +-- @string opt option name +-- @param value option argument value +local function set (self, opt, value) + local key = self[opt].key + + if type (self.opts[key]) == "table" then + table.insert (self.opts[key], value) + elseif self.opts[key] ~= nil then + self.opts[key] = { self.opts[key], value } + else + self.opts[key] = value + end +end + + + +--[[ ============= ]]-- +--[[ Option Types. ]]-- +--[[ ============= ]]-- + + +--- Option at `arglist[i]` can take an argument. +-- Argument is accepted only if there is a following entry that does not +-- begin with a '-'. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt=true] value either a function to process the option +-- argument, or a default value if encountered without an optarg +-- @treturn int index of next element of `arglist` to process +function optional (self, arglist, i, value) + if i + 1 <= #arglist and arglist[i + 1]:sub (1, 1) ~= "-" then + return self:required (arglist, i, value) + end + + if type (value) == "function" then + value = value (self, opt, nil) + elseif value == nil then + value = true + end + + set (self, arglist[i], value) + return i + 1 +end + + +--- Option at `arglist[i}` requires an argument. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt] value either a function to process the option argument, +-- or a forced value to replace the user's option argument. +-- @treturn int index of next element of `arglist` to process +function required (self, arglist, i, value) + local opt = arglist[i] + if i + 1 > #arglist then + self:opterr ("option '" .. opt .. "' requires an argument") + return i + 1 + end + + if type (value) == "function" then + value = value (self, opt, arglist[i + 1]) + elseif value == nil then + value = arglist[i + 1] + end + + set (self, opt, value) + return i + 2 +end + + +--- Finish option processing +-- Usually indicated by `--` at `arglist[i]`. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @treturn int index of next element of `arglist` to process +local function finished (self, arglist, i) + for opt = i + 1, #arglist do + table.insert (self.unrecognised, arglist[opt]) + end + return 1 + #arglist +end + + +--- Option at `arglist[i]` is a boolean switch. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt] value either a function to process the option argument, +-- or a value to store when this flag is encountered +-- @treturn int index of next element of `arglist` to process +local function flag (self, arglist, i, value) + if type (value) == "function" then + value = value (self, opt, true) + elseif value == nil then + value = true + end + + set (self, arglist[i], value) + return i + 1 +end + + +--- Option should display help text, then exit. +-- @function help +local function help (self) + print (self.helptext) + os.exit (0) +end + + +--- Option should display version text, then exit. +-- @function version +local function version (self) + print (self.versiontext) + os.exit (0) +end + + + +--[[ =============== ]]-- +--[[ Argument Types. ]]-- +--[[ =============== ]]-- + + +--- Map various option strings to equivalent Lua boolean values. +-- @table boolvals +-- @field false false +-- @field 0 false +-- @field no false +-- @field n false +-- @field true true +-- @field 1 true +-- @field yes true +-- @field y true +local boolvals = { + ["false"] = false, ["true"] = true, + ["0"] = false, ["1"] = true, + no = false, yes = true, + n = false, y = true, +} + + +--- Return a Lua boolean equivalent of various `optarg` strings. +-- Report an option parse error if `optarg` is not recognised. +-- @string opt option name +-- @string[opt="1"] optarg option argument, must be a key in @{boolvals} +-- @treturn bool `true` or `false` +local function boolean (self, opt, optarg) + if optarg == nil then optarg = "1" end -- default to truthy + local b = boolvals[tostring (optarg):lower ()] + if b == nil then + return self:opterr (optarg .. ": Not a valid argument to " ..opt[1] .. ".") + end + return b +end + + +--- Report an option parse error unless `optarg` names an +-- existing file. +-- @fixme this only checks whether the file has read permissions +-- @string opt option name +-- @string optarg option argument, must be an existing file +-- @treturn `optarg` +local function file (self, opt, optarg) + local h, errmsg = io.open (optarg, "r") + if h == nil then + return self:opterr (optarg .. ": " .. errmsg) + end + h:close () + return optarg +end + + + +--[[ =============== ]]-- +--[[ Option Parsing. ]]-- +--[[ =============== ]]-- + + +--- Report an option parse error, then exit with status 2. +-- @string msg error message +local function opterr (self, msg) + local prog = self.program + -- Ensure final period. + if msg:match ("%.$") == nil then msg = msg .. "." end + io.stderr:write (prog .. ": error: " .. msg .. "\n") + io.stderr:write (prog .. ": Try '" .. prog .. " --help' for help.\n") + os.exit (2) +end + + +------ +-- Function signature of an option handler for @{on}. +-- @function on_handler +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt=nil] value additional `value` registered with @{on} +-- @treturn int index of next element of `arglist` to process + + +--- Add an option handler. +-- @function on +-- @tparam[string|table] opts name of the option, or list of option names +-- @tparam on_handler handler function to call when any of `opts` is +-- encountered +-- @param value additional value passed to @{on_handler} +local function on (self, opts, handler, value) + if type (opts) == "string" then opts = { opts } end + handler = handler or flag -- unspecified options behave as flags + + normal = {} + for _, optspec in ipairs (opts) do + optspec:gsub ("(%S+)", + function (opt) + -- 'x' => '-x' + if string.len (opt) == 1 then + opt = "-" .. opt + + -- 'option-name' => '--option-name' + elseif opt:match ("^[^%-]") ~= nil then + opt = "--" .. opt + end + + if opt:match ("^%-[^%-]+") ~= nil then + -- '-xyz' => '-x -y -z' + for i = 2, string.len (opt) do + table.insert (normal, "-" .. opt:sub (i, i)) + end + else + table.insert (normal, opt) + end + end) + end + + -- strip leading '-', and convert non-alphanums to '_' + key = normal[#normal]:match ("^%-*(.*)$"):gsub ("%W", "_") + + for _, opt in ipairs (normal) do + self[opt] = { key = key, handler = handler, value = value } + end +end + + +------ +-- Parsed options table, with a key for each encountered option, each +-- with value set by that option's @{on_handler}. +-- @table opts + + +--- Parse `arglist`. +-- @tparam table arglist list of arguments +-- @treturn table a list of unrecognised `arglist` elements +-- @treturn opts parsing results +local function parse (self, arglist) + self.unrecognised = {} + + arglist = normalise (self, arglist) + + local i = 1 + while i > 0 and i <= #arglist do + local opt = arglist[i] + + if self[opt] == nil then + table.insert (self.unrecognised, opt) + i = i + 1 + + -- Following non-'-' prefixed argument is an optarg. + if i <= #arglist and arglist[i]:match "^[^%-]" then + table.insert (self.unrecognised, arglist[i]) + i = i + 1 + end + + -- Run option handler functions. + else + assert (type (self[opt].handler) == "function") + + i = self[opt].handler (self, arglist, i, self[opt].value) + end + end + + return self.unrecognised, self.opts +end + + +--- @export +local methods = { + boolean = boolean, + file = file, + finished = finished, + flag = flag, + help = help, + optional = optional, + required = required, + version = version, + + on = on, + opterr = opterr, + parse = parse, +} + + + +--- Take care not to register duplicate handlers. +-- @param current current handler value +-- @param new new handler value +-- @return `new` if `current` is nil +local function set_handler (current, new) + assert (current == nil, "only one handler per option") + return new +end + + +--- Instantiate a new parser. +-- Read the documented options from `spec` and return a new parser that +-- can be passed to @{parse} for parsing those options from an argument +-- list. +-- @static +-- @string spec option parsing specification +-- @treturn parser a parser for options described by `spec` +function OptionParser (spec) + local parser = setmetatable ({ opts = {} }, { __index = methods }) + + parser.versiontext, parser.version, parser.helptext, parser.program = + spec:match ("^([^\n]-(%S+)\n.-)%s*([Uu]sage: (%S+).-)%s*$") + + if parser.versiontext == nil then + error ("OptionParser spec argument must match '\\n" .. + "...Usage: ...'") + end + + -- Collect helptext lines that begin with two or more spaces followed + -- by a '-'. + local specs = {} + parser.helptext:gsub ("\n %s*(%-[^\n]+)", + function (spec) table.insert (specs, spec) end) + + -- Register option handlers according to the help text. + for _, spec in ipairs (specs) do + local options, handler = {} + + -- Loop around each '-' prefixed option on this line. + while spec:sub (1, 1) == "-" do + + -- Capture end of options processing marker. + if spec:match "^%-%-,?%s" then + handler = set_handler (handler, finished) + + -- Capture optional argument in the option string. + elseif spec:match "^%-[%-%w]+=%[.+%],?%s" then + handler = set_handler (handler, optional) + + -- Capture required argument in the option string. + elseif spec:match "^%-[%-%w]+=%S+,?%s" then + handler = set_handler (handler, required) + + -- Capture any specially handled arguments. + elseif spec:match "^%-%-help,?%s" then + handler = set_handler (handler, help) + + elseif spec:match "^%-%-version,?%s" then + handler = set_handler (handler, version) + end + + -- Consume argument spec, now that it was processed above. + spec = spec:gsub ("^(%-[%-%w]+)=%S+%s", "%1 ") + + -- Consume short option. + local _, c = spec:gsub ("^%-([-%w]),?%s+(.*)$", + function (opt, rest) + if opt == "-" then opt = "--" end + table.insert (options, opt) + spec = rest + end) + + -- Be careful not to consume more than one option per iteration, + -- otherwise we might miss a handler test at the next loop. + if c == 0 then + -- Consume long option. + spec:gsub ("^%-%-([%-%w]+),?%s+(.*)$", + function (opt, rest) + table.insert (options, opt) + spec = rest + end) + end + end + + -- Unless specified otherwise, treat each option as a flag. + parser:on (options, handler or flag) + end + + return parser +end + + +-- Support calling the returned table: +return setmetatable (methods, { + __call = function (_, ...) + return OptionParser (...) + end, +}) diff --git a/lib/std/set.lua b/lib/std/set.lua index 2eb032c..5d8034b 100644 --- a/lib/std/set.lua +++ b/lib/std/set.lua @@ -63,7 +63,8 @@ end -- High level methods (representation-independent) -local difference, symmetric_difference, intersection, union, subset, equal +local difference, symmetric_difference, intersection, union, subset, + proper_subset, equal --- Find the difference of two sets. diff --git a/lib/std/string.lua b/lib/std/string.lua index c4008e8..3d58393 100644 --- a/lib/std/string.lua +++ b/lib/std/string.lua @@ -104,7 +104,7 @@ end -- @param min lowest acceptable version (default: any) -- @param too_big lowest version that is too big (default: none) -- @param pattern to match version in `module.version` or --- `module.VERSION` (default: `".*[%.%d]+"` +-- `module.VERSION` (default: `".*[%.%d]+"`) local function require_version (module, min, too_big, pattern) local function version_to_list (v) return list.new (split (v, "%.")) diff --git a/local.mk b/local.mk index 23c0ad0..fc2170b 100644 --- a/local.mk +++ b/local.mk @@ -29,7 +29,7 @@ LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" ## Bootstrap. ## ## ---------- ## -old_NEWS_hash = 7ef01dfb840329db3d8db218bfe9d075 +old_NEWS_hash = 7a7647cb5b2d5d886a18070e1f4ac5fd update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ @@ -65,14 +65,13 @@ dist_luastd_DATA = \ lib/std/base.lua \ lib/std/container.lua \ lib/std/debug.lua \ - lib/std/debug_init.lua \ lib/std/functional.lua \ - lib/std/getopt.lua \ lib/std/io.lua \ lib/std/list.lua \ lib/std/math.lua \ lib/std/modules.lua \ lib/std/object.lua \ + lib/std/optparse.lua \ lib/std/package.lua \ lib/std/set.lua \ lib/std/strbuf.lua \ @@ -82,6 +81,19 @@ dist_luastd_DATA = \ lib/std/tree.lua \ $(NOTHING_ELSE) + +# For bugwards compatibility with LuaRocks 2.1, while ensuring that +# `require "std.debug_init"` continues to work, we have to install +# the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. +# When everyone has upgraded to a LuaRocks that works, move this +# file back to dist_luastd_DATA above and rename to debug_init.lua. + +luastddebugdir = $(luastddir)/debug_init + +dist_luastddebug_DATA = \ + lib/std/debug_init/init.lua \ + $(NOTHING_ELSE) + # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to # have ldoc installed, put std/std.lua in as a Makefile dependency. @@ -90,8 +102,9 @@ lib/std.lua: lib/std.lua.in ./config.status --file=$@ -## Use a builtin rockspec build with root at $(srcdir)/lib -mkrockspecs_args = --module-dir $(srcdir)/lib +## Use a builtin rockspec build with root at $(srcdir)/lib, and note +## the github repository doesn't have the same name as the rockspec! +mkrockspecs_args = --module-dir $(srcdir)/lib --repository lua-stdlib ## ------------- ## @@ -117,6 +130,7 @@ dist_classes_DATA += \ $(srcdir)/doc/classes/std.container.html \ $(srcdir)/doc/classes/std.list.html \ $(srcdir)/doc/classes/std.object.html \ + $(srcdir)/doc/classes/std.optparse.html \ $(srcdir)/doc/classes/std.set.html \ $(srcdir)/doc/classes/std.strbuf.html \ $(srcdir)/doc/classes/std.tree.html \ @@ -126,7 +140,6 @@ dist_modules_DATA += \ $(srcdir)/doc/modules/std.html \ $(srcdir)/doc/modules/std.debug.html \ $(srcdir)/doc/modules/std.functional.html \ - $(srcdir)/doc/modules/std.getopt.html \ $(srcdir)/doc/modules/std.io.html \ $(srcdir)/doc/modules/std.math.html \ $(srcdir)/doc/modules/std.package.html \ diff --git a/rockspec.conf b/rockspec.conf index c7813c7..2e1e688 100644 --- a/rockspec.conf +++ b/rockspec.conf @@ -6,8 +6,8 @@ description: summary: General Lua Libraries detailed: stdlib is a library of modules for common programming tasks, - including list, table and functional operations, regexps, objects, - pickling, pretty-printing and getopt. + including list, table and functional operations, objects, + pickling, pretty-printing and command-line option parsing. dependencies: - lua >= 5.1 diff --git a/specs/container_spec.yaml b/specs/container_spec.yaml index 34a8ef0..ab37b67 100644 --- a/specs/container_spec.yaml +++ b/specs/container_spec.yaml @@ -1,8 +1,15 @@ before: + require "spec_helper" Container = require "std.container" prototype = (require "std.object").prototype -specify Container: +specify std.container: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.container"}). + should_equal {} + - describe construction: - context from Container prototype: - before: diff --git a/specs/debug_spec.yaml b/specs/debug_spec.yaml index 6ba7acc..038fe7c 100644 --- a/specs/debug_spec.yaml +++ b/specs/debug_spec.yaml @@ -1,60 +1,29 @@ -specify debug: -- before: | - M = require "std.debug" +before: | + require "spec_helper" - extends = debug - enhancements = {} - extensions = { "say", "trace" } + this_module = "std.debug" -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + global_table = "_G" - - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end + base_module = "debug" + extend_base = { "say", "trace" } + + M = require "std.debug" - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end +specify std.debug: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core debug table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (extend_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the core debug table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) - describe _DEBUG: diff --git a/specs/functional_spec.yaml b/specs/functional_spec.yaml new file mode 100644 index 0000000..26b87ab --- /dev/null +++ b/specs/functional_spec.yaml @@ -0,0 +1,55 @@ +before: | + require "spec_helper" + + global_table = "_G" + this_module = "std.functional" + std_globals = { "bind", "collect", "compose", "curry", "eval", + "filter", "fold", "id", "map", "memoize", + "metamethod", "op" } + + M = require (this_module) + +specify std.functional: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + + - context via the std module: + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + + +- describe bind: + + +- describe collect: + + +- describe compose: + + +- describe curry: + + +- describe eval: + + +- describe filter: + + +- describe fold: + + +- describe id: + + +- describe map: + + +- describe memoize: + + +- describe metamethod: diff --git a/specs/getopt_spec.yaml b/specs/getopt_spec.yaml deleted file mode 100644 index c36c7d0..0000000 --- a/specs/getopt_spec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -specify getopt: -- before: - getopt = require "std.getopt" - -- "describe getopt.getOpt": - - before: | - prog = { - name = "getopt_spec.lua", - options = { {{"verbose", "v"}, "verbosely list files"}, - {{"output", "o"}, "dump to FILE", "Opt", "FILE"}, - {{"name", "n"}, "only dump USER's files", "Req", "USER"}, - } - } - - function test (cmdLine, stop_at_nonopt) - local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options, stop_at_nonopt) - if #errors == 0 then - return { options = opts, args = nonOpts } - else - return errors - end - end - - getopt.processArgs (prog) - - - it recognizes a user defined option: - expect (test {"foo", "-v"}).should_equal ( - { options = { verbose = {1}}, args = { "foo" } }) - - "it treats -- as the end of the option list": - expect (test {"foo", "--", "-v"}).should_equal ( - { options = {}, args = { "foo", "-v" } }) - - it captures a list of repeated option arguments: - expect (test {"-o", "-V", "-name", "bar", "--name=baz"}).should_equal ( - { options = { name = {"bar", "baz"}, version = {1}, output = {1}}, - args = {} }) - - it diagnoses unrecognized options: - expect (test {"-foo"}).should_contain "unrecognized option `-foo'" - - it stops option parsing at the first non-option if told to: - expect (test ({"foo", "-bar"}, true)).should_equal ( - { options = {}, args = {"foo", "-bar"} }) - -- "describe getopt.usageInfo": - - context when specifying options: - - before: - helppatt = "%-h, %-%-help%s+print this help, then exit" - versionpatt = "%-V, %-%-version%s+print version information, then exit" - prog = { name = "getopt_spec.lua", options = {} } - options = { {{"help", "?"}, "display this help"}, - {{"version"}, "display version number"} } - f = getopt.usageInfo - - - it provides a default version option: - getopt.processArgs (prog) - expect (f ("", prog.options)).should_match (versionpatt) - - it allows the user to override the version option: - prog.options = options - getopt.processArgs (prog) - expect (f ("", prog.options)).should_not_match (versionpatt) - expect (f ("", prog.options)).should_match (" %-%-version%s+display") - - it provides a default help option: - getopt.processArgs (prog) - expect (f ("", prog.options)).should_match (helppatt) - - it allows the user to override the help option: - prog.options = options - getopt.processArgs (prog) - expect (f ("", prog.options)).should_not_match (helppatt) - expect (f ("", prog.options)).should_match ("%-%?, %-%-help%s+display") diff --git a/specs/io_spec.yaml b/specs/io_spec.yaml index 758060a..4c82dbf 100644 --- a/specs/io_spec.yaml +++ b/specs/io_spec.yaml @@ -1,64 +1,47 @@ -specify io: -- before: | - M = require "std.io" - - extends = io - enhancements = {} - extensions = { "catdir", "catfile", "die", "process_files", - "readlines", "shell", "slurp", "splitdir", "warn", - "writelines", - -- camelCase compatibility: - "processFiles" } +before: | + require "spec_helper" -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + this_module = "std.io" + + global_table = "_G" + std_globals = { "die", "warn" } + + base_module = "io" + extend_base = { "catdir", "catfile", "die", "process_files", + "readlines", "shell", "slurp", "splitdir", + "warn", "writelines", + -- camelCase compatibility: + "processFiles" } + extend_metamethods = { "readlines", "writelines" } + M = require (this_module) + +specify std.io: +- context when required: - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end - - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core io table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (extend_base) + - it replaces no apis from the core io table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_equal {} - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + - it adds apis to the core io table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it adds methods to the file metatable: + expect (show_apis {added_to="getmetatable (io.stdin)", by="std"}). + should_contain.a_permutation_of (extend_metamethods) + - it replaces no apis from the core io table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_equal {} - describe catdir: @@ -67,11 +50,12 @@ specify io: - describe catfile: +- describe die: + + - describe process_files: - - before: - subject = M.process_files - it is the same function as legacy processFiles call: - expect (io.processFiles).should_be (subject) + expect (M.process_files).should_be (M.processFiles) - describe readlines: @@ -86,4 +70,7 @@ specify io: - describe splitdir: +- describe warn: + + - describe writelines: diff --git a/specs/list_spec.yaml b/specs/list_spec.yaml index a80749a..523b058 100644 --- a/specs/list_spec.yaml +++ b/specs/list_spec.yaml @@ -5,7 +5,13 @@ before: l = List {"foo", "bar", "baz"} -specify List: +specify std.list: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.list"}). + should_equal {} + - describe construction: - context from List clone method: - it constructs a new list: diff --git a/specs/math_spec.yaml b/specs/math_spec.yaml index d812d4a..02c2cb0 100644 --- a/specs/math_spec.yaml +++ b/specs/math_spec.yaml @@ -1,61 +1,40 @@ -specify math: -- before: | - M = require "std.math" +before: | + require "spec_helper" - extends = math - enhancements = { "floor" } - extensions = { "round" } + this_module = "std.math" + global_table = "_G" + base_module = "math" + extend_base = { "round", "_floor" } + enhance_base = { "floor" } -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + -- 'should_contain' will match keys as well as values :) + all_apis = {} + for _, s in ipairs (extend_base) do all_apis[s] = true end + for _, s in ipairs (enhance_base) do all_apis[s] = true end - - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end + M = require (this_module) - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end +specify std.math: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core math table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (all_apis) + - it enhances some apis from the core math table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_contain.a_permutation_of (enhance_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the core math table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it replaces some apis from the core math table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_base) - describe floor: diff --git a/specs/object_spec.yaml b/specs/object_spec.yaml index 2a07af2..c0102f3 100644 --- a/specs/object_spec.yaml +++ b/specs/object_spec.yaml @@ -1,9 +1,16 @@ before: + require "spec_helper" Object = require "std.object" obj = Object {"foo", "bar", baz="quux"} prototype = Object.prototype -specify Object: +specify std.object: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.object"}). + should_equal {} + - describe construction: - context from Object clone method: - it constructs a new object: diff --git a/specs/optparse_spec.yaml b/specs/optparse_spec.yaml new file mode 100644 index 0000000..a3547fb --- /dev/null +++ b/specs/optparse_spec.yaml @@ -0,0 +1,370 @@ +before: + require "spec_helper" + hell = require "specl.shell" + +specify std.optparse: +- before: | + OptionParser = require "std.optparse" + + help = [[ + parseme (specl spec) 0α1 + + Copyright © 2013 Gary V. Vaughan + This test program comes with ABSOLUTELY NO WARRANTY. + + Usage: parseme [] ... + + Banner text. + + Long description. + + Options: + + -h, --help display this help, then exit + --version display version information, then exit + -b a short option with no long option + --long a long option with no short option + --another-long a long option with internal hypen + --true a Lua keyword as an option name + -v, --verbose a combined short and long option + -n, --dryrun, --dry-run several spellings of the same option + -u, --name=USER require an argument + -o, --output=[FILE] accept an optional argument + -- end of options + + Footer text. + + Please report bugs at . + ]] + + -- strip off the leading whitespace required for YAML + parser = OptionParser (help:gsub ("^ ", "")) + +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.optparse"}). + should_equal {} + +- describe OptionParser: + - it recognises the program name: + expect (parser.program).should_be "parseme" + - it recognises the version number: + expect (parser.version).should_be "0α1" + - it recognises the version text: + expect (parser.versiontext). + should_match "^parseme .*Copyright .*NO WARRANTY%." + - it recognises the help text: | + expect (parser.helptext). + should_match ("^Usage: parseme .*Banner .*Long .*Options:.*" .. + "Footer .*/issues>%.") + - it diagnoses incorrect input text: + expect (OptionParser "garbage in").should_error "argument must match" + +- describe parser: + - before: | + f = os.tmpname () + + function parse (arglist) + local d = f:gsub ("/[^/]*$", "", 1) + local h = io.open (f, "w") + + h:write ([[ + package.path = "]] .. package.path .. [[" + local OptionParser = require 'std.optparse' + local help = [=[]] .. help .. [[]=] + help = help:match ("^[%s\n]*(.-)[%s\n]*$") + + local parser = OptionParser (help) + local arg, opts = parser:parse (_G.arg) + + o = {} + for k, v in pairs (opts) do + table.insert (o, k .. " = " .. tostring (v)) + end + if #o > 0 then + table.sort (o) + print ("opts = { " .. table.concat (o, ", ") .. " }") + end + if #arg > 0 then + print ("args = { " .. table.concat (arg, ", ") .. " }") + end + ]]) + h:close () + + return hell.spawn {arg[-1], f, unpack (arglist)} + end + - after: os.remove (f) + + - it leaves behind unrecognised options: + expect (parse {"--not-an-option"}). + should_output "args = { --not-an-option }\n" + - it responds to --version with version text: + expect (parse {"--version"}). + should_match_output "^%s*parseme .*Copyright .*NO WARRANTY%.\n$" + - it responds to --help with help text: | + expect (parse {"--help"}). + should_match_output ("^%s*Usage: parseme .*Banner.*Long.*" .. + "Options:.*Footer.*/issues>%.\n$") + - it recognises short options: + expect (parse {"-b"}).should_output "opts = { b = true }\n" + - it recognises long options: + expect (parse {"--long"}).should_output "opts = { long = true }\n" + - it recognises long options with hyphens: + expect (parse {"--another-long"}). + should_output "opts = { another_long = true }\n" + - it recognises long options named after Lua keywords: + expect (parse {"--true"}).should_output "opts = { true = true }\n" + - it recognises combined short and long option specs: + expect (parse {"-v"}).should_output "opts = { verbose = true }\n" + expect (parse {"--verbose"}).should_output "opts = { verbose = true }\n" + - it recognises options with several spellings: + expect (parse {"-n"}).should_output "opts = { dry_run = true }\n" + expect (parse {"--dry-run"}).should_output "opts = { dry_run = true }\n" + expect (parse {"--dryrun"}).should_output "opts = { dry_run = true }\n" + - it recognises end of options marker: + expect (parse {"-- -n"}).should_output "args = { -n }\n" + - context given an option with a required argument: + - it records an argument to a long option following an '=' delimiter: + expect (parse {"--name=Gary"}). + should_output "opts = { name = Gary }\n" + - it records an argument to a short option without a space: + expect (parse {"-uGary"}). + should_output "opts = { name = Gary }\n" + - it records an argument to a long option following a space: + expect (parse {"--name Gary"}). + should_output "opts = { name = Gary }\n" + - it records an argument to a short option following a space: + expect (parse {"-u Gary"}). + should_output "opts = { name = Gary }\n" + - it diagnoses a missing argument: + expect (parse {"--name"}). + should_contain_error "'--name' requires an argument" + expect (parse {"-u"}). + should_contain_error "'-u' requires an argument" + - context given an option with an optional argument: + - it records an argument to a long option following an '=' delimiter: + expect (parse {"--output=filename"}). + should_output "opts = { output = filename }\n" + - it records an argument to a short option without a space: + expect (parse {"-ofilename"}). + should_output "opts = { output = filename }\n" + - it records an argument to a long option following a space: + expect (parse {"--output filename"}). + should_output "opts = { output = filename }\n" + - it records an argument to a short option following a space: + expect (parse {"-o filename"}). + should_output "opts = { output = filename }\n" + - it doesn't consume the following option: + expect (parse {"--output -v"}). + should_output "opts = { output = true, verbose = true }\n" + expect (parse {"-o -v"}). + should_output "opts = { output = true, verbose = true }\n" + - context when splitting combined short options: + - it separates non-argument options: + expect (parse {"-bn"}). + should_output "opts = { b = true, dry_run = true }\n" + expect (parse {"-vbn"}). + should_output "opts = { b = true, dry_run = true, verbose = true }\n" + - it stops separating at a required argument option: + expect (parse {"-vuname"}). + should_output "opts = { name = name, verbose = true }\n" + expect (parse {"-vuob"}). + shauld_output "opts = { name = ob, verbose = true }\n" + - it stops separating at an optional argument option: + expect (parse {"-vofilename"}). + should_output "opts = { output = filename, verbose = true }\n" + expect (parse {"-vobn"}). + should_output "opts = { output = bn, verbose = true }\n" + +- describe parser:on: + - before: | + f = os.tmpname () + + function parseargs (onargstr, arglist) + local d = f:gsub ("/[^/]*$", "", 1) + local h = io.open (f, "w") + + h:write ([[ + package.path = "]] .. package.path .. [[" + local OptionParser = require 'std.optparse' + local help = [=[]] .. help .. [[]=] + help = help:match ("^[%s\n]*(.-)[%s\n]*$") + + local parser = OptionParser (help) + + parser:on (]] .. onargstr .. [[) + + local arg, opts = parser:parse (_G.arg) + + o = {} + for k, v in pairs (opts) do + table.insert (o, k .. " = " .. tostring (v)) + end + if #o > 0 then + table.sort (o) + print ("opts = { " .. table.concat (o, ", ") .. " }") + end + if #arg > 0 then + print ("args = { " .. table.concat (arg, ", ") .. " }") + end + ]]) + h:close () + + return hell.spawn {arg[-1], f, unpack (arglist)} + end + - after: os.remove (f) + + - it recognises short options: + expect (parseargs ([["x"]], {"-x"})). + should_output "opts = { x = true }\n" + - it recognises long options: + expect (parseargs([["something"]], {"--something"})). + should_output "opts = { something = true }\n" + - it recognises long options with hyphens: + expect (parseargs([["some-thing"]], {"--some-thing"})). + should_output "opts = { some_thing = true }\n" + - it recognises long options named after Lua keywords: + expect (parseargs ([["if"]], {"--if"})). + should_output "opts = { if = true }\n" + - it recognises combined short and long option specs: + expect (parseargs ([[{"x", "if"}]], {"-x"})). + should_output "opts = { if = true }\n" + expect (parseargs ([[{"x", "if"}]], {"--if"})). + should_output "opts = { if = true }\n" + - it recognises options with several spellings: + expect (parseargs ([[{"x", "blah", "if"}]], {"-x"})). + should_output "opts = { if = true }\n" + expect (parseargs ([[{"x", "blah", "if"}]], {"--blah"})). + should_output "opts = { if = true }\n" + expect (parseargs ([[{"x", "blah", "if"}]], {"--if"})). + should_output "opts = { if = true }\n" + - it recognises end of options marker: + expect (parseargs ([["x"]], {"--", "-x"})). + should_output "args = { -x }\n" + - context given an option with a required argument: + - it records an argument to a short option without a space: + expect (parseargs ([["x", parser.required]], {"-y", "-xarg", "-b"})). + should_contain_output "opts = { b = true, x = arg }" + - it records an argument to a short option following a space: + expect (parseargs ([["x", parser.required]], {"-y", "-x", "arg", "-b"})). + should_contain_output "opts = { b = true, x = arg }\n" + - it records an argument to a long option following a space: + expect (parseargs ([["this", parser.required]], {"--this", "arg"})). + should_output "opts = { this = arg }\n" + - it records an argument to a long option following an '=' delimiter: + expect (parseargs ([["this", parser.required]], {"--this=arg"})). + should_output "opts = { this = arg }\n" + - it diagnoses a missing argument: + expect (parseargs ([[{"x", "this"}, parser.required]], {"-x"})). + should_contain_error "'-x' requires an argument" + expect (parseargs ([[{"x", "this"}, parser.required]], {"--this"})). + should_contain_error "'--this' requires an argument" + - context with a boolean handler function: + - it records a truthy argument: + for _, optarg in ipairs {"1", "TRUE", "true", "yes", "Yes", "y"} + do + expect (parseargs ([["x", parser.required, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = true }\n" + end + - it records a falsey argument: + for _, optarg in ipairs {"0", "FALSE", "false", "no", "No", "n"} + do + expect (parseargs ([["x", parser.required, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = false }\n" + end + - context with a file handler function: + - it records an existing file: + expect (parseargs ([["x", parser.required, parser.file]], + {"-x", "/dev/null"})). + should_output "opts = { x = /dev/null }\n" + - it diagnoses a missing file: | + expect (parseargs ([["x", parser.required, parser.file]], + {"-x", "/this/file/does/not/exist"})). + should_contain_error "error: /this/file/does/not/exist: " + - context with a custom handler function: + - it calls the handler: + expect (parseargs ([["x", parser.required, function (p,o,a) + return "custom" + end + ]], {"-x", "ignored"})). + should_output "opts = { x = custom }\n" + - it diagnoses a missing argument: + expect (parseargs ([["x", parser.required, function (p,o,a) + return "custom" + end + ]], {"-x"})). + should_contain_error "option '-x' requires an argument" + - context given an option with an optional argument: + - it records an argument to a short option without a space: + expect (parseargs ([["x", parser.optional]], {"-y", "-xarg", "-b"})). + should_contain_output "opts = { b = true, x = arg }" + - it records an argument to a short option following a space: + expect (parseargs ([["x", parser.optional]], {"-y", "-x", "arg", "-b"})). + should_contain_output "opts = { b = true, x = arg }\n" + - it records an argument to a long option following a space: + expect (parseargs ([["this", parser.optional]], {"--this", "arg"})). + should_output "opts = { this = arg }\n" + - it records an argument to a long option following an '=' delimiter: + expect (parseargs ([["this", parser.optional]], {"--this=arg"})). + should_output "opts = { this = arg }\n" + - it does't consume the following option: + expect (parseargs ([[{"x", "this"}, parser.optional]], {"-x", "-b"})). + should_output "opts = { b = true, this = true }\n" + expect (parseargs ([[{"x", "this"}, parser.optional]], {"--this", "-b"})). + should_output "opts = { b = true, this = true }\n" + - context with a boolean handler function: + - it records a truthy argument: + for _, optarg in ipairs {"1", "TRUE", "true", "yes", "Yes", "y"} + do + expect (parseargs ([["x", parser.optional, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = true }\n" + end + - it records a falsey argument: + for _, optarg in ipairs {"0", "FALSE", "false", "no", "No", "n"} + do + expect (parseargs ([["x", parser.optional, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = false }\n" + end + - it defaults to a truthy value: + expect (parseargs ([["x", parser.optional, parser.boolean]], + {"-x", "-b"})). + should_output "opts = { b = true, x = true }\n" + - context with a file handler function: + - it records an existing file: + expect (parseargs ([["x", parser.optional, parser.file]], + {"-x", "/dev/null"})). + should_output "opts = { x = /dev/null }\n" + - it diagnoses a missing file: | + expect (parseargs ([["x", parser.optional, parser.file]], + {"-x", "/this/file/does/not/exist"})). + should_contain_error "error: /this/file/does/not/exist: " + - context with a custom handler function: + - it calls the handler: + expect (parseargs ([["x", parser.optional, function (p,o,a) + return "custom" + end + ]], {"-x", "ignored"})). + should_output "opts = { x = custom }\n" + - it does not consume a following option: + expect (parseargs ([["x", parser.optional, function (p,o,a) + return a or "default" + end + ]], {"-x", "-b"})). + should_output "opts = { b = true, x = default }\n" + - context when splitting combined short options: + - it separates non-argument options: + expect (parseargs ([["x"]], {"-xb"})). + should_output "opts = { b = true, x = true }\n" + expect (parseargs ([["x"]], {"-vxb"})). + should_output "opts = { b = true, verbose = true, x = true }\n" + - it stops separating at a required argument option: + expect (parseargs ([[{"x", "this"}, parser.required]], {"-bxbit"})). + should_output "opts = { b = true, this = bit }\n" + - it stops separating at an optional argument option: + expect (parseargs ([[{"x", "this"}, parser.optional]], {"-bxbit"})). + should_output "opts = { b = true, this = bit }\n" diff --git a/specs/package_spec.yaml b/specs/package_spec.yaml index c7b4bbd..bf561d2 100644 --- a/specs/package_spec.yaml +++ b/specs/package_spec.yaml @@ -1,63 +1,38 @@ -specify package: -- before: | - M = require "std.package" +before: | + require "spec_helper" - extends = package - extensions = { "dirsep", "pathsep", "path_mark", "execdir", "igmark" } - enhancements = {} + this_module = "std.package" - -- Do not try to check all the entries in unextended package, - -- because they naturally change as modules are loaded. - coreapis = { "config", "cpath", "loaders", "loadlib", "preload", - "searchers", "searchpath", "seeall" } + global_table = "_G" + base_module = "package" + extend_base = { "dirsep", "pathsep", "path_mark", + "execdir", "igmark" } -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + M = require (this_module) +specify std.package: +- context when required: - context by name: - - before: - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - for _, api in ipairs (enhancements) do - extends[api], extends["_" .. api] = M[api], M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = M[api] end - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for _, api in ipairs (coreapis) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core package table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (extend_base) + - it replaces no apis from the core package table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_equal {} - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for _, api in ipairs (coreapis) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the core package table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it replaces no apis from the core package table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_equal {} + -- "it splits package.config up": +- it splits package.config up: expect (string.format ("%s\n%s\n%s\n%s\n%s\n", M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark) ).should_contain (package.config) diff --git a/specs/set_spec.yaml b/specs/set_spec.yaml index 4e7f931..9f96e3a 100644 --- a/specs/set_spec.yaml +++ b/specs/set_spec.yaml @@ -5,7 +5,13 @@ before: totable = (require "std.table").totable s = Set {"foo", "bar", "bar"} -specify Set: +specify std.set: +- describe require: + - it does not perturb the global namespace: + expect (show_apis {added_to="_G", by="std.set"}). + should_equal {} + + - describe construction: - it constructs a new set: s = Set {} diff --git a/specs/spec_helper.lua b/specs/spec_helper.lua deleted file mode 100644 index 2480cc1..0000000 --- a/specs/spec_helper.lua +++ /dev/null @@ -1,29 +0,0 @@ --- Not local, so that it is available in spec examples. -totable = (require "std.table").totable - - --- Custom matcher for set membership. - -local set = require "std.set" -local util = require "specl.util" -local matchers = require "specl.matchers" - -local Matcher, matchers, q = - matchers.Matcher, matchers.matchers, matchers.stringify - -matchers.have_member = Matcher { - function (actual, expect) - return set.member (actual, expect) - end, - - actual = "set", - - format_expect = function (expect) - return " a set containing " .. q (expect) .. ", " - end, - - format_any_of = function (alternatives) - return " a set containing any of " .. - util.concat (alternatives, util.QUOTED) .. ", " - end, -} diff --git a/specs/spec_helper.lua.in b/specs/spec_helper.lua.in new file mode 100644 index 0000000..75b4232 --- /dev/null +++ b/specs/spec_helper.lua.in @@ -0,0 +1,145 @@ +local hell = require "specl.shell" + +-- Substitute configured LUA so that hell.spawn doesn't pick up +-- a different Lua binary to the one used by Specl itself. If +-- we could rely on luaposix availability `posix.getenv` would +-- be a nicer way to find this... +local LUA = "@LUA@" + +local function mkscript (code) + local f = os.tmpname () + local h = io.open (f, "w") + h:write (code) + h:close () + return f +end + +local function tabulate_output (code) + local f = mkscript (code) + local proc = hell.spawn { + LUA, f; + env = { LUA_PATH=package.path, LUA_INIT="", LUA_INIT_5_2="" }, + } + os.remove (f) + if proc.status ~= 0 then return error (proc.errout) end + local r = {} + proc.output:gsub ("(%S*)[%s]*", + function (x) + if x ~= "" then r[x] = true end + end) + return r +end + + +--- Show changes to tables wrought by a require statement. +-- There are a few modes to this function, controlled by what named +-- arguments are given. Lists new keys in T1 after `require "import"`: +-- +-- show_apis {added_to=T1, by=import} +-- +-- List keys returned from `require "import"`, which have the same +-- value in T1: +-- +-- show_apis {from=T1, used_by=import} +-- +-- List keys from `require "import"`, which are also in T1 but with +-- a different value: +-- +-- show_apis {from=T1, enhanced_by=import} +-- +-- List keys from T2, which are also in T1 but with a different value: +-- +-- show_apis {from=T1, enhanced_in=T2} +-- +-- @tparam table argt one of the combinations above +-- @treturn table a list of keys according to criteria above +function show_apis (argt) + local added_to, from, not_in, enhanced_in, enhanced_after, by = + argt.added_to, argt.from, argt.not_in, argt.enhanced_in, + argt.enhanced_after, argt.by + + if added_to and by then + return tabulate_output ([[ + local before, after = {}, {} + for k in pairs (]] .. added_to .. [[) do + before[k] = true + end + + local M = require "]] .. by .. [[" + for k in pairs (]] .. added_to .. [[) do + after[k] = true + end + + for k in pairs (after) do + if not before[k] then print (k) end + end + ]]) + + elseif from and not_in then + return tabulate_output ([[ + local from = ]] .. from .. [[ + local M = require "]] .. not_in .. [[" + + for k in pairs (M) do + if from[k] ~= M[k] then print (k) end + end + ]]) + + elseif from and enhanced_in then + return tabulate_output ([[ + local from = ]] .. from .. [[ + local M = require "]] .. enhanced_in .. [[" + + for k, v in pairs (M) do + if from[k] ~= M[k] and from[k] ~= nil then print (k) end + end + ]]) + + elseif from and enhanced_after then + return tabulate_output ([[ + local before, after = {}, {} + local from = ]] .. from .. [[ + + for k, v in pairs (from) do before[k] = v end + ]] .. enhanced_after .. [[ + for k, v in pairs (from) do after[k] = v end + + for k, v in pairs (before) do + if after[k] ~= nil and after[k] ~= v then print (k) end + end + ]]) + end + + assert (false, "missing argument to show_apis") +end + + +-- Not local, so that it is available in spec examples. +totable = (require "std.table").totable + + +-- Custom matcher for set membership. + +local set = require "std.set" +local util = require "specl.util" +local matchers = require "specl.matchers" + +local Matcher, matchers, q = + matchers.Matcher, matchers.matchers, matchers.stringify + +matchers.have_member = Matcher { + function (actual, expect) + return set.member (actual, expect) + end, + + actual = "set", + + format_expect = function (expect) + return " a set containing " .. q (expect) .. ", " + end, + + format_any_of = function (alternatives) + return " a set containing any of " .. + util.concat (alternatives, util.QUOTED) .. ", " + end, +} diff --git a/specs/specs.mk b/specs/specs.mk index 99ae87a..45c1fcc 100644 --- a/specs/specs.mk +++ b/specs/specs.mk @@ -5,31 +5,41 @@ ## Environment. ## ## ------------ ## -SPECL_ENV = $(LUA_ENV) +specs_path = $(abs_builddir)/specs/?.lua +SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" ## ------ ## ## Specs. ## ## ------ ## +SPECL_OPTS = --unicode + +## For compatibility with Specl < 11, std_spec.yaml has to be +## last, so that when `require "std"` leaks symbols into the +## Specl global environment, subsequent example blocks are not +## affected. + specl_SPECS = \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ - $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/functional_spec.yaml \ $(srcdir)/specs/io_spec.yaml \ $(srcdir)/specs/list_spec.yaml \ $(srcdir)/specs/math_spec.yaml \ $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/optparse_spec.yaml \ $(srcdir)/specs/package_spec.yaml \ $(srcdir)/specs/set_spec.yaml \ $(srcdir)/specs/strbuf_spec.yaml \ $(srcdir)/specs/string_spec.yaml \ $(srcdir)/specs/table_spec.yaml \ $(srcdir)/specs/tree_spec.yaml \ + $(srcdir)/specs/std_spec.yaml \ $(NOTHING_ELSE) EXTRA_DIST += \ - $(srcdir)/specs/spec_helper.lua \ + $(srcdir)/specs/spec_helper.lua.in \ $(NOTHING_ELSE) include build-aux/specl.mk diff --git a/specs/std_spec.yaml b/specs/std_spec.yaml new file mode 100644 index 0000000..f8f758c --- /dev/null +++ b/specs/std_spec.yaml @@ -0,0 +1,12 @@ +specify std: +- describe lazy loading: + - before: + std = require "std" + - it has no submodules on initial load: + expect (std).should_equal {version = std.version} + - it loads submodules on demand: + lazy = std.set + expect (lazy).should_be (require "std.set") + - it loads submodule functions on demand: + expect (std.object.prototype (std.set {"Lazy"})). + should_be "Set" diff --git a/specs/strbuf_spec.yaml b/specs/strbuf_spec.yaml index 11bdc9a..6851dcd 100644 --- a/specs/strbuf_spec.yaml +++ b/specs/strbuf_spec.yaml @@ -1,9 +1,16 @@ before: + require "spec_helper" object = require "std.object" StrBuf = require "std.strbuf" b = StrBuf {"foo", "bar"} -specify StrBuf: +specify std.strbuf: +- describe require: + - it does not perturb the global namespace: + expect (show_apis {added_to="_G", by="std.strbuf"}). + should_equal {} + + - describe construction: - context from StrBuf clone method: - it constructs a new strbuf: diff --git a/specs/string_spec.yaml b/specs/string_spec.yaml index d4de247..e141a41 100644 --- a/specs/string_spec.yaml +++ b/specs/string_spec.yaml @@ -1,70 +1,73 @@ -specify string: -- before: | - M = require "std.string" - - extends = string - enhancements = { "assert", "format", "tostring" } - extensions = { "caps", "chomp", "escape_pattern", "escape_shell", - "finds", "ltrim", "numbertosi", "ordinal_suffix", - "pad", "pickle", "prettytostring", "render", - "require_version", "rtrim", "split", "tfind", - "trim", "wrap", - -- make these available after require "std" - "__index", "_format", "_tostring", - -- camelCase compatibility: - "escapePattern", "escapeShell", "ordinalSuffix" } - +before: | + require "spec_helper" + + this_module = "std.string" + + global_table = "_G" + std_globals = { "pickle", "prettytostring", "render", + "require_version" } + enhance_globals = { "assert", "tostring" } + + base_module = "string" + extend_base = { "assert", "caps", "chomp", "escape_pattern", + "escape_shell", "finds", "ltrim", "numbertosi", + "ordinal_suffix", "pad", "pickle", + "prettytostring", "render", "require_version", + "rtrim", "split", "tfind", "tostring", "trim", + "wrap", + -- make these available after require "std" + "__index", "_format", "_tostring", + -- camelCase compatibility: + "escapePattern", "escapeShell", + "ordinalSuffix" } + enhance_base = { "format" } + extend_metamethods = { "__append", "__concat" } + enhance_metamethods = { "__index" } + + -- 'should_contain' will match keys as well as values :) + all_apis = {} + for _, s in ipairs (std_globals) do all_apis[s] = true end + for _, s in ipairs (enhance_globals) do all_apis[s] = true end + for _, s in ipairs (extend_base) do all_apis[s] = true end + for _, s in ipairs (enhance_base) do all_apis[s] = true end + + M = require "std.string" + +specify std.string: +- before: subject = "a string \n\n" - - context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end - - context by name: - - before: | - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - for _, api in ipairs (enhancements) do - extends[api], extends["_" .. api] = M[api], M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = M[api] end - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core string table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (all_apis) + - it enhances some apis from the core string table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_contain.a_permutation_of (enhance_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end - - -- "describe ..": + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + - it adds apis to the core string table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it adds methods to the string metatable: + expect (show_apis {added_to="getmetatable ('')", by="std"}). + should_contain.a_permutation_of (extend_metamethods) + - it replaces some entries in the string metatable: + expect (show_apis {from="getmetatable ('')", enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_metamethods) + - it replaces some apis in the core string table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_base) + + +- describe ..: - it concatenates string arguments: target = "a string \n\n another string" expect (subject .. " another string").should_be (target) diff --git a/specs/table_spec.yaml b/specs/table_spec.yaml index 2620d5c..d33cbf9 100644 --- a/specs/table_spec.yaml +++ b/specs/table_spec.yaml @@ -1,62 +1,58 @@ -specify table: -- before: | - M = require "std.table" - - extends = table - enhancements = { "sort" } - extensions = { "clone", "clone_rename", "empty", "invert", "keys", - "merge", "new", "pack", "ripairs", "size", "totable", - "values" } - +before: | + require "spec_helper" + + base_module = "table" + this_module = "std.table" + global_table = "_G" + + std_globals = { "pack", "ripairs", "totable" } + extend_base = { "clone", "clone_rename", "empty", + "invert", "keys", "merge", "new", + "ripairs", "size", "totable", "values", + -- make these available after require "std" + "_sort" } + enhance_base = { "sort" } + + + -- 'should_contain' will match keys as well as values :) + all_apis = {} + for _, s in ipairs (std_globals) do all_apis[s] = true end + for _, s in ipairs (extend_base) do all_apis[s] = true end + for _, s in ipairs (enhance_base) do all_apis[s] = true end + + if table.pack then + -- Lua 5.2 + table.insert (enhance_base, "pack") + else + -- Lua 5.1 + table.insert (extend_base, "pack") + end + + M = require "std.table" + +specify std.table: - context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end - - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end - - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core table table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (all_apis) + - it enhances some apis from the core table table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_contain.a_permutation_of (enhance_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + - it adds apis to the core table table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it replaces some apis in the core table table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_base) - describe clone: diff --git a/specs/tree_spec.yaml b/specs/tree_spec.yaml index c0520da..d9ec245 100644 --- a/specs/tree_spec.yaml +++ b/specs/tree_spec.yaml @@ -1,11 +1,30 @@ -before: - Tree = require "std.tree" - prototype = (require "std.object").prototype - totable = (require "std.table").totable - t = {foo="foo", fnord={branch={bar="bar", baz="baz"}}, quux="quux"} - tr = Tree (t) +before: | + require "spec_helper" + + global_table = "_G" + this_module = "std.tree" + std_globals = { "ileaves", "inodes", "leaves", "nodes" } + + Tree = require "std.tree" + +specify std.tree: +- before: + prototype = (require "std.object").prototype + totable = (require "std.table").totable + t = {foo="foo", fnord={branch={bar="bar", baz="baz"}}, quux="quux"} + tr = Tree (t) + +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + + - context via the std module: + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) -specify tree: - describe construction: - it constructs a new tree: tr = Tree {} diff --git a/stdlib-36-1.rockspec b/stdlib-37-1.rockspec similarity index 78% rename from stdlib-36-1.rockspec rename to stdlib-37-1.rockspec index 7e9574e..3f12722 100644 --- a/stdlib-36-1.rockspec +++ b/stdlib-37-1.rockspec @@ -1,14 +1,14 @@ package = "stdlib" -version = "36-1" +version = "37-1" description = { - detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt.", + detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://rrthomas.github.io/lua-stdlib", license = "MIT/X11", summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v36", - url = "http://github.com/rrthomas/lua-stdlib/archive/release-v36.zip", + dir = "lua-stdlib-release-v37", + url = "http://github.com/rrthomas/lua-stdlib/archive/release-v37.zip", } dependencies = { "lua >= 5.1", @@ -20,14 +20,14 @@ build = { ["std.base"] = "lib/std/base.lua", ["std.container"] = "lib/std/container.lua", ["std.debug"] = "lib/std/debug.lua", - ["std.debug_init"] = "lib/std/debug_init.lua", + ["std.debug_init"] = "lib/std/debug_init/init.lua", ["std.functional"] = "lib/std/functional.lua", - ["std.getopt"] = "lib/std/getopt.lua", ["std.io"] = "lib/std/io.lua", ["std.list"] = "lib/std/list.lua", ["std.math"] = "lib/std/math.lua", ["std.modules"] = "lib/std/modules.lua", ["std.object"] = "lib/std/object.lua", + ["std.optparse"] = "lib/std/optparse.lua", ["std.package"] = "lib/std/package.lua", ["std.set"] = "lib/std/set.lua", ["std.strbuf"] = "lib/std/strbuf.lua", diff --git a/travis.yml.in b/travis.yml.in index 1d4be12..602e072 100644 --- a/travis.yml.in +++ b/travis.yml.in @@ -29,12 +29,11 @@ install: # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz - - cd $LUAROCKS_BASE - - ./configure - --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX - --with-lua-include=$LUA_INCDIR - - make all install - - cd .. + - ( cd $LUAROCKS_BASE; + ./configure + --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX + --with-lua-include=$LUA_INCDIR; + make all install; ) # Configure and build. script: @@ -54,7 +53,7 @@ script: # Install extra rocks into $LUAROCKS_CONFIG rocks tree. @EXTRA_ROCKS@ - # Make git rockspec for this package. + # Make git rockspec for this @PACKAGE@ - make rockspecs LUAROCKS="$LUAROCKS" V=1 || { $LUAROCKS path; cat $ROCKSPEC; } @@ -63,11 +62,7 @@ script: - $LUAROCKS make $ROCKSPEC LUA="$LUA" # Run self-tests in the `luarocks make` build tree. - # Use bin/specl if present, or else the specl rock from EXTRA_ROCKS - # above. - - if test -f luarocks/bin/specl; then export SPECL=luarocks/bin/specl; - elif test -f bin/specl; then export SPECL=bin/specl; fi - - export LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" - - export LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" - - export LUA_INIT=; export LUA_INIT_5_2= - - make check SPECL="$SPECL" V=1 + - LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" + LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" + LUA_INIT= LUA_INIT_5_2= + make check V=1 From 045f3dcd1c6dd616836218ce7f27845d1ba4df01 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Sun, 19 Jan 2014 19:50:19 +1300 Subject: [PATCH 22/34] Release v37. Signed-off-by: Gary V. Vaughan --- .travis.yml | 28 +- ChangeLog | 155 +++ Makefile.in | 108 +- NEWS | 38 + build-aux/mkrockspecs | 42 +- build-aux/sanity-cfg.mk | 3 + build-aux/specl.mk | 2 +- configure | 26 +- configure.ac | 4 +- doc/classes/std.container.html | 4 +- doc/classes/std.list.html | 962 +++++++++++++++--- doc/classes/std.object.html | 4 +- doc/classes/std.optparse.html | 742 ++++++++++++++ doc/classes/std.set.html | 4 +- doc/classes/std.strbuf.html | 4 +- doc/classes/std.tree.html | 4 +- doc/config.ld | 3 +- doc/config.ld.in | 30 + doc/index.html | 12 +- doc/modules/std.debug.html | 4 +- doc/modules/std.functional.html | 4 +- doc/modules/std.getopt.html | 248 ----- doc/modules/std.html | 55 +- doc/modules/std.io.html | 4 +- doc/modules/std.math.html | 4 +- doc/modules/std.package.html | 4 +- doc/modules/std.strict.html | 4 +- doc/modules/std.string.html | 6 +- doc/modules/std.table.html | 4 +- lib/std.lua | 33 +- lib/std.lua.in | 31 +- lib/std/base.lua | 2 + lib/std/container.lua | 2 +- .../{debug_init.lua => debug_init/init.lua} | 0 lib/std/getopt.lua | 299 ------ lib/std/list.lua | 592 +++++++---- lib/std/modules.lua | 2 +- lib/std/optparse.lua | 533 ++++++++++ lib/std/set.lua | 38 +- lib/std/strbuf.lua | 5 + lib/std/string.lua | 8 +- lib/std/tree.lua | 28 +- local.mk | 25 +- rockspec.conf | 4 +- specs/container_spec.yaml | 9 +- specs/debug_spec.yaml | 71 +- specs/functional_spec.yaml | 55 + specs/getopt_spec.yaml | 67 -- specs/io_spec.yaml | 105 +- specs/list_spec.yaml | 8 +- specs/math_spec.yaml | 81 +- specs/object_spec.yaml | 9 +- specs/optparse_spec.yaml | 370 +++++++ specs/package_spec.yaml | 79 +- specs/set_spec.yaml | 8 +- specs/spec_helper.lua | 29 - specs/spec_helper.lua.in | 145 +++ specs/specs.mk | 16 +- specs/std_spec.yaml | 12 + specs/strbuf_spec.yaml | 9 +- specs/string_spec.yaml | 125 +-- specs/table_spec.yaml | 106 +- specs/tree_spec.yaml | 33 +- stdlib-36-1.rockspec => stdlib-37-1.rockspec | 12 +- travis.yml.in | 25 +- 65 files changed, 3961 insertions(+), 1527 deletions(-) create mode 100644 build-aux/sanity-cfg.mk create mode 100644 doc/classes/std.optparse.html create mode 100644 doc/config.ld.in delete mode 100644 doc/modules/std.getopt.html rename lib/std/{debug_init.lua => debug_init/init.lua} (100%) delete mode 100644 lib/std/getopt.lua create mode 100644 lib/std/optparse.lua create mode 100644 specs/functional_spec.yaml delete mode 100644 specs/getopt_spec.yaml create mode 100644 specs/optparse_spec.yaml delete mode 100644 specs/spec_helper.lua create mode 100644 specs/spec_helper.lua.in create mode 100644 specs/std_spec.yaml rename stdlib-36-1.rockspec => stdlib-37-1.rockspec (78%) diff --git a/.travis.yml b/.travis.yml index 6f3f7be..cead315 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - LUAROCKS_BASE=luarocks-2.1.1 - LUAROCKS="$LUA $HOME/bin/luarocks" + - LDOC_ROCKSPEC=http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec matrix: - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 LUA_SUFFIX=5.2 @@ -29,12 +30,11 @@ install: # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz - - cd $LUAROCKS_BASE - - ./configure - --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX - --with-lua-include=$LUA_INCDIR - - make all install - - cd .. + - ( cd $LUAROCKS_BASE; + ./configure + --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX + --with-lua-include=$LUA_INCDIR; + make all install; ) # Configure and build. script: @@ -54,9 +54,9 @@ script: # Install extra rocks into $LUAROCKS_CONFIG rocks tree. - $LUAROCKS install lyaml; $LUAROCKS install specl; # LDoc 1.4.0 is not in luarocks yet, and LDoc master has no rockspec :( - - $LUAROCKS install http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec + - $LUAROCKS install $LDOC_ROCKSPEC - # Make git rockspec for this package. + # Make git rockspec for this stdlib - make rockspecs LUAROCKS="$LUAROCKS" V=1 || { $LUAROCKS path; cat $ROCKSPEC; } @@ -65,11 +65,7 @@ script: - $LUAROCKS make $ROCKSPEC LUA="$LUA" # Run self-tests in the `luarocks make` build tree. - # Use bin/specl if present, or else the specl rock from EXTRA_ROCKS - # above. - - if test -f luarocks/bin/specl; then export SPECL=luarocks/bin/specl; - elif test -f bin/specl; then export SPECL=bin/specl; fi - - export LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" - - export LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" - - export LUA_INIT=; export LUA_INIT_5_2= - - make check SPECL="$SPECL" V=1 + - LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" + LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" + LUA_INIT= LUA_INIT_5_2= + make check V=1 diff --git a/ChangeLog b/ChangeLog index 341c8ff..cba7d37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,160 @@ +2014-01-19 Gary V. Vaughan + + Release version 37 + * NEWS: Record release date. + + refactor: rearrange methods and functions for backwards compatibility. + * lib/std/list.lua: Make use of `_function` table to reinstate + backwards compatible module functions. + + maint: retract release 36. + Release 36 intentionally, but unnecessarily, broke backwards + compatibility in list, set, strbuf and tree. Reinstate + compatibility with v35 and earlier where possible. + * lib/std/list.lua (list.filter, list.foldl, list.foldr) + (list.indexKey, list.indexValue, list.map, list.mapWith) + (list.new, list.project, list.shape, list.zipWith): Accept + parameters in the original v35 order. + * lib/std/set.lua, lib/std/strbuf.lua, lib/std/tree.lua (new): + Reinstate for undocumented backwards compatibility. + * News: Update. + + object: share metatables more aggressively. + * lib/std/container.lua (clone): Don't create a new metatable + unnecessarily just because the base object has a `_function` + element -- which is not copied in any case. + + string: use new syntax for List instantiation. + * lib/std/string.lua: List is an Object now. + (split): Use `List` instead of `list`. + (require_version): Use new syntax for List instantiation. + + Revert "maint: post-release administrivia." + This reverts commit 846fd4e578cf8a57c8268979c9fbd2495b0e7b5b. + +2014-01-18 Gary V. Vaughan + + maint: post-release administrivia. + * configure.ac (AC_INIT): Bump version to 38. + * NEWS: Add header line for next release. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + + Release version 37 + * NEWS: Record release date. + + specs: make sure hell.spawn uses the same Lua as Specl examples. + * slingshot: Sync with upstream, for build-aux/specs.mk fix. + * configure.ac (AC_CONFIG_FILES): Add specs/spec_helper.lua. + * specs/spec_helper.lua: Move from here... + * specs/spec_helper.lua.in: ...to here. + * .gitignore: Add spec_helper.lua. + * specs/specs.mk (SPECL_ENV): Add $builddir/specs to LUA_PATH + for generated spec_helper.lua. + * specs/spec_helper.lua.in (LUA): Don't dig through `_G.arg`, + wait for configure substitution. + + specs: remove duplicate examples. + * specs/math_spec.yaml: forgot to remove the old namespace + corruption tests from this file when adding new check in 3507e84. + + specs: compatibility with Specl < 11. + * specs/specs.mk (specl_SPECS): Move std_spec.yaml to the end of + the list, where symbol leaks don't affect subsequent examples. + +2014-01-17 Gary V. Vaughan + + specs: compensate for table.pack differences between Lua 5.1/5.2. + * specs/table_spec (before): Make sure `extend_base` and + `enhance_base` reflect whether core table library has a `pack` + entry. + + std: lazy load submodules on demand. + * specs/std_spec.yaml: New specifications for lazy loading. + * specs/specs.mk (specl_SPECS): Add specs/std_spec.yaml. + * lib/std.lua.in (std.__index): Implement it. + * NEWS: Update. + + doc: add the package name and version to html doc page titles. + * doc/config.ld: Move from here... + * doc/config.ld.in: ...to here. Add a title setting incorporating + @PACKAGE@ and @VERSION@. + * configure.ac (AC_CONFIG_FILES): Add doc/config.ld. + * .gitignore: Add doc/config.ld. + Suggested by Dirk Laurie + + maint: plug symbol leaks with working specifications. + * specs/spec_helper.lua (show_apis): New function. Compare table + entries in a sub-process, to support tracking namespace changes + when requiring modules by various means. + * specs/functional_spec.yaml: New file. Use it to ensure + "std.functional" doesn't leak symbols. + * specs/debug_spec.yaml, specs/functional_spec.yaml, + specs/io_spec.yaml, specs/list_spec.yaml, specs/math_spec.yaml, + specs/object_spec.yaml, specs/optparse_spec.yaml, + specs/package_spec.yaml, specs/set_spec.yaml, + specs/spec_helper.lua, specs/specs.mk, specs/strbuf_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml, + specs/tree_spec.yaml: Rewrite specs that check symbol leaks + using show_apis(). + * lib/std/base.lua (new): Don't forget the forward declaration. + * lib/std/set.lua (proper_subset): Likewise. + * NEWS: Update. + Reported by Dirk Laurie + + rockspecs: update detailed description text. + * rockspec.conf (description.detailed): Remove mention of regexps + and getopt. Add mention of civilised option parsing. + + maint: cosmetic fix to imported module list. + * lib/std/modules.lua: Replace `getopt` with `optparse`. + + maint: workaround a luarocks bug handling debug_init.lua. + LuaRocks misinstalls build.modules entries ending in `init.lua`, + so rearrange the source tree and Automake rules so that + `require "std.debug_init"` still works as before even though + the file ends up in the wrong directory after installation. + * lib/std/debug_init.lua: Move from here... + * lib/std/debug_init/init.lua: ...to here. + * slingshot: upgrade for `.../init.lua` handling in mkrockspecs. + * local.mk (dist_luastd_DATA): Remove lib/std/debug_init.lua. + (dist_luastddebug_DATA): New installation dir. Add + lib/std/debug_init/init.lua. + + optparse: replace getopt with an easier to use option parser. + * specs/optparse_spec.yaml: Specify behaviour for a civilised + option parsing API. + * lib/std/optparse.lua: New module. + * lib/std/getopt.lua: Remove. + * doc/config.ld (file), local.mk (dist_luastd_DATA): Adjust. + * specs/getopt_spec.yaml: Remove. + * local.mk (dist_modules_DATA, dist_classes_DATA): Adjust. + * specs/specs.mk (specl_SPECS): Likewise. + * build-aux/sanity-cfg.mk: New file. Don't fail sanity checks on + account of 'OptionParser' in optparse.lua error message. + * NEWS: Update. + +2014-01-17 Reuben Thomas + + string.lua: fix a missing close paren in a docstring + 2014-01-16 Gary V. Vaughan + slingshot: resync for `mkrockspecs --repository` support. + * slingshot: Sync with upstream. + * local.mk (mkrockspecs_args): Add `--repository lua-stdlib`. + * .travis.yml: Regenerate. + + slingshot: sync with upstream, for bootstrap git detection fix. + * slingshot: Sync with upstream. + * bootstrap: Sync with slingshot. + + maint: post-release administrivia. + * NEWS: Add header line for next release. + * configure.ac: Bump version number to 37. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + Release version 36 * NEWS: Record release date. diff --git a/Makefile.in b/Makefile.in index 307409a..269b227 100644 --- a/Makefile.in +++ b/Makefile.in @@ -185,10 +185,12 @@ DIST_COMMON = $(srcdir)/local.mk $(srcdir)/specs/specs.mk \ INSTALL NEWS README AUTHORS ChangeLog $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(srcdir)/travis.yml.in \ - $(dist_bin_SCRIPTS) $(dist_classes_DATA) $(dist_doc_DATA) \ - $(dist_lua_DATA) $(dist_luastd_DATA) $(dist_modules_DATA) \ - COPYING build-aux/install-sh build-aux/missing \ - $(top_srcdir)/build-aux/install-sh \ + $(top_srcdir)/doc/config.ld.in \ + $(top_srcdir)/specs/spec_helper.lua.in $(dist_bin_SCRIPTS) \ + $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ + $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ + $(dist_modules_DATA) COPYING build-aux/install-sh \ + build-aux/missing $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -200,7 +202,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = .travis.yml +CONFIG_CLEAN_FILES = .travis.yml doc/config.ld specs/spec_helper.lua CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -232,8 +234,8 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" \ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" \ - "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(modulesdir)" \ - "$(DESTDIR)$(docdir)" + "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" \ + "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)" LTLIBRARIES = $(lib_LTLIBRARIES) SCRIPTS = $(bin_SCRIPTS) $(dist_bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) @@ -256,7 +258,8 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ - $(dist_luastd_DATA) $(dist_modules_DATA) $(doc_DATA) + $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ + $(dist_modules_DATA) $(doc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -366,7 +369,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 AM_CPPFLAGS = $(LUA_INCLUDE) -EXTRA_DIST = $(srcdir)/specs/spec_helper.lua $(NOTHING_ELSE) \ +EXTRA_DIST = $(srcdir)/specs/spec_helper.lua.in $(NOTHING_ELSE) \ $(specl_SPECS) $(NOTHING_ELSE) doc/config.ld lib/std.lua.in \ $(NOTHING_ELSE) $(mkrockspecs) $(package_rockspec) \ $(rockspec_conf) $(NOTHING_ELSE) @@ -386,7 +389,7 @@ man_MANS = save_release_files = $(scm_rockspec) std_path = $(abs_srcdir)/lib/?.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = 7ef01dfb840329db3d8db218bfe9d075 +old_NEWS_hash = 7a7647cb5b2d5d886a18070e1f4ac5fd update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ UPDATE_COPYRIGHT_USE_INTERVALS=1 \ @@ -398,34 +401,38 @@ dist_doc_DATA = $(srcdir)/doc/index.html $(srcdir)/doc/ldoc.css dist_classes_DATA = $(srcdir)/doc/classes/std.container.html \ $(srcdir)/doc/classes/std.list.html \ $(srcdir)/doc/classes/std.object.html \ + $(srcdir)/doc/classes/std.optparse.html \ $(srcdir)/doc/classes/std.set.html \ $(srcdir)/doc/classes/std.strbuf.html \ $(srcdir)/doc/classes/std.tree.html $(NOTHING_ELSE) dist_modules_DATA = $(srcdir)/doc/modules/std.html \ $(srcdir)/doc/modules/std.debug.html \ $(srcdir)/doc/modules/std.functional.html \ - $(srcdir)/doc/modules/std.getopt.html \ $(srcdir)/doc/modules/std.io.html \ $(srcdir)/doc/modules/std.math.html \ $(srcdir)/doc/modules/std.package.html \ $(srcdir)/doc/modules/std.strict.html \ $(srcdir)/doc/modules/std.string.html \ $(srcdir)/doc/modules/std.table.html $(NOTHING_ELSE) -SPECL_ENV = $(LUA_ENV) +specs_path = $(abs_builddir)/specs/?.lua +SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" +SPECL_OPTS = --unicode specl_SPECS = \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ - $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/functional_spec.yaml \ $(srcdir)/specs/io_spec.yaml \ $(srcdir)/specs/list_spec.yaml \ $(srcdir)/specs/math_spec.yaml \ $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/optparse_spec.yaml \ $(srcdir)/specs/package_spec.yaml \ $(srcdir)/specs/set_spec.yaml \ $(srcdir)/specs/strbuf_spec.yaml \ $(srcdir)/specs/string_spec.yaml \ $(srcdir)/specs/table_spec.yaml \ $(srcdir)/specs/tree_spec.yaml \ + $(srcdir)/specs/std_spec.yaml \ $(NOTHING_ELSE) luastddir = $(luadir)/std @@ -433,14 +440,13 @@ dist_luastd_DATA = \ lib/std/base.lua \ lib/std/container.lua \ lib/std/debug.lua \ - lib/std/debug_init.lua \ lib/std/functional.lua \ - lib/std/getopt.lua \ lib/std/io.lua \ lib/std/list.lua \ lib/std/math.lua \ lib/std/modules.lua \ lib/std/object.lua \ + lib/std/optparse.lua \ lib/std/package.lua \ lib/std/set.lua \ lib/std/strbuf.lua \ @@ -450,7 +456,18 @@ dist_luastd_DATA = \ lib/std/tree.lua \ $(NOTHING_ELSE) -mkrockspecs_args = --module-dir $(srcdir)/lib + +# For bugwards compatibility with LuaRocks 2.1, while ensuring that +# `require "std.debug_init"` continues to work, we have to install +# the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. +# When everyone has upgraded to a LuaRocks that works, move this +# file back to dist_luastd_DATA above and rename to debug_init.lua. +luastddebugdir = $(luastddir)/debug_init +dist_luastddebug_DATA = \ + lib/std/debug_init/init.lua \ + $(NOTHING_ELSE) + +mkrockspecs_args = --module-dir $(srcdir)/lib --repository lua-stdlib ldoc_DEPS = $(dist_lua_DATA) $(dist_luastd_DATA) luarocks_config = build-aux/luarocks-config.lua rockspec_conf = $(srcdir)/rockspec.conf @@ -514,6 +531,10 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): .travis.yml: $(top_builddir)/config.status $(srcdir)/travis.yml.in cd $(top_builddir) && $(SHELL) ./config.status $@ +doc/config.ld: $(top_builddir)/config.status $(top_srcdir)/doc/config.ld.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +specs/spec_helper.lua: $(top_builddir)/config.status $(top_srcdir)/specs/spec_helper.lua.in + cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @@ -703,6 +724,27 @@ uninstall-dist_luastdDATA: @list='$(dist_luastd_DATA)'; test -n "$(luastddir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(luastddir)'; $(am__uninstall_files_from_dir) +install-dist_luastddebugDATA: $(dist_luastddebug_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_luastddebug_DATA)'; test -n "$(luastddebugdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(luastddebugdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(luastddebugdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(luastddebugdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(luastddebugdir)" || exit $$?; \ + done + +uninstall-dist_luastddebugDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_luastddebug_DATA)'; test -n "$(luastddebugdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(luastddebugdir)'; $(am__uninstall_files_from_dir) install-dist_modulesDATA: $(dist_modules_DATA) @$(NORMAL_INSTALL) @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ @@ -920,7 +962,7 @@ check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -979,7 +1021,8 @@ info-am: install-data-am: install-dist_classesDATA install-dist_docDATA \ install-dist_luaDATA install-dist_luastdDATA \ - install-dist_modulesDATA install-docDATA + install-dist_luastddebugDATA install-dist_modulesDATA \ + install-docDATA install-dvi: install-dvi-am @@ -1030,8 +1073,8 @@ ps-am: uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ uninstall-dist_classesDATA uninstall-dist_docDATA \ uninstall-dist_luaDATA uninstall-dist_luastdDATA \ - uninstall-dist_modulesDATA uninstall-docDATA \ - uninstall-libLTLIBRARIES + uninstall-dist_luastddebugDATA uninstall-dist_modulesDATA \ + uninstall-docDATA uninstall-libLTLIBRARIES .MAKE: check-am install-am install-exec-am install-strip @@ -1044,17 +1087,18 @@ uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ install-data install-data-am install-dist_binSCRIPTS \ install-dist_classesDATA install-dist_docDATA \ install-dist_luaDATA install-dist_luastdDATA \ - install-dist_modulesDATA install-docDATA install-dvi \ - install-dvi-am install-exec install-exec-am install-exec-hook \ - install-html install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags-am uninstall uninstall-am \ - uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ - uninstall-dist_classesDATA uninstall-dist_docDATA \ - uninstall-dist_luaDATA uninstall-dist_luastdDATA \ + install-dist_luastddebugDATA install-dist_modulesDATA \ + install-docDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ + uninstall uninstall-am uninstall-binSCRIPTS \ + uninstall-dist_binSCRIPTS uninstall-dist_classesDATA \ + uninstall-dist_docDATA uninstall-dist_luaDATA \ + uninstall-dist_luastdDATA uninstall-dist_luastddebugDATA \ uninstall-dist_modulesDATA uninstall-docDATA \ uninstall-libLTLIBRARIES @@ -1062,7 +1106,7 @@ uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ LUA_PATH ?= ; LUA_CPATH ?= ; specl-check-local: $(specl_SPECS) - $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) + $(SPECL_ENV) LUA=$(LUA) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to diff --git a/NEWS b/NEWS index b3fd9f0..53c9b21 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,43 @@ Stdlib NEWS - User visible changes +* Noteworthy changes in release 37 (2014-01-19) [stable] + +** New features: + + - Lazy loading of submodules into `std` on first reference. On initial + load, `std` has the usual single `version` entry, but the `__index` + metatable will automatically require submodules on first reference: + + local std = require "std" + local prototype = std.container.prototype + + - New `std.optparse` module: A civilised option parser. + (L)Documentation distributed in doc/classes/std.optparse.html. + +** Bug fixes: + + - Modules no longer leak `new' and `proper_subset' into the global + table. + + - Cloned `Object` and `Container` derived types are more aggressive + about sharing metatables, where previously the metatable was copied + unnecessarily the base object used `_functions` for module functions + + - The retracted release 36 changed the operand order of many `std.list` + module functions unnecessarily. Now that `_function` support is + available, there's no need to be so draconian, so the original v35 + and earlier operand order works as before again. + + - `std.list.new`, `std.set.new`, `set.strbuf.new` and `std.tree.new` + are available again for backwards compatibility. + +** Incompatible changes: + + - `std.getopt` is no more. It appears to have no users, though if there + is a great outcry, it should be easy to make a compatibility api over + `std.optparse` in the next release. + + * Noteworthy changes in release 36 (2014-01-16) [stable] ** New features: diff --git a/build-aux/mkrockspecs b/build-aux/mkrockspecs index 9fd26fc..63386bd 100755 --- a/build-aux/mkrockspecs +++ b/build-aux/mkrockspecs @@ -113,6 +113,15 @@ local function opterr (msg) os.exit (2) end +local function setopt (optname, arglist, i) + local opt = arglist[i] + if i + 1 > #arglist then + opterr ("option '" .. opt .. "' requires an argument") + end + prog.opts[optname] = arglist[i + 1] + return i + 1 +end + local function die (msg) msg:gsub ("([^\n]+)\n?", function () @@ -135,16 +144,18 @@ PACKAGE and VERSION are the package name and version number as defined by 'configure.ac' or similar. REVISION is only required for a revised rockspec if the default "-1" revision was released with errors. + -b, --branch=BRANCH make git rockspec use BRANCH + -m, --module-dir=ROOT directory of lua-files for builtin build type + -r, --repository=REPO set the repository name (default=PACKAGE) --help print this help, then exit --version print version number, then exit - -m, --module-dir=ROOT directory of lua-files for builtin build type Report bugs to http://github.com/gvvaughan/slingshot/issues.]]) os.exit (0) end prog["--version"] = function () - print [[mkrockspecs (slingshot) 6 + print [[mkrockspecs (slingshot) 7 Written by Gary V. Vaughan , 2013 Copyright (C) 2013, Gary V. Vaughan @@ -153,17 +164,14 @@ See source files for individual license conditions.]] os.exit (0) end -prog["--module-dir"] = function (arglist, i) - local opt = arglist[i] - if i + 1 > #arglist then - opterr ("option '" .. opt .. "' requires an argument") - end +prog["-b"] = function (argl, i) return setopt ("branch", argl, i) end +prog["--branch"] = prog["-b"] - prog.opts.module_root = arglist[i + 1] - return i + 1 -end +prog["-m"] = function (argl, i) return setopt ("module_root", argl, i) end +prog["--module-dir"] = prog["-m"] -prog["-m"] = prog["--module-dir"] +prog["-r"] = function (argl, i) return setopt ("repository", argl, i) end +prog["--repository"] = prog["-r"] local nonopts local i = 0 @@ -207,6 +215,11 @@ local version = arg[2] local revision = arg[3] or "1" local conf = arg[4] or "rockspec.conf" +-- Unless set explicity, assume the repo is named after the package. +if prog.opts.repository == nil then + prog.opts.repository = package +end + --[[ ================= ]]-- --[[ Helper functions. ]]-- @@ -258,7 +271,7 @@ local function loadmap (root) tree (root) for _, f in ipairs (files) do local m = f:match ("^" .. escape_pattern (root) .. "/(.*)%.lua") - map [m:gsub ("/", ".")] = f:gsub ("^%./", "") + map [m:gsub ("/", "."):gsub ("%.init$", "")] = f:gsub ("^%./", "") end return map end @@ -355,11 +368,12 @@ spec.source = spec.source or {} spec.build = spec.build or {} if version ~= "scm" and version ~= "git" then spec.source.url = "http://" .. url .. "/archive/release-v" .. version .. ".zip" - spec.source.dir = package .. "-release-v" .. version + spec.source.dir = prog.opts.repository .. "-release-v" .. version else spec.source.url = "git://" .. url .. ".git" - default.build.build_command = "./bootstrap && " .. default.build.build_command + spec.source.branch = prog.opts.branch spec.build.modules = nil + default.build.build_command = "./bootstrap && " .. default.build.build_command end diff --git a/build-aux/sanity-cfg.mk b/build-aux/sanity-cfg.mk new file mode 100644 index 0000000..693103f --- /dev/null +++ b/build-aux/sanity-cfg.mk @@ -0,0 +1,3 @@ +exclude_file_name_regexp--sc_error_message_uppercase = ^lib/std/optparse.lua$$ + +EXTRA_DIST += build-aux/sanity-cfg.mk diff --git a/build-aux/specl.mk b/build-aux/specl.mk index f5ec9fc..6cee599 100644 --- a/build-aux/specl.mk +++ b/build-aux/specl.mk @@ -35,7 +35,7 @@ check_local += specl-check-local specl-check-local: $(specl_SPECS) - $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) + $(SPECL_ENV) LUA=$(LUA) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) ## ------------- ## diff --git a/configure b/configure index efe5681..fa259fe 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 36. +# Generated by GNU Autoconf 2.69 for stdlib 37. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='36' -PACKAGE_STRING='stdlib 36' +PACKAGE_VERSION='37' +PACKAGE_STRING='stdlib 37' PACKAGE_BUGREPORT='http://github.com/rrthomas/lua-stdlib/issues' PACKAGE_URL='' @@ -1217,7 +1217,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 36 to adapt to many kinds of systems. +\`configure' configures stdlib 37 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1283,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 36:";; + short | recursive ) echo "Configuration of stdlib 37:";; esac cat <<\_ACEOF @@ -1363,7 +1363,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 36 +stdlib configure 37 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1380,7 +1380,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 36, which was +It was created by stdlib $as_me 37, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1760,7 +1760,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. $as_echo "## --------------------- ## -## Configuring stdlib 36 ## +## Configuring stdlib 37 ## ## --------------------- ##" echo @@ -2250,7 +2250,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='36' + VERSION='37' cat >>confdefs.h <<_ACEOF @@ -3086,7 +3086,7 @@ $as_echo "$ac_cv_path_SED" >&6; } ac_config_files="$ac_config_files .travis.yml:travis.yml.in" -ac_config_files="$ac_config_files Makefile" +ac_config_files="$ac_config_files Makefile doc/config.ld specs/spec_helper.lua" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -3639,7 +3639,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 36, which was +This file was extended by stdlib $as_me 37, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3692,7 +3692,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 36 +stdlib config.status 37 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -3807,6 +3807,8 @@ do case $ac_config_target in ".travis.yml") CONFIG_FILES="$CONFIG_FILES .travis.yml:travis.yml.in" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "doc/config.ld") CONFIG_FILES="$CONFIG_FILES doc/config.ld" ;; + "specs/spec_helper.lua") CONFIG_FILES="$CONFIG_FILES specs/spec_helper.lua" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/configure.ac b/configure.ac index 60a4f26..24c91cd 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [36], [http://github.com/rrthomas/lua-stdlib/issues]) +AC_INIT([stdlib], [37], [http://github.com/rrthomas/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) @@ -37,5 +37,5 @@ AC_PROG_SED dnl Generate output files SS_CONFIG_TRAVIS([ldoc specl]) -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([Makefile doc/config.ld specs/spec_helper.lua]) AC_OUTPUT diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 8fdd62f..07d98db 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,6 +42,7 @@

    Classes

  • std.container
  • std.list
  • std.object
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • std.tree
  • @@ -51,7 +52,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 561ad08..47a0644 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -33,6 +33,7 @@

    stdlib

    Contents

    @@ -43,6 +44,7 @@

    Classes

  • std.container
  • std.list
  • std.object
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • std.tree
  • @@ -52,7 +54,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -83,7 +84,9 @@

    Class std.list

    => 1 -

    ...they can also be called as module functions with an explicit argument:

    +

    ... some can also be called as module functions with an explicit list + argument in the first or last parameter, check the documentation for + details:

     local List = require "std.list"
      local l = List {1, 2, 3}
    @@ -98,27 +101,95 @@ 

    Class std.list

    Functions

    + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -127,6 +198,13 @@

    Functions

    std.list.append (l, x)Append an item to a list.
    std.list.compare (l, m)Compare two lists element-by-element, from left-to-right.
    std.list.concat (l, ...)Concatenate arguments into a list.
    std.list.cons (l, x)Prepend an item to a list.
    std.list.depair (ls) Turn a list of pairs into a table.
    std.list.elems (l)An iterator over the elements of a list.
    std.list.enpair (t) Turn a table into a list of pairs.
    std.list.index_key (l, f)std.list.filter (p, l)Filter a list according to a predicate.
    std.list.flatten (l)Flatten a list.
    std.list.foldl (fn, e, l)Fold a binary function through a list left associatively.
    std.list.foldr (fn, e, l)Fold a binary function through a list right associatively.
    std.list.index_key (f, l) Make an index of a list of tables on a given field
    std.list.index_value (l, f)std.list.index_value (f, l) Copy a list of tables, indexed on a given field
    std.list.map_with (ls, f)std.list.map (fn, l)Map a function over a list.
    std.list.map_with (fn, ls) Map a function over a list of lists.
    std.list.project (f, l)Project a list of fields from a list of tables.
    std.list.relems (l)An iterator over the elements of a list, in reverse.
    std.list.rep (l, n)Repeat a list.
    std.list.reverse (l)Reverse a list.
    std.list.shape (s, l)Shape a list according to a list of dimensions.
    std.list.sub (l, from, to)Return a sub-range of a list.
    std.list.tail (l)Return a list with its first element removed.
    std.list.transpose (ls) Transpose a list of lists.
    Zip a list of lists together with a function.
    +

    Tables

    + + + + + +
    std.list.ListAn Object derived List.

    Metamethods

    @@ -173,11 +251,11 @@

    Methods

    - + - + @@ -185,7 +263,7 @@

    Methods

    - + @@ -193,7 +271,7 @@

    Methods

    - + @@ -201,7 +279,7 @@

    Methods

    - + @@ -213,103 +291,594 @@

    Methods

    - +
    Filter a list according to a predicate.
    std.list:flatten (self)std.list:flatten () Flatten a list.
    std.list:foldl (f, e)std.list:foldl (fn, e) Fold a binary function through a list left associatively.
    Fold a binary function through a list right associatively.
    std.list:map (f)std.list:map (fn) Map a function over a list.
    Project a list of fields from a list of tables.
    std.list:relems (self)std.list:relems () An iterator over the elements of a list, in reverse.
    Repeat a list.
    std.list:reverse (self)std.list:reverse () Reverse a list.
    Return a sub-range of a list.
    std.list:tail (self)std.list:tail () Return a list with its first element removed.
    -
    -
    +
    +
    + + +

    Functions

    +
    +
    + + std.list.append (l, x) +
    +
    + Append an item to a list. + + +

    Parameters:

    +
      +
    • l + List + a list +
    • +
    • x + item +
    • +
    + +

    Returns:

    +
      + + List + new list containing {l[1], ..., l[#l], x} +
    + + + + +
    +
    + + std.list.compare (l, m) +
    +
    + +

    Compare two lists element-by-element, from left-to-right.

    + +
     if a_list:compare (another_list) == 0 then print "same" end
    +
    + + + +

    Parameters:

    +
      +
    • l + List + a list +
    • +
    • m + table + another list +
    • +
    + +

    Returns:

    +
      + + -1 if l is less than m, 0 if they are the same, and 1 + if l is greater than m +
    + + + + +
    +
    + + std.list.concat (l, ...) +
    +
    + Concatenate arguments into a list. + + +

    Parameters:

    +
      +
    • l + List + a list +
    • +
    • ... + tuple of lists +
    • +
    + +

    Returns:

    +
      + + List + new list containing + {l[1], ..., l[#l], l_1[1], ..., l_1[#l_1], ..., l_n[1], ..., l_n[#l_n]} +
    + + + + +
    +
    + + std.list.cons (l, x) +
    +
    + Prepend an item to a list. + + +

    Parameters:

    +
      +
    • l + List + a list +
    • +
    • x + item +
    • +
    + +

    Returns:

    +
      + + List + new list containing {x, unpack (l)} +
    + + + + +
    +
    + + std.list.depair (ls) +
    +
    + Turn a list of pairs into a table. + + +

    Parameters:

    +
      +
    • ls + table + list of lists {{i1, v1}, ..., {in, vn}} +
    • +
    + +

    Returns:

    +
      + + table + a new list containing table {i1=v1, ..., in=vn} +
    + + +

    See also:

    + + + +
    +
    + + std.list.elems (l) +
    +
    + An iterator over the elements of a list. + + +

    Parameters:

    +
      +
    • l + List + a list +
    • +
    + +

    Returns:

    +
      +
    1. + function + iterator function which returns successive elements + of l
    2. +
    3. + List + l
    4. +
    5. + true
    6. +
    + + + + +
    +
    + + std.list.enpair (t) +
    +
    + Turn a table into a list of pairs. + + +

    Parameters:

    +
      +
    • t + table + a table {i1=v1, ..., in=vn} +
    • +
    + +

    Returns:

    +
      + + List + a new list containing {{i1, v1}, ..., {in, vn}} +
    + + +

    See also:

    + + + +
    +
    + + std.list.filter (p, l) +
    +
    + Filter a list according to a predicate. + + +

    Parameters:

    +
      +
    • p + func + predicate function, of one argument returning a boolean +
    • +
    • l + List + a list +
    • +
    + +

    Returns:

    +
      + + List + new list containing elements e of l for which + p (e) is true +
    + + +

    See also:

    + + + +
    +
    + + std.list.flatten (l) +
    +
    + Flatten a list. + + +

    Parameters:

    +
      +
    • l + List + a list +
    • +
    + +

    Returns:

    +
      + + List + flattened list +
    + + + + +
    +
    + + std.list.foldl (fn, e, l) +
    +
    + Fold a binary function through a list left associatively. + + +

    Parameters:

    +
      +
    • fn + func + binary function +
    • +
    • e + element to place in left-most position +
    • +
    • l + List + a list +
    • +
    + +

    Returns:

    +
      + + result +
    + + +

    See also:

    + + + +
    +
    + + std.list.foldr (fn, e, l) +
    +
    + Fold a binary function through a list right associatively. + + +

    Parameters:

    +
      +
    • fn + func + binary function +
    • +
    • e + element to place in right-most position +
    • +
    • l + List + a list +
    • +
    + +

    Returns:

    +
      + + result +
    + + +

    See also:

    + + + +
    +
    + + std.list.index_key (f, l) +
    +
    + Make an index of a list of tables on a given field + + +

    Parameters:

    +
      +
    • f + field +
    • +
    • l + List + list of tables {t1, ..., tn} +
    • +
    + +

    Returns:

    +
      + + List + index {t1[f]=1, ..., tn[f]=n} +
    + + + + +
    +
    + + std.list.index_value (f, l) +
    +
    + Copy a list of tables, indexed on a given field + + +

    Parameters:

    +
      +
    • f + field whose value should be used as index +
    • +
    • l + List + list of tables {i1=t1, ..., in=tn} +
    • +
    + +

    Returns:

    +
      + + List + index {t1[f]=t1, ..., tn[f]=tn} +
    + + + + +
    +
    + + std.list.map (fn, l) +
    +
    + Map a function over a list. + + +

    Parameters:

    +
      +
    • fn + func + map function +
    • +
    • l + List + a list +
    • +
    +

    Returns:

    +
      -

      Functions

      -
      + List + new list containing {fn (l[1]), ..., fn (l[#l])} +
    + + +

    See also:

    + + + +
    - - std.list.depair (ls) + + std.list.map_with (fn, ls)
    - Turn a list of pairs into a table. + Map a function over a list of lists.

    Parameters:

      +
    • fn + func + map function +
    • ls - table - list of lists {{i1, v1}, ..., {in, vn}} + List + a list of lists

    Returns:

      - table - a new list containing table {i1=v1, ..., in=vn} + List + new list {fn (unpack (ls[1]))), ..., fn (unpack (ls[#ls]))}
    -

    See also:

    -
    - - std.list.enpair (t) + + std.list.project (f, l)
    - Turn a table into a list of pairs. + Project a list of fields from a list of tables.

    Parameters:

      -
    • t - table - a table {i1=v1, ..., in=vn} +
    • f + field to project +
    • +
    • l + List + a list

    Returns:

      - std.list - a new list containing {{i1, v1}, ..., {in, vn}} + List + list of f fields

    See also:

    - - std.list.index_key (l, f) + + std.list.relems (l)
    - Make an index of a list of tables on a given field + An iterator over the elements of a list, in reverse.

    Parameters:

    • l - table - list of tables {t1, ..., tn} + List + a list
    • -
    • f - field +
    + +

    Returns:

    +
      +
    1. + function + iterator function which returns precessive elements + of the l
    2. +
    3. + List + l
    4. +
    5. + true
    6. +
    + + + + +
    +
    + + std.list.rep (l, n) +
    +
    + Repeat a list. + + +

    Parameters:

    +
      +
    • l + List + a list +
    • +
    • n + int + number of times to repeat

    Returns:

      - std.list - index {t1[f]=1, ..., tn[f]=n} + List + n copies of l appended together
    @@ -317,60 +886,136 @@

    Returns:

    - - std.list.index_value (l, f) + + std.list.reverse (l)
    - Copy a list of tables, indexed on a given field + Reverse a list.

    Parameters:

    • l + List + a list +
    • +
    + +

    Returns:

    +
      + + List + new list containing {l[#l], ..., l[1]} +
    + + + + +
    +
    + + std.list.shape (s, l) +
    +
    + Shape a list according to a list of dimensions.

    + +

    Dimensions are given outermost first and items from the original + list are distributed breadth first; there may be one 0 indicating + an indefinite number. Hence, {0} is a flat list, + {1} is a singleton, {2, 0} is a list of + two lists, and {0, 2} is a list of pairs.

    + +

    Algorithm: turn shape into all positive numbers, calculating + the zero if necessary and making sure there is at most one; + recursively walk the shape, adding empty tables until the bottom + level is reached at which point add table items instead, using a + counter to walk the flattened original list. + + +

    Parameters:

    +
      +
    • s table - list of tables {i1=t1, ..., in=tn} + {d1, ..., dn}
    • -
    • f - field whose value should be used as index +
    • l + List + a list

    Returns:

      - std.list - index {t1[f]=t1, ..., tn[f]=tn} + reshaped list
    +

    See also:

    +
    - - std.list.map_with (ls, f) + + std.list.sub (l, from, to)
    - Map a function over a list of lists. + Return a sub-range of a list. + (The equivalent of string.sub on strings; negative list indices + count from the end of the list.)

    Parameters:

      -
    • ls - table - a list of lists +
    • l + List + a list
    • -
    • f - function - map function +
    • from + int + start of range (default: 1) +
    • +
    • to + int + end of range (default: #l) +
    • +
    + +

    Returns:

    +
      + + List + new list containing {l[from], ..., l[to]} +
    + + + + +
    +
    + + std.list.tail (l) +
    +
    + Return a list with its first element removed. + + +

    Parameters:

    +
      +
    • l + List + a list

    Returns:

      - std.list - new list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} + List + new list containing {l[2], ..., l[#l]}
    @@ -398,7 +1043,7 @@

    Parameters:

    Returns:

      - std.list + List new list containing {{ls<1,1>, ..., ls<r,1>}, ..., {ls<1,c>, ..., ls<r,c>}}
    @@ -430,7 +1075,7 @@

    Parameters:

    Returns:

      - std.list + List
      a new list containing
       
      @@ -442,6 +1087,23 @@

      Returns:

      +
    +
    +

    Tables

    +
    +
    + + std.list.List +
    +
    + An Object derived List. + + + + + + +

    Metamethods

    @@ -461,7 +1123,7 @@

    Metamethods

    Parameters:

    • list - std.list + List a list
    • element @@ -493,7 +1155,7 @@

      See also:

      Parameters:

      • list - std.list + List a list
      • table @@ -526,11 +1188,11 @@

        See also:

        Parameters:

        @@ -559,11 +1221,11 @@

        See also:

        Parameters:

        @@ -591,14 +1253,14 @@

        Methods

        Parameters:

        • x - item + item

        Returns:

          - std.list + List new list containing {self[1], ..., self[#self], x}
        @@ -623,7 +1285,7 @@

        Parameters:

        • l table - another list + a list
        @@ -656,7 +1318,7 @@

        Parameters:

        Returns:

          - std.list + List new list containing {self[1], ..., self[#self], l_1[1], ..., l_1[#l_1], ..., l_n[1], ..., l_n[#l_n]}
        @@ -676,14 +1338,14 @@

        Returns:

        Parameters:

        • x - item + item

        Returns:

          - std.list + List new list containing {x, unpack (self)}
        @@ -704,10 +1366,11 @@

        Returns:

        1. function - iterator function which returns successive elements of self
        2. + iterator function which returns successive + elements of self
        3. - table - list
        4. + List + self
        5. true
        @@ -727,7 +1390,7 @@

        Returns:

        Parameters:

        • p - function + func predicate function, of one argument returning a boolean
        @@ -735,35 +1398,32 @@

        Parameters:

        Returns:

          - std.list - new list containing elements e of self for which p (e) is true + List + new list containing elements e of self for which + p (e) is true
        +

        See also:

        +
    - std.list:flatten (self) + std.list:flatten ()
    Flatten a list. -

    Parameters:

    -
      -
    • self - - - -
    • -

    Returns:

      - std.list + List flattened list
    @@ -773,7 +1433,7 @@

    Returns:

    - std.list:foldl (f, e) + std.list:foldl (fn, e)
    Fold a binary function through a list left associatively. @@ -781,12 +1441,12 @@

    Returns:

    Parameters:

      -
    • f - function - binary function +
    • fn + func + binary function
    • e - element to place in left-most position + element to place in left-most position
    @@ -797,6 +1457,10 @@

    Returns:

    +

    See also:

    +
    @@ -811,8 +1475,8 @@

    Returns:

    Parameters:

    • f - function - binary function + func + binary function
    • e element to place in right-most position @@ -826,12 +1490,16 @@

      Returns:

      +

      See also:

      +
      - std.list:map (f) + std.list:map (fn)
      Map a function over a list. @@ -839,8 +1507,8 @@

      Returns:

      Parameters:

        -
      • f - function +
      • fn + func map function
      @@ -848,11 +1516,16 @@

      Parameters:

      Returns:

        - std.list - new list containing {f (self[1]), ..., f (self[#self])} + List + new list containing + {fn (self[1]), ..., fn (self[#self])}
      +

      See also:

      +
      @@ -867,45 +1540,42 @@

      Returns:

      Parameters:

      • f - field to project + field to project

      Returns:

        - std.list + List list of f fields
      +

      See also:

      +
      - std.list:relems (self) + std.list:relems ()
      An iterator over the elements of a list, in reverse. -

      Parameters:

      -
        -
      • self - - - -
      • -

      Returns:

      1. function - iterator function which returns precessive elements of the self
      2. + iterator function which returns precessive elements + of the self
      3. - std.list + List self
      4. true
      5. @@ -926,7 +1596,7 @@

        Returns:

        Parameters:

        • n - number + int number of times to repeat
        @@ -934,7 +1604,7 @@

        Parameters:

        Returns:

          - std.list + List n copies of self appended together
        @@ -944,25 +1614,17 @@

        Returns:

      - std.list:reverse (self) + std.list:reverse ()
      Reverse a list. -

      Parameters:

      -
        -
      • self - - - -
      • -

      Returns:

        - std.list + List new list containing {self[#self], ..., self[1]}
      @@ -975,19 +1637,7 @@

      Returns:

      std.list:shape (s)
      - Shape a list according to a list of dimensions.

      - -

      Dimensions are given outermost first and items from the original - list are distributed breadth first; there may be one 0 indicating - an indefinite number. Hence, {0} is a flat list, - {1} is a singleton, {2, 0} is a list of - two lists, and {0, 2} is a list of pairs.

      - -

      Algorithm: turn shape into all positive numbers, calculating - the zero if necessary and making sure there is at most one; - recursively walk the shape, adding empty tables until the bottom - level is reached at which point add table items instead, using a - counter to walk the flattened original list. + Shape a list according to a list of dimensions.

      Parameters:

      @@ -1005,6 +1655,10 @@

      Returns:

      +

      See also:

      +
      @@ -1021,19 +1675,19 @@

      Returns:

      Parameters:

      • from - number + int start of range (default: 1)
      • to - number - end of range (default: #self) + int + end of range (default: #self)

      Returns:

        - std.list + List new list containing {self[from], ..., self[to]}
      @@ -1043,25 +1697,17 @@

      Returns:

      - std.list:tail (self) + std.list:tail ()
      Return a list with its first element removed. -

      Parameters:

      -
        -
      • self - - - -
      • -

      Returns:

        - std.list + List new list containing {self[2], ..., self[#self]}
      diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index 82f840c..28373a2 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -43,6 +43,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -52,7 +53,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html new file mode 100644 index 0000000..704bec4 --- /dev/null +++ b/doc/classes/std.optparse.html @@ -0,0 +1,742 @@ + + + + + stdlib 37 Reference + + + + +
      + +
      + +
      +
      +
      + + +
      + + + + + + +
      + +

      Class std.optparse

      +

      Parse and process command line options.

      +

      + + +

       local OptionParser = require "std.optparse"
      + local parser = OptionParser (spec)
      + _G.arg, opts = parser:parse (_G.arg)
      +
      + +

      The string spec passed to OptionParser must be a specially formatted + help text, of the form:

      + +
       any text VERSION
      + Additional lines of text to show when the --version
      + option is passed.
      +
      + Several lines or paragraphs are permitted.
      +
      + Usage: PROGNAME
      +
      + Banner text.
      +
      + Optional long description text to show when the --help
      + option is passed.
      +
      + Several lines or paragraphs of long description are permitted.
      +
      + Options:
      +
      +   -h, --help               display this help, then exit
      +       --version            display version information, then exit
      +   -b                       a short option with no long option
      +       --long               a long option with no short option
      +       --another-long       a long option with internal hypen
      +       --true               a Lua keyword as an option name
      +   -v, --verbose            a combined short and long option
      +   -n, --dryrun, --dry-run  several spellings of the same option
      +   -u, --name=USER          require an argument
      +   -o, --output=[FILE]      accept an optional argument
      +   --                       end of options
      +
      +Footer text.  Several lines or paragraphs are permitted.
      +
      +Please report bugs at bug-list@yourhost.com
      +
      + +

      Most often, everything else is handled automatically. After calling + parser:parse as shown above, _G.arg will contain unparsed arguments, + usually filenames or similar, and opts will be a table of parsed + option values. The keys to the table are the long-options with leading + hyphens stripped, and non-word characters turned to _. For example + if --another-long had been found in _G.arg then opts would + have a key named another_long. If there is no long option name, then + the short option is used, e.g. opts.b will be set. The values saved + in those keys are controlled by the option handler, usually just true + or the option argument string as appropriate.

      + +

      On those occasions where more complex processing is required, handlers + can be replaced or added using parser:on.

      + +

      + + +

      Functions

      + + + + + +
      std.optparse.OptionParser (spec)Instantiate a new parser.
      +

      Tables

      + + + + + + + + + + + + + +
      std.optparse.boolvalsMap various option strings to equivalent Lua boolean values.
      std.optparse.optsParsed options table, with a key for each encountered option, each + with value set by that option's on_handler.
      std.optparse.parserCustomized parser for your options.
      +

      Methods

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      std.optparse:boolean (opt[, optarg="1"])Return a Lua boolean equivalent of various optarg strings.
      std.optparse:file (opt, optarg)Report an option parse error unless optarg names an + existing file.
      std.optparse:finished (arglist, i)Finish option processing + Usually indicated by -- at arglist[i].
      std.optparse:flag (arglist, i[, value])Option at arglist[i] is a boolean switch.
      std.optparse:help ()Option should display help text, then exit.
      std.optparse:normalise (arglist)Normalise an argument list.
      std.optparse:on (name, handler, value)Add an option handler.
      std.optparse:on_handler (arglist, i[, value=nil])Function signature of an option handler for on.
      std.optparse:opterr (msg)Report an option parse error, then exit with status 2.
      std.optparse:optional (arglist, i[, value=true])Option at arglist[i] can take an argument.
      std.optparse:parse (arglist)Parse arglist.
      std.optparse:required (arglist, i[, value])Option at arglist[i} requires an argument.
      std.optparse:set (opt, value)Store value with opt.
      std.optparse:version ()Option should display version text, then exit.
      + +
      +
      + + +

      Functions

      +
      +
      + + std.optparse.OptionParser (spec) +
      +
      + Instantiate a new parser. + Read the documented options from spec and return a new parser that + can be passed to parse for parsing those options from an argument + list. + + +

      Parameters:

      +
        +
      • spec + string + option parsing specification +
      • +
      + +

      Returns:

      +
        + + parser + a parser for options described by spec +
      + + + + +
      +
      +

      Tables

      +
      +
      + + std.optparse.boolvals +
      +
      + Map various option strings to equivalent Lua boolean values. + + +

      Fields:

      +
        +
      • false + false +
      • +
      • 0 + false +
      • +
      • no + false +
      • +
      • n + false +
      • +
      • true + true +
      • +
      • 1 + true +
      • +
      • yes + true +
      • +
      • y + true +
      • +
      + + + + + +
      +
      + + std.optparse.opts +
      +
      + Parsed options table, with a key for each encountered option, each + with value set by that option's on_handler. + + + + + + + +
      +
      + + std.optparse.parser +
      +
      + Customized parser for your options. + + + + + + + +
      +
      +

      Methods

      +
      +
      + + std.optparse:boolean (opt[, optarg="1"]) +
      +
      + Return a Lua boolean equivalent of various optarg strings. + Report an option parse error if optarg is not recognised. + + +

      Parameters:

      +
        +
      • opt + string + option name +
      • +
      • optarg + string + option argument, must be a key in boolvals + (default "1") +
      • +
      + +

      Returns:

      +
        + + bool + true or false +
      + + + + +
      +
      + + std.optparse:file (opt, optarg) +
      +
      + Report an option parse error unless optarg names an + existing file. + + +

      Parameters:

      +
        +
      • opt + string + option name +
      • +
      • optarg + string + option argument, must be an existing file +
      • +
      + +

      Returns:

      +
        + + `optarg` + + + +
      + + + + +
      +
      + + std.optparse:finished (arglist, i) +
      +
      + Finish option processing + Usually indicated by -- at arglist[i]. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:flag (arglist, i[, value]) +
      +
      + Option at arglist[i] is a boolean switch. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + either a function to process the option argument, + or a value to store when this flag is encountered +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:help () +
      +
      + Option should display help text, then exit. + + + + + + + +
      +
      + + std.optparse:normalise (arglist) +
      +
      + Normalise an argument list. + Separate short options, remove = separators from + --long-option=optarg etc. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments to normalise +
      • +
      + +

      Returns:

      +
        + + table + normalised argument list +
      + + + + +
      +
      + + std.optparse:on (name, handler, value) +
      +
      + Add an option handler. + + +

      Parameters:

      +
        +
      • name + opts + of the option, or list of option names +
      • +
      • handler + on_handler + function to call when any of opts is + encountered +
      • +
      • value + additional value passed to on_handler +
      • +
      + + + + + +
      +
      + + std.optparse:on_handler (arglist, i[, value=nil]) +
      +
      + Function signature of an option handler for on. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + additional value registered with on + (default nil) +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:opterr (msg) +
      +
      + Report an option parse error, then exit with status 2. + + +

      Parameters:

      +
        +
      • msg + string + error message +
      • +
      + + + + + +
      +
      + + std.optparse:optional (arglist, i[, value=true]) +
      +
      + Option at arglist[i] can take an argument. + Argument is accepted only if there is a following entry that does not + begin with a '-'. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + either a function to process the option + argument, or a default value if encountered without an optarg + (default true) +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:parse (arglist) +
      +
      + Parse arglist. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      + +

      Returns:

      +
        +
      1. + table + a list of unrecognised arglist elements
      2. +
      3. + opts + parsing results
      4. +
      + + + + +
      +
      + + std.optparse:required (arglist, i[, value]) +
      +
      + Option at arglist[i} requires an argument. + + +

      Parameters:

      +
        +
      • arglist + table + list of arguments +
      • +
      • i + int + index of last processed element of arglist +
      • +
      • value + either a function to process the option argument, + or a forced value to replace the user's option argument. +
      • +
      + +

      Returns:

      +
        + + int + index of next element of arglist to process +
      + + + + +
      +
      + + std.optparse:set (opt, value) +
      +
      + Store value with opt. + + +

      Parameters:

      +
        +
      • opt + string + option name +
      • +
      • value + option argument value +
      • +
      + + + + + +
      +
      + + std.optparse:version () +
      +
      + Option should display version text, then exit. + + + + + + + +
      +
      + + +
      +
      +
      +generated by LDoc 1.4.0 +
      +
      + + diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index b1b8754..b291a94 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -43,6 +43,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -52,7 +53,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index a5ec6be..cefb45c 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,6 +42,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -51,7 +52,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index 261ecad..f6ffff8 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -43,6 +43,7 @@

      Classes

    • std.container
    • std.list
    • std.object
    • +
    • std.optparse
    • std.set
    • std.strbuf
    • std.tree
    • @@ -52,7 +53,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • diff --git a/doc/config.ld b/doc/config.ld index fb5c297..1cd763c 100644 --- a/doc/config.ld +++ b/doc/config.ld @@ -1,4 +1,5 @@ -- -*- lua -*- +title = "stdlib 37 Reference" project = "stdlib" description = "Standard Lua Libraries" dir = "." @@ -8,7 +9,6 @@ file = { "../lib/std.lua", "../lib/std/debug.lua", "../lib/std/functional.lua", - "../lib/std/getopt.lua", "../lib/std/io.lua", "../lib/std/math.lua", "../lib/std/package.lua", @@ -21,6 +21,7 @@ file = { "../lib/std/container.lua", "../lib/std/object.lua", "../lib/std/list.lua", + "../lib/std/optparse.lua", "../lib/std/set.lua", "../lib/std/strbuf.lua", } diff --git a/doc/config.ld.in b/doc/config.ld.in new file mode 100644 index 0000000..fb4576f --- /dev/null +++ b/doc/config.ld.in @@ -0,0 +1,30 @@ +-- -*- lua -*- +title = "@PACKAGE@ @VERSION@ Reference" +project = "stdlib" +description = "Standard Lua Libraries" +dir = "." + +file = { + -- Modules + "../lib/std.lua", + "../lib/std/debug.lua", + "../lib/std/functional.lua", + "../lib/std/io.lua", + "../lib/std/math.lua", + "../lib/std/package.lua", + "../lib/std/strict.lua", + "../lib/std/string.lua", + "../lib/std/table.lua", + "../lib/std/tree.lua", + + -- Classes + "../lib/std/container.lua", + "../lib/std/object.lua", + "../lib/std/list.lua", + "../lib/std/optparse.lua", + "../lib/std/set.lua", + "../lib/std/strbuf.lua", +} + +format = "markdown" +sort = true diff --git a/doc/index.html b/doc/index.html index 954c2bd..12a01ee 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -34,7 +34,6 @@

      Modules

    • std
    • std.debug
    • std.functional
    • -
    • std.getopt
    • std.io
    • std.math
    • std.package
    • @@ -48,6 +47,7 @@

      Classes

    • std.container
    • std.object
    • std.list
    • +
    • std.optparse
    • std.set
    • std.strbuf
    @@ -73,10 +73,6 @@

    Modules

    std.functional Functional programming. - - std.getopt - Simplified getopt, based on Svenne Panne's Haskell GetOpt. - std.io Additions to the io module. @@ -120,6 +116,10 @@

    Classes

    std.list Tables as lists. + + std.optparse + Parse and process command line options. + std.set Set container. diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html index e919d11..615896c 100644 --- a/doc/modules/std.debug.html +++ b/doc/modules/std.debug.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,7 +42,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +55,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index c3bf40b..b9730a2 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,7 +42,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +55,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.getopt.html b/doc/modules/std.getopt.html deleted file mode 100644 index 5a915a0..0000000 --- a/doc/modules/std.getopt.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Reference - - - - -
    - -
    - -
    -
    -
    - - -
    - - - - - - -
    - -

    Module std.getopt

    -

    Simplified getopt, based on Svenne Panne's Haskell GetOpt.

    -

    Usage:

    - -
     prog = {<
    -   name = <progname>,
    -   [usage = <usage line>,]
    -   [options = {
    -     {{<name>[, ...]}, <desc>, [<type> [, <var>]]},
    -     ...
    -   },]
    -   [banner = <banner string>,]
    -   [purpose = <purpose string>,]
    -   [notes = <additional notes>]
    - }
    -
    - -
      -
    • The type of option argument is one of Req(uired), - Opt(ional)
    • -
    • The varis a descriptive name for the option argument.
    • -
    • getopt.processargs (prog)
    • -
    • Options take a single dash, but may have a double dash.
    • -
    • Arguments may be given as -opt=arg or -opt arg.
    • -
    • If an option taking an argument is given multiple times, only the - last value is returned; missing arguments are returned as 1.
    • -
    - -

    getOpt, usageinfo and usage can be called directly (see - below, and the example at the end). Set _DEBUG.std to a non-nil - value to run the example.

    - - -

    Functions

    - - - - - - - - - - - - - - - - - -
    getopt (argIn, options, stop_at_nonopt)Perform argument processing
    processargs (prog, ...)Simple getopt wrapper.
    usage (prog)Emit a usage message.
    usageinfo (header, optDesc, pageWidth)Produce usage info for the given options.
    - -
    -
    - - -

    Functions

    -
    -
    - - getopt (argIn, options, stop_at_nonopt) -
    -
    - Perform argument processing - - -

    Parameters:

    -
      -
    • argIn - list of command-line args -
    • -
    • options - options table -
    • -
    • stop_at_nonopt - if true, stop option processing at first non-option -
    • -
    - -

    Returns:

    -
      -
    1. - table of remaining non-options
    2. -
    3. - table of option key-value list pairs
    4. -
    5. - table of error messages
    6. -
    - - - - -
    -
    - - processargs (prog, ...) -
    -
    - Simple getopt wrapper. - If the caller didn't supply their own already, adds --version/-V - and --help/-h options automatically; - stops program if there was an error, or if --help or --version was - used. - - -

    Parameters:

    -
      -
    • prog - table of named parameters -
    • -
    • ... - extra arguments for getopt -
    • -
    - - - - - -
    -
    - - usage (prog) -
    -
    - Emit a usage message. - - -

    Parameters:

    -
      -
    • prog - table of named parameters -
    • -
    - - - - - -
    -
    - - usageinfo (header, optDesc, pageWidth) -
    -
    - Produce usage info for the given options. - - -

    Parameters:

    -
      -
    • header - header string -
    • -
    • optDesc - option descriptors -
    • -
    • pageWidth - width to format to [78] -
    • -
    - -

    Returns:

    -
      - - formatted string -
    - - - - -
    -
    - - -
    -
    -
    -generated by LDoc 1.4.0 -
    -
    - - diff --git a/doc/modules/std.html b/doc/modules/std.html index 1ab8ea2..b5efcff 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -34,6 +34,7 @@

    Contents

    @@ -42,7 +43,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +56,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • @@ -194,6 +195,13 @@

    Tables

    Module table. +

    Metamethods

    + + + + + +
    __index (name)Lazy loading of stdlib modules.


    @@ -695,7 +703,16 @@

    See also:

    std
    - Module table. + +

    Module table. + Lazy load submodules into std on first reference. On initial + load, std has the usual single version entry, but the __index + metatable will automatically require submodules on first reference:

    + +
     local std = require "std"
    + local prototype = std.container.prototype
    +
    +

    Fields:

    @@ -709,6 +726,38 @@

    Fields:

    +
    + +

    Metamethods

    + +
    +
    + + __index (name) +
    +
    + Lazy loading of stdlib modules. + Don't load everything on initial startup, wait until first attempt + to access a submodule, and then load it on demand. + + +

    Parameters:

    +
      +
    • name + string + submodule name +
    • +
    + +

    Returns:

    +
      + + the submodule that was loaded to satisfy the missing name +
    + + + +
    diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index 812381e..c1109d9 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index 1d26c3b..eb857ed 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index 3285807..7c0b2eb 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index c0184a7..cfdc552 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index c3f1211..f99a396 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -42,7 +42,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -56,6 +55,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • @@ -808,7 +808,7 @@

    Parameters:

  • pattern to match version in module.version or - module.VERSION (default: ".*[%.%d]+" + module.VERSION (default: ".*[%.%d]+")
  • diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index 05cb962..96ebab2 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - Reference + stdlib 37 Reference @@ -41,7 +41,6 @@

    Modules

  • std
  • std.debug
  • std.functional
  • -
  • std.getopt
  • std.io
  • std.math
  • std.package
  • @@ -55,6 +54,7 @@

    Classes

  • std.container
  • std.object
  • std.list
  • +
  • std.optparse
  • std.set
  • std.strbuf
  • diff --git a/lib/std.lua b/lib/std.lua index 0a17601..af93195 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -19,12 +19,21 @@ @module std ]] + --- Module table. +-- Lazy load submodules into `std` on first reference. On initial +-- load, `std` has the usual single `version` entry, but the `__index` +-- metatable will automatically require submodules on first reference: +-- +-- local std = require "std" +-- local prototype = std.container.prototype -- @table std -- @field version release version string -local version = "General Lua libraries / 36" +local version = "General Lua libraries / 37" + +local modules = require "std.modules" -for m, globally in pairs (require "std.modules") do +for m, globally in pairs (modules) do if globally == true then -- Inject stdlib extensions directly into global package namespaces. for k, v in pairs (require ("std." .. m)) do @@ -193,4 +202,22 @@ local M = { version = version, } -return M + +--- Metamethods +-- @section Metamethods + +return setmetatable (M, { + --- Lazy loading of stdlib modules. + -- Don't load everything on initial startup, wait until first attempt + -- to access a submodule, and then load it on demand. + -- @function __index + -- @string name submodule name + -- @return the submodule that was loaded to satisfy the missing `name` + __index = function (self, name) + local ok, t = pcall (require, "std." .. name) + if ok then + rawset (self, name, t) + return t + end + end, +}) diff --git a/lib/std.lua.in b/lib/std.lua.in index 508f0b3..da0fb77 100644 --- a/lib/std.lua.in +++ b/lib/std.lua.in @@ -19,12 +19,21 @@ @module std ]] + --- Module table. +-- Lazy load submodules into `std` on first reference. On initial +-- load, `std` has the usual single `version` entry, but the `__index` +-- metatable will automatically require submodules on first reference: +-- +-- local std = require "std" +-- local prototype = std.container.prototype -- @table std -- @field version release version string local version = "General Lua libraries / @VERSION@" -for m, globally in pairs (require "std.modules") do +local modules = require "std.modules" + +for m, globally in pairs (modules) do if globally == true then -- Inject stdlib extensions directly into global package namespaces. for k, v in pairs (require ("std." .. m)) do @@ -193,4 +202,22 @@ local M = { version = version, } -return M + +--- Metamethods +-- @section Metamethods + +return setmetatable (M, { + --- Lazy loading of stdlib modules. + -- Don't load everything on initial startup, wait until first attempt + -- to access a submodule, and then load it on demand. + -- @function __index + -- @string name submodule name + -- @return the submodule that was loaded to satisfy the missing `name` + __index = function (self, name) + local ok, t = pcall (require, "std." .. name) + if ok then + rawset (self, name, t) + return t + end + end, +}) diff --git a/lib/std/base.lua b/lib/std/base.lua index bc26f82..0ac5aad 100644 --- a/lib/std/base.lua +++ b/lib/std/base.lua @@ -31,6 +31,8 @@ local function merge (t, u) return t end +local new -- forward declaration + -- Doc-commented in list.lua... local function append (l, x) local r = {unpack (l)} diff --git a/lib/std/container.lua b/lib/std/container.lua index 5104569..b5f9874 100644 --- a/lib/std/container.lua +++ b/lib/std/container.lua @@ -159,7 +159,7 @@ local metatable = { pairs, obj_mt._functions or {}) -- _functions is not propagated from prototype to clone. - if next (obj_mt) == nil and mt._functions == nil then + if next (obj_mt) == nil then -- Reuse metatable if possible obj_mt = getmetatable (self) else diff --git a/lib/std/debug_init.lua b/lib/std/debug_init/init.lua similarity index 100% rename from lib/std/debug_init.lua rename to lib/std/debug_init/init.lua diff --git a/lib/std/getopt.lua b/lib/std/getopt.lua deleted file mode 100644 index f57fb10..0000000 --- a/lib/std/getopt.lua +++ /dev/null @@ -1,299 +0,0 @@ ---- Simplified getopt, based on Svenne Panne's Haskell GetOpt. --- --- Usage: --- --- prog = {< --- name = , --- [usage = ,] --- [options = { --- {{[, ...]}, , [ [, ]]}, --- ... --- },] --- [banner = ,] --- [purpose = ,] --- [notes = ] --- } --- --- * The `type` of option argument is one of `Req`(uired), --- `Opt`(ional) --- * The `var`is a descriptive name for the option argument. --- * `getopt.processargs (prog)` --- * Options take a single dash, but may have a double dash. --- * Arguments may be given as `-opt=arg` or `-opt arg`. --- * If an option taking an argument is given multiple times, only the --- last value is returned; missing arguments are returned as 1. --- --- getOpt, usageinfo and usage can be called directly (see --- below, and the example at the end). Set _DEBUG.std to a non-nil --- value to run the example. --- --- @todo Wrap all messages; do all wrapping in processargs, not --- usageinfo; use sdoc-like library (see string.format todos). --- @todo Don't require name to be repeated in banner. --- @todo Store version separately (construct banner?). --- --- @module std.getopt - -local io = require "std.io" -local List = require "std.list" -local Object = require "std.object" -local string = require "std.string" -local table = require "std.table" - -local M = { - opt = {}, -} - -local argtype = { Opt = true, Req = true } - - ---- Perform argument processing --- @param argIn list of command-line args --- @param options options table --- @param stop_at_nonopt if true, stop option processing at first non-option --- @return table of remaining non-options --- @return table of option key-value list pairs --- @return table of error messages -local function getopt (argIn, options, stop_at_nonopt) - local noProcess = nil - local argOut, optOut, errors = {[0] = argIn[0]}, {}, {} - -- get an argument for option opt - local function getArg (o, opt, arg, oldarg) - if not argtype[o.type] then - if arg ~= nil then - table.insert (errors, "option `" .. opt .. "' doesn't take an argument") - end - else - if arg == nil and argIn[1] and - string.sub (argIn[1], 1, 1) ~= "-" then - arg = argIn[1] - table.remove (argIn, 1) - end - if arg == nil and o.type == "Req" then - table.insert (errors, "option `" .. opt .. - "' requires an argument `" .. o.var .. "'") - return nil - end - end - return arg or 1 -- make sure arg has a value - end - - local function parseOpt (opt, arg) - local o = options.name[opt] - if o ~= nil then - o = o or {name = {opt}} - optOut[o.name[1]] = optOut[o.name[1]] or {} - table.insert (optOut[o.name[1]], getArg (o, opt, arg, optOut[o.name[1]])) - else - table.insert (errors, "unrecognized option `-" .. opt .. "'") - end - end - while argIn[1] do - local v = argIn[1] - table.remove (argIn, 1) - local _, _, dash, opt = string.find (v, "^(%-%-?)([^=-][^=]*)") - local _, _, arg = string.find (v, "=(.*)$") - if not dash and stop_at_nonopt then - noProcess = true - end - if v == "--" then - noProcess = true - elseif not dash or noProcess then -- non-option - table.insert (argOut, v) - else -- option - parseOpt (opt, arg) - end - end - return argOut, optOut, errors -end - - --- Object that defines a single Option entry. -local Option = Object {_init = {"name", "desc", "type", "var"}} - ---- Options table constructor: adds lookup tables for the option names. -local function makeOptions (t) - local options, name = {}, {} - local function appendOpt (v, nodupes) - local dupe = false - v = Option (v) - for s in List.elems (v.name) do - if name[s] then - dupe = true - end - name[s] = v - end - if not dupe or nodupes ~= true then - if dupe then io.warn ("duplicate option '%s'", s) end - for s in List.elems (v.name) do name[s] = v end - options = List.concat (options, {v}) - end - end - for v in List.elems (t or {}) do - appendOpt (v) - end - -- Unless they were supplied already, add version and help options - appendOpt ({{"version", "V"}, "print version information, then exit"}, - true) - appendOpt ({{"help", "h"}, "print this help, then exit"}, true) - options.name = name - return options -end - - ---- Produce usage info for the given options. --- @param header header string --- @param optDesc option descriptors --- @param pageWidth width to format to [78] --- @return formatted string -local function usageinfo (header, optDesc, pageWidth) - pageWidth = pageWidth or 78 - -- Format the usage info for a single option - -- @param opt the option table - -- @return options - -- @return description - local function fmtOpt (opt) - local function fmtName (o) - return (#o > 1 and "--" or "-") .. o - end - local function fmtArg () - if opt.type == "Req" then - return "=" .. opt.var - elseif opt.type == "Opt" then - return "[=" .. opt.var .. "]" - else - return "" - end - end - local textName = List.reverse (List.map (opt.name, fmtName)) - textName[#textName] = textName[#textName] .. fmtArg () - local indent = "" - if #opt.name == 1 and #opt.name[1] > 1 then - indent = " " - end - return {indent .. table.concat ({table.concat (textName, ", ")}, ", "), - opt.desc} - end - local function sameLen (xs) - local n = math.max (unpack (List.map (xs, string.len))) - for i, v in pairs (xs) do - xs[i] = string.sub (v .. string.rep (" ", n), 1, n) - end - return xs, n - end - local function paste (x, y) - return " " .. x .. " " .. y - end - local function wrapper (w, i) - return function (s) - return string.wrap (s, w, i, 0) - end - end - local optText = "" - if #optDesc > 0 then - local cols = List.transpose (List.map (optDesc, fmtOpt)) - local width - cols[1], width = sameLen (cols[1]) - cols[2] = List.map (cols[2], wrapper (pageWidth, width + 4)) - optText = "\n\n" .. - table.concat (List.map_with (List.transpose ({sameLen (cols[1]), - cols[2]}), - paste), - "\n") - end - return header .. optText -end - ---- Emit a usage message. --- @param prog table of named parameters -local function usage (prog) - local usage = "[OPTION]... [FILE]..." - local purpose, description, notes = "", "", "" - if prog.usage then - usage = prog.usage - end - usage = "Usage: " .. prog.name .. " " .. usage - if prog.purpose then - purpose = "\n\n" .. prog.purpose - end - if prog.description then - for para in List.elems (string.split (prog.description, "\n")) do - description = description .. "\n\n" .. string.wrap (para) - end - end - if prog.notes then - notes = "\n\n" - if not string.find (prog.notes, "\n") then - notes = notes .. string.wrap (prog.notes) - else - notes = notes .. prog.notes - end - end - local header = usage .. purpose .. description - io.writelines (usageinfo (header, prog.options) .. notes) -end - - -local function version (prog) - local version = prog.version or prog.name or "unknown version!" - if prog.copyright then - version = version .. "\n\n" .. prog.copyright - end - io.writelines (version) -end - - - ---- Simple getopt wrapper. --- If the caller didn't supply their own already, adds `--version`/`-V` --- and `--help`/`-h` options automatically; --- stops program if there was an error, or if `--help` or `--version` was --- used. --- @param prog table of named parameters --- @param ... extra arguments for getopt -local function processargs (prog, ...) - local totArgs = #_G.arg - local errors - prog.options = makeOptions (prog.options) - _G.arg, M.opt, errors = getopt (_G.arg, prog.options, ...) - local opt = M.opt - if (opt.version or opt.help) and prog.banner then - io.writelines (prog.banner) - end - if #errors > 0 then - local name = prog.name - prog.name = nil - if #errors > 0 then - io.warn (name .. ": " .. table.concat (errors, "\n")) - io.warn (name .. ": Try '" .. (arg[0] or name) .. " --help' for more help") - end - if #errors > 0 then - error () - end - elseif opt.version then - version (prog) - elseif opt.help then - usage (prog) - end - if opt.version or opt.help then - os.exit () - end -end - - ---- @export -local Getopt = { - getopt = getopt, - processargs = processargs, - usage = usage, - usageinfo = usageinfo, -} - --- camelCase compatibility. -Getopt = table.merge (Getopt, { - getOpt = getopt, - processArgs = processargs, - usageInfo = usageinfo, -}) - -return table.merge (M, Getopt) diff --git a/lib/std/list.lua b/lib/std/list.lua index 5cb0ea8..1343277 100644 --- a/lib/std/list.lua +++ b/lib/std/list.lua @@ -13,7 +13,9 @@ => 2 => 1 - ...they can also be called as module functions with an explicit argument: + ... some can also be called as module functions with an explicit list + argument in the first or last parameter, check the documentation for + details: local List = require "std.list" local l = List {1, 2, 3} @@ -30,238 +32,236 @@ local func = require "std.functional" local Object = require "std.object" +local List -- forward declaration + +------ +-- An Object derived List. +-- @table List + +--- Append an item to a list. +-- @tparam List l a list +-- @param x item +-- @treturn List new list containing `{l[1], ..., l[#l], x}` +local function append (l, x) + return List (base.append (l, x)) +end + + --- Compare two lists element-by-element, from left-to-right. -- -- if a_list:compare (another_list) == 0 then print "same" end +-- @static -- @function compare --- @tparam table l another list --- @return -1 if `self` is less than `l`, 0 if they are the same, and 1 --- if `self` is greater than `l` +-- @tparam List l a list +-- @tparam table m another list +-- @return -1 if `l` is less than `m`, 0 if they are the same, and 1 +-- if `l` is greater than `m` local compare = base.compare ---- An iterator over the elements of a list. --- @function elems --- @treturn function iterator function which returns successive elements of `self` --- @treturn table *list* --- @return `true` -local elems = base.elems - - -local List -- list prototype object forward declaration - - ---- Append an item to a list. --- @param x item --- @treturn std.list new list containing `{self[1], ..., self[#self], x}` -local function append (self, x) - return List (base.append (self, x)) +--- Concatenate arguments into a list. +-- @tparam List l a list +-- @param ... tuple of lists +-- @treturn List new list containing +-- `{l[1], ..., l[#l], l\_1[1], ..., l\_1[#l\_1], ..., l\_n[1], ..., l\_n[#l\_n]}` +local function concat (l, ...) + return List (base.concat (l, ...)) end ---- Concatenate arguments into a list. --- @param ... tuple of lists --- @treturn std.list new list containing --- `{self[1], ..., self[#self], l\_1[1], ..., l\_1[#l\_1], ..., l\_n[1], ..., l\_n[#l\_n]}` -local function concat (self, ...) - return List (base.concat (self, ...)) +--- Prepend an item to a list. +-- @tparam List l a list +-- @param x item +-- @treturn List new list containing `{x, unpack (l)}` +local function cons (l, x) + return List {x, unpack (l)} end ---- An iterator over the elements of a list, in reverse. --- @treturn function iterator function which returns precessive elements of the `self` --- @treturn std.list `self` +--- An iterator over the elements of a list. +-- @static +-- @function elems +-- @tparam List l a list +-- @treturn function iterator function which returns successive elements +-- of `l` +-- @treturn List `l` -- @return `true` -local function relems (self) - local n = #self + 1 - return function (self) - n = n - 1 - if n > 0 then - return self[n] - end - end, - self, true -end +local elems = base.elems ---- Map a function over a list. --- @tparam function f map function --- @treturn std.list new list containing `{f (self[1]), ..., f (self[#self])}` -local function map (self, f) - return List (func.map (f, elems, self)) +--- Turn a list of pairs into a table. +-- @todo Find a better name. +-- @tparam table ls list of lists `{{i1, v1}, ..., {in, vn}}` +-- @treturn table a new list containing table `{i1=v1, ..., in=vn}` +-- @see enpair +local function depair (ls) + local t = {} + for v in elems (ls) do + t[v[1]] = v[2] + end + return t end ---- Map a function over a list of lists. --- @tparam table ls a list of lists --- @tparam function f map function --- @treturn std.list new list `{f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))}` -local function map_with (ls, f) - return List (func.map (func.compose (f, unpack), elems, ls)) +--- Turn a table into a list of pairs. +-- @todo Find a better name. +-- @tparam table t a table `{i1=v1, ..., in=vn}` +-- @treturn List a new list containing `{{i1, v1}, ..., {in, vn}}` +-- @see depair +local function enpair (t) + local ls = List {} + for i, v in pairs (t) do + table.insert (ls, List {i, v}) + end + return ls end --- Filter a list according to a predicate. --- @tparam function p predicate function, of one argument returning a boolean --- @treturn std.list new list containing elements `e` of `self` for which `p (e)` is true -local function filter (self, p) - return List (func.filter (p, elems, self)) +-- @func p predicate function, of one argument returning a boolean +-- @tparam List l a list +-- @treturn List new list containing elements `e` of `l` for which +-- `p (e)` is true +-- @see std.list:filter +local function filter (p, l) + return List (func.filter (p, elems, l)) end ---- Return a sub-range of a list. --- (The equivalent of `string.sub` on strings; negative list indices --- count from the end of the list.) --- @tparam number from start of range (default: 1) --- @tparam number to end of range (default: `#self`) --- @treturn std.list new list containing `{self[from], ..., self[to]}` -local function sub (self, from, to) +--- Flatten a list. +-- @tparam List l a list +-- @treturn List flattened list +local function flatten (l) local r = List {} - local len = #self - from = from or 1 - to = to or len - if from < 0 then - from = from + len + 1 - end - if to < 0 then - to = to + len + 1 - end - for i = from, to do - table.insert (r, self[i]) + for v in base.ileaves (l) do + table.insert (r, v) end return r end ---- Return a list with its first element removed. --- @treturn std.list new list containing `{self[2], ..., self[#self]}` -local function tail (self) - return sub (self, 2) -end - - --- Fold a binary function through a list left associatively. --- @tparam function f binary function --- @param e element to place in left-most position +-- @func fn binary function +-- @param e element to place in left-most position +-- @tparam List l a list -- @return result -local function foldl (self, f, e) - return func.fold (f, e, elems, self) +-- @see std.list:foldl +local function foldl (fn, e, l) + return func.fold (fn, e, elems, l) end ---- Fold a binary function through a list right associatively. --- @tparam function f binary function --- @param e element to place in right-most position --- @return result -local function foldr (self, f, e) - return List (func.fold (function (x, y) return f (y, x) end, - e, relems, self)) +--- An iterator over the elements of a list, in reverse. +-- @tparam List l a list +-- @treturn function iterator function which returns precessive elements +-- of the `l` +-- @treturn List `l` +-- @return `true` +local function relems (l) + local n = #l + 1 + return function (l) + n = n - 1 + if n > 0 then + return l[n] + end + end, + l, true end ---- Prepend an item to a list. --- @param x item --- @treturn std.list new list containing `{x, unpack (self)}` -local function cons (self, x) - return List {x, unpack (self)} +--- Fold a binary function through a list right associatively. +-- @func fn binary function +-- @param e element to place in right-most position +-- @tparam List l a list +-- @return result +-- @see std.list:foldr +local function foldr (fn, e, l) + return List (func.fold (function (x, y) return fn (y, x) end, + e, relems, l)) end ---- Repeat a list. --- @tparam number n number of times to repeat --- @treturn std.list `n` copies of `self` appended together -local function rep (self, n) +--- Make an index of a list of tables on a given field +-- @param f field +-- @tparam List l list of tables `{t1, ..., tn}` +-- @treturn List index `{t1[f]=1, ..., tn[f]=n}` +local function index_key (f, l) local r = List {} - for i = 1, n do - r = concat (r, self) + for i, v in ipairs (l) do + local k = v[f] + if k then + r[k] = i + end end return r end ---- Reverse a list. --- @treturn std.list new list containing `{self[#self], ..., self[1]}` -local function reverse (self) +--- Copy a list of tables, indexed on a given field +-- @param f field whose value should be used as index +-- @tparam List l list of tables `{i1=t1, ..., in=tn}` +-- @treturn List index `{t1[f]=t1, ..., tn[f]=tn}` +local function index_value (f, l) local r = List {} - for i = #self, 1, -1 do - table.insert (r, self[i]) + for i, v in ipairs (l) do + local k = v[f] + if k then + r[k] = v + end end return r end ---- Transpose a list of lists. --- This function in Lua is equivalent to zip and unzip in more strongly --- typed languages. --- @tparam table ls --- `{{ls<1,1>, ..., ls<1,c>}, ..., {ls<r,1>, ..., ls<r,c>}}` --- @treturn std.list new list containing --- `{{ls<1,1>, ..., ls<r,1>}, ..., {ls<1,c>, ..., ls<r,c>}}` -local function transpose (ls) - local rs, len = List {}, #ls - for i = 1, math.max (unpack (map (ls, function (l) return #l end))) do - rs[i] = List {} - for j = 1, len do - rs[i][j] = ls[j][i] - end - end - return rs +--- Map a function over a list. +-- @func fn map function +-- @tparam List l a list +-- @treturn List new list containing `{fn (l[1]), ..., fn (l[#l])}` +-- @see std.list:map +local function map (fn, l) + return List (func.map (fn, elems, l)) end ---- Zip a list of lists together with a function. --- @tparam table ls list of lists --- @tparam function f function --- @treturn std.list a new list containing --- `{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N])` --- where `N = max {map (function (l) return #l end, ls)}` -local function zip_with (ls, f) - return map_with (transpose (ls), f) +--- Map a function over a list of lists. +-- @func fn map function +-- @tparam List ls a list of lists +-- @treturn List new list `{fn (unpack (ls[1]))), ..., fn (unpack (ls[#ls]))}` +local function map_with (fn, ls) + return List (func.map (func.compose (fn, unpack), elems, ls)) end --- Project a list of fields from a list of tables. --- @param f field to project --- @treturn std.list list of `f` fields -local function project (self, f) - return map (self, function (t) return t[f] end) +-- @param f field to project +-- @tparam List l a list +-- @treturn List list of `f` fields +-- @see std.list:project +local function project (f, l) + return map (function (t) return t[f] end, l) end ---- Turn a table into a list of pairs. --- @todo Find a better name. --- @tparam table t a table `{i1=v1, ..., in=vn}` --- @treturn std.list a new list containing `{{i1, v1}, ..., {in, vn}}` --- @see depair -local function enpair (t) - local ls = List {} - for i, v in pairs (t) do - table.insert (ls, List {i, v}) - end - return ls -end - - ---- Turn a list of pairs into a table. --- @todo Find a better name. --- @tparam table ls list of lists `{{i1, v1}, ..., {in, vn}}` --- @treturn table a new list containing table `{i1=v1, ..., in=vn}` --- @see enpair -local function depair (ls) - local t = {} - for v in elems (ls) do - t[v[1]] = v[2] +--- Repeat a list. +-- @tparam List l a list +-- @int n number of times to repeat +-- @treturn List `n` copies of `l` appended together +local function rep (l, n) + local r = List {} + for i = 1, n do + r = concat (r, l) end - return t + return r end ---- Flatten a list. --- @treturn std.list flattened list -local function flatten (self) +--- Reverse a list. +-- @tparam List l a list +-- @treturn List new list containing `{l[#l], ..., l[1]}` +local function reverse (l) local r = List {} - for v in base.ileaves (self) do - table.insert (r, v) + for i = #l, 1, -1 do + table.insert (r, l[i]) end return r end @@ -284,9 +284,11 @@ end -- @todo Use ileaves instead of flatten (needs a while instead of a -- for in fill function) -- @tparam table s `{d1, ..., dn}` +-- @tparam List l a list -- @return reshaped list -local function shape (self, s) - self = flatten (self) +-- @see std.list:shape +local function shape (s, l) + l = flatten (l) -- Check the shape and calculate the size of the zero, if any local size = 1 local zero @@ -302,11 +304,11 @@ local function shape (self, s) end end if zero then - s[zero] = math.ceil (#self / size) + s[zero] = math.ceil (#l / size) end local function fill (i, d) if d > #s then - return self[i], i + 1 + return l[i], i + 1 else local r = List {} for j = 1, s[d] do @@ -321,40 +323,71 @@ local function shape (self, s) end ---- Make an index of a list of tables on a given field --- @tparam table l list of tables `{t1, ..., tn}` --- @param f field --- @treturn std.list index `{t1[f]=1, ..., tn[f]=n}` -local function index_key (l, f) +--- Return a sub-range of a list. +-- (The equivalent of `string.sub` on strings; negative list indices +-- count from the end of the list.) +-- @tparam List l a list +-- @int from start of range (default: 1) +-- @int to end of range (default: `#l`) +-- @treturn List new list containing `{l[from], ..., l[to]}` +local function sub (l, from, to) local r = List {} - for i, v in ipairs (l) do - local k = v[f] - if k then - r[k] = i - end + local len = #l + from = from or 1 + to = to or len + if from < 0 then + from = from + len + 1 + end + if to < 0 then + to = to + len + 1 + end + for i = from, to do + table.insert (r, l[i]) end return r end ---- Copy a list of tables, indexed on a given field --- @tparam table l list of tables `{i1=t1, ..., in=tn}` --- @param f field whose value should be used as index --- @treturn std.list index `{t1[f]=t1, ..., tn[f]=tn}` -local function index_value (l, f) - local r = List {} - for i, v in ipairs (l) do - local k = v[f] - if k then - r[k] = v +--- Return a list with its first element removed. +-- @tparam List l a list +-- @treturn List new list containing `{l[2], ..., l[#l]}` +local function tail (l) + return sub (l, 2) +end + + +--- Transpose a list of lists. +-- This function in Lua is equivalent to zip and unzip in more strongly +-- typed languages. +-- @tparam table ls +-- `{{ls<1,1>, ..., ls<1,c>}, ..., {ls<r,1>, ..., ls<r,c>}}` +-- @treturn List new list containing +-- `{{ls<1,1>, ..., ls<r,1>}, ..., {ls<1,c>, ..., ls<r,c>}}` +local function transpose (ls) + local rs, len = List {}, #ls + for i = 1, math.max (unpack (map (ls, function (l) return #l end))) do + rs[i] = List {} + for j = 1, len do + rs[i][j] = ls[j][i] end end - return r + return rs +end + + +--- Zip a list of lists together with a function. +-- @tparam table ls list of lists +-- @tparam function f function +-- @treturn List a new list containing +-- `{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N])` +-- where `N = max {map (function (l) return #l end, ls)}` +local function zip_with (ls, f) + return map_with (transpose (ls), f) end --- @export -local metamethods = { +local _functions = { append = append, compare = compare, concat = concat, @@ -390,7 +423,7 @@ List = Object { -- Concatenate lists. -- new = list .. table -- @function __concat - -- @tparam std.list list a list + -- @tparam List list a list -- @tparam table table another list, hash part is ignored -- @see concat __concat = concat, @@ -399,7 +432,7 @@ List = Object { -- Append element to list. -- list = list + element -- @function __add - -- @tparam std.list list a list + -- @tparam List list a list -- @param element element to append -- @see append __add = append, @@ -407,30 +440,185 @@ List = Object { ------ -- List order operator. -- max = list1 > list2 and list1 or list2 - -- @tparam std.list list1 a list - -- @tparam std.list list2 another list + -- @tparam List list1 a list + -- @tparam List list2 another list -- @see std.list:compare __lt = function (list1, list2) return compare (list1, list2) < 0 end, ------ -- List equality or order operator. -- min = list1 <= list2 and list1 or list2 - -- @tparam std.list list1 a list - -- @tparam std.list list2 another list + -- @tparam List list1 a list + -- @tparam List list2 another list -- @see std.list:compare __le = function (list1, list2) return compare (list1, list2) <= 0 end, - __index = base.merge (metamethods, { - -- camelCase compatibility. - indexKey = index_key, - indexValue = index_value, - mapWith = map_with, - zipWith = zip_with, - }), + __index = { + ------ + -- Append an item to a list. + -- @function append + -- @param x item + -- @treturn List new list containing `{self[1], ..., self[#self], x}` + append = append, + + ------ + -- Compare two lists element-by-element, from left-to-right. + -- + -- if a_list:compare (another_list) == 0 then print "same" end + -- @function compare + -- @tparam table l a list + -- @return -1 if `self` is less than `l`, 0 if they are the same, and 1 + -- if `self` is greater than `l` + compare = compare, + + ------ + -- Concatenate arguments into a list. + -- @function concat + -- @param ... tuple of lists + -- @treturn List new list containing + -- `{self[1], ..., self[#self], l\_1[1], ..., l\_1[#l\_1], ..., l\_n[1], ..., l\_n[#l\_n]}` + concat = concat, + + ------ + -- Prepend an item to a list. + -- @function cons + -- @param x item + -- @treturn List new list containing `{x, unpack (self)}` + cons = cons, + + ------ + -- An iterator over the elements of a list. + -- @function elems + -- @treturn function iterator function which returns successive + -- elements of `self` + -- @treturn List `self` + -- @return `true` + elems = elems, + + ------ + -- Filter a list according to a predicate. + -- @function filter + -- @func p predicate function, of one argument returning a boolean + -- @treturn List new list containing elements `e` of `self` for which + -- `p (e)` is true + -- @see std.list.filter + filter = function (self, p) return filter (p, self) end, + + ------ + -- Flatten a list. + -- @function flatten + -- @treturn List flattened list + flatten = flatten, + + ------ + -- Fold a binary function through a list left associatively. + -- @function foldl + -- @func fn binary function + -- @param e element to place in left-most position + -- @return result + -- @see std.list.foldl + foldl = function (self, fn, e) return foldl (fn, e, self) end, + + ------ + -- Fold a binary function through a list right associatively. + -- @function foldr + -- @func f binary function + -- @param e element to place in right-most position + -- @return result + -- @see std.list.foldr + foldr = function (self, fn, e) return foldr (fn, e, self) end, + + ------ + -- Map a function over a list. + -- @function map + -- @func fn map function + -- @treturn List new list containing + -- `{fn (self[1]), ..., fn (self[#self])}` + -- @see std.list.map + map = function (self, fn) return map (fn, self) end, + + ------ + -- Project a list of fields from a list of tables. + -- @function project + -- @param f field to project + -- @treturn List list of `f` fields + -- @see std.list.project + project = function (self, f) return project (f, self) end, + + ------ + -- An iterator over the elements of a list, in reverse. + -- @function relems + -- @treturn function iterator function which returns precessive elements + -- of the `self` + -- @treturn List `self` + -- @return `true` + relems = relems, + + ------ + -- Repeat a list. + -- @function rep + -- @int n number of times to repeat + -- @treturn List `n` copies of `self` appended together + rep = rep, + + ------ + -- Reverse a list. + -- @function reverse + -- @treturn List new list containing `{self[#self], ..., self[1]}` + reverse = reverse, + + ----- + -- Shape a list according to a list of dimensions. + -- @function shape + -- @tparam table s `{d1, ..., dn}` + -- @return reshaped list + -- @see std.list.shape + shape = function (self, s) return shape (s, self) end, + + ------ + -- Return a sub-range of a list. + -- (The equivalent of `string.sub` on strings; negative list indices + -- count from the end of the list.) + -- @function sub + -- @int from start of range (default: 1) + -- @int to end of range (default: `#self`) + -- @treturn List new list containing `{self[from], ..., self[to]}` + sub = sub, + + ------ + -- Return a list with its first element removed. + -- @function tail + -- @treturn List new list containing `{self[2], ..., self[#self]}` + tail = tail, + + -- For backwards compatibility with pre-Object era lists, but + -- undocumented so that new code doesn't get tangled up in it. + depair = depair, + index_key = function (self, f) return index_key (f, self) end, + index_value = function (self, f) return index_value (f, self) end, + indexKey = function (self, f) return indexKey (f, self) end, + indexValue = function (self, f) return indexValue (f, self) end, + map_with = function (self, f) return map_with (f, self) end, + transpose = transpose, + zip_with = function (self, f) return zip_with (f, self) end, + }, + + _functions = (base.merge (_functions, { + -- backwards compatibility + new = function (t) return List (t or {}) end, + slice = sub, + + -- camelCase compatibility + indexKey = index_key, + indexValue = index_value, + mapWith = map_with, + zipWith = zip_with, + })), } -- Function forms of operators func.op[".."] = concat + return List diff --git a/lib/std/modules.lua b/lib/std/modules.lua index 2beaf18..d023b1b 100644 --- a/lib/std/modules.lua +++ b/lib/std/modules.lua @@ -6,10 +6,10 @@ return { debug = true, debug_init = false, functional = false, - getopt = false, io = true, list = false, math = true, + optparse = false, package = true, set = false, strbuf = false, diff --git a/lib/std/optparse.lua b/lib/std/optparse.lua new file mode 100644 index 0000000..7bf0ee5 --- /dev/null +++ b/lib/std/optparse.lua @@ -0,0 +1,533 @@ +--[[-- + Parse and process command line options. + + local OptionParser = require "std.optparse" + local parser = OptionParser (spec) + _G.arg, opts = parser:parse (_G.arg) + + The string `spec` passed to `OptionParser` must be a specially formatted + help text, of the form: + + any text VERSION + Additional lines of text to show when the --version + option is passed. + + Several lines or paragraphs are permitted. + + Usage: PROGNAME + + Banner text. + + Optional long description text to show when the --help + option is passed. + + Several lines or paragraphs of long description are permitted. + + Options: + + -h, --help display this help, then exit + --version display version information, then exit + -b a short option with no long option + --long a long option with no short option + --another-long a long option with internal hypen + --true a Lua keyword as an option name + -v, --verbose a combined short and long option + -n, --dryrun, --dry-run several spellings of the same option + -u, --name=USER require an argument + -o, --output=[FILE] accept an optional argument + -- end of options + + Footer text. Several lines or paragraphs are permitted. + + Please report bugs at bug-list@yourhost.com + + Most often, everything else is handled automatically. After calling + `parser:parse` as shown above, `_G.arg` will contain unparsed arguments, + usually filenames or similar, and `opts` will be a table of parsed + option values. The keys to the table are the long-options with leading + hyphens stripped, and non-word characters turned to `_`. For example + if `--another-long` had been found in `_G.arg` then `opts` would + have a key named `another_long`. If there is no long option name, then + the short option is used, e.g. `opts.b` will be set. The values saved + in those keys are controlled by the option handler, usually just `true` + or the option argument string as appropriate. + + On those occasions where more complex processing is required, handlers + can be replaced or added using parser:@{on}. + + @classmod std.optparse +]] + + +local OptionParser -- forward declaration + + +------ +-- Customized parser for your options. +-- @table parser + + +--[[ ----------------- ]]-- +--[[ Helper Functions. ]]-- +--[[ ----------------- ]]-- + + +local optional, required + + +--- Normalise an argument list. +-- Separate short options, remove `=` separators from +-- `--long-option=optarg` etc. +-- @function normalise +-- @tparam table arglist list of arguments to normalise +-- @treturn table normalised argument list +local function normalise (self, arglist) + -- First pass: Normalise to long option names, without '=' separators. + local normal = {} + local i = 0 + while i < #arglist do + i = i + 1 + local opt = arglist[i] + + -- Split '--long-option=option-argument'. + if opt:sub (1, 2) == "--" then + local x = opt:find ("=", 3, true) + if x then + table.insert (normal, opt:sub (1, x - 1)) + table.insert (normal, opt:sub (x + 1)) + else + table.insert (normal, opt) + end + + elseif opt:sub (1, 1) == "-" and string.len (opt) > 2 then + local rest + repeat + opt, rest = opt:sub (1, 2), opt:sub (3) + + table.insert (normal, opt) + + -- Split '-xyz' into '-x -yz', and reiterate for '-yz' + if self[opt].handler ~= optional and + self[opt].handler ~= required then + if string.len (rest) > 0 then + opt = "-" .. rest + else + opt = nil + end + + -- Split '-xshortargument' into '-x shortargument'. + else + table.insert (normal, rest) + opt = nil + end + until opt == nil + else + table.insert (normal, opt) + end + end + + normal[-1], normal[0] = arglist[-1], arglist[0] + return normal +end + + +--- Store `value` with `opt`. +-- @function set +-- @string opt option name +-- @param value option argument value +local function set (self, opt, value) + local key = self[opt].key + + if type (self.opts[key]) == "table" then + table.insert (self.opts[key], value) + elseif self.opts[key] ~= nil then + self.opts[key] = { self.opts[key], value } + else + self.opts[key] = value + end +end + + + +--[[ ============= ]]-- +--[[ Option Types. ]]-- +--[[ ============= ]]-- + + +--- Option at `arglist[i]` can take an argument. +-- Argument is accepted only if there is a following entry that does not +-- begin with a '-'. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt=true] value either a function to process the option +-- argument, or a default value if encountered without an optarg +-- @treturn int index of next element of `arglist` to process +function optional (self, arglist, i, value) + if i + 1 <= #arglist and arglist[i + 1]:sub (1, 1) ~= "-" then + return self:required (arglist, i, value) + end + + if type (value) == "function" then + value = value (self, opt, nil) + elseif value == nil then + value = true + end + + set (self, arglist[i], value) + return i + 1 +end + + +--- Option at `arglist[i}` requires an argument. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt] value either a function to process the option argument, +-- or a forced value to replace the user's option argument. +-- @treturn int index of next element of `arglist` to process +function required (self, arglist, i, value) + local opt = arglist[i] + if i + 1 > #arglist then + self:opterr ("option '" .. opt .. "' requires an argument") + return i + 1 + end + + if type (value) == "function" then + value = value (self, opt, arglist[i + 1]) + elseif value == nil then + value = arglist[i + 1] + end + + set (self, opt, value) + return i + 2 +end + + +--- Finish option processing +-- Usually indicated by `--` at `arglist[i]`. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @treturn int index of next element of `arglist` to process +local function finished (self, arglist, i) + for opt = i + 1, #arglist do + table.insert (self.unrecognised, arglist[opt]) + end + return 1 + #arglist +end + + +--- Option at `arglist[i]` is a boolean switch. +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt] value either a function to process the option argument, +-- or a value to store when this flag is encountered +-- @treturn int index of next element of `arglist` to process +local function flag (self, arglist, i, value) + if type (value) == "function" then + value = value (self, opt, true) + elseif value == nil then + value = true + end + + set (self, arglist[i], value) + return i + 1 +end + + +--- Option should display help text, then exit. +-- @function help +local function help (self) + print (self.helptext) + os.exit (0) +end + + +--- Option should display version text, then exit. +-- @function version +local function version (self) + print (self.versiontext) + os.exit (0) +end + + + +--[[ =============== ]]-- +--[[ Argument Types. ]]-- +--[[ =============== ]]-- + + +--- Map various option strings to equivalent Lua boolean values. +-- @table boolvals +-- @field false false +-- @field 0 false +-- @field no false +-- @field n false +-- @field true true +-- @field 1 true +-- @field yes true +-- @field y true +local boolvals = { + ["false"] = false, ["true"] = true, + ["0"] = false, ["1"] = true, + no = false, yes = true, + n = false, y = true, +} + + +--- Return a Lua boolean equivalent of various `optarg` strings. +-- Report an option parse error if `optarg` is not recognised. +-- @string opt option name +-- @string[opt="1"] optarg option argument, must be a key in @{boolvals} +-- @treturn bool `true` or `false` +local function boolean (self, opt, optarg) + if optarg == nil then optarg = "1" end -- default to truthy + local b = boolvals[tostring (optarg):lower ()] + if b == nil then + return self:opterr (optarg .. ": Not a valid argument to " ..opt[1] .. ".") + end + return b +end + + +--- Report an option parse error unless `optarg` names an +-- existing file. +-- @fixme this only checks whether the file has read permissions +-- @string opt option name +-- @string optarg option argument, must be an existing file +-- @treturn `optarg` +local function file (self, opt, optarg) + local h, errmsg = io.open (optarg, "r") + if h == nil then + return self:opterr (optarg .. ": " .. errmsg) + end + h:close () + return optarg +end + + + +--[[ =============== ]]-- +--[[ Option Parsing. ]]-- +--[[ =============== ]]-- + + +--- Report an option parse error, then exit with status 2. +-- @string msg error message +local function opterr (self, msg) + local prog = self.program + -- Ensure final period. + if msg:match ("%.$") == nil then msg = msg .. "." end + io.stderr:write (prog .. ": error: " .. msg .. "\n") + io.stderr:write (prog .. ": Try '" .. prog .. " --help' for help.\n") + os.exit (2) +end + + +------ +-- Function signature of an option handler for @{on}. +-- @function on_handler +-- @tparam table arglist list of arguments +-- @int i index of last processed element of `arglist` +-- @param[opt=nil] value additional `value` registered with @{on} +-- @treturn int index of next element of `arglist` to process + + +--- Add an option handler. +-- @function on +-- @tparam[string|table] opts name of the option, or list of option names +-- @tparam on_handler handler function to call when any of `opts` is +-- encountered +-- @param value additional value passed to @{on_handler} +local function on (self, opts, handler, value) + if type (opts) == "string" then opts = { opts } end + handler = handler or flag -- unspecified options behave as flags + + normal = {} + for _, optspec in ipairs (opts) do + optspec:gsub ("(%S+)", + function (opt) + -- 'x' => '-x' + if string.len (opt) == 1 then + opt = "-" .. opt + + -- 'option-name' => '--option-name' + elseif opt:match ("^[^%-]") ~= nil then + opt = "--" .. opt + end + + if opt:match ("^%-[^%-]+") ~= nil then + -- '-xyz' => '-x -y -z' + for i = 2, string.len (opt) do + table.insert (normal, "-" .. opt:sub (i, i)) + end + else + table.insert (normal, opt) + end + end) + end + + -- strip leading '-', and convert non-alphanums to '_' + key = normal[#normal]:match ("^%-*(.*)$"):gsub ("%W", "_") + + for _, opt in ipairs (normal) do + self[opt] = { key = key, handler = handler, value = value } + end +end + + +------ +-- Parsed options table, with a key for each encountered option, each +-- with value set by that option's @{on_handler}. +-- @table opts + + +--- Parse `arglist`. +-- @tparam table arglist list of arguments +-- @treturn table a list of unrecognised `arglist` elements +-- @treturn opts parsing results +local function parse (self, arglist) + self.unrecognised = {} + + arglist = normalise (self, arglist) + + local i = 1 + while i > 0 and i <= #arglist do + local opt = arglist[i] + + if self[opt] == nil then + table.insert (self.unrecognised, opt) + i = i + 1 + + -- Following non-'-' prefixed argument is an optarg. + if i <= #arglist and arglist[i]:match "^[^%-]" then + table.insert (self.unrecognised, arglist[i]) + i = i + 1 + end + + -- Run option handler functions. + else + assert (type (self[opt].handler) == "function") + + i = self[opt].handler (self, arglist, i, self[opt].value) + end + end + + return self.unrecognised, self.opts +end + + +--- @export +local methods = { + boolean = boolean, + file = file, + finished = finished, + flag = flag, + help = help, + optional = optional, + required = required, + version = version, + + on = on, + opterr = opterr, + parse = parse, +} + + + +--- Take care not to register duplicate handlers. +-- @param current current handler value +-- @param new new handler value +-- @return `new` if `current` is nil +local function set_handler (current, new) + assert (current == nil, "only one handler per option") + return new +end + + +--- Instantiate a new parser. +-- Read the documented options from `spec` and return a new parser that +-- can be passed to @{parse} for parsing those options from an argument +-- list. +-- @static +-- @string spec option parsing specification +-- @treturn parser a parser for options described by `spec` +function OptionParser (spec) + local parser = setmetatable ({ opts = {} }, { __index = methods }) + + parser.versiontext, parser.version, parser.helptext, parser.program = + spec:match ("^([^\n]-(%S+)\n.-)%s*([Uu]sage: (%S+).-)%s*$") + + if parser.versiontext == nil then + error ("OptionParser spec argument must match '\\n" .. + "...Usage: ...'") + end + + -- Collect helptext lines that begin with two or more spaces followed + -- by a '-'. + local specs = {} + parser.helptext:gsub ("\n %s*(%-[^\n]+)", + function (spec) table.insert (specs, spec) end) + + -- Register option handlers according to the help text. + for _, spec in ipairs (specs) do + local options, handler = {} + + -- Loop around each '-' prefixed option on this line. + while spec:sub (1, 1) == "-" do + + -- Capture end of options processing marker. + if spec:match "^%-%-,?%s" then + handler = set_handler (handler, finished) + + -- Capture optional argument in the option string. + elseif spec:match "^%-[%-%w]+=%[.+%],?%s" then + handler = set_handler (handler, optional) + + -- Capture required argument in the option string. + elseif spec:match "^%-[%-%w]+=%S+,?%s" then + handler = set_handler (handler, required) + + -- Capture any specially handled arguments. + elseif spec:match "^%-%-help,?%s" then + handler = set_handler (handler, help) + + elseif spec:match "^%-%-version,?%s" then + handler = set_handler (handler, version) + end + + -- Consume argument spec, now that it was processed above. + spec = spec:gsub ("^(%-[%-%w]+)=%S+%s", "%1 ") + + -- Consume short option. + local _, c = spec:gsub ("^%-([-%w]),?%s+(.*)$", + function (opt, rest) + if opt == "-" then opt = "--" end + table.insert (options, opt) + spec = rest + end) + + -- Be careful not to consume more than one option per iteration, + -- otherwise we might miss a handler test at the next loop. + if c == 0 then + -- Consume long option. + spec:gsub ("^%-%-([%-%w]+),?%s+(.*)$", + function (opt, rest) + table.insert (options, opt) + spec = rest + end) + end + end + + -- Unless specified otherwise, treat each option as a flag. + parser:on (options, handler or flag) + end + + return parser +end + + +-- Support calling the returned table: +return setmetatable (methods, { + __call = function (_, ...) + return OptionParser (...) + end, +}) diff --git a/lib/std/set.lua b/lib/std/set.lua index 2eb032c..c3911d1 100644 --- a/lib/std/set.lua +++ b/lib/std/set.lua @@ -63,7 +63,8 @@ end -- High level methods (representation-independent) -local difference, symmetric_difference, intersection, union, subset, equal +local difference, symmetric_difference, intersection, union, subset, + proper_subset, equal --- Find the difference of two sets. @@ -170,6 +171,23 @@ function equal (set1, set2) return subset (set1, set2) and subset (set2, set1) end + +--- @export +local _functions = { + delete = delete, + difference = difference, + elems = elems, + equal = equal, + insert = insert, + intersection = intersection, + member = member, + proper_subset = proper_subset, + subset = subset, + symmetric_difference = symmetric_difference, + union = union, +} + + --- Set prototype object. -- @table std.set -- @string[opt="Set"] _type type of Set, returned by @@ -268,20 +286,10 @@ Set = Container { end, - --- @export - _functions = { - delete = delete, - difference = difference, - elems = elems, - equal = equal, - insert = insert, - intersection = intersection, - member = member, - proper_subset = proper_subset, - subset = subset, - symmetric_difference = symmetric_difference, - union = union, - }, + _functions = base.merge (_functions, { + -- backwards compatibility. + new = function (t) return Set (t or {}) end, + }), } return Set diff --git a/lib/std/strbuf.lua b/lib/std/strbuf.lua index 77ed1bb..a2ee225 100644 --- a/lib/std/strbuf.lua +++ b/lib/std/strbuf.lua @@ -53,4 +53,9 @@ return Object { concat = concat, tostring = tostring, }, + + -- backwards compatibility. + _functions = { + new = function () return StrBuf {} end, + }, } diff --git a/lib/std/string.lua b/lib/std/string.lua index c4008e8..08a6b9c 100644 --- a/lib/std/string.lua +++ b/lib/std/string.lua @@ -4,7 +4,7 @@ ]] local func = require "std.functional" -local list = require "std.list" +local List = require "std.list" local StrBuf = require "std.strbuf" local table = require "std.table" @@ -91,7 +91,7 @@ local function split (s, sep) -- flatten the result, discarding the captures, and prepend 0 (1 -- before the first character) and append 0 (1 after the last -- character), and then read off the result in pairs. - local pairs = list.concat ({0}, list.flatten (finds (s, sep)), {0}) + local pairs = List.concat ({0}, List.flatten (finds (s, sep)), {0}) local l = {} for i = 1, #pairs, 2 do table.insert (l, string.sub (s, pairs[i] + 1, pairs[i + 1] - 1)) @@ -104,10 +104,10 @@ end -- @param min lowest acceptable version (default: any) -- @param too_big lowest version that is too big (default: none) -- @param pattern to match version in `module.version` or --- `module.VERSION` (default: `".*[%.%d]+"` +-- `module.VERSION` (default: `".*[%.%d]+"`) local function require_version (module, min, too_big, pattern) local function version_to_list (v) - return list.new (split (v, "%.")) + return List (split (v, "%.")) end local function module_version (module, pattern) return version_to_list (string.match (module.version or module._VERSION, diff --git a/lib/std/tree.lua b/lib/std/tree.lua index f1c2d28..643fe49 100644 --- a/lib/std/tree.lua +++ b/lib/std/tree.lua @@ -13,7 +13,7 @@ local base = require "std.base" local Container = require "std.container" -local list = require "std.list" +local List = require "std.list" local func = require "std.functional" local prototype = (require "std.object").prototype @@ -177,6 +177,17 @@ local function merge (t, u) end +--- @export +local _functions = { + clone = clone, + ileaves = ileaves, + inodes = inodes, + leaves = leaves, + merge = merge, + nodes = nodes, +} + + --- Tree prototype object. -- @table std.tree -- @string[opt="Tree"] _type type of Tree, returned by @@ -197,7 +208,7 @@ Tree = Container { -- e.g. self[{{1, 2}, {3, 4}}], maybe flatten first? __index = function (self, i) if type (i) == "table" and #i > 0 then - return list.foldl (i, func.op["[]"], self) + return List.foldl (func.op["[]"], self, i) else return rawget (self, i) end @@ -223,15 +234,10 @@ Tree = Container { end end, - --- @export - _functions = { - clone = clone, - ileaves = ileaves, - inodes = inodes, - leaves = leaves, - merge = merge, - nodes = nodes, - }, + _functions = base.merge (_functions, { + -- backwards compatibility. + new = function (t) return Tree (t or {}) end, + }), } return Tree diff --git a/local.mk b/local.mk index 23c0ad0..fc2170b 100644 --- a/local.mk +++ b/local.mk @@ -29,7 +29,7 @@ LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" ## Bootstrap. ## ## ---------- ## -old_NEWS_hash = 7ef01dfb840329db3d8db218bfe9d075 +old_NEWS_hash = 7a7647cb5b2d5d886a18070e1f4ac5fd update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ @@ -65,14 +65,13 @@ dist_luastd_DATA = \ lib/std/base.lua \ lib/std/container.lua \ lib/std/debug.lua \ - lib/std/debug_init.lua \ lib/std/functional.lua \ - lib/std/getopt.lua \ lib/std/io.lua \ lib/std/list.lua \ lib/std/math.lua \ lib/std/modules.lua \ lib/std/object.lua \ + lib/std/optparse.lua \ lib/std/package.lua \ lib/std/set.lua \ lib/std/strbuf.lua \ @@ -82,6 +81,19 @@ dist_luastd_DATA = \ lib/std/tree.lua \ $(NOTHING_ELSE) + +# For bugwards compatibility with LuaRocks 2.1, while ensuring that +# `require "std.debug_init"` continues to work, we have to install +# the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. +# When everyone has upgraded to a LuaRocks that works, move this +# file back to dist_luastd_DATA above and rename to debug_init.lua. + +luastddebugdir = $(luastddir)/debug_init + +dist_luastddebug_DATA = \ + lib/std/debug_init/init.lua \ + $(NOTHING_ELSE) + # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to # have ldoc installed, put std/std.lua in as a Makefile dependency. @@ -90,8 +102,9 @@ lib/std.lua: lib/std.lua.in ./config.status --file=$@ -## Use a builtin rockspec build with root at $(srcdir)/lib -mkrockspecs_args = --module-dir $(srcdir)/lib +## Use a builtin rockspec build with root at $(srcdir)/lib, and note +## the github repository doesn't have the same name as the rockspec! +mkrockspecs_args = --module-dir $(srcdir)/lib --repository lua-stdlib ## ------------- ## @@ -117,6 +130,7 @@ dist_classes_DATA += \ $(srcdir)/doc/classes/std.container.html \ $(srcdir)/doc/classes/std.list.html \ $(srcdir)/doc/classes/std.object.html \ + $(srcdir)/doc/classes/std.optparse.html \ $(srcdir)/doc/classes/std.set.html \ $(srcdir)/doc/classes/std.strbuf.html \ $(srcdir)/doc/classes/std.tree.html \ @@ -126,7 +140,6 @@ dist_modules_DATA += \ $(srcdir)/doc/modules/std.html \ $(srcdir)/doc/modules/std.debug.html \ $(srcdir)/doc/modules/std.functional.html \ - $(srcdir)/doc/modules/std.getopt.html \ $(srcdir)/doc/modules/std.io.html \ $(srcdir)/doc/modules/std.math.html \ $(srcdir)/doc/modules/std.package.html \ diff --git a/rockspec.conf b/rockspec.conf index c7813c7..2e1e688 100644 --- a/rockspec.conf +++ b/rockspec.conf @@ -6,8 +6,8 @@ description: summary: General Lua Libraries detailed: stdlib is a library of modules for common programming tasks, - including list, table and functional operations, regexps, objects, - pickling, pretty-printing and getopt. + including list, table and functional operations, objects, + pickling, pretty-printing and command-line option parsing. dependencies: - lua >= 5.1 diff --git a/specs/container_spec.yaml b/specs/container_spec.yaml index 34a8ef0..ab37b67 100644 --- a/specs/container_spec.yaml +++ b/specs/container_spec.yaml @@ -1,8 +1,15 @@ before: + require "spec_helper" Container = require "std.container" prototype = (require "std.object").prototype -specify Container: +specify std.container: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.container"}). + should_equal {} + - describe construction: - context from Container prototype: - before: diff --git a/specs/debug_spec.yaml b/specs/debug_spec.yaml index 6ba7acc..038fe7c 100644 --- a/specs/debug_spec.yaml +++ b/specs/debug_spec.yaml @@ -1,60 +1,29 @@ -specify debug: -- before: | - M = require "std.debug" +before: | + require "spec_helper" - extends = debug - enhancements = {} - extensions = { "say", "trace" } + this_module = "std.debug" -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + global_table = "_G" - - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end + base_module = "debug" + extend_base = { "say", "trace" } + + M = require "std.debug" - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end +specify std.debug: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core debug table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (extend_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the core debug table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) - describe _DEBUG: diff --git a/specs/functional_spec.yaml b/specs/functional_spec.yaml new file mode 100644 index 0000000..26b87ab --- /dev/null +++ b/specs/functional_spec.yaml @@ -0,0 +1,55 @@ +before: | + require "spec_helper" + + global_table = "_G" + this_module = "std.functional" + std_globals = { "bind", "collect", "compose", "curry", "eval", + "filter", "fold", "id", "map", "memoize", + "metamethod", "op" } + + M = require (this_module) + +specify std.functional: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + + - context via the std module: + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + + +- describe bind: + + +- describe collect: + + +- describe compose: + + +- describe curry: + + +- describe eval: + + +- describe filter: + + +- describe fold: + + +- describe id: + + +- describe map: + + +- describe memoize: + + +- describe metamethod: diff --git a/specs/getopt_spec.yaml b/specs/getopt_spec.yaml deleted file mode 100644 index c36c7d0..0000000 --- a/specs/getopt_spec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -specify getopt: -- before: - getopt = require "std.getopt" - -- "describe getopt.getOpt": - - before: | - prog = { - name = "getopt_spec.lua", - options = { {{"verbose", "v"}, "verbosely list files"}, - {{"output", "o"}, "dump to FILE", "Opt", "FILE"}, - {{"name", "n"}, "only dump USER's files", "Req", "USER"}, - } - } - - function test (cmdLine, stop_at_nonopt) - local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options, stop_at_nonopt) - if #errors == 0 then - return { options = opts, args = nonOpts } - else - return errors - end - end - - getopt.processArgs (prog) - - - it recognizes a user defined option: - expect (test {"foo", "-v"}).should_equal ( - { options = { verbose = {1}}, args = { "foo" } }) - - "it treats -- as the end of the option list": - expect (test {"foo", "--", "-v"}).should_equal ( - { options = {}, args = { "foo", "-v" } }) - - it captures a list of repeated option arguments: - expect (test {"-o", "-V", "-name", "bar", "--name=baz"}).should_equal ( - { options = { name = {"bar", "baz"}, version = {1}, output = {1}}, - args = {} }) - - it diagnoses unrecognized options: - expect (test {"-foo"}).should_contain "unrecognized option `-foo'" - - it stops option parsing at the first non-option if told to: - expect (test ({"foo", "-bar"}, true)).should_equal ( - { options = {}, args = {"foo", "-bar"} }) - -- "describe getopt.usageInfo": - - context when specifying options: - - before: - helppatt = "%-h, %-%-help%s+print this help, then exit" - versionpatt = "%-V, %-%-version%s+print version information, then exit" - prog = { name = "getopt_spec.lua", options = {} } - options = { {{"help", "?"}, "display this help"}, - {{"version"}, "display version number"} } - f = getopt.usageInfo - - - it provides a default version option: - getopt.processArgs (prog) - expect (f ("", prog.options)).should_match (versionpatt) - - it allows the user to override the version option: - prog.options = options - getopt.processArgs (prog) - expect (f ("", prog.options)).should_not_match (versionpatt) - expect (f ("", prog.options)).should_match (" %-%-version%s+display") - - it provides a default help option: - getopt.processArgs (prog) - expect (f ("", prog.options)).should_match (helppatt) - - it allows the user to override the help option: - prog.options = options - getopt.processArgs (prog) - expect (f ("", prog.options)).should_not_match (helppatt) - expect (f ("", prog.options)).should_match ("%-%?, %-%-help%s+display") diff --git a/specs/io_spec.yaml b/specs/io_spec.yaml index 758060a..4c82dbf 100644 --- a/specs/io_spec.yaml +++ b/specs/io_spec.yaml @@ -1,64 +1,47 @@ -specify io: -- before: | - M = require "std.io" - - extends = io - enhancements = {} - extensions = { "catdir", "catfile", "die", "process_files", - "readlines", "shell", "slurp", "splitdir", "warn", - "writelines", - -- camelCase compatibility: - "processFiles" } +before: | + require "spec_helper" -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + this_module = "std.io" + + global_table = "_G" + std_globals = { "die", "warn" } + + base_module = "io" + extend_base = { "catdir", "catfile", "die", "process_files", + "readlines", "shell", "slurp", "splitdir", + "warn", "writelines", + -- camelCase compatibility: + "processFiles" } + extend_metamethods = { "readlines", "writelines" } + M = require (this_module) + +specify std.io: +- context when required: - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end - - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core io table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (extend_base) + - it replaces no apis from the core io table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_equal {} - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + - it adds apis to the core io table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it adds methods to the file metatable: + expect (show_apis {added_to="getmetatable (io.stdin)", by="std"}). + should_contain.a_permutation_of (extend_metamethods) + - it replaces no apis from the core io table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_equal {} - describe catdir: @@ -67,11 +50,12 @@ specify io: - describe catfile: +- describe die: + + - describe process_files: - - before: - subject = M.process_files - it is the same function as legacy processFiles call: - expect (io.processFiles).should_be (subject) + expect (M.process_files).should_be (M.processFiles) - describe readlines: @@ -86,4 +70,7 @@ specify io: - describe splitdir: +- describe warn: + + - describe writelines: diff --git a/specs/list_spec.yaml b/specs/list_spec.yaml index a80749a..523b058 100644 --- a/specs/list_spec.yaml +++ b/specs/list_spec.yaml @@ -5,7 +5,13 @@ before: l = List {"foo", "bar", "baz"} -specify List: +specify std.list: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.list"}). + should_equal {} + - describe construction: - context from List clone method: - it constructs a new list: diff --git a/specs/math_spec.yaml b/specs/math_spec.yaml index d812d4a..02c2cb0 100644 --- a/specs/math_spec.yaml +++ b/specs/math_spec.yaml @@ -1,61 +1,40 @@ -specify math: -- before: | - M = require "std.math" +before: | + require "spec_helper" - extends = math - enhancements = { "floor" } - extensions = { "round" } + this_module = "std.math" + global_table = "_G" + base_module = "math" + extend_base = { "round", "_floor" } + enhance_base = { "floor" } -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + -- 'should_contain' will match keys as well as values :) + all_apis = {} + for _, s in ipairs (extend_base) do all_apis[s] = true end + for _, s in ipairs (enhance_base) do all_apis[s] = true end - - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end + M = require (this_module) - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end +specify std.math: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core math table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (all_apis) + - it enhances some apis from the core math table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_contain.a_permutation_of (enhance_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the core math table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it replaces some apis from the core math table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_base) - describe floor: diff --git a/specs/object_spec.yaml b/specs/object_spec.yaml index 2a07af2..c0102f3 100644 --- a/specs/object_spec.yaml +++ b/specs/object_spec.yaml @@ -1,9 +1,16 @@ before: + require "spec_helper" Object = require "std.object" obj = Object {"foo", "bar", baz="quux"} prototype = Object.prototype -specify Object: +specify std.object: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.object"}). + should_equal {} + - describe construction: - context from Object clone method: - it constructs a new object: diff --git a/specs/optparse_spec.yaml b/specs/optparse_spec.yaml new file mode 100644 index 0000000..a3547fb --- /dev/null +++ b/specs/optparse_spec.yaml @@ -0,0 +1,370 @@ +before: + require "spec_helper" + hell = require "specl.shell" + +specify std.optparse: +- before: | + OptionParser = require "std.optparse" + + help = [[ + parseme (specl spec) 0α1 + + Copyright © 2013 Gary V. Vaughan + This test program comes with ABSOLUTELY NO WARRANTY. + + Usage: parseme [] ... + + Banner text. + + Long description. + + Options: + + -h, --help display this help, then exit + --version display version information, then exit + -b a short option with no long option + --long a long option with no short option + --another-long a long option with internal hypen + --true a Lua keyword as an option name + -v, --verbose a combined short and long option + -n, --dryrun, --dry-run several spellings of the same option + -u, --name=USER require an argument + -o, --output=[FILE] accept an optional argument + -- end of options + + Footer text. + + Please report bugs at . + ]] + + -- strip off the leading whitespace required for YAML + parser = OptionParser (help:gsub ("^ ", "")) + +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to="_G", by="std.optparse"}). + should_equal {} + +- describe OptionParser: + - it recognises the program name: + expect (parser.program).should_be "parseme" + - it recognises the version number: + expect (parser.version).should_be "0α1" + - it recognises the version text: + expect (parser.versiontext). + should_match "^parseme .*Copyright .*NO WARRANTY%." + - it recognises the help text: | + expect (parser.helptext). + should_match ("^Usage: parseme .*Banner .*Long .*Options:.*" .. + "Footer .*/issues>%.") + - it diagnoses incorrect input text: + expect (OptionParser "garbage in").should_error "argument must match" + +- describe parser: + - before: | + f = os.tmpname () + + function parse (arglist) + local d = f:gsub ("/[^/]*$", "", 1) + local h = io.open (f, "w") + + h:write ([[ + package.path = "]] .. package.path .. [[" + local OptionParser = require 'std.optparse' + local help = [=[]] .. help .. [[]=] + help = help:match ("^[%s\n]*(.-)[%s\n]*$") + + local parser = OptionParser (help) + local arg, opts = parser:parse (_G.arg) + + o = {} + for k, v in pairs (opts) do + table.insert (o, k .. " = " .. tostring (v)) + end + if #o > 0 then + table.sort (o) + print ("opts = { " .. table.concat (o, ", ") .. " }") + end + if #arg > 0 then + print ("args = { " .. table.concat (arg, ", ") .. " }") + end + ]]) + h:close () + + return hell.spawn {arg[-1], f, unpack (arglist)} + end + - after: os.remove (f) + + - it leaves behind unrecognised options: + expect (parse {"--not-an-option"}). + should_output "args = { --not-an-option }\n" + - it responds to --version with version text: + expect (parse {"--version"}). + should_match_output "^%s*parseme .*Copyright .*NO WARRANTY%.\n$" + - it responds to --help with help text: | + expect (parse {"--help"}). + should_match_output ("^%s*Usage: parseme .*Banner.*Long.*" .. + "Options:.*Footer.*/issues>%.\n$") + - it recognises short options: + expect (parse {"-b"}).should_output "opts = { b = true }\n" + - it recognises long options: + expect (parse {"--long"}).should_output "opts = { long = true }\n" + - it recognises long options with hyphens: + expect (parse {"--another-long"}). + should_output "opts = { another_long = true }\n" + - it recognises long options named after Lua keywords: + expect (parse {"--true"}).should_output "opts = { true = true }\n" + - it recognises combined short and long option specs: + expect (parse {"-v"}).should_output "opts = { verbose = true }\n" + expect (parse {"--verbose"}).should_output "opts = { verbose = true }\n" + - it recognises options with several spellings: + expect (parse {"-n"}).should_output "opts = { dry_run = true }\n" + expect (parse {"--dry-run"}).should_output "opts = { dry_run = true }\n" + expect (parse {"--dryrun"}).should_output "opts = { dry_run = true }\n" + - it recognises end of options marker: + expect (parse {"-- -n"}).should_output "args = { -n }\n" + - context given an option with a required argument: + - it records an argument to a long option following an '=' delimiter: + expect (parse {"--name=Gary"}). + should_output "opts = { name = Gary }\n" + - it records an argument to a short option without a space: + expect (parse {"-uGary"}). + should_output "opts = { name = Gary }\n" + - it records an argument to a long option following a space: + expect (parse {"--name Gary"}). + should_output "opts = { name = Gary }\n" + - it records an argument to a short option following a space: + expect (parse {"-u Gary"}). + should_output "opts = { name = Gary }\n" + - it diagnoses a missing argument: + expect (parse {"--name"}). + should_contain_error "'--name' requires an argument" + expect (parse {"-u"}). + should_contain_error "'-u' requires an argument" + - context given an option with an optional argument: + - it records an argument to a long option following an '=' delimiter: + expect (parse {"--output=filename"}). + should_output "opts = { output = filename }\n" + - it records an argument to a short option without a space: + expect (parse {"-ofilename"}). + should_output "opts = { output = filename }\n" + - it records an argument to a long option following a space: + expect (parse {"--output filename"}). + should_output "opts = { output = filename }\n" + - it records an argument to a short option following a space: + expect (parse {"-o filename"}). + should_output "opts = { output = filename }\n" + - it doesn't consume the following option: + expect (parse {"--output -v"}). + should_output "opts = { output = true, verbose = true }\n" + expect (parse {"-o -v"}). + should_output "opts = { output = true, verbose = true }\n" + - context when splitting combined short options: + - it separates non-argument options: + expect (parse {"-bn"}). + should_output "opts = { b = true, dry_run = true }\n" + expect (parse {"-vbn"}). + should_output "opts = { b = true, dry_run = true, verbose = true }\n" + - it stops separating at a required argument option: + expect (parse {"-vuname"}). + should_output "opts = { name = name, verbose = true }\n" + expect (parse {"-vuob"}). + shauld_output "opts = { name = ob, verbose = true }\n" + - it stops separating at an optional argument option: + expect (parse {"-vofilename"}). + should_output "opts = { output = filename, verbose = true }\n" + expect (parse {"-vobn"}). + should_output "opts = { output = bn, verbose = true }\n" + +- describe parser:on: + - before: | + f = os.tmpname () + + function parseargs (onargstr, arglist) + local d = f:gsub ("/[^/]*$", "", 1) + local h = io.open (f, "w") + + h:write ([[ + package.path = "]] .. package.path .. [[" + local OptionParser = require 'std.optparse' + local help = [=[]] .. help .. [[]=] + help = help:match ("^[%s\n]*(.-)[%s\n]*$") + + local parser = OptionParser (help) + + parser:on (]] .. onargstr .. [[) + + local arg, opts = parser:parse (_G.arg) + + o = {} + for k, v in pairs (opts) do + table.insert (o, k .. " = " .. tostring (v)) + end + if #o > 0 then + table.sort (o) + print ("opts = { " .. table.concat (o, ", ") .. " }") + end + if #arg > 0 then + print ("args = { " .. table.concat (arg, ", ") .. " }") + end + ]]) + h:close () + + return hell.spawn {arg[-1], f, unpack (arglist)} + end + - after: os.remove (f) + + - it recognises short options: + expect (parseargs ([["x"]], {"-x"})). + should_output "opts = { x = true }\n" + - it recognises long options: + expect (parseargs([["something"]], {"--something"})). + should_output "opts = { something = true }\n" + - it recognises long options with hyphens: + expect (parseargs([["some-thing"]], {"--some-thing"})). + should_output "opts = { some_thing = true }\n" + - it recognises long options named after Lua keywords: + expect (parseargs ([["if"]], {"--if"})). + should_output "opts = { if = true }\n" + - it recognises combined short and long option specs: + expect (parseargs ([[{"x", "if"}]], {"-x"})). + should_output "opts = { if = true }\n" + expect (parseargs ([[{"x", "if"}]], {"--if"})). + should_output "opts = { if = true }\n" + - it recognises options with several spellings: + expect (parseargs ([[{"x", "blah", "if"}]], {"-x"})). + should_output "opts = { if = true }\n" + expect (parseargs ([[{"x", "blah", "if"}]], {"--blah"})). + should_output "opts = { if = true }\n" + expect (parseargs ([[{"x", "blah", "if"}]], {"--if"})). + should_output "opts = { if = true }\n" + - it recognises end of options marker: + expect (parseargs ([["x"]], {"--", "-x"})). + should_output "args = { -x }\n" + - context given an option with a required argument: + - it records an argument to a short option without a space: + expect (parseargs ([["x", parser.required]], {"-y", "-xarg", "-b"})). + should_contain_output "opts = { b = true, x = arg }" + - it records an argument to a short option following a space: + expect (parseargs ([["x", parser.required]], {"-y", "-x", "arg", "-b"})). + should_contain_output "opts = { b = true, x = arg }\n" + - it records an argument to a long option following a space: + expect (parseargs ([["this", parser.required]], {"--this", "arg"})). + should_output "opts = { this = arg }\n" + - it records an argument to a long option following an '=' delimiter: + expect (parseargs ([["this", parser.required]], {"--this=arg"})). + should_output "opts = { this = arg }\n" + - it diagnoses a missing argument: + expect (parseargs ([[{"x", "this"}, parser.required]], {"-x"})). + should_contain_error "'-x' requires an argument" + expect (parseargs ([[{"x", "this"}, parser.required]], {"--this"})). + should_contain_error "'--this' requires an argument" + - context with a boolean handler function: + - it records a truthy argument: + for _, optarg in ipairs {"1", "TRUE", "true", "yes", "Yes", "y"} + do + expect (parseargs ([["x", parser.required, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = true }\n" + end + - it records a falsey argument: + for _, optarg in ipairs {"0", "FALSE", "false", "no", "No", "n"} + do + expect (parseargs ([["x", parser.required, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = false }\n" + end + - context with a file handler function: + - it records an existing file: + expect (parseargs ([["x", parser.required, parser.file]], + {"-x", "/dev/null"})). + should_output "opts = { x = /dev/null }\n" + - it diagnoses a missing file: | + expect (parseargs ([["x", parser.required, parser.file]], + {"-x", "/this/file/does/not/exist"})). + should_contain_error "error: /this/file/does/not/exist: " + - context with a custom handler function: + - it calls the handler: + expect (parseargs ([["x", parser.required, function (p,o,a) + return "custom" + end + ]], {"-x", "ignored"})). + should_output "opts = { x = custom }\n" + - it diagnoses a missing argument: + expect (parseargs ([["x", parser.required, function (p,o,a) + return "custom" + end + ]], {"-x"})). + should_contain_error "option '-x' requires an argument" + - context given an option with an optional argument: + - it records an argument to a short option without a space: + expect (parseargs ([["x", parser.optional]], {"-y", "-xarg", "-b"})). + should_contain_output "opts = { b = true, x = arg }" + - it records an argument to a short option following a space: + expect (parseargs ([["x", parser.optional]], {"-y", "-x", "arg", "-b"})). + should_contain_output "opts = { b = true, x = arg }\n" + - it records an argument to a long option following a space: + expect (parseargs ([["this", parser.optional]], {"--this", "arg"})). + should_output "opts = { this = arg }\n" + - it records an argument to a long option following an '=' delimiter: + expect (parseargs ([["this", parser.optional]], {"--this=arg"})). + should_output "opts = { this = arg }\n" + - it does't consume the following option: + expect (parseargs ([[{"x", "this"}, parser.optional]], {"-x", "-b"})). + should_output "opts = { b = true, this = true }\n" + expect (parseargs ([[{"x", "this"}, parser.optional]], {"--this", "-b"})). + should_output "opts = { b = true, this = true }\n" + - context with a boolean handler function: + - it records a truthy argument: + for _, optarg in ipairs {"1", "TRUE", "true", "yes", "Yes", "y"} + do + expect (parseargs ([["x", parser.optional, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = true }\n" + end + - it records a falsey argument: + for _, optarg in ipairs {"0", "FALSE", "false", "no", "No", "n"} + do + expect (parseargs ([["x", parser.optional, parser.boolean]], + {"-x", optarg})). + should_output "opts = { x = false }\n" + end + - it defaults to a truthy value: + expect (parseargs ([["x", parser.optional, parser.boolean]], + {"-x", "-b"})). + should_output "opts = { b = true, x = true }\n" + - context with a file handler function: + - it records an existing file: + expect (parseargs ([["x", parser.optional, parser.file]], + {"-x", "/dev/null"})). + should_output "opts = { x = /dev/null }\n" + - it diagnoses a missing file: | + expect (parseargs ([["x", parser.optional, parser.file]], + {"-x", "/this/file/does/not/exist"})). + should_contain_error "error: /this/file/does/not/exist: " + - context with a custom handler function: + - it calls the handler: + expect (parseargs ([["x", parser.optional, function (p,o,a) + return "custom" + end + ]], {"-x", "ignored"})). + should_output "opts = { x = custom }\n" + - it does not consume a following option: + expect (parseargs ([["x", parser.optional, function (p,o,a) + return a or "default" + end + ]], {"-x", "-b"})). + should_output "opts = { b = true, x = default }\n" + - context when splitting combined short options: + - it separates non-argument options: + expect (parseargs ([["x"]], {"-xb"})). + should_output "opts = { b = true, x = true }\n" + expect (parseargs ([["x"]], {"-vxb"})). + should_output "opts = { b = true, verbose = true, x = true }\n" + - it stops separating at a required argument option: + expect (parseargs ([[{"x", "this"}, parser.required]], {"-bxbit"})). + should_output "opts = { b = true, this = bit }\n" + - it stops separating at an optional argument option: + expect (parseargs ([[{"x", "this"}, parser.optional]], {"-bxbit"})). + should_output "opts = { b = true, this = bit }\n" diff --git a/specs/package_spec.yaml b/specs/package_spec.yaml index c7b4bbd..bf561d2 100644 --- a/specs/package_spec.yaml +++ b/specs/package_spec.yaml @@ -1,63 +1,38 @@ -specify package: -- before: | - M = require "std.package" +before: | + require "spec_helper" - extends = package - extensions = { "dirsep", "pathsep", "path_mark", "execdir", "igmark" } - enhancements = {} + this_module = "std.package" - -- Do not try to check all the entries in unextended package, - -- because they naturally change as modules are loaded. - coreapis = { "config", "cpath", "loaders", "loadlib", "preload", - "searchers", "searchpath", "seeall" } + global_table = "_G" + base_module = "package" + extend_base = { "dirsep", "pathsep", "path_mark", + "execdir", "igmark" } -- context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end + M = require (this_module) +specify std.package: +- context when required: - context by name: - - before: - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - for _, api in ipairs (enhancements) do - extends[api], extends["_" .. api] = M[api], M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = M[api] end - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for _, api in ipairs (coreapis) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core package table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (extend_base) + - it replaces no apis from the core package table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_equal {} - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for _, api in ipairs (coreapis) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the core package table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it replaces no apis from the core package table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_equal {} + -- "it splits package.config up": +- it splits package.config up: expect (string.format ("%s\n%s\n%s\n%s\n%s\n", M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark) ).should_contain (package.config) diff --git a/specs/set_spec.yaml b/specs/set_spec.yaml index 4e7f931..9f96e3a 100644 --- a/specs/set_spec.yaml +++ b/specs/set_spec.yaml @@ -5,7 +5,13 @@ before: totable = (require "std.table").totable s = Set {"foo", "bar", "bar"} -specify Set: +specify std.set: +- describe require: + - it does not perturb the global namespace: + expect (show_apis {added_to="_G", by="std.set"}). + should_equal {} + + - describe construction: - it constructs a new set: s = Set {} diff --git a/specs/spec_helper.lua b/specs/spec_helper.lua deleted file mode 100644 index 2480cc1..0000000 --- a/specs/spec_helper.lua +++ /dev/null @@ -1,29 +0,0 @@ --- Not local, so that it is available in spec examples. -totable = (require "std.table").totable - - --- Custom matcher for set membership. - -local set = require "std.set" -local util = require "specl.util" -local matchers = require "specl.matchers" - -local Matcher, matchers, q = - matchers.Matcher, matchers.matchers, matchers.stringify - -matchers.have_member = Matcher { - function (actual, expect) - return set.member (actual, expect) - end, - - actual = "set", - - format_expect = function (expect) - return " a set containing " .. q (expect) .. ", " - end, - - format_any_of = function (alternatives) - return " a set containing any of " .. - util.concat (alternatives, util.QUOTED) .. ", " - end, -} diff --git a/specs/spec_helper.lua.in b/specs/spec_helper.lua.in new file mode 100644 index 0000000..75b4232 --- /dev/null +++ b/specs/spec_helper.lua.in @@ -0,0 +1,145 @@ +local hell = require "specl.shell" + +-- Substitute configured LUA so that hell.spawn doesn't pick up +-- a different Lua binary to the one used by Specl itself. If +-- we could rely on luaposix availability `posix.getenv` would +-- be a nicer way to find this... +local LUA = "@LUA@" + +local function mkscript (code) + local f = os.tmpname () + local h = io.open (f, "w") + h:write (code) + h:close () + return f +end + +local function tabulate_output (code) + local f = mkscript (code) + local proc = hell.spawn { + LUA, f; + env = { LUA_PATH=package.path, LUA_INIT="", LUA_INIT_5_2="" }, + } + os.remove (f) + if proc.status ~= 0 then return error (proc.errout) end + local r = {} + proc.output:gsub ("(%S*)[%s]*", + function (x) + if x ~= "" then r[x] = true end + end) + return r +end + + +--- Show changes to tables wrought by a require statement. +-- There are a few modes to this function, controlled by what named +-- arguments are given. Lists new keys in T1 after `require "import"`: +-- +-- show_apis {added_to=T1, by=import} +-- +-- List keys returned from `require "import"`, which have the same +-- value in T1: +-- +-- show_apis {from=T1, used_by=import} +-- +-- List keys from `require "import"`, which are also in T1 but with +-- a different value: +-- +-- show_apis {from=T1, enhanced_by=import} +-- +-- List keys from T2, which are also in T1 but with a different value: +-- +-- show_apis {from=T1, enhanced_in=T2} +-- +-- @tparam table argt one of the combinations above +-- @treturn table a list of keys according to criteria above +function show_apis (argt) + local added_to, from, not_in, enhanced_in, enhanced_after, by = + argt.added_to, argt.from, argt.not_in, argt.enhanced_in, + argt.enhanced_after, argt.by + + if added_to and by then + return tabulate_output ([[ + local before, after = {}, {} + for k in pairs (]] .. added_to .. [[) do + before[k] = true + end + + local M = require "]] .. by .. [[" + for k in pairs (]] .. added_to .. [[) do + after[k] = true + end + + for k in pairs (after) do + if not before[k] then print (k) end + end + ]]) + + elseif from and not_in then + return tabulate_output ([[ + local from = ]] .. from .. [[ + local M = require "]] .. not_in .. [[" + + for k in pairs (M) do + if from[k] ~= M[k] then print (k) end + end + ]]) + + elseif from and enhanced_in then + return tabulate_output ([[ + local from = ]] .. from .. [[ + local M = require "]] .. enhanced_in .. [[" + + for k, v in pairs (M) do + if from[k] ~= M[k] and from[k] ~= nil then print (k) end + end + ]]) + + elseif from and enhanced_after then + return tabulate_output ([[ + local before, after = {}, {} + local from = ]] .. from .. [[ + + for k, v in pairs (from) do before[k] = v end + ]] .. enhanced_after .. [[ + for k, v in pairs (from) do after[k] = v end + + for k, v in pairs (before) do + if after[k] ~= nil and after[k] ~= v then print (k) end + end + ]]) + end + + assert (false, "missing argument to show_apis") +end + + +-- Not local, so that it is available in spec examples. +totable = (require "std.table").totable + + +-- Custom matcher for set membership. + +local set = require "std.set" +local util = require "specl.util" +local matchers = require "specl.matchers" + +local Matcher, matchers, q = + matchers.Matcher, matchers.matchers, matchers.stringify + +matchers.have_member = Matcher { + function (actual, expect) + return set.member (actual, expect) + end, + + actual = "set", + + format_expect = function (expect) + return " a set containing " .. q (expect) .. ", " + end, + + format_any_of = function (alternatives) + return " a set containing any of " .. + util.concat (alternatives, util.QUOTED) .. ", " + end, +} diff --git a/specs/specs.mk b/specs/specs.mk index 99ae87a..45c1fcc 100644 --- a/specs/specs.mk +++ b/specs/specs.mk @@ -5,31 +5,41 @@ ## Environment. ## ## ------------ ## -SPECL_ENV = $(LUA_ENV) +specs_path = $(abs_builddir)/specs/?.lua +SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" ## ------ ## ## Specs. ## ## ------ ## +SPECL_OPTS = --unicode + +## For compatibility with Specl < 11, std_spec.yaml has to be +## last, so that when `require "std"` leaks symbols into the +## Specl global environment, subsequent example blocks are not +## affected. + specl_SPECS = \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ - $(srcdir)/specs/getopt_spec.yaml \ + $(srcdir)/specs/functional_spec.yaml \ $(srcdir)/specs/io_spec.yaml \ $(srcdir)/specs/list_spec.yaml \ $(srcdir)/specs/math_spec.yaml \ $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/optparse_spec.yaml \ $(srcdir)/specs/package_spec.yaml \ $(srcdir)/specs/set_spec.yaml \ $(srcdir)/specs/strbuf_spec.yaml \ $(srcdir)/specs/string_spec.yaml \ $(srcdir)/specs/table_spec.yaml \ $(srcdir)/specs/tree_spec.yaml \ + $(srcdir)/specs/std_spec.yaml \ $(NOTHING_ELSE) EXTRA_DIST += \ - $(srcdir)/specs/spec_helper.lua \ + $(srcdir)/specs/spec_helper.lua.in \ $(NOTHING_ELSE) include build-aux/specl.mk diff --git a/specs/std_spec.yaml b/specs/std_spec.yaml new file mode 100644 index 0000000..f8f758c --- /dev/null +++ b/specs/std_spec.yaml @@ -0,0 +1,12 @@ +specify std: +- describe lazy loading: + - before: + std = require "std" + - it has no submodules on initial load: + expect (std).should_equal {version = std.version} + - it loads submodules on demand: + lazy = std.set + expect (lazy).should_be (require "std.set") + - it loads submodule functions on demand: + expect (std.object.prototype (std.set {"Lazy"})). + should_be "Set" diff --git a/specs/strbuf_spec.yaml b/specs/strbuf_spec.yaml index 11bdc9a..6851dcd 100644 --- a/specs/strbuf_spec.yaml +++ b/specs/strbuf_spec.yaml @@ -1,9 +1,16 @@ before: + require "spec_helper" object = require "std.object" StrBuf = require "std.strbuf" b = StrBuf {"foo", "bar"} -specify StrBuf: +specify std.strbuf: +- describe require: + - it does not perturb the global namespace: + expect (show_apis {added_to="_G", by="std.strbuf"}). + should_equal {} + + - describe construction: - context from StrBuf clone method: - it constructs a new strbuf: diff --git a/specs/string_spec.yaml b/specs/string_spec.yaml index d4de247..e141a41 100644 --- a/specs/string_spec.yaml +++ b/specs/string_spec.yaml @@ -1,70 +1,73 @@ -specify string: -- before: | - M = require "std.string" - - extends = string - enhancements = { "assert", "format", "tostring" } - extensions = { "caps", "chomp", "escape_pattern", "escape_shell", - "finds", "ltrim", "numbertosi", "ordinal_suffix", - "pad", "pickle", "prettytostring", "render", - "require_version", "rtrim", "split", "tfind", - "trim", "wrap", - -- make these available after require "std" - "__index", "_format", "_tostring", - -- camelCase compatibility: - "escapePattern", "escapeShell", "ordinalSuffix" } - +before: | + require "spec_helper" + + this_module = "std.string" + + global_table = "_G" + std_globals = { "pickle", "prettytostring", "render", + "require_version" } + enhance_globals = { "assert", "tostring" } + + base_module = "string" + extend_base = { "assert", "caps", "chomp", "escape_pattern", + "escape_shell", "finds", "ltrim", "numbertosi", + "ordinal_suffix", "pad", "pickle", + "prettytostring", "render", "require_version", + "rtrim", "split", "tfind", "tostring", "trim", + "wrap", + -- make these available after require "std" + "__index", "_format", "_tostring", + -- camelCase compatibility: + "escapePattern", "escapeShell", + "ordinalSuffix" } + enhance_base = { "format" } + extend_metamethods = { "__append", "__concat" } + enhance_metamethods = { "__index" } + + -- 'should_contain' will match keys as well as values :) + all_apis = {} + for _, s in ipairs (std_globals) do all_apis[s] = true end + for _, s in ipairs (enhance_globals) do all_apis[s] = true end + for _, s in ipairs (extend_base) do all_apis[s] = true end + for _, s in ipairs (enhance_base) do all_apis[s] = true end + + M = require "std.string" + +specify std.string: +- before: subject = "a string \n\n" - - context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end - - context by name: - - before: | - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - for _, api in ipairs (enhancements) do - extends[api], extends["_" .. api] = M[api], M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = M[api] end - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core string table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (all_apis) + - it enhances some apis from the core string table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_contain.a_permutation_of (enhance_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end - - -- "describe ..": + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + - it adds apis to the core string table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it adds methods to the string metatable: + expect (show_apis {added_to="getmetatable ('')", by="std"}). + should_contain.a_permutation_of (extend_metamethods) + - it replaces some entries in the string metatable: + expect (show_apis {from="getmetatable ('')", enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_metamethods) + - it replaces some apis in the core string table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_base) + + +- describe ..: - it concatenates string arguments: target = "a string \n\n another string" expect (subject .. " another string").should_be (target) diff --git a/specs/table_spec.yaml b/specs/table_spec.yaml index 2620d5c..d33cbf9 100644 --- a/specs/table_spec.yaml +++ b/specs/table_spec.yaml @@ -1,62 +1,58 @@ -specify table: -- before: | - M = require "std.table" - - extends = table - enhancements = { "sort" } - extensions = { "clone", "clone_rename", "empty", "invert", "keys", - "merge", "new", "pack", "ripairs", "size", "totable", - "values" } - +before: | + require "spec_helper" + + base_module = "table" + this_module = "std.table" + global_table = "_G" + + std_globals = { "pack", "ripairs", "totable" } + extend_base = { "clone", "clone_rename", "empty", + "invert", "keys", "merge", "new", + "ripairs", "size", "totable", "values", + -- make these available after require "std" + "_sort" } + enhance_base = { "sort" } + + + -- 'should_contain' will match keys as well as values :) + all_apis = {} + for _, s in ipairs (std_globals) do all_apis[s] = true end + for _, s in ipairs (extend_base) do all_apis[s] = true end + for _, s in ipairs (enhance_base) do all_apis[s] = true end + + if table.pack then + -- Lua 5.2 + table.insert (enhance_base, "pack") + else + -- Lua 5.1 + table.insert (extend_base, "pack") + end + + M = require "std.table" + +specify std.table: - context when required: - - before: - enhanced = {} - for _, api in ipairs (enhancements) do enhanced[api] = true end - - context by name: - - before: | - function restore (g, m) - for _, api in ipairs (enhancements) do - g[api], g["_" .. api] = m[api], m["_" .. api] - end - for _, api in ipairs (extensions) do g[api] = m[api] end - end - - for _, api in ipairs (enhancements) do - extends[api] = M["_" .. api] - end - for _, api in ipairs (extensions) do extends[api] = nil end - - after: - restore (extends, M) - - it does not perturb the global table: - for _, api in ipairs (extensions) do - expect (extends[api]).should_be (nil) - end - for _, api in ipairs (enhancements) do - expect (extends[api]).should_be (M["_" .. api]) - end - - it contains all global access points: - for api in pairs (extends) do - if enhanced[api] then - expect (M[api]).should_not_be (extends[api]) - else - expect (M[api]).should_be (extends[api]) - end - end + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + - it contains apis from the core table table: + expect (show_apis {from=base_module, not_in=this_module}). + should_contain.a_permutation_of (all_apis) + - it enhances some apis from the core table table: + expect (show_apis {from=base_module, enhanced_in=this_module}). + should_contain.a_permutation_of (enhance_base) - context via the std module: - - before: - require "std" - - it adds extension apis to the global table: - for api in pairs (M) do - expect (extends[api]).should_be (M[api]) - end - - it does not add any other global access points: - for api in pairs (extends) do - if not enhanced[api] then - expect (M[api]).should_be (extends[api]) - end - end + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) + - it adds apis to the core table table: + expect (show_apis {added_to=base_module, by="std"}). + should_contain.a_permutation_of (extend_base) + - it replaces some apis in the core table table: + expect (show_apis {from=base_module, enhanced_after='require "std"'}). + should_contain.a_permutation_of (enhance_base) - describe clone: diff --git a/specs/tree_spec.yaml b/specs/tree_spec.yaml index c0520da..d9ec245 100644 --- a/specs/tree_spec.yaml +++ b/specs/tree_spec.yaml @@ -1,11 +1,30 @@ -before: - Tree = require "std.tree" - prototype = (require "std.object").prototype - totable = (require "std.table").totable - t = {foo="foo", fnord={branch={bar="bar", baz="baz"}}, quux="quux"} - tr = Tree (t) +before: | + require "spec_helper" + + global_table = "_G" + this_module = "std.tree" + std_globals = { "ileaves", "inodes", "leaves", "nodes" } + + Tree = require "std.tree" + +specify std.tree: +- before: + prototype = (require "std.object").prototype + totable = (require "std.table").totable + t = {foo="foo", fnord={branch={bar="bar", baz="baz"}}, quux="quux"} + tr = Tree (t) + +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + should_equal {} + + - context via the std module: + - it adds apis to the global table: + expect (show_apis {added_to=global_table, by="std"}). + should_contain.all_of (std_globals) -specify tree: - describe construction: - it constructs a new tree: tr = Tree {} diff --git a/stdlib-36-1.rockspec b/stdlib-37-1.rockspec similarity index 78% rename from stdlib-36-1.rockspec rename to stdlib-37-1.rockspec index 7e9574e..3f12722 100644 --- a/stdlib-36-1.rockspec +++ b/stdlib-37-1.rockspec @@ -1,14 +1,14 @@ package = "stdlib" -version = "36-1" +version = "37-1" description = { - detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt.", + detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://rrthomas.github.io/lua-stdlib", license = "MIT/X11", summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v36", - url = "http://github.com/rrthomas/lua-stdlib/archive/release-v36.zip", + dir = "lua-stdlib-release-v37", + url = "http://github.com/rrthomas/lua-stdlib/archive/release-v37.zip", } dependencies = { "lua >= 5.1", @@ -20,14 +20,14 @@ build = { ["std.base"] = "lib/std/base.lua", ["std.container"] = "lib/std/container.lua", ["std.debug"] = "lib/std/debug.lua", - ["std.debug_init"] = "lib/std/debug_init.lua", + ["std.debug_init"] = "lib/std/debug_init/init.lua", ["std.functional"] = "lib/std/functional.lua", - ["std.getopt"] = "lib/std/getopt.lua", ["std.io"] = "lib/std/io.lua", ["std.list"] = "lib/std/list.lua", ["std.math"] = "lib/std/math.lua", ["std.modules"] = "lib/std/modules.lua", ["std.object"] = "lib/std/object.lua", + ["std.optparse"] = "lib/std/optparse.lua", ["std.package"] = "lib/std/package.lua", ["std.set"] = "lib/std/set.lua", ["std.strbuf"] = "lib/std/strbuf.lua", diff --git a/travis.yml.in b/travis.yml.in index 1d4be12..602e072 100644 --- a/travis.yml.in +++ b/travis.yml.in @@ -29,12 +29,11 @@ install: # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz - - cd $LUAROCKS_BASE - - ./configure - --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX - --with-lua-include=$LUA_INCDIR - - make all install - - cd .. + - ( cd $LUAROCKS_BASE; + ./configure + --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX + --with-lua-include=$LUA_INCDIR; + make all install; ) # Configure and build. script: @@ -54,7 +53,7 @@ script: # Install extra rocks into $LUAROCKS_CONFIG rocks tree. @EXTRA_ROCKS@ - # Make git rockspec for this package. + # Make git rockspec for this @PACKAGE@ - make rockspecs LUAROCKS="$LUAROCKS" V=1 || { $LUAROCKS path; cat $ROCKSPEC; } @@ -63,11 +62,7 @@ script: - $LUAROCKS make $ROCKSPEC LUA="$LUA" # Run self-tests in the `luarocks make` build tree. - # Use bin/specl if present, or else the specl rock from EXTRA_ROCKS - # above. - - if test -f luarocks/bin/specl; then export SPECL=luarocks/bin/specl; - elif test -f bin/specl; then export SPECL=bin/specl; fi - - export LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" - - export LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" - - export LUA_INIT=; export LUA_INIT_5_2= - - make check SPECL="$SPECL" V=1 + - LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" + LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" + LUA_INIT= LUA_INIT_5_2= + make check V=1 From 3d81b80c89397bb5de08d86091d8bf3680b72ef0 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 30 Jan 2014 21:11:57 +1300 Subject: [PATCH 23/34] Release v38. Signed-off-by: Gary V. Vaughan --- .travis.yml | 5 +- ChangeLog | 143 +++++ Makefile.in | 2 +- NEWS | 78 +++ bootstrap.conf | 4 +- configure | 27 +- configure.ac | 5 +- doc/classes/std.container.html | 28 +- doc/classes/std.list.html | 32 +- doc/classes/std.object.html | 82 ++- doc/classes/std.optparse.html | 642 +++++++++++-------- doc/classes/std.set.html | 36 +- doc/classes/std.strbuf.html | 12 +- doc/classes/std.tree.html | 36 +- doc/index.html | 4 +- doc/modules/std.debug.html | 4 +- doc/modules/std.functional.html | 4 +- doc/modules/std.html | 6 +- doc/modules/std.io.html | 33 +- doc/modules/std.math.html | 4 +- doc/modules/std.package.html | 4 +- doc/modules/std.strict.html | 4 +- doc/modules/std.string.html | 21 +- doc/modules/std.table.html | 42 +- lib/std.lua | 2 +- lib/std/container.lua | 209 +++--- lib/std/io.lua | 48 +- lib/std/object.lua | 40 +- lib/std/optparse.lua | 198 +++++- lib/std/string.lua | 26 +- local.mk | 2 +- specs/io_spec.yaml | 99 +++ specs/optparse_spec.yaml | 59 +- specs/spec_helper.lua.in | 99 ++- specs/string_spec.yaml | 25 +- specs/tree_spec.yaml | 80 +-- stdlib-37-1.rockspec => stdlib-38-1.rockspec | 6 +- 37 files changed, 1518 insertions(+), 633 deletions(-) rename stdlib-37-1.rockspec => stdlib-38-1.rockspec (95%) diff --git a/.travis.yml b/.travis.yml index cead315..4a5973e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,6 @@ env: - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - LUAROCKS_BASE=luarocks-2.1.1 - LUAROCKS="$LUA $HOME/bin/luarocks" - - LDOC_ROCKSPEC=http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec matrix: - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 LUA_SUFFIX=5.2 @@ -52,9 +51,7 @@ script: - export PATH=`pwd`/luarocks/bin:$PATH # Install extra rocks into $LUAROCKS_CONFIG rocks tree. - - $LUAROCKS install lyaml; $LUAROCKS install specl; - # LDoc 1.4.0 is not in luarocks yet, and LDoc master has no rockspec :( - - $LUAROCKS install $LDOC_ROCKSPEC + - $LUAROCKS install lyaml; $LUAROCKS install ldoc; $LUAROCKS install specl; # Make git rockspec for this stdlib - make rockspecs LUAROCKS="$LUAROCKS" V=1 diff --git a/ChangeLog b/ChangeLog index 373b2b0..09c2075 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,148 @@ +2014-01-30 Gary V. Vaughan + + Release version 38 + * NEWS: Record release date. + + specs: commit new have_size matcher. + * specs/spec_helper.lua.in (matchers.have_size): New matcher + used by std.string.split specs. + * configure.ac (AC_CONFIG_FILES): Remove write permission from + generated spec_helper so I don't edit the wrong file next time. + + specs: remove trailing whitespace. + * specs/optparse_spec.yaml: Remove trailing whitespace. + + NEWS: reword a doubled 'to' to satisfy sanity checks. + * NEWS: Reword a doubled 'to'. + + string: split now splits on consecutive whitespace by default. + * lib/std/string.lua (split): Improve LDocs. + Remove @todo. We now have whitespace default split pattern unless + otherwise specified, just like Python. I didn't consider Perl, + because my brain starts to haemorrhage whenever I do that. :-p + * specs/string_spec.yaml (split): Remove spec for string `sep` + argument now that it is optional. + * NEWS: Update. + + string: simplify and speed up `std.string.split`. + * lib/std/string.lua (split): It's a bit more code, but it is + much easier to understand, and it's a lot faster now! + * specs/string_spec.yaml (split): Uncomment pending infinite loop + fix. + * NEWS: Update. + + specs: more comprehensive specs for std.string.split. + * specs/string_spec.yaml (split): Add a lot more specs. + Empty separator causes an infinite loop with the current + implementation. + +2014-01-28 Gary V. Vaughan + + specs: use Specl 10 `a_permutation_of` adaptor for tighter specs. + * specs/tree_spec.yaml: Use `a_permutation_of` instead of + `all_of` to enforce some reordering of only the specified + elements. + + specs: use a custom matcher to specify process status and error. + * specs/spec_helper.lua.in (matchers.fail_with): Custom matcher + to specify process non-zero exit as well as stderr content. + * specs/io_spec.yaml (io.die), specs/optparse_spec.yaml (io.die): + Use it to ensure that in addition to the correct error output, + the exit status is non-zero. + + optparse: integrate with `io.die` and `io.warn`. + * specs/io_spec.yaml: Additional specs for what to do when + `opts.program` and/or `opts.line` are set. + * specs/optparse_spec.yaml (io.die, io.warn): New specs how to + behave when `io.die` or `io.warn` are called after a successful + `parser:parse` call. + * lib/std/io.lua (warn): Implement specified behaviour for new + `opts.line` and `opts.warn` specs. + * lib/std/optparse.lua: Add LDocs for new behaviour. + (parser:parse): Set a metatable on the returned opts table so + than `opts.program` etc. can be found by `io.die` and `io.warn`. + * NEWS: Update. + + io: fix actual and latent bugs in `io.die` and `io.warn`. + * specs/spec_helper.lua.in (luaproc): Factor out of + `tabulate_output`. + (tabulate_output): Adjust. + * specs/io_spec.lua (die, warn): Add new behaviour examples. + * lib/std/io.lua (warn): Adjust to work properly with new specs. + * NEWS: Update. + +2014-01-24 Gary V. Vaughan + + container: inline calls to `empty`. + * lib/std/container (mapfields, metatable._init): Replace + `not empty` with `next`. + (empty): Remove. + + container: drastically simplify and speed up `prototype`. + * lib/std/container.lua (prototype): Inline metaentry, and + simplify. + (metatable.__tostring): Use it. + (metaentry): Remove. + * NEWS: Update. + + container: inline `filter` to only caller. + * lib/std/container.lua (filter): Remove from here. + (metatable.__totable): Inline `filter` here. + + container: cleanup, speedup and bonus bugfix. + * lib/std/container.lua (mapfields): Factored out of + `metatable.__call` and optimised for speed. + (metatable.__call): Adjust accordingly. + (empty): Copied from table.empty to avoind introducing a require + loop. + (modulefunction): Wrap argument in a functable for easily + recognising what not to copy during cloning. + (metatable): Simplify. + * lib/std/object.lua: Import mapfields from Containec, but unwrap + it along with Container.prototype before saving in the Object + metatable for faster access. + Add appropriate LDocs. + * NEWS: Update. + +2014-01-23 Gary V. Vaughan + + container: distinguish between the two `functions` tables. + One is the core of Container with metatable as its metatable; the + other is metatable._functions, and is just a list of unpropagated + method functions. We don't want to give the latter a __tostring + metamethod or printing gets very weird. + * lib/std/container.lua (metatable._functions): Make a nometa + clone of the table we return. + * NEWS: Update. + +2014-01-22 Gary V. Vaughan + + configury: update rockspecs in buildreq. + * bootstrap.conf (buildreq): LDoc is now available in the required + version from the official luarocks repo. + + travis: remove unrelease ldoc workarounds. + * .travis.yml: Regenerate, to delete local patches for LDoc. + +2014-01-21 Gary V. Vaughan + + doc: vastly improve optparse LDocs. + * lib/std/optparse.lua: Vastly improve optparse LDocs. + * NEWS: Update. + +2014-01-21 Reuben Thomas + + optparse.lua: move "default" options to bottom of help + A more standard position. + 2014-01-19 Gary V. Vaughan + maint: post-release administrivia. + * configure: Bump revision to 38. + * NEWS: Add header line for next release. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + Release version 37 * NEWS: Record release date. diff --git a/Makefile.in b/Makefile.in index cb0cc59..7db3b67 100644 --- a/Makefile.in +++ b/Makefile.in @@ -390,7 +390,7 @@ man_MANS = save_release_files = $(scm_rockspec) std_path = $(abs_srcdir)/lib/?.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = 7a7647cb5b2d5d886a18070e1f4ac5fd +old_NEWS_hash = 1a28799a850e021e45c3e98064a746d7 update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ UPDATE_COPYRIGHT_USE_INTERVALS=1 \ diff --git a/NEWS b/NEWS index 639ce82..369d8d2 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,83 @@ Stdlib NEWS - User visible changes +* Noteworthy changes in release 38 (2014-01-30) [stable] + +** New features: + + - The separator parameter to `std.string.split` is now optional. It + now splits strings with `%s+` when no separator is specified. The + new implementation is faster too. + + - New `std.object.mapfields` method factors out the table field copying + and mapping performed when cloning a table `_init` style object. This + means you can call it from a function `_init` style object after + collecting a table to serve as `src` to support derived objects with + normal std.object syntax: + + Proto = Object { + _type = "proto" + _init = function (self, arg, ...) + if type (arg) == "table" then + mapfields (self, arg) + else + -- non-table instantiation code + end + end, + } + new = Proto (str, #str) + Derived = proto { _type = "Derived", ... } + + - Much faster object cloning; `mapfields` is in imperative style and + makes one pass over each table it looks at, where previous releases + used functional style (stack frame overhead) and multiple passes over + input tables. + + On my 2013 Macbook Air with 1.3GHz Core i5 CPU, I can now create a + million std.objects with several assorted fields in 3.2s. Prior to + this release, the same process took 8.15s... and even release 34.1, + with drastically simpler Objects (19SLOC vs over 120) took 5.45s. + + - `std.object.prototype` is now almost an order of magnitude faster + than previous releases, taking about 20% of the time it previously + used to return its results. + + - `io.warn` and `io.die` now integrate properly with `std.optparse`, + provided you save the `opts` return from `parser:parse` back to the + global namespace where they can access it: + + local OptionParser = require "std.optparse" + local parser = OptionParser "eg 0\nUsage: eg\n" + _G.arg, _G.opts = parser:parse (_G.arg) + if not _G.opts.keep_going then + require "std.io".warn "oh noes!" + end + + will, when run, output to stderr: "eg: oh noes!" + +** Bug fixes: + + - Much improved documentation for `optparse`, so you should be able + to use it without reading the source code now! + + - `io.warn` and `io.die` no longer output a line-number when there is + no file name to append it to. + + - `io.warn` and `io.die` no longer crash in the absence of a global + `prog` table. + + - `string.split` no longer goes into an infinite loop when given an + empty separator string. + + - Fix `getmetatable (container._functions) == getmetatable (container)`, + which made tostring on containers misbehave, among other latent bugs. + + - `_functions` is never copied into a metatable now, finally solving + the conflicted concerns of needing metatables to be shared between + all objects of the same `_type` (for `__lt` to work correctly for one + thing) and not leaving a dangling `_functions` list in the metatable + of cloned objects, which could delete functions with matching names + from subsequent clones. + * Noteworthy changes in release 37 (2014-01-19) [stable] ** New features: diff --git a/bootstrap.conf b/bootstrap.conf index d9b0e91..90eff27 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -33,8 +33,8 @@ # Build prerequisites buildreq=' git 1.5.5 http://git-scm.com - ldoc =next-1 http://raw.github.com/gvvaughan/LDoc/next/ldoc-next-1.rockspec - specl 8 http://luarocks.org/repositories/rocks/specl-9-1.rockspec + ldoc 1.4.0 http://luarocks.org/repositories/rocks/ldoc-1.4.2-1.rockspec + specl 8 http://luarocks.org/repositories/rocks/specl-10-1.rockspec ' # List of slingshot files to link into stdlib tree before autotooling. diff --git a/configure b/configure index 9a9ca0e..5b46e4e 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 37. +# Generated by GNU Autoconf 2.69 for stdlib 38. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='37' -PACKAGE_STRING='stdlib 37' +PACKAGE_VERSION='38' +PACKAGE_STRING='stdlib 38' PACKAGE_BUGREPORT='http://github.com/rrthomas/lua-stdlib/issues' PACKAGE_URL='' @@ -1217,7 +1217,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 37 to adapt to many kinds of systems. +\`configure' configures stdlib 38 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1283,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 37:";; + short | recursive ) echo "Configuration of stdlib 38:";; esac cat <<\_ACEOF @@ -1363,7 +1363,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 37 +stdlib configure 38 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1380,7 +1380,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 37, which was +It was created by stdlib $as_me 38, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1760,7 +1760,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. $as_echo "## --------------------- ## -## Configuring stdlib 37 ## +## Configuring stdlib 38 ## ## --------------------- ##" echo @@ -2250,7 +2250,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='37' + VERSION='38' cat >>confdefs.h <<_ACEOF @@ -3086,7 +3086,9 @@ $as_echo "$ac_cv_path_SED" >&6; } ac_config_files="$ac_config_files .travis.yml:travis.yml.in" -ac_config_files="$ac_config_files Makefile build-aux/config.ld specs/spec_helper.lua" +ac_config_files="$ac_config_files Makefile build-aux/config.ld" + +ac_config_files="$ac_config_files specs/spec_helper.lua" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -3639,7 +3641,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 37, which was +This file was extended by stdlib $as_me 38, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3692,7 +3694,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 37 +stdlib config.status 38 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -4238,6 +4240,7 @@ which seems to be undefined. Please make sure it is defined" >&2;} ".travis.yml":F) # Remove trailing blanks so as not to trip sc_trailing_blank in syntax check sed 's| *$||' < .travis.yml > ss_tmp && mv ss_tmp .travis.yml; rm -f ss_tmp ;; + "specs/spec_helper.lua":F) chmod a-w specs/spec_helper.lua ;; esac done # for ac_tag diff --git a/configure.ac b/configure.ac index c0b6bf8..63c8860 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [37], [http://github.com/rrthomas/lua-stdlib/issues]) +AC_INIT([stdlib], [38], [http://github.com/rrthomas/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) @@ -37,5 +37,6 @@ AC_PROG_SED dnl Generate output files SS_CONFIG_TRAVIS([ldoc specl]) -AC_CONFIG_FILES([Makefile build-aux/config.ld specs/spec_helper.lua]) +AC_CONFIG_FILES([Makefile build-aux/config.ld]) +AC_CONFIG_FILES([specs/spec_helper.lua], [chmod a-w specs/spec_helper.lua]) AC_OUTPUT diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 07d98db..613f274 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -80,9 +80,9 @@

    Class std.container

    std.object module functions, or anywhere else a std.object is expected.

    -

    Container derived objects returned directly from a require statement +

    Container derived objects returned directly from a require statement may also provide module functions, which can be called only from the - initial prototype object returned by require , but are not passed + initial prototype object returned by require , but are not passed on to derived objects during cloning:

      > Container = require "std.container"
    @@ -132,7 +132,7 @@ 

    Tables

    Metamethods

    - + @@ -162,17 +162,17 @@

    Tables

    Fields:

    • _init - table or function + table or function a table of field names, or initialisation function, used by __call
    • _functions - nil or table + nil or table a table of module functions not copied by std.object.__call
    • _type - string + string type of Container, returned by std.object.prototype (default "Container") @@ -189,7 +189,7 @@

      Metamethods

      - std.container:__call (...) + std.container:__call (x, ...)
      Return a clone of this container. @@ -197,8 +197,12 @@

      Metamethods

      Parameters:

        +
      • x + a table if prototype _init is a table, otherwise first + argument for a function type _init +
      • ... - arguments for _init + any additional arguments for _init
      @@ -229,7 +233,7 @@

      See also:

      Returns:

        - string + string stringified container representation
      @@ -253,7 +257,7 @@

      See also:

      Returns:

        - table + table a shallow copy of non-private container fields
      @@ -271,7 +275,7 @@

      See also:

      -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
      diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 47a0644..5422e25 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -352,7 +352,7 @@

      Parameters:

      a list
    • m - table + table another list
    @@ -440,7 +440,7 @@

    Returns:

    Parameters:

    • ls - table + table list of lists {{i1, v1}, ..., {in, vn}}
    @@ -448,7 +448,7 @@

    Parameters:

    Returns:

      - table + table a new list containing table {i1=v1, ..., in=vn}
    @@ -504,7 +504,7 @@

    Returns:

    Parameters:

    @@ -935,7 +935,7 @@

    Returns:

    Parameters:

    • s - table + table {d1, ..., dn}
    • l @@ -964,7 +964,7 @@

      See also:

      Return a sub-range of a list. - (The equivalent of string.sub on strings; negative list indices + (The equivalent of string.sub on strings; negative list indices count from the end of the list.) @@ -1035,7 +1035,7 @@

      Returns:

      Parameters:

      • ls - table + table {{ls<1,1>, ..., ls<1,c>}, ..., {ls<r,1>, ..., ls<r,c>}}
      @@ -1063,7 +1063,7 @@

      Returns:

      Parameters:

      • ls - table + table list of lists
      • f @@ -1135,7 +1135,7 @@

        Parameters:

        See also:

        @@ -1159,7 +1159,7 @@

        Parameters:

        a list
      • table - table + table another list, hash part is ignored
      @@ -1168,7 +1168,7 @@

      Parameters:

      See also:

      @@ -1284,7 +1284,7 @@

      Returns:

      Parameters:

      @@ -1643,7 +1643,7 @@

      Returns:

      Parameters:

      @@ -1668,7 +1668,7 @@

      See also:

      Return a sub-range of a list. - (The equivalent of string.sub on strings; negative list indices + (The equivalent of string.sub on strings; negative list indices count from the end of the list.) @@ -1721,7 +1721,7 @@

      Returns:

      -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
      diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index 28373a2..fd6c8a7 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -149,10 +149,14 @@

      Metamethods

      Methods

    std.container:__call (...)std.container:__call (x, ...) Return a clone of this container.
    - + + + + + @@ -178,17 +182,17 @@

    Tables

    Fields:

    • _init - table or function + table or function a table of field names, or initialisation function, used by clone
    • _functions - nil or table + nil or table a table of module functions not copied by std.object.__call
    • _type - string + string type of Object, returned by prototype (default "Object")
    • @@ -253,14 +257,14 @@

      See also:

      Returns:

        - string + string stringified container representation

      See also:

      @@ -281,7 +285,7 @@

      See also:

      Returns:

        - table + table a shallow copy of non-private object fields
      @@ -298,7 +302,7 @@

      Methods

      - std.object:clone (o, ...) + std.object:clone (obj, ...)
      Clone this Object. @@ -306,7 +310,7 @@

      Methods

      Parameters:

        -
      • o +
      • obj std.object an object
      • @@ -330,6 +334,60 @@

        See also:

      +
      +
      + + std.object:mapfields (obj, src[, map={}]) +
      +
      + Return obj with references to the fields of src merged in.

      + +

      More importantly, split the fields in src between obj and its + metatable. If any field names begin with _, attach a metatable + to obj if it doesn't have one yet, and copy the "private" _ + prefixed fields there.

      + +

      You might want to use this function to instantiate your derived + objct clones when the prototype's _init is a function -- when + _init is a table, the default (inherited unless you overwrite + it) clone method calls mapfields automatically. When you're + using a function _init setting, clone doesn't know what to + copy into a new object from the _init function's arguments... + so you're on your own. Except that calling mapfields inside + _init is safer than manually splitting src into obj and + its metatable, because you'll pick up fixes and changes when you + upgrade stdlib. + + +

      Parameters:

      +
        +
      • obj + table + destination object +
      • +
      • src + table + fields to copy int clone +
      • +
      • map + table + {oldkey=newkey, ...} + (default {}) +
      • +
      + +

      Returns:

      +
        + + table + obj with non-private fields from src merged, + and a metatable with private fields (if any) merged, both sets + of keys renamed according to map +
      + + + +
      @@ -371,7 +429,7 @@

      Parameters:

      Returns:

        - string + string type of x
      @@ -385,7 +443,7 @@

      Returns:

      -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
      diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html index 704bec4..2a0ac2a 100644 --- a/doc/classes/std.optparse.html +++ b/doc/classes/std.optparse.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -71,14 +71,9 @@

      Class std.optparse

       local OptionParser = require "std.optparse"
      - local parser = OptionParser (spec)
      - _G.arg, opts = parser:parse (_G.arg)
      -
      - -

      The string spec passed to OptionParser must be a specially formatted - help text, of the form:

      -
       any text VERSION
      + local parser = OptionParser [[
      + any text VERSION
        Additional lines of text to show when the --version
        option is passed.
       
      @@ -95,36 +90,56 @@ 

      Class std.optparse

      Options: - -h, --help display this help, then exit - --version display version information, then exit -b a short option with no long option --long a long option with no short option --another-long a long option with internal hypen - --true a Lua keyword as an option name -v, --verbose a combined short and long option -n, --dryrun, --dry-run several spellings of the same option -u, --name=USER require an argument -o, --output=[FILE] accept an optional argument - -- end of options + --version display version information, then exit + --help display this help, then exit Footer text. Several lines or paragraphs are permitted. Please report bugs at bug-list@yourhost.com +]] + +_G.arg, _G.opts = parser:parse (_G.arg)

      Most often, everything else is handled automatically. After calling parser:parse as shown above, _G.arg will contain unparsed arguments, - usually filenames or similar, and opts will be a table of parsed + usually filenames or similar, and _G.opts will be a table of parsed option values. The keys to the table are the long-options with leading hyphens stripped, and non-word characters turned to _. For example - if --another-long had been found in _G.arg then opts would + if --another-long had been found in _G.arg then _G.opts would have a key named another_long. If there is no long option name, then - the short option is used, e.g. opts.b will be set. The values saved - in those keys are controlled by the option handler, usually just true - or the option argument string as appropriate.

      + the short option is used, e.g. _G.opts.b will be set. The values + saved in those keys are controlled by the option handler, usually just + true or the option argument string as appropriate.

      On those occasions where more complex processing is required, handlers - can be replaced or added using parser:on.

      + can be replaced or added using parser:on. A good option to always + add, is to make -- signal the end of processed options, so that any + options following -- on the command line, even if they begin with a + hyphen and look like options otherwise, are not processed but instead + left in the modified _G.arg returned by parser:parse:

      + +
       parser:on ('--', parser.finished)
      +
      + +

      See the documentation for std.optparse:on for more details of how to + use this powerful method.

      + +

      When writing your own handlers for std.optparse:on, you only need + to deal with normalised arguments, because combined short arguments + (-xyz), equals separators to long options (--long=ARG) are fully + expanded before any handler is called.

      + +

      Note that std.io.die and std.io.warn will only prefix messages + with parser.program if the parser options are assigned back to + _G.opts as shown in the example above.

      @@ -135,82 +150,76 @@

      Functions

    -
    std.object:clone (o, ...)std.object:clone (obj, ...) Clone this Object.
    std.object:mapfields (obj, src[, map={}])Return obj with references to the fields of src merged in.
    std.object:prototype (x) Type of an object, or primitive.
    std.optparse.OptionParser (spec) Instantiate a new parser.
    -

    Tables

    - - - - - - - - - - - - -
    std.optparse.boolvalsMap various option strings to equivalent Lua boolean values.
    std.optparse.optsParsed options table, with a key for each encountered option, each - with value set by that option's on_handler.
    std.optparse.parserCustomized parser for your options.
    -

    Methods

    - - - + - + - - + + - + - + - - + + - - + + - - + + - - + + +
    std.optparse:boolean (opt[, optarg="1"])std.optparse.boolean (opt[, optarg="1"]) Return a Lua boolean equivalent of various optarg strings.
    std.optparse:file (opt, optarg)std.optparse.file (opt, optarg) Report an option parse error unless optarg names an existing file.
    std.optparse:finished (arglist, i)Finish option processing - Usually indicated by -- at arglist[i].std.optparse.finished (arglist, i)Finish option processing

    + +

    This is the handler automatically assigned to the option written as + -- in the OptionParser spec argument.

    std.optparse:flag (arglist, i[, value])std.optparse.flag (arglist, i[, value]) Option at arglist[i] is a boolean switch.
    std.optparse:help ()std.optparse.help () Option should display help text, then exit.
    std.optparse:normalise (arglist)Normalise an argument list.std.optparse.opterr (msg)Report an option parse error, then exit with status 2.
    std.optparse:on (name, handler, value)Add an option handler.std.optparse.optional (arglist, i[, value=true])Option at arglist[i] can take an argument.
    std.optparse:on_handler (arglist, i[, value=nil])Function signature of an option handler for on.std.optparse.required (arglist, i[, value])Option at arglist[i} requires an argument.
    std.optparse:opterr (msg)Report an option parse error, then exit with status 2.std.optparse.version ()Option should display version text, then exit.
    +

    Tables

    + - - + + - - + + - - + + + +
    std.optparse:optional (arglist, i[, value=true])Option at arglist[i] can take an argument.std.optparse.boolvalsMap various option strings to equivalent Lua boolean values.
    std.optparse:parse (arglist)Parse arglist.std.optparse.optsParsed options table, with a key for each encountered option, each + with value set by that option's on_handler.
    std.optparse:required (arglist, i[, value])Option at arglist[i} requires an argument.std.optparse.parserCustomized parser for your options.
    +

    Methods

    + + + + - - + + - - + +
    std.optparse:on (name, handler, value)Add an option handler.
    std.optparse:set (opt, value)Store value with opt.std.optparse:on_handler (arglist, i[, value=nil])Function signature of an option handler for on.
    std.optparse:version ()Option should display version text, then exit.std.optparse:parse (arglist)Parse arglist.
    @@ -228,13 +237,14 @@

    Functions

    Instantiate a new parser. Read the documented options from spec and return a new parser that can be passed to parse for parsing those options from an argument - list. + list. Options are recognised as lines that begin with at least two + spaces, followed by a hyphen.

    Parameters:

    @@ -250,99 +260,27 @@

    Returns:

    - -

    Tables

    -
    - - std.optparse.boolvals -
    -
    - Map various option strings to equivalent Lua boolean values. - - -

    Fields:

    -
      -
    • false - false -
    • -
    • 0 - false -
    • -
    • no - false -
    • -
    • n - false -
    • -
    • true - true -
    • -
    • 1 - true -
    • -
    • yes - true -
    • -
    • y - true -
    • -
    - - - - - -
    -
    - - std.optparse.opts -
    -
    - Parsed options table, with a key for each encountered option, each - with value set by that option's on_handler. - - - - - - - -
    -
    - - std.optparse.parser -
    -
    - Customized parser for your options. - - - - - - - -
    -
    -

    Methods

    -
    -
    - - std.optparse:boolean (opt[, optarg="1"]) + + std.optparse.boolean (opt[, optarg="1"])
    Return a Lua boolean equivalent of various optarg strings. - Report an option parse error if optarg is not recognised. + Report an option parse error if optarg is not recognised.

    + +

    Pass this as the value function to on when you want various + truthy or falsey option arguments to be coerced to a Lua true + or false respectively in the options table.

    Parameters:

    - - std.optparse:file (opt, optarg) + + std.optparse.file (opt, optarg)
    Report an option parse error unless optarg names an - existing file. + existing file.

    + +

    Pass this as the value function to on when you want to accept + only option arguments that name an existing file.

    Parameters:

    @@ -394,18 +335,26 @@

    Returns:

    - - std.optparse:finished (arglist, i) + + std.optparse.finished (arglist, i)
    - Finish option processing - Usually indicated by -- at arglist[i]. + Finish option processing

    + +

    This is the handler automatically assigned to the option written as + -- in the OptionParser spec argument. You can also pass it as + the handler argument to on if you want to manually add an end + of options marker without writing it in the OptionParser spec.

    + +

    This handler tells the parser to stop processing arguments, so that + anything after it will be an argument even if it otherwise looks + like an option.

    Parameters:

    • arglist - table + table list of arguments
    • i @@ -426,17 +375,29 @@

      Returns:

    - - std.optparse:flag (arglist, i[, value]) + + std.optparse.flag (arglist, i[, value])
    - Option at arglist[i] is a boolean switch. + Option at arglist[i] is a boolean switch.

    + +

    This is the handler automatically assigned to options that have + --long-opt or -x style specifications in the OptionParser spec + argument. You can also pass it as the handler argument to on for + options you want to add manually without putting them in the + OptionParser spec.

    + +

    Beware that, unlike required, this handler will store multiple + occurrences of a command-line option as a table only when given a + value function. Automatically assigned handlers do not do this, so + the option will simply be true if the option was given one or more + times on the command-line.

    Parameters:

    • arglist - table + table list of arguments
    • i @@ -461,11 +422,14 @@

      Returns:

    - - std.optparse:help () + + std.optparse.help ()
    - Option should display help text, then exit. + Option should display help text, then exit.

    + +

    This is the handler automatically assigned tooptions that have + --help in the specification, e.g. -h, -?, --help. @@ -475,75 +439,112 @@

    Returns:

    - - std.optparse:normalise (arglist) + + std.optparse.opterr (msg)
    - Normalise an argument list. - Separate short options, remove = separators from - --long-option=optarg etc. + Report an option parse error, then exit with status 2.

    + +

    Use this in your custom option handlers for consistency with the + error output from built-in optparse error messages.

    Parameters:

      -
    • arglist - table - list of arguments to normalise +
    • msg + string + error message
    -

    Returns:

    -
      - - table - normalised argument list -
    - - std.optparse:on (name, handler, value) + + std.optparse.optional (arglist, i[, value=true])
    - Add an option handler. + Option at arglist[i] can take an argument. + Argument is accepted only if there is a following entry that does not + begin with a '-'.

    + +

    This is the handler automatically assigned to options that have + --opt=[ARG] style specifications in the OptionParser spec + argument. You can also pass it as the handler argument to on for + options you want to add manually without putting them in the + OptionParser spec.

    + +

    Like required, this handler will store multiple occurrences of a + command-line option.

    Parameters:

      -
    • name - opts - of the option, or list of option names +
    • arglist + table + list of arguments
    • -
    • handler - on_handler - function to call when any of opts is - encountered +
    • i + int + index of last processed element of arglist
    • value - additional value passed to on_handler + either a function to process the option + argument, or a default value if encountered without an optarg + (default true)
    +

    Returns:

    +
      + + int + index of next element of arglist to process +
    - - std.optparse:on_handler (arglist, i[, value=nil]) + + std.optparse.required (arglist, i[, value])
    - Function signature of an option handler for on. + +

    Option at arglist[i} requires an argument.

    + +

    This is the handler automatically assigned to options that have + --opt=ARG style specifications in the OptionParser spec argument. + You can also pass it as the handler argument to on for options + you want to add manually without putting them in the OptionParser + spec.

    + +

    Normally the value stored in the opt table by this handler will be + the string given as the argument to that option on the command line. + However, if the option is given on the command-line multiple times, + opt["name"] will end up with all those arguments stored in the + array part of a table:

    + +
     $ cat ./prog
    + ...
    + parser:on ({"-e", "-exec"}, required)
    + _G.arg, _G.opt = parser:parse (_G.arg)
    + print std.string.tostring (_G.opt.exec)
    + ...
    + $ ./prog -e '(foo bar)' -e '(foo baz)' -- qux
    + {1=(foo bar),2=(foo baz)}
    +
    +

    Parameters:

    • arglist - table + table list of arguments
    • i @@ -551,8 +552,8 @@

      Parameters:

      index of last processed element of arglist
    • value - additional value registered with on - (default nil) + either a function to process the option argument, + or a forced value to replace the user's option argument.
    @@ -568,162 +569,267 @@

    Returns:

    - - std.optparse:opterr (msg) + + std.optparse.version ()
    - Report an option parse error, then exit with status 2. + Option should display version text, then exit.

    + +

    This is the handler automatically assigned tooptions that have + --version in the specification, e.g. -V, --version. -

    Parameters:

    -
      -
    • msg - string - error message -
    • -
    +
    +

    Tables

    +
    - - std.optparse:optional (arglist, i[, value=true]) + + std.optparse.boolvals
    - Option at arglist[i] can take an argument. - Argument is accepted only if there is a following entry that does not - begin with a '-'. + Map various option strings to equivalent Lua boolean values. -

    Parameters:

    +

    Fields:

      -
    • arglist - table - list of arguments +
    • false + false
    • -
    • i - int - index of last processed element of arglist +
    • 0 + false
    • -
    • value - either a function to process the option - argument, or a default value if encountered without an optarg - (default true) +
    • no + false +
    • +
    • n + false +
    • +
    • true + true +
    • +
    • 1 + true +
    • +
    • yes + true +
    • +
    • y + true
    -

    Returns:

    -
      - int - index of next element of arglist to process -
    + + + +
    +
    + + std.optparse.opts +
    +
    + Parsed options table, with a key for each encountered option, each + with value set by that option's on_handler. Where an option + has one or more long-options specified, the key will be the first + one of those with leading hyphens stripped and non-alphanumeric + characters replaced with underscores. For options that can only be + specified by a short option, the key will be the letter of the first + of the specified short options:

    + +
     {"-e", "--eval-file"} => opts.eval_file
    + {"-n", "--dryrun", "--dry-run"} => opts.dryrun
    + {"-t", "-T"} => opts.t
    +
    + +

    Generally there will be one key for each previously specified + option (either automatically assigned by OptionParser or + added manually with on) containing the value(s) assigned by the + associated on_handler. For automatically assigned handlers, + that means true for straight-forward flags and + optional-argument options for which no argument was given; or else + the string value of the argument passed with an option given only + once; or a table of string values of the same for arguments given + multiple times.

    + +
     ./prog -x -n -x => opts = { x = true, dryrun = true }
    + ./prog -e '(foo bar)' -e '(foo baz)'
    +     => opts = {eval_file = {"(foo bar)", "(foo baz)"} }
    +
    + +

    If you write your own handlers, or otherwise specify custom + handling of options with on, then whatever value those handlers + return will be assigned to the respective keys in opts . + + +

    - - std.optparse:parse (arglist) + + std.optparse.parser
    - Parse arglist. + Customized parser for your options.

    +

    This table is returned by OptionParser, and most importantly has + the parse method you call to fill the opts table according to + what command-line options were passed to your program. -

    Parameters:

    + +

    Fields:

      -
    • arglist - table - list of arguments +
    • program + string + the first word following Usage: in OptionParser + spec string +
    • +
    • version + string + the last white-space delimited word on the first line + of text in the spec string +
    • +
    • versiontext + string + everything preceding Usage: in the spec string, + and which will be displayed by the version on_handler +
    • +
    • helptext + string + everything including and following Usage: in the + spec string and which will be displayed by the help + on_handler +
    • +
    • parse + func + see parse +
    • +
    • on + func + see on
    -

    Returns:

    -
      -
    1. - table - a list of unrecognised arglist elements
    2. -
    3. - opts - parsing results
    4. -
    +
    +

    Methods

    +
    - - std.optparse:required (arglist, i[, value]) + + std.optparse:on (name, handler, value)
    - Option at arglist[i} requires an argument. + +

    Add an option handler.

    + +

    When the automatically assigned option handlers don't do everything + you require, or when you don't want to put an option into the + OptionParser spec argument, use this function to specify custom + behaviour. If you write the option into the spec argument anyway, + calling this function will replace the automatically assigned handler + with your own.

    + +
     parser:on ("--", parser.finished)
    + parser:on ("-V", parser.version)
    + parser:on ("--config-file", parser.required, parser.file)
    + parser:on ("--enable-nls", parser.optional, parser.boolean)
    +
    +

    Parameters:

      -
    • arglist - table - list of arguments +
    • name + opts + of the option, or list of option names
    • -
    • i - int - index of last processed element of arglist +
    • handler + on_handler + function to call when any of opts is + encountered
    • value - either a function to process the option argument, - or a forced value to replace the user's option argument. + additional value passed to on_handler
    -

    Returns:

    -
      - - int - index of next element of arglist to process -
    - - std.optparse:set (opt, value) + + std.optparse:on_handler (arglist, i[, value=nil])
    - Store value with opt. + Function signature of an option handler for on.

    Parameters:

      -
    • opt - string - option name +
    • arglist + table + list of arguments +
    • +
    • i + int + index of last processed element of arglist
    • value - option argument value + additional value registered with on + (default nil)
    +

    Returns:

    +
      + + int + index of next element of arglist to process +
    - - std.optparse:version () + + std.optparse:parse (arglist)
    - Option should display version text, then exit. + Parse arglist. +

    Parameters:

    +
      +
    • arglist + table + list of arguments +
    • +
    +

    Returns:

    +
      +
    1. + table + a list of unrecognised arglist elements
    2. +
    3. + opts + parsing results
    4. +
    @@ -735,7 +841,7 @@

    Parameters:

    -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
    diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index b291a94..035f68e 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -206,7 +206,7 @@

    Parameters:

    a set
  • set2 - table or set + table or set another set, or table
  • @@ -257,7 +257,7 @@

    Parameters:

    a set
  • set2 - table or set + table or set another set, or table
  • @@ -316,7 +316,7 @@

    Parameters:

    a set
  • set2 - table or set + table or set another set, or table
  • @@ -376,7 +376,7 @@

    Parameters:

    a set
  • set2 - table or set + table or set another set, or table
  • @@ -406,7 +406,7 @@

    Parameters:

    a set
  • set2 - table or set + table or set another set, or table
  • @@ -436,7 +436,7 @@

    Parameters:

    a set
  • set2 - table or set + table or set another set, or table
  • @@ -466,7 +466,7 @@

    Parameters:

    a set
  • set2 - table or set + table or set another set, or table
  • @@ -495,17 +495,17 @@

    Tables

    Fields:

    @@ -578,7 +578,7 @@

    Parameters:

    set
  • table - table or set + table or set another set or table
  • @@ -617,7 +617,7 @@

    Parameters:

    set
  • table - table or set + table or set another set or table
  • @@ -656,7 +656,7 @@

    Parameters:

    set
  • table - table or set + table or set another set or table
  • @@ -695,7 +695,7 @@

    Parameters:

    set
  • table - table or set + table or set another set or table
  • @@ -734,7 +734,7 @@

    Parameters:

    set
  • table - table or set + table or set another set or table
  • @@ -760,7 +760,7 @@

    See also:

    -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
    diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index cefb45c..5b9e82f 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -119,7 +119,7 @@

    Parameters:

    StrBuf object
  • str - string + string a string or string-like object
  • @@ -162,7 +162,7 @@

    Parameters:

    Returns:

      - string + string concatenation of buffer contents
    @@ -188,7 +188,7 @@

    Methods

    Parameters:

    @@ -224,7 +224,7 @@

    Parameters:

    Returns:

      - string + string stringified self
    @@ -238,7 +238,7 @@

    Returns:

    -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
    diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index f6ffff8..a8f9e36 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -139,7 +139,7 @@

    Functions

    Parameters:

    • t - table or tree + table or tree table or tree to be cloned
    • nometa @@ -151,7 +151,7 @@

      Parameters:

      Returns:

        - table or tree + table or tree a deep copy of t
      @@ -170,7 +170,7 @@

      Returns:

      Parameters:

      @@ -181,7 +181,7 @@

      Returns:

      function iterator function
    • - tree or table + tree or table the tree tr
    • @@ -203,7 +203,7 @@

      Returns:

      Parameters:

      @@ -214,7 +214,7 @@

      Returns:

      function iterator function
    • - tree or table + tree or table the tree, tr
    • @@ -237,7 +237,7 @@

      See also:

      Parameters:

      @@ -248,7 +248,7 @@

      Returns:

      function iterator function
    • - tree or table + tree or table the tree, tr
    • @@ -267,11 +267,11 @@

      Returns:

      Parameters:

      @@ -279,7 +279,7 @@

      Parameters:

      Returns:

        - tree or table + tree or table t with nodes from u merged in
      @@ -335,7 +335,7 @@

      See also:

      Parameters:

      @@ -346,7 +346,7 @@

      Returns:

      function iterator function
    • - tree or table + tree or table the tree, tr
    • @@ -372,18 +372,18 @@

      Tables

      Fields:

      • _init - table or function + table or function a table of field names, or initialisation function, see std.object.__call (default {})
      • _functions - nil or table + nil or table a table of module functions not copied by std.object.__call
      • _type - string + string type of Tree, returned by std.object.prototype (default "Tree") @@ -454,7 +454,7 @@

        Parameters:

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/index.html b/doc/index.html index 12a01ee..d422ffa 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -133,7 +133,7 @@

        Classes

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html index 615896c..a6f797d 100644 --- a/doc/modules/std.debug.html +++ b/doc/modules/std.debug.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -201,7 +201,7 @@

        Fields:

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index b9730a2..51d6393 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -494,7 +494,7 @@

        Fields:

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.html b/doc/modules/std.html index b5efcff..717aa6f 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -744,7 +744,7 @@

        Metamethods

        Parameters:

        @@ -765,7 +765,7 @@

        Returns:

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index c1109d9..fc955af 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -176,6 +176,8 @@

        Returns:

        Die with error. + This function uses the same rules to build a message prefix + as std.io.warn.

        Parameters:

        @@ -187,6 +189,10 @@

        Parameters:

        +

        See also:

        +
        @@ -320,7 +326,24 @@

        Returns:

        warn (...)
        - Give warning with the name of program and file (if any). + +

        Give warning with the name of program and file (if any). + If there is a global prog table, prefix the message with + prog.name or prog.file, and prog.line if any. Otherwise + if there is a global opts table, prefix the message with + opts.program and opts.line if any. std.optparse:parse + returns an opts table that provides the required program + field, as long as you assign it back to _G.opts:

        + +
         local OptionParser = require "std.optparse"
        + local parser = OptionParser "eg 0\nUsage: eg\n"
        + _G.arg, _G.opts = parser:parse (_G.arg)
        + if not _G.opts.keep_going then
        +   require "std.io".warn "oh noes!"
        + end
        +
        + +

        Parameters:

        @@ -332,6 +355,10 @@

        Parameters:

        +

        See also:

        +
        @@ -364,7 +391,7 @@

        Parameters:

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index eb857ed..1455e3b 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -150,7 +150,7 @@

        Returns:

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index 7c0b2eb..63712df 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -124,7 +124,7 @@

        Fields:

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index cfdc552..a595470 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -123,7 +123,7 @@

        Functions

        -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
        diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index f99a396..c734fd0 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -166,7 +166,7 @@

        Functions

        Remove trailing matter from a string. - split (s, sep) + split (s[, sep="%s*"]) Split a string at a given separator. @@ -847,26 +847,33 @@

        Returns:

    - split (s, sep) + split (s[, sep="%s*"])
    Split a string at a given separator. + Separator is a Lua pattern, so you have to escape active characters, + ^$()%.[]*+-? with a % prefix to match a literal character in s .

    Parameters:

    • s - string to split + string + to split
    • sep + string separator pattern + (default "%s*")

    Returns:

      - - list of strings +
    1. + list of strings
    2. +
    3. + list of strings
    @@ -1069,7 +1076,7 @@

    Fields

    -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
    diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index 96ebab2..d992c03 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - stdlib 37 Reference + stdlib 38 Reference @@ -145,7 +145,7 @@

    Functions

    Parameters:

    • t - table + table
        source table
       
      @@ -178,11 +178,11 @@

      Returns:

      Parameters:

      @@ -208,7 +208,7 @@

      Returns:

      Parameters:

      @@ -234,7 +234,7 @@

      Returns:

      Parameters:

      @@ -242,7 +242,7 @@

      Parameters:

      Returns:

        - table + table inverted table {v=k, ...}
      @@ -261,7 +261,7 @@

      Returns:

      Parameters:

      @@ -269,7 +269,7 @@

      Parameters:

      Returns:

        - table + table list of keys
      @@ -288,11 +288,11 @@

      Returns:

      Parameters:

      @@ -321,7 +321,7 @@

      Parameters:

      default entry value (default: nil)
    • t - table + table initial table (default: {})
    @@ -329,7 +329,7 @@

    Parameters:

    Returns:

      - table + table table whose unset elements are x
    @@ -373,7 +373,7 @@

    Returns:

    Parameters:

    @@ -384,7 +384,7 @@

    Returns:

    function iterator function
  • - table + table the table, t
  • number @@ -406,7 +406,7 @@

    Returns:

    Parameters:

    @@ -432,7 +432,7 @@

    Returns:

    Parameters:

    • t - table + table unsorted table
    • c @@ -470,7 +470,7 @@

      Parameters:

      Returns:

        - table + table resulting table or nil
      @@ -489,7 +489,7 @@

      Returns:

      Parameters:

      @@ -497,7 +497,7 @@

      Parameters:

      Returns:

        - table + table list of values
      @@ -511,7 +511,7 @@

      Returns:

      -generated by LDoc 1.4.0 +generated by LDoc 1.4.2
      diff --git a/lib/std.lua b/lib/std.lua index af93195..9980604 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -29,7 +29,7 @@ -- local prototype = std.container.prototype -- @table std -- @field version release version string -local version = "General Lua libraries / 37" +local version = "General Lua libraries / 38" local modules = require "std.modules" diff --git a/lib/std/container.lua b/lib/std/container.lua index b5f9874..64cd413 100644 --- a/lib/std/container.lua +++ b/lib/std/container.lua @@ -59,55 +59,77 @@ local base = require "std.base" -local func = require "std.functional" - - ---- Return the named entry from x's metatable. --- @param x anything --- @tparam string n name of entry --- @return value associate with `n` in `x`'s metatable, else nil -local function metaentry (x, n) - local ok, f = pcall (function (x) - return getmetatable (x)[n] - end, - x) - if not ok then f = nil end - return f + +local clone, merge = base.clone, base.merge + + +local ModuleFunction = { + __tostring = function (self) return tostring (self.call) end, + __call = function (self, ...) return self.call (...) end, +} + + +--- Mark a function not to be copied into clones. +-- +-- It responds to `type` with `table`, but otherwise behaves like a +-- regular function. Marking uncopied module functions in-situ like this +-- (as opposed to doing book keeping in the metatable) means that we +-- don't have to create a new metatable with the book keeping removed for +-- cloned objects, we can just share our existing metatable directly. +-- @func fn a function +-- @treturn functable a callable functable for `fn` +local function modulefunction (fn) + return setmetatable ({_type = "modulefunction", call = fn}, ModuleFunction) end ---- Filter a table with a function. --- @tparam table t source table --- @tparam function f a function that takes key and value arguments --- from calling `pairs` on `t`, and returns non-`nil` for elements --- that should be in the returned table --- @treturn table a shallow copy of `t`, with elements removed according --- to `f` -local function filter (t, f) - local r = {} - for k, v in pairs (t) do - if f (k, v) then - r[k] = v +--- Return `obj` with references to the fields of `src` merged in. +-- @static +-- @tparam table obj destination object +-- @tparam table src fields to copy int clone +-- @tparam[opt={}] table map `{old_key=new_key, ...}` +-- @treturn table `obj` with non-private fields from `src` merged, and +-- a metatable with private fields (if any) merged, both sets of keys +-- renamed according to `map` +-- @see std.object.mapfields +local function mapfields (obj, src, map) + map = map or {} + local mt = getmetatable (obj) or {} + + -- Map key pairs. + for k, v in pairs (src) do + local key, dst = map[k] or k, obj + if type (key) == "string" and key:sub (1, 1) == "_" then + dst = mt end + dst[key] = v end - return r + + -- Quicker to remove this after copying fields than test for it + -- it on every iteration above. + mt._functions = nil + + -- Inject module functions. + for k, v in pairs (src._functions or {}) do + obj[k] = modulefunction (v) + end + + -- Only set non-empty metatable. + if next (mt) then + setmetatable (obj, mt) + end + return obj end -local functions = { - -- Type of this container. - -- @static - -- @tparam std.container o an container - -- @treturn string type of the container - -- @see std.object.prototype - prototype = function (o) - local _type = metaentry (o, "_type") - if type (o) == "table" and _type ~= nil then - return _type - end - return type (o) - end, -} +-- Type of this container. +-- @static +-- @tparam std.container o an container +-- @treturn string type of the container +-- @see std.object.prototype +local function prototype (o) + return (getmetatable (o) or {})._type or type (o) +end --- Container prototype. @@ -119,65 +141,46 @@ local functions = { -- @tfield nil|table _functions a table of module functions not copied -- by @{std.object.__call} local metatable = { - _type = "Container", - _init = {}, - _functions = functions, - + _type = "Container", + _init = {}, --- Return a clone of this container. -- @function __call - -- @param ... arguments for `_init` + -- @param x a table if prototype `_init` is a table, otherwise first + -- argument for a function type `_init` + -- @param ... any additional arguments for `_init` -- @treturn std.container a clone of the called container. -- @see std.object:__call - __call = function (self, ...) - local mt = getmetatable (self) - - -- Make a shallow copy of prototype, skipping metatable - -- _functions. - local fn = mt._functions or {} - local obj = filter (self, function (e) return not fn[e] end) - - -- Map arguments according to _init metamethod. - local _init = metaentry (self, "_init") - if type (_init) == "table" then - base.merge (obj, base.clone_rename (_init, ...)) - else - obj = _init (obj, ...) - end - - -- Extract any new fields beginning with "_". - local obj_mt = {} - for k, v in pairs (obj) do - if type (k) == "string" and k:sub (1, 1) == "_" then - obj_mt[k], obj[k] = v, nil + __call = function (self, x, ...) + local mt = getmetatable (self) + local obj_mt = mt + local obj = {} + + -- This is the slowest part of cloning for any objects that have + -- a lot of fields to test and copy. If you need to clone a lot of + -- objects from a prototype with several module functions, it's much + -- faster to clone objects from each other than the prototype! + for k, v in pairs (self) do + if type (v) ~= "table" or v._type ~= "modulefunction" then + obj[k] = v end end - -- However, newly passed _functions from _init arguments are - -- copied as prototype functions into the object. - func.map (function (k) obj[k] = obj_mt._functions[k] end, - pairs, obj_mt._functions or {}) - - -- _functions is not propagated from prototype to clone. - if next (obj_mt) == nil then - -- Reuse metatable if possible - obj_mt = getmetatable (self) + if type (mt._init) == "table" then + obj = (self.mapfields or mapfields) (obj, x, mt._init) else + obj = mt._init (obj, x, ...) + end + + -- If a metatable was set, then merge our fields and use it. + if next (getmetatable (obj) or {}) then + obj_mt = merge (clone (mt), getmetatable (obj)) - -- Otherwise copy the prototype metatable... - local t = filter (mt, function (e) return e ~= "_functions" end) - -- ...but give preference to "_" prefixed keys from init table - obj_mt = base.merge (t, obj_mt) - - -- ...and merge container methods from prototype too. - if mt then - if type (obj_mt.__index) == "table" and type (mt.__index) == "table" then - local methods = base.clone (obj_mt.__index) - for k, v in pairs (mt.__index) do - methods[k] = methods[k] or v - end - obj_mt.__index = methods - end + -- Merge object methods. + if type (obj_mt.__index) == "table" and + type ((mt or {}).__index) == "table" + then + obj_mt.__index = merge (clone (mt.__index), obj_mt.__index) end end @@ -191,8 +194,8 @@ local metatable = { -- @see std.object.__tostring __tostring = function (self) local totable = getmetatable (self).__totable - local array = base.clone (totable (self), "nometa") - local other = base.clone (array, "nometa") + local array = clone (totable (self), "nometa") + local other = clone (array, "nometa") local s = "" if #other > 0 then for i in ipairs (other) do other[i] = nil end @@ -215,7 +218,7 @@ local metatable = { s = s .. table.concat (dict, ", ") end - return metaentry (self, "_type") .. " {" .. s .. "}" + return prototype (self) .. " {" .. s .. "}" end, @@ -224,10 +227,22 @@ local metatable = { -- @treturn table a shallow copy of non-private container fields -- @see std.object:__totable __totable = function (self) - return filter (self, function (e) - return type (e) ~= "string" or e:sub (1, 1) ~= "_" - end) + local t = {} + for k, v in pairs (self) do + if type (k) ~= "string" or k:sub (1, 1) ~= "_" then + t[k] = v + end + end + return t end, } -return setmetatable (functions, metatable) +return setmetatable ({ + + -- Normally, these are set and wrapped automatically during cloning. + -- But, we have to bootstrap the first object, so in this one instance + -- it has to be done manually. + + mapfields = modulefunction (mapfields), + prototype = modulefunction (prototype), +}, metatable) diff --git a/lib/std/io.lua b/lib/std/io.lua index d72883d..609fc6d 100644 --- a/lib/std/io.lua +++ b/lib/std/io.lua @@ -110,25 +110,49 @@ local function process_files (f) end --- Give warning with the name of program and file (if any). +-- If there is a global `prog` table, prefix the message with +-- `prog.name` or `prog.file`, and `prog.line` if any. Otherwise +-- if there is a global `opts` table, prefix the message with +-- `opts.program` and `opts.line` if any. @{std.optparse:parse} +-- returns an `opts` table that provides the required `program` +-- field, as long as you assign it back to `_G.opts`: +-- +-- local OptionParser = require "std.optparse" +-- local parser = OptionParser "eg 0\nUsage: eg\n" +-- _G.arg, _G.opts = parser:parse (_G.arg) +-- if not _G.opts.keep_going then +-- require "std.io".warn "oh noes!" +-- end +-- -- @param ... arguments for format +-- @see std.optparse:parse local function warn (...) - if prog.name then - io.stderr:write (prog.name .. ":") - end - if prog.file then - io.stderr:write (prog.file .. ":") - end - if prog.line then - io.stderr:write (tostring (prog.line) .. ":") - end - if prog.name or prog.file or prog.line then - io.stderr:write (" ") + local prefix = "" + if (prog or {}).name then + prefix = prog.name .. ":" + if prog.line then + prefix = prefix .. tostring (prog.line) .. ":" + end + elseif (prog or {}).file then + prefix = prog.file .. ":" + if prog.line then + prefix = prefix .. tostring (prog.line) .. ":" + end + elseif (opts or {}).program then + prefix = opts.program .. ":" + if opts.line then + prefix = prefix .. tostring (opts.line) .. ":" + end end - writelines (io.stderr, string.format (...)) + if #prefix > 0 then prefix = prefix .. " " end + writelines (io.stderr, prefix .. string.format (...)) end --- Die with error. +-- This function uses the same rules to build a message prefix +-- as @{std.io.warn}. -- @param ... arguments for format +-- @see std.io.warn local function die (...) warn (...) error () diff --git a/lib/std/object.lua b/lib/std/object.lua index 355f2b7..eea9635 100644 --- a/lib/std/object.lua +++ b/lib/std/object.lua @@ -57,6 +57,13 @@ ]] + +-- Surprise!! The real root object is Container, which has less +-- functionality than Object, but that makes the heirarchy hard to +-- explain, so the documentation pretends this is the root object, and +-- Container is derived from it. Confused? ;-) + + local Container = require "std.container" local metamethod = (require "std.functional").metamethod @@ -81,7 +88,7 @@ return Container { __index = { --- Clone this Object. -- @function clone - -- @tparam std.object o an object + -- @tparam std.object obj an object -- @param ... a list of arguments if `o._init` is a function, or a -- single table if `o._init` is a table. -- @treturn std.object a clone of `o` @@ -112,11 +119,38 @@ return Container { -- @function prototype -- @param x anything -- @treturn string type of `x` - prototype = Container.prototype, + prototype = Container.prototype.call, + + + --- Return `obj` with references to the fields of `src` merged in. + -- + -- More importantly, split the fields in `src` between `obj` and its + -- metatable. If any field names begin with `\_`, attach a metatable + -- to `obj` if it doesn't have one yet, and copy the "private" `\_` + -- prefixed fields there. + -- + -- You might want to use this function to instantiate your derived + -- objct clones when the prototype's `_init` is a function -- when + -- `_init` is a table, the default (inherited unless you overwrite + -- it) clone method calls `mapfields` automatically. When you're + -- using a function `_init` setting, `clone` doesn't know what to + -- copy into a new object from the `_init` function's arguments... + -- so you're on your own. Except that calling `mapfields` inside + -- `_init` is safer than manually splitting `src` into `obj` and + -- its metatable, because you'll pick up fixes and changes when you + -- upgrade stdlib. + -- @function mapfields + -- @tparam table obj destination object + -- @tparam table src fields to copy int clone + -- @tparam[opt={}] table map `{old_key=new_key, ...}` + -- @treturn table `obj` with non-private fields from `src` merged, + -- and a metatable with private fields (if any) merged, both sets + -- of keys renamed according to `map` + mapfields = Container.mapfields.call, -- Backwards compatibility: - type = Container.prototype, + type = Container.prototype.call, }, diff --git a/lib/std/optparse.lua b/lib/std/optparse.lua index 7bf0ee5..f57592a 100644 --- a/lib/std/optparse.lua +++ b/lib/std/optparse.lua @@ -1,13 +1,9 @@ ---[[-- +--[=[-- Parse and process command line options. local OptionParser = require "std.optparse" - local parser = OptionParser (spec) - _G.arg, opts = parser:parse (_G.arg) - - The string `spec` passed to `OptionParser` must be a specially formatted - help text, of the form: + local parser = OptionParser [[ any text VERSION Additional lines of text to show when the --version option is passed. @@ -25,38 +21,57 @@ Options: - -h, --help display this help, then exit - --version display version information, then exit -b a short option with no long option --long a long option with no short option --another-long a long option with internal hypen - --true a Lua keyword as an option name -v, --verbose a combined short and long option -n, --dryrun, --dry-run several spellings of the same option -u, --name=USER require an argument -o, --output=[FILE] accept an optional argument - -- end of options + --version display version information, then exit + --help display this help, then exit Footer text. Several lines or paragraphs are permitted. Please report bugs at bug-list@yourhost.com + ]] + + _G.arg, _G.opts = parser:parse (_G.arg) Most often, everything else is handled automatically. After calling `parser:parse` as shown above, `_G.arg` will contain unparsed arguments, - usually filenames or similar, and `opts` will be a table of parsed + usually filenames or similar, and `_G.opts` will be a table of parsed option values. The keys to the table are the long-options with leading hyphens stripped, and non-word characters turned to `_`. For example - if `--another-long` had been found in `_G.arg` then `opts` would + if `--another-long` had been found in `_G.arg` then `_G.opts` would have a key named `another_long`. If there is no long option name, then - the short option is used, e.g. `opts.b` will be set. The values saved - in those keys are controlled by the option handler, usually just `true` - or the option argument string as appropriate. + the short option is used, e.g. `_G.opts.b` will be set. The values + saved in those keys are controlled by the option handler, usually just + `true` or the option argument string as appropriate. On those occasions where more complex processing is required, handlers - can be replaced or added using parser:@{on}. + can be replaced or added using parser:@{on}. A good option to always + add, is to make `--` signal the end of processed options, so that any + options following `--` on the command line, even if they begin with a + hyphen and look like options otherwise, are not processed but instead + left in the modified `_G.arg` returned by `parser:parse`: + + parser:on ('--', parser.finished) + + See the documentation for @{std.optparse:on} for more details of how to + use this powerful method. + + When writing your own handlers for @{std.optparse:on}, you only need + to deal with normalised arguments, because combined short arguments + (`-xyz`), equals separators to long options (`--long=ARG`) are fully + expanded before any handler is called. + + Note that @{std.io.die} and @{std.io.warn} will only prefix messages + with `parser.program` if the parser options are assigned back to + `_G.opts` as shown in the example above. @classmod std.optparse -]] +]=] local OptionParser -- forward declaration @@ -64,7 +79,22 @@ local OptionParser -- forward declaration ------ -- Customized parser for your options. +-- +-- This table is returned by @{OptionParser}, and most importantly has +-- the @{parse} method you call to fill the `opts` table according to +-- what command-line options were passed to your program. -- @table parser +-- @string program the first word following `Usage:` in @{OptionParser} +-- spec string +-- @string version the last white-space delimited word on the first line +-- of text in the spec string +-- @string versiontext everything preceding `Usage:` in the spec string, +-- and which will be displayed by the @{version} @{on_handler} +-- @string helptext everything including and following `Usage:` in the +-- spec string and which will be displayed by the @{help} +-- @{on_handler} +-- @func parse see @{parse} +-- @func on see @{on} --[[ ----------------- ]]-- @@ -78,6 +108,7 @@ local optional, required --- Normalise an argument list. -- Separate short options, remove `=` separators from -- `--long-option=optarg` etc. +-- @local -- @function normalise -- @tparam table arglist list of arguments to normalise -- @treturn table normalised argument list @@ -132,6 +163,7 @@ end --- Store `value` with `opt`. +-- @local -- @function set -- @string opt option name -- @param value option argument value @@ -157,6 +189,16 @@ end --- Option at `arglist[i]` can take an argument. -- Argument is accepted only if there is a following entry that does not -- begin with a '-'. +-- +-- This is the handler automatically assigned to options that have +-- `--opt=[ARG]` style specifications in the @{OptionParser} spec +-- argument. You can also pass it as the `handler` argument to @{on} for +-- options you want to add manually without putting them in the +-- @{OptionParser} spec. +-- +-- Like @{required}, this handler will store multiple occurrences of a +-- command-line option. +-- @static -- @tparam table arglist list of arguments -- @int i index of last processed element of `arglist` -- @param[opt=true] value either a function to process the option @@ -179,6 +221,28 @@ end --- Option at `arglist[i}` requires an argument. +-- +-- This is the handler automatically assigned to options that have +-- `--opt=ARG` style specifications in the @{OptionParser} spec argument. +-- You can also pass it as the `handler` argument to @{on} for options +-- you want to add manually without putting them in the @{OptionParser} +-- spec. +-- +-- Normally the value stored in the `opt` table by this handler will be +-- the string given as the argument to that option on the command line. +-- However, if the option is given on the command-line multiple times, +-- `opt["name"]` will end up with all those arguments stored in the +-- array part of a table: +-- +-- $ cat ./prog +-- ... +-- parser:on ({"-e", "-exec"}, required) +-- _G.arg, _G.opt = parser:parse (_G.arg) +-- print std.string.tostring (_G.opt.exec) +-- ... +-- $ ./prog -e '(foo bar)' -e '(foo baz)' -- qux +-- {1=(foo bar),2=(foo baz)} +-- @static -- @tparam table arglist list of arguments -- @int i index of last processed element of `arglist` -- @param[opt] value either a function to process the option argument, @@ -203,7 +267,16 @@ end --- Finish option processing --- Usually indicated by `--` at `arglist[i]`. +-- +-- This is the handler automatically assigned to the option written as +-- `--` in the @{OptionParser} spec argument. You can also pass it as +-- the `handler` argument to @{on} if you want to manually add an end +-- of options marker without writing it in the @{OptionParser} spec. +-- +-- This handler tells the parser to stop processing arguments, so that +-- anything after it will be an argument even if it otherwise looks +-- like an option. +-- @static -- @tparam table arglist list of arguments -- @int i index of last processed element of `arglist` -- @treturn int index of next element of `arglist` to process @@ -216,24 +289,42 @@ end --- Option at `arglist[i]` is a boolean switch. +-- +-- This is the handler automatically assigned to options that have +-- `--long-opt` or `-x` style specifications in the @{OptionParser} spec +-- argument. You can also pass it as the `handler` argument to @{on} for +-- options you want to add manually without putting them in the +-- @{OptionParser} spec. +-- +-- Beware that, _unlike_ @{required}, this handler will store multiple +-- occurrences of a command-line option as a table **only** when given a +-- `value` function. Automatically assigned handlers do not do this, so +-- the option will simply be `true` if the option was given one or more +-- times on the command-line. +-- @static -- @tparam table arglist list of arguments -- @int i index of last processed element of `arglist` -- @param[opt] value either a function to process the option argument, -- or a value to store when this flag is encountered -- @treturn int index of next element of `arglist` to process local function flag (self, arglist, i, value) + local opt = arglist[i] if type (value) == "function" then - value = value (self, opt, true) + set (self, opt, value (self, opt, true)) elseif value == nil then - value = true + local key = self[opt].key + self.opts[key] = true end - set (self, arglist[i], value) return i + 1 end --- Option should display help text, then exit. +-- +-- This is the handler automatically assigned tooptions that have +-- `--help` in the specification, e.g. `-h, -?, --help`. +-- @static -- @function help local function help (self) print (self.helptext) @@ -242,6 +333,10 @@ end --- Option should display version text, then exit. +-- +-- This is the handler automatically assigned tooptions that have +-- `--version` in the specification, e.g. `-V, --version`. +-- @static -- @function version local function version (self) print (self.versiontext) @@ -275,6 +370,11 @@ local boolvals = { --- Return a Lua boolean equivalent of various `optarg` strings. -- Report an option parse error if `optarg` is not recognised. +-- +-- Pass this as the `value` function to @{on} when you want various +-- *truthy* or *falsey* option arguments to be coerced to a Lua `true` +-- or `false` respectively in the options table. +-- @static -- @string opt option name -- @string[opt="1"] optarg option argument, must be a key in @{boolvals} -- @treturn bool `true` or `false` @@ -290,7 +390,11 @@ end --- Report an option parse error unless `optarg` names an -- existing file. +-- +-- Pass this as the `value` function to @{on} when you want to accept +-- only option arguments that name an existing file. -- @fixme this only checks whether the file has read permissions +-- @static -- @string opt option name -- @string optarg option argument, must be an existing file -- @treturn `optarg` @@ -311,6 +415,10 @@ end --- Report an option parse error, then exit with status 2. +-- +-- Use this in your custom option handlers for consistency with the +-- error output from built-in `optparse` error messages. +-- @static -- @string msg error message local function opterr (self, msg) local prog = self.program @@ -332,6 +440,18 @@ end --- Add an option handler. +-- +-- When the automatically assigned option handlers don't do everything +-- you require, or when you don't want to put an option into the +-- @{OptionParser} `spec` argument, use this function to specify custom +-- behaviour. If you write the option into the `spec` argument anyway, +-- calling this function will replace the automatically assigned handler +-- with your own. +-- +-- parser:on ("--", parser.finished) +-- parser:on ("-V", parser.version) +-- parser:on ("--config-file", parser.required, parser.file) +-- parser:on ("--enable-nls", parser.optional, parser.boolean) -- @function on -- @tparam[string|table] opts name of the option, or list of option names -- @tparam on_handler handler function to call when any of `opts` is @@ -376,7 +496,34 @@ end ------ -- Parsed options table, with a key for each encountered option, each --- with value set by that option's @{on_handler}. +-- with value set by that option's @{on_handler}. Where an option +-- has one or more long-options specified, the key will be the first +-- one of those with leading hyphens stripped and non-alphanumeric +-- characters replaced with underscores. For options that can only be +-- specified by a short option, the key will be the letter of the first +-- of the specified short options: +-- +-- {"-e", "--eval-file"} => opts.eval_file +-- {"-n", "--dryrun", "--dry-run"} => opts.dryrun +-- {"-t", "-T"} => opts.t +-- +-- Generally there will be one key for each previously specified +-- option (either automatically assigned by @{OptionParser} or +-- added manually with @{on}) containing the value(s) assigned by the +-- associated @{on_handler}. For automatically assigned handlers, +-- that means `true` for straight-forward flags and +-- optional-argument options for which no argument was given; or else +-- the string value of the argument passed with an option given only +-- once; or a table of string values of the same for arguments given +-- multiple times. +-- +-- ./prog -x -n -x => opts = { x = true, dryrun = true } +-- ./prog -e '(foo bar)' -e '(foo baz)' +-- => opts = {eval_file = {"(foo bar)", "(foo baz)"} } +-- +-- If you write your own handlers, or otherwise specify custom +-- handling of options with @{on}, then whatever value those handlers +-- return will be assigned to the respective keys in `opts`. -- @table opts @@ -411,7 +558,9 @@ local function parse (self, arglist) end end - return self.unrecognised, self.opts + -- metatable allows `io.warn` to find `parser.program` when assigned + -- back to _G.opts. + return self.unrecognised, setmetatable (self.opts, {__index = self}) end @@ -446,7 +595,8 @@ end --- Instantiate a new parser. -- Read the documented options from `spec` and return a new parser that -- can be passed to @{parse} for parsing those options from an argument --- list. +-- list. Options are recognised as lines that begin with at least two +-- spaces, followed by a hyphen. -- @static -- @string spec option parsing specification -- @treturn parser a parser for options described by `spec` diff --git a/lib/std/string.lua b/lib/std/string.lua index 08a6b9c..b11f135 100644 --- a/lib/std/string.lua +++ b/lib/std/string.lua @@ -82,21 +82,23 @@ local function finds (s, p, init, plain) end --- Split a string at a given separator. --- @todo Consider Perl and Python versions. --- @param s string to split --- @param sep separator pattern +-- Separator is a Lua pattern, so you have to escape active characters, +-- `^$()%.[]*+-?` with a `%` prefix to match a literal character in `s`. +-- @string s to split +-- @string[opt="%s*"] sep separator pattern +-- @return list of strings -- @return list of strings local function split (s, sep) - -- finds gets a list of {from, to, capt = {}} lists; we then - -- flatten the result, discarding the captures, and prepend 0 (1 - -- before the first character) and append 0 (1 after the last - -- character), and then read off the result in pairs. - local pairs = List.concat ({0}, List.flatten (finds (s, sep)), {0}) - local l = {} - for i = 1, #pairs, 2 do - table.insert (l, string.sub (s, pairs[i] + 1, pairs[i + 1] - 1)) + assert (type (s) == "string", + "bad argument #1 to 'split' (string expected, got " .. type (s) .. ")") + local b, len, t, patt = 0, #s, {}, "(.-)" .. sep + if sep == "" then patt = "(.)"; table.insert (t, "") end + while b <= len do + local e, n, m = string.find (s, patt, b + 1) + table.insert (t, m or s:sub (b + 1, len)) + b = n or len + 1 end - return l + return t end --- Require a module with a particular version. diff --git a/local.mk b/local.mk index 3e62865..4fe5628 100644 --- a/local.mk +++ b/local.mk @@ -29,7 +29,7 @@ LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" ## Bootstrap. ## ## ---------- ## -old_NEWS_hash = 7a7647cb5b2d5d886a18070e1f4ac5fd +old_NEWS_hash = 1a28799a850e021e45c3e98064a746d7 update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ diff --git a/specs/io_spec.yaml b/specs/io_spec.yaml index 4c82dbf..cc76e82 100644 --- a/specs/io_spec.yaml +++ b/specs/io_spec.yaml @@ -51,6 +51,57 @@ specify std.io: - describe die: + - before: + script = [[require "std.io".die "By 'eck!"]] + - it outputs a message to stderr: + expect (luaproc (script)).should_fail_with "By 'eck!\n" + - it ignores `prog.line` without `prog.file` or `prog.name`: + script = [[prog = { line = 125 };]] .. script + expect (luaproc (script)).should_fail_with "By 'eck!\n" + - it ignores `opts.line` without `opts.program`: + script = [[opts = { line = 99 };]] .. script + expect (luaproc (script)).should_fail_with "By 'eck!\n" + - it prefixes `prog.name` if any: | + script = [[prog = { name = "name" };]] .. script + expect (luaproc (script)).should_fail_with "name: By 'eck!\n" + - it appends `prog.line` if any, to `prog.name`: | + script = [[prog = { line = 125, name = "name" };]] .. script + expect (luaproc (script)).should_fail_with "name:125: By 'eck!\n" + - it prefixes `prog.file` if any: | + script = [[prog = { file = "file" };]] .. script + expect (luaproc (script)).should_fail_with "file: By 'eck!\n" + - it appends `prog.line` if any, to `prog.name`: | + script = [[prog = { file = "file", line = 125 };]] .. script + expect (luaproc (script)).should_fail_with "file:125: By 'eck!\n" + - it prefers `prog.name` to `prog.file` or `opts.program`: | + script = [[ + prog = { file = "file", name = "name" } + opts = { program = "program" } + ]] .. script + expect (luaproc (script)).should_fail_with "name: By 'eck!\n" + - it appends `prog.line` if any to `prog.name` over anything else: | + script = [[ + prog = { file = "file", line = 125, name = "name" } + opts = { line = 99, program = "program" } + ]] .. script + expect (luaproc (script)).should_fail_with "name:125: By 'eck!\n" + - it prefers `prog.file` to `opts.program`: | + script = [[ + prog = { file = "file" }; opts = { program = "program" } + ]] .. script + expect (luaproc (script)).should_fail_with "file: By 'eck!\n" + - it appends `prog.line` if any to `prog.file` over using `opts`: | + script = [[ + prog = { file = "file", line = 125 } + opts = { line = 99, program = "program" } + ]] .. script + expect (luaproc (script)).should_fail_with "file:125: By 'eck!\n" + - it prefixes `opts.program` if any: | + script = [[opts = { program = "program" };]] .. script + expect (luaproc (script)).should_fail_with "program: By 'eck!\n" + - it appends `opts.line` if any, to `opts.program`: | + script = [[opts = { line = 99, program = "program" };]] .. script + expect (luaproc (script)).should_fail_with "program:99: By 'eck!\n" - describe process_files: @@ -71,6 +122,54 @@ specify std.io: - describe warn: + - before: + script = [[require "std.io".warn "Ayup!"]] + - it outputs a message to stderr: + expect (luaproc (script)).should_output_error "Ayup!\n" + - it ignores `prog.line` without `prog.file`, `prog.name` or `opts.program`: + script = [[prog = { line = 125 };]] .. script + expect (luaproc (script)).should_output_error "Ayup!\n" + - it prefixes `prog.name` if any: | + script = [[prog = { name = "name" };]] .. script + expect (luaproc (script)).should_output_error "name: Ayup!\n" + - it appends `prog.line` if any, to `prog.name`: | + script = [[prog = { line = 125, name = "name" };]] .. script + expect (luaproc (script)).should_output_error "name:125: Ayup!\n" + - it prefixes `prog.file` if any: | + script = [[prog = { file = "file" };]] .. script + expect (luaproc (script)).should_output_error "file: Ayup!\n" + - it appends `prog.line` if any, to `prog.name`: | + script = [[prog = { file = "file", line = 125 };]] .. script + expect (luaproc (script)).should_output_error "file:125: Ayup!\n" + - it prefers `prog.name` to `prog.file` or `opts.program`: | + script = [[ + prog = { file = "file", name = "name" } + opts = { program = "program" } + ]] .. script + expect (luaproc (script)).should_output_error "name: Ayup!\n" + - it appends `prog.line` if any to `prog.name` over anything else: | + script = [[ + prog = { file = "file", line = 125, name = "name" } + opts = { line = 99, program = "program" } + ]] .. script + expect (luaproc (script)).should_output_error "name:125: Ayup!\n" + - it prefers `prog.file` to `opts.program`: | + script = [[ + prog = { file = "file" }; opts = { program = "program" } + ]] .. script + expect (luaproc (script)).should_output_error "file: Ayup!\n" + - it appends `prog.line` if any to `prog.file` over using `opts`: | + script = [[ + prog = { file = "file", line = 125 } + opts = { line = 99, program = "program" } + ]] .. script + expect (luaproc (script)).should_output_error "file:125: Ayup!\n" + - it prefixes `opts.program` if any: | + script = [[opts = { program = "program" };]] .. script + expect (luaproc (script)).should_output_error "program: Ayup!\n" + - it appends `opts.line` if any, to `opts.program`: | + script = [[opts = { line = 99, program = "program" };]] .. script + expect (luaproc (script)).should_output_error "program:99: Ayup!\n" - describe writelines: diff --git a/specs/optparse_spec.yaml b/specs/optparse_spec.yaml index a3547fb..c16829a 100644 --- a/specs/optparse_spec.yaml +++ b/specs/optparse_spec.yaml @@ -195,7 +195,7 @@ specify std.optparse: parser:on (]] .. onargstr .. [[) - local arg, opts = parser:parse (_G.arg) + _G.arg, _G.opts = parser:parse (_G.arg) o = {} for k, v in pairs (opts) do @@ -368,3 +368,60 @@ specify std.optparse: - it stops separating at an optional argument option: expect (parseargs ([[{"x", "this"}, parser.optional]], {"-bxbit"})). should_output "opts = { b = true, this = bit }\n" + + - context with io.die: + - before: | + runscript = function (code) + return luaproc ([[ + local OptionParser = require "std.optparse" + local parser = OptionParser ("program 0\nUsage: program\n") + _G.arg, _G.opts = parser:parse (_G.arg) + ]] .. code .. [[ + require "std.io".die "By 'eck!" + ]]) + end + - it prefers `prog.name` to `opts.program`: | + code = [[prog = { file = "file", name = "name" }]] + expect (runscript (code)).should_fail_with "name: By 'eck!\n" + - it prefers `prog.file` to `opts.program`: | + code = [[prog = { file = "file" }]] + expect (runscript (code)).should_fail_with "file: By 'eck!\n" + - it appends `prog.line` if any to `prog.file` over using `opts`: | + code = [[ + prog = { file = "file", line = 125 }; opts.line = 99]] + expect (runscript (code)).should_fail_with "file:125: By 'eck!\n" + - it prefixes `opts.program` if any: | + expect (runscript ("")).should_fail_with "program: By 'eck!\n" + - it appends `opts.line` if any, to `opts.program`: | + code = [[opts.line = 99]] + expect (runscript (code)). + should_fail_with "program:99: By 'eck!\n" + + - context with io.warn: + - before: | + runscript = function (code) + return luaproc ([[ + local OptionParser = require "std.optparse" + local parser = OptionParser ("program 0\nUsage: program\n") + _G.arg, _G.opts = parser:parse (_G.arg) + ]] .. code .. [[ + require "std.io".warn "Ayup!" + ]]) + end + - it prefers `prog.name` to `opts.program`: | + code = [[prog = { file = "file", name = "name" }]] + expect (runscript (code)).should_output_error "name: Ayup!\n" + - it prefers `prog.file` to `opts.program`: | + code = [[prog = { file = "file" }]] + expect (runscript (code)).should_output_error "file: Ayup!\n" + - it appends `prog.line` if any to `prog.file` over using `opts`: | + code = [[ + prog = { file = "file", line = 125 }; opts.line = 99]] + expect (runscript (code)). + should_output_error "file:125: Ayup!\n" + - it prefixes `opts.program` if any: | + expect (runscript ("")).should_output_error "program: Ayup!\n" + - it appends `opts.line` if any, to `opts.program`: | + code = [[opts.line = 99]] + expect (runscript (code)). + should_output_error "program:99: Ayup!\n" diff --git a/specs/spec_helper.lua.in b/specs/spec_helper.lua.in index 75b4232..bb0a7c0 100644 --- a/specs/spec_helper.lua.in +++ b/specs/spec_helper.lua.in @@ -14,13 +14,18 @@ local function mkscript (code) return f end -local function tabulate_output (code) +function luaproc (code) local f = mkscript (code) local proc = hell.spawn { LUA, f; env = { LUA_PATH=package.path, LUA_INIT="", LUA_INIT_5_2="" }, } os.remove (f) + return proc +end + +local function tabulate_output (code) + local proc = luaproc (code) if proc.status ~= 0 then return error (proc.errout) end local r = {} proc.output:gsub ("(%S*)[%s]*", @@ -118,28 +123,82 @@ end totable = (require "std.table").totable --- Custom matcher for set membership. +do + -- Custom matcher for set size and set membership. + + local set = require "std.set" + local util = require "specl.util" + local matchers = require "specl.matchers" + + local Matcher, matchers, q = + matchers.Matcher, matchers.matchers, matchers.stringify + + matchers.have_size = Matcher { + function (actual, expect) + local size = 0 + for _ in pairs (actual) do size = size + 1 end + return size == expect + end, + + actual = "table", + + format_expect = function (expect) + return " a table containing " .. expect .. " elements, " + end, + + format_any_of = function (alternatives) + return " a table with any of " .. + util.concat (alternatives, util.QUOTED) .. " elements, " + end, + } + + matchers.have_member = Matcher { + function (actual, expect) + return set.member (actual, expect) + end, + + actual = "set", + + format_expect = function (expect) + return " a set containing " .. q (expect) .. ", " + end, + + format_any_of = function (alternatives) + return " a set containing any of " .. + util.concat (alternatives, util.QUOTED) .. ", " + end, + } +end -local set = require "std.set" -local util = require "specl.util" -local matchers = require "specl.matchers" -local Matcher, matchers, q = - matchers.Matcher, matchers.matchers, matchers.stringify +do + --[[ ======================================= ]]-- + --[[ Remove this after Specl 11 is released. ]]-- + --[[ ======================================= ]]-- -matchers.have_member = Matcher { - function (actual, expect) - return set.member (actual, expect) - end, + -- Custom matcher for specl.shell failure with error message. - actual = "set", + local matchers = require "specl.matchers" + local Matcher, matchers, reformat = + matchers.Matcher, matchers.matchers, matchers.reformat - format_expect = function (expect) - return " a set containing " .. q (expect) .. ", " - end, + matchers.fail_with = matchers.fail_with or Matcher { + function (actual, expect) + return (actual.status ~= 0) and (actual.errout == expect) + end, - format_any_of = function (alternatives) - return " a set containing any of " .. - util.concat (alternatives, util.QUOTED) .. ", " - end, -} + actual_type = "Process", + + format_actual = function (process) + return ":" .. reformat (process.errout) + end, + + format_expect = function (expect) + return " error output: " .. reformat (expect) + end, + + format_alternatives = function (adaptor, alternatives) + return " error output:" .. reformat (alternatives, adaptor) + end, + } +end diff --git a/specs/string_spec.yaml b/specs/string_spec.yaml index e141a41..e061eab 100644 --- a/specs/string_spec.yaml +++ b/specs/string_spec.yaml @@ -415,17 +415,36 @@ specify std.string: target = { "first", "the second one", "final entry" } subject = table.concat (target, ", ") f = M.split + - it returns a one-element list for an empty string: + expect (f ("", ", ")).should_equal {""} - it makes a table of substrings delimited by a separator: expect (f (subject, ", ")).should_equal (target) + - it returns n+1 elements for n separators: + expect (f (subject, "zero")).should_have_size (1) + expect (f (subject, "c")).should_have_size (2) + expect (f (subject, "s")).should_have_size (3) + expect (f (subject, "t")).should_have_size (4) + expect (f (subject, "e")).should_have_size (5) + - it returns an empty string element for consecutive separators: + expect (f ("xyzyzxy", "yz")).should_equal {"x", "", "xy"} + - it returns an empty string element when starting with separator: + expect (f ("xyzyzxy", "xyz")).should_equal {"", "yzxy"} + - it returns an empty string element when ending with separator: + expect (f ("xyzyzxy", "zxy")).should_equal {"xyzy", ""} + - it returns a table of 1-character strings for "" separator: + expect (f ("abcdef", "")).should_equal {"", "a", "b", "c", "d", "e", "f", ""} - it is available as a string metamethod: expect (subject:split ", ").should_equal (target) - expect (("/foo/bar/baz.quux"):split "/").should_equal {"", "foo", "bar", "baz.quux"} + expect (("/foo/bar/baz.quux"):split "/"). + should_equal {"", "foo", "bar", "baz.quux"} - the original subject is not perturbed: original = subject newstring = f (subject, "e") expect (subject).should_be (original) - - "it diagnoses non-string arguments": - expect (f ("a string")).should_error ("string expected") + - it takes a Lua pattern as a separator: + expect (f (subject, "%s+")). + should_equal {"first,", "the", "second", "one,", "final", "entry"} + - it diagnoses non-string arguments: expect (f (nil, ",")).should_error ("string expected") expect (f ({"a table"}, ",")).should_error ("string expected") diff --git a/specs/tree_spec.yaml b/specs/tree_spec.yaml index d9ec245..ca0c8b7 100644 --- a/specs/tree_spec.yaml +++ b/specs/tree_spec.yaml @@ -205,7 +205,8 @@ specify std.tree: for v in f {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} do l[1+#l]=v end - expect (l).should_contain.all_of {"one", 2, "three", 4, "bar", "five"} + expect (l).should_contain. + a_permutation_of {"one", 2, "three", 4, "bar", "five"} - it works on trees too: for v in f (Tree {Tree {"one", Tree {two=2}, @@ -215,7 +216,8 @@ specify std.tree: do l[1+#l]=v end - expect (l).should_contain.all_of {"one", 2, "three", 4, "bar", "five"} + expect (l).should_contain. + a_permutation_of {"one", 2, "three", 4, "bar", "five"} - it diagnoses non-table arguments: expect (f ()).should_error ("table expected") expect (f "string").should_error ("table expected") @@ -293,33 +295,33 @@ specify std.tree: -- even that the array elements are visited in order! subject = {"first", "second"; third = "3rd"} expect (traverse (subject)).should_contain. - all_of {{"branch", {}, subject}, -- { - {"leaf", {1}, subject[1]}, -- first, - {"leaf", {2}, subject[2]}, -- second, - {"leaf", {"third"}, subject["third"]}, -- 3rd - {"join", {}, subject}} -- } + a_permutation_of {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"leaf", {"third"}, subject["third"]}, -- 3rd + {"join", {}, subject}} -- } - it includes hash parts of a nested table argument: | -- like `pairs`, `nodes` can visit elements in any order, so we cannot -- guarantee the array part is always visited before the hash part, or -- even that the array elements are visited in order! subject = {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} expect (traverse (subject)).should_contain. - all_of {{"branch", {}, subject}, -- { - {"branch", {1}, subject[1]}, -- { - {"leaf", {1,1}, subject[1][1]}, -- one, - {"branch", {1,2}, subject[1][2]}, -- { - {"leaf", {1,2,"two"}, subject[1][2]["two"]}, -- 2, - {"join", {1,2}, subject[1][2]}, -- }, - {"branch", {1,3}, subject[1][3]}, -- { - {"branch", {1,3,1}, subject[1][3][1]}, -- { - {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, - {"join", {1,3,1}, subject[1][3][1]}, -- }, - {"leaf", {1,3,"four"}, subject[1][3]["four"]}, -- 4, - {"join", {1,3}, subject[1][3]}, -- }, - {"join", {1}, subject[1]}, -- }, - {"leaf", {2}, subject[2]}, -- five, - {"leaf", {"foo"}, subject["foo"]}, -- bar, - {"join", {}, subject}} -- } + a_permutation_of {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,"two"}, subject[1][2]["two"]}, -- 2, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,"four"}, subject[1][3]["four"]}, -- 4, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"leaf", {"foo"}, subject["foo"]}, -- bar, + {"join", {}, subject}} -- } - it works on trees too: | -- like `pairs`, `nodes` can visit elements in any order, so we cannot -- guarantee the array part is always visited before the hash part, or @@ -330,22 +332,22 @@ specify std.tree: foo="bar", "five"} expect (traverse (subject)).should_contain. - all_of {{"branch", {}, subject}, -- { - {"branch", {1}, subject[1]}, -- { - {"leaf", {1,1}, subject[1][1]}, -- one, - {"branch", {1,2}, subject[1][2]}, -- { - {"leaf", {1,2,"two"}, subject[1][2]["two"]}, -- 2, - {"join", {1,2}, subject[1][2]}, -- }, - {"branch", {1,3}, subject[1][3]}, -- { - {"branch", {1,3,1}, subject[1][3][1]}, -- { - {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, - {"join", {1,3,1}, subject[1][3][1]}, -- }, - {"leaf", {1,3,"four"}, subject[1][3]["four"]}, -- 4, - {"join", {1,3}, subject[1][3]}, -- }, - {"join", {1}, subject[1]}, -- }, - {"leaf", {2}, subject[2]}, -- five, - {"leaf", {"foo"}, subject["foo"]}, -- bar, - {"join", {}, subject}} -- } + a_permutation_of {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,"two"}, subject[1][2]["two"]}, -- 2, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,"four"}, subject[1][3]["four"]}, -- 4, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"leaf", {"foo"}, subject["foo"]}, -- bar, + {"join", {}, subject}} -- } - it generates path key-lists that are valid __index arguments: | pending "std.tree.__index handling empty list keys" subject = Tree {"first", Tree {"second"}, "3rd"} diff --git a/stdlib-37-1.rockspec b/stdlib-38-1.rockspec similarity index 95% rename from stdlib-37-1.rockspec rename to stdlib-38-1.rockspec index 3f12722..505d9ef 100644 --- a/stdlib-37-1.rockspec +++ b/stdlib-38-1.rockspec @@ -1,5 +1,5 @@ package = "stdlib" -version = "37-1" +version = "38-1" description = { detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://rrthomas.github.io/lua-stdlib", @@ -7,8 +7,8 @@ description = { summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v37", - url = "http://github.com/rrthomas/lua-stdlib/archive/release-v37.zip", + dir = "lua-stdlib-release-v38", + url = "http://github.com/rrthomas/lua-stdlib/archive/release-v38.zip", } dependencies = { "lua >= 5.1", From c8327639c4f5f785c79e18a2596b4a916ca13635 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Wed, 23 Apr 2014 18:17:22 +0700 Subject: [PATCH 24/34] Release v39. Signed-off-by: Gary V. Vaughan --- .travis.yml | 10 +- ChangeLog | 539 ++++++++++++++----- Makefile.in | 14 +- NEWS | 98 ++++ README | 10 +- bootstrap | 2 +- bootstrap.conf | 5 +- build-aux/release.mk | 8 +- configure | 38 +- configure.ac | 2 +- doc/classes/std.container.html | 2 +- doc/classes/std.list.html | 4 +- doc/classes/std.object.html | 2 +- doc/classes/std.optparse.html | 10 +- doc/classes/std.set.html | 6 +- doc/classes/std.strbuf.html | 2 +- doc/classes/std.tree.html | 2 +- doc/index.html | 2 +- doc/modules/std.debug.html | 2 +- doc/modules/std.functional.html | 68 ++- doc/modules/std.html | 2 +- doc/modules/std.io.html | 4 +- doc/modules/std.math.html | 2 +- doc/modules/std.package.html | 241 ++++++++- doc/modules/std.strict.html | 2 +- doc/modules/std.string.html | 120 ++--- doc/modules/std.table.html | 41 +- lib/std.lua | 8 +- lib/std.lua.in | 6 + lib/std/base.lua | 34 +- lib/std/container.lua | 30 +- lib/std/functional.lua | 50 +- lib/std/io.lua | 6 +- lib/std/list.lua | 2 +- lib/std/optparse.lua | 45 +- lib/std/package.lua | 157 +++++- lib/std/set.lua | 4 +- lib/std/string.lua | 100 ++-- lib/std/table.lua | 49 +- lib/std/tree.lua | 2 +- local.mk | 11 +- rockspec.conf | 4 +- specs/base_spec.yaml | 49 ++ specs/container_spec.yaml | 68 ++- specs/debug_spec.yaml | 8 +- specs/functional_spec.yaml | 42 +- specs/io_spec.yaml | 68 ++- specs/list_spec.yaml | 234 ++++---- specs/math_spec.yaml | 14 +- specs/object_spec.yaml | 147 +++-- specs/optparse_spec.yaml | 328 ++++++----- specs/package_spec.yaml | 152 +++++- specs/set_spec.yaml | 197 ++++--- specs/spec_helper.lua.in | 56 +- specs/specs.mk | 8 +- specs/std_spec.yaml | 6 +- specs/strbuf_spec.yaml | 55 +- specs/string_spec.yaml | 276 +++++----- specs/table_spec.yaml | 200 ++++--- specs/tree_spec.yaml | 297 +++++----- stdlib-38-1.rockspec => stdlib-39-1.rockspec | 8 +- travis.yml.in | 10 +- 62 files changed, 2595 insertions(+), 1374 deletions(-) create mode 100644 specs/base_spec.yaml rename stdlib-38-1.rockspec => stdlib-39-1.rockspec (87%) diff --git a/.travis.yml b/.travis.yml index 4a5973e..30c24f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ env: - PACKAGE=stdlib - ROCKSPEC=$PACKAGE-git-1.rockspec - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - - LUAROCKS_BASE=luarocks-2.1.1 + - LUAROCKS_BASE=luarocks-2.1.2 - LUAROCKS="$LUA $HOME/bin/luarocks" matrix: - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 @@ -29,11 +29,13 @@ install: # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz + # LuaRocks configure --with-lua argument is just a prefix! - ( cd $LUAROCKS_BASE; ./configure - --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX - --with-lua-include=$LUA_INCDIR; - make all install; ) + --prefix=$HOME --with-lua=/usr --lua-version=$LUA_SUFFIX + --lua-suffix=$LUA_SUFFIX --with-lua-include=$LUA_INCDIR; + make build; + make install; ) # Configure and build. script: diff --git a/ChangeLog b/ChangeLog index 09c2075..eaaa3ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,272 @@ +2014-04-23 Gary V. Vaughan + + Release v39. + + Release version 39 + * NEWS: Record release date. + + string: leave global string metatable alone. + Close #30. + * lib/std/string.lua (__append, __concat, __index): Move these + metamethods together at the start of the file, and store them in + the returned module table rather than setting them in the global + string metatable. + Improve header comments, to describe namespace issues. + * lib/std.lua.in: Set string metatable elements from string module + as before. + * specs/string_spec.yaml: Adjust to compensate for changes in + returned string module table. + * NEWS: Update. + + specs: no need to explicitly require spec_helper any more. + Since Specl 11, every spec-file automatically loads the + spec_helper.lua from the same directory, if any. + * specs/container_spec.yaml, specs/debug_spec.yaml, + specs/functional_spec.yaml, specs/io_spec.yaml, + specs/list_spec.yaml, specs/math_spec.yaml, + specs/object_spec.yaml, specs/optparse_spec.yaml, + specs/package_spec.yaml, specs/set_spec.yaml, + specs/strbuf_spec.yaml, specs/string_spec.yaml, + specs/table_spec.yaml, specs/tree_spec.yaml: Remove explicit + `require "spec_helper"`. + + specs: take advantage of improvements to Specl DSL. + * specs/container_spec.yaml, specs/debug_spec.yaml, + specs/functional_spec.yaml, specs/io_spec.yaml, + specs/list_spec.yaml, specs/math_spec.yaml, + specs/object_spec.yaml, specs/optparse_spec.yaml, + specs/package_spec.yaml, specs/set_spec.yaml, + specs/std_spec.yaml, specs/strbuf_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml, + specs/tree_spec.yaml: Use `not_to_` instead of `should_not`, + `to_` instead of `should_` and `to_copy` instead of + `should_equal` plus `should_not_be`. + +2014-04-22 Gary V. Vaughan + + maint: update raw urls to new github url scheme. + * README.md: Use new `raw.githubusercontent.com` url scheme + throughout. + + maint: regenerate spec_helper.lua for `make check` if necessary. + * specs/specs.mk (specl-check-local): Add dependency on + specs/spec_helper.lua, so that it is regenerated before the main + `check-local` body is executed if necessary. + + specs: capture stub should return nil to match Specl 12. + * specs/spec_helper.lua.in (capture): Return `nil` for stdout + and stderr to match Specl 12 API. + * specs/table_spec.yaml (clone_rename): Test for `nil`. + + specs: skip deprecation warning expectation when Specl < 12. + * specs/table_spec.yaml (clone_rename): Skip deprecation warning + expectation when the ""-returning stub is being used. + + specs: return empty out and err values from `capture` stub. + * specs/spec_helper.lua.in (table.clone_rename): Return empty + strings for stderr and stdout from fallback stubbed `capture` + implementation. + + specs: elide clone_rename deprecation warning, with Specl 12. + Fix #54. + * specs/spec_helper.lua.in (capture): Stub inprocess.capture if + installed Specl is too old to implement it. + * specs/table_spec.yaml (clone_rename): Wrap clone_rename in + inprocess.capture to elide deprecation warning on stderr. + + refactor: restore alphabetical ordering to table specs. + * specs/table_spec.yaml (clone_rename): Move back into alpha- + betical order. + +2014-04-21 Gary V. Vaughan + + maint: move repository to its own project. + * README.md, configure.ac, rockspec.conf, + * specs/optparse_spec.yaml: Replace rrthomas with lua-stdlib. + + specs: ignore local LUA_INIT and LUA_INIT_5_2 settings. + Fix #53. + * specs/specs.mk (SPECL_ENV): Until the next Specl release is + available, manually reset LUA_INIT and LUA_INIT_5_2. + * bootstrap.conf (buildreq): Add a reminder to clean up after + Specl 12. + +2014-04-21 Reuben Thomas + + Reverse order of arguments to functional.compose; closes #52 + +2014-04-21 Gary V. Vaughan + + tree: return tree root from tree[{}]. + Fix #41. + * specs/tree_spec.yaml (returns tree root for an empty list): New + specification. + * lib/std/tree.lua (__index): Allow empty list as a valid key. + * specs/tree_spec.yaml (std.tree): Remove pending call for + newly passing examples. + * NEWS: Update. + + table: no need to pull all of std.list into memory. + * lib/std/table (elems): Capture base.elems in a local. + (clone_select): Use it. + +2014-04-21 Reuben Thomas + + Modify API of functional.bind, and add spec; closes #48 + + Add a missing require to table.lua + + Add clone_select, closing #50. + + Don’t imply that clone requires its nometa argument to be the literal `true`, thereby blessing our use of string "nometa" argument. + + Remove comment that gives a false impression that the behaviour is there to support backwards-compatibility, whereas in fact it’s necessary for the current API. + +2014-04-21 Gary V. Vaughan + + container: discard unmapped positional parameters. + Fix #35. + * lib/std/container.lua (mapfields): When `map` argument is + given, discard unmapped positional parameters. + (metatable._init): Remove to imply a `nil` value (copy all + fields), because `{}` now discards all positional parameters. + (metatable.__call): Reverse type check of `_init`, so that + mapfields is still called when _init is `nil`. + * specs/object_spec.yaml (std.object): Remove pending call from + newly passing examples. + * NEWS: Update. + + tree: always return nil for non-existent key path. + Fix #39. + * lib/std/functional.lua (function.op["[]"]): Return nil instead + of dereferencing a nil valued table argument. + * specs/tree_spec.yaml (std.tree): Remove pending call prior to + newly passing example. + + functional: handle false valued elements correctly in `map`. + Fix #34. + * lib/std/functional.lua (map): Also insert `false` values into + the results table. + * specs/list_spec.yaml (std.list): Remove pending call from newly + passing example. + +2014-04-16 Gary V. Vaughan + + table: fold `clone_rename` into `clone`. + * specs/table_spec.yaml (std.table): Specify new behaviour with + optional `map` argument. + * lib/std/base.lua (clone): Implement new behaviours. + * lib/std/table.lua (clone_rename): Add deprecation warning, and + move out of the LDoc export table. + (clone): Update doc-comments. + * NEWS: Update. + + base: provide a deprecation mechanism for gentle API upgrades. + * specs/base_spec.yaml: New file. Specify behaviour for a + deprecation wrapper. + * specs/specs.mk (specl_SPECS): Add base_spec.yaml. + * lib/std/base.lua (deprecate): New function. Implement the + specification. + + maint: remove trailing whitespace in NEWS. + * NEWS: Remove trailing whitespace. + + specs: set package.path for in tree specl calls. + Specl 11 works well when called directly in a project root dir, + eg. `specl -freport -v1`, but only if the package path is set + appropriately in each `spec_helper.lua` or similar. + * specs/spec_helper.lua.in: Use `package.normalize` to safely + inject ./lib/?.lua into the head of package.path. + +2014-04-16 Reuben Thomas + + Fix a comment typo + + Fix a comment typo + +2014-04-15 Gary V. Vaughan + + slingshot: sync with upstream. + * slingshot: Sync with latest upstream master. + * bootstrap: Update from slingshot. + * .travis.yml: Regenerate. + + specs: update custom matchers for Specl 11. + * bootstrap.conf (buildreq): Bump specl minimum version to 11. + * specs/spec_helper.lua (matchers.have_size, matchers.have_member): + Matcher object functions require an initial `self` parameter. + (matchers.fail_with): Remove. + + specs: fix a typo; there is no 'a' in should_output. + * specs/optparse_spec.yaml: Fix a typo. + +2014-04-15 Reuben Thomas + + Fix a comment typo + + Fix documentation of table.clone_rename: the parameters got swapped during the earlier re-org + +2014-02-06 Gary V. Vaughan + + package: new path management apis. + * specs/package_spec.yaml: Specify behaviour of new apis. + * lib/std/io.lua (pathsep): Recalculate rather than introduce a + require loop with std.package. + * lib/std/package.lua (find, insert, mappath, normalize, remove): + New functions for maintaining clean pathstrings. + * NEWS: Update. + + functional: new `case` module function. + * specs/functional_spec.yaml: Add specifications for a `case` + function. + * lib/std/functional.lua (case): New function. + * NEWS: Update. + +2014-02-05 Gary V. Vaughan + + optparse: simplify default option setting. + * specs/optparse_spec.yaml: Specify behaviour of new option + defaults parameter. + * lib/std/optparse.lua (parser): Add an optional default options + parameter. + * NEWS: Update. + +2014-02-03 Gary V. Vaughan + + configury: use a sentinel file for multi-target rules. + With thanks to + http://stackoverflow.com/questions/17216048/parallel-gnu-make-and-rules-that-create-several-targets-at-once + * local.mk (ldoc_DEPS): Remove. + $(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): + Depend on sentinel file. + ($(srcdir)/doc): Make and populate doc tree atomically for + parallel make. + + configury: be nicer to parallel make. + * local.mk ($(srcdir)/doc): Factor out of... + ($(dist_doc_DATA)): ...here. + (ldoc_DEPS): Add $(srcdir)/doc. + +2014-02-01 Gary V. Vaughan + + optparse: fix a parse error with unhandled opt in combined options. + * specs/optparse_spec.yaml: Add specifications for behaviour + when encountering unhandled options in various circumstances. + * lib/std/optparse.lua (normalise): Meet specifications. + * NEWS: Update. + + specs: remove last vestiges of optparse's specl origins. + * specs/optparse_spec.yaml (std.optparse): Update category, bug + address, and copyright to be stdlib appropriate. + 2014-01-30 Gary V. Vaughan + maint: post-release administrivia. + * configure.ac (AC_INIT): Bump release number to 39. + * NEWS: Add header line for next release. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + Release version 38 * NEWS: Record release date. @@ -71,7 +338,7 @@ * lib/std/io.lua (warn): Adjust to work properly with new specs. * NEWS: Update. -2014-01-24 Gary V. Vaughan +2014-01-23 Gary V. Vaughan container: inline calls to `empty`. * lib/std/container (mapfields, metatable._init): Replace @@ -104,8 +371,6 @@ Add appropriate LDocs. * NEWS: Update. -2014-01-23 Gary V. Vaughan - container: distinguish between the two `functions` tables. One is the core of Container with metatable as its metatable; the other is metatable._functions, and is just a list of unpropagated @@ -130,7 +395,7 @@ * lib/std/optparse.lua: Vastly improve optparse LDocs. * NEWS: Update. -2014-01-21 Reuben Thomas +2014-01-20 Reuben Thomas optparse.lua: move "default" options to bottom of help A more standard position. @@ -403,6 +668,8 @@ * specs/set_spec.yaml: Write "shows the type name" instead of "contains the type". +2013-12-10 Gary V. Vaughan + refactor: automatically fill method functions form _functions table. * lib/std/container.lua (metatable.__call): Copy entries from newly passed _functions table to object. @@ -417,8 +684,6 @@ Change object methods to Container style prototype functions. * NEWS: Update. -2013-12-10 Gary V. Vaughan - list: remove trailing whitespace. * lib/std/list.lua: Remove trailing whitespace. @@ -758,7 +1023,7 @@ * specs/spec_helper.lua: Fix table_ext reference for name change to straight table. -2013-05-30 Gary V. Vaughan +2013-05-29 Gary V. Vaughan object: __tostring should call __totable metamethod, not method. * lib/std/object.lua (new.__tostring): Because we have to set a @@ -767,7 +1032,7 @@ __totable (self). Use the longhand so that __tostring calls the right function in both cases. -2013-05-23 Gary V. Vaughan +2013-05-22 Gary V. Vaughan travis: use specl from git until specl 8 is released. * .travis.yml: Fetch the rockspec from github. Install it. @@ -790,8 +1055,6 @@ all elements already be strings, so call tostring on the array part of the object table before passing to table.concat. -2013-05-22 Gary V. Vaughan - object: respond to tostring() with stringified table of non-hidden fields. Rather than add individual __tostring metamethods to every object type, implement a general stringification algorithm in the base @@ -916,6 +1179,8 @@ * specs/object_spec.yaml: Adjust. * NEWS: Update. +2013-05-15 Gary V. Vaughan + set: derive from `std.object.Object`. * specs/set_spec.yaml: Describe expected behaviour of set as an Object. @@ -931,8 +1196,6 @@ `new` function. * NEWS: Update. -2013-05-15 Gary V. Vaughan - strbuf: derive from `std.object.Object`. * specs/strbuf_spec.yaml: Describe expected behaviour of strbuf as an Object. @@ -943,6 +1206,8 @@ `new` function. * NEWS: Update. +2013-05-14 Gary V. Vaughan + object: bake in inherited object type names. * specs/object_spec.yaml: New file. Examples of how typed objects should behave. @@ -957,14 +1222,12 @@ Return the public interface table, with a `__call`able metatable that delegates to Object for instantiation. -2013-05-14 Gary V. Vaughan - configury: bump minimum specl version to release 7. Specl 6 has a bug in `should_contain` matcher that makes the package_ext checks fail spuriously. * configure.ac (SPECL_MIN): Bump to 7. -2013-05-13 Gary V. Vaughan +2013-05-12 Gary V. Vaughan string_ext: make escape_pattern compatible with Lua 5.2. Lua 5.2 complains of an illegal character if a non-pattern meta @@ -974,8 +1237,6 @@ code to match. * NEWS: Update. -2013-05-12 Gary V. Vaughan - refactor: move base.lua methods to more appropriate modules. Move things around to remove more trampling of _G, and break the remaining dependency loops, so that modules can all be required @@ -1120,6 +1381,8 @@ * .gitignore: Update. * .travis.yml: Regenerate. +2013-05-05 Gary V. Vaughan + slingshot: add slingshot as a git submodule. * .gitmodules: New file. * slingshot: New submodule. @@ -1144,18 +1407,18 @@ Remove non-core modules, which go into separate lua-rrtlib for ad-hoc modules -2013-04-12 Gary V. Vaughan +2013-04-11 Gary V. Vaughan specs: upgrade to Specl 5. * specs/string_ext_spec.yaml, specs/table_ext_spec.yaml: Update all 'should_error' matchers to saner Specl 5 ordering. * specs/specs.mk (SPECL_MIN): Bump to 5. -2013-04-11 Gary V. Vaughan - getopt: also requires io_ext module to be loaded. * std/getopt.lua: Load io_ext into a local table. +2013-04-10 Gary V. Vaughan + configury: install correctly with configure or luarocks. For the classic './configure; make; make install' to work we need to install to '$luadir' as discovered by ax_lua.m4. But we also @@ -1325,7 +1588,7 @@ * std/std.lua.in: Strip "std." prefix before injecting required symbols into global namespace. -2013-03-30 Gary V. Vaughan +2013-03-29 Gary V. Vaughan maint: support rerunning check-local in multiple lua environments. * .luamultienv: Example multienv runner. @@ -1333,8 +1596,6 @@ (MULTICHECK): Location of multicheck script. (check-local): Run multicheck without looping, if present. -2013-03-29 Gary V. Vaughan - getopt: ensure we find _G.arg from Specl nested setfenv environments. (issue #27) Although only necessary for Lua 5.1, this fix is harmless for Lua 5.2, and we support both! @@ -1392,6 +1653,8 @@ (MKROCKSPECS): Now uses lua-stdlib from the build tree, not the previously installed version. +2013-03-25 Gary V. Vaughan + debug_ext: don't perturb the global environment by default. For backwards compatibility, `require "std"` will still write symbols into the global environment, but when loaded directly be @@ -1495,7 +1758,7 @@ configury: bump release number to 35. * configure.ac (AC_INIT): Bump release number to 35. -2013-03-25 Gary V. Vaughan +2013-03-24 Gary V. Vaughan configury: warn if `make check` needs a newer Specl. * Makefile.am (SPECL_MIN): Oldest release capable of running our @@ -1514,18 +1777,18 @@ maint: revert premature merge of pull request #23. Reverse apply 5508adb. -2013-03-24 Reuben Thomas +2013-03-23 Reuben Thomas README: make formatting consistent GNUmakefile: change to using a separate checkout for release branch -2013-03-16 Reuben Thomas +2013-03-15 Reuben Thomas Merge pull request #23 from rrthomas/gary/ext-hygiene package_ext: don't perturb the global environment by default. -2013-03-16 Gary V. Vaughan +2013-03-15 Gary V. Vaughan package_ext: don't perturb the global environment by default. For backwards compatibility, `require "std"` will still write @@ -1539,8 +1802,6 @@ * specs/package_ext_spec.yaml: Specify new behaviour, being careful about `require "std"` side-effects. -2013-03-15 Gary V. Vaughan - string_ext: fix a bad assumption in a spec example. Running string.format in the expectation `should` uses the core Lua string.format which doesn't prettify tables, but we're @@ -1596,6 +1857,8 @@ * Makeflie.am (SPECS): Remove old _spec.lua filenames, and add new _spec.yaml filenames. +2013-03-06 Gary V. Vaughan + specs: allow for package.config differences in Lua 5.1. * specs/package_ext_spec.lua (it splits package.config up): Allow for optional trailing \n present in 5.2 but not 5.1. @@ -1637,7 +1900,7 @@ a copy of each file name, so no need to make assumptions about global variables in here. -2013-02-24 Gary V. Vaughan +2013-02-23 Gary V. Vaughan specs: add a skeleton specl spec for getopt module. * src/getopt.lua (test): Remove. @@ -1701,7 +1964,7 @@ string_ext.lua: fix a reference to string.sub. -2013-02-23 Gary V. Vaughan +2013-02-22 Gary V. Vaughan string_ext: prefer snake_case to camelCase APIs. * src/string_ext.lua (escapePattern, escapeShell, ordinalSuffix): @@ -1738,13 +2001,13 @@ * specs/string_ext_spec.lua (describe string.ordinalSuffix): Make the expectations match reality. -2013-02-23 Reuben Thomas +2013-02-22 Reuben Thomas Fix ordinalSuffix for negative arguments (issue #20). string_ext.lua: use Lua terminology "pattern" rather than "regex" -2013-02-23 Gary V. Vaughan +2013-02-22 Gary V. Vaughan specs: add specl specification for string_ext module. * specs/string_ext_spec.lua: New file. Specl specs for @@ -1759,8 +2022,6 @@ * string_ext.lua (ordinalSuffix): Use '%' operator instead of math.mod, which is compatible with Lua 5.1 and 5.2. -2013-02-22 Gary V. Vaughan - maint: move maintainer rules into GNUmakefile. * Makefile.am: Move maintainer rules from here... * GNUmakefile.am: New file. ...to here. @@ -1788,6 +2049,8 @@ configury: bump release number to 32. * configure.ac (AC_INIT): Bump release number to 32. +2013-02-21 Gary V. Vaughan + specs: add specl specification for package_ext module. * specs/package_ext_spec.lua: New file. Specl specs for package_ext. @@ -1925,6 +2188,8 @@ of interfaces, per lua 5.2 module style. Adjust all callers. +2013-02-11 Gary V. Vaughan + maint: update mbox to use lua 5.2 style modules. * src/mbox.lua: Declare parse locally, and return a table with a reference, per lua 5.2 module style. @@ -1962,8 +2227,6 @@ * src/set.lua: Declare everything locally, and return a table of interfaces, per lua 5.2 module style. -2013-02-11 Gary V. Vaughan - configury: fix hard dependency on luadocs. * m4/ax_with_prog.m4: New file. * configure.ac (AX_WITH_PROG): Use it to find a luadocs binary. @@ -1979,12 +2242,10 @@ outdated versions from the lua installation. (rockspecs): Run lua with LUA_ENV set. -2013-02-10 Reuben Thomas +2013-02-09 Reuben Thomas rockspecs.lua: add luadoc as a dependency for git rockspec. -2013-02-09 Reuben Thomas - rockspecs.lua: fix build command for building from git. mkrockspecs.lua: whitespace fix. @@ -1993,20 +2254,20 @@ tree.lua: add tree.merge. +2013-02-08 Reuben Thomas + set.lua: fix broken elems iterator (issue #10) strict.lua: tweak formatting to match other modules base.lua: note availability of original tostring as _tostring. -2013-02-08 Reuben Thomas +2013-02-07 Reuben Thomas set.lua: add missing dependency on list.lua Avoid rebuilding documentation in distributed sources, so users don't need luadoc installed. -2013-02-07 Reuben Thomas - Makefile.am: some more fixups to release-by-git. .gitignore: we have reverted from zip to tgz tarballs. @@ -2027,13 +2288,15 @@ Makefile.am: enable building of documentation from git checkout. +2013-02-06 Reuben Thomas + Change to building (with LuaRocks) direct from git, not releasing a zip. README: update installation instructions and mention GitHub, not LuaForge. Update to latest ax_lua.m4. -2013-02-06 Reuben Thomas +2013-02-05 Reuben Thomas README: Make Lua 5.2 compatibility definite, and update copyright years. @@ -2041,7 +2304,7 @@ stdlib.rockspec.in: remove redundant dir setting -2012-10-31 Reuben Thomas +2012-10-30 Reuben Thomas .gitignore: add luarocks directory @@ -2065,7 +2328,7 @@ Bump version to 28, and simplify slightly, requiring automake 1.11 -2012-10-16 Reuben Thomas +2012-10-15 Reuben Thomas base.lua: move a documentation stanza to a more apt location @@ -2113,30 +2376,30 @@ set.lua: revert elements iterator to being pairs; leaves is wrong! -2012-09-13 Reuben Thomas +2012-09-12 Reuben Thomas Turn on debugging by default and tweak what the global debug function does. -2012-09-13 Reuben Thomas +2012-09-12 Reuben Thomas I misunderstood what finds did, and didn't spot that it was needed for split! Revert "string_ext: remove finds; map should be used with string.find instead" This reverts commit 5a62e3ee7ad2514b681ff6f348c43b797088b089. -2012-09-12 Reuben Thomas +2012-09-11 Reuben Thomas string_ext: remove finds; map should be used with string.find instead -2012-09-07 Reuben Thomas +2012-09-06 Reuben Thomas Remove string.gsubs: the order of substitutions was undefined, and map can be used just as well. -2012-07-07 Reuben Thomas +2012-07-06 Reuben Thomas build: Check MD5 sum of rockspec against tarball before releasing -2012-06-01 Reuben Thomas +2012-05-31 Reuben Thomas object: fix an incorrect simplification in the previous commit. @@ -2155,7 +2418,7 @@ parser.lua: fix call to renamed method. -2012-05-30 Reuben Thomas +2012-05-29 Reuben Thomas object.lua: fix inconsistency and missing HTML close tag in doc comments. @@ -2178,7 +2441,7 @@ Reformat some code to make lua-mode happier (most of the time, sigh). -2012-02-23 Gary V. Vaughan +2012-02-22 Gary V. Vaughan AUTHORS: Add myself. * AUTHORS: List the few small contributions I've made. @@ -2229,11 +2492,13 @@ string_ext: fix new string.__concat metamethod to run tostring on both args, thus avoiding infinite recursion. +2012-01-17 Reuben Thomas + string_ext: add __concat metamethod for strings which runs tostring. Reformat some code to please lua-mode and add some missing quotes in a comment. -2012-01-10 Reuben Thomas +2012-01-09 Reuben Thomas io_ext: Add slurp; use it in various places. @@ -2241,7 +2506,7 @@ Bump version to 26. -2011-12-17 Reuben Thomas +2011-12-16 Reuben Thomas Merge pull request #1 from gvvaughan/patch-1 tree: fix bugs when using a list of tables as keys @@ -2274,7 +2539,7 @@ io_ext: unset prog.file at the end of io.processFiles -2011-09-28 Reuben Thomas +2011-09-27 Reuben Thomas getopt: improve output and conformance to best practice Make the short option for -version be -V, not -v. @@ -2303,6 +2568,8 @@ .gitignore: ignore correct zip name. +2011-09-19 Reuben Thomas + configury: rename project to stdlib for consistency and to make luarocks happy. Make rockspec on release. @@ -2311,7 +2578,7 @@ string_ext.lua: fix old call of findl (is now called tfind). -2011-09-18 Reuben Thomas +2011-09-17 Reuben Thomas Makefile.am: fix getting summary description, and reminder message output by make release. @@ -2322,19 +2589,19 @@ Build system: autotoolize and generate rockspec. -2011-09-12 Reuben Thomas +2011-09-11 Reuben Thomas Rename findl to tfind to conform to lrexlib. Also fix a bug in the LuaDoc documentation of the return values. -2011-09-08 Reuben Thomas +2011-09-07 Reuben Thomas Remove posix_ext module (is going in luaposix instead). Update documentation about LuaDoc. Add posix.creat. -2011-09-03 Reuben Thomas +2011-09-02 Reuben Thomas Fix typo. @@ -2385,7 +2652,7 @@ Fix calls to writeLine to be to writeline. -2011-05-03 Reuben Thomas +2011-05-02 Reuben Thomas Add readlines and writeline to file handle metatable. @@ -2395,7 +2662,7 @@ Fixed bug: ldoc used writeLine() rather than writeline(). -2011-04-13 Reuben Thomas +2011-04-12 Reuben Thomas Always return nil on error, not -1. @@ -2407,7 +2674,7 @@ Only set _DEBUG to false if it’s not already initialised. -2011-03-20 Reuben Thomas +2011-03-19 Reuben Thomas Fix splitdir. @@ -2417,14 +2684,12 @@ Shorten a TODO. -2011-03-10 Reuben Thomas +2011-03-09 Reuben Thomas Restore modules.lua as holding standard list, to un-break std.lua. Allow mk1file to generate customized sets of modules, with the standard set as the default. -2011-03-09 Reuben Thomas - Remove unnecessary posix. prefix. Correct name of package_ext. @@ -2435,10 +2700,10 @@ Merge branch 'origin' of github.com:rrthomas/lua-stdlib into origin - Remove posix_ext and object from standard set. - 2011-03-08 Reuben Thomas + Remove posix_ext and object from standard set. + Remove posix prefix from function calls. Add euidaccess. @@ -2450,7 +2715,7 @@ Add __index method to allow OO syntax use of methods. Add delete method. -2011-03-02 Reuben Thomas +2011-03-01 Reuben Thomas Reverse order of list methods for convenient OO use. @@ -2484,7 +2749,7 @@ Improve release target to tag releases. -2011-02-08 Reuben Thomas +2011-02-07 Reuben Thomas Fix missing math. prefix, and swap incorrect sign in sub. Thanks to Bob Chapman. @@ -2492,7 +2757,7 @@ Speed up math.floor for case where p is 0 or absent (thanks, Lukáš Procházka). -2010-12-10 Reuben Thomas +2010-12-09 Reuben Thomas Change rules from using CVS to using git. @@ -2502,7 +2767,7 @@ Point to tree.clone for deep copies. -2010-10-13 Reuben Thomas +2010-10-12 Reuben Thomas Restore 'dubious' but used string metamethod fallback. @@ -2510,6 +2775,8 @@ Move .cvsignore's to .gitignore's. +2010-10-08 Reuben Thomas + Fix typo in io.catfile. Add commit that seems to be missing from import from CVS. @@ -2520,8 +2787,6 @@ Remove spurious full stop. -2010-10-08 Reuben Thomas - Add catfile and fix catdir to return `/' when necessary. 2010-10-07 Reuben Thomas @@ -2538,14 +2803,12 @@ Fix an incompatibility with strict.lua. -2010-06-12 rrt +2010-06-11 rrt Simplify nodes iterator and make it more efficient; thanks to Alistair Turnbull for the hint. Simplify, generalise and rename (from treeIter to nodes) tree iterator. -2010-06-11 rrt - Whitespace correction. Simplify implementation of empty, using next as per manual. @@ -2575,7 +2838,7 @@ Remove table.subscripts function: it’s easily replaced by subscript plus string.split, as in its definition. -2010-06-08 rrt +2010-06-07 rrt Initialise _DEBUG to nil so stdlib works with strict.lua. Rename debug.traceCall to debug.trace (more Lua-ish). @@ -2599,11 +2862,11 @@ Add missing dependency on list. -2009-09-15 rrt +2009-09-14 rrt Improve formatting slightly. -2009-09-08 rrt +2009-09-07 rrt Avoid using removed function io.changeSuffix. @@ -2656,6 +2919,8 @@ Add support for not cloning metatables. +2009-03-13 rrt + Check no outstanding changes and tag release. Fix typo. @@ -2678,7 +2943,7 @@ Update object module to correspond with Lua Gems version. -2008-09-05 rrt +2008-09-04 rrt Fix Diego Nehab's name. Sorry Diego! Thanks to Shmuel Zeigerman for pointing out my error. @@ -2698,10 +2963,10 @@ Cope with nil values in map. - Fix elems and relems - 2008-07-27 niklas + Fix elems and relems + Fix make dist; $REL -> ${REL}, add --exclude for .#*, and no longer exclude template-rrt.lua, which no longer lives in the tree. 2008-06-21 niklas @@ -2719,7 +2984,7 @@ Fix a comment typo. -2008-03-29 rrt +2008-03-28 rrt Add some TODOs to make the prog structure a bit more sensible. @@ -2741,6 +3006,8 @@ Remove _INTEGER_BITS and unneeded dependency +2008-03-03 rrt + Update date and prerequisites. 2008-03-02 rrt @@ -2787,7 +3054,7 @@ Clarify TODO. -2007-04-27 rrt +2007-04-26 rrt Tidy length slightly. @@ -2800,8 +3067,6 @@ Revert to plain implementation of length to avoid using POSIX library which is currently unmaintained. -2007-04-26 rrt - Clear up uses of old vararg "arg" syntax (thanks Matt). 2007-03-02 rrt @@ -2810,10 +3075,10 @@ Add FIXME for commented-out require - Make join cope with empty lists. - 2007-03-01 rrt + Make join cope with empty lists. + Remove default separator in string.split, and hence a TODO. Add string.join. @@ -2846,7 +3111,7 @@ Make a note to find better names for enpair and depair, which are useful but confusing. Something like pairsToTable and tableToPairs? -2007-01-27 rrt +2007-01-26 rrt Add missing dirname and basename @@ -2886,6 +3151,8 @@ Note problem with external dependencies. +2006-11-05 rrt + Sort out adding to module metatables. Add a FIXME @@ -2896,8 +3163,6 @@ Remove @module from list of tags to add, as we already have it. -2006-11-05 rrt - Clarify Reuben's role. Remove rex.lua, now imported from lrexlib @@ -2989,12 +3254,10 @@ Add deepclone to table from Jamie Webb's code. -2006-10-09 rrt +2006-10-08 rrt Update to match stdlib. Remove revision history as it's in CVS, and replace version number with CVS Revision tag. -2006-10-08 rrt - table.getn --> # 2006-10-01 rrt @@ -3009,7 +3272,7 @@ Fix ordering of deps -2006-07-15 rrt +2006-07-14 rrt Escape quotes and apostrophes in string.escapeShell. @@ -3019,19 +3282,21 @@ Prepend redefinition of require to the output. +2006-04-25 rrt + Use string methods rather than functions so that the functions here work on regexs as well. Add a note to make the whole API work properly with regexs as well as Lua patterns. Add TODO Reformat and improve comments. -2006-04-25 rrt +2006-04-24 rrt Simplify assignment of retry. Correct name of table.filterItem (was table.mapItem). -2006-04-16 rrt +2006-04-15 rrt Reformat. @@ -3039,8 +3304,6 @@ Add table.filter and table.filterItem. Add list.filterItem and implement list.filter in terms of it. -2006-04-15 rrt - Fix more bugs, patch from Shmuel Zeigerman. Call rex:flags() to inject flags into rex table. @@ -3078,7 +3341,7 @@ Add io.dirname. -2006-04-10 rrt +2006-04-09 rrt Update Lua code from Shmuel's version and write gmatch in Lua. @@ -3087,7 +3350,7 @@ Update to 5.1 vararg syntax -2006-03-31 rrt +2006-03-30 rrt string.gfind is now string.gmatch. @@ -3099,8 +3362,6 @@ Update to match reality. -2006-03-30 rrt - Fix handling of global arg table. Use new form of message-less error. @@ -3115,6 +3376,8 @@ Simplify adding functions to global table. +2006-03-28 rrt + Add module calls everywhere, and do some necessary renaming to avoid clashes 2006-03-23 rrt @@ -3132,7 +3395,7 @@ Rename sub to cap for clarity (Shmuel Zeigerman). -2006-01-27 rrt +2006-01-26 rrt More fixes from Shmuel to mimic string.gsub better. @@ -3140,10 +3403,10 @@ Fix endless loop when pattern is .* (bug reported by Shmuel Zeigerman). - Cope with capture being false (Shmuel Zeigerman). - 2006-01-24 rrt + Cope with capture being false (Shmuel Zeigerman). + Fix bug when n == 0 (thanks Shmuel Zeigerman), and tidy up. 2006-01-23 rrt @@ -3154,10 +3417,10 @@ More bug fixes; thanks to Shmuel Zeigerman for reporting the bugs and in one case giving the fix. - Fix bugs with %n replacements in rex.gsub - 2006-01-21 rrt + Fix bugs with %n replacements in rex.gsub + Make rex.gsub a full gsub for rex. 2006-01-20 rrt @@ -3179,9 +3442,11 @@ Remove table.filterItem, as it really only works for lists. Inline the function in list.filter. Add table.map. +2005-11-22 rrt + Add XML output, assuming Lua tables created by luaexpat. -2005-11-22 rrt +2005-11-21 rrt Add generic printing framework, and use it to add prettytostring. @@ -3193,7 +3458,7 @@ Add two iterators: ripairs which is like ipairs, but in reverse, and deepipairs, which recurses into nested tables. -2005-11-10 rrt +2005-11-09 rrt Remove import. @@ -3315,15 +3580,15 @@ Fix tostring to work on self-referential tables. -2004-01-28 rrt +2004-01-27 rrt Corrected misnaming of functions and added documentation. -2004-01-27 rrt +2004-01-26 rrt Add string.format extension to make it not try to format if there is only one argument. -2004-01-26 rrt +2004-01-25 rrt Update to Lua 5. This is an old change which I forgot to check in; ldoc is *not* the way forward for stdlib documentation. This checkin is just for completeness. @@ -3349,17 +3614,17 @@ Add "import" from LTN 11 to overcome require's problem with circular dependencies. Remove string.next, as string.gfind provides an equivalent iterator. - More renaming for consistency, and move more code around. This introduced the first cyclic dependency between modules since I moved to Lua 5, and I've had to cure this with a C include-style trick, since Lua 5 require just overflows the stack when there's a recursive call of require. - 2003-10-20 rrt + More renaming for consistency, and move more code around. This introduced the first cyclic dependency between modules since I moved to Lua 5, and I've had to cure this with a C include-style trick, since Lua 5 require just overflows the stack when there's a recursive call of require. + Add an iterator for the values in a set, and use it; methods are now organised into those that access the data structure and those that call other methods. Objectify the implementation, and add LuaDoc-style markup to the comments. Write methods outside object prototype (i.e. in more consistent form for stdlib). -2003-10-19 rrt +2003-10-18 rrt Rename std.data.logic to std.bit, as it extends the C bit library. @@ -3367,8 +3632,6 @@ Fix bug in curry properly. -2003-10-18 rrt - Finish renaming in io.io. Update TODO for getopt in std.lua. Re-add mistakenly removed logic (I confused the ability to take multiple args with the ability to take lists). @@ -3400,7 +3663,7 @@ Some other Lua 5-isation has been done, but not much; there's still a lot left to do in std.data in particular. -2003-10-14 rrt +2003-10-13 rrt Fix call to writeLine (now io.writeLine). @@ -3426,6 +3689,8 @@ More changes to update to Lua 5.0. Nearly there now, I think, as I have several scripts working! +2003-09-11 rrt + Another few search-and-replace function names to update to Lua 5. Mostly string functions this time. 2003-09-10 rrt @@ -3464,18 +3729,16 @@ Merge the two logic modules. -2002-09-29 rrt +2002-09-28 rrt Add tabulate function to use tabulator methods, and use it. -2002-09-11 rrt +2002-09-10 rrt Sigh. New bnot didn't work. Next time I'll think and test rather better before straying from the path of righteousness. I was being very dim about bnot. Oops. Roberto pointed it out. I hang my head in shame. -2002-09-10 rrt - Revert to previous version to avoid losing precision (specifically, LSB). Shorter implementation of bxor, and bnot thanks to a remark by Paul Hsieh on lual (Message-Id: <0H26009OMQ9J59@mta5.snfc21.pbi.net>). @@ -3493,7 +3756,7 @@ Improve layout of usage message when no command line options (don't have trailing blank line). -2002-09-06 rrt +2002-09-05 rrt Add withFileOrHandle, which takes a filename, handle or uses a default handle, opens the file if appropriate, and passes the handle to a given function. Use it to generalise readLines and readFile. @@ -3502,14 +3765,12 @@ ambiguous: do we want to write "foo" and "bar" to _OUTPUT, or "bar" to file "foo"? -2002-09-06 rrt +2002-09-05 rrt Make patches work with any version that starts with "Lua 4.0", to cope with 4.0.1 and any future point releases. Replace unpack with a recursive version (based on code from John Belmonte) that copes with any number of values. -2002-09-05 rrt - Change "key" to "index" everywhere for consistency. Improve comments for tinvert @@ -3518,21 +3779,19 @@ Rename intersect to setintersect for consistency, and define setunion (= merge). -2002-08-29 rrt +2002-08-28 rrt Allow stringifier methods again, but they are now only used by tostring. Allows more cosmetic stringification, while not stopping pickling from working. -2002-08-28 rrt +2002-08-27 rrt Don't need stringify and pickler tables any more, and tostring and pickle can be simplified. They both use tabulator where necessary. -2002-08-27 rrt - Remove interaction between pickle and tostring, which is no longer needed, as they both now use tabulator methods where necessary. Add tabulator method table for turning arbitrary objects (typically tagged userdata) into tables. Use this to finally fix tostring and pickle. Oh, yes. -2002-08-24 rrt +2002-08-23 rrt A last gamble. Then I'll have to sit down and work it out again. @@ -3556,15 +3815,13 @@ Make pickle work for numbers and nil. -2002-08-23 rrt - Add tinvert, and update some comments to LDoc format. 2002-08-22 rrt Correct call of warn to expand arg list. -2002-08-16 rrt +2002-08-15 rrt Add utility for making zip dist of stdlib. @@ -3572,8 +3829,6 @@ Fix paths for new directory structure and get rid of one or two gremlins. -2002-08-15 rrt - Finish editing std.cfg into new form (configuration file with require implementation tacked on the end) and rename it. Update some TODOs. @@ -3620,6 +3875,8 @@ Fix spacing in comments. +2002-08-12 rrt + Allow new tostring methods to be registered. *** empty log message *** @@ -3652,7 +3909,7 @@ Generalised daySuffix to ordinalSuffix. Still English-specific :-( -2002-07-28 rrt +2002-07-27 rrt Improve comment for mapIter @@ -3666,7 +3923,7 @@ This tool is provisional, and subject to improvement. The TODOs in the file indicate some of my first thoughts in that direction. -2002-07-25 rrt +2002-07-24 rrt Move methodify to table.lua where it belongs (it has nothing to do with lists!) diff --git a/Makefile.in b/Makefile.in index 7db3b67..cd28743 100644 --- a/Makefile.in +++ b/Makefile.in @@ -390,7 +390,7 @@ man_MANS = save_release_files = $(scm_rockspec) std_path = $(abs_srcdir)/lib/?.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = 1a28799a850e021e45c3e98064a746d7 +old_NEWS_hash = 1c4d1bfae2d511327b83800043bc19c7 update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ UPDATE_COPYRIGHT_USE_INTERVALS=1 \ @@ -416,9 +416,10 @@ dist_modules_DATA = $(srcdir)/doc/modules/std.html \ $(srcdir)/doc/modules/std.string.html \ $(srcdir)/doc/modules/std.table.html $(NOTHING_ELSE) specs_path = $(abs_builddir)/specs/?.lua -SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" +SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" LUA_INIT= LUA_INIT_5_2= SPECL_OPTS = --unicode specl_SPECS = \ + $(srcdir)/specs/base_spec.yaml \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ $(srcdir)/specs/functional_spec.yaml \ @@ -469,7 +470,6 @@ dist_luastddebug_DATA = \ $(NOTHING_ELSE) mkrockspecs_args = --module-dir $(srcdir)/lib --repository lua-stdlib -ldoc_DEPS = $(dist_lua_DATA) $(dist_luastd_DATA) luarocks_config = build-aux/luarocks-config.lua rockspec_conf = $(srcdir)/rockspec.conf mkrockspecs = $(srcdir)/build-aux/mkrockspecs @@ -1106,6 +1106,8 @@ uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ LUA_PATH ?= ; LUA_CPATH ?= ; + +specl-check-local: specs/spec_helper.lua specl-check-local: $(specl_SPECS) $(SPECL_ENV) LUA=$(LUA) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) @@ -1116,8 +1118,10 @@ specl-check-local: $(specl_SPECS) lib/std.lua: lib/std.lua.in ./config.status --file=$@ -$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(ldoc_DEPS) - test -d "$(srcdir)/doc" || mkdir "$(srcdir)/doc" +$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(srcdir)/doc + +$(srcdir)/doc: $(dist_lua_DATA) $(dist_luastd_DATA) + test -d $@ || mkdir $@ $(LDOC) -c build-aux/config.ld -d $(abs_srcdir)/doc . $(luarocks_config): Makefile.am diff --git a/NEWS b/NEWS index 369d8d2..6dc0fce 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,103 @@ Stdlib NEWS - User visible changes +* Noteworthy changes in release 39 (2014-04-23) [stable] + +** New features: + + - New `std.functional.case` function for rudimentary case statements. + The main difference from serial if/elseif/end comparisons is that + `with` is evaluated only once, and then the match function is looked + up with an O(1) table reference and function call, as opposed to + hoisting an expression result into a temporary variable, and O(n) + comparisons. + + The function call overhead is much more significant than several + comparisons, and so `case` is slower for all but the largest series + of if/elseif/end comparisons. It can make your code more readable, + however. + + See LDocs for usage. + + - New pathstring management functions in `std.package`. + + Manage `package.path` with normalization, duplicate removal, + insertion & removal of elements and automatic folding of '/' and '?' + onto `package.dirsep` and `package.path_mark`, for easy addition of + new paths. For example, instead of all this: + + lib = std.io.catfile (".", "lib", package.path_mark .. ".lua") + paths = std.string.split (package.path, package.pathsep) + for i, path in ipairs (paths) do + ... lots of normalization code... + end + i = 1 + while i <= #paths do + if paths[i] == lib then + table.remove (paths, i) + else + i = i + 1 + end + end + table.insert (paths, 1, lib) + package.path = table.concat (paths, package.pathsep) + + You can now write just: + + package.path = package.normalize ("./lib/?.lua", package.path) + + - `std.optparse:parse` accepts a second optional parameter, a table of + default option values. + + - `table.clone` accepts an optional table of key field renames in the + form of `{oldkey = newkey, ...}` subsuming the functionality of + `table.clone_rename`. The final `nometa` parameter is supported + whether or not a rename map is given: + + r = table.clone (t, "nometa") + r = table.clone (t, {oldkey = newkey}, "nometa") + +** Deprecations: + + - `table.clone_rename` now gives a warning on first call, and will be + removed entirely in a few releases. The functionality has been + subsumed by the improvements to `table.clone` described above. + +** Bug fixes: + + - `std.optparse` no longer throws an error when it encounters an + unhandled option in a combined (i.e. `-xyz`) short option string. + + - Surplus unmapped fields are now discarded during object cloning, for + example when a prototype has `_init` set to `{ "first", "second" }`, + and is cloned using `Proto {'one', 'two', 'three'}`, then the + unmapped `three` argument is now discarded. + + - The path element returned by `std.tree.nodes` can now always be + used as a key list to dereference the root of the tree, particularly + `tree[{}]` now returns the root node of `tree`, to match the initial + `branch` and final `join` results from a full traversal by + `std.tree.nodes (tree)`. + +** Incompatible changes: + + - `std.string` no longer sets `__append`, `__concat` and `__index` in + the core strings metatable by default, though `require "std"` does + continue to do so. See LDocs for `std.string` for details. + + - `std.optparse` no longer normalizes unhandled options. For example, + `--unhandled-option=argument` is returned unmolested from `parse`, + rather than as two elements split on the `=`; and if a combined + short option string contains an unhandled option, then whatever was + typed at the command line is returned unmolested, rather than first + stripping off and processing handled options, and returning only the + unhandled substring. + + - Setting `_init` to `{}` in a prototype object will now discard all + positional parameters passed during cloning, because a table valued + `_init` is a list of field names, beyond which surplus arguments (in + this case, all arguments!) are discarded. + + * Noteworthy changes in release 38 (2014-01-30) [stable] ** New features: diff --git a/README b/README index a076bf0..8ba232c 100644 --- a/README +++ b/README @@ -3,9 +3,9 @@ Standard Lua libraries by the [stdlib project][github] -[github]: http://github.com/rrthomas/lua-stdlib/ "Github repository" +[github]: http://github.com/lua-stdlib/lua-stdlib/ "Github repository" -[![travis-ci status](https://secure.travis-ci.org/rrthomas/lua-stdlib.png?branch=master)](http://travis-ci.org/rrthomas/lua-stdlib/builds) +[![travis-ci status](https://secure.travis-ci.org/lua-stdlib/lua-stdlib.png?branch=master)](http://travis-ci.org/lua-stdlib/lua-stdlib/builds) This is a collection of Lua libraries for Lua 5.1 and 5.2. The @@ -26,7 +26,7 @@ latest release (recommended): To install current git master (for testing): - luarocks install https://raw.github.com/rrthomas/lua-stdlib/release/stdlib-git-1.rockspec + luarocks install https://raw.githubusercontent.com/lua-stdlib/lua-stdlib/release/stdlib-git-1.rockspec To install without LuaRocks, check out the sources from the [repository][github], and then run the following commands: the @@ -41,7 +41,7 @@ dependencies are listed in the dependencies entry of the file See [INSTALL][] for instructions for `configure`. [luarocks]: http://www.luarocks.org "LuaRocks Project" -[install]: https://raw.github.com/rrthomas/lua-stdlib/master/INSTALL +[install]: https://raw.githubusercontent.com/lua-stdlib/lua-stdlib/master/INSTALL Use --- @@ -61,7 +61,7 @@ Documentation The libraries are [documented in LDoc][github.io]. Pre-built HTML files are included. -[github.io]: http://rrthomas.github.io/lua-stdlib +[github.io]: http://lua-stdlib.github.io/lua-stdlib Bug reports and code contributions diff --git a/bootstrap b/bootstrap index 82dcf5c..575ce48 100755 --- a/bootstrap +++ b/bootstrap @@ -2163,7 +2163,7 @@ Slingshot Options: --luarocks-tree=DIR check a non-default tree for prerequisite rocks --skip-rock-checks - ignore Lua rocks in bootstrap.conf:buidreq' + ignore Lua rocks in bootstrap.conf:buildreq' func_quote_for_eval ${1+"$@"} slingshot_options_prep_result=$func_quote_for_eval_result diff --git a/bootstrap.conf b/bootstrap.conf index 90eff27..19ba632 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -30,11 +30,14 @@ # List of programs, minimum versions, and software urls required to # bootstrap, maintain and release GNU Zile. +## !!WARNING!! Tidy up specs/specs.mk as instructed when buildreq bumps +#@ specl requirement to 12 or higher. + # Build prerequisites buildreq=' git 1.5.5 http://git-scm.com ldoc 1.4.0 http://luarocks.org/repositories/rocks/ldoc-1.4.2-1.rockspec - specl 8 http://luarocks.org/repositories/rocks/specl-10-1.rockspec + specl 11 http://luarocks.org/repositories/rocks/specl-11-1.rockspec ' # List of slingshot files to link into stdlib tree before autotooling. diff --git a/build-aux/release.mk b/build-aux/release.mk index 6941603..698670b 100644 --- a/build-aux/release.mk +++ b/build-aux/release.mk @@ -168,8 +168,8 @@ public-submodule-commit: && git --version >/dev/null 2>&1; then \ cd $(srcdir) && \ git submodule --quiet foreach \ - test '"$$(git rev-parse "$$sha1")"' \ - = '"$$(git merge-base origin "$$sha1")"' \ + 'test "$$(git rev-parse "$$sha1")" \ + = "$$(git merge-base origin "$$sha1")"' \ || { echo '$(ME): found non-public submodule commit' >&2; \ exit 1; }; \ else \ @@ -291,9 +291,9 @@ update-old-NEWS-hash: NEWS ANNOUNCE_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' ANNOUNCE_PRINT = $(ANNOUNCE_ENV) $(LUA) -l$(PACKAGE) -e -_PRE = " http://raw." +_PRE = " https://raw.githubusercontent" _POST = "/release-v$(VERSION)/$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec" -GITHUB_ROCKSPEC = (source.url:gsub ("^git://", $(_PRE)):gsub ("%.git$$", $(_POST))) +GITHUB_ROCKSPEC = (source.url:gsub ("^git://github", $(_PRE)):gsub ("%.git$$", $(_POST))) announcement: NEWS # Not $(AM_V_GEN) since the output of this command serves as diff --git a/configure b/configure index 5b46e4e..88f48c1 100755 --- a/configure +++ b/configure @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 38. +# Generated by GNU Autoconf 2.69 for stdlib 39. # -# Report bugs to . +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -267,10 +267,10 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: http://github.com/rrthomas/lua-stdlib/issues about your -$0: system, including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." +$0: http://github.com/lua-stdlib/lua-stdlib/issues about +$0: your system, including any error possibly output before +$0: this message. Then install a modern shell, or manually +$0: run the script under such a shell if you do have one." fi exit 1 fi @@ -580,9 +580,9 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='38' -PACKAGE_STRING='stdlib 38' -PACKAGE_BUGREPORT='http://github.com/rrthomas/lua-stdlib/issues' +PACKAGE_VERSION='39' +PACKAGE_STRING='stdlib 39' +PACKAGE_BUGREPORT='http://github.com/lua-stdlib/lua-stdlib/issues' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS @@ -1217,7 +1217,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 38 to adapt to many kinds of systems. +\`configure' configures stdlib 39 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1283,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 38:";; + short | recursive ) echo "Configuration of stdlib 39:";; esac cat <<\_ACEOF @@ -1300,7 +1300,7 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to . +Report bugs to . _ACEOF ac_status=$? fi @@ -1363,7 +1363,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 38 +stdlib configure 39 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1380,7 +1380,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 38, which was +It was created by stdlib $as_me 39, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1760,7 +1760,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. $as_echo "## --------------------- ## -## Configuring stdlib 38 ## +## Configuring stdlib 39 ## ## --------------------- ##" echo @@ -2250,7 +2250,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='38' + VERSION='39' cat >>confdefs.h <<_ACEOF @@ -3641,7 +3641,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 38, which was +This file was extended by stdlib $as_me 39, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3688,13 +3688,13 @@ Usage: $0 [OPTION]... [TAG]... Configuration files: $config_files -Report bugs to ." +Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 38 +stdlib config.status 39 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 63c8860..2965667 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [38], [http://github.com/rrthomas/lua-stdlib/issues]) +AC_INIT([stdlib], [39], [http://github.com/lua-stdlib/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 613f274..92391de 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 5422e25..6d48174 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -1135,7 +1135,7 @@

      Parameters:

      See also:

      diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index fd6c8a7..05bbeab 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html index 2a0ac2a..05f451d 100644 --- a/doc/classes/std.optparse.html +++ b/doc/classes/std.optparse.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -218,7 +218,7 @@

      Methods

      Function signature of an option handler for on. - std.optparse:parse (arglist) + std.optparse:parse (arglist[, defaults]) Parse arglist. @@ -807,7 +807,7 @@

      Returns:

  • - std.optparse:parse (arglist) + std.optparse:parse (arglist[, defaults])
    Parse arglist. @@ -819,6 +819,10 @@

    Parameters:

    table list of arguments +
  • defaults + table + table of default option values +
  • Returns:

    diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index 035f68e..a6de351 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -69,8 +69,8 @@

    Class std.set

    Set container.

    Derived from std.container, and inherits Container's metamethods.

    -

    Note that Functions listed below are available only available from the - Set prototype returned by requiring this module, because Container +

    Note that Functions listed below are only available from the Set + prototype returned by requiring this module, because Container objects cannot have object methods.

    diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index 5b9e82f..5ff78cf 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index a8f9e36..1f56bde 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/index.html b/doc/index.html index d422ffa..31e52fc 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html index a6f797d..3802b07 100644 --- a/doc/modules/std.debug.html +++ b/doc/modules/std.debug.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index 51d6393..1ccfd60 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -74,10 +74,14 @@

    Module std.functional

    Functions

    - + + + + + @@ -134,7 +138,7 @@

    Functions

    - bind (f, ...) + bind (f, p1)
    Partially apply a function. @@ -145,15 +149,58 @@

    Parameters:

  • f function to apply partially
  • -
  • ... - arguments to bind +
  • p1 + table + =a1, ..., pn=an} table of parameters to bind to given arguments
  • Returns:

      - function with ai already bound + function with pi already bound +
    + + + + +
    +
    + + case (with, branches) +
    +
    + +

    A rudimentary case statement. + Match with against keys in branches table, and return the result + of running the function in the table value for the matching key, or + the first non-key value function if no key matches.

    + +
     return case (type (object), {
    +   table  = function ()  return something end,
    +   string = function ()  return something else end,
    +            function (s) error ("unhandled type: "..s) end,
    + })
    +
    + + + + +

    Parameters:

    +
      +
    • with + expression to match +
    • +
    • branches + table + map possible matches to functions +
    • +
    + +

    Returns:

    +
      + + the return value from function with a matching key, or nil.
    @@ -197,7 +244,14 @@

    Returns:

    Returns:

      - composition of f1 ... fn + composition of fn (... (f1) ...): note that this is the reverse + of what you might expect, but means that code like:

      + +
       functional.compose (function (x) return f (x) end,
      +                     function (x) return g (x) end))
      +
      + +

      can be read from top to bottom.

    diff --git a/doc/modules/std.html b/doc/modules/std.html index 717aa6f..9f51b5f 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index fc955af..129f739 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -373,7 +373,7 @@

    See also:

    Parameters:

    • h - file handle (default: io.output () + file handle (default: io.output ())
    • ... values to write (as for write) diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index 1455e3b..534ce7e 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index 63712df..620b004 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -32,6 +32,7 @@

      stdlib

      Contents

      @@ -70,6 +71,33 @@

      Module std.package

      +

      Functions

      +
    bind (f, ...)bind (f, p1) Partially apply a function.
    case (with, branches)A rudimentary case statement.
    collect (i) Collect the results of an iterator.
    + + + + + + + + + + + + + + + + + + + + + + + + +
    find (pathstrings, patt[, init=1[, plain=false]])Look for a path segment match of patt in pathstrings.
    insert (pathstrings[, pos=n+1], value)Insert a new element into a package.path like string of paths.
    mappath (pathstrings, callback, ...)Call a function with each element of a path string.
    mappath_callback (element, ...)Function signature of a callback for mappath.
    normalize (...)Normalize a path list.
    remove (pathstrings[, pos=n])Remove any element from a package.path like string of paths.

    Tables

    @@ -83,6 +111,217 @@

    Tables


    +

    Functions

    +
    +
    + + find (pathstrings, patt[, init=1[, plain=false]]) +
    +
    + Look for a path segment match of patt in pathstrings. + + +

    Parameters:

    +
      +
    • pathstrings + string + pathsep delimited path elements +
    • +
    • patt + string + a Lua pattern to search for in pathstrings +
    • +
    • init + int + element (not byte index!) to start search at. + Negative numbers begin counting backwards from the last element + (default 1) +
    • +
    • plain + bool + unless false, treat patt as a plain + string, not a pattern. Note that if plain is given, then init + must be given as well. + (default false) +
    • +
    + +

    Returns:

    +
      + + the matching element number (not byte index!) and full text + of the matching element, if any; otherwise nil +
    + + + + +
    +
    + + insert (pathstrings[, pos=n+1], value) +
    +
    + Insert a new element into a package.path like string of paths. + + +

    Parameters:

    +
      +
    • pathstrings + string + a package.path like string +
    • +
    • pos + int + element index at which to insert value, where n is + the number of elements prior to insertion + (default n+1) +
    • +
    • value + string + new path element to insert +
    • +
    + +

    Returns:

    +
      + + string + a new string with the new element inserted +
    + + + + +
    +
    + + mappath (pathstrings, callback, ...) +
    +
    + Call a function with each element of a path string. + + +

    Parameters:

    +
      +
    • pathstrings + string + a package.path like string +
    • +
    • callback + mappath_callback + function to call for each element +
    • +
    • ... + additional arguments passed to callback +
    • +
    + +

    Returns:

    +
      + + nil, or first non-nil returned by callback +
    + + + + +
    +
    + + mappath_callback (element, ...) +
    +
    + Function signature of a callback for mappath. + + +

    Parameters:

    +
      +
    • element + string + an element from a pathsep delimited string of + paths +
    • +
    • ... + additional arguments propagated from mappath +
    • +
    + +

    Returns:

    +
      + + non-nil to break, otherwise continue with the next element +
    + + + + +
    +
    + + normalize (...) +
    +
    + Normalize a path list. + Removing redundant . and .. directories, and keep only the first + instance of duplicate elements. Each argument can contain any number + of pathsep delimited elements; wherein characters are subject to + / and ? normalization, converting / to dirsep and ? to + path_mark (unless immediately preceded by a % character). + + +

    Parameters:

    +
      +
    • ... + path elements +
    • +
    + +

    Returns:

    +
      + + string + a single normalized pathsep delimited paths string +
    + + + + +
    +
    + + remove (pathstrings[, pos=n]) +
    +
    + Remove any element from a package.path like string of paths. + + +

    Parameters:

    +
      +
    • pathstrings + string + a package.path like string +
    • +
    • pos + int + element index from which to remove an item, where n + is the number of elements prior to removal + (default n) +
    • +
    + +

    Returns:

    +
      + + string + a new string with given element removed +
    + + + + +
    +

    Tables

    diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index a595470..c68fd7e 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index c734fd0..8af1ec3 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -33,7 +33,6 @@

    stdlib

    Contents

    @@ -68,6 +67,37 @@

    Module std.string

    Additions to the string module.

    + +

    If you require "std", the contents of this module are all available + in the std.string table.

    + +

    However, this module also contains references to the Lua core string + table entries, so it's safe to load it like this:

    + +
     local string = require "std.string"
    +
    + +

    Of course, if you do that you'll lose references to any core string + functions overwritten by std.string , so you might want to save any + that you want access to before you overwrite them.

    + +

    If your code does not require "std" anywhere, then you'll also need + to manually overwrite string functions in the global namespace if you + want to use them from there:

    + +
     local assert, tostring = string.assert, string.tostring
    +
    + +

    And finally, to use the string metatable improvements with all core + strings, you'll need to merge this module's metatable into the core + string metatable (again, require "std" does this automatically):

    + +
     local string_metatable = getmetatable ""
    + string_metatable.__append = string.__append
    + string_metatable.__concat = string.__concat
    + string_metatable.__index = string.__index
    +
    +

    @@ -186,21 +216,6 @@

    Functions

    Wrap a string into a paragraph.
    -

    Fields

    - - - - - - - - - - - - - -
    sGive strings a subscription operator.
    sGive strings an append metamethod.
    sGive strings a concat metamethod.


    @@ -852,7 +867,7 @@

    Returns:

    Split a string at a given separator. Separator is a Lua pattern, so you have to escape active characters, - ^$()%.[]*+-? with a % prefix to match a literal character in s . + ^$()%.[]*+-? with a % prefix to match a literal character in s.

    Parameters:

    @@ -1000,75 +1015,6 @@

    Returns:

    -
    -
    -

    Fields

    -
    -
    - - s -
    -
    - Give strings a subscription operator. - - -
      -
    • s - string -
    • -
    • i - index -
    • -
    - - - - - -
    -
    - - s -
    -
    - Give strings an append metamethod. - - -
      -
    • s - string -
    • -
    • c - character (1-character string) -
    • -
    - - - - - -
    -
    - - s -
    -
    - Give strings a concat metamethod. - - -
      -
    • s - string -
    • -
    • o - object -
    • -
    - - - - -
    diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index d992c03..bd3fad9 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - stdlib 38 Reference + stdlib 39 Reference @@ -73,12 +73,12 @@

    Module std.table

    Functions

    - + - - + + @@ -134,7 +134,7 @@

    Functions

    - clone (t, nometa) + clone (t[, map={}], nometa)
    Make a shallow copy of a table, including any metatable.

    @@ -146,10 +146,12 @@

    Parameters:

    • t table - -
        source table
      -
      - + source table +
    • +
    • map + table + table of {oldkey=newkey, ...} + (default {})
    • nometa boolean @@ -160,7 +162,8 @@

      Parameters:

      Returns:

        - copy of table + copy of t, also sharing t's metatable unless nometa + is true, and with keys renamed according to map
      @@ -168,29 +171,33 @@

      Returns:

    - - clone_rename (t, map) + + clone_select (t[, selection={}])
    - Clone a table, renaming some keys. + Make a partial clone of a table.

    + +

    Like clone , but does not copy any fields by default.

    Parameters:

    • t table - source table + source table
    • -
    • map +
    • selection table - table {oldkey=newkey, ...} + list of keys to copy + (default {})

    Returns:

      - copy of table + copy of fields in selection from t, also sharing t's + metatable unless nometa
    diff --git a/lib/std.lua b/lib/std.lua index 9980604..4b33517 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -29,7 +29,7 @@ -- local prototype = std.container.prototype -- @table std -- @field version release version string -local version = "General Lua libraries / 38" +local version = "General Lua libraries / 39" local modules = require "std.modules" @@ -49,6 +49,12 @@ local file_metatable = getmetatable (io.stdin) file_metatable.readlines = io.readlines file_metatable.writelines = io.writelines +-- Add string metamethods to the string metatable. +local string_metatable = getmetatable "" +string_metatable.__append = string.__append +string_metatable.__concat = string.__concat +string_metatable.__index = string.__index + -- Maintain old global interface access points. for _, api in ipairs { --- Partially apply a function. diff --git a/lib/std.lua.in b/lib/std.lua.in index da0fb77..6b0d0f1 100644 --- a/lib/std.lua.in +++ b/lib/std.lua.in @@ -49,6 +49,12 @@ local file_metatable = getmetatable (io.stdin) file_metatable.readlines = io.readlines file_metatable.writelines = io.writelines +-- Add string metamethods to the string metatable. +local string_metatable = getmetatable "" +string_metatable.__append = string.__append +string_metatable.__concat = string.__concat +string_metatable.__index = string.__index + -- Maintain old global interface access points. for _, api in ipairs { --- Partially apply a function. diff --git a/lib/std/base.lua b/lib/std/base.lua index 0ac5aad..c56d290 100644 --- a/lib/std/base.lua +++ b/lib/std/base.lua @@ -1,14 +1,41 @@ ------ -- @module std.base + +--- Write a deprecation warning to stderr on first call. +-- @func fn deprecated function +-- @string[opt] name function name for automatic warning message. +-- @string[opt] warnmsg full specified warning message (overrides *name*) +-- @return a function to show the warning on first call, and hand off to *fn* +local function deprecate (fn, name, warnmsg) + assert (name or warnmsg, + "missing argument to 'deprecate', expecting 2 or 3 parameters") + warnmsg = warnmsg or (name .. " is deprecated, and will go away in a future release.") + local warnp = true + return function (...) + if warnp then + local _, where = pcall (function () error ("", 4) end) + io.stderr:write ((string.gsub (where, "(^w%*%.%w*%:%d+)", "%1"))) + io.stderr:write (warnmsg .. "\n") + warnp = false + end + return fn (...) + end +end + -- Doc-commented in table.lua... -local function clone (t, nometa) +local function clone (t, map, nometa) + map = map or {} + if type (map) ~= "table" then + map, nometa = {}, map + end + local u = {} if not nometa then setmetatable (u, getmetatable (t)) end - for i, v in pairs (t) do - u[i] = v + for k, v in pairs (t) do + u[map[k] or k] = v end return u end @@ -146,6 +173,7 @@ local M = { clone_rename = clone_rename, compare = compare, concat = concat, + deprecate = deprecate, elems = elems, ileaves = ileaves, leaves = leaves, diff --git a/lib/std/container.lua b/lib/std/container.lua index 64cd413..97dce77 100644 --- a/lib/std/container.lua +++ b/lib/std/container.lua @@ -86,23 +86,32 @@ end --- Return `obj` with references to the fields of `src` merged in. -- @static -- @tparam table obj destination object --- @tparam table src fields to copy int clone +-- @tparam table src fields to copy into clone -- @tparam[opt={}] table map `{old_key=new_key, ...}` -- @treturn table `obj` with non-private fields from `src` merged, and -- a metatable with private fields (if any) merged, both sets of keys -- renamed according to `map` -- @see std.object.mapfields local function mapfields (obj, src, map) - map = map or {} local mt = getmetatable (obj) or {} -- Map key pairs. - for k, v in pairs (src) do - local key, dst = map[k] or k, obj - if type (key) == "string" and key:sub (1, 1) == "_" then - dst = mt + -- Copy all pairs when `map == nil`, but discard unmapped src keys + -- when map is provided (i.e. if `map == {}`, copy nothing). + if map == nil or next (map) then + map = map or {} + for k, v in pairs (src) do + local key, dst = map[k] or k, obj + local kind = type (key) + if kind == "string" and key:sub (1, 1) == "_" then + dst = mt + elseif kind == "number" and #dst + 1 < key then + -- When map is given, but has fewer entries than src, stop copying + -- fields when map is exhausted. + break + end + dst[key] = v end - dst[key] = v end -- Quicker to remove this after copying fields than test for it @@ -142,7 +151,6 @@ end -- by @{std.object.__call} local metatable = { _type = "Container", - _init = {}, --- Return a clone of this container. -- @function __call @@ -166,10 +174,10 @@ local metatable = { end end - if type (mt._init) == "table" then - obj = (self.mapfields or mapfields) (obj, x, mt._init) - else + if type (mt._init) == "function" then obj = mt._init (obj, x, ...) + else + obj = (self.mapfields or mapfields) (obj, x, mt._init) end -- If a metatable was set, then merge our fields and use it. diff --git a/lib/std/functional.lua b/lib/std/functional.lua index a151ab8..2be45b9 100644 --- a/lib/std/functional.lua +++ b/lib/std/functional.lua @@ -35,16 +35,43 @@ end --- Partially apply a function. -- @param f function to apply partially --- @param ... arguments to bind --- @return function with ai already bound +-- @tparam table {p1=a1, ..., pn=an} table of parameters to bind to given arguments +-- @return function with pi already bound local function bind (f, ...) - local fix = {...} + local fix = {...} -- backwards compatibility with old API; DEPRECATED: remove in first release after 2015-04-21 + if type (fix[1]) == "table" and fix[2] == nil then + fix = fix[1] + end return function (...) - return f (unpack (list.concat (fix, {...}))) + local arg = {...} + for i, v in pairs (fix) do + arg[i] = v + end + return f (unpack (arg)) end end +--- A rudimentary case statement. +-- Match `with` against keys in `branches` table, and return the result +-- of running the function in the table value for the matching key, or +-- the first non-key value function if no key matches. +-- +-- return case (type (object), { +-- table = function () return something end, +-- string = function () return something else end, +-- function (s) error ("unhandled type: "..s) end, +-- }) +-- +-- @param with expression to match +-- @tparam table branches map possible matches to functions +-- @return the return value from function with a matching key, or nil. +local function case (with, branches) + local fn = branches[with] or branches[1] + if fn then return fn (with) end +end + + --- Curry a function. -- @param f function to curry -- @param n number of arguments @@ -62,13 +89,19 @@ end --- Compose functions. -- @param f1...fn functions to compose --- @return composition of f1 ... fn +-- @return composition of fn (... (f1) ...): note that this is the reverse +-- of what you might expect, but means that code like: +-- +-- functional.compose (function (x) return f (x) end, +-- function (x) return g (x) end)) +-- +-- can be read from top to bottom. local function compose (...) local arg = {...} local fns, n = arg, #arg return function (...) local arg = {...} - for i = n, 1, -1 do + for i = 1, n do arg = {fns[i] (unpack (arg))} end return unpack (arg) @@ -122,7 +155,7 @@ local function map (f, i, ...) local t = {} for e in i (...) do local r = f (e) - if r then + if r ~= nil then table.insert (t, r) end end @@ -161,6 +194,7 @@ end --- @export functional = { bind = bind, + case = case, collect = collect, compose = compose, curry = curry, @@ -187,7 +221,7 @@ functional = { -- @field == equality -- @field ~= inequality functional.op = { - ["[]"] = function (t, s) return t[s] end, + ["[]"] = function (t, s) return t and t[s] or nil end, ["+"] = function (a, b) return a + b end, ["-"] = function (a, b) return a - b end, ["*"] = function (a, b) return a * b end, diff --git a/lib/std/io.lua b/lib/std/io.lua index 609fc6d..46f0db2 100644 --- a/lib/std/io.lua +++ b/lib/std/io.lua @@ -3,10 +3,12 @@ @module std.io ]] -local package = require "std.package" local string = require "std.string" local tree = require "std.tree" +local package = { + dirsep = string.match (package.config, "^([^\n]+)\n"), +} -- Get an input file handle. -- @param h file handle or name (default: `io.input ()`) @@ -47,7 +49,7 @@ local function readlines (h) end --- Write values adding a newline after each. --- @param h file handle (default: `io.output ()` +-- @param h file handle (default: `io.output ()`) -- @param ... values to write (as for write) local function writelines (h, ...) if io.type (h) ~= "file" then diff --git a/lib/std/list.lua b/lib/std/list.lua index 1343277..1a5347e 100644 --- a/lib/std/list.lua +++ b/lib/std/list.lua @@ -228,7 +228,7 @@ end -- @tparam List ls a list of lists -- @treturn List new list `{fn (unpack (ls[1]))), ..., fn (unpack (ls[#ls]))}` local function map_with (fn, ls) - return List (func.map (func.compose (fn, unpack), elems, ls)) + return List (func.map (func.compose (unpack, fn), elems, ls)) end diff --git a/lib/std/optparse.lua b/lib/std/optparse.lua index f57592a..8ebb188 100644 --- a/lib/std/optparse.lua +++ b/lib/std/optparse.lua @@ -113,7 +113,6 @@ local optional, required -- @tparam table arglist list of arguments to normalise -- @treturn table normalised argument list local function normalise (self, arglist) - -- First pass: Normalise to long option names, without '=' separators. local normal = {} local i = 0 while i < #arglist do @@ -124,22 +123,37 @@ local function normalise (self, arglist) if opt:sub (1, 2) == "--" then local x = opt:find ("=", 3, true) if x then - table.insert (normal, opt:sub (1, x - 1)) - table.insert (normal, opt:sub (x + 1)) - else + local optname = opt:sub (1, x -1) + + -- Only split recognised long options. + if self[optname] then + table.insert (normal, optname) + table.insert (normal, opt:sub (x + 1)) + else + x = nil + end + end + + if x == nil then + -- No '=', or substring before '=' is not a known option name. table.insert (normal, opt) end elseif opt:sub (1, 1) == "-" and string.len (opt) > 2 then - local rest + local orig, split, rest = opt, {} repeat opt, rest = opt:sub (1, 2), opt:sub (3) - table.insert (normal, opt) + table.insert (split, opt) + + -- If there's no handler, the option was a typo, or not supposed + -- to be an option at all. + if self[opt] == nil then + opt, split = nil, { orig } -- Split '-xyz' into '-x -yz', and reiterate for '-yz' - if self[opt].handler ~= optional and - self[opt].handler ~= required then + elseif self[opt].handler ~= optional and + self[opt].handler ~= required then if string.len (rest) > 0 then opt = "-" .. rest else @@ -148,10 +162,13 @@ local function normalise (self, arglist) -- Split '-xshortargument' into '-x shortargument'. else - table.insert (normal, rest) + table.insert (split, rest) opt = nil end until opt == nil + + -- Append split options to normalised list + for _, v in ipairs (split) do table.insert (normal, v) end else table.insert (normal, opt) end @@ -529,10 +546,11 @@ end --- Parse `arglist`. -- @tparam table arglist list of arguments +-- @tparam[opt] table defaults table of default option values -- @treturn table a list of unrecognised `arglist` elements -- @treturn opts parsing results -local function parse (self, arglist) - self.unrecognised = {} +local function parse (self, arglist, defaults) + self.unrecognised, self.opts = {}, {} arglist = normalise (self, arglist) @@ -558,6 +576,11 @@ local function parse (self, arglist) end end + -- Merge defaults into user options. + for k, v in pairs (defaults or {}) do + if self.opts[k] == nil then self.opts[k] = v end + end + -- metatable allows `io.warn` to find `parser.program` when assigned -- back to _G.opts. return self.unrecognised, setmetatable (self.opts, {__index = self}) diff --git a/lib/std/package.lua b/lib/std/package.lua index ab791b5..4034aa8 100644 --- a/lib/std/package.lua +++ b/lib/std/package.lua @@ -3,7 +3,161 @@ @module std.package ]] -local M = {} + +local M -- forward declaration + + +local string = require "std.string" + +local split, escape_pattern = string.split, string.escape_pattern + + +--- Look for a path segment match of `patt` in `pathstrings`. +-- @string pathstrings `pathsep` delimited path elements +-- @string patt a Lua pattern to search for in `pathstrings` +-- @int[opt=1] init element (not byte index!) to start search at. +-- Negative numbers begin counting backwards from the last element +-- @bool[opt=false] plain unless false, treat `patt` as a plain +-- string, not a pattern. Note that if `plain` is given, then `init` +-- must be given as well. +-- @return the matching element number (not byte index!) and full text +-- of the matching element, if any; otherwise nil +local function find (pathstrings, patt, init, plain) + assert (type (pathstrings) == "string", + "bad argument #1 to find (string expected, got " .. type (pathstrings) .. ")") + assert (type (patt) == "string", + "bad argument #2 to find (string expected, got " .. type (patt) .. ")") + local paths = split (pathstrings, M.pathsep) + if plain then patt = escape_pattern (patt) end + init = init or 1 + if init < 0 then init = #paths - init end + for i = init, #paths do + if paths[i]:find (patt) then return i, paths[i] end + end +end + + +local case = require "std.functional".case + +--- Substitute special characters in a path string. +-- Characters prefixed with `%` have the `%` stripped, but are not +-- subject to further substitution. +-- @string path a path element with explicit `/` and `?` as necessary +-- @treturn string `path` with `dirsep` and `path_mark` substituted +-- for `/` and `?` +local function pathsub (path) + return path:gsub ("%%?.", function (capture) + return case (capture, { + ["?"] = function () return M.path_mark end, + ["/"] = function () return M.dirsep end, + function (s) return s:gsub ("^%%", "", 1) end, + }) + end) +end + + +local catfile = require "std.io".catfile +local invert = require "std.table".invert + +--- Normalize a path list. +-- Removing redundant `.` and `..` directories, and keep only the first +-- instance of duplicate elements. Each argument can contain any number +-- of `pathsep` delimited elements; wherein characters are subject to +-- `/` and `?` normalization, converting `/` to `dirsep` and `?` to +-- `path_mark` (unless immediately preceded by a `%` character). +-- @param ... path elements +-- @treturn string a single normalized `pathsep` delimited paths string +local function normalize (...) + assert (select ("#", ...) > 0, "wrong number of arguments to 'normalize'") + local i, paths, pathstrings = 1, {}, table.concat ({...}, M.pathsep) + for _, path in ipairs (split (pathstrings, M.pathsep)) do + path = pathsub (path): + gsub (catfile ("^[^", "]"), catfile (".", "%0")): + gsub (catfile ("", "%.", ""), M.dirsep): + gsub (catfile ("", "%.$"), ""): + gsub (catfile ("", "[^", "]+", "%.%.", ""), M.dirsep): + gsub (catfile ("", "[^", "]+", "%.%.$"), ""): + gsub (catfile ("%.", "%..", ""), catfile ("..", "")): + gsub (catfile ("", "$"), "") + + -- Build an inverted table of elements to eliminate duplicates after + -- normalization. + if not paths[path] then + paths[path], i = i, i + 1 + end + end + return table.concat (invert (paths), M.pathsep) +end + + +------ +-- Insert a new element into a `package.path` like string of paths. +-- @function insert +-- @string pathstrings a `package.path` like string +-- @int[opt=n+1] pos element index at which to insert `value`, where `n` is +-- the number of elements prior to insertion +-- @string value new path element to insert +-- @treturn string a new string with the new element inserted + +local unpack = unpack or table.unpack + +local function insert (pathstrings, ...) + assert (type (pathstrings) == "string", + "bad argument #1 to insert (string expected, got " .. type (pathstrings) .. ")") + local paths = split (pathstrings, M.pathsep) + table.insert (paths, ...) + return normalize (unpack (paths)) +end + + +------ +-- Function signature of a callback for @{mappath}. +-- @function mappath_callback +-- @string element an element from a `pathsep` delimited string of +-- paths +-- @param ... additional arguments propagated from @{mappath} +-- @return non-nil to break, otherwise continue with the next element + + +--- Call a function with each element of a path string. +-- @string pathstrings a `package.path` like string +-- @tparam mappath_callback callback function to call for each element +-- @param ... additional arguments passed to `callback` +-- @return nil, or first non-nil returned by `callback` +local function mappath (pathstrings, callback, ...) + assert (type (pathstrings) == "string", + "bad argument #1 to mappath (string expected, got " .. type (pathstrings) .. ")") + assert (type (callback) == "function", + "bad argument #2 to mappath (function expected, got " .. type (pathstrings) .. ")") + for _, path in ipairs (split (pathstrings, M.pathsep)) do + local r = callback (path, ...) + if r ~= nil then return r end + end +end + + +--- Remove any element from a `package.path` like string of paths. +-- @string pathstrings a `package.path` like string +-- @int[opt=n] pos element index from which to remove an item, where `n` +-- is the number of elements prior to removal +-- @treturn string a new string with given element removed +local function remove (pathstrings, pos) + assert (type (pathstrings) == "string", + "bad argument #1 to remove (string expected, got " .. type (pathstrings) .. ")") + local paths = split (pathstrings, M.pathsep) + table.remove (paths, pos) + return table.concat (paths, M.pathsep) +end + + +--- @export +M = { + find = find, + insert = insert, + mappath = mappath, + normalize = normalize, + remove = remove, +} --- Make named constants for `package.config` -- (undocumented in 5.1; see luaconf.h for C equivalents). @@ -16,6 +170,7 @@ local M = {} M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark = string.match (package.config, "^([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)") + for k, v in pairs (package) do M[k] = M[k] or v end diff --git a/lib/std/set.lua b/lib/std/set.lua index c3911d1..94a13a1 100644 --- a/lib/std/set.lua +++ b/lib/std/set.lua @@ -3,8 +3,8 @@ Derived from @{std.container}, and inherits Container's metamethods. - Note that Functions listed below are available only available from the - Set prototype returned by requiring this module, because Container + Note that Functions listed below are only available from the Set + prototype returned by requiring this module, because Container objects cannot have object methods. @classmod std.set diff --git a/lib/std/string.lua b/lib/std/string.lua index b11f135..20b8367 100644 --- a/lib/std/string.lua +++ b/lib/std/string.lua @@ -1,5 +1,33 @@ --[[-- Additions to the string module. + + If you `require "std"`, the contents of this module are all available + in the `std.string` table. + + However, this module also contains references to the Lua core string + table entries, so it's safe to load it like this: + + local string = require "std.string" + + Of course, if you do that you'll lose references to any core string + functions overwritten by `std.string`, so you might want to save any + that you want access to before you overwrite them. + + If your code does not `require "std"` anywhere, then you'll also need + to manually overwrite string functions in the global namespace if you + want to use them from there: + + local assert, tostring = string.assert, string.tostring + + And finally, to use the string metatable improvements with all core + strings, you'll need to merge this module's metatable into the core + string metatable (again, `require "std"` does this automatically): + + local string_metatable = getmetatable "" + string_metatable.__append = string.__append + string_metatable.__concat = string.__concat + string_metatable.__index = string.__index + @module std.string ]] @@ -8,13 +36,43 @@ local List = require "std.list" local StrBuf = require "std.strbuf" local table = require "std.table" -local _assert = _G.assert local _format = string.format local _tostring = _G.tostring -local old__index = getmetatable ("").__index local M = {} +--- String append operation. +-- @param s string +-- @param c character (1-character string) +-- @return `s .. c` +local function __append (s, c) + return s .. c +end + +--- String concatenation operation. +-- @param s string +-- @param o object +-- @return s .. tostring (o) +local function __concat (s, o) + return M.tostring (s) .. M.tostring (o) +end + +--- String subscript operation. +-- @param s string +-- @param i index +-- @return `s:sub (i, i)` if i is a number, otherwise +-- fall back to a `std.string` metamethod (if any). +local function __index (s, i) + if type (i) == "number" then + return s:sub (i, i) + else + -- Fall back to module metamethods + return M[i] + end +end + + + --- Extend to work better with one argument. -- If only one argument is passed, no formatting is attempted. -- @param f format @@ -335,36 +393,6 @@ local function pickle (x) end ---- Give strings a subscription operator. --- @param s string --- @param i index --- @return `string.sub (s, i, i)` if i is a number, or --- falls back to any previous metamethod (by default, string methods) -getmetatable ("").__index = function (s, i) - if type (i) == "number" then - return s:sub (i, i) - -- Fall back to module metamethods - else - return M[i] - end -end - ---- Give strings an append metamethod. --- @param s string --- @param c character (1-character string) --- @return `s .. c` -getmetatable ("").__append = function (s, c) - return s .. c -end - ---- Give strings a concat metamethod. --- @param s string --- @param o object --- @return s .. tostring (o) -getmetatable ("").__concat = function (s, o) - return tostring (s) .. tostring (o) -end - --- Capitalise each word in a string. -- @param s string -- @return capitalised string @@ -517,7 +545,9 @@ end --- @export local String = { - __index = old__index, + __append = __append, + __concat = __concat, + __index = __index, assert = assert, caps = caps, chomp = chomp, @@ -547,10 +577,6 @@ for k,v in pairs (table.merge (String, { escapePattern = escape_pattern, escapeShell = escape_shell, ordinalSuffix = ordinal_suffix, - - -- Core Lua function implementations. - _format = _format, - _tostring = _tostring, })) do M[k] = v end diff --git a/lib/std/table.lua b/lib/std/table.lua index f4261b5..3a6aefb 100644 --- a/lib/std/table.lua +++ b/lib/std/table.lua @@ -6,23 +6,57 @@ local base = require "std.base" local func = require "std.functional" +-- No need to pull all of std.list into memory. +local elems = base.elems + --- Make a shallow copy of a table, including any metatable. -- -- To make deep copies, use @{std.tree.clone}. -- @function clone --- @tparam table t source table +-- @tparam table t source table +-- @tparam[opt={}] table map table of `{old_key=new_key, ...}` -- @tparam boolean nometa if non-nil don't copy metatable --- @return copy of *table* +-- @return copy of *t*, also sharing *t*'s metatable unless *nometa* +-- is true, and with keys renamed according to *map* local clone = base.clone ---- Clone a table, renaming some keys. +-- DEPRECATED: Remove in first release following 2015-04-15. +-- Clone a table, renaming some keys. -- @function clone_rename --- @tparam table t source table -- @tparam table map table `{old_key=new_key, ...}` +-- @tparam table t source table -- @return copy of *table* -local clone_rename = base.clone_rename +local clone_rename = base.deprecate (base.clone_rename, nil, + "table.clone_rename is deprecated, use the new `map` argument to table.clone instead.") + + +--- Make a partial clone of a table. +-- +-- Like `clone`, but does not copy any fields by default. +-- @function clone_select +-- @tparam table t source table +-- @tparam[opt={}] table selection list of keys to copy +-- @return copy of fields in *selection* from *t*, also sharing *t*'s +-- metatable unless *nometa* +local function clone_select (t, map, nometa) + assert (type (t) == "table", + "bad argument #1 to 'clone_select' (table expected, got " .. type (t) .. ")") + map = map or {} + if type (map) ~= "table" then + map, nometa = {}, map + end + + local r = {} + if not nometa then + setmetatable (r, getmetatable (t)) + end + for i in elems (map) do + r[i] = t[i] + end + return r +end --- Destructively merge another table's fields into *table*. @@ -160,7 +194,7 @@ end --- @export local Table = { clone = clone, - clone_rename = clone_rename, + clone_select = clone_select, empty = empty, invert = invert, keys = keys, @@ -177,6 +211,9 @@ local Table = { _sort = _sort, } +-- Deprecated and undocumented. +Table.clone_rename = clone_rename + for k, v in pairs (table) do Table[k] = Table[k] or v end diff --git a/lib/std/tree.lua b/lib/std/tree.lua index 643fe49..a809fc7 100644 --- a/lib/std/tree.lua +++ b/lib/std/tree.lua @@ -207,7 +207,7 @@ Tree = Container { -- @todo the following doesn't treat list keys correctly -- e.g. self[{{1, 2}, {3, 4}}], maybe flatten first? __index = function (self, i) - if type (i) == "table" and #i > 0 then + if type (i) == "table" then return List.foldl (func.op["[]"], self, i) else return rawget (self, i) diff --git a/local.mk b/local.mk index 4fe5628..c3176b8 100644 --- a/local.mk +++ b/local.mk @@ -29,7 +29,7 @@ LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" ## Bootstrap. ## ## ---------- ## -old_NEWS_hash = 1a28799a850e021e45c3e98064a746d7 +old_NEWS_hash = 1c4d1bfae2d511327b83800043bc19c7 update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ @@ -148,8 +148,11 @@ dist_modules_DATA += \ $(srcdir)/doc/modules/std.table.html \ $(NOTHING_ELSE) -ldoc_DEPS = $(dist_lua_DATA) $(dist_luastd_DATA) +## Parallel make gets confused when one command ($(LDOC)) produces +## multiple targets (all the html files above), so use the presence +## of the doc directory as a sentinel file. +$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(srcdir)/doc -$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(ldoc_DEPS) - test -d "$(srcdir)/doc" || mkdir "$(srcdir)/doc" +$(srcdir)/doc: $(dist_lua_DATA) $(dist_luastd_DATA) + test -d $@ || mkdir $@ $(LDOC) -c build-aux/config.ld -d $(abs_srcdir)/doc . diff --git a/rockspec.conf b/rockspec.conf index 2e1e688..3376ac9 100644 --- a/rockspec.conf +++ b/rockspec.conf @@ -1,7 +1,7 @@ # stdlib rockspec configuration. description: - homepage: http://rrthomas.github.io/lua-stdlib + homepage: http://lua-stdlib.github.io/lua-stdlib license: MIT/X11 summary: General Lua Libraries detailed: @@ -13,4 +13,4 @@ dependencies: - lua >= 5.1 source: - url: git://github.com/rrthomas/lua-stdlib.git + url: git://github.com/lua-stdlib/lua-stdlib.git diff --git a/specs/base_spec.yaml b/specs/base_spec.yaml new file mode 100644 index 0000000..cae43d1 --- /dev/null +++ b/specs/base_spec.yaml @@ -0,0 +1,49 @@ +before: + base = require "std.base" + +specify std.base: +- describe deprecate: + - before: | + deprecate = base.deprecate + + function runscript (body, name, args) + return luaproc ( + "require 'std.base'.deprecate (function (...)" .. + " " .. body .. + " end, '" .. (name or "runscript") .. "') " .. + "('" .. table.concat (args or {}, "', '") .. "')" + ) + end + - it diagnoses missing arguments: + expect (deprecate ()).to_error "missing argument" + - it returns a function: + f = deprecate (base.clone_rename, "clone_rename") + expect (type (f)).to_be "function" + - context with deprecated function: + - it executes the deprecated function: + expect (runscript 'error "oh noes!"').to_contain_error "oh noes!" + - it passes arguments to the deprecated function: + expect (runscript ("print (table.concat ({...}, ', '))", nil, + {"foo", "bar", "baz"})).to_output "foo, bar, baz\n" + - it returns deprecated function results: + script = [[ + deprecate = require "std.base".deprecate + fn = deprecate (function () return "foo", "bar", "baz" end, "fn") + print (fn ()) + ]] + expect (luaproc (script)).to_output "foo\tbar\tbaz\n" + - it writes a warning to stderr: + expect (runscript 'error "oh noes!"'). + to_contain_error "deprecated, and will go away" + - it writes the call location to stderr: | + expect (runscript 'error "oh noes!"'). + to_match_error "^%S+:1: " + - it does not repeat the warning on additional calls: + script = [[ + deprecate = require "std.base".deprecate + fn = deprecate (function () error "oh noes!" end, "fn") + fn () -- line 3 + fn () -- line 4 + ]] + expect (luaproc (script)). + not_to_match_error "^%S+:3:.*deprecated.*\n%S+:4:.*deprecated" diff --git a/specs/container_spec.yaml b/specs/container_spec.yaml index ab37b67..9e8d85c 100644 --- a/specs/container_spec.yaml +++ b/specs/container_spec.yaml @@ -1,5 +1,4 @@ before: - require "spec_helper" Container = require "std.container" prototype = (require "std.object").prototype @@ -8,35 +7,34 @@ specify std.container: - context by name: - it does not touch the global table: expect (show_apis {added_to="_G", by="std.container"}). - should_equal {} + to_equal {} - describe construction: - context from Container prototype: - before: things = Container {"foo", "bar", baz="quux"} - it constructs a new container: - expect (things).should_not_be (Container) - expect (type (things)).should_be "table" - expect (prototype (things)).should_be "Container" + expect (things).not_to_be (Container) + expect (type (things)).to_be "table" + expect (prototype (things)).to_be "Container" - it reuses the container metatable: o, p = things {"o"}, things {"p"} - expect (getmetatable (o)).should_be (getmetatable (p)) + expect (getmetatable (o)).to_be (getmetatable (p)) - it sets container fields from arguments: o = Container {"foo", "bar", baz="quux"} - expect (o).should_equal (things) + expect (o).to_equal (things) - it serves as a prototype for new instances: o = things {} - expect (prototype (o)).should_be "Container" - expect (o).should_not_be (things) - expect (o).should_equal (things) - expect (getmetatable (o)).should_be (getmetatable (things)) + expect (prototype (o)).to_be "Container" + expect (o).to_copy (things) + expect (getmetatable (o)).to_be (getmetatable (things)) - it separates '_' prefixed fields: expect (Container {foo="bar", _baz="quux"}). - should_equal (Container {foo="bar"}) + to_equal (Container {foo="bar"}) - it puts '_' prefixed fields in a new metatable: things = Container {foo="bar", _baz="quux"} - expect (getmetatable (things)).should_not_be (getmetatable (Container)) - expect (getmetatable (things)._baz).should_be "quux" + expect (getmetatable (things)).not_to_be (getmetatable (Container)) + expect (getmetatable (things)._baz).to_be "quux" - context with module functions: - before: fold = (require "std.functional").fold @@ -50,16 +48,16 @@ specify std.container: } - it does not propagate _functions: things = Bag {} - expect (things.count).should_be (nil) + expect (things.count).to_be (nil) - it does not provide object methods: | things = Bag {} - expect (things:count ()).should_error "attempt to call method 'count'" + expect (things:count ()).to_error "attempt to call method 'count'" - it does retain module functions: things = Bag { apples = 1, oranges = 3 } - expect (Bag.count (things)).should_be (4) + expect (Bag.count (things)).to_be (4) - it does allow elements named after module functions: things = Bag { count = 1337 } - expect (Bag.count (things)).should_be (1337) + expect (Bag.count (things)).to_be (1337) - describe field access: @@ -67,40 +65,40 @@ specify std.container: things = Container {"foo", "bar", baz="quux"} - context with bracket notation: - it provides access to existing contents: - expect (things[1]).should_be "foo" - expect (things["baz"]).should_be "quux" + expect (things[1]).to_be "foo" + expect (things["baz"]).to_be "quux" - it assigns new contents: things["new"] = "value" - expect (things["new"]).should_be "value" + expect (things["new"]).to_be "value" - context with dot notation: - it provides access to existing contents: - expect (things.baz).should_be "quux" + expect (things.baz).to_be "quux" - it assigns new contents: things.new = "value" - expect (things.new).should_be "value" + expect (things.new).to_be "value" - describe stringification: - before: things = Container {_type = "Derived", "one", "two", "three"} - it returns a string: - expect (type (tostring (things))).should_be "string" + expect (type (tostring (things))).to_be "string" - it contains the type: - expect (tostring (Container {})).should_contain "Container" - expect (tostring (things)).should_contain (prototype (things)) + expect (tostring (Container {})).to_contain "Container" + expect (tostring (things)).to_contain (prototype (things)) - it contains the ordered array part elements: - expect (tostring (things)).should_contain "one, two, three" + expect (tostring (things)).to_contain "one, two, three" - it contains the ordered dictionary part elements: expect (tostring (Container {one = true, two = true, three = true})). - should_contain "one=true, three=true, two=true" + to_contain "one=true, three=true, two=true" expect (tostring (things {one = true, two = true, three = true})). - should_contain "one=true, three=true, two=true" + to_contain "one=true, three=true, two=true" - it contains a ';' separator only when container has array and dictionary parts: - expect (tostring (things)).should_not_contain ";" + expect (tostring (things)).not_to_contain ";" expect (tostring (Container {one = true, two = true, three = true})). - should_not_contain ";" + not_to_contain ";" expect (tostring (things {one = true, two = true, three = true})). - should_contain ";" + to_contain ";" - describe tablification: @@ -108,8 +106,8 @@ specify std.container: totable = (require "std.table").totable Derived = Container {_type = "Derived", "one", "two", three = true} - it returns a table: - expect (prototype (totable (Derived))).should_be "table" + expect (prototype (totable (Derived))).to_be "table" - it contains all non-hidden fields of container: - expect (totable (Derived)).should_contain.all_of {"one", "two", "three"} + expect (totable (Derived)).to_contain.all_of {"one", "two", "three"} - it does not contain any hidden fields of container: - expect (totable (Derived)).should_equal {"one", "two", three = true} + expect (totable (Derived)).to_equal {"one", "two", three = true} diff --git a/specs/debug_spec.yaml b/specs/debug_spec.yaml index 038fe7c..4fbcf3a 100644 --- a/specs/debug_spec.yaml +++ b/specs/debug_spec.yaml @@ -1,6 +1,4 @@ before: | - require "spec_helper" - this_module = "std.debug" global_table = "_G" @@ -15,15 +13,15 @@ specify std.debug: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - it contains apis from the core debug table: expect (show_apis {from=base_module, not_in=this_module}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - context via the std module: - it adds apis to the core debug table: expect (show_apis {added_to=base_module, by="std"}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - describe _DEBUG: diff --git a/specs/functional_spec.yaml b/specs/functional_spec.yaml index 26b87ab..e44a957 100644 --- a/specs/functional_spec.yaml +++ b/specs/functional_spec.yaml @@ -1,6 +1,4 @@ before: | - require "spec_helper" - global_table = "_G" this_module = "std.functional" std_globals = { "bind", "collect", "compose", "curry", "eval", @@ -14,21 +12,57 @@ specify std.functional: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - context via the std module: - it adds apis to the global table: expect (show_apis {added_to=global_table, by="std"}). - should_contain.all_of (std_globals) + to_contain.all_of (std_globals) - describe bind: + - it does not affect normal operation if no arguments are bound: + expect (M.bind (math.min, {}) (2, 3, 4)). + to_equal (2) + - the extra arguments are taken into account: + expect (M.bind (math.min, {1, 0}) (2, 3, 4)). + to_equal (0) + - the extra arguments can be out of order: + expect (M.bind (math.pow, {[2] = 3}) (2)). + to_equal (8) + + +- describe case: + - before: + yes = function () return true end + no = function () return false end + default = function (s) return s end + branches = { yes = yes, no = no, default } + - it matches against branch keys: + expect (M.case ("yes", branches)).to_be (true) + expect (M.case ("no", branches)).to_be (false) + - it has a default for unmatched keys: + expect (M.case ("none", branches)).to_be "none" + - it returns nil for unmatched keys with no default: + expect (M.case ("none", { yes = yes, no = no })).to_be (nil) + - it evaluates `with` exactly once: + s = "prince" + function acc () s = s .. "s"; return s end + expect (M.case (acc (), { + prince = function () return "one" end, + princes = function () return "many" end, + princess = function () return "one" end, + function () return "gibberish" end, + })).to_be "many" - describe collect: - describe compose: + - it composes functions in the correct order: + expect (M.compose (math.sin, math.cos) (1)). + to_equal (math.cos (math.sin (1))) - describe curry: diff --git a/specs/io_spec.yaml b/specs/io_spec.yaml index cc76e82..1c26e36 100644 --- a/specs/io_spec.yaml +++ b/specs/io_spec.yaml @@ -1,6 +1,4 @@ before: | - require "spec_helper" - this_module = "std.io" global_table = "_G" @@ -21,27 +19,27 @@ specify std.io: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - it contains apis from the core io table: expect (show_apis {from=base_module, not_in=this_module}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - it replaces no apis from the core io table: expect (show_apis {from=base_module, enhanced_in=this_module}). - should_equal {} + to_equal {} - context via the std module: - it adds apis to the global table: expect (show_apis {added_to=global_table, by="std"}). - should_contain.all_of (std_globals) + to_contain.all_of (std_globals) - it adds apis to the core io table: expect (show_apis {added_to=base_module, by="std"}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - it adds methods to the file metatable: expect (show_apis {added_to="getmetatable (io.stdin)", by="std"}). - should_contain.a_permutation_of (extend_metamethods) + to_contain.a_permutation_of (extend_metamethods) - it replaces no apis from the core io table: expect (show_apis {from=base_module, enhanced_after='require "std"'}). - should_equal {} + to_equal {} - describe catdir: @@ -54,59 +52,59 @@ specify std.io: - before: script = [[require "std.io".die "By 'eck!"]] - it outputs a message to stderr: - expect (luaproc (script)).should_fail_with "By 'eck!\n" + expect (luaproc (script)).to_fail_with "By 'eck!\n" - it ignores `prog.line` without `prog.file` or `prog.name`: script = [[prog = { line = 125 };]] .. script - expect (luaproc (script)).should_fail_with "By 'eck!\n" + expect (luaproc (script)).to_fail_with "By 'eck!\n" - it ignores `opts.line` without `opts.program`: script = [[opts = { line = 99 };]] .. script - expect (luaproc (script)).should_fail_with "By 'eck!\n" + expect (luaproc (script)).to_fail_with "By 'eck!\n" - it prefixes `prog.name` if any: | script = [[prog = { name = "name" };]] .. script - expect (luaproc (script)).should_fail_with "name: By 'eck!\n" + expect (luaproc (script)).to_fail_with "name: By 'eck!\n" - it appends `prog.line` if any, to `prog.name`: | script = [[prog = { line = 125, name = "name" };]] .. script - expect (luaproc (script)).should_fail_with "name:125: By 'eck!\n" + expect (luaproc (script)).to_fail_with "name:125: By 'eck!\n" - it prefixes `prog.file` if any: | script = [[prog = { file = "file" };]] .. script - expect (luaproc (script)).should_fail_with "file: By 'eck!\n" + expect (luaproc (script)).to_fail_with "file: By 'eck!\n" - it appends `prog.line` if any, to `prog.name`: | script = [[prog = { file = "file", line = 125 };]] .. script - expect (luaproc (script)).should_fail_with "file:125: By 'eck!\n" + expect (luaproc (script)).to_fail_with "file:125: By 'eck!\n" - it prefers `prog.name` to `prog.file` or `opts.program`: | script = [[ prog = { file = "file", name = "name" } opts = { program = "program" } ]] .. script - expect (luaproc (script)).should_fail_with "name: By 'eck!\n" + expect (luaproc (script)).to_fail_with "name: By 'eck!\n" - it appends `prog.line` if any to `prog.name` over anything else: | script = [[ prog = { file = "file", line = 125, name = "name" } opts = { line = 99, program = "program" } ]] .. script - expect (luaproc (script)).should_fail_with "name:125: By 'eck!\n" + expect (luaproc (script)).to_fail_with "name:125: By 'eck!\n" - it prefers `prog.file` to `opts.program`: | script = [[ prog = { file = "file" }; opts = { program = "program" } ]] .. script - expect (luaproc (script)).should_fail_with "file: By 'eck!\n" + expect (luaproc (script)).to_fail_with "file: By 'eck!\n" - it appends `prog.line` if any to `prog.file` over using `opts`: | script = [[ prog = { file = "file", line = 125 } opts = { line = 99, program = "program" } ]] .. script - expect (luaproc (script)).should_fail_with "file:125: By 'eck!\n" + expect (luaproc (script)).to_fail_with "file:125: By 'eck!\n" - it prefixes `opts.program` if any: | script = [[opts = { program = "program" };]] .. script - expect (luaproc (script)).should_fail_with "program: By 'eck!\n" + expect (luaproc (script)).to_fail_with "program: By 'eck!\n" - it appends `opts.line` if any, to `opts.program`: | script = [[opts = { line = 99, program = "program" };]] .. script - expect (luaproc (script)).should_fail_with "program:99: By 'eck!\n" + expect (luaproc (script)).to_fail_with "program:99: By 'eck!\n" - describe process_files: - it is the same function as legacy processFiles call: - expect (M.process_files).should_be (M.processFiles) + expect (M.process_files).to_be (M.processFiles) - describe readlines: @@ -125,51 +123,51 @@ specify std.io: - before: script = [[require "std.io".warn "Ayup!"]] - it outputs a message to stderr: - expect (luaproc (script)).should_output_error "Ayup!\n" + expect (luaproc (script)).to_output_error "Ayup!\n" - it ignores `prog.line` without `prog.file`, `prog.name` or `opts.program`: script = [[prog = { line = 125 };]] .. script - expect (luaproc (script)).should_output_error "Ayup!\n" + expect (luaproc (script)).to_output_error "Ayup!\n" - it prefixes `prog.name` if any: | script = [[prog = { name = "name" };]] .. script - expect (luaproc (script)).should_output_error "name: Ayup!\n" + expect (luaproc (script)).to_output_error "name: Ayup!\n" - it appends `prog.line` if any, to `prog.name`: | script = [[prog = { line = 125, name = "name" };]] .. script - expect (luaproc (script)).should_output_error "name:125: Ayup!\n" + expect (luaproc (script)).to_output_error "name:125: Ayup!\n" - it prefixes `prog.file` if any: | script = [[prog = { file = "file" };]] .. script - expect (luaproc (script)).should_output_error "file: Ayup!\n" + expect (luaproc (script)).to_output_error "file: Ayup!\n" - it appends `prog.line` if any, to `prog.name`: | script = [[prog = { file = "file", line = 125 };]] .. script - expect (luaproc (script)).should_output_error "file:125: Ayup!\n" + expect (luaproc (script)).to_output_error "file:125: Ayup!\n" - it prefers `prog.name` to `prog.file` or `opts.program`: | script = [[ prog = { file = "file", name = "name" } opts = { program = "program" } ]] .. script - expect (luaproc (script)).should_output_error "name: Ayup!\n" + expect (luaproc (script)).to_output_error "name: Ayup!\n" - it appends `prog.line` if any to `prog.name` over anything else: | script = [[ prog = { file = "file", line = 125, name = "name" } opts = { line = 99, program = "program" } ]] .. script - expect (luaproc (script)).should_output_error "name:125: Ayup!\n" + expect (luaproc (script)).to_output_error "name:125: Ayup!\n" - it prefers `prog.file` to `opts.program`: | script = [[ prog = { file = "file" }; opts = { program = "program" } ]] .. script - expect (luaproc (script)).should_output_error "file: Ayup!\n" + expect (luaproc (script)).to_output_error "file: Ayup!\n" - it appends `prog.line` if any to `prog.file` over using `opts`: | script = [[ prog = { file = "file", line = 125 } opts = { line = 99, program = "program" } ]] .. script - expect (luaproc (script)).should_output_error "file:125: Ayup!\n" + expect (luaproc (script)).to_output_error "file:125: Ayup!\n" - it prefixes `opts.program` if any: | script = [[opts = { program = "program" };]] .. script - expect (luaproc (script)).should_output_error "program: Ayup!\n" + expect (luaproc (script)).to_output_error "program: Ayup!\n" - it appends `opts.line` if any, to `opts.program`: | script = [[opts = { line = 99, program = "program" };]] .. script - expect (luaproc (script)).should_output_error "program:99: Ayup!\n" + expect (luaproc (script)).to_output_error "program:99: Ayup!\n" - describe writelines: diff --git a/specs/list_spec.yaml b/specs/list_spec.yaml index 523b058..3ebf355 100644 --- a/specs/list_spec.yaml +++ b/specs/list_spec.yaml @@ -1,5 +1,4 @@ before: - require "spec_helper" Object = require "std.object" List = require "std.list" l = List {"foo", "bar", "baz"} @@ -10,72 +9,72 @@ specify std.list: - context by name: - it does not touch the global table: expect (show_apis {added_to="_G", by="std.list"}). - should_equal {} + to_equal {} - describe construction: - context from List clone method: - it constructs a new list: l = List:clone {} - expect (l).should_not_be (List) - expect (Object.type (l)).should_be "List" + expect (l).not_to_be (List) + expect (Object.type (l)).to_be "List" - it reuses the List metatable: l, m = List:clone {"l"}, List:clone {"m"} - expect (getmetatable (l)).should_be (getmetatable (m)) + expect (getmetatable (l)).to_be (getmetatable (m)) - it initialises list with constructor parameters: m = List:clone {"foo", "bar", "baz"} - expect (m).should_equal (l) + expect (m).to_equal (l) - it serves as a prototype for new instances: obj = l:clone {} - expect (Object.type (obj)).should_be "List" - expect (obj).should_equal (l) - expect (getmetatable (obj)).should_be (getmetatable (l)) + expect (Object.type (obj)).to_be "List" + expect (obj).to_equal (l) + expect (getmetatable (obj)).to_be (getmetatable (l)) # List {args} is just syntactic sugar for List:clone {args} - context from List object prototype: - it constructs a new list: l = List {} - expect (l).should_not_be (List) - expect (Object.type (l)).should_be "List" + expect (l).not_to_be (List) + expect (Object.type (l)).to_be "List" - it reuses the List metatable: l, m = List {"l"}, List {"m"} - expect (getmetatable (l)).should_be (getmetatable (m)) + expect (getmetatable (l)).to_be (getmetatable (m)) - it initialises list with constructor parameters: m = List {"foo", "bar", "baz"} - expect (m).should_equal (l) + expect (m).to_equal (l) - it serves as a prototype for new instances: obj = l {} - expect (Object.type (obj)).should_be "List" - expect (obj).should_equal (l) - expect (getmetatable (obj)).should_be (getmetatable (l)) + expect (Object.type (obj)).to_be "List" + expect (obj).to_equal (l) + expect (getmetatable (obj)).to_be (getmetatable (l)) - describe metatable propagation: - it reuses the metatable for List constructed objects: obj = List {"foo", "bar"} - expect (getmetatable (obj)).should_be (getmetatable (l)) + expect (getmetatable (obj)).to_be (getmetatable (l)) - describe append: - context when called as a list object method: - it returns a list object: l = l:append ("quux") - expect (Object.type (l)).should_be "List" + expect (Object.type (l)).to_be "List" - it works for an empty list: l = List {} - expect (l:append ("quux")).should_equal (List {"quux"}) + expect (l:append ("quux")).to_equal (List {"quux"}) - it appends an item to a list: expect (l:append ("quux")). - should_equal (List {"foo", "bar", "baz", "quux"}) + to_equal (List {"foo", "bar", "baz", "quux"}) - context when called as a list metamethod: - it returns a list object: l = l + "quux" - expect (Object.type (l)).should_be "List" + expect (Object.type (l)).to_be "List" - it works for an empty list: l = List {} - expect (l + "quux").should_equal (List {"quux"}) + expect (l + "quux").to_equal (List {"quux"}) - it appends an item to a list: expect (l + "quux"). - should_equal (List {"foo", "bar", "baz", "quux"}) + to_equal (List {"foo", "bar", "baz", "quux"}) - describe compare: @@ -83,45 +82,45 @@ specify std.list: a, b = List {"foo", "bar"}, List {"foo", "baz"} - context when called as a list object method: - it returns -1 when the first list is less than the second: | - expect (a:compare {"foo", "baz"}).should_be (-1) - expect (a:compare (List {"foo", "baz"})).should_be (-1) + expect (a:compare {"foo", "baz"}).to_be (-1) + expect (a:compare (List {"foo", "baz"})).to_be (-1) - it returns -1 when the second list has additional elements: | b = List {"foo"} - expect (b:compare {"foo", "bar"}).should_be (-1) - expect (List {"foo"}:compare (List {"foo", "bar"})).should_be (-1) + expect (b:compare {"foo", "bar"}).to_be (-1) + expect (List {"foo"}:compare (List {"foo", "bar"})).to_be (-1) - it returns 0 when two lists are the same: | - expect (a:compare {"foo", "bar"}).should_be (0) - expect (a:compare (List {"foo", "bar"})).should_be (0) + expect (a:compare {"foo", "bar"}).to_be (0) + expect (a:compare (List {"foo", "bar"})).to_be (0) - it returns +1 when the first list is greater than the second: | - expect (a:compare {"baz", "quux"}).should_be (1) - expect (a:compare (List {"baz", "quux"})).should_be (1) + expect (a:compare {"baz", "quux"}).to_be (1) + expect (a:compare (List {"baz", "quux"})).to_be (1) - it returns +1 when the first list has additional elements: | - expect (a:compare {"foo"}).should_be (1) - expect (a:compare (List {"foo"})).should_be (1) + expect (a:compare {"foo"}).to_be (1) + expect (a:compare (List {"foo"})).to_be (1) - context when called as a '<' list metamethod: - it succeeds when the first list is less than the second: - expect (a < b).should_be (true) + expect (a < b).to_be (true) - it fails when the first list is not less than the second: - expect (a < a).should_be (false) - expect (b < a).should_be (false) + expect (a < a).to_be (false) + expect (b < a).to_be (false) - context when called as a '>' list metamethod: - it succeeds when the first list is greater than the second: - expect (b > a).should_be (true) + expect (b > a).to_be (true) - it fails when the first list is not greater than the second: - expect (b > b).should_be (false) - expect (a > b).should_be (false) + expect (b > b).to_be (false) + expect (a > b).to_be (false) - context when called as a '<=' list metamethod: - it succeeds when the first list is less than or equal to the second: - expect (a <= b).should_be (true) - expect (a <= a).should_be (true) + expect (a <= b).to_be (true) + expect (a <= a).to_be (true) - it fails when the first list is not less than or equal to the second: - expect (b <= a).should_be (false) + expect (b <= a).to_be (false) - context when called as a '>=' list metamethod: - it succeeds when the first list is greater than or equal to the second: - expect (b >= a).should_be (true) - expect (b >= b).should_be (true) + expect (b >= a).to_be (true) + expect (b >= b).to_be (true) - it fails when the first list is not greater than or equal to the second: - expect (a >= b).should_be (false) + expect (a >= b).to_be (false) - describe concat: @@ -130,40 +129,40 @@ specify std.list: - context when called as a list object method: - it returns a list object: l = l:concat (List {"baz"}) - expect (Object.type (l)).should_be "List" + expect (Object.type (l)).to_be "List" - it works for an empty list: l = List {} - expect (l:concat (List {"baz"})).should_equal (List {"baz"}) + expect (l:concat (List {"baz"})).to_equal (List {"baz"}) - it concatenates lists: expect (l:concat (List {"baz", "quux"})). - should_equal (List {"foo", "bar", "baz", "quux"}) + to_equal (List {"foo", "bar", "baz", "quux"}) expect (l:concat (List {"baz"}, List {"quux"})). - should_equal (List {"foo", "bar", "baz", "quux"}) + to_equal (List {"foo", "bar", "baz", "quux"}) - context whne called as a list metamethod: - it returns a list object: l = l .. List {"baz"} - expect (Object.type (l)).should_be "List" + expect (Object.type (l)).to_be "List" - it works for an empty list: l = List {} - expect (l .. List {"baz"}).should_equal (List {"baz"}) + expect (l .. List {"baz"}).to_equal (List {"baz"}) - it concatenates lists: expect (l .. List {"baz", "quux"}). - should_equal (List {"foo", "bar", "baz", "quux"}) + to_equal (List {"foo", "bar", "baz", "quux"}) expect (l .. List {"baz"} .. List {"quux"}). - should_equal (List {"foo", "bar", "baz", "quux"}) + to_equal (List {"foo", "bar", "baz", "quux"}) - describe cons: - context when called as a list object method: - it returns a list object: l = l:cons "quux" - expect (Object.type (l)).should_be "List" + expect (Object.type (l)).to_be "List" - it works for empty lists: l = List {} - expect (l:cons "quux").should_equal (List {"quux"}) + expect (l:cons "quux").to_equal (List {"quux"}) - it prepends an item to a list: expect (l:cons "quux"). - should_equal (List {"quux", "foo", "bar", "baz"}) + to_equal (List {"quux", "foo", "bar", "baz"}) - describe depair: @@ -174,31 +173,31 @@ specify std.list: - it diagnoses an argument that is not a list of lists: - context when called as a list object method: - it returns a primitive table: - expect (Object.type (l:depair ())).should_be "table" + expect (Object.type (l:depair ())).to_be "table" - it works with an empty list: l = List {} - expect (l:depair ()).should_equal {} + expect (l:depair ()).to_equal {} - it is the inverse of enpair: - expect (l:depair ()).should_equal (t) + expect (l:depair ()).to_equal (t) - describe elems: - it is an iterator over list members: t = {} for e in List.elems (l) do table.insert (t, e) end - expect (t).should_equal {"foo", "bar", "baz"} + expect (t).to_equal {"foo", "bar", "baz"} - it works for an empty list: t = {} for e in List.elems (List {}) do table.insert (t, e) end - expect (t).should_equal {} + expect (t).to_equal {} - it can be called from the list module: t = {} for e in List.elems (l) do table.insert (t, e) end - expect (t).should_equal {"foo", "bar", "baz"} + expect (t).to_equal {"foo", "bar", "baz"} - it can be called as a list object method: t = {} for e in l:elems () do table.insert (t, e) end - expect (t).should_equal {"foo", "bar", "baz"} + expect (t).to_equal {"foo", "bar", "baz"} - describe enpair: @@ -208,12 +207,12 @@ specify std.list: - it diagnoses a missing argument: - it diagnoses a non-table argument: - it returns a list object: - expect (Object.type (List.enpair (t))).should_be "List" + expect (Object.type (List.enpair (t))).to_be "List" - it works for an empty table: - expect (List.enpair {}).should_equal (List {}) + expect (List.enpair {}).to_equal (List {}) - it turns a table into a list of pairs: expect (List.enpair (t)). - should_equal (List {List {1, "first"}, List {2, "second"}, List {"third", 4}}) + to_equal (List {List {1, "first"}, List {2, "second"}, List {"third", 4}}) - describe filter: @@ -224,12 +223,12 @@ specify std.list: - context when called as a list object method: - it returns a list object: m = l:filter (p) - expect (Object.type (m)).should_be "List" + expect (Object.type (m)).to_be "List" - it works for an empty list: l = List {} - expect (l:filter (p)).should_equal (List {}) + expect (l:filter (p)).to_equal (List {}) - it filters a list according to a predicate: - expect (l:filter (p)).should_equal (List {"bar", "baz"}) + expect (l:filter (p)).to_equal (List {"bar", "baz"}) - describe flatten: @@ -239,13 +238,13 @@ specify std.list: - context when called as a list object method: - it returns a list object: m = List.flatten (l) - expect (Object.type (m)).should_be "List" + expect (Object.type (m)).to_be "List" - it works for an empty list: l = List {} - expect (l:flatten ()).should_equal (List {}) + expect (l:flatten ()).to_equal (List {}) - it flattens a list: expect (l:flatten ()). - should_equal (List {"one", "two", "three", "four"}) + to_equal (List {"one", "two", "three", "four"}) - describe foldl: @@ -256,9 +255,9 @@ specify std.list: - context when called as a list object method: - it works with an empty list: l = List {} - expect (l:foldl (op["+"], 10000)).should_be (10000) + expect (l:foldl (op["+"], 10000)).to_be (10000) - it folds a binary function through a list: - expect (l:foldl (op["+"], 10000)).should_be (10111) + expect (l:foldl (op["+"], 10000)).to_be (10111) - describe foldr: @@ -269,9 +268,9 @@ specify std.list: - context when called as a list object method: - it works with an empty list: l = List {} - expect (l:foldl (op["/"], 1)).should_be (1) + expect (l:foldl (op["/"], 1)).to_be (1) - it folds a binary function through a list: - expect (l:foldl (op["/"], 10000)).should_be (10) + expect (l:foldl (op["/"], 10000)).to_be (10) - describe index_key: @@ -288,18 +287,18 @@ specify std.list: - context when called as a list object method: - it returns a list object: m = l:map (f) - expect (Object.type (m)).should_be "List" + expect (Object.type (m)).to_be "List" - it works for an empty list: l = List {} - expect (l:map (f)).should_equal (List {}) + expect (l:map (f)).to_equal (List {}) - it creates a new list: o = l m = l:map (f) - expect (l).should_equal (o) - expect (m).should_not_equal (o) - expect (l).should_equal (List {1, 2, 3, 4, 5}) + expect (l).to_equal (o) + expect (m).not_to_equal (o) + expect (l).to_equal (List {1, 2, 3, 4, 5}) - it maps a function over a list: - expect (l:map (f)).should_equal (List {1, 4, 9, 16, 25}) + expect (l:map (f)).to_equal (List {1, 4, 9, 16, 25}) - describe map_with: @@ -311,18 +310,18 @@ specify std.list: - context when called as a list object method: - it returns a list object: m = l:map_with (f) - expect (Object.type (m)).should_be "List" + expect (Object.type (m)).to_be "List" - it works for an empty list: l = List {} - expect (l:map_with (f)).should_equal (List {}) + expect (l:map_with (f)).to_equal (List {}) - it creates a new list: o = l m = l:map_with (f) - expect (l).should_equal (o) - expect (m).should_not_equal (o) - expect (l).should_equal (List {List {1, 2, 3}, List {4, 5}}) + expect (l).to_equal (o) + expect (m).not_to_equal (o) + expect (l).to_equal (List {List {1, 2, 3}, List {4, 5}}) - it maps a function over a list: - expect (l:map_with (f)).should_equal (List {3, 2}) + expect (l:map_with (f)).to_equal (List {3, 2}) - describe project: @@ -337,36 +336,35 @@ specify std.list: - context when called as a list object method: - it returns a list object: p = l:project ("third") - expect (Object.type (p)).should_be "List" + expect (Object.type (p)).to_be "List" - it works with an empty list: l = List {} - expect (l:project ("third")).should_equal (List {}) + expect (l:project ("third")).to_equal (List {}) - it projects a list of fields from a list of tables: expect (l:project ("third")). - should_equal (List {true, 3, "3rd"}) - - it projects fields with a falsey value correctly: | - pending "see issue #34" + to_equal (List {true, 3, "3rd"}) + - it projects fields with a falsey value correctly: expect (l:project ("first")). - should_equal (List {false, 1, "1st"}) + to_equal (List {false, 1, "1st"}) - describe relems: - it is a reverse iterator over list members: t = {} for e in List.relems (l) do table.insert (t, e) end - expect (t).should_equal {"baz", "bar", "foo"} + expect (t).to_equal {"baz", "bar", "foo"} - it works for an empty list: t = {} for e in List.relems (List {}) do table.insert (t, e) end - expect (t).should_equal {} + expect (t).to_equal {} - it can be called from the list module: t = {} for e in List.relems (l) do table.insert (t, e) end - expect (t).should_equal {"baz", "bar", "foo"} + expect (t).to_equal {"baz", "bar", "foo"} - it can be called as a list object method: t = {} for e in l:relems () do table.insert (t, e) end - expect (t).should_equal {"baz", "bar", "foo"} + expect (t).to_equal {"baz", "bar", "foo"} - describe rep: @@ -374,13 +372,13 @@ specify std.list: - context when called as a list object method: - it returns a list object: - expect (Object.type (l:rep (3))).should_be "List" + expect (Object.type (l:rep (3))).to_be "List" - it works for an empty list: l = List {} - expect (l:rep (99)).should_equal (List {}) + expect (l:rep (99)).to_equal (List {}) - it repeats the contents of a list: expect (l:rep (3)). - should_equal (List {"foo", "bar", "foo", "bar", "foo", "bar"}) + to_equal (List {"foo", "bar", "foo", "bar", "foo", "bar"}) - describe reverse: @@ -388,16 +386,16 @@ specify std.list: - context when called as a list object method: - it returns a list object: - expect (Object.type (l:reverse ())).should_be "List" + expect (Object.type (l:reverse ())).to_be "List" - it works for an empty list: l = List {} - expect (l:reverse ()).should_equal (List {}) + expect (l:reverse ()).to_equal (List {}) - it makes a new reversed list: m = l expect (l:reverse ()). - should_equal (List {"quux", "baz", "bar", "foo"}) - expect (l).should_equal (List {"foo", "bar", "baz", "quux"}) - expect (l).should_be (m) + to_equal (List {"quux", "baz", "bar", "foo"}) + expect (l).to_equal (List {"foo", "bar", "baz", "quux"}) + expect (l).to_be (m) - describe shape: @@ -408,21 +406,21 @@ specify std.list: - context when called as a list object method: - it returns a list object: | - expect (Object.type (l:sub (1, 1))).should_be "List" + expect (Object.type (l:sub (1, 1))).to_be "List" - it makes a list from a subrange of another list: | - expect (l:sub (2, 5)).should_equal (List {2, 3, 4, 5}) + expect (l:sub (2, 5)).to_equal (List {2, 3, 4, 5}) - it truncates the result if 'to' argument is too large: | - expect (l:sub (5, 10)).should_equal (List {5, 6, 7}) + expect (l:sub (5, 10)).to_equal (List {5, 6, 7}) - it defaults 'to' to the end of the list: | - expect (l:sub (5)).should_equal (List {5, 6, 7}) + expect (l:sub (5)).to_equal (List {5, 6, 7}) - it defaults 'from' to the beginning of the list: | - expect (l:sub ()).should_equal (l) + expect (l:sub ()).to_equal (l) - it returns an empty list when 'from' is greater than 'to': | - expect (l:sub (2, 1)).should_equal (List {}) + expect (l:sub (2, 1)).to_equal (List {}) - it counts from the end of the list for a negative 'from' argument: | - expect (l:sub (-3)).should_equal (List {5, 6, 7}) + expect (l:sub (-3)).to_equal (List {5, 6, 7}) - it counts from the end of the list for a negative 'to' argument: | - expect (l:sub (-5, -2)).should_equal (List {3, 4, 5, 6}) + expect (l:sub (-5, -2)).to_equal (List {3, 4, 5, 6}) - describe tail: @@ -430,15 +428,15 @@ specify std.list: - context when called as a list object method: - it returns a list object: | - expect (Object.type (l:tail ())).should_be "List" + expect (Object.type (l:tail ())).to_be "List" - it makes a new list with the first element removed: | - expect (l:tail ()).should_equal (List {2, 3, 4, 5, 6, 7}) + expect (l:tail ()).to_equal (List {2, 3, 4, 5, 6, 7}) - it works for an empty list: | l = List {} - expect (l:tail ()).should_equal (List {}) + expect (l:tail ()).to_equal (List {}) - it returns an empty list when passed a list with one element: | l = List {1} - expect (l:tail ()).should_equal (List {}) + expect (l:tail ()).to_equal (List {}) - describe transpose: diff --git a/specs/math_spec.yaml b/specs/math_spec.yaml index 02c2cb0..8c7895b 100644 --- a/specs/math_spec.yaml +++ b/specs/math_spec.yaml @@ -1,6 +1,4 @@ before: | - require "spec_helper" - this_module = "std.math" global_table = "_G" @@ -8,7 +6,7 @@ before: | extend_base = { "round", "_floor" } enhance_base = { "floor" } - -- 'should_contain' will match keys as well as values :) + -- 'to_contain' will match keys as well as values :) all_apis = {} for _, s in ipairs (extend_base) do all_apis[s] = true end for _, s in ipairs (enhance_base) do all_apis[s] = true end @@ -20,21 +18,21 @@ specify std.math: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - it contains apis from the core math table: expect (show_apis {from=base_module, not_in=this_module}). - should_contain.a_permutation_of (all_apis) + to_contain.a_permutation_of (all_apis) - it enhances some apis from the core math table: expect (show_apis {from=base_module, enhanced_in=this_module}). - should_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (enhance_base) - context via the std module: - it adds apis to the core math table: expect (show_apis {added_to=base_module, by="std"}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - it replaces some apis from the core math table: expect (show_apis {from=base_module, enhanced_after='require "std"'}). - should_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (enhance_base) - describe floor: diff --git a/specs/object_spec.yaml b/specs/object_spec.yaml index c0102f3..acf06ba 100644 --- a/specs/object_spec.yaml +++ b/specs/object_spec.yaml @@ -1,5 +1,4 @@ before: - require "spec_helper" Object = require "std.object" obj = Object {"foo", "bar", baz="quux"} prototype = Object.prototype @@ -9,72 +8,69 @@ specify std.object: - context by name: - it does not touch the global table: expect (show_apis {added_to="_G", by="std.object"}). - should_equal {} + to_equal {} - describe construction: - context from Object clone method: - it constructs a new object: obj = Object:clone {} - expect (obj).should_not_be (Object) - expect (type (obj)).should_be "table" - expect (prototype (obj)).should_be "Object" + expect (obj).not_to_be (Object) + expect (type (obj)).to_be "table" + expect (prototype (obj)).to_be "Object" - it reuses the Object metatable: o = obj:clone {"o"} p = o:clone {"p"} - expect (p).should_not_be (o) - expect (getmetatable (o)).should_be (getmetatable (p)) + expect (p).not_to_be (o) + expect (getmetatable (o)).to_be (getmetatable (p)) - it sets object fields from arguments: - o = obj:clone {} - expect (o).should_not_be (obj) - expect (o).should_equal (obj) + expect (obj:clone {}).to_copy (obj) - it serves as a prototype for new instances: o = obj:clone {} - expect (prototype (o)).should_be "Object" - expect (o).should_not_be (obj) - expect (o).should_equal (obj) - expect (getmetatable (o)).should_be (getmetatable (obj)) + expect (prototype (o)).to_be "Object" + expect (o).to_copy (obj) + expect (getmetatable (o)).to_be (getmetatable (obj)) - it separates '_' prefixed fields: expect (Object:clone {foo="bar", _baz="quux"}). - should_equal (Object:clone {foo="bar"}) + to_equal (Object:clone {foo="bar"}) - it puts '_' prefixed fields in a new metatable: obj = Object:clone {foo="bar", _baz="quux"} - expect (getmetatable (obj)).should_not_be (getmetatable (Object)) - expect (getmetatable (obj)._baz).should_be "quux" + expect (getmetatable (obj)).not_to_be (getmetatable (Object)) + expect (getmetatable (obj)._baz).to_be "quux" - describe prototype: - before: o = Object {} - context when called from the object module: - it reports the prototype stored in the object's metatable: - expect (prototype (o)).should_be "Object" + expect (prototype (o)).to_be "Object" - it reports the type of a cloned object: - expect (prototype (o {})).should_be "Object" + expect (prototype (o {})).to_be "Object" - it reports the type of a derived object: Example = Object {_type = "Example"} - expect (prototype (Example)).should_be "Example" + expect (prototype (Example)).to_be "Example" - it reports the type of a cloned derived object: Portal = Object {_type = "Demon"} p = Portal {} - expect (prototype (p)).should_be "Demon" - expect (prototype (p {})).should_be "Demon" + expect (prototype (p)).to_be "Demon" + expect (prototype (p {})).to_be "Demon" - context when called as an object method: - it reports the type stored in the object's metatable: - expect (o:prototype ()).should_be "Object" + expect (o:prototype ()).to_be "Object" - it reports the type of a cloned object: - expect ((o {}):prototype ()).should_be "Object" + expect ((o {}):prototype ()).to_be "Object" - it reports the type of a subclassed object: Example = Object {_type = "Example"} - expect (Example:prototype ()).should_be "Example" + expect (Example:prototype ()).to_be "Example" - it reports the type of a cloned subclassed object: Portal = Object {_type = "Demon"} p = Portal {} - expect (p:prototype ()).should_be "Demon" - expect ((p {}):prototype ()).should_be "Demon" + expect (p:prototype ()).to_be "Demon" + expect ((p {}):prototype ()).to_be "Demon" - context backwards compatibility: - it reports the prototype stored in the object's metatable: - expect (Object.type (o)).should_be "Object" + expect (Object.type (o)).to_be "Object" - it reports the type stored in the object's metatable: - expect (o:type ()).should_be "Object" + expect (o:type ()).to_be "Object" - describe instantiation from a prototype: @@ -90,19 +86,19 @@ specify std.object: Array._init = nil - it contains user-defined fields: expect (totable (Array)). - should_equal {"foo", "bar", "baz"} + to_equal {"foo", "bar", "baz"} - it sets array part of instance object from positional parameters: array = Array {"first", "second", "third"} expect (totable (array)). - should_equal {"first", "second", "third"} + to_equal {"first", "second", "third"} - it uses prototype values for missing positional parameters: array = Array {"first", "second"} expect (totable (array)). - should_equal {"first", "second", "baz"} + to_equal {"first", "second", "baz"} - it merges surplas positional parameters: array = Array {"first", "second", "third", "fourth"} expect (totable (array)). - should_equal {"first", "second", "third", "fourth"} + to_equal {"first", "second", "third", "fourth"} - context when _init is an empty table: - before: @@ -113,12 +109,10 @@ specify std.object: } - it contains user-defined fields: expect (totable (Prototype)). - should_equal {"first", "second", "third"} + to_equal {"first", "second", "third"} - it ignores positional parameters: | instance = Prototype {"foo", "bar"} - expect (instance).should_not_be (Prototype) - pending "see issue #35" - expect (instance).should_equal (Prototype) + expect (instance).to_copy (Prototype) - context when _init is a table of field names: - before: @@ -131,20 +125,19 @@ specify std.object: } - it contains user-defined fields: expect (totable (Process)). - should_equal {status = -1, output = "empty", errout = "no errors"} + to_equal {status = -1, output = "empty", errout = "no errors"} - it sets user-defined fields from positional parameters: proc = Process {0, "output", "diagnostics"} expect (totable (proc)). - should_equal {status = 0, output = "output", errout = "diagnostics"} + to_equal {status = 0, output = "output", errout = "diagnostics"} - it uses prototype values for missing positional parameters: proc = Process {0, "output"} expect (totable (proc)). - should_equal {status = 0, output = "output", errout = "no errors"} - - it merges surplus positional parameters into array part of new object: | + to_equal {status = 0, output = "output", errout = "no errors"} + - it discards surplus positional parameters: proc = Process {0, "output", "diagnostics", "garbage"} - pending "see issue #35" expect (totable (proc)). - should_equal { status = 0, output = "output", errout = "diagnostics" } + to_equal { status = 0, output = "output", errout = "diagnostics" } - context when _init is a function: - before: @@ -159,7 +152,7 @@ specify std.object: - it passes user defined fields to custom _init function: instance = Prototype {"param1", "param2"} expect ({instance.f1, instance.f2, instance.args}). - should_equal {"proto1", "proto2", {"param1", "param2"}} + to_equal {"proto1", "proto2", {"param1", "param2"}} - describe field access: - before: @@ -179,29 +172,29 @@ specify std.object: } - it provides object field access with dot notation: - expect (instance.field).should_be "in object" + expect (instance.field).to_be "in object" - it provides class field acces with dot notation: - expect (Prototype.field).should_be "in prototype" + expect (Prototype.field).to_be "in prototype" - it provides object method acces with colon notation: expect (instance:method "object method call"). - should_be "Prototype instance, object method call" + to_be "Prototype instance, object method call" - it provides class method access with class dot notation: expect (Prototype.method (instance, "class method call")). - should_be "Prototype class, class method call" + to_be "Prototype class, class method call" - it allows new instance fields to be added: instance.newfield = "new" - expect (instance.newfield).should_be "new" + expect (instance.newfield).to_be "new" - it allows new instance methods to be added: instance.newmethod = function (self) return prototype (self) .. ", new instance method" end - expect (instance:newmethod ()).should_be "Prototype, new instance method" + expect (instance:newmethod ()).to_be "Prototype, new instance method" - it allows new class methods to be added: Prototype.newmethod = function (self) return prototype (self) .. ", new class method" end expect (Prototype.newmethod (instance)). - should_be "Prototype, new class method" + to_be "Prototype, new class method" - describe object method propagation: @@ -209,11 +202,11 @@ specify std.object: # :prototype is a method defined by the root object - it inherits prototype object methods: instance = Object {} - expect (instance:prototype ()).should_be "Object" + expect (instance:prototype ()).to_be "Object" - it propagates prototype methods to derived instances: Derived = Object {_type = "Derived"} instance = Derived {} - expect (instance:prototype ()).should_be "Derived" + expect (instance:prototype ()).to_be "Derived" - context with custom object methods: - before: bag = Object { @@ -227,13 +220,13 @@ specify std.object: } # :prototype is a method defined by the root object - it inherits prototype object methods: - expect (bag:prototype ()).should_be "bag" + expect (bag:prototype ()).to_be "bag" - it propagates prototype methods to derived instances: instance = bag {} - expect (instance:prototype ()).should_be "bag" + expect (instance:prototype ()).to_be "bag" - it supports method calls: - expect (bag:add "foo").should_be (bag) - expect (bag.foo).should_be (1) + expect (bag:add "foo").to_be (bag) + expect (bag.foo).to_be (1) # Metatable propagation is an important property of Object cloning, @@ -247,12 +240,12 @@ specify std.object: - context with no custom metamethods: - it inherits prototype object metatable: instance = Object {} - expect (getmetatable (instance)).should_be (root_mt) + expect (getmetatable (instance)).to_be (root_mt) - it propagates prototype metatable to derived instances: Derived = Object {_type = "Derived"} instance = Derived {} - expect (getmetatable (Derived)).should_not_be (root_mt) - expect (getmetatable (instance)).should_be (getmetatable (Derived)) + expect (getmetatable (Derived)).not_to_be (root_mt) + expect (getmetatable (instance)).to_be (getmetatable (Derived)) - context with custom metamethods: - before: base = require "std.base" @@ -261,15 +254,15 @@ specify std.object: __lt = function (a, b) return base.compare (a, b) < 0 end, } - it has it's own metatable: - expect (getmetatable (bag)).should_not_be (root_mt) + expect (getmetatable (bag)).not_to_be (root_mt) - it propagates prototype metatable to derived instances: instance = bag {} - expect (getmetatable (instance)).should_be (getmetatable (bag)) + expect (getmetatable (instance)).to_be (getmetatable (bag)) - it supports __lt calls: a, b = bag {"a"}, bag {"b"} - expect (a < b).should_be (true) - expect (a < a).should_be (false) - expect (a > b).should_be (false) + expect (a < b).to_be (true) + expect (a < a).to_be (false) + expect (a > b).to_be (false) - describe __totable: @@ -278,31 +271,31 @@ specify std.object: Derived = Object {_type = "Derived", "one", "two", three = true} - it returns a table: - expect (prototype (totable (Derived))).should_be "table" + expect (prototype (totable (Derived))).to_be "table" - it contains all non-hidden fields of object: - expect (totable (Derived)).should_contain.all_of {"one", "two", "three"} + expect (totable (Derived)).to_contain.all_of {"one", "two", "three"} - it does not contain any hidden fields of object: - expect (totable (Derived)).should_equal {"one", "two", three = true} + expect (totable (Derived)).to_equal {"one", "two", three = true} - describe __tostring: - before: obj = Object {_type = "Derived", "one", "two", "three"} - it returns a string: - expect (type (tostring (obj))).should_be "string" + expect (type (tostring (obj))).to_be "string" - it contains the type: - expect (tostring (Object {})).should_contain "Object" - expect (tostring (obj)).should_contain (prototype (obj)) + expect (tostring (Object {})).to_contain "Object" + expect (tostring (obj)).to_contain (prototype (obj)) - it contains the ordered array part elements: - expect (tostring (obj)).should_contain "one, two, three" + expect (tostring (obj)).to_contain "one, two, three" - it contains the ordered dictionary part elements: expect (tostring (Object {one = true, two = true, three = true})). - should_contain "one=true, three=true, two=true" + to_contain "one=true, three=true, two=true" expect (tostring (obj {one = true, two = true, three = true})). - should_contain "one=true, three=true, two=true" + to_contain "one=true, three=true, two=true" - it contains a ';' separator only when object has array and dictionary parts: - expect (tostring (obj)).should_not_contain ";" + expect (tostring (obj)).not_to_contain ";" expect (tostring (Object {one = true, two = true, three = true})). - should_not_contain ";" + not_to_contain ";" expect (tostring (obj {one = true, two = true, three = true})). - should_contain ";" + to_contain ";" diff --git a/specs/optparse_spec.yaml b/specs/optparse_spec.yaml index c16829a..feae149 100644 --- a/specs/optparse_spec.yaml +++ b/specs/optparse_spec.yaml @@ -1,5 +1,4 @@ before: - require "spec_helper" hell = require "specl.shell" specify std.optparse: @@ -7,9 +6,9 @@ specify std.optparse: OptionParser = require "std.optparse" help = [[ - parseme (specl spec) 0α1 + parseme (stdlib spec) 0α1 - Copyright © 2013 Gary V. Vaughan + Copyright © 2014 Gary V. Vaughan This test program comes with ABSOLUTELY NO WARRANTY. Usage: parseme [] ... @@ -34,7 +33,7 @@ specify std.optparse: Footer text. - Please report bugs at . + Please report bugs at . ]] -- strip off the leading whitespace required for YAML @@ -44,22 +43,22 @@ specify std.optparse: - context by name: - it does not touch the global table: expect (show_apis {added_to="_G", by="std.optparse"}). - should_equal {} + to_equal {} - describe OptionParser: - it recognises the program name: - expect (parser.program).should_be "parseme" + expect (parser.program).to_be "parseme" - it recognises the version number: - expect (parser.version).should_be "0α1" + expect (parser.version).to_be "0α1" - it recognises the version text: expect (parser.versiontext). - should_match "^parseme .*Copyright .*NO WARRANTY%." + to_match "^parseme .*Copyright .*NO WARRANTY%." - it recognises the help text: | expect (parser.helptext). - should_match ("^Usage: parseme .*Banner .*Long .*Options:.*" .. + to_match ("^Usage: parseme .*Banner .*Long .*Options:.*" .. "Footer .*/issues>%.") - it diagnoses incorrect input text: - expect (OptionParser "garbage in").should_error "argument must match" + expect (OptionParser "garbage in").to_error "argument must match" - describe parser: - before: | @@ -96,86 +95,194 @@ specify std.optparse: end - after: os.remove (f) - - it leaves behind unrecognised options: - expect (parse {"--not-an-option"}). - should_output "args = { --not-an-option }\n" - it responds to --version with version text: expect (parse {"--version"}). - should_match_output "^%s*parseme .*Copyright .*NO WARRANTY%.\n$" + to_match_output "^%s*parseme .*Copyright .*NO WARRANTY%.\n$" - it responds to --help with help text: | expect (parse {"--help"}). - should_match_output ("^%s*Usage: parseme .*Banner.*Long.*" .. + to_match_output ("^%s*Usage: parseme .*Banner.*Long.*" .. "Options:.*Footer.*/issues>%.\n$") + - it leaves behind unrecognised short options: + expect (parse {"-x"}).to_output "args = { -x }\n" - it recognises short options: - expect (parse {"-b"}).should_output "opts = { b = true }\n" + expect (parse {"-b"}).to_output "opts = { b = true }\n" + - it leaves behind unrecognised options: + expect (parse {"--not-an-option"}). + to_output "args = { --not-an-option }\n" - it recognises long options: - expect (parse {"--long"}).should_output "opts = { long = true }\n" + expect (parse {"--long"}).to_output "opts = { long = true }\n" - it recognises long options with hyphens: expect (parse {"--another-long"}). - should_output "opts = { another_long = true }\n" + to_output "opts = { another_long = true }\n" - it recognises long options named after Lua keywords: - expect (parse {"--true"}).should_output "opts = { true = true }\n" + expect (parse {"--true"}).to_output "opts = { true = true }\n" - it recognises combined short and long option specs: - expect (parse {"-v"}).should_output "opts = { verbose = true }\n" - expect (parse {"--verbose"}).should_output "opts = { verbose = true }\n" + expect (parse {"-v"}).to_output "opts = { verbose = true }\n" + expect (parse {"--verbose"}).to_output "opts = { verbose = true }\n" - it recognises options with several spellings: - expect (parse {"-n"}).should_output "opts = { dry_run = true }\n" - expect (parse {"--dry-run"}).should_output "opts = { dry_run = true }\n" - expect (parse {"--dryrun"}).should_output "opts = { dry_run = true }\n" + expect (parse {"-n"}).to_output "opts = { dry_run = true }\n" + expect (parse {"--dry-run"}).to_output "opts = { dry_run = true }\n" + expect (parse {"--dryrun"}).to_output "opts = { dry_run = true }\n" - it recognises end of options marker: - expect (parse {"-- -n"}).should_output "args = { -n }\n" + expect (parse {"-- -n"}).to_output "args = { -n }\n" + - context given an unhandled long option: + - it leaves behind unmangled argument: + expect (parse {"--not-an-option=with-an-argument"}). + to_output "args = { --not-an-option=with-an-argument }\n" - context given an option with a required argument: - it records an argument to a long option following an '=' delimiter: expect (parse {"--name=Gary"}). - should_output "opts = { name = Gary }\n" + to_output "opts = { name = Gary }\n" - it records an argument to a short option without a space: expect (parse {"-uGary"}). - should_output "opts = { name = Gary }\n" + to_output "opts = { name = Gary }\n" - it records an argument to a long option following a space: expect (parse {"--name Gary"}). - should_output "opts = { name = Gary }\n" + to_output "opts = { name = Gary }\n" - it records an argument to a short option following a space: expect (parse {"-u Gary"}). - should_output "opts = { name = Gary }\n" + to_output "opts = { name = Gary }\n" - it diagnoses a missing argument: expect (parse {"--name"}). - should_contain_error "'--name' requires an argument" + to_contain_error "'--name' requires an argument" expect (parse {"-u"}). - should_contain_error "'-u' requires an argument" + to_contain_error "'-u' requires an argument" - context given an option with an optional argument: - it records an argument to a long option following an '=' delimiter: expect (parse {"--output=filename"}). - should_output "opts = { output = filename }\n" + to_output "opts = { output = filename }\n" - it records an argument to a short option without a space: expect (parse {"-ofilename"}). - should_output "opts = { output = filename }\n" + to_output "opts = { output = filename }\n" - it records an argument to a long option following a space: expect (parse {"--output filename"}). - should_output "opts = { output = filename }\n" + to_output "opts = { output = filename }\n" - it records an argument to a short option following a space: expect (parse {"-o filename"}). - should_output "opts = { output = filename }\n" + to_output "opts = { output = filename }\n" - it doesn't consume the following option: expect (parse {"--output -v"}). - should_output "opts = { output = true, verbose = true }\n" + to_output "opts = { output = true, verbose = true }\n" expect (parse {"-o -v"}). - should_output "opts = { output = true, verbose = true }\n" + to_output "opts = { output = true, verbose = true }\n" - context when splitting combined short options: - it separates non-argument options: expect (parse {"-bn"}). - should_output "opts = { b = true, dry_run = true }\n" + to_output "opts = { b = true, dry_run = true }\n" expect (parse {"-vbn"}). - should_output "opts = { b = true, dry_run = true, verbose = true }\n" + to_output "opts = { b = true, dry_run = true, verbose = true }\n" - it stops separating at a required argument option: expect (parse {"-vuname"}). - should_output "opts = { name = name, verbose = true }\n" + to_output "opts = { name = name, verbose = true }\n" expect (parse {"-vuob"}). - shauld_output "opts = { name = ob, verbose = true }\n" + to_output "opts = { name = ob, verbose = true }\n" - it stops separating at an optional argument option: expect (parse {"-vofilename"}). - should_output "opts = { output = filename, verbose = true }\n" + to_output "opts = { output = filename, verbose = true }\n" expect (parse {"-vobn"}). - should_output "opts = { output = bn, verbose = true }\n" + to_output "opts = { output = bn, verbose = true }\n" + - it leaves behind unsplittable short options: + expect (parse {"-xvb"}).to_output "args = { -xvb }\n" + expect (parse {"-vxb"}).to_output "args = { -vxb }\n" + expect (parse {"-vbx"}).to_output "args = { -vbx }\n" + - it separates short options before unsplittable options: + expect (parse {"-vb -xvb"}). + to_output "opts = { b = true, verbose = true }\nargs = { -xvb }\n" + expect (parse {"-vb -vxb"}). + to_output "opts = { b = true, verbose = true }\nargs = { -vxb }\n" + expect (parse {"-vb -vbx"}). + to_output "opts = { b = true, verbose = true }\nargs = { -vbx }\n" + - it separates short options after unsplittable options: + expect (parse {"-xvb -vb"}). + to_output "opts = { b = true, verbose = true }\nargs = { -xvb }\n" + expect (parse {"-vxb -vb"}). + to_output "opts = { b = true, verbose = true }\nargs = { -vxb }\n" + expect (parse {"-vbx -vb"}). + to_output "opts = { b = true, verbose = true }\nargs = { -vbx }\n" + + - context with option defaults: + - before: | + function main (arg) + local OptionParser = require "std.optparse" + local parser = OptionParser ("program 0\nUsage: program\n" .. + " -x set x\n" .. + " -y set y\n" .. + " -z set z\n") + local state = { arg = {}, opts = { x={"t"}, y=false }} + state.arg, state.opts = parser:parse (arg, state.opts) + return state + end + - it prefers supplied argument: + expect (main {"-x", "-y"}). + to_equal { arg = {}, opts = { x=true, y=true }} + expect (main {"-x", "-y", "-z"}). + to_equal { arg = {}, opts = { x=true, y=true, z=true }} + expect (main {"-w", "-x", "-y"}). + to_equal { arg = {"-w"}, opts = { x=true, y=true }} + - it defers to default value: + expect (main {}). + to_equal { arg = {}, opts = { x={"t"}, y=false }} + expect (main {"-z"}). + to_equal { arg = {}, opts = { x={"t"}, y=false, z=true }} + expect (main {"-w"}). + to_equal { arg = {"-w"}, opts = { x={"t"}, y=false }} + + - context with io.die: + - before: | + runscript = function (code) + return luaproc ([[ + local OptionParser = require "std.optparse" + local parser = OptionParser ("program 0\nUsage: program\n") + _G.arg, _G.opts = parser:parse (_G.arg) + ]] .. code .. [[ + require "std.io".die "By 'eck!" + ]]) + end + - it prefers `prog.name` to `opts.program`: | + code = [[prog = { file = "file", name = "name" }]] + expect (runscript (code)).to_fail_with "name: By 'eck!\n" + - it prefers `prog.file` to `opts.program`: | + code = [[prog = { file = "file" }]] + expect (runscript (code)).to_fail_with "file: By 'eck!\n" + - it appends `prog.line` if any to `prog.file` over using `opts`: | + code = [[ + prog = { file = "file", line = 125 }; opts.line = 99]] + expect (runscript (code)).to_fail_with "file:125: By 'eck!\n" + - it prefixes `opts.program` if any: | + expect (runscript ("")).to_fail_with "program: By 'eck!\n" + - it appends `opts.line` if any, to `opts.program`: | + code = [[opts.line = 99]] + expect (runscript (code)). + to_fail_with "program:99: By 'eck!\n" + + - context with io.warn: + - before: | + runscript = function (code) + return luaproc ([[ + local OptionParser = require "std.optparse" + local parser = OptionParser ("program 0\nUsage: program\n") + _G.arg, _G.opts = parser:parse (_G.arg) + ]] .. code .. [[ + require "std.io".warn "Ayup!" + ]]) + end + - it prefers `prog.name` to `opts.program`: | + code = [[prog = { file = "file", name = "name" }]] + expect (runscript (code)).to_output_error "name: Ayup!\n" + - it prefers `prog.file` to `opts.program`: | + code = [[prog = { file = "file" }]] + expect (runscript (code)).to_output_error "file: Ayup!\n" + - it appends `prog.line` if any to `prog.file` over using `opts`: | + code = [[ + prog = { file = "file", line = 125 }; opts.line = 99]] + expect (runscript (code)). + to_output_error "file:125: Ayup!\n" + - it prefixes `opts.program` if any: | + expect (runscript ("")).to_output_error "program: Ayup!\n" + - it appends `opts.line` if any, to `opts.program`: | + code = [[opts.line = 99]] + expect (runscript (code)). + to_output_error "program:99: Ayup!\n" - describe parser:on: - before: | @@ -217,211 +324,154 @@ specify std.optparse: - it recognises short options: expect (parseargs ([["x"]], {"-x"})). - should_output "opts = { x = true }\n" + to_output "opts = { x = true }\n" - it recognises long options: expect (parseargs([["something"]], {"--something"})). - should_output "opts = { something = true }\n" + to_output "opts = { something = true }\n" - it recognises long options with hyphens: expect (parseargs([["some-thing"]], {"--some-thing"})). - should_output "opts = { some_thing = true }\n" + to_output "opts = { some_thing = true }\n" - it recognises long options named after Lua keywords: expect (parseargs ([["if"]], {"--if"})). - should_output "opts = { if = true }\n" + to_output "opts = { if = true }\n" - it recognises combined short and long option specs: expect (parseargs ([[{"x", "if"}]], {"-x"})). - should_output "opts = { if = true }\n" + to_output "opts = { if = true }\n" expect (parseargs ([[{"x", "if"}]], {"--if"})). - should_output "opts = { if = true }\n" + to_output "opts = { if = true }\n" - it recognises options with several spellings: expect (parseargs ([[{"x", "blah", "if"}]], {"-x"})). - should_output "opts = { if = true }\n" + to_output "opts = { if = true }\n" expect (parseargs ([[{"x", "blah", "if"}]], {"--blah"})). - should_output "opts = { if = true }\n" + to_output "opts = { if = true }\n" expect (parseargs ([[{"x", "blah", "if"}]], {"--if"})). - should_output "opts = { if = true }\n" + to_output "opts = { if = true }\n" - it recognises end of options marker: expect (parseargs ([["x"]], {"--", "-x"})). - should_output "args = { -x }\n" + to_output "args = { -x }\n" - context given an option with a required argument: - it records an argument to a short option without a space: expect (parseargs ([["x", parser.required]], {"-y", "-xarg", "-b"})). - should_contain_output "opts = { b = true, x = arg }" + to_contain_output "opts = { b = true, x = arg }" - it records an argument to a short option following a space: expect (parseargs ([["x", parser.required]], {"-y", "-x", "arg", "-b"})). - should_contain_output "opts = { b = true, x = arg }\n" + to_contain_output "opts = { b = true, x = arg }\n" - it records an argument to a long option following a space: expect (parseargs ([["this", parser.required]], {"--this", "arg"})). - should_output "opts = { this = arg }\n" + to_output "opts = { this = arg }\n" - it records an argument to a long option following an '=' delimiter: expect (parseargs ([["this", parser.required]], {"--this=arg"})). - should_output "opts = { this = arg }\n" + to_output "opts = { this = arg }\n" - it diagnoses a missing argument: expect (parseargs ([[{"x", "this"}, parser.required]], {"-x"})). - should_contain_error "'-x' requires an argument" + to_contain_error "'-x' requires an argument" expect (parseargs ([[{"x", "this"}, parser.required]], {"--this"})). - should_contain_error "'--this' requires an argument" + to_contain_error "'--this' requires an argument" - context with a boolean handler function: - it records a truthy argument: for _, optarg in ipairs {"1", "TRUE", "true", "yes", "Yes", "y"} do expect (parseargs ([["x", parser.required, parser.boolean]], {"-x", optarg})). - should_output "opts = { x = true }\n" + to_output "opts = { x = true }\n" end - it records a falsey argument: for _, optarg in ipairs {"0", "FALSE", "false", "no", "No", "n"} do expect (parseargs ([["x", parser.required, parser.boolean]], {"-x", optarg})). - should_output "opts = { x = false }\n" + to_output "opts = { x = false }\n" end - context with a file handler function: - it records an existing file: expect (parseargs ([["x", parser.required, parser.file]], {"-x", "/dev/null"})). - should_output "opts = { x = /dev/null }\n" + to_output "opts = { x = /dev/null }\n" - it diagnoses a missing file: | expect (parseargs ([["x", parser.required, parser.file]], {"-x", "/this/file/does/not/exist"})). - should_contain_error "error: /this/file/does/not/exist: " + to_contain_error "error: /this/file/does/not/exist: " - context with a custom handler function: - it calls the handler: expect (parseargs ([["x", parser.required, function (p,o,a) return "custom" end ]], {"-x", "ignored"})). - should_output "opts = { x = custom }\n" + to_output "opts = { x = custom }\n" - it diagnoses a missing argument: expect (parseargs ([["x", parser.required, function (p,o,a) return "custom" end ]], {"-x"})). - should_contain_error "option '-x' requires an argument" + to_contain_error "option '-x' requires an argument" - context given an option with an optional argument: - it records an argument to a short option without a space: expect (parseargs ([["x", parser.optional]], {"-y", "-xarg", "-b"})). - should_contain_output "opts = { b = true, x = arg }" + to_contain_output "opts = { b = true, x = arg }" - it records an argument to a short option following a space: expect (parseargs ([["x", parser.optional]], {"-y", "-x", "arg", "-b"})). - should_contain_output "opts = { b = true, x = arg }\n" + to_contain_output "opts = { b = true, x = arg }\n" - it records an argument to a long option following a space: expect (parseargs ([["this", parser.optional]], {"--this", "arg"})). - should_output "opts = { this = arg }\n" + to_output "opts = { this = arg }\n" - it records an argument to a long option following an '=' delimiter: expect (parseargs ([["this", parser.optional]], {"--this=arg"})). - should_output "opts = { this = arg }\n" + to_output "opts = { this = arg }\n" - it does't consume the following option: expect (parseargs ([[{"x", "this"}, parser.optional]], {"-x", "-b"})). - should_output "opts = { b = true, this = true }\n" + to_output "opts = { b = true, this = true }\n" expect (parseargs ([[{"x", "this"}, parser.optional]], {"--this", "-b"})). - should_output "opts = { b = true, this = true }\n" + to_output "opts = { b = true, this = true }\n" - context with a boolean handler function: - it records a truthy argument: for _, optarg in ipairs {"1", "TRUE", "true", "yes", "Yes", "y"} do expect (parseargs ([["x", parser.optional, parser.boolean]], {"-x", optarg})). - should_output "opts = { x = true }\n" + to_output "opts = { x = true }\n" end - it records a falsey argument: for _, optarg in ipairs {"0", "FALSE", "false", "no", "No", "n"} do expect (parseargs ([["x", parser.optional, parser.boolean]], {"-x", optarg})). - should_output "opts = { x = false }\n" + to_output "opts = { x = false }\n" end - it defaults to a truthy value: expect (parseargs ([["x", parser.optional, parser.boolean]], {"-x", "-b"})). - should_output "opts = { b = true, x = true }\n" + to_output "opts = { b = true, x = true }\n" - context with a file handler function: - it records an existing file: expect (parseargs ([["x", parser.optional, parser.file]], {"-x", "/dev/null"})). - should_output "opts = { x = /dev/null }\n" + to_output "opts = { x = /dev/null }\n" - it diagnoses a missing file: | expect (parseargs ([["x", parser.optional, parser.file]], {"-x", "/this/file/does/not/exist"})). - should_contain_error "error: /this/file/does/not/exist: " + to_contain_error "error: /this/file/does/not/exist: " - context with a custom handler function: - it calls the handler: expect (parseargs ([["x", parser.optional, function (p,o,a) return "custom" end ]], {"-x", "ignored"})). - should_output "opts = { x = custom }\n" + to_output "opts = { x = custom }\n" - it does not consume a following option: expect (parseargs ([["x", parser.optional, function (p,o,a) return a or "default" end ]], {"-x", "-b"})). - should_output "opts = { b = true, x = default }\n" + to_output "opts = { b = true, x = default }\n" - context when splitting combined short options: - it separates non-argument options: expect (parseargs ([["x"]], {"-xb"})). - should_output "opts = { b = true, x = true }\n" + to_output "opts = { b = true, x = true }\n" expect (parseargs ([["x"]], {"-vxb"})). - should_output "opts = { b = true, verbose = true, x = true }\n" + to_output "opts = { b = true, verbose = true, x = true }\n" - it stops separating at a required argument option: expect (parseargs ([[{"x", "this"}, parser.required]], {"-bxbit"})). - should_output "opts = { b = true, this = bit }\n" + to_output "opts = { b = true, this = bit }\n" - it stops separating at an optional argument option: expect (parseargs ([[{"x", "this"}, parser.optional]], {"-bxbit"})). - should_output "opts = { b = true, this = bit }\n" - - - context with io.die: - - before: | - runscript = function (code) - return luaproc ([[ - local OptionParser = require "std.optparse" - local parser = OptionParser ("program 0\nUsage: program\n") - _G.arg, _G.opts = parser:parse (_G.arg) - ]] .. code .. [[ - require "std.io".die "By 'eck!" - ]]) - end - - it prefers `prog.name` to `opts.program`: | - code = [[prog = { file = "file", name = "name" }]] - expect (runscript (code)).should_fail_with "name: By 'eck!\n" - - it prefers `prog.file` to `opts.program`: | - code = [[prog = { file = "file" }]] - expect (runscript (code)).should_fail_with "file: By 'eck!\n" - - it appends `prog.line` if any to `prog.file` over using `opts`: | - code = [[ - prog = { file = "file", line = 125 }; opts.line = 99]] - expect (runscript (code)).should_fail_with "file:125: By 'eck!\n" - - it prefixes `opts.program` if any: | - expect (runscript ("")).should_fail_with "program: By 'eck!\n" - - it appends `opts.line` if any, to `opts.program`: | - code = [[opts.line = 99]] - expect (runscript (code)). - should_fail_with "program:99: By 'eck!\n" - - - context with io.warn: - - before: | - runscript = function (code) - return luaproc ([[ - local OptionParser = require "std.optparse" - local parser = OptionParser ("program 0\nUsage: program\n") - _G.arg, _G.opts = parser:parse (_G.arg) - ]] .. code .. [[ - require "std.io".warn "Ayup!" - ]]) - end - - it prefers `prog.name` to `opts.program`: | - code = [[prog = { file = "file", name = "name" }]] - expect (runscript (code)).should_output_error "name: Ayup!\n" - - it prefers `prog.file` to `opts.program`: | - code = [[prog = { file = "file" }]] - expect (runscript (code)).should_output_error "file: Ayup!\n" - - it appends `prog.line` if any to `prog.file` over using `opts`: | - code = [[ - prog = { file = "file", line = 125 }; opts.line = 99]] - expect (runscript (code)). - should_output_error "file:125: Ayup!\n" - - it prefixes `opts.program` if any: | - expect (runscript ("")).should_output_error "program: Ayup!\n" - - it appends `opts.line` if any, to `opts.program`: | - code = [[opts.line = 99]] - expect (runscript (code)). - should_output_error "program:99: Ayup!\n" + to_output "opts = { b = true, this = bit }\n" diff --git a/specs/package_spec.yaml b/specs/package_spec.yaml index bf561d2..f93683e 100644 --- a/specs/package_spec.yaml +++ b/specs/package_spec.yaml @@ -1,38 +1,170 @@ before: | - require "spec_helper" - this_module = "std.package" global_table = "_G" base_module = "package" - extend_base = { "dirsep", "pathsep", "path_mark", - "execdir", "igmark" } + extend_base = { "dirsep", "execdir", "find", "igmark", "insert", + "mappath", "normalize", "pathsep", "path_mark", + "remove" } M = require (this_module) + path = M.normalize ("begin", "middle", "end") + + function catfile (...) return table.concat ({...}, M.dirsep) end + function catpath (...) return table.concat ({...}, M.pathsep) end + + specify std.package: - context when required: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - it contains apis from the core package table: expect (show_apis {from=base_module, not_in=this_module}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - it replaces no apis from the core package table: expect (show_apis {from=base_module, enhanced_in=this_module}). - should_equal {} + to_equal {} - context via the std module: - it adds apis to the core package table: expect (show_apis {added_to=base_module, by="std"}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - it replaces no apis from the core package table: expect (show_apis {from=base_module, enhanced_after='require "std"'}). - should_equal {} + to_equal {} + + +- describe find: + - before: path = table.concat ({"begin", "m%ddl.", "end"}, M.pathsep) + - it diagnoses missing arguments: | + expect (M.find ()).to_error "bad argument #1 to find" + expect (M.find (path)).to_error "bad argument #2 to find" + - it returns nil for unmatched element: + expect (M.find (path, "unmatchable")).to_be (nil) + - it returns the element index for a matched element: + expect (M.find (path, "end")).to_be (3) + - it returns the element text for a matched element: + i, element = M.find (path, "e.*n") + expect ({i, element}).to_equal {1, "begin"} + - it accepts a search start element argument: + i, element = M.find (path, "e.*n", 2) + expect ({i, element}).to_equal {3, "end"} + - it works with plain text search strings: + expect (M.find (path, "m%ddl.")).to_be (nil) + i, element = M.find (path, "%ddl.", 1, ":plain") + expect ({i, element}).to_equal {2, "m%ddl."} + + +- describe insert: + - it diagnoses missing arguments: | + expect (M.insert ()).to_error "bad argument #1 to insert" + expect (M.insert (path)).to_error "wrong number of arguments" + - it appends by default: + expect (M.insert (path, "new")). + to_be (M.normalize ("begin", "middle", "end", "new")) + - it prepends with pos set to 1: + expect (M.insert (path, 1, "new")). + to_be (M.normalize ("new", "begin", "middle", "end")) + - it can insert in the middle too: + expect (M.insert (path, 2, "new")). + to_be (M.normalize ("begin", "new", "middle", "end")) + expect (M.insert (path, 3, "new")). + to_be (M.normalize ("begin", "middle", "new", "end")) + - it normalizes the returned path: + path = table.concat ({"begin", "middle", "end"}, M.pathsep) + expect (M.insert (path, "new")). + to_be (M.normalize ("begin", "middle", "end", "new")) + expect (M.insert (path, 1, "./x/../end")). + to_be (M.normalize ("end", "begin", "middle")) + + +- describe mappath: + - before: + expected = require "std.string".split (path, M.pathsep) + - it diagnoses bad arguments: | + expect (M.mappath ()).to_error "bad argument #1 to mappath" + expect (M.mappath ("")).to_error "bad argument #2 to mappath" + - it calls a function with each path element: + t = {} + M.mappath (path, function (e) t[#t + 1] = e end) + expect (t).to_equal (expected) + - it passes additional arguments through: | + reversed = {} + for i = #expected, 1, -1 do + table.insert (reversed, expected[i]) + end + t = {} + M.mappath (path, function (e, pos) table.insert (t, pos, e) end, 1) + expect (t).to_equal (reversed) + + +- describe normalize: + - it diagnoses bad arguments: + expect (M.normalize ()).to_error "wrong number of arguments" + + - context with a single element: + - it strips redundant . directories: + expect (M.normalize "./x/./y/.").to_be (catfile (".", "x", "y")) + - it strips redundant .. directories: + expect (M.normalize "../x/../y/z/..").to_be (catfile ("..", "y")) + - it normalizes / to platform dirsep: + expect (M.normalize "/foo/bar").to_be (catfile ("", "foo", "bar")) + - it normalizes ? to platform path_mark: + expect (M.normalize "?.lua"). + to_be (catfile (".", M.path_mark .. ".lua")) + - it strips redundant trailing /: + expect (M.normalize "/foo/bar/").to_be (catfile ("", "foo", "bar")) + - it inserts missing ./ for relative paths: + for _, path in ipairs {"x", "./x"} do + expect (M.normalize (path)).to_be (catfile (".", "x")) + end + + - context with multiple elements: + - it strips redundant . directories: + expect (M.normalize ("./x/./y/.", "x")). + to_be (catpath (catfile (".", "x", "y"), catfile (".", "x"))) + - it strips redundant .. directories: + expect (M.normalize ("../x/../y/z/..", "x")). + to_be (catpath (catfile ("..", "y"), catfile (".", "x"))) + - it normalizes / to platform dirsep: + expect (M.normalize ("/foo/bar", "x")). + to_be (catpath (catfile ("", "foo", "bar"), catfile (".", "x"))) + - it normalizes ? to platform path_mark: + expect (M.normalize ("?.lua", "x")). + to_be (catpath (catfile (".", M.path_mark .. ".lua"), catfile (".", "x"))) + - it strips redundant trailing /: + expect (M.normalize ("/foo/bar/", "x")). + to_be (catpath (catfile ("", "foo", "bar"), catfile (".", "x"))) + - it inserts missing ./ for relative paths: + for _, path in ipairs {"x", "./x"} do + expect (M.normalize (path, "a")). + to_be (catpath (catfile (".", "x"), catfile (".", "a"))) + end + + - it eliminates all but the first equivalent elements: + expect (M.normalize (catpath ("1", "x", "2", "./x", "./2", "./x/../x"))). + to_be (catpath ("./1", "./x", "./2")) + + +- describe remove: + - it diagnoses bad arguments: | + expect (M.remove ()).to_error "bad argument #1 to remove" + - it removes the last item by default: + expect (M.remove (path)).to_be (M.normalize ("begin", "middle")) + - it pops the first item with pos set to 1: + expect (M.remove (path, 1)).to_be (M.normalize ("middle", "end")) + - it can remove from the middle too: + expect (M.remove (path, 2)).to_be (M.normalize ("begin", "end")) + - it does not normalize the returned path: + path = table.concat ({"begin", "middle", "end"}, M.pathsep) + expect (M.remove (path)). + to_be (table.concat ({"begin", "middle"}, M.pathsep)) - it splits package.config up: expect (string.format ("%s\n%s\n%s\n%s\n%s\n", M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark) - ).should_contain (package.config) + ).to_contain (package.config) diff --git a/specs/set_spec.yaml b/specs/set_spec.yaml index 9f96e3a..e401aef 100644 --- a/specs/set_spec.yaml +++ b/specs/set_spec.yaml @@ -1,5 +1,4 @@ before: - require "spec_helper" Set = require "std.set" prototype = (require "std.object").prototype totable = (require "std.table").totable @@ -9,22 +8,22 @@ specify std.set: - describe require: - it does not perturb the global namespace: expect (show_apis {added_to="_G", by="std.set"}). - should_equal {} + to_equal {} - describe construction: - it constructs a new set: s = Set {} - expect (s).should_not_be (Set) - expect (prototype (s)).should_be "Set" + expect (s).not_to_be (Set) + expect (prototype (s)).to_be "Set" - it initialises set with constructor parameters: t = Set {"foo", "bar", "bar"} - expect (t).should_equal (s) + expect (t).to_equal (s) - it serves as a prototype for new instances: obj = s {} - expect (prototype (obj)).should_be "Set" - expect (obj).should_equal (s) - expect (getmetatable (obj)).should_be (getmetatable (s)) + expect (prototype (obj)).to_be "Set" + expect (obj).to_equal (s) + expect (getmetatable (obj)).to_be (getmetatable (s)) - describe delete: @@ -32,21 +31,21 @@ specify std.set: - before: s = Set {"foo", "bar", "baz"} - it returns a set object: - expect (prototype (Set.delete (s, "foo"))).should_be "Set" + expect (prototype (Set.delete (s, "foo"))).to_be "Set" - it is destructive: Set.delete (s, "bar") - expect (s).should_not_have_member "bar" + expect (s).not_to_have_member "bar" - it returns the modified set: - expect (Set.delete (s, "baz")).should_not_have_member "baz" + expect (Set.delete (s, "baz")).not_to_have_member "baz" - it ignores removal of non-members: | clone = s {} - expect (Set.delete (s, "quux")).should_equal (clone) + expect (Set.delete (s, "quux")).to_equal (clone) - it deletes a member from the set: - expect (s).should_have_member "bar" + expect (s).to_have_member "bar" Set.delete (s, "bar") - expect (s).should_not_have_member "bar" + expect (s).not_to_have_member "bar" - it works with an empty set: - expect (Set.delete (Set {}, "quux")).should_equal (Set {}) + expect (Set.delete (Set {}, "quux")).to_equal (Set {}) - describe difference: @@ -56,26 +55,26 @@ specify std.set: - context when called as a Set module function: - it returns a set object: - expect (prototype (Set.difference (r, s))).should_be "Set" + expect (prototype (Set.difference (r, s))).to_be "Set" - it is non-destructive: Set.difference (r, s) - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members of the first that are not in the second: - expect (Set.difference (r, s)).should_equal (Set {"foo"}) + expect (Set.difference (r, s)).to_equal (Set {"foo"}) - it coerces a table argument to a set: - expect (Set.difference (r, {"bar"})).should_equal (Set {"baz", "foo"}) + expect (Set.difference (r, {"bar"})).to_equal (Set {"baz", "foo"}) - context when called as a set metamethod: - it returns a set object: - expect (prototype (r - s)).should_be "Set" + expect (prototype (r - s)).to_be "Set" - it is non-destructive: q = r - s - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members of the first that are not in the second: - expect (r - s).should_equal (Set {"foo"}) + expect (r - s).to_equal (Set {"foo"}) - it coerces a table argument to a set: - expect (r - {"bar"}).should_equal (Set {"baz", "foo"}) + expect (r - {"bar"}).to_equal (Set {"baz", "foo"}) - describe elems: @@ -87,11 +86,11 @@ specify std.set: t = {} for e in Set.elems (s) do table.insert (t, e) end table.sort (t) - expect (t).should_equal {"bar", "baz", "foo"} + expect (t).to_equal {"bar", "baz", "foo"} - it works for an empty set: t = {} for e in Set.elems (Set {}) do table.insert (t, e) end - expect (t).should_equal {} + expect (t).to_equal {} - describe insert: @@ -99,40 +98,40 @@ specify std.set: - before: s = Set {"foo"} - it returns a set object: - expect (prototype (Set.insert (s, "bar"))).should_be "Set" + expect (prototype (Set.insert (s, "bar"))).to_be "Set" - it is destructive: Set.insert (s, "bar") - expect (s).should_have_member "bar" + expect (s).to_have_member "bar" - it returns the modified set: - expect (Set.insert (s, "baz")).should_have_member "baz" + expect (Set.insert (s, "baz")).to_have_member "baz" - it ignores insertion of existing members: - expect (Set.insert (s, "foo")).should_equal (Set {"foo"}) + expect (Set.insert (s, "foo")).to_equal (Set {"foo"}) - it inserts a new member into the set: - expect (s).should_not_have_member "bar" + expect (s).not_to_have_member "bar" Set.insert (s, "bar") - expect (s).should_have_member "bar" + expect (s).to_have_member "bar" - it works with an empty set: - expect (Set.insert (Set {}, "foo")).should_equal (s) + expect (Set.insert (Set {}, "foo")).to_equal (s) - context when called as a set metamethod: - before: s = Set {"foo"} - it returns a set object: s["bar"] = true - expect (prototype (s)).should_be "Set" + expect (prototype (s)).to_be "Set" - it is destructive: s["bar"] = true - expect (s).should_have_member "bar" + expect (s).to_have_member "bar" - it ignores insertion of existing members: s["foo"] = true - expect (s).should_equal (Set {"foo"}) + expect (s).to_equal (Set {"foo"}) - it inserts a new member into the set: - expect (s).should_not_have_member "bar" + expect (s).not_to_have_member "bar" s["bar"] = true - expect (s).should_have_member "bar" + expect (s).to_have_member "bar" - it works with an empty set: s = Set {} s.foo = true - expect (s).should_equal (s) + expect (s).to_equal (s) - describe intersection: @@ -142,29 +141,29 @@ specify std.set: - context when called as a Set module function: - it returns a set object: - expect (prototype (Set.intersection (r, s))).should_be "Set" + expect (prototype (Set.intersection (r, s))).to_be "Set" - it is non-destructive: Set.intersection (r, s) - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members common to both arguments: expect (Set.intersection (r, s)). - should_equal (Set {"bar", "baz"}) + to_equal (Set {"bar", "baz"}) - it coerces a table argument to a set: expect (Set.intersection (r, {"bar", "quux"})). - should_equal (Set {"bar"}) + to_equal (Set {"bar"}) - context when called as a set metamethod: - it returns a set object: q = r * s - expect (prototype (q)).should_be "Set" + expect (prototype (q)).to_be "Set" - it is non-destructive: q = r * s - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members common to both arguments: - expect (r * s).should_equal (Set {"bar", "baz"}) + expect (r * s).to_equal (Set {"bar", "baz"}) - it coerces a table argument to a set: - expect (r * {"bar", "quux"}).should_equal (Set {"bar"}) + expect (r * {"bar", "quux"}).to_equal (Set {"bar"}) - describe member: @@ -172,20 +171,20 @@ specify std.set: - context when called as a Set module function: - it succeeds when set contains the given member: - expect (Set.member (s, "foo")).should_be (true) + expect (Set.member (s, "foo")).to_be (true) - it fails when set does not contain the given member: - expect (Set.member (s, "baz")).should_not_be (true) + expect (Set.member (s, "baz")).not_to_be (true) - it works with the empty set: s = Set {} - expect (Set.member (s, "foo")).should_not_be (true) + expect (Set.member (s, "foo")).not_to_be (true) - context when called as a set metamethod: - it succeeds when set contains the given member: - expect (s["foo"]).should_be (true) + expect (s["foo"]).to_be (true) - it fails when set does not contain the given member: - expect (s["baz"]).should_not_be (true) + expect (s["baz"]).not_to_be (true) - it works with the empty set: s = Set {} - expect (s["foo"]).should_not_be (true) + expect (s["foo"]).not_to_be (true) - describe proper_subset: @@ -195,25 +194,25 @@ specify std.set: - context when called as a Set module function: - it succeeds when set contains all elements of another: - expect (Set.proper_subset (s, r)).should_be (true) + expect (Set.proper_subset (s, r)).to_be (true) - it fails when two sets are equal: r = s {} - expect (Set.proper_subset (s, r)).should_be (false) + expect (Set.proper_subset (s, r)).to_be (false) - it fails when set does not contain all elements of another: s = s + Set {"quux"} - expect (Set.proper_subset (r, s)).should_be (false) + expect (Set.proper_subset (r, s)).to_be (false) - it coerces a table argument to a set: - expect (Set.proper_subset (s, {"foo", "bar", "baz"})).should_be (true) - expect (Set.proper_subset (s, {"foo"})).should_be (false) + expect (Set.proper_subset (s, {"foo", "bar", "baz"})).to_be (true) + expect (Set.proper_subset (s, {"foo"})).to_be (false) - context when called as a set metamethod: - it succeeds when set contains all elements of another: - expect (s < r).should_be (true) + expect (s < r).to_be (true) - it fails when two sets are equal: r = s {} - expect (s < r).should_be (false) + expect (s < r).to_be (false) - it fails when set does not contain all elements of another: s = s + Set {"quux"} - expect (r < s).should_be (false) + expect (r < s).to_be (false) - describe subset: @@ -223,25 +222,25 @@ specify std.set: - context when called as a Set module function: - it succeeds when set contains all elements of another: - expect (Set.subset (s, r)).should_be (true) + expect (Set.subset (s, r)).to_be (true) - it succeeds when two sets are equal: r = s {} - expect (Set.subset (s, r)).should_be (true) + expect (Set.subset (s, r)).to_be (true) - it fails when set does not contain all elements of another: s = s + Set {"quux"} - expect (Set.subset (r, s)).should_be (false) + expect (Set.subset (r, s)).to_be (false) - it coerces a table argument to a set: - expect (Set.subset (s, {"foo", "bar", "baz"})).should_be (true) - expect (Set.subset (s, {"foo"})).should_be (false) + expect (Set.subset (s, {"foo", "bar", "baz"})).to_be (true) + expect (Set.subset (s, {"foo"})).to_be (false) - context when called as a set metamethod: - it succeeds when set contains all elements of another: - expect (s <= r).should_be (true) + expect (s <= r).to_be (true) - it succeeds when two sets are equal: r = s {} - expect (s <= r).should_be (true) + expect (s <= r).to_be (true) - it fails when set does not contain all elements of another: s = s + Set {"quux"} - expect (r <= s).should_be (false) + expect (r <= s).to_be (false) - describe symmetric_difference: @@ -252,28 +251,28 @@ specify std.set: - context when called as a Set module function: - it returns a set object: expect (prototype (Set.symmetric_difference (r, s))). - should_be "Set" + to_be "Set" - it is non-destructive: Set.symmetric_difference (r, s) - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members in only one argument set: expect (Set.symmetric_difference (r, s)). - should_equal (Set {"foo", "quux"}) + to_equal (Set {"foo", "quux"}) - it coerces a table argument to a set: expect (Set.symmetric_difference (r, {"bar"})). - should_equal (Set {"baz", "foo"}) + to_equal (Set {"baz", "foo"}) - context when called as a set metamethod: - it returns a set object: - expect (prototype (r / s)).should_be "Set" + expect (prototype (r / s)).to_be "Set" - it is non-destructive: q = r / s - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members in only one argument set: - expect (r / s).should_equal (Set {"foo", "quux"}) + expect (r / s).to_equal (Set {"foo", "quux"}) - it coerces a table argument to a set: - expect (r / {"bar"}).should_equal (Set {"baz", "foo"}) + expect (r / {"bar"}).to_equal (Set {"baz", "foo"}) - describe union: @@ -283,29 +282,29 @@ specify std.set: - context when called as a Set module function: - it returns a set object: - expect (prototype (Set.union (r, s))).should_be "Set" + expect (prototype (Set.union (r, s))).to_be "Set" - it is non-destructive: Set.union (r, s) - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members in only one argument set: expect (Set.union (r, s)). - should_equal (Set {"foo", "bar", "baz", "quux"}) + to_equal (Set {"foo", "bar", "baz", "quux"}) - it coerces a table argument to a set: expect (Set.union (r, {"quux"})). - should_equal (Set {"foo", "bar", "baz", "quux"}) + to_equal (Set {"foo", "bar", "baz", "quux"}) - context when called as a set metamethod: - it returns a set object: - expect (prototype (r + s)).should_be "Set" + expect (prototype (r + s)).to_be "Set" - it is non-destructive: q = r + s - expect (r).should_equal (Set {"foo", "bar", "baz"}) - expect (s).should_equal (Set {"bar", "baz", "quux"}) + expect (r).to_equal (Set {"foo", "bar", "baz"}) + expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members in only one argument set: - expect (r + s).should_equal (Set {"foo", "bar", "baz", "quux"}) + expect (r + s).to_equal (Set {"foo", "bar", "baz", "quux"}) - it coerces a table argument to a set: expect (r + {"quux"}). - should_equal (Set {"foo", "bar", "baz", "quux"}) + to_equal (Set {"foo", "bar", "baz", "quux"}) - describe __totable: @@ -313,13 +312,13 @@ specify std.set: s = Set {"foo", "bar", "baz"} - it returns a table: - expect (prototype (totable (s))).should_be "table" + expect (prototype (totable (s))).to_be "table" - it contains all non-hidden fields of object: - expect (totable (s)).should_contain.all_of {"foo", "bar", "baz"} + expect (totable (s)).to_contain.all_of {"foo", "bar", "baz"} - it contains fields of set in order: - expect (totable (s)).should_equal {"bar", "baz", "foo"} + expect (totable (s)).to_equal {"bar", "baz", "foo"} - it does not contain any hidden fields of object: - expect (totable (s)).should_equal {"bar", "baz", "foo"} + expect (totable (s)).to_equal {"bar", "baz", "foo"} - describe __tostring: @@ -327,8 +326,8 @@ specify std.set: s = Set {"foo", "bar", "baz"} - it returns a string: - expect (type (tostring (s))).should_be "string" + expect (type (tostring (s))).to_be "string" - it shows the type name: - expect (tostring (s)).should_contain "Set" + expect (tostring (s)).to_contain "Set" - it contains the ordered set elements: - expect (tostring (s)).should_contain "bar, baz, foo" + expect (tostring (s)).to_contain "bar, baz, foo" diff --git a/specs/spec_helper.lua.in b/specs/spec_helper.lua.in index bb0a7c0..99a0fae 100644 --- a/specs/spec_helper.lua.in +++ b/specs/spec_helper.lua.in @@ -1,4 +1,8 @@ -local hell = require "specl.shell" +local hell = require "specl.shell" +local inprocess = require "specl.inprocess" +local std = require "specl.std" + +package.path = std.package.normalize ("lib/?.lua", package.path) -- Substitute configured LUA so that hell.spawn doesn't pick up -- a different Lua binary to the one used by Specl itself. If @@ -123,6 +127,11 @@ end totable = (require "std.table").totable +-- Stub inprocess.capture if necessary; new in Specl 12. +capture = inprocess.capture or + function (f, arg) return nil, nil, f (unpack (arg or {})) end + + do -- Custom matcher for set size and set membership. @@ -134,7 +143,7 @@ do matchers.Matcher, matchers.matchers, matchers.stringify matchers.have_size = Matcher { - function (actual, expect) + function (self, actual, expect) local size = 0 for _ in pairs (actual) do size = size + 1 end return size == expect @@ -142,63 +151,30 @@ do actual = "table", - format_expect = function (expect) + format_expect = function (self, expect) return " a table containing " .. expect .. " elements, " end, - format_any_of = function (alternatives) + format_any_of = function (self, alternatives) return " a table with any of " .. util.concat (alternatives, util.QUOTED) .. " elements, " end, } matchers.have_member = Matcher { - function (actual, expect) + function (self, actual, expect) return set.member (actual, expect) end, actual = "set", - format_expect = function (expect) + format_expect = function (self, expect) return " a set containing " .. q (expect) .. ", " end, - format_any_of = function (alternatives) + format_any_of = function (self, alternatives) return " a set containing any of " .. util.concat (alternatives, util.QUOTED) .. ", " end, } end - - -do - --[[ ======================================= ]]-- - --[[ Remove this after Specl 11 is released. ]]-- - --[[ ======================================= ]]-- - - -- Custom matcher for specl.shell failure with error message. - - local matchers = require "specl.matchers" - local Matcher, matchers, reformat = - matchers.Matcher, matchers.matchers, matchers.reformat - - matchers.fail_with = matchers.fail_with or Matcher { - function (actual, expect) - return (actual.status ~= 0) and (actual.errout == expect) - end, - - actual_type = "Process", - - format_actual = function (process) - return ":" .. reformat (process.errout) - end, - - format_expect = function (expect) - return " error output: " .. reformat (expect) - end, - - format_alternatives = function (adaptor, alternatives) - return " error output:" .. reformat (alternatives, adaptor) - end, - } -end diff --git a/specs/specs.mk b/specs/specs.mk index 45c1fcc..0f5aa9b 100644 --- a/specs/specs.mk +++ b/specs/specs.mk @@ -5,8 +5,11 @@ ## Environment. ## ## ------------ ## +## !!WARNING!! When bootstrap.conf:buildreq specl setting requires specl +## 12 or higher, remove this entire Environment section! + specs_path = $(abs_builddir)/specs/?.lua -SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" +SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" LUA_INIT= LUA_INIT_5_2= ## ------ ## @@ -21,6 +24,7 @@ SPECL_OPTS = --unicode ## affected. specl_SPECS = \ + $(srcdir)/specs/base_spec.yaml \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ $(srcdir)/specs/functional_spec.yaml \ @@ -42,4 +46,6 @@ EXTRA_DIST += \ $(srcdir)/specs/spec_helper.lua.in \ $(NOTHING_ELSE) +specl-check-local: specs/spec_helper.lua + include build-aux/specl.mk diff --git a/specs/std_spec.yaml b/specs/std_spec.yaml index f8f758c..e4754b4 100644 --- a/specs/std_spec.yaml +++ b/specs/std_spec.yaml @@ -3,10 +3,10 @@ specify std: - before: std = require "std" - it has no submodules on initial load: - expect (std).should_equal {version = std.version} + expect (std).to_equal {version = std.version} - it loads submodules on demand: lazy = std.set - expect (lazy).should_be (require "std.set") + expect (lazy).to_be (require "std.set") - it loads submodule functions on demand: expect (std.object.prototype (std.set {"Lazy"})). - should_be "Set" + to_be "Set" diff --git a/specs/strbuf_spec.yaml b/specs/strbuf_spec.yaml index 6851dcd..efdff04 100644 --- a/specs/strbuf_spec.yaml +++ b/specs/strbuf_spec.yaml @@ -1,5 +1,4 @@ before: - require "spec_helper" object = require "std.object" StrBuf = require "std.strbuf" b = StrBuf {"foo", "bar"} @@ -8,53 +7,53 @@ specify std.strbuf: - describe require: - it does not perturb the global namespace: expect (show_apis {added_to="_G", by="std.strbuf"}). - should_equal {} + to_equal {} - describe construction: - context from StrBuf clone method: - it constructs a new strbuf: b = StrBuf:clone {} - expect (b).should_not_be (StrBuf) - expect (object.type (b)).should_be "StrBuf" + expect (b).not_to_be (StrBuf) + expect (object.type (b)).to_be "StrBuf" - it reuses the StrBuf metatable: a, b = StrBuf:clone {"a"}, StrBuf:clone {"b"} - expect (getmetatable (a)).should_be (getmetatable (b)) + expect (getmetatable (a)).to_be (getmetatable (b)) - it initialises strbuf with constructor parameters: a = StrBuf:clone {"foo", "bar"} - expect (a).should_equal (b) + expect (a).to_equal (b) - it serves as a prototype for new instances: obj = b:clone {} - expect (object.type (obj)).should_be "StrBuf" - expect (obj).should_equal (b) - expect (getmetatable (obj)).should_be (getmetatable (b)) + expect (object.type (obj)).to_be "StrBuf" + expect (obj).to_equal (b) + expect (getmetatable (obj)).to_be (getmetatable (b)) # StrBuf {args} is just syntactic sugar for StrBuf:clone {args} - context from StrBuf object prototype: - it constructs a new strbuf: b = StrBuf {} - expect (b).should_not_be (StrBuf) - expect (object.type (b)).should_be "StrBuf" + expect (b).not_to_be (StrBuf) + expect (object.type (b)).to_be "StrBuf" - it reuses the StrBuf metatable: a, b = StrBuf {"a"}, StrBuf {"b"} - expect (getmetatable (a)).should_be (getmetatable (b)) + expect (getmetatable (a)).to_be (getmetatable (b)) - it initialises strbuf with constructor parameters: a = StrBuf:clone {"foo", "bar"} - expect (a).should_equal (b) + expect (a).to_equal (b) - it serves as a prototype for new instances: obj = b {} - expect (object.type (obj)).should_be "StrBuf" - expect (obj).should_equal (b) - expect (getmetatable (obj)).should_be (getmetatable (b)) + expect (object.type (obj)).to_be "StrBuf" + expect (obj).to_equal (b) + expect (getmetatable (obj)).to_be (getmetatable (b)) - describe tostring: - it can be called from strbuf module: - expect (StrBuf.tostring (b)).should_be "foobar" + expect (StrBuf.tostring (b)).to_be "foobar" - it can be called as a strbuf object method: - expect (b:tostring ()).should_be "foobar" + expect (b:tostring ()).to_be "foobar" - it can be called as a strbuf metabethod: - expect (tostring (b)).should_be "foobar" + expect (tostring (b)).to_be "foobar" - describe concat: @@ -62,16 +61,16 @@ specify std.strbuf: b = StrBuf {"foo", "bar"} - it can be called from strbuf module: b = StrBuf.concat (b, "baz") - expect (object.type (b)).should_be "StrBuf" - expect (StrBuf.tostring (b)).should_be "foobarbaz" + expect (object.type (b)).to_be "StrBuf" + expect (StrBuf.tostring (b)).to_be "foobarbaz" - it can be called as a strbuf object method: b:concat "baz" - expect (object.type (b)).should_be "StrBuf" - expect (b:tostring()).should_be "foobarbaz" + expect (object.type (b)).to_be "StrBuf" + expect (b:tostring()).to_be "foobarbaz" - it can be called as a strbuf metamethod: b = b .. "baz" - expect (object.type (b)).should_be "StrBuf" - expect (tostring (b)).should_be "foobarbaz" + expect (object.type (b)).to_be "StrBuf" + expect (tostring (b)).to_be "foobarbaz" - describe __totable: @@ -79,8 +78,8 @@ specify std.strbuf: totable = (require "std.table").totable - it returns a table: - expect (object.type (totable (b))).should_be "table" + expect (object.type (totable (b))).to_be "table" - it contains all non-hidden fields of object: - expect (totable (b)).should_contain.all_of {"foo", "bar"} + expect (totable (b)).to_contain.all_of {"foo", "bar"} - it does not contain any hidden fields of object: - expect (totable (b)).should_equal {"foo", "bar"} + expect (totable (b)).to_equal {"foo", "bar"} diff --git a/specs/string_spec.yaml b/specs/string_spec.yaml index e061eab..942f7e5 100644 --- a/specs/string_spec.yaml +++ b/specs/string_spec.yaml @@ -1,6 +1,4 @@ before: | - require "spec_helper" - this_module = "std.string" global_table = "_G" @@ -9,14 +7,13 @@ before: | enhance_globals = { "assert", "tostring" } base_module = "string" - extend_base = { "assert", "caps", "chomp", "escape_pattern", + extend_base = { "__append", "__concat", "__index", + "assert", "caps", "chomp", "escape_pattern", "escape_shell", "finds", "ltrim", "numbertosi", "ordinal_suffix", "pad", "pickle", "prettytostring", "render", "require_version", "rtrim", "split", "tfind", "tostring", "trim", "wrap", - -- make these available after require "std" - "__index", "_format", "_tostring", -- camelCase compatibility: "escapePattern", "escapeShell", "ordinalSuffix" } @@ -24,7 +21,7 @@ before: | extend_metamethods = { "__append", "__concat" } enhance_metamethods = { "__index" } - -- 'should_contain' will match keys as well as values :) + -- 'to_contain' will match keys as well as values :) all_apis = {} for _, s in ipairs (std_globals) do all_apis[s] = true end for _, s in ipairs (enhance_globals) do all_apis[s] = true end @@ -32,6 +29,8 @@ before: | for _, s in ipairs (enhance_base) do all_apis[s] = true end M = require "std.string" + getmetatable("").__index = M.__index + getmetatable ("").__concat = M.__concat specify std.string: - before: @@ -41,46 +40,46 @@ specify std.string: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - it contains apis from the core string table: expect (show_apis {from=base_module, not_in=this_module}). - should_contain.a_permutation_of (all_apis) + to_contain.a_permutation_of (all_apis) - it enhances some apis from the core string table: expect (show_apis {from=base_module, enhanced_in=this_module}). - should_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (enhance_base) - context via the std module: - it adds apis to the global table: expect (show_apis {added_to=global_table, by="std"}). - should_contain.all_of (std_globals) + to_contain.all_of (std_globals) - it adds apis to the core string table: expect (show_apis {added_to=base_module, by="std"}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - it adds methods to the string metatable: expect (show_apis {added_to="getmetatable ('')", by="std"}). - should_contain.a_permutation_of (extend_metamethods) + to_contain.a_permutation_of (extend_metamethods) - it replaces some entries in the string metatable: expect (show_apis {from="getmetatable ('')", enhanced_after='require "std"'}). - should_contain.a_permutation_of (enhance_metamethods) + to_contain.a_permutation_of (enhance_metamethods) - it replaces some apis in the core string table: expect (show_apis {from=base_module, enhanced_after='require "std"'}). - should_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (enhance_base) - describe ..: - it concatenates string arguments: target = "a string \n\n another string" - expect (subject .. " another string").should_be (target) + expect (subject .. " another string").to_be (target) - "it stringifies non-string arguments": argument = { "a table" } - expect (subject .. argument).should_match (string.format ("%s{1=a table}", subject)) + expect (subject .. argument).to_match (string.format ("%s%s", subject, M.tostring (argument))) - it stringifies nil arguments: argument = nil - expect (subject .. argument).should_be (string.format ("%s%s", subject, tostring (argument))) + expect (subject .. argument).to_be (string.format ("%s%s", subject, M.tostring (argument))) - the original subject is not perturbed: original = subject newstring = subject .. " concatenate something" - expect (subject).should_be (original) + expect (subject).to_be (original) - describe assert: @@ -91,18 +90,18 @@ specify std.string: f = M.caps - it capitalises words of a string: target = "A String \n\n" - expect (f (subject)).should_be (target) + expect (f (subject)).to_be (target) - it changes only the first letter of each word: - expect (f "a stRiNg").should_be "A StRiNg" + expect (f "a stRiNg").to_be "A StRiNg" - it is available as a string metamethod: - expect (("a stRiNg"):caps ()).should_be "A StRiNg" + expect (("a stRiNg"):caps ()).to_be "A StRiNg" - the original subject is not perturbed: original = subject newstring = f (subject) - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe chomp: @@ -110,19 +109,19 @@ specify std.string: f = M.chomp target = "a string \n" - it removes a single trailing newline from a string: - expect (f (subject)).should_be (target) + expect (f (subject)).to_be (target) - it does not change a string with no trailing newline: subject = "a string " - expect (f (subject)).should_be (subject) + expect (f (subject)).to_be (subject) - it is available as a string metamethod: - expect (subject:chomp ()).should_be (target) + expect (subject:chomp ()).to_be (target) - the original subject is not perturbed: original = subject newstring = f (subject) - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe escape_pattern: @@ -145,18 +144,18 @@ specify std.string: target = target .. s end - "it inserts a % before any non-alphanumeric in a string": - expect (f (subject)).should_be (target) + expect (f (subject)).to_be (target) - it is available as a string metamethod: - expect (subject:escape_pattern ()).should_be (target) + expect (subject:escape_pattern ()).to_be (target) - legacy escapePattern call is the same function: - expect (M.escapePattern).should_be (f) + expect (M.escapePattern).to_be (f) - the original subject is not perturbed: original = subject newstring = f (subject) - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe escape_shell: @@ -172,18 +171,18 @@ specify std.string: target = target .. s end - "it inserts a \\ before any shell metacharacters": - expect (f (subject)).should_be (target) + expect (f (subject)).to_be (target) - it is available as a string metamethod: - expect (subject:escape_shell ()).should_be (target) + expect (subject:escape_shell ()).to_be (target) - legacy escapeShell call is the same function: - expect (M.escapeShell).should_be (f) + expect (M.escapeShell).to_be (f) - the original subject is not perturbed: original = subject newstring = f (subject) - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe finds: @@ -194,25 +193,25 @@ specify std.string: - before: target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } - it creates a list of pattern captures: - expect ({f (subject, "(.)(.)")}).should_equal ({ target }) + expect ({f (subject, "(.)(.)")}).to_equal ({ target }) - it is available as a string metamethod: - expect ({subject:finds ("(.)(.)")}).should_equal ({ target }) + expect ({subject:finds ("(.)(.)")}).to_equal ({ target }) - it creates an empty list where no captures are matched: target = {} - expect ({f (subject, "(x)")}).should_equal ({ target }) + expect ({f (subject, "(x)")}).to_equal ({ target }) - it creates an empty list for a pattern without captures: target = { { 1, 1; capt = {} } } - expect ({f (subject, "a")}).should_equal ({ target }) + expect ({f (subject, "a")}).to_equal ({ target }) - it starts the search at a specified index into the subject: target = { { 8, 9; capt = { "a", "b" } }, { 10, 11; capt = { "c", "d" } } } - expect ({f ("garbage" .. subject, "(.)(.)", 8)}).should_equal ({ target }) + expect ({f ("garbage" .. subject, "(.)(.)", 8)}).to_equal ({ target }) - the original subject is not perturbed: original = subject newstring = f (subject, "...") - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") # FIXME: This looks like a misfeature to me, let's remove it! @@ -221,16 +220,16 @@ specify std.string: subject = "string: %s, number: %d" f = M.format - it returns a single argument without attempting formatting: - expect (f (subject)).should_be (subject) + expect (f (subject)).to_be (subject) - it is available as a string metamethod: - expect (subject:format ()).should_be (subject) + expect (subject:format ()).to_be (subject) - the original subject is not perturbed: original = subject newstring = f (subject) - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f (nil, "arg")).should_error ("string expected") - expect (f ({"a table"}, "arg")).should_error ("string expected") + expect (f (nil, "arg")).to_error ("string expected") + expect (f ({"a table"}, "arg")).to_error ("string expected") - describe ltrim: @@ -239,20 +238,20 @@ specify std.string: f = M.ltrim - it removes whitespace from the start of a string: target = "a short string \t\r\n " - expect (f (subject)).should_equal (target) + expect (f (subject)).to_equal (target) - it supports custom removal patterns: target = "\r\n a short string \t\r\n " - expect (f (subject, "[ \t\n]+")).should_equal (target) + expect (f (subject, "[ \t\n]+")).to_equal (target) - it is available as a string metamethod: target = "\r\n a short string \t\r\n " - expect (subject:ltrim ("[ \t\n]+")).should_equal (target) + expect (subject:ltrim ("[ \t\n]+")).to_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe numbertosi: @@ -266,12 +265,12 @@ specify std.string: m = 10 * (10 ^ n) table.insert (subject, f (m)) end - expect (subject).should_equal (target) + expect (subject).to_equal (target) - it coerces string arguments to a number: - expect (f "1000").should_be "1k" + expect (f "1000").to_be "1k" - "it diagnoses non-numeric arguments": - expect (f ()).should_error ("attempt to perform arithmetic") - expect (f {"a table"}).should_error ("number expected") + expect (f ()).to_error ("attempt to perform arithmetic") + expect (f {"a table"}).to_error ("number expected") - describe ordinal_suffix: @@ -289,14 +288,14 @@ specify std.string: table.insert (target, n .. suffix) table.insert (subject, n .. f (n)) end - expect (subject).should_equal (target) + expect (subject).to_equal (target) - legacy ordinalSuffix call is the same function: - expect (M.ordinalSuffix).should_be (f) + expect (M.ordinalSuffix).to_be (f) - it coerces string arguments to a number: - expect (f "-91").should_be "st" + expect (f "-91").to_be "st" - "it diagnoses non-numeric arguments": - expect (f ()).should_error ("number expected") - expect (f {"a table"}).should_error ("number expected") + expect (f ()).to_error ("number expected") + expect (f {"a table"}).to_error ("number expected") - describe pad: @@ -309,38 +308,39 @@ specify std.string: subject = "short string" - it right pads a string to the given width with spaces: target = "short string " - expect (f (subject, width)).should_be (target) + expect (f (subject, width)).to_be (target) - it left pads a string to the given negative width with spaces: width = -width target = " short string" - expect (f (subject, width)).should_be (target) + expect (f (subject, width)).to_be (target) - it is available as a string metamethod: target = "short string " - expect (subject:pad (width)).should_be (target) + expect (subject:pad (width)).to_be (target) - context when string is longer than given width: - before: subject = "a string that's longer than twenty characters" - it truncates a string to the given width: target = "a string that's long" - expect (f (subject, width)).should_be (target) + expect (f (subject, width)).to_be (target) - it left pads a string to given width with spaces: width = -width target = "an twenty characters" - expect (f (subject, width)).should_be (target) + expect (f (subject, width)).to_be (target) - it is available as a string metamethod: target = "a string that's long" - expect (subject:pad (width)).should_be (target) + expect (subject:pad (width)).to_be (target) - the original subject is not perturbed: original = subject newstring = f (subject, width) - expect (subject).should_be (original) + expect (subject).to_be (original) - "it coerces non-string arguments to a string": - expect (f ({ "a table" }, width)).should_contain "a table" + argument = { "a table " } + expect (f (argument, width)).to_contain (M.tostring (argument)) - "it diagnoses non-numeric width arguments": - expect (f (subject, nil)).should_error ("number expected") - expect (f (subject, {"a table"})).should_error ("number expected") + expect (f (subject, nil)).to_error ("number expected") + expect (f (subject, {"a table"})).to_error ("number expected") - describe pickle: @@ -350,36 +350,36 @@ specify std.string: - before: f = M.prettytostring - it renders nil exactly like system tostring: - expect (f (nil)).should_be (tostring (nil)) + expect (f (nil)).to_be (tostring (nil)) - it renders booleans exactly like system tostring: - expect (f (true)).should_be (tostring (true)) - expect (f (false)).should_be (tostring (false)) + expect (f (true)).to_be (tostring (true)) + expect (f (false)).to_be (tostring (false)) - it renders numbers exactly like system tostring: n = 8723643 - expect (f (n)).should_be (tostring (n)) + expect (f (n)).to_be (tostring (n)) - it renders functions exactly like system tostring: - expect (f (f)).should_be (tostring (f)) + expect (f (f)).to_be (tostring (f)) - it renders strings with format "%q" styling: s = "a string" - expect (f (s)).should_be (string.format ("%q", s)) + expect (f (s)).to_be (string.format ("%q", s)) - it renders empty tables as a pair of braces: - expect (f {}).should_be ("{\n}") + expect (f {}).to_be ("{\n}") - it renders an array prettily: a = {"one", "two", "three"} expect (f (a, "")). - should_be '{\n[1] = "one",\n[2] = "two",\n[3] = "three",\n}' + to_be '{\n[1] = "one",\n[2] = "two",\n[3] = "three",\n}' - it renders a table prettily: t = { one = true, two = 2, three = {3}} expect (f (t, "")). - should_be '{\none = true,\nthree =\n{\n[1] = 3,\n},\ntwo = 2,\n}' + to_be '{\none = true,\nthree =\n{\n[1] = 3,\n},\ntwo = 2,\n}' - it renders table keys in table.sort order: t = { one = 3, two = 5, three = 4, four = 2, five = 1 } expect (f (t, "")). - should_be '{\nfive = 1,\nfour = 2,\none = 3,\nthree = 4,\ntwo = 5,\n}' + to_be '{\nfive = 1,\nfour = 2,\none = 3,\nthree = 4,\ntwo = 5,\n}' - it renders keys with invalid symbol names in long hand: t = { _ = 0, word = 0, ["?"] = 1, ["a-key"] = 1, ["[]"] = 1 } expect (f (t, "")). - should_be '{\n["?"] = 1,\n["[]"] = 1,\n_ = 0,\n["a-key"] = 1,\nword = 0,\n}' + to_be '{\n["?"] = 1,\n["[]"] = 1,\n_ = 0,\n["a-key"] = 1,\nword = 0,\n}' - describe render: @@ -394,20 +394,20 @@ specify std.string: f = M.rtrim - it removes whitespace from the end of a string: target = " \t\r\n a short string" - expect (f (subject)).should_equal (target) + expect (f (subject)).to_equal (target) - it supports custom removal patterns: target = " \t\r\n a short string \t\r" - expect (f (subject, "[ \t\n]+")).should_equal (target) + expect (f (subject, "[ \t\n]+")).to_equal (target) - it is available as a string metamethod: target = " \t\r\n a short string \t\r" - expect (subject:rtrim ("[ \t\n]+")).should_equal (target) + expect (subject:rtrim ("[ \t\n]+")).to_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe split: @@ -416,37 +416,37 @@ specify std.string: subject = table.concat (target, ", ") f = M.split - it returns a one-element list for an empty string: - expect (f ("", ", ")).should_equal {""} + expect (f ("", ", ")).to_equal {""} - it makes a table of substrings delimited by a separator: - expect (f (subject, ", ")).should_equal (target) + expect (f (subject, ", ")).to_equal (target) - it returns n+1 elements for n separators: - expect (f (subject, "zero")).should_have_size (1) - expect (f (subject, "c")).should_have_size (2) - expect (f (subject, "s")).should_have_size (3) - expect (f (subject, "t")).should_have_size (4) - expect (f (subject, "e")).should_have_size (5) + expect (f (subject, "zero")).to_have_size (1) + expect (f (subject, "c")).to_have_size (2) + expect (f (subject, "s")).to_have_size (3) + expect (f (subject, "t")).to_have_size (4) + expect (f (subject, "e")).to_have_size (5) - it returns an empty string element for consecutive separators: - expect (f ("xyzyzxy", "yz")).should_equal {"x", "", "xy"} + expect (f ("xyzyzxy", "yz")).to_equal {"x", "", "xy"} - it returns an empty string element when starting with separator: - expect (f ("xyzyzxy", "xyz")).should_equal {"", "yzxy"} + expect (f ("xyzyzxy", "xyz")).to_equal {"", "yzxy"} - it returns an empty string element when ending with separator: - expect (f ("xyzyzxy", "zxy")).should_equal {"xyzy", ""} + expect (f ("xyzyzxy", "zxy")).to_equal {"xyzy", ""} - it returns a table of 1-character strings for "" separator: - expect (f ("abcdef", "")).should_equal {"", "a", "b", "c", "d", "e", "f", ""} + expect (f ("abcdef", "")).to_equal {"", "a", "b", "c", "d", "e", "f", ""} - it is available as a string metamethod: - expect (subject:split ", ").should_equal (target) + expect (subject:split ", ").to_equal (target) expect (("/foo/bar/baz.quux"):split "/"). - should_equal {"", "foo", "bar", "baz.quux"} + to_equal {"", "foo", "bar", "baz.quux"} - the original subject is not perturbed: original = subject newstring = f (subject, "e") - expect (subject).should_be (original) + expect (subject).to_be (original) - it takes a Lua pattern as a separator: expect (f (subject, "%s+")). - should_equal {"first,", "the", "second", "one,", "final", "entry"} + to_equal {"first,", "the", "second", "one,", "final", "entry"} - it diagnoses non-string arguments: - expect (f (nil, ",")).should_error ("string expected") - expect (f ({"a table"}, ",")).should_error ("string expected") + expect (f (nil, ",")).to_error ("string expected") + expect (f ({"a table"}, ",")).to_error ("string expected") - describe tfind: @@ -455,26 +455,26 @@ specify std.string: f = M.tfind - it creates a list of pattern captures: target = { 1, 3, { "a", "b", "c" } } - expect ({f (subject, "(.)(.)(.)")}).should_equal (target) + expect ({f (subject, "(.)(.)(.)")}).to_equal (target) - it creates an empty list where no captures are matched: target = { nil, nil, {} } - expect ({f (subject, "(x)(y)(z)")}).should_equal (target) + expect ({f (subject, "(x)(y)(z)")}).to_equal (target) - it creates an empty list for a pattern without captures: target = { 1, 1, {} } - expect ({f (subject, "a")}).should_equal (target) + expect ({f (subject, "a")}).to_equal (target) - it starts the search at a specified index into the subject: target = { 8, 10, { "a", "b", "c" } } - expect ({f ("garbage" .. subject, "(.)(.)(.)", 8)}).should_equal (target) + expect ({f ("garbage" .. subject, "(.)(.)(.)", 8)}).to_equal (target) - it is available as a string metamethod: target = { 8, 10, { "a", "b", "c" } } - expect ({("garbage" .. subject):tfind ("(.)(.)(.)", 8)}).should_equal (target) + expect ({("garbage" .. subject):tfind ("(.)(.)(.)", 8)}).to_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "...") - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe tostring: @@ -486,20 +486,20 @@ specify std.string: f = M.trim - it removes whitespace from each end of a string: target = "a short string" - expect (f (subject)).should_equal (target) + expect (f (subject)).to_equal (target) - it supports custom removal patterns: target = "\r\n a short string \t\r" - expect (f (subject, "[ \t\n]+")).should_equal (target) + expect (f (subject, "[ \t\n]+")).to_equal (target) - it is available as a string metamethod: target = "\r\n a short string \t\r" - expect (subject:trim ("[ \t\n]+")).should_equal (target) + expect (subject:trim ("[ \t\n]+")).to_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") - expect (subject).should_be (original) + expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") - describe wrap: @@ -516,21 +516,21 @@ specify std.string: "-2013 (see the AUTHORS file for details), and\nreleased un" .. "der the MIT license (the same license as Lua itself). Ther" .. "e is no\nwarranty." - expect (f (subject)).should_be (target) + expect (f (subject)).to_be (target) - it honours a column width parameter: target = "This is a collection of Lua libraries for Lua 5.1 a" .. "nd 5.2. The libraries\nare copyright by their authors 2000" .. "-2013 (see the AUTHORS file for\ndetails), and released un" .. "der the MIT license (the same license as Lua\nitself). The" .. "re is no warranty." - expect (f (subject, 72)).should_be (target) + expect (f (subject, 72)).to_be (target) - it supports indenting by a fixed number of columns: target = " This is a collection of Lua libraries for L" .. "ua 5.1 and 5.2. The\n libraries are copyright by th" .. "eir authors 2000-2013 (see the\n AUTHORS file for d" .. "etails), and released under the MIT license\n (the " .. "same license as Lua itself). There is no warranty." - expect (f (subject, 72, 8)).should_be (target) + expect (f (subject, 72, 8)).to_be (target) - context given a long unwrapped string: - before: target = " This is a collection of Lua libraries for Lua 5" .. @@ -539,16 +539,16 @@ specify std.string: "eased under the MIT\n license (the same license as Lua it" .. "self). There is no\n warranty." - it can indent the first line differently: - expect (f (subject, 64, 2, 4)).should_be (target) + expect (f (subject, 64, 2, 4)).to_be (target) - it is available as a string metamethod: - expect (subject:wrap (64, 2, 4)).should_be (target) + expect (subject:wrap (64, 2, 4)).to_be (target) - the original subject is not perturbed: original = subject newstring = f (subject, 55, 5) - expect (subject).should_be (original) + expect (subject).to_be (original) - it diagnoses indent greater than line width: - expect (f (subject, 10, 12)).should_error ("less than the line width") - expect (f (subject, 99, 99)).should_error ("less than the line width") + expect (f (subject, 10, 12)).to_error ("less than the line width") + expect (f (subject, 99, 99)).to_error ("less than the line width") - it diagnoses non-string arguments: - expect (f ()).should_error ("string expected") - expect (f {"a table"}).should_error ("string expected") + expect (f ()).to_error ("string expected") + expect (f {"a table"}).to_error ("string expected") diff --git a/specs/table_spec.yaml b/specs/table_spec.yaml index d33cbf9..3f9073d 100644 --- a/specs/table_spec.yaml +++ b/specs/table_spec.yaml @@ -1,12 +1,10 @@ before: | - require "spec_helper" - base_module = "table" this_module = "std.table" global_table = "_G" std_globals = { "pack", "ripairs", "totable" } - extend_base = { "clone", "clone_rename", "empty", + extend_base = { "clone", "clone_select", "clone_rename", "empty", "invert", "keys", "merge", "new", "ripairs", "size", "totable", "values", -- make these available after require "std" @@ -14,7 +12,7 @@ before: | enhance_base = { "sort" } - -- 'should_contain' will match keys as well as values :) + -- 'to_contain' will match keys as well as values :) all_apis = {} for _, s in ipairs (std_globals) do all_apis[s] = true end for _, s in ipairs (extend_base) do all_apis[s] = true end @@ -35,24 +33,24 @@ specify std.table: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - it contains apis from the core table table: expect (show_apis {from=base_module, not_in=this_module}). - should_contain.a_permutation_of (all_apis) + to_contain.a_permutation_of (all_apis) - it enhances some apis from the core table table: expect (show_apis {from=base_module, enhanced_in=this_module}). - should_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (enhance_base) - context via the std module: - it adds apis to the global table: expect (show_apis {added_to=global_table, by="std"}). - should_contain.all_of (std_globals) + to_contain.all_of (std_globals) - it adds apis to the core table table: expect (show_apis {added_to=base_module, by="std"}). - should_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (extend_base) - it replaces some apis in the core table table: expect (show_apis {from=base_module, enhanced_after='require "std"'}). - should_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (enhance_base) - describe clone: @@ -60,58 +58,114 @@ specify std.table: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } f = M.clone - it does not just return the subject: - expect (f (subject)).should_not_be (subject) + expect (f (subject)).not_to_be (subject) - it does copy the subject: - expect (f (subject)).should_equal (subject) + expect (f (subject)).to_equal (subject) - it only makes a shallow copy: - expect (f (subject).k1).should_be (subject.k1) + expect (f (subject).k1).to_be (subject.k1) - the original subject is not perturbed: target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } copy = f (subject) - expect (subject).should_equal (target) - expect (subject).should_be (subject) + expect (subject).to_equal (target) + expect (subject).to_be (subject) + - it treats non-table arg2 as nometa parameter: + mt = setmetatable (f (subject, true), {}) + expect (getmetatable (f (mt, true))).to_be (nil) + - it treats table arg2 as a map parameter: + mt = setmetatable (f (subject, true), {}) + expect (getmetatable (f (mt, {}))).to_be (getmetatable (mt)) + - it supports 3 arguments with nometa as arg3: + mt = setmetatable (f (subject, true), {}) + expect (getmetatable (f (mt, {}, "nometa"))).to_be (nil) + + - context when renaming some keys: + - before: + target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } + - it renames during cloning: + expect (f (subject, {k1 = "newkey"})).to_equal (target) + - it does not perturb the value in the renamed key field: + expect (f (subject, {k1 = "newkey"}).newkey).to_be (subject.k1) + - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe clone_rename: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } f = M.clone_rename - - it does not just return the subject: - expect (f ({}, subject)).should_not_be (subject) + - it writes a deprecation warning to standard error on first call: | + _, err = capture (f, {{}, subject}) + if err ~= nil then + -- skip this test when using Specl < 12 capture stub + expect (err).to_contain "clone_rename is deprecated" + end + _, err = capture (f, {{}, subject}) + expect (err).to_be (nil) - it copies the subject: - expect (f ({}, subject)).should_equal (subject) + expect (f ({}, subject)).to_copy (subject) - it only makes a shallow copy: - expect (f ({}, subject).k2).should_be (subject.k2) + expect (f ({}, subject).k2).to_be (subject.k2) - context when renaming some keys: - before: target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } - it renames during cloning: - expect (f ({k1 = "newkey"}, subject)).should_equal (target) + expect (f ({k1 = "newkey"}, subject)).to_equal (target) - it does not perturb the value in the renamed key field: - expect (f ({k1 = "newkey"}, subject).newkey).should_be (subject.k1) + expect (f ({k1 = "newkey"}, subject).newkey).to_be (subject.k1) + + - "it diagnoses non-table arguments": + expect (f {}).to_error ("table expected") + expect (f ({}, "foo")).to_error ("table expected") + + +- describe clone_select: + - before: + subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + f = M.clone_select + - it does not just return the subject: + expect (f (subject)).not_to_be (subject) + - it copies the keys selected: + expect (f (subject, {"k1", "k2"})).to_equal ({ k1 = {"v1"}, k2 = {"v2"} }) + - it does copy the subject when supplied with a full list of keys: + expect (f (subject, {"k1", "k2", "k3"})).to_equal (subject) + - it only makes a shallow copy: + expect (f (subject, {"k1"}).k1).to_be (subject.k1) + - the original subject is not perturbed: + target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } + copy = f (subject, {"k1", "k2", "k3"}) + expect (subject).to_equal (target) + expect (subject).to_be (subject) + - it treats non-table arg2 as nometa parameter: + mt = setmetatable (f (subject, true), {}) + expect (getmetatable (f (mt, true))).to_be (nil) + - it treats table arg2 as a map parameter: + mt = setmetatable (f (subject, true), {}) + expect (getmetatable (f (mt, {}))).to_be (getmetatable (mt)) + - it supports 3 arguments with nometa as arg3: + mt = setmetatable (f (subject, true), {}) + expect (getmetatable (f (mt, {}, "nometa"))).to_be (nil) - "it diagnoses non-table arguments": - expect (f {}).should_error ("table expected") - expect (f ({}, "foo")).should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe empty: - before: f = M.empty - it returns true for an empty table: - expect (f {}).should_be (true) - expect (f {nil}).should_be (true) + expect (f {}).to_be (true) + expect (f {nil}).to_be (true) - "it returns false for a non-empty table": - expect (f {"stuff"}).should_be (false) - expect (f {{}}).should_be (false) - expect (f {false}).should_be (false) + expect (f {"stuff"}).to_be (false) + expect (f {{}}).to_be (false) + expect (f {false}).to_be (false) - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe invert: @@ -119,18 +173,17 @@ specify std.table: subject = { k1 = 1, k2 = 2, k3 = 3 } f = M.invert - it returns a new table: - expect (f (subject)).should_not_be (subject) + expect (f (subject)).not_to_be (subject) - it inverts keys and values in the returned table: - expect (f (subject)).should_equal { "k1", "k2", "k3" } + expect (f (subject)).to_equal { "k1", "k2", "k3" } - it is reversible: - expect (f (f (subject))).should_equal (subject) + expect (f (f (subject))).to_equal (subject) - "it seems to copy a list of 1..n numbers": subject = { 1, 2, 3 } - expect (f (subject)).should_equal (subject) - expect (f (subject)).should_not_be (subject) + expect (f (subject)).to_copy (subject) - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe keys: @@ -138,19 +191,19 @@ specify std.table: subject = { k1 = 1, k2 = 2, k3 = 3 } f = M.keys - it returns an empty list when subject is empty: - expect (f {}).should_equal {} + expect (f {}).to_equal {} - it makes a list of table keys: cmp = function (a, b) return a < b end - expect (M.sort (f (subject), cmp)).should_equal {"k1", "k2", "k3"} + expect (M.sort (f (subject), cmp)).to_equal {"k1", "k2", "k3"} - it does not guarantee stable ordering: subject = {} -- is this a good test? there is a vanishingly small possibility the -- returned table will have all 10000 keys in the same order... for i = 10000, 1, -1 do table.insert (subject, i) end - expect (f (subject)).should_not_equal (subject) + expect (f (subject)).not_to_equal (subject) - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe merge: @@ -164,22 +217,21 @@ specify std.table: for k, v in pairs (t1) do target[k] = v end for k, v in pairs (t2) do target[k] = v end - it does not create a whole new table: - expect (f (t1, t2)).should_be (t1) + expect (f (t1, t2)).to_be (t1) - it does not change t1 when t2 is empty: - expect (f (t1, {})).should_be (t1) + expect (f (t1, {})).to_be (t1) - it copies t2 when t1 is empty: - expect (f ({}, t1)).should_not_be (t1) - expect (f ({}, t1)).should_equal (t1) + expect (f ({}, t1)).to_copy (t1) - it merges keys from t2 into t1: - expect (f (t1, t2)).should_equal (target) + expect (f (t1, t2)).to_equal (target) - it gives precedence to values from t2: original = M.clone (t1) m = f (t1, t2) -- Merge is destructive, do it once only. - expect (m.k3).should_be (t2.k3) - expect (m.k3).should_not_be (original.k3) + expect (m.k3).to_be (t2.k3) + expect (m.k3).not_to_be (original.k3) - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f ("foo", "bar")).should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f ("foo", "bar")).to_error ("table expected") - describe new: @@ -189,34 +241,34 @@ specify std.table: - context when not setting a default: - before: default = nil - it returns a new table when nil is passed: - expect (f (default, nil)).should_equal {} + expect (f (default, nil)).to_equal {} - it returns any table passed in: t = { "unique table" } - expect (f (default, t)).should_be (t) + expect (f (default, t)).to_be (t) - context when setting a default: - before: default = "default" - it returns a new table when nil is passed: - expect (f (default, nil)).should_equal {} + expect (f (default, nil)).to_equal {} - it returns any table passed in: t = { "unique table" } - expect (f (default, t)).should_be (t) + expect (f (default, t)).to_be (t) - it returns the stored value for existing keys: t = f ("default") v = { "unique value" } t[1] = v - expect (t[1]).should_be (v) + expect (t[1]).to_be (v) - it returns the constructor default for unset keys: t = f ("default") - expect (t[1]).should_be "default" + expect (t[1]).to_be "default" - it returns the actual default object: default = { "unique object" } t = f (default) - expect (t[1]).should_be (default) + expect (t[1]).to_be (default) - "it diagnoses non-tables/non-nil in the second argument": - expect (f (nil, "foo")).should_error ("table expected") + expect (f (nil, "foo")).to_error ("table expected") - describe pack: @@ -231,12 +283,12 @@ specify std.table: subject = { "one", { { "two" }, "three" }, four = 5 } f = M.size - it counts the number of keys in a table: - expect (f (subject)).should_be (3) + expect (f (subject)).to_be (3) - it counts no keys in an empty table: - expect (f {}).should_be (0) + expect (f {}).to_be (0) - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe sort: @@ -247,12 +299,12 @@ specify std.table: f = M.sort - it sorts elements in place: f (subject, cmp) - expect (subject).should_equal (target) + expect (subject).to_equal (target) - it returns the sorted table: - expect (f (subject, cmp)).should_equal (target) + expect (f (subject, cmp)).to_equal (target) - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe totable: @@ -263,15 +315,15 @@ specify std.table: subject = { k1 = {1}, k2 = {2}, k3 = {3} } f = M.values - it returns an empty list when subject is empty: - expect (f {}).should_equal {} + expect (f {}).to_equal {} - it makes a list of table values: cmp = function (a, b) return a[1] < b[1] end - expect (M.sort (f (subject), cmp)).should_equal {{1}, {2}, {3}} + expect (M.sort (f (subject), cmp)).to_equal {{1}, {2}, {3}} - it does guarantee stable ordering: subject = {} -- is this a good test? or just requiring an implementation quirk? for i = 10000, 1, -1 do table.insert (subject, i) end - expect (f (subject)).should_equal (subject) + expect (f (subject)).to_equal (subject) - "it diagnoses non-table arguments": - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") diff --git a/specs/tree_spec.yaml b/specs/tree_spec.yaml index ca0c8b7..6f02ea1 100644 --- a/specs/tree_spec.yaml +++ b/specs/tree_spec.yaml @@ -1,6 +1,4 @@ before: | - require "spec_helper" - global_table = "_G" this_module = "std.tree" std_globals = { "ileaves", "inodes", "leaves", "nodes" } @@ -18,31 +16,31 @@ specify std.tree: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). - should_equal {} + to_equal {} - context via the std module: - it adds apis to the global table: expect (show_apis {added_to=global_table, by="std"}). - should_contain.all_of (std_globals) + to_contain.all_of (std_globals) - describe construction: - it constructs a new tree: tr = Tree {} - expect (tr).should_not_be (Tree) - expect (prototype (tr)).should_be "Tree" + expect (tr).not_to_be (Tree) + expect (prototype (tr)).to_be "Tree" - it turns a table argument into a tree: - expect (prototype (Tree (tr))).should_be "Tree" + expect (prototype (Tree (tr))).to_be "Tree" - it does not turn table argument values into sub-Trees: - expect (prototype (tr["fnord"])).should_be "table" + expect (prototype (tr["fnord"])).to_be "table" - it understands branched nodes: - expect (tr).should_equal (Tree (t)) - expect (tr[{"fnord"}]).should_equal (t.fnord) - expect (tr[{"fnord", "branch", "bar"}]).should_equal (t.fnord.branch.bar) + expect (tr).to_equal (Tree (t)) + expect (tr[{"fnord"}]).to_equal (t.fnord) + expect (tr[{"fnord", "branch", "bar"}]).to_equal (t.fnord.branch.bar) - it serves as a prototype for new instances: obj = tr {} - expect (prototype (obj)).should_be "Tree" - expect (obj).should_equal (tr) - expect (getmetatable (obj)).should_be (getmetatable (tr)) + expect (prototype (obj)).to_be "Tree" + expect (obj).to_equal (tr) + expect (getmetatable (obj)).to_be (getmetatable (tr)) - describe clone: @@ -50,19 +48,19 @@ specify std.tree: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } f = Tree.clone - it does not just return the subject: - expect (f (subject)).should_not_be (subject) + expect (f (subject)).not_to_be (subject) - it does copy the subject: - expect (f (subject)).should_equal (subject) + expect (f (subject)).to_equal (subject) - it makes a deep copy: - expect (f (subject).k1).should_not_be (subject.k1) + expect (f (subject).k1).not_to_be (subject.k1) - it does not perturb the original subject: target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } copy = f (subject) - expect (subject).should_equal (target) - expect (subject).should_be (subject) + expect (subject).to_equal (target) + expect (subject).to_be (subject) - it diagnoses non-table arguments: - expect (f ()).should_error ("table expected") - expect (f "foo").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "foo").to_error ("table expected") - describe ileaves: @@ -71,20 +69,20 @@ specify std.tree: l = {} - it iterates over array part of a table argument: for v in f {"first", "second", "3rd"} do l[1+#l]=v end - expect (l).should_equal {"first", "second", "3rd"} + expect (l).to_equal {"first", "second", "3rd"} - it iterates over array parts of nested table argument: for v in f {{"one", {"two"}, {{"three"}, "four"}}, "five"} do l[1+#l]=v end - expect (l).should_equal {"one", "two", "three", "four", "five"} + expect (l).to_equal {"one", "two", "three", "four", "five"} - it skips hash part of a table argument: for v in f {"first", "second"; third = "2rd"} do l[1+#l]=v end - expect (l).should_equal {"first", "second"} + expect (l).to_equal {"first", "second"} - it skips hash parts of nested table argument: for v in f {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} do l[1+#l]=v end - expect (l).should_equal {"one", "three", "five"} + expect (l).to_equal {"one", "three", "five"} - it works on trees too: for v in f (Tree {Tree {"one", Tree {two=2}, @@ -94,10 +92,10 @@ specify std.tree: do l[1+#l]=v end - expect (l).should_equal {"one", "three", "five"} + expect (l).to_equal {"one", "three", "five"} - it diagnoses non-table arguments: - expect (f ()).should_error ("table expected") - expect (f "string").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "string").to_error ("table expected") - describe inodes: @@ -115,52 +113,52 @@ specify std.tree: - it iterates over array part of a table argument: | subject = {"first", "second", "3rd"} expect (traverse (subject)). - should_equal {{"branch", {}, subject}, -- { - {"leaf", {1}, subject[1]}, -- first, - {"leaf", {2}, subject[2]}, -- second, - {"leaf", {3}, subject[3]}, -- 3rd, - {"join", {}, subject}} -- } + to_equal {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"leaf", {3}, subject[3]}, -- 3rd, + {"join", {}, subject}} -- } - it iterates over array parts of nested table argument: | subject = {{"one", {"two"}, {{"three"}, "four"}}, "five"} expect (traverse (subject)). - should_equal {{"branch", {}, subject}, -- { - {"branch", {1}, subject[1]}, -- { - {"leaf", {1,1}, subject[1][1]}, -- one, - {"branch", {1,2}, subject[1][2]}, -- { - {"leaf", {1,2,1}, subject[1][2][1]}, -- two, - {"join", {1,2}, subject[1][2]}, -- }, - {"branch", {1,3}, subject[1][3]}, -- { - {"branch", {1,3,1}, subject[1][3][1]}, -- { - {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, - {"join", {1,3,1}, subject[1][3][1]}, -- }, - {"leaf", {1,3,2}, subject[1][3][2]}, -- four, - {"join", {1,3}, subject[1][3]}, -- }, - {"join", {1}, subject[1]}, -- }, - {"leaf", {2}, subject[2]}, -- five, - {"join", {}, subject}} -- } + to_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,1}, subject[1][2][1]}, -- two, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,2}, subject[1][3][2]}, -- four, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } - it skips hash part of a table argument: | subject = {"first", "second"; third = "3rd"} expect (traverse (subject)). - should_equal {{"branch", {}, subject}, -- { - {"leaf", {1}, subject[1]}, -- first, - {"leaf", {2}, subject[2]}, -- second, - {"join", {}, subject}} -- } + to_equal {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"join", {}, subject}} -- } - it skips hash parts of nested table argument: | subject = {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} expect (traverse (subject)). - should_equal {{"branch", {}, subject}, -- { - {"branch", {1}, subject[1]}, -- { - {"leaf", {1,1}, subject[1][1]}, -- one, - {"branch", {1,2}, subject[1][2]}, -- { - {"join", {1,2}, subject[1][2]}, -- }, - {"branch", {1,3}, subject[1][3]}, -- { - {"branch", {1,3,1}, subject[1][3][1]}, -- { - {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, - {"join", {1,3,1}, subject[1][3][1]}, -- }, - {"join", {1,3}, subject[1][3]}, -- }, - {"join", {1}, subject[1]}, -- }, - {"leaf", {2}, subject[2]}, -- five, - {"join", {}, subject}} -- } + to_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } - it works on trees too: | subject = Tree {Tree {"one", Tree {two=2}, @@ -168,22 +166,22 @@ specify std.tree: foo="bar", "five"} expect (traverse (subject)). - should_equal {{"branch", {}, subject}, -- { - {"branch", {1}, subject[1]}, -- { - {"leaf", {1,1}, subject[1][1]}, -- one, - {"branch", {1,2}, subject[1][2]}, -- { - {"join", {1,2}, subject[1][2]}, -- }, - {"branch", {1,3}, subject[1][3]}, -- { - {"branch", {1,3,1}, subject[1][3][1]}, -- { - {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, - {"join", {1,3,1}, subject[1][3][1]}, -- }, - {"join", {1,3}, subject[1][3]}, -- }, - {"join", {1}, subject[1]}, -- }, - {"leaf", {2}, subject[2]}, -- five, - {"join", {}, subject}} -- } + to_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } - it diagnoses non-table arguments: - expect (f ()).should_error ("table expected") - expect (f "string").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "string").to_error ("table expected") - describe leaves: @@ -192,20 +190,20 @@ specify std.tree: l = {} - it iterates over elements of a table argument: for v in f {"first", "second", "3rd"} do l[1+#l]=v end - expect (l).should_equal {"first", "second", "3rd"} + expect (l).to_equal {"first", "second", "3rd"} - it iterates over elements of a nested table argument: for v in f {{"one", {"two"}, {{"three"}, "four"}}, "five"} do l[1+#l]=v end - expect (l).should_equal {"one", "two", "three", "four", "five"} + expect (l).to_equal {"one", "two", "three", "four", "five"} - it includes the hash part of a table argument: for v in f {"first", "second"; third = "3rd"} do l[1+#l]=v end - expect (l).should_equal {"first", "second", "3rd"} + expect (l).to_equal {"first", "second", "3rd"} - it includes hash parts of a nested table argument: for v in f {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} do l[1+#l]=v end - expect (l).should_contain. + expect (l).to_contain. a_permutation_of {"one", 2, "three", 4, "bar", "five"} - it works on trees too: for v in f (Tree {Tree {"one", @@ -216,11 +214,11 @@ specify std.tree: do l[1+#l]=v end - expect (l).should_contain. + expect (l).to_contain. a_permutation_of {"one", 2, "three", 4, "bar", "five"} - it diagnoses non-table arguments: - expect (f ()).should_error ("table expected") - expect (f "string").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "string").to_error ("table expected") - describe merge: @@ -236,22 +234,21 @@ specify std.tree: if ty == "leaf" then target[p] = n end end - it does not create a whole new table: - expect (f (t1, t2)).should_be (t1) + expect (f (t1, t2)).to_be (t1) - it does not change t1 when t2 is empty: - expect (f (t1, Tree {})).should_be (t1) + expect (f (t1, Tree {})).to_be (t1) - it copies t2 when t1 is empty: | - expect (f (Tree {}, t1)).should_not_be (t1) - expect (f (Tree {}, t1)).should_equal (t1) + expect (f (Tree {}, t1)).to_copy (t1) - it merges keys from t2 into t1: | - expect (f (t1, t2)).should_equal (target) + expect (f (t1, t2)).to_equal (target) - it gives precedence to values from t2: original = Tree.clone (t1) m = f (t1, t2) -- Merge is destructive, do it once only. - expect (m.k3).should_be (t2.k3) - expect (m.k3).should_not_be (original.k3) + expect (m.k3).to_be (t2.k3) + expect (m.k3).not_to_be (original.k3) - it diagnoses non-table arguments: - expect (f (nil, {})).should_error ("table expected") - expect (f ({}, nil)).should_error ("table expected") + expect (f (nil, {})).to_error ("table expected") + expect (f ({}, nil)).to_error ("table expected") - describe nodes: @@ -266,35 +263,35 @@ specify std.tree: - it iterates over the elements of a table argument: | subject = {"first", "second", "3rd"} expect (traverse (subject)). - should_equal {{"branch", {}, subject}, -- { - {"leaf", {1}, subject[1]}, -- first, - {"leaf", {2}, subject[2]}, -- second, - {"leaf", {3}, subject[3]}, -- 3rd, - {"join", {}, subject}} -- } + to_equal {{"branch", {}, subject}, -- { + {"leaf", {1}, subject[1]}, -- first, + {"leaf", {2}, subject[2]}, -- second, + {"leaf", {3}, subject[3]}, -- 3rd, + {"join", {}, subject}} -- } - it iterates over the elements of nested a table argument: | subject = {{"one", {"two"}, {{"three"}, "four"}}, "five"} expect (traverse (subject)). - should_equal {{"branch", {}, subject}, -- { - {"branch", {1}, subject[1]}, -- { - {"leaf", {1,1}, subject[1][1]}, -- one, - {"branch", {1,2}, subject[1][2]}, -- { - {"leaf", {1,2,1}, subject[1][2][1]}, -- two, - {"join", {1,2}, subject[1][2]}, -- }, - {"branch", {1,3}, subject[1][3]}, -- { - {"branch", {1,3,1}, subject[1][3][1]}, -- { - {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, - {"join", {1,3,1}, subject[1][3][1]}, -- }, - {"leaf", {1,3,2}, subject[1][3][2]}, -- four, - {"join", {1,3}, subject[1][3]}, -- }, - {"join", {1}, subject[1]}, -- }, - {"leaf", {2}, subject[2]}, -- five, - {"join", {}, subject}} -- } + to_equal {{"branch", {}, subject}, -- { + {"branch", {1}, subject[1]}, -- { + {"leaf", {1,1}, subject[1][1]}, -- one, + {"branch", {1,2}, subject[1][2]}, -- { + {"leaf", {1,2,1}, subject[1][2][1]}, -- two, + {"join", {1,2}, subject[1][2]}, -- }, + {"branch", {1,3}, subject[1][3]}, -- { + {"branch", {1,3,1}, subject[1][3][1]}, -- { + {"leaf", {1,3,1,1}, subject[1][3][1][1]}, -- three, + {"join", {1,3,1}, subject[1][3][1]}, -- }, + {"leaf", {1,3,2}, subject[1][3][2]}, -- four, + {"join", {1,3}, subject[1][3]}, -- }, + {"join", {1}, subject[1]}, -- }, + {"leaf", {2}, subject[2]}, -- five, + {"join", {}, subject}} -- } - it includes the hash part of a table argument: | -- like `pairs`, `nodes` can visit elements in any order, so we cannot -- guarantee the array part is always visited before the hash part, or -- even that the array elements are visited in order! subject = {"first", "second"; third = "3rd"} - expect (traverse (subject)).should_contain. + expect (traverse (subject)).to_contain. a_permutation_of {{"branch", {}, subject}, -- { {"leaf", {1}, subject[1]}, -- first, {"leaf", {2}, subject[2]}, -- second, @@ -305,7 +302,7 @@ specify std.tree: -- guarantee the array part is always visited before the hash part, or -- even that the array elements are visited in order! subject = {{"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} - expect (traverse (subject)).should_contain. + expect (traverse (subject)).to_contain. a_permutation_of {{"branch", {}, subject}, -- { {"branch", {1}, subject[1]}, -- { {"leaf", {1,1}, subject[1][1]}, -- one, @@ -331,7 +328,7 @@ specify std.tree: Tree {Tree {"three"}, four=4}}, foo="bar", "five"} - expect (traverse (subject)).should_contain. + expect (traverse (subject)).to_contain. a_permutation_of {{"branch", {}, subject}, -- { {"branch", {1}, subject[1]}, -- { {"leaf", {1,1}, subject[1][1]}, -- one, @@ -349,39 +346,39 @@ specify std.tree: {"leaf", {"foo"}, subject["foo"]}, -- bar, {"join", {}, subject}} -- } - it generates path key-lists that are valid __index arguments: | - pending "std.tree.__index handling empty list keys" subject = Tree {"first", Tree {"second"}, "3rd"} expect (traverse (subject)). - should_equal {{"branch", {}, subject[{}]}, -- { - {"leaf", {1}, subject[{1}]}, -- first, - {"branch", {2}, subject[{2}]}, -- { - {"leaf", {2,1}, subject[{2,1}]}, -- second - {"join", {2}, subject[{2}]}, -- } - {"leaf", {3}, subject[{3}]}, -- 3rd, - {"join", {}, subject[{}]}} -- } + to_equal {{"branch", {}, subject[{}]}, -- { + {"leaf", {1}, subject[{1}]}, -- first, + {"branch", {2}, subject[{2}]}, -- { + {"leaf", {2,1}, subject[{2,1}]}, -- second + {"join", {2}, subject[{2}]}, -- } + {"leaf", {3}, subject[{3}]}, -- 3rd, + {"join", {}, subject[{}]}} -- } - it diagnoses non-table arguments: - expect (f ()).should_error ("table expected") - expect (f "string").should_error ("table expected") + expect (f ()).to_error ("table expected") + expect (f "string").to_error ("table expected") - describe __index: - it returns nil for a missing key: - expect (tr["no such key"]).should_be (nil) + expect (tr["no such key"]).to_be (nil) - it returns nil for missing single element key lists: - expect (tr[{"no such key"}]).should_be (nil) - - it returns nil for missing multi-element key lists: | - expect (tr[{"fnord", "foo"}]).should_be (nil) - pending "see issue #39" - expect (tr[{"no", "such", "key"}]).should_be (nil) + expect (tr[{"no such key"}]).to_be (nil) + - it returns nil for missing multi-element key lists: + expect (tr[{"fnord", "foo"}]).to_be (nil) + expect (tr[{"no", "such", "key"}]).to_be (nil) - it returns a value for the given key: - expect (tr["foo"]).should_be "foo" - expect (tr["quux"]).should_be "quux" + expect (tr["foo"]).to_be "foo" + expect (tr["quux"]).to_be "quux" + - it returns tree root for empty key list: + expect (tr[{}]).to_be (tr) - it returns values for single element key lists: - expect (tr[{"foo"}]).should_be "foo" - expect (tr[{"quux"}]).should_be "quux" + expect (tr[{"foo"}]).to_be "foo" + expect (tr[{"quux"}]).to_be "quux" - it returns values for multi-element key lists: - expect (tr[{"fnord", "branch", "bar"}]).should_be "bar" - expect (tr[{"fnord", "branch", "baz"}]).should_be "baz" + expect (tr[{"fnord", "branch", "bar"}]).to_be "bar" + expect (tr[{"fnord", "branch", "baz"}]).to_be "baz" - describe __newindex: @@ -389,31 +386,31 @@ specify std.tree: tr = Tree {} - it stores values for simple keys: tr["foo"] = "foo" - expect (tr).should_equal (Tree {foo="foo"}) + expect (tr).to_equal (Tree {foo="foo"}) - it stores values for single element key lists: tr[{"foo"}] = "foo" - expect (tr).should_equal (Tree {foo="foo"}) + expect (tr).to_equal (Tree {foo="foo"}) - it stores values for multi-element key lists: tr[{"foo", "bar"}] = "baz" - expect (tr).should_equal (Tree {foo=Tree {bar="baz"}}) + expect (tr).to_equal (Tree {foo=Tree {bar="baz"}}) - it separates branches for diverging key lists: tr[{"foo", "branch", "bar"}] = "leaf1" tr[{"foo", "branch", "baz"}] = "leaf2" - expect (tr).should_equal (Tree {foo=Tree {branch=Tree {bar="leaf1", baz="leaf2"}}}) + expect (tr).to_equal (Tree {foo=Tree {branch=Tree {bar="leaf1", baz="leaf2"}}}) - describe __totable: - it returns a table: - expect (prototype (totable (tr))).should_be "table" + expect (prototype (totable (tr))).to_be "table" - it contains all non-hidden fields of object: - expect (totable (tr)).should_contain. + expect (totable (tr)).to_contain. all_of {"foo", branch={bar="bar", baz="baz"}, "quux"} - describe __tostring: - it returns a string: - expect (prototype (tostring (tr))).should_be "string" + expect (prototype (tostring (tr))).to_be "string" - it shows the type name: - expect (tostring (tr)).should_contain "Tree" + expect (tostring (tr)).to_contain "Tree" - it shows the contents in order: | pending "see issue #44" expect (tostring (tr)). - should_contain 'fnord={branch={bar=bar, baz=baz}}, foo=foo, quux=quux' + to_contain 'fnord={branch={bar=bar, baz=baz}}, foo=foo, quux=quux' diff --git a/stdlib-38-1.rockspec b/stdlib-39-1.rockspec similarity index 87% rename from stdlib-38-1.rockspec rename to stdlib-39-1.rockspec index 505d9ef..60f7bd8 100644 --- a/stdlib-38-1.rockspec +++ b/stdlib-39-1.rockspec @@ -1,14 +1,14 @@ package = "stdlib" -version = "38-1" +version = "39-1" description = { detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", - homepage = "http://rrthomas.github.io/lua-stdlib", + homepage = "http://lua-stdlib.github.io/lua-stdlib", license = "MIT/X11", summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v38", - url = "http://github.com/rrthomas/lua-stdlib/archive/release-v38.zip", + dir = "lua-stdlib-release-v39", + url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v39.zip", } dependencies = { "lua >= 5.1", diff --git a/travis.yml.in b/travis.yml.in index 602e072..d39c34d 100644 --- a/travis.yml.in +++ b/travis.yml.in @@ -6,7 +6,7 @@ env: - PACKAGE=@PACKAGE@ - ROCKSPEC=$PACKAGE-git-1.rockspec - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - - LUAROCKS_BASE=luarocks-2.1.1 + - LUAROCKS_BASE=luarocks-2.1.2 - LUAROCKS="$LUA $HOME/bin/luarocks" matrix: - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 @@ -29,11 +29,13 @@ install: # Install a recent luarocks release locally for everything else. - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - tar zxvpf $LUAROCKS_BASE.tar.gz + # LuaRocks configure --with-lua argument is just a prefix! - ( cd $LUAROCKS_BASE; ./configure - --prefix=$HOME --lua-version=$LUA_SUFFIX --lua-suffix=$LUA_SUFFIX - --with-lua-include=$LUA_INCDIR; - make all install; ) + --prefix=$HOME --with-lua=/usr --lua-version=$LUA_SUFFIX + --lua-suffix=$LUA_SUFFIX --with-lua-include=$LUA_INCDIR; + make build; + make install; ) # Configure and build. script: From 5353b258fd729b358497afca6afb760fd577f377 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Thu, 1 May 2014 17:46:25 +0700 Subject: [PATCH 25/34] Release v40. Signed-off-by: Gary V. Vaughan --- ChangeLog | 163 ++++- Makefile.in | 3 +- NEWS | 63 ++ configure | 22 +- configure.ac | 2 +- doc/classes/std.container.html | 2 +- doc/classes/std.list.html | 2 +- doc/classes/std.object.html | 2 +- doc/classes/std.optparse.html | 2 +- doc/classes/std.set.html | 2 +- doc/classes/std.strbuf.html | 2 +- doc/classes/std.tree.html | 2 +- doc/index.html | 4 +- doc/modules/std.debug.html | 2 +- doc/modules/std.functional.html | 37 +- doc/modules/std.html | 624 ++----------------- doc/modules/std.io.html | 36 +- doc/modules/std.math.html | 2 +- doc/modules/std.package.html | 2 +- doc/modules/std.strict.html | 2 +- doc/modules/std.string.html | 40 +- doc/modules/std.table.html | 138 +++- lib/std.lua | 264 +++----- lib/std.lua.in | 262 +++----- lib/std/base.lua | 138 +--- lib/std/container.lua | 36 +- lib/std/functional.lua | 45 +- lib/std/io.lua | 31 +- lib/std/list.lua | 133 ++-- lib/std/math.lua | 31 +- lib/std/modules.lua | 19 - lib/std/object.lua | 2 +- lib/std/optparse.lua | 39 +- lib/std/set.lua | 36 +- lib/std/strbuf.lua | 7 +- lib/std/string.lua | 52 +- lib/std/table.lua | 278 ++++++--- lib/std/tree.lua | 46 +- local.mk | 3 +- specs/debug_spec.yaml | 13 +- specs/functional_spec.yaml | 13 +- specs/io_spec.yaml | 54 +- specs/math_spec.yaml | 41 +- specs/object_spec.yaml | 4 +- specs/package_spec.yaml | 18 +- specs/std_spec.yaml | 108 +++- specs/string_spec.yaml | 129 ++-- specs/table_spec.yaml | 219 ++++--- specs/tree_spec.yaml | 11 +- stdlib-39-1.rockspec => stdlib-40-1.rockspec | 7 +- 50 files changed, 1554 insertions(+), 1639 deletions(-) delete mode 100644 lib/std/modules.lua rename stdlib-39-1.rockspec => stdlib-40-1.rockspec (92%) diff --git a/ChangeLog b/ChangeLog index eaaa3ef..8b7545c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,167 @@ +2014-05-01 Gary V. Vaughan + + Release version 40 + * NEWS: Record release date. + + refactor: remove unused `std.modules`. + * lib/std/modules.lua: Remove. + * local.mk (dist_luastd_DATA): Adjust. + + refactor: use `t[#t + 1] = v` rather than `table.insert (t, v)`. + Save a function call by factoring away calls to table.insert. + * lib/std/container.lua, lib/std/functional.lua, lib/std/io.lua, + lib/std/list.lua, lib/std/optparse.lua, lib/std/set.lua, + lib/std/strbuf.lua, lib/std/string.lua, lib/std/table.lua, + lib/std/tree.lua: Substitute accordingly. + + refactor: factor out merge_allfields and merge_namedfields. + * lib/std/table (clone, merge): Move shared functionality from + here... + (merge_allfields): ...to here. + (clone_select, merge_select): Move shared funtionality from + here... + (merge_namedfields): ...to here. + + refactor: move leaves and ileaves from base to tree module. + * lib/std/base.lua (ileaves, leaves): Move from here... + * lib/std/tree.lua (ileaves, leaves): ...to here. + * lib/std/base.lua (_leaves): Rename from this... + (leaves): ...to this. + * lib/std/list.lua (flatten): Adjust. + + refactor: move unshared methods out of std.base. + * lib/std/base.lua (merge): Move from here... + * lib/std/table.lua (merge): ...to here. + * lib/std/base.lua (append, compare, concat): Move from here... + * lib/std/list.lua (append, compare, concat): ...to here. + * specs/object_spec.yaml (std.object): Adjust. + + refactor: remove deprecated methods. + * lib/std/base.lua (new, metatable): Remove. + (concat, M): Simplify accordingly. + * lib/std/functional.lua: No need to require std.base. + * lib/std/set.lua (_functions): Move into object declaration, + removing `new`. + * lib/std/strbuf.lua (new): Remove. + * lib/std/tree.lua (new): Remove. + * NEWS: Update. + + tree: allow objects as keys. + * lib/std/tree.lua (Tree.__index): Only fold key list when key + parameter is a raw list, and not when it is a std.object derived + table. + (Tree.__newindex): Only descend the key list creating sub-Trees + when key parameter is a raw list, and not when it is a std.object + derived table. + * NEWS: Update. + + functional: generalize memoize with normalization parameter. + * lib/std/functional.lua (memoize): Don't rely on tostring + having been monkey-patched to std.string.tostring already, but + also don't automatically load all of std.string into memory + unless memoize is called without a normalization function. + * NEWS: Update. + + list: remove deprecated methods. + * lib/std/list.lua: Remove indexKey, indexValue, mapWith, zipWith, + new and slice. + * NEWS: Update. + + specs: std.table.pack is present for any supported Lua release. + * specs/table_spec.yaml (extend_base): List "pack" unconditionally. + + specs: Lua 5.1 does not call tostring on format "%s" arguments. + * specs/string_spec.yaml (..): Explicitly stringify nil argument. + +2014-04-26 Gary V. Vaughan + + std: barrel of monkey(patche)s! + Close #56. + Segregate monkey patching into module functions that have to + be called explicitly. + * lib/std.lua.in: Don't clobber any core metatables, or change + any global symbols on load. + * specs/io_spec.lua (monkey_patch): Specify behaviour of + std.io.monkey_patch function. + * lib/std/io.lua (monkey_patch): Add readlines and writelines + methods to core file objects. + (processFiles): Remove. + * specs/math_spec.lua (monkey_patch): Specify behaviour of + std.math.monkey_patch function. + * lib/std/math.lua (monkey_patch): Overwrite core math.floor. + * specs/string_spec.lua (monkey_patch): Specify behaviour of + std.string.monkey_patch function. + * lib/std/string.lua (monkey_patch): Overwrite core assert and + tostring functions, and add methods and metamethods to core + string objects. + (escapePattern, escapeShell, ordinalSuffix): Remove. + * specs/table_spec.lua (monkey_patch): Specify behaviour of + std.table.monkey_patch function. + * lib/std/table.lua (monkey_patch): Overwrite core table.sort. + * specs/table_spec.lua (barrel, monkey_patch): Specify behaviour + of std.barrel and std.monkey_patch functions. + * lib/std.lua.in (monkey_patch): New function for patching core + symbols and metatables by calling submodule `monkey_patch` + functions. + (barrel): New function for scribbling all over the given + namespace, as well as installing all std monkey_patches. + * specs/debug_spec.yaml, specs/functional_spec.yaml, + specs/io_spec.yaml, specs/math_spec.yaml, specs/package_spec.yaml, + specs/std_spec.yaml, specs/string_spec.yaml, specs/table_spec.yaml, + specs/tree_spec.yaml: Update to reflect removal of default + monkey patching. + + refactor: move `metamethod` from `functional` to `table` module. + * lib/std/functional.lua (metamethod): Move from here... + * lib/std/base.lua (metamethod): ...to here; and... + * lib/std/table.lua (metamethod): ...re-export from here. + Break dependency on `std.functional`. + Adjust all callers. + * NEWS: Update. + + refactor: move clone and clone_rename back into std.table. + * lib/std/base.lua (clone, clone_rename): Move from here... + * lib/std/table.lua (clone, clone_rename): ...to here. + + refactor: break std.container dependency on std.base. + * lib/std/container.lua (instantiate): New function; a faster + equivalent to `merge (clone (proto), t or {})`. + Adjust all callers. + + specs: fix a garbage-in, garbage-out example. + Close #44. + * specs/tree_spec.yaml (tostring): The assumption that tostring + should recurse by itself, or that the Tree constructor should + massage subtables on instantiation were both flawed. Fix the + input to be properly nested tree, and `tostring` will indeed + output a properly nested tree. + +2014-04-25 Gary V. Vaughan + + docs: add missing doc for nometa arg of merge_select. + * lib/std/table.lua (merge_select): Add missing nometa doc. + + table: add merge_select, and support map and nometa args to merge. + Close #56. + * specs/table_spec.yaml (extend_base): Add merge_select. + (merge): Specify behaviour of new `map` and `nometa` args. + (merge_select): Specify behaviour of new `merge_select` api. + (clone, clone_select): Refactor for clarity and orthogonality. + * lib/std/base.lua (merge): Rewrite to support clone-like `map` + and `nometa` parameters, according to improved specifications. + (clone): Rewrite as a call to `merge`. + * lib/std/table.lua (merge_select): New `clone_select` like api + satisfying specs. + (clone_select): Rewrite as a call to `merge_select`. + * NEWS: Update. + 2014-04-23 Gary V. Vaughan - Release v39. + maint: post-release administrivia. + * configure.ac (AC_INIT): Bump release number to 40. + * NEWS: Add header line for next release. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. Release version 39 * NEWS: Record release date. diff --git a/Makefile.in b/Makefile.in index cd28743..4593e03 100644 --- a/Makefile.in +++ b/Makefile.in @@ -390,7 +390,7 @@ man_MANS = save_release_files = $(scm_rockspec) std_path = $(abs_srcdir)/lib/?.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = 1c4d1bfae2d511327b83800043bc19c7 +old_NEWS_hash = 606609f9586288cfe6d9df676719570a update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ UPDATE_COPYRIGHT_USE_INTERVALS=1 \ @@ -446,7 +446,6 @@ dist_luastd_DATA = \ lib/std/io.lua \ lib/std/list.lua \ lib/std/math.lua \ - lib/std/modules.lua \ lib/std/object.lua \ lib/std/optparse.lua \ lib/std/package.lua \ diff --git a/NEWS b/NEWS index 6dc0fce..fbfcf80 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,68 @@ Stdlib NEWS - User visible changes +* Noteworthy changes in release 40 (2014-05-01) [stable] + +** New features: + + - `functional.memoize` now accepts a user normalization function, + falling back on `string.tostring` otherwise. + + - `table.merge` now supports `map` and `nometa` arguments orthogonally + to `table.clone`. + + - New `table.merge_select` function, orthogonal to + `table.clone_select`. See LDocs for details. + +** Incompatible changes: + + - Core methods and metamethods are no longer monkey patched by default + when you `require "std"` (or `std.io`, `std.math`, `std.string` or + `std.table`). Instead they provide a new `monkey_patch` method you + should use when you don't care about interactions with other + modules: + + local io = require "std.io".monkey_patch () + + To install all of stdlib's monkey patches, the `std` module itself + has a `monkey_patch` method that loads all submodules with their own + `monkey_patch` method and runs them all. + + If you want full compatibility with the previous release, in addition + to the global namespace scribbling snippet above, then you need to + adjust the first line to: + + local std = require "std".monkey_patch () + + - The global namespace is no longer clobbered by `require "std"`. To + get the old behaviour back: + + local std = require "std".barrel (_G) + + This will execute all available monkey_patch functions, and then + scribble all over the `_G` namespace, just like the old days. + + - The `metamethod` call is no longer in `std.functional`, but has moved + to `std.table` where it properly belongs. It is a utility method for + tables and has nothing to do with functional programming. + + - The following deprecated camelCase names have been removed, you + should update your code to use the snake_case equivalents: + `std.io.processFiles`, `std.list.indexKey`, `std.list.indexValue`, + `std.list.mapWith`, `std.list.zipWith`, `std.string.escapePattern`, + `std.string. escapeShell`, `std.string.ordinalSuffix`. + + - The following deprecated function names have been removed: + `std.list.new` (call `std.list` directly instead), + `std.list.slice` (use `std.list.sub` instead), + `std.set.new` (call `std.set` directly instead), + `std.strbuf.new` (call `std.strbuf` directly instead), and + `std.tree.new` (call `std.tree` directly instead). + +** Bug fixes: + + - Allow `std.object` derived tables as `std.tree` keys again. + + * Noteworthy changes in release 39 (2014-04-23) [stable] ** New features: diff --git a/configure b/configure index 88f48c1..145e36b 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 39. +# Generated by GNU Autoconf 2.69 for stdlib 40. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='39' -PACKAGE_STRING='stdlib 39' +PACKAGE_VERSION='40' +PACKAGE_STRING='stdlib 40' PACKAGE_BUGREPORT='http://github.com/lua-stdlib/lua-stdlib/issues' PACKAGE_URL='' @@ -1217,7 +1217,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 39 to adapt to many kinds of systems. +\`configure' configures stdlib 40 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1283,7 +1283,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 39:";; + short | recursive ) echo "Configuration of stdlib 40:";; esac cat <<\_ACEOF @@ -1363,7 +1363,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 39 +stdlib configure 40 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1380,7 +1380,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 39, which was +It was created by stdlib $as_me 40, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1760,7 +1760,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. $as_echo "## --------------------- ## -## Configuring stdlib 39 ## +## Configuring stdlib 40 ## ## --------------------- ##" echo @@ -2250,7 +2250,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='39' + VERSION='40' cat >>confdefs.h <<_ACEOF @@ -3641,7 +3641,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 39, which was +This file was extended by stdlib $as_me 40, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3694,7 +3694,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 39 +stdlib config.status 40 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 2965667..e767700 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [39], [http://github.com/lua-stdlib/lua-stdlib/issues]) +AC_INIT([stdlib], [40], [http://github.com/lua-stdlib/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 92391de..35ce67d 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 6d48174..14faae7 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index 05bbeab..c30d9a5 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html index 05f451d..1ad8ebd 100644 --- a/doc/classes/std.optparse.html +++ b/doc/classes/std.optparse.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index a6de351..3b6fd70 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index 5ff78cf..0fd26f0 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index 1f56bde..6e33ccc 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/index.html b/doc/index.html index 31e52fc..b9bac87 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference @@ -63,7 +63,7 @@

    Modules

    clone (t, nometa)clone (t[, map={}], nometa) Make a shallow copy of a table, including any metatable.
    clone_rename (t, map)Clone a table, renaming some keys.clone_select (t[, selection={}])Make a partial clone of a table.
    empty (t)
    - + diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html index 3802b07..08aa6a1 100644 --- a/doc/modules/std.debug.html +++ b/doc/modules/std.debug.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index 1ccfd60..918f20a 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference @@ -114,12 +114,12 @@

    Functions

    - + - - + +
    stdGlobal namespace scribbler.Submodule lazy loader.
    std.debug Map a function over an iterator.
    memoize (fn)memoize (fn, normalize) Memoize a function, by wrapping it in a functable.
    metamethod (x, n)Return given metamethod, if any, or nil.memoize_normalize (...)Signature of memoize normalize functions.

    Tables

    @@ -427,10 +427,15 @@

    Returns:

    - memoize (fn) + memoize (fn, normalize)
    - Memoize a function, by wrapping it in a functable. + Memoize a function, by wrapping it in a functable.

    + +

    To ensure that memoize always returns the same object for the same + arguments, it passes arguments to normalize (std.string.tostring + by default). You may need a more sophisticated function if memoize + should handle complicated argument equivalencies.

    Parameters:

    @@ -438,6 +443,9 @@

    Parameters:

  • fn function that returns a single result
  • +
  • normalize + [opt] function to normalize arguments +
  • Returns:

    @@ -451,28 +459,25 @@

    Returns:

    - - metamethod (x, n) + + memoize_normalize (...)
    - Return given metamethod, if any, or nil. + Signature of memoize normalize functions.

    Parameters:

      -
    • x - object to get metamethod of -
    • -
    • n - name of metamethod to get +
    • ... + arguments

    Returns:

      - metamethod function or nil if no metamethod or not a - function + string + normalized arguments
    diff --git a/doc/modules/std.html b/doc/modules/std.html index 9f51b5f..e3dac79 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference @@ -66,130 +66,35 @@

    Classes

    Module std

    -

    Global namespace scribbler.

    -

    For backwards compatibility with older releases, require "std" - will inject the same functions into the global namespace as it - has done previously, even though it is now deprecated.

    +

    Submodule lazy loader.

    +

    After requiring this module, simply referencing symbols in the submodule + hierarchy will load the necessary modules on demand.

    -

    For new code, much better than scribbling all over the global - namespace, it's more hygienic to explicitly assign the results of - requiring just the submodules you actually use to a local variable, - and access its functions via that table.

    +

    Clients of older releases might be surprised by this new-found hygiene, + expecting the various changes that used to be automatically installed as + global symbols, or monkey patched into the core module tables and + metatables. Sometimes, it's still convenient to do that... when using + stdlib from the REPL, or in a prototype where you want to throw caution + to the wind and compatibility with other modules be damned, for example. + In that case, you can give stdlib permission to scribble all over your + namespaces with:

    + +

    local std = require "std".monkey_patch ()

    Functions

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + +
    _G.assert ()Extend to allow formatted arguments.
    _G.bind ()Partially apply a function.
    _G.collect ()Collect the results of an iterator.
    _G.compose ()Compose functions.
    _G.curry ()Curry a function.
    _G.die ()Die with an error.
    _G.eval ()Evaluate a string.
    _G.filter ()Filter an iterator with a predicate.
    _G.fold ()Fold a binary function into an iterator.
    _G.id ()Identity function.
    _G.ileaves ()Tree iterator which returns just numbered leaves, in order.
    _G.inodes ()Tree iterator over numbered nodes, in order.
    _G.leaves ()Tree iterator which returns just leaves.
    _G.map ()Map a function over an iterator.
    _G.memoize ()Memoize a function, by wrapping it in a functable.
    _G.metamethod ()Return given metamethod, if any, else nil.
    _G.nodes ()Tree iterator.
    _G.pack ()Turn a tuple into a list.
    _G.pickle ()Convert a value to a string.
    _G.prettytostring ()Pretty-print a table.
    _G.render ()Turn tables into strings with recursion detection.
    _G.require_version ()Require a module with a particular version.
    _G.ripairs ()An iterator like ipairs, but in reverse.
    _G.tostring ()Extend tostring to work better on tables.
    _G.totable ()Turn an object into a table, according to __totable metamethod.barrel ([namespace=_G])A barrel of monkey_patches.
    _G.warn ()Give a warning with the name of program and file (if any).monkey_patch ([namespace=_G])Overwrite core methods and metamethods with std enhanced versions.

    Tables

    - - - - @@ -210,502 +115,79 @@

    Metamethods

    Functions

    - - _G.assert () -
    -
    - Extend to allow formatted arguments. - - - - - -

    See also:

    - - - -
    -
    - - _G.bind () -
    -
    - Partially apply a function. - - - - - -

    See also:

    - - - -
    -
    - - _G.collect () -
    -
    - Collect the results of an iterator. - - - - - -

    See also:

    - - - -
    -
    - - _G.compose () -
    -
    - Compose functions. - - - - - -

    See also:

    - - - -
    -
    - - _G.curry () -
    -
    - Curry a function. - - - - - -

    See also:

    - - - -
    -
    - - _G.die () -
    -
    - Die with an error. - - - - - -

    See also:

    - - - -
    -
    - - _G.eval () -
    -
    - Evaluate a string. - - - - - -

    See also:

    - - - -
    -
    - - _G.filter () -
    -
    - Filter an iterator with a predicate. - - - - - -

    See also:

    - - - -
    -
    - - _G.fold () -
    -
    - Fold a binary function into an iterator. - - - - - -

    See also:

    - - - -
    -
    - - _G.id () + + barrel ([namespace=_G])
    - Identity function. + A barrel of monkey_patches.

    +

    Scribble all over the given namespace, and apply all available + monkey_patch functions. - - -

    See also:

    - - - -
    -
    - - _G.ileaves () -
    -
    - Tree iterator which returns just numbered leaves, in order. - - - - - -

    See also:

    - - - -
    -
    - - _G.inodes () -
    -
    - Tree iterator over numbered nodes, in order. - - - - - -

    See also:

    - - - -
    -
    - - _G.leaves () -
    -
    - Tree iterator which returns just leaves. - - - - - -

    See also:

    - - - -
    -
    - - _G.map () -
    -
    - Map a function over an iterator. - - - - - -

    See also:

    - - - -
    -
    - - _G.memoize () -
    -
    - Memoize a function, by wrapping it in a functable. - - - - - -

    See also:

    - - - -
    -
    - - _G.metamethod () -
    -
    - Return given metamethod, if any, else nil. - - - - - -

    See also:

    - - - -
    -
    - - _G.nodes () -
    -
    - Tree iterator. - - - - - -

    See also:

    - - - -
    -
    - - _G.pack () -
    -
    - Turn a tuple into a list. - - - - - -

    See also:

    - - - -
    -
    - - _G.pickle () -
    -
    - Convert a value to a string. - - - - - -

    See also:

    - - - -
    -
    - - _G.prettytostring () -
    -
    - Pretty-print a table. - - - - - -

    See also:

    - - - -
    -
    - - _G.render () -
    -
    - Turn tables into strings with recursion detection. - - - - - -

    See also:

    - - - -
    -
    - - _G.require_version () -
    -
    - Require a module with a particular version. - - - - - -

    See also:

    - - - -
    -
    - - _G.ripairs () -
    -
    - An iterator like ipairs, but in reverse. - - - - - -

    See also:

    +

    Parameters:

    +

    Returns:

    +
      -
    -
    - - _G.tostring () -
    -
    - Extend tostring to work better on tables. - - - + table + module table + -

    See also:

    -
    - - _G.totable () + + monkey_patch ([namespace=_G])
    - Turn an object into a table, according to __totable metamethod. - + Overwrite core methods and metamethods with std enhanced versions.

    +

    Loads all std submodules with a monkey_patch method, and runs + them. - -

    See also:

    +

    Parameters:

    +

    Returns:

    +
      -
    -
    - - _G.warn () -
    -
    - Give a warning with the name of program and file (if any). - - - + table + the module table + -

    See also:

    -

    Tables

    -
    - - _G.op -
    -
    - Functional forms of infix operators. - - - - - -

    See also:

    - - - -
    std
    -

    Module table. - Lazy load submodules into std on first reference. On initial +

    Module table.

    + +

    Lazy load submodules into std on first reference. On initial load, std has the usual single version entry, but the __index metatable will automatically require submodules on first reference:

    diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index 129f739..450acb3 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference @@ -85,6 +85,10 @@

    Functions

    + + + + @@ -195,6 +199,36 @@

    See also:

    + +
    + + monkey_patch ([namespace=_G]) +
    +
    + Overwrite core methods and metamethods with std enhanced versions.

    + +

    Adds readlines and writelines metamethods to core file objects. + + +

    Parameters:

    +
      +
    • namespace + table + where to install global functions + (default _G) +
    • +
    + +

    Returns:

    +
      + + table + the module table +
    + + + +
    diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index 534ce7e..50408e6 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index 620b004..1378d42 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index c68fd7e..a2a8444 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index 8af1ec3..d41ef7b 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference @@ -136,6 +136,10 @@

    Functions

    + + + + @@ -449,6 +453,40 @@

    Returns:

    + +
    + + monkey_patch ([namespace=_G]) +
    +
    + Overwrite core methods and metamethods with std enhanced versions.

    + +

    Adds auto-stringification to .. operator on core strings, and + integer indexing of strings with [] dereferencing.

    + +

    Also replaces core assert and tostring functions with + std.string versions. + + +

    Parameters:

    +
      +
    • namespace + table + where to install global functions + (default _G) +
    • +
    + +

    Returns:

    +
      + + table + the module table +
    + + + +
    diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index bd3fad9..e565d06 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - stdlib 39 Reference + stdlib 40 Reference @@ -77,7 +77,7 @@

    Functions

    - + @@ -93,8 +93,20 @@

    Functions

    - - + + + + + + + + + + + + + + @@ -172,7 +184,7 @@

    Returns:

    - clone_select (t[, selection={}]) + clone_select (t[, keys={}])
    Make a partial clone of a table.

    @@ -186,7 +198,7 @@

    Parameters:

    table source table -
  • selection +
  • keys table list of keys to copy (default {}) @@ -286,10 +298,10 @@

    Returns:

  • - merge (t, u) + merge (t, u[, map={}], nometa)
    - Destructively merge another table's fields into table. + Destructively merge another table's fields into another.

    Parameters:

    @@ -302,6 +314,15 @@

    Parameters:

    table table with fields to merge +
  • map + table + table of {oldkey=newkey, ...} + (default {}) +
  • +
  • nometa + boolean + if non-nil don't copy metatable +
  • Returns:

    @@ -313,6 +334,107 @@

    Returns:

    +
    +
    + + merge_select (t, u[, keys={}], nometa) +
    +
    + Destructively merge another table's named fields into table.

    + +

    Like merge , but does not merge any fields by default. + + +

    Parameters:

    +
      +
    • t + table + destination table +
    • +
    • u + table + table with fields to merge +
    • +
    • keys + table + list of keys to copy + (default {}) +
    • +
    • nometa + boolean + if non-nil don't copy metatable +
    • +
    + +

    Returns:

    +
      + + copy of fields in selection from t, also sharing t's + metatable unless nometa +
    + + + + +
    +
    + + metamethod (x, n) +
    +
    + Return given metamethod, if any, or nil. + + +

    Parameters:

    +
      +
    • x + object to get metamethod of +
    • +
    • n + name of metamethod to get +
    • +
    + +

    Returns:

    +
      + + metamethod function or nil if no metamethod or not a + function +
    + + + + +
    +
    + + monkey_patch ([namespace=_G]) +
    +
    + Overwrite core methods with std enhanced versions.

    + +

    Replaces core table.sort with std.table version. + + +

    Parameters:

    +
      +
    • namespace + table + where to install global functions + (default _G) +
    • +
    + +

    Returns:

    +
      + + table + the module table +
    + + + +
    diff --git a/lib/std.lua b/lib/std.lua index 4b33517..08d797f 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -1,14 +1,19 @@ --[[-- - Global namespace scribbler. + Submodule lazy loader. - For backwards compatibility with older releases, `require "std"` - will inject the same functions into the global namespace as it - has done previously, even though it is now deprecated. + After requiring this module, simply referencing symbols in the submodule + hierarchy will load the necessary modules on demand. - For new code, much better than scribbling all over the global - namespace, it's more hygienic to explicitly assign the results of - requiring just the submodules you actually use to a local variable, - and access its functions via that table. + Clients of older releases might be surprised by this new-found hygiene, + expecting the various changes that used to be automatically installed as + global symbols, or monkey patched into the core module tables and + metatables. Sometimes, it's still convenient to do that... when using + stdlib from the REPL, or in a prototype where you want to throw caution + to the wind and compatibility with other modules be damned, for example. + In that case, you can give stdlib permission to scribble all over your + namespaces with: + + local std = require "std".monkey_patch () @todo Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call @@ -20,7 +25,70 @@ ]] +local M -- forward declaration + +--- Overwrite core methods and metamethods with `std` enhanced versions. +-- +-- Loads all `std` submodules with a `monkey_patch` method, and runs +-- them. +-- @function monkey_patch +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table the module table +local function monkey_patch (namespace) + namespace = namespace or _G + + assert (type (namespace) == "table", + "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") + + require "std.io".monkey_patch (namespace) + require "std.math".monkey_patch (namespace) + require "std.string".monkey_patch (namespace) + require "std.table".monkey_patch (namespace) + + return M +end + + +--- A [barrel of monkey_patches](http://dictionary.reference.com/browse/barrel+of+monkeys). +-- +-- Scribble all over the given namespace, and apply all available +-- `monkey_patch` functions. +-- @function barrel +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table module table +local function barrel (namespace) + namespace = namespace or _G + + assert (type (namespace) == "table", + "bad argument #1 to 'barrel' (table expected, got " .. type (namespace) .. ")") + + -- Older releases installed the following into _G by default. + for _, v in pairs { + "functional.bind", "functional.collect", "functional.compose", + "functional.curry", "functional.eval", "functional.filter", + "functional.fold", "functional.id", "functional.map", + "functional.memoize", "functional.op", + + "io.die", "io.warn", + + "string.assert", "string.pickle", "string.prettytostring", + "string.render", "string.require_version", "string.tostring", + + "table.metamethod", "table.pack", "table.ripairs", + "table.totable", + + "tree.ileaves", "tree.inodes", "tree.leaves", "tree.nodes", + } do + local module, method = v:match "^(.*)%.(.-)$" + namespace[method] = M[module][method] + end + + return monkey_patch (namespace) +end + + --- Module table. +-- -- Lazy load submodules into `std` on first reference. On initial -- load, `std` has the usual single `version` entry, but the `__index` -- metatable will automatically require submodules on first reference: @@ -29,183 +97,13 @@ -- local prototype = std.container.prototype -- @table std -- @field version release version string -local version = "General Lua libraries / 39" - -local modules = require "std.modules" - -for m, globally in pairs (modules) do - if globally == true then - -- Inject stdlib extensions directly into global package namespaces. - for k, v in pairs (require ("std." .. m)) do - _G[m][k] = v - end - else - _G[m] = require ("std." .. m) - end -end - --- Add io functions to the file handle metatable. -local file_metatable = getmetatable (io.stdin) -file_metatable.readlines = io.readlines -file_metatable.writelines = io.writelines - --- Add string metamethods to the string metatable. -local string_metatable = getmetatable "" -string_metatable.__append = string.__append -string_metatable.__concat = string.__concat -string_metatable.__index = string.__index - --- Maintain old global interface access points. -for _, api in ipairs { - --- Partially apply a function. - -- @function _G.bind - -- @see std.functional.bind - "functional.bind", - - --- Collect the results of an iterator. - -- @function _G.collect - -- @see std.functional.collect - "functional.collect", - - --- Compose functions. - -- @function _G.compose - -- @see std.functional.compose - "functional.compose", - - --- Curry a function. - -- @function _G.curry - -- @see std.functional.curry - "functional.curry", - - --- Evaluate a string. - -- @function _G.eval - -- @see std.functional.eval - "functional.eval", +local version = "General Lua libraries / 40" - --- Filter an iterator with a predicate. - -- @function _G.filter - -- @see std.functional.filter - "functional.filter", - - --- Fold a binary function into an iterator. - -- @function _G.fold - -- @see std.functional.fold - "functional.fold", - - --- Identity function. - -- @function _G.id - -- @see std.functional.id - "functional.id", - - --- Map a function over an iterator. - -- @function _G.map - -- @see std.functional.map - "functional.map", - - --- Memoize a function, by wrapping it in a functable. - -- @function _G.memoize - -- @see std.functional.memoize - "functional.memoize", - - --- Return given metamethod, if any, else nil. - -- @function _G.metamethod - -- @see std.functional.metamethod - "functional.metamethod", - - --- Functional forms of infix operators. - -- @table _G.op - -- @see std.functional.op - "functional.op", - - - - --- Die with an error. - -- @function _G.die - -- @see std.io.die - "io.die", - - --- Give a warning with the name of program and file (if any). - -- @function _G.warn - -- @see std.io.warn - "io.warn", - - - - --- Extend to allow formatted arguments. - -- @function _G.assert - -- @see std.string.assert - "string.assert", - - --- Convert a value to a string. - -- @function _G.pickle - -- @see std.string.pickle - "string.pickle", - - --- Pretty-print a table. - -- @function _G.prettytostring - -- @see std.string.prettytostring - "string.prettytostring", - - --- Turn tables into strings with recursion detection. - -- @function _G.render - -- @see std.string.render - "string.render", - - --- Require a module with a particular version. - -- @function _G.require_version - -- @see std.string.require_version - "string.require_version", - - --- Extend `tostring` to work better on tables. - -- @function _G.tostring - -- @see std.string.tostring - "string.tostring", - - - - --- Turn a tuple into a list. - -- @function _G.pack - -- @see std.table.pack - "table.pack", - - --- An iterator like ipairs, but in reverse. - -- @function _G.ripairs - -- @see std.table.ripairs - "table.ripairs", - - --- Turn an object into a table, according to `__totable` metamethod. - -- @function _G.totable - -- @see std.table.totable - "table.totable", - - - - --- Tree iterator which returns just numbered leaves, in order. - -- @function _G.ileaves - -- @see std.tree.ileaves - "tree.ileaves", - - --- Tree iterator over numbered nodes, in order. - -- @function _G.inodes - -- @see std.tree.inodes - "tree.inodes", - - --- Tree iterator which returns just leaves. - -- @function _G.leaves - -- @see std.tree.leaves - "tree.leaves", - - --- Tree iterator. - -- @function _G.nodes - -- @see std.tree.nodes - "tree.nodes", -} do - local module, method = api:match "^(.*)%.(.-)$" - _G[method] = _G[module][method] -end -local M = { - version = version, +M = { + barrel = barrel, + monkey_patch = monkey_patch, + version = version, } diff --git a/lib/std.lua.in b/lib/std.lua.in index 6b0d0f1..74b8eb3 100644 --- a/lib/std.lua.in +++ b/lib/std.lua.in @@ -1,14 +1,19 @@ --[[-- - Global namespace scribbler. + Submodule lazy loader. - For backwards compatibility with older releases, `require "std"` - will inject the same functions into the global namespace as it - has done previously, even though it is now deprecated. + After requiring this module, simply referencing symbols in the submodule + hierarchy will load the necessary modules on demand. - For new code, much better than scribbling all over the global - namespace, it's more hygienic to explicitly assign the results of - requiring just the submodules you actually use to a local variable, - and access its functions via that table. + Clients of older releases might be surprised by this new-found hygiene, + expecting the various changes that used to be automatically installed as + global symbols, or monkey patched into the core module tables and + metatables. Sometimes, it's still convenient to do that... when using + stdlib from the REPL, or in a prototype where you want to throw caution + to the wind and compatibility with other modules be damned, for example. + In that case, you can give stdlib permission to scribble all over your + namespaces with: + + local std = require "std".monkey_patch () @todo Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call @@ -20,7 +25,70 @@ ]] +local M -- forward declaration + +--- Overwrite core methods and metamethods with `std` enhanced versions. +-- +-- Loads all `std` submodules with a `monkey_patch` method, and runs +-- them. +-- @function monkey_patch +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table the module table +local function monkey_patch (namespace) + namespace = namespace or _G + + assert (type (namespace) == "table", + "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") + + require "std.io".monkey_patch (namespace) + require "std.math".monkey_patch (namespace) + require "std.string".monkey_patch (namespace) + require "std.table".monkey_patch (namespace) + + return M +end + + +--- A [barrel of monkey_patches](http://dictionary.reference.com/browse/barrel+of+monkeys). +-- +-- Scribble all over the given namespace, and apply all available +-- `monkey_patch` functions. +-- @function barrel +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table module table +local function barrel (namespace) + namespace = namespace or _G + + assert (type (namespace) == "table", + "bad argument #1 to 'barrel' (table expected, got " .. type (namespace) .. ")") + + -- Older releases installed the following into _G by default. + for _, v in pairs { + "functional.bind", "functional.collect", "functional.compose", + "functional.curry", "functional.eval", "functional.filter", + "functional.fold", "functional.id", "functional.map", + "functional.memoize", "functional.op", + + "io.die", "io.warn", + + "string.assert", "string.pickle", "string.prettytostring", + "string.render", "string.require_version", "string.tostring", + + "table.metamethod", "table.pack", "table.ripairs", + "table.totable", + + "tree.ileaves", "tree.inodes", "tree.leaves", "tree.nodes", + } do + local module, method = v:match "^(.*)%.(.-)$" + namespace[method] = M[module][method] + end + + return monkey_patch (namespace) +end + + --- Module table. +-- -- Lazy load submodules into `std` on first reference. On initial -- load, `std` has the usual single `version` entry, but the `__index` -- metatable will automatically require submodules on first reference: @@ -31,181 +99,11 @@ -- @field version release version string local version = "General Lua libraries / @VERSION@" -local modules = require "std.modules" - -for m, globally in pairs (modules) do - if globally == true then - -- Inject stdlib extensions directly into global package namespaces. - for k, v in pairs (require ("std." .. m)) do - _G[m][k] = v - end - else - _G[m] = require ("std." .. m) - end -end - --- Add io functions to the file handle metatable. -local file_metatable = getmetatable (io.stdin) -file_metatable.readlines = io.readlines -file_metatable.writelines = io.writelines - --- Add string metamethods to the string metatable. -local string_metatable = getmetatable "" -string_metatable.__append = string.__append -string_metatable.__concat = string.__concat -string_metatable.__index = string.__index - --- Maintain old global interface access points. -for _, api in ipairs { - --- Partially apply a function. - -- @function _G.bind - -- @see std.functional.bind - "functional.bind", - - --- Collect the results of an iterator. - -- @function _G.collect - -- @see std.functional.collect - "functional.collect", - - --- Compose functions. - -- @function _G.compose - -- @see std.functional.compose - "functional.compose", - - --- Curry a function. - -- @function _G.curry - -- @see std.functional.curry - "functional.curry", - - --- Evaluate a string. - -- @function _G.eval - -- @see std.functional.eval - "functional.eval", - - --- Filter an iterator with a predicate. - -- @function _G.filter - -- @see std.functional.filter - "functional.filter", - - --- Fold a binary function into an iterator. - -- @function _G.fold - -- @see std.functional.fold - "functional.fold", - - --- Identity function. - -- @function _G.id - -- @see std.functional.id - "functional.id", - - --- Map a function over an iterator. - -- @function _G.map - -- @see std.functional.map - "functional.map", - - --- Memoize a function, by wrapping it in a functable. - -- @function _G.memoize - -- @see std.functional.memoize - "functional.memoize", - - --- Return given metamethod, if any, else nil. - -- @function _G.metamethod - -- @see std.functional.metamethod - "functional.metamethod", - - --- Functional forms of infix operators. - -- @table _G.op - -- @see std.functional.op - "functional.op", - - - - --- Die with an error. - -- @function _G.die - -- @see std.io.die - "io.die", - - --- Give a warning with the name of program and file (if any). - -- @function _G.warn - -- @see std.io.warn - "io.warn", - - - - --- Extend to allow formatted arguments. - -- @function _G.assert - -- @see std.string.assert - "string.assert", - - --- Convert a value to a string. - -- @function _G.pickle - -- @see std.string.pickle - "string.pickle", - - --- Pretty-print a table. - -- @function _G.prettytostring - -- @see std.string.prettytostring - "string.prettytostring", - - --- Turn tables into strings with recursion detection. - -- @function _G.render - -- @see std.string.render - "string.render", - - --- Require a module with a particular version. - -- @function _G.require_version - -- @see std.string.require_version - "string.require_version", - - --- Extend `tostring` to work better on tables. - -- @function _G.tostring - -- @see std.string.tostring - "string.tostring", - - - - --- Turn a tuple into a list. - -- @function _G.pack - -- @see std.table.pack - "table.pack", - - --- An iterator like ipairs, but in reverse. - -- @function _G.ripairs - -- @see std.table.ripairs - "table.ripairs", - - --- Turn an object into a table, according to `__totable` metamethod. - -- @function _G.totable - -- @see std.table.totable - "table.totable", - - - - --- Tree iterator which returns just numbered leaves, in order. - -- @function _G.ileaves - -- @see std.tree.ileaves - "tree.ileaves", - - --- Tree iterator over numbered nodes, in order. - -- @function _G.inodes - -- @see std.tree.inodes - "tree.inodes", - - --- Tree iterator which returns just leaves. - -- @function _G.leaves - -- @see std.tree.leaves - "tree.leaves", - - --- Tree iterator. - -- @function _G.nodes - -- @see std.tree.nodes - "tree.nodes", -} do - local module, method = api:match "^(.*)%.(.-)$" - _G[method] = _G[module][method] -end -local M = { - version = version, +M = { + barrel = barrel, + monkey_patch = monkey_patch, + version = version, } diff --git a/lib/std/base.lua b/lib/std/base.lua index c56d290..b96663e 100644 --- a/lib/std/base.lua +++ b/lib/std/base.lua @@ -23,66 +23,6 @@ local function deprecate (fn, name, warnmsg) end end --- Doc-commented in table.lua... -local function clone (t, map, nometa) - map = map or {} - if type (map) ~= "table" then - map, nometa = {}, map - end - - local u = {} - if not nometa then - setmetatable (u, getmetatable (t)) - end - for k, v in pairs (t) do - u[map[k] or k] = v - end - return u -end - --- Doc-commented in table.lua... -local function clone_rename (map, t) - local r = clone (t) - for i, v in pairs (map) do - r[v] = t[i] - r[i] = nil - end - return r -end - --- Doc-commented in table.lua... -local function merge (t, u) - for i, v in pairs (u) do - t[i] = v - end - return t -end - -local new -- forward declaration - --- Doc-commented in list.lua... -local function append (l, x) - local r = {unpack (l)} - table.insert (r, x) - return r -end - --- Doc-commented in list.lua... -local function compare (l, m) - for i = 1, math.min (#l, #m) do - if l[i] < m[i] then - return -1 - elseif l[i] > m[i] then - return 1 - end - end - if #l < #m then - return -1 - elseif #l > #m then - return 1 - end - return 0 -end -- Doc-commented in list.lua... local function elems (l) @@ -96,22 +36,9 @@ local function elems (l) l, true end ---- Concatenate lists. --- @param ... lists --- @return `{l1[1], ..., --- l1[#l1], ..., ln[1], ..., --- ln[#ln]}` -local function concat (...) - local r = new () - for l in elems ({...}) do - for v in elems (l) do - table.insert (r, v) - end - end - return r -end -local function _leaves (it, tr) +-- Iterator returning leaf nodes from nested tables. +local function leaves (it, tr) local function visit (n) if type (n) == "table" then for _, v in it (n) do @@ -124,64 +51,25 @@ local function _leaves (it, tr) return coroutine.wrap (visit), tr end --- Metamethods for lists --- It would be nice to define this in `list.lua`, but then we --- couldn't keep `new` here, and other modules that really only --- need `list.new` (as opposed to the entire `std.list` API) get --- caught in a dependency loop. -local metatable = { - -- list .. table = list.concat - __concat = concat, - - -- list == list retains its referential meaning - -- - -- list < list = list.compare returns < 0 - __lt = function (l, m) return compare (l, m) < 0 end, - - -- list <= list = list.compare returns <= 0 - __le = function (l, m) return compare (l, m) <= 0 end, - __append = append, -} - ---- List constructor. --- Needed in order to use metamethods. --- @param t list (as a table), or nil for empty list --- @return list (with list metamethods) -function new (t) - return setmetatable (t or {}, metatable) -end - - --- Doc-commented in tree.lua... -local function ileaves (tr) - assert (type (tr) == "table", - "bad argument #1 to 'ileaves' (table expected, got " .. type (tr) .. ")") - return _leaves (ipairs, tr) +-- Doc-commented in table.lua... +local function metamethod (x, n) + local _, m = pcall (function (x) + return getmetatable (x)[n] + end, + x) + if type (m) ~= "function" then + m = nil + end + return m end --- Doc-commented in tree.lua... -local function leaves (tr) - assert (type (tr) == "table", - "bad argument #1 to 'leaves' (table expected, got " .. type (tr) .. ")") - return _leaves (pairs, tr) -end local M = { - append = append, - clone = clone, - clone_rename = clone_rename, - compare = compare, - concat = concat, deprecate = deprecate, elems = elems, - ileaves = ileaves, leaves = leaves, - merge = merge, - new = new, - - -- list metatable - _list_mt = metatable, + metamethod = metamethod, } return M diff --git a/lib/std/container.lua b/lib/std/container.lua index 97dce77..c507d5e 100644 --- a/lib/std/container.lua +++ b/lib/std/container.lua @@ -58,9 +58,27 @@ ]] -local base = require "std.base" - -local clone, merge = base.clone, base.merge +-- Instantiate a new object based on *proto*. +-- +-- This is equivalent to: +-- +-- base.merge (base.clone (proto), t or {}) +-- +-- But, not typechecking arguments or checking for metatables, is +-- slightly faster. +-- @tparam table proto base object to copy from +-- @tparam[opt={}] table t additional fields to merge in +-- @treturn table a new table with fields from proto and t merged in. +local function instantiate (proto, t) + local obj = {} + for k, v in pairs (proto) do + obj[k] = v + end + for k, v in pairs (t or {}) do + obj[k] = v + end + return obj +end local ModuleFunction = { @@ -182,13 +200,13 @@ local metatable = { -- If a metatable was set, then merge our fields and use it. if next (getmetatable (obj) or {}) then - obj_mt = merge (clone (mt), getmetatable (obj)) + obj_mt = instantiate (mt, getmetatable (obj)) -- Merge object methods. if type (obj_mt.__index) == "table" and type ((mt or {}).__index) == "table" then - obj_mt.__index = merge (clone (mt.__index), obj_mt.__index) + obj_mt.__index = instantiate (mt.__index, obj_mt.__index) end end @@ -202,8 +220,8 @@ local metatable = { -- @see std.object.__tostring __tostring = function (self) local totable = getmetatable (self).__totable - local array = clone (totable (self), "nometa") - local other = clone (array, "nometa") + local array = instantiate (totable (self)) + local other = instantiate (array) local s = "" if #other > 0 then for i in ipairs (other) do other[i] = nil end @@ -212,10 +230,10 @@ local metatable = { for i, v in ipairs (array) do array[i] = tostring (v) end local keys, dict = {}, {} - for k in pairs (other) do table.insert (keys, k) end + for k in pairs (other) do keys[#keys + 1] = k end table.sort (keys, function (a, b) return tostring (a) < tostring (b) end) for _, k in ipairs (keys) do - table.insert (dict, tostring (k) .. "=" .. tostring (other[k])) + dict[#dict + 1] = tostring (k) .. "=" .. tostring (other[k]) end if #array > 0 then diff --git a/lib/std/functional.lua b/lib/std/functional.lua index 2be45b9..ce3e32b 100644 --- a/lib/std/functional.lua +++ b/lib/std/functional.lua @@ -3,28 +3,9 @@ @module std.functional ]] -local list = require "std.base" - local functional -- forward declaration ---- Return given metamethod, if any, or nil. --- @param x object to get metamethod of --- @param n name of metamethod to get --- @return metamethod function or nil if no metamethod or not a --- function -local function metamethod (x, n) - local _, m = pcall (function (x) - return getmetatable (x)[n] - end, - x) - if type (m) ~= "function" then - m = nil - end - return m -end - - --- Identity function. -- @param ... -- @return the arguments passed to the function @@ -109,13 +90,32 @@ local function compose (...) end +--- Signature of memoize `normalize` functions. +-- @function memoize_normalize +-- @param ... arguments +-- @treturn string normalized arguments + + --- Memoize a function, by wrapping it in a functable. +-- +-- To ensure that memoize always returns the same object for the same +-- arguments, it passes arguments to `normalize` (std.string.tostring +-- by default). You may need a more sophisticated function if memoize +-- should handle complicated argument equivalencies. -- @param fn function that returns a single result +-- @param normalize[opt] function to normalize arguments -- @return memoized function -local function memoize (fn) +local function memoize (fn, normalize) + if normalize == nil then + -- Call require here, to avoid pulling in all of 'std.string' + -- even when memoize is never called. + local stringify = require "std.string".tostring + normalize = function (...) return stringify {...} end + end + return setmetatable ({}, { __call = function (self, ...) - local k = tostring ({...}) + local k = normalize (...) local v = self[k] if v == nil then v = fn (...) @@ -141,7 +141,7 @@ end local function collect (i, ...) local t = {} for e in i (...) do - table.insert (t, e) + t[#t + 1] = e end return t end @@ -204,7 +204,6 @@ functional = { id = id, map = map, memoize = memoize, - metamethod = metamethod, } --- Functional forms of infix operators. diff --git a/lib/std/io.lua b/lib/std/io.lua index 46f0db2..4681126 100644 --- a/lib/std/io.lua +++ b/lib/std/io.lua @@ -10,6 +10,9 @@ local package = { dirsep = string.match (package.config, "^([^\n]+)\n"), } +local M -- forward declaration + + -- Get an input file handle. -- @param h file handle or name (default: `io.input ()`) -- @return file handle, or nil on error @@ -42,7 +45,7 @@ local function readlines (h) h = input_handle (h) local l = {} for line in h:lines () do - table.insert (l, line) + l[#l + 1] = line end h:close () return l @@ -61,6 +64,24 @@ local function writelines (h, ...) end end +--- Overwrite core methods and metamethods with `std` enhanced versions. +-- +-- Adds `readlines` and `writelines` metamethods to core file objects. +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table the module table +local function monkey_patch (namespace) + namespace = namespace or _G + + assert (type (namespace) == "table", + "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") + + local file_metatable = getmetatable (namespace.io.stdin) + file_metatable.readlines = readlines + file_metatable.writelines = writelines + + return M +end + --- Split a directory path into components. -- Empty components are retained: the root directory becomes `{"", ""}`. -- @param path path @@ -99,7 +120,7 @@ end local function process_files (f) -- N.B. "arg" below refers to the global array of command-line args if #arg == 0 then - table.insert (arg, "-") + arg[#arg + 1] = "-" end for i, v in ipairs (arg) do if v == "-" then @@ -162,10 +183,11 @@ end --- @export -local M = { +M = { catdir = catdir, catfile = catfile, die = die, + monkey_patch = monkey_patch, process_files = process_files, readlines = readlines, shell = shell, @@ -175,9 +197,6 @@ local M = { writelines = writelines, } --- camelCase compatibility. -M.processFiles = process_files - for k, v in pairs (io) do M[k] = M[k] or v end diff --git a/lib/std/list.lua b/lib/std/list.lua index 1a5347e..33caa98 100644 --- a/lib/std/list.lua +++ b/lib/std/list.lua @@ -43,7 +43,9 @@ local List -- forward declaration -- @param x item -- @treturn List new list containing `{l[1], ..., l[#l], x}` local function append (l, x) - return List (base.append (l, x)) + local r = List {unpack (l)} + r[#r + 1] = x + return r end @@ -56,7 +58,32 @@ end -- @tparam table m another list -- @return -1 if `l` is less than `m`, 0 if they are the same, and 1 -- if `l` is greater than `m` -local compare = base.compare +local function compare (l, m) + for i = 1, math.min (#l, #m) do + if l[i] < m[i] then + return -1 + elseif l[i] > m[i] then + return 1 + end + end + if #l < #m then + return -1 + elseif #l > #m then + return 1 + end + return 0 +end + + +--- An iterator over the elements of a list. +-- @static +-- @function elems +-- @tparam List l a list +-- @treturn function iterator function which returns successive elements +-- of `l` +-- @treturn List `l` +-- @return `true` +local elems = base.elems --- Concatenate arguments into a list. @@ -65,7 +92,13 @@ local compare = base.compare -- @treturn List new list containing -- `{l[1], ..., l[#l], l\_1[1], ..., l\_1[#l\_1], ..., l\_n[1], ..., l\_n[#l\_n]}` local function concat (l, ...) - return List (base.concat (l, ...)) + local r = List {} + for e in elems ({l, ...}) do + for v in elems (e) do + r[#r + 1] = v + end + end + return r end @@ -78,17 +111,6 @@ local function cons (l, x) end ---- An iterator over the elements of a list. --- @static --- @function elems --- @tparam List l a list --- @treturn function iterator function which returns successive elements --- of `l` --- @treturn List `l` --- @return `true` -local elems = base.elems - - --- Turn a list of pairs into a table. -- @todo Find a better name. -- @tparam table ls list of lists `{{i1, v1}, ..., {in, vn}}` @@ -111,7 +133,7 @@ end local function enpair (t) local ls = List {} for i, v in pairs (t) do - table.insert (ls, List {i, v}) + ls[#ls + 1] = List {i, v} end return ls end @@ -133,8 +155,8 @@ end -- @treturn List flattened list local function flatten (l) local r = List {} - for v in base.ileaves (l) do - table.insert (r, v) + for v in base.leaves (ipairs, l) do + r[#r + 1] = v end return r end @@ -261,7 +283,7 @@ end local function reverse (l) local r = List {} for i = #l, 1, -1 do - table.insert (r, l[i]) + r[#r + 1] = l[i] end return r end @@ -314,7 +336,7 @@ local function shape (s, l) for j = 1, s[d] do local e e, i = fill (i, d + 1) - table.insert (r, e) + r[#r + 1] = e end return r, i end @@ -342,7 +364,7 @@ local function sub (l, from, to) to = to + len + 1 end for i = from, to do - table.insert (r, l[i]) + r[#r + 1] = l[i] end return r end @@ -386,39 +408,11 @@ local function zip_with (ls, f) end ---- @export -local _functions = { - append = append, - compare = compare, - concat = concat, - cons = cons, - depair = depair, - elems = elems, - enpair = enpair, - filter = filter, - flatten = flatten, - foldl = foldl, - foldr = foldr, - index_key = index_key, - index_value = index_value, - map = map, - map_with = map_with, - project = project, - relems = relems, - rep = rep, - reverse = reverse, - shape = shape, - sub = sub, - tail = tail, - transpose = transpose, - zip_with = zip_with, -} - - List = Object { -- Derived object type. _type = "List", + ------ -- Concatenate lists. -- new = list .. table @@ -596,24 +590,39 @@ List = Object { depair = depair, index_key = function (self, f) return index_key (f, self) end, index_value = function (self, f) return index_value (f, self) end, - indexKey = function (self, f) return indexKey (f, self) end, - indexValue = function (self, f) return indexValue (f, self) end, map_with = function (self, f) return map_with (f, self) end, transpose = transpose, zip_with = function (self, f) return zip_with (f, self) end, }, - _functions = (base.merge (_functions, { - -- backwards compatibility - new = function (t) return List (t or {}) end, - slice = sub, - - -- camelCase compatibility - indexKey = index_key, - indexValue = index_value, - mapWith = map_with, - zipWith = zip_with, - })), + + --- @export + _functions = { + append = append, + compare = compare, + concat = concat, + cons = cons, + depair = depair, + elems = elems, + enpair = enpair, + filter = filter, + flatten = flatten, + foldl = foldl, + foldr = foldr, + index_key = index_key, + index_value = index_value, + map = map, + map_with = map_with, + project = project, + relems = relems, + rep = rep, + reverse = reverse, + shape = shape, + sub = sub, + tail = tail, + transpose = transpose, + zip_with = zip_with, + }, } diff --git a/lib/std/math.lua b/lib/std/math.lua index a50859f..b595bb1 100644 --- a/lib/std/math.lua +++ b/lib/std/math.lua @@ -3,6 +3,8 @@ @module std.math ]] +local M -- forward declaration + local _floor = math.floor @@ -21,6 +23,21 @@ local function floor (n, p) end +--- Overwrite core methods with `std` enhanced versions. +-- +-- Replaces core `math.floor` with `std.math` version. +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table the module table +local function monkey_patch (namespace) + namespace = namespace or _G + assert (type (namespace) == "table", + "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") + + namespace.math.floor = floor + return M +end + + --- Round a number to a given number of decimal places -- @function round -- @param n number @@ -32,16 +49,14 @@ local function round (n, p) end -local Math = { - floor = floor, - round = round, - - -- Core Lua function implementations. - _floor = _floor, +local M = { + floor = floor, + monkey_patch = monkey_patch, + round = round, } for k, v in pairs (math) do - Math[k] = Math[k] or v + M[k] = M[k] or v end -return Math +return M diff --git a/lib/std/modules.lua b/lib/std/modules.lua deleted file mode 100644 index d023b1b..0000000 --- a/lib/std/modules.lua +++ /dev/null @@ -1,19 +0,0 @@ --- Set of imported modules. - -return { - -- true => module symbols injected into equivalent core namespace - -- with `require 'std'`: - debug = true, - debug_init = false, - functional = false, - io = true, - list = false, - math = true, - optparse = false, - package = true, - set = false, - strbuf = false, - string = true, - table = true, - tree = false, -} diff --git a/lib/std/object.lua b/lib/std/object.lua index eea9635..34eef40 100644 --- a/lib/std/object.lua +++ b/lib/std/object.lua @@ -65,7 +65,7 @@ local Container = require "std.container" -local metamethod = (require "std.functional").metamethod +local metamethod = (require "std.base").metamethod --- Root object. diff --git a/lib/std/optparse.lua b/lib/std/optparse.lua index 8ebb188..62610b0 100644 --- a/lib/std/optparse.lua +++ b/lib/std/optparse.lua @@ -127,8 +127,8 @@ local function normalise (self, arglist) -- Only split recognised long options. if self[optname] then - table.insert (normal, optname) - table.insert (normal, opt:sub (x + 1)) + normal[#normal + 1] = optname + normal[#normal + 1] = opt:sub (x + 1) else x = nil end @@ -136,7 +136,7 @@ local function normalise (self, arglist) if x == nil then -- No '=', or substring before '=' is not a known option name. - table.insert (normal, opt) + normal[#normal + 1] = opt end elseif opt:sub (1, 1) == "-" and string.len (opt) > 2 then @@ -144,7 +144,7 @@ local function normalise (self, arglist) repeat opt, rest = opt:sub (1, 2), opt:sub (3) - table.insert (split, opt) + split[#split + 1] = opt -- If there's no handler, the option was a typo, or not supposed -- to be an option at all. @@ -162,15 +162,15 @@ local function normalise (self, arglist) -- Split '-xshortargument' into '-x shortargument'. else - table.insert (split, rest) + split[#split + 1] = rest opt = nil end until opt == nil -- Append split options to normalised list - for _, v in ipairs (split) do table.insert (normal, v) end + for _, v in ipairs (split) do normal[#normal + 1] = v end else - table.insert (normal, opt) + normal[#normal + 1] = opt end end @@ -186,11 +186,12 @@ end -- @param value option argument value local function set (self, opt, value) local key = self[opt].key + local opts = self.opts[key] - if type (self.opts[key]) == "table" then - table.insert (self.opts[key], value) - elseif self.opts[key] ~= nil then - self.opts[key] = { self.opts[key], value } + if type (opts) == "table" then + opts[#opts + 1] = value + elseif opts ~= nil then + self.opts[key] = { opts, value } else self.opts[key] = value end @@ -299,7 +300,7 @@ end -- @treturn int index of next element of `arglist` to process local function finished (self, arglist, i) for opt = i + 1, #arglist do - table.insert (self.unrecognised, arglist[opt]) + self.unrecognised[#self.unrecognised + 1] = arglist[opt] end return 1 + #arglist end @@ -494,10 +495,10 @@ local function on (self, opts, handler, value) if opt:match ("^%-[^%-]+") ~= nil then -- '-xyz' => '-x -y -z' for i = 2, string.len (opt) do - table.insert (normal, "-" .. opt:sub (i, i)) + normal[#normal + 1] = "-" .. opt:sub (i, i) end else - table.insert (normal, opt) + normal[#normal + 1] = opt end end) end @@ -559,12 +560,12 @@ local function parse (self, arglist, defaults) local opt = arglist[i] if self[opt] == nil then - table.insert (self.unrecognised, opt) + self.unrecognised[#self.unrecognised + 1] = opt i = i + 1 -- Following non-'-' prefixed argument is an optarg. if i <= #arglist and arglist[i]:match "^[^%-]" then - table.insert (self.unrecognised, arglist[i]) + self.unrecognised[#self.unrecognised + 1] = arglist[i] i = i + 1 end @@ -638,7 +639,7 @@ function OptionParser (spec) -- by a '-'. local specs = {} parser.helptext:gsub ("\n %s*(%-[^\n]+)", - function (spec) table.insert (specs, spec) end) + function (spec) specs[#specs + 1] = spec end) -- Register option handlers according to the help text. for _, spec in ipairs (specs) do @@ -674,7 +675,7 @@ function OptionParser (spec) local _, c = spec:gsub ("^%-([-%w]),?%s+(.*)$", function (opt, rest) if opt == "-" then opt = "--" end - table.insert (options, opt) + options[#options + 1] = opt spec = rest end) @@ -684,7 +685,7 @@ function OptionParser (spec) -- Consume long option. spec:gsub ("^%-%-([%-%w]+),?%s+(.*)$", function (opt, rest) - table.insert (options, opt) + options[#options + 1] = opt spec = rest end) end diff --git a/lib/std/set.lua b/lib/std/set.lua index 94a13a1..e7e6802 100644 --- a/lib/std/set.lua +++ b/lib/std/set.lua @@ -172,22 +172,6 @@ function equal (set1, set2) end ---- @export -local _functions = { - delete = delete, - difference = difference, - elems = elems, - equal = equal, - insert = insert, - intersection = intersection, - member = member, - proper_subset = proper_subset, - subset = subset, - symmetric_difference = symmetric_difference, - union = union, -} - - --- Set prototype object. -- @table std.set -- @string[opt="Set"] _type type of Set, returned by @@ -279,17 +263,27 @@ Set = Container { __totable = function (self) local t = {} for e in elems (self) do - table.insert (t, e) + t[#t + 1] = e end table.sort (t) return t end, - _functions = base.merge (_functions, { - -- backwards compatibility. - new = function (t) return Set (t or {}) end, - }), + --- @export + _functions = { + delete = delete, + difference = difference, + elems = elems, + equal = equal, + insert = insert, + intersection = intersection, + member = member, + proper_subset = proper_subset, + subset = subset, + symmetric_difference = symmetric_difference, + union = union, + }, } return Set diff --git a/lib/std/strbuf.lua b/lib/std/strbuf.lua index a2ee225..114a24c 100644 --- a/lib/std/strbuf.lua +++ b/lib/std/strbuf.lua @@ -11,7 +11,7 @@ local Object = require "std.object" -- @tparam string s string to add -- @treturn std.strbuf modified buffer local function concat (self, s) - table.insert (self, s) + self[#self + 1] = s return self end @@ -53,9 +53,4 @@ return Object { concat = concat, tostring = tostring, }, - - -- backwards compatibility. - _functions = { - new = function () return StrBuf {} end, - }, } diff --git a/lib/std/string.lua b/lib/std/string.lua index 20b8367..7855ea4 100644 --- a/lib/std/string.lua +++ b/lib/std/string.lua @@ -31,11 +31,12 @@ @module std.string ]] -local func = require "std.functional" local List = require "std.list" local StrBuf = require "std.strbuf" local table = require "std.table" +local metamethod = (require "std.base").metamethod + local _format = string.format local _tostring = _G.tostring @@ -132,7 +133,7 @@ local function finds (s, p, init, plain) repeat from, to, r = tfind (s, p, init, plain) if from ~= nil then - table.insert (l, {from, to, capt = r}) + l[#l + 1] = {from, to, capt = r} init = to + 1 end until not from @@ -150,10 +151,10 @@ local function split (s, sep) assert (type (s) == "string", "bad argument #1 to 'split' (string expected, got " .. type (s) .. ")") local b, len, t, patt = 0, #s, {}, "(.-)" .. sep - if sep == "" then patt = "(.)"; table.insert (t, "") end + if sep == "" then patt = "(.)"; t[#t + 1] = "" end while b <= len do local e, n, m = string.find (s, patt, b + 1) - table.insert (t, m or s:sub (b + 1, len)) + t[#t + 1] = m or s:sub (b + 1, len) b = n or len + 1 end return t @@ -228,7 +229,7 @@ local function render (x, open, close, elem, pair, sep, roots) return roots[x] or render (x, open, close, elem, pair, sep, table.clone (roots)) end roots = roots or {} - if type (x) ~= "table" or func.metamethod (x, "__tostring") then + if type (x) ~= "table" or metamethod (x, "__tostring") then return elem (x) else local s = StrBuf {} @@ -237,7 +238,7 @@ local function render (x, open, close, elem, pair, sep, roots) -- create a sorted list of keys local ord = {} - for k, _ in pairs (x) do table.insert (ord, k) end + for k, _ in pairs (x) do ord[#ord + 1] = k end table.sort (ord, function (a, b) return tostring (a) < tostring (b) end) -- render x elements in order @@ -365,6 +366,32 @@ local function prettytostring (t, indent, spacing) end +--- Overwrite core methods and metamethods with `std` enhanced versions. +-- +-- Adds auto-stringification to `..` operator on core strings, and +-- integer indexing of strings with `[]` dereferencing. +-- +-- Also replaces core `assert` and `tostring` functions with +-- `std.string` versions. +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table the module table +local function monkey_patch (namespace) + namespace = namespace or _G + + assert (type (namespace) == "table", + "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") + + namespace.assert, namespace.tostring = assert, tostring + + local string_metatable = getmetatable "" + string_metatable.__append = __append + string_metatable.__concat = __concat + string_metatable.__index = __index + + return M +end + + --- Convert a value to a string. -- The string can be passed to dostring to retrieve the value. -- @todo Make it work for recursive tables. @@ -544,7 +571,7 @@ end --- @export -local String = { +M = { __append = __append, __concat = __concat, __index = __index, @@ -556,6 +583,7 @@ local String = { finds = finds, format = format, ltrim = ltrim, + monkey_patch = monkey_patch, numbertosi = numbertosi, ordinal_suffix = ordinal_suffix, pad = pad, @@ -571,16 +599,6 @@ local String = { wrap = wrap, } --- Merge non-@export functions: -for k,v in pairs (table.merge (String, { - -- camelCase compatibility: - escapePattern = escape_pattern, - escapeShell = escape_shell, - ordinalSuffix = ordinal_suffix, -})) do - M[k] = v -end - for k, v in pairs (string) do M[k] = M[k] or v end diff --git a/lib/std/table.lua b/lib/std/table.lua index 3a6aefb..b2ddd4b 100644 --- a/lib/std/table.lua +++ b/lib/std/table.lua @@ -4,22 +4,72 @@ ]] local base = require "std.base" -local func = require "std.functional" + + +local M -- forward declaration -- No need to pull all of std.list into memory. local elems = base.elems +--- Merge one table's fields into another. +-- @tparam table t destination table +-- @tparam table u table with fields to merge +-- @tparam[opt={}] table map table of `{old_key=new_key, ...}` +-- @tparam boolean nometa if non-nil don't copy metatable +-- @return table `t` with fields from `u` merged in +local function merge_allfields (t, u, map, nometa) + map = map or {} + if type (map) ~= "table" then + map, nometa = {}, map + end + + if not nometa then + setmetatable (t, getmetatable (u)) + end + for k, v in pairs (u) do + t[map[k] or k] = v + end + return t +end + + +--- Merge one table's named fields into another. +-- @tparam table t destination table +-- @tparam table u table with fields to merge +-- @tparam[opt={}] table keys list of keys to copy +-- @tparam boolean nometa if non-nil don't copy metatable +-- @return copy of fields in *selection* from *t*, also sharing *t*'s +-- metatable unless *nometa* +local function merge_namedfields (t, u, keys, nometa) + keys = keys or {} + if type (keys) ~= "table" then + keys, nometa = {}, keys + end + + if not nometa then + setmetatable (t, getmetatable (u)) + end + for k in elems (keys) do + t[k] = u[k] + end + return t +end + + --- Make a shallow copy of a table, including any metatable. -- -- To make deep copies, use @{std.tree.clone}. --- @function clone -- @tparam table t source table -- @tparam[opt={}] table map table of `{old_key=new_key, ...}` -- @tparam boolean nometa if non-nil don't copy metatable -- @return copy of *t*, also sharing *t*'s metatable unless *nometa* -- is true, and with keys renamed according to *map* -local clone = base.clone +local function clone (t, map, nometa) + assert (type (t) == "table", + "bad argument #1 to 'clone' (table expected, got " .. type (t) .. ")") + return merge_allfields ({}, t, map, nometa) +end -- DEPRECATED: Remove in first release following 2015-04-15. @@ -28,7 +78,14 @@ local clone = base.clone -- @tparam table map table `{old_key=new_key, ...}` -- @tparam table t source table -- @return copy of *table* -local clone_rename = base.deprecate (base.clone_rename, nil, +local clone_rename = base.deprecate (function (map, t) + local r = clone (t) + for i, v in pairs (map) do + r[v] = t[i] + r[i] = nil + end + return r + end, nil, "table.clone_rename is deprecated, use the new `map` argument to table.clone instead.") @@ -37,46 +94,13 @@ local clone_rename = base.deprecate (base.clone_rename, nil, -- Like `clone`, but does not copy any fields by default. -- @function clone_select -- @tparam table t source table --- @tparam[opt={}] table selection list of keys to copy +-- @tparam[opt={}] table keys list of keys to copy -- @return copy of fields in *selection* from *t*, also sharing *t*'s -- metatable unless *nometa* -local function clone_select (t, map, nometa) +local function clone_select (t, keys, nometa) assert (type (t) == "table", "bad argument #1 to 'clone_select' (table expected, got " .. type (t) .. ")") - map = map or {} - if type (map) ~= "table" then - map, nometa = {}, map - end - - local r = {} - if not nometa then - setmetatable (r, getmetatable (t)) - end - for i in elems (map) do - r[i] = t[i] - end - return r -end - - ---- Destructively merge another table's fields into *table*. --- @function merge --- @tparam table t destination table --- @tparam table u table with fields to merge --- @return table `t` with fields from `u` merged in -local merge = base.merge - - --- Preserve core table sort function. -local _sort = table.sort - ---- Make table.sort return its result. --- @tparam table t unsorted table --- @tparam function c comparator function --- @return `t` with keys sorted accordind to `c` -local function sort (t, c) - _sort (t, c) - return t + return merge_namedfields ({}, t, keys, nometa) end @@ -88,23 +112,15 @@ local function empty (t) end ---- Turn a tuple into a list. --- @param ... tuple --- @return list -local function pack (...) - return {...} -end - - ---- Find the number of elements in a table. --- @tparam table t any table --- @return number of non-nil values in `t` -local function size (t) - local n = 0 - for _ in pairs (t) do - n = n + 1 +--- Invert a table. +-- @tparam table t a table with `{k=v, ...}` +-- @treturn table inverted table `{v=k, ...}` +local function invert (t) + local i = {} + for k, v in pairs (t) do + i[v] = k end - return n + return i end @@ -114,33 +130,71 @@ end local function keys (t) local l = {} for k, _ in pairs (t) do - table.insert (l, k) + l[#l + 1] = k end return l end ---- Make the list of values of a table. --- @tparam table t any table --- @treturn table list of values -local function values (t) - local l = {} - for _, v in pairs (t) do - table.insert (l, v) - end - return l +--- Destructively merge another table's fields into another. +-- @tparam table t destination table +-- @tparam table u table with fields to merge +-- @tparam[opt={}] table map table of `{old_key=new_key, ...}` +-- @tparam boolean nometa if non-nil don't copy metatable +-- @return table `t` with fields from `u` merged in +local function merge (t, u, map, nometa) + assert (type (t) == "table", + "bad argument #1 to 'merge' (table expected, got " .. type (t) .. ")") + assert (type (u) == "table", + "bad argument #2 to 'merge' (table expected, got " .. type (u) .. ")") + return merge_allfields (t, u, map, nometa) end ---- Invert a table. --- @tparam table t a table with `{k=v, ...}` --- @treturn table inverted table `{v=k, ...}` -local function invert (t) - local i = {} - for k, v in pairs (t) do - i[v] = k - end - return i +--- Destructively merge another table's named fields into *table*. +-- +-- Like `merge`, but does not merge any fields by default. +-- @tparam table t destination table +-- @tparam table u table with fields to merge +-- @tparam[opt={}] table keys list of keys to copy +-- @tparam boolean nometa if non-nil don't copy metatable +-- @return copy of fields in *selection* from *t*, also sharing *t*'s +-- metatable unless *nometa* +local function merge_select (t, u, keys, nometa) + assert (type (t) == "table", + "bad argument #1 to 'merge_select' (table expected, got " .. type (t) .. ")") + assert (type (u) == "table", + "bad argument #2 to 'merge_select' (table expected, got " .. type (u) .. ")") + return merge_namedfields (t, u, keys, nometa) +end + + +--- Return given metamethod, if any, or nil. +-- @function metamethod +-- @param x object to get metamethod of +-- @param n name of metamethod to get +-- @return metamethod function or nil if no metamethod or not a +-- function +local metamethod = base.metamethod + + +--- Make a table with a default value for unset keys. +-- @param x default entry value (default: `nil`) +-- @tparam table t initial table (default: `{}`) +-- @treturn table table whose unset elements are x +local function new (x, t) + return setmetatable (t or {}, + {__index = function (t, i) + return x + end}) +end + + +--- Turn a tuple into a list. +-- @param ... tuple +-- @return list +local function pack (...) + return {...} end @@ -160,11 +214,51 @@ local function ripairs (t) end +--- Find the number of elements in a table. +-- @tparam table t any table +-- @return number of non-nil values in `t` +local function size (t) + local n = 0 + for _ in pairs (t) do + n = n + 1 + end + return n +end + + +-- Preserve core table sort function. +local _sort = table.sort + +--- Make table.sort return its result. +-- @tparam table t unsorted table +-- @tparam function c comparator function +-- @return `t` with keys sorted accordind to `c` +local function sort (t, c) + _sort (t, c) + return t +end + + +--- Overwrite core methods with `std` enhanced versions. +-- +-- Replaces core `table.sort` with `std.table` version. +-- @tparam[opt=_G] table namespace where to install global functions +-- @treturn table the module table +local function monkey_patch (namespace) + namespace = namespace or _G + assert (type (namespace) == "table", + "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") + + namespace.table.sort = sort + return M +end + + --- Turn an object into a table according to __totable metamethod. -- @tparam std.object x object to turn into a table -- @treturn table resulting table or `nil` local function totable (x) - local m = func.metamethod (x, "__totable") + local m = metamethod (x, "__totable") if m then return m (x) elseif type (x) == "table" then @@ -179,26 +273,29 @@ local function totable (x) end ---- Make a table with a default value for unset keys. --- @param x default entry value (default: `nil`) --- @tparam table t initial table (default: `{}`) --- @treturn table table whose unset elements are x -local function new (x, t) - return setmetatable (t or {}, - {__index = function (t, i) - return x - end}) +--- Make the list of values of a table. +-- @tparam table t any table +-- @treturn table list of values +local function values (t) + local l = {} + for _, v in pairs (t) do + l[#l + 1] = v + end + return l end --- @export -local Table = { +M = { clone = clone, clone_select = clone_select, empty = empty, invert = invert, keys = keys, merge = merge, + merge_select = merge_select, + metamethod = metamethod, + monkey_patch = monkey_patch, new = new, pack = pack, ripairs = ripairs, @@ -206,16 +303,13 @@ local Table = { sort = sort, totable = totable, values = values, - - -- Core Lua table.sort function - _sort = _sort, } -- Deprecated and undocumented. -Table.clone_rename = clone_rename +M.clone_rename = clone_rename for k, v in pairs (table) do - Table[k] = Table[k] or v + M[k] = M[k] or v end -return Table +return M diff --git a/lib/std/tree.lua b/lib/std/tree.lua index a809fc7..2776a78 100644 --- a/lib/std/tree.lua +++ b/lib/std/tree.lua @@ -13,7 +13,7 @@ local base = require "std.base" local Container = require "std.container" -local List = require "std.list" +local list = require "std.list" local func = require "std.functional" local prototype = (require "std.object").prototype @@ -27,7 +27,11 @@ local Tree -- forward declaration -- @tparam tree|table tr tree or tree-like table -- @treturn function iterator function -- @treturn tree|table the tree `tr` -local ileaves = base.ileaves +local function ileaves (tr) + assert (type (tr) == "table", + "bad argument #1 to 'ileaves' (table expected, got " .. type (tr) .. ")") + return base.leaves (ipairs, tr) +end --- Tree iterator which returns just leaves. @@ -36,7 +40,11 @@ local ileaves = base.ileaves -- @tparam tree|table tr tree or tree-like table -- @treturn function iterator function -- @treturn tree|table the tree, `tr` -local leaves = base.leaves +local function leaves (tr) + assert (type (tr) == "table", + "bad argument #1 to 'leaves' (table expected, got " .. type (tr) .. ")") + return base.leaves (pairs, tr) +end --- Make a deep copy of a tree, including any metatables. @@ -87,7 +95,7 @@ local function _nodes (it, tr) if type (n) == "table" then coroutine.yield ("branch", p, n) for i, v in it (n) do - table.insert (p, i) + p[#p + 1] = i visit (v) table.remove (p) end @@ -177,17 +185,6 @@ local function merge (t, u) end ---- @export -local _functions = { - clone = clone, - ileaves = ileaves, - inodes = inodes, - leaves = leaves, - merge = merge, - nodes = nodes, -} - - --- Tree prototype object. -- @table std.tree -- @string[opt="Tree"] _type type of Tree, returned by @@ -207,8 +204,8 @@ Tree = Container { -- @todo the following doesn't treat list keys correctly -- e.g. self[{{1, 2}, {3, 4}}], maybe flatten first? __index = function (self, i) - if type (i) == "table" then - return List.foldl (func.op["[]"], self, i) + if prototype (i) == "table" then + return list.foldl (func.op["[]"], self, i) else return rawget (self, i) end @@ -221,7 +218,7 @@ Tree = Container { -- @param i non-table, or list of keys `{i\_1 ... i\_n}` -- @param v value __newindex = function (self, i, v) - if type (i) == "table" then + if prototype (i) == "table" then for n = 1, #i - 1 do if prototype (self[i[n]]) ~= "Tree" then rawset (self, i[n], Tree {}) @@ -234,10 +231,15 @@ Tree = Container { end end, - _functions = base.merge (_functions, { - -- backwards compatibility. - new = function (t) return Tree (t or {}) end, - }), + --- @export + _functions = { + clone = clone, + ileaves = ileaves, + inodes = inodes, + leaves = leaves, + merge = merge, + nodes = nodes, + }, } return Tree diff --git a/local.mk b/local.mk index c3176b8..d0f7fdc 100644 --- a/local.mk +++ b/local.mk @@ -29,7 +29,7 @@ LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" ## Bootstrap. ## ## ---------- ## -old_NEWS_hash = 1c4d1bfae2d511327b83800043bc19c7 +old_NEWS_hash = 606609f9586288cfe6d9df676719570a update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ @@ -69,7 +69,6 @@ dist_luastd_DATA = \ lib/std/io.lua \ lib/std/list.lua \ lib/std/math.lua \ - lib/std/modules.lua \ lib/std/object.lua \ lib/std/optparse.lua \ lib/std/package.lua \ diff --git a/specs/debug_spec.yaml b/specs/debug_spec.yaml index 4fbcf3a..2520d5c 100644 --- a/specs/debug_spec.yaml +++ b/specs/debug_spec.yaml @@ -1,9 +1,8 @@ before: | + base_module = "debug" this_module = "std.debug" - global_table = "_G" - base_module = "debug" extend_base = { "say", "trace" } M = require "std.debug" @@ -14,14 +13,20 @@ specify std.debug: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). to_equal {} + - it does not touch the core debug table: + expect (show_apis {added_to=base_module, by=this_module}). + to_equal {} - it contains apis from the core debug table: expect (show_apis {from=base_module, not_in=this_module}). to_contain.a_permutation_of (extend_base) - context via the std module: - - it adds apis to the core debug table: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by="std"}). + to_equal {} + - it does not touch the core debug table: expect (show_apis {added_to=base_module, by="std"}). - to_contain.a_permutation_of (extend_base) + to_equal {} - describe _DEBUG: diff --git a/specs/functional_spec.yaml b/specs/functional_spec.yaml index e44a957..a3f75dd 100644 --- a/specs/functional_spec.yaml +++ b/specs/functional_spec.yaml @@ -1,9 +1,6 @@ before: | - global_table = "_G" this_module = "std.functional" - std_globals = { "bind", "collect", "compose", "curry", "eval", - "filter", "fold", "id", "map", "memoize", - "metamethod", "op" } + global_table = "_G" M = require (this_module) @@ -15,19 +12,19 @@ specify std.functional: to_equal {} - context via the std module: - - it adds apis to the global table: + - it does not touch the global table: expect (show_apis {added_to=global_table, by="std"}). - to_contain.all_of (std_globals) + to_equal {} - describe bind: - it does not affect normal operation if no arguments are bound: expect (M.bind (math.min, {}) (2, 3, 4)). to_equal (2) - - the extra arguments are taken into account: + - it takes the extra arguments into account: expect (M.bind (math.min, {1, 0}) (2, 3, 4)). to_equal (0) - - the extra arguments can be out of order: + - it supports out of order extra arguments: expect (M.bind (math.pow, {[2] = 3}) (2)). to_equal (8) diff --git a/specs/io_spec.yaml b/specs/io_spec.yaml index 1c26e36..33ab3df 100644 --- a/specs/io_spec.yaml +++ b/specs/io_spec.yaml @@ -1,16 +1,11 @@ before: | + base_module = "io" this_module = "std.io" - global_table = "_G" - std_globals = { "die", "warn" } - base_module = "io" - extend_base = { "catdir", "catfile", "die", "process_files", - "readlines", "shell", "slurp", "splitdir", - "warn", "writelines", - -- camelCase compatibility: - "processFiles" } - extend_metamethods = { "readlines", "writelines" } + extend_base = { "catdir", "catfile", "die", "monkey_patch", + "process_files", "readlines", "shell", "slurp", + "splitdir", "warn", "writelines" } M = require (this_module) @@ -20,25 +15,19 @@ specify std.io: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). to_equal {} + - it does not touch the core io table: + expect (show_apis {added_to=base_module, by=this_module}). + to_equal {} - it contains apis from the core io table: expect (show_apis {from=base_module, not_in=this_module}). to_contain.a_permutation_of (extend_base) - - it replaces no apis from the core io table: - expect (show_apis {from=base_module, enhanced_in=this_module}). - to_equal {} - context via the std module: - - it adds apis to the global table: + - it does not touch the global table: expect (show_apis {added_to=global_table, by="std"}). - to_contain.all_of (std_globals) - - it adds apis to the core io table: + to_equal {} + - it does not touch the core io table: expect (show_apis {added_to=base_module, by="std"}). - to_contain.a_permutation_of (extend_base) - - it adds methods to the file metatable: - expect (show_apis {added_to="getmetatable (io.stdin)", by="std"}). - to_contain.a_permutation_of (extend_metamethods) - - it replaces no apis from the core io table: - expect (show_apis {from=base_module, enhanced_after='require "std"'}). to_equal {} @@ -102,9 +91,28 @@ specify std.io: expect (luaproc (script)).to_fail_with "program:99: By 'eck!\n" +- describe monkey_patch: + - before: + f = M.monkey_patch + mt = {} + t = { + io = { + stdin = setmetatable ({}, mt), + stdout = setmetatable ({}, mt), + stderr = setmetatable ({}, mt), + }, + } + - it installs readlines metamethod: + f (t) + expect (mt.readlines).to_be (M.readlines) + - it installs writelines metamethod: + f (t) + expect (mt.writelines).to_be (M.writelines) + - it diagnoses non-table argument: + expect (f "bad").to_error "table expected" + + - describe process_files: - - it is the same function as legacy processFiles call: - expect (M.process_files).to_be (M.processFiles) - describe readlines: diff --git a/specs/math_spec.yaml b/specs/math_spec.yaml index 8c7895b..8d05107 100644 --- a/specs/math_spec.yaml +++ b/specs/math_spec.yaml @@ -1,15 +1,9 @@ before: | + base_module = "math" this_module = "std.math" - global_table = "_G" - base_module = "math" - extend_base = { "round", "_floor" } - enhance_base = { "floor" } - -- 'to_contain' will match keys as well as values :) - all_apis = {} - for _, s in ipairs (extend_base) do all_apis[s] = true end - for _, s in ipairs (enhance_base) do all_apis[s] = true end + extend_base = { "floor", "monkey_patch", "round" } M = require (this_module) @@ -19,23 +13,36 @@ specify std.math: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). to_equal {} + - it does not touch the core math table: + expect (show_apis {added_to=base_module, by=this_module}). + to_equal {} - it contains apis from the core math table: expect (show_apis {from=base_module, not_in=this_module}). - to_contain.a_permutation_of (all_apis) - - it enhances some apis from the core math table: - expect (show_apis {from=base_module, enhanced_in=this_module}). - to_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (extend_base) - context via the std module: - - it adds apis to the core math table: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by="std"}). + to_equal {} + - it does not touch the core math table: expect (show_apis {added_to=base_module, by="std"}). - to_contain.a_permutation_of (extend_base) - - it replaces some apis from the core math table: - expect (show_apis {from=base_module, enhanced_after='require "std"'}). - to_contain.a_permutation_of (enhance_base) + to_equal {} - describe floor: +- describe monkey_patch: + - before: + f = M.monkey_patch + t = { + math = {}, + } + f (t) + - it installs math.floor function: + expect (t.math.floor).to_be (M.floor) + - it diagnoses non-table argument: + expect (f "bad").to_error "table expected" + + - describe round: diff --git a/specs/object_spec.yaml b/specs/object_spec.yaml index acf06ba..cc12538 100644 --- a/specs/object_spec.yaml +++ b/specs/object_spec.yaml @@ -248,10 +248,10 @@ specify std.object: expect (getmetatable (instance)).to_be (getmetatable (Derived)) - context with custom metamethods: - before: - base = require "std.base" + compare = require "std.list".compare bag = Object { _type = "bag", - __lt = function (a, b) return base.compare (a, b) < 0 end, + __lt = function (a, b) return compare (a, b) < 0 end, } - it has it's own metatable: expect (getmetatable (bag)).not_to_be (root_mt) diff --git a/specs/package_spec.yaml b/specs/package_spec.yaml index f93683e..184cd00 100644 --- a/specs/package_spec.yaml +++ b/specs/package_spec.yaml @@ -1,8 +1,8 @@ before: | + base_module = "package" this_module = "std.package" - global_table = "_G" - base_module = "package" + extend_base = { "dirsep", "execdir", "find", "igmark", "insert", "mappath", "normalize", "pathsep", "path_mark", "remove" } @@ -21,19 +21,19 @@ specify std.package: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). to_equal {} + - it does not touch the core package table: + expect (show_apis {added_to=base_module, by=this_module}). + to_equal {} - it contains apis from the core package table: expect (show_apis {from=base_module, not_in=this_module}). to_contain.a_permutation_of (extend_base) - - it replaces no apis from the core package table: - expect (show_apis {from=base_module, enhanced_in=this_module}). - to_equal {} - context via the std module: - - it adds apis to the core package table: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by="std"}). + to_equal {} + - it does not touch the core package table: expect (show_apis {added_to=base_module, by="std"}). - to_contain.a_permutation_of (extend_base) - - it replaces no apis from the core package table: - expect (show_apis {from=base_module, enhanced_after='require "std"'}). to_equal {} diff --git a/specs/std_spec.yaml b/specs/std_spec.yaml index e4754b4..f6477f5 100644 --- a/specs/std_spec.yaml +++ b/specs/std_spec.yaml @@ -1,12 +1,114 @@ +before: + std = require "std" + specify std: - describe lazy loading: - - before: - std = require "std" - it has no submodules on initial load: - expect (std).to_equal {version = std.version} + expect (std).to_equal { + barrel = std.barrel, + monkey_patch = std.monkey_patch, + version = std.version, + } - it loads submodules on demand: lazy = std.set expect (lazy).to_be (require "std.set") - it loads submodule functions on demand: expect (std.object.prototype (std.set {"Lazy"})). to_be "Set" + +- describe barrel: + - before: + f = std.barrel + io_mt = {} + t = { + io = { + stdin = setmetatable ({}, io_mt), + stdout = setmetatable ({}, io_mt), + stderr = setmetatable ({}, io_mt), + }, + math = {}, + table = {}, + } + f (t) + - it installs std.io monkey patches: + expect (io_mt.readlines).to_be (std.io.readlines) + expect (io_mt.writelines).to_be (std.io.writelines) + - it installs std.math monkey patches: + expect (t.math.floor).to_be (std.math.floor) + - it installs std.string monkey patches: + # FIXME: string metatable monkey-patches leak out! + mt = getmetatable "" + expect (mt.__append).to_be (std.string.__append) + expect (mt.__concat).to_be (std.string.__concat) + expect (mt.__index).to_be (std.string.__index) + expect (t.assert).to_be (std.string.assert) + expect (t.tostring).to_be (std.string.tostring) + - it installs std.table monkey patches: + expect (t.table.sort).to_be (std.table.sort) + - it scribbles into the supplied namespace: + expect (t).should_equal { + assert = std.string.assert, + bind = std.functional.bind, + collect = std.functional.collect, + compose = std.functional.compose, + curry = std.functional.curry, + die = std.io.die, + eval = std.functional.eval, + filter = std.functional.filter, + fold = std.functional.fold, + id = std.functional.id, + ileaves = std.tree.ileaves, + inodes = std.tree.inodes, + io = t.io, + leaves = std.tree.leaves, + map = std.functional.map, + math = t.math, + memoize = std.functional.memoize, + metamethod = std.table.metamethod, + nodes = std.tree.nodes, + op = std.functional.op, + pack = std.table.pack, + pickle = std.string.pickle, + prettytostring = std.string.prettytostring, + render = std.string.render, + require_version = std.string.require_version, + ripairs = std.table.ripairs, + table = t.table, + tostring = std.string.tostring, + totable = std.table.totable, + warn = std.io.warn, + } + - it diagnoses non-table argument: + expect (f "bad").to_error "table expected" + +- describe monkey_patch: + - before: + f = std.monkey_patch + io_mt = {} + t = { + io = { + stdin = setmetatable ({}, io_mt), + stdout = setmetatable ({}, io_mt), + stderr = setmetatable ({}, io_mt), + }, + math = {}, + table = {}, + } + f (t) + - it installs std.io monkey patches: + expect (io_mt.readlines).to_be (std.io.readlines) + expect (io_mt.writelines).to_be (std.io.writelines) + - it installs std.math monkey patches: + expect (t.math.floor).to_be (std.math.floor) + - it installs std.string monkey patches: + # FIXME: string metatable monkey-patches leak out! + mt = getmetatable "" + expect (mt.__append).to_be (std.string.__append) + expect (mt.__concat).to_be (std.string.__concat) + expect (mt.__index).to_be (std.string.__index) + expect (t.assert).to_be (std.string.assert) + expect (t.tostring).to_be (std.string.tostring) + - it installs std.table monkey patches: + expect (t.table.sort).to_be (std.table.sort) + - it diagnoses non-table argument: + expect (f "bad").to_error "table expected" diff --git a/specs/string_spec.yaml b/specs/string_spec.yaml index 942f7e5..205ff4f 100644 --- a/specs/string_spec.yaml +++ b/specs/string_spec.yaml @@ -1,36 +1,20 @@ before: | + base_module = "string" this_module = "std.string" - global_table = "_G" - std_globals = { "pickle", "prettytostring", "render", - "require_version" } - enhance_globals = { "assert", "tostring" } - base_module = "string" extend_base = { "__append", "__concat", "__index", "assert", "caps", "chomp", "escape_pattern", - "escape_shell", "finds", "ltrim", "numbertosi", - "ordinal_suffix", "pad", "pickle", - "prettytostring", "render", "require_version", - "rtrim", "split", "tfind", "tostring", "trim", - "wrap", - -- camelCase compatibility: - "escapePattern", "escapeShell", - "ordinalSuffix" } - enhance_base = { "format" } - extend_metamethods = { "__append", "__concat" } - enhance_metamethods = { "__index" } - - -- 'to_contain' will match keys as well as values :) - all_apis = {} - for _, s in ipairs (std_globals) do all_apis[s] = true end - for _, s in ipairs (enhance_globals) do all_apis[s] = true end - for _, s in ipairs (extend_base) do all_apis[s] = true end - for _, s in ipairs (enhance_base) do all_apis[s] = true end - - M = require "std.string" - getmetatable("").__index = M.__index + "escape_shell", "finds", "format", "ltrim", + "monkey_patch", "numbertosi", "ordinal_suffix", + "pad", "pickle", "prettytostring", "render", + "require_version", "rtrim", "split", "tfind", + "tostring", "trim", "wrap" } + + M = require (this_module) + getmetatable ("").__append = M.__append getmetatable ("").__concat = M.__concat + getmetatable ("").__index = M.__index specify std.string: - before: @@ -41,42 +25,34 @@ specify std.string: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). to_equal {} + - it does not touch the core string table: + expect (show_apis {added_to=base_module, by=this_module}). + to_equal {} - it contains apis from the core string table: expect (show_apis {from=base_module, not_in=this_module}). - to_contain.a_permutation_of (all_apis) - - it enhances some apis from the core string table: - expect (show_apis {from=base_module, enhanced_in=this_module}). - to_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (extend_base) - context via the std module: - - it adds apis to the global table: + - it does not touch the global table: expect (show_apis {added_to=global_table, by="std"}). - to_contain.all_of (std_globals) - - it adds apis to the core string table: + to_equal {} + - it does not touch the core string table: expect (show_apis {added_to=base_module, by="std"}). - to_contain.a_permutation_of (extend_base) - - it adds methods to the string metatable: - expect (show_apis {added_to="getmetatable ('')", by="std"}). - to_contain.a_permutation_of (extend_metamethods) - - it replaces some entries in the string metatable: - expect (show_apis {from="getmetatable ('')", enhanced_after='require "std"'}). - to_contain.a_permutation_of (enhance_metamethods) - - it replaces some apis in the core string table: - expect (show_apis {from=base_module, enhanced_after='require "std"'}). - to_contain.a_permutation_of (enhance_base) - + to_equal {} - describe ..: - it concatenates string arguments: target = "a string \n\n another string" expect (subject .. " another string").to_be (target) - - "it stringifies non-string arguments": + - it stringifies non-string arguments: argument = { "a table" } - expect (subject .. argument).to_match (string.format ("%s%s", subject, M.tostring (argument))) + expect (subject .. argument). + to_be (string.format ("%s%s", subject, M.tostring (argument))) - it stringifies nil arguments: argument = nil - expect (subject .. argument).to_be (string.format ("%s%s", subject, M.tostring (argument))) - - the original subject is not perturbed: + expect (subject .. argument). + to_be (string.format ("%s%s", subject, M.tostring (argument))) + - it does not perturb the original subject: original = subject newstring = subject .. " concatenate something" expect (subject).to_be (original) @@ -95,7 +71,7 @@ specify std.string: expect (f "a stRiNg").to_be "A StRiNg" - it is available as a string metamethod: expect (("a stRiNg"):caps ()).to_be "A StRiNg" - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject) expect (subject).to_be (original) @@ -115,7 +91,7 @@ specify std.string: expect (f (subject)).to_be (subject) - it is available as a string metamethod: expect (subject:chomp ()).to_be (target) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject) expect (subject).to_be (original) @@ -147,9 +123,7 @@ specify std.string: expect (f (subject)).to_be (target) - it is available as a string metamethod: expect (subject:escape_pattern ()).to_be (target) - - legacy escapePattern call is the same function: - expect (M.escapePattern).to_be (f) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject) expect (subject).to_be (original) @@ -174,9 +148,7 @@ specify std.string: expect (f (subject)).to_be (target) - it is available as a string metamethod: expect (subject:escape_shell ()).to_be (target) - - legacy escapeShell call is the same function: - expect (M.escapeShell).to_be (f) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject) expect (subject).to_be (original) @@ -205,7 +177,7 @@ specify std.string: - it starts the search at a specified index into the subject: target = { { 8, 9; capt = { "a", "b" } }, { 10, 11; capt = { "c", "d" } } } expect ({f ("garbage" .. subject, "(.)(.)", 8)}).to_equal ({ target }) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, "...") expect (subject).to_be (original) @@ -223,7 +195,7 @@ specify std.string: expect (f (subject)).to_be (subject) - it is available as a string metamethod: expect (subject:format ()).to_be (subject) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject) expect (subject).to_be (original) @@ -245,7 +217,7 @@ specify std.string: - it is available as a string metamethod: target = "\r\n a short string \t\r\n " expect (subject:ltrim ("[ \t\n]+")).to_equal (target) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, "%W") expect (subject).to_be (original) @@ -254,6 +226,31 @@ specify std.string: expect (f {"a table"}).to_error ("string expected") +- describe monkey_patch: + - before: + f = M.monkey_patch + t = {} + f (t) + - it installs append metamethod: + # FIXME: string metatable monkey-patches leak out! + mt = getmetatable "" + expect (mt.__append).to_be (M.__append) + - it installs concat metamethod: + # FIXME: string metatable monkey-patches leak out! + mt = getmetatable "" + expect (mt.__concat).to_be (M.__concat) + - it installs index metamethod: + # FIXME: string metatable monkey-patches leak out! + mt = getmetatable "" + expect (mt.__index).to_be (M.__index) + - it installs the assert function: + expect (t.assert).to_be (M.assert) + - it installs the tostring function: + expect (t.tostring).to_be (M.tostring) + - it diagnoses non-table argument: + expect (f "bad").to_error "table expected" + + - describe numbertosi: - before: f = M.numbertosi @@ -289,8 +286,6 @@ specify std.string: table.insert (subject, n .. f (n)) end expect (subject).to_equal (target) - - legacy ordinalSuffix call is the same function: - expect (M.ordinalSuffix).to_be (f) - it coerces string arguments to a number: expect (f "-91").to_be "st" - "it diagnoses non-numeric arguments": @@ -331,7 +326,7 @@ specify std.string: target = "a string that's long" expect (subject:pad (width)).to_be (target) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, width) expect (subject).to_be (original) @@ -401,7 +396,7 @@ specify std.string: - it is available as a string metamethod: target = " \t\r\n a short string \t\r" expect (subject:rtrim ("[ \t\n]+")).to_equal (target) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, "%W") expect (subject).to_be (original) @@ -437,7 +432,7 @@ specify std.string: expect (subject:split ", ").to_equal (target) expect (("/foo/bar/baz.quux"):split "/"). to_equal {"", "foo", "bar", "baz.quux"} - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, "e") expect (subject).to_be (original) @@ -468,7 +463,7 @@ specify std.string: - it is available as a string metamethod: target = { 8, 10, { "a", "b", "c" } } expect ({("garbage" .. subject):tfind ("(.)(.)(.)", 8)}).to_equal (target) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, "...") expect (subject).to_be (original) @@ -493,7 +488,7 @@ specify std.string: - it is available as a string metamethod: target = "\r\n a short string \t\r" expect (subject:trim ("[ \t\n]+")).to_equal (target) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, "%W") expect (subject).to_be (original) @@ -542,7 +537,7 @@ specify std.string: expect (f (subject, 64, 2, 4)).to_be (target) - it is available as a string metamethod: expect (subject:wrap (64, 2, 4)).to_be (target) - - the original subject is not perturbed: + - it does not perturb the original subject: original = subject newstring = f (subject, 55, 5) expect (subject).to_be (original) diff --git a/specs/table_spec.yaml b/specs/table_spec.yaml index 3f9073d..e0f72cf 100644 --- a/specs/table_spec.yaml +++ b/specs/table_spec.yaml @@ -3,28 +3,10 @@ before: | this_module = "std.table" global_table = "_G" - std_globals = { "pack", "ripairs", "totable" } - extend_base = { "clone", "clone_select", "clone_rename", "empty", - "invert", "keys", "merge", "new", - "ripairs", "size", "totable", "values", - -- make these available after require "std" - "_sort" } - enhance_base = { "sort" } - - - -- 'to_contain' will match keys as well as values :) - all_apis = {} - for _, s in ipairs (std_globals) do all_apis[s] = true end - for _, s in ipairs (extend_base) do all_apis[s] = true end - for _, s in ipairs (enhance_base) do all_apis[s] = true end - - if table.pack then - -- Lua 5.2 - table.insert (enhance_base, "pack") - else - -- Lua 5.1 - table.insert (extend_base, "pack") - end + extend_base = { "clone", "clone_rename", "clone_select", "empty", + "invert", "keys", "merge", "merge_select", + "metamethod", "monkey_patch", "new", "pack", + "ripairs", "size", "sort", "totable", "values" } M = require "std.table" @@ -34,59 +16,55 @@ specify std.table: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). to_equal {} + - it does not touch the core table table: + expect (show_apis {added_to=base_module, by=this_module}). + to_equal {} - it contains apis from the core table table: expect (show_apis {from=base_module, not_in=this_module}). - to_contain.a_permutation_of (all_apis) - - it enhances some apis from the core table table: - expect (show_apis {from=base_module, enhanced_in=this_module}). - to_contain.a_permutation_of (enhance_base) + to_contain.a_permutation_of (extend_base) - context via the std module: - - it adds apis to the global table: - expect (show_apis {added_to=global_table, by="std"}). - to_contain.all_of (std_globals) - - it adds apis to the core table table: - expect (show_apis {added_to=base_module, by="std"}). - to_contain.a_permutation_of (extend_base) - - it replaces some apis in the core table table: - expect (show_apis {from=base_module, enhanced_after='require "std"'}). - to_contain.a_permutation_of (enhance_base) + - it does not touch the global table: + expect (show_apis {added_to=global_table, by="std"}).to_equal {} + - it does not touch the core table table: + expect (show_apis {added_to=base_module, by="std"}).to_equal {} - describe clone: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + withmt = setmetatable (M.clone (subject), {"meta!"}) f = M.clone - it does not just return the subject: expect (f (subject)).not_to_be (subject) - it does copy the subject: expect (f (subject)).to_equal (subject) - - it only makes a shallow copy: + - it only makes a shallow copy of field values: expect (f (subject).k1).to_be (subject.k1) - - the original subject is not perturbed: + - it does not perturb the original subject: target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } copy = f (subject) expect (subject).to_equal (target) expect (subject).to_be (subject) - - it treats non-table arg2 as nometa parameter: - mt = setmetatable (f (subject, true), {}) - expect (getmetatable (f (mt, true))).to_be (nil) - - it treats table arg2 as a map parameter: - mt = setmetatable (f (subject, true), {}) - expect (getmetatable (f (mt, {}))).to_be (getmetatable (mt)) - - it supports 3 arguments with nometa as arg3: - mt = setmetatable (f (subject, true), {}) - expect (getmetatable (f (mt, {}, "nometa"))).to_be (nil) + + - context with metatables: + - it copies the metatable by default: + expect (getmetatable (f (withmt))).to_be (getmetatable (withmt)) + - it treats non-table arg2 as nometa parameter: + expect (getmetatable (f (withmt, "nometa"))).to_be (nil) + - it treats table arg2 as a map parameter: + expect (getmetatable (f (withmt, {}))).to_be (getmetatable (withmt)) + - it supports 3 arguments with nometa as arg3: + expect (getmetatable (f (withmt, {}, "nometa"))).to_be (nil) - context when renaming some keys: - - before: - target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } - it renames during cloning: + target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } expect (f (subject, {k1 = "newkey"})).to_equal (target) - it does not perturb the value in the renamed key field: expect (f (subject, {k1 = "newkey"}).newkey).to_be (subject.k1) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") @@ -116,7 +94,7 @@ specify std.table: - it does not perturb the value in the renamed key field: expect (f ({k1 = "newkey"}, subject).newkey).to_be (subject.k1) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f {}).to_error ("table expected") expect (f ({}, "foo")).to_error ("table expected") @@ -124,7 +102,9 @@ specify std.table: - describe clone_select: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } + withmt = setmetatable (M.clone (subject), {"meta!"}) f = M.clone_select + - it does not just return the subject: expect (f (subject)).not_to_be (subject) - it copies the keys selected: @@ -133,22 +113,23 @@ specify std.table: expect (f (subject, {"k1", "k2", "k3"})).to_equal (subject) - it only makes a shallow copy: expect (f (subject, {"k1"}).k1).to_be (subject.k1) - - the original subject is not perturbed: + - it does not perturb the original subject: target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } copy = f (subject, {"k1", "k2", "k3"}) expect (subject).to_equal (target) expect (subject).to_be (subject) - - it treats non-table arg2 as nometa parameter: - mt = setmetatable (f (subject, true), {}) - expect (getmetatable (f (mt, true))).to_be (nil) - - it treats table arg2 as a map parameter: - mt = setmetatable (f (subject, true), {}) - expect (getmetatable (f (mt, {}))).to_be (getmetatable (mt)) - - it supports 3 arguments with nometa as arg3: - mt = setmetatable (f (subject, true), {}) - expect (getmetatable (f (mt, {}, "nometa"))).to_be (nil) - - - "it diagnoses non-table arguments": + + - context with metatables: + - it treats non-table arg2 as nometa parameter: + expect (getmetatable (f (withmt, "nometa"))).to_be (nil) + - it treats table arg2 as a map parameter: + expect (getmetatable (f (withmt, {}))).to_be (getmetatable (withmt)) + expect (getmetatable (f (withmt, {"k1"}))).to_be (getmetatable (withmt)) + - it supports 3 arguments with nometa as arg3: + expect (getmetatable (f (withmt, {}, "nometa"))).to_be (nil) + expect (getmetatable (f (withmt, {"k1"}, "nometa"))).to_be (nil) + + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") @@ -159,11 +140,11 @@ specify std.table: - it returns true for an empty table: expect (f {}).to_be (true) expect (f {nil}).to_be (true) - - "it returns false for a non-empty table": + - it returns false for a non-empty table: expect (f {"stuff"}).to_be (false) expect (f {{}}).to_be (false) expect (f {false}).to_be (false) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") @@ -178,10 +159,10 @@ specify std.table: expect (f (subject)).to_equal { "k1", "k2", "k3" } - it is reversible: expect (f (f (subject))).to_equal (subject) - - "it seems to copy a list of 1..n numbers": + - it seems to copy a list of 1..n numbers: subject = { 1, 2, 3 } expect (f (subject)).to_copy (subject) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") @@ -201,7 +182,7 @@ specify std.table: -- returned table will have all 10000 keys in the same order... for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).not_to_equal (subject) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") @@ -209,9 +190,10 @@ specify std.table: - describe merge: - before: | -- Additional merge keys which are moderately unusual - t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } - t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } - f = M.merge + t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } + t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } + t1mt = setmetatable (M.clone (t1), {"meta!"}) + f = M.merge target = {} for k, v in pairs (t1) do target[k] = v end @@ -229,11 +211,98 @@ specify std.table: m = f (t1, t2) -- Merge is destructive, do it once only. expect (m.k3).to_be (t2.k3) expect (m.k3).not_to_be (original.k3) - - "it diagnoses non-table arguments": + - it only makes a shallow copy of field values: + expect (f ({}, t1).k1).to_be (t1.k1) + + - context with metatables: + - it copies the metatable by default: + expect (getmetatable (f ({}, t1mt))).to_be (getmetatable (t1mt)) + expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) + - it treats non-table arg3 as nometa parameter: + expect (getmetatable (f ({}, t1mt, "nometa"))).to_be (nil) + - it treats table arg3 as a map parameter: + expect (getmetatable (f ({}, t1mt, {}))).to_be (getmetatable (t1mt)) + expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) + - it supports 4 arguments with nometa as arg4: + expect (getmetatable (f ({}, t1mt, {}, "nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, {"k1"}, "nometa"))).to_be (nil) + + - context when renaming some keys: + - it renames during merging: + target = { newkey = t1.k1, k2 = t1.k2, k3 = t1.k3 } + expect (f ({}, t1, {k1 = "newkey"})).to_equal (target) + - it does not perturb the value in the renamed key field: + expect (f ({}, t1, {k1 = "newkey"}).newkey).to_be (t1.k1) + + - it diagnoses non-table arguments: + expect (f ()).to_error ("table expected") + expect (f ("foo", "bar")).to_error ("table expected") + + +- describe merge_select: + - before: | + -- Additional merge keys which are moderately unusual + tablekey = {"?"} + t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } + t1mt = setmetatable (M.clone (t1), {"meta!"}) + t2 = { ["if"] = true, [tablekey] = false, _ = "underscore", k3 = t1.k1 } + t2keys = { "if", tablekey, "_", "k3" } + f = M.merge_select + + target = {} + for k, v in pairs (t1) do target[k] = v end + for k, v in pairs (t2) do target[k] = v end + - it does not create a whole new table: + expect (f (t1, t2)).to_be (t1) + - it does not change t1 when t2 is empty: + expect (f (t1, {})).to_be (t1) + - it does not change t1 when key list is empty: + expect (f (t1, t2, {})).to_be (t1) + - it copies the named fields: + expect (f ({}, t2, t2keys)).to_equal (t2) + - it makes a shallow copy: + expect (f ({}, t1, {"k1"}).k1).to_be (t1.k1) + - it copies exactly named fields of t2 when t1 is empty: + expect (f ({}, t1, {"k1", "k2", "k3"})).to_copy (t1) + - it merges keys from t2 into t1: + expect (f (t1, t2, t2keys)).to_equal (target) + - it gives precedence to values from t2: + original = M.clone (t1) + m = f (t1, t2, t2keys) -- Merge is destructive, do it once only. + expect (m.k3).to_be (t2.k3) + expect (m.k3).not_to_be (original.k3) + + - context with metatables: + - it copies the metatable by default: + expect (getmetatable (f ({}, t1mt))).to_be (getmetatable (t1mt)) + expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) + - it treats non-table arg3 as nometa parameter: + expect (getmetatable (f ({}, t1mt, "nometa"))).to_be (nil) + - it treats table arg3 as a map parameter: + expect (getmetatable (f ({}, t1mt, {}))).to_be (getmetatable (t1mt)) + expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) + - it supports 4 arguments with nometa as arg4: + expect (getmetatable (f ({}, t1mt, {}, "nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, {"k1"}, "nometa"))).to_be (nil) + + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f ("foo", "bar")).to_error ("table expected") +- describe monkey_patch: + - before: + f = M.monkey_patch + t = { + table = {}, + } + f (t) + - it installs table.sort function: + expect (t.table.sort).to_be (M.sort) + - it diagnoses non-table argument: + expect (f "bad").to_error "table expected" + + - describe new: - before: f = M.new @@ -267,7 +336,7 @@ specify std.table: default = { "unique object" } t = f (default) expect (t[1]).to_be (default) - - "it diagnoses non-tables/non-nil in the second argument": + - it diagnoses non-tables/non-nil in the second argument: expect (f (nil, "foo")).to_error ("table expected") @@ -286,7 +355,7 @@ specify std.table: expect (f (subject)).to_be (3) - it counts no keys in an empty table: expect (f {}).to_be (0) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") @@ -302,7 +371,7 @@ specify std.table: expect (subject).to_equal (target) - it returns the sorted table: expect (f (subject, cmp)).to_equal (target) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") @@ -324,6 +393,6 @@ specify std.table: -- is this a good test? or just requiring an implementation quirk? for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).to_equal (subject) - - "it diagnoses non-table arguments": + - it diagnoses non-table arguments: expect (f ()).to_error ("table expected") expect (f "foo").to_error ("table expected") diff --git a/specs/tree_spec.yaml b/specs/tree_spec.yaml index 6f02ea1..0d9da21 100644 --- a/specs/tree_spec.yaml +++ b/specs/tree_spec.yaml @@ -1,7 +1,6 @@ before: | global_table = "_G" this_module = "std.tree" - std_globals = { "ileaves", "inodes", "leaves", "nodes" } Tree = require "std.tree" @@ -19,9 +18,9 @@ specify std.tree: to_equal {} - context via the std module: - - it adds apis to the global table: + - it does not touch the global table: expect (show_apis {added_to=global_table, by="std"}). - to_contain.all_of (std_globals) + to_equal {} - describe construction: - it constructs a new tree: @@ -411,6 +410,8 @@ specify std.tree: - it shows the type name: expect (tostring (tr)).to_contain "Tree" - it shows the contents in order: | - pending "see issue #44" + tr = Tree {foo = "foo", + fnord = Tree {branch = Tree {bar="bar", baz="baz"}}, + quux = "quux"} expect (tostring (tr)). - to_contain 'fnord={branch={bar=bar, baz=baz}}, foo=foo, quux=quux' + to_contain 'fnord=Tree {branch=Tree {bar=bar, baz=baz}}, foo=foo, quux=quux' diff --git a/stdlib-39-1.rockspec b/stdlib-40-1.rockspec similarity index 92% rename from stdlib-39-1.rockspec rename to stdlib-40-1.rockspec index 60f7bd8..d0ee09f 100644 --- a/stdlib-39-1.rockspec +++ b/stdlib-40-1.rockspec @@ -1,5 +1,5 @@ package = "stdlib" -version = "39-1" +version = "40-1" description = { detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://lua-stdlib.github.io/lua-stdlib", @@ -7,8 +7,8 @@ description = { summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v39", - url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v39.zip", + dir = "lua-stdlib-release-v40", + url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v40.zip", } dependencies = { "lua >= 5.1", @@ -25,7 +25,6 @@ build = { ["std.io"] = "lib/std/io.lua", ["std.list"] = "lib/std/list.lua", ["std.math"] = "lib/std/math.lua", - ["std.modules"] = "lib/std/modules.lua", ["std.object"] = "lib/std/object.lua", ["std.optparse"] = "lib/std/optparse.lua", ["std.package"] = "lib/std/package.lua", From 06386eb7a07369a02455d3655d4e1b89e29df462 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Sat, 3 Jan 2015 16:26:15 +0000 Subject: [PATCH 26/34] maint: remove git rockspec from release branch. * stdlib-git-1.rockspec: Remove rockspec for master branch. Signed-off-by: Gary V. Vaughan --- stdlib-git-1.rockspec | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 stdlib-git-1.rockspec diff --git a/stdlib-git-1.rockspec b/stdlib-git-1.rockspec deleted file mode 100644 index 161f21f..0000000 --- a/stdlib-git-1.rockspec +++ /dev/null @@ -1,21 +0,0 @@ -package = "stdlib" -version = "git-1" -description = { - detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt.", - homepage = "http://rrthomas.github.io/lua-stdlib", - license = "MIT/X11", - summary = "General Lua Libraries", -} -source = { - url = "git://github.com/rrthomas/lua-stdlib.git", -} -dependencies = { - "lua >= 5.1", -} -external_dependencies = nil -build = { - build_command = "./bootstrap && ./configure LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' --prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' && make clean all", - copy_directories = {}, - install_command = "make install luadir='$(LUADIR)'", - type = "command", -} From 6fc3c75641eeef8719c67959d94fe649d62c08b1 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Sat, 3 Jan 2015 18:39:59 +0000 Subject: [PATCH 27/34] Release v41.0.0. Signed-off-by: Gary V. Vaughan --- .travis.yml | 187 +- AUTHORS | 13 +- COPYING | 2 +- ChangeLog | 3083 ++++++++++++++++- GNUmakefile | 2 +- Makefile.am | 35 +- Makefile.in | 174 +- NEWS | 1502 +++++--- README | 7 +- aclocal.m4 | 2 - bootstrap | 327 +- bootstrap.conf | 35 +- build-aux/config.ld.in | 8 +- build-aux/mkrockspecs | 15 +- build-aux/release.mk | 53 +- build-aux/rockspecs.mk | 2 +- build-aux/sanity-cfg.mk | 2 +- build-aux/specl.mk | 12 +- configure | 292 +- configure.ac | 8 +- doc/classes/std.container.html | 221 +- doc/classes/std.list.html | 1496 +------- doc/classes/std.object.html | 443 ++- doc/classes/std.optparse.html | 407 ++- doc/classes/std.set.html | 497 +-- doc/classes/std.strbuf.html | 199 +- doc/classes/std.tree.html | 318 +- doc/index.html | 32 +- doc/ldoc.css | 15 +- doc/modules/std.debug.html | 438 ++- doc/modules/std.functional.html | 720 +++- doc/modules/std.html | 576 ++- doc/modules/std.io.html | 296 +- doc/modules/std.math.html | 89 +- doc/modules/std.operator.html | 755 ++++ doc/modules/std.package.html | 156 +- doc/modules/std.strict.html | 53 +- doc/modules/std.string.html | 821 +++-- doc/modules/std.table.html | 729 +++- lib/std.lua | 272 +- lib/std.lua.in | 272 +- lib/std/base.lua | 469 ++- lib/std/container.lua | 350 +- lib/std/debug.lua | 745 +++- lib/std/debug_init/init.lua | 42 +- lib/std/functional.lua | 688 +++- lib/std/io.lua | 331 +- lib/std/list.lua | 794 ++--- lib/std/math.lua | 81 +- lib/std/object.lua | 246 +- lib/std/operator.lua | 163 + lib/std/optparse.lua | 355 +- lib/std/package.lua | 243 +- lib/std/set.lua | 407 ++- lib/std/strbuf.lua | 85 +- lib/std/strict.lua | 17 +- lib/std/string.lua | 886 +++-- lib/std/table.lua | 627 ++-- lib/std/tree.lua | 383 +- local.mk | 13 +- m4/ax_compare_version.m4 | 177 - m4/ax_lua.m4 | 87 +- m4/slingshot.m4 | 42 - rockspec.conf | 2 +- specs/base_spec.yaml | 49 - specs/container_spec.yaml | 41 +- specs/debug_spec.yaml | 780 ++++- specs/functional_spec.yaml | 684 +++- specs/io_spec.yaml | 320 +- specs/list_spec.yaml | 1290 +++++-- specs/math_spec.yaml | 71 +- specs/object_spec.yaml | 58 +- specs/operator_spec.yaml | 227 ++ specs/optparse_spec.yaml | 82 +- specs/package_spec.yaml | 111 +- specs/set_spec.yaml | 43 +- specs/{spec_helper.lua.in => spec_helper.lua} | 114 +- specs/specs.mk | 17 +- specs/std_spec.yaml | 559 ++- specs/strbuf_spec.yaml | 12 - specs/string_spec.yaml | 372 +- specs/table_spec.yaml | 515 ++- specs/tree_spec.yaml | 34 +- ...-40-1.rockspec => stdlib-41.0.0-1.rockspec | 9 +- travis.yml.in | 184 +- 85 files changed, 19345 insertions(+), 8026 deletions(-) create mode 100644 doc/modules/std.operator.html create mode 100644 lib/std/operator.lua delete mode 100644 m4/ax_compare_version.m4 delete mode 100644 m4/slingshot.m4 delete mode 100644 specs/base_spec.yaml create mode 100644 specs/operator_spec.yaml rename specs/{spec_helper.lua.in => spec_helper.lua} (57%) rename stdlib-40-1.rockspec => stdlib-41.0.0-1.rockspec (89%) diff --git a/.travis.yml b/.travis.yml index 30c24f3..f514a51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,70 +1,137 @@ -# Lua is not officially supported, but an erlang environment will do. -language: erlang +language: c env: global: - - PACKAGE=stdlib - - ROCKSPEC=$PACKAGE-git-1.rockspec - - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - - LUAROCKS_BASE=luarocks-2.1.2 - - LUAROCKS="$LUA $HOME/bin/luarocks" + - _COMPILE="libtool --mode=compile --tag=CC gcc" + - _CFLAGS="-O2 -Wall -DLUA_COMPAT_ALL -DLUA_USE_LINUX" + - _INSTALL="libtool --mode=install install -p" + - _LINK="libtool --mode=link --tag=CC gcc" + - _LIBS="-lm -Wl,-E -ldl -lreadline" + + - prefix=/usr/local + - bindir=$prefix/bin + - incdir=$prefix/include + - libdir=$prefix/lib matrix: - - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 - - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 LUA_SUFFIX=5.2 - - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 LUA_SUFFIX=5.1 + - LUA=lua5.3 + - LUA=lua5.2 + - LUA=lua5.1 + - LUA=luajit -# Tool setup. -install: + +before_install: # Put back the links for libyaml, which are missing on recent Travis VMs - test -f /usr/lib/libyaml.so || sudo find /usr/lib -name 'libyaml*' -exec ln -s {} /usr/lib \; - - sudo apt-get install help2man - - sudo apt-get install luajit - - sudo apt-get install libluajit-5.1-dev - - sudo apt-get install lua5.1 - - sudo apt-get install liblua5.1-dev - - sudo apt-get install lua5.2 - - sudo apt-get install liblua5.2-dev - # Install a recent luarocks release locally for everything else. - - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - - tar zxvpf $LUAROCKS_BASE.tar.gz - # LuaRocks configure --with-lua argument is just a prefix! - - ( cd $LUAROCKS_BASE; - ./configure - --prefix=$HOME --with-lua=/usr --lua-version=$LUA_SUFFIX - --lua-suffix=$LUA_SUFFIX --with-lua-include=$LUA_INCDIR; - make build; - make install; ) - -# Configure and build. + + # Fetch Lua sources. + - cd $TRAVIS_BUILD_DIR + - 'if test lua5.3 = "$LUA"; then + curl http://www.lua.org/work/lua-5.3.0-rc3.tar.gz | tar xz; + cd lua-5.3.0; + fi' + - 'if test lua5.2 = "$LUA"; then + curl http://www.lua.org/ftp/lua-5.2.3.tar.gz | tar xz; + cd lua-5.2.3; + fi' + - 'if test lua5.1 = "$LUA"; then + curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz; + cd lua-5.1.5; + fi' + + # Unpack, compile and install Lua. + - 'if test luajit = "$LUA"; then + curl http://luajit.org/download/LuaJIT-2.0.3.tar.gz | tar xz; + cd LuaJIT-2.0.3; + make && sudo make install; + for header in lua.h luaconf.h lualib.h lauxlib.h luajit.h lua.hpp; do + if test -f /usr/local/include/luajit-2.0/$header; then + sudo ln -s /usr/local/include/luajit-2.0/$header /usr/local/include/$header; + fi; + done; + else + for src in src/*.c; do + test src/lua.c = "$src" || test src/luac.c = "$src" || eval $_COMPILE $_CFLAGS -c $src; + done; + eval $_LINK -o lib$LUA.la -version-info 0:0:0 -rpath $libdir *.lo; + sudo mkdir -p $libdir; + eval sudo $_INSTALL lib$LUA.la $libdir/lib$LUA.la; + + eval $_COMPILE $_CFLAGS -c src/lua.c; + eval $_LINK -static -o $LUA lua.lo lib$LUA.la $_LIBS; + sudo mkdir -p $bindir; + eval sudo $_INSTALL $LUA $bindir/$LUA; + + sudo mkdir -p $incdir; + for header in lua.h luaconf.h lualib.h lauxlib.h lua.hpp; do + if test -f src/$header; then + eval sudo $_INSTALL src/$header $incdir/$header; + fi; + done; + fi' + + # Fetch LuaRocks. + - cd $TRAVIS_BUILD_DIR + - 'git clone https://github.com/keplerproject/luarocks.git luarocks-2.2.0' + - cd luarocks-2.2.0 + - git checkout v2.2.0 + + # Compile and install luarocks. + - if test luajit = "$LUA"; then + ./configure --lua-suffix=jit; + else + ./configure; + fi + - 'make build && sudo make install' + + # Tidy up file droppings. + - cd $TRAVIS_BUILD_DIR + - rm -rf lua-5.3.0 lua-5.2.3 lua-5.1.5 LuaJIT-2.0.3 luarocks-2.2.0 + + +install: + # Use Lua 5.3 compatible rocks, where available. + - 'for rock in ansicolors ldoc specl""; do + if test -z "$rock"; then break; fi; + if luarocks list | grep "^$rock$" >/dev/null; then continue; fi; + sudo luarocks install --server=http://rocks.moonscript.org/manifests/gvvaughan $rock; + done' + + # Fudge timestamps on release branches. + - 'if test -f configure; then + test -f aclocal.m4 && touch aclocal.m4; + sleep 1; touch Makefile.in; + sleep 1; test -f config.h.in && touch config.h.in; + sleep 1; touch configure; + fi' + + # Build from rockspec. + - export ROCKSPEC=stdlib-41.0.0-1.rockspec + - 'test -f "$ROCKSPEC" || ROCKSPEC=stdlib-git-1.rockspec' + - sudo luarocks make $ROCKSPEC LUA="$LUA" + + # Clean up files created by root + - sudo git clean -dfx + - sudo rm -rf slingshot /tmp/ldoc + + script: - # Initial bootstrap to build luarocks-config.lua, before we've - # installed our rocks. - - ./bootstrap --skip-rock-checks - - ./configure LUA="$LUA" - - make $LUAROCKS_CONFIG - LUA="$LUA" LUA_INCDIR="$LUA_INCDIR" V=1 - || cat $LUAROCKS_CONFIG config.log - - # Set Lua and Shell paths up for local luarocks tree. - # this package depends on will be installed. - - eval `$LUAROCKS path` - - export PATH=`pwd`/luarocks/bin:$PATH - - # Install extra rocks into $LUAROCKS_CONFIG rocks tree. - - $LUAROCKS install lyaml; $LUAROCKS install ldoc; $LUAROCKS install specl; - - # Make git rockspec for this stdlib - - make rockspecs LUAROCKS="$LUAROCKS" V=1 - || { $LUAROCKS path; cat $ROCKSPEC; } - - # The git rockspec will rerun bootstrap, and check any rock versions - # in bootstrap.conf:buildreq this time. - - $LUAROCKS make $ROCKSPEC LUA="$LUA" - - # Run self-tests in the `luarocks make` build tree. - - LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" - LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" - LUA_INIT= LUA_INIT_5_2= - make check V=1 + - test -f configure || ./bootstrap --verbose + - test -f Makefile || ./configure --disable-silent-rules LUA="$LUA" + - make + - make check V=1 + + +# Run sanity checks on CI server, ignoring buggy automakes. +after_success: + - '{ _assign="="; + if grep local-checks-to-skip build-aux/sanity-cfg.mk >/dev/null; then + _assign="+="; + fi; + printf "local-checks-to-skip %s sc_vulnerable_makefile_CVE-2012-3386\n" "$_assign"; + } >> build-aux/sanity-cfg.mk' + - 'make syntax-check || : this will usually fail on the release branch' + +notifications: + slack: aspirinc:JyWeNrIdS0J5nf2Pn2BS1cih diff --git a/AUTHORS b/AUTHORS index 0cbc134..9a36600 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,9 +6,13 @@ be on it, please tell the mailing list (see README for the address). Thanks also to all those who have contributed bug fixes, suggestions and support. +Gary V. Vaughan now maintains stdlib, having rewritten and reorganised +the libraries for hygiene, consistent argument type checking in debug +mode, and object orientation, in addition to adding a lot of new +functionality. -Reuben Thomas started and maintains the standard libraries project, -wrote many of the libraries, and integrated code from other authors. +Reuben Thomas started the standard libraries project, wrote many of the +libraries, and integrated code from other authors. John Belmonte helped set the project up on lua-users, and contributed to the early organisation of the libraries. @@ -21,8 +25,3 @@ private standard library. Johann Hibschman supplied the code on which math.floor and math.round were based. - -Diego Nehab wrote the original version of the mbox parser module. - -Gary V. Vaughan contributed table key support to the tree module, and -the memoize implementation. diff --git a/COPYING b/COPYING index 8aecd8e..ec03e04 100644 --- a/COPYING +++ b/COPYING @@ -4,7 +4,7 @@ the terms of the MIT license (the same license as Lua itself), unless noted otherwise in the body of that file. ==================================================================== -Copyright (C) 2002-2014 stdlib authors +Copyright (C) 2002-2015 stdlib authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/ChangeLog b/ChangeLog index 8b7545c..5c7ebe3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,2782 @@ +2015-01-03 Gary V. Vaughan + + Release version 41.0.0 + * NEWS.md: Record release date. + + maint: don't use math.pow, which some Lua 5.3 builds don't support. + When compiled without -DLUA_COMPAT_5_2, Lua 5.3 removes a good + chunk of the math library, including math.pow. + * lib/std.lua.in (eval): Use math.min in LDocs usage. + * specs/functional_spec.yaml (bind, curry, eval): Instead of + math.pow, use math.min where sensible, otherwise std.operator.pow. + * specs/operator_spec.yaml (pow): Compare with result calculated + using ^ infix operator. + * specs/std_spec.yaml (eval): Use math.min over math.pow. + + std: ireverse only operates on the proper sequence part. + * lib/std/base.lua (ireverse): Ignore any holes in the argument + table, returning only the reversed proper sequence part. + * NEWS.md: Update. + + std: make ripairs respect contiguous integer keys like ipairs. + * lib/std/base.lua (ripairs): Start from lowest contiguous integer + key with a nil value, and iterate backwards to 1. + * NEWS.md: Update. + + std: revert std.ipairs to return all contiguous key pairs 1..n. + Now that Lua 5.3 returned to an ipairs implementation that returns + contiguous key-value pairs from 1..n, where n is the last non-nil + integer key, stdlib can do the same for simpler compliance with + all supported Lua versions. + * lib/std/base.lua (ipairs): Simplify accordingly. + * lib/std.lua.in (ipairs): Update LDocs accordingly. + * NEWS.md: Update. + + maint: commit git rockspec to master branch. + * .gitignore: Allow git rockspecs. + * stdlib-git-1.rockspec: New file. + + configury: add ansicolors to travis_extra_rocks. + * bootstrap.conf (buildreq): Bump Specl requirement to 14.1.0. + (travis_extra_rocks): Add ansicolors for color specl output. + * .travis.yml: Regenerate. + + maint: add 5.3 to compatibility statement. + * README.md: Add 5.3 to compatibility statement. + * specs/std_spec.yaml (std.version): Update accordingly. + + maint: update copyrights. + * COPYING, README.md, bootstrap.conf, configure.ac, local.mk, + specs/optparse_spec.yaml, specs/string_spec.yaml: Add 2015 to + copyright statement. + + rockspec: Lua 5.4 and higher not yet supported. + * rockspec.conf (dependencies): Add lua < 5.4 constraint. + + io: pass io.die message as an error() string. + * lib/std/io.lua (warnfmt): New function factored out of warn(). + Adjust callers. + (die): Pass result of warnfmt to error instead of writing directly + to stderr. + * specs/io_spec.yaml, specs/optparse_spec.yaml: Adjust + specifications accordingly. + * NEWS.md: Update. + + specs: support Lua 5.3 variants of core error messages. + * specs/container_spec.yaml, specs/debug_spec.ymal: Also accept + slightly different error message formats from Lua 5.3 core. + + slingshot: sync with upstream, for Lua 5.3.0 compatibility. + * slingshot: Sync with upstream. + * bootstrap: Update from slingshot. + * NEWS: Move from here... + * NEWS.md: ...to here. Reformat as Markdown and update. + * local.mk (old_NEWS_hash): Update. + * .gitignore: Add NEWS. + * .travis.yml: Regenerate. + +2014-12-29 Gary V. Vaughan + + string: consistent numbertosi output in Lua 5.3. + * lib/std/string.lua (numbertosi): Be careful to output an + integer even when handling a number ('double') in Lua 5.3. + + maint: 5.3 uses load instead of loadstring. + * lib/std/base.lua (loadstring): Set to load if loadstring is not + available. + * lib/std/functional.lua (loadstring): Likewise. + + maint: preliminary Lua 5.3.0 compatibility. + * configure.ac (AX_PROG_LUA): Accept Lua 5.3 interpreters. + * lib/std/io.lua (setmetatable): Define locally to + debug.setmetatable for resetting FILE* metatable in given + namespace. + * lib/std/base.lua, lib/std/debug.lua, lib/std/functional.lua, + lib/std/list.lua, lib/std/package.lua (unpack): Set to either + table.unpack or _G.unpack to satisfy Lua 5.1, 5.2 and 5.3. + * specs/spec_helper.lua (unpack): Set appropriately for all + supported Lua releases. + * NEWS: Update. + +2014-12-24 Gary V. Vaughan + + specs: use correct Specl > 13 arity for bad argument errors. + Now that Specl's badargs module is generating examples with + the correct messages, we can now say 'no more than 0 arguments'. + * lib/std/debug.lua (toomanyargmsg): Return singular 'argument' + in error message only for exactly 1 expected argument, otherwise + plural. + * bootstrap.conf (buildreq): Bump specl requirement. + + refactor: rename operator.deref to operator.get. + * specs/operator_spec.yaml (deref): Rename from this... + (get): ...to this. + * lib/std/operator.lua (deref): Rename from this... + (get): ...to this. + Adjust all callers. + * NEWS: Update. + + functional: generalize reduce to any table. + * specs/functional_spec.yaml (reduce): Specify optional iterator + argument defaulting to std.pairs. + Specify requirement for std.ielems when ignoring reduced table + keys. + * specs/operator_spec.yaml (set): Specify behaviours for a new + table element setting operator. + * specs/container_spec.yaml: Use appropriate iterator functions + for new reduce API. + * lib/std/functional.lua (reduce): Diagnose optional iterator + argument to std.pairs. + (fold): Copy old reduce implementation into deprecated call. + * lib/std.lua.in (barrel): Adjust accordingly. + * lib/std/base.lua (reduce): Default optional iterator argument + to std.pairs. + Pass all iterator results to accumulator function. + Adjust all clients. + * lib/std/operator.lua (set): Implement according to new specs. + * NEWS: Update. + + functional: improve lambda expressiveness. + * specs/functional_spec.yaml: Specify new behaviours with omitted + optional '=', and '_' alias argument. + * lib/std/functional.lua (lambda): Strip more useless whitespace + in parsing to improve memoize cache hits. + Support omitting leading '=' when first non-whitespace of lambda + string is '_'. + Add '_' alias to '_1' for lambda string compiled expressions. + Update LDocs. + + doc: show release version in LDocs column headings. + * build-aux/config.ld.in (project): Add release version. + +2014-12-21 Gary V. Vaughan + + string: don't return spurious additional values. + * lib/std/base.lua (escape_pattern): Wrap gsub return value in + parens to strip all but the first string return value. + * lib/std/string.lua (caps, chomp, escape_shell, ltrim, rtrim) + (trim): Likewise. + + io: add dirname function again. + * specs/io_spec.yaml (dirname): Specify behaviour of a new + function to discard the final path separator in a string and all + that follows. + * lib/std/io.lua (M.dirname): Implement it. + * NEWS: Update. + + vector: remove unneeded module. + On second thoughts, this is not necessary. Adding methods to core + table would give us the API benefits, and posix.curses.chstr is a + much easier way of handling arrays of attributed strings. + * lib/std/vector.lua: Remove. + * build-aux/config.ld.in (file): Remove lib/std/vector.lua. + * local.mk (dist_luastd_DATA): Likewise. + (dist_classes_DATA): Remove doc/classes/std.vector.html. + * specs/vector_spec.yaml: Remove. + * specs/string_spec.yaml (render): Remove vector examples. + * specs/specs.mk (specl_SPECS): Remove specs/vector_spec.yaml. + * NEWS: Remove vector references. + +2014-12-16 Gary V. Vaughan + + configury: adopt semantic versioning. + * configure.ac (AC_INIT): Set version to 41.0.0. + +2014-11-05 Gary V. Vaughan + + maint: fix bitrot in README. + * README.md: Update. + +2014-10-05 Gary V. Vaughan + + specs: simplify bad argument checking with specl.badargs. + * specs/spec_helper.lua (badargs): Expose specl.badargs to the + example execution environment. + (badarg, init): Remove. Superseded by badargs.init. + * specs/debug_spec.yaml, specs/string_spec.yaml: Use badargs.init + instead of init. + * specs/functional_spec.yaml, specs/io_spec.yaml, + specs/list_spec.yaml, specs/math_spec.yaml, + specs/package_spec.yaml, specs/std_spec.yaml, + specs/table_spec.yaml: Use badargs.diagnose to write bad argument + diagnostics examples automatically. + * bootstrap.conf (buildreq): Use moonscript rocks server URLs. + + travis: remove temporary specl-git-1.rockspec dependency. + * .travis.yml (script): Regenerate from travis.yml.n. + +2014-10-01 Gary V. Vaughan + + slingshot: sync with upstream for SPECL_ENV improvements. + * slingshot: Sync with upstream. + * specs/specs.mk: Simplify accordingly. + * specs/spec_helper.lua (package.path): Set according to slingshot + recommendations. + * bootstrap.conf: Require latest specl, and tidy accordingly. + + functional: fill unbound arguments in order with bind. + * lib/std/functional (bind): When filling unbound arguments, be + sure to traverse the remaining arguments *in* order! + + debug: improve argscheck parsing patterns. + * lib/std/debug.lua (argscheck): Strip leading and trailing + whitespace from argument type list. + Allow commas without trailing whitespace. + Allow periods in `fname` pattern. + + travis: reformat .travis.yml. + * .travis.yml: Reformat. + + travis: use specl-git-1.rockspec from specl git master branch. + * .travis.yml (script): Adjust specl-git-1.rockspec URL. + + refactor: rationalize deprecation interfaces. + Tracking one deprecation warning per deprecated function is + fiddly and confusing. Change the semantics to this: by + default calling deprecated API fires a warning message; turn + off the messages with `_DEBUG.deprecate = false`; elide + deprecated APIs entirely with `_DEBUG.deprecate = true`. + Easy and useful :) + * lib/std/debug_init/init.lua (_ARGCHECK): Remove. Adjust all + callers to use _DEBUG.argcheck instead. + (_DEBUG): Always a table, with fields initialised according to + global _DEBUG if necessary. Simplify all callers accordingly. + * lib/std/debug.lua (setcompat, getcompat): Remove. + (DEPRECATIONMSG): If _DEBUG.deprecate is nil, always return a + deprecation message, otherwise the empty string. + (DEPRECATED): If _DEBUG.deprecate is truthy, don't return a + function at all. + (_setdebug): New private function. A reliable way to jigger the + _DEBUG table contents, without worrying about nested specl + environments. + * specs/spec_helper.lua (setdebug): Import std.debug._setdebug + into the outermost execution environment. + * specs/debug_spec.yaml (extend_base): Add _setdebug. + Adjust other behaviour specs to match saner _DEBUG.deprecate + semantics. + * specs/functional_spec.yaml, specs/list_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml: Adjust deprecation + warning behaviour examples to match new semantics. + * NEWS: Update. + +2014-09-04 Gary V. Vaughan + + tree: use argscheck on exported apis. + * lib/std/tree.lua: Move LDocs and add argschecks to returned + Tree object function declarations. + + set: check for strict Set type arguments. + Since we have type checking to help maintain correctness, don't + undermine ourselves and add complexity by adding type coercions + and looser type safety. When we're using Set's, passing a table + instead of a Set is probably an error, so treat it as one! + * specs/set_spec.yaml: Remove specifications for type coercions. + * lib/std/set.lua: Remove type coercions and require strict Set + arguments everywhere. + Add type checks to metamethods. + * NEWS: Update. + + strbuf: use argscheck on exported apis. + * lib/std/strbuf.lua: Move LDocs and add argschecks to returned + StrBuf object declarations. + * HACKING: Update. + + set: use argscheck on exported apis. + * lib/std/set.lua: Move LDocs and add argschecks to returned Set + object declaration. + * HACKING: Add items about best practices for `debug.argscheck`. + +2014-09-03 Gary V. Vaughan + + refactor: simplify primitive std.set functions. + * lib/std/set.lua (insert, delete): Return results of calling + rawset. + + refactor: simplify string.render and clients. + * lib/std/base.lua (render): Use `cb` suffix for callback + parameter names. + Rename j and w locals to k_ and v_, as they represent the values + of k and v resp. from the previous iteration. + Remove unrelated Haskell comments. + * lib/std/string.lua (prettytostring): Likewise. + * lib/std/container.lua (__tostring): Manually unroll render + invocation with base.tostring functions plugged in. + +2014-09-02 Gary V. Vaughan + + refactor: factor away std.container.__pairs. + Object pairs iteration shouldn't rely on slow in-order traversal, + we only care about key order when printing. + * lib/std/container.lua (__pairs): Remove. By the time this is + called, private keys are already moved into the metatable, and + the client would be using ipairs and okeys for ordered traversal. + (__tostring): Use ipairs and okeys here, because we do care about + ordering. + + std: use numeric keys first ordering when stringifying a table. + Closes #81. + * specs/table_spec.yaml (okeys): Specify behaviours of a new + ordered keys function. + * lib/std/container.lua (__pairs): Factor key sorting algorithm + from here... + * lib/std/base.lua (keysort): New function. ...to here. + (okeys): Use keysort to extract a sorted key list from a table. + * lib/std/table.lua (okeys): Re-export from here. + * lib/std/base.lua (render): Simplify accordingly, and always + sort keys nicely as a pleasant side-effect. + * NEWS: Update. + +2014-09-01 Gary V. Vaughan + + doc: Use LDoc @object type for std.vector. + Closes #65. + * lib/std/vector.lua: Improve documentation. + +2014-08-31 Gary V. Vaughan + + doc: use LDoc @object type for std.tree. + * lib/std/tree.lua: Improve documentation. + + doc: use LDoc @object type for std.strbuf. + * lib/std/strbuf.lua: Improve documentation. + + doc: use LDoc @object type for std.list + * lib/std/list.lua: Improve documentation. + + refactor: upgrade OptionParser implementation to a std.object. + * lib/std/optparse.lua (OptionParser): Reimplement as a std.object, + and simplify accordingly. + + doc: use LDoc @object type for std.set. + * lib/std/set.lua: Improve documentation. + + doc: use LDoc @object type for std.container. + * lib/std/container.lua: Improve documentation. + + doc: use LDoc @object type for std.object. + * build-aux/config.ld.in (object): New type for documenting + objects. + * lib/std/object.lua: Improve documentation. + + doc: add prototype chains to object LDocs. + * lib/std/list.lua, lib/std/set.lua, lib/std/strbuf.lua, + lib/std/tree.lua, lib/std/vector.lua: LDocument prototype chains. + + doc: simplify and clarify container and object LDocs. + * lib/std/object.lua, lib/std/container.lua: Simplify and clarify + LDocs. + + doc: fix a broken cross-reference. + * lib/std/container.lua (std.container): Now that we're not + documenting inherited methods, reference std.object.__call from + the prototype object. + * HACKING: Document rationale for slimming LDocs in this way. + + debug: argcheck accepts objects as valid table type arguments. + Closes #84. + Really, table is the base type of object (or strictly speaking, + container), and its almost always desirable to be able to pass + objects to functions that operate on tables. + * specs/debug_spec.yaml (argcheck): Specify this behaviour when + an object argument is given where a table is required. + * lib/std/debug.lua (argcheck): Accept any object argument + where a table parameter is expected. + +2014-08-30 Gary V. Vaughan + + table: deprecate totable. + Closes #74. + * specs/container_spec.yaml (tablification): Remove specs. + * specs/object_spec.yaml (copy): Use this new function instead of + `totable`. + * specs/object_spec.yaml, specs/set_spec.yaml, + specs/strbuf_spec.yaml, specs/tree_spec.yaml (__totable): Remove. + * specs/table_spec.yaml (totable): Deprecate this function. + * specs/spec_helper.lua (totable): Remove. + * lib/std/table.lua (totable): Likewise. + * lib/std/base.lua (totable): Remove implementation. + * lib/std.lua.in (barrel): Remove "table.totable". + * lib/std/container.lua (__totable): Remove. + (__pairs): Return elements in order, omitting private elements. + (__tostring): Use it to concatenate elements in order. + (__call, instantiate, mapfields): Iterate with `next` to fetch + raw elements, rather than ordered object __pairs elements. + * lib/std/object (__totable): Remove reference. + * lib/std/set.lua (__totable): Remove. + (__tostring): Fetch keys for display using std.pairs. + * lib/std/string.lua (pickle): Likewise. + * NEWS: Update. + +2014-08-29 Gary V. Vaughan + + doc: overhaul LDocs for std.table. + * lib/std/table.lua: Tidy up LDocs, and add @usage examples. + +2014-08-28 Gary V. Vaughan + + table: add remove for orthogonality with insert. + * specs/table_spec.yaml (remove): Specify expected behaviour. + * lib/std/table.lua (remove): Implement specified behaviors. + * NEWS: Update. + + refactor: modules can only require std.base and std.debug. + * lib/std/table.lua (totable): Move implementation from here... + * lib/std/base.lua (totable): ...to here. + * lib/std/string.lua: Import core implementation from std.base + instead of argcheck wrapper from std.table. + * lib/std/io.lua (dirsep, catfile): Move implementations from + here... + * lib/std/string.lua (escape_pattern): ...here... + * lib/std/table.lua (invert): ... and here... + * lib/std/base.lua (dirsep, catfile, invert): ...to here. + * lib/std/package.lua: Import core implementations from std.base + instead eof argcheck wrappers from user interface files. + * lib/std/list.lua, lib/std/tree.lua (func): Remove spurious + require. + * lib/std/set.lua, lib/std/tree.lua, lib/std/vector.lua + (container): Fold into Container prototype constructor. + * lib/std/list.lua, lib/std/strbuf.lua (object): Fold into + Object prototype constructor. + * lib/std/string.lua (strbuf): Fold into StrBuf prototype + constructor. + * lib/std/math.lua (debug): Fold into X definition. + * HACKING: Add a description of how to use `require` + idiomatically in stdlib source. + + table: ensure there is always a maxn function. + * specs/table_spec.yaml (maxn): Specify behaviour of maxn. + (len): Add missing specifications. + * specs/std_spec.yaml (barrel): Add maxn to list of monkey_patch + apis from std.table. + * lib/std/base.lua (maxn): Use core table.maxn if available, or + else define our own. + * lib/std/container.lua, lib/std/debug.lua: Use it! + * lib/std/table.lua (maxn): Export it. + * NEWS: Update. + + refactor: make all monkey_patch functions work the same. + * specs/std_spec.yaml, specs/io_spec.yaml, specs/math_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml (monkey_patch): + Specify injection of all exported apis into the given namespace. + * lib/std/base.lua (copy): Support an optional `dest` argument. + (merge): Like copy, but don't overwrite pre-existing entries at + the same key. + * lib/std.lua.in, lib/std/io.lua, lib/std/math.lua, + lib/std/string.lua, lib/std/table.lua: Use merge and copy to + simplify tracking and injecting monkey_patches. + * specs/std_specl.yaml (barrel): Specify behaviour of running all + monkey_patch functions, and recreating the legacy global api by + additionally injecting those functions. + * lib/std.lua.in (barrel): Update to meet tighter specifications. + * HACKING: Note about global hygiene and use of monkey_patch (). + * NEWS: Update. + +2014-08-27 Gary V. Vaughan + + package: tidy up LDocs, and remove unnecessary M references. + * lib/std/package.lua (pathsub, find): Remove spurious `M.` + prefixes. + (mappath_callback): Rename from this... + (mappathcb): ...to this. + * HACKING: Add LDoc style notes. + + functional: remove std.operator expansions from lambda. + There's no good reason to clog up the lambda functable with a copy + of std.operator, when we can just pass the operators without + interposing lambda if we need to. + * lib/std/functional.lua (lambda): Remove std.operator expansions. + * NEWS: Update. + + operator: more RSI-reducing operator function name changes. + * specs/operator_spec.yaml (cons, length): Remove - just pass + `table.pack` or `table.len` instead, resp. + (["and"], ["or"], ["not"]): Rename these... + (conj, disj, neg): ...to these. + * lib/std/operator.lua: Likewise. + Give full and proper LDocs for each function. + * lib/std/functional.lua (M.op): Update deprecation redirections. + * NEWS: Update. + + refactor: reorder function definitions in base.lua. + * lib/std/base.lua: Rather than mostly random order, subject to + interdepencies, put functions in asciibetical order as far as + possible while avoiding forward declarations. + * HACKING: Update. + + table: diagnose insert out of bounds arguments on all Lua. + * specs/table_spec.yaml (insert): Adjust errors to include out of + bounds position. + * lib/std/debug.lua (argerror): Move implementation from here... + * lib/std/base.lua (argerror): ...to here. + (insert): Use it to diagnose out of bounds arguments. + * NEWS: Update. + + table: add missing specs for table.insert, and correct argtypes. + * specs/table_spec.yaml (insert): Specify behaviours. + * lib/std/table.lua (insert): Don't double import. + (M): Don't allow nil valued final argument. + + table: new insert method. + * specs/table_spec.yaml (insert, len): Specify behaviours. + * lib/std/base.lua (insert, last): New functions that + respect `__len` when calculating table length. + (len): Use callable to extract __len metamethod. + * HACKING: New file to document coding style and design choices. + * lib/std/base.lua, lib/std/container.lua, lib/std/debug.lua, + lib/std/io.lua, lib/std/list.lua, lib/std/optparse.lua, + lib/std/strbuf.lua, lib/std/string.lua, lib/std/table.lua, + lib/std/tree.lua, lib/std/vector.lua: Follow HACKING rules for + use of len and insert. + * NEWS: Update. + + refactor: assorted simplifications to std.table. + * lib/std/table.lua (merge_allfields): Use `nil` for unspecified + `map` argument, and when `nil` use a faster inner loop for + copying. + (merge_namedfields): Use `nil` for unspecified `keys` argument. + (clone): Unroll into export table. + (depair, keys): Use ipairs and dummy variable, rather than ielems. + (pack): Remove duplicate definition. + + refactor: remove arglen, duplicates table.maxn functionality. + * specs/debug_spec.yaml (arglen): Remove specifications. + * lib/std/debug.lua (arglen): Remove. + * lib/std/container.lua (M.__call), lib/std/debug.lua (match) + (argcheck): Change all callers to use table.maxn instead. + +2014-08-26 Gary V. Vaughan + + operator: use non-RSI inducing operator function names. + * lib/std/operator.lua ([".."], ["[]"], ["{}"], ["#"], ["+"]) + (["-"], ["*"], ["/"], ["%"], ["^"], ["=="], ["~="], ["<"], ["<="]) + ([">"], [">="]): Rename from these... + (concat, deref, cons, length, sum, diff, prod, quot, mod, pow, eq) + (neq, lt, lte, gt, gte): ...to these. + (['""']): Remove. Just pass the tostring function. + (["~"]): Remove. Just pass string.find. + Adjust all callers. + * NEWS: Update. + + functional: deprecate functional.op properly. + * specs/functional_spec.yaml (op): Specify deprecation warnings + when using old functional.op API. + * lib/std/functional.lua (M.op): Deprecate old APIs. + * NEWS: Update. + + refactor: modernize std/debug.lua. + * lib/std/debug.lua: Reorder declarations and LDocs to match + latest style. + + std: commit missed change to lib/std.lua.in. + * lib/std.lua.in (X): Update export call to argscheck. + + doc: improve LDoc usage examples in std.debug. + * lib/std/debug (DEPRECATIONMSG, DEPRECATED): Improve LDoc usage + examples. + + refactor: merge debug.argscheck and debug.export. + * lib/std/debug.lua (argscheck): Remove. + (export): Rename to argscheck. + Adjust all callers. + + refactor: merge lib/std/base files into std.base. + * lib/std/base/functional.lua (callable, collect, reduce): Move + from here... + * lib/std/base/string.lua (copy, render, split): ...here... + * lib/std/base/tree.lua (leaves): ...and here... + * lib/std/base.lua (callable, collect, reduce, copy, render) + (split, leaves): ...to here. + Adjust all callers. + * lib/std/base/functional.lua, lib/std/base/string.lua, + lib/std/base/tree.lua: Remove files. + * local.mk (luastdbasedir, dist_luastdbase_DATA): Remove. + + refactor: std.vector simplifications. + * lib/std/vector.lua: Fix usage examples to use `avector` instead + of `anvector`. + (set): Factor away use of debug.argscheck. + + refactor: simplify export implementation and api. + * specs/debug_spec.yaml (export): specify behaviours with + explicit arguments instead of introspection. + * lib/std/debug.lua (export): expect explicit declaration string + with argument types, and inner function. + (whatpath, getinfo): Remove unused introspection functions. + * lib/std.lua.in, lib/std/base/string.lua, lib/std/functional.lua, + lib/std/io.lua, lib/std/list.lua, lib/std/math.lua, + lib/std/package.lua, lib/std/string.lua, lib/std/table.lua: + Move LDocs and export declarations to module table constructors. + + refactor: remove obsolete __ipairs specs. + stdlib no longer supports __ipairs metamethods. + * specs/vector_spec.yaml (__ipairs): Remove. + + list: remove workaround for old module metadata layout. + * lib/std/list.lua (transpose): Remove workaround for old module + data layout. + + refactor: simplify functional.memoize. + * lib/std/functional.lua (memoize): Remove spurious require and + associated comment. + +2014-08-25 Gary V. Vaughan + + refactor: use toomanyargmsg function instead of toomanyarg_fmt string. + * lib/std/debug.lua (toomanyarg_fmt): Remove. + (toomanyargmsg): A replacement function that returns the formatted + string. Adjust all callers. + * specs/debug_spec.yaml (extend_base): Adjust accordingly. + + refactor: factor getcompat and setcompat out of debug api. + * specs/debug_spec.yaml (getcompat, setcompat): Remove. + * lib/std/debug.lua (DEPRECATIONMSG): Use getcompat and setcompat + internally, returning an empty string if necessary. + (DEPRECATED): Don't use getcompat or setcompat now that + DEPRECATIONMSG does that. + (M): Remove getcompat and setcompat. + * lib/std/functional.lua (bind): Simplify. + + refactor: move DEPRECATED, export et.al. from `base` to `debug`. + * specs/base_spec.yaml (export, DEPRECATED): Move from here... + * specs/debug_spec.yaml (export, DEPRECATED): ...to here. + * specs/base_spec.yaml: Remove unused file. + * specs/specs.mk (specl_SPECS): Remove specs/base_spec.yaml. + * lib/std/base.lua (DEPRECATED, DEPRECATIONMSG, argcheck) + (argerror, arglen, argscheck, export, getcompat, setcompat) + (toomanyarg_fmt): Move from here... + * lib/std/debug.lua (DEPRECATED, DEPRECATIONMSG, argcheck) + (argerror, arglen, argscheck, export, getcompat, setcompat) + (toomanyarg_fmt): ...to here. Adjust all callers. + * lib/std/base.lua (argpairs, checktype, concat, formaterror) + (getfenv, getinfo, match, merge, normalize, permutations) + (setfenv, whatpath): Move from here... + * lib/std/debug.lua (argpairs, checktype, concat, formaterror) + (getfenv, getinfo, match, merge, normalize, permutations) + (setfenv, whatpath): ...to here, but elide their definitions + if _DEBUG.argcheck is false, or equivalent. + * NEWS: Update. + + refactor: break std.debug dependency on std.functional and std.string. + * specs/debug.spec (say): Specify usage of std.tostring. + * lib/std/debug.lua (tabify): Remove. + (say) Manually unroll functional compose sequence, formerly + knows as tabify. + (trace): Manually unroll and consequently remove string.rep call. + + base: support module name override with std.base.export. + * lib/std/base/list.lua (compare): Move from here... + * lib/std/base.lua (compare): ...to here. + * lib/std/base/list.lua: Remove. + * local.mk (dist_luastdbase_DATA): Remove lib/std/base/list.lua. + * lib/std/list.lua (M.compare): Provide explicit module name + argument. + * lib/std/base.lua (export): If an explicit module name was + passed, use that instead of reverse engineering it from the + source file containing an exported function. + +2014-08-24 Gary V. Vaughan + + base: remove export table metadata. + * lib/std/base.lua: Remove export table metadata. + + refactor: simplify std.require, and improve error diagnostics. + Closes #78. + * specs/std_spec.yaml (require): Specify better diagnostics on + failure. + * lib/std/list.lua (compare): Move from here... + * lib/std/base/list.lua (compare): ...to here. + * local.mk (dist_luastdbase_DATA): Add lib/std/base/list.lua. + * lib/std/base.lua: Break dependency on "std.list". + (require): Use base.list.compare directly, and show verbose + diagnostics on failure. + (module_version, version_to_list): Remove; no longer used. + * NEWS: Update. + + refactor: remove spurious comments from base.lua. + * lib/std/base.lua: Remove spurious comments. + +2014-08-23 Gary V. Vaughan + + maint: fix a typo in std.lua.in. + * lib/std.lua.in (export): Import this symbol correctly. + + refactor: simplify use of export by looking up local functions. + Prior to this changeset, export worked by creating an argument + checking wrapper function when called with an inner function, a + destination table containing metadata and the argument spec + string. The metadata leaked out into the library interface, as + well as other assorted clunkiness. Clean up and simplify the + whole thing. + * specs/spec_helper.lua (badarg): Adjust to produce consolidated + error messages. + * specs/functional_spec.yaml, specs/list_spec.yaml, + specs/std_spec.yaml: Remove element `1` from expected entries in + export table, now that metadata isn't leaked. + * specs/base_spec.yaml (DEPRECATED, export): Remove argument + checking specifications. + * lib/std/base.lua (getinfo): New functions. Use `debug.getinfo` + to lookup a local function in the given scope given only its + name. + (whatpath): Cross reference the package.path and function source + file from `debug.getinfo` to reverse engineer the module path + passed to require that was used to load this function. + (export): Remove all vestiges of hard-coded module metadata from + the destination table, and passing of an inner function; instead + look everything up using introspection and the new functions + above. Don't stash the result in a table parameter, return it. + Adjust all callers. + (copy, render, split): Move from here... + * lib/std/base/string.lua (copy, render, split): New file. ...to + here, so that base.whatpath reports the correct module path. + * local.mk (dist_luastdbase_DATA): Add lib/std/base/string.lua. + * lib/std/container.lua, lib/std/debug.lua, + lib/std/functional.lua, lib/std/io.lua, lib/std/list.lua, + lib/std/math.lua, lib/std/package.lua, lib/std/string.lua, + lib/std/table.lua (M): Remove metadata, rebuild after exported + functions' local declarations. + * NEWS: Update. + +2014-08-21 Gary V. Vaughan + + functional: have callable return the function rather than a bool. + * specs/functional_spec.yaml (callable): Adjust to check that + return values are the actual function. + * lib/std/base/functional.lua (callable): Return the actual + function. + + specs: break dependency on M[1], M[2] in badarg. + That is, polluting the exported module tables with the module + name (M = {"std.base"}) and object name (M = {"std.list", "List"}) + for argument error message text generation is ugly. + * specs/spec_helper.lua (badarg): Require an explicit module + name arg, and use it instead of relying on M[1]. + * specs/base_spec.yaml, specs/debug_spec.yaml, + specs/functional_spec.yaml, specs/io_spec.yaml, + specs/list_spec.yaml, specs/math_spec.yaml, + specs/package_spec.yaml, specs/std_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml: Pass the explicit + module name arg to badarg calls. + * specs/list_spec.yaml: The goal is not to output different + error messages when called with ':' syntax than with '.' syntax. + Move module function argument check specifications into higher + scope; remove object method argument check specifications + entirely. + +2014-08-18 Gary V. Vaughan + + maint: prepare lib/std/list.lua for deprecation-apocalypse! + Almost half of lib/std/list.lua is only there to take care of + warning about deprecated usage. + * lib/std/list.lua: Group all deprecation support code in one + huge block ready for quick and easy annihilation in due course. + + refactor: move list.depair and list.enpair into std.table. + * specs/table_spec.yaml (depair, enpair): Specify full behaviours. + * specs/list_spec.yaml (depair, enpair): Specify deprecation + warnings. + * lib/std/list.lua (depair, enpair): Move from here... + * lib/std/table.lua (depair, enpair): ...to here. + * NEWS: Update. + +2014-08-18 Gary V. Vaughan + + Revert "list: exchange parameter order for list.cons." + This reverts commit 1b290ee40f638b03a4dd4b3c4f5b8faa6cdd2479. + + + Conflicts: + lib/std/list.lua + specs/list_spec.yaml + +2014-08-18 Gary V. Vaughan + + maint: disable specl rock version check by bootstrap. + Specl 13 is not released yet, but we're relying on some fixes + it has. + * bootstrap.conf (buildreq): Disable specl temporarily. + + travis: use unreleased specl rockspec. + * .travis.yml (script): Use specl-git-1.rockspec from github. + + refactor: move `list.project` to `table.project`. + * specs/table_spec.yaml (project): Specify behaviours of project. + * specs/list_spec.yaml (project): Specify deprecation warnings. + * lib/std/list.lua (project): Move from here... + * lib/std/table.lua (project): ...to here. + * NEWS: Update. + + refactor: move `list.shape` to `table.shape`. + * specs/table_spec.yaml (shape): Specify full behaviours. + * specs/list_spec.yaml (shape): Specify deprecation warnings. + * lib/std/list.lua (shape): Move from here... + * lib/std/table.lua (shape): ...to here. + * NEWS: Update. + +2014-08-18 Gary V. Vaughan + + refactor: move list.flatten to table.flatten. + * specs/list_spec.yaml (flatten): Specify deprecation warnings. + * specs/functional_spec.yaml (flatten): Move from here... + * specs/table_spec.yaml (flatten): ...to here. + * lib/std/list.lua (flatten): Move from here... + * lib/std/table.lua (fatten): ...to here. + * lib/std/functional.lua (collect): Move core from here... + * lib/std/base/functional.lua (collect): ...to here. + + * specs/list_spec.yaml (flatten): Deprecated properly. + * lib/std/list.lua (flatten): Wrap object method in deprecation + warning. + +2014-08-18 Gary V. Vaughan + + list: deprecate filter in favour of functional.filter. + * specs/list_spec.yaml (filter): Specify deprecation messages. + * lib/std/list.lua (filter): Deprecated. + * NEWS: Update. + + list: properly deprecate `list.map` to match NEWS. + * specs/list_spec.yaml (map): Deprecated properly. + * lib/std/base/functional.lua (map): Move from here... + * lib/std/functional.lua (map): ...back to here. + * lib/std/list.lua (map): Reinstate deprecated version of this + function locally, for simplicity. + + doc: document list.cons arguments in the correct order. + * lib/std/list.lua (cons): Fix LDoc to display parameters in the + correct order. + + list: export all apis for automatic argument type checking. + * specs/list_spec.yaml: Specify argument checking of all apis. + * lib/std/functional.lua (map): Move core function from here... + * lib/std/base/functional.lua (map): ...to here. + * lib/std/list.lua (project, map, map_with, transpose): Use it. + (m): Collect exported object methods here. + (List.__index): Set to m. + + refactor: simplify deprecation specs. + * lib/std/base.lua (DEPRECATED): Use `name` as the key into the + table for recording whether each deprecation message has been + output yet... it's more likely to be unique than the inner + function address, which might be shared between a module function + and object method. + * specs/functional_spec.yaml, specs/list_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml: Simplify + specifications for deprecation warning. + + specs: fix os.execute thinko. + * specs/spec_helper.lua (LUA): No need to repeat ourselves by + looking for lua in the PATH with which and again at runtime. + + configury: use static specs/spec_helper.lua. + No need to generate this file just to substitute @LUA@, just + use os.getenv "LUA" in a static file instead. + * specs/spec_helper.lua.in: Move from here... + * specs/spec_helper.lua: New file. ...to here. + (LUA): Set from LUA environment, or call `which lua` or just rely + on path search for "lua". + * .gitignore: Remove specs/spec_helper.lua. + * configure.ac (AC_CONFIG_FILES): Remove specs/spec_helper.lua + generator. + * specs/specs.mk (specs_path, spec-check-local): Remove. + (SPECL_ENV): Simplify. + (EXTRA_DIST): Adjust. + * specs/io_spec.yaml (process_files, readlines, slurp) + (writelines): Don't rely on specs/spec_helper.lua being in the + builddir, in case of VPATH builds. + + travis: add .slackid for slack notifications. + * .slackid: New file. + * .travis.yml: Regenerate. + + slingshot: sync with upstream, for slack notifications. + * slingshot: Sync with upstream. + * .travis.yml: Regenerate. + + maint: remove stale files from .gitignore. + * .gitignore: Remove unused /m4/ax_compare_version.m4. + +2014-08-17 Gary V. Vaughan + + refactor: use to_raise matcher alias consistently. + Slingshot sanity checks flag strings with an initial capital + following 'error' as bad style. Rather than switch off that + check, use a matcher alias. + * build-aux/sanity-cfg.mk (sc_error_message_uppercase): Remove + spec-files from regexp. + specs/base_spec.yaml, specs/container_spec.yaml, + specs/debug_spec.yaml, specs/functional_spec.yaml, + specs/io_spec.yaml, specs/list_spec.yaml, specs/math_spec.yaml, + specs/optparse_spec.yaml, specs/package_spec.yaml, + specs/std_spec.yaml, specs/string_spec.yaml, + specs/table_spec.yaml, specs/tree_spec.yaml, + specs/vector_spec.yaml: s/to_error/to_raise/ + s/not_to_raise ()/not_to_raise "any error"/ + + refactor: simplify argument error specifications. + * specs/spec_helper.lua.in (toomanyarg): Remove. + (badarg): Now file local, and treats one or two numeric args as + a `too many arguments` error request. + (init): Prebind badarg module and function names. + * lib/std/base.lua: Add M[1] for error message matching. + * specs/container_spec.yaml (construction): Unroll non-generated + bad argument error messages. + * specs/base_spec.yaml, specs/debug_spec.yaml, + specs/functional_spec.yaml, specs/io_spec.yaml, + specs/list_spec.yaml, specs/math_spec.yaml, + specs/package_spec.yaml, specs/std_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml: Simplify argument + error specifications. + +2014-08-16 Gary V. Vaughan + + base: support zero argument exports. + * specs/base_spec.yaml (export): Remove specification for zero + argument export error. + * lib/std/base.lua (export): Remove zero argument error. + * specs/base_spec.yaml (export): Specify argument checking of + zero argument exports. + * lib/std/base.lua (export): Support zero arguments. + + base: ensure export errors report callsite in stack trace. + * specs/base_spec.yaml (export): Finish and simplify mkstack(). + Specify callsite line numbers in export errors. + * lib/std/base.lua (formaterror): Allow expectedtypes to be a + string. + (export): Use it to generate error messages. + (export): Set levels correctly for correct callsite reporting. + +2014-08-15 Gary V. Vaughan + + refactor: move list.flatten to functional.flatten. + * lib/std/list.lua (flatten): Deprecate. + * lib/std/functional.lua (flatten): Export from here. + * specs/list_spec.yaml, specs/functional_spec.yaml: Adjust. + * NEWS: Update. + + refactor: merge most of std.base.functional back into functional. + * lib/std/base/functional.lua: Remove comment about needing to + wait until deprecated access points are gone before merging. + (foldl, foldr, memoize, nop): Move from here... + * lib/std/functional.lua (foldl, foldr, memoize, nop): ...to here. + * lib/std/list.lua (foldl, foldr): Keep a file local copy of + these functions to satisfy deprecated access points. + + refactor: share leaves implementation from new std.base.tree. + * lib/std/base.lua (leaves): Move from here... + * lib/std/base/tree.lua (leaves): New file. ...to here. + * local.mk (dist_luastdbase_DATA): Add lib/std/base/tree.lua. + * lib/std/io.lua, lib/std/list.lua, lib/std/tree.lua: Adjust. + + refactor: use new functional apis in std.tree. + * lib/std/tree.lua (reduce, operator): Use these... + (fold, op): ...instead of these. + + functional: new zip and zip_with replace list transpose and zip_with. + * specs/functional_spec.yaml (zip, zip_with): Specify behaviour + of new general zip and zip_with apis. + * lib/std/functional.lua (zip, zip_with): New functions. + * lib/std/list.lua (transpose, zip_with): Deprecate. + * specs/list_spec.yaml (transpose, zip_with): Specify deprecation + warning behaviours. + * NEWS: Update. + +2014-08-14 Gary V. Vaughan + + list: deprecate list.map. + * specs/list_spec.yaml (map): Specify output of deprecation + warning on first call. + * specs/debug_spec.yaml (debug, say): Use functional.map for + mkwrap instead of deprecated list.map. + * lib/std/list.lua (map): Deprecate. + * NEWS: Update. + + functional: support default iterators where possible. + * specs/functional_spec.yaml (collect, filter, map): Specify + behaviours when iterator argument is omitted. + * lib/std/functional.lua (collect): Default iterator to ipairs. + (filter, map): Default iterator to pairs. + * NEWS: Update. + + functional: new callable module function. + * specs/functional_spec.yaml (callable): Specify correct behaviour + for new callable function. + * lib/std/functional.lua (iscallable): Move from here... + * lib/std/base/functional.lua (callable): ...to here. Adjust all + callers. + * lib/std/functional.lua (M.callable): Reexport as a public api. + * NEWS: Update. + + functional: improve LDocs for consistency and clarity. + * lib/std/functional.lua: Be consistent with parameter names in + all functions. + Be consistent with usage example formats. + Be consistent with lambda string quoting in examples. + +2014-08-13 Gary V. Vaughan + + functional: replace list.map_with using new functional.map_with. + * specs/functional_spec.yaml (map_with): Specify behaviour of + improved map_with implementation that handles tables. + * lib/std/functional.lua (map_with): Improved implementation of + `list.map_with`. + * lib/std/list.lua (map_with): Deprecate. + * specs/list_spec.yaml (map_with): Adjust accordingly. + * NEWS: Update. + + list: factor out manual argument checking. + * lib/std/list.lua (depair, map_with, project, transpose) + (zip_with): Use new "container of thing" support in export type- + lists to replace manual checks. + (_ARGCHECK): Remove. No longer used. + * specs/list_spec.yaml (depair, map_with, project, transpose) + (zip_with): Adjust error expectations accordingly. + + debug: support "container of homogenous_thing" in argcheck. + * specs/debug_spec.yaml (argcheck): Specify behaviours when + checking for combinations of "List of table" variations. + * lib/std/base.lua (formaterror): Add optional index parameter, + and diagnose errors that use it with new "type at index N" + format; otherwise, simplify "List of table" strings in + expectedtypes to just "List" when the error is in the outer + type matching. + (checktype): Abstracted out of `argcheck`. + (argcheck): Simplify accordingly. + Detect and diagnose element mismatches with "List of table" + expected types. + (export): Likewise. + (typeof): Factored out entirely. + + list: update LDocs. + * lib/std/list.lua: Add @function and @static keywords. + + list: base.export module functions for improved argchecks. + * lib/std/list.lua (_functions): Rename from this... + (M): ...to this. Add a module name entry for export. + * specs/list_spec.yaml (exported_apis): Adjust accordingly. + (append, compare, concat, filter, flatten, map, project, rep) + (sub, tail, transpose, zip_with): Modernize badarg error + specifications. Specify "too many arguments" error behaviours. + * lib/std/list.lua (cons): Store in M; adjust getcompat/setcompat + id. + (map_with, project, transpose, zip_with): Use export for improved + argchecks. + (append, compare, concat, depair, enpair, filter, flatten, map) + (rep, shape, sub, tail): Likewise. Remove manual argcheck calls. + + specs: specify `std.list` apis. + * specs/list_spec.yaml (std.list): Add specs for exported apis, + and global table hygiene. + + string: remove unused local. + * lib/std/string.lua (render): Remove unused local. + + refactor: split out base functions for `std.functional`. + * lib/std/base.lua (foldl, foldr, memoize, nop, reduce): Move + from here... + * lib/std/base/functional.lua (foldl, foldr, memoize, nop) + (reduce): New file. ...to here. + * lib/std/functional.lua, lib/std/list.lua: Adjust imports + accordingly. + * local.mk (luastdbasedir, dist_luastdbase_DATA): Install new + file correctly. + + refactor: move list.foldl and list.foldr to std.functional. + Move the documented location for foldl and foldr from list.lua + to functional.lua, modernizing specs as we go. Keep the old + access points, with a deprecation warning. + * lib/std/list.lua (foldl, foldr): Move from here... + * lib/std/base.lua (foldl, foldr): ...to here. + * lib/std/functional.lua (reduce): Move from here... + * lib/std/base.lua (reduce): ...to here, where foldl and foldr + can use it. + * specs/list_spec.yaml (foldl, foldr): Copy from here... + * specs/functional_spec.yaml (foldl, foldr): ...to here. + * specs/base_spec.yaml (before): Don't depend on the location of + implementation of nop. + * NEWS: Update. + + travis: add slack notifications. + * .travis.yml (notifications): Add slack. + +2014-08-11 Gary V. Vaughan + + refactor: move lambda back to std.functional. + * lib/std.lua.in (lambda): Move from here... + * lib/std/base.lua (lamba): ...and here... + * lib/std/functional.lua (lambda): ...to here. + * specs/functional_spec.yaml, specs/std_spec.yaml: Adjust + accordingly. + * lib/std/base.lua (tostring): Unroll lambda calls. + * lib/std/operator.lua ("#"): Move implementation from here... + * lib/std/base.lua (len): ...to here. Adjust all callers. + (_len): Remove. + (operator): Remove unused require statement + * lib/std/list.lua (transpose): Unroll lambda call. + * NEWS: Update. + + functional: new `cond` function. + * specs/functional_spec.yaml (cond): Specify behaviour of a new + cond function. + * lib/std/functional.lua (cond): Satisfy specified behaviours. + * NEWS: Update. + + functional: process non-function branch values with case. + * specs/functional_spec.yaml (case): Specify behaviours with new + functable and non-callable branch values. + * lib/std/functional.lua (case): Call functables as if they were + regular functions, and return non-callable values directly. + * NEWS: Update. + + specs: add exported api specification to functional_spec.yaml. + * specs/functional_spec.yaml (std.functional): Specify exported + apis. + + refactor: functional.eval issues a deprecation warning. + * specs/functional_spec.yaml (eval): Specify deprecation warning. + * lib/std/functional.lua (eval): Deprecated. + * NEWS: Update. + + refactor: move memoize back to std.functional. + * specs/std_spec.yaml (memoize): Move from here... + * specs/functional_spec.yaml (memoize): ...to here. + * lib/std.lua.in (memoize): Move from here... + * lib/std/functional.lua (memoize): ...to here. + * NEWS: Update. + + refactor: move case back to std.functional. + * specs/std_spec.yaml (case): Move from here... + * specs/functional_spec.yaml (case): ...to here. + * lib/std/base.lua (case): Move implementation from here.. + * lib/std.lua.in (case): ...and argcheck wrapper from here... + * lib/std/functional.lua (case): ...to here. + * lib/std/package.lua (path_sub): Decouple from std.functional by + comparing manually rather than using functional.case. + +2014-08-07 Gary V. Vaughan + + functional: rename fold to reduce. + * specs/functional_spec.yaml (fold): Remove argument checking + specifications. + Add deprecation warning specification. + (reduce): Specify identical behaviour to old fold api. + * lib/std/functional.lua (fold): Rename from this... + (reduce): ...to this. + (fold): Show a deprecation warning on first use. + * specs/container_spec.yaml (construction): Adjust. + * lib/std/list.lua (foldl, foldr): Use functional.reduce instead + of deprecated functional.fold. + * lib/std.lua.in (barrel): Install _G.fold from + `std.functional.reduce`. + * specs/std_spec.yaml (barrel): Adjust. + * NEWS: Update. + + functional: map supports key:value remapping functions. + * specs/functional_spec.yaml (map): Specify behaviour of passing + all iteration return values to mapping function; and remapping + when mapping function returns a key:value pair. + * lib/std/functional.lua (map): Collect all iteration return + values and propagate them to the mapping callback function. + If there are two values returned from the callback, treat them as + a key and value for setting in the results table. + * NEWS: Update. + + functional: fold supports multi-return iterators. + * specs/functional_spec.yaml (fold): Specify behaviour with + iterators that return multiple values. + * lib/std/functional.lua (fold): Collect all values returned by + iterator and operate on the last one of those. + * specs/container_spec.yaml (construction): Fold dereferences + automatically, no need to manually dereference any more. + * NEWS: Update. + + doc: add LDoc Type section for callback function signatures. + * lib/std.lua.in (normalizecb): Document signature of memoize + callback function. + (memoize): Set type of *normalize* argument to new `normalizecb` + signature. + * lib/std/functional.lua (predicate): Document signature for a + predicate function. + (filter): Set type of *p* argument to new `predicate` signature. + * lib/std/io.lua (fileprocessor): Document signature of + process_files callback function. + (process_files): Set type of *fn* to new `fileprocessor` function. + * lib/std/string.lua (opentablecb, closetablecb, elementcb) + (paircb, separatorcb): Document signature for render callback + functions. + (render): Set type of callback functions accordingly. + * lib/std/table.lua (comparator): Document signature of sort + comparison function. + (sort): Set type of *c* argument to new `comparator` signature. + + functional: filter supports multi-parameter predicates. + * specs/functional_spec.yaml (filter): Specify behaviours when + called with an iterator that returns multiple values, and + predicate that accepts multiple parameters. + * lib/std/functional.lua (filter): Collect all results from + iterator function, and propagate them all to the predicate call. + * NEWS: Update. + + functional: collect creates tables from multi-return iterators. + * specs/functional_spec.yaml (collect): Differentiate behaviours + of calling collect with single return versus multiple return + iterators. + * lib/std/functional.lua (collect): Inject new elements into the + collected values table using key:value pairs when the iterator + returns more than one value. + * NEWS: Update. + + maint: bump copyright years. + * README.md: Bump copyright years to include 2014. + + maint: Update AUTHORS file. + * AUTHORS: Update. + + maint: use fully qualified api names in all deprecation messages. + * specs/list_spec.yaml (elems, index_key, index_value, relems) + (reverse, :depair, :map_with, :transpose, :zip_with): Specify + fully qualified api name in deprecation message. + * specs/string_spec.yaml (assert, require_version, tostring): + Likewise. + * specs/table_spec.yaml (clone_rename, metamethod, ripairs): + Likewise. + * lib/std/list.lua (elems, index_key, index_value, relems) + (reverse, :depair, :map_with, :transpose, :zip_with): Add `std.` + prefix to deprecation messages. + * lib/std/string.lua (assert, require_version, tostring): + Likewise. + * lib/table.lua (clone_rename, metamethod, ripairs): Likewise. + + functional: report bind api deprecations correctly. + * specs/functional.yaml (bind): Specify deprecation warning + behaviour when called with the legacy multi-argument parameter + passing. + * lib/std/functional.lua (bind): Use new getcompat/setcompat + internal apis to report deprecation of legacy calling convention. + + base: unwrap functables before calling debug.setenv on Lua 5.1. + * lib/std/base.lua (setfenv): Unwrap functables unconditionally, + before delegating to `debug.setfenv` or Lua 5.2 emulation. + + base: propagate environments through export argcheck wrappers. + * lib/std/base.lua (debug): Rename from this... + (debug_init): ...to this. + (_ARGCHECK, _DEBUG): Adjust accordingly. + (getfenv, setfenv): Compatibility functions for Lua 5.2. + (export): When returning argchecking wrapper function, propagate + the wrapper's function environment to the inner function. + * specs/base_spec.yaml (export): Adjust mkmagic not to rely on + out-of-scope MAGIC table. + +2014-08-05 Gary V. Vaughan + + list: exchange parameter order for list.cons. + Closes #72. + * specs/list_spec.yaml (cons): Modernize specifications. + Specify deprecation warning behaviour when calling cons with + arguments in legacy order. + * lib/std/list.lua (cons): If arguments appear to be in the + wrong order, issue a deprecation warning and rewrite them into + the correct order. + * NEWS: Update. + + refactor: break apart base.DEPRECATED for component reuse. + * lib/std/base.lua (DEPRECATIONMSG, getcompat, setcompat): New + functions, factored out of... + (DEPRECATED): ...here. Simplify accordingly. + + refactor: use std.ipairs and std.pairs everywhere internally. + * lib/std/container.lua, lib/std/functional.lua, lib/std/io.lua, + lib/std/list.lua, lib/std/optparse.lua, lib/std/package.lua, + lib/std/set.lua, lib/std/string.lua, lib/std/table.lua, + lib/std/tree.lua, lib/std/vector.lua: Import and use `base.ipairs` + and `base.pairs` everywhere + * NEWS: Update. + + specs: capture list.map_with deprecation warning. + * specs/list_spec.yaml (map_with): Modernize specifications for + argument checking, split module function and object method + specifications, and capture deprecation warning for list:map_with + on first invocation. + + std: remove __ipairs support in favour of 1..#t iteration. + * specs/std_spec.yaml (ipairs, ireverse, ripairs): Adjust + specifications to verify treatment of __len metamethod, and + ignore __ipairs metamethod. + * lib/base.lua (ipairs): Using __len if available, or # operator + otherwise, iterate over elments 1..#t. + (unwrap__ipairs): Remove. Simplifications above make this + function superfluous. + (ripairs, ireverse): Adjust accordingly. + * lib/std/vector.lua (core_metatable.__ipairs) + (alien_functions.__ipairs): Remove. + * lib/std.lua.in (ipairs, ireverse, ripairs): Update LDocs. + * NEWS: Update. + +2014-08-04 Gary V. Vaughan + + refactor: factor away math.pow. + Upcoming Lua 5.3 deprecates `math.pow` in favour of the `^` + operator. We can easily eliminate stdlib's references to + `math.pow` for future compatibility. + * lib/std/operator.lua ("^"): Use `^` rather than `math.pow`. + * lib/std/functional.lua (bind, fold): Use "^" lambda function + instead of `math.pow` in LDocs. + +2014-08-02 Gary V. Vaughan + + refactor: simplify deprecation management. + Closes #73. + * specs/base_spec.yaml (DEPRECATED): Specify behaviours of an + improved internal deprecation API. + * specs/list_spec.yaml (elems, index_key, index_value, relems) + (reverse): Specify default deprecation behaviours. + * specs/string_spec.yaml (assert, require_version, tostring): + Likewise. + * specs/table_spec.yaml (clone_rename, metamethod, ripairs): + Likewise. + * lib/std/debug.lua (_DEBUG): Document new compat field. + * lib/std/base.lua (_DEBUG): Set from debug_init.lua. + (deprecate): Rename from this... + (DEPRECATED): ...to this, and improve API. + * lib/std/functional.lua (bind): Use it to mark the old bind + API as deprecated since release 39. + * lib/std/list.lua (elems, index_key, index_value, relems) + (reverse): Collect in a new section and deprecate with the + improved API. + * lib/std/string.lua (assert, require_version, tostring): + Likewise. + * lib/std/table.lua (clone_rename, metamethod, ripairs): + Likewise. + * build-aux/sanity-cfg.mk (exclude_file_name_regexp): Don't choke + on error specs in specs/list_spec.yaml + * NEWS (Deprecations): Collect deprecated API NEWS for this + release. + + string: reference totable correctly in string.pickle. + Closes #79. + * lib/std/string.lua (totable): Set to table.totable. + Reported by Simon Cozens. + + list: specify shape method behaviours. + * specs/list_spec.yaml (shape): Specify method behaviours. + + list: specify list.zip_with, and fix revealed bugs. + * specs/list_spec.yaml (zip_with): Specify behaviour of zip_with + method. + * lib/std/list.lua (zip_with): Call list.map with correctly + * ordered arguments. + * NEWS: Update. + + list: specify list.transpose, and fix revealed bugs. + * specs/list_spec.yaml (transpose): Specify behaviour of transpose + method. + * lib/std/list.lua (transpose): Handle empty list argument. + Call list.map with correctly ordered arguments. + * NEWS: Update. + + maint: reinstate specl package.path workaround for luarocks bug. + Now that we're supporting LuaRocks' `init.lua suffixed filenames + get installed to an init installation directory` bug again, we + must adjust Specl's in-tree package.path to accommodate. + * specs/spec_helper.lua.in (package.path): Add "lib/?/init.lua". + * local.mk (std_path): Likewise + + specs: don't rely on `_G.arg[-1]:match "/lua[0-9.]*$"` + When `specs/optparse_spec.yaml` came over from Specl, I forgot to + upgrade the direct `hell.spawn` invocations to nicely abstracted + `spec_helper.lua:luaproc` calls. + * specs/optparse_spec.yaml (parser): Replace hell.spawn calls + with luaproc calls, so that Lua interpreter is set correctly. + +2014-07-31 Gary V. Vaughan + + slingshot: sync with upstream for upload and moonscript support. + * slingshot: Sync with upstream. + * bootstrap.conf (slingshot_files): Delete removed + ax_compare_version.m4. + * README.md (Installation): Show moonscript rocks repo. + * .travis.yml: Regenerate. + +2014-07-29 Gary V. Vaughan + + std: `std.require` now matches last dot-delimited version number. + * specs/std_spec.yaml (require): Specify behaviours when a version + string contains more than one substring with dot-delimited digits. + * lib/std/base.lua (module_version): Anchor the version matching + pattern at the end of the string. + * lib/std.lua.in (require): Improve LDocs accordingly. + * NEWS: Update. + + maint: reinstate LuaRocks init install bug workaround. + Latest LuaRocks still has the bug where Lua source files ending + in `init.lua` are installed to a subdirectory. Put back the + workaround I removed prematurely. + * lib/std/debug_init.lua: Move from here... + * lib/std/debug_init/init.lua: ...to here. + * local.mk (dist_luastd_DATA): Remove lib/std/debug_init.lua. + (dist_luastddebug_DATA): Add lib/std/debug_init/init.lua. + +2014-07-25 Gary V. Vaughan + + spec: modernize and normalize std specs. + * specs/std_spec.yaml: Reduce redundancy, and update to modern + style with fully argchecked apis. + * lib/std.lua.in (barrel): Scribble deprecated functions into + global namespace. + + doc: improve LDocs for std.lua. + * lib/std.lua.in: Tidy up and normalize LDocs. + + refactor: move `table.metamethod` to `std.getmetamethod`. + Be more in keeping with the style of core Lua. + * lib/std/table.lua (metamethod): Deprecate. + * lib/std.lua.in (getmetamethod): Export from here instead. + * specs/table_spec.yaml, specs/std_spec.yaml: Adjust accordingly. + * NEWS: Update. + + refactor: move `std.string.tostring` to `std.tostring`. + * lib/std/string.lua (render, tostring): Move from here... + * lib/std/base.lua (render, tostring): ...to here, with argchecks + removed. + * lib/std/string.lua (render): Re-export base.render from here. + (tostring): Re-export base.tostring with a deprecation notice. + * lib/std.lua.in (tostring): Re-export base.tostring from here. + (memoize): Simplify accordingly. + * specs/debug_spec.yaml, specs/string_spec.yaml, + specs/std_spec.yaml: Adjust accordingly. + * NEWS: Update. + + refactor: relocate std.lua contents to std.base and std. + * specs/lua_spec.yaml: Remove. All specs moved from here... + * specs/std_spec.yaml: ...to here. + * specs/specs.mk (specl_SPECS): Remove specs/lua_spec.yaml. + * lib/std/operator.lua (getmetamethod): Remove to break a + require loop. + * lib/std/lua.lua (assert, case, elems, eval, ielems, ipairs) + (ireverse, lambda, memoize, pairs, require, ripairs): Move from + here... + * lib/std/base.lua (assert, case, elems, eval, ielems, ipairs) + (ireverse, lambda, memoize, pairs, require, ripairs): ...to here, + removing argchecks... + * lib/std.lua.in (assert, case, elems, eval, ielems, ipairs) + (ireverse, lambda, memoize, pairs, require, ripairs): ...and + re-export from here with argcheck wrappers. + (barrel, monkey_patch): Adjust accordingly. + * lib/std/functional.lua (filter, fold, map): Adjust LDocs. + (case, eval, memoize): Re-export with argcheck wrappers. + * lib/std/string.lua (assert, require_version): Deprecate. + * build-aux/config.ld.in (file): Remove lib/std/lua.lua. + * local.mk (dist_luastd_DATA): Remove lib/std/lua.lua. + * specs/functional_spec.yaml (fold): Adjust require imports. + * NEWS: Update. + +2014-07-24 Gary V. Vaughan + + refactor: move `table.ripairs` to `lua.ripairs`. + * specs/table_spec.yaml (ripairs): Specify deprecation warning + on first use. + * specs/lua_spec.yaml (ripairs): Specify all behaviours for + ripairs. + * lib/std/base.lua (ripairs): Shared core functionality for + ripairs, respecting `__ipairs` metamethod even on Lua 5.1. + * lib/std/table.lua (ripairs): Use it, with a deprecation + warning on first use. + * lib/std/lua.lua (ripairs): Re-export it from here with full + argchecks. + * NEWS: Update. + +2014-07-23 Gary V. Vaughan + + refactor: replace `list.reverse` with `lua.ireverse`. + * specs/lua_spec.yaml (ireverse): Specify behaviour of new + ireverse function. + * specs/list_spec.yaml (relems, reverse): Specify new deprecated + behaviours of these functions. + * lib/std/list.lua (relems, reverse): Deprecated. + * lib/std/base.lua (ireverse): New `__ipairs` aware generator of + new reversed array-part of any table. + * lib/std/lua.lua (ireverse): Export `base.ireverse`. + (monkey_patch): Inject ireverse into given namespace. + * specs/std_spec.yaml (monkey_patch): Adjust accordingly. + * NEWS: Updated. + +2014-07-21 Gary V. Vaughan + + operator: break a require loop. + * lib/std/base.lua: Remove unused `require "std.operator"` to + break a require loop. + + operator: make '#' operator Lua 5.1 compatible. + * specs/operator_spec.yaml (#): Specify behaviour of # operator. + * lib/std/operator.lua (#): If there's a `__len` metamethod, call + it manually before falling back to actual `#` operator. + +2014-07-18 Gary V. Vaughan + + doc: improve render LDocs @usage examples. + * lib/std/string.lua (render, render_separator): Improve LDocs + @usage examples. + + doc: add missing @function to prettytostring LDocs. + * lib/std/string.lua (prettytostring): Add missing @function. + + refactor: move assert and require from std.string to std.lua. + * specs/string_spec.yaml (assert, require): Move from here... + * specs/lua_spec.yaml (assert, require): ...to here. + * lib/std/string.lua (assert, module_version, require, + version_to_list): Move from here... + * lib/std/lua.lua (assert, module_version, require, + version_to_list): ...to here. + * lib/std/string.lua (assert): Propagate invocations to std.lua, + with a deprecation warning. + * NEWS: Update. + + refactor: decouple std.lua from other modules. + * lib/std/lua.lua (wrapiterator): Move from here... + * lib/std/base.lua (wrapiterator): ...to here. + (ielems): Non-argchecked implementation. + * lib/std/lua.lua (ielems): Use it. + * lib/std/debug.lua, lib/std/list.lua, lib/std/set.lua, + lib/std/tree.lua: Use base.ielems internally. + * lib/std/functional.lua (case, eval, lambda, memoize): Load + std.lua on demand when these functions are called rather than + depending on it at require time. + * lib/std/table.lua: Remove unused std.lua requirement. + + lua: add a monkey_patch function. + * specs/lua_spec.yaml (monkey_patch): Specify behaviour of lua + monkey_patch function. + * lib/std/lua.lua (monkey_patch): Install lua functions into the + given namespace. + * lib/std/std.lua.in (monkey_patch): Add lua.monkey_patch + invocation. + (barrel): Remove double injection of `std.lua` functions. + * specs/std_spec.yaml (barrel): Add new 'std.lua' functions. + +2014-07-17 Gary V. Vaughan + + Merge branch 'waffle-iron-master' + +2014-07-17 Making GitHub Delicious. + + add waffle.io badge + +2014-07-17 Gary V. Vaughan + + lua: support __ipairs and __pairs metamethods on Lua 5.1. + * specs/lua_spec.yaml (ipairs, pairs): Specify portable behaviour + for new functions. + * lib/std/lua.lua (ipairs, pairs): New functions that support + __ipairs and __pairs metamethods, even on Lua 5.1. + (ielems, elems): Improve LDocs and argchecks. + * specs/lua_spec.yaml (elems, ielems): Adjust error message specs. + * NEWS: Update. + + debug: argcheck accepts a List object for a list parameter. + * specs/debug_spec.yaml (argcheck): Remove specifications for + mismatch errors between list parameters and List arguments. + * lib/std/base.lua (argcheck): Accept an empty List object for a + + refactor: simplify list.flatten implementation. + * lib/std/list.lua (flatten): Simplify. + + container: don't rewrap existing modulefunction functables. + * lib/std/container.lua (modulefunction): When re-exporting + module functions from another module, don't wrap inside another + functable. + +2014-07-16 Gary V. Vaughan + + list: deprecate list.elems module function. + * lib/std/list.lua (elems): Deprecate. + * specs/list_spec.yaml (elems): Specify deprecation warning + behaviour. + + refactor: consolidate and speed-up ielems and elems functions. + * specs/table_spec.yaml (elems, ielems): Move from here... + * specs/lua_spec.yaml (elems, ielems): ...to here. + * specs/functional_spec.yaml (fold): Adjust ielems import. + * lib/std/base.lua (ielems): Remove. + * lib/std/table.lua (elems, ielems): Remove. + * lib/std/lua.lua (elems, ielems): Wrap ipairs and pairs, taking + care to honor __ipairs and __pairs metamethods, for a noticeable + speedup. + * lib/std/debug.lua, lib/std/list.lua, lib/std/tree.lua: Adjust + ielems imports and examples. + * build-aux/sanity-cfg.mk (sc_error_message_uppercase): Add + specs/lua_spec.yaml. + * NEWS: Update. + +2014-07-14 Gary V. Vaughan + + refactor: move language features to a new `std.lua` module. + * specs/functional_spec.yaml (case, eval, lambda, memoize): Move + from here... + * specs/lua_spec.yaml: New file. ...to here. + * specs/std_spec.yaml: Adjust accordingly. + * specs/specs.mk (specl_SPECS): Add specs/lua_spec.yaml. + * build-aux/config.ld.in (file): Add lib/std/lua.lua. + * lib/std/base.lua (lambda): Move from here... + * lib/std/lua.lua (lambda): New file. ...to here. + * local.mk (dist_luastd_DATA): Add lib/std/lua.lua. + * lib/std/functional.lua (case, eval, lambda, memoize): Move from + here... + * lib/std/lua.lua (case, eval, lambda, memoize): ...to here. + * lib/std/string.lua (pickle): Adjust LDocs eval cross reference. + * NEWS: Update. + +2014-07-11 Gary V. Vaughan + + maint: revert automatic lambda string compilation. + * lib/std/base.lua (lambda): Core Lua APIs require actual + functions, so to be useful for passing lambda strings to core + APIs and stdlib APIs alike, return a raw function rather than a + functable. + (argcheck): Don't accept a compilable lambda string where a + function argument is expected. + * lib/std/debug.lua (lambda, argcheck): Adjust LDocs. + * lib/std/functional.lua: Likewise. + (bind, case, collect, compose, curry, filter, fold, map) + (memoize): Remove lambda argument compilation. + * lib/std/io.lua (process_files): Likewise. + * lib/std/list.lua (filter, foldl, foldr, map, map_with) + (zip_with): Likewise. + * lib/std/package.lua (mappath): Likewise. + * lib/std/string.lua (render): Likewise. + * lib/std/table.lua (sort): Likewise. + * specs/debug_spec.yaml, specs/functional_spec.yaml, + specs/io_spec.yaml, specs/list_spec.yaml, + specs/package_spec.yaml, specs/string_spec.yaml, + specs/table_spec.yaml: Adjust lambda specs. + * NEWS: Update. + + specs: don't load std.object for std.list spec examples. + * specs/spec_helper.lua.in (prototype): Copied from + lib/std/base.lua. + * specs/list_spec.yaml: Don't load 'std.object', use prototype + from spec_helper. + + base: provide better errors from exported object methods. + * specs/base_spec.yaml (export): Specify behaviour of exported + object methods. + * lib/std/base.lua (export): Use separator ':' between module name + and method name when dealing with methods, as opposed to '.' when + dealing with functions. + Count method arguments starting at '0' for self in error messages. + * build-aux/sanity-cfg.mk (sc_error_message_uppercase): Add + specs/base_spec.yaml. + +2014-07-10 Gary V. Vaughan + + doc: object and container _functions fields are optional. + * lib/std/container.lua (Container): _functions field is optional. + * lib/std/object.lua (Object): Likewise. + + doc: clarify use of compiled lambda strings. + * lib/std/functional.lua (Lambda): Add LDocs cross-references, + and a usage example with call field. + (lambda): Fix usage example not to show calling core Lua + table.sort with a functable! + + refactor: simplify std.base.lambda. + * lib/std/base.lua (lambda): Use `unpack` unconditionally. + Save lambda string in Lambda object. + + doc: add LDocs for functional.lambda return functables. + * lib/std/functional.lua (Lambda): Add LDocs. + (lambda): Document return type correctly. + + doc: improve debug module LDocs. + * lib/std/debug.lua (_DEBUG): Document default field values. + (argerror): Document interaction between function and lambda + strings. + + doc: improve functional module LDocs. + * lib/std/functional.lua: Improve module header LDocs. + + functional: make nop an official functional method. + * specs/functional_spec.yaml (nop): Specify behaviour of new nop + module method. + * specs/spec_helper.lua.in (nop): Remove one-off nop declaration. + * specs/string_spec.yaml (finds): Specify in-situ nop. + * specs/base_spec.yaml (std.base): Likewise. + * lib/std/base.lua (nop): Declare an official nop function. + * lib/std/functional.lua (nop): Re-export std.base.nop. + * NEWS: Update. + +2014-07-09 Gary V. Vaughan + + maint: clean up NEWS. + * NEWS: Update bitrotted recent entries to match reality. + + std: accept lamda strings as an alternative to functions. + * specs/functional_spec.yaml, specs/io_spec.yaml, + specs/list_spec.yaml, specs/package_spec.yaml, + specs/string_spec.yaml, specs/table_spec.yaml: Specify behaviours + of API calls that accept functions when given a lambda string + instead. + * lib/std/functional.lua (Lambda, lambda): Move from here... + * lib/std/base.lua (Lambda, lamba): ...to here. + (Lambda): Save arguments in table fields. + (argcheck): Accept a valid lambda string in lieu of a Lua + function. + * lib/std/table.lua (sort): When passed a lambda string, pass the + associated function to core table.sort. + * lib/std/functional.lua (bind, case, collect, curry, filter) + (fold, map, memoize): Accept lamda strings in lieu of Lua + functions. + * lib/std/io.lua (process_files): Likewise. + * lib/std/list.lua (filter, foldl, foldr, map, map_with) + (zip_with): Likewise. + * lib/std/string.lua (render): Likewise. + * NEWS: Update. + + specs: add specifications for std.operator. + * specs/operator_spec.yaml: New file. Specify behaviours for + operator functions. + * specs/specs.mk (specl_SPECS): Add specs/operator_spec.yaml. + +2014-07-08 Gary V. Vaughan + + refactor: factor functional.op into new std.operator module. + * lib/std/functional.lua (op): Move from here... + * lib/std/operator.lua (M): ...to here. + (M[".."], M["{}"], M[#"], M["~"], M["%"], M["^"]): New operators. + * local.mk (dist_luastd_DATA): Add lib/std/operator.lua. + * build-aux/config.ld.in (files): Likewise. + * local.mk (dist_module_DATA): Add std.operator.html. + * NEWS: Update. + +2014-07-07 Gary V. Vaughan + + functional: new lambda function. + Support compiling an anonymous Lua function from a "lambda string". + * specs/functional_spec.yaml (lambda): Specify behaviour for a + new lambda function. + * lib/std/functional.lua (lambda): Satisfy specification. + * NEWS: Update. + + functional: support multiple return values with memoize. + * specs/functional_spec.yaml (memoize): Specify behaviour when + passed a function with multiple return values. + * lib/std/functional.lua (memoize): Save return values from + wrapped function as a table, and unpack it when called again with + the same arguments. + * NEWS: Update. + +2014-07-04 Gary V. Vaughan + + doc: fix functional.op LDocs. + * lib/std/functional.lua (op): Workaround LDoc's inability to + render non-alphanumeric @field names. + + functional: support relational operators in op table. + * lib/std/functional.lua (op): Add `<`, `<=`, `>` and `>=`. + * NEWS: Update. + + specs: avoid tickling sc_error_message_uppercase sanity check. + * specs/spec_helper.lua.in (raise): An alias to the error matcher + to subvert matching `error` followed by `"[A-Z]` that prevents + make dist from completing. + * specs/container_spec.yaml (construction): Use the raise alias. + + reformat: order functional module functions asciibetically. + * lib/std/functional.lua: Reorder module functions asciibetically. + + specs: don't pass a Tree to object constructor. + * specs/tree_spec.yaml (construction): Don't pass a Tree to an + object constructor. + + refactor: use a function to export container module methods. + * specs/spec_helper.lua.in (badarg, toomanyarg): Format + appropriately when module name is not given. + * specs/container_spec.yaml (construction) + Update to latest style: + Add argcheck behaviour examples. + * lib/std/base.lua (olen): Rename from this... + (arglen): ...to this. + (M): Export arglen and toomanyarg_fmt. + * lib/std/container.lua (M): Add module name at element 1. + (__tostring, __totable): Reformat these... + (M.__tostring, M.__totable): ...as local table function + declarations. + (M.__call): When _ARGCHECK is not disabled, diagnose argument + type errors in table _init styl objects, to satisfy newly + specified behaviours. + (mapfields): Upgrade to base export declaration (for overhead + free argcheck calls with _DEBUG=false) and simplify accordingly. + +2014-07-03 Gary V. Vaughan + + maint: rename array to vector. + In mathematics "array" suggests the possibility of multiple + dimensions, and while one can simulate that with a std.array + of std.arrays, the name "vector" is a better fit for what this + class supports. + * lib/std/array.lua, specs/array_spec.yaml: Move from here... + * lib/std/vector.lua, specs/vector_spec.yaml: ...to here. + Rename symbols accordingly. + * build-aux/config.ld.in (file): Adjust accordingly. + * local.mk (dist_luastd_DATA, dist_classes_DATA): Likewise. + * specs/specs.mk (specl_SPECS): Likewise. + * specs/string_spec.yaml (render): Adjust Array using example to + Vector. + + refactor: use a function to export table apis. + * specs/table_spec.yaml (clone, clone_select, elems, empty) + (ielems, invert, keys, merge, merge_select, metamethod) + (monkey_patch, new, pack, ripairs, size, totable, values): + Update to latest style: + Add "too many argument" behaviour checks. + Simplify and standardise argument error message comparisons. + * lib/std/table.lua (M): Add module name at element 1. + (clone, clone_select, elems, empty, ielems, invert, keys) + (merge, merge_select, metamethod, monkey_patch, new, pack) + (ripairs, size, totable, values): Upgrade to base export + declarations (for overhead free argcheck calls with _DEBUG=false) + and simplify accordingly. + + maint: settle on calling std api calls `Module Functions`. + * lib/std/debug.lua, lib/std/io.lua, lib/std/package.lua, + lib/std/table.lua, lib/std/tree.lua: Consolidate comment section + header as "Module Functions.". + +2014-07-02 Gary V. Vaughan + + maint: don't flag `Lua` strings as invalid errors in spec-files. + * build-aux/sanity-cfg.mk (exclude_file_name_regexp): Add + specs/debug_spec.yaml. + + debug: finish support for nil arguments in exported functions. + Because luajit (legitimately) stops counting on the first nil + value in a list, where Lua 5.1 and 5.2 keep counting, we have + to do our own size calculations on argument vectors to be + consistent. + * lib/std/base.lua (olen): Return the largest integer key from a + table. + (match, export): Use it to ignore `nil` elements in the argument + list when counting the number of arguments. + + debug: support nil arguments in functions declared with export. + * lib/std/base.lua (opairs): Like ipairs, but does not stop at + the first nil value. + +2014-07-01 Gary V. Vaughan + + refactor: use a function to export string apis. + * specs/string_spec.yaml (__concat, __index, assert, caps, chomp) + (escape_pattern, escape_shell, finds, format, ltrim, monkey_patch) + (numbertosi, ordinal_suffix, pad, pickle, prettytostring, render) + (require, require_version, rtrim, split, tfind, tostring, trim) + (wrap): Update to latest style: + Add "too many argument" behaviour checks. + Simplify and standardise argument error message comparisons. + * lib/std/string.lua (M): Add module name at element 1. + (__concat, __index, assert, caps, chomp, escape_pattern) + (escape_shell, finds, format, ltrim, monkey_patch, numbertosi) + (ordinal_suffix, pad, pickle, prettytostring, render, require) + (require_version, rtrim, split, tfind, tostring, trim): Upgrade + to base.export declarations (for overhead free argcheck calls + with _DEBUG = false) and simplify accordingly. + + refactor: simplify caps, chomp, escape_pattern and escape_shell. + * lib/std/string.lua (caps, chomp, escape_pattern, escape_shell): + Remove extraneous parens around return argument. + Use Lua :-method call sugar to shorten gsub invocations. + + refactor: rename string.require_version to string.require. + * specs/string_spec.yaml (require): A copy of the require_version + specs. + (require_version): Also check for deprecation warning on first + use. + (monkey_patch): Check that new `require` function is written into + the given namespace. + * specs/std_spec.yaml (barrel): Likewise. + (monkey_patch): Check that the deprecated `require_version` is + still written into the global namespace. + * lib/std/string.lua (require_version): Rename from this... + (require): ...to this. + (require_version): A deprecated copy of `string.require`. + * NEWS: Update. + + refactor: simplify std.string.require_version. + * lib/std/string.lua (version_to_list, module_version): Factored + out of require_version, rather than defining new temporary local + functions on each invocation of require_version. + (require_version): Simplify accordingly. + + refactor: simplify std.string.tfind. + * lib/std/string.lua (tpack): Factored out of tfind, rather than + defining a new temporary local pack function on every invocation. + (tfind): Simplify accordingly. + + refactor: simplify std.string.format. + * lib/std/string.lua (format): Simplify. + + refactor: simplify std.string.assert. + * lib/std/string.lua (assert): Simplify. + + refactor: no need for the underscore in local _floor. + There's no clash between M.floor and local floor now we're using + `export` to declare api calls. + * lib/std/math.lua (_floor): Rename from this... + (floor): ...to this. Adjust all callers. + + refactor: use a function to export package apis. + * specs/package_spec.yaml (find, insert, mappath, normalize) + (remove): Update to latest style. + Add "too many argument" behaviour checks. + Simplify and standardise argument error message comparisons. + * lib/std/package.lua (M): Add module name at element 1. + (find, insert, mappath, normalize, remove): Upgrade to + base.export declarations (for overhead free argcheck calls with + _DEBUG = false) and simplify accordingly. + (package): Improve LDocs. + + specs: work around luajit argument counting gotcha. + Luajit truncates a variadic function call's argument list at + the first nil! + * specs/base_spec.yaml (export): Don't pass nil part way through + a variadic function call's argument list. + + base: support optional arguments in export type declarations. + The algorithm is approximately to collect every possible + permutation of argument type-spec list with and without any + optional arguments. An optional argument in the last position + must match the given type or nil, so that the permutation with + the final optional removed matches, allowing an uncaught + mismatched type at that position. Then we try to match the + actual arguments against each permutation until one passes, + otherwise diagnose the mismatch, reporting that any type + at the mismatched index from all permutations is required. + * specs/base_spec.yaml (export): Specify behaviours when called + with a declaration containing an optional argument wrappend in + square brackets. + * lib/std/base.lua (match, formaterror): New functions; factored + out of argcheck. + (copy, match, normalize, permutations): New functions; support + classification of matchable argument type-specs. + (export): Use them to implement optional arguments in export + type declarations to satisfy new specifications. + + doc: improve strict LDocs. + * lib/std/strict.lua: Improve LDocs. + + doc: correct parameter descriptions on debug.argscheck. + * lib/std/debug.lua (argscheck): Improve LDocs. + + specs: decouple spec_helper.lua from std.table and std.functional. + * specs/spec_helper.lua.in (bind): Use our own implmentation of + bind, otherwise if std.functional becomes unloadable, the whole + specl suite is unusable. + (totable): Likewise for std.table.totable. + (set): No need to rely on std.set, when a simple table index + dereference works equally well. + + refactor: use a function to export io apis. + * specs/io_spec.yaml (catdir, catfile, die, monkey_patch) + (process_files, readlines, shell, slurp, splitdir, warn) + (writelines): Update to latest style. + Add "too many argument" behaviour checks. + Simplify and standardise argument error message comparisons. + * lib/std/io.lua (M): Add module name at element 1. + (catdir, catfile, die, monkey_patch, process_files, readlines) + (shell, slurp, splitdir, warn, writelines): Upgrade to + base.export declarations (for overhead free argcheck calls with + _DEBUG = false) and simplify accordingly. + (catdir, catfile, die, monkey_patch, process_files, readlines) + (shell, slurp, splitdir, warn, writelines): Improve LDocs. + * NEWS: Update. + + debug: revert export of trace. + Both because the argument check wrapper is not properly tail-call + eliminated by Lua 5.1, and because as a core function callback + the function signature is fixed already, there's no good reason + to check arguments on debug.trace. + * specs/debug_spec.yaml (trace): Remove argument check behaviour + specifications. + * lib/std/debug.lua (trace): Remove the export wrapper. + +2014-06-30 Gary V. Vaughan + + debug: revert export of argerror, argcheck and argscheck. + Annoyingly, Lua 5.1 misses an obvious tail call elimination when + _DEBUG.argcheck is set, so the deep call to error gets the wrong + level, and reports argument errors in the wrong functions!! Rather + than uglify the code to remove the tail-calls and do a recount, + or add a fudge factor when Lua 5.1 is detected, it's cleaner to + remove the argchecking wrappers of the 3 affected functions -- at + least until we're ready to drop Lua 5.1 support entirely. + * specs/debug_spec.yaml (argerror, argcheck, argscheck): Mark the + argument checking behaviours as pending. + * lib/std/debug.lua (argerror, argcheck, argscheck): Comment out + the argument checking wrappers, and call the bare functions. + +2014-06-13 Gary V. Vaughan + + debug: improve argcheck list semantics. + Following the principle of least surprise, make a new `#list` + check type that has the same behaviour as `list` did previously, + for orthogonality with `#table`, and add a new `list` + implementation for orthogonality with `table`. + * specs/debug_spec.yaml (argcheck): Specify behaviours of `list` + and `#list` with new semantics. + * lib/std/debug.lua (argcheck): Update LDocs. + * lib/std/base.lua (argcheck): Count the elements of a `list` + and ensure that number is not greater than the result of the + length operator -- i.e. the table has no holes, and no non- + integer keys. + When building a type-mismatch error, write `empty list` where + appropriate. + * lib/std/debug.lua (argcheck): Make the 2nd argument a `#list`. + + refactor: use export function to simplify debug argchecks. + * lib/std/debug.lua (argcheck, argerror, argscheck, trace): Add + argument checking. + * specs/debug_spec.yaml: Adjust. + + refactor: use a string specifier instead of a table for export. + * specs/base_spec.yaml (export): Specify behaviours of export + function, particularly with argument errors. + * lib/std/base.lua (export): In place of an export name and a + table of expected argument types, parse a single `decl` argument + into an export name and table of argument types. + Support specified argument error behaviours. + * lib/std/math.lua (floor, monkey_patch, round): Simplify + accordingly. + * lib/std/functional.lua (bind, case, collect, compose, curry) + (eval, filter, fold, map, memoize): Likewise. + + refactor: use pipe-delimited strings for argcheck type lists. + * specs/debug_spec.yaml (argcheck, argscheck): Adjust for + pipe-delimited string instead of table of strings. + * lib/std/base (argcheck): Use base.split to make a table from + expected argument. + * lib/std/array.lua, lib/std/container.lua, lib/std/debug.lua, + lib/std/io.lua, lib/std/list.lua, lib/std/package.lua, + lib/std/string.lua, lib/std/table.lua: Adjust argcheck and + argscheck types argument accordingly. + + refactor: use a function to simplify bad argument specs. + * specs/spec_helper.lua.in (badarg, toomanyarg): Assemble a + suitable error string from arguments. + * specs/function_spec.yaml, specs/math_spec.yaml: Simplify + accordingly. + + refactor: use a function to export functional apis. + * lib/std/base.lua (argcheck): Accept "func" as an alias for + "function". + (export): When the last types element ends with "*", check type + of remaining unchecked args against it. + If there is no "*" mark in the types list, and more arguments are + passed than types entries, throw a "too many arguments" error. + Return the unwrapped function argument, so it can be captured + back into a local by the caller. + * specs/functional_spec.yaml (case, curry, eval, memoize): Check + these fixed argument functions throw a "too many arguments" error + when called with too many arguments. + * specs/math_spec.yaml (floor, monkey_patch, round): Likewise. + * lib/std/functional.lua (bind, case, collect, compose, curry) + (eval, filter, fold, map, memoize): Use base.export for + conditional argument checking. Simplify accordingly. + (functional): Rename from this... + (M): ...to this. + + refactor: use a function to export math apis. + * lib/std/base.lua (export): New function. Add a function to the + module export table, with or without argument checking as + appropriate. + * lib/std/math.lua (floor, monkey_path, round): Simplify + accordingly. + (M): Store the module prefix at index 1, for export argerror + calls. + * specs/spec_helper.lua.in (show_apis): Ignore module prefix at + index 1 of export table. + * specs/math_spec.yaml (round): Correct a typo in argerrors. + + list: deprecate index_key and index_value. + * specs/list_spec.yaml (index_key, index_value): Check that the + functions issue a depraction warning on first use. + * lib/std/list.lua (index_key, index_value): Add deprecation + warning with base.deprecate. + * NEWS (Incompatible changes): Update. + + table: add elems and ielems module functions. + * specs/table_spec.yaml (elems, ielems): Specify behaviour of + new iterators. + * lib/std/table.lua (elems): Iterate over all values of a table, + for orthogonality with std.list and std.set. + (ielems): Expose base.ielems in a type checking wrapper. + * NEWS: Update. + + doc: disable LDoc backtick references. + * build-aux/config.ld.in (backtick_references): Set to false, so + we can write fixed-width font words in LDoc comments. + +2014-06-10 Gary V. Vaughan + + list: prefer numeric comparison to asciibetical in compare. + Close #60. + * lib/std/list.lua (compare): If tonumber can make numbers out + of both arguments, use those results in preference to strings. + * specs/list_spec.yaml (compare): Specify behaviours with elements + that can be coerced to numbers. + * specs/string_spec.yaml (require_string): Remove pending #60 + commands. Add some more happy path examples. + +2014-06-09 Gary V. Vaughan + + refactor: differentiate module tables and prototype objects. + It turns out that documentation and code is much clearer when + we differentiate between `list` (the module table for `std.list`) + and `List` (the prototype List object), because that makes it + explicit whether we're calling a module function (`list.append`) + or performing an operation with the prototype (`List.clone {}`). + As a bonus, we gain a bit of speed by cloning the prototype + object from the module table, by virtue of not having a + `_functions` table to administer. + * lib/std/array.lua, lib/std/base.lua, lib/std/container.lua, + lib/std/debug.lua, lib/std/functional.lua, lib/std/io.lua, + lib/std/list.lua, lib/std/math.lua, lib/std/object.lua, + lib/std/optparse.lua, lib/std/set.lua, lib/std/strbuf.lua, + lib/std/string.lua, lib/std/table.lua, lib/std/tree.lua: Always + use the module table or prototype object as appropriate. Make + sure the LDocs don't contradict us. + + doc: add functional.memoize usage example. + * lib/std/functional.lua (memoize): Add a usage example. + + doc: fix some errors in functional usage docs. + * lib/std/functional.lua (collect): list.relems requires a List. + (map, filter, fold): list.elems requires a List. + + refactor: set local _ARGCHECK instead of dereferencing debug_init. + * lib/std/array.lua, lib/std/base.lua, lib/std/function.lua, + lib/std/io.lua, lib/std/list.lua, lib/std/package.lua, + lib/std/string.lua, lib/std/table.lua: Set local _ARGCHECK + instead of importing std.debug_init and dereferencing it all the + time. + + refactor: string.split is an argchecking base.split. + * lib/std/base.lua (split): Remove argument checking. + * lib/std/string.lua (split): Re-export base.split when we are + not argchecking, otherwise check types and call base.split when + successful. + + refactor: table.metamethod is an argchecking base.getmetamethod. + * lib/std/base.lua (metamethod): Rename from this... + (getmetamethod): ...to this, and remove argument checking. + Adjust export table. + * lib/std/table.lua (metamethod): Re-export base.getmetamethod + when we are not argchecking, otherwise check types and call + base.getmetamethod when successful. + * lib/std/object.lua (clone): Adjust. + * lib/std/string.lua (render): Likewise. + + refactor: list.elems is an argument checking base.ielem wrapper. + Functions in std.base are for internal use, and so all callers + have already validated arguments, so we shouldn't waste time + rechecking types on every call to base.elems. + Also this means list.elems can be strict about only accepting + List objects, and catch accidental table passing earlier. + * lib/std/base.lua (elems): Move from here... + (ielems): ...to here, and remove argument checking. Adjust + export table. + * lib/std/list.lua (elems): Re-export base.ielems when we are not + argchecking, otherwise check types and call base.ielems when + successful. + * lib/std/debug.lua (tabify): Use non-argchecked base.ielems. + * lib/std/list.lua (concat, depair, filter, foldl, map) + (map_with): Likewise. + * lib/std/set.lua (Set._init): Likewise. + * lib/std/table.lua (merge_namedfields): Likewise. + * lib/std/tree.lua (Tree.__index): Likewise. + * specs/functional_spec.yaml (fold): Use List objects + consistently. + * specs/list_spec.yaml (elems): Adjust error message + expectations. + + list: add argchecks. + * specs/list_spec.yaml (append, compare, concat, cons, depair) + (elems, enpair, filter, flatten, foldl, foldr, index_key) + (index_value, map, map_with, project, relems, rep, reverse) + (shape, sub, tail, traspose, zip_with): Specify behaviours for + missing or wrong type arguments. + 8 specs/object_spec.yaml: Decouple from list implementation + details. + * lib/std/list.lua (append, compare, concat, cons, depair) + (elems, enpair, filter, flatten, foldl, foldr, index_key) + (index_value, map, map_with, project, relems, rep, reverse) + (shape, sub, tail, traspose, zip_with): Check argument types + when not disabled by _DEBUG. + * build-aux/sanity-cfg.mk: Disable bogus failures when rejecting + uppercase error messages with lib/std/list.lua. + +2014-06-08 Gary V. Vaughan + + refactor: use list copying constructor to simplify list.append. + * lib/std/list.lua (append): Use implicit copy of argument object + constructor rather than slower __call constructor and explicit + unpack of argument elements. + + list: index_value and index_key return raw tables. + * specs/list_spec.yaml (index_key, index_value): Specify proper + behaviours. + * lib/std/list.lua (index_key, index_value): A non-contiguous + set of valid results cannot be represented as a std.list object, + so return a raw table. + +2014-06-07 Gary V. Vaughan + + doc: improve object LDocs, and add usage examples. + * lib/std/object.lua: Add usage examples to apis. + (clone): Normally we'd use the __call metamethod to clone from a + given object, so mark the LDocs for clone as @static because it + is primarily a module function. + (prototype): Mark the function documentation as @static, and add + equivalent method documentation. + + doc: add usage examples to container LDocs. + * lib/std/container.lua (__call, __tostring, __totable): Add + usage examples to LDocs. + + container: argcheck apis. + * lib/std/container.lua (mapfields, __call, __tostring) + (__totable): While it would be extremely convoluted to dig out + the functions behind these apis to call them with non-object + initial arguments, add type checking for completeness. + + doc: add usage examples to array LDocs. + * lib/std.array.lua: Add usage examples to LDocs. + + doc: move stringification functions to their own section. + * lib/std/string.lua (render, tostring, prettytostring, pickle): + Move to a new 'Stringification Functions' section. + + string: split on whitespace by default. + * specs/string_spec.yaml (split): Add an example with no explicit + split-pattern argument. + * lib/std/base.lua (split): Default split-pattern to `%s+` when + no argument provided. + * lib/std/string.lua (split): LDocs cite `%s+` as the default + pattern instead of `%s*`. + * NEWS: Update. + +2014-06-06 Gary V. Vaughan + + std: use argcheck instead of assert for type checking. + * specs/std_spec.yaml (barrel, monkey_patch): Make bad argument + examples more specific. + * lib/std.lua.in (barrel, monkey_patch): Use argcheck calls for + type checking insntead of assert. + + debug: support trailing "?" in place of separate "nil" in argcheck. + * specs/debug_spec.yaml (argcheck): Specify behaviour of trailing + "?" in type specifiers. + * lib/std/base.lua (argcheck): Strip trailing "?" from acceptable + argument types, appending a "nil" entry to the list if any "?" + is stripped. + * lib/std/base.lua, lib/std/debug.lua, lib/std/functional.lua, + lib/std/math.lua, lib/std/package.lua, lib/std/string.lua, + lib/std/table.lua: Adjust all callers to use trailing "?" instead + of separate explicit "nil" in type list. + + string: add argchecks and improve LDocs. + * specs/string_spec.yaml (assert, caps, chomp, escape_pattern) + (escape_shell, finds, format, ltrim, monkey_patch, numbertosi) + (ordinal_suffix, pad, prettytostring, render, require_version) + (rtrim, split, tfind, trim, wrap): Specify behaviours with bad + or missing arguments. + * lib/std/string.lua (assert, caps, chomp, escape_pattern) + (escape_shell, finds, format, ltrim, monkey_patch, numbertosi) + (ordinal_suffix, pad, prettytostring, render, require_version) + (rtrim, split, tfind, trim, wrap): Use argcheck or argscheck to + ensure argument types are validated when _DEBUG is not `false`. + Improve LDocs with @usage examples and parameter types. + * NEWS: Update. + + specs: add missing std.string specs. + * specs/string_spec.yaml (assert, pickle, render, require_version) + (tostring): Specify behaviour of these calls. + (require_version): Add pending examples for newly discovered + issue with non-numeric ordering. + +2014-06-05 Gary V. Vaughan + + string: fix number extraction in require_version. + * lib/std/string.lua (require_version): Change the match pattern + to actually extract the numeric part of the version string. + Also update LDocs to cite correct module._VERSION (with an under- + score). + * NEWS: Update. + + tree: remove std.object dependency. + No need to pull in all of std.object when loading std.tree. + * lib/std/tree.lua: Use base.prototype directly instead of via + re-exported object.prototype, which allows complete removal of + std.object dependency. + While we're here, use imported functions from locals to speed up + access a tiny bit. + + tree: remove std.list dependency requirement. + No need to pull in all of std.list when loading std.tree, just + for the foldl function. + * lib/std/tree.lua (__index): Use func.fold and base.elems from + existing required modules instead of list.foldl. + + string: remove unused string.__append metamethod. + The __append metamethod was added in commit 7a548ba, but only + ever had one client in the defunct std.lcs module which was + removed in commet 5f0a8af. + * lib/std/string.lua (__append): Remove. No longer required. + * specs/string_spec.yaml: Remove __append examples and references. + + refactor: put api and helper functions in sections. + * lib/std/array.lua, lib/std/container.lua, lib/std/io.lua, + lib/std/optparse.lua, lib/std/package.lua, lib/std/set.lua, + lib/std/string.lua, lib/std/table.lua, lib/std/tree.lua: To make + it clear that user-facing code ("api functions") need argument + checking, but internal code ("helper functions") does not, + explicitly separate those kinds of functions, and add some + block headers. + + array: remove duplicate nested argcheck, correctly this time. + * lib/std/array.lua: Where a function or metamethod is called via + `dispatch`, which already checks that the first argument is an + Array object, don't recheck type of self. If that leaves only + arguments of type "any" then don't spend any time checking + argument types at all. + + array: remove duplicate nested argcheck. + * lib/std/array.lua (dispatch): Remove duplicate nested argcheck. + The dispatched to functions already run a full argscheck, so no + need to check again here. + + maint: minimize overhead with argchecks disabled. + * lib/std/array.lua (__call): Wrap argchecking block in + `if debug._ARGCHECK`. + * lib/std/functional.lua (compose): Likewise. + * lib/std/io.lua (catdir, catfile): Likewise. + * lib/std/package.lua (normalize, insert): Likewise. + * lib/std/base.lua (split): Use argscheck instead of assert. + * lib/std/math.lua (monkey_patch): Likewise. + * specs/math_spec.yaml (monkey_patch): Adjust bad argument + behaviours. + + table: complete specs and improve LDocs. + * lib/std/table.lua (clone, clone_select, empty, invert, keys) + (merge, merge_select, monkey_patch, new, pack, ripairs, size) + (sort, totable, values): Add argcheck calls, and improve LDocs + with usage examples & cross-references. + (clone, clone_select, merge, merge_select): Minimise overhead + when argchecking is disabled by wrapping complex argument + checking in `if init._ARGCHECK`. + * specs/table_spec.yaml (pack, ripairs, totable): Add missing + specifications. + (clone, clone_select, empty, invert, keys, merge, merge_select) + (monkey_patch, new, size, sort, values): Improve specs to match + argcheck behaviours. + +2014-06-04 Gary V. Vaughan + + refactor: move _ARGCHECK calculation into std.debug_init. + * lib/std/base.lua (_ARGCHECK): Move from here... + * lib/std/debug_init.lua (M._ARGCHECK): ...to here. + Adjust clients. + + maint: remove workaround for legacy LuaRocks bug. + * local.mk (dist_luastddebug_DATA): Move + lib/std/debug_init/init.lua from here... + (dist_luastd_DATA): ...to lib/std/debug_init.lua. + (luastddebugdir, dit_luastddebug_DATA): Remove. + + doc: consolidate LDoc headers for core extension modules. + * lib/std/debug.lua, lib/std/io.lua, lib/std/math.lua, + lib/std/package.lua, lib/std/string.lua, lib/std/table.lua: + Consolidate LDoc headers for consistency. + +2014-06-03 Gary V. Vaughan + + package: check api call argument types, and improve LDocs. + * specs/package_spec.yaml (find, insert, mappath, normalize) + (remove): Specify bad argument behaviours. + * lib/std/package.lua (find, insert, mappath, normalize) + (remove): Use argscheck to diagnose bad arguments. + Add usage examples to LDocs. + + debug: support ":foo" parameter types with argcheck. + * specs/debug_spec.yaml (argcheck): Specify behaviours of using + ":foo" as a parameter type. + * lib/std/base.lua (argcheck): Implement ":foo" parameter checking. + * lib/std/debug.lua (argcheck): Update LDocs. + + refactor: reduce module dependencies of std.debug. + * lib/std/debug.lua: Remove std.io dependency by using core + file:write instead of std.io.writelines. + Remove std.list dependency by using lighter functional.map instead + of list.map. + Remove unused std.object dependency. + (tabify): Instead of a deeply nested in-situ call to list.map + and others, functionally compose an equivalent and use that to + simplify. + + maint: use "int" argcheck type as appropriate. + * lib/std/array.lua, lib/std/functional.lua: Use "int" parameter + type with argcheck as appropriate. + * lib/std/debug.lua (argscheck): Adjust usage example. + * specs/array_spec.yaml, specs/functional_spec.yaml: Adjust. + + math: check api call argument types. + * specs/math_spec.yaml (floor, round): Specify bad argument + behaviours. + * lib/std/math.yaml (floor, round): Use argscheck to diagnose + bad arguments. + + debug: support "int" parameter type with argcheck. + * specs/debug_spec.yaml (argcheck): Specify behaviours of using + "int" as a parameter type. + * lib/std/base.lua (argcheck): Implement "int" parameter checking. + + math: complete specs and improve LDocs. + * lib/std/math.lua (floor, monkey_patch, round): Improve LDocs + with usage examples. + * specs/io_spec.yaml (floor, round): Add missing specifications. + + maint: add an LDoc module header to private std.base module. + * lib/std/base.lua: Add LDoc module header. + + refactor: move split implementation from string to base. + Decouple std.io from std.string (and hence std.table, std.list, + std.functional, std.object, and std.container) by moving + implementation of split into lib/std/base.lua. + * lib/std/string.lua (split): Move from here... + * lib/std/base.lua (base): ...to here, and export. + * lib/std/string.lua: Re-export base.split as string.split. + * lib/std/io.lua: Don't pull all of string.lua and it's + dependencies into memory; use base.split instead of string.split. + + maint: use 2 blank lines between function definitions. + * lib/std/package.lua, lib/std/strict.lua, lib/std/string.lua: + Use 2 blank lines between function definitions. + + debug: complete specs and improve LDocs. + * lib/std/debug.lua (__call, _DEBUG, argcheck, argerror) + (argscheck, say, trace): Improve LDocs with usage examples and + cross-references. + * specs/debug_spec.yaml (_DEBUG): Remove. _DEBUG behaviours are + specified in the api calls that are affected by it. + (say, trace): Add missing specificatons. + + specs: account for different error messages between 5.1 and 5.2. + * specs/io_spec.yaml (process_files): Accept either of the + error message formats for passing a non-existent file to io.input + for Lua 5.1 or Lua 5.2. + +2014-06-02 Gary V. Vaughan + + std: improve LDocs. + * lib/std.lua.in: Improve LDocs with usage examples and + clearer language. + + io: complete specs and improve LDocs. + * lib/std/io.lua (catdir, catfile, die, monkey_patch) + (process_files, readlines, shell, slurp, splitdir, warn) + (writelines): Improve LDocs with usage examples and cross- + references. + * specs/io_spec.yaml (catdir, catfile, die, monkey_patch) + (process_files, readlines, shell, slurp, splitdir, warn) + (writelines): Add missing specificatons. + * specs/spec_helper.yaml (concat_file_content): New function to + support new specifications. + (luaproc): Support subprocess arguments and standard input. + +2014-06-01 Gary V. Vaughan + + object: enhance prototype to recognize file objects. + * specs/object_spec.yaml (prototype): Specify results of passing + file handles and Lua primitives to prototype. + * lib/std/object.lua (prototype): Improve LDocs. + * lib/std/base.lua (prototype): Enhance implementation to meet + new specifications. + * NEWS: Update. + + io: use argcheck for api functions. + * specs/io_spec.yaml (catdir, catfile, die, monkey_patch) + (process_files, readlines, shell, slurp, splitdir, warn) + (writelines): Specify argument type mismatch messages. + * lib/std/io.lua (catdir, catfile, die, monkey_patch) + (process_files, readlines, shell, slurp, splitdir, warn) + (writelines): Call argcheck to validate arguments and meet + specifications. + +2014-05-31 Gary V. Vaughan + + debug: add file object matching to argcheck. + * specs/debug_spec.yaml (argcheck): Specify behaviour when + matching against a file type argument. + * lib/std/debug.lua (argcheck): Add LDocs for file type. + * lib/std/base.lua (argcheck): When the required type is "file" + use io.type () to ensure that an open file object argument was + passed. + + io: don't pull in tree and dependencies with `require "io"`. + * lib/std/io.lua (tree): Remove requirement. + (base): Replace with much lighter module. + (writelines): Call base.leaves instead of tree.ileaves. In + addition to reducing coupling, this also saves another round + of `argscheck`ing, and a callstack frame. + +2014-05-30 Gary V. Vaughan + + array: support ipairs iteration over elements. + * specs/array_spec.yaml (__ipairs): Specify behaviour of ipairs + with arrays. + * lib/std/array.lua (core_metatable.__ipairs) + (alien_metatable.__ipairs): Implement ipairs support for table + and alien.buffer managed table elements. + + maint: demonstrate new and legacy bind api correctly. + Seems like I was confused over which functional.bind api was the + old, and which was the new. Correct that. + * specs/functional_spec.yaml (bind): Swap examples of new bind + api labelled legacy and vice versa. + * NEWS: Update. + +2014-05-29 Gary V. Vaughan + + refactor: merge std.base_array into std.array. + Instead of a one-way degrading from alien.buffer managed elements + to table managed elements with a sub-type, combine both sets of + optimised methods and metamethods back into a single `std.array` + container, which decides with each clone operation how to manage + elements of the named type. + * specs/array_spec.yaml: Specify behaviours for Array object that + dispatches module function calls at runtime, and assigns + optimized methods and metamethods on cloned objects according to + element type. + * lib/std/base_array.lua (pop, push, realloc, set, shift, unshift) + (__index, __newindex, __len, __tostring): Move from here... + * lib/std/array.lua (core_functions.pop, core_functions.push) + (core_functions.realloc, core_functions.set, core_functions.shift) + (core_functions.unshift, core_metatable.__index) + (core_metatable.__newindex, core_metatable.__len) + (core_metatable.__tostring: ...to here. + (pop, push, realloc, set, shift, unshift, __index, __newindex): + Move from here... + (alien_functions.pop, alien_functions.push, alien_functions.set) + (alien_functions.realloc, alien_functions,shift) + (alien_functions.unshift, alien_metatable.__index) + (alien_metatable.__newindex): ...to here. + (core_metatable.__call): Clone a new Array object, setting the + method and metatables with functions optimised for alien.buffer + or Lua table based element management according to availability of + alien, and element type name. + (dispatch): New runtime virtual table dispatch function. + (Array): Dispatch module functions at runtime based on element + type. + * lib/std/base_array.lua: Remove. + * local.mk (dist_luastd_DATA): Remove lib/std/base_array.lua. + * specs/base_array_spec.yaml: Remove. + * specs/specs.mk (specl_SPECS): Remove specs/base_array_spec.yaml. + * NEWS: Update. + + functional: complete specs and improve LDocs. + * lib/std/functional.lua (bind, case, curry, compose, eval) + (collect, map, filter, fold): Improve LDocs with usage examples, + and cross-references. + * specs/functional_spec.yaml (collect, compose, curry, eval) + (filter, fold, id, map, memoize): Add missing specifications. + + debug: argcheck can match functable with "function". + * specs/debug_spec.yaml (argcheck): Specify correct behaviour + when matching a functable against a "function" argument. + * lib/std/base.lua (argcheck): Allow functables when a "function" + type argument is required. + * lib/std/debug.lua (argcheck): Update LDocs. + + functional: bind should not require respecifying fixed args. + * specs/functional_spec.yaml (bind): Move incumbent examples to + a new legacy example. Rewrite original examples with new api. + Add specifications for behaviour when not all arguments are + given in the call to the bound function. + * lib/std/functional.lua (bind): Fill initial argument positions + from original bind arguments, and then propagate final call + arguments into non-fixed parameter positions. + * NEWS: Update. + + functional: use argscheck for api functions. + * specs/functional_spec.yaml (metamethod): Remove. This method + has moved to std.table. + (bind, case, collect, compose, curry, eval, filter, fold, map) + (memoize): Specify behaviour with missing or wrong type + arguments. + * lib/std/functional.yaml (bind, case, collect, compose, curry) + (eval, filter, fold, map, memoize): Add argscheck calls to + validate arguments when _DEBUG or _DEBUG.argcheck are not false. + + refactor: omit spurious parentheses around require result dereferences. + * lib/std/container.lua, lib/std/object.lua, lib/std/set.lua, + lib/std/string.lua, lib/std/tree.lua, specs/container_spec.yaml, + specs/list_spec.yaml, specs/object_spec.yaml, + specs/set_spec.yaml, specs/spec_helper.lua.in: Omit spurious + parentheses around require result dereferences. + + base: use argscheck for api functions. + * specs/base_spec.yaml (deprecate), specs/list_spec.yaml (elems): + Specify bad argument behaviours. + * specs/table_spec.yaml (metamethod): Add missing specifications, + including bad argument behaviours. + * lib/std/base.lua (deprecate, elems, metamethod): Use argscheck + to implement specified behaviours. + + refactor: don't pull in all of debug's dependencies for array. + * lib/std/array.lua, lib/std/base_array.lua: Import argcheck and + argscheck from std.base. + + refactor: move argscheck et.al. into std.base module. + Unfortunately, debug.say is a very high level function that pulls + in a lot of other modules, modules that we'd like to be able to + add debug.argscheck to... since argscheck has almost no pre- + requisites, move it into the base module where it can then be + available everywhere else. + * lib/std/container.lua (prototype): Move from here... + * lib/std/base.lua (prototype): ...to here. + * lib/std/debug.lua (concat, argerror, argcheck, argscheck): + Move from here... + * lib/std/base.lua (concat, argerror, argcheck, argscheck): ...to + here. + Be sure to disable argument checking if _DEBUG or _DEBUG.argcheck + are false. + +2014-05-27 Reuben Thomas + + functional.lua: add missing parameter name to docstring + +2014-05-24 Gary V. Vaughan + + alien: remove surplus std.alien module. + * lib/std/array.lua: Factor away dependencies on std.alien. + (__call): Instead of an _init call built for container.__call, + we now use a custom __call metamethod that returns a base_array + object that is optimized for Lua table buffers when the element + type is not recognized (either because there is no alien module + installed, or it does not support buffers of the given type), or + else builds an alien.buffer optimised object and returns that. + * lib/std/alien.lua, specs/alien_spec.yaml: Remove. + * build-aux/config.ld.in (file): Remove lib/std/alien.lua. + * local.mk (dist_luastd_DATA): Likewise. + (dist_modules_DATA): Remove doc/modules/std.alien.html. + * specs/specs.mk (specl_SPECS): Remove specs/alien_spec.yaml. + + base_array: non-alien capable base class for std.array. + * specs/base_array_spec.yaml: New file. Specify behaviour for + base_array. + * specs/specs.mk (specl_SPECS): Add specs/base_array_spec.yaml. + * lib/std/base_array.lua: New file. Implement base_array class to + satisfy specification. + * local.mk (dist_luastd_DATA): Add lib/std/base_array.lua. + + debug: argcheck "any" does not match `nil`. + * specs/debug_spec.yaml (argcheck): Passing a nil argument does + not satisfy the "any" spec. + * lib/debug.lua (argcheck): Require non-nil argument before + setting passing status for an "any" spec. + (argscheck): Remove "any" shortcut. + +2014-05-21 Gary V. Vaughan + + optparse: fix another global symbol leak. + * lib/std/optparse.lua (on): Declare `key` as a local variable. + + optparse: fix a global symbol leak. + * lib/std/optparse.lua (on): Declare `normal` as a local variable. + * NEWS (Bug fixes): Updated. + + configury: don't require specific git version. + * bootstrap.conf (buildreq): Don't set a git version number, or + else `GIT=true ./bootstrap` doesn't work. + + slingshot: sync with upstream. + * slingshot: Sync with upstream for grep GNUism fix. + +2014-05-20 Gary V. Vaughan + + array: support simultaneous alien and Lua array objects. + * lib/std/array.lua (alien_type): A set of valid types for + arrays to be implemented with alien.array. + (topointer): Default offset to 1. + (setzero): Use memset for alien arrays, direct element buffer + copying for Lua arrays. + (shift, unshift): Use memmove for manipulating alien.arrays, or + else table.insert and table.remove for Lua tables. + (copy): Remove. + (clone): Use memmove for copying elements between same-size + element alien arrays, direct element buffer copying otherwise. + (_init): Simplify accordingly. + + array: a new Object based array for queue and stack-like ops. + * specs/array_spec.yaml: New file. Specify base behaviours for a + new array object. + * specs/specs.mk (specl_SPECS): Add specs/array_spec.yaml. + * lib/std/array.lua: New file. Implement specified behaviours. + * build-aux/config.ld.in (files): Add lib/std/array.lua. + * local.mk (dist_classes_DATA): Add doc/std.array.html. + (dist_luastd_DATA): Add lib/std/array.lua. + * NEWS: Update. + + debug: fix argerror diagnostics on luajit. + Luajit seems to treat `return error` (where error never returns + anyway) as subject to some kind of optimisation that loses a call + stack level by the time `error` looks up the line number for the + targetted level. Removing the `return` results in the same call + stack frame reference in luajit, 5.2 and 5.1. + * lib/std/debug.lua (argerror): Drop the extraneous `return` + statement. + + debug: fix argcheck diagnostics on Lua 5.1. + Lua 5.2 seems to treat `return argerror` (where argerror never + returns anyway) as subject to some kind of optimisation that loses + a call stack level by the time control flow reaches the `error` + call inside. Removing the `return` results in the same call stack + frame reference in 5.2 and 5.1, but requires incrementing the + level for the correct result. + * lib/std/debug.lua (argcheck): Drop the extraneous `return` + statement, and increment `level` before calling `argerror`. + +2014-05-19 Gary V. Vaughan + + alien: implement a subset of alien to simplify wrappers. + * specs/alien_spec.yaml: Specify behaviour for a useful subset + of the alien APIs. + * specs/specs.mk (specl_SPECS): Add specs/alien_spec.yaml. + * local.mk (dist_modules_DATA): Add doc/modules/std.alien.html. + * lib/std/alien.lua: New file, provide pure Lua implementation + of alien.array, alien.memmove and alien.memset. + * build-aux/config.ld.in (files): Add lib/std/alien.lua. + * local.mk (dist_luastd_DATA): Add lib/std/alien.lua. + + debug: make sure to use debug.getinfo (). + * lib/std/debug.lua (trace): Use debug.getinfo instead of bare + getinfo. + * NEWS: Update. + + debug: add argcheck APIs. + * specs/debug_spec.yaml (argcheck, argerror, argscheck): Specify + behaviour of argument checking functions based on luaL_argerror + and luaL_argcheck, for standardised argument error diagnostics. + * lib/std/debug.lua: Tidy up LDocs. + (argcheck, argerror, argscheck): New functions to satisfy the + specifications. + * NEWS: Update. + 2014-05-01 Gary V. Vaughan + maint: post-release administrivia. + * configure.ac (AC_INIT): Bump version to 41. + * NEWS: Add header line for next release. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + Release version 40 * NEWS: Record release date. @@ -339,7 +3116,7 @@ * specs/spec_helper.lua.in: Use `package.normalize` to safely inject ./lib/?.lua into the head of package.path. -2014-04-16 Reuben Thomas +2014-04-15 Reuben Thomas Fix a comment typo @@ -361,7 +3138,7 @@ specs: fix a typo; there is no 'a' in should_output. * specs/optparse_spec.yaml: Fix a typo. -2014-04-15 Reuben Thomas +2014-04-14 Reuben Thomas Fix a comment typo @@ -541,7 +3318,7 @@ clone of the table we return. * NEWS: Update. -2014-01-22 Gary V. Vaughan +2014-01-21 Gary V. Vaughan configury: update rockspecs in buildreq. * bootstrap.conf (buildreq): LDoc is now available in the required @@ -550,8 +3327,6 @@ travis: remove unrelease ldoc workarounds. * .travis.yml: Regenerate, to delete local patches for LDoc. -2014-01-21 Gary V. Vaughan - doc: vastly improve optparse LDocs. * lib/std/optparse.lua: Vastly improve optparse LDocs. * NEWS: Update. @@ -608,7 +3383,7 @@ Revert "maint: post-release administrivia." This reverts commit 846fd4e578cf8a57c8268979c9fbd2495b0e7b5b. -2014-01-18 Gary V. Vaughan +2014-01-17 Gary V. Vaughan maint: post-release administrivia. * configure.ac (AC_INIT): Bump version to 38. @@ -638,8 +3413,6 @@ * specs/specs.mk (specl_SPECS): Move std_spec.yaml to the end of the list, where symbol leaks don't affect subsequent examples. -2014-01-17 Gary V. Vaughan - specs: compensate for table.pack differences between Lua 5.1/5.2. * specs/table_spec (before): Make sure `extend_base` and `enhance_base` reflect whether core table library has a `pack` @@ -721,6 +3494,8 @@ * local.mk (mkrockspecs_args): Add `--repository lua-stdlib`. * .travis.yml: Regenerate. +2014-01-15 Gary V. Vaughan + slingshot: sync with upstream, for bootstrap git detection fix. * slingshot: Sync with upstream. * bootstrap: Sync with slingshot. @@ -916,6 +3691,8 @@ * ext/std/object.lua, ext/std/set.lua, ext/std/strbuf.lua, ext/std/strict.lua, ext/std/tree.lua: Update doc-comments. +2013-11-27 Gary V. Vaughan + tree: add specl specs, and fix simple API inconsistencies. * specs/tree_spec.yaml: New file. Examples of how tree APIs should behave. @@ -923,8 +3700,6 @@ * ext/std/base.lua (ileaves, leaves): Report non-table arguments. * ext/std/tree.lua (clone, inodes, nodes, merge): Likewise. -2013-11-27 Gary V. Vaughan - string: report assert failures from assert caller level. * ext/std/string.lua (assert): Call error with level 2, to report errors from the assert caller not assert itself. @@ -935,7 +3710,7 @@ * ext/std/tree.lua (metatable.__index): Use new argument order for list.foldl call. -2013-11-27 Reuben Thomas +2013-11-26 Reuben Thomas Remove some spurious comment markers in docstrings. These were introduced by commit 31b314c835 converting doc-comments to @@ -1469,6 +4244,8 @@ * configure.ac: Adjust. * .travis.yml: Regenerate. +2013-05-05 Gary V. Vaughan + Revert "travis: force luadoc to run only using Lua 5.1." This reverts commit d54819f8b58988b10f8a298746abc28ce30b41c8. @@ -1542,8 +4319,6 @@ * .gitignore: Update. * .travis.yml: Regenerate. -2013-05-05 Gary V. Vaughan - slingshot: add slingshot as a git submodule. * .gitmodules: New file. * slingshot: New submodule. @@ -1564,7 +4339,7 @@ `package.path` and `package.cpath` being lost when set from LUA_INIT, among many other potential issues. -2013-04-14 Reuben Thomas +2013-04-13 Reuben Thomas Remove non-core modules, which go into separate lua-rrtlib for ad-hoc modules @@ -1611,7 +4386,7 @@ installing git master with Luarocks. Liberal use of additional useful links. -2013-04-08 Reuben Thomas +2013-04-07 Reuben Thomas README.md: simplify installation instructions, and other minor tweaks @@ -1711,13 +4486,11 @@ * README: Add travis build status badge markup. Plus some indentation corrections for correct markdown code rendering. -2013-04-02 Gary V. Vaughan +2013-04-01 Gary V. Vaughan docs: improved installation instructions. * README: improve installation instructions. -2013-04-01 Gary V. Vaughan - maint: The Grand Renaming™ - use `require "std.list"` etc. * Makefile.am (SPEC_ENV, SPECL, SPECL_MIN, SPECS, MULTICHECK) (check-local, src_spec): Split out from here... @@ -1989,7 +4762,7 @@ * src/getopt.lua (processArgs): Call local 'getOpt' function. Global getopt.getOpt may never exist! -2013-03-10 Reuben Thomas +2013-03-09 Reuben Thomas README: mention all extra dependencies of fstable @@ -2024,7 +4797,7 @@ * specs/package_ext_spec.lua (it splits package.config up): Allow for optional trailing \n present in 5.2 but not 5.1. -2013-02-28 Gary V. Vaughan +2013-02-27 Gary V. Vaughan configury: bump release number to 34. * configure.ac (AC_INIT): Bump release number to 34. @@ -2119,7 +4892,7 @@ Remove TODO. * template.lua, specs/specl: Update. -2013-02-23 Reuben Thomas +2013-02-22 Reuben Thomas Fix some spec failures in string.wrap, and one error in a spec. @@ -2194,6 +4967,8 @@ configury: bump release number to 33. * configure.ac (AC_INIT): Bump release number to 33. +2013-02-21 Gary V. Vaughan + configury: make the release rules more robust. * Makefile.am (GIT, GIT_REMOTE, LN_S): Set as macros that can be overridden during testing. @@ -2210,8 +4985,6 @@ configury: bump release number to 32. * configure.ac (AC_INIT): Bump release number to 32. -2013-02-21 Gary V. Vaughan - specs: add specl specification for package_ext module. * specs/package_ext_spec.lua: New file. Specl specs for package_ext. @@ -2257,7 +5030,7 @@ * Makefile.am (SOURCES): Remove the GNU Make extensions used to dynamically build the list, and just list each file statically. -2013-02-21 Reuben Thomas +2013-02-20 Reuben Thomas Makefile.am: bump version to 31. @@ -2269,7 +5042,7 @@ Makefile.am: no longer need to re-bootstrap after checking in release files. -2013-02-19 Reuben Thomas +2013-02-18 Reuben Thomas m4/ax_lua.m4: get latest version; no code changes, but some pleasing spelling corrections. @@ -2279,7 +5052,7 @@ list.lua: make all methods that return lists make them with list.new, not {}. Also rename result variables consistently to r, not, in some cases, m. -2013-02-18 Reuben Thomas +2013-02-17 Reuben Thomas Makefile.am: checking out release branch in same directory doesn't work; use another directory. @@ -2291,7 +5064,7 @@ Makefile.am: only supply std.lua once (fixes make distcheck in some setups) -2013-02-16 Reuben Thomas +2013-02-15 Reuben Thomas Makefile.am: copy a couple of fixes from luaposix. @@ -2328,14 +5101,14 @@ Merge pull request #11 from gvvaughan/pull-request/use-uninstalled-stdlib configury: load local std modules as expected by mkrockspecs.lua. -2013-02-12 Reuben Thomas +2013-02-11 Reuben Thomas parser.lua: update to current stdlib and Lua 5.2, fixing a couple of small bugs Remove a debugging line accidentally left in before. base.lua: fix die; previously produced rubbish! -2013-02-12 Gary V. Vaughan +2013-02-11 Gary V. Vaughan maint: update parser to use lua 5.2 style modules. * src/parser.lua: Simply return the Parser object. @@ -2349,8 +5122,6 @@ of interfaces, per lua 5.2 module style. Adjust all callers. -2013-02-11 Gary V. Vaughan - maint: update mbox to use lua 5.2 style modules. * src/mbox.lua: Declare parse locally, and return a table with a reference, per lua 5.2 module style. @@ -2407,6 +5178,8 @@ rockspecs.lua: add luadoc as a dependency for git rockspec. +2013-02-08 Reuben Thomas + rockspecs.lua: fix build command for building from git. mkrockspecs.lua: whitespace fix. @@ -2415,8 +5188,6 @@ tree.lua: add tree.merge. -2013-02-08 Reuben Thomas - set.lua: fix broken elems iterator (issue #10) strict.lua: tweak formatting to match other modules @@ -2429,6 +5200,8 @@ Avoid rebuilding documentation in distributed sources, so users don't need luadoc installed. +2013-02-06 Reuben Thomas + Makefile.am: some more fixups to release-by-git. .gitignore: we have reverted from zip to tgz tarballs. @@ -2449,8 +5222,6 @@ Makefile.am: enable building of documentation from git checkout. -2013-02-06 Reuben Thomas - Change to building (with LuaRocks) direct from git, not releasing a zip. README: update installation instructions and mention GitHub, not LuaForge. @@ -2461,7 +5232,7 @@ README: Make Lua 5.2 compatibility definite, and update copyright years. -2012-12-24 Reuben Thomas +2012-12-23 Reuben Thomas stdlib.rockspec.in: remove redundant dir setting @@ -2469,13 +5240,13 @@ .gitignore: add luarocks directory -2012-10-29 Reuben Thomas +2012-10-28 Reuben Thomas Add testing of luarock against uploaded archive before mailing announcement base.lua: user simpler default require_version pattern that works in more cases -2012-10-29 Reuben Thomas +2012-10-28 Reuben Thomas Generate Lua version in rockspec from that in configure.ac Bump version to 28 @@ -2485,7 +5256,7 @@ Tweak pattern used to substitute MD5 sum into rockspec to be compatible with gnulib syntax checks, should we ever use them. -2012-10-29 Reuben Thomas +2012-10-28 Reuben Thomas Bump version to 28, and simplify slightly, requiring automake 1.11 @@ -2497,13 +5268,15 @@ release: fix call to woger to generate correct URLs +2012-10-03 Reuben Thomas + rockspec: fix homepage URL Makefile.am: really distribute all docs rockspec: fix download URL (thanks, Hisham Muhammad) -2012-10-02 Reuben Thomas +2012-10-01 Reuben Thomas base.lua: add require_version @@ -2513,7 +5286,7 @@ Install documentation with 'make install' and from luarocks. -2012-09-23 Reuben Thomas +2012-09-22 Reuben Thomas Rename table.indices to table.keys, and use term 'keys' more. @@ -2531,6 +5304,8 @@ getopt.lua: improve some comments and remove a redundant require +2012-09-17 Reuben Thomas + set.lua: fix last commit: elements should be elems base.lua: remove a spurious blank line @@ -2583,20 +5358,20 @@ object.lua: fix inconsistency and missing HTML close tag in doc comments. -2012-02-23 Reuben Thomas +2012-02-22 Reuben Thomas base.lua: Fix minor formatting variation. Merge pull request #5 from gvvaughan/pull-request/for-fame-and-glory AUTHORS: Add myself. -2012-02-23 Gary V. Vaughan +2012-02-22 Gary V. Vaughan base.lua: new memoize function. * src/base.lua (memoize): Memoize a single result function by wrapping it in a functable. -2012-02-23 Reuben Thomas +2012-02-22 Reuben Thomas Update URL to point to github. @@ -2607,7 +5382,7 @@ AUTHORS: Add myself. * AUTHORS: List the few small contributions I've made. -2012-02-19 Reuben Thomas +2012-02-18 Reuben Thomas Update rockspec for github. @@ -2633,7 +5408,7 @@ strict.lua: improve error message. -2012-01-20 Reuben Thomas +2012-01-19 Reuben Thomas Add leaves, ileaves and inodes tree iterators; simplify nodes slightly. Use ileaves to simplify flatten. @@ -2645,16 +5420,14 @@ Fix FIXME in set: use leaves as elements to return only the key. -2012-01-19 Reuben Thomas +2012-01-18 Reuben Thomas src/io_ext.lua: Improve docstring for readlines. -2012-01-18 Reuben Thomas +2012-01-17 Reuben Thomas string_ext: fix new string.__concat metamethod to run tostring on both args, thus avoiding infinite recursion. -2012-01-17 Reuben Thomas - string_ext: add __concat metamethod for strings which runs tostring. Reformat some code to please lua-mode and add some missing quotes in a comment. @@ -2663,7 +5436,7 @@ io_ext: Add slurp; use it in various places. -2011-12-17 Reuben Thomas +2011-12-16 Reuben Thomas Bump version to 26. @@ -2696,7 +5469,7 @@ and should be folded, but k1 (k1 = {key='a'}) is not a list and should not. -2011-10-01 Reuben Thomas +2011-09-30 Reuben Thomas io_ext: unset prog.file at the end of io.processFiles @@ -2711,7 +5484,7 @@ Remove publicly Options constructor, as it’s not needed externally. -2011-09-20 Reuben Thomas +2011-09-19 Reuben Thomas Makefile.am: tweak rockspec's deps. @@ -2729,8 +5502,6 @@ .gitignore: ignore correct zip name. -2011-09-19 Reuben Thomas - configury: rename project to stdlib for consistency and to make luarocks happy. Make rockspec on release. @@ -2774,7 +5545,7 @@ Remove some non-LuaDoc markup. -2011-08-20 Reuben Thomas +2011-08-19 Reuben Thomas Fixup. @@ -2794,20 +5565,24 @@ Convert documentation to LuaDoc, and retire ldoc. +2011-06-05 Reuben Thomas + Add index.html. 2011-05-22 Reuben Thomas Fix faulty ldoc tags. +2011-05-21 Reuben Thomas + Fix return code on --help to be 0. Make dieWithUsage into plain usage, and don’t exit at end. -2011-05-20 Reuben Thomas +2011-05-19 Reuben Thomas Add some missing param tags. -2011-05-04 Reuben Thomas +2011-05-03 Reuben Thomas Comment out strict from default set to make co-existence with other code easier. @@ -2819,7 +5594,7 @@ Fix capitalization of readlines and writeline in docstrings. -2011-04-16 David Favro +2011-04-15 David Favro Fixed bug: ldoc used writeLine() rather than writeline(). @@ -2831,7 +5606,7 @@ Rename readLines to readlines and writeLine to writeline. -2011-03-24 Reuben Thomas +2011-03-23 Reuben Thomas Only set _DEBUG to false if it’s not already initialised. @@ -2851,6 +5626,8 @@ Allow mk1file to generate customized sets of modules, with the standard set as the default. +2011-03-08 Reuben Thomas + Remove unnecessary posix. prefix. Correct name of package_ext. @@ -2861,10 +5638,10 @@ Merge branch 'origin' of github.com:rrthomas/lua-stdlib into origin -2011-03-08 Reuben Thomas - Remove posix_ext and object from standard set. +2011-03-07 Reuben Thomas + Remove posix prefix from function calls. Add euidaccess. @@ -2882,7 +5659,7 @@ Merge from HEAD. -2011-02-27 Reuben Thomas +2011-02-26 Reuben Thomas In future, make zip distros. @@ -2906,7 +5683,7 @@ Use undocumented package.config to get platform’s directory separator. -2011-02-09 Reuben Thomas +2011-02-08 Reuben Thomas Improve release target to tag releases. @@ -2914,7 +5691,7 @@ Fix missing math. prefix, and swap incorrect sign in sub. Thanks to Bob Chapman. -2010-12-15 Reuben Thomas +2010-12-14 Reuben Thomas Speed up math.floor for case where p is 0 or absent (thanks, Lukáš Procházka). @@ -2948,17 +5725,19 @@ Remove spurious full stop. +2010-10-07 Reuben Thomas + Add catfile and fix catdir to return `/' when necessary. -2010-10-07 Reuben Thomas +2010-10-06 Reuben Thomas Fix permissions. -2010-06-21 rrt +2010-06-20 rrt Remove dubious metamethod fallback for string.__index. -2010-06-14 rrt +2010-06-13 rrt Fix and simplify tree.__newindex: there was a variable name typo, and sub-tables should also be initialised to trees, as otherwise the relevant metamethods are not called. @@ -2983,11 +5762,13 @@ Make the set metatable a local variable. +2010-06-08 rrt + Add Lua distribution’s strict.lua to standard modules. Have a single list of modules in modules.lua and use it to load them in std.lua and generate the single-file version in mk1file, which latter is now a Lua script. -2010-06-08 rrt +2010-06-07 rrt Fix list.foldl, list.foldr, and the fold iterator combinator. Simplify the op table functions to be exactly the primitive operators, @@ -2995,7 +5776,7 @@ (Possibly) improve the commented-out simpler version of treeIter. -2010-06-08 rrt +2010-06-07 rrt Remove table.subscripts function: it’s easily replaced by subscript plus string.split, as in its definition. @@ -3008,7 +5789,7 @@ Improve some documentation. -2010-06-03 rrt +2010-06-02 rrt Remove redundant redefinition of print (it already calls tostring). Fix op table so that base can require list without breaking; fixes @@ -3019,7 +5800,7 @@ Bump copyright year to 2010. -2010-03-19 rrt +2010-03-18 rrt Add missing dependency on list. @@ -3044,7 +5825,7 @@ Add explanatory comment. -2009-09-01 rrt +2009-08-31 rrt Add requirement of posix and copyright notice to output. @@ -3072,6 +5853,8 @@ Simplify assert. +2009-03-15 rrt + Simplify string.format. Remove string.join, which is the same as table.concat. Thanks to David Kantowitz for spotting it. @@ -3130,7 +5913,7 @@ Fix make dist; $REL -> ${REL}, add --exclude for .#*, and no longer exclude template-rrt.lua, which no longer lives in the tree. -2008-06-21 niklas +2008-06-20 niklas Add collect, from Patrick Walton, to run an iterator and collect the results in a table. As a result, rewrite all the table functionals to be iterator @@ -3149,14 +5932,14 @@ Add some TODOs to make the prog structure a bit more sensible. -2008-03-05 rrt +2008-03-04 rrt Make a note to compare pathSplit and pathConcat with Perl equivalents. -2008-03-04 rrt - Add TODO to use LuaDoc instead. +2008-03-03 rrt + Add Makefile with dist target Fix typo in comment. @@ -3167,11 +5950,9 @@ Remove _INTEGER_BITS and unneeded dependency -2008-03-03 rrt - Update date and prerequisites. -2008-03-02 rrt +2008-03-01 rrt Require external deps before neutering "require". @@ -3183,33 +5964,33 @@ Use LFS for length() function. -2008-01-20 niklas +2008-01-19 niklas Add pathSplit and pathConcat from nancy. -2008-01-13 rrt +2008-01-12 rrt Make calls to find and gsub get the function from the pattern, meaning that in theory they could work with other regex engines than Lua's. Remove pointless object notation on a string. -2007-11-20 rrt +2007-11-19 rrt Now that INTEGER_BITS is added to the math namespace, no need to prefix it with _. Note that bitlib is needed. -2007-10-07 rrt +2007-10-06 rrt Rename 'permute' to the more accurate 'rearrange' Update some comments to match changes in the Lua Gem about this code. -2007-10-06 rrt +2007-10-05 rrt Fix from Roberto Ierusalimschy. -2007-05-12 rrt +2007-05-11 rrt Fix up single-file stdlib @@ -3228,26 +6009,26 @@ Revert to plain implementation of length to avoid using POSIX library which is currently unmaintained. +2007-04-25 rrt + Clear up uses of old vararg "arg" syntax (thanks Matt). -2007-03-02 rrt +2007-03-01 rrt Add list.rep Add FIXME for commented-out require -2007-03-01 rrt - Make join cope with empty lists. Remove default separator in string.split, and hence a TODO. Add string.join. -2007-02-26 rrt +2007-02-25 rrt Mention the dependency on lrexlib. -2007-02-25 rrt +2007-02-24 rrt Use __append metamethod, not __concat, which was wrong @@ -3266,9 +6047,11 @@ avoid overflowing the parameter stack (with the unpack) when splitting large strings. Clarify the comment for this code. +2007-02-21 rrt + Fix indexKey and indexValue: the function passed to table.process wasn't returning the accumulator as it should have. -2007-02-21 rrt +2007-02-20 rrt Make a note to find better names for enpair and depair, which are useful but confusing. Something like pairsToTable and tableToPairs? @@ -3276,29 +6059,27 @@ Add missing dirname and basename -2007-01-06 rrt +2007-01-05 rrt Sync with reality. -2007-01-05 rrt +2007-01-04 rrt Document. Set rex = rex_pcre, so that we actually have the functions we expect under "rex". -2007-01-04 rrt - Now that lrexlib no longer has a Lua component or a default library, add a library to load it (currently just require rex_pcre). -2006-12-07 rrt +2006-12-06 rrt Remove TODOs that apply to lrexlib. -2006-11-28 rrt +2006-11-27 rrt Use non-list-capable math.max correctly -2006-11-21 rrt +2006-11-20 rrt Fix from Jerôme Vuarand to string subscription that deals with oldmetas that are functions. @@ -3306,14 +6087,12 @@ Stop string subscription operator from hiding other methods. -2006-11-06 rrt +2006-11-05 rrt Note that rex is now an external dependency. Note problem with external dependencies. -2006-11-05 rrt - Sort out adding to module metatables. Add a FIXME @@ -3346,7 +6125,7 @@ Remove listable and listabled functions. This wasn't really that useful, and could confuse. -2006-11-02 rrt +2006-11-01 rrt Correct @function to @func @@ -3362,7 +6141,7 @@ Fix list.concat (thanks to Avi Yagodnick for reporting the bug). -2006-10-29 niklas +2006-10-28 niklas Remove require loops by commenting out looping requires. This needs fixing properly (by permitting them). Where possible without further change, remove the "std" prefix from @@ -3421,7 +6200,7 @@ table.getn --> # -2006-10-01 rrt +2006-09-30 rrt Remove io.readDir, as it is replaced by posix.dir. @@ -3439,12 +6218,10 @@ Escape square brackets too in string.escapeShell. -2006-04-26 rrt +2006-04-25 rrt Prepend redefinition of require to the output. -2006-04-25 rrt - Use string methods rather than functions so that the functions here work on regexs as well. Add a note to make the whole API work properly with regexs as well as Lua patterns. Add TODO @@ -3470,7 +6247,7 @@ Remove unnecessary local line from gmatch, and initialise st to 1, not 0 (thanks to Shmuel Zeigerman). -2006-04-10 rrt +2006-04-09 rrt Reorganise libraries with simpler names @@ -3490,7 +6267,7 @@ Rename algorithm.lcs to lcs -2006-04-10 rrt +2006-04-09 rrt Rewrite string.split to be regex-system-neutral. Change string.findl to return from and to in list form, not {from = f, @@ -3541,7 +6318,7 @@ Add module calls everywhere, and do some necessary renaming to avoid clashes -2006-03-23 rrt +2006-03-22 rrt Use module and require in properly 5.1-compatible way, and change module names to work better with 5.1. This should all still work fine with 5.0 using compat-5.1.lua. @@ -3550,7 +6327,7 @@ More fixes and tests from Shmuel Zeigerman. -2006-01-29 rrt +2006-01-28 rrt Add tests from Shmuel Zeigerman, reorganised somewhat. They are run when the module is loaded. @@ -3560,12 +6337,10 @@ More fixes from Shmuel to mimic string.gsub better. -2006-01-25 rrt +2006-01-24 rrt Fix endless loop when pattern is .* (bug reported by Shmuel Zeigerman). -2006-01-24 rrt - Cope with capture being false (Shmuel Zeigerman). Fix bug when n == 0 (thanks Shmuel Zeigerman), and tidy up. @@ -3574,44 +6349,40 @@ Fix from Shmuel Zeigerman to match string.gsub better: when the pattern contains no captures, pass the entire match to the replacement function. -2006-01-22 rrt +2006-01-21 rrt More bug fixes; thanks to Shmuel Zeigerman for reporting the bugs and in one case giving the fix. -2006-01-21 rrt - Fix bugs with %n replacements in rex.gsub Make rex.gsub a full gsub for rex. -2006-01-20 rrt +2006-01-19 rrt Don't escape & in entities Improve rex.gsub -2006-01-17 rrt +2006-01-16 rrt Escape <, > and & in XML output. -2005-11-24 rrt +2005-11-23 rrt Replace deepipairs with treeIter to iterate properly over trees. -2005-11-23 rrt +2005-11-22 rrt Remove table.filterItem, as it really only works for lists. Inline the function in list.filter. Add table.map. -2005-11-22 rrt - Add XML output, assuming Lua tables created by luaexpat. 2005-11-21 rrt Add generic printing framework, and use it to add prettytostring. -2005-11-19 rrt +2005-11-18 rrt Use table.process to implement list processing functions. @@ -3648,7 +6419,7 @@ Check error return when loading file, so that if file is not found we don't abort immediately so that all LUA_PATH entries are checked. -2004-02-05 rrt +2004-02-04 rrt Tidy up abstract syntax rules: there's now only one per production. Keep action functions for more complex rules. Looks as though we only @@ -3661,19 +6432,19 @@ Return false instead of nil for empty parse trees, so as not to upset ipairs iterations over lists. -2004-02-05 rrt +2004-02-04 rrt Tidy up the code, mostly by shortening the names of frequently-used variables. Allow import to report errors during importing. -2004-02-04 rrt +2004-02-03 rrt Added Diego Nahab for his mbox parser. Added Diego Nahab's mbox parser. -2004-02-04 rrt +2004-02-03 rrt Rework the API: now has a single method exposed, parse, and the other methods have been moved inside parse as local functions. The constructor no longer takes a token list. Also, provide support for producing an abstract parse tree rather than @@ -3681,11 +6452,11 @@ Full details in the all-new documentation. -2004-02-04 rrt +2004-02-03 rrt Clarify note about import and add TODO about markup tags. -2004-02-02 rrt +2004-02-01 rrt Massacre the object implementation, reverting to implementing sets as simple tables, which seems to be better for general use. A lot of the code in this file is now non-functional; I'll be making it work later, integrating it with Jamie Webb's code. The module may get folded back into table. @@ -3701,7 +6472,7 @@ Various modifications prompted by Jamie Webb's submission of his own standard library. So far I have assimilated improvements that map directly on to existing code, and also removed some functions that didn't seem to be that useful. Looking at the code again provoked other miscellaneous improvements. -2004-02-01 rrt +2004-01-31 rrt In the previous commit, which had a bogus log message, I fixed io.readDir: split --> string.split. In this one, I improved the formatting of io.readDir slightly. @@ -3725,11 +6496,9 @@ Add math.floor and math.round, based on code from Johann Hibschman. -2004-01-31 rrt - Fix pickle: format->string.format (thanks to Johann Hibschman). -2004-01-29 rrt +2004-01-28 rrt Default the from and to parameters of list.slice to the start and end of the list respectively. @@ -3768,19 +6537,19 @@ More Lua 5 tweaks, and a couple of minor bugfixes. -2003-10-21 rrt +2003-10-20 rrt Oops; added file with incorrect name; re-add with correct name. Add "import" from LTN 11 to overcome require's problem with circular dependencies. Remove string.next, as string.gfind provides an equivalent iterator. -2003-10-20 rrt - More renaming for consistency, and move more code around. This introduced the first cyclic dependency between modules since I moved to Lua 5, and I've had to cure this with a C include-style trick, since Lua 5 require just overflows the stack when there's a recursive call of require. Add an iterator for the values in a set, and use it; methods are now organised into those that access the data structure and those that call other methods. +2003-10-19 rrt + Objectify the implementation, and add LuaDoc-style markup to the comments. Write methods outside object prototype (i.e. in more consistent form for stdlib). @@ -3813,9 +6582,11 @@ Renamed some libraries for Lua 5-ification reasons. +2003-10-17 rrt + Fix a minor bug and remove some debugging code. -2003-10-18 rrt +2003-10-17 rrt A new module (and family): algorithm, with first member algorithm.lcs, which implements the longest common subsequence algorithm needed for diff. std.object has been reworked, and now fits much better with Lua 5, @@ -3828,19 +6599,19 @@ Fix call to writeLine (now io.writeLine). -2003-09-28 rrt +2003-09-27 rrt More Lua 5-ification changes, mostly to the io modules this time. -2003-09-26 uid30086 +2003-09-25 uid30086 Another round of changes for Lua 5-ification. This completes the changes to the string library (used to be the text library), and adds std.rex (complements my C rex library). Other changes are mostly to accomodate this; a few extras have snuck in. -2003-09-25 rrt +2003-09-24 rrt First set of changes moving to Lua 5-like naming conventions for the libraries. -2003-09-15 rrt +2003-09-14 rrt Use math.mod rather than bit.mod for wider compatibility. @@ -3854,17 +6625,17 @@ Another few search-and-replace function names to update to Lua 5. Mostly string functions this time. -2003-09-10 rrt +2003-09-09 rrt More search-and-replace and wholesale code removal (notably POSIX getopt) for Lua 5. Another swathe of Lua 5 updates. Now my little script that I'm testing nearly works, which means that quite a lot of the code in the libraries is at least vaguely correct! -2003-09-09 rrt +2003-09-08 rrt A slew of updates in the march to Lua-5-ify the libraries. I've just been working on a particular small script and changing things "on demand", and I've not even managed to make the script work yet, so there's almost certainly a lot of work still to go. -2003-06-04 rrt +2003-06-03 rrt Convert to Lua 5.0, and some slight tidying. @@ -3874,15 +6645,15 @@ Make readDir return an unsorted list of files. Unfortunately, -U isn't supported by ls on all platforms. -2003-03-14 rrt +2003-03-13 rrt Update to match new directory structure (rather overdue!). -2003-01-06 rrt +2003-01-05 rrt Use endOfLine in chomp and wrap. -2002-10-18 rrt +2002-10-17 rrt Removed std.logic; now folded into std.data.logic @@ -3902,12 +6673,14 @@ Revert to previous version to avoid losing precision (specifically, LSB). +2002-09-09 rrt + Shorter implementation of bxor, and bnot thanks to a remark by Paul Hsieh on lual (Message-Id: <0H26009OMQ9J59@mta5.snfc21.pbi.net>). Kept band (as the primitive to make bxor) and bor (because de Morganising it would involve a call to bnot and two to band, hence making it three times slower). -2002-09-09 rrt +2002-09-08 rrt Poor man's logic functions (for those who can't use bitlib). Also calculate the number of bits in the word. @@ -3996,6 +6769,8 @@ Rename std->modules and remove stray std.lua +2002-08-14 rrt + Standardize code style, and make changes (mostly to the comments) to prepare for renaming to std.config, as per John's suggestion. This file will only secondarily contain require, and will typically be built into the Lua system anyway. When we move to Lua 5.0, require will disappear, anyway. John Belmonte's replacement require implementation (5.0-compatible). @@ -4026,6 +6801,8 @@ Correct punctuation. +2002-08-12 rrt + Fix a typo loading pickle.lua in text.lua Make pickle escape characters in strings that need it @@ -4036,8 +6813,6 @@ Fix spacing in comments. -2002-08-12 rrt - Allow new tostring methods to be registered. *** empty log message *** @@ -4060,13 +6835,13 @@ Move print from assert to debug. This not only makes sense, but breaks a recursive dependency between assert and text/text. -2002-07-31 rrt +2002-07-30 rrt Remove require for now-defunct time.lua, and tidy up the TODOs. Correct endofLine -> endOfLine again; this must have crept back in with the last diff. Using CVS everywhere rather than manual copying will be a Good Thing in this respect! -2002-07-30 rrt +2002-07-29 rrt Generalised daySuffix to ordinalSuffix. Still English-specific :-( diff --git a/GNUmakefile b/GNUmakefile index 307d9a6..f477d0a 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,6 +1,6 @@ # Maintainer rules. # -# Copyright (C) 2013-2014 Gary V. Vaughan +# Copyright (C) 2013-2015 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # # This program is free software; you can redistribute it and/or modify it diff --git a/Makefile.am b/Makefile.am index d707341..eb5bd80 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # Non-recursive Make rules. # -# Copyright (C) 2013-2014 Gary V. Vaughan +# Copyright (C) 2013-2015 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # # This program is free software; you can redistribute it and/or modify it @@ -24,6 +24,8 @@ LUA_PATH ?= ; LUA_CPATH ?= ; +SPECL_ENV = + ## ---------- ## ## Bootstrap. ## @@ -50,8 +52,10 @@ check_local = dist_bin_SCRIPTS = dist_lua_DATA = doc_DATA = -install_exec_hooks = +install_exec_hooks = remove-luaexec-lafiles +uninstall_hooks = uninstall-luaexec-modules lib_LTLIBRARIES = +luaexec_LTLIBRARIES = man_MANS = save_release_files = @@ -71,3 +75,30 @@ check-local: $(check_local) ## ------------- ## install-exec-hook: $(install_exec_hooks) + +# Neither Lua itself, nor LuaRocks can use .la files, and LuaRocks +# actually moves such files aside anyway, so we just remove them from +# the installation directory. +remove-luaexec-lafiles: + @for la in $(luaexec_LTLIBRARIES); do \ + f=`echo "$$la" |sed 's|^.*/||'`; \ + echo rm -f $(luaexecdir)/$$f; \ + rm -f $(luaexecdir)/$$f; \ + done + + +## --------------- ## +## Uninstallation. ## +## --------------- ## + +uninstall-hook: $(uninstall_hooks) + +# We removed the .la files from luaexecdir, so the standard uninstall, +# with libtool --mode=uninstall, can't find everything anymore. +uninstall-luaexec-modules: + @for la in $(luaexec_LTLIBRARIES); do \ + base=`echo "$$la" \ + |sed 's|^.*/\(.*\)\.la|\1|'`; \ + echo rm -f $(luaexecdir)/$$base.so; \ + rm -f $(luaexecdir)/$$base.so; \ + done diff --git a/Makefile.in b/Makefile.in index 4593e03..12b6d44 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ # Non-recursive Make rules. # -# Copyright (C) 2013-2014 Gary V. Vaughan +# Copyright (C) 2013-2015 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # # This program is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ # Local Make rules. # -# Copyright (C) 2013-2014 Gary V. Vaughan +# Copyright (C) 2013-2015 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # # This program is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ # terms of the MIT license reproduced below. # ==================================================================== # -# Copyright (C) 2013-2014 Gary V. Vaughan # +# Copyright (C) 2013-2015 Gary V. Vaughan # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation # @@ -89,7 +89,7 @@ # terms of the MIT license reproduced below. # ==================================================================== # -# Copyright (C) 2013-2014 Reuben Thomas and Gary V. Vaughan # +# Copyright (C) 2013-2015 Reuben Thomas and Gary V. Vaughan # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation # @@ -184,26 +184,22 @@ DIST_COMMON = $(srcdir)/local.mk $(srcdir)/specs/specs.mk \ $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk \ INSTALL NEWS README AUTHORS ChangeLog $(srcdir)/Makefile.in \ $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(srcdir)/travis.yml.in \ - $(top_srcdir)/build-aux/config.ld.in \ - $(top_srcdir)/specs/spec_helper.lua.in $(dist_bin_SCRIPTS) \ - $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ - $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ + $(am__configure_deps) $(top_srcdir)/build-aux/config.ld.in \ + $(dist_bin_SCRIPTS) $(dist_classes_DATA) $(dist_doc_DATA) \ + $(dist_lua_DATA) $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ $(dist_modules_DATA) COPYING build-aux/install-sh \ build-aux/missing $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ - $(top_srcdir)/m4/ax_lua.m4 $(top_srcdir)/m4/slingshot.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lua.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = .travis.yml build-aux/config.ld \ - specs/spec_helper.lua +CONFIG_CLEAN_FILES = build-aux/config.ld CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -232,12 +228,13 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" \ - "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" \ - "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" \ - "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)" -LTLIBRARIES = $(lib_LTLIBRARIES) +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(luaexecdir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" \ + "$(DESTDIR)$(luastddebugdir)" "$(DESTDIR)$(modulesdir)" \ + "$(DESTDIR)$(docdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) $(luaexec_LTLIBRARIES) SCRIPTS = $(bin_SCRIPTS) $(dist_bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -292,7 +289,6 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -EXTRA_ROCKS = @EXTRA_ROCKS@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ @@ -368,9 +364,13 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +SPECL_ENV = LUA='$(LUA)' abs_top_builddir='$(abs_top_builddir)' \ + abs_top_srcdir='$(abs_top_srcdir)' \ + top_builddir='$(top_builddir)' top_srcdir='$(top_srcdir)' \ + $(NOTHING_ELSE) ACLOCAL_AMFLAGS = -I m4 AM_CPPFLAGS = $(LUA_INCLUDE) -EXTRA_DIST = $(srcdir)/specs/spec_helper.lua.in $(NOTHING_ELSE) \ +EXTRA_DIST = $(srcdir)/specs/spec_helper.lua $(NOTHING_ELSE) \ $(specl_SPECS) $(NOTHING_ELSE) build-aux/config.ld.in \ lib/std.lua.in $(NOTHING_ELSE) $(mkrockspecs) \ $(package_rockspec) $(rockspec_conf) $(NOTHING_ELSE) @@ -384,13 +384,15 @@ check_local = specl-check-local dist_bin_SCRIPTS = dist_lua_DATA = lib/std.lua $(NOTHING_ELSE) doc_DATA = -install_exec_hooks = +install_exec_hooks = remove-luaexec-lafiles +uninstall_hooks = uninstall-luaexec-modules lib_LTLIBRARIES = +luaexec_LTLIBRARIES = man_MANS = save_release_files = $(scm_rockspec) -std_path = $(abs_srcdir)/lib/?.lua +std_path = $(abs_srcdir)/lib/?.lua;$(abs_srcdir)/lib/?/init.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = 606609f9586288cfe6d9df676719570a +old_NEWS_hash = d41d8cd98f00b204e9800998ecf8427e update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ UPDATE_COPYRIGHT_USE_INTERVALS=1 \ @@ -411,15 +413,13 @@ dist_modules_DATA = $(srcdir)/doc/modules/std.html \ $(srcdir)/doc/modules/std.functional.html \ $(srcdir)/doc/modules/std.io.html \ $(srcdir)/doc/modules/std.math.html \ + $(srcdir)/doc/modules/std.operator.html \ $(srcdir)/doc/modules/std.package.html \ $(srcdir)/doc/modules/std.strict.html \ $(srcdir)/doc/modules/std.string.html \ $(srcdir)/doc/modules/std.table.html $(NOTHING_ELSE) -specs_path = $(abs_builddir)/specs/?.lua -SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" LUA_INIT= LUA_INIT_5_2= SPECL_OPTS = --unicode specl_SPECS = \ - $(srcdir)/specs/base_spec.yaml \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ $(srcdir)/specs/functional_spec.yaml \ @@ -427,6 +427,7 @@ specl_SPECS = \ $(srcdir)/specs/list_spec.yaml \ $(srcdir)/specs/math_spec.yaml \ $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/operator_spec.yaml \ $(srcdir)/specs/optparse_spec.yaml \ $(srcdir)/specs/package_spec.yaml \ $(srcdir)/specs/set_spec.yaml \ @@ -447,6 +448,7 @@ dist_luastd_DATA = \ lib/std/list.lua \ lib/std/math.lua \ lib/std/object.lua \ + lib/std/operator.lua \ lib/std/optparse.lua \ lib/std/package.lua \ lib/std/set.lua \ @@ -461,8 +463,8 @@ dist_luastd_DATA = \ # For bugwards compatibility with LuaRocks 2.1, while ensuring that # `require "std.debug_init"` continues to work, we have to install # the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. -# When everyone has upgraded to a LuaRocks that works, move this -# file back to dist_luastd_DATA above and rename to debug_init.lua. +# When LuaRocks works again, move this file back to dist_luastd_DATA +# above and rename to debug_init.lua. luastddebugdir = $(luastddir)/debug_init dist_luastddebug_DATA = \ lib/std/debug_init/init.lua \ @@ -529,12 +531,8 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): -.travis.yml: $(top_builddir)/config.status $(srcdir)/travis.yml.in - cd $(top_builddir) && $(SHELL) ./config.status $@ build-aux/config.ld: $(top_builddir)/config.status $(top_srcdir)/build-aux/config.ld.in cd $(top_builddir) && $(SHELL) ./config.status $@ -specs/spec_helper.lua: $(top_builddir)/config.status $(top_srcdir)/specs/spec_helper.lua.in - cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @@ -570,6 +568,41 @@ clean-libLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } + +install-luaexecLTLIBRARIES: $(luaexec_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(luaexec_LTLIBRARIES)'; test -n "$(luaexecdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(luaexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(luaexecdir)" || exit 1; \ + echo " $(INSTALL) $(INSTALL_STRIP_FLAG) $$list '$(DESTDIR)$(luaexecdir)'"; \ + $(INSTALL) $(INSTALL_STRIP_FLAG) $$list "$(DESTDIR)$(luaexecdir)"; \ + } + +uninstall-luaexecLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(luaexec_LTLIBRARIES)'; test -n "$(luaexecdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(luaexecdir)/$$f'"; \ + rm -f "$(DESTDIR)$(luaexecdir)/$$f"; \ + done + +clean-luaexecLTLIBRARIES: + -test -z "$(luaexec_LTLIBRARIES)" || rm -f $(luaexec_LTLIBRARIES) + @list='$(luaexec_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ @@ -962,7 +995,7 @@ check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(luaexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -1000,7 +1033,8 @@ maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am -clean-am: clean-generic clean-libLTLIBRARIES mostlyclean-am +clean-am: clean-generic clean-libLTLIBRARIES clean-luaexecLTLIBRARIES \ + mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -1029,7 +1063,7 @@ install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binSCRIPTS install-dist_binSCRIPTS \ - install-libLTLIBRARIES + install-libLTLIBRARIES install-luaexecLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am @@ -1074,41 +1108,43 @@ uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ uninstall-dist_classesDATA uninstall-dist_docDATA \ uninstall-dist_luaDATA uninstall-dist_luastdDATA \ uninstall-dist_luastddebugDATA uninstall-dist_modulesDATA \ - uninstall-docDATA uninstall-libLTLIBRARIES - -.MAKE: check-am install-am install-exec-am install-strip + uninstall-docDATA uninstall-libLTLIBRARIES \ + uninstall-luaexecLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: check-am install-am install-exec-am install-strip uninstall-am .PHONY: all all-am am--refresh check check-am check-local clean \ - clean-generic clean-libLTLIBRARIES cscopelist-am ctags-am dist \ - dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ - dist-xz dist-zip distcheck distclean distclean-generic \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-binSCRIPTS \ - install-data install-data-am install-dist_binSCRIPTS \ + clean-generic clean-libLTLIBRARIES clean-luaexecLTLIBRARIES \ + cscopelist-am ctags-am dist dist-all dist-bzip2 dist-gzip \ + dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \ + distclean distclean-generic distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binSCRIPTS install-data \ + install-data-am install-dist_binSCRIPTS \ install-dist_classesDATA install-dist_docDATA \ install-dist_luaDATA install-dist_luastdDATA \ install-dist_luastddebugDATA install-dist_modulesDATA \ install-docDATA install-dvi install-dvi-am install-exec \ install-exec-am install-exec-hook install-html install-html-am \ install-info install-info-am install-libLTLIBRARIES \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ - uninstall uninstall-am uninstall-binSCRIPTS \ - uninstall-dist_binSCRIPTS uninstall-dist_classesDATA \ - uninstall-dist_docDATA uninstall-dist_luaDATA \ - uninstall-dist_luastdDATA uninstall-dist_luastddebugDATA \ - uninstall-dist_modulesDATA uninstall-docDATA \ - uninstall-libLTLIBRARIES + install-luaexecLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ + uninstall-dist_classesDATA uninstall-dist_docDATA \ + uninstall-dist_luaDATA uninstall-dist_luastdDATA \ + uninstall-dist_luastddebugDATA uninstall-dist_modulesDATA \ + uninstall-docDATA uninstall-hook uninstall-libLTLIBRARIES \ + uninstall-luaexecLTLIBRARIES LUA_PATH ?= ; LUA_CPATH ?= ; - -specl-check-local: specs/spec_helper.lua specl-check-local: $(specl_SPECS) - $(SPECL_ENV) LUA=$(LUA) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) + $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to @@ -1159,6 +1195,28 @@ check-local: $(check_local) install-exec-hook: $(install_exec_hooks) +# Neither Lua itself, nor LuaRocks can use .la files, and LuaRocks +# actually moves such files aside anyway, so we just remove them from +# the installation directory. +remove-luaexec-lafiles: + @for la in $(luaexec_LTLIBRARIES); do \ + f=`echo "$$la" |sed 's|^.*/||'`; \ + echo rm -f $(luaexecdir)/$$f; \ + rm -f $(luaexecdir)/$$f; \ + done + +uninstall-hook: $(uninstall_hooks) + +# We removed the .la files from luaexecdir, so the standard uninstall, +# with libtool --mode=uninstall, can't find everything anymore. +uninstall-luaexec-modules: + @for la in $(luaexec_LTLIBRARIES); do \ + base=`echo "$$la" \ + |sed 's|^.*/\(.*\)\.la|\1|'`; \ + echo rm -f $(luaexecdir)/$$base.so; \ + rm -f $(luaexecdir)/$$base.so; \ + done + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/NEWS b/NEWS index fbfcf80..7284b9d 100644 --- a/NEWS +++ b/NEWS @@ -1,771 +1,1167 @@ -Stdlib NEWS - User visible changes +# Stdlib NEWS - User visible changes -* Noteworthy changes in release 40 (2014-05-01) [stable] +## Noteworthy changes in release 41.0.0 (2015-01-03) [beta] -** New features: +### New features - - `functional.memoize` now accepts a user normalization function, - falling back on `string.tostring` otherwise. + - Preliminary Lua 5.3.0 compatibility. - - `table.merge` now supports `map` and `nometa` arguments orthogonally - to `table.clone`. + - `object.prototype` now reports "file" for open file handles, and + "closed file" for closed file handles. - - New `table.merge_select` function, orthogonal to - `table.clone_select`. See LDocs for details. + - New `debug.argerror` and `debug.argcheck` functions that provide Lua + equivalents of `luaL_argerror` and `luaL_argcheck`. -** Incompatible changes: + - New `debug.argscheck` function for checking all function parameter + types with a single function call in the common case. - - Core methods and metamethods are no longer monkey patched by default - when you `require "std"` (or `std.io`, `std.math`, `std.string` or - `std.table`). Instead they provide a new `monkey_patch` method you - should use when you don't care about interactions with other - modules: + - New `debug.export` function, which returns a wrapper function for + checking all arguments of an inner function against a type list. - local io = require "std.io".monkey_patch () + - New `_DEBUG.argcheck` field that disables `debug.argcheck`, and + changes `debug.argscheck` to return its function argument unwrapped, + for production code. Similarly `_DEBUG = false` deactivates these + functions in the same way. - To install all of stdlib's monkey patches, the `std` module itself - has a `monkey_patch` method that loads all submodules with their own - `monkey_patch` method and runs them all. + - New `std.operator` module, with easier to type operator names (`conj`, + `deref`, `diff`, `disj`, `eq`, `neg`, `neq`, `prod`, `quot`, and `sum`), + and a functional operator for concatenation `concat`; plus new mathematical + operators `mod`, and `pow`; and relational operators `lt`, `lte`, `gt` and + `gte`. - If you want full compatibility with the previous release, in addition - to the global namespace scribbling snippet above, then you need to - adjust the first line to: + - `functional.case` now accepts non-callable branch values, which are + simply returned as is, and functable values which are called and + their return value propagated back to the case caller. Function + values behave the same as in previous releases. - local std = require "std".monkey_patch () + - `functional.collect`, `functional.filter`, `functional.map` and + `functional.reduce` now work with standard multi-return iterators, + such as `std.pairs`. - - The global namespace is no longer clobbered by `require "std"`. To - get the old behaviour back: + - `functional.collect` defaults to using `std.ipairs` as an iterator. - local std = require "std".barrel (_G) + - New `functional.cond`, for evaluating multiple distinct expressions + to determine what following value to be the returned. - This will execute all available monkey_patch functions, and then - scribble all over the `_G` namespace, just like the old days. + - `functional.filter` and `functional.map` default to using `std.pairs` + as an iterator. - - The `metamethod` call is no longer in `std.functional`, but has moved - to `std.table` where it properly belongs. It is a utility method for - tables and has nothing to do with functional programming. + - The init argument to `functional.foldl` and `functional.foldr` is now + optional; when omitted these functions automatically start with + the left- or right-most element of the table argument resp. - - The following deprecated camelCase names have been removed, you - should update your code to use the snake_case equivalents: - `std.io.processFiles`, `std.list.indexKey`, `std.list.indexValue`, - `std.list.mapWith`, `std.list.zipWith`, `std.string.escapePattern`, - `std.string. escapeShell`, `std.string.ordinalSuffix`. + - New `functional.callable` function for unwrapping objects or + primitives that can be called as if they were a function. - - The following deprecated function names have been removed: - `std.list.new` (call `std.list` directly instead), - `std.list.slice` (use `std.list.sub` instead), - `std.set.new` (call `std.set` directly instead), - `std.strbuf.new` (call `std.strbuf` directly instead), and - `std.tree.new` (call `std.tree` directly instead). + - New `functional.lambda` function for compiling lambda strings: -** Bug fixes: + ```lua + table.sort (t, lambda "|a,b| a + explaining why any deprecation should be reinstated or at least kept + around for more than 1 year. + + - By default, deprecated APIs will issue a warning to stderr on every + call. However, in production code, you can turn off these warnings + entirely with any of: + + ```lua + _DEBUG = false + _DEBUG = { deprecate = false } + require "std.debug_init".deprecate = false + ``` + + Or, to confirm you're not trying to call a deprecated function at + runtime, you can prevent deprecated functions from being defined at + all with any of: + + ```lua + _DEBUG = true + _DEBUG = { deprecate = true } + require "std.debug_init".deprecate = true + ``` + + The `_DEBUG` global must be set before requiring any stdlib modules, + but you can adjust the fields in the `std.debug_init` table at any + time. + + - `functional.eval` has been moved to `std.eval`, the old name now + gives a deprecation warning. + + - `functional.fold` has been renamed to `functional.reduce`, the old + name now gives a deprecation warning. + + - `functional.op` has been moved to a new `std.operator` module, the + old function names now gives deprecation warnings. + + - `list.depair` and `list.enpair` have been moved to `table.depair` and + `table.enpair`, the old names now give deprecation warnings. + + - `list.filter` has been moved to `functional.filter`, the old name now + gives a deprecation warning. + + - `list.flatten` has been moved to `table.flatten`, the old name now + gives a deprecation warning. + + - `list.foldl` and `list.foldr` have been replaced by the richer + `functional.foldl` and `functional.foldr` respectively. The old + names now give a deprecation warning. Note that List object methods + `foldl` and `foldr` are not affected. + + - `list.index_key` and `list.index_value` have been deprecated. These + functions are not general enough to belong in lua-stdlib, because + (among others) they only work correctly with tables that can be + inverted without loss of key values. They currently give deprecation + warnings. + + - `list.map` and `list.map_with` has been deprecated, in favour of the + more powerful new `functional.map` and `functional.map_with` which + handle tables as well as lists. + + - `list.project` has been deprecated in favour of `table.project`, the + old name now gives a deprecation warning. + + - `list.relems` has been deprecated, in favour of the more idiomatic + `functional.compose (std.ireverse, std.ielems)`. + + - `list.reverse` has been deprecated in favour of the more general + and more accurately named `std.ireverse`. + + - `list.shape` has been deprecated in favour of `table.shape`, the old + name now gives a deprecation warning. + + - `list.transpose` has been deprecated in favour of `functional.zip`, + see above for details. + + - `list.zip_with` has been deprecated in favour of `functional.zip_with`, + see above for details. + + - `string.assert` has been moved to `std.assert`, the old name now + gives a deprecation warning. + + - `string.require_version` has been moved to `std.require`, the old + name now gives a deprecation warning. + + - `string.tostring` has been moved to `std.tostring`, the old name now + gives a deprecation warning. + + - `table.metamethod` has been moved to `std.getmetamethod`, the old + name now gives a deprecation warning. + + - `table.ripairs` has been moved to `std.ripairs`, the old name now + gives a deprecation warning. + + - `table.totable` has been deprecated and now gives a warning when used. + +### Incompatible changes + + - `std.monkey_patch` works the same way as the other submodule + monkey_patch functions now, by injecting its methods into the given + (or global) namespace. To get the previous effect of running all the + monkey_patch functions, either run them all manually, or call + `std.barrel ()` as before. + + - `functional.bind` sets fixed positional arguments when called as + before, but when the newly bound function is called, those arguments + fill remaining unfixed positions rather than being overwritten by + original fixed arguments. For example, where this would have caused + an error previously, it now prints "100" as expected. + + ```lua + local function add (a, b) return a + b end + local incr = functional.bind (add, {1}) + print (incr (99)) + ``` + + If you have any code that calls functions returned from `bind`, you + need to remove the previously ignored arguments that correspond to + the fixed argument positions in the `bind` invocation. + + - `functional.collect`, `functional.filter` and `functional.map` still + make a list from the results from an iterator that returns single + values, but when an iterator returns multiple values they now make a + table with key:value pairs taken from the first two returned values of + each iteration. + + - The `functional.op` table has been factored out into its own new + module `std.operator`. It will also continue to be available from the + legacy `functional.op` access point for the forseeable future. + + - The `functional.op[".."]` operator is no longer a list concatenation + only loaded when `std.list` is required, but a regular string + concatenation just like Lua's `..` operator. + + - `io.catdir` now raises an error when called with no arguments, for + consistency with `io.catfile`. + + - `io.die` no longer calls `io.warn` to write the error message to + stderr, but passes that error message to the core `error` function. + + - `std.set` objects used to be lax about enforcing type correctness in + function arguments, but now that we have strict type-checking on all + apis, table arguments are not coerced to Set objects but raise an + error. Due to an accident of implementation, you can get the old + inconsistent behaviour back for now by turning off type checking + before loading any stdlib modules: + + ```lua + _DEBUG = { argcheck = false } + local set = require "std.set" + ``` + + - `string.pad` will still (by implementation accident) coerce non- + string initial arguments to a string using `string.tostring` as long + as argument checking is disabled. Under normal circumstances, + passing a non-string will now raise an error as specified in the api + documentation. + + - `table.totable` is deprecated, and thus objects no longer provide or + use a `__totable` metamethod. Instead, using a `__pairs` metamethod + to return key/value pairs, and that will automatically be used by + `__tostring`, `object.mapfields` etc. The base object now provides a + `__pairs` metamethod that returns key/value pairs in order, and + ignores private fields. If you have objects that relied on the + previous treatment of `__totable`, please convert them to set a + custom `__pairs` instead. + + +### Bug fixes + + - Removed LDocs for unused `_DEBUG.std` field. + + - `debug.trace` works with Lua 5.2.x again. + + - `list:foldr` works again instead of raising a "bad argument #1 to + 'List'" error. + + - `list.transpose` works again, and handles empty lists without + raising an error; but is deprecated and will be removed in a future + release (see above). + + - `list.zip_with` no longer raises an argument error on every call; but, + like `list.transpose`, is also deprecated (see above). + + - `optparse.on` now works with `std.strict` enabled. + + - `std.require` (nee `string.require_version`) now extracts the last + substring made entirely of digits and periods from the required + module's version string before splitting on period. That means, for + version strings like luaposix's "posix library for Lua 5.2 / 32" we + now correctly compare just the numeric part against specified version + range rather than an ASCII comparison of the whole thing as before! + + - The documentation now correcly notes that `std.require` looks + first in `module.version` and then `module._VERSION` to match the + long-standing implementation. + + - `string.split` now really does split on whitespace when no split + pattern argument is provided. Also, the documentation now + correctly cites `%s+` as the default whitespace splitting pattern + (not `%s*` which splits between every non-whitespace character). + + +## Noteworthy changes in release 40 (2014-05-01) [stable] + +### New features + + - `functional.memoize` now accepts a user normalization function, + falling back on `string.tostring` otherwise. + + - `table.merge` now supports `map` and `nometa` arguments orthogonally + to `table.clone`. + + - New `table.merge_select` function, orthogonal to + `table.clone_select`. See LDocs for details. + +### Incompatible changes + + - Core methods and metamethods are no longer monkey patched by default + when you `require "std"` (or `std.io`, `std.math`, `std.string` or + `std.table`). Instead they provide a new `monkey_patch` method you + should use when you don't care about interactions with other + modules: + + ```lua + local io = require "std.io".monkey_patch () + ``` + + To install all of stdlib's monkey patches, the `std` module itself + has a `monkey_patch` method that loads all submodules with their own + `monkey_patch` method and runs them all. + + If you want full compatibility with the previous release, in addition + to the global namespace scribbling snippet above, then you need to + adjust the first line to: + + ```lua + local std = require "std".monkey_patch () + ``` + + - The global namespace is no longer clobbered by `require "std"`. To + get the old behaviour back: + + ```lua + local std = require "std".barrel (_G) + ``` + + This will execute all available monkey_patch functions, and then + scribble all over the `_G` namespace, just like the old days. + + - The `metamethod` call is no longer in `std.functional`, but has moved + to `std.table` where it properly belongs. It is a utility method for + tables and has nothing to do with functional programming. + + - The following deprecated camelCase names have been removed, you + should update your code to use the snake_case equivalents: + `std.io.processFiles`, `std.list.indexKey`, `std.list.indexValue`, + `std.list.mapWith`, `std.list.zipWith`, `std.string.escapePattern`, + `std.string. escapeShell`, `std.string.ordinalSuffix`. + + - The following deprecated function names have been removed: + `std.list.new` (call `std.list` directly instead), + `std.list.slice` (use `std.list.sub` instead), + `std.set.new` (call `std.set` directly instead), + `std.strbuf.new` (call `std.strbuf` directly instead), and + `std.tree.new` (call `std.tree` directly instead). + +### Bug fixes + + - Allow `std.object` derived tables as `std.tree` keys again. + + +## Noteworthy changes in release 39 (2014-04-23) [stable] + +### New features + + - New `std.functional.case` function for rudimentary case statements. + The main difference from serial if/elseif/end comparisons is that + `with` is evaluated only once, and then the match function is looked + up with an O(1) table reference and function call, as opposed to + hoisting an expression result into a temporary variable, and O(n) + comparisons. + + The function call overhead is much more significant than several + comparisons, and so `case` is slower for all but the largest series + of if/elseif/end comparisons. It can make your code more readable, + however. + + See LDocs for usage. + + - New pathstring management functions in `std.package`. + + Manage `package.path` with normalization, duplicate removal, + insertion & removal of elements and automatic folding of '/' and '?' + onto `package.dirsep` and `package.path_mark`, for easy addition of + new paths. For example, instead of all this: + + ```lua + lib = std.io.catfile (".", "lib", package.path_mark .. ".lua") + paths = std.string.split (package.path, package.pathsep) + for i, path in ipairs (paths) do + -- ... lots of normalization code... + end + i = 1 + while i <= #paths do + if paths[i] == lib then + table.remove (paths, i) + else + i = i + 1 + end + end + table.insert (paths, 1, lib) + package.path = table.concat (paths, package.pathsep) + ``` + + You can now write just: + + ```lua + package.path = package.normalize ("./lib/?.lua", package.path) + ``` + + - `std.optparse:parse` accepts a second optional parameter, a table of + default option values. + + - `table.clone` accepts an optional table of key field renames in the + form of `{oldkey = newkey, ...}` subsuming the functionality of + `table.clone_rename`. The final `nometa` parameter is supported + whether or not a rename map is given: + + ```lua + r = table.clone (t, "nometa") + r = table.clone (t, {oldkey = newkey}, "nometa") + ``` + +### Deprecations + + - `table.clone_rename` now gives a warning on first call, and will be + removed entirely in a few releases. The functionality has been + subsumed by the improvements to `table.clone` described above. + +### Bug fixes + + - `std.optparse` no longer throws an error when it encounters an + unhandled option in a combined (i.e. `-xyz`) short option string. + + - Surplus unmapped fields are now discarded during object cloning, for + example when a prototype has `_init` set to `{ "first", "second" }`, + and is cloned using `Proto {'one', 'two', 'three'}`, then the + unmapped `three` argument is now discarded. + + - The path element returned by `std.tree.nodes` can now always be + used as a key list to dereference the root of the tree, particularly + `tree[{}]` now returns the root node of `tree`, to match the initial + `branch` and final `join` results from a full traversal by + `std.tree.nodes (tree)`. + +### Incompatible changes + + - `std.string` no longer sets `__append`, `__concat` and `__index` in + the core strings metatable by default, though `require "std"` does + continue to do so. See LDocs for `std.string` for details. + + - `std.optparse` no longer normalizes unhandled options. For example, + `--unhandled-option=argument` is returned unmolested from `parse`, + rather than as two elements split on the `=`; and if a combined + short option string contains an unhandled option, then whatever was + typed at the command line is returned unmolested, rather than first + stripping off and processing handled options, and returning only the + unhandled substring. + + - Setting `_init` to `{}` in a prototype object will now discard all + positional parameters passed during cloning, because a table valued + `_init` is a list of field names, beyond which surplus arguments (in + this case, all arguments!) are discarded. + + +## Noteworthy changes in release 38 (2014-01-30) [stable] + +### New features + + - The separator parameter to `std.string.split` is now optional. It + now splits strings with `%s+` when no separator is specified. The + new implementation is faster too. + + - New `std.object.mapfields` method factors out the table field copying + and mapping performed when cloning a table `_init` style object. This + means you can call it from a function `_init` style object after + collecting a table to serve as `src` to support derived objects with + normal std.object syntax: + + ```lua + Proto = Object { + _type = "proto" + _init = function (self, arg, ...) + if type (arg) == "table" then + mapfields (self, arg) + else + -- non-table instantiation code + end + end, + } + new = Proto (str, #str) + Derived = proto { _type = "Derived", ... } + ``` + + - Much faster object cloning; `mapfields` is in imperative style and + makes one pass over each table it looks at, where previous releases + used functional style (stack frame overhead) and multiple passes over + input tables. + + On my 2013 Macbook Air with 1.3GHz Core i5 CPU, I can now create a + million std.objects with several assorted fields in 3.2s. Prior to + this release, the same process took 8.15s... and even release 34.1, + with drastically simpler Objects (19SLOC vs over 120) took 5.45s. + + - `std.object.prototype` is now almost an order of magnitude faster + than previous releases, taking about 20% of the time it previously + used to return its results. + + - `io.warn` and `io.die` now integrate properly with `std.optparse`, + provided you save the `opts` return from `parser:parse` back to the + global namespace where they can access it: + + ```lua + local OptionParser = require "std.optparse" + local parser = OptionParser "eg 0\nUsage: eg\n" + _G.arg, _G.opts = parser:parse (_G.arg) + if not _G.opts.keep_going then + require "std.io".warn "oh noes!" + end + ``` will, when run, output to stderr: "eg: oh noes!" -** Bug fixes: +### Bug fixes + + - Much improved documentation for `optparse`, so you should be able + to use it without reading the source code now! + + - `io.warn` and `io.die` no longer output a line-number when there is + no file name to append it to. + + - `io.warn` and `io.die` no longer crash in the absence of a global + `prog` table. + + - `string.split` no longer goes into an infinite loop when given an + empty separator string. + + - Fix `getmetatable (container._functions) == getmetatable (container)`, + which made tostring on containers misbehave, among other latent bugs. + + - `_functions` is never copied into a metatable now, finally solving + the conflicted concerns of needing metatables to be shared between + all objects of the same `_type` (for `__lt` to work correctly for one + thing) and not leaving a dangling `_functions` list in the metatable + of cloned objects, which could delete functions with matching names + from subsequent clones. + + +## Noteworthy changes in release 37 (2014-01-19) [stable] + +### New features - - Much improved documentation for `optparse`, so you should be able - to use it without reading the source code now! + - Lazy loading of submodules into `std` on first reference. On initial + load, `std` has the usual single `version` entry, but the `__index` + metatable will automatically require submodules on first reference: - - `io.warn` and `io.die` no longer output a line-number when there is - no file name to append it to. + ```lua + local std = require "std" + local prototype = std.container.prototype + ``` - - `io.warn` and `io.die` no longer crash in the absence of a global - `prog` table. + - New `std.optparse` module: A civilised option parser. + (L)Documentation distributed in doc/classes/std.optparse.html. - - `string.split` no longer goes into an infinite loop when given an - empty separator string. +### Bug fixes - - Fix `getmetatable (container._functions) == getmetatable (container)`, - which made tostring on containers misbehave, among other latent bugs. + - Modules no longer leak `new' and `proper_subset' into the global + table. - - `_functions` is never copied into a metatable now, finally solving - the conflicted concerns of needing metatables to be shared between - all objects of the same `_type` (for `__lt` to work correctly for one - thing) and not leaving a dangling `_functions` list in the metatable - of cloned objects, which could delete functions with matching names - from subsequent clones. + - Cloned `Object` and `Container` derived types are more aggressive + about sharing metatables, where previously the metatable was copied + unnecessarily the base object used `_functions` for module functions -* Noteworthy changes in release 37 (2014-01-19) [stable] + - The retracted release 36 changed the operand order of many `std.list` + module functions unnecessarily. Now that `_function` support is + available, there's no need to be so draconian, so the original v35 + and earlier operand order works as before again. -** New features: + - `std.list.new`, `std.set.new`, `set.strbuf.new` and `std.tree.new` + are available again for backwards compatibility. - - Lazy loading of submodules into `std` on first reference. On initial - load, `std` has the usual single `version` entry, but the `__index` - metatable will automatically require submodules on first reference: + - LuaRocks install doesn't copy config.ld and config.ld to $docdir. - local std = require "std" - local prototype = std.container.prototype +### Incompatible changes - - New `std.optparse` module: A civilised option parser. - (L)Documentation distributed in doc/classes/std.optparse.html. + - `std.getopt` is no more. It appears to have no users, though if there + is a great outcry, it should be easy to make a compatibility api over + `std.optparse` in the next release. -** Bug fixes: - - Modules no longer leak `new' and `proper_subset' into the global - table. +## Noteworthy changes in release 36 (2014-01-16) [stable] - - Cloned `Object` and `Container` derived types are more aggressive - about sharing metatables, where previously the metatable was copied - unnecessarily the base object used `_functions` for module functions +### New features - - The retracted release 36 changed the operand order of many `std.list` - module functions unnecessarily. Now that `_function` support is - available, there's no need to be so draconian, so the original v35 - and earlier operand order works as before again. + - Modules have been refactored so that they can be safely + required individually, and without loading themselves or any + dependencies on other std modules into the global namespace. - - `std.list.new`, `std.set.new`, `set.strbuf.new` and `std.tree.new` - are available again for backwards compatibility. + - Objects derived from the `std.object` prototype have a new + :prototype () method that returns the contents of the + new internal `_type` field. This can be overridden during cloning + with, e.g.: - - LuaRocks install doesn't copy config.ld and config.ld to $docdir. + ```lua + local Object = require "std.object" + Prototype = Object { _type = "Prototype", } + ``` -** Incompatible changes: + - Objects derived from the `std.object` prototype return a new table + with a shallow copy of all non-private fields (keys that do not + begin with "_") when passed to `table.totable` - unless overridden + in the derived object's __totable field. - - `std.getopt` is no more. It appears to have no users, though if there - is a great outcry, it should be easy to make a compatibility api over - `std.optparse` in the next release. + - list and strbuf are now derived from `std.object`, which means that + they respond to `object.prototype` with appropriate type names ("List", + "StrBuf", etc.) and can be used as prototypes for further derived + objects or clones; support object:prototype (); respond to totable etc. + - A new Container module at `std.container` makes separation between + container objects (which are free to use __index as a "[]" access + metamethod, but) which have no object methods, and regular objects + (which do have object methods, but) which cannot use the __index + metamethod for "[]" access to object contents. -* Noteworthy changes in release 36 (2014-01-16) [stable] + - set and tree are now derived from `std.container`, so there are no + object methods. Instead there are a full complement of equivalent + module functions. Metamethods continue to work as before. -** New features: + - `string.prettytostring` always displays table elements in the same + order, as provided by `table.sort`. - - Modules have been refactored so that they can be safely - required individually, and without loading themselves or any - dependencies on other std modules into the global namespace. + - `table.totable` now accepts a string, and returns a list of the + characters that comprise the string. - - Objects derived from the `std.object` prototype have a new - :prototype () method that returns the contents of the - new internal `_type` field. This can be overridden during cloning - with, e.g.: + - Can now be installed directly from a release tarball by `luarocks`. + No need to run `./configure` or `make`, unless you want to install to + a custom location, or do not use LuaRocks. - local Object = require "std.object" - Prototype = Object { _type = "Prototype", } +### Bug fixes - - Objects derived from the `std.object` prototype return a new table - with a shallow copy of all non-private fields (keys that do not - begin with "_") when passed to `table.totable` - unless overridden - in the derived object's __totable field. + - string.escape_pattern is now Lua 5.2 compatible. - - list and strbuf are now derived from `std.object`, which means that - they respond to `object.prototype` with appropriate type names ("List", - "StrBuf", etc.) and can be used as prototypes for further derived - objects or clones; support object:prototype (); respond to totable etc. + - all objects now reuse prototype metatables, as required for __le and + __lt metamethods to work as documented. - - A new Container module at `std.container` makes separation between - container objects (which are free to use __index as a "[]" access - metamethod, but) which have no object methods, and regular objects - (which do have object methods, but) which cannot use the __index - metamethod for "[]" access to object contents. +### Deprecations - - set and tree are now derived from `std.container`, so there are no - object methods. Instead there are a full complement of equivalent - module functions. Metamethods continue to work as before. + - To avoid confusion between the builtin Lua `type` function and the + method for finding the object prototype names, `std.object.type` is + deprecated in favour of `std.object.prototype`. `std.object.type` + continues to work for now, but might be removed from a future + release. - - `string.prettytostring` always displays table elements in the same - order, as provided by `table.sort`. + ```lua + local prototype = (require 'std.object').prototype + ``` - - `table.totable` now accepts a string, and returns a list of the - characters that comprise the string. + ...makes for more readable code, rather than confusion between the + different flavours of `type`. - - Can now be installed directly from a release tarball by `luarocks`. - No need to run `./configure` or `make`, unless you want to install to - a custom location, or do not use LuaRocks. +### Incompatible changes -** Bug fixes: + - Following on from the Grand Renaming™ change in the last release, + `std.debug_ext`, `std.io_ext`, `std.math_ext`, `std.package_ext`, + `std.string_ext` and `std.table_ext` no longer have the spurious + `_ext` suffix. Instead, you must now use, e.g.: - - string.escape_pattern is now Lua 5.2 compatible. + ```lua + local string = require "std.string" + ``` - - all objects now reuse prototype metatables, as required for __le and - __lt metamethods to work as documented. + These names are now stable, and will be available from here for + future releases. -** Deprecations: + - The `std.list` module, as a consequence of returning a List object + prototype rather than a table of functions including a constructor, + now always has the list operand as the first argument, whether that + function is called with `.` syntax or `:` syntax. Functions which + previously had the list operand in a different position when called + with `.` syntax were: list.filter, list.foldl, list.foldr, + list.index_key, list.index_value, list.map, list.map_with, + list.project, list.shape and list.zip_with. Calls made as object + methods using `:` calling syntax are unchanged. - - To avoid confusion between the builtin Lua `type` function and the - method for finding the object prototype names, `std.object.type` is - deprecated in favour of `std.object.prototype`. `std.object.type` - continues to work for now, but might be removed from a future - release. + - The `std.set` module is a `std.container` with no object methods, + and now uses prototype functions instead: - local prototype = (require 'std.object').prototype + ```lua + local union = Set.union (set1, set2) + ``` - ...makes for more readable code, rather than confusion between the - different flavours of `type`. -** Incompatible changes: +## Noteworthy changes in release 35 (2013-05-06) [stable] - - Following on from the Grand Renaming™ change in the last release, - `std.debug_ext`, `std.io_ext`, `std.math_ext`, `std.package_ext`, - `std.string_ext` and `std.table_ext` no longer have the spurious - `_ext` suffix. Instead, you must now use, e.g.: +### New features - local string = require "std.string" + - Move to the Slingshot release system. + - Continuous integration from Travis automatically builds stdilb + with Lua 5.1, Lua 5.2 and luajit-2.0 with every commit, which + should help prevent future release breaking compatibility with + one or another of those interpreters. - These names are now stable, and will be available from here for - future releases. +### Bug fixes - - The `std.list` module, as a consequence of returning a List object - prototype rather than a table of functions including a constructor, - now always has the list operand as the first argument, whether that - function is called with `.` syntax or `:` syntax. Functions which - previously had the list operand in a different position when called - with `.` syntax were: list.filter, list.foldl, list.foldr, - list.index_key, list.index_value, list.map, list.map_with, - list.project, list.shape and list.zip_with. Calls made as object - methods using `:` calling syntax are unchanged. + - `std.package_ext` no longer overwrites the core `package` table, + leaving the core holding on to memory that Lua code could no + longer access. - - The `std.set` module is a `std.container` with no object methods, - and now uses prototype functions instead: +### Incompatible changes - local union = Set.union (set1, set2) + - The Grand Renaming™ - everything now installs to $luaprefix/std/, + except `std.lua` itself. Importing individual modules now involves: + ```lua + local list = require "std.list" + ``` -* Noteworthy changes in release 35 (2013-05-06) [stable] + If you want to have all the symbols previously available from the + global and core module namespaces, you will need to put them there + yourself, or import everything with: -** New features: + ```lua + require "std" + ``` - - Move to the Slingshot release system. - - Continuous integration from Travis automatically builds stdilb - with Lua 5.1, Lua 5.2 and luajit-2.0 with every commit, which - should help prevent future release breaking compatibility with - one or another of those interpreters. + which still behaves per previous releases. -** Bug fixes: + Not all of the modules work correctly when imported individually + right now, until we figure out how to break some circular dependencies. - - `std.package_ext` no longer overwrites the core `package` table, - leaving the core holding on to memory that Lua code could no - longer access. -** Incompatible changes: +## Noteworthy changes in release 34.1 (2013-04-01) [stable] - - The Grand Renaming™ - everything now installs to $luaprefix/std/, - except `std.lua` itself. Importing individual modules now involves: + - This is a maintenance release to quickly fix a breakage in getopt + from release v34. Getopt no longer parses non-options, but stops + on the first non-option... if a use case for the other method + comes up, we can always add it back in. - local list = require "std.list" - If you want to have all the symbols previously available from the - global and core module namespaces, you will need to put them there - yourself, or import everything with: +## Noteworthy changes in release 34 (2013-03-25) [stable] - require "std" + - stdlib is moving towards supporting separate requirement of individual + modules, without scribbling on the global environment; the work is not + yet complete, but we're collecting tests along the way to ensure that + once it is all working, it will carry on working; - which still behaves per previous releases. + - there are some requirement loops between modules, so not everything can + be required independently just now; - Not all of the modules work correctly when imported individually - right now, until we figure out how to break some circular dependencies. + - `require "std"` will continue to inject std symbols into the system + tables for backwards compatibility; + - stdlib no longer ships a copy of Specl, which you will need to install + separately if you want to run the bundled tests; -* Noteworthy changes in release 34.1 (2013-04-01) [stable] + - getopt supports parsing of undefined options; useful for programs that + wrap other programs; -** This is a maintenance release to quickly fix a breakage in getopt - from release v34. Getopt no longer parses non-options, but stops - on the first non-option... if a use case for the other method - comes up, we can always add it back in. + - getopt.Option constructor is no longer used, pass a plain Lua table of + options, and getopt will do the rest; -* Noteworthy changes in release 34 (2013-03-25) [stable] +## Noteworthy changes in release 33 (2013-07-27) [stable] - - stdlib is moving towards supporting separate requirement of individual - modules, without scribbling on the global environment; the work is not - yet complete, but we're collecting tests along the way to ensure that - once it is all working, it will carry on working; - - there are some requirement loops between modules, so not everything can - be required independently just now; - - `require "std"` will continue to inject std symbols into the system - tables for backwards compatibility; - - stdlib no longer ships a copy of Specl, which you will need to install - separately if you want to run the bundled tests; - - getopt supports parsing of undefined options; useful for programs that - wrap other programs; - - getopt.Option constructor is no longer used, pass a plain Lua table of - options, and getopt will do the rest; + - This release improves stability where Specl has helped locate some + corner cases that are now fixed. + - `string_ext.wrap` and `string_ext.tfind` now diagnose invalid arguments. -* Noteworthy changes in release 33 (2013-07-27) [stable] + - Specl code coverage is improving. -** This release improves stability where Specl has helped locate some - corner cases that are now fixed. - - `string_ext.wrap` and `string_ext.tfind` now diagnose invalid arguments. + - OrdinalSuffix improvements. -** Specl code coverage is improving. + - Use '%' instead of math.mod, as the latter does not exist in Lua 5.2. -** OrdinalSuffix improvements. - - Use '%' instead of math.mod, as the latter does not exist in Lua 5.2. - - Accept negative arguments. + - Accept negative arguments. -* Noteworthy changes in release 32 (2013-02-22) [stable] +## Noteworthy changes in release 32 (2013-02-22) [stable] -** This release fixes a critical bug preventing getopt from returning - anything in getopt.opt. Gary V. Vaughan is now a co-maintainer, currently - reworking the sources to use (Lua 5.1 compatible) Lua 5.2 style module - packaging, which requires you to assign the return values from your imports: + - This release fixes a critical bug preventing getopt from returning + anything in getopt.opt. Gary V. Vaughan is now a co-maintainer, currently + reworking the sources to use (Lua 5.1 compatible) Lua 5.2 style module + packaging, which requires you to assign the return values from your imports: - getopt = require "getopt" + ```lua + getopt = require "getopt" + ``` -** Extension modules, table_ext, package_ext etc. return the unextended module - table before injecting additional package methods, so you can ignore those - return values or save them for programatically backing out the changes: + - Extension modules, table_ext, package_ext etc. return the unextended module + table before injecting additional package methods, so you can ignore those + return values or save them for programatically backing out the changes: - table_unextended = require "table_ext" + ```lua + table_unextended = require "table_ext" + ``` -** Additionally, Specl (see http://github.com/gvvaughan/specl/) specifications - are being written for stdlib modules to help us stop accidentally breaking - things between releases. + - Additionally, Specl (see http://github.com/gvvaughan/specl/) specifications + are being written for stdlib modules to help us stop accidentally breaking + things between releases. -* Noteworthy changes in release 31 (2013-02-20) [stable] +## Noteworthy changes in release 31 (2013-02-20) [stable] -** This release improves the list module: lists now have methods, list.slice - is renamed to list.sub (the old name is provided as an alias for backwards - compatibility), and all functions that construct a new list return a proper - list, not a table. As a result, it is now often possible to write code that - works on both lists and strings. + - This release improves the list module: lists now have methods, list.slice + is renamed to list.sub (the old name is provided as an alias for backwards + compatibility), and all functions that construct a new list return a proper + list, not a table. As a result, it is now often possible to write code that + works on both lists and strings. -* Noteworthy changes in release 30 (2013-02-17) [stable] +## Noteworthy changes in release 30 (2013-02-17) [stable] -** This release changes some modules to be written in a Lua 5.2 style (but - not the way they work with 5.1). Some fixes and improvements were made to - the build system. Bugs in the die function, the parser module, and a nasty - bug in the set module introduced in the last release (29) were fixed. + - This release changes some modules to be written in a Lua 5.2 style (but + not the way they work with 5.1). Some fixes and improvements were made to + the build system. Bugs in the die function, the parser module, and a nasty + bug in the set module introduced in the last release (29) were fixed. -* Noteworthy changes in release 29 (2013-02-06) [stable] +## Noteworthy changes in release 29 (2013-02-06) [stable] -** This release overhauls the build system to have LuaRocks install releases - directly from git rather than from tarballs, and fixes a bug in set (issue - #8). + - This release overhauls the build system to have LuaRocks install releases + directly from git rather than from tarballs, and fixes a bug in set (issue + #8). -* Noteworthy changes in release 28 (2012-10-28) [stable] +## Noteworthy changes in release 28 (2012-10-28) [stable] -** This release improves the documentation and build system, and improves - require_version to work by default with more libraries. + - This release improves the documentation and build system, and improves + require_version to work by default with more libraries. -* Noteworthy changes in release 27 (2012-10-03) [stable] +## Noteworthy changes in release 27 (2012-10-03) [stable] -** This release changes getopt to return all arguments in a list, rather than - optionally processing them with a function, fixes an incorrect definition - of set.elems introduced in release 26, turns on debugging by default, - removes the not-very-useful string.gsubs, adds constructor functions for - objects, renames table.rearrange to the more descriptive table.clone_rename - and table.indices to table.keys, and makes table.merge not clone but modify - its left-hand argument. A function require_version has been added to allow - version constraints on a module being required. Gary Vaughan has - contributed a memoize function, and minor documentation and build system - improvements have been made. Usage information is now output to stdout, not - stderr. The build system has been fixed to accept Lua 5.2. The luarock now - installs documentation, and the build command used is now more robust - against previous builds in the same tree. + - This release changes getopt to return all arguments in a list, rather than + optionally processing them with a function, fixes an incorrect definition + of set.elems introduced in release 26, turns on debugging by default, + removes the not-very-useful string.gsubs, adds constructor functions for + objects, renames table.rearrange to the more descriptive table.clone_rename + and table.indices to table.keys, and makes table.merge not clone but modify + its left-hand argument. A function require_version has been added to allow + version constraints on a module being required. Gary Vaughan has + contributed a memoize function, and minor documentation and build system + improvements have been made. Usage information is now output to stdout, not + stderr. The build system has been fixed to accept Lua 5.2. The luarock now + installs documentation, and the build command used is now more robust + against previous builds in the same tree. -* Noteworthy changes in release 26 (2012-02-18) [stable] +## Noteworthy changes in release 26 (2012-02-18) [stable] -** This release improves getoptâs output messages and conformance to - standard practice for default options. io.processFiles now unsets prog.file - when it finishes, so that a program can tell when itâs no longer - processing a file. Three new tree iterators, inodes, leaves and ileaves, - have been added; the set iterator set.elements (renamed to set.elems for - consistency with list.elems) is now leaves rather than pairs. tree indexing - has been made to work in more circumstances (thanks, Gary Vaughan). - io.writeline is renamed io.writelines for consistency with io.readlines and - its function. A slurping function, io.slurp, has been added. Strings now - have a __concat metamethod. + - This release improves getoptâs output messages and conformance to + standard practice for default options. io.processFiles now unsets prog.file + when it finishes, so that a program can tell when itâs no longer + processing a file. Three new tree iterators, inodes, leaves and ileaves, + have been added; the set iterator set.elements (renamed to set.elems for + consistency with list.elems) is now leaves rather than pairs. tree indexing + has been made to work in more circumstances (thanks, Gary Vaughan). + io.writeline is renamed io.writelines for consistency with io.readlines and + its function. A slurping function, io.slurp, has been added. Strings now + have a __concat metamethod. -* Noteworthy changes in release 25 (2011-09-19) [stable] +## Noteworthy changes in release 25 (2011-09-19) [stable] -** This release adds a version string to the std module and fixes a buglet in - the build system. + - This release adds a version string to the std module and fixes a buglet in + the build system. -* Noteworthy changes in release 24 (2011-09-19) [stable] +## Noteworthy changes in release 24 (2011-09-19) [stable] -** This release fixes a rename missing from release 23, and makes a couple of - fixes to the new build system, also from release 23. + - This release fixes a rename missing from release 23, and makes a couple of + fixes to the new build system, also from release 23. -* Noteworthy changes in release 23 (2011-09-17) [stable] +## Noteworthy changes in release 23 (2011-09-17) [stable] -** This release removes the posix_ext module, which is now part of luaposix, - renames string.findl to string.tfind to be the same as lrexlib, and - autotoolizes the build system, as well as providing a rockspec file. + - This release removes the posix_ext module, which is now part of luaposix, + renames string.findl to string.tfind to be the same as lrexlib, and + autotoolizes the build system, as well as providing a rockspec file. -* Noteworthy changes in release 22 (2011-09-02) [stable] +## Noteworthy changes in release 22 (2011-09-02) [stable] -** This release adds two new modules: strbuf, a trivial string buffers - implementation, which is used to speed up the stdlib tostring method for - tables, and bin, which contains a couple of routines for converting binary - data into numbers and strings. Some small documentation and build system - fixes have been made. + - This release adds two new modules: strbuf, a trivial string buffers + implementation, which is used to speed up the stdlib tostring method for + tables, and bin, which contains a couple of routines for converting binary + data into numbers and strings. Some small documentation and build system + fixes have been made. -* Noteworthy changes in release 21 (2011-06-06) [stable] +## Noteworthy changes in release 21 (2011-06-06) [stable] -** This release converts the documentation of stdlib to LuaDoc, adds an - experimental Lua 5.2 module "fstable", for storing tables directly on - disk as files and directories, and fixes a few minor bugs (with help from - David Favro). + - This release converts the documentation of stdlib to LuaDoc, adds an + experimental Lua 5.2 module "fstable", for storing tables directly on + disk as files and directories, and fixes a few minor bugs (with help from + David Favro). -** This release has been tested lightly on Lua 5.2 alpha, but is not - guaranteed to work fully. + - This release has been tested lightly on Lua 5.2 alpha, but is not + guaranteed to work fully. -* Noteworthy changes in release 20 (2011-04-14) [stable] +## Noteworthy changes in release 20 (2011-04-14) [stable] -** This release fixes a conflict between the global _DEBUG setting and the use - of strict.lua, changes the argument order of some list functions to favour - OO-style use, adds posix.euidaccess, and adds OO-style use to set. mk1file - can now produce a single-file version of a user-supplied list of modules, - not just the standard set. + - This release fixes a conflict between the global _DEBUG setting and the use + of strict.lua, changes the argument order of some list functions to favour + OO-style use, adds posix.euidaccess, and adds OO-style use to set. mk1file + can now produce a single-file version of a user-supplied list of modules, + not just the standard set. -* Noteworthy changes in release 19 (2011-02-26) [stable] +## Noteworthy changes in release 19 (2011-02-26) [stable] -** This release puts the package.config reflection in a new package_ext - module, where it belongs. Thanks to David Manura for this point, and for a - small improvement to the code. + - This release puts the package.config reflection in a new package_ext + module, where it belongs. Thanks to David Manura for this point, and for a + small improvement to the code. -* Noteworthy changes in release 18 (2011-02-26) [stable] +## Noteworthy changes in release 18 (2011-02-26) [stable] -** This release provides named access to the contents of package.config, which - is undocumented in Lua 5.1. See luaconf.h and the Lua 5.2 manual for more - details. + - This release provides named access to the contents of package.config, which + is undocumented in Lua 5.1. See luaconf.h and the Lua 5.2 manual for more + details. -* Noteworthy changes in release 17 (2011-02-07) [stable] +## Noteworthy changes in release 17 (2011-02-07) [stable] -** This release fixes two bugs in string.pad (thanks to Bob Chapman for the - fixes). + - This release fixes two bugs in string.pad (thanks to Bob Chapman for the + fixes). -* Noteworthy changes in release 16 (2010-12-09) [stable] +## Noteworthy changes in release 16 (2010-12-09) [stable] -** Adds posix module, using luaposix, and makes various other small fixes and - improvements. + - Adds posix module, using luaposix, and makes various other small fixes and + improvements. -* Noteworthy changes in release 15 (2010-06-14) [stable] +## Noteworthy changes in release 15 (2010-06-14) [stable] -** This release fixes list.foldl, list.foldr, the fold iterator combinator and - io.writeLine. It also simplifies the op table, which now merely sugars the - built-in operators rather than extending them. It adds a new tree module, - which subsumes the old table.deepclone and table.lookup functions. - table.subscript has become op["[]"], and table.subscripts has been removed; - the old treeIter iterator has been simplified and generalised, and renamed - to nodes. The mk1file script and std.lua library loader have had the module - list factored out into modules.lua. strict.lua from the Lua distribution is - now included in stdlib, which has been fixed to work with it. Some minor - documentation and other code improvements and fixes have been made. + - This release fixes list.foldl, list.foldr, the fold iterator combinator and + io.writeLine. It also simplifies the op table, which now merely sugars the + built-in operators rather than extending them. It adds a new tree module, + which subsumes the old table.deepclone and table.lookup functions. + table.subscript has become op["[]"], and table.subscripts has been removed; + the old treeIter iterator has been simplified and generalised, and renamed + to nodes. The mk1file script and std.lua library loader have had the module + list factored out into modules.lua. strict.lua from the Lua distribution is + now included in stdlib, which has been fixed to work with it. Some minor + documentation and other code improvements and fixes have been made. -* Noteworthy changes in release 14 (2010-06-07) [stable] +## Noteworthy changes in release 14 (2010-06-07) [stable] -** This release makes stdlib compatible with strict.lua, which required a - small change to the debug_ext module. Some other minor changes have also - been made to that module. The table.subscripts function has been removed - from the table_ext.lua. + - This release makes stdlib compatible with strict.lua, which required a + small change to the debug_ext module. Some other minor changes have also + been made to that module. The table.subscripts function has been removed + from the table_ext.lua. -* Noteworthy changes in release 13 (2010-06-02) [stable] +## Noteworthy changes in release 13 (2010-06-02) [stable] -** This release removes the lcs module from the standard set loaded by - "std", removes an unnecessary definition of print, and tidies up the - implementation of the "op" table of functional versions of the infix - operators and logical operators. + - This release removes the lcs module from the standard set loaded by + "std", removes an unnecessary definition of print, and tidies up the + implementation of the "op" table of functional versions of the infix + operators and logical operators. -* Noteworthy changes in release 12 (2009-09-07) [stable] +## Noteworthy changes in release 12 (2009-09-07) [stable] -** This release removes io.basename and io.dirname, which are now available in - lposix, and the little-used functions addSuffix and changeSuffix which - dependend on them. io.pathConcat is renamed to io.catdir and io.pathSplit - to io.splitdir, making them behave the same as the corresponding Perl - functions. The dependency on lrexlib has been removed along with the rex - wrapper module. Some of the more esoteric and special-purpose modules - (mbox, xml, parser) are no longer loaded by 'require "std"'. + - This release removes io.basename and io.dirname, which are now available in + lposix, and the little-used functions addSuffix and changeSuffix which + dependend on them. io.pathConcat is renamed to io.catdir and io.pathSplit + to io.splitdir, making them behave the same as the corresponding Perl + functions. The dependency on lrexlib has been removed along with the rex + wrapper module. Some of the more esoteric and special-purpose modules + (mbox, xml, parser) are no longer loaded by 'require "std"'. - This leaves stdlib with no external dependencies, and a rather more - coherent set of basic modules. + This leaves stdlib with no external dependencies, and a rather more + coherent set of basic modules. -* Noteworthy changes in release 11 (2009-03-15) [stable] +## Noteworthy changes in release 11 (2009-03-15) [stable] -** This release fixes a bug in string.format, removes the redundant - string.join (it's the same as table.concat), and adds to table.clone and - table.deepclone the ability to copy without metatables. Thanks to David - Kantowitz for pointing out the various deficiencies. + - This release fixes a bug in string.format, removes the redundant + string.join (it's the same as table.concat), and adds to table.clone and + table.deepclone the ability to copy without metatables. Thanks to David + Kantowitz for pointing out the various deficiencies. -* Noteworthy changes in release 10 (2009-03-13) [stable] +## Noteworthy changes in release 10 (2009-03-13) [stable] -** This release fixes table.deepclone to copy metatables, as it should. - Thanks to David Kantowitz for the fix. + - This release fixes table.deepclone to copy metatables, as it should. + Thanks to David Kantowitz for the fix. -* Noteworthy changes in release 9 (2009-02-19) [stable] +## Noteworthy changes in release 9 (2009-02-19) [stable] -** This release updates the object module to be the same as that published - in "Lua Gems", and fixes a bug in the utility mk1file which makes a - one-file version of the library, to stop it permanently redefining require. + - This release updates the object module to be the same as that published + in "Lua Gems", and fixes a bug in the utility mk1file which makes a + one-file version of the library, to stop it permanently redefining require. -* Noteworthy changes in release 8 (2008-09-04) [stable] +## Noteworthy changes in release 8 (2008-09-04) [stable] -** This release features fixes and improvements to the set module; thanks to - Jiutian Yanling for a bug report and suggestion which led to this work. + - This release features fixes and improvements to the set module; thanks to + Jiutian Yanling for a bug report and suggestion which led to this work. -* Noteworthy changes in release 7 (2008-09-04) [stable] +## Noteworthy changes in release 7 (2008-09-04) [stable] -** just a bug fix + - just a bug fix -* Noteworthy changes in release 6 (2008-07-28) [stable] +## Noteworthy changes in release 6 (2008-07-28) [stable] -** This release rewrites the iterators in a more Lua-ish 5.1 style. + - This release rewrites the iterators in a more Lua-ish 5.1 style. -* Noteworthy changes in release 5 (2008-03-04) [stable] +## Noteworthy changes in release 5 (2008-03-04) [stable] -** I'm happy to announce a new release of my standard Lua libraries. It's been - nearly a year since the last release, and I'm happy to say that since then - only one bug has been found (thanks Roberto!). Two functions have been - added in this release, to deal with file paths, and one removed (io.length, - which is handled by lfs.attributes) along with one constant (INTEGER_BITS, - handled by bitlib's bit.bits). + - I'm happy to announce a new release of my standard Lua libraries. It's been + nearly a year since the last release, and I'm happy to say that since then + only one bug has been found (thanks Roberto!). Two functions have been + added in this release, to deal with file paths, and one removed (io.length, + which is handled by lfs.attributes) along with one constant (INTEGER_BITS, + handled by bitlib's bit.bits). -** For those not familiar with stdlib, it's a pure-Lua library of mostly - fundamental data structures and algorithms, in particular support for - functional and object-oriented programming, string and regex operations and - extensible pretty printing of data structures. More specific modules - include a getopt implementation, a generalised least common subsequences - (i.e. diff algorithm) implementation, a recursive-descent parser generator, - and an mbox parser. + - For those not familiar with stdlib, it's a pure-Lua library of mostly + fundamental data structures and algorithms, in particular support for + functional and object-oriented programming, string and regex operations and + extensible pretty printing of data structures. More specific modules + include a getopt implementation, a generalised least common subsequences + (i.e. diff algorithm) implementation, a recursive-descent parser generator, + and an mbox parser. -** It's quite a mixed bag, but almost all written for real projects. It's - written in a doc-string-ish style with the supplied very simple ldoc tool. + - It's quite a mixed bag, but almost all written for real projects. It's + written in a doc-string-ish style with the supplied very simple ldoc tool. -** I am happy with this code base, but there are various things it could use: + - I am happy with this code base, but there are various things it could use: - 0. Tests. Tests. Tests. The code has no unit tests. It so needs them. + 0. Tests. Tests. Tests. The code has no unit tests. It so needs them. - 1. More code. Nothing too specialised (unless it's too small to be released - on its own, although very little seems "too small" in the Lua - community). Anything that either has widespread applicability (like - getopt) or is very general (data structures, algorithms, design - patterns) is good. + 1. More code. Nothing too specialised (unless it's too small to be released + on its own, although very little seems "too small" in the Lua + community). Anything that either has widespread applicability (like + getopt) or is very general (data structures, algorithms, design + patterns) is good. - 2. Refactoring. The code is not ideally factored. At the moment it is - divided into modules that extend existing libraries, and new modules - constructed along similar lines, but I think that some of the divisions - are confusing. For example, the functional programming support is spread - between the list and base modules, and would probably be better in its - own module, as those who aren't interested in the functional style won't - want the functional list support or the higher-order functions support, - and those who want one will probably want the other. + 2. Refactoring. The code is not ideally factored. At the moment it is + divided into modules that extend existing libraries, and new modules + constructed along similar lines, but I think that some of the divisions + are confusing. For example, the functional programming support is spread + between the list and base modules, and would probably be better in its + own module, as those who aren't interested in the functional style won't + want the functional list support or the higher-order functions support, + and those who want one will probably want the other. - 3. Documentation work. There's not a long wrong with the existing - documentation, but it would be nice, now that there is a stable LuaDoc, - to use that instead of the built-in ldoc, which I'm happy to discard now - that LuaDoc is stable. ldoc was always designed as a minimal LuaDoc - substitute in any case. + 3. Documentation work. There's not a long wrong with the existing + documentation, but it would be nice, now that there is a stable LuaDoc, + to use that instead of the built-in ldoc, which I'm happy to discard now + that LuaDoc is stable. ldoc was always designed as a minimal LuaDoc + substitute in any case. - 4. Maintenance and advocacy. For a while I have been reducing my work on - Lua, and am also now reducing my work in Lua. If anyone would like to - take on stdlib, please talk to me. It fills a much-needed function: I - suspect a lot of Lua programmers have invented the wheels with which it - is filled over and over again. In particular, many programmers could - benefit from the simplicity of its simple and well-designed functional, - string and regex capabilities, and others will love its comprehensive - getopt. + 4. Maintenance and advocacy. For a while I have been reducing my work on + Lua, and am also now reducing my work in Lua. If anyone would like to + take on stdlib, please talk to me. It fills a much-needed function: I + suspect a lot of Lua programmers have invented the wheels with which it + is filled over and over again. In particular, many programmers could + benefit from the simplicity of its simple and well-designed functional, + string and regex capabilities, and others will love its comprehensive + getopt. -* Noteworthy changes in release 4 (2007-04-26) [beta] +## Noteworthy changes in release 4 (2007-04-26) [beta] -** This release removes the dependency on the currently unmaintained lposix - library, includes pre-built HTML documentation, and fixes some 5.0-style - uses of variadic arguments. + - This release removes the dependency on the currently unmaintained lposix + library, includes pre-built HTML documentation, and fixes some 5.0-style + uses of variadic arguments. - Thanks to Matt for pointing out all these problems. stdlib is very much - user-driven at the moment, since it already does everything I need, and I - don't have much time to work on it, so do please contact me if you find - bugs or problems or simply don't understand it, as the one thing I *do* - want to do is make it useful and accessible! + Thanks to Matt for pointing out all these problems. stdlib is very much + user-driven at the moment, since it already does everything I need, and I + don't have much time to work on it, so do please contact me if you find + bugs or problems or simply don't understand it, as the one thing I *do* + want to do is make it useful and accessible! -* Noteworthy changes in release 3 (2007-02-25) [beta] +## Noteworthy changes in release 3 (2007-02-25) [beta] -** This release fixes the "set" and "lcs" (longest common subsequence, or - "grep") libraries, which were broken, and adds one or two other bug and - design fixes. Thanks are due to Enrico Tassi for pointing out some of the - problems. + - This release fixes the "set" and "lcs" (longest common subsequence, or + "grep") libraries, which were broken, and adds one or two other bug and + design fixes. Thanks are due to Enrico Tassi for pointing out some of the + problems. -* Noteworthy changes in release 2 (2007-01-05) [beta] +## Noteworthy changes in release 2 (2007-01-05) [beta] -** This release includes some bug fixes, and compatibility with lrexlib 2.0. + - This release includes some bug fixes, and compatibility with lrexlib 2.0. -* Noteworthy changes in release 1 (2011-09-02) [beta] +## Noteworthy changes in release 1 (2011-09-02) [beta] -** It's just a snapshot of CVS, but it's pretty stable at the moment; stdlib, - until such time as greater interest or participation enables (or forces!) - formal releases will be in permanent beta, and tracking CVS is recommended. + - It's just a snapshot of CVS, but it's pretty stable at the moment; stdlib, + until such time as greater interest or participation enables (or forces!) + formal releases will be in permanent beta, and tracking CVS is recommended. diff --git a/README b/README index 8ba232c..d5a82a5 100644 --- a/README +++ b/README @@ -6,10 +6,11 @@ by the [stdlib project][github] [github]: http://github.com/lua-stdlib/lua-stdlib/ "Github repository" [![travis-ci status](https://secure.travis-ci.org/lua-stdlib/lua-stdlib.png?branch=master)](http://travis-ci.org/lua-stdlib/lua-stdlib/builds) +[![Stories in Ready](https://badge.waffle.io/lua-stdlib/lua-stdlib.png?label=ready&title=Ready)](https://waffle.io/lua-stdlib/lua-stdlib) -This is a collection of Lua libraries for Lua 5.1 and 5.2. The -libraries are copyright by their authors 2000-2013 (see the AUTHORS +This is a collection of Lua libraries for Lua 5.1, 5.2 and 5.3. The +libraries are copyright by their authors 2000-2015 (see the AUTHORS file for details), and released under the MIT license (the same license as Lua itself). There is no warranty. @@ -59,7 +60,7 @@ Documentation ------------- The libraries are [documented in LDoc][github.io]. Pre-built HTML -files are included. +files are included in the release. [github.io]: http://lua-stdlib.github.io/lua-stdlib diff --git a/aclocal.m4 b/aclocal.m4 index 05b078f..267246d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -735,6 +735,4 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR -m4_include([m4/ax_compare_version.m4]) m4_include([m4/ax_lua.m4]) -m4_include([m4/slingshot.m4]) diff --git a/bootstrap b/bootstrap index 575ce48..0b70e37 100755 --- a/bootstrap +++ b/bootstrap @@ -5,7 +5,7 @@ # Bootstrap an Autotooled package from checked-out sources. # Written by Gary V. Vaughan, 2010 -# Copyright (C) 2010-2014 Free Software Foundation, Inc. +# Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -820,30 +820,31 @@ slingshot_require_slingshot_submodule () else $require_slingshot_dotgitmodules - if test -f .gitmodules && test -f "slingshot/src/mkrockspecs.in" - then - : All present and correct. - - else + if test -f .gitmodules; then $require_slingshot_path $require_slingshot_url - trap slingshot_cleanup 1 2 13 15 + if test -f "slingshot/src/mkrockspecs.in"; then + : All present and correct. - shallow= - $GIT clone -h 2>&1 |func_grep_q -- --depth \ - && shallow='--depth 365' + else + trap slingshot_cleanup 1 2 13 15 - func_show_eval "$GIT clone $shallow '$slingshot_url' '$slingshot_path'" \ - slingshot_cleanup + shallow= + $GIT clone -h 2>&1 |func_grep_q -- --depth \ + && shallow='--depth 365' - # FIXME: Solaris /bin/sh will try to execute '-' if any of - # these signals are caught after this. - trap - 1 2 13 15 + func_show_eval "$GIT clone $shallow '$slingshot_url' '$slingshot_path'" \ + slingshot_cleanup + + # FIXME: Solaris /bin/sh will try to execute '-' if any of + # these signals are caught after this. + trap - 1 2 13 15 + fi # Make sure we've checked out the correct revision of slingshot. - func_show_eval "$GIT submodule init" \ - && func_show_eval "$GIT submodule update" \ + func_show_eval "$GIT submodule init -- $slingshot_path" \ + && func_show_eval "$GIT submodule update -- $slingshot_path" \ || func_fatal_error "Unable to update slingshot submodule." fi fi @@ -852,6 +853,49 @@ slingshot_require_slingshot_submodule () } +# require_bootstrap_uptodate +# -------------------------- +# Complain if the version of bootstrap in the build-aux directory differs +# from the one we are running. +require_bootstrap_uptodate=slingshot_require_bootstrap_uptodate +slingshot_require_bootstrap_uptodate () +{ + $debug_cmd + + $require_slingshot_submodule + + _G_slingshot_bootstrap=slingshot/bootstrap + + rm -f $progname.new + + if test -f "$_G_slingshot_bootstrap"; then + if func_cmp_s "$progpath" "$_G_slingshot_bootstrap"; then + func_verbose "bootstrap script up to date" + else + cp -f $_G_slingshot_bootstrap $progname.new + func_warning upgrade "\ +An updated slingshot bootstrap script is ready for you in +'$progname.new'. After you've verified that you want the +changes, you can update with: + mv -f $progname.new $progname + ./$progname + +Or you can disable this check permanently by adding the +following to 'bootstrap.conf': + require_bootstrap_uptodate=:" + fi + else + func_warning upgrade "\ +Your slingshot submodule appears to be damagedi, so I can't tell +whether your bootstrap has gone out of sync. Please check for +and undo any local changes, or revert to the slingshot revision +you were using previously, and rerun this script." + fi + + require_bootstrap_uptodate=: +} + + # slingshot_cleanup # ----------------- # Recursively delete everything at $slingshot_path. @@ -2424,7 +2468,7 @@ test -z "$progpath" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/funclib.sh test extract-trace = "$progname" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/options-parser # Set a version string. -scriptversion=2014-01-04.01; # UTC +scriptversion=2014-12-03.16; # UTC # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -2569,6 +2613,69 @@ func_autoconf_configure () } +# func_tool_version_output CMD [FATAL-ERROR-MSG] +# ---------------------------------------------- +# Attempt to run 'CMD --version', discarding errors. The output can be +# ignored by redirecting stdout, and this function used simply to test +# whether the command exists and exits normally when passed a +# '--version' argument. +# When FATAL-ERROR-MSG is given, then this function will display the +# message and exit if running 'CMD --version' returns a non-zero exit +# status. +func_tool_version_output () +{ + $debug_cmd + + _G_cmd=$1 + _G_fatal_error_msg=$2 + + # Some tools, like 'git2cl' produce thousands of lines of output + # unless stdin is /dev/null - in that case we want to return + # successfully without saving all of that output. Other tools, + # such as 'help2man' exit with a non-zero status when stdin comes + # from /dev/null, so we re-execute without /dev/null if that + # happens. This means that occasionally, the output from both calls + # ends up in the result, but the alternative would be to discard the + # output from one call, and hope the other produces something useful. + { $_G_cmd --version /dev/null + _G_status=$? + + test 0 -ne "$_G_status" && test -n "$_G_fatal_error_msg" \ + && func_fatal_error "$_G_fatal_error_msg" + + (exit $_G_status) +} + + +# func_tool_version_number CMD [FATAL-ERROR-MSG] +# ---------------------------------------------- +# Pass arguments to func_tool_version_output, but set +# $func_tool_version_number_result to the last dot delimited digit string +# on the first line of output. +func_tool_version_number () +{ + $debug_cmd + + _G_verout=`func_tool_version_output "$@"` + _G_status=$? + + # A version number starts with a digit following a space on the first + # line of output from `--version`. + _G_verout=`echo "$_G_verout" |sed 1q` + if test -n "$_G_verout"; then + _G_vernum=`expr "$_G_verout" : '.* \([0-9][^ ]*\)'` + fi + + if test -n "$_G_vernum"; then + printf '%s\n' "$_G_vernum" + else + printf '%s\n' "$_G_verout" + fi + + (exit $_G_status) +} + + # func_find_tool ENVVAR NAMES... # ------------------------------ # Search for a required program. Use the value of ENVVAR, if set, @@ -2586,16 +2693,44 @@ func_find_tool () if test -n "$_G_find_tool_res"; then _G_find_tool_error_prefix="\$$find_tool_envvar: " else + _G_find_tool_res= + _G_bestver= for _G_prog do - if func_tool_version_output $_G_prog >/dev/null; then - _G_find_tool_res=$_G_prog - break - fi + _G_find_tool_save_IFS=$IFS + IFS=: + for _G_dir in $PATH; do + IFS=$_G_find_tool_save_IFS + _G_progpath=$_G_dir/$_G_prog + test -r "$_G_progpath" && { + _G_curver=`func_tool_version_number $_G_progpath` + case $_G_bestver,$_G_curver in + ,) + # first non--version responsive prog sticks! + test -n "$_G_progpath" || _G_find_tool_res=$_G_progpath + ;; + ,*) + # first --version responsive prog beats non--version responsive! + _G_find_tool_res=$_G_progpath + _G_bestver=$_G_curver + ;; + *,*) + # another --version responsive prog must be newer to beat previous one! + test "x$_G_curver" = "x$_G_bestver" \ + || func_lt_ver "$_G_curver" "$_G_bestver" \ + || { + _G_find_tool_res=$_G_progpath + _G_bestver=$_G_curver + } + ;; + esac + } + done + IFS=$_G_find_tool_save_IFS done fi if test -n "$_G_find_tool_res"; then - func_tool_version_output >/dev/null $_G_find_tool_res "\ + func_tool_version_number >/dev/null $_G_find_tool_res "\ ${_G_find_tool_error_prefix}Cannot run '$_G_find_tool_res --version'" # Make sure the result is exported to the environment for children @@ -2610,39 +2745,6 @@ One of these is required: } -# func_tool_version_output CMD [FATAL-ERROR-MSG] -# ---------------------------------------------- -# Attempt to run 'CMD --version', discarding errors. The output can be -# ignored by redirecting stdout, and this function used simply to test -# whether the command exists and exits normally when passed a -# '--version' argument. -# When FATAL-ERROR-MSG is given, then this function will display the -# message and exit if running 'CMD --version' returns a non-zero exit -# status. -func_tool_version_output () -{ - $debug_cmd - - _G_cmd=$1 - _G_fatal_error_msg=$2 - - # Some tools, like 'git2cl' produce thousands of lines of output - # unless stdin is /dev/null - in that case we want to return - # successfully without saving all of that output. Other tools, - # such as 'help2man' exit with a non-zero status when stdin comes - # from /dev/null, so we re-execute without /dev/null if that - # happens. This means that occasionally, the output from both calls - # ends up in the result, but the alternative would be to discard the - # output from one call, and hope the other produces something useful. - { $_G_cmd --version /dev/null - _G_status=$? - - test 0 -ne "$_G_status" && test -n "$_G_fatal_error_msg" \ - && func_fatal_error "$_G_fatal_error_msg" - - (exit $_G_status) -} - ## -------------------- ## ## Resource management. ## @@ -2908,7 +3010,7 @@ test extract-trace = "$progname" && func_main "$@" # End: # Set a version string for *this* script. -scriptversion=2014-01-04.01; # UTC +scriptversion=2014-11-04.13; # UTC ## ------------------- ## @@ -3034,10 +3136,13 @@ func_reconfigure () $require_automake_options - # Automake (without 'foreign' option) requires that README exists. + # Automake (without 'foreign' option) requires that NEWS & README exist. case " $automake_options " in " foreign ") ;; - *) func_ensure_README ;; + *) + func_ensure_NEWS + func_ensure_README + ;; esac # Ensure ChangeLog presence. @@ -3336,6 +3441,7 @@ slingshot_copy_files () $require_slingshot_submodule # Make sure we have the latest mkrockspecs + # (the rebootstrap rule in slingshot/GNUmakefile autoruns). make -C slingshot build-aux/mkrockspecs # Update in-tree links. @@ -3367,6 +3473,65 @@ slingshot_ensure_changelog () func_add_hook func_prep slingshot_ensure_changelog +# slingshot_update_travis_yml +# --------------------------- +# When 'travis.yml.in' is listed in $slingshot_files, complain if +# regenerating '.travis.yml' would change it. +slingshot_update_travis_yml () +{ + $debug_cmd + + $require_git + + _G_travis_yml_in=travis.yml.in + _G_travis_yml_out=.travis.yml + + rm -f "$_G_travis_yml_out.new" + + test true = "$GIT" || { + case " "`echo $slingshot_files`" " in + *" travis.yml.in "*) + # Remove trailing blanks so as not to trip sc_trailing_blank in syntax check + test -f "$_G_travis_yml_in" && { + $slingshot_require_travis_extra_rocks + + eval `grep '^ *PACKAGE=' configure | sed 1q` + eval `grep '^ *VERSION=' configure | sed 1q` + + cat "$_G_travis_yml_in" | + sed 's| *$||' | + sed "s|@EXTRA_ROCKS@|`echo $travis_extra_rocks`|g" | + sed "s|@PACKAGE@|$PACKAGE|g" | + sed "s|@VERSION@|$VERSION|g" + + if test -f .slackid; then + read slackid < .slackid + printf '%s\n' '' 'notifications:' " slack: $slackid" + fi + } > "$_G_travis_yml_out.new" + + if test -f "$_G_travis_yml_out"; then + if func_cmp_s "$_G_travis_yml_out" "$_G_travis_yml_out.new"; then + func_verbose "$_G_travis_yml_out is up to date" + rm -f "$_G_travis_yml_out.new" + else + func_warning upgrade "\ +An updated $_G_travis_yml_out script is ready for you in +'$_G_travis_yml_out.new'. After you've verified that you want +the changes, you can update with: + mv -f $_G_travis_yml_out.new $_G_travis_yml_out" + fi + else + func_verbose "creating '$_G_travis_yml_out'" + mv -f "$_G_travis_yml_out.new" "$_G_travis_yml_out" + fi + ;; + esac + } +} +func_add_hook func_fini slingshot_update_travis_yml + + # slingshot_check_rockstree_path # ------------------------------ # Show a warning at the end of bootstrap if --luarocks-tree was passed @@ -3529,6 +3694,29 @@ EOT } +# func_ensure_NEWS +# ---------------- +# Without AM_INIT_AUTOMAKE([foreign]), automake will not run to +# completion with no NEWS file, even though NEWS.md or NEWS.txt +# is often preferable. +func_ensure_NEWS () +{ + $debug_cmd + + test -f NEWS || { + _G_NEWS= + for _G_news in NEWS.txt NEWS.md NEWS.rst; do + test -f "$_G_news" && break + done + + test -f "$_G_news" && $LN_S $_G_news NEWS + func_verbose "$LN_S $_G_news NEWS" + } + + return 0 +} + + # func_ensure_README # ------------------ # Without AM_INIT_AUTOMAKE([foreign]), automake will not run to @@ -3852,7 +4040,7 @@ func_require_autopoint () # -------------------------- # Complain if the version of bootstrap in the gnulib directory differs # from the one we are running. -require_bootstrap_uptodate=func_require_bootstrap_uptodate + func_require_bootstrap_uptodate () { $debug_cmd @@ -4054,7 +4242,7 @@ func_require_buildreq_patch () # The ugly find invocation is necessary to exit with non-zero # status for old find binaries that don't support -exec fully. if test ! -d "$local_gl_dir" \ - || find "$local_gl_dir" -name *.diff -exec false {} \; ; then : + || find "$local_gl_dir" -name "*.diff" -exec false {} \; ; then : else func_append buildreq 'patch - http://www.gnu.org/s/patch ' @@ -4206,7 +4394,7 @@ func_require_git () $opt_skip_git && GIT=true test true = "$GIT" || { - if test -f .git; then + if test -d .git/.; then ($GIT --version) >/dev/null 2>&1 || GIT=true fi } @@ -4424,8 +4612,8 @@ func_require_gnulib_submodule () fi # Make sure we've checked out the correct revision of gnulib. - func_show_eval "$GIT submodule init" \ - && func_show_eval "$GIT submodule update" \ + func_show_eval "$GIT submodule init -- $gnulib_path" \ + && func_show_eval "$GIT submodule update -- $gnulib_path" \ || func_fatal_error "Unable to update gnulib submodule." fi @@ -4529,6 +4717,9 @@ func_require_libtoolize () func_find_tool LIBTOOLIZE libtoolize glibtoolize } + test -n "$LIBTOOLIZE" || func_fatal_error "\ +Please install GNU Libtool, or 'export LIBTOOLIZE=/path/to/libtoolize'." + func_verbose "export LIBTOOLIZE='$LIBTOOLIZE'" # Make sure the search result is visible to subshells @@ -4766,6 +4957,9 @@ func_require_patch () func_find_tool PATCH gpatch patch } + test -n "$PATCH" || func_fatal_error "\ +Please install GNU Patch, or 'export PATCH=/path/to/gnu/patch'." + func_verbose "export PATCH='$PATCH'" # Make sure the search result is visible to subshells @@ -5257,7 +5451,7 @@ func_check_tool () ;; *) save_IFS=$IFS - IFS=: + IFS=${PATH_SEPARATOR-:} for _G_check_tool_path in $PATH; do IFS=$save_IFS if test -x "$_G_check_tool_path/$1"; then @@ -5403,6 +5597,9 @@ func_update_po_files () # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6+. func_find_tool SHA1SUM sha1sum gsha1sum shasum sha1 + test -n "$SHA1SUM" || func_fatal_error "\ +Please install GNU Coreutils, or 'export SHA1SUM=/path/to/sha1sum'." + _G_langs=`cd $_G_ref_po_dir && echo *.po|$SED 's|\.po||g'` test '*' = "$_G_langs" && _G_langs=x for _G_po in $_G_langs; do diff --git a/bootstrap.conf b/bootstrap.conf index 19ba632..ae8a642 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -1,6 +1,6 @@ -# bootstrap.conf (Stdlib) version 2014-01-04 +# bootstrap.conf (Stdlib) version 2015-01-03 # -# Copyright (C) 2013-2014 Gary V. Vaughan +# Copyright (C) 2013-2015 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # This is free software; see the source for copying conditions. There is NO @@ -17,10 +17,8 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html. ## -------------- ## @@ -28,16 +26,12 @@ ## -------------- ## # List of programs, minimum versions, and software urls required to -# bootstrap, maintain and release GNU Zile. +# bootstrap, maintain and release this project. -## !!WARNING!! Tidy up specs/specs.mk as instructed when buildreq bumps -#@ specl requirement to 12 or higher. - -# Build prerequisites buildreq=' - git 1.5.5 http://git-scm.com - ldoc 1.4.0 http://luarocks.org/repositories/rocks/ldoc-1.4.2-1.rockspec - specl 11 http://luarocks.org/repositories/rocks/specl-11-1.rockspec + git - http://git-scm.com + ldoc 1.4.2 http://rocks.moonscript.org/manifests/steved/ldoc-1.4.2-1.rockspec + specl 14.1.0 http://rocks.moonscript.org/manifests/gvvaughan/specl-14.1.0-1.rockspec ' # List of slingshot files to link into stdlib tree before autotooling. @@ -53,19 +47,20 @@ slingshot_files=' build-aux/sanity.mk build-aux/specl.mk build-aux/update-copyright - m4/ax_compare_version.m4 m4/ax_lua.m4 - m4/slingshot.m4 travis.yml.in ' +# Prequisite rocks that need to be installed for travis builds to work. +travis_extra_rocks=' + ansicolors + ldoc + specl +' + # No need to do any gnulib-tooling here. gnulib_tool=true -# The not-synced with gnulib warning is bogus until upstream adopts -# the saner bootstrap script. -require_bootstrap_uptodate=: - # Local variables: # mode: shell-script diff --git a/build-aux/config.ld.in b/build-aux/config.ld.in index fb4576f..7eff64d 100644 --- a/build-aux/config.ld.in +++ b/build-aux/config.ld.in @@ -1,6 +1,6 @@ -- -*- lua -*- -title = "@PACKAGE@ @VERSION@ Reference" -project = "stdlib" +title = "@PACKAGE_STRING@ Reference" +project = "@PACKAGE_STRING@" description = "Standard Lua Libraries" dir = "." @@ -11,6 +11,7 @@ file = { "../lib/std/functional.lua", "../lib/std/io.lua", "../lib/std/math.lua", + "../lib/std/operator.lua", "../lib/std/package.lua", "../lib/std/strict.lua", "../lib/std/string.lua", @@ -26,5 +27,8 @@ file = { "../lib/std/strbuf.lua", } +new_type ("object", "Objects", false, "Fields") + format = "markdown" +backtick_references = false sort = true diff --git a/build-aux/mkrockspecs b/build-aux/mkrockspecs index 63386bd..1b1080b 100755 --- a/build-aux/mkrockspecs +++ b/build-aux/mkrockspecs @@ -6,7 +6,7 @@ SH=--[[ # -*- mode: lua; -*- ## terms of the MIT license reproduced below. ## ==================================================================== -## Copyright (C) 2013-2014 Gary V. Vaughan +## Copyright (C) 2013-2015 Gary V. Vaughan ## ## Permission is hereby granted, free of charge, to any person ## obtaining a copy of this software and associated documentation @@ -29,11 +29,13 @@ SH=--[[ # -*- mode: lua; -*- ## ==================================================================== -_lua_version_re='"Lua 5."[12]*' -_lua_binaries='lua lua5.2 lua52 lua5.1 lua51' +_lua_version_re='"Lua 5."[123]*' +_lua_binaries='lua lua5.3 lua53 lua5.2 lua52 luajit lua5.1 lua51' +export LUA export LUA_INIT export LUA_INIT_5_2 +export LUA_INIT_5_3 export LUA_PATH export LUA_CPATH @@ -86,6 +88,7 @@ test -n "$LUA" || { LUA_INIT= LUA_INIT_5_2= +LUA_INIT_5_3= # Reexecute using the interpreter suppiled in LUA, or found above. exec "$LUA" "$0" "$@" @@ -155,7 +158,7 @@ Report bugs to http://github.com/gvvaughan/slingshot/issues.]]) end prog["--version"] = function () - print [[mkrockspecs (slingshot) 7 + print [[mkrockspecs (slingshot) 8.0.0 Written by Gary V. Vaughan , 2013 Copyright (C) 2013, Gary V. Vaughan @@ -358,8 +361,8 @@ default.build = default.build or { build_command = "./configure " .. "LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' " .. configure_flags .. "--prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' " .. - "&& make clean all", - install_command = "make install luadir='$(LUADIR)'", + "--datarootdir='$(PREFIX)' && make clean all", + install_command = "make install luadir='$(LUADIR)' luaexecdir='$(LIBDIR)'", copy_directories = {}, } diff --git a/build-aux/release.mk b/build-aux/release.mk index 698670b..13dce9a 100644 --- a/build-aux/release.mk +++ b/build-aux/release.mk @@ -1,7 +1,7 @@ # Slingshot release rules for GNU Make. # ====================================================================== -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2015 Free Software Foundation, Inc. # Originally by Jim Meyering, Simon Josefsson, Eric Blake, # Akim Demaille, Gary V. Vaughan, and others. # This version by Gary V. Vaughan, 2013. @@ -57,9 +57,10 @@ include Makefile ## Defaults. ## ## --------- ## -GIT ?= git -LUA ?= lua -TAR ?= tar +GIT ?= git +LUA ?= lua +LUAROCKS ?= luarocks +TAR ?= tar # Override this in cfg.mk if you are using a different format in your # NEWS file. @@ -75,7 +76,7 @@ _build-aux ?= build-aux my_distdir ?= $(PACKAGE)-$(VERSION) prev_version_file ?= $(srcdir)/.prev-version old_NEWS_hash-file ?= $(srcdir)/local.mk -gl_noteworthy_news_ = * Noteworthy changes in release ?.? (????-??-??) [?] +gl_noteworthy_news_ = \#\# Noteworthy changes in release ?.? (????-??-??) [?] PREV_VERSION = $(shell cat $(prev_version_file) 2>/dev/null) VERSION_REGEXP = $(subst .,\.,$(VERSION)) @@ -142,6 +143,7 @@ release-type = $(call member-check,RELEASE_TYPE,$(RELEASE_TYPES)) release: $(AM_V_GEN)$(MAKE) $(release-type) $(AM_V_GEN)$(MAKE) push + $(AM_V_GEN)$(MAKE) upload $(AM_V_GEN)$(MAKE) mail submodule-checks ?= no-submodule-changes public-submodule-commit @@ -225,7 +227,15 @@ vc-diff-check: # of '$(_build-aux)/do-release-commit-and-tag'. # If you want to search only lines 1-10, use "1,10". news-check-lines-spec ?= 3 -news-check-regexp ?= '^\*.* $(VERSION_REGEXP) \($(today)\)' +news-check-regexp ?= '^\#\#.* $(VERSION_REGEXP) \($(today)\)' + +Makefile.in: NEWS + +NEWS: + $(AM_V_GEN)if test -f NEWS.md; then ln -s NEWS.md NEWS; \ + elif test -f NEWS.rst; then ln -s NEWS.rst NEWS; \ + elif test -f NEWS.txt; then ln -s NEWS.txt NEWS; \ + fi news-check: NEWS $(AM_V_GEN)if $(SED) -n $(news-check-lines-spec)p $< \ @@ -237,7 +247,7 @@ news-check: NEWS fi .PHONY: release-commit -release-commit: +release-commit: NEWS $(AM_V_GEN)cd $(srcdir) \ && $(_build-aux)/do-release-commit-and-tag \ -C $(abs_builddir) $(VERSION) $(RELEASE_TYPE) @@ -261,7 +271,7 @@ release-prep: $(scm_rockspec) $(AM_V_at)$(MAKE) update-old-NEWS-hash $(AM_V_at)perl -pi \ -e '$$. == 3 and print "$(gl_noteworthy_news_)\n\n\n"' \ - $(srcdir)/NEWS + `readlink $(srcdir)/NEWS 2>/dev/null || echo $(srcdir)/NEWS` $(AM_V_at)msg=$$($(emit-commit-log)) || exit 1; \ cd $(srcdir) && $(GIT) commit -s -m "$$msg" -a @echo '**** Release announcement in ~/announce-$(my_distdir)' @@ -298,7 +308,10 @@ GITHUB_ROCKSPEC = (source.url:gsub ("^git://github", $(_PRE)):gsub ("%.git$$", $ announcement: NEWS # Not $(AM_V_GEN) since the output of this command serves as # announcement message: else, it would start with " GEN announcement". - $(AM_V_at)$(ANNOUNCE_PRINT) 'print (description.summary)' + $(AM_V_at)printf '%s\n' \ + '# [ANN] $(PACKAGE_NAME) $(VERSION) released' \ + '' + $(AM_V_at)$(ANNOUNCE_PRINT) 'print (description.detailed)' $(AM_V_at)printf '%s\n' '' \ 'I am happy to announce release $(VERSION) of $(PACKAGE_NAME).' \ '' @@ -306,14 +319,11 @@ announcement: NEWS 'print ("$(PACKAGE_NAME)'\''s home page is at " .. description.homepage)' $(AM_V_at)printf '\n' $(AM_V_at)$(SED) -n \ - -e '/^\* Noteworthy changes in release $(PREV_VERSION)/q' \ + -e '/^\#\# Noteworthy changes in release $(PREV_VERSION)/q' \ -e p NEWS |$(SED) -e 1,2d $(AM_V_at)printf '%s\n' \ 'Install it with LuaRocks, using:' '' \ - ' luarocks install $(PACKAGE) $(VERSION)' '' \ - 'Until the rocks are available from the official repository in a few days,' \ - 'you can install directly from the $(PACKAGE) release branch, with:' \ - '' ' $$ luarocks install '\\ + ' luarocks install $(PACKAGE) $(VERSION)' $(AM_V_at)$(ANNOUNCE_PRINT) 'print ($(GITHUB_ROCKSPEC))' @@ -358,8 +368,8 @@ check-in-release-branch: $(AM_V_at)$(TAR) zxf '$(release-tarball)' $(AM_V_at)rm -f '$(my_distdir)' '$(release-tarball)' $(AM_V_at)$(GIT) add . - $(AM_V_at)$(GIT) commit -s -a -m "Release v$(VERSION)." - $(AM_V_at)$(GIT) tag -s -a -m "Full source $(VERSION) release" release-v$(VERSION) + $(AM_V_at)$(GIT) commit -s -a -m 'Release v$(VERSION).' + $(AM_V_at)$(GIT) tag -s -a -m 'Full source release v$(VERSION)' release-v$(VERSION) $(AM_V_at)$(GCO) $(branch) .PHONY: push @@ -369,16 +379,15 @@ push: $(AM_V_at)$(GIT) push origin v$(VERSION) $(AM_V_at)$(GIT) push origin release-v$(VERSION) +.PHONY: upload +upload: rockspecs + $(AM_V_at)$(LUAROCKS) upload $${API_KEY+--api-key=$$API_KEY} \ + '$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec' + announce_emails ?= lua-l@lists.lua.org -rockspec_emails ?= luarocks-developers@lists.sourceforge.net .PHONY: mail mail: rockspecs $(AM_V_at)cat ~/announce-$(my_distdir) \ | mail -s '[ANN] $(PACKAGE) $(VERSION) released' -- \ $(announce_emails) - $(AM_V_at)printf '%s\n' \ - 'Rockspec for $(PACKAGE) version $(VERSION) at:' \ - `$(ANNOUNCE_PRINT) 'print ($(GITHUB_ROCKSPEC))'` \ - | mail -s '[ANN] $(PACKAGE) $(VERSION) released; rockspec url included' -- \ - $(rockspec_emails) diff --git a/build-aux/rockspecs.mk b/build-aux/rockspecs.mk index dc8859b..e64cab1 100644 --- a/build-aux/rockspecs.mk +++ b/build-aux/rockspecs.mk @@ -4,7 +4,7 @@ # terms of the MIT license reproduced below. # ==================================================================== # -# Copyright (C) 2013-2014 Reuben Thomas and Gary V. Vaughan # +# Copyright (C) 2013-2015 Reuben Thomas and Gary V. Vaughan # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation # diff --git a/build-aux/sanity-cfg.mk b/build-aux/sanity-cfg.mk index 693103f..6bbf697 100644 --- a/build-aux/sanity-cfg.mk +++ b/build-aux/sanity-cfg.mk @@ -1,3 +1,3 @@ -exclude_file_name_regexp--sc_error_message_uppercase = ^lib/std/optparse.lua$$ +exclude_file_name_regexp--sc_error_message_uppercase = ^lib/std/(list|optparse).lua$$ EXTRA_DIST += build-aux/sanity-cfg.mk diff --git a/build-aux/specl.mk b/build-aux/specl.mk index 6cee599..69ae66d 100644 --- a/build-aux/specl.mk +++ b/build-aux/specl.mk @@ -4,7 +4,7 @@ # terms of the MIT license reproduced below. # ==================================================================== # -# Copyright (C) 2013-2014 Gary V. Vaughan # +# Copyright (C) 2013-2015 Gary V. Vaughan # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation # @@ -33,9 +33,17 @@ ## Specl. ## ## ------ ## +SPECL_ENV += \ + LUA='$(LUA)' \ + abs_top_builddir='$(abs_top_builddir)' \ + abs_top_srcdir='$(abs_top_srcdir)' \ + top_builddir='$(top_builddir)' \ + top_srcdir='$(top_srcdir)' \ + $(NOTHING_ELSE) + check_local += specl-check-local specl-check-local: $(specl_SPECS) - $(SPECL_ENV) LUA=$(LUA) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) + $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) ## ------------- ## diff --git a/configure b/configure index 145e36b..5240374 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 40. +# Generated by GNU Autoconf 2.69 for stdlib 41.0.0. # # Report bugs to . # @@ -580,14 +580,13 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='40' -PACKAGE_STRING='stdlib 40' +PACKAGE_VERSION='41.0.0' +PACKAGE_STRING='stdlib 41.0.0' PACKAGE_BUGREPORT='http://github.com/lua-stdlib/lua-stdlib/issues' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS -EXTRA_ROCKS SED EGREP GREP @@ -1217,7 +1216,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 40 to adapt to many kinds of systems. +\`configure' configures stdlib 41.0.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1283,7 +1282,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 40:";; + short | recursive ) echo "Configuration of stdlib 41.0.0:";; esac cat <<\_ACEOF @@ -1363,7 +1362,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 40 +stdlib configure 41.0.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1380,7 +1379,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 40, which was +It was created by stdlib $as_me 41.0.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1759,9 +1758,9 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -$as_echo "## --------------------- ## -## Configuring stdlib 40 ## -## --------------------- ##" +$as_echo "## ------------------------- ## +## Configuring stdlib 41.0.0 ## +## ------------------------- ##" echo am__api_version='1.14' @@ -2250,7 +2249,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='40' + VERSION='41.0.0' cat >>confdefs.h <<_ACEOF @@ -2391,7 +2390,7 @@ AM_BACKSLASH='\' { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LUA is a Lua interpreter" >&5 $as_echo_n "checking if $LUA is a Lua interpreter... " >&6; } - if $LUA -e "print('Hello ' .. _VERSION .. '!')" &>/dev/null; then : + if $LUA -e "print('Hello ' .. _VERSION .. '!')" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -2401,89 +2400,16 @@ $as_echo "no" >&6; } fi - _ax_check_text="whether $LUA version >= 5.1, < 5.3" + _ax_check_text="whether $LUA version >= 5.1, < 5.4" { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 $as_echo_n "checking $_ax_check_text... " >&6; } - _ax_test_ver=`$LUA -e "print(_VERSION)" 2>/dev/null | \ - sed "s|^Lua \(.*\)|\1|" | grep -o "^[0-9]\+\\.[0-9]\+"` - if test "x$_ax_test_ver" = 'x'; then : - _ax_test_ver='0' -fi - - - - # Used to indicate true or false condition - ax_compare_version=false - - # Convert the two version strings to be compared into a format that - # allows a simple string comparison. The end result is that a version - # string of the form 1.12.5-r617 will be converted to the form - # 0001001200050617. In other words, each number is zero padded to four - # digits, and non digits are removed. - - ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version_B=`echo "5.1" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version=`echo "x$ax_compare_version_A -x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` - - - - if test "$ax_compare_version" = "true" ; then - : - fi - - if $ax_compare_version; then : - - - - # Used to indicate true or false condition - ax_compare_version=false - - # Convert the two version strings to be compared into a format that - # allows a simple string comparison. The end result is that a version - # string of the form 1.12.5-r617 will be converted to the form - # 0001001200050617. In other words, each number is zero padded to four - # digits, and non digits are removed. - - ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version_B=`echo "5.3" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version=`echo "x$ax_compare_version_A -x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/false/;s/x${ax_compare_version_B}/true/;1q"` - - - - if test "$ax_compare_version" = "true" ; then - : - fi - -fi - - if $ax_compare_version; then : + if $LUA 2>/dev/null -e ' + function norm (v) + i,j=v:match "(%d+)%.(%d+)" if i then return 100 * i + j end + end + v, toobig=norm (_VERSION), norm "5.4" or math.huge + os.exit ((v >= norm ("5.1") and v < toobig) and 0 or 1)'; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -2495,101 +2421,28 @@ fi ax_display_LUA=$LUA else - _ax_check_text="for a Lua interpreter with version >= 5.1, < 5.3" + _ax_check_text="for a Lua interpreter with version >= 5.1, < 5.4" { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 $as_echo_n "checking $_ax_check_text... " >&6; } if ${ax_cv_pathless_LUA+:} false; then : $as_echo_n "(cached) " >&6 else - for ax_cv_pathless_LUA in lua lua5.2 lua5.1 lua50 none; do + for ax_cv_pathless_LUA in lua lua5.2 lua52 lua5.1 lua51 lua50 none; do test "x$ax_cv_pathless_LUA" = 'xnone' && break - if $ax_cv_pathless_LUA -e "print('Hello ' .. _VERSION .. '!')" &>/dev/null; then : + if $ax_cv_pathless_LUA -e "print('Hello ' .. _VERSION .. '!')" >/dev/null 2>&1; then : else continue fi - _ax_test_ver=`$ax_cv_pathless_LUA -e "print(_VERSION)" 2>/dev/null | \ - sed "s|^Lua \(.*\)|\1|" | grep -o "^[0-9]\+\\.[0-9]\+"` - if test "x$_ax_test_ver" = 'x'; then : - _ax_test_ver='0' -fi - - - - # Used to indicate true or false condition - ax_compare_version=false - - # Convert the two version strings to be compared into a format that - # allows a simple string comparison. The end result is that a version - # string of the form 1.12.5-r617 will be converted to the form - # 0001001200050617. In other words, each number is zero padded to four - # digits, and non digits are removed. - - ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version_B=`echo "5.1" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version=`echo "x$ax_compare_version_A -x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` - - - - if test "$ax_compare_version" = "true" ; then - : - fi - - if $ax_compare_version; then : - - - - # Used to indicate true or false condition - ax_compare_version=false - - # Convert the two version strings to be compared into a format that - # allows a simple string comparison. The end result is that a version - # string of the form 1.12.5-r617 will be converted to the form - # 0001001200050617. In other words, each number is zero padded to four - # digits, and non digits are removed. - - ax_compare_version_A=`echo "$_ax_test_ver" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version_B=`echo "5.3" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ - -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ - -e 's/[^0-9]//g'` - - - ax_compare_version=`echo "x$ax_compare_version_A -x$ax_compare_version_B" | sed 's/^ *//' | sort -r | sed "s/x${ax_compare_version_A}/false/;s/x${ax_compare_version_B}/true/;1q"` - - - - if test "$ax_compare_version" = "true" ; then - : - fi - -fi - - if $ax_compare_version; then : + if $ax_cv_pathless_LUA 2>/dev/null -e ' + function norm (v) + i,j=v:match "(%d+)%.(%d+)" if i then return 100 * i + j end + end + v, toobig=norm (_VERSION), norm "5.4" or math.huge + os.exit ((v >= norm ("5.1") and v < toobig) and 0 or 1)'; then : break fi @@ -2656,10 +2509,7 @@ $as_echo_n "checking for $ax_display_LUA version... " >&6; } if ${ax_cv_lua_version+:} false; then : $as_echo_n "(cached) " >&6 else - ax_cv_lua_version=`$LUA -e "print(_VERSION)" | \ - sed "s|^Lua \(.*\)|\1|" | \ - grep -o "^[0-9]\+\\.[0-9]\+"` - + ax_cv_lua_version=`$LUA -e 'print(_VERSION:match "(%d+%.%d+)")'` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_version" >&5 $as_echo "$ax_cv_lua_version" >&6; } @@ -2703,21 +2553,15 @@ fi - ax_lua_prefixed_path='' - _ax_package_paths=`$LUA -e 'print(package.path)' 2>/dev/null | sed 's|;|\n|g'` - for _ax_package_path in $_ax_package_paths; do - _ax_path_parts=`echo "$_ax_package_path" | sed 's|/|\n|g'` - _ax_reassembled='' - for _ax_path_part in $_ax_path_parts; do - echo "$_ax_path_part" | grep '\?' >/dev/null && break - _ax_reassembled="$_ax_reassembled/$_ax_path_part" - done - _ax_package_path=$_ax_reassembled - if echo "$_ax_package_path" | grep "^$ax_lua_prefix" >/dev/null; then - ax_lua_prefixed_path=$_ax_package_path - break - fi - done + ax_lua_prefixed_path=`$LUA 2>/dev/null -e ' + package.path:gsub ("([^;]+)", + function (p) + p = p:gsub ("%?.*$", ""):gsub ("/[^/]*$", "") + if p:match ("^$ax_lua_prefix") and (not shortest or #shortest > #p) then + shortest = p + end + end) + print (shortest or "")'` if test "x$ax_lua_prefixed_path" != 'x'; then : _ax_strip_prefix=`echo "$ax_lua_prefix" | sed 's|.|.|g'` @@ -2749,21 +2593,15 @@ fi - ax_lua_prefixed_path='' - _ax_package_paths=`$LUA -e 'print(package.cpathd)' 2>/dev/null | sed 's|;|\n|g'` - for _ax_package_path in $_ax_package_paths; do - _ax_path_parts=`echo "$_ax_package_path" | sed 's|/|\n|g'` - _ax_reassembled='' - for _ax_path_part in $_ax_path_parts; do - echo "$_ax_path_part" | grep '\?' >/dev/null && break - _ax_reassembled="$_ax_reassembled/$_ax_path_part" - done - _ax_package_path=$_ax_reassembled - if echo "$_ax_package_path" | grep "^$ax_lua_exec_prefix" >/dev/null; then - ax_lua_prefixed_path=$_ax_package_path - break - fi - done + ax_lua_prefixed_path=`$LUA 2>/dev/null -e ' + package.cpath:gsub ("([^;]+)", + function (p) + p = p:gsub ("%?.*$", ""):gsub ("/[^/]*$", "") + if p:match ("^$ax_lua_exec_prefix") and (not shortest or #shortest > #p) then + shortest = p + end + end) + print (shortest or "")'` if test "x$ax_lua_prefixed_path" != 'x'; then : _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | sed 's|.|.|g'` @@ -3066,30 +2904,8 @@ $as_echo "$ac_cv_path_SED" >&6; } rm -f conftest.sed - - # is required by all slingshot clients for mkrockspecs. - EXTRA_ROCKS=- - for _ss_rock in lyaml ldoc specl; do - case $EXTRA_ROCKS in - *" $_ss_rock;"*) ;; # ignore duplicates - *) - test "x$PACKAGE_NAME" != "x$_ss_rock" \ - && EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" - ;; - esac - done - - # Avoid empty travis commands. - test "x$EXTRA_ROCKS" != "x-" || EXTRA_ROCKS='# No extra rocks needed here;' - - - ac_config_files="$ac_config_files .travis.yml:travis.yml.in" - - ac_config_files="$ac_config_files Makefile build-aux/config.ld" -ac_config_files="$ac_config_files specs/spec_helper.lua" - cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -3641,7 +3457,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 40, which was +This file was extended by stdlib $as_me 41.0.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3694,7 +3510,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 40 +stdlib config.status 41.0.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -3807,10 +3623,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - ".travis.yml") CONFIG_FILES="$CONFIG_FILES .travis.yml:travis.yml.in" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "build-aux/config.ld") CONFIG_FILES="$CONFIG_FILES build-aux/config.ld" ;; - "specs/spec_helper.lua") CONFIG_FILES="$CONFIG_FILES specs/spec_helper.lua" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac @@ -4235,14 +4049,6 @@ which seems to be undefined. Please make sure it is defined" >&2;} esac - - case $ac_file$ac_mode in - ".travis.yml":F) - # Remove trailing blanks so as not to trip sc_trailing_blank in syntax check - sed 's| *$||' < .travis.yml > ss_tmp && mv ss_tmp .travis.yml; rm -f ss_tmp ;; - "specs/spec_helper.lua":F) chmod a-w specs/spec_helper.lua ;; - - esac done # for ac_tag diff --git a/configure.ac b/configure.ac index e767700..fe6dc3d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl configure.ac dnl -dnl Copyright (c) 2012-2014 Free Software Foundation, Inc. +dnl Copyright (C) 2012-2015 Gary V. Vaughan dnl Written by Gary V. Vaughan, 2012 dnl dnl This program is free software; you can redistribute it and/or modify @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [40], [http://github.com/lua-stdlib/lua-stdlib/issues]) +AC_INIT([stdlib], [41.0.0], [http://github.com/lua-stdlib/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) @@ -29,14 +29,12 @@ AM_INIT_AUTOMAKE([-Wall]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) dnl Check for programs -AX_PROG_LUA([5.1], [5.3]) +AX_PROG_LUA([5.1], [5.4]) AC_PATH_PROG([LDOC], [ldoc], [:]) AC_PATH_PROG([SPECL], [specl], [:]) AC_PROG_EGREP AC_PROG_SED dnl Generate output files -SS_CONFIG_TRAVIS([ldoc specl]) AC_CONFIG_FILES([Makefile build-aux/config.ld]) -AC_CONFIG_FILES([specs/spec_helper.lua], [chmod a-w specs/spec_helper.lua]) AC_OUTPUT diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 35ce67d..09ccb87 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    _G.opFunctional forms of infix operators.
    std Module table. Die with error.
    monkey_patch ([namespace=_G])Overwrite core methods and metamethods with std enhanced versions.
    process_files (f) Process files specified on the command-line.
    Remove leading matter from a string.
    monkey_patch ([namespace=_G])Overwrite core methods and metamethods with std enhanced versions.
    numbertosi (n) Write a number using SI suffixes.
    Make a shallow copy of a table, including any metatable.
    clone_select (t[, selection={}])clone_select (t[, keys={}]) Make a partial clone of a table.
    Make the list of keys in table.
    merge (t, u)Destructively merge another table's fields into table.merge (t, u[, map={}], nometa)Destructively merge another table's fields into another.
    merge_select (t, u[, keys={}], nometa)Destructively merge another table's named fields into table.
    metamethod (x, n)Return given metamethod, if any, or nil.
    monkey_patch ([namespace=_G])Overwrite core methods with std enhanced versions.
    new (x, t)
    - +
    std.containerstd.container.Container Container prototype.
    -

    Metamethods

    - - - - - - - - - - - - - -
    std.container:__call (x, ...)Return a clone of this container.
    std.container:__tostring ()Return a string representation of this container.
    std.container:__totable ()Return a table representation of this container.


    -

    Tables

    +

    Objects

    +
    - - std.container + + std.container.Container
    - Container prototype. + Container prototype.

    + +

    Container also inherits all the fields and methods from + std.object.Object.

    Fields:

    - - -
    -
    -

    Metamethods

    -
    -
    - - std.container:__call (x, ...) -
    -
    - Return a clone of this container. - - -

    Parameters:

    -
      -
    • x - a table if prototype _init is a table, otherwise first - argument for a function type _init -
    • -
    • ... - any additional arguments for _init -
    • -
    - -

    Returns:

    -
      - - std.container - a clone of the called container. -
    - -

    See also:

    - -
    -
    - - std.container:__tostring () -
    -
    - Return a string representation of this container. - - - -

    Returns:

    -
      - - string - stringified container representation -
    - - -

    See also:

    +

    Usage:

      - std.object.__tostring +
      + local std = require "std"
      + local Container = std.container {}
      +
      + local Graph = Container {
      +   _type = "Graph",
      +   _functions = {
      +     nodes = function (graph)
      +       local n = 0
      +       for _ in std.pairs (graph) do n = n + 1 end
      +       return n
      +     end,
      +   },
      + }
      + local g = Graph { "node1", "node2" }
      + --> 2
      + print (Graph.nodes (g))
    - -
    -
    - - std.container:__totable () -
    -
    - Return a table representation of this container. - - - -

    Returns:

    -
      - - table - a shallow copy of non-private container fields -
    - - -

    See also:

    - - -
    @@ -275,7 +171,8 @@

    See also:

    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 14faae7..5d9c2d5 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    @@ -337,12 +205,7 @@

    Returns:

    std.list.compare (l, m)
    - -

    Compare two lists element-by-element, from left-to-right.

    - -
     if a_list:compare (another_list) == 0 then print "same" end
    -
    - + Compare two lists element-by-element, from left-to-right.

    Parameters:

    @@ -352,20 +215,24 @@

    Parameters:

    a list
  • m - table - another list + List or table + another list, or table
  • Returns:

      - -1 if l is less than m, 0 if they are the same, and 1 - if l is greater than m + -1 if l is less than m, 0 if they are the same, and 1 + if l is greater than m
    +

    Usage:

    +
      +
      if a_list:compare (another_list) == 0 then print "same" end
      +
    @@ -373,7 +240,7 @@

    Returns:

    std.list.concat (l, ...)
    - Concatenate arguments into a list. + Concatenate the elements from any number of lists.

    Parameters:

    @@ -391,12 +258,17 @@

    Returns:

      List - new list containing - {l[1], ..., l[#l], l_1[1], ..., l_1[#l_1], ..., l_n[1], ..., l_n[#l_n]} + new list with elements from arguments
    +

    Usage:

    +
      +
      + --> {1, 2, 3, {4, 5}, 6, 7}
      + list.concat ({1, 2, 3}, {{4, 5}, 6, 7})
      +
    @@ -422,50 +294,25 @@

    Returns:

      List - new list containing {x, unpack (l)} + new list with x followed by elements of l
    - - -
    - - std.list.depair (ls) -
    -
    - Turn a list of pairs into a table. - - -

    Parameters:

    -
      -
    • ls - table - list of lists {{i1, v1}, ..., {in, vn}} -
    • -
    - -

    Returns:

    -
      - - table - a new list containing table {i1=v1, ..., in=vn} -
    - - -

    See also:

    +

    Usage:

      - enpair +
      + --> {"x", 1, 2, 3}
      + list.cons ({1, 2, 3}, "x")
    -
    - - std.list.elems (l) + + std.list.rep (l, n)
    - An iterator over the elements of a list. + Repeat a list.

    Parameters:

    @@ -474,38 +321,9 @@

    Parameters:

    List a list - - -

    Returns:

    -
      -
    1. - function - iterator function which returns successive elements - of l
    2. -
    3. - List - l
    4. -
    5. - true
    6. -
    - - - - -
    -
    - - std.list.enpair (t) -
    -
    - Turn a table into a list of pairs. - - -

    Parameters:

    -
      -
    • t - table - a table {i1=v1, ..., in=vn} +
    • n + int + number of times to repeat
    @@ -513,59 +331,71 @@

    Returns:

      List - a new list containing {{i1, v1}, ..., {in, vn}} + n copies of l appended together
    -

    See also:

    + +

    Usage:

      - depair +
      + --> {1, 2, 3, 1, 2, 3, 1, 2, 3}
      + list.rep ({1, 2, 3}, 3)
    -
    - - std.list.filter (p, l) + + std.list.sub (l[, from=1[, to=#l]])
    - Filter a list according to a predicate. + Return a sub-range of a list. + (The equivalent of ??? on strings; negative list indices + count from the end of the list.)

    Parameters:

      -
    • p - func - predicate function, of one argument returning a boolean -
    • l List a list
    • +
    • from + int + start of range + (default 1) +
    • +
    • to + int + end of range + (default #l) +

    Returns:

      List - new list containing elements e of l for which - p (e) is true + new list containing elements between from and to + inclusive
    -

    See also:

    + +

    Usage:

      - std.list:filter +
      + --> {3, 4, 5}
      + list.sub ({1, 2, 3, 4, 5, 6}, 3, 5)
    -
    - - std.list.flatten (l) + + std.list.tail (l)
    - Flatten a list. + Return a list with its first element removed.

    Parameters:

    @@ -580,1140 +410,153 @@

    Returns:

      List - flattened list + new list with all but the first element of l
    +

    Usage:

    +
      +
      + --> {3, {4, 5}, 6, 7}
      + list.tail {{1, 2}, 3, {4, 5}, 6, 7}
      +
    + +

    Metamethods

    + +
    - - std.list.foldl (fn, e, l) + + std.list:__add (l, e)
    - Fold a binary function through a list left associatively. + Append element to list.

    Parameters:

      -
    • fn - func - binary function -
    • -
    • e - element to place in left-most position -
    • l List a list
    • +
    • e + element to append +
    -

    Returns:

    -
      - - result -

    See also:

    +

    Usage:

    +
      +
      list = list + "element"
      +
    - - std.list.foldr (fn, e, l) + + std.list:__concat (l, m)
    - Fold a binary function through a list right associatively. + Concatenate lists.

    Parameters:

      -
    • fn - func - binary function -
    • -
    • e - element to place in right-most position -
    • l List a list
    • +
    • m + List or table + another list, or table (hash part is ignored) +
    -

    Returns:

    -
      - - result -

    See also:

    +

    Usage:

    +
      +
      new = alist .. {"append", "these", "elements"}
      +
    - - std.list.index_key (f, l) + + std.list:__le (l, m)
    - Make an index of a list of tables on a given field + List equality or order operator.

    Parameters:

      -
    • f - field -
    • l List - list of tables {t1, ..., tn} + a list +
    • +
    • m + List + another list
    -

    Returns:

    -
      - - List - index {t1[f]=1, ..., tn[f]=n} -
    +

    See also:

    + +

    Usage:

    +
      +
      min = list1 <= list2 and list1 or list2
      +
    - - std.list.index_value (f, l) + + std.list:__lt (l, m)
    - Copy a list of tables, indexed on a given field + List order operator.

    Parameters:

      -
    • f - field whose value should be used as index -
    • l List - list of tables {i1=t1, ..., in=tn} + a list +
    • +
    • m + List + another list
    -

    Returns:

    -
      - - List - index {t1[f]=t1, ..., tn[f]=tn} -
    - - - - -
    -
    - - std.list.map (fn, l) -
    -
    - Map a function over a list. -

    Parameters:

    +

    See also:

      -
    • fn - func - map function -
    • -
    • l - List - a list -
    • + compare
    -

    Returns:

    -
      - - List - new list containing {fn (l[1]), ..., fn (l[#l])} -
    - - -

    See also:

    - - - -
    -
    - - std.list.map_with (fn, ls) -
    -
    - Map a function over a list of lists. - - -

    Parameters:

    -
      -
    • fn - func - map function -
    • -
    • ls - List - a list of lists -
    • -
    - -

    Returns:

    -
      - - List - new list {fn (unpack (ls[1]))), ..., fn (unpack (ls[#ls]))} -
    - - - - -
    -
    - - std.list.project (f, l) -
    -
    - Project a list of fields from a list of tables. - - -

    Parameters:

    -
      -
    • f - field to project -
    • -
    • l - List - a list -
    • -
    - -

    Returns:

    -
      - - List - list of f fields -
    - - -

    See also:

    - - - -
    -
    - - std.list.relems (l) -
    -
    - An iterator over the elements of a list, in reverse. - - -

    Parameters:

    -
      -
    • l - List - a list -
    • -
    - -

    Returns:

    -
      -
    1. - function - iterator function which returns precessive elements - of the l
    2. -
    3. - List - l
    4. -
    5. - true
    6. -
    - - - - -
    -
    - - std.list.rep (l, n) -
    -
    - Repeat a list. - - -

    Parameters:

    -
      -
    • l - List - a list -
    • -
    • n - int - number of times to repeat -
    • -
    - -

    Returns:

    -
      - - List - n copies of l appended together -
    - - - - -
    -
    - - std.list.reverse (l) -
    -
    - Reverse a list. - - -

    Parameters:

    -
      -
    • l - List - a list -
    • -
    - -

    Returns:

    -
      - - List - new list containing {l[#l], ..., l[1]} -
    - - - - -
    -
    - - std.list.shape (s, l) -
    -
    - Shape a list according to a list of dimensions.

    - -

    Dimensions are given outermost first and items from the original - list are distributed breadth first; there may be one 0 indicating - an indefinite number. Hence, {0} is a flat list, - {1} is a singleton, {2, 0} is a list of - two lists, and {0, 2} is a list of pairs.

    - -

    Algorithm: turn shape into all positive numbers, calculating - the zero if necessary and making sure there is at most one; - recursively walk the shape, adding empty tables until the bottom - level is reached at which point add table items instead, using a - counter to walk the flattened original list. - - -

    Parameters:

    -
      -
    • s - table - {d1, ..., dn} -
    • -
    • l - List - a list -
    • -
    - -

    Returns:

    -
      - - reshaped list -
    - - -

    See also:

    - - - -
    -
    - - std.list.sub (l, from, to) -
    -
    - Return a sub-range of a list. - (The equivalent of string.sub on strings; negative list indices - count from the end of the list.) - - -

    Parameters:

    -
      -
    • l - List - a list -
    • -
    • from - int - start of range (default: 1) -
    • -
    • to - int - end of range (default: #l) -
    • -
    - -

    Returns:

    -
      - - List - new list containing {l[from], ..., l[to]} -
    - - - - -
    -
    - - std.list.tail (l) -
    -
    - Return a list with its first element removed. - - -

    Parameters:

    -
      -
    • l - List - a list -
    • -
    - -

    Returns:

    -
      - - List - new list containing {l[2], ..., l[#l]} -
    - - - - -
    -
    - - std.list.transpose (ls) -
    -
    - Transpose a list of lists. - This function in Lua is equivalent to zip and unzip in more strongly - typed languages. - - -

    Parameters:

    -
      -
    • ls - table - {{ls<1,1>, ..., ls<1,c>}, ..., {ls<r,1>, ..., ls<r,c>}} -
    • -
    - -

    Returns:

    -
      - - List - new list containing - {{ls<1,1>, ..., ls<r,1>}, ..., {ls<1,c>, ..., ls<r,c>}} -
    - - - - -
    -
    - - std.list.zip_with (ls, f) -
    -
    - Zip a list of lists together with a function. - - -

    Parameters:

    -
      -
    • ls - table - list of lists -
    • -
    • f - function - function -
    • -
    - -

    Returns:

    -
      - - List - -
      a new list containing
      -
      -

      {f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) - where N = max {map (function (l) return #l end, ls)}

      - -
    - - - - -
    -
    -

    Tables

    -
    -
    - - std.list.List -
    -
    - An Object derived List. - - - - - - - -
    -
    -

    Metamethods

    -
    -
    - - std.list:__add (list, element) -
    -
    - -

    Append element to list.

    -
     list = list + element
    -
    - - - -

    Parameters:

    -
      -
    • list - List - a list -
    • -
    • element - element to append -
    • -
    - - - -

    See also:

    - - - -
    -
    - - std.list:__concat (list, table) -
    -
    - -

    Concatenate lists.

    -
     new = list .. table
    -
    - - - -

    Parameters:

    -
      -
    • list - List - a list -
    • -
    • table - table - another list, hash part is ignored -
    • -
    - - - -

    See also:

    - - - -
    -
    - - std.list:__le (list1, list2) -
    -
    - -

    List equality or order operator.

    -
     min = list1 <= list2 and list1 or list2
    -
    - - - -

    Parameters:

    -
      -
    • list1 - List - a list -
    • -
    • list2 - List - another list -
    • -
    - - - -

    See also:

    - - - -
    -
    - - std.list:__lt (list1, list2) -
    -
    - -

    List order operator.

    -
     max = list1 > list2 and list1 or list2
    -
    - - - -

    Parameters:

    -
      -
    • list1 - List - a list -
    • -
    • list2 - List - another list -
    • -
    - - - -

    See also:

    - - - -
    -
    -

    Methods

    -
    -
    - - std.list:append (x) -
    -
    - Append an item to a list. - - -

    Parameters:

    -
      -
    • x - item -
    • -
    - -

    Returns:

    -
      - - List - new list containing {self[1], ..., self[#self], x} -
    - - - - -
    -
    - - std.list:compare (l) -
    -
    - -

    Compare two lists element-by-element, from left-to-right.

    - -
     if a_list:compare (another_list) == 0 then print "same" end
    -
    - - - -

    Parameters:

    -
      -
    • l - table - a list -
    • -
    - -

    Returns:

    -
      - - -1 if self is less than l, 0 if they are the same, and 1 - if self is greater than l -
    - - - - -
    -
    - - std.list:concat (...) -
    -
    - Concatenate arguments into a list. - - -

    Parameters:

    -
      -
    • ... - tuple of lists -
    • -
    - -

    Returns:

    -
      - - List - new list containing - {self[1], ..., self[#self], l_1[1], ..., l_1[#l_1], ..., l_n[1], ..., l_n[#l_n]} -
    - - - - -
    -
    - - std.list:cons (x) -
    -
    - Prepend an item to a list. - - -

    Parameters:

    -
      -
    • x - item -
    • -
    - -

    Returns:

    -
      - - List - new list containing {x, unpack (self)} -
    - - - - -
    -
    - - std.list:elems () -
    -
    - An iterator over the elements of a list. - - - -

    Returns:

    -
      -
    1. - function - iterator function which returns successive - elements of self
    2. -
    3. - List - self
    4. -
    5. - true
    6. -
    - - - - -
    -
    - - std.list:filter (p) -
    -
    - Filter a list according to a predicate. - - -

    Parameters:

    -
      -
    • p - func - predicate function, of one argument returning a boolean -
    • -
    - -

    Returns:

    -
      - - List - new list containing elements e of self for which - p (e) is true -
    - - -

    See also:

    - - - -
    -
    - - std.list:flatten () -
    -
    - Flatten a list. - - - -

    Returns:

    -
      - - List - flattened list -
    - - - - -
    -
    - - std.list:foldl (fn, e) -
    -
    - Fold a binary function through a list left associatively. - - -

    Parameters:

    -
      -
    • fn - func - binary function -
    • -
    • e - element to place in left-most position -
    • -
    - -

    Returns:

    -
      - - result -
    - - -

    See also:

    - - - -
    -
    - - std.list:foldr (f, e) -
    -
    - Fold a binary function through a list right associatively. - - -

    Parameters:

    -
      -
    • f - func - binary function -
    • -
    • e - element to place in right-most position -
    • -
    - -

    Returns:

    -
      - - result -
    - - -

    See also:

    - - - -
    -
    - - std.list:map (fn) -
    -
    - Map a function over a list. - - -

    Parameters:

    -
      -
    • fn - func - map function -
    • -
    - -

    Returns:

    -
      - - List - new list containing - {fn (self[1]), ..., fn (self[#self])} -
    - - -

    See also:

    - - - -
    -
    - - std.list:project (f) -
    -
    - Project a list of fields from a list of tables. - - -

    Parameters:

    -
      -
    • f - field to project -
    • -
    - -

    Returns:

    -
      - - List - list of f fields -
    - - -

    See also:

    - - - -
    -
    - - std.list:relems () -
    -
    - An iterator over the elements of a list, in reverse. - - - -

    Returns:

    -
      -
    1. - function - iterator function which returns precessive elements - of the self
    2. -
    3. - List - self
    4. -
    5. - true
    6. -
    - - - - -
    -
    - - std.list:rep (n) -
    -
    - Repeat a list. - - -

    Parameters:

    -
      -
    • n - int - number of times to repeat -
    • -
    - -

    Returns:

    -
      - - List - n copies of self appended together -
    - - - - -
    -
    - - std.list:reverse () -
    -
    - Reverse a list. - - - -

    Returns:

    -
      - - List - new list containing {self[#self], ..., self[1]} -
    - - - - -
    -
    - - std.list:shape (s) -
    -
    - Shape a list according to a list of dimensions. - - -

    Parameters:

    -
      -
    • s - table - {d1, ..., dn} -
    • -
    - -

    Returns:

    -
      - - reshaped list -
    - - -

    See also:

    - - - -
    -
    - - std.list:sub (from, to) -
    -
    - Return a sub-range of a list. - (The equivalent of string.sub on strings; negative list indices - count from the end of the list.) - - -

    Parameters:

    +

    Usage:

      -
    • from - int - start of range (default: 1) -
    • -
    • to - int - end of range (default: #self) -
    • +
      max = list1 > list2 and list1 or list2
    -

    Returns:

    -
      - - List - new list containing {self[from], ..., self[to]} -
    - - - - -
    -
    - - std.list:tail () -
    -
    - Return a list with its first element removed. - - - -

    Returns:

    -
      - - List - new list containing {self[2], ..., self[#self]} -
    - - - -
    @@ -1721,7 +564,8 @@

    Returns:

    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index c30d9a5..6571276 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html index 1ad8ebd..aef1c22 100644 --- a/doc/classes/std.optparse.html +++ b/doc/classes/std.optparse.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index 3b6fd70..d4fb328 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index 0fd26f0..c03f0c4 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index 6e33ccc..9574f29 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/index.html b/doc/index.html index b9bac87..a71f6c0 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index 918f20a..3c43793 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.html b/doc/modules/std.html index e3dac79..2f35a44 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index 450acb3..ef8ab21 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index 50408e6..f4e68b7 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.operator.html b/doc/modules/std.operator.html new file mode 100644 index 0000000..1772f4a --- /dev/null +++ b/doc/modules/std.operator.html @@ -0,0 +1,755 @@ + + + + + stdlib 41.0.0 Reference + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module std.operator

    +

    Functional forms of Lua operators.

    +

    + +

    + + +

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    concat (a, b)Stringify and concatenate arguments.
    conj (a, b)Return the logical conjunction of the arguments.
    diff (a, b)Return the difference of the arguments.
    disj (a, b)Return the logical disjunction of the arguments.
    eq (a, b)Return the equality of the arguments.
    get (t, k)Dereference a table.
    gt (a, b)Return whether the arguments are in descending order.
    gte (a, b)Return whether the arguments are not in ascending order.
    lt (a, b)Return whether the arguments are in ascending order.
    lte (a, b)Return whether the arguments are not in descending order.
    mod (a, b)Return the modulus of the arguments.
    neg (a)Return the logical negation of the arguments.
    neq (a, b)Return the inequality of the arguments.
    pow (a, b)Return the exponent of the arguments.
    prod (a, b)Return the product of the arguments.
    quot (a, b)Return the quotient of the arguments.
    set (t, k, v)Set a table element, honoring metamethods.
    sum (a, b)Return the sum of the arguments.
    + +
    +
    + + +

    Functions

    + Methods +
    +
    + + concat (a, b) +
    +
    + Stringify and concatenate arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + concatenation of stringified arguments. +
    + + + +

    Usage:

    +
      +
      + --> "=> 1000010010"
      + functional.foldl (concat, "=> ", {10000, 100, 10})
      +
    + +
    +
    + + conj (a, b) +
    +
    + Return the logical conjunction of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + logical a and b +
    + + + +

    Usage:

    +
      +
      + --> true
      + functional.foldl (conj, {true, 1, "false"})
      +
    + +
    +
    + + diff (a, b) +
    +
    + Return the difference of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + the difference between a and b +
    + + + +

    Usage:

    +
      +
      + --> 890
      + functional.foldl (diff, {10000, 100, 10})
      +
    + +
    +
    + + disj (a, b) +
    +
    + Return the logical disjunction of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + logical a or b +
    + + + +

    Usage:

    +
      +
      + --> true
      + functional.foldl (disj, {true, 1, false})
      +
    + +
    +
    + + eq (a, b) +
    +
    + Return the equality of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + true if a is b, otherwise false +
    + + + + +
    +
    + + get (t, k) +
    +
    + Dereference a table. + + +

    Parameters:

    +
      +
    • t + table + a table +
    • +
    • k + a key to lookup in t +
    • +
    + +

    Returns:

    +
      + + value stored at t[k] if any, otherwise nil +
    + + + +

    Usage:

    +
      +
      + --> 4
      + functional.foldl (get, {1, {{2, 3, 4}, 5}}, {2, 1, 3})
      +
    + +
    +
    + + gt (a, b) +
    +
    + Return whether the arguments are in descending order. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + true if a is greater then b, otherwise false +
    + + + + +
    +
    + + gte (a, b) +
    +
    + Return whether the arguments are not in ascending order. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + true if a is not greater then b, otherwise false +
    + + + + +
    +
    + + lt (a, b) +
    +
    + Return whether the arguments are in ascending order. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + true if a is less then b, otherwise false +
    + + + + +
    +
    + + lte (a, b) +
    +
    + Return whether the arguments are not in descending order. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + true if a is not greater then b, otherwise false +
    + + + + +
    +
    + + mod (a, b) +
    +
    + Return the modulus of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + the modulus of a and b +
    + + + +

    Usage:

    +
      +
      + --> 3
      + functional.foldl (mod, {65536, 100, 11})
      +
    + +
    +
    + + neg (a) +
    +
    + Return the logical negation of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    + +

    Returns:

    +
      + + not a +
    + + + +

    Usage:

    +
      +
      + --> {true, false, false, false}
      + functional.bind (functional.map, {std.ielems, neg}) {false, true, 1, 0}
      +
    + +
    +
    + + neq (a, b) +
    +
    + Return the inequality of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + false if a is b, otherwise true +
    + + + +

    Usage:

    +
      +
      + --> true
      + local f = require "std.functional"
      + table.empty (f.filter (f.bind (neq, {6}), std.ielems, {6, 6, 6})
      +
    + +
    +
    + + pow (a, b) +
    +
    + Return the exponent of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + the a to the power of b +
    + + + +

    Usage:

    +
      +
      + --> 4096
      + functional.foldl (pow, {2, 3, 4})
      +
    + +
    +
    + + prod (a, b) +
    +
    + Return the product of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + the product of a and b +
    + + + +

    Usage:

    +
      +
      + --> 10000000
      + functional.foldl (prod, {10000, 100, 10})
      +
    + +
    +
    + + quot (a, b) +
    +
    + Return the quotient of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + the quotient a and b +
    + + + +

    Usage:

    +
      +
      + --> 1000
      + functional.foldr (quot, {10000, 100, 10})
      +
    + +
    +
    + + set (t, k, v) +
    +
    + Set a table element, honoring metamethods. + + +

    Parameters:

    +
      +
    • t + table + a table +
    • +
    • k + a key to lookup in t +
    • +
    • v + a value to set for k +
    • +
    + +

    Returns:

    +
      + + table + t +
    + + + +

    Usage:

    +
      +
      + -- destructive table merge:
      + --> {"one", bar="baz", two=5}
      + functional.reduce (set, {"foo", bar="baz"}, {"one", two=5})
      +
    + +
    +
    + + sum (a, b) +
    +
    + Return the sum of the arguments. + + +

    Parameters:

    +
      +
    • a + an argument +
    • +
    • b + another argument +
    • +
    + +

    Returns:

    +
      + + the sum of the a and b +
    + + + +

    Usage:

    +
      +
      + --> 10110
      + functional.foldl (sum, {10000, 100, 10})
      +
    + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43 +
    +
    + + diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index 1378d42..130ba8a 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index a2a8444..e238fa5 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index d41ef7b..c1eff4e 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index e565d06..4924700 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - stdlib 40 Reference + stdlib 41.0.0 Reference @@ -24,7 +24,7 @@
    -generated by LDoc 1.4.2 +generated by LDoc 1.4.3 +Last updated 2015-01-03 18:38:43
    diff --git a/lib/std.lua b/lib/std.lua index 08d797f..0d9f436 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -1,112 +1,256 @@ --[[-- - Submodule lazy loader. + Lua Standard Libraries. - After requiring this module, simply referencing symbols in the submodule - hierarchy will load the necessary modules on demand. + This module contains a selection of improved Lua core functions, among + others. - Clients of older releases might be surprised by this new-found hygiene, - expecting the various changes that used to be automatically installed as - global symbols, or monkey patched into the core module tables and - metatables. Sometimes, it's still convenient to do that... when using - stdlib from the REPL, or in a prototype where you want to throw caution - to the wind and compatibility with other modules be damned, for example. - In that case, you can give stdlib permission to scribble all over your - namespaces with: + Also, after requiring this module, simply referencing symbols in the + submodule hierarchy will load the necessary modules on demand. - local std = require "std".monkey_patch () + By default there are no changes to any global symbols, or monkey + patching of core module tables and metatables. However, sometimes it's + still convenient to do that: For example, when using stdlib from the + REPL, or in a prototype where you want to throw caution to the wind and + compatibility with other modules be damned. In that case, you can give + `stdlib` permission to scribble all over your namespaces by using the + various `monkey_patch` calls in the library. @todo Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call error, not die; OO vs non-OO (a thorny problem). - @todo Add tests for each function immediately after the function; - this also helps to check module dependencies. @todo pre-compile. @module std ]] -local M -- forward declaration +local base = require "std.base" ---- Overwrite core methods and metamethods with `std` enhanced versions. --- --- Loads all `std` submodules with a `monkey_patch` method, and runs --- them. --- @function monkey_patch --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table the module table -local function monkey_patch (namespace) - namespace = namespace or _G +local M, monkeys - assert (type (namespace) == "table", - "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") - - require "std.io".monkey_patch (namespace) - require "std.math".monkey_patch (namespace) - require "std.string".monkey_patch (namespace) - require "std.table".monkey_patch (namespace) - return M +local function monkey_patch (namespace) + return base.copy (namespace or _G, monkeys) end ---- A [barrel of monkey_patches](http://dictionary.reference.com/browse/barrel+of+monkeys). --- --- Scribble all over the given namespace, and apply all available --- `monkey_patch` functions. --- @function barrel --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table module table local function barrel (namespace) namespace = namespace or _G - assert (type (namespace) == "table", - "bad argument #1 to 'barrel' (table expected, got " .. type (namespace) .. ")") - -- Older releases installed the following into _G by default. - for _, v in pairs { + for _, name in pairs { "functional.bind", "functional.collect", "functional.compose", - "functional.curry", "functional.eval", "functional.filter", - "functional.fold", "functional.id", "functional.map", - "functional.memoize", "functional.op", + "functional.curry", "functional.filter", "functional.id", + "functional.map", "io.die", "io.warn", - "string.assert", "string.pickle", "string.prettytostring", - "string.render", "string.require_version", "string.tostring", + "string.pickle", "string.prettytostring", "string.render", - "table.metamethod", "table.pack", "table.ripairs", - "table.totable", + "table.pack", "tree.ileaves", "tree.inodes", "tree.leaves", "tree.nodes", } do - local module, method = v:match "^(.*)%.(.-)$" + local module, method = name:match "^(.*)%.(.-)$" namespace[method] = M[module][method] end + -- Support old api names, for backwards compatibility. + namespace.fold = M.functional.fold + namespace.metamethod = M.getmetamethod + namespace.op = M.operator + namespace.require_version = M.require + + require "std.io".monkey_patch (namespace) + require "std.math".monkey_patch (namespace) + require "std.string".monkey_patch (namespace) + require "std.table".monkey_patch (namespace) + return monkey_patch (namespace) end + --- Module table. -- --- Lazy load submodules into `std` on first reference. On initial --- load, `std` has the usual single `version` entry, but the `__index` --- metatable will automatically require submodules on first reference: --- --- local std = require "std" --- local prototype = std.container.prototype +-- In addition to the functions documented on this page, and a `version` +-- field, references to other submodule functions will be loaded on +-- demand. -- @table std -- @field version release version string -local version = "General Lua libraries / 40" +local function X (decl, fn) + return require "std.debug".argscheck ("std." .. decl, fn) +end M = { - barrel = barrel, - monkey_patch = monkey_patch, - version = version, + --- Enhance core `assert` to also allow formatted arguments. + -- @function assert + -- @param expect expression, expected to be *truthy* + -- @string[opt=""] f format string + -- @param[opt] ... arguments to format + -- @return value of *expect*, if *truthy* + -- @usage + -- std.assert (expected ~= nil, "100% unexpected!") + -- std.assert (expected ~= nil, "%s unexpected!", expected) + assert = X ("assert (any?, string?, any?*)", base.assert), + + --- A [barrel of monkey_patches](http://dictionary.reference.com/browse/barrel+of+monkeys). + -- + -- Apply **all** `monkey_patch` functions. Additionally, for backwards + -- compatibility only, write a selection of sub-module functions into + -- the given namespace. + -- @function barrel + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table module table + -- @usage local std = require "std".barrel () + barrel = X ("barrel (table?)", barrel), + + --- An iterator over all elements of a sequence. + -- If *t* has a `__pairs` metamethod, use that to iterate. + -- @function elems + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @return *key*, the previous iteration key + -- @see ielems + -- @see pairs + -- @usage + -- for value in std.elems {a = 1, b = 2, c = 5} do process (value) end + elems = X ("elems (table)", base.elems), + + --- Evaluate a string as Lua code. + -- @function eval + -- @string s string of Lua code + -- @return result of evaluating `s` + -- @usage std.eval "math.min (2, 10)" + eval = X ("eval (string)", base.eval), + + --- An iterator over the integer keyed elements of a sequence. + -- If *t* has a `__len` metamethod, iterate up to the index it returns. + -- @function ielems + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @treturn int *index*, the previous iteration index + -- @see elems + -- @see ipairs + -- @usage + -- for v in std.ielems {"a", "b", "c"} do process (v) end + ielems = X ("ielems (table)", base.ielems), + + --- An iterator over elements of a sequence, until the first `nil` value. + -- + -- Like Lua 5.1 and 5.3, but unlike Lua 5.2 (which looks for and uses the + -- `__ipairs` metamethod), this iterator returns successive key-value + -- pairs with integer keys starting at 1, up to the first `nil` valued + -- pair. + -- @function ipairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @treturn int *index*, the previous iteration index + -- @see ielems + -- @see pairs + -- @usage + -- -- length of sequence + -- args = {"first", "second", nil, "last"} + -- --> 1=first + -- --> 2=second + -- for i, v in std.ipairs (args) do + -- print (string.format ("%d=%s", i, v)) + -- end + ipairs = X ("ipairs (table)", base.ipairs), + + --- Return a new table with element order reversed. + -- Apart from the order of the elments returned, this function follows + -- the same rules as @{ipairs} for determining first and last elements. + -- @function ireverse + -- @tparam table t a table + -- @treturn table a new table with integer keyed elements in reverse + -- order with respect to *t* + -- @see ielems + -- @see ipairs + -- @usage + -- local rielems = std.functional.compose (std.ireverse, std.ielems) + -- for e in rielems (l) do process (e) end + ireverse = X ("ireverse (table)", base.ireverse), + + --- Return named metamethod, if any, otherwis `nil`. + -- @function getmetamethod + -- @tparam table t table to get metamethod of + -- @string n name of metamethod to get + -- @treturn function|nil metamethod function, or `nil` if no metamethod + -- @usage lookup = std.getmetamethod (require "std.object", "__index") + getmetamethod = X ("getmetamethod (object|table, string)", base.getmetamethod), + + --- Overwrite core methods and metamethods with `std` enhanced versions. + -- + -- Write all functions from this module, except `std.barrel` and + -- `std.monkey_patch`, into the given namespace. + -- @function monkey_patch + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table the module table + -- @usage local std = require "std".monkey_patch () + monkey_patch = X ("monkey_patch (table?)", monkey_patch), + + --- Enhance core `pairs` to respect `__pairs` even in Lua 5.1. + -- @function pairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @return *key*, the previous iteration key + -- @see elems + -- @see ipairs + -- @usage + -- for k, v in pairs {"a", b = "c", foo = 42} do process (k, v) end + pairs = X ("pairs (table)", base.pairs), + + --- Enhance core `require` to assert version number compatibility. + -- By default match against the last substring of (dot-delimited) + -- digits in the module version string. + -- @function require + -- @string module module to require + -- @string[opt] min lowest acceptable version + -- @string[opt] too_big lowest version that is too big + -- @string[opt] pattern to match version in `module.version` or + -- `module._VERSION` (default: `"([%.%d]+)%D*$"`) + -- @usage + -- -- posix.version == "posix library for Lua 5.2 / 32" + -- posix = require ("posix", "29") + require = X ("require (string, string?, string?, string?)", base.require), + + --- An iterator like ipairs, but in reverse. + -- Apart from the order of the elments returned, this function follows + -- the same rules as @{ipairs} for determining first and last elements. + -- @function ripairs + -- @tparam table t any table + -- @treturn function iterator function + -- @treturn table *t* + -- @treturn number `#t + 1` + -- @usage for i, v = ripairs (t) do ... end + ripairs = X ("ripairs (table)", base.ripairs), + + --- Enhance core `tostring` to render table contents as a string. + -- @function tostring + -- @param x object to convert to string + -- @treturn string compact string rendering of *x* + -- @usage + -- -- {1=baz,foo=bar} + -- print (std.tostring {foo="bar","baz"}) + tostring = X ("tostring (any?)", base.tostring), + + version = "General Lua libraries / 41.0.0", } +monkeys = base.copy ({}, M) + +-- Don't monkey_patch these apis into _G! +for _, api in ipairs {"barrel", "monkey_patch", "version"} do + monkeys[api] = nil +end + + --- Metamethods -- @section Metamethods @@ -116,7 +260,11 @@ return setmetatable (M, { -- to access a submodule, and then load it on demand. -- @function __index -- @string name submodule name - -- @return the submodule that was loaded to satisfy the missing `name` + -- @treturn table|nil the submodule that was loaded to satisfy the missing + -- `name`, otherwise `nil` if nothing was found + -- @usage + -- local std = require "std" + -- local prototype = std.object.prototype __index = function (self, name) local ok, t = pcall (require, "std." .. name) if ok then diff --git a/lib/std.lua.in b/lib/std.lua.in index 74b8eb3..3f12f47 100644 --- a/lib/std.lua.in +++ b/lib/std.lua.in @@ -1,112 +1,256 @@ --[[-- - Submodule lazy loader. + Lua Standard Libraries. - After requiring this module, simply referencing symbols in the submodule - hierarchy will load the necessary modules on demand. + This module contains a selection of improved Lua core functions, among + others. - Clients of older releases might be surprised by this new-found hygiene, - expecting the various changes that used to be automatically installed as - global symbols, or monkey patched into the core module tables and - metatables. Sometimes, it's still convenient to do that... when using - stdlib from the REPL, or in a prototype where you want to throw caution - to the wind and compatibility with other modules be damned, for example. - In that case, you can give stdlib permission to scribble all over your - namespaces with: + Also, after requiring this module, simply referencing symbols in the + submodule hierarchy will load the necessary modules on demand. - local std = require "std".monkey_patch () + By default there are no changes to any global symbols, or monkey + patching of core module tables and metatables. However, sometimes it's + still convenient to do that: For example, when using stdlib from the + REPL, or in a prototype where you want to throw caution to the wind and + compatibility with other modules be damned. In that case, you can give + `stdlib` permission to scribble all over your namespaces by using the + various `monkey_patch` calls in the library. @todo Write a style guide (indenting/wrapping, capitalisation, function and variable names); library functions should call error, not die; OO vs non-OO (a thorny problem). - @todo Add tests for each function immediately after the function; - this also helps to check module dependencies. @todo pre-compile. @module std ]] -local M -- forward declaration +local base = require "std.base" ---- Overwrite core methods and metamethods with `std` enhanced versions. --- --- Loads all `std` submodules with a `monkey_patch` method, and runs --- them. --- @function monkey_patch --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table the module table -local function monkey_patch (namespace) - namespace = namespace or _G +local M, monkeys - assert (type (namespace) == "table", - "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") - - require "std.io".monkey_patch (namespace) - require "std.math".monkey_patch (namespace) - require "std.string".monkey_patch (namespace) - require "std.table".monkey_patch (namespace) - return M +local function monkey_patch (namespace) + return base.copy (namespace or _G, monkeys) end ---- A [barrel of monkey_patches](http://dictionary.reference.com/browse/barrel+of+monkeys). --- --- Scribble all over the given namespace, and apply all available --- `monkey_patch` functions. --- @function barrel --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table module table local function barrel (namespace) namespace = namespace or _G - assert (type (namespace) == "table", - "bad argument #1 to 'barrel' (table expected, got " .. type (namespace) .. ")") - -- Older releases installed the following into _G by default. - for _, v in pairs { + for _, name in pairs { "functional.bind", "functional.collect", "functional.compose", - "functional.curry", "functional.eval", "functional.filter", - "functional.fold", "functional.id", "functional.map", - "functional.memoize", "functional.op", + "functional.curry", "functional.filter", "functional.id", + "functional.map", "io.die", "io.warn", - "string.assert", "string.pickle", "string.prettytostring", - "string.render", "string.require_version", "string.tostring", + "string.pickle", "string.prettytostring", "string.render", - "table.metamethod", "table.pack", "table.ripairs", - "table.totable", + "table.pack", "tree.ileaves", "tree.inodes", "tree.leaves", "tree.nodes", } do - local module, method = v:match "^(.*)%.(.-)$" + local module, method = name:match "^(.*)%.(.-)$" namespace[method] = M[module][method] end + -- Support old api names, for backwards compatibility. + namespace.fold = M.functional.fold + namespace.metamethod = M.getmetamethod + namespace.op = M.operator + namespace.require_version = M.require + + require "std.io".monkey_patch (namespace) + require "std.math".monkey_patch (namespace) + require "std.string".monkey_patch (namespace) + require "std.table".monkey_patch (namespace) + return monkey_patch (namespace) end + --- Module table. -- --- Lazy load submodules into `std` on first reference. On initial --- load, `std` has the usual single `version` entry, but the `__index` --- metatable will automatically require submodules on first reference: --- --- local std = require "std" --- local prototype = std.container.prototype +-- In addition to the functions documented on this page, and a `version` +-- field, references to other submodule functions will be loaded on +-- demand. -- @table std -- @field version release version string -local version = "General Lua libraries / @VERSION@" +local function X (decl, fn) + return require "std.debug".argscheck ("std." .. decl, fn) +end M = { - barrel = barrel, - monkey_patch = monkey_patch, - version = version, + --- Enhance core `assert` to also allow formatted arguments. + -- @function assert + -- @param expect expression, expected to be *truthy* + -- @string[opt=""] f format string + -- @param[opt] ... arguments to format + -- @return value of *expect*, if *truthy* + -- @usage + -- std.assert (expected ~= nil, "100% unexpected!") + -- std.assert (expected ~= nil, "%s unexpected!", expected) + assert = X ("assert (any?, string?, any?*)", base.assert), + + --- A [barrel of monkey_patches](http://dictionary.reference.com/browse/barrel+of+monkeys). + -- + -- Apply **all** `monkey_patch` functions. Additionally, for backwards + -- compatibility only, write a selection of sub-module functions into + -- the given namespace. + -- @function barrel + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table module table + -- @usage local std = require "std".barrel () + barrel = X ("barrel (table?)", barrel), + + --- An iterator over all elements of a sequence. + -- If *t* has a `__pairs` metamethod, use that to iterate. + -- @function elems + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @return *key*, the previous iteration key + -- @see ielems + -- @see pairs + -- @usage + -- for value in std.elems {a = 1, b = 2, c = 5} do process (value) end + elems = X ("elems (table)", base.elems), + + --- Evaluate a string as Lua code. + -- @function eval + -- @string s string of Lua code + -- @return result of evaluating `s` + -- @usage std.eval "math.min (2, 10)" + eval = X ("eval (string)", base.eval), + + --- An iterator over the integer keyed elements of a sequence. + -- If *t* has a `__len` metamethod, iterate up to the index it returns. + -- @function ielems + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @treturn int *index*, the previous iteration index + -- @see elems + -- @see ipairs + -- @usage + -- for v in std.ielems {"a", "b", "c"} do process (v) end + ielems = X ("ielems (table)", base.ielems), + + --- An iterator over elements of a sequence, until the first `nil` value. + -- + -- Like Lua 5.1 and 5.3, but unlike Lua 5.2 (which looks for and uses the + -- `__ipairs` metamethod), this iterator returns successive key-value + -- pairs with integer keys starting at 1, up to the first `nil` valued + -- pair. + -- @function ipairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @treturn int *index*, the previous iteration index + -- @see ielems + -- @see pairs + -- @usage + -- -- length of sequence + -- args = {"first", "second", nil, "last"} + -- --> 1=first + -- --> 2=second + -- for i, v in std.ipairs (args) do + -- print (string.format ("%d=%s", i, v)) + -- end + ipairs = X ("ipairs (table)", base.ipairs), + + --- Return a new table with element order reversed. + -- Apart from the order of the elments returned, this function follows + -- the same rules as @{ipairs} for determining first and last elements. + -- @function ireverse + -- @tparam table t a table + -- @treturn table a new table with integer keyed elements in reverse + -- order with respect to *t* + -- @see ielems + -- @see ipairs + -- @usage + -- local rielems = std.functional.compose (std.ireverse, std.ielems) + -- for e in rielems (l) do process (e) end + ireverse = X ("ireverse (table)", base.ireverse), + + --- Return named metamethod, if any, otherwis `nil`. + -- @function getmetamethod + -- @tparam table t table to get metamethod of + -- @string n name of metamethod to get + -- @treturn function|nil metamethod function, or `nil` if no metamethod + -- @usage lookup = std.getmetamethod (require "std.object", "__index") + getmetamethod = X ("getmetamethod (object|table, string)", base.getmetamethod), + + --- Overwrite core methods and metamethods with `std` enhanced versions. + -- + -- Write all functions from this module, except `std.barrel` and + -- `std.monkey_patch`, into the given namespace. + -- @function monkey_patch + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table the module table + -- @usage local std = require "std".monkey_patch () + monkey_patch = X ("monkey_patch (table?)", monkey_patch), + + --- Enhance core `pairs` to respect `__pairs` even in Lua 5.1. + -- @function pairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table *t*, the table being iterated over + -- @return *key*, the previous iteration key + -- @see elems + -- @see ipairs + -- @usage + -- for k, v in pairs {"a", b = "c", foo = 42} do process (k, v) end + pairs = X ("pairs (table)", base.pairs), + + --- Enhance core `require` to assert version number compatibility. + -- By default match against the last substring of (dot-delimited) + -- digits in the module version string. + -- @function require + -- @string module module to require + -- @string[opt] min lowest acceptable version + -- @string[opt] too_big lowest version that is too big + -- @string[opt] pattern to match version in `module.version` or + -- `module._VERSION` (default: `"([%.%d]+)%D*$"`) + -- @usage + -- -- posix.version == "posix library for Lua 5.2 / 32" + -- posix = require ("posix", "29") + require = X ("require (string, string?, string?, string?)", base.require), + + --- An iterator like ipairs, but in reverse. + -- Apart from the order of the elments returned, this function follows + -- the same rules as @{ipairs} for determining first and last elements. + -- @function ripairs + -- @tparam table t any table + -- @treturn function iterator function + -- @treturn table *t* + -- @treturn number `#t + 1` + -- @usage for i, v = ripairs (t) do ... end + ripairs = X ("ripairs (table)", base.ripairs), + + --- Enhance core `tostring` to render table contents as a string. + -- @function tostring + -- @param x object to convert to string + -- @treturn string compact string rendering of *x* + -- @usage + -- -- {1=baz,foo=bar} + -- print (std.tostring {foo="bar","baz"}) + tostring = X ("tostring (any?)", base.tostring), + + version = "General Lua libraries / @VERSION@", } +monkeys = base.copy ({}, M) + +-- Don't monkey_patch these apis into _G! +for _, api in ipairs {"barrel", "monkey_patch", "version"} do + monkeys[api] = nil +end + + --- Metamethods -- @section Metamethods @@ -116,7 +260,11 @@ return setmetatable (M, { -- to access a submodule, and then load it on demand. -- @function __index -- @string name submodule name - -- @return the submodule that was loaded to satisfy the missing `name` + -- @treturn table|nil the submodule that was loaded to satisfy the missing + -- `name`, otherwise `nil` if nothing was found + -- @usage + -- local std = require "std" + -- local prototype = std.object.prototype __index = function (self, name) local ok, t = pcall (require, "std." .. name) if ok then diff --git a/lib/std/base.lua b/lib/std/base.lua index b96663e..2b4efd3 100644 --- a/lib/std/base.lua +++ b/lib/std/base.lua @@ -1,43 +1,239 @@ ------- --- @module std.base - - ---- Write a deprecation warning to stderr on first call. --- @func fn deprecated function --- @string[opt] name function name for automatic warning message. --- @string[opt] warnmsg full specified warning message (overrides *name*) --- @return a function to show the warning on first call, and hand off to *fn* -local function deprecate (fn, name, warnmsg) - assert (name or warnmsg, - "missing argument to 'deprecate', expecting 2 or 3 parameters") - warnmsg = warnmsg or (name .. " is deprecated, and will go away in a future release.") - local warnp = true - return function (...) - if warnp then - local _, where = pcall (function () error ("", 4) end) - io.stderr:write ((string.gsub (where, "(^w%*%.%w*%:%d+)", "%1"))) - io.stderr:write (warnmsg .. "\n") - warnp = false +--[[-- + Prevent dependency loops with key function implementations. + + A few key functions are used in several stdlib modules; we implement those + functions in this internal module to prevent dependency loops in the first + instance, and to minimise coupling between modules where the use of one of + these functions might otherwise load a whole selection of other supporting + modules unnecessarily. + + Although the implementations are here for logistical reasons, we re-export + them from their respective logical modules so that the api is not affected + as far as client code is concerned. The functions in this file do not make + use of `argcheck` or similar, because we know that they are only called by + other stdlib functions which have already performed the necessary checking + and neither do we want to slow everything down by recheckng those argument + types here. + + This implies that when re-exporting from another module when argument type + checking is in force, we must export a wrapper function that can check the + user's arguments fully at the API boundary. + + @module std.base +]] + + +local dirsep = string.match (package.config, "^(%S+)\n") +local loadstring = loadstring or load +local unpack = table.unpack or unpack + + +local function argerror (name, i, extramsg, level) + level = level or 1 + local s = string.format ("bad argument #%d to '%s'", i, name) + if extramsg ~= nil then + s = s .. " (" .. extramsg .. ")" + end + error (s, level + 1) +end + + +local function assert (expect, fmt, arg1, ...) + local msg = (arg1 ~= nil) and string.format (fmt, arg1, ...) or fmt or "" + return expect or error (msg, 2) +end + + +local function getmetamethod (x, n) + local _, m = pcall (function (x) + return getmetatable (x)[n] + end, + x) + if type (m) ~= "function" then + m = nil + end + return m +end + + +local function callable (x) + if type (x) == "function" then return x end + return getmetamethod (x, "__call") +end + + +local function catfile (...) + return table.concat ({...}, dirsep) +end + + +-- Lua < 5.2 doesn't call `__len` automatically! +local function len (t) + local m = getmetamethod (t, "__len") + return m and m (t) or #t +end + + +-- Iterate over keys 1..n, where n is the key before the first nil +-- valued ordinal key (like Lua 5.3). +local function ipairs (l) + return function (l, n) + n = n + 1 + if l[n] ~= nil then + return n, l[n] end - return fn (...) + end, l, 0 +end + + +local function collect (ifn, ...) + local argt = {...} + if not callable (ifn) then + ifn, argt = ipairs, {ifn, ...} + end + + local r = {} + for k, v in ifn (unpack (argt)) do + if v == nil then k, v = #r + 1, k end + r[k] = v end + return r end --- Doc-commented in list.lua... -local function elems (l) - local n = 0 - return function (l) - n = n + 1 - if n <= #l then - return l[n] - end - end, - l, true +local function compare (l, m) + local lenl, lenm = len (l), len (m) + for i = 1, math.min (lenl, lenm) do + local li, mi = tonumber (l[i]), tonumber (m[i]) + if li == nil or mi == nil then + li, mi = l[i], m[i] + end + if li < mi then + return -1 + elseif li > mi then + return 1 + end + end + if lenl < lenm then + return -1 + elseif lenl > lenm then + return 1 + end + return 0 +end + + +local _pairs = pairs + +-- Respect __pairs metamethod, even in Lua 5.1. +local function pairs (t) + return (getmetamethod (t, "__pairs") or _pairs) (t) +end + + +local function copy (dest, src) + if src == nil then dest, src = {}, dest end + for k, v in pairs (src) do dest[k] = v end + return dest +end + + +--- Iterator adaptor for discarding first value from core iterator function. +-- @func factory iterator to be wrapped +-- @param ... *factory* arguments +-- @treturn function iterator that discards first returned value of +-- factory iterator +-- @return invariant state from *factory* +-- @return `true` +-- @usage +-- for v in wrapiterator (ipairs {"a", "b", "c"}) do process (v) end +local function wrapiterator (factory, ...) + -- Capture wrapped ctrl variable into an upvalue... + local fn, istate, ctrl = factory (...) + -- Wrap the returned iterator fn to maintain wrapped ctrl. + return function (state, _) + local v + ctrl, v = fn (state, ctrl) + if ctrl then return v end + end, istate, true -- wrapped initial state, and wrapper ctrl end --- Iterator returning leaf nodes from nested tables. +local function elems (t) + return wrapiterator (pairs, t) +end + + +local function escape_pattern (s) + return (s:gsub ("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")) +end + + +local function eval (s) + return loadstring ("return " .. s)() +end + + +local function ielems (l) + return wrapiterator (ipairs, l) +end + + +local _insert = table.insert + +local function insert (t, pos, v) + if v == nil then pos, v = len (t) + 1, pos end + if pos < 1 or pos > len (t) + 1 then + argerror ("std.table.insert", 2, "position " .. pos .. " out of bounds", 2) + end + _insert (t, pos, v) + return t +end + + +local function invert (t) + local i = {} + for k, v in pairs (t) do + i[v] = k + end + return i +end + + +-- Be careful to reverse only the valid sequence part of a table. +local function ireverse (t) + local oob = 1 + while t[oob] ~= nil do + oob = oob + 1 + end + + local r = {} + for i = 1, oob - 1 do r[oob - i] = t[i] end + return r +end + + +-- Sort numbers first then asciibetically +local function keysort (a, b) + if type (a) == "number" then + return type (b) ~= "number" or a < b + else + return type (b) ~= "number" and tostring (a) < tostring (b) + end +end + + +local function okeys (t) + local r = {} + for k in pairs (t) do r[#r + 1] = k end + table.sort (r, keysort) + return r +end + + +local function last (t) return t[len (t)] end + + local function leaves (it, tr) local function visit (n) if type (n) == "table" then @@ -52,24 +248,203 @@ local function leaves (it, tr) end --- Doc-commented in table.lua... -local function metamethod (x, n) - local _, m = pcall (function (x) - return getmetatable (x)[n] - end, - x) - if type (m) ~= "function" then - m = nil +local maxn = table.maxn or function (t) + local n = 0 + for k in pairs (t) do + if type (k) == "number" and k > n then n = k end + end + return n +end + + +local function merge (dest, src) + for k, v in pairs (src) do dest[k] = dest[k] or v end + return dest +end + + +local function prototype (o) + return (getmetatable (o) or {})._type or io.type (o) or type (o) +end + + +local function reduce (fn, d, ifn, ...) + local argt = {...} + if not callable (ifn) then + ifn, argt = pairs, {ifn, ...} + end + + local nextfn, state, k = ifn (unpack (argt)) + local t = {nextfn (state, k)} -- table of iteration 1 + + local r = d -- initialise accumulator + while t[1] ~= nil do -- until iterator returns nil + k = t[1] + r = fn (r, unpack (t)) -- pass all iterator results to fn + t = {nextfn (state, k)} -- maintain loop invariant + end + return r +end + + +-- Write pretty-printing based on: +-- +-- John Hughes's and Simon Peyton Jones's Pretty Printer Combinators +-- +-- Based on "The Design of a Pretty-printing Library in Advanced +-- Functional Programming", Johan Jeuring and Erik Meijer (eds), LNCS 925 +-- http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps +-- Heavily modified by Simon Peyton Jones, Dec 96 + +local function render (x, opencb, closecb, elemcb, paircb, sepcb, roots) + roots = roots or {} + local function stop_roots (x) + return roots[x] or render (x, opencb, closecb, elemcb, paircb, sepcb, copy (roots)) + end + + if type (x) ~= "table" or getmetamethod (x, "__tostring") then + return elemcb (x) + else + local buf, k_, v_ = { opencb (x) } -- pre-buffer table open + roots[x] = elemcb (x) -- initialise recursion protection + + for _, k in ipairs (okeys (x)) do -- for ordered table members + local v = x[k] + buf[#buf + 1] = sepcb (x, k_, v_, k, v) -- | buffer separator + buf[#buf + 1] = paircb (x, k, v, stop_roots (k), stop_roots (v)) + -- | buffer key/value pair + k_, v_ = k, v + end + buf[#buf + 1] = sepcb (x, k_, v_) -- buffer trailing separator + buf[#buf + 1] = closecb (x) -- buffer table close + + return table.concat (buf) -- stringify buffer + end +end + + +local function ripairs (t) + local oob = 1 + while t[oob] ~= nil do + oob = oob + 1 + end + + return function (t, n) + n = n - 1 + if n > 0 then + return n, t[n] + end + end, t, oob +end + + +local function split (s, sep) + local r, patt = {} + if sep == "" then + patt = "(.)" + insert (r, "") + else + patt = "(.-)" .. (sep or "%s+") + end + local b, lens = 0, len (s) + while b <= lens do + local e, n, m = string.find (s, patt, b + 1) + insert (r, m or s:sub (b + 1, lens)) + b = n or lens + 1 + end + return r +end + + +local function vcompare (a, b) + return compare (split (a, "%."), split (b, "%.")) +end + + +local _require = require + +local function require (module, min, too_big, pattern) + local m = _require (module) + local v = (m.version or m._VERSION or ""):match (pattern or "([%.%d]+)%D*$") + if min then + assert (vcompare (v, min) >= 0, "require '" .. module .. + "' with at least version " .. min .. ", but found version " .. v) + end + if too_big then + assert (vcompare (v, too_big) < 0, "require '" .. module .. + "' with version less than " .. too_big .. ", but found version " .. v) end return m end -local M = { - deprecate = deprecate, - elems = elems, - leaves = leaves, - metamethod = metamethod, -} +local _tostring = _G.tostring + +local function tostring (x) + return render (x, + function () return "{" end, + function () return "}" end, + _tostring, + function (_, _, _, is, vs) return is .."=".. vs end, + function (_, i, _, k) return i and k and "," or "" end) +end + + + +return { + copy = copy, + keysort = keysort, + merge = merge, + okeys = okeys, + + -- std.lua -- + assert = assert, + case = case, + eval = eval, + elems = elems, + ielems = ielems, + ipairs = ipairs, + ireverse = ireverse, + pairs = pairs, + ripairs = ripairs, + require = require, + tostring = tostring, + + -- debug.lua -- + argerror = argerror, -return M + -- functional.lua -- + callable = callable, + collect = collect, + nop = function () end, + reduce = reduce, + + -- io.lua -- + catfile = catfile, + + -- list.lua -- + compare = compare, + + -- object.lua -- + prototype = prototype, + + -- package.lua -- + dirsep = dirsep, + + -- string.lua -- + escape_pattern = escape_pattern, + render = render, + split = split, + + -- table.lua -- + getmetamethod = getmetamethod, + insert = insert, + invert = invert, + last = last, + len = len, + maxn = maxn, + + -- tree.lua -- + leaves = leaves, + +} diff --git a/lib/std/container.lua b/lib/std/container.lua index c507d5e..eb21aa4 100644 --- a/lib/std/container.lua +++ b/lib/std/container.lua @@ -1,68 +1,58 @@ --[[-- - Container object. + Container prototype. A container is a @{std.object} with no methods. It's functionality is instead defined by its *meta*methods. - Where an Object uses the `\_\_index` metatable entry to hold object - methods, a Container stores its contents using `\_\_index`, preventing + Where an Object uses the `__index` metatable entry to hold object + methods, a Container stores its contents using `__index`, preventing it from having methods in there too. Although there are no actual methods, Containers are free to use - metamethods (`\_\_index`, `\_\_sub`, etc) and, like Objects, can supply - module functions by listing them in `\_functions`. Also, since a + metamethods (`__index`, `__sub`, etc) and, like Objects, can supply + module functions by listing them in `_functions`. Also, since a @{std.container} is a @{std.object}, it can be passed to the @{std.object} module functions, or anywhere else a @{std.object} is expected. - Container derived objects returned directly from a `require` statement - may also provide module functions, which can be called only from the - initial prototype object returned by `require`, but are **not** passed - on to derived objects during cloning: - - > Container = require "std.container" - > x = Container {} - > = Container.prototype (x) - Object - > = x.prototype (o) - stdin:1: attempt to call field 'prototype' (a nil value) - ... - - To add functions like this to your own prototype objects, pass a table - of the module functions in the `_functions` private field before - cloning, and those functions will not be inherited by clones. - - > Container = require "std.container" - > Graph = Container { - >> _type = "Graph", - >> _functions = { - >> nodes = function (graph) - >> local n = 0 - >> for _ in pairs (graph) do n = n + 1 end - >> return n - >> end, - >> }, - >> } - > g = Graph { "node1", "node2" } - > = Graph.nodes (g) - 2 - > = g.nodes - nil - - When making your own prototypes, start from @{std.container} if you - want to access the contents of your objects with the `[]` operator, or - @{std.object} if you want to access the functionality of your objects - with named object methods. + When making your own prototypes, derive from @{std.container} if you want + to access the contents of your objects with the `[]` operator, or from + @{std.object} if you want to access the functionality of your objects with + named object methods. + + Prototype Chain + --------------- + + table + `-> Object + `-> Container @classmod std.container ]] +local _DEBUG = require "std.debug_init"._DEBUG + +local base = require "std.base" +local debug = require "std.debug" + +local ipairs, pairs, okeys = base.ipairs, base.pairs, base.okeys +local insert, len, maxn = base.insert, base.len, base.maxn +local okeys, prototype, tostring = base.okeys, base.prototype, base.tostring +local argcheck = debug.argcheck + + + +--[[ ================= ]]-- +--[[ Helper Functions. ]]-- +--[[ ================= ]]-- + + -- Instantiate a new object based on *proto*. -- -- This is equivalent to: -- --- base.merge (base.clone (proto), t or {}) +-- table.merge (table.clone (proto), t or {}) -- -- But, not typechecking arguments or checking for metatables, is -- slightly faster. @@ -71,11 +61,17 @@ -- @treturn table a new table with fields from proto and t merged in. local function instantiate (proto, t) local obj = {} - for k, v in pairs (proto) do + local k, v = next (proto) + while k do obj[k] = v + k, v = next (proto, k) end - for k, v in pairs (t or {}) do + + t = t or {} + k, v = next (t) + while k do obj[k] = v + k, v = next (t, k) end return obj end @@ -97,19 +93,21 @@ local ModuleFunction = { -- @func fn a function -- @treturn functable a callable functable for `fn` local function modulefunction (fn) - return setmetatable ({_type = "modulefunction", call = fn}, ModuleFunction) + if getmetatable (fn) == ModuleFunction then + -- Don't double wrap! + return fn + else + return setmetatable ({_type = "modulefunction", call = fn}, ModuleFunction) + end end ---- Return `obj` with references to the fields of `src` merged in. --- @static --- @tparam table obj destination object --- @tparam table src fields to copy into clone --- @tparam[opt={}] table map `{old_key=new_key, ...}` --- @treturn table `obj` with non-private fields from `src` merged, and --- a metatable with private fields (if any) merged, both sets of keys --- renamed according to `map` --- @see std.object.mapfields + +--[[ ================= ]]-- +--[[ Container Object. ]]-- +--[[ ================= ]]-- + + local function mapfields (obj, src, map) local mt = getmetatable (obj) or {} @@ -118,17 +116,20 @@ local function mapfields (obj, src, map) -- when map is provided (i.e. if `map == {}`, copy nothing). if map == nil or next (map) then map = map or {} - for k, v in pairs (src) do + local k, v = next (src) + while k do local key, dst = map[k] or k, obj local kind = type (key) if kind == "string" and key:sub (1, 1) == "_" then - dst = mt - elseif kind == "number" and #dst + 1 < key then + mt[key] = v + elseif next (map) and kind == "number" and len (dst) + 1 < key then -- When map is given, but has fewer entries than src, stop copying -- fields when map is exhausted. break + else + dst[key] = v end - dst[key] = v + k, v = next (src, k) end end @@ -137,8 +138,11 @@ local function mapfields (obj, src, map) mt._functions = nil -- Inject module functions. - for k, v in pairs (src._functions or {}) do + local t = src._functions or {} + local k, v = next (t) + while (k) do obj[k] = modulefunction (v) + k, v = next (t, k) end -- Only set non-empty metatable. @@ -149,119 +153,141 @@ local function mapfields (obj, src, map) end --- Type of this container. --- @static --- @tparam std.container o an container --- @treturn string type of the container --- @see std.object.prototype -local function prototype (o) - return (getmetatable (o) or {})._type or type (o) +local function __call (self, x, ...) + local mt = getmetatable (self) + local obj_mt = mt + local obj = {} + + -- This is the slowest part of cloning for any objects that have + -- a lot of fields to test and copy. If you need to clone a lot of + -- objects from a prototype with several module functions, it's much + -- faster to clone objects from each other than the prototype! + local k, v = next (self) + while (k) do + if type (v) ~= "table" or v._type ~= "modulefunction" then + obj[k] = v + end + k, v = next (self, k) + end + + if type (mt._init) == "function" then + obj = mt._init (obj, x, ...) + else + obj = (self.mapfields or mapfields) (obj, x, mt._init) + end + + -- If a metatable was set, then merge our fields and use it. + if next (getmetatable (obj) or {}) then + obj_mt = instantiate (mt, getmetatable (obj)) + + -- Merge object methods. + if type (obj_mt.__index) == "table" and + type ((mt or {}).__index) == "table" + then + obj_mt.__index = instantiate (mt.__index, obj_mt.__index) + end + end + + return setmetatable (obj, obj_mt) end ---- Container prototype. --- @table std.container --- @string[opt="Container"] _type type of Container, returned by --- @{std.object.prototype} --- @tfield table|function _init a table of field names, or --- initialisation function, used by @{__call} --- @tfield nil|table _functions a table of module functions not copied --- by @{std.object.__call} -local metatable = { - _type = "Container", +local function X (decl, fn) + return debug.argscheck ("std.container." .. decl, fn) +end - --- Return a clone of this container. - -- @function __call - -- @param x a table if prototype `_init` is a table, otherwise first - -- argument for a function type `_init` - -- @param ... any additional arguments for `_init` - -- @treturn std.container a clone of the called container. - -- @see std.object:__call - __call = function (self, x, ...) - local mt = getmetatable (self) - local obj_mt = mt - local obj = {} - - -- This is the slowest part of cloning for any objects that have - -- a lot of fields to test and copy. If you need to clone a lot of - -- objects from a prototype with several module functions, it's much - -- faster to clone objects from each other than the prototype! - for k, v in pairs (self) do - if type (v) ~= "table" or v._type ~= "modulefunction" then - obj[k] = v +local M = { + mapfields = X ("mapfields (table, table|object, table?)", mapfields), +} + + +if _DEBUG.argcheck then + + local toomanyargmsg = debug.toomanyargmsg + + M.__call = function (self, x, ...) + local mt = getmetatable (self) + + -- A function initialised object can be passed arguments of any + -- type, so only argcheck non-function initialised objects. + if type (mt._init) ~= "function" then + local name, argt = mt._type, {...} + -- Don't count `self` as an argument for error messages, because + -- it just refers back to the object being called: `Container {"x"}. + argcheck (name, 1, "table", x) + if next (argt) then + error (toomanyargmsg (name, 1, 1 + maxn (argt)), 2) end end - if type (mt._init) == "function" then - obj = mt._init (obj, x, ...) - else - obj = (self.mapfields or mapfields) (obj, x, mt._init) - end + return __call (self, x, ...) + end + +else - -- If a metatable was set, then merge our fields and use it. - if next (getmetatable (obj) or {}) then - obj_mt = instantiate (mt, getmetatable (obj)) + M.__call = __call + +end - -- Merge object methods. - if type (obj_mt.__index) == "table" and - type ((mt or {}).__index) == "table" - then - obj_mt.__index = instantiate (mt.__index, obj_mt.__index) + +function M.__tostring (self) + local n, k_ = 1, nil + local buf = { prototype (self), " {" } -- pre-buffer object open + for _, k in ipairs (okeys (self)) do -- for ordered public members + local v = self[k] + + if k_ ~= nil then -- | buffer separator + if k ~= n and type (k_) == "number" and k_ == n - 1 then + -- `;` separates `v` elements from `k=v` elements + buf[#buf + 1] = "; " + elseif k ~= nil then + -- `,` separator everywhere else + buf[#buf + 1] = ", " end end - return setmetatable (obj, obj_mt) - end, - - - --- Return a string representation of this container. - -- @function __tostring - -- @treturn string stringified container representation - -- @see std.object.__tostring - __tostring = function (self) - local totable = getmetatable (self).__totable - local array = instantiate (totable (self)) - local other = instantiate (array) - local s = "" - if #other > 0 then - for i in ipairs (other) do other[i] = nil end - end - for k in pairs (other) do array[k] = nil end - for i, v in ipairs (array) do array[i] = tostring (v) end - - local keys, dict = {}, {} - for k in pairs (other) do keys[#keys + 1] = k end - table.sort (keys, function (a, b) return tostring (a) < tostring (b) end) - for _, k in ipairs (keys) do - dict[#dict + 1] = tostring (k) .. "=" .. tostring (other[k]) + if type (k) == "number" and k == n then -- | buffer key/value pair + -- render initial array-like elements as just `v` + buf[#buf + 1] = tostring (v) + n = n + 1 + else + -- render remaining elements as `k=v` + buf[#buf + 1] = tostring (k) .. "=" .. tostring (v) end - if #array > 0 then - s = s .. table.concat (array, ", ") - if next (dict) ~= nil then s = s .. "; " end - end - if #dict > 0 then - s = s .. table.concat (dict, ", ") - end + k_ = k -- maintain loop invariant: k_ is previous key + end + buf[#buf + 1] = "}" -- buffer object close - return prototype (self) .. " {" .. s .. "}" - end, + return table.concat (buf) -- stringify buffer +end - --- Return a table representation of this container. - -- @function __totable - -- @treturn table a shallow copy of non-private container fields - -- @see std.object:__totable - __totable = function (self) - local t = {} - for k, v in pairs (self) do - if type (k) ~= "string" or k:sub (1, 1) ~= "_" then - t[k] = v - end - end - return t - end, -} +--- Container prototype. +-- +-- Container also inherits all the fields and methods from +-- @{std.object.Object}. +-- @object Container +-- @string[opt="Container"] _type object name +-- @see std.object +-- @see std.object.__call +-- @usage +-- local std = require "std" +-- local Container = std.container {} +-- +-- local Graph = Container { +-- _type = "Graph", +-- _functions = { +-- nodes = function (graph) +-- local n = 0 +-- for _ in std.pairs (graph) do n = n + 1 end +-- return n +-- end, +-- }, +-- } +-- local g = Graph { "node1", "node2" } +-- --> 2 +-- print (Graph.nodes (g)) return setmetatable ({ @@ -269,6 +295,12 @@ return setmetatable ({ -- But, we have to bootstrap the first object, so in this one instance -- it has to be done manually. - mapfields = modulefunction (mapfields), + mapfields = modulefunction (M.mapfields), prototype = modulefunction (prototype), -}, metatable) +}, { + _type = "Container", + + __call = M.__call, + __tostring = M.__tostring, + __pairs = M.__pairs, +}) diff --git a/lib/std/debug.lua b/lib/std/debug.lua index 555d09a..7995839 100644 --- a/lib/std/debug.lua +++ b/lib/std/debug.lua @@ -1,55 +1,547 @@ --[[-- - Additions to the debug module + Additions to the core debug module. + + The module table returned by `std.debug` also contains all of the entries + from the core debug table. An hygienic way to import this module, then, is + simply to override the core `debug` locally: + + local debug = require "std.debug" + + The behaviour of the functions in this module are controlled by the value + of the global `_DEBUG`. Not setting `_DEBUG` prior to requiring **any** of + stdlib's modules is equivalent to having `_DEBUG = true`. + + The first line of Lua code in production quality projects that use stdlib + should be either: + + _DEBUG = false + + or alternatively, if you need to be careful not to damage the global + environment: + + local init = require "std.debug_init" + init._DEBUG = false + + This mitigates almost all of the overhead of argument typechecking in + stdlib API functions. + @module std.debug ]] -local init = require "std.debug_init" -local io = require "std.io" -local list = require "std.list" -local string = require "std.string" ---- To activate debugging set _DEBUG either to any true value --- (equivalent to {level = 1}), or as documented below. --- @class table --- @name _DEBUG --- @field level debugging level --- @field call do call trace debugging --- @field std do standard library debugging (run examples & test code) +local debug_init = require "std.debug_init" +local base = require "std.base" + +local _DEBUG = debug_init._DEBUG +local argerror = base.argerror +local split, tostring = base.split, base.tostring +local insert, last, len, maxn = base.insert, base.last, base.len, base.maxn +local ipairs, pairs = base.ipairs, base.pairs +local unpack = table.unpack or unpack + +local M + + +-- Return a deprecation message if _DEBUG.deprecate is `nil`, otherwise "". +local function DEPRECATIONMSG (version, name, extramsg, level) + if level == nil then level, extramsg = extramsg, nil end + extramsg = extramsg or "and will be removed entirely in a future release" + + local _, where = pcall (function () error ("", level + 3) end) + if _DEBUG.deprecate == nil then + return (where .. string.format ("%s was deprecated in release %s, %s.\n", + name, tostring (version), extramsg)) + end + + return "" +end + + +-- Define deprecated functions when _DEBUG.deprecate is not "truthy", +-- and write `DEPRECATIONMSG` output to stderr. +local function DEPRECATED (version, name, extramsg, fn) + if fn == nil then fn, extramsg = extramsg, nil end + + if not _DEBUG.deprecate then + return function (...) + io.stderr:write (DEPRECATIONMSG (version, name, extramsg, 2)) + return fn (...) + end + end +end + + +--- Extend `debug.setfenv` to unwrap functables correctly. +-- @tparam function|functable fn target function +-- @tparam table env new function environment +-- @treturn function *fn* + +local _setfenv = debug.setfenv + +local function setfenv (fn, env) + -- Unwrap functable: + if type (fn) == "table" then + fn = fn.call or (getmetatable (fn) or {}).__call + end + + if _setfenv then + return _setfenv (fn, env) + + else + -- From http://lua-users.org/lists/lua-l/2010-06/msg00313.html + local name + local up = 0 + repeat + up = up + 1 + name = debug.getupvalue (fn, up) + until name == '_ENV' or name == nil + if name then + debug.upvaluejoin (fn, up, function () return name end, 1) + debug.setupvalue (fn, up, env) + end + + return fn + end +end + + +--- Extend `debug.getfenv` to unwrap functables correctly. +-- @tparam int|function|functable fn target function, or stack level +-- @treturn table environment of *fn* +local getfenv = getfenv or function (fn) + -- Unwrap functable: + if type (fn) == "table" then + fn = fn.call or (getmetatable (fn) or {}).__call + elseif type (fn) == "number" then + fn = debug.getinfo (fn + 1, "f").func + end + + local name, env + local up = 0 + repeat + up = up + 1 + name, env = debug.getupvalue (fn, up) + until name == '_ENV' or name == nil + return env +end + + +local function toomanyargmsg (name, expect, actual) + local fmt = "bad argument #%d to '%s' (no more than %d argument%s expected, got %d)" + return string.format (fmt, expect + 1, name, expect, expect == 1 and "" or "s", actual) +end + + +local argcheck, argscheck -- forward declarations + +if _DEBUG.argcheck then + + local copy, prototype = base.copy, base.prototype + + --- Concatenate a table of strings using ", " and " or " delimiters. + -- @tparam table alternatives a table of strings + -- @treturn string string of elements from alternatives delimited by ", " + -- and " or " + local function concat (alternatives) + if len (alternatives) > 1 then + local t = copy (alternatives) + local top = table.remove (t) + t[#t] = t[#t] .. " or " .. top + alternatives = t + end + return table.concat (alternatives, ", ") + end + + + --- Normalize a list of type names. + -- @tparam table t list of type names, trailing "?" as required + -- @treturn table a new list with "?" stripped, "nil" appended if so, + -- and with duplicates stripped. + local function normalize (t) + local i, r, add_nil = 1, {}, false + for _, v in ipairs (t) do + local m = v:match "^(.+)%?$" + if m then + add_nil = true + r[m] = r[m] or i + i = i + 1 + elseif v then + r[v] = r[v] or i + i = i + 1 + end + end + if add_nil then + r["nil"] = r["nil"] or i + end + + -- Invert the return table. + local t = {} + for v, i in pairs (r) do t[i] = v end + return t + end + + + --- Ordered iterator for integer keyed values. + -- Like ipairs, but does not stop at the first nil value. + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table t + -- @usage + -- for i,v in argpairs {"one", nil, "three"} do print (i, v) end + local function argpairs (t) + local i, max = 0, 0 + for k in pairs (t) do + if type (k) == "number" and k > max then max = k end + end + return function (t) + i = i + 1 + if i <= max then return i, t[i] end + end, + t, true + end + + + --- Merge |-delimited type-specs, omitting duplicates. + -- @string ... type-specs + -- @treturn table list of merged and normalized type-specs + local function merge (...) + local i, t = 1, {} + for _, v in argpairs {...} do + v:gsub ("([^|]+)", function (m) t[i] = m; i = i + 1 end) + end + return normalize (t) + end + + + --- Calculate permutations of type lists with and without [optionals]. + -- @tparam table types a list of expected types by argument position + -- @treturn table set of possible type lists + local function permutations (types) + local p, sentinel = {{}}, {"optional arg"} + for i, v in ipairs (types) do + -- Remove sentinels before appending `v` to each list. + for _, v in ipairs (p) do + if last (v) == sentinel then table.remove (v) end + end + + local opt = v:match "%[(.+)%]" + if opt == nil then + -- Append non-optional type-spec to each permutation. + for b = 1, len (p) do insert (p[b], v) end + else + -- Duplicate all existing permutations, and add optional type-spec + -- to the unduplicated permutations. + local o = len (p) + for b = 1, o do + p[b + o] = copy (p[b]) + insert (p[b], opt) + end + + -- Leave a marker for optional argument in final position. + for _, v in ipairs (p) do + insert (v, sentinel) + end + end + end + + -- Replace sentinels with "nil". + for i, v in ipairs (p) do + if v[#v] == sentinel then + table.remove (v) + if #v > 0 then + v[#v] = v[#v] .. "|nil" + else + v[1] = "nil" + end + end + end + + return p + end + + + --- Return index of the first mismatch between types and args, or `nil`. + -- @tparam table types a list of expected types by argument position + -- @tparam table args a table of arguments to compare + -- @tparam boolean allargs whether to match all arguments + -- @treturn int|nil position of first mismatch in *types* + local function match (types, args, allargs) + local typec, argc = len (types), maxn (args) + for i = 1, typec do + local ok = pcall (argcheck, "pcall", i, types[i], args[i]) + if not ok then return i end + end + if allargs then + for i = typec + 1, argc do + local ok = pcall (argcheck, name, i, types[typec], args[i]) + if not ok then return i end + end + end + end + + + --- Format a type mismatch error. + -- @tparam table expectedtypes a table of matchable types + -- @string actual the actual argument to match with + -- @number[opt] index erroring container element index + -- @treturn string formatted *extramsg* for this mismatch for @{argerror} + local function formaterror (expectedtypes, actual, index) + local actualtype = prototype (actual) + + -- Tidy up actual type for display. + if actualtype == "nil" then + actualtype = "no value" + elseif actualtype == "string" and actual:sub (1, 1) == ":" then + actualtype = actual + elseif type (actual) == "table" and next (actual) == nil then + local matchstr = "," .. table.concat (expectedtypes, ",") .. "," + if actualtype == "table" and matchstr == ",#list," then + actualtype = "empty list" + elseif actualtype == "table" or matchstr:match ",#" then + actualtype = "empty " .. actualtype + end + end + + if index then + actualtype = actualtype .. " at index " .. tostring (index) + end + + -- Tidy up expected types for display. + local expectedstr = expectedtypes + if type (expectedtypes) == "table" then + local t = {} + for i, v in ipairs (expectedtypes) do + if v == "func" then + t[i] = "function" + elseif v == "any" then + t[i] = "any value" + elseif v == "file" then + t[i] = "FILE*" + elseif not index then + t[i] = v:match "(%S+) of %S+" or v + else + t[i] = v + end + end + expectedstr = concat (t): + gsub ("#table", "non-empty table"): + gsub ("#list", "non-empty list"): + gsub ("(%S+ of %S+)", "%1s"): + gsub ("(%S+ of %S+)ss", "%1s") + end + + return expectedstr .. " expected, got " .. actualtype + end + + + --- Compare *check* against type of *actual* + -- @string check extended type name expected + -- @param actual object being typechecked + -- @treturn boolean `true` if *actual* is of type *check*, otherwise + -- `false` + local function checktype (check, actual) + if check == "any" and actual ~= nil then + return true + elseif check == "file" and io.type (actual) == "file" then + return true + end + + local actualtype = type (actual) + if check == actualtype then + return true + elseif check == "#table" then + if actualtype == "table" and next (actual) then + return true + end + elseif check == "function" or check == "func" then + if actualtype == "function" or + (getmetatable (actual) or {}).__call ~= nil + then + return true + end + elseif check == "int" then + if actualtype == "number" and actual == math.floor (actual) then + return true + end + elseif type (check) == "string" and check:sub (1, 1) == ":" then + if check == actual then + return true + end + end + + actualtype = prototype (actual) + if check == actualtype then + return true + elseif check == "list" or check == "#list" then + if actualtype == "table" or actualtype == "List" then + local len, count = len (actual), 0 + local i = next (actual) + repeat + if i ~= nil then count = count + 1 end + i = next (actual, i) + until i == nil or count > len + if count == len and (check == "list" or count > 0) then + return true + end + end + elseif check == "object" then + if actualtype ~= "table" and type (actual) == "table" then + return true + end + end + + return false + end + + + function argcheck (name, i, expected, actual, level) + level = level or 2 + expected = normalize (split (expected, "|")) + + -- Check actual has one of the types from expected + local ok = false + for _, expect in ipairs (expected) do + local check, contents = expect:match "^(%S+) of (%S-)s?$" + check = check or expect + + -- Does the type of actual check out? + ok = checktype (check, actual) + + -- For "table of things", check all elements are a thing too. + if ok and contents and type (actual) == "table" then + for k, v in pairs (actual) do + if not checktype (contents, v) then + argerror (name, i, formaterror (expected, v, k), level + 1) + end + end + end + if ok then break end + end + + if not ok then + argerror (name, i, formaterror (expected, actual), level + 1) + end + end + + + function argscheck (decl, inner) + -- Parse "fname (argtype, argtype, argtype...)". + local fname, types = decl:match "([%w_][%.%d%w_]*)%s+%(%s*(.*)%s*%)" + if types == "" then + types = {} + elseif types then + types = split (types, ",%s*") + else + fname = decl:match "([%w_][%.%d%w_]*)" + end + + -- If the final element of types ends with "*", then set max to a + -- sentinel value to denote type-checking of *all* remaining + -- unchecked arguments against that type-spec is required. + local max, fin = len (types), (last (types) or ""):match "^(.+)%*$" + if fin then + max = math.huge + types[len (types)] = fin + end + + -- For optional arguments wrapped in square brackets, make sure + -- type-specs allow for passing or omitting an argument of that + -- type. + local typec, type_specs = len (types), permutations (types) + + return function (...) + local args = {...} + local argc, bestmismatch, at = maxn (args), 0, 0 + + for i, types in ipairs (type_specs) do + local mismatch = match (types, args, max == math.huge) + if mismatch == nil then + bestmismatch = nil + break -- every argument matched its type-spec + end + + if mismatch > bestmismatch then bestmismatch, at = mismatch, i end + end + + if bestmismatch ~= nil then + -- Report an error for all possible types at bestmismatch index. + local expected + if max == math.huge and bestmismatch >= typec then + expected = normalize (split (types[typec], "|")) + else + local tables = {} + for i, types in ipairs (type_specs) do + if types[bestmismatch] then + insert (tables, types[bestmismatch]) + end + end + expected = merge (unpack (tables)) + end + local i = bestmismatch + + -- For "table of things", check all elements are a thing too. + if types[i] then + local check, contents = types[i]:match "^(%S+) of (%S-)s?$" + if contents and type (args[i]) == "table" then + for k, v in pairs (args[i]) do + if not checktype (contents, v) then + argerror (fname, i, formaterror (expected, v, k), 2) + end + end + end + end + + -- Otherwise the argument type itself was mismatched. + argerror (fname, i, formaterror (expected, args[i]), 2) + end + + if argc > max then + error (toomanyargmsg (fname, max, argc), 2) + end + + -- Propagate outer environment to inner function. + setfenv (inner, getfenv (1)) + + return inner (...) + end + end + +else + + -- Turn off argument checking if _DEBUG is false, or a table containing + -- a false valued `argcheck` field. + + argcheck = base.nop + argscheck = function (decl, inner) return inner end + +end ---- Print a debugging message. --- @param n debugging level, defaults to 1 --- @param ... objects to print (as for print) local function say (n, ...) - local level = 1 - local arg = {n, ...} - if type (arg[1]) == "number" then - level = arg[1] - table.remove (arg, 1) - end - if init._DEBUG and - ((type (init._DEBUG) == "table" and type (init._DEBUG.level) == "number" and - init._DEBUG.level >= level) - or level <= 1) then - io.writelines (io.stderr, table.concat (list.map (string.tostring, arg), "\t")) + local level, argt = n, {...} + if type (n) ~= "number" then + level, argt = 1, {n, ...} + end + if _DEBUG.level ~= math.huge and + ((type (_DEBUG.level) == "number" and _DEBUG.level >= level) or level <= 1) + then + local t = {} + for k, v in pairs (argt) do t[k] = tostring (v) end + io.stderr:write (table.concat (t, "\t") .. "\n") end end ---- Trace function calls. --- Use as debug.sethook (trace, "cr"), which is done automatically --- when _DEBUG.call is set. --- Based on test/trace-calls.lua from the Lua distribution. --- @class function --- @name trace --- @param event event causing the call + local level = 0 + local function trace (event) local t = debug.getinfo (3) - local s = " >>> " .. string.rep (" ", level) + local s = " >>> " + for i = 1, level do s = s .. " " end if t ~= nil and t.currentline >= 0 then s = s .. t.short_src .. ":" .. t.currentline .. " " end - t = getinfo (2) + t = debug.getinfo (2) if event == "call" then level = level + 1 else @@ -67,31 +559,198 @@ local function trace (event) else s = s .. event .. " " .. (t.name or "(C)") .. " [" .. t.what .. "]" end - io.writelines (io.stderr, s) + io.stderr:write (s .. "\n") end --- Set hooks according to init._DEBUG -if type (init._DEBUG) == "table" and init._DEBUG.call then +-- Set hooks according to _DEBUG +if type (_DEBUG) == "table" and _DEBUG.call then debug.sethook (trace, "cr") end ---- @export -local M = { - say = say, + + +M = { + --- Provide a deprecated function definition according to _DEBUG.deprecate. + -- You can check whether your covered code uses deprecated functions by + -- setting `_DEBUG.deprecate` to `true` before loading any stdlib modules, + -- or silence deprecation warnings by setting `_DEBUG.deprecate = false`. + -- @function DEPRECATED + -- @string version first deprecation release version + -- @string name function name for automatic warning message + -- @string[opt] extramsg additional warning text + -- @func fn deprecated function + -- @return a function to show the warning on first call, and hand off to *fn* + -- @usage + -- M.op = DEPRECATED ("41", "'std.functional.op'", std.operator) + DEPRECATED = DEPRECATED, + + --- Format a deprecation warning message. + -- @function DEPRECATIONMSG + -- @string version first deprecation release version + -- @string name function name for automatic warning message + -- @string[opt] extramsg additional warning text + -- @int level call stack level to blame for the error + -- @treturn string deprecation warning message, or empty string + -- @usage + -- io.stderr:write (DEPRECATIONMSG ("42", "multi-argument 'module.fname'", 2)) + DEPRECATIONMSG = DEPRECATIONMSG, + + --- Check the type of an argument against expected types. + -- Equivalent to luaL_argcheck in the Lua C API. + -- + -- Call `argerror` if there is a type mismatch. + -- + -- Argument `actual` must match one of the types from in `expected`, each + -- of which can be the name of a primitive Lua type, a stdlib object type, + -- or one of the special options below: + -- + -- #table accept any non-empty table + -- any accept any non-nil argument type + -- file accept an open file object + -- function accept a function, or object with a __call metamethod + -- int accept an integer valued number + -- list accept a table where all keys are a contiguous 1-based integer range + -- #list accept any non-empty list + -- object accept any std.Object derived type + -- :foo accept only the exact string ":foo", works for any :-prefixed string + -- + -- The `:foo` format allows for type-checking of self-documenting + -- boolean-like constant string parameters predicated on `nil` versus + -- `:option` instead of `false` versus `true`. Or you could support + -- both: + -- + -- argcheck ("table.copy", 2, "boolean|:nometa|nil", nometa) + -- + -- A very common pattern is to have a list of possible types including + -- "nil" when the argument is optional. Rather than writing long-hand + -- as above, append a question mark to at least one of the list types + -- and omit the explicit "nil" entry: + -- + -- argcheck ("table.copy", 2, "boolean|:nometa?", predicate) + -- + -- Normally, you should not need to use the `level` parameter, as the + -- default is to blame the caller of the function using `argcheck` in + -- error messages; which is almost certainly what you want. + -- @function argcheck + -- @string name function to blame in error message + -- @int i argument number to blame in error message + -- @string expected specification for acceptable argument types + -- @param actual argument passed + -- @int[opt=2] level call stack level to blame for the error + -- @usage + -- local function case (with, branches) + -- argcheck ("std.functional.case", 2, "#table", branches) + -- ... + argcheck = argcheck, + + --- Raise a bad argument error. + -- Equivalent to luaL_argerror in the Lua C API. This function does not + -- return. The `level` argument behaves just like the core `error` + -- function. + -- @function argerror + -- @string name function to callout in error message + -- @int i argument number + -- @string[opt] extramsg additional text to append to message inside parentheses + -- @int[opt=1] level call stack level to blame for the error + -- @usage + -- local function slurp (file) + -- local h, err = input_handle (file) + -- if h == nil then argerror ("std.io.slurp", 1, err, 2) end + -- ... + argerror = argerror, + + --- Wrap a function definition with argument type and arity checking. + -- In addition to checking that each argument type matches the corresponding + -- element in the *types* table with `argcheck`, if the final element of + -- *types* ends with an asterisk, remaining unchecked arguments are checked + -- against that type. + -- @function argscheck + -- @string decl function type declaration string + -- @func inner function to wrap with argument checking + -- @usage + -- M.square = argscheck ("util.square (number)", function (n) return n * n end) + argscheck = argscheck, + + --- Print a debugging message to `io.stderr`. + -- Display arguments passed through `std.tostring` and separated by tab + -- characters when `_DEBUG` is `true` and *n* is 1 or less; or `_DEBUG.level` + -- is a number greater than or equal to *n*. If `_DEBUG` is false or + -- nil, nothing is written. + -- @function say + -- @int[opt=1] n debugging level, smaller is higher priority + -- @param ... objects to print (as for print) + -- @usage + -- local _DEBUG = require "std.debug_init"._DEBUG + -- _DEBUG.level = 3 + -- say (2, "_DEBUG table contents:", _DEBUG) + say = say, + + --- Format a standard "too many arguments" error message. + -- @fixme remove this wart! + -- @function toomanyargmsg + -- @string name function name + -- @number expect maximum number of arguments accepted + -- @number actual number of arguments received + -- @treturn string standard "too many arguments" error message + -- @usage + -- if table.maxn {...} > 1 then + -- io.stderr:write ("module.fname", 7, table.maxn {...}) + -- ... + toomanyargmsg = toomanyargmsg, + + --- Trace function calls. + -- Use as debug.sethook (trace, "cr"), which is done automatically + -- when `_DEBUG.call` is set. + -- Based on test/trace-calls.lua from the Lua distribution. + -- @function trace + -- @string event event causing the call + -- @usage + -- _DEBUG = { call = true } + -- local debug = require "std.debug" trace = trace, + + + -- Private: + _setdebug = function (t) + for k, v in pairs (t) do + if v == "nil" then v = nil end + _DEBUG[k] = v + end + end, } + for k, v in pairs (debug) do M[k] = M[k] or v end ---- The global function `debug` is an abbreviation for `debug.say (1, ...)` +--- Equivalent to calling `debug.say (1, ...)` -- @function debug -- @see say +-- @usage +-- local debug = require "std.debug" +-- debug "oh noes!" local metatable = { __call = function (self, ...) - say (1, ...) + M.say (1, ...) end, } return setmetatable (M, metatable) + + + +--- Control std.debug function behaviour. +-- To declare debugging state, set _DEBUG either to `false` to disable all +-- runtime debugging; to any "truthy" value (equivalent to enabling everything +-- except *call*, or as documented below. +-- @class table +-- @name _DEBUG +-- @tfield[opt=true] boolean argcheck honor argcheck and argscheck calls +-- @tfield[opt=false] boolean call do call trace debugging +-- @field[opt=nil] deprecate if `false`, deprecated APIs are defined, +-- and do not issue deprecation warnings when used; if `nil` issue a +-- deprecation warning each time a deprecated api is used; any other +-- value causes deprecated APIs not to be defined at all +-- @tfield[opt=1] int level debugging level +-- @usage _DEBUG = { argcheck = false, level = 9 } diff --git a/lib/std/debug_init/init.lua b/lib/std/debug_init/init.lua index f008777..17bd557 100644 --- a/lib/std/debug_init/init.lua +++ b/lib/std/debug_init/init.lua @@ -1,10 +1,44 @@ -- Debugging is on by default -local M = { - _DEBUG = true, -} +local M = {} -if _G._DEBUG ~= nil then +-- User specified fields. +if type (_G._DEBUG) == "table" then M._DEBUG = _G._DEBUG + +-- Turn everything off. +elseif _G._DEBUG == false then + M._DEBUG = { + argcheck = false, + call = false, + deprecate = false, + level = math.huge, + } + +-- Turn everything on (except _DEBUG.call must be set explicitly). +elseif _G._DEBUG == true then + M._DEBUG = { + argcheck = true, + call = false, + deprecate = true, + } + +else + M._DEBUG = {} end + +local function setdefault (field, value) + if M._DEBUG[field] == nil then + M._DEBUG[field] = value + end +end + + +-- Default settings if otherwise unspecified. +setdefault ("argcheck", true) +setdefault ("call", false) +setdefault ("deprecate", nil) +setdefault ("level", 1) + + return M diff --git a/lib/std/functional.lua b/lib/std/functional.lua index ce3e32b..026d7b7 100644 --- a/lib/std/functional.lua +++ b/lib/std/functional.lua @@ -1,85 +1,64 @@ --[[-- Functional programming. + + A selection of higher-order functions to enable a functional style of + programming in Lua. + @module std.functional ]] -local functional -- forward declaration +local base = require "std.base" +local debug = require "std.debug" ---- Identity function. --- @param ... --- @return the arguments passed to the function -local function id (...) - return ... -end +local ielems, ipairs, ireverse, len, pairs = + base.ielems, base.ipairs, base.ireverse, base.len, base.pairs +local callable, reduce = base.callable, base.reduce +local loadstring = loadstring or load +local unpack = table.unpack or unpack ---- Partially apply a function. --- @param f function to apply partially --- @tparam table {p1=a1, ..., pn=an} table of parameters to bind to given arguments --- @return function with pi already bound -local function bind (f, ...) - local fix = {...} -- backwards compatibility with old API; DEPRECATED: remove in first release after 2015-04-21 - if type (fix[1]) == "table" and fix[2] == nil then - fix = fix[1] +local function bind (fn, ...) + local argt = {...} + if type (argt[1]) == "table" and argt[2] == nil then + argt = argt[1] + else + io.stderr:write (debug.DEPRECATIONMSG ("39", + "multi-argument 'std.functional.bind'", + "use a table of arguments as the second parameter instead", 2)) end + return function (...) - local arg = {...} - for i, v in pairs (fix) do + local arg = {} + for i, v in pairs (argt) do arg[i] = v end - return f (unpack (arg)) + local i = 1 + for _, v in ipairs {...} do + while arg[i] ~= nil do i = i + 1 end + arg[i] = v + end + return fn (unpack (arg)) end end ---- A rudimentary case statement. --- Match `with` against keys in `branches` table, and return the result --- of running the function in the table value for the matching key, or --- the first non-key value function if no key matches. --- --- return case (type (object), { --- table = function () return something end, --- string = function () return something else end, --- function (s) error ("unhandled type: "..s) end, --- }) --- --- @param with expression to match --- @tparam table branches map possible matches to functions --- @return the return value from function with a matching key, or nil. local function case (with, branches) - local fn = branches[with] or branches[1] - if fn then return fn (with) end -end - - ---- Curry a function. --- @param f function to curry --- @param n number of arguments --- @return curried version of f -local function curry (f, n) - if n <= 1 then - return f - else - return function (x) - return curry (bind (f, x), n - 1) - end + local match = branches[with] or branches[1] + if callable (match) then + return match (with) end + return match end ---- Compose functions. --- @param f1...fn functions to compose --- @return composition of fn (... (f1) ...): note that this is the reverse --- of what you might expect, but means that code like: --- --- functional.compose (function (x) return f (x) end, --- function (x) return g (x) end)) --- --- can be read from top to bottom. local function compose (...) local arg = {...} local fns, n = arg, #arg + for i = 1, n do + local f = fns[i] + end + return function (...) local arg = {...} for i = 1, n do @@ -90,146 +69,531 @@ local function compose (...) end ---- Signature of memoize `normalize` functions. --- @function memoize_normalize --- @param ... arguments --- @treturn string normalized arguments +local function cond (expr, branch, ...) + if branch == nil and select ("#", ...) == 0 then + expr, branch = true, expr + end + if expr then + if callable (branch) then + return branch (expr) + end + return branch + end + return cond (...) +end + + +local function curry (fn, n) + if n <= 1 then + return fn + else + return function (x) + return curry (bind (fn, x), n - 1) + end + end +end + + +local function filter (pfn, ifn, ...) + local argt = {...} + if not callable (ifn) then + ifn, argt = pairs, {ifn, ...} + end + + local nextfn, state, k = ifn (unpack (argt)) + local t = {nextfn (state, k)} -- table of iteration 1 + + local r = {} -- new results table + while t[1] ~= nil do -- until iterator returns nil + k = t[1] + if pfn (unpack (t)) then -- pass all iterator results to p + if t[2] ~= nil then + r[k] = t[2] -- k,v = t[1],t[2] + else + r[#r + 1] = k -- k,v = #r + 1,t[1] + end + end + t = {nextfn (state, k)} -- maintain loop invariant + end + return r +end + + +local function foldl (fn, d, t) + if t == nil then + local tail = {} + for i = 2, len (d) do tail[#tail + 1] = d[i] end + d, t = d[1], tail + end + return reduce (fn, d, ielems, t) +end + + +local function foldr (fn, d, t) + if t == nil then + local u, last = {}, len (d) + for i = 1, last - 1 do u[#u + 1] = d[i] end + d, t = d[last], u + end + return reduce (function (x, y) return fn (y, x) end, d, ielems, ireverse (t)) +end + + +local function id (...) + return ... +end ---- Memoize a function, by wrapping it in a functable. --- --- To ensure that memoize always returns the same object for the same --- arguments, it passes arguments to `normalize` (std.string.tostring --- by default). You may need a more sophisticated function if memoize --- should handle complicated argument equivalencies. --- @param fn function that returns a single result --- @param normalize[opt] function to normalize arguments --- @return memoized function local function memoize (fn, normalize) if normalize == nil then - -- Call require here, to avoid pulling in all of 'std.string' - -- even when memoize is never called. - local stringify = require "std.string".tostring - normalize = function (...) return stringify {...} end + normalize = function (...) return base.tostring {...} end end return setmetatable ({}, { __call = function (self, ...) local k = normalize (...) - local v = self[k] - if v == nil then - v = fn (...) - self[k] = v + local t = self[k] + if t == nil then + t = {fn (...)} + self[k] = t end - return v + return unpack (t) end }) end ---- Evaluate a string. --- @param s string --- @return value of string -local function eval (s) - return loadstring ("return " .. s)() -end +local lambda = memoize (function (s) + local expr + -- Support "|args|expression" format. + local args, body = s:match "^%s*|%s*([^|]*)|%s*(.+)%s*$" + if args and body then + expr = "return function (" .. args .. ") return " .. body .. " end" + end ---- Collect the results of an iterator. --- @param i iterator --- @return results of running the iterator on its arguments -local function collect (i, ...) - local t = {} - for e in i (...) do - t[#t + 1] = e + -- Support "expression" format. + if not expr then + body = s:match "^%s*(_.*)%s*$" or s:match "^=%s*(.+)%s*$" + if body then + expr = [[ + return function (...) + local unpack = table.unpack or unpack + local _1,_2,_3,_4,_5,_6,_7,_8,_9 = unpack {...} + local _ = _1 + return ]] .. body .. [[ + end + ]] + end + end + + local ok, fn + if expr then + ok, fn = pcall (loadstring (expr)) + end + + -- Diagnose invalid input. + if not ok then + return nil, "invalid lambda string '" .. s .. "'" end - return t -end + return fn +end, id) ---- Map a function over an iterator. --- @param f function --- @param i iterator --- @return result table -local function map (f, i, ...) - local t = {} - for e in i (...) do - local r = f (e) - if r ~= nil then - table.insert (t, r) + +local function map (mapfn, ifn, ...) + local argt = {...} + if not callable (ifn) or not next (argt) then + ifn, argt = pairs, {ifn, ...} + end + + local nextfn, state, k = ifn (unpack (argt)) + local mapargs = {nextfn (state, k)} + + local r = {} + while mapargs[1] ~= nil do + k = mapargs[1] + local d, v = mapfn (unpack (mapargs)) + if v == nil then d, v = #r + 1, d end + if v ~= nil then + r[d] = v end + mapargs = {nextfn (state, k)} + end + return r +end + + +local function map_with (mapfn, tt) + local r = {} + for k, v in pairs (tt) do + r[k] = mapfn (unpack (v)) end - return t + return r end ---- Filter an iterator with a predicate. --- @param p predicate --- @param i iterator --- @return result table containing elements e for which p (e) -local function filter (p, i, ...) - local t = {} - for e in i (...) do - if p (e) then - table.insert (t, e) +local function zip (tt) + local r = {} + for outerk, inner in pairs (tt) do + for k, v in pairs (inner) do + r[k] = r[k] or {} + r[k][outerk] = v end end - return t + return r +end + + +local function zip_with (fn, tt) + return map_with (fn, zip (tt)) +end + + + +--[[ ================= ]]-- +--[[ Public Interface. ]]-- +--[[ ================= ]]-- + + +local function X (decl, fn) + return debug.argscheck ("std.functional." .. decl, fn) end +local M = { + --- Partially apply a function. + -- @function bind + -- @func fn function to apply partially + -- @tparam table argt table of *fn* arguments to bind + -- @return function with *argt* arguments already bound + -- @usage + -- cube = bind (std.operator.pow, {[2] = 3}) + bind = X ("bind (func, any?*)", bind), + + --- Identify callable types. + -- @function callable + -- @param x an object or primitive + -- @return `true` if *x* can be called, otherwise `false` + -- @usage + -- if callable (functable) then functable (args) end + callable = X ("callable (any)", callable), + + --- A rudimentary case statement. + -- Match *with* against keys in *branches* table. + -- @function case + -- @param with expression to match + -- @tparam table branches map possible matches to functions + -- @return the value associated with a matching key, or the first non-key + -- value if no key matches. Function or functable valued matches are + -- called using *with* as the sole argument, and the result of that call + -- returned; otherwise the matching value associated with the matching + -- key is returned directly; or else `nil` if there is no match and no + -- default. + -- @see cond + -- @usage + -- return case (type (object), { + -- table = "table", + -- string = function () return "string" end, + -- function (s) error ("unhandled type: " .. s) end, + -- }) + case = X ("case (any?, #table)", case), + + --- Collect the results of an iterator. + -- @function collect + -- @func[opt=std.ipairs] ifn iterator function + -- @param ... *ifn* arguments + -- @treturn table of results from running *ifn* on *args* + -- @see filter + -- @see map + -- @usage + -- --> {"a", "b", "c"} + -- collect {"a", "b", "c", x=1, y=2, z=5} + collect = X ("collect ([func], any*)", base.collect), + + --- Compose functions. + -- @function compose + -- @func ... functions to compose + -- @treturn function composition of fnN .. fn1: note that this is the + -- reverse of what you might expect, but means that code like: + -- + -- functional.compose (function (x) return f (x) end, + -- function (x) return g (x) end)) + -- + -- can be read from top to bottom. + -- @usage + -- vpairs = compose (table.invert, ipairs) + -- for v, i in vpairs {"a", "b", "c"} do process (v, i) end + compose = X ("compose (func*)", compose), + + --- A rudimentary condition-case statement. + -- If *expr* is "truthy" return *branch* if given, otherwise *expr* + -- itself. If the return value is a function or functable, then call it + -- with *expr* as the sole argument and return the result; otherwise + -- return it explicitly. If *expr* is "falsey", then recurse with the + -- first two arguments stripped. + -- @function cond + -- @param expr a Lua expression + -- @param branch a function, functable or value to use if *expr* is + -- "truthy" + -- @param ... additional arguments to retry if *expr* is "falsey" + -- @see case + -- @usage + -- -- recursively calculate the nth triangular number + -- function triangle (n) + -- return cond ( + -- n <= 0, 0, + -- n == 1, 1, + -- function () return n + triangle (n - 1) end) + -- end + cond = cond, -- any number of any type arguments! + + --- Curry a function. + -- @function curry + -- @func fn function to curry + -- @int n number of arguments + -- @treturn function curried version of *fn* + -- @usage + -- add = curry (function (x, y) return x + y end, 2) + -- incr, decr = add (1), add (-1) + curry = X ("curry (func, int)", curry), + + --- Filter an iterator with a predicate. + -- @function filter + -- @tparam predicate pfn predicate function + -- @func[opt=std.pairs] ifn iterator function + -- @param ... iterator arguments + -- @treturn table elements e for which `pfn (e)` is not "falsey". + -- @see collect + -- @see map + -- @usage + -- --> {2, 4} + -- filter (lambda '|e|e%2==0', std.elems, {1, 2, 3, 4}) + filter = X ("filter (func, [func], any*)", filter), + + --- Fold a binary function left associatively. + -- If parameter *d* is omitted, the first element of *t* is used, + -- and *t* treated as if it had been passed without that element. + -- @function foldl + -- @func fn binary function + -- @param[opt=t[1]] d initial left-most argument + -- @tparam table t a table + -- @return result + -- @see foldr + -- @see reduce + -- @usage + -- foldl (std.operator.quot, {10000, 100, 10}) == (10000 / 100) / 10 + foldl = X ("foldl (function, [any], table)", foldl), + + --- Fold a binary function right associatively. + -- If parameter *d* is omitted, the last element of *t* is used, + -- and *t* treated as if it had been passed without that element. + -- @function foldr + -- @func fn binary function + -- @param[opt=t[1]] d initial right-most argument + -- @tparam table t a table + -- @return result + -- @see foldl + -- @see reduce + -- @usage + -- foldr (std.operator.quot, {10000, 100, 10}) == 10000 / (100 / 10) + foldr = X ("foldr (function, [any], table)", foldr), + + --- Identity function. + -- @function id + -- @param ... arguments + -- @return *arguments* + id = id, -- any number of any type arguments! + + --- Compile a lambda string into a Lua function. + -- + -- A valid lambda string takes one of the following forms: + -- + -- 1. `'=expression'`: equivalent to `function (...) return expression end` + -- 1. `'|args|expression'`: equivalent to `function (args) return expression end` + -- + -- The first form (starting with `'='`) automatically assigns the first + -- nine arguments to parameters `'_1'` through `'_9'` for use within the + -- expression body. The parameter `'_1'` is aliased to `'_'`, and if the + -- first non-whitespace of the whole expression is `'_'`, then the + -- leading `'='` can be omitted. + -- + -- The results are memoized, so recompiling a previously compiled + -- lambda string is extremely fast. + -- @function lambda + -- @string s a lambda string + -- @treturn functable compiled lambda string, can be called like a function + -- @usage + -- -- The following are equivalent: + -- lambda '= _1 < _2' + -- lambda '|a,b| a {1, 4, 9, 16} + -- map (lambda '=_1*_1', std.ielems, {1, 2, 3, 4}) + map = X ("map (func, [func], any*)", map), + + --- Map a function over a table of argument lists. + -- @function map_with + -- @func fn map function + -- @tparam table tt a table of *fn* argument lists + -- @treturn table new table of *fn* results + -- @see map + -- @see zip_with + -- @usage + -- --> {"123", "45"}, {a="123", b="45"} + -- conc = bind (map_with, {lambda '|...|table.concat {...}'}) + -- conc {{1, 2, 3}, {4, 5}}, conc {a={1, 2, 3, x="y"}, b={4, 5, z=6}} + map_with = X ("map_with (function, table of tables)", map_with), + + --- Memoize a function, by wrapping it in a functable. + -- + -- To ensure that memoize always returns the same results for the same + -- arguments, it passes arguments to *fn*. You can specify a more + -- sophisticated function if memoize should handle complicated argument + -- equivalencies. + -- @function memoize + -- @func fn pure function: a function with no side effects + -- @tparam[opt=std.tostring] normalize normfn function to normalize arguments + -- @treturn functable memoized function + -- @usage + -- local fast = memoize (function (...) --[[ slow code ]] end) + memoize = X ("memoize (func, func?)", memoize), + + --- No operation. + -- This function ignores all arguments, and returns no values. + -- @function nop + -- @see id + -- @usage + -- if unsupported then vtable["memrmem"] = nop end + nop = base.nop, -- ignores all arguments + + --- Fold a binary function into an iterator. + -- @function reduce + -- @func fn reduce function + -- @param d initial first argument + -- @func[opt=std.pairs] ifn iterator function + -- @param ... iterator arguments + -- @return result + -- @see foldl + -- @see foldr + -- @usage + -- --> 2 ^ 3 ^ 4 ==> 4096 + -- reduce (std.operator.pow, 2, std.ielems, {3, 4}) + reduce = X ("reduce (func, any, [func], any*)", reduce), + + --- Zip a table of tables. + -- Make a new table, with lists of elements at the same index in the + -- original table. This function is effectively its own inverse. + -- @function zip + -- @tparam table tt a table of tables + -- @treturn table new table with lists of elements of the same key + -- from *tt* + -- @see map + -- @see zip_with + -- @usage + -- --> {{1, 3, 5}, {2, 4}}, {a={x=1, y=3, z=5}, b={x=2, y=4}} + -- zip {{1, 2}, {3, 4}, {5}}, zip {x={a=1, b=2}, y={a=3, b=4}, z={a=5}} + zip = X ("zip (table of tables)", zip), + + --- Zip a list of tables together with a function. + -- @function zip_with + -- @tparam function fn function + -- @tparam table tt table of tables + -- @treturn table a new table of results from calls to *fn* with arguments + -- made from all elements the same key in the original tables; effectively + -- the "columns" in a simple list + -- of lists. + -- @see map_with + -- @see zip + -- @usage + -- --> {"135", "24"}, {a="1", b="25"} + -- conc = bind (zip_with, {lambda '|...|table.concat {...}'}) + -- conc {{1, 2}, {3, 4}, {5}}, conc {{a=1, b=2}, x={a=3, b=4}, {b=5}} + zip_with = X ("zip_with (function, table of tables)", zip_with), +} + + + +--[[ ============= ]]-- +--[[ Deprecations. ]]-- +--[[ ============= ]]-- + + +local DEPRECATED = debug.DEPRECATED + + +M.eval = DEPRECATED ("41", "'std.functional.eval'", + "use 'std.eval' instead", base.eval) + + +local function fold (fn, d, ifn, ...) + local nextfn, state, k = ifn (...) + local t = {nextfn (state, k)} ---- Fold a binary function into an iterator. --- @param f function --- @param d initial first argument --- @param i iterator --- @return result -local function fold (f, d, i, ...) local r = d - for e in i (...) do - r = f (r, e) + while t[1] ~= nil do + r = fn (r, t[#t]) + t = {nextfn (state, t[1])} end return r end ---- @export -functional = { - bind = bind, - case = case, - collect = collect, - compose = compose, - curry = curry, - eval = eval, - filter = filter, - fold = fold, - id = id, - map = map, - memoize = memoize, -} +M.fold = DEPRECATED ("41", "'std.functional.fold'", + "use 'std.functional.reduce' instead", fold) + + +local operator = require "std.operator" + +local function DEPRECATEOP (old, new) + return DEPRECATED ("41", "'std.functional.op[" .. old .. "]'", + "use 'std.operator." .. new .. "' instead", operator[new]) +end ---- Functional forms of infix operators. --- Defined here so that other modules can write to it. --- @table op --- @field [] dereference table index --- @field + addition --- @field - subtraction --- @field * multiplication --- @field / division --- @field and logical and --- @field or logical or --- @field not logical not --- @field == equality --- @field ~= inequality -functional.op = { - ["[]"] = function (t, s) return t and t[s] or nil end, - ["+"] = function (a, b) return a + b end, - ["-"] = function (a, b) return a - b end, - ["*"] = function (a, b) return a * b end, - ["/"] = function (a, b) return a / b end, - ["and"] = function (a, b) return a and b end, - ["or"] = function (a, b) return a or b end, - ["not"] = function (a) return not a end, - ["=="] = function (a, b) return a == b end, - ["~="] = function (a, b) return a ~= b end, +M.op = { + ["[]"] = DEPRECATEOP ("[]", "get"), + ["+"] = DEPRECATEOP ("+", "sum"), + ["-"] = DEPRECATEOP ("-", "diff"), + ["*"] = DEPRECATEOP ("*", "prod"), + ["/"] = DEPRECATEOP ("/", "quot"), + ["and"] = DEPRECATEOP ("and", "conj"), + ["or"] = DEPRECATEOP ("or", "disj"), + ["not"] = DEPRECATEOP ("not", "neg"), + ["=="] = DEPRECATEOP ("==", "eq"), + ["~="] = DEPRECATEOP ("~=", "neq"), } -return functional +return M + + + +--- Types +-- @section Types + + +--- Signature of a @{memoize} argument normalization callback function. +-- @function normalize +-- @param ... arguments +-- @treturn string normalized arguments +-- @usage +-- local normalize = function (name, value, props) return name end +-- local intern = std.functional.memoize (mksymbol, normalize) + + +--- Signature of a @{filter} predicate callback function. +-- @function predicate +-- @param ... arguments +-- @treturn boolean "truthy" if the predicate condition succeeds, +-- "falsey" otherwise +-- @usage +-- local predicate = lambda '|k,v|type(v)=="string"' +-- local strvalues = filter (predicate, std.pairs, {name="Roberto", id=12345}) diff --git a/lib/std/io.lua b/lib/std/io.lua index 4681126..f6d198f 100644 --- a/lib/std/io.lua +++ b/lib/std/io.lua @@ -1,35 +1,44 @@ --[[-- - Additions to the io module. + Additions to the core io module. + + The module table returned by `std.io` also contains all of the entries from + the core `io` module table. An hygienic way to import this module, then, + is simply to override core `io` locally: + + local io = require "std.io" + @module std.io ]] -local string = require "std.string" -local tree = require "std.tree" -local package = { - dirsep = string.match (package.config, "^([^\n]+)\n"), -} +local base = require "std.base" +local debug = require "std.debug" + +local argerror = debug.argerror +local catfile, dirsep, insert, len, leaves, split = + base.catfile, base.dirsep, base.insert, base.len, base.leaves, base.split +local ipairs, pairs = base.ipairs, base.pairs +local setmetatable = debug.setmetatable + -local M -- forward declaration + +local M, monkeys --- Get an input file handle. --- @param h file handle or name (default: `io.input ()`) --- @return file handle, or nil on error local function input_handle (h) if h == nil then - h = io.input () + return io.input () elseif type (h) == "string" then - h = io.open (h) + return io.open (h) end return h end ---- Slurp a file handle. --- @param h file handle or name (default: `io.input ()`) --- @return contents of file or handle, or nil if error -local function slurp (h) - h = input_handle (h) + +local function slurp (file) + local h, err = input_handle (file) + if h == nil then argerror ("std.io.slurp", 1, err, 2) end + if h then local s = h:read ("*a") h:close () @@ -37,12 +46,11 @@ local function slurp (h) end end ---- Read a file or file handle into a list of lines. --- @param h file handle or name (default: `io.input ()`); --- if h is a handle, the file is closed after reading --- @return list of lines -local function readlines (h) - h = input_handle (h) + +local function readlines (file) + local h, err = input_handle (file) + if h == nil then argerror ("std.io.readlines", 1, err, 2) end + local l = {} for line in h:lines () do l[#l + 1] = line @@ -51,76 +59,37 @@ local function readlines (h) return l end ---- Write values adding a newline after each. --- @param h file handle (default: `io.output ()`) --- @param ... values to write (as for write) + local function writelines (h, ...) if io.type (h) ~= "file" then io.write (h, "\n") h = io.output () end - for v in tree.ileaves ({...}) do + for v in leaves (ipairs, {...}) do h:write (v, "\n") end end ---- Overwrite core methods and metamethods with `std` enhanced versions. --- --- Adds `readlines` and `writelines` metamethods to core file objects. --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table the module table + local function monkey_patch (namespace) namespace = namespace or _G + namespace.io = base.copy (namespace.io or {}, monkeys) - assert (type (namespace) == "table", - "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") - - local file_metatable = getmetatable (namespace.io.stdin) - file_metatable.readlines = readlines - file_metatable.writelines = writelines - - return M -end - ---- Split a directory path into components. --- Empty components are retained: the root directory becomes `{"", ""}`. --- @param path path --- @return list of path components -local function splitdir (path) - return string.split (path, package.dirsep) -end - ---- Concatenate one or more directories and a filename into a path. --- @param ... path components --- @return path -local function catfile (...) - return table.concat ({...}, package.dirsep) -end + if namespace.io.stdin then + local mt = getmetatable (namespace.io.stdin) or {} + mt.readlines = M.readlines + mt.writelines = M.writelines + setmetatable (namespace.io.stdin, mt) + end ---- Concatenate two or more directories into a path, removing the trailing slash. --- @param ... path components --- @return path -local function catdir (...) - return (string.gsub (catfile (...), "^$", package.dirsep)) + return namespace.io end ---- Perform a shell command and return its output. --- @param c command --- @return output, or nil if error -local function shell (c) - return slurp (io.popen (c)) -end ---- Process files specified on the command-line. --- If no files given, process `io.stdin`; in list of files, --- `-` means `io.stdin`. --- @todo Make the file list an argument to the function. --- @param f function to process files with, which is passed --- `(name, arg_no)` -local function process_files (f) +local function process_files (fn) -- N.B. "arg" below refers to the global array of command-line args - if #arg == 0 then - arg[#arg + 1] = "-" + if len (arg) == 0 then + insert (arg, "-") end for i, v in ipairs (arg) do if v == "-" then @@ -128,28 +97,12 @@ local function process_files (f) else io.input (v) end - f (v, i) + fn (v, i) end end ---- Give warning with the name of program and file (if any). --- If there is a global `prog` table, prefix the message with --- `prog.name` or `prog.file`, and `prog.line` if any. Otherwise --- if there is a global `opts` table, prefix the message with --- `opts.program` and `opts.line` if any. @{std.optparse:parse} --- returns an `opts` table that provides the required `program` --- field, as long as you assign it back to `_G.opts`: --- --- local OptionParser = require "std.optparse" --- local parser = OptionParser "eg 0\nUsage: eg\n" --- _G.arg, _G.opts = parser:parse (_G.arg) --- if not _G.opts.keep_going then --- require "std.io".warn "oh noes!" --- end --- --- @param ... arguments for format --- @see std.optparse:parse -local function warn (...) + +local function warnfmt (msg, ...) local prefix = "" if (prog or {}).name then prefix = prog.name .. ":" @@ -168,37 +121,175 @@ local function warn (...) end end if #prefix > 0 then prefix = prefix .. " " end - writelines (io.stderr, prefix .. string.format (...)) + return prefix .. string.format (msg, ...) +end + + +local function warn (msg, ...) + writelines (io.stderr, warnfmt (msg, ...)) end ---- Die with error. --- This function uses the same rules to build a message prefix --- as @{std.io.warn}. --- @param ... arguments for format --- @see std.io.warn -local function die (...) - warn (...) - error () + + +--[[ ================= ]]-- +--[[ Public Interface. ]]-- +--[[ ================= ]]-- + + +local function X (decl, fn) + return debug.argscheck ("std.io." .. decl, fn) end ---- @export M = { - catdir = catdir, - catfile = catfile, - die = die, - monkey_patch = monkey_patch, - process_files = process_files, - readlines = readlines, - shell = shell, - slurp = slurp, - splitdir = splitdir, - warn = warn, - writelines = writelines, + --- Concatenate directory names into a path. + -- @function catdir + -- @string ... path components + -- @return path without trailing separator + -- @see catfile + -- @usage dirpath = catdir ("", "absolute", "directory") + catdir = X ("catdir (string*)", function (...) + return table.concat ({...}, dirsep):gsub("^$", dirsep) + end), + + --- Concatenate one or more directories and a filename into a path. + -- @function catfile + -- @string ... path components + -- @treturn string path + -- @see catdir + -- @see splitdir + -- @usage filepath = catfile ("relative", "path", "filename") + catfile = X ("catfile (string*)", base.catfile), + + --- Die with error. + -- This function uses the same rules to build a message prefix + -- as @{warn}. + -- @function die + -- @string msg format string + -- @param ... additional arguments to plug format string specifiers + -- @see warn + -- @usage die ("oh noes! (%s)", tostring (obj)) + die = X ("die (string, any?*)", function (...) + error (warnfmt (...), 0) + end), + + --- Remove the last dirsep delimited element from a path. + -- @function dirname + -- @string path file path + -- @treturn string a new path with the last dirsep and following + -- truncated + -- @usage dir = dirname "/base/subdir/filename" + dirname = X ("dirname (string)", function (path) + return path:gsub (catfile ("", "[^", "]*$"), "") + end), + + --- Overwrite core `io` methods with `std` enhanced versions. + -- + -- Also adds @{readlines} and @{writelines} metamethods to core file objects. + -- @function monkey_patch + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table the `std.io` module table + -- @usage local io = require "std.io".monkey_patch () + monkey_patch = X ("monkey_patch (table?)", monkey_patch), + + --- Process files specified on the command-line. + -- Each filename is made the default input source with `io.input`, and + -- then the filename and argument number are passed to the callback + -- function. In list of filenames, `-` means `io.stdin`. If no + -- filenames were given, behave as if a single `-` was passed. + -- @todo Make the file list an argument to the function. + -- @function process_files + -- @tparam fileprocessor fn function called for each file argument + -- @usage + -- #! /usr/bin/env lua + -- -- minimal cat command + -- local io = require "std.io" + -- io.process_files (function () io.write (io.slurp ()) end) + process_files = X ("process_files (function)", process_files), + + --- Read a file or file handle into a list of lines. + -- The lines in the returned list are not `\n` terminated. + -- @function readlines + -- @tparam[opt=io.input()] file|string file file handle or name; + -- if file is a file handle, that file is closed after reading + -- @treturn list lines + -- @usage list = readlines "/etc/passwd" + readlines = X ("readlines (file|string|nil)", readlines), + + --- Perform a shell command and return its output. + -- @function shell + -- @string c command + -- @treturn string output, or nil if error + -- @see os.execute + -- @usage users = shell [[cat /etc/passwd | awk -F: '{print $1;}']] + shell = X ("shell (string)", function (c) return slurp (io.popen (c)) end), + + --- Slurp a file handle. + -- @function slurp + -- @tparam[opt=io.input()] file|string file file handle or name; + -- if file is a file handle, that file is closed after reading + -- @return contents of file or handle, or nil if error + -- @see process_files + -- @usage contents = slurp (filename) + slurp = X ("slurp (file|string|nil)", slurp), + + --- Split a directory path into components. + -- Empty components are retained: the root directory becomes `{"", ""}`. + -- @function splitdir + -- @param path path + -- @return list of path components + -- @see catdir + -- @usage dir_components = splitdir (filepath) + splitdir = X ("splitdir (string)", + function (path) return split (path, dirsep) end), + + --- Give warning with the name of program and file (if any). + -- If there is a global `prog` table, prefix the message with + -- `prog.name` or `prog.file`, and `prog.line` if any. Otherwise + -- if there is a global `opts` table, prefix the message with + -- `opts.program` and `opts.line` if any. @{std.optparse:parse} + -- returns an `opts` table that provides the required `program` + -- field, as long as you assign it back to `_G.opts`. + -- @function warn + -- @string msg format string + -- @param ... additional arguments to plug format string specifiers + -- @see std.optparse:parse + -- @see die + -- @usage + -- local OptionParser = require "std.optparse" + -- local parser = OptionParser "eg 0\nUsage: eg\n" + -- _G.arg, _G.opts = parser:parse (_G.arg) + -- if not _G.opts.keep_going then + -- require "std.io".warn "oh noes!" + -- end + warn = X ("warn (string, any?*)", warn), + + --- Write values adding a newline after each. + -- @function writelines + -- @tparam[opt=io.output()] file h open writable file handle; + -- the file is **not** closed after writing + -- @tparam string|number ... values to write (as for write) + -- @usage writelines (io.stdout, "first line", "next line") + writelines = X ("writelines (file|string|number?, string|number?*)", writelines), } -for k, v in pairs (io) do - M[k] = M[k] or v -end -return M +monkeys = base.copy ({}, M) -- before deprecations and core merge + + +return base.merge (M, io) + + + +--- Types +-- @section Types + +--- Signature of @{process_files} callback function. +-- @function fileprocessor +-- @string filename filename +-- @int i argument number of *filename* +-- @usage +-- local fileprocessor = function (filename, i) +-- io.write (tostring (i) .. ":\n===\n" .. io.slurp (filename) .. "\n") +-- end +-- io.process_files (fileprocessor) diff --git a/lib/std/list.lua b/lib/std/list.lua index 33caa98..8932028 100644 --- a/lib/std/list.lua +++ b/lib/std/list.lua @@ -1,135 +1,191 @@ --[[-- Tables as lists. - Every list is also an object, and thus inherits all of the `std.object` - methods, particularly use of object cloning for making new list objects. + Prototype Chain + --------------- - In addition to calling methods on list objects in OO style... - - local List = require "std.list" - local l = List {1, 2, 3} - for e in l:relems () do print (e) end - => 3 - => 2 - => 1 - - ... some can also be called as module functions with an explicit list - argument in the first or last parameter, check the documentation for - details: - - local List = require "std.list" - local l = List {1, 2, 3} - for e in List.relems (l) do print (e) end - => 3 - => 2 - => 1 + table + `-> Object + `-> List @classmod std.list ]] + local base = require "std.base" -local func = require "std.functional" -local Object = require "std.object" +local debug = require "std.debug" +local Object = require "std.object" {} -local List -- forward declaration +local ipairs, pairs = base.ipairs, base.pairs +local len = base.len +local compare = base.compare +local prototype = base.prototype +local unpack = table.unpack or unpack + +local M, List ------- --- An Object derived List. --- @table List ---- Append an item to a list. --- @tparam List l a list --- @param x item --- @treturn List new list containing `{l[1], ..., l[#l], x}` local function append (l, x) - local r = List {unpack (l)} + local r = l {} r[#r + 1] = x return r end ---- Compare two lists element-by-element, from left-to-right. --- --- if a_list:compare (another_list) == 0 then print "same" end --- @static --- @function compare --- @tparam List l a list --- @tparam table m another list --- @return -1 if `l` is less than `m`, 0 if they are the same, and 1 --- if `l` is greater than `m` -local function compare (l, m) - for i = 1, math.min (#l, #m) do - if l[i] < m[i] then - return -1 - elseif l[i] > m[i] then - return 1 +local function concat (l, ...) + local r = List {} + for _, e in ipairs {l, ...} do + for _, v in ipairs (e) do + r[#r + 1] = v end end - if #l < #m then - return -1 - elseif #l > #m then - return 1 - end - return 0 + return r end ---- An iterator over the elements of a list. --- @static --- @function elems --- @tparam List l a list --- @treturn function iterator function which returns successive elements --- of `l` --- @treturn List `l` --- @return `true` -local elems = base.elems +local function rep (l, n) + local r = List {} + for i = 1, n do + r = concat (r, l) + end + return r +end ---- Concatenate arguments into a list. --- @tparam List l a list --- @param ... tuple of lists --- @treturn List new list containing --- `{l[1], ..., l[#l], l\_1[1], ..., l\_1[#l\_1], ..., l\_n[1], ..., l\_n[#l\_n]}` -local function concat (l, ...) +local function sub (l, from, to) local r = List {} - for e in elems ({l, ...}) do - for v in elems (e) do - r[#r + 1] = v - end + local lenl = len (l) + from = from or 1 + to = to or lenl + if from < 0 then + from = from + lenl + 1 + end + if to < 0 then + to = to + lenl + 1 + end + for i = from, to do + r[#r + 1] = l[i] end return r end ---- Prepend an item to a list. --- @tparam List l a list --- @param x item --- @treturn List new list containing `{x, unpack (l)}` -local function cons (l, x) - return List {x, unpack (l)} + +--[[ ================= ]]-- +--[[ Public Interface. ]]-- +--[[ ================= ]]-- + + +local function X (decl, fn) + return debug.argscheck ("std.list." .. decl, fn) end ---- Turn a list of pairs into a table. --- @todo Find a better name. --- @tparam table ls list of lists `{{i1, v1}, ..., {in, vn}}` --- @treturn table a new list containing table `{i1=v1, ..., in=vn}` --- @see enpair +M = { + --- Append an item to a list. + -- @static + -- @function append + -- @tparam List l a list + -- @param x item + -- @treturn List new list with *x* appended + -- @usage + -- longer = append (short, "last") + append = X ("append (List, any)", append), + + --- Compare two lists element-by-element, from left-to-right. + -- @static + -- @function compare + -- @tparam List l a list + -- @tparam List|table m another list, or table + -- @return -1 if *l* is less than *m*, 0 if they are the same, and 1 + -- if *l* is greater than *m* + -- @usage + -- if a_list:compare (another_list) == 0 then print "same" end + compare = X ("compare (List, List|table)", compare), + + --- Concatenate the elements from any number of lists. + -- @static + -- @function concat + -- @tparam List l a list + -- @param ... tuple of lists + -- @treturn List new list with elements from arguments + -- @usage + -- --> {1, 2, 3, {4, 5}, 6, 7} + -- list.concat ({1, 2, 3}, {{4, 5}, 6, 7}) + concat = X ("concat (List, List|table*)", concat), + + --- Prepend an item to a list. + -- @static + -- @function cons + -- @tparam List l a list + -- @param x item + -- @treturn List new list with *x* followed by elements of *l* + -- @usage + -- --> {"x", 1, 2, 3} + -- list.cons ({1, 2, 3}, "x") + cons = X ("cons (List, any)", function (l, x) return List {x, unpack (l)} end), + + --- Repeat a list. + -- @static + -- @function rep + -- @tparam List l a list + -- @int n number of times to repeat + -- @treturn List *n* copies of *l* appended together + -- @usage + -- --> {1, 2, 3, 1, 2, 3, 1, 2, 3} + -- list.rep ({1, 2, 3}, 3) + rep = X ("rep (List, int)", rep), + + --- Return a sub-range of a list. + -- (The equivalent of @{string.sub} on strings; negative list indices + -- count from the end of the list.) + -- @static + -- @function sub + -- @tparam List l a list + -- @int[opt=1] from start of range + -- @int[opt=#l] to end of range + -- @treturn List new list containing elements between *from* and *to* + -- inclusive + -- @usage + -- --> {3, 4, 5} + -- list.sub ({1, 2, 3, 4, 5, 6}, 3, 5) + sub = X ("sub (List, int?, int?)", sub), + + --- Return a list with its first element removed. + -- @static + -- @function tail + -- @tparam List l a list + -- @treturn List new list with all but the first element of *l* + -- @usage + -- --> {3, {4, 5}, 6, 7} + -- list.tail {{1, 2}, 3, {4, 5}, 6, 7} + tail = X ("tail (List)", function (l) return sub (l, 2) end), +} + + + +--[[ ============= ]]-- +--[[ Deprecations. ]]-- +--[[ ============= ]]-- + +-- This entire section can be deleted in due course, with just one +-- additional small correction noted in FIXME comments in the List +-- object constructor at the end of this file. + + +local DEPRECATED = debug.DEPRECATED + + local function depair (ls) local t = {} - for v in elems (ls) do + for _, v in ipairs (ls) do t[v[1]] = v[2] end return t end ---- Turn a table into a list of pairs. --- @todo Find a better name. --- @tparam table t a table `{i1=v1, ..., in=vn}` --- @treturn List a new list containing `{{i1, v1}, ..., {in, vn}}` --- @see depair local function enpair (t) local ls = List {} for i, v in pairs (t) do @@ -139,20 +195,17 @@ local function enpair (t) end ---- Filter a list according to a predicate. --- @func p predicate function, of one argument returning a boolean --- @tparam List l a list --- @treturn List new list containing elements `e` of `l` for which --- `p (e)` is true --- @see std.list:filter -local function filter (p, l) - return List (func.filter (p, elems, l)) +local function filter (pfn, l) + local r = List {} + for _, e in ipairs (l) do + if pfn (e) then + r[#r + 1] = e + end + end + return r end ---- Flatten a list. --- @tparam List l a list --- @treturn List flattened list local function flatten (l) local r = List {} for v in base.leaves (ipairs, l) do @@ -162,53 +215,29 @@ local function flatten (l) end ---- Fold a binary function through a list left associatively. --- @func fn binary function --- @param e element to place in left-most position --- @tparam List l a list --- @return result --- @see std.list:foldl -local function foldl (fn, e, l) - return func.fold (fn, e, elems, l) -end - - ---- An iterator over the elements of a list, in reverse. --- @tparam List l a list --- @treturn function iterator function which returns precessive elements --- of the `l` --- @treturn List `l` --- @return `true` -local function relems (l) - local n = #l + 1 - return function (l) - n = n - 1 - if n > 0 then - return l[n] - end - end, - l, true +local function foldl (fn, d, t) + if t == nil then + local tail = {} + for i = 2, len (d) do tail[#tail + 1] = d[i] end + d, t = d[1], tail + end + return base.reduce (fn, d, base.ielems, t) end ---- Fold a binary function through a list right associatively. --- @func fn binary function --- @param e element to place in right-most position --- @tparam List l a list --- @return result --- @see std.list:foldr -local function foldr (fn, e, l) - return List (func.fold (function (x, y) return fn (y, x) end, - e, relems, l)) +local function foldr (fn, d, t) + if t == nil then + local u, last = {}, len (d) + for i = 1, last - 1 do u[#u + 1] = d[i] end + d, t = d[last], u + end + return base.reduce ( + function (x, y) return fn (y, x) end, d, base.ielems, base.ireverse (t)) end ---- Make an index of a list of tables on a given field --- @param f field --- @tparam List l list of tables `{t1, ..., tn}` --- @treturn List index `{t1[f]=1, ..., tn[f]=n}` local function index_key (f, l) - local r = List {} + local r = {} for i, v in ipairs (l) do local k = v[f] if k then @@ -219,12 +248,8 @@ local function index_key (f, l) end ---- Copy a list of tables, indexed on a given field --- @param f field whose value should be used as index --- @tparam List l list of tables `{i1=t1, ..., in=tn}` --- @treturn List index `{t1[f]=t1, ..., tn[f]=tn}` local function index_value (f, l) - local r = List {} + local r = {} for i, v in ipairs (l) do local k = v[f] if k then @@ -235,80 +260,34 @@ local function index_value (f, l) end ---- Map a function over a list. --- @func fn map function --- @tparam List l a list --- @treturn List new list containing `{fn (l[1]), ..., fn (l[#l])}` --- @see std.list:map local function map (fn, l) - return List (func.map (fn, elems, l)) + local r = List {} + for _, e in ipairs (l) do + local v = fn (e) + if v ~= nil then + r[#r + 1] = v + end + end + return r end ---- Map a function over a list of lists. --- @func fn map function --- @tparam List ls a list of lists --- @treturn List new list `{fn (unpack (ls[1]))), ..., fn (unpack (ls[#ls]))}` local function map_with (fn, ls) - return List (func.map (func.compose (unpack, fn), elems, ls)) + return map (function (...) return fn (unpack (...)) end, ls) end ---- Project a list of fields from a list of tables. --- @param f field to project --- @tparam List l a list --- @treturn List list of `f` fields --- @see std.list:project -local function project (f, l) - return map (function (t) return t[f] end, l) +local function project (x, l) + return map (function (t) return t[x] end, l) end ---- Repeat a list. --- @tparam List l a list --- @int n number of times to repeat --- @treturn List `n` copies of `l` appended together -local function rep (l, n) - local r = List {} - for i = 1, n do - r = concat (r, l) - end - return r -end +local function relems (l) return base.ielems (base.ireverse (l)) end ---- Reverse a list. --- @tparam List l a list --- @treturn List new list containing `{l[#l], ..., l[1]}` -local function reverse (l) - local r = List {} - for i = #l, 1, -1 do - r[#r + 1] = l[i] - end - return r -end +local function reverse (l) return List (base.ireverse (l)) end ---- Shape a list according to a list of dimensions. --- --- Dimensions are given outermost first and items from the original --- list are distributed breadth first; there may be one 0 indicating --- an indefinite number. Hence, `{0}` is a flat list, --- `{1}` is a singleton, `{2, 0}` is a list of --- two lists, and `{0, 2}` is a list of pairs. --- --- Algorithm: turn shape into all positive numbers, calculating --- the zero if necessary and making sure there is at most one; --- recursively walk the shape, adding empty tables until the bottom --- level is reached at which point add table items instead, using a --- counter to walk the flattened original list. --- --- @todo Use ileaves instead of flatten (needs a while instead of a --- for in fill function) --- @tparam table s `{d1, ..., dn}` --- @tparam List l a list --- @return reshaped list --- @see std.list:shape local function shape (s, l) l = flatten (l) -- Check the shape and calculate the size of the zero, if any @@ -326,10 +305,10 @@ local function shape (s, l) end end if zero then - s[zero] = math.ceil (#l / size) + s[zero] = math.ceil (len (l) / size) end local function fill (i, d) - if d > #s then + if d > len (s) then return l[i], i + 1 else local r = List {} @@ -345,289 +324,192 @@ local function shape (s, l) end ---- Return a sub-range of a list. --- (The equivalent of `string.sub` on strings; negative list indices --- count from the end of the list.) --- @tparam List l a list --- @int from start of range (default: 1) --- @int to end of range (default: `#l`) --- @treturn List new list containing `{l[from], ..., l[to]}` -local function sub (l, from, to) - local r = List {} - local len = #l - from = from or 1 - to = to or len - if from < 0 then - from = from + len + 1 - end - if to < 0 then - to = to + len + 1 - end - for i = from, to do - r[#r + 1] = l[i] +local function transpose (ls) + local rs, lenls, dims = List {}, len (ls), map (len, ls) + if len (dims) > 0 then + for i = 1, math.max (unpack (dims)) do + rs[i] = List {} + for j = 1, lenls do + rs[i][j] = ls[j][i] + end + end end - return r + return rs end ---- Return a list with its first element removed. --- @tparam List l a list --- @treturn List new list containing `{l[2], ..., l[#l]}` -local function tail (l) - return sub (l, 2) +local function zip_with (ls, fn) + return map_with (fn, transpose (ls)) end ---- Transpose a list of lists. --- This function in Lua is equivalent to zip and unzip in more strongly --- typed languages. --- @tparam table ls --- `{{ls<1,1>, ..., ls<1,c>}, ..., {ls<r,1>, ..., ls<r,c>}}` --- @treturn List new list containing --- `{{ls<1,1>, ..., ls<r,1>}, ..., {ls<1,c>, ..., ls<r,c>}}` -local function transpose (ls) - local rs, len = List {}, #ls - for i = 1, math.max (unpack (map (ls, function (l) return #l end))) do - rs[i] = List {} - for j = 1, len do - rs[i][j] = ls[j][i] - end - end - return rs -end +local m = { + append = M.append, + compare = M.compare, + concat = M.concat, + cons = M.cons, + rep = M.rep, + sub = M.sub, + tail = M.tail, +} ---- Zip a list of lists together with a function. --- @tparam table ls list of lists --- @tparam function f function --- @treturn List a new list containing --- `{f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N])` --- where `N = max {map (function (l) return #l end, ls)}` -local function zip_with (ls, f) - return map_with (transpose (ls), f) -end +m.depair = DEPRECATED ("38", "'std.list:depair'", depair) +m.map_with = DEPRECATED ("38", "'std.list:map_with'", + function (self, fn) return map_with (fn, self) end) +m.transpose = DEPRECATED ("38", "'std.list:transpose'", transpose) +m.zip_with = DEPRECATED ("38", "'std.list:zip_with'", zip_with) + + +M.depair = DEPRECATED ("41", "'std.list.depair'", depair) +M.enpair = DEPRECATED ("41", "'std.list.enpair'", enpair) +m.enpair = DEPRECATED ("41", "'std.list:enpair'", enpair) + +M.elems = DEPRECATED ("41", "'std.list.elems'", + "use 'std.ielems' instead", base.ielems) +m.elems = DEPRECATED ("41", "'std.list:elems'", + "use 'std.ielems' instead", base.ielems) + +M.filter = DEPRECATED ("41", "'std.list.filter'", + "use 'std.functional.filter' instead", filter) +m.filter = DEPRECATED ("41", "'std.list:filter'", + "use 'std.functional.filter' instead", + function (self, p) return filter (p, self) end) + + +M.flatten = DEPRECATED ("41", "'std.list.flatten'", + "use 'std.functional.flatten' instead", flatten) +m.flatten = DEPRECATED ("41", "'std.list:flatten'", + "use 'std.functional.flatten' instead", flatten) + + +M.foldl = DEPRECATED ("41", "'std.list.foldl'", + "use 'std.functional.foldl' instead", foldl) +m.foldl = DEPRECATED ("41", "'std.list:foldl'", + "use 'std.functional.foldl' instead", + function (self, fn, e) + if e ~= nil then return foldl (fn, e, self) end + return foldl (fn, self) + end) + +M.foldr = DEPRECATED ("41", "'std.list.foldr'", + "use 'std.functional.foldr' instead", foldr) +m.foldr = DEPRECATED ("41", "'std.list:foldr'", + "use 'std.functional.foldr' instead", + function (self, fn, e) + if e ~= nil then return foldr (fn, e, self) end + return foldr (fn, self) + end) + +M.index_key = DEPRECATED ("41", "'std.list.index_key'", + "compose 'std.functional.filter' and 'std.table.invert' instead", + index_key) +m.index_key = DEPRECATED ("41", "'std.list:index_key'", + function (self, fn) return index_key (fn, self) end) + + +M.index_value = DEPRECATED ("41", "'std.list.index_value'", + "compose 'std.functional.filter' and 'std.table.invert' instead", + index_value) +m.index_value = DEPRECATED ("41", "'std.list:index_value'", + function (self, fn) return index_value (fn, self) end) + + +M.map = DEPRECATED ("41", "'std.list.map'", + "use 'std.functional.map' instead", map) +m.map = DEPRECATED ("41", "'std.list:map'", + "use 'std.functional.map' instead", + function (self, fn) return map (fn, self) end) + + + +M.map_with = DEPRECATED ("41", "'std.list.map_with'", + "use 'std.functional.map_with' instead", map_with) + +M.project = DEPRECATED ("41", "'std.list.project'", + "use 'std.table.project' instead", project) +m.project = DEPRECATED ("41", "'std.list:project'", + "use 'std.table.project' instead", + function (self, x) return project (x, self) end) + +M.relems = DEPRECATED ("41", "'std.list.relems'", + "compose 'std.ielems' and 'std.ireverse' instead", relems) +m.relems = DEPRECATED ("41", "'std.list:relems'", relems) + +M.reverse = DEPRECATED ("41", "'std.list.reverse'", + "use 'std.ireverse' instead", reverse) +m.reverse = DEPRECATED ("41", "'std.list:reverse'", + "use 'std.ireverse' instead", reverse) + +M.shape = DEPRECATED ("41", "'std.list.shape'", + "use 'std.table.shape' instead", shape) +m.shape = DEPRECATED ("41", "'std.list:shape'", + "use 'std.table.shape' instead", + function (t, l) return shape (l, t) end) + +M.transpose = DEPRECATED ("41", "'std.list.transpose'", + "use 'std.functional.zip' instead", transpose) + +M.zip_with = DEPRECATED ("41", "'std.list.zip_with'", + "use 'std.functional.zip_with' instead", zip_with) + + + +--[[ ================== ]]-- +--[[ Type Declarations. ]]-- +--[[ ================== ]]-- + + +--- An Object derived List. +-- @object List List = Object { -- Derived object type. - _type = "List", - + _type = "List", + _functions = M, -- FIXME: remove this when DEPRECATIONS have gone + __index = m, -- FIXME: `__index = M` when DEPRECATIONS have gone ------ -- Concatenate lists. - -- new = list .. table -- @function __concat - -- @tparam List list a list - -- @tparam table table another list, hash part is ignored + -- @tparam List l a list + -- @tparam List|table m another list, or table (hash part is ignored) -- @see concat + -- @usage + -- new = alist .. {"append", "these", "elements"} __concat = concat, ------ -- Append element to list. - -- list = list + element -- @function __add - -- @tparam List list a list - -- @param element element to append + -- @tparam List l a list + -- @param e element to append -- @see append - __add = append, + -- @usage + -- list = list + "element" + __add = append, ------ -- List order operator. - -- max = list1 > list2 and list1 or list2 - -- @tparam List list1 a list - -- @tparam List list2 another list - -- @see std.list:compare + -- @function __lt + -- @tparam List l a list + -- @tparam List m another list + -- @see compare + -- @usage + -- max = list1 > list2 and list1 or list2 __lt = function (list1, list2) return compare (list1, list2) < 0 end, ------ -- List equality or order operator. - -- min = list1 <= list2 and list1 or list2 - -- @tparam List list1 a list - -- @tparam List list2 another list - -- @see std.list:compare + -- @function __le + -- @tparam List l a list + -- @tparam List m another list + -- @see compare + -- @usage + -- min = list1 <= list2 and list1 or list2 __le = function (list1, list2) return compare (list1, list2) <= 0 end, - - __index = { - ------ - -- Append an item to a list. - -- @function append - -- @param x item - -- @treturn List new list containing `{self[1], ..., self[#self], x}` - append = append, - - ------ - -- Compare two lists element-by-element, from left-to-right. - -- - -- if a_list:compare (another_list) == 0 then print "same" end - -- @function compare - -- @tparam table l a list - -- @return -1 if `self` is less than `l`, 0 if they are the same, and 1 - -- if `self` is greater than `l` - compare = compare, - - ------ - -- Concatenate arguments into a list. - -- @function concat - -- @param ... tuple of lists - -- @treturn List new list containing - -- `{self[1], ..., self[#self], l\_1[1], ..., l\_1[#l\_1], ..., l\_n[1], ..., l\_n[#l\_n]}` - concat = concat, - - ------ - -- Prepend an item to a list. - -- @function cons - -- @param x item - -- @treturn List new list containing `{x, unpack (self)}` - cons = cons, - - ------ - -- An iterator over the elements of a list. - -- @function elems - -- @treturn function iterator function which returns successive - -- elements of `self` - -- @treturn List `self` - -- @return `true` - elems = elems, - - ------ - -- Filter a list according to a predicate. - -- @function filter - -- @func p predicate function, of one argument returning a boolean - -- @treturn List new list containing elements `e` of `self` for which - -- `p (e)` is true - -- @see std.list.filter - filter = function (self, p) return filter (p, self) end, - - ------ - -- Flatten a list. - -- @function flatten - -- @treturn List flattened list - flatten = flatten, - - ------ - -- Fold a binary function through a list left associatively. - -- @function foldl - -- @func fn binary function - -- @param e element to place in left-most position - -- @return result - -- @see std.list.foldl - foldl = function (self, fn, e) return foldl (fn, e, self) end, - - ------ - -- Fold a binary function through a list right associatively. - -- @function foldr - -- @func f binary function - -- @param e element to place in right-most position - -- @return result - -- @see std.list.foldr - foldr = function (self, fn, e) return foldr (fn, e, self) end, - - ------ - -- Map a function over a list. - -- @function map - -- @func fn map function - -- @treturn List new list containing - -- `{fn (self[1]), ..., fn (self[#self])}` - -- @see std.list.map - map = function (self, fn) return map (fn, self) end, - - ------ - -- Project a list of fields from a list of tables. - -- @function project - -- @param f field to project - -- @treturn List list of `f` fields - -- @see std.list.project - project = function (self, f) return project (f, self) end, - - ------ - -- An iterator over the elements of a list, in reverse. - -- @function relems - -- @treturn function iterator function which returns precessive elements - -- of the `self` - -- @treturn List `self` - -- @return `true` - relems = relems, - - ------ - -- Repeat a list. - -- @function rep - -- @int n number of times to repeat - -- @treturn List `n` copies of `self` appended together - rep = rep, - - ------ - -- Reverse a list. - -- @function reverse - -- @treturn List new list containing `{self[#self], ..., self[1]}` - reverse = reverse, - - ----- - -- Shape a list according to a list of dimensions. - -- @function shape - -- @tparam table s `{d1, ..., dn}` - -- @return reshaped list - -- @see std.list.shape - shape = function (self, s) return shape (s, self) end, - - ------ - -- Return a sub-range of a list. - -- (The equivalent of `string.sub` on strings; negative list indices - -- count from the end of the list.) - -- @function sub - -- @int from start of range (default: 1) - -- @int to end of range (default: `#self`) - -- @treturn List new list containing `{self[from], ..., self[to]}` - sub = sub, - - ------ - -- Return a list with its first element removed. - -- @function tail - -- @treturn List new list containing `{self[2], ..., self[#self]}` - tail = tail, - - -- For backwards compatibility with pre-Object era lists, but - -- undocumented so that new code doesn't get tangled up in it. - depair = depair, - index_key = function (self, f) return index_key (f, self) end, - index_value = function (self, f) return index_value (f, self) end, - map_with = function (self, f) return map_with (f, self) end, - transpose = transpose, - zip_with = function (self, f) return zip_with (f, self) end, - }, - - - --- @export - _functions = { - append = append, - compare = compare, - concat = concat, - cons = cons, - depair = depair, - elems = elems, - enpair = enpair, - filter = filter, - flatten = flatten, - foldl = foldl, - foldr = foldr, - index_key = index_key, - index_value = index_value, - map = map, - map_with = map_with, - project = project, - relems = relems, - rep = rep, - reverse = reverse, - shape = shape, - sub = sub, - tail = tail, - transpose = transpose, - zip_with = zip_with, - }, } --- Function forms of operators -func.op[".."] = concat - - return List diff --git a/lib/std/math.lua b/lib/std/math.lua index b595bb1..b197c21 100644 --- a/lib/std/math.lua +++ b/lib/std/math.lua @@ -1,18 +1,23 @@ --[[-- - Additions to the math module. + Additions to the core math module. + + The module table returned by `std.math` also contains all of the entries from + the core math table. An hygienic way to import this module, then, is simply + to override the core `math` locally: + + local math = require "std.math" + @module std.math ]] -local M -- forward declaration -local _floor = math.floor +local base = require "std.base" + +local M ---- Extend `math.floor` to take the number of decimal places. --- @function floor --- @param n number --- @param p number of decimal places to truncate to (default: 0) --- @return `n` truncated to `p` decimal places +local _floor = math.floor + local function floor (n, p) if p and p ~= 0 then local e = 10 ^ p @@ -23,40 +28,54 @@ local function floor (n, p) end ---- Overwrite core methods with `std` enhanced versions. --- --- Replaces core `math.floor` with `std.math` version. --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table the module table local function monkey_patch (namespace) namespace = namespace or _G - assert (type (namespace) == "table", - "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") - - namespace.math.floor = floor - return M + namespace.math = base.copy (namespace.math or {}, M) + return namespace.math end ---- Round a number to a given number of decimal places --- @function round --- @param n number --- @param p number of decimal places to round to (default: 0) --- @return `n` rounded to `p` decimal places local function round (n, p) local e = 10 ^ (p or 0) return _floor (n * e + 0.5) / e end -local M = { - floor = floor, - monkey_patch = monkey_patch, - round = round, -} -for k, v in pairs (math) do - M[k] = M[k] or v +--[[ ================= ]]-- +--[[ Public Interface. ]]-- +--[[ ================= ]]-- + + +local function X (decl, fn) + return require "std.debug".argscheck ("std.math." .. decl, fn) end -return M + +M = { + --- Extend `math.floor` to take the number of decimal places. + -- @function floor + -- @number n number + -- @int[opt=0] p number of decimal places to truncate to + -- @treturn number `n` truncated to `p` decimal places + -- @usage tenths = floor (magnitude, 1) + floor = X ("floor (number, int?)", floor), + + --- Overwrite core `math` methods with `std` enhanced versions. + -- @function monkey_patch + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table the module table + -- @usage require "std.math".monkey_patch () + monkey_patch = X ("monkey_patch (table?)", monkey_patch), + + --- Round a number to a given number of decimal places + -- @function round + -- @number n number + -- @int[opt=0] p number of decimal places to round to + -- @treturn number `n` rounded to `p` decimal places + -- @usage roughly = round (exactly, 2) + round = X ("round (number, int?)", round), +} + + +return base.merge (M, math) diff --git a/lib/std/object.lua b/lib/std/object.lua index 34eef40..423507f 100644 --- a/lib/std/object.lua +++ b/lib/std/object.lua @@ -10,147 +10,185 @@ Objects are cloned by simply calling an existing object, which then serves as a prototype from which the new object is copied. - All valid objects contain a field `_init`, which determines the syntax - required to execute the cloning process: - - 1. `_init` can be a list of keys; then the unnamed `init_1` through - `init_m` values from the argument table are assigned to the - corresponding keys in `new_object`; - - new_object = proto_object { - init_1, ..., init_m; - field_1 = value_1, - ... - field_n = value_n, - } - - 2. Or it can be a function, in which the arguments passed to the - prototype during cloning are simply handed to the `_init` function: - - new_object = proto_object (arg, ...) - - Objects, then, are essentially tables of `field\_n = value\_n` pairs: - - > o = Object { - >> field_1 = "value_1", - >> method_1 = function (self) return self.field_1 end, - >> } - > = o.field_1 - value_1 - > o.field_2 = 2 - > function o:method_2 (n) return self.field_2 + n end - > = o:method_2 (2) - 4 - - Normally `new_object` automatically shares a metatable with - `proto_object`. However, field names beginning with "_" are *private*, - and moved into the object metatable during cloning. So, adding new - private fields to an object during cloning will result in a new - metatable for `new_object` that also contains a copy of all the entries - in the `proto_object` metatable. - - Note that Object methods are stored in the `\_\_index` field of their - metatable, and so cannot also use `\_\_index` to lookup references with + Note that Object methods are stored in the `__index` field of their + metatable, and so cannot also use `__index` to lookup references with square brackets. See @{std.container} objects if you want to do that. + Prototype Chain + --------------- + + table + `-> Object + @classmod std.object ]] - -- Surprise!! The real root object is Container, which has less -- functionality than Object, but that makes the heirarchy hard to -- explain, so the documentation pretends this is the root object, and -- Container is derived from it. Confused? ;-) -local Container = require "std.container" -local metamethod = (require "std.base").metamethod +local base = require "std.base" +local container = require "std.container" + +local Container = container {} +local getmetamethod, prototype = base.getmetamethod, base.prototype + --- Root object. -- -- Changing the values of these fields in a new object will change the -- corresponding behaviour. --- @table std.object --- @string[opt="Object"] _type type of Object, returned by @{prototype} --- @tfield table|function _init a table of field names, or --- initialisation function, used by @{clone} --- @tfield nil|table _functions a table of module functions not copied --- by @{std.object.__call} +-- @object Object +-- @string[opt="Object"] _type object name +-- @tfield[opt={}] table|function _init object initialisation +-- @tfield table _functions module functions omitted when cloned +-- @see __call +-- @usage +-- -- `_init` can be a list of keys; then the unnamed `init_1` through +-- -- `init_m` values from the argument table are assigned to the +-- -- corresponding keys in `new_object`. +-- local Process = Object { +-- _type = "Process", +-- _init = { "status", "out", "err" }, +-- } +-- local process = Process { +-- procs[pid].status, procs[pid].out, procs[pid].err, -- auto assigned +-- command = pipeline[pid], -- manual assignment +-- } +-- @usage +-- -- Or it can be a function, in which the arguments passed to the +-- -- prototype during cloning are simply handed to the `_init` function. +-- local Bag = Object { +-- _type = "Bag", +-- _init = function (obj, ...) +-- for e in std.elems {...} do +-- obj[#obj + 1] = e +-- end +-- return obj +-- end, +-- } +-- local bag = Bag ("function", "arguments", "sent", "to", "_init") + return Container { _type = "Object", -- No need for explicit module functions here, because calls to, e.g. -- `Object.prototype` will automatically fall back metamethods in - -- `\_\_index`. + -- `__index`. __index = { - --- Clone this Object. + --- Clone an Object. + -- + -- Objects are essentially tables of `field_n = value_n` pairs. + -- + -- Normally `new_object` automatically shares a metatable with + -- `proto_object`. However, field names beginning with "_" are *private*, + -- and moved into the object metatable during cloning. So, adding new + -- private fields to an object during cloning will result in a new + -- metatable for `new_object` that also happens to contain a copy of all + -- the entries from the `proto_object` metatable. + -- + -- While clones of @{Object} inherit all properties of their prototype, + -- it's idiomatic to always keep separate tables for the module table and + -- the root object itself: That way you can't mistakenly engage the slower + -- clone-from-module-table process unnecessarily. + -- @static -- @function clone - -- @tparam std.object obj an object - -- @param ... a list of arguments if `o._init` is a function, or a - -- single table if `o._init` is a table. - -- @treturn std.object a clone of `o` + -- @tparam Object obj an object + -- @param ... a list of arguments if *obj.\_init* is a function, or a + -- single table if *obj.\_init* is a table. + -- @treturn Object a clone of *obj* -- @see __call - clone = metamethod (Container, "__call"), - + -- @usage + -- local object = require "std.object" -- module table + -- local Object = object {} -- root object + -- local o = Object { + -- field_1 = "value_1", + -- method_1 = function (self) return self.field_1 end, + -- } + -- print (o.field_1) --> value_1 + -- o.field_2 = 2 + -- function o:method_2 (n) return self.field_2 + n end + -- print (o:method_2 (2)) --> 4 + -- os.exit (0) + clone = getmetamethod (container, "__call"), --- Type of an object, or primitive. -- -- It's conventional to organise similar objects according to a - -- string valued `_type` field, which can then be queried using this + -- string valued *\_type* field, which can then be queried using this -- function. -- - -- Stack = Object { - -- _type = "Stack", + -- Additionally, this function returns the results of @{io.type} for + -- file objects, or @{type} otherwise. -- - -- __tostring = function (self) ... end, + -- @static + -- @function prototype + -- @param x anything + -- @treturn string type of *x* + -- @usage + -- local Stack = Object { + -- _type = "Stack", -- - -- __index = { - -- push = function (self) ... end, - -- pop = function (self) ... end, - -- }, - -- } - -- stack = Stack {} + -- __tostring = function (self) ... end, -- - -- stack:prototype () --> "Stack" + -- __index = { + -- push = function (self) ... end, + -- pop = function (self) ... end, + -- }, + -- } + -- local stack = Stack {} + -- assert (stack:prototype () == getmetatable (stack)._type) -- - -- @function prototype - -- @param x anything - -- @treturn string type of `x` - prototype = Container.prototype.call, + -- local prototype = Object.prototype + -- assert (prototype (stack) == getmetatable (stack)._type) + -- + -- local h = io.open (os.tmpname (), "w") + -- assert (prototype (h) == io.type (h)) + -- + -- assert (prototype {} == type {}) + prototype = prototype, - --- Return `obj` with references to the fields of `src` merged in. + --- Return *obj* with references to the fields of *src* merged in. -- - -- More importantly, split the fields in `src` between `obj` and its - -- metatable. If any field names begin with `\_`, attach a metatable - -- to `obj` if it doesn't have one yet, and copy the "private" `\_` - -- prefixed fields there. + -- More importantly, split the fields in *src* between *obj* and its + -- metatable. If any field names begin with "_", attach a metatable + -- to *obj* by cloning the metatable from *src*, and then copy the + -- "private" `_` prefixed fields there. -- -- You might want to use this function to instantiate your derived - -- objct clones when the prototype's `_init` is a function -- when - -- `_init` is a table, the default (inherited unless you overwrite - -- it) clone method calls `mapfields` automatically. When you're - -- using a function `_init` setting, `clone` doesn't know what to + -- object clones when the *src.\_init* is a function -- when + -- *src.\_init* is a table, the default (inherited unless you overwrite + -- it) clone method calls @{mapfields} automatically. When you're + -- using a function `_init` setting, @{clone} doesn't know what to -- copy into a new object from the `_init` function's arguments... - -- so you're on your own. Except that calling `mapfields` inside + -- so you're on your own. Except that calling @{mapfields} inside -- `_init` is safer than manually splitting `src` into `obj` and - -- its metatable, because you'll pick up fixes and changes when you - -- upgrade stdlib. + -- its metatable, because you'll pick up any fixes and changes when + -- you upgrade stdlib. + -- @static -- @function mapfields -- @tparam table obj destination object -- @tparam table src fields to copy int clone - -- @tparam[opt={}] table map `{old_key=new_key, ...}` - -- @treturn table `obj` with non-private fields from `src` merged, + -- @tparam[opt={}] table map key renames as `{old_key=new_key, ...}` + -- @treturn table *obj* with non-private fields from *src* merged, -- and a metatable with private fields (if any) merged, both sets - -- of keys renamed according to `map` - mapfields = Container.mapfields.call, + -- of keys renamed according to *map* + -- @usage + -- myobject.mapfields = function (obj, src, map) + -- object.mapfields (obj, src, map) + -- ... + -- end + mapfields = container.mapfields.call, -- Backwards compatibility: - type = Container.prototype.call, + type = prototype, }, @@ -158,9 +196,20 @@ return Container { -- -- Private fields are stored in the metatable. -- @function __call - -- @param ... arguments for `\_init` - -- @treturn std.object a clone of the this object. + -- @param ... arguments for prototype's *\_init* + -- @treturn Object a clone of the this object. -- @see clone + -- @usage + -- local Object = require "std.object" {} -- not a typo! + -- new = Object {"initialisation", "elements"} + + + --- Return an in-order iterator over public object fields. + -- @function __pairs + -- @treturn function iterator function + -- @treturn Object *self* + -- @usage + -- for k, v in std.pairs (anobject) do process (k, v) end --- Return a string representation of this object. @@ -172,16 +221,7 @@ return Container { -- This function doesn't recurse explicity, but relies upon suitable -- `__tostring` metamethods in field values. -- @function __tostring - -- @treturn string stringified container representation + -- @treturn string stringified object representation -- @see tostring - - - --- Return a shallow copy of non-private object fields. - -- - -- Used by @{clone} to get the base contents of the new object. Can - -- be overridden in other objects for greater control of which fields - -- are considered non-private. - -- @function __totable - -- @treturn table a shallow copy of non-private object fields - -- @see std.table.totable + -- @usage print (anobject) } diff --git a/lib/std/operator.lua b/lib/std/operator.lua new file mode 100644 index 0000000..1f77e78 --- /dev/null +++ b/lib/std/operator.lua @@ -0,0 +1,163 @@ +--[[-- + Functional forms of Lua operators. + + @module std.operator +]] + +local base = require "std.base" + +local tostring = base.tostring + + +local M = { + --- Stringify and concatenate arguments. + -- @param a an argument + -- @param b another argument + -- @return concatenation of stringified arguments. + -- @usage + -- --> "=> 1000010010" + -- functional.foldl (concat, "=> ", {10000, 100, 10}) + concat = function (a, b) return tostring (a) .. tostring (b) end, + + --- Dereference a table. + -- @tparam table t a table + -- @param k a key to lookup in *t* + -- @return value stored at *t[k]* if any, otherwise `nil` + -- @usage + -- --> 4 + -- functional.foldl (get, {1, {{2, 3, 4}, 5}}, {2, 1, 3}) + get = function (t, k) return t and t[k] or nil end, + + --- Set a table element, honoring metamethods. + -- @tparam table t a table + -- @param k a key to lookup in *t* + -- @param v a value to set for *k* + -- @treturn table *t* + -- @usage + -- -- destructive table merge: + -- --> {"one", bar="baz", two=5} + -- functional.reduce (set, {"foo", bar="baz"}, {"one", two=5}) + set = function (t, k, v) t[k]=v; return t end, + + --- Return the sum of the arguments. + -- @param a an argument + -- @param b another argument + -- @return the sum of the *a* and *b* + -- @usage + -- --> 10110 + -- functional.foldl (sum, {10000, 100, 10}) + sum = function (a, b) return a + b end, + + --- Return the difference of the arguments. + -- @param a an argument + -- @param b another argument + -- @return the difference between *a* and *b* + -- @usage + -- --> 890 + -- functional.foldl (diff, {10000, 100, 10}) + diff = function (a, b) return a - b end, + + --- Return the product of the arguments. + -- @param a an argument + -- @param b another argument + -- @return the product of *a* and *b* + -- @usage + -- --> 10000000 + -- functional.foldl (prod, {10000, 100, 10}) + prod = function (a, b) return a * b end, + + --- Return the quotient of the arguments. + -- @param a an argument + -- @param b another argument + -- @return the quotient *a* and *b* + -- @usage + -- --> 1000 + -- functional.foldr (quot, {10000, 100, 10}) + quot = function (a, b) return a / b end, + + --- Return the modulus of the arguments. + -- @param a an argument + -- @param b another argument + -- @return the modulus of *a* and *b* + -- @usage + -- --> 3 + -- functional.foldl (mod, {65536, 100, 11}) + mod = function (a, b) return a % b end, + + --- Return the exponent of the arguments. + -- @param a an argument + -- @param b another argument + -- @return the *a* to the power of *b* + -- @usage + -- --> 4096 + -- functional.foldl (pow, {2, 3, 4}) + pow = function (a, b) return a ^ b end, + + --- Return the logical conjunction of the arguments. + -- @param a an argument + -- @param b another argument + -- @return logical *a* and *b* + -- @usage + -- --> true + -- functional.foldl (conj, {true, 1, "false"}) + conj = function (a, b) return a and b end, + + --- Return the logical disjunction of the arguments. + -- @param a an argument + -- @param b another argument + -- @return logical *a* or *b* + -- @usage + -- --> true + -- functional.foldl (disj, {true, 1, false}) + disj = function (a, b) return a or b end, + + --- Return the logical negation of the arguments. + -- @param a an argument + -- @return not *a* + -- @usage + -- --> {true, false, false, false} + -- functional.bind (functional.map, {std.ielems, neg}) {false, true, 1, 0} + neg = function (a) return not a end, + + --- Return the equality of the arguments. + -- @param a an argument + -- @param b another argument + -- @return `true` if *a* is *b*, otherwise `false` + eq = function (a, b) return a == b end, + + --- Return the inequality of the arguments. + -- @param a an argument + -- @param b another argument + -- @return `false` if *a* is *b*, otherwise `true` + -- @usage + -- --> true + -- local f = require "std.functional" + -- table.empty (f.filter (f.bind (neq, {6}), std.ielems, {6, 6, 6}) + neq = function (a, b) return a ~= b end, + + --- Return whether the arguments are in ascending order. + -- @param a an argument + -- @param b another argument + -- @return `true` if *a* is less then *b*, otherwise `false` + lt = function (a, b) return a < b end, + + --- Return whether the arguments are not in descending order. + -- @param a an argument + -- @param b another argument + -- @return `true` if *a* is not greater then *b*, otherwise `false` + lte = function (a, b) return a <= b end, + + --- Return whether the arguments are in descending order. + -- @param a an argument + -- @param b another argument + -- @return `true` if *a* is greater then *b*, otherwise `false` + gt = function (a, b) return a > b end, + + --- Return whether the arguments are not in ascending order. + -- @param a an argument + -- @param b another argument + -- @return `true` if *a* is not greater then *b*, otherwise `false` + gte = function (a, b) return a >= b end, +} + +return M diff --git a/lib/std/optparse.lua b/lib/std/optparse.lua index 62610b0..29ebe93 100644 --- a/lib/std/optparse.lua +++ b/lib/std/optparse.lua @@ -1,105 +1,29 @@ --[=[-- Parse and process command line options. - local OptionParser = require "std.optparse" + Prototype Chain + --------------- - local parser = OptionParser [[ - any text VERSION - Additional lines of text to show when the --version - option is passed. - - Several lines or paragraphs are permitted. - - Usage: PROGNAME - - Banner text. - - Optional long description text to show when the --help - option is passed. - - Several lines or paragraphs of long description are permitted. - - Options: - - -b a short option with no long option - --long a long option with no short option - --another-long a long option with internal hypen - -v, --verbose a combined short and long option - -n, --dryrun, --dry-run several spellings of the same option - -u, --name=USER require an argument - -o, --output=[FILE] accept an optional argument - --version display version information, then exit - --help display this help, then exit - - Footer text. Several lines or paragraphs are permitted. - - Please report bugs at bug-list@yourhost.com - ]] - - _G.arg, _G.opts = parser:parse (_G.arg) - - Most often, everything else is handled automatically. After calling - `parser:parse` as shown above, `_G.arg` will contain unparsed arguments, - usually filenames or similar, and `_G.opts` will be a table of parsed - option values. The keys to the table are the long-options with leading - hyphens stripped, and non-word characters turned to `_`. For example - if `--another-long` had been found in `_G.arg` then `_G.opts` would - have a key named `another_long`. If there is no long option name, then - the short option is used, e.g. `_G.opts.b` will be set. The values - saved in those keys are controlled by the option handler, usually just - `true` or the option argument string as appropriate. - - On those occasions where more complex processing is required, handlers - can be replaced or added using parser:@{on}. A good option to always - add, is to make `--` signal the end of processed options, so that any - options following `--` on the command line, even if they begin with a - hyphen and look like options otherwise, are not processed but instead - left in the modified `_G.arg` returned by `parser:parse`: - - parser:on ('--', parser.finished) - - See the documentation for @{std.optparse:on} for more details of how to - use this powerful method. - - When writing your own handlers for @{std.optparse:on}, you only need - to deal with normalised arguments, because combined short arguments - (`-xyz`), equals separators to long options (`--long=ARG`) are fully - expanded before any handler is called. - - Note that @{std.io.die} and @{std.io.warn} will only prefix messages - with `parser.program` if the parser options are assigned back to - `_G.opts` as shown in the example above. + table + `-> Object + `-> OptionParser @classmod std.optparse ]=] -local OptionParser -- forward declaration +local base = require "std.base" +local Object = require "std.object" {} ------- --- Customized parser for your options. --- --- This table is returned by @{OptionParser}, and most importantly has --- the @{parse} method you call to fill the `opts` table according to --- what command-line options were passed to your program. --- @table parser --- @string program the first word following `Usage:` in @{OptionParser} --- spec string --- @string version the last white-space delimited word on the first line --- of text in the spec string --- @string versiontext everything preceding `Usage:` in the spec string, --- and which will be displayed by the @{version} @{on_handler} --- @string helptext everything including and following `Usage:` in the --- spec string and which will be displayed by the @{help} --- @{on_handler} --- @func parse see @{parse} --- @func on see @{on} +local ipairs, pairs = base.ipairs, base.pairs +local insert, last, len = base.insert, base.last, base.len ---[[ ----------------- ]]-- + +--[[ ================= ]]-- --[[ Helper Functions. ]]-- ---[[ ----------------- ]]-- +--[[ ================= ]]-- local optional, required @@ -115,7 +39,7 @@ local optional, required local function normalise (self, arglist) local normal = {} local i = 0 - while i < #arglist do + while i < len (arglist) do i = i + 1 local opt = arglist[i] @@ -127,8 +51,8 @@ local function normalise (self, arglist) -- Only split recognised long options. if self[optname] then - normal[#normal + 1] = optname - normal[#normal + 1] = opt:sub (x + 1) + insert (normal, optname) + insert (normal, opt:sub (x + 1)) else x = nil end @@ -136,7 +60,7 @@ local function normalise (self, arglist) if x == nil then -- No '=', or substring before '=' is not a known option name. - normal[#normal + 1] = opt + insert (normal, opt) end elseif opt:sub (1, 1) == "-" and string.len (opt) > 2 then @@ -168,9 +92,9 @@ local function normalise (self, arglist) until opt == nil -- Append split options to normalised list - for _, v in ipairs (split) do normal[#normal + 1] = v end + for _, v in ipairs (split) do insert (normal, v) end else - normal[#normal + 1] = opt + insert (normal, opt) end end @@ -189,7 +113,7 @@ local function set (self, opt, value) local opts = self.opts[key] if type (opts) == "table" then - opts[#opts + 1] = value + insert (opts, value) elseif opts ~= nil then self.opts[key] = { opts, value } else @@ -218,12 +142,14 @@ end -- command-line option. -- @static -- @tparam table arglist list of arguments --- @int i index of last processed element of `arglist` +-- @int i index of last processed element of *arglist* -- @param[opt=true] value either a function to process the option -- argument, or a default value if encountered without an optarg --- @treturn int index of next element of `arglist` to process +-- @treturn int index of next element of *arglist* to process +-- @usage +-- parser:on ("--enable-nls", parser.option, parser.boolean) function optional (self, arglist, i, value) - if i + 1 <= #arglist and arglist[i + 1]:sub (1, 1) ~= "-" then + if i + 1 <= len (arglist) and arglist[i + 1]:sub (1, 1) ~= "-" then return self:required (arglist, i, value) end @@ -262,13 +188,15 @@ end -- {1=(foo bar),2=(foo baz)} -- @static -- @tparam table arglist list of arguments --- @int i index of last processed element of `arglist` +-- @int i index of last processed element of *arglist* -- @param[opt] value either a function to process the option argument, -- or a forced value to replace the user's option argument. --- @treturn int index of next element of `arglist` to process +-- @treturn int index of next element of *arglist* to process +-- @usage +-- parser:on ({"-o", "--output"}, parser.required) function required (self, arglist, i, value) local opt = arglist[i] - if i + 1 > #arglist then + if i + 1 > len (arglist) then self:opterr ("option '" .. opt .. "' requires an argument") return i + 1 end @@ -298,11 +226,13 @@ end -- @tparam table arglist list of arguments -- @int i index of last processed element of `arglist` -- @treturn int index of next element of `arglist` to process +-- @usage +-- parser:on ("--", parser.finished) local function finished (self, arglist, i) - for opt = i + 1, #arglist do - self.unrecognised[#self.unrecognised + 1] = arglist[opt] + for opt = i + 1, len (arglist) do + insert (self.unrecognised, arglist[opt]) end - return 1 + #arglist + return 1 + len (arglist) end @@ -321,10 +251,12 @@ end -- times on the command-line. -- @static -- @tparam table arglist list of arguments --- @int i index of last processed element of `arglist` +-- @int i index of last processed element of *arglist* -- @param[opt] value either a function to process the option argument, -- or a value to store when this flag is encountered --- @treturn int index of next element of `arglist` to process +-- @treturn int index of next element of *arglist* to process +-- @usage +-- parser:on ({"--long-opt", "-x"}, parser.flag) local function flag (self, arglist, i, value) local opt = arglist[i] if type (value) == "function" then @@ -344,6 +276,8 @@ end -- `--help` in the specification, e.g. `-h, -?, --help`. -- @static -- @function help +-- @usage +-- parser:on ("-?", parser.version) local function help (self) print (self.helptext) os.exit (0) @@ -356,6 +290,8 @@ end -- `--version` in the specification, e.g. `-V, --version`. -- @static -- @function version +-- @usage +-- parser:on ("-V", parser.version) local function version (self) print (self.versiontext) os.exit (0) @@ -386,16 +322,18 @@ local boolvals = { } ---- Return a Lua boolean equivalent of various `optarg` strings. --- Report an option parse error if `optarg` is not recognised. +--- Return a Lua boolean equivalent of various *optarg* strings. +-- Report an option parse error if *optarg* is not recognised. -- -- Pass this as the `value` function to @{on} when you want various --- *truthy* or *falsey* option arguments to be coerced to a Lua `true` +-- "truthy" or "falsey" option arguments to be coerced to a Lua `true` -- or `false` respectively in the options table. -- @static -- @string opt option name -- @string[opt="1"] optarg option argument, must be a key in @{boolvals} -- @treturn bool `true` or `false` +-- @usage +-- parser:on ("--enable-nls", parser.optional, parser.boolean) local function boolean (self, opt, optarg) if optarg == nil then optarg = "1" end -- default to truthy local b = boolvals[tostring (optarg):lower ()] @@ -406,7 +344,7 @@ local function boolean (self, opt, optarg) end ---- Report an option parse error unless `optarg` names an +--- Report an option parse error unless *optarg* names an -- existing file. -- -- Pass this as the `value` function to @{on} when you want to accept @@ -415,7 +353,9 @@ end -- @static -- @string opt option name -- @string optarg option argument, must be an existing file --- @treturn `optarg` +-- @treturn string *optarg* +-- @usage +-- parser:on ("--config-file", parser.required, parser.file) local function file (self, opt, optarg) local h, errmsg = io.open (optarg, "r") if h == nil then @@ -435,7 +375,7 @@ end --- Report an option parse error, then exit with status 2. -- -- Use this in your custom option handlers for consistency with the --- error output from built-in `optparse` error messages. +-- error output from built-in @{std.optparse} error messages. -- @static -- @string msg error message local function opterr (self, msg) @@ -452,9 +392,9 @@ end -- Function signature of an option handler for @{on}. -- @function on_handler -- @tparam table arglist list of arguments --- @int i index of last processed element of `arglist` +-- @int i index of last processed element of *arglist* -- @param[opt=nil] value additional `value` registered with @{on} --- @treturn int index of next element of `arglist` to process +-- @treturn int index of next element of *arglist* to process --- Add an option handler. @@ -466,20 +406,23 @@ end -- calling this function will replace the automatically assigned handler -- with your own. -- --- parser:on ("--", parser.finished) --- parser:on ("-V", parser.version) --- parser:on ("--config-file", parser.required, parser.file) --- parser:on ("--enable-nls", parser.optional, parser.boolean) +-- When writing your own handlers for @{std.optparse:on}, you only need +-- to deal with normalised arguments, because combined short arguments +-- (`-xyz`), equals separators to long options (`--long=ARG`) are fully +-- expanded before any handler is called. -- @function on -- @tparam[string|table] opts name of the option, or list of option names --- @tparam on_handler handler function to call when any of `opts` is +-- @tparam on_handler handler function to call when any of *opts* is -- encountered -- @param value additional value passed to @{on_handler} +-- @usage +-- -- Don't process any arguments after `--` +-- parser:on ('--', parser.finished) local function on (self, opts, handler, value) if type (opts) == "string" then opts = { opts } end handler = handler or flag -- unspecified options behave as flags - normal = {} + local normal = {} for _, optspec in ipairs (opts) do optspec:gsub ("(%S+)", function (opt) @@ -495,16 +438,16 @@ local function on (self, opts, handler, value) if opt:match ("^%-[^%-]+") ~= nil then -- '-xyz' => '-x -y -z' for i = 2, string.len (opt) do - normal[#normal + 1] = "-" .. opt:sub (i, i) + insert (normal, "-" .. opt:sub (i, i)) end else - normal[#normal + 1] = opt + insert (normal, opt) end end) end -- strip leading '-', and convert non-alphanums to '_' - key = normal[#normal]:match ("^%-*(.*)$"):gsub ("%W", "_") + local key = last (normal):match ("^%-*(.*)$"):gsub ("%W", "_") for _, opt in ipairs (normal) do self[opt] = { key = key, handler = handler, value = value } @@ -545,10 +488,10 @@ end -- @table opts ---- Parse `arglist`. +--- Parse an argument list. -- @tparam table arglist list of arguments -- @tparam[opt] table defaults table of default option values --- @treturn table a list of unrecognised `arglist` elements +-- @treturn table a list of unrecognised *arglist* elements -- @treturn opts parsing results local function parse (self, arglist, defaults) self.unrecognised, self.opts = {}, {} @@ -556,16 +499,16 @@ local function parse (self, arglist, defaults) arglist = normalise (self, arglist) local i = 1 - while i > 0 and i <= #arglist do + while i > 0 and i <= len (arglist) do local opt = arglist[i] if self[opt] == nil then - self.unrecognised[#self.unrecognised + 1] = opt + insert (self.unrecognised, opt) i = i + 1 -- Following non-'-' prefixed argument is an optarg. - if i <= #arglist and arglist[i]:match "^[^%-]" then - self.unrecognised[#self.unrecognised + 1] = arglist[i] + if i <= len (arglist) and arglist[i]:match "^[^%-]" then + insert (self.unrecognised, arglist[i]) i = i + 1 end @@ -588,24 +531,6 @@ local function parse (self, arglist, defaults) end ---- @export -local methods = { - boolean = boolean, - file = file, - finished = finished, - flag = flag, - help = help, - optional = optional, - required = required, - version = version, - - on = on, - opterr = opterr, - parse = parse, -} - - - --- Take care not to register duplicate handlers. -- @param current current handler value -- @param new new handler value @@ -616,16 +541,8 @@ local function set_handler (current, new) end ---- Instantiate a new parser. --- Read the documented options from `spec` and return a new parser that --- can be passed to @{parse} for parsing those options from an argument --- list. Options are recognised as lines that begin with at least two --- spaces, followed by a hyphen. --- @static --- @string spec option parsing specification --- @treturn parser a parser for options described by `spec` -function OptionParser (spec) - local parser = setmetatable ({ opts = {} }, { __index = methods }) +local function _init (_, spec) + local parser = {} parser.versiontext, parser.version, parser.helptext, parser.program = spec:match ("^([^\n]-(%S+)\n.-)%s*([Uu]sage: (%S+).-)%s*$") @@ -639,7 +556,7 @@ function OptionParser (spec) -- by a '-'. local specs = {} parser.helptext:gsub ("\n %s*(%-[^\n]+)", - function (spec) specs[#specs + 1] = spec end) + function (spec) insert (specs, spec) end) -- Register option handlers according to the help text. for _, spec in ipairs (specs) do @@ -675,7 +592,7 @@ function OptionParser (spec) local _, c = spec:gsub ("^%-([-%w]),?%s+(.*)$", function (opt, rest) if opt == "-" then opt = "--" end - options[#options + 1] = opt + insert (options, opt) spec = rest end) @@ -685,23 +602,127 @@ function OptionParser (spec) -- Consume long option. spec:gsub ("^%-%-([%-%w]+),?%s+(.*)$", function (opt, rest) - options[#options + 1] = opt + insert (options, opt) spec = rest end) end end -- Unless specified otherwise, treat each option as a flag. - parser:on (options, handler or flag) + on (parser, options, handler or flag) end return parser end --- Support calling the returned table: -return setmetatable (methods, { - __call = function (_, ...) - return OptionParser (...) - end, -}) +--- Signature for initialising a custom OptionParser. +-- +-- Read the documented options from *spec* and return custom parser that +-- can be used for parsing the options described in *spec* from a run-time +-- argument list. Options in *spec* are recognised as lines that begin +-- with at least two spaces, followed by a hyphen. +-- @static +-- @function OptionParser_Init +-- @string spec option parsing specification +-- @treturn OptionParser a parser for options described by *spec* +-- @usage +-- customparser = std.optparse (optparse_spec) + + +--- OptionParser prototype object. +-- +-- Most often, after instantiating an @{OptionParser}, everything else +-- is handled automatically. +-- +-- Then, calling `parser:parse` as shown below saves unparsed arguments +-- into `_G.arg` (usually filenames or similar), and `_G.opts` will be a +-- table of successfully parsed option values. The keys into this table +-- are the long-options with leading hyphens stripped, and non-word +-- characters turned to `_`. For example if `--another-long` had been +-- found in the initial `_G.arg`, then `_G.opts` will have a key named +-- `another_long`, with an appropriate value. If there is no long +-- option name, then the short option is used, i.e. `_G.opts.b` will be +-- set. +-- +-- The values saved against those keys are controlled by the option +-- handler, usually just `true` or the option argument string as +-- appropriate. +-- @object OptionParser +-- @tparam OptionParser_Init _init initialisation function +-- @string program the first word following "Usage:" from *spec* +-- @string version the last white-space delimited word on the first line +-- of text from *spec* +-- @string versiontext everything preceding "Usage:" from *spec*, and +-- which will be displayed by the @{version} @{on_handler} +-- @string helptext everything including and following "Usage:" from +-- *spec* string and which will be displayed by the @{help} +-- @{on_handler} +-- @usage +-- local std = require "std" +-- +-- local optparser = std.optparse [[ +-- any text VERSION +-- Additional lines of text to show when the --version +-- option is passed. +-- +-- Several lines or paragraphs are permitted. +-- +-- Usage: PROGNAME +-- +-- Banner text. +-- +-- Optional long description text to show when the --help +-- option is passed. +-- +-- Several lines or paragraphs of long description are permitted. +-- +-- Options: +-- +-- -b a short option with no long option +-- --long a long option with no short option +-- --another-long a long option with internal hypen +-- -v, --verbose a combined short and long option +-- -n, --dryrun, --dry-run several spellings of the same option +-- -u, --name=USER require an argument +-- -o, --output=[FILE] accept an optional argument +-- --version display version information, then exit +-- --help display this help, then exit +-- +-- Footer text. Several lines or paragraphs are permitted. +-- +-- Please report bugs at bug-list@yourhost.com +-- ]] +-- +-- -- Note that @{std.io.die} and @{std.io.warn} will only prefix messages +-- -- with `parser.program` if the parser options are assigned back to +-- -- `_G.opts`: +-- _G.arg, _G.opts = optparser:parse (_G.arg) +return Object { + _type = "OptionParser", + + _init = _init, + + -- Prototype initial values. + opts = {}, + helptext = "", + program = "", + versiontext = "", + version = 0, + + --- @export + __index = { + boolean = boolean, + file = file, + finished = finished, + flag = flag, + help = help, + optional = optional, + required = required, + version = version, + + on = on, + opterr = opterr, + parse = parse, + }, +} diff --git a/lib/std/package.lua b/lib/std/package.lua index 4034aa8..0c13a64 100644 --- a/lib/std/package.lua +++ b/lib/std/package.lua @@ -1,33 +1,54 @@ --[[-- - Additions to the package module. + Additions to the core package module. + + The module table returned by `std.package` also contains all of the entries + from the core `package` table. An hygienic way to import this module, then, is + simply to override core `package` locally: + + local package = require "std.package" + @module std.package ]] -local M -- forward declaration +local base = require "std.base" +local debug = require "std.debug" + +local catfile, escape_pattern, invert = + base.catfile, base.escape_pattern, base.invert +local ipairs, pairs, split = base.ipairs, base.pairs, base.split + +local M + -local string = require "std.string" +--- Make named constants for `package.config` +-- (undocumented in 5.1; see luaconf.h for C equivalents). +-- @table package +-- @string dirsep directory separator +-- @string pathsep path separator +-- @string path_mark string that marks substitution points in a path template +-- @string execdir (Windows only) replaced by the executable's directory in a path +-- @string igmark Mark to ignore all before it when building `luaopen_` function name. +local dirsep, pathsep, path_mark, execdir, igmark = + string.match (package.config, "^([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)") + -local split, escape_pattern = string.split, string.escape_pattern +local function pathsub (path) + return path:gsub ("%%?.", function (capture) + if capture == "?" then + return path_mark + elseif capture == "/" then + return dirsep + else + return capture:gsub ("^%%", "", 1) + end + end) +end ---- Look for a path segment match of `patt` in `pathstrings`. --- @string pathstrings `pathsep` delimited path elements --- @string patt a Lua pattern to search for in `pathstrings` --- @int[opt=1] init element (not byte index!) to start search at. --- Negative numbers begin counting backwards from the last element --- @bool[opt=false] plain unless false, treat `patt` as a plain --- string, not a pattern. Note that if `plain` is given, then `init` --- must be given as well. --- @return the matching element number (not byte index!) and full text --- of the matching element, if any; otherwise nil local function find (pathstrings, patt, init, plain) - assert (type (pathstrings) == "string", - "bad argument #1 to find (string expected, got " .. type (pathstrings) .. ")") - assert (type (patt) == "string", - "bad argument #2 to find (string expected, got " .. type (patt) .. ")") - local paths = split (pathstrings, M.pathsep) + local paths = split (pathstrings, pathsep) if plain then patt = escape_pattern (patt) end init = init or 1 if init < 0 then init = #paths - init end @@ -37,45 +58,14 @@ local function find (pathstrings, patt, init, plain) end -local case = require "std.functional".case - ---- Substitute special characters in a path string. --- Characters prefixed with `%` have the `%` stripped, but are not --- subject to further substitution. --- @string path a path element with explicit `/` and `?` as necessary --- @treturn string `path` with `dirsep` and `path_mark` substituted --- for `/` and `?` -local function pathsub (path) - return path:gsub ("%%?.", function (capture) - return case (capture, { - ["?"] = function () return M.path_mark end, - ["/"] = function () return M.dirsep end, - function (s) return s:gsub ("^%%", "", 1) end, - }) - end) -end - - -local catfile = require "std.io".catfile -local invert = require "std.table".invert - ---- Normalize a path list. --- Removing redundant `.` and `..` directories, and keep only the first --- instance of duplicate elements. Each argument can contain any number --- of `pathsep` delimited elements; wherein characters are subject to --- `/` and `?` normalization, converting `/` to `dirsep` and `?` to --- `path_mark` (unless immediately preceded by a `%` character). --- @param ... path elements --- @treturn string a single normalized `pathsep` delimited paths string local function normalize (...) - assert (select ("#", ...) > 0, "wrong number of arguments to 'normalize'") - local i, paths, pathstrings = 1, {}, table.concat ({...}, M.pathsep) - for _, path in ipairs (split (pathstrings, M.pathsep)) do + local i, paths, pathstrings = 1, {}, table.concat ({...}, pathsep) + for _, path in ipairs (split (pathstrings, pathsep)) do path = pathsub (path): gsub (catfile ("^[^", "]"), catfile (".", "%0")): - gsub (catfile ("", "%.", ""), M.dirsep): + gsub (catfile ("", "%.", ""), dirsep): gsub (catfile ("", "%.$"), ""): - gsub (catfile ("", "[^", "]+", "%.%.", ""), M.dirsep): + gsub (catfile ("", "[^", "]+", "%.%.", ""), dirsep): gsub (catfile ("", "[^", "]+", "%.%.$"), ""): gsub (catfile ("%.", "%..", ""), catfile ("..", "")): gsub (catfile ("", "$"), "") @@ -86,89 +76,107 @@ local function normalize (...) paths[path], i = i, i + 1 end end - return table.concat (invert (paths), M.pathsep) + return table.concat (invert (paths), pathsep) end ------- --- Insert a new element into a `package.path` like string of paths. --- @function insert --- @string pathstrings a `package.path` like string --- @int[opt=n+1] pos element index at which to insert `value`, where `n` is --- the number of elements prior to insertion --- @string value new path element to insert --- @treturn string a new string with the new element inserted - -local unpack = unpack or table.unpack +local unpack = table.unpack or unpack local function insert (pathstrings, ...) - assert (type (pathstrings) == "string", - "bad argument #1 to insert (string expected, got " .. type (pathstrings) .. ")") - local paths = split (pathstrings, M.pathsep) + local paths = split (pathstrings, pathsep) table.insert (paths, ...) return normalize (unpack (paths)) end ------- --- Function signature of a callback for @{mappath}. --- @function mappath_callback --- @string element an element from a `pathsep` delimited string of --- paths --- @param ... additional arguments propagated from @{mappath} --- @return non-nil to break, otherwise continue with the next element - - ---- Call a function with each element of a path string. --- @string pathstrings a `package.path` like string --- @tparam mappath_callback callback function to call for each element --- @param ... additional arguments passed to `callback` --- @return nil, or first non-nil returned by `callback` local function mappath (pathstrings, callback, ...) - assert (type (pathstrings) == "string", - "bad argument #1 to mappath (string expected, got " .. type (pathstrings) .. ")") - assert (type (callback) == "function", - "bad argument #2 to mappath (function expected, got " .. type (pathstrings) .. ")") - for _, path in ipairs (split (pathstrings, M.pathsep)) do + for _, path in ipairs (split (pathstrings, pathsep)) do local r = callback (path, ...) if r ~= nil then return r end end end ---- Remove any element from a `package.path` like string of paths. --- @string pathstrings a `package.path` like string --- @int[opt=n] pos element index from which to remove an item, where `n` --- is the number of elements prior to removal --- @treturn string a new string with given element removed local function remove (pathstrings, pos) - assert (type (pathstrings) == "string", - "bad argument #1 to remove (string expected, got " .. type (pathstrings) .. ")") - local paths = split (pathstrings, M.pathsep) + local paths = split (pathstrings, pathsep) table.remove (paths, pos) - return table.concat (paths, M.pathsep) + return table.concat (paths, pathsep) end ---- @export + +--[[ ================= ]]-- +--[[ Public Interface. ]]-- +--[[ ================= ]]-- + + +local function X (decl, fn) + return debug.argscheck ("std.package." .. decl, fn) +end + M = { - find = find, - insert = insert, - mappath = mappath, - normalize = normalize, - remove = remove, + --- Look for a path segment match of *patt* in *pathstrings*. + -- @function find + -- @string pathstrings `pathsep` delimited path elements + -- @string patt a Lua pattern to search for in *pathstrings* + -- @int[opt=1] init element (not byte index!) to start search at. + -- Negative numbers begin counting backwards from the last element + -- @bool[opt=false] plain unless false, treat *patt* as a plain + -- string, not a pattern. Note that if *plain* is given, then *init* + -- must be given as well. + -- @return the matching element number (not byte index!) and full text + -- of the matching element, if any; otherwise nil + -- @usage i, s = find (package.path, "^[^" .. package.dirsep .. "/]") + find = X ("find (string, string, int?, boolean|:plain?)", find), + + --- Insert a new element into a `package.path` like string of paths. + -- @function insert + -- @string pathstrings a `package.path` like string + -- @int[opt=n+1] pos element index at which to insert *value*, where `n` is + -- the number of elements prior to insertion + -- @string value new path element to insert + -- @treturn string a new string with the new element inserted + -- @usage + -- package.path = insert (package.path, 1, install_dir .. "/?.lua") + insert = X ("insert (string, [int], string)", insert), + + --- Call a function with each element of a path string. + -- @function mappath + -- @string pathstrings a `package.path` like string + -- @tparam mappathcb callback function to call for each element + -- @param ... additional arguments passed to *callback* + -- @return nil, or first non-nil returned by *callback* + -- @usage mappath (package.path, searcherfn, transformfn) + mappath = X ("mappath (string, function, any?*)", mappath), + + --- Normalize a path list. + -- Removing redundant `.` and `..` directories, and keep only the first + -- instance of duplicate elements. Each argument can contain any number + -- of `pathsep` delimited elements; wherein characters are subject to + -- `/` and `?` normalization, converting `/` to `dirsep` and `?` to + -- `path_mark` (unless immediately preceded by a `%` character). + -- @function normalize + -- @param ... path elements + -- @treturn string a single normalized `pathsep` delimited paths string + -- @usage package.path = normalize (user_paths, sys_paths, package.path) + normalize = X ("normalize (string*)", normalize), + + --- Remove any element from a `package.path` like string of paths. + -- @function remove + -- @string pathstrings a `package.path` like string + -- @int[opt=n] pos element index from which to remove an item, where `n` + -- is the number of elements prior to removal + -- @treturn string a new string with given element removed + -- @usage package.path = remove (package.path) + remove = X ("remove (string, int?)", remove), } ---- Make named constants for `package.config` --- (undocumented in 5.1; see luaconf.h for C equivalents). --- @table package --- @field dirsep directory separator --- @field pathsep path separator --- @field path_mark string that marks substitution points in a path template --- @field execdir (Windows only) replaced by the executable's directory in a path --- @field igmark Mark to ignore all before it when building `luaopen_` function name. -M.dirsep, M.pathsep, M.path_mark, M.execdir, M.igmark = - string.match (package.config, "^([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)") + +M.dirsep = dirsep +M.execdir = execdir +M.igmark = igmark +M.path_mark = path_mark +M.pathsep = pathsep for k, v in pairs (package) do @@ -176,3 +184,14 @@ for k, v in pairs (package) do end return M + + +--- Types +-- @section Types + +--- Function signature of a callback for @{mappath}. +-- @function mappathcb +-- @string element an element from a `pathsep` delimited string of +-- paths +-- @param ... additional arguments propagated from @{mappath} +-- @return non-nil to break, otherwise continue with the next element diff --git a/lib/std/set.lua b/lib/std/set.lua index e7e6802..580f3bb 100644 --- a/lib/std/set.lua +++ b/lib/std/set.lua @@ -1,147 +1,106 @@ --[[-- - Set container. - - Derived from @{std.container}, and inherits Container's metamethods. + Set container prototype. Note that Functions listed below are only available from the Set prototype returned by requiring this module, because Container objects cannot have object methods. + Prototype Chain + --------------- + + table + `-> Object + `-> Container + `-> Set + @classmod std.set @see std.container ]] local base = require "std.base" -local Container = require "std.container" -local prototype = (require "std.object").prototype + +local Container = require "std.container" {} + +local ielems, pairs, prototype = base.ielems, base.pairs, base.prototype local Set -- forward declaration --- Primitive methods (know about representation) + + +--[[ ==================== ]]-- +--[[ Primitive Functions. ]]-- +--[[ ==================== ]]-- + + +-- These functions know about internal implementatation. -- The representation is a table whose tags are the elements, and -- whose values are true. ---- Say whether an element is in a set. --- @tparam set set a set --- @param e element --- @return `true` if `e` is in `set`, otherwise `false` --- otherwise -local function member (set, e) - return rawget (set, e) == true -end +local elems = base.pairs ---- Insert an element into a set. --- @tparam set set a set --- @param e element --- @return the modified set local function insert (set, e) - rawset (set, e, true) - return set + return rawset (set, e, true) end ---- Delete an element from a set. --- @tparam set set a set --- @param e element --- @return the modified set -local function delete (set, e) - rawset (set, e, nil) - return set +local function member (set, e) + return rawget (set, e) == true end ---- Iterator for sets. --- @tparam set set a set --- @todo Make the iterator return only the key -local function elems (set) - return pairs (set) -end +--[[ ===================== ]]-- +--[[ High Level Functions. ]]-- +--[[ ===================== ]]-- + + +-- These functions are independent of the internal implementation. --- High level methods (representation-independent) local difference, symmetric_difference, intersection, union, subset, proper_subset, equal ---- Find the difference of two sets. --- @tparam set set1 a set --- @tparam table|set set2 another set, or table --- @return `set1` with elements of s removed function difference (set1, set2) - if prototype (set2) == "table" then - set2 = Set (set2) - end - local t = Set {} + local r = Set {} for e in elems (set1) do if not member (set2, e) then - insert (t, e) + insert (r, e) end end - return t + return r end ---- Find the symmetric difference of two sets. --- @tparam set set1 a set --- @tparam table|set set2 another set, or table --- @return elements of `set1` and `set2` that are in `set1` or `set2` but not both function symmetric_difference (set1, set2) - if prototype (set2) == "table" then - set2 = Set (set2) - end return difference (union (set1, set2), intersection (set2, set1)) end ---- Find the intersection of two sets. --- @tparam set set1 a set --- @tparam table|set set2 another set, or table --- @return set intersection of `set1` and `set2` function intersection (set1, set2) - if prototype (set2) == "table" then - set2 = Set (set2) - end - local t = Set {} + local r = Set {} for e in elems (set1) do if member (set2, e) then - insert (t, e) + insert (r, e) end end - return t + return r end ---- Find the union of two sets. --- @tparam set set1 a set --- @tparam table|set set2 another set, or table --- @return set union of `set1` and `set2` function union (set1, set2) - if prototype (set2) == "table" then - set2 = Set (set2) - end - local t = Set {} - for e in elems (set1) do - insert (t, e) - end + local r = set1 {} for e in elems (set2) do - insert (t, e) + insert (r, e) end - return t + return r end ---- Find whether one set is a subset of another. --- @tparam set set1 a set --- @tparam table|set set2 another set, or table --- @return `true` if `set1` is a subset of `set2`, `false` otherwise function subset (set1, set2) - if prototype (set2) == "table" then - set2 = Set (set2) - end for e in elems (set1) do if not member (set2, e) then return false @@ -151,138 +110,254 @@ function subset (set1, set2) end ---- Find whether one set is a proper subset of another. --- @tparam set set1 a set --- @tparam table|set set2 another set, or table --- @return `true` if `set1` is a proper subset of `set2`, `false` otherwise function proper_subset (set1, set2) - if prototype (set2) == "table" then - t = Set (set2) - end return subset (set1, set2) and not subset (set2, set1) end ---- Find whether two sets are equal. --- @tparam set set1 a set --- @tparam table|set set2 another set, or table --- @return `true` if `set1` and `set2` are equal, `false` otherwise function equal (set1, set2) return subset (set1, set2) and subset (set2, set1) end + +--[[ =========== ]]-- +--[[ Set Object. ]]-- +--[[ =========== ]]-- + + +local function X (decl, fn) + return require "std.debug".argscheck ("std.set." .. decl, fn) +end + + --- Set prototype object. --- @table std.set --- @string[opt="Set"] _type type of Set, returned by --- @{std.object.prototype} --- @tfield table|function _init a table of field names, or --- initialisation function, see @{std.object.__call} --- @tfield nil|table _functions a table of module functions not copied --- by @{std.object.__call} +-- +-- Set also inherits all the fields and methods from +-- @{std.container.Container}. +-- @object Set +-- @string[opt="Set"] _type object name +-- @see std.container +-- @see std.object.__call +-- @usage +-- local std = require "std" +-- std.prototype (std.set) --> "Set" +-- os.exit (0) Set = Container { _type = "Set", _init = function (self, t) - for e in base.elems (t) do + for e in ielems (t) do insert (self, e) end return self end, - --- Union operator. - -- union = set + table - -- @function __add -- @static - -- @tparam set set set - -- @tparam table|set table another set or table - -- @treturn set union + -- @function __add + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set everything from *set1* plus everything from *set2* -- @see union - __add = union, - + -- @usage + -- union = set1 + set2 + __add = X ("__add (Set, Set)", union), --- Difference operator. - -- difference = set - table - -- @function __sub -- @static - -- @tparam set set set - -- @tparam table|set table another set or table - -- @treturn set difference + -- @function __sub + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set everything from *set1* that is not also in *set2* -- @see difference - __sub = difference, - + -- @usage + -- difference = set1 - set2 + __sub = X ("__sub (Set, Set)", difference), --- Intersection operator. - -- intersection = set * table - -- @function __mul -- @static - -- @tparam set set set - -- @tparam table|set table another set or table - -- @treturn set intersection + -- @function __mul + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set anything this is in both *set1* and *set2* -- @see intersection - __mul = intersection, - + -- @usage + -- intersection = set1 * set2 + __mul = X ("__mul (Set, Set)", intersection), --- Symmetric difference operator. - -- symmetric_difference = set / table -- @function __div -- @static - -- @tparam set set set - -- @tparam table|set table another set or table - -- @treturn set symmetric_difference + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set everything from *set1* or *set2* but not both -- @see symmetric_difference - __div = symmetric_difference, - + -- @usage + -- symmetric_difference = set1 / set2 + __div = X ("__div (Set, Set)", symmetric_difference), --- Subset operator. - -- set = set <= table - -- @function __le -- @static - -- @tparam set set set - -- @tparam table|set table another set or table - -- @treturn set subset + -- @function __le + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn boolean `true` if everything in *set1* is also in *set2* -- @see subset - __le = subset, - + -- @usage + -- issubset = set1 <= set2 + __le = X ("__le (Set, Set)", subset), --- Proper subset operator. - -- proper_subset = set < table - -- @function __lt -- @static - -- @tparam set set set - -- @tparam table|set table another set or table - -- @treturn set proper_subset + -- @function __lt + -- @tparam Set set1 set + -- @tparam Set set2 another set + -- @treturn boolean `true` if *set2* is not equal to *set1*, but does + -- contain everything from *set1* -- @see proper_subset - __lt = proper_subset, - - - -- Set to table conversion. - -- @treturn table table representation of a set. - -- @see std.table.totable - __totable = function (self) - local t = {} - for e in elems (self) do - t[#t + 1] = e - end - table.sort (t) - return t - end, + -- @usage + -- ispropersubset = set1 < set2 + __lt = X ("__lt (Set, Set)", proper_subset), + + -- Return a string representation of this set. + -- @treturn string string representation of a set. + -- @see std.tostring + __tostring = X ("__tostring (Set)", + function (self) + local keys = {} + for k in pairs (self) do + keys[#keys + 1] = tostring (k) + end + table.sort (keys) + return prototype (self) .. " {" .. table.concat (keys, ", ") .. "}" + end), - --- @export _functions = { - delete = delete, - difference = difference, - elems = elems, - equal = equal, - insert = insert, - intersection = intersection, - member = member, - proper_subset = proper_subset, - subset = subset, - symmetric_difference = symmetric_difference, - union = union, + --- Delete an element from a set. + -- @static + -- @function delete + -- @tparam Set set a set + -- @param e element + -- @treturn Set the modified *set* + -- @usage + -- set.delete (available, found) + delete = X ("delete (Set, any)", + function (set, e) return rawset (set, e, nil) end), + + --- Find the difference of two sets. + -- @static + -- @function difference + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set a copy of *set1* with elements of *set2* removed + -- @usage + -- all = set.difference (all, {32, 49, 56}) + difference = X ("difference (Set, Set)", difference), + + --- Iterator for sets. + -- @static + -- @function elems + -- @tparam Set set a set + -- @treturn *set* iterator + -- @todo Make the iterator return only the key + -- @usage + -- for code in set.elems (isprintable) do print (code) end + elems = X ("elems (Set)", elems), + + --- Find whether two sets are equal. + -- @static + -- @function equal + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn boolean `true` if *set1* and *set2* each contain identical + -- elements, `false` otherwise + -- @usage + -- if set.equal (keys, {META, CTRL, "x"}) then process (keys) end + equal = X ( "equal (Set, Set)", equal), + + --- Insert an element into a set. + -- @static + -- @function insert + -- @tparam Set set a set + -- @param e element + -- @treturn Set the modified *set* + -- @usage + -- for byte = 32,126 do + -- set.insert (isprintable, string.char (byte)) + -- end + insert = X ("insert (Set, any)", insert), + + --- Find the intersection of two sets. + -- @static + -- @function intersection + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set a new set with elements in both *set1* and *set2* + -- @usage + -- common = set.intersection (a, b) + intersection = X ("intersection (Set, Set)", intersection), + + --- Say whether an element is in a set. + -- @static + -- @function difference + -- @tparam Set set a set + -- @param e element + -- @return `true` if *e* is in *set*, otherwise `false` + -- otherwise + -- @usage + -- if not set.member (keyset, pressed) then return nil end + member = X ("member (Set, any)", member), + + --- Find whether one set is a proper subset of another. + -- @static + -- @function proper_subset + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn boolean `true` if *set2* contains all elements in *set1* + -- but not only those elements, `false` otherwise + -- @usage + -- if set.proper_subset (a, b) then + -- for e in set.elems (set.difference (b, a)) do + -- set.delete (b, e) + -- end + -- end + -- assert (set.equal (a, b)) + proper_subset = X ("proper_subset (Set, Set)", proper_subset), + + --- Find whether one set is a subset of another. + -- @static + -- @function subset + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn boolean `true` if all elements in *set1* are also in *set2*, + -- `false` otherwise + -- @usage + -- if set.subset (a, b) then a = b end + subset = X ("subset (Set, Set)", subset), + + --- Find the symmetric difference of two sets. + -- @static + -- @function symmetric_difference + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set a new set with elements that are in *set1* or *set2* + -- but not both + -- @usage + -- unique = set.symmetric_difference (a, b) + symmetric_difference = X ("symmetric_difference (Set, Set)", + symmetric_difference), + + --- Find the union of two sets. + -- @static + -- @function union + -- @tparam Set set1 a set + -- @tparam Set set2 another set + -- @treturn Set a copy of *set1* with elements in *set2* merged in + -- @usage + -- all = set.union (a, b) + union = X ("union (Set, Set)", union), }, } diff --git a/lib/std/strbuf.lua b/lib/std/strbuf.lua index 114a24c..937f616 100644 --- a/lib/std/strbuf.lua +++ b/lib/std/strbuf.lua @@ -1,56 +1,79 @@ --[[-- String buffers. - @classmod std.strbuf -]] + Prototype Chain + --------------- -local Object = require "std.object" + table + `-> Object + `-> StrBuf + + @classmod std.strbuf +]] +local base = require "std.base" ---- Add a string to a buffer. --- @tparam string s string to add --- @treturn std.strbuf modified buffer -local function concat (self, s) - self[#self + 1] = s - return self -end +local Object = require "std.object" {} ---- Convert a buffer to a string. --- @treturn string stringified `self` -local function tostring (self) - return table.concat (self) +local function X (decl, fn) + return require "std.debug".argscheck ("std.strbuf." .. decl, fn) end +--- StrBuf prototype object. +-- +-- Set also inherits all the fields and methods from +-- @{std.object.Object}. +-- @object StrBuf +-- @string[opt="StrBuf"] _type object name +-- @see std.object.__call +-- @usage +-- local std = require "std" +-- local StrBuf = std.strbuf {} +-- local buf = StrBuf {"initial buffer contents"} +-- buf = buf .. "append to buffer" +-- print (buf) -- implicit `tostring` concatenates everything +-- os.exit (0) return Object { - -- Derived object type. _type = "StrBuf", - ------ - -- Support concatenation of StrBuf objects. - -- buffer = buffer .. str + --- Support concatenation to StrBuf objects. -- @function __concat - -- @tparam std.strbuf buffer StrBuf object - -- @tparam string str a string or string-like object - -- @treturn std.strbuf modified `buffer` + -- @tparam StrBuf buffer object + -- @string s a string + -- @treturn StrBuf modified *buf* -- @see concat - __concat = concat, + -- @usage + -- buf = buf .. str + __concat = X ("__concat (StrBuf, string)", base.insert), - - ------ - -- Support fast conversion to Lua string. - -- str = tostring (buffer) + --- Support fast conversion to Lua string. -- @function __tostring - -- @tparam std.strbuf buffer Strbuf object + -- @tparam StrBuf buffer object -- @treturn string concatenation of buffer contents -- @see tostring - __tostring = tostring, + -- @usage + -- str = tostring (buf) + __tostring = X ("__tostring (StrBuf)", table.concat), - --- @export __index = { - concat = concat, - tostring = tostring, + --- Add a string to a buffer. + -- @static + -- @function concat + -- @string s string to add + -- @treturn StrBuf modified buffer + -- @usage + -- buf = concat (buf, "append this") + concat = X ("concat (StrBuf, string)", base.insert), + + --- Convert a buffer to a string. + -- @static + -- @function tostring + -- @treturn string stringified `buf` + -- @usage + -- string = buf:tostring () + tostring = X ("tostring (StrBuf)", table.concat), }, } diff --git a/lib/std/strict.lua b/lib/std/strict.lua index 5c06551..6d7be04 100644 --- a/lib/std/strict.lua +++ b/lib/std/strict.lua @@ -4,6 +4,9 @@ All global variables must be 'declared' through a regular assignment (even assigning `nil` will do) in a top-level chunk before being used anywhere or assigned to inside a function. + + To use this module, just require it near the start of your program. + From Lua distribution (`etc/strict.lua`). @module std.strict @@ -17,15 +20,24 @@ if mt == nil then setmetatable (_G, mt) end + +-- The set of globally declared variables. mt.__declared = {} + +--- What kind of variable declaration is this? +-- @treturn string "C", "Lua" or "main" local function what () local d = getinfo (3, "S") return d and d.what or "C" end + --- Detect assignment to undeclared global. -- @function __newindex +-- @tparam table t `_G` +-- @string n name of the variable being declared +-- @param v initial value of the variable mt.__newindex = function (t, n, v) if not mt.__declared[n] then local w = what () @@ -37,8 +49,11 @@ mt.__newindex = function (t, n, v) rawset (t, n, v) end ---- Detect derefrence of undeclared global. + +--- Detect dereference of undeclared global. -- @function __index +-- @tparam table t `_G` +-- @string n name of the variable being dereferenced mt.__index = function (t, n) if not mt.__declared[n] and what () ~= "C" then error ("variable '" .. n .. "' is not declared", 2) diff --git a/lib/std/string.lua b/lib/std/string.lua index 7855ea4..ec5aab3 100644 --- a/lib/std/string.lua +++ b/lib/std/string.lua @@ -1,68 +1,37 @@ --[[-- - Additions to the string module. + Additions to the core string module. - If you `require "std"`, the contents of this module are all available - in the `std.string` table. + The module table returned by `std.string` also contains all of the entries + from the core string table. An hygienic way to import this module, then, is + simply to override the core `string` locally: - However, this module also contains references to the Lua core string - table entries, so it's safe to load it like this: - - local string = require "std.string" - - Of course, if you do that you'll lose references to any core string - functions overwritten by `std.string`, so you might want to save any - that you want access to before you overwrite them. - - If your code does not `require "std"` anywhere, then you'll also need - to manually overwrite string functions in the global namespace if you - want to use them from there: - - local assert, tostring = string.assert, string.tostring - - And finally, to use the string metatable improvements with all core - strings, you'll need to merge this module's metatable into the core - string metatable (again, `require "std"` does this automatically): - - local string_metatable = getmetatable "" - string_metatable.__append = string.__append - string_metatable.__concat = string.__concat - string_metatable.__index = string.__index + local string = require "std.string" @module std.string ]] -local List = require "std.list" -local StrBuf = require "std.strbuf" -local table = require "std.table" +local base = require "std.base" +local debug = require "std.debug" -local metamethod = (require "std.base").metamethod +local StrBuf = require "std.strbuf" {} -local _format = string.format -local _tostring = _G.tostring +local copy = base.copy +local getmetamethod = base.getmetamethod +local insert, len = base.insert, base.len +local pairs = base.pairs +local render = base.render -local M = {} +local M ---- String append operation. --- @param s string --- @param c character (1-character string) --- @return `s .. c` -local function __append (s, c) - return s .. c -end ---- String concatenation operation. --- @param s string --- @param o object --- @return s .. tostring (o) + +local _tostring = base.tostring + local function __concat (s, o) - return M.tostring (s) .. M.tostring (o) + return _tostring (s) .. _tostring (o) end ---- String subscript operation. --- @param s string --- @param i index --- @return `s:sub (i, i)` if i is a number, otherwise --- fall back to a `std.string` metamethod (if any). + local function __index (s, i) if type (i) == "number" then return s:sub (i, i) @@ -73,249 +42,140 @@ local function __index (s, i) end +local _format = string.format ---- Extend to work better with one argument. --- If only one argument is passed, no formatting is attempted. --- @param f format --- @param arg1 first argument to format --- @param ... arguments to format --- @return formatted string local function format (f, arg1, ...) - if arg1 == nil then - return f - else - return _format (f, arg1, ...) - end + return (arg1 ~= nil) and _format (f, arg1, ...) or f end ---- Extend to allow formatted arguments. --- @param v value to assert --- @param f format --- @param ... arguments to format --- @return value -local function assert (v, f, ...) - if not v then - if f == nil then - f = "" - end - error (format (f, ...), 2) - end - return v + +local function tpack (from, to, ...) + return from, to, {...} end ---- Do find, returning captures as a list. --- @param s target string --- @param p pattern --- @param init start position (default: 1) --- @param plain inhibit magic characters (default: nil) --- @return start of match, end of match, table of captures -local function tfind (s, p, init, plain) - assert (type (s) == "string", - "bad argument #1 to 'tfind' (string expected, got " .. type (s) .. ")") - assert (type (p) == "string", - "bad argument #2 to 'tfind' (string expected, got " .. type (p) .. ")") - local function pack (from, to, ...) - return from, to, {...} - end - return pack (p.find (s, p, init, plain)) +local function tfind (s, ...) + return tpack (s:find (...)) end ---- Do multiple `find`s on a string. --- @param s target string --- @param p pattern --- @param init start position (default: 1) --- @param plain inhibit magic characters (default: nil) --- @return list of `{from, to; capt = {captures}}` -local function finds (s, p, init, plain) - init = init or 1 + +local function finds (s, p, i, ...) + i = i or 1 local l = {} local from, to, r repeat - from, to, r = tfind (s, p, init, plain) + from, to, r = tfind (s, p, i, ...) if from ~= nil then - l[#l + 1] = {from, to, capt = r} - init = to + 1 + insert (l, {from, to, capt = r}) + i = to + 1 end until not from return l end ---- Split a string at a given separator. --- Separator is a Lua pattern, so you have to escape active characters, --- `^$()%.[]*+-?` with a `%` prefix to match a literal character in `s`. --- @string s to split --- @string[opt="%s*"] sep separator pattern --- @return list of strings --- @return list of strings -local function split (s, sep) - assert (type (s) == "string", - "bad argument #1 to 'split' (string expected, got " .. type (s) .. ")") - local b, len, t, patt = 0, #s, {}, "(.-)" .. sep - if sep == "" then patt = "(.)"; t[#t + 1] = "" end - while b <= len do - local e, n, m = string.find (s, patt, b + 1) - t[#t + 1] = m or s:sub (b + 1, len) - b = n or len + 1 - end - return t + +local function monkey_patch (namespace) + namespace = namespace or _G + namespace.string = base.copy (namespace.string or {}, M) + + local string_metatable = getmetatable "" + string_metatable.__concat = M.__concat + string_metatable.__index = M.__index + + return namespace.string end ---- Require a module with a particular version. --- @param module module to require --- @param min lowest acceptable version (default: any) --- @param too_big lowest version that is too big (default: none) --- @param pattern to match version in `module.version` or --- `module.VERSION` (default: `".*[%.%d]+"`) -local function require_version (module, min, too_big, pattern) - local function version_to_list (v) - return List (split (v, "%.")) - end - local function module_version (module, pattern) - return version_to_list (string.match (module.version or module._VERSION, - pattern or ".*[%.%d]+")) - end - local m = require (module) - if min then - assert (module_version (m, pattern) >= version_to_list (min)) - end - if too_big then - assert (module_version (m, pattern) < version_to_list (too_big)) + +local function caps (s) + return (s:gsub ("(%w)([%w]*)", function (l, ls) return l:upper () .. ls end)) +end + + +local function escape_shell (s) + return (s:gsub ("([ %(%)%\\%[%]\"'])", "\\%1")) +end + + +local function ordinal_suffix (n) + n = math.abs (n) % 100 + local d = n % 10 + if d == 1 and n ~= 11 then + return "st" + elseif d == 2 and n ~= 12 then + return "nd" + elseif d == 3 and n ~= 13 then + return "rd" + else + return "th" end - return m end --- Write pretty-printing based on: --- --- John Hughes's and Simon Peyton Jones's Pretty Printer Combinators --- --- Based on "The Design of a Pretty-printing Library in Advanced --- Functional Programming", Johan Jeuring and Erik Meijer (eds), LNCS 925 --- http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps --- Heavily modified by Simon Peyton Jones, Dec 96 --- --- Haskell types: --- data Doc list of lines --- quote :: Char -> Char -> Doc -> Doc Wrap document in ... --- (<>) :: Doc -> Doc -> Doc Beside --- (<+>) :: Doc -> Doc -> Doc Beside, separated by space --- ($$) :: Doc -> Doc -> Doc Above; if there is no overlap it "dovetails" the two --- nest :: Int -> Doc -> Doc Nested --- punctuate :: Doc -> [Doc] -> [Doc] punctuate p [d1, ... dn] = [d1 <> p, d2 <> p, ... dn-1 <> p, dn] --- render :: Int Line length --- -> Float Ribbons per line --- -> (TextDetails -> a -> a) What to do with text --- -> a What to do at the end --- -> Doc The document --- -> a Result - - ---- Turn tables into strings with recursion detection. --- N.B. Functions calling render should not recurse, or recursion --- detection will not work. --- @see render_OpenRenderer, render_CloseRenderer --- @see render_ElementRenderer, render_PairRenderer --- @see render_SeparatorRenderer --- @param x object to convert to string --- @param open open table renderer --- @param close close table renderer --- @param elem element renderer --- @param pair pair renderer --- @param sep separator renderer --- @param roots accumulates table references to detect recursion --- @return string representation -local function render (x, open, close, elem, pair, sep, roots) - local function stop_roots (x) - return roots[x] or render (x, open, close, elem, pair, sep, table.clone (roots)) +local function pad (s, w, p) + p = string.rep (p or " ", math.abs (w)) + if w < 0 then + return string.sub (p .. s, w) end - roots = roots or {} - if type (x) ~= "table" or metamethod (x, "__tostring") then - return elem (x) - else - local s = StrBuf {} - s = s .. open (x) - roots[x] = elem (x) - - -- create a sorted list of keys - local ord = {} - for k, _ in pairs (x) do ord[#ord + 1] = k end - table.sort (ord, function (a, b) return tostring (a) < tostring (b) end) - - -- render x elements in order - local i, v = nil, nil - for _, j in ipairs (ord) do - local w = x[j] - s = s .. sep (x, i, v, j, w) .. pair (x, j, w, stop_roots (j), stop_roots (w)) - i, v = j, w + return string.sub (s .. p, 1, w) +end + + +local function wrap (s, w, ind, ind1) + w = w or 78 + ind = ind or 0 + ind1 = ind1 or ind + assert (ind1 < w and ind < w, + "the indents must be less than the line width") + local r = StrBuf { string.rep (" ", ind1) } + local i, lstart, lens = 1, ind1, len (s) + while i <= lens do + local j = i + w - lstart + while len (s[j]) > 0 and s[j] ~= " " and j > i do + j = j - 1 + end + local ni = j + 1 + while s[j] == " " do + j = j - 1 + end + r:concat (s:sub (i, j)) + i = ni + if i < lens then + r:concat ("\n" .. string.rep (" ", ind)) + lstart = ind end - s = s .. sep (x, i, v, nil, nil) .. close (x) - return s:tostring () end + return r:tostring () end ---- --- @function render_OpenRenderer --- @param t table --- @return open table string - ---- --- @function render_CloseRenderer --- @param t table --- @return close table string - ---- --- @function render_ElementRenderer --- @param e element --- @return element string - ---- NB. the function should not try to render i and v, or treat them recursively. --- @function render_PairRenderer --- @param t table --- @param i index --- @param v value --- @param is index string --- @param vs value string --- @return element string - ---- --- @function render_SeparatorRenderer --- @param t table --- @param i preceding index (nil on first call) --- @param v preceding value (nil on first call) --- @param j following index (nil on last call) --- @param w following value (nil on last call) --- @return separator string - ---- Extend `tostring` to work better on tables. --- @function tostring --- @param x object to convert to string --- @return string representation -local function tostring (x) - return render (x, - function () return "{" end, - function () return "}" end, - _tostring, - function (t, _, _, i, v) - return i .. "=" .. v - end, - function (_, i, _, j) - if i and j then - return "," - end - return "" - end) + +local function numbertosi (n) + local SIprefix = { + [-8] = "y", [-7] = "z", [-6] = "a", [-5] = "f", + [-4] = "p", [-3] = "n", [-2] = "mu", [-1] = "m", + [0] = "", [1] = "k", [2] = "M", [3] = "G", + [4] = "T", [5] = "P", [6] = "E", [7] = "Z", + [8] = "Y" + } + local t = format("% #.2e", n) + local _, _, m, e = t:find(".(.%...)e(.+)") + local man, exp = tonumber (m), tonumber (e) + local siexp = math.floor (exp / 3) + local shift = exp - siexp * 3 + local s = SIprefix[siexp] or "e" .. tostring (siexp) + man = man * (10 ^ shift) + return format ("%0.f", man) .. s +end + + +local function trim (s, r) + r = r or "%s+" + return (s:gsub ("^" .. r, ""):gsub (r .. "$", "")) end ---- Pretty-print a table. --- @param t table to print --- @param indent indent between levels ["\t"] --- @param spacing space before every line --- @return pretty-printed string -local function prettytostring (t, indent, spacing) +local function prettytostring (x, indent, spacing) indent = indent or "\t" spacing = spacing or "" - return render (t, + return render (x, function () local s = spacing .. "{" spacing = spacing .. indent @@ -332,20 +192,20 @@ local function prettytostring (t, indent, spacing) return tostring (x) end end, - function (x, i, v, is, vs) + function (x, k, v, ks, vs) local s = spacing - if type (i) ~= "string" or i:match "[^%w_]" then + if type (k) ~= "string" or k:match "[^%w_]" then s = s .. "[" - if type (i) == "table" then + if type (k) == "table" then s = s .. "\n" end - s = s .. is - if type (i) == "table" then + s = s .. ks + if type (k) == "table" then s = s .. "\n" end s = s .. "]" else - s = s .. i + s = s .. k end s = s .. " =" if type (v) == "table" then @@ -356,9 +216,9 @@ local function prettytostring (t, indent, spacing) s = s .. vs return s end, - function (_, i) + function (_, k) local s = "\n" - if i then + if k then s = "," .. s end return s @@ -366,37 +226,6 @@ local function prettytostring (t, indent, spacing) end ---- Overwrite core methods and metamethods with `std` enhanced versions. --- --- Adds auto-stringification to `..` operator on core strings, and --- integer indexing of strings with `[]` dereferencing. --- --- Also replaces core `assert` and `tostring` functions with --- `std.string` versions. --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table the module table -local function monkey_patch (namespace) - namespace = namespace or _G - - assert (type (namespace) == "table", - "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") - - namespace.assert, namespace.tostring = assert, tostring - - local string_metatable = getmetatable "" - string_metatable.__append = __append - string_metatable.__concat = __concat - string_metatable.__index = __index - - return M -end - - ---- Convert a value to a string. --- The string can be passed to dostring to retrieve the value. --- @todo Make it work for recursive tables. --- @param x object to pickle --- @return string such that eval (s) is the same value as x local function pickle (x) if type (x) == "string" then return format ("%q", x) @@ -404,11 +233,11 @@ local function pickle (x) type (x) == "nil" then return tostring (x) else - x = totable (x) or x + x = copy (x) or x if type (x) == "table" then local s, sep = "{", "" for i, v in pairs (x) do - s = s .. sep .. "[" .. pickle (i) .. "]=" .. pickle (v) + s = s .. sep .. "[" .. M.pickle (i) .. "]=" .. M.pickle (v) sep = "," end s = s .. "}" @@ -420,187 +249,304 @@ local function pickle (x) end ---- Capitalise each word in a string. --- @param s string --- @return capitalised string -local function caps (s) - return (string.gsub (s, "(%w)([%w]*)", - function (l, ls) - return string.upper (l) .. ls - end)) -end ---- Remove any final newline from a string. --- @param s string to process --- @return processed string -local function chomp (s) - return (string.gsub (s, "\n$", "")) -end +--[[ ================= ]]-- +--[[ Public Interface. ]]-- +--[[ ================= ]]-- ---- Escape a string to be used as a pattern. --- @param s string to process --- @return processed string -local function escape_pattern (s) - return (string.gsub (s, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")) -end ---- Escape a string to be used as a shell token. --- Quotes spaces, parentheses, brackets, quotes, apostrophes and --- whitespace. --- @param s string to process --- @return processed string -local function escape_shell (s) - return (string.gsub (s, "([ %(%)%\\%[%]\"'])", "\\%1")) +local function X (decl, fn) + return debug.argscheck ("std.string." .. decl, fn) end ---- Return the English suffix for an ordinal. --- @param n number of the day --- @return suffix -local function ordinal_suffix (n) - n = math.abs (n) % 100 - local d = n % 10 - if d == 1 and n ~= 11 then - return "st" - elseif d == 2 and n ~= 12 then - return "nd" - elseif d == 3 and n ~= 13 then - return "rd" - else - return "th" - end -end +M = { + --- String concatenation operation. + -- @string s initial string + -- @param o object to stringify and concatenate + -- @return s .. tostring (o) + -- @usage + -- local string = require "std.string".monkey_patch () + -- concatenated = "foo" .. {"bar"} + __concat = __concat, + + --- String subscript operation. + -- @string s string + -- @tparam int|string i index or method name + -- @return `s:sub (i, i)` if i is a number, otherwise + -- fall back to a `std.string` metamethod (if any). + -- @usage + -- getmetatable ("").__index = require "std.string".__index + -- third = ("12345")[3] + __index = __index, + + --- Capitalise each word in a string. + -- @function caps + -- @string s any string + -- @treturn string *s* with each word capitalized + -- @usage userfullname = caps (input_string) + caps = X ("caps (string)", caps), + + --- Remove any final newline from a string. + -- @function chomp + -- @string s any string + -- @treturn string *s* with any single trailing newline removed + -- @usage line = chomp (line) + chomp = X ("chomp (string)", function (s) return (s:gsub ("\n$", "")) end), + + --- Escape a string to be used as a pattern. + -- @function escape_pattern + -- @string s any string + -- @treturn string *s* with active pattern characters escaped + -- @usage substr = inputstr:match (escape_pattern (literal)) + escape_pattern = X ("escape_pattern (string)", base.escape_pattern), + + --- Escape a string to be used as a shell token. + -- Quotes spaces, parentheses, brackets, quotes, apostrophes and + -- whitespace. + -- @function escape_shell + -- @string s any string + -- @treturn string *s* with active shell characters escaped + -- @usage os.execute ("echo " .. escape_shell (outputstr)) + escape_shell = X ("escape_shell (string)", escape_shell), + + --- Repeatedly `string.find` until target string is exhausted. + -- @function finds + -- @string s target string + -- @string pattern pattern to match in *s* + -- @int[opt=1] init start position + -- @bool[opt] plain inhibit magic characters + -- @return list of `{from, to; capt = {captures}}` + -- @see std.string.tfind + -- @usage + -- for t in std.elems (finds ("the target string", "%S+")) do + -- print (tostring (t.capt)) + -- end + finds = X ("finds (string, string, int?, boolean|:plain?)", finds), + + --- Extend to work better with one argument. + -- If only one argument is passed, no formatting is attempted. + -- @function format + -- @string f format string + -- @param[opt] ... arguments to format + -- @return formatted string + -- @usage print (format "100% stdlib!") + format = X ("format (string, any?*)", format), + + --- Remove leading matter from a string. + -- @function ltrim + -- @string s any string + -- @string[opt="%s+"] r leading pattern + -- @treturn string *s* with leading *r* stripped + -- @usage print ("got: " .. ltrim (userinput)) + ltrim = X ("ltrim (string, string?)", + function (s, r) return (s:gsub ("^" .. (r or "%s+"), "")) end), + + --- Overwrite core `string` methods with `std` enhanced versions. + -- + -- Also adds auto-stringification to `..` operator on core strings, and + -- integer indexing of strings with `[]` dereferencing. + -- @function monkey_patch + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table the module table + -- @usage local string = require "std.string".monkey_patch () + monkey_patch = X ("monkey_patch (table?)", monkey_patch), + + --- Write a number using SI suffixes. + -- The number is always written to 3 s.f. + -- @function numbertosi + -- @tparam number|string n any numeric value + -- @treturn string *n* simplifed using largest available SI suffix. + -- @usage print (numbertosi (bitspersecond) .. "bps") + numbertosi = X ("numbertosi (number|string)", numbertosi), + + --- Return the English suffix for an ordinal. + -- @function ordinal_suffix + -- @tparam int|string n any integer value + -- @treturn string English suffix for *n* + -- @usage + -- local now = os.date "*t" + -- print ("%d%s day of the week", now.day, ordinal_suffix (now.day)) + ordinal_suffix = X ("ordinal_suffix (int|string)", ordinal_suffix), + + --- Justify a string. + -- When the string is longer than w, it is truncated (left or right + -- according to the sign of w). + -- @function pad + -- @string s a string to justify + -- @int w width to justify to (-ve means right-justify; +ve means + -- left-justify) + -- @string[opt=" "] p string to pad with + -- @treturn string *s* justified to *w* characters wide + -- @usage print (pad (trim (outputstr, 78)) .. "\n") + pad = X ("pad (string, int, string?)", pad), + + --- Convert a value to a string. + -- The string can be passed to `functional.eval` to retrieve the value. + -- @todo Make it work for recursive tables. + -- @param x object to pickle + -- @treturn string reversible string rendering of *x* + -- @see std.eval + -- @usage + -- function slow_identity (x) return functional.eval (pickle (x)) end + pickle = pickle, + + --- Pretty-print a table, or other object. + -- @function prettytostring + -- @param x object to convert to string + -- @string[opt="\t"] indent indent between levels + -- @string[opt=""] spacing space before every line + -- @treturn string pretty string rendering of *x* + -- @usage print (prettytostring (std, " ")) + prettytostring = X ("prettytostring (any?, string?, string?)", prettytostring), + + --- Turn tables into strings with recursion detection. + -- N.B. Functions calling render should not recurse, or recursion + -- detection will not work. + -- @function render + -- @param x object to convert to string + -- @tparam opentablecb open open table rendering function + -- @tparam closetablecb close close table rendering function + -- @tparam elementcb elem element rendering function + -- @tparam paircb pair pair rendering function + -- @tparam separatorcb sep separator rendering function + -- @tparam[opt] table roots accumulates table references to detect recursion + -- @return string representation of *x* + -- @usage + -- function tostring (x) + -- return render (x, lambda '="{"', lambda '="}"', tostring, + -- lambda '=_4.."=".._5', lambda '= _4 and "," or ""', + -- lambda '=","') + -- end + render = X ("render (any?, func, func, func, func, func, table?)", render), + + --- Remove trailing matter from a string. + -- @function rtrim + -- @string s any string + -- @string[opt="%s+"] r trailing pattern + -- @treturn string *s* with trailing *r* stripped + -- @usage print ("got: " .. rtrim (userinput)) + rtrim = X ("rtrim (string, string?)", + function (s, r) return (s:gsub ((r or "%s+") .. "$", "")) end), + + --- Split a string at a given separator. + -- Separator is a Lua pattern, so you have to escape active characters, + -- `^$()%.[]*+-?` with a `%` prefix to match a literal character in *s*. + -- @function split + -- @string s to split + -- @string[opt="%s+"] sep separator pattern + -- @return list of strings + -- @usage words = split "a very short sentence" + split = X ("split (string, string?)", base.split), + + --- Do `string.find`, returning a table of captures. + -- @function tfind + -- @string s target string + -- @string pattern pattern to match in *s* + -- @int[opt=1] init start position + -- @bool[opt] plain inhibit magic characters + -- @treturn int start of match + -- @treturn int end of match + -- @treturn table list of captured strings + -- @see std.string.finds + -- @usage b, e, captures = tfind ("the target string", "%s", 10) + tfind = X ("tfind (string, string, int?, boolean|:plain?)", tfind), + + --- Remove leading and trailing matter from a string. + -- @function trim + -- @string s any string + -- @string[opt="%s+"] r trailing pattern + -- @treturn string *s* with leading and trailing *r* stripped + -- @usage print ("got: " .. trim (userinput)) + trim = X ("trim (string, string?)", trim), + + --- Wrap a string into a paragraph. + -- @function wrap + -- @string s a paragraph of text + -- @int[opt=78] w width to wrap to + -- @int[opt=0] ind indent + -- @int[opt=ind] ind1 indent of first line + -- @treturn string *s* wrapped to *w* columns + -- @usage + -- print (wrap (copyright, 72, 4)) + wrap = X ("wrap (string, int?, int?, int?)", wrap), +} ---- Justify a string. --- When the string is longer than w, it is truncated (left or right --- according to the sign of w). --- @param s string to justify --- @param w width to justify to (-ve means right-justify; +ve means --- left-justify) --- @param p string to pad with (default: `" "`) --- @return justified string -local function pad (s, w, p) - p = string.rep (p or " ", math.abs (w)) - if w < 0 then - return string.sub (p .. s, w) - end - return string.sub (s .. p, 1, w) -end ---- Wrap a string into a paragraph. --- @param s string to wrap --- @param w width to wrap to (default: 78) --- @param ind indent (default: 0) --- @param ind1 indent of first line (default: ind) --- @return wrapped paragraph -local function wrap (s, w, ind, ind1) - w = w or 78 - ind = ind or 0 - ind1 = ind1 or ind - assert (ind1 < w and ind < w, - "the indents must be less than the line width") - assert (type (s) == "string", - "bad argument #1 to 'wrap' (string expected, got " .. type (s) .. ")") - local r = StrBuf { string.rep (" ", ind1) } - local i, lstart, len = 1, ind1, #s - while i <= #s do - local j = i + w - lstart - while #s[j] > 0 and s[j] ~= " " and j > i do - j = j - 1 - end - local ni = j + 1 - while s[j] == " " do - j = j - 1 - end - r:concat (s:sub (i, j)) - i = ni - if i < #s then - r:concat ("\n" .. string.rep (" ", ind)) - lstart = ind - end - end - return r:tostring () -end ---- Write a number using SI suffixes. --- The number is always written to 3 s.f. --- @param n number --- @return string -local function numbertosi (n) - local SIprefix = { - [-8] = "y", [-7] = "z", [-6] = "a", [-5] = "f", - [-4] = "p", [-3] = "n", [-2] = "mu", [-1] = "m", - [0] = "", [1] = "k", [2] = "M", [3] = "G", - [4] = "T", [5] = "P", [6] = "E", [7] = "Z", - [8] = "Y" - } - local t = format("% #.2e", n) - local _, _, m, e = t:find(".(.%...)e(.+)") - local man, exp = tonumber (m), tonumber (e) - local siexp = math.floor (exp / 3) - local shift = exp - siexp * 3 - local s = SIprefix[siexp] or "e" .. tostring (siexp) - man = man * (10 ^ shift) - return tostring (man) .. s -end +--[[ ============= ]]-- +--[[ Deprecations. ]]-- +--[[ ============= ]]-- ---- Remove leading matter from a string. --- @param s string --- @param r leading pattern (default: `"%s+"`) --- @return string without leading r -local function ltrim (s, r) - r = r or "%s+" - return (string.gsub (s, "^" .. r, "")) -end ---- Remove trailing matter from a string. --- @param s string --- @param r trailing pattern (default: `"%s+"`) --- @return string without trailing r -local function rtrim (s, r) - r = r or "%s+" - return (string.gsub (s, r .. "$", "")) -end +local DEPRECATED = debug.DEPRECATED ---- Remove leading and trailing matter from a string. --- @param s string --- @param r leading/trailing pattern (default: `"%s+"`) --- @return string without leading/trailing r -local function trim (s, r) - return rtrim (ltrim (s, r), r) -end +M.assert = DEPRECATED ("41", "'std.string.assert'", + "use 'std.assert' instead", base.assert) ---- @export -M = { - __append = __append, - __concat = __concat, - __index = __index, - assert = assert, - caps = caps, - chomp = chomp, - escape_pattern = escape_pattern, - escape_shell = escape_shell, - finds = finds, - format = format, - ltrim = ltrim, - monkey_patch = monkey_patch, - numbertosi = numbertosi, - ordinal_suffix = ordinal_suffix, - pad = pad, - pickle = pickle, - prettytostring = prettytostring, - render = render, - require_version = require_version, - rtrim = rtrim, - split = split, - tfind = tfind, - tostring = tostring, - trim = trim, - wrap = wrap, -} -for k, v in pairs (string) do - M[k] = M[k] or v -end +M.require_version = DEPRECATED ("41", "'std.string.require_version'", + "use 'std.require' instead", base.require) + + +M.tostring = DEPRECATED ("41", "'std.string.tostring'", + "use 'std.tostring' instead", base.tostring) + + + +return base.merge (M, string) + + + +--- Types +-- @section Types + +--- Signature of @{render} open table callback. +-- @function opentablecb +-- @tparam table t table about to be rendered +-- @treturn string open table rendering +-- @see render +-- @usage function open (t) return "{" end + + +--- Signature of @{render} close table callback. +-- @function closetablecb +-- @tparam table t table just rendered +-- @treturn string close table rendering +-- @see render +-- @usage function close (t) return "}" end + + +--- Signature of @{render} element callback. +-- @function elementcb +-- @param x element to render +-- @treturn string element rendering +-- @see render +-- @usage function element (e) return require "std".tostring (e) end + + +--- Signature of @{render} pair callback. +-- Trying to re-render *key* or *value* here will break recursion +-- detection, use *strkey* and *strvalue* pre-rendered values instead. +-- @function paircb +-- @tparam table t table containing pair being rendered +-- @param key key part of key being rendered +-- @param value value part of key being rendered +-- @string keystr prerendered *key* +-- @string valuestr prerendered *value* +-- @treturn string pair rendering +-- @see render +-- @usage +-- function pair (_, _, _, key, value) return key .. "=" .. value end + -return M +--- Signature of @{render} separator callback. +-- @function separatorcb +-- @tparam table t table currently being rendered +-- @param pk *t* key preceding separator, or `nil` for first key +-- @param pv *t* value preceding separator, or `nil` for first value +-- @param fk *t* key following separator, or `nil` for last key +-- @param fv *t* value following separator, or `nil` for last value +-- @treturn string separator rendering +-- @usage +-- function separator (_, _, _, fk) return fk and "," or "" end diff --git a/lib/std/table.lua b/lib/std/table.lua index b2ddd4b..cdb32fd 100644 --- a/lib/std/table.lua +++ b/lib/std/table.lua @@ -1,187 +1,93 @@ --[[-- - Extensions to the table module. + Extensions to the core table module. + + The module table returned by `std.table` also contains all of the entries from + the core table module. An hygienic way to import this module, then, is simply + to override the core `table` locally: + + local table = require "std.table" + @module std.table ]] -local base = require "std.base" +local core = _G.table + +local base = require "std.base" +local debug = require "std.debug" -local M -- forward declaration +local argerror = debug.argerror +local collect = base.collect +local leaves = base.leaves +local ipairs, pairs = base.ipairs, base.pairs +local len = base.len --- No need to pull all of std.list into memory. -local elems = base.elems + +local M, monkeys ---- Merge one table's fields into another. --- @tparam table t destination table --- @tparam table u table with fields to merge --- @tparam[opt={}] table map table of `{old_key=new_key, ...}` --- @tparam boolean nometa if non-nil don't copy metatable --- @return table `t` with fields from `u` merged in local function merge_allfields (t, u, map, nometa) - map = map or {} if type (map) ~= "table" then - map, nometa = {}, map + map, nometa = nil, map end if not nometa then setmetatable (t, getmetatable (u)) end - for k, v in pairs (u) do - t[map[k] or k] = v + if map then + for k, v in pairs (u) do t[map[k] or k] = v end + else + for k, v in pairs (u) do t[k] = v end end return t end ---- Merge one table's named fields into another. --- @tparam table t destination table --- @tparam table u table with fields to merge --- @tparam[opt={}] table keys list of keys to copy --- @tparam boolean nometa if non-nil don't copy metatable --- @return copy of fields in *selection* from *t*, also sharing *t*'s --- metatable unless *nometa* local function merge_namedfields (t, u, keys, nometa) - keys = keys or {} if type (keys) ~= "table" then - keys, nometa = {}, keys + keys, nometa = nil, keys end if not nometa then setmetatable (t, getmetatable (u)) end - for k in elems (keys) do - t[k] = u[k] - end + for _, k in pairs (keys or {}) do t[k] = u[k] end return t end ---- Make a shallow copy of a table, including any metatable. --- --- To make deep copies, use @{std.tree.clone}. --- @tparam table t source table --- @tparam[opt={}] table map table of `{old_key=new_key, ...}` --- @tparam boolean nometa if non-nil don't copy metatable --- @return copy of *t*, also sharing *t*'s metatable unless *nometa* --- is true, and with keys renamed according to *map* -local function clone (t, map, nometa) - assert (type (t) == "table", - "bad argument #1 to 'clone' (table expected, got " .. type (t) .. ")") - return merge_allfields ({}, t, map, nometa) -end - - --- DEPRECATED: Remove in first release following 2015-04-15. --- Clone a table, renaming some keys. --- @function clone_rename --- @tparam table map table `{old_key=new_key, ...}` --- @tparam table t source table --- @return copy of *table* -local clone_rename = base.deprecate (function (map, t) - local r = clone (t) - for i, v in pairs (map) do - r[v] = t[i] - r[i] = nil - end - return r - end, nil, - "table.clone_rename is deprecated, use the new `map` argument to table.clone instead.") - - ---- Make a partial clone of a table. --- --- Like `clone`, but does not copy any fields by default. --- @function clone_select --- @tparam table t source table --- @tparam[opt={}] table keys list of keys to copy --- @return copy of fields in *selection* from *t*, also sharing *t*'s --- metatable unless *nometa* -local function clone_select (t, keys, nometa) - assert (type (t) == "table", - "bad argument #1 to 'clone_select' (table expected, got " .. type (t) .. ")") - return merge_namedfields ({}, t, keys, nometa) +local function depair (ls) + local t = {} + for _, v in ipairs (ls) do + t[v[1]] = v[2] + end + return t end ---- Return whether table is empty. --- @tparam table t any table --- @return `true` if `t` is empty, otherwise `false` -local function empty (t) - return not next (t) +local function enpair (t) + local tt = {} + for i, v in pairs (t) do + tt[#tt + 1] = {i, v} + end + return tt end ---- Invert a table. --- @tparam table t a table with `{k=v, ...}` --- @treturn table inverted table `{v=k, ...}` -local function invert (t) - local i = {} - for k, v in pairs (t) do - i[v] = k - end - return i +local function flatten (t) + return collect (leaves, ipairs, t) end ---- Make the list of keys in table. --- @tparam table t any table --- @treturn table list of keys local function keys (t) local l = {} - for k, _ in pairs (t) do + for k in pairs (t) do l[#l + 1] = k end return l end ---- Destructively merge another table's fields into another. --- @tparam table t destination table --- @tparam table u table with fields to merge --- @tparam[opt={}] table map table of `{old_key=new_key, ...}` --- @tparam boolean nometa if non-nil don't copy metatable --- @return table `t` with fields from `u` merged in -local function merge (t, u, map, nometa) - assert (type (t) == "table", - "bad argument #1 to 'merge' (table expected, got " .. type (t) .. ")") - assert (type (u) == "table", - "bad argument #2 to 'merge' (table expected, got " .. type (u) .. ")") - return merge_allfields (t, u, map, nometa) -end - - ---- Destructively merge another table's named fields into *table*. --- --- Like `merge`, but does not merge any fields by default. --- @tparam table t destination table --- @tparam table u table with fields to merge --- @tparam[opt={}] table keys list of keys to copy --- @tparam boolean nometa if non-nil don't copy metatable --- @return copy of fields in *selection* from *t*, also sharing *t*'s --- metatable unless *nometa* -local function merge_select (t, u, keys, nometa) - assert (type (t) == "table", - "bad argument #1 to 'merge_select' (table expected, got " .. type (t) .. ")") - assert (type (u) == "table", - "bad argument #2 to 'merge_select' (table expected, got " .. type (u) .. ")") - return merge_namedfields (t, u, keys, nometa) -end - - ---- Return given metamethod, if any, or nil. --- @function metamethod --- @param x object to get metamethod of --- @param n name of metamethod to get --- @return metamethod function or nil if no metamethod or not a --- function -local metamethod = base.metamethod - - ---- Make a table with a default value for unset keys. --- @param x default entry value (default: `nil`) --- @tparam table t initial table (default: `{}`) --- @treturn table table whose unset elements are x local function new (x, t) return setmetatable (t or {}, {__index = function (t, i) @@ -190,33 +96,51 @@ local function new (x, t) end ---- Turn a tuple into a list. --- @param ... tuple --- @return list -local function pack (...) - return {...} +local function project (fkey, tt) + local r = {} + for _, t in ipairs (tt) do + r[#r + 1] = t[fkey] + end + return r end ---- An iterator like ipairs, but in reverse. --- @tparam table t any table --- @treturn function iterator function --- @treturn table the table, `t` --- @treturn number `#t + 1` -local function ripairs (t) - return function (t, n) - n = n - 1 - if n > 0 then - return n, t[n] - end - end, - t, #t + 1 +local function shape (dims, t) + t = flatten (t) + -- Check the shape and calculate the size of the zero, if any + local size = 1 + local zero + for i, v in ipairs (dims) do + if v == 0 then + if zero then -- bad shape: two zeros + return nil + else + zero = i + end + else + size = size * v + end + end + if zero then + dims[zero] = math.ceil (len (t) / size) + end + local function fill (i, d) + if d > len (dims) then + return t[i], i + 1 + else + local r = {} + for j = 1, dims[d] do + local e + e, i = fill (i, d + 1) + r[#r + 1] = e + end + return r, i + end + end + return (fill (1, 1)) end ---- Find the number of elements in a table. --- @tparam table t any table --- @return number of non-nil values in `t` local function size (t) local n = 0 for _ in pairs (t) do @@ -229,53 +153,31 @@ end -- Preserve core table sort function. local _sort = table.sort ---- Make table.sort return its result. --- @tparam table t unsorted table --- @tparam function c comparator function --- @return `t` with keys sorted accordind to `c` local function sort (t, c) _sort (t, c) return t end ---- Overwrite core methods with `std` enhanced versions. --- --- Replaces core `table.sort` with `std.table` version. --- @tparam[opt=_G] table namespace where to install global functions --- @treturn table the module table local function monkey_patch (namespace) namespace = namespace or _G - assert (type (namespace) == "table", - "bad argument #1 to 'monkey_patch' (table expected, got " .. type (namespace) .. ")") - - namespace.table.sort = sort - return M + namespace.table = base.copy (namespace.table or {}, monkeys) + return namespace.table end ---- Turn an object into a table according to __totable metamethod. --- @tparam std.object x object to turn into a table --- @treturn table resulting table or `nil` -local function totable (x) - local m = metamethod (x, "__totable") - if m then - return m (x) - elseif type (x) == "table" then - return x - elseif type (x) == "string" then - local t = {} - x:gsub (".", function (c) t[#t + 1] = c end) - return t - else - return nil +local _remove = table.remove + +local function remove (t, pos) + local lent = len (t) + pos = pos or lent + if pos < math.min (1, lent) or pos > lent + 1 then -- +1? whu? that's what 5.2.3 does!?! + argerror ("std.table.remove", 2, "position " .. pos .. " out of bounds", 2) end + return _remove (t, pos) end ---- Make the list of values of a table. --- @tparam table t any table --- @treturn table list of values local function values (t) local l = {} for _, v in pairs (t) do @@ -285,31 +187,334 @@ local function values (t) end ---- @export + +--[[ ================= ]]-- +--[[ Public Interface. ]]-- +--[[ ================= ]]-- + + +local function X (decl, fn) + return debug.argscheck ("std.table." .. decl, fn) +end + M = { - clone = clone, - clone_select = clone_select, - empty = empty, - invert = invert, - keys = keys, - merge = merge, - merge_select = merge_select, - metamethod = metamethod, - monkey_patch = monkey_patch, - new = new, - pack = pack, - ripairs = ripairs, - size = size, - sort = sort, - totable = totable, - values = values, + --- Make a shallow copy of a table, including any metatable. + -- + -- To make deep copies, use @{tree.clone}. + -- @function clone + -- @tparam table t source table + -- @tparam[opt={}] table map table of `{old_key=new_key, ...}` + -- @bool[opt] nometa if non-nil don't copy metatable + -- @return copy of *t*, also sharing *t*'s metatable unless *nometa* + -- is true, and with keys renamed according to *map* + -- @see merge + -- @see clone_select + -- @usage + -- shallowcopy = clone (original, {rename_this = "to_this"}, ":nometa") + clone = X ("clone (table, [table], boolean|:nometa?)", + function (...) return merge_allfields ({}, ...) end), + + --- Make a partial clone of a table. + -- + -- Like `clone`, but does not copy any fields by default. + -- @function clone_select + -- @tparam table t source table + -- @tparam[opt={}] table keys list of keys to copy + -- @bool[opt] nometa if non-nil don't copy metatable + -- @treturn table copy of fields in *selection* from *t*, also sharing *t*'s + -- metatable unless *nometa* + -- @see clone + -- @see merge_select + -- @usage + -- partialcopy = clone_select (original, {"this", "and_this"}, true) + clone_select = X ("clone_select (table, [table], boolean|:nometa?)", + function (...) return merge_namedfields ({}, ...) end), + + --- Turn a list of pairs into a table. + -- @todo Find a better name. + -- @function depair + -- @tparam table ls list of lists + -- @treturn table a flat table with keys and values from *ls* + -- @see enpair + -- @usage + -- --> {a=1, b=2, c=3} + -- depair {{"a", 1}, {"b", 2}, {"c", 3}} + depair = X ("depair (list of lists)", depair), + + --- Turn a table into a list of pairs. + -- @todo Find a better name. + -- @function enpair + -- @tparam table t a table `{i1=v1, ..., in=vn}` + -- @treturn table a new list of pairs containing `{{i1, v1}, ..., {in, vn}}` + -- @see depair + -- @usage + -- --> {{1, "a"}, {2, "b"}, {3, "c"}} + -- enpair {"a", "b", "c"} + enpair = X ("enpair (table)", enpair), + + --- Return whether table is empty. + -- @function empty + -- @tparam table t any table + -- @treturn boolean `true` if *t* is empty, otherwise `false` + -- @usage if empty (t) then error "ohnoes" end + empty = X ("empty (table)", function (t) return not next (t) end), + + --- Flatten a nested table into a list. + -- @function flatten + -- @tparam table t a table + -- @treturn table a list of all non-table elements of *t* + -- @usage + -- --> {1, 2, 3, 4, 5} + -- flatten {{1, {{2}, 3}, 4}, 5} + flatten = X ("flatten (table)", flatten), + + --- Enhance core *table.insert* to return its result. + -- If *pos* is not given, respect `__len` metamethod when calculating + -- default append. Also, diagnose out of bounds *pos* arguments + -- consistently on any supported version of Lua. + -- @function insert + -- @tparam table t a table + -- @int[opt=len (t)] pos index at which to insert new element + -- @param v value to insert into *t* + -- @treturn table *t* + -- @usage + -- --> {1, "x", 2, 3, "y"} + -- insert (insert ({1, 2, 3}, 2, "x"), "y") + insert = X ("insert (table, [int], any)", base.insert), + + --- Invert a table. + -- @function invert + -- @tparam table t a table with `{k=v, ...}` + -- @treturn table inverted table `{v=k, ...}` + -- @usage + -- --> {a=1, b=2, c=3} + -- invert {"a", "b", "c"} + invert = X ("invert (table)", base.invert), + + --- Make the list of keys in table. + -- @function keys + -- @tparam table t a table + -- @treturn table list of keys from *t* + -- @see okeys + -- @see values + -- @usage globals = keys (_G) + keys = X ("keys (table)", keys), + + --- Equivalent to `#` operation, but respecting `__len` even on Lua 5.1. + -- @function len + -- @tparam table t a table + -- @treturn int length of list part of *t* + -- @usage for i = 1, len (t) do process (t[i]) end + len = X ("len (table)", base.len), + + --- Largest integer key in a table. + -- @function maxn + -- @tparam table t a table + -- @treturn int largest integer key in *t* + -- @usage + -- --> 42 + -- maxn {"a", b="c", 99, [42]="x", "x", [5]=67} + maxn = X ("maxn (table)", base.maxn), + + --- Destructively merge another table's fields into another. + -- @function merge + -- @tparam table t destination table + -- @tparam table u table with fields to merge + -- @tparam[opt={}] table map table of `{old_key=new_key, ...}` + -- @bool[opt] nometa if `true` or ":nometa" don't copy metatable + -- @treturn table *t* with fields from *u* merged in + -- @see clone + -- @see merge_select + -- @usage merge (_G, require "std.debug", {say = "log"}, ":nometa") + merge = X ("merge (table, table, [table], boolean|:nometa?)", merge_allfields), + + --- Destructively merge another table's named fields into *table*. + -- + -- Like `merge`, but does not merge any fields by default. + -- @function merge_select + -- @tparam table t destination table + -- @tparam table u table with fields to merge + -- @tparam[opt={}] table keys list of keys to copy + -- @bool[opt] nometa if `true` or ":nometa" don't copy metatable + -- @treturn table copy of fields in *selection* from *t*, also sharing *t*'s + -- metatable unless *nometa* + -- @see merge + -- @see clone_select + -- @usage merge_select (_G, require "std.debug", {"say"}, false) + merge_select = X ("merge_select (table, table, [table], boolean|:nometa?)", + merge_namedfields), + + --- Overwrite core `table` methods with `std` enhanced versions. + -- @function monkey_patch + -- @tparam[opt=_G] table namespace where to install global functions + -- @treturn table the module table + -- @usage local table = require "std.table".monkey_patch () + monkey_patch = X ("monkey_patch (table?)", monkey_patch), + + --- Make a table with a default value for unset keys. + -- @function new + -- @param[opt=nil] x default entry value + -- @tparam[opt={}] table t initial table + -- @treturn table table whose unset elements are *x* + -- @usage t = new (0) + new = X ("new (any?, table?)", new), + + --- Make an ordered list of keys in table. + -- @function okeys + -- @tparam table t a table + -- @treturn table ordered list of keys from *t* + -- @see keys + -- @usage globals = keys (_G) + okeys = X ("okeys (table)", base.okeys), + + --- Turn a tuple into a list. + -- @function pack + -- @param ... tuple + -- @return list + -- @usage + -- --> {1, 2, "ax"} + -- pack (("ax1"):find "(%D+)") + pack = function (...) return {...} end, + + --- Project a list of fields from a list of tables. + -- @function project + -- @param fkey field to project + -- @tparam table tt a list of tables + -- @treturn table list of *fkey* fields from *tt* + -- @usage + -- --> {1, 3, "yy"} + -- project ("xx", {{"a", xx=1, yy="z"}, {"b", yy=2}, {"c", xx=3}, {xx="yy"}) + project = X ("project (any, list of tables)", project), + + --- Enhance core *table.remove* to respect `__len` when *pos* is omitted. + -- Also, diagnose out of bounds *pos* arguments consistently on any supported + -- version of Lua. + -- @function remove + -- @tparam table t a table + -- @int[opt=len (t)] pos index from which to remove an element + -- @return removed value, or else `nil` + -- @usage + -- --> {1, 2, 5} + -- t = {1, 2, "x", 5} + -- remove (t, 3) == "x" and t + remove = X ("remove (table, int?)", remove), + + --- Shape a table according to a list of dimensions. + -- + -- Dimensions are given outermost first and items from the original + -- list are distributed breadth first; there may be one 0 indicating + -- an indefinite number. Hence, `{0}` is a flat list, + -- `{1}` is a singleton, `{2, 0}` is a list of + -- two lists, and `{0, 2}` is a list of pairs. + -- + -- Algorithm: turn shape into all positive numbers, calculating + -- the zero if necessary and making sure there is at most one; + -- recursively walk the shape, adding empty tables until the bottom + -- level is reached at which point add table items instead, using a + -- counter to walk the flattened original list. + -- + -- @todo Use ileaves instead of flatten (needs a while instead of a + -- for in fill function) + -- @function shape + -- @tparam table dims table of dimensions `{d1, ..., dn}` + -- @tparam table t a table of elements + -- @return reshaped list + -- @usage + -- --> {{"a", "b"}, {"c", "d"}, {"e", "f"}} + -- shape ({3, 2}, {"a", "b", "c", "d", "e", "f"}) + shape = X ("shape (table, table)", shape), + + --- Find the number of elements in a table. + -- @function size + -- @tparam table t any table + -- @treturn int number of non-nil values in *t* + -- @usage + -- --> 3 + -- size {foo = true, bar = true, baz = false} + size = X ("size (table)", size), + + --- Enhance core *table.sort* to return its result. + -- @function sort + -- @tparam table t unsorted table + -- @tparam[opt=std.operator.lt] comparator c ordering function callback + -- @return *t* with keys sorted accordind to *c* + -- @usage table.concat (sort (object)) + sort = X ("sort (table, function?)", sort), + + --- Make the list of values of a table. + -- @function values + -- @tparam table t any table + -- @treturn table list of values in *t* + -- @see keys + -- @usage + -- --> {"a", "c", 42} + -- values {"a", b="c", [-1]=42} + values = X ("values (table)", values), } --- Deprecated and undocumented. -M.clone_rename = clone_rename -for k, v in pairs (table) do - M[k] = M[k] or v -end +monkeys = base.copy ({}, M) -- before deprecations and core merge + + +--[[ ============= ]]-- +--[[ Deprecations. ]]-- +--[[ ============= ]]-- + + +local DEPRECATED = debug.DEPRECATED + +M.clone_rename = DEPRECATED ("39", "'std.table.clone_rename'", + "use the new `map` argument to 'std.table.clone' instead", + function (map, t) + local r = merge_allfields ({}, t) + for i, v in pairs (map) do + r[v] = t[i] + r[i] = nil + end + return r + end) + + +M.metamethod = DEPRECATED ("41", "'std.table.metamethod'", + "use 'std.getmetamethod' instead", base.getmetamethod) + + +M.ripairs = DEPRECATED ("41", "'std.table.ripairs'", + "use 'std.ripairs' instead", base.ripairs) + + +M.totable = DEPRECATED ("41", "'std.table.totable'", + "use 'std.pairs' instead", + function (x) + local m = base.getmetamethod (x, "__totable") + if m then + return m (x) + elseif type (x) == "table" then + return x + elseif type (x) == "string" then + local t = {} + x:gsub (".", function (c) t[#t + 1] = c end) + return t + else + return nil + end + end) + + + +return base.merge (M, table) + + + +--- Types +-- @section Types -return M +--- Signature of a @{sort} comparator function. +-- @function comparator +-- @param a any object +-- @param b any object +-- @treturn boolean `true` if *a* sorts before *b*, otherwise `false` +-- @see sort +-- @usage +-- local reversor = function (a, b) return a > b end +-- sort (t, reversor) diff --git a/lib/std/tree.lua b/lib/std/tree.lua index 2776a78..91b7665 100644 --- a/lib/std/tree.lua +++ b/lib/std/tree.lua @@ -1,61 +1,62 @@ --[[-- - Tree container. - - Derived from @{std.container}, and inherits Container's metamethods. + Tree container prototype. Note that Functions listed below are only available from the Tree - prototype return by requiring this module, because Container objects + prototype returned by requiring this module, because Container objects cannot have object methods. + Prototype Chain + --------------- + + table + `-> Object + `-> Container + `-> Tree + @classmod std.tree @see std.container ]] local base = require "std.base" -local Container = require "std.container" -local list = require "std.list" -local func = require "std.functional" +local operator = require "std.operator" -local prototype = (require "std.object").prototype +local Container = require "std.container" {} -local Tree -- forward declaration +local ielems, ipairs, leaves, pairs, prototype = + base.ielems, base.ipairs, base.leaves, base.pairs, base.prototype +local last, len = base.last, base.len +local reduce = base.reduce +local Tree -- forward declaration ---- Tree iterator which returns just numbered leaves, in order. --- @function ileaves --- @static --- @tparam tree|table tr tree or tree-like table --- @treturn function iterator function --- @treturn tree|table the tree `tr` -local function ileaves (tr) - assert (type (tr) == "table", - "bad argument #1 to 'ileaves' (table expected, got " .. type (tr) .. ")") - return base.leaves (ipairs, tr) -end ---- Tree iterator which returns just leaves. --- @function leaves --- @static --- @tparam tree|table tr tree or tree-like table --- @treturn function iterator function --- @treturn tree|table the tree, `tr` -local function leaves (tr) - assert (type (tr) == "table", - "bad argument #1 to 'leaves' (table expected, got " .. type (tr) .. ")") - return base.leaves (pairs, tr) +--- Tree iterator. +-- @tparam function it iterator function +-- @tparam tree|table tr tree or tree-like table +-- @treturn string type ("leaf", "branch" (pre-order) or "join" (post-order)) +-- @treturn table path to node (`{i1, ...in}`) +-- @treturn node node +local function _nodes (it, tr) + local p = {} + local function visit (n) + if type (n) == "table" then + coroutine.yield ("branch", p, n) + for i, v in it (n) do + p[#p + 1] = i + visit (v) + table.remove (p) + end + coroutine.yield ("join", p, n) + else + coroutine.yield ("leaf", p, n) + end + end + return coroutine.wrap (visit), tr end ---- Make a deep copy of a tree, including any metatables. --- --- To make fast shallow copies, use @{std.table.clone}. --- @tparam table|tree t table or tree to be cloned --- @tparam boolean nometa if non-nil don't copy metatables --- @treturn table|tree a deep copy of `t` local function clone (t, nometa) - assert (type (t) == "table", - "bad argument #1 to 'clone' (table expected, got " .. type (t) .. ")") local r = {} if not nometa then setmetatable (r, getmetatable (t)) @@ -83,162 +84,198 @@ local function clone (t, nometa) end ---- Tree iterator. --- @tparam function it iterator function --- @tparam tree|table tr tree or tree-like table --- @treturn string type ("leaf", "branch" (pre-order) or "join" (post-order)) --- @treturn table path to node ({i\_1...i\_k}) --- @return node -local function _nodes (it, tr) - local p = {} - local function visit (n) - if type (n) == "table" then - coroutine.yield ("branch", p, n) - for i, v in it (n) do - p[#p + 1] = i - visit (v) - table.remove (p) - end - coroutine.yield ("join", p, n) - else - coroutine.yield ("leaf", p, n) +local function merge (t, u) + for ty, p, n in _nodes (pairs, u) do + if ty == "leaf" then + t[p] = n end end - return coroutine.wrap (visit), tr + return t end ---- Tree iterator over all nodes. --- --- The returned iterator function performs a depth-first traversal of --- `tr`, and at each node it returns `{node-type, tree-path, tree-node}` --- where `node-type` is `branch`, `join` or `leaf`; `tree-path` is a --- list of keys used to reach this node, and `tree-node` is the current --- node. --- --- Given a `tree` to represent: --- --- + root --- +-- node1 --- | +-- leaf1 --- | '-- leaf2 --- '-- leaf 3 --- --- tree = std.tree { std.tree { "leaf1", "leaf2"}, "leaf3" } --- --- A series of calls to `tree.nodes` will return: --- --- "branch", {}, {{"leaf1", "leaf2"}, "leaf3"} --- "branch", {1}, {"leaf1", "leaf"2") --- "leaf", {1,1}, "leaf1" --- "leaf", {1,2}, "leaf2" --- "join", {1}, {"leaf1", "leaf2"} --- "leaf", {2}, "leaf3" --- "join", {}, {{"leaf1", "leaf2"}, "leaf3"} --- --- Note that the `tree-path` reuses the same table on each iteration, so --- you must `table.clone` a copy if you want to take a snap-shot of the --- current state of the `tree-path` list before the next iteration --- changes it. --- @tparam tree|table tr tree or tree-like table to iterate over --- @treturn function iterator function --- @treturn tree|table the tree, `tr` --- @see inodes -local function nodes (tr) - assert (type (tr) == "table", - "bad argument #1 to 'nodes' (table expected, got " .. type (tr) .. ")") - return _nodes (pairs, tr) -end - ---- Tree iterator over numbered nodes, in order. --- --- The iterator function behaves like @{nodes}, but only traverses the --- array part of the nodes of `tr`, ignoring any others. --- @tparam tree|table tr tree to iterate over --- @treturn function iterator function --- @treturn tree|table the tree, `tr` --- @see nodes -local function inodes (tr) - assert (type (tr) == "table", - "bad argument #1 to 'inodes' (table expected, got " .. type (tr) .. ")") - return _nodes (ipairs, tr) -end +--[[ ============ ]]-- +--[[ Tree Object. ]]-- +--[[ ============ ]]-- ---- Destructively deep-merge one tree into another. --- @tparam tree|table t destination tree or table --- @tparam tree|table u tree or table with nodes to merge --- @treturn tree|table `t` with nodes from `u` merged in --- @see std.table.merge -local function merge (t, u) - assert (type (t) == "table", - "bad argument #1 to 'merge' (table expected, got " .. type (t) .. ")") - assert (type (u) == "table", - "bad argument #2 to 'merge' (table expected, got " .. type (u) .. ")") - for ty, p, n in nodes (u) do - if ty == "leaf" then - t[p] = n - end - end - return t +local function X (decl, fn) + return require "std.debug".argscheck ("std.tree." .. decl, fn) end --- Tree prototype object. --- @table std.tree --- @string[opt="Tree"] _type type of Tree, returned by --- @{std.object.prototype} --- @tfield[opt={}] table|function _init a table of field names, or --- initialisation function, see @{std.object.__call} --- @tfield nil|table _functions a table of module functions not copied --- by @{std.object.__call} +-- @object Tree +-- @string[opt="Tree"] _type object name +-- @see std.container +-- @see std.object.__call +-- @usage +-- local std = require "std" +-- local Tree = std.tree {} +-- local tr = Tree {} +-- tr[{"branch1", 1}] = "leaf1" +-- tr[{"branch1", 2}] = "leaf2" +-- tr[{"branch2", 1}] = "leaf3" +-- print (tr[{"branch1"}]) --> Tree {leaf1, leaf2} +-- print (tr[{"branch1", 2}]) --> leaf2 +-- print (tr[{"branch1", 3}]) --> nil +-- --> leaf1 leaf2 leaf3 +-- for leaf in std.tree.leaves (tr) do +-- io.write (leaf .. "\t") +-- end Tree = Container { - -- Derived object type. _type = "Tree", - --- Tree `__index` metamethod. + --- Deep retrieval. + -- @static -- @function __index - -- @param i non-table, or list of keys `{i\_1 ... i\_n}` - -- @return `self[i]...[i\_n]` if i is a table, or `self[i]` otherwise + -- @tparam Tree tr a tree + -- @param i non-table, or list of keys `{i1, ...i_n}` + -- @return `tr[i1]...[i_n]` if *i* is a key list, `tr[i]` otherwise -- @todo the following doesn't treat list keys correctly - -- e.g. self[{{1, 2}, {3, 4}}], maybe flatten first? - __index = function (self, i) - if prototype (i) == "table" then - return list.foldl (func.op["[]"], self, i) - else - return rawget (self, i) - end - end, + -- e.g. tr[{{1, 2}, {3, 4}}], maybe flatten first? + -- @usage + -- del_other_window = keymap[{"C-x", "4", KEY_DELETE}] + __index = X ("__index (Tree, any)", + function (tr, i) + if prototype (i) == "table" then + return reduce (operator.get, tr, ielems, i) + else + return rawget (tr, i) + end + end), - --- Tree `__newindex` metamethod. - -- - -- Sets `self[i\_1]...[i\_n] = v` if i is a table, or `self[i] = v` otherwise + --- Deep insertion. + -- @static -- @function __newindex - -- @param i non-table, or list of keys `{i\_1 ... i\_n}` - -- @param v value - __newindex = function (self, i, v) - if prototype (i) == "table" then - for n = 1, #i - 1 do - if prototype (self[i[n]]) ~= "Tree" then - rawset (self, i[n], Tree {}) - end - self = self[i[n]] - end - rawset (self, i[#i], v) - else - rawset (self, i, v) - end - end, + -- @tparam Tree tr a tree + -- @param i non-table, or list of keys `{i1, ...i_n}` + -- @param[opt] v value + -- @usage + -- function bindkey (keylist, fn) keymap[keylist] = fn end + __newindex = X ("__newindex (Tree, any, any?)", + function (tr, i, v) + if prototype (i) == "table" then + for n = 1, len (i) - 1 do + if prototype (tr[i[n]]) ~= "Tree" then + rawset (tr, i[n], Tree {}) + end + tr = tr[i[n]] + end + rawset (tr, last (i), v) + else + rawset (tr, i, v) + end + end), - --- @export _functions = { - clone = clone, - ileaves = ileaves, - inodes = inodes, - leaves = leaves, - merge = merge, - nodes = nodes, + --- Make a deep copy of a tree, including any metatables. + -- @static + -- @function clone + -- @tparam table t tree or tree-like table + -- @tparam boolean nometa if non-`nil` don't copy metatables + -- @treturn Tree|table a deep copy of *tr* + -- @see std.table.clone + -- @usage + -- tr = {"one", {two=2}, {{"three"}, four=4}} + -- copy = clone (tr) + -- copy[2].two=5 + -- assert (tr[2].two == 2) + clone = X ("clone (table, boolean|:nometa?)", clone), + + --- Tree iterator which returns just numbered leaves, in order. + -- @static + -- @function ileaves + -- @tparam Tree|table tr tree or tree-like table + -- @treturn function iterator function + -- @treturn Tree|table the tree *tr* + -- @see inodes + -- @see leaves + -- @usage + -- --> t = {"one", "three", "five"} + -- for leaf in ileaves {"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} + -- do + -- t[#t + 1] = leaf + -- end + ileaves = X ("ileaves (table)", function (t) return leaves (ipairs, t) end), + + --- Tree iterator over numbered nodes, in order. + -- + -- The iterator function behaves like @{nodes}, but only traverses the + -- array part of the nodes of *tr*, ignoring any others. + -- @static + -- @function inodes + -- @tparam Tree|table tr tree or tree-like table to iterate over + -- @treturn function iterator function + -- @treturn tree|table the tree, *tr* + -- @see nodes + inodes = X ("inodes (table)", function (t) return _nodes (ipairs, t) end), + + --- Tree iterator which returns just leaves. + -- @static + -- @function leaves + -- @tparam table t tree or tree-like table + -- @treturn function iterator function + -- @treturn table *t* + -- @see ileaves + -- @see nodes + -- @usage + -- for leaf in leaves {"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"} + -- do + -- t[#t + 1] = leaf + -- end + -- --> t = {2, 4, "five", "foo", "one", "three"} + -- table.sort (t, lambda "=tostring(_1) < tostring(_2)") + leaves = X ("leaves (table)", function (t) return leaves (pairs, t) end), + + --- Destructively deep-merge one tree into another. + -- @static + -- @function merge + -- @tparam table t destination tree + -- @tparam table u table with nodes to merge + -- @treturn table *t* with nodes from *u* merged in + -- @see std.table.merge + -- @usage + -- merge (dest, {{exists=1}, {{not = {present = { inside = "dest" }}}}}) + merge = X ("merge (table, table)", merge), + + --- Tree iterator over all nodes. + -- + -- The returned iterator function performs a depth-first traversal of + -- `tr`, and at each node it returns `{node-type, tree-path, tree-node}` + -- where `node-type` is `branch`, `join` or `leaf`; `tree-path` is a + -- list of keys used to reach this node, and `tree-node` is the current + -- node. + -- + -- Note that the `tree-path` reuses the same table on each iteration, so + -- you must `table.clone` a copy if you want to take a snap-shot of the + -- current state of the `tree-path` list before the next iteration + -- changes it. + -- @static + -- @function nodes + -- @tparam Tree|table tr tree or tree-like table to iterate over + -- @treturn function iterator function + -- @treturn Tree|table the tree, *tr* + -- @see inodes + -- @usage + -- -- tree = +-- node1 + -- -- | +-- leaf1 + -- -- | '-- leaf2 + -- -- '-- leaf 3 + -- tree = Tree { Tree { "leaf1", "leaf2"}, "leaf3" } + -- for node_type, path, node in nodes (tree) do + -- print (node_type, path, node) + -- end + -- --> "branch" {} {{"leaf1", "leaf2"}, "leaf3"} + -- --> "branch" {1} {"leaf1", "leaf"2") + -- --> "leaf" {1,1} "leaf1" + -- --> "leaf" {1,2} "leaf2" + -- --> "join" {1} {"leaf1", "leaf2"} + -- --> "leaf" {2} "leaf3" + -- --> "join" {} {{"leaf1", "leaf2"}, "leaf3"} + -- os.exit (0) + nodes = X ("nodes (table)", function (t) return _nodes (pairs, t) end), }, } diff --git a/local.mk b/local.mk index d0f7fdc..e3fdc97 100644 --- a/local.mk +++ b/local.mk @@ -1,6 +1,6 @@ # Local Make rules. # -# Copyright (C) 2013-2014 Gary V. Vaughan +# Copyright (C) 2013-2015 Gary V. Vaughan # Written by Gary V. Vaughan, 2013 # # This program is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ ## Environment. ## ## ------------ ## -std_path = $(abs_srcdir)/lib/?.lua +std_path = $(abs_srcdir)/lib/?.lua;$(abs_srcdir)/lib/?/init.lua LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" @@ -29,7 +29,7 @@ LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" ## Bootstrap. ## ## ---------- ## -old_NEWS_hash = 606609f9586288cfe6d9df676719570a +old_NEWS_hash = d41d8cd98f00b204e9800998ecf8427e update_copyright_env = \ UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ @@ -70,6 +70,7 @@ dist_luastd_DATA = \ lib/std/list.lua \ lib/std/math.lua \ lib/std/object.lua \ + lib/std/operator.lua \ lib/std/optparse.lua \ lib/std/package.lua \ lib/std/set.lua \ @@ -80,12 +81,11 @@ dist_luastd_DATA = \ lib/std/tree.lua \ $(NOTHING_ELSE) - # For bugwards compatibility with LuaRocks 2.1, while ensuring that # `require "std.debug_init"` continues to work, we have to install # the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. -# When everyone has upgraded to a LuaRocks that works, move this -# file back to dist_luastd_DATA above and rename to debug_init.lua. +# When LuaRocks works again, move this file back to dist_luastd_DATA +# above and rename to debug_init.lua. luastddebugdir = $(luastddir)/debug_init @@ -141,6 +141,7 @@ dist_modules_DATA += \ $(srcdir)/doc/modules/std.functional.html \ $(srcdir)/doc/modules/std.io.html \ $(srcdir)/doc/modules/std.math.html \ + $(srcdir)/doc/modules/std.operator.html \ $(srcdir)/doc/modules/std.package.html \ $(srcdir)/doc/modules/std.strict.html \ $(srcdir)/doc/modules/std.string.html \ diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4 deleted file mode 100644 index 74dc0fd..0000000 --- a/m4/ax_compare_version.m4 +++ /dev/null @@ -1,177 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_compare_version.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) -# -# DESCRIPTION -# -# This macro compares two version strings. Due to the various number of -# minor-version numbers that can exist, and the fact that string -# comparisons are not compatible with numeric comparisons, this is not -# necessarily trivial to do in a autoconf script. This macro makes doing -# these comparisons easy. -# -# The six basic comparisons are available, as well as checking equality -# limited to a certain number of minor-version levels. -# -# The operator OP determines what type of comparison to do, and can be one -# of: -# -# eq - equal (test A == B) -# ne - not equal (test A != B) -# le - less than or equal (test A <= B) -# ge - greater than or equal (test A >= B) -# lt - less than (test A < B) -# gt - greater than (test A > B) -# -# Additionally, the eq and ne operator can have a number after it to limit -# the test to that number of minor versions. -# -# eq0 - equal up to the length of the shorter version -# ne0 - not equal up to the length of the shorter version -# eqN - equal up to N sub-version levels -# neN - not equal up to N sub-version levels -# -# When the condition is true, shell commands ACTION-IF-TRUE are run, -# otherwise shell commands ACTION-IF-FALSE are run. The environment -# variable 'ax_compare_version' is always set to either 'true' or 'false' -# as well. -# -# Examples: -# -# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) -# AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) -# -# would both be true. -# -# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) -# AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) -# -# would both be false. -# -# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) -# -# would be true because it is only comparing two minor versions. -# -# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) -# -# would be true because it is only comparing the lesser number of minor -# versions of the two values. -# -# Note: The characters that separate the version numbers do not matter. An -# empty string is the same as version 0. OP is evaluated by autoconf, not -# configure, so must be a string, not a variable. -# -# The author would like to acknowledge Guido Draheim whose advice about -# the m4_case and m4_ifvaln functions make this macro only include the -# portions necessary to perform the specific comparison specified by the -# OP argument in the final configure script. -# -# LICENSE -# -# Copyright (c) 2008 Tim Toolan -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 11 - -dnl ######################################################################### -AC_DEFUN([AX_COMPARE_VERSION], [ - AC_REQUIRE([AC_PROG_AWK]) - - # Used to indicate true or false condition - ax_compare_version=false - - # Convert the two version strings to be compared into a format that - # allows a simple string comparison. The end result is that a version - # string of the form 1.12.5-r617 will be converted to the form - # 0001001200050617. In other words, each number is zero padded to four - # digits, and non digits are removed. - AS_VAR_PUSHDEF([A],[ax_compare_version_A]) - A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ - -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/[[^0-9]]//g'` - - AS_VAR_PUSHDEF([B],[ax_compare_version_B]) - B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ - -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/[[^0-9]]//g'` - - dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary - dnl # then the first line is used to determine if the condition is true. - dnl # The sed right after the echo is to remove any indented white space. - m4_case(m4_tolower($2), - [lt],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` - ], - [gt],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` - ], - [le],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` - ], - [ge],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` - ],[ - dnl Split the operator from the subversion count if present. - m4_bmatch(m4_substr($2,2), - [0],[ - # A count of zero means use the length of the shorter version. - # Determine the number of characters in A and B. - ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` - ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` - - # Set A to no more than B's length and B to no more than A's length. - A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` - B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` - ], - [[0-9]+],[ - # A count greater than zero means use only that many subversions - A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` - B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` - ], - [.+],[ - AC_WARNING( - [illegal OP numeric parameter: $2]) - ],[]) - - # Pad zeros at end of numbers to make same length. - ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" - B="$B`echo $A | sed 's/./0/g'`" - A="$ax_compare_version_tmp_A" - - # Check for equality or inequality as necessary. - m4_case(m4_tolower(m4_substr($2,0,2)), - [eq],[ - test "x$A" = "x$B" && ax_compare_version=true - ], - [ne],[ - test "x$A" != "x$B" && ax_compare_version=true - ],[ - AC_WARNING([illegal OP parameter: $2]) - ]) - ]) - - AS_VAR_POPDEF([A])dnl - AS_VAR_POPDEF([B])dnl - - dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. - if test "$ax_compare_version" = "true" ; then - m4_ifvaln([$4],[$4],[:])dnl - m4_ifvaln([$5],[else $5])dnl - fi -]) dnl AX_COMPARE_VERSION diff --git a/m4/ax_lua.m4 b/m4/ax_lua.m4 index f158253..15376af 100644 --- a/m4/ax_lua.m4 +++ b/m4/ax_lua.m4 @@ -55,9 +55,6 @@ # version number greater or equal to MINIMUM-VERSION and less than # TOO-BIG-VERSION will be accepted. # -# Version comparisons require the AX_COMPARE_VERSION macro, which is -# provided by ax_compare_version.m4 from the Autoconf Archive. -# # The Lua version number, LUA_VERSION, is found from the interpreter, and # substituted. LUA_PLATFORM is also found, but not currently supported (no # standard representation). @@ -109,6 +106,7 @@ # * /usr/include/lua/X.Y # * /usr/include/luaXY # * /usr/local/include/luaX.Y +# * /usr/local/include/lua-X.Y # * /usr/local/include/lua/X.Y # * /usr/local/include/luaXY # @@ -153,8 +151,8 @@ # # LICENSE # +# Copyright (c) 2014 Reuben Thomas # Copyright (c) 2013 Tim Perkins -# Copyright (c) 2013 Reuben Thomas # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -182,7 +180,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 20 +#serial 28 dnl ========================================================================= dnl AX_PROG_LUA([MINIMUM-VERSION], [TOO-BIG-VERSION], @@ -195,7 +193,7 @@ AC_DEFUN([AX_PROG_LUA], dnl Find a Lua interpreter. m4_define_default([_AX_LUA_INTERPRETER_LIST], - [lua lua5.2 lua5.1 lua50]) + [lua lua5.2 lua52 lua5.1 lua51 lua50]) m4_if([$1], [], [ dnl No version check is needed. Find any Lua interpreter. @@ -257,10 +255,7 @@ AC_DEFUN([AX_PROG_LUA], ], [ dnl Query Lua for its version number. AC_CACHE_CHECK([for $ax_display_LUA version], [ax_cv_lua_version], - [ ax_cv_lua_version=`$LUA -e "print(_VERSION)" | \ - sed "s|^Lua \(.*\)|\1|" | \ - grep -o "^@<:@0-9@:>@\+\\.@<:@0-9@:>@\+"` - ]) + [ ax_cv_lua_version=`$LUA -e 'print(_VERSION:match "(%d+%.%d+)")'` ]) AS_IF([test "x$ax_cv_lua_version" = 'x'], [AC_MSG_ERROR([invalid Lua version number])]) AC_SUBST([LUA_VERSION], [$ax_cv_lua_version]) @@ -322,7 +317,7 @@ AC_DEFUN([AX_PROG_LUA], dnl Try to find a path with the prefix. _AX_LUA_FND_PRFX_PTH([$LUA], - [$ax_lua_exec_prefix], [package.cpathd]) + [$ax_lua_exec_prefix], [package.cpath]) AS_IF([test "x$ax_lua_prefixed_path" != 'x'], [ dnl Fix the prefix. _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | sed 's|.|.|g'` @@ -352,7 +347,7 @@ dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_IS_INTRP], [ dnl Just print _VERSION because all Lua interpreters have this global. - AS_IF([$1 -e "print('Hello ' .. _VERSION .. '!')" &>/dev/null], + AS_IF([$1 -e "print('Hello ' .. _VERSION .. '!')" >/dev/null 2>&1], [$2], [$3]) ]) @@ -363,16 +358,13 @@ dnl [ACTION-IF-TRUE], [ACTION-IF-FALSE]) dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_VER], [ - _ax_test_ver=`$1 -e "print(_VERSION)" 2>/dev/null | \ - sed "s|^Lua \(.*\)|\1|" | grep -o "^@<:@0-9@:>@\+\\.@<:@0-9@:>@\+"` - AS_IF([test "x$_ax_test_ver" = 'x'], - [_ax_test_ver='0']) - AX_COMPARE_VERSION([$_ax_test_ver], [ge], [$2]) - m4_if([$3], [], [], - [ AS_IF([$ax_compare_version], - [AX_COMPARE_VERSION([$_ax_test_ver], [lt], [$3])]) - ]) - AS_IF([$ax_compare_version], [$4], [$5]) + AS_IF([$1 2>/dev/null -e ' + function norm (v) + i,j=v:match "(%d+)%.(%d+)" if i then return 100 * i + j end + end + v, toobig=norm (_VERSION), norm "$3" or math.huge + os.exit ((v >= norm ("$2") and v < toobig) and 0 or 1)'], + [$4], [$5]) ]) @@ -383,28 +375,19 @@ AC_DEFUN([_AX_LUA_FND_PRFX_PTH], [ dnl Invokes the Lua interpreter PROG to print the path variable dnl LUA-PATH-VARIABLE, usually package.path or package.cpath. Paths are - dnl then matched against PREFIX. The first path to begin with PREFIX is set - dnl to ax_lua_prefixed_path. - - ax_lua_prefixed_path='' - _ax_package_paths=`$1 -e 'print($3)' 2>/dev/null | sed 's|;|\n|g'` - dnl Try the paths in order, looking for the prefix. - for _ax_package_path in $_ax_package_paths; do - dnl Copy the path, up to the use of a Lua wildcard. - _ax_path_parts=`echo "$_ax_package_path" | sed 's|/|\n|g'` - _ax_reassembled='' - for _ax_path_part in $_ax_path_parts; do - echo "$_ax_path_part" | grep '\?' >/dev/null && break - _ax_reassembled="$_ax_reassembled/$_ax_path_part" - done - dnl Check the path against the prefix. - _ax_package_path=$_ax_reassembled - if echo "$_ax_package_path" | grep "^$2" >/dev/null; then - dnl Found it. - ax_lua_prefixed_path=$_ax_package_path - break - fi - done + dnl then matched against PREFIX. Then ax_lua_prefixed_path is set to the + dnl shortest sub path beginning with PREFIX up to the last directory + dnl that does not contain a '?', if any. + + ax_lua_prefixed_path=`$1 2>/dev/null -e ' + $3:gsub ("(@<:@^;@:>@+)", + function (p) + p = p:gsub ("%?.*$", ""):gsub ("/@<:@^/@:>@*$", "") + if p:match ("^$2") and (not shortest or #shortest > #p) then + shortest = p + end + end) + print (shortest or "")'` ]) @@ -431,6 +414,7 @@ AC_DEFUN([AX_LUA_HEADERS], /usr/include/lua/$LUA_VERSION \ /usr/include/lua$LUA_SHORT_VERSION \ /usr/local/include/lua$LUA_VERSION \ + /usr/local/include/lua-$LUA_VERSION \ /usr/local/include/lua/$LUA_VERSION \ /usr/local/include/lua$LUA_SHORT_VERSION \ ]) @@ -490,7 +474,7 @@ int main(int argc, char ** argv) ], [ ax_cv_lua_header_version=`./conftest$EXEEXT p | \ sed "s|^Lua \(.*\)|\1|" | \ - grep -o "^@<:@0-9@:>@\+\\.@<:@0-9@:>@\+"` + grep -E -o "^@<:@0-9@:>@+\.@<:@0-9@:>@+"` ], [ax_cv_lua_header_version='unknown']) CPPFLAGS=$_ax_lua_saved_cppflags @@ -578,10 +562,15 @@ AC_DEFUN([AX_LUA_LIBS], dnl Try to find the Lua libs. _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" - AC_SEARCH_LIBS([lua_load], [lua$LUA_VERSION lua$LUA_SHORT_VERSION lua], - [_ax_found_lua_libs='yes'], - [_ax_found_lua_libs='no'], - [$_ax_lua_extra_libs]) + AC_SEARCH_LIBS([lua_load], + [ lua$LUA_VERSION \ + lua$LUA_SHORT_VERSION \ + lua-$LUA_VERSION \ + lua-$LUA_SHORT_VERSION \ + lua], + [_ax_found_lua_libs='yes'], + [_ax_found_lua_libs='no'], + [$_ax_lua_extra_libs]) LIBS=$_ax_lua_saved_libs AS_IF([test "x$ac_cv_search_lua_load" != 'xno' && diff --git a/m4/slingshot.m4 b/m4/slingshot.m4 deleted file mode 100644 index 541f8f5..0000000 --- a/m4/slingshot.m4 +++ /dev/null @@ -1,42 +0,0 @@ -dnl slingshot.m4 -dnl -dnl Copyright (c) 2013-2014 Free Software Foundation, Inc. -dnl Written by Gary V. Vaughan, 2013 -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published -dnl by the Free Software Foundation; either version 3, or (at your -dnl option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program. If not, see . - -# SS_CONFIG_TRAVIS(LUAROCKS) -# -------------------------- -# Generate .travis.yml, ensuring LUAROCKS are installed. -AC_DEFUN([SS_CONFIG_TRAVIS], [ - # is required by all slingshot clients for mkrockspecs. - EXTRA_ROCKS=- - for _ss_rock in lyaml $1; do - case $EXTRA_ROCKS in - *" $_ss_rock;"*) ;; # ignore duplicates - *) - test "x$PACKAGE_NAME" != "x$_ss_rock" \ - && EXTRA_ROCKS="$EXTRA_ROCKS"' $LUAROCKS install '"$_ss_rock;" - ;; - esac - done - - # Avoid empty travis commands. - test "x$EXTRA_ROCKS" != "x-" || EXTRA_ROCKS='# No extra rocks needed here;' - - AC_SUBST([EXTRA_ROCKS]) - AC_CONFIG_FILES([.travis.yml:travis.yml.in], [ - # Remove trailing blanks so as not to trip sc_trailing_blank in syntax check - sed 's| *$||' < .travis.yml > ss_tmp && mv ss_tmp .travis.yml; rm -f ss_tmp]) -]) diff --git a/rockspec.conf b/rockspec.conf index 3376ac9..397ad26 100644 --- a/rockspec.conf +++ b/rockspec.conf @@ -10,7 +10,7 @@ description: pickling, pretty-printing and command-line option parsing. dependencies: -- lua >= 5.1 +- lua >= 5.1, < 5.4 source: url: git://github.com/lua-stdlib/lua-stdlib.git diff --git a/specs/base_spec.yaml b/specs/base_spec.yaml deleted file mode 100644 index cae43d1..0000000 --- a/specs/base_spec.yaml +++ /dev/null @@ -1,49 +0,0 @@ -before: - base = require "std.base" - -specify std.base: -- describe deprecate: - - before: | - deprecate = base.deprecate - - function runscript (body, name, args) - return luaproc ( - "require 'std.base'.deprecate (function (...)" .. - " " .. body .. - " end, '" .. (name or "runscript") .. "') " .. - "('" .. table.concat (args or {}, "', '") .. "')" - ) - end - - it diagnoses missing arguments: - expect (deprecate ()).to_error "missing argument" - - it returns a function: - f = deprecate (base.clone_rename, "clone_rename") - expect (type (f)).to_be "function" - - context with deprecated function: - - it executes the deprecated function: - expect (runscript 'error "oh noes!"').to_contain_error "oh noes!" - - it passes arguments to the deprecated function: - expect (runscript ("print (table.concat ({...}, ', '))", nil, - {"foo", "bar", "baz"})).to_output "foo, bar, baz\n" - - it returns deprecated function results: - script = [[ - deprecate = require "std.base".deprecate - fn = deprecate (function () return "foo", "bar", "baz" end, "fn") - print (fn ()) - ]] - expect (luaproc (script)).to_output "foo\tbar\tbaz\n" - - it writes a warning to stderr: - expect (runscript 'error "oh noes!"'). - to_contain_error "deprecated, and will go away" - - it writes the call location to stderr: | - expect (runscript 'error "oh noes!"'). - to_match_error "^%S+:1: " - - it does not repeat the warning on additional calls: - script = [[ - deprecate = require "std.base".deprecate - fn = deprecate (function () error "oh noes!" end, "fn") - fn () -- line 3 - fn () -- line 4 - ]] - expect (luaproc (script)). - not_to_match_error "^%S+:3:.*deprecated.*\n%S+:4:.*deprecated" diff --git a/specs/container_spec.yaml b/specs/container_spec.yaml index 9e8d85c..8f1c333 100644 --- a/specs/container_spec.yaml +++ b/specs/container_spec.yaml @@ -1,6 +1,6 @@ before: - Container = require "std.container" - prototype = (require "std.object").prototype + Container = require "std.container" {} + prototype = require "std.object".prototype specify std.container: - context when required: @@ -10,6 +10,21 @@ specify std.container: to_equal {} - describe construction: + - context with table _init: + - it diagnoses missing arguments: | + expect (Container ()). + to_raise "bad argument #1 to 'Container' (table expected, got no value)" + - it diagnoses too many arguments: | + expect (Container ({}, false)). + to_raise "bad argument #2 to 'Container' (no more than 1 argument expected, got 2)" + - context with function _init: + - before: + Thing = Container { _type = "Thing", _init = function (obj) return obj end } + - it doesn't diagnose missing arguments: + expect (Thing ()).not_to_raise "any error" + - it doesn't diagnose too many args: + expect (Thing ({}, false)).not_to_raise "any error" + - context from Container prototype: - before: things = Container {"foo", "bar", baz="quux"} @@ -37,10 +52,11 @@ specify std.container: expect (getmetatable (things)._baz).to_be "quux" - context with module functions: - before: - fold = (require "std.functional").fold + reduce = require "std.functional".reduce + elems = require "std".elems functions = { count = function (bag) - return fold (function (r, k) return r + bag[k] end, 0, pairs, bag) + return reduce (function (r, k) return r + k end, 0, elems, bag) end, } Bag = Container { @@ -51,7 +67,10 @@ specify std.container: expect (things.count).to_be (nil) - it does not provide object methods: | things = Bag {} - expect (things:count ()).to_error "attempt to call method 'count'" + expect (things:count ()).to_raise.any_of { + "attempt to call method 'count'", + "attempt to call a nil value (method 'count'" + } - it does retain module functions: things = Bag { apples = 1, oranges = 3 } expect (Bag.count (things)).to_be (4) @@ -99,15 +118,3 @@ specify std.container: not_to_contain ";" expect (tostring (things {one = true, two = true, three = true})). to_contain ";" - - -- describe tablification: - - before: - totable = (require "std.table").totable - Derived = Container {_type = "Derived", "one", "two", three = true} - - it returns a table: - expect (prototype (totable (Derived))).to_be "table" - - it contains all non-hidden fields of container: - expect (totable (Derived)).to_contain.all_of {"one", "two", "three"} - - it does not contain any hidden fields of container: - expect (totable (Derived)).to_equal {"one", "two", three = true} diff --git a/specs/debug_spec.yaml b/specs/debug_spec.yaml index 2520d5c..970a56a 100644 --- a/specs/debug_spec.yaml +++ b/specs/debug_spec.yaml @@ -3,9 +3,11 @@ before: | this_module = "std.debug" global_table = "_G" - extend_base = { "say", "trace" } + extend_base = { "DEPRECATED", "DEPRECATIONMSG", "argcheck", "argerror", + "argscheck", "say", "toomanyargmsg", "trace", + "_setdebug" } - M = require "std.debug" + M = require (this_module) specify std.debug: - context when required: @@ -29,13 +31,785 @@ specify std.debug: to_equal {} -- describe _DEBUG: +- describe DEPRECATED: + - before: | + function runscript (body, name, args) + return luaproc ( + "require '" .. this_module .. "'.DEPRECATED ('0', '" .. + (name or "runscript") .. "', function (...)" .. + " " .. body .. + " end) " .. + "('" .. table.concat (args or {}, "', '") .. "')" + ) + end + + f, badarg = init (M, this_module, "DEPRECATED") + + - it returns a function: + expect (type (f ("0", "deprecated", nop))).to_be "function" + expect (f ("0", "deprecated", nop)).not_to_be (nop) + - context with deprecated function: + - it executes the deprecated function: + expect (runscript 'error "oh noes!"').to_contain_error "oh noes!" + - it passes arguments to the deprecated function: + expect (runscript ("print (table.concat ({...}, ', '))", nil, + {"foo", "bar", "baz"})).to_output "foo, bar, baz\n" + - it returns deprecated function results: | + script = [[ + DEPRECATED = require "std.debug".DEPRECATED + fn = DEPRECATED ("0", "fn", function () return "foo", "bar", "baz" end) + print (fn ()) + ]] + expect (luaproc (script)).to_output "foo\tbar\tbaz\n" + - it writes a warning to stderr: + expect (runscript 'error "oh noes!"'). + to_match_error "deprecated.*, and will be removed" + - it writes the version string to stderr: + expect (runscript 'error "oh noes!"'). + to_contain_error "in release 0" + - it writes the call location to stderr: | + expect (runscript 'error "oh noes!"'). + to_match_error "^%S+:1: " + - context with _DEBUG: + - before: | + script = [[ + DEPRECATED = require "]] .. this_module .. [[".DEPRECATED + fn = DEPRECATED ("0", "fn", function () io.stderr:write "oh noes!\n" end) + fn () -- line 3 + fn () -- line 4 + ]] + - it warns every call by default: + expect (luaproc (script)).to_match_error "^%S+:3:.*deprecated" + expect (luaproc (script)).to_match_error "\n%S+:4:.*deprecated" + - it does not warn at all with _DEBUG set to false: + script = "_DEBUG = false " .. script + expect (luaproc (script)).not_to_match_error "%d:.*deprecated" + - it does not define the function with _DEBUG set to true: | + script = "_DEBUG = true " .. script + expect (luaproc (script)).to_contain_error.any_of { + ":3: attempt to call global 'fn'", + ":3: attempt to call a nil value (global 'fn')", + } + - it warns on every call with _DEBUG.deprecate unset: + script = "_DEBUG = {} " .. script + expect (luaproc (script)).to_match_error "^%S+:3:.*deprecated" + expect (luaproc (script)).to_match_error "\n%S+:4:.*deprecated" + - it does not warn at all with _DEBUG.deprecate set to false: + script = "_DEBUG = { deprecate = false } " .. script + expect (luaproc (script)).not_to_match_error "%d:.*deprecated" + - it warns on every call with _DEBUG.deprecate set to true: | + script = "_DEBUG = { deprecate = true } " .. script + expect (luaproc (script)).to_contain_error.any_of { + ":3: attempt to call global 'fn'", + ":3: attempt to call a nil value (global 'fn')", + } + + +- describe DEPRECATIONMSG: + - before: | + function mkscript (lvl) + return [[ + DEPRECATIONMSG = require "]] .. this_module .. [[".DEPRECATIONMSG + function fn () + io.stderr:write (DEPRECATIONMSG ("42", "spec file", ]] .. lvl .. [[)) + end + fn () -- line 5 + fn () -- line 6 + ]] + end + + f = M.DEPRECATIONMSG + + - it contains deprecating the release version: + expect (f ("41", "foo", 2)).to_contain "41" + - it contains the deprecation function name: + expect (f ("41", "some.module.fname", 2)).to_contain "some.module.fname" + - it appends an optional extra message: + expect (f ("41", "wuh", "ah boo", 2)).to_contain ", ah boo." + - it blames the given stack level: + expect (luaproc (mkscript (1))).to_match_error "^%S+:3:.*deprecated" + expect (luaproc (mkscript (2))).to_match_error "^%S+:5:.*deprecated" + + +- describe argerror: + - before: | + function mkstack (level) + return string.format ([[ + _DEBUG = true -- line 1 + local debug = require "std.debug" -- line 2 + function ohnoes () -- line 3 + debug.argerror ("ohnoes", 1, nil, %s) -- line 4 + end -- line 5 + function caller () -- line 6 + local r = ohnoes () -- line 7 + return "not a tail call" -- line 8 + end -- line 9 + caller () -- line 10 + ]], tostring (level)) + end + + f, badarg = init (M, this_module, "argerror") + + - it diagnoses missing arguments: + pending "Lua 5.1 support is dropped" + expect (f ()).to_raise (badarg (1, "string")) + expect (f "foo").to_raise (badarg (2, "int")) + - it diagnoses wrong argument types: + pending "Lua 5.1 support is dropped" + expect (f (false)).to_raise (badarg (1, "string", "boolean")) + expect (f ("foo", false)).to_raise (badarg (2, "int", "boolean")) + expect (f ("foo", 1, false)). + to_raise (badarg (3, "string or nil", "boolean")) + expect (f ("foo", 1, "bar", false)). + to_raise (badarg (4, "int or nil", "boolean")) + - it diagnoses too many arguments: + pending "Lua 5.1 support is dropped" + expect (f ("foo", 1, "bar", 2, false)).to_raise (badarg (5)) + + - it blames the call site by default: | + expect (luaproc (mkstack ())).to_contain_error ":4: bad argument" + - it honors optional call stack level reporting: | + expect (luaproc (mkstack (1))).to_contain_error ":4: bad argument" + expect (luaproc (mkstack (2))).to_contain_error ":7: bad argument" + - it reports the calling function name: + expect (f ('expect', 1)).to_raise "'expect'" + - it reports the argument number: | + expect (f ('expect', 12345)).to_raise "#12345" + - it reports extra message in parentheses: + expect (f ('expect', 1, "extramsg")).to_raise " (extramsg)" + + +- describe argcheck: + - before: | + Object = require 'std.object' + List = Object { _type = "List" } + Foo = Object { _type = "Foo" } + + function fn (...) return M.argcheck ('expect', 1, ...) end + + function mkstack (level, debugp) + return string.format ([[ + _DEBUG = %s -- line 1 + local debug = require "std.debug" -- line 2 + function ohnoes (t) -- line 3 + debug.argcheck ("ohnoes", 1, "table", t, %s) -- line 4 + end -- line 5 + function caller () -- line 6 + local r = ohnoes "not a table" -- line 7 + return "not a tail call" -- line 8 + end -- line 9 + caller () -- line 10 + ]], tostring (debugp), tostring (level)) + end + + f, badarg = init (M, this_module, "argcheck") + + - it diagnoses missing arguments: + pending "Lua 5.1 support is dropped" + expect (f ()).to_raise (badarg (1, "string")) + expect (f "foo").to_raise (badarg (2, "int")) + expect (f ("foo", 1)).to_raise (badarg (3, "string")) + - it diagnoses wrong argument types: + pending "Lua 5.1 support is dropped" + expect (f (false)).to_raise (badarg (1, "string", "boolean")) + expect (f ("foo", false)).to_raise (badarg (2, "int", "boolean")) + expect (f ("foo", 1, false)).to_raise (badarg (3, "string", "boolean")) + expect (f ("foo", 1, "bar", 2, false)). + to_raise (badarg (5, "int or nil", "boolean")) + - it diagnoses too many arguments: + pending "Lua 5.1 support is dropped" + expect (f ("foo", 1, "bar", 2, 3, false)).to_raise (badarg (6)) + + - it blames the calling function by default: | + expect (luaproc (mkstack ())).to_contain_error ":7: bad argument" + - it honors optional call stack level reporting: | + expect (luaproc (mkstack (1))).to_contain_error ":4: bad argument" + expect (luaproc (mkstack (2))).to_contain_error ":7: bad argument" + expect (luaproc (mkstack (3))).to_contain_error ":10: bad argument" + - it can be disabled by setting _DEBUG to false: + expect (luaproc (mkstack (nil, false))). + not_to_contain_error "bad argument" + - it can be disabled by setting _DEBUG.argcheck to false: + expect (luaproc (mkstack (nil, "{ argcheck = false }"))). + not_to_contain_error "bad argument" + - it is not disabled by setting _DEBUG.argcheck to true: + expect (luaproc (mkstack (nil, "{ argcheck = true }"))). + to_contain_error "bad argument" + - it is not disabled by leaving _DEBUG.argcheck unset: + expect (luaproc (mkstack (nil, "{}"))). + to_contain_error "bad argument" + + - context with primitives: + - it diagnoses missing types: + expect (fn ("boolean", nil)).to_raise "boolean expected, got no value" + expect (fn ("file", nil)).to_raise "FILE* expected, got no value" + expect (fn ("number", nil)).to_raise "number expected, got no value" + expect (fn ("string", nil)).to_raise "string expected, got no value" + expect (fn ("table", nil)).to_raise "table expected, got no value" + - it diagnoses mismatched types: + expect (fn ("boolean", {0})).to_raise "boolean expected, got table" + expect (fn ("file", {0})).to_raise "FILE* expected, got table" + expect (fn ("number", {0})).to_raise "number expected, got table" + expect (fn ("string", {0})).to_raise "string expected, got table" + expect (fn ("table", false)).to_raise "table expected, got boolean" + - it matches types: + expect (fn ("boolean", true)).not_to_raise "any error" + expect (fn ("file", io.stderr)).not_to_raise "any error" + expect (fn ("number", 1)).not_to_raise "any error" + expect (fn ("string", "s")).not_to_raise "any error" + expect (fn ("table", {})).not_to_raise "any error" + expect (fn ("table", require "std.object")).not_to_raise "any error" + + - context with int: + - it diagnoses missing types: + expect (fn ("int", nil)).to_raise "int expected, got no value" + - it diagnoses mismatched types: + expect (fn ("int", false)).to_raise "int expected, got boolean" + expect (fn ("int", 1.234)).to_raise "int expected, got number" + expect (fn ("int", 1234e-3)).to_raise "int expected, got number" + - it matches types: + expect (fn ("int", 1)).not_to_raise "any error" + expect (fn ("int", 1.0)).not_to_raise "any error" + expect (fn ("int", 0x1234)).not_to_raise "any error" + expect (fn ("int", 1.234e3)).not_to_raise "any error" + - context with constant string: + - it diagnoses missing types: + expect (fn (":foo", nil)).to_raise ":foo expected, got no value" + - it diagnoses mismatched types: + expect (fn (":foo", false)).to_raise ":foo expected, got boolean" + expect (fn (":foo", ":bar")).to_raise ":foo expected, got :bar" + expect (fn (":foo", "foo")).to_raise ":foo expected, got string" + - it matches types: + expect (fn (":foo", ":foo")).not_to_raise "any error" + - context with callable types: + - it diagnoses missing types: + expect (fn ("function", nil)).to_raise "function expected, got no value" + - it diagnoses mismatched types: + expect (fn ("function", {0})).to_raise "function expected, got table" + - it matches types: + expect (fn ("function", function () end)).not_to_raise "any error" + expect (fn ("function", setmetatable ({}, {__call = function () end}))). + not_to_raise "any error" + - context with table of homogenous elements: + - it diagnoses missing types: + expect (fn ("table of boolean", nil)). + to_raise "table expected, got no value" + expect (fn ("table of booleans", nil)). + to_raise "table expected, got no value" + - it diagnoses mismatched types: + expect (fn ("table of file", io.stderr)). + to_raise "table expected, got file" + expect (fn ("table of files", io.stderr)). + to_raise "table expected, got file" + - it diagnoses mismatched element types: + expect (fn ("table of number", {false})). + to_raise "table of numbers expected, got boolean at index 1" + expect (fn ("table of numbers", {1, 2, "3"})). + to_raise "table of numbers expected, got string at index 3" + expect (fn ("table of numbers", {a=1, b=2, c="3"})). + to_raise "table of numbers expected, got string at index c" + - it matches types: + expect (fn ("table of string", {})).not_to_raise "any error" + expect (fn ("table of string", {"foo"})).not_to_raise "any error" + expect (fn ("table of string", {"f", "o", "o"})).not_to_raise "any error" + expect (fn ("table of string", {b="b", a="a", r="r"})).not_to_raise "any error" + - context with non-empty table types: + - it diagnoses missing types: + expect (fn ("#table", nil)). + to_raise "non-empty table expected, got no value" + - it diagnoses mismatched types: + expect (fn ("#table", false)). + to_raise "non-empty table expected, got boolean" + expect (fn ("#table", {})). + to_raise "non-empty table expected, got empty table" + - it matches types: + expect (fn ("#table", {0})).not_to_raise "any error" + - context with non-empty table of homogenous elements: + - it diagnoses missing types: + expect (fn ("#table of boolean", nil)). + to_raise "non-empty table expected, got no value" + expect (fn ("#table of booleans", nil)). + to_raise "non-empty table expected, got no value" + - it diagnoses mismatched types: + expect (fn ("#table of file", {})). + to_raise "non-empty table expected, got empty table" + expect (fn ("#table of file", io.stderr)). + to_raise "non-empty table expected, got file" + - it diagnoses mismatched element types: + expect (fn ("#table of number", {false})). + to_raise "non-empty table of numbers expected, got boolean at index 1" + expect (fn ("#table of numbers", {1, 2, "3"})). + to_raise "non-empty table of numbers expected, got string at index 3" + expect (fn ("#table of numbers", {a=1, b=2, c="3"})). + to_raise "non-empty table of numbers expected, got string at index c" + - it matches types: + expect (fn ("#table of string", {"foo"})).not_to_raise "any error" + expect (fn ("#table of string", {"f", "o", "o"})).not_to_raise "any error" + expect (fn ("#table of string", {b="b", a="a", r="r"})).not_to_raise "any error" + - context with list: + - it diagnonses missing types: + expect (fn ("list", nil)). + to_raise "list expected, got no value" + - it diagnoses mismatched types: + expect (fn ("list", false)). + to_raise "list expected, got boolean" + expect (fn ("list", {foo=1})). + to_raise "list expected, got table" + expect (fn ("list", Object)). + to_raise "list expected, got Object" + - it matches types: + expect (fn ("list", {})).not_to_raise "any error" + expect (fn ("list", {1})).not_to_raise "any error" + - context with list of homogenous elements: + - it diagnoses missing types: + expect (fn ("list of boolean", nil)). + to_raise "list expected, got no value" + expect (fn ("list of booleans", nil)). + to_raise "list expected, got no value" + - it diagnoses mismatched types: + expect (fn ("list of file", io.stderr)). + to_raise "list expected, got file" + expect (fn ("list of files", io.stderr)). + to_raise "list expected, got file" + expect (fn ("list of files", {file=io.stderr})). + to_raise "list expected, got table" + - it diagnoses mismatched element types: + expect (fn ("list of number", {false})). + to_raise "list of numbers expected, got boolean at index 1" + expect (fn ("list of numbers", {1, 2, "3"})). + to_raise "list of numbers expected, got string at index 3" + - it matches types: + expect (fn ("list of string", {})).not_to_raise "any error" + expect (fn ("list of string", {"foo"})).not_to_raise "any error" + expect (fn ("list of string", {"f", "o", "o"})).not_to_raise "any error" + - context with non-empty list: + - it diagnonses missing types: + expect (fn ("#list", nil)). + to_raise "non-empty list expected, got no value" + - it diagnoses mismatched types: + expect (fn ("#list", false)). + to_raise "non-empty list expected, got boolean" + expect (fn ("#list", {})). + to_raise "non-empty list expected, got empty list" + expect (fn ("#list", {foo=1})). + to_raise "non-empty list expected, got table" + expect (fn ("#list", Object)). + to_raise "non-empty list expected, got empty Object" + expect (fn ("#list", List {})). + to_raise "non-empty list expected, got empty List" + - it matches types: + expect (fn ("#list", {1})).not_to_raise "any error" + - context with non-empty list of homogenous elements: + - it diagnoses missing types: + expect (fn ("#list of boolean", nil)). + to_raise "non-empty list expected, got no value" + expect (fn ("#list of booleans", nil)). + to_raise "non-empty list expected, got no value" + - it diagnoses mismatched types: + expect (fn ("#list of file", {})). + to_raise "non-empty list expected, got empty table" + expect (fn ("#list of file", io.stderr)). + to_raise "non-empty list expected, got file" + expect (fn ("#list of files", {file=io.stderr})). + to_raise "non-empty list expected, got table" + - it diagnoses mismatched element types: + expect (fn ("#list of number", {false})). + to_raise "non-empty list of numbers expected, got boolean at index 1" + expect (fn ("#list of numbers", {1, 2, "3"})). + to_raise "non-empty list of numbers expected, got string at index 3" + - it matches types: + expect (fn ("#list of string", {"foo"})).not_to_raise "any error" + expect (fn ("#list of string", {"f", "o", "o"})).not_to_raise "any error" + - context with container: + - it diagnoses missing types: + expect (fn ("List of boolean", nil)). + to_raise "List expected, got no value" + expect (fn ("List of booleans", nil)). + to_raise "List expected, got no value" + - it diagnoses mismatched types: + expect (fn ("List of file", io.stderr)). + to_raise "List expected, got file" + expect (fn ("List of files", io.stderr)). + to_raise "List expected, got file" + expect (fn ("List of files", {file=io.stderr})). + to_raise "List expected, got table" + - it diagnoses mismatched element types: + expect (fn ("List of number", List {false})). + to_raise "List of numbers expected, got boolean at index 1" + expect (fn ("List of numbers", List {1, 2, "3"})). + to_raise "List of numbers expected, got string at index 3" + - it matches types: + expect (fn ("list of string", List {})).not_to_raise "any error" + expect (fn ("list of string", List {"foo"})).not_to_raise "any error" + expect (fn ("list of string", List {"f", "o", "o"})).not_to_raise "any error" + - context with object: + - it diagnoses missing types: + expect (fn ("object", nil)).to_raise "object expected, got no value" + expect (fn ("Object", nil)).to_raise "Object expected, got no value" + expect (fn ("Foo", nil)).to_raise "Foo expected, got no value" + expect (fn ("any", nil)).to_raise "any value expected, got no value" + - it diagnoses mismatched types: + expect (fn ("object", {0})).to_raise "object expected, got table" + expect (fn ("Object", {0})).to_raise "Object expected, got table" + expect (fn ("object", {_type="Object"})).to_raise "object expected, got table" + expect (fn ("Object", {_type="Object"})).to_raise "Object expected, got table" + expect (fn ("Object", Foo)).to_raise "Object expected, got Foo" + expect (fn ("Foo", {0})).to_raise "Foo expected, got table" + expect (fn ("Foo", Object)).to_raise "Foo expected, got Object" + - it matches types: + expect (fn ("object", Object)).not_to_raise "any error" + expect (fn ("object", Object {})).not_to_raise "any error" + expect (fn ("object", Foo)).not_to_raise "any error" + expect (fn ("object", Foo {})).not_to_raise "any error" + - it matches anything: + expect (fn ("any", true)).not_to_raise "any error" + expect (fn ("any", {})).not_to_raise "any error" + expect (fn ("any", Object)).not_to_raise "any error" + expect (fn ("any", Foo {})).not_to_raise "any error" + - context with a list of valid types: + - it diagnoses missing elements: + expect (fn ("string|table", nil)). + to_raise "string or table expected, got no value" + expect (fn ("string|list|#table", nil)). + to_raise "string, list or non-empty table expected, got no value" + expect (fn ("string|number|list|object", nil)). + to_raise "string, number, list or object expected, got no value" + - it diagnoses mismatched elements: + expect (fn ("string|table", false)). + to_raise "string or table expected, got boolean" + expect (fn ("string|#table", {})). + to_raise "string or non-empty table expected, got empty table" + expect (fn ("string|number|#list|object", {})). + to_raise "string, number, non-empty list or object expected, got empty table" + - it matches any type from a list: + expect (fn ("string|table", "foo")).not_to_raise "any error" + expect (fn ("string|table", {})).not_to_raise "any error" + expect (fn ("string|table", {0})).not_to_raise "any error" + expect (fn ("table|table", {})).not_to_raise "any error" + expect (fn ("#table|table", {})).not_to_raise "any error" + - context with an optional type element: + - it diagnoses mismatched elements: + expect (fn ("boolean?", "string")). + to_raise "boolean or nil expected, got string" + expect (fn ("boolean?|:symbol", {})). + to_raise "boolean, :symbol or nil expected, got empty table" + - it matches nil against a single type: + expect (fn ("any?", nil)).not_to_raise "any error" + expect (fn ("boolean?", nil)).not_to_raise "any error" + expect (fn ("string?", nil)).not_to_raise "any error" + - it matches nil against a list of types: + expect (fn ("boolean?|table", nil)).not_to_raise "any error" + expect (fn ("string?|table", nil)).not_to_raise "any error" + expect (fn ("table?|#table", nil)).not_to_raise "any error" + expect (fn ("#table?|table", nil)).not_to_raise "any error" + - it matches nil against a list of optional types: + expect (fn ("boolean?|table?", nil)).not_to_raise "any error" + expect (fn ("string?|table?", nil)).not_to_raise "any error" + expect (fn ("table?|#table?", nil)).not_to_raise "any error" + expect (fn ("#table?|table?", nil)).not_to_raise "any error" + - it matches any named type: + expect (fn ("any?", false)).not_to_raise "any error" + expect (fn ("boolean?", false)).not_to_raise "any error" + expect (fn ("string?", "string")).not_to_raise "any error" + - it matches any type from a list: + expect (fn ("boolean?|table", {})).not_to_raise "any error" + expect (fn ("string?|table", {0})).not_to_raise "any error" + expect (fn ("table?|#table", {})).not_to_raise "any error" + expect (fn ("#table?|table", {})).not_to_raise "any error" + - it matches any type from a list with several optional specifiers: + expect (fn ("boolean?|table?", {})).not_to_raise "any error" + expect (fn ("string?|table?", {0})).not_to_raise "any error" + expect (fn ("table?|table?", {})).not_to_raise "any error" + expect (fn ("#table?|table?", {})).not_to_raise "any error" - describe debug: + - before: | + function mkwrap (k, v) + local fmt = "%s" + if type (v) == "string" then fmt = "%q" end + return k, string.format (fmt, require "std".tostring (v)) + end + + function mkdebug (debugp, ...) + return string.format ([[ + _DEBUG = %s + require "std.debug" (%s) + ]], + require "std".tostring (debugp), + table.concat (require "std.functional".map (mkwrap, {...}), ", ")) + end + + - it does nothing when _DEBUG is disabled: + expect (luaproc (mkdebug (false, "nothing to see here"))). + not_to_contain_error "nothing to see here" + - it writes to stderr when _DEBUG is not set: + expect (luaproc (mkdebug (nil, "debugging"))). + to_contain_error "debugging" + - it writes to stderr when _DEBUG is enabled: + expect (luaproc (mkdebug (true, "debugging"))). + to_contain_error "debugging" + - it writes to stderr when _DEBUG.level is not set: + expect (luaproc (mkdebug ({}, "debugging"))). + to_contain_error "debugging" + - it writes to stderr when _DEBUG.level is specified: + expect (luaproc (mkdebug ({level = 0}, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mkdebug ({level = 1}, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mkdebug ({level = 2}, "debugging"))). + to_contain_error "debugging" + + +- describe argscheck: + - before: | + function mkstack (name, spec) + return string.format ([[ + local argscheck = require "std.debug".argscheck -- line 1 + local function caller () -- line 2 + argscheck ("%s", function () end) -- line 3 + end -- line 4 + caller () -- line 5 + ]], tostring (name), tostring (spec)) + end + + f, badarg = init (M, this_module, "argscheck") + + mkmagic = function () return "MAGIC" end + wrapped = f ("inner ()", mkmagic) + + - it returns the wrapped function: + expect (wrapped).not_to_be (inner) + expect (wrapped ()).to_be "MAGIC" + - it does not wrap the function when _ARGCHECK is disabled: | + script = [[ + _DEBUG = false + local debug = require "std.debug_init" + local argscheck = require "std.debug".argscheck + local function inner () return "MAGIC" end + local wrapped = argscheck ("inner (any?)", inner) + os.exit (wrapped == inner and 0 or 1) + ]] + expect (luaproc (script)).to_succeed () + + - context when checking zero argument function: + - before: + _, badarg = init (M, "", "inner") + - it diagnoses too many arguments: + expect (wrapped (false)).to_raise (badarg (1)) + - it accepts correct argument types: + expect (wrapped ()).to_be "MAGIC" + + - context when checking single argument function: + - before: + _, badarg = init (M, "", "inner") + wrapped = f ("inner (#table)", mkmagic) + - it diagnoses missing arguments: + expect (wrapped ()).to_raise (badarg (1, "non-empty table")) + - it diagnoses wrong argument types: + expect (wrapped {}).to_raise (badarg (1, "non-empty table", "empty table")) + - it diagnoses too many arguments: + expect (wrapped ({1}, 2, nop, "", false)).to_raise (badarg (1, 5)) + - it accepts correct argument types: + expect (wrapped ({1})).to_be "MAGIC" + + - context when checking multi-argument function: + - before: + _, badarg = init (M, "", "inner") + wrapped = f ("inner (table, function)", mkmagic) + - it diagnoses missing arguments: + expect (wrapped ()).to_raise (badarg (1, "table")) + expect (wrapped ({})).to_raise (badarg (2, "function")) + - it diagnoses wrong argument types: + expect (wrapped (false)).to_raise (badarg (1, "table", "boolean")) + expect (wrapped ({}, false)).to_raise (badarg (2, "function", "boolean")) + - it diagnoses too many arguments: + expect (wrapped ({}, nop, false)).to_raise (badarg (3)) + - it accepts correct argument types: + expect (wrapped ({}, nop)).to_be "MAGIC" + + - context when checking optional argument function: + - before: + _, badarg = init (M, "", "inner") + wrapped = f ("inner ([int])", mkmagic) + - it diagnoses wrong argument types: + expect (wrapped (false)).to_raise (badarg (1, "int or nil", "boolean")) + - it diagnoses too many arguments: + expect (wrapped (1, nop)).to_raise (badarg (2)) + - it accepts correct argument types: + expect (wrapped ()).to_be "MAGIC" + expect (wrapped (1)).to_be "MAGIC" + + - context when checking optional multi-argument function: + - before: + _, badarg = init (M, "", "inner") + wrapped = f ("inner ([int], string)", mkmagic) + - it diagnoses missing arguments: + expect (wrapped ()).to_raise (badarg (1, "int or string")) + expect (wrapped (1)).to_raise (badarg (2, "string")) + - it diagnoses wrong argument types: + expect (wrapped (false)).to_raise (badarg (1, "int or string", "boolean")) + - it diagnoses too many arguments: + expect (wrapped (1, "two", nop)).to_raise (badarg (3)) + - it accepts correct argument types: + expect (wrapped ("two")).to_be "MAGIC" + expect (wrapped (1, "two")).to_be "MAGIC" - describe say: + - before: | + function mkwrap (k, v) + local fmt = "%s" + if type (v) == "string" then fmt = "%q" end + return k, string.format (fmt, require "std".tostring (v)) + end + + function mksay (debugp, ...) + return string.format ([[ + _DEBUG = %s + require "std.debug".say (%s) + ]], + require "std".tostring (debugp), + table.concat (require "std.functional".map (mkwrap, {...}), ", ")) + end + + f = M.say + + - it uses stdlib tostring: + expect (luaproc [[require "std.debug".say {"debugging"}]]). + to_contain_error (require "std".tostring {"debugging"}) + - context when _DEBUG is disabled: + - it does nothing when message level is not set: + expect (luaproc (mksay (false, "nothing to see here"))). + not_to_contain_error "nothing to see here" + - it does nothing when message is set: + expect (luaproc (mksay (false, -999, "nothing to see here"))). + not_to_contain_error "nothing to see here" + expect (luaproc (mksay (false, 0, "nothing to see here"))). + not_to_contain_error "nothing to see here" + expect (luaproc (mksay (false, 1, "nothing to see here"))). + not_to_contain_error "nothing to see here" + expect (luaproc (mksay (false, 2, "nothing to see here"))). + not_to_contain_error "nothing to see here" + expect (luaproc (mksay (false, 999, "nothing to see here"))). + not_to_contain_error "nothing to see here" + - context when _DEBUG is not set: + - it writes to stderr when message level is not set: + expect (luaproc (mksay (nil, "debugging"))). + to_contain_error "debugging" + - it writes to stderr when message level is 1 or lower: + expect (luaproc (mksay (nil, -999, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay (nil, 0, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay (nil, 1, "debugging"))). + to_contain_error "debugging" + - it does nothing when message level is 2 or higher: + expect (luaproc (mksay (nil, 2, "nothing to see here"))). + not_to_contain_error "nothing to see here" + expect (luaproc (mksay (nil, 999, "nothing to see here"))). + not_to_contain_error "nothing to see here" + - context when _DEBUG is enabled: + - it writes to stderr when message level is not set: + expect (luaproc (mksay (true, "debugging"))). + to_contain_error "debugging" + - it writes to stderr when message level is 1 or lower: + expect (luaproc (mksay (true, -999, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay (true, 0, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay (true, 1, "debugging"))). + to_contain_error "debugging" + - it does nothing when message level is 2 or higher: + expect (luaproc (mksay (true, 2, "nothing to see here"))). + not_to_contain_error "nothing to see here" + expect (luaproc (mksay (true, 999, "nothing to see here"))). + not_to_contain_error "nothing to see here" + - context when _DEBUG.level is not set: + - it writes to stderr when message level is not set: + expect (luaproc (mksay ({}, "debugging"))). + to_contain_error "debugging" + - it writes to stderr when message level is 1 or lower: + expect (luaproc (mksay ({}, -999, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay ({}, 0, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay ({}, 1, "debugging"))). + to_contain_error "debugging" + - it does nothing when message level is 2 or higher: + expect (luaproc (mksay ({}, 2, "nothing to see here"))). + not_to_contain_error "nothing to see here" + expect (luaproc (mksay ({}, 999, "nothing to see here"))). + not_to_contain_error "nothing to see here" + - context when _DEBUG.level is specified: + - it writes to stderr when message level is 1 or lower: + expect (luaproc (mksay ({level = 0}, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay ({level = 1}, "debugging"))). + to_contain_error "debugging" + expect (luaproc (mksay ({level = 2}, "debugging"))). + to_contain_error "debugging" + - it does nothing when message level is higher than debug level: + expect (luaproc (mksay ({level = 2}, 3, "nothing to see here"))). + not_to_contain_error "nothing to see here" + - it writes to stderr when message level equals debug level: + expect (luaproc (mksay ({level = 2}, 2, "debugging"))). + to_contain_error "debugging" + - it writes to stderr when message level is lower than debug level: + expect (luaproc (mksay ({level = 2}, 1, "debugging"))). + to_contain_error "debugging" - describe trace: + - before: + f = init (M, this_module, "trace") + + - it does nothing when _DEBUG is disabled: + expect (luaproc [[ + _DEBUG = false + require "std.debug" + os.exit (0) + ]]).to_succeed_with "" + - it does nothing when _DEBUG is not set: + expect (luaproc [[ + require "std.debug" + os.exit (0) + ]]).to_succeed_with "" + - it does nothing when _DEBUG is enabled: + expect (luaproc [[ + _DEBUG = true + require "std.debug" + os.exit (0) + ]]).to_succeed_with "" + - it enables automatically when _DEBUG.call is set: | + expect (luaproc [[ + _DEBUG = {call = true} + local debug = require "std.debug" + os.exit (1) + ]]).to_fail_while_containing ":3 call exit" + - it is enabled manually with debug.sethook: | + expect (luaproc [[ + local debug = require "std.debug" + debug.sethook (debug.trace, "cr") + os.exit (1) + ]]).to_fail_while_containing ":3 call exit" + - it writes call trace log to standard error: | + expect (luaproc [[ + local debug = require "std.debug" + debug.sethook (debug.trace, "cr") + os.exit (0) + ]]).to_contain_error ":3 call exit" + - it traces lua calls: | + expect (luaproc [[ + local debug = require "std.debug" -- line 1 + local function incr (i) return i + 1 end -- line 2 + debug.sethook (debug.trace, "cr") -- line 3 + os.exit (incr (41)) -- line 4 + ]]).to_fail_while_matching ".*:4 call incr <2:.*:4 return incr <2:.*" + - it traces C api calls: | + expect (luaproc [[ + local debug = require "std.debug" + local function incr (i) return i + 1 end + debug.sethook (debug.trace, "cr") + os.exit (incr (41)) + ]]).to_fail_while_matching ".*:4 call exit %[C%]%s$" diff --git a/specs/functional_spec.yaml b/specs/functional_spec.yaml index a3f75dd..f4b8a27 100644 --- a/specs/functional_spec.yaml +++ b/specs/functional_spec.yaml @@ -1,15 +1,27 @@ -before: | +before: + base = require "std.base" + this_module = "std.functional" global_table = "_G" + exported_apis = { "bind", "callable", "case", "collect", "compose", + "cond", "curry", "eval", "filter", "fold", "foldl", + "foldr", "id", "lambda", "map", "map_with", + "memoize", "nop", "op", "reduce", "zip", "zip_with" } + M = require (this_module) + specify std.functional: - context when required: - context by name: - it does not touch the global table: expect (show_apis {added_to=global_table, by=this_module}). to_equal {} + - it exports the documented apis: + t = {} + for k in pairs (M) do t[#t + 1] = k end + expect (t).to_contain.a_permutation_of (exported_apis) - context via the std module: - it does not touch the global table: @@ -18,34 +30,94 @@ specify std.functional: - describe bind: + - before: + op = require "std.operator" + + f = M.bind + + - it writes an argument passing deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {nop, M, "bind"})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {nop, M, "bind"})). + not_to_contain_error "was deprecated" + + - context with bad arguments: + badargs.diagnose (f, "std.functional.bind (function, ?any*)") + - it does not affect normal operation if no arguments are bound: - expect (M.bind (math.min, {}) (2, 3, 4)). - to_equal (2) + expect (f (math.min, {}) (2, 3, 4)).to_be (2) - it takes the extra arguments into account: - expect (M.bind (math.min, {1, 0}) (2, 3, 4)). - to_equal (0) + expect (f (math.min, {1, 0}) (2, 3, 4)).to_be (0) + - it appends final call arguments: + expect (f (math.max, {2, 3}) (4, 5, 1)).to_be (5) + - it does not require all arguments in final call: + div = function (a, b) return a / b end + expect (f (div, {100}) (25)).to_be (4) - it supports out of order extra arguments: - expect (M.bind (math.pow, {[2] = 3}) (2)). - to_equal (8) + expect (f (op.pow, {[2] = 3}) (2)).to_be (8) + - it supports the legacy api: + expect (f (math.min) (2, 3, 4)).to_be (2) + expect (f (math.min, 1, 0) (2, 3, 4)).to_be (0) + expect (f (op.pow, nil, 3) (2)).to_be (8) +- describe callable: + - before: + f = M.callable + + - context with bad arguments: + badargs.diagnose (f, "std.functional.callable (?any)") + + - it returns the function associated with a callable: + Container = require "std.container" { __call = M.nop } + for _, v in ipairs { + true, + 42, + "str", + io.stderr, + {}, + M.nop, + setmetatable ({}, {__call = M.nop}), + Container, + } do + expect (f (v)).to_be (pcall (v, {}) and M.nop or nil) + end + - describe case: - before: yes = function () return true end no = function () return false end default = function (s) return s end branches = { yes = yes, no = no, default } + + f = M.case + + - context with bad arguments: | + badargs.diagnose (f, "std.functional.case (?any, #table)") + - it matches against branch keys: - expect (M.case ("yes", branches)).to_be (true) - expect (M.case ("no", branches)).to_be (false) + expect (f ("yes", branches)).to_be (true) + expect (f ("no", branches)).to_be (false) - it has a default for unmatched keys: - expect (M.case ("none", branches)).to_be "none" + expect (f ("none", branches)).to_be "none" - it returns nil for unmatched keys with no default: - expect (M.case ("none", { yes = yes, no = no })).to_be (nil) - - it evaluates `with` exactly once: + expect (f ("none", { yes = yes, no = no })).to_be (nil) + - it returns non-function matches: + expect (f ("t", {t = true})).to_be (true) + - it evaluates returned functions: + expect (f ("fn", {fn = function () return true end})). + to_be (true) + - it passes 'with' to function matches: + expect (f ("with", {function (s) return s end})).to_be "with" + - it evaluates returned functables: + functable = setmetatable ({}, {__call = function (t, with) return with end}) + expect (f ("functable", {functable})).to_be "functable" + - it evaluates 'with' exactly once: s = "prince" function acc () s = s .. "s"; return s end - expect (M.case (acc (), { + expect (f (acc (), { prince = function () return "one" end, princes = function () return "many" end, princess = function () return "one" end, @@ -54,33 +126,613 @@ specify std.functional: - describe collect: + - before: + f = M.collect + + - context with bad arguments: + badargs.diagnose (f, "std.functional.collect ([func], any*)") + + - it collects a list of single return value iterator results: + expect (f (base.ielems, {"a", "b", "c"})).to_equal {"a", "b", "c"} + - it collects a table of key:value iterator results: + t = {"first", second="two", last=3} + expect (f (pairs, t)).to_equal (t) + - it defaults to ipairs iteration: + expect (f {1, 2, [5]=5, a="b", c="d"}).to_equal {1, 2} - describe compose: + - before: + f = M.compose + + - context with bad arguments: + badargs.diagnose (f, "std.functional.compose (func*)") + + - it composes a single function correctly: + expect (f (M.id) (1)).to_be (1) - it composes functions in the correct order: - expect (M.compose (math.sin, math.cos) (1)). - to_equal (math.cos (math.sin (1))) + expect (f (math.sin, math.cos) (1)). + to_be (math.cos (math.sin (1))) + + +- describe cond: + - before: + yes = function () return true end + no = function () return false end + default = function (s) return s end + branches = { yes = yes, no = no, default } + + f = M.cond + + - it returns nil for no arguments: + expect (f ()).to_be (nil) + - it evaluates a single function argument: + expect (f (function () return true end)).to_be (true) + - it evaluates a single functable argument: + functable = setmetatable ({}, {__call = function () return true end}) + expect (f (functable)).to_be (true) + - it returns a non-callable single argument directly: + expect (f "foo").to_be "foo" + - it evaluates a branch function if expr is truthy: + expect (f ("truthy", function (s) return s end)).to_be "truthy" + - it returns nil if the last expr is falsey: + expect (f (nil, function (s) return "falsey" end)).to_be (nil) + expect (f (false, true, false, true)).to_be (nil) + - it recurses with remaining arguments if first argument is falsey: + expect (f (nil, true, 42, M.id)).to_be (42) + expect (f (nil, true, false, false, 42, M.id)).to_be (42) - describe curry: + - before: + op = require "std.operator" + + f = M.curry + + - context with bad arguments: + badargs.diagnose (f, "std.functional.curry (func, int)") + + - it returns a zero argument function uncurried: + expect (f (f, 0)).to_be (f) + - it returns a one argument function uncurried: + expect (f (f, 1)).to_be (f) + - it curries a two argument function: + expect (f (f, 2)).not_to_be (f) + - it evaluates intermediate arguments one at a time: + expect (f (math.min, 3) (2) (3) (4)).to_equal (2) + - it returns a curried function that can be partially applied: + bin = f (op.pow, 2) (2) + expect (bin (2)).to_be (op.pow (2, 2)) + expect (bin (10)).to_be (op.pow (2, 10)) - describe eval: + - before: + f = M.eval + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {"42"})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {"42"})).not_to_contain_error "was deprecated" + + - it diagnoses invalid lua: + # Some internal error when eval tries to call uncompilable "=" code. + expect (f "=").to_raise () + - it evaluates a string of lua code: + expect (f "math.min (2, 10)").to_be (math.min (2, 10)) - describe filter: + - before: + elements = {"a", "b", "c", "d", "e"} + inverse = require "std.table".invert (elements) + + f = M.filter + + - context with bad arguments: + badargs.diagnose (f, "std.functional.filter (func, [func], any*)") + + - it works with an empty table: + expect (f (M.id, pairs, {})).to_equal {} + - it iterates through element keys: + expect (f (M.id, base.ielems, elements)).to_equal {"a", "b", "c", "d", "e"} + expect (f (M.id, base.elems, inverse)).to_contain.a_permutation_of {1, 2, 3, 4, 5} + - it passes all iteration result values to filter predicate: + t = {} + f (function (k, v) t[k] = v end, pairs, elements) + expect (t).to_equal (elements) + - it returns a list of filtered single return value iterator results: + expect (f (function (e) return e:match "[aeiou]" end, base.ielems, elements)). + to_equal {"a", "e"} + - it returns a table of filtered key:value iterator results: + t = {"first", second=2, last="three"} + expect (f (function (k, v) return type (v) == "string" end, pairs, t)). + to_equal {"first", last="three"} + expect (f (function (k, v) return k % 2 == 0 end, ipairs, elements)). + to_equal {[2]="b", [4]="d"} + - it defaults to pairs iteration: + t = {"first", second=2, last="three"} + expect (f (function (k, v) return type (v) == "string" end, t)). + to_equal {"first", last="three"} - describe fold: + - before: + op = require "std.operator" + f = M.fold + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {M.id, 1, ipairs, {}})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {M.id, 1, ipairs, {}})). + not_to_contain_error "was deprecated" + + - it works with an empty table: + expect (f (op.sum, 2, ipairs, {})).to_be (2) + - it calls a binary function over single return value iterator results: + expect (f (op.sum, 2, base.ielems, {3})). + to_be (2 + 3) + expect (f (op.prod, 2, base.ielems, {3, 4})). + to_be (2 * 3 * 4) + - it calls a binary function over key:value iterator results: + expect (f (op.sum, 2, ipairs, {3})).to_be (2 + 3) + expect (f (op.prod, 2, ipairs, {3, 4})).to_be (2 * 3 * 4) + - it folds elements from left to right: + expect (f (op.pow, 2, ipairs, {3, 4})).to_be ((2 ^ 3) ^ 4) + + +- describe foldl: + - before: + op = require "std.operator" + f = M.foldl + + - context with bad arguments: + badargs.diagnose (f, "std.functional.foldl (func, [any], table)") + + - it works with an empty table: + expect (f (op.sum, 10000, {})).to_be (10000) + - it folds a binary function through a table: + expect (f (op.sum, 10000, {1, 10, 100})).to_be (10111) + - it folds from left to right: + expect (f (op.pow, 2, {3, 4})).to_be ((2 ^ 3) ^ 4) + - it supports eliding init argument: + expect (f (op.pow, {2, 3, 4})).to_be ((2 ^ 3) ^ 4) + + +- describe foldr: + - before: + op = require "std.operator" + f = M.foldr + + - context with bad arguments: + badargs.diagnose (f, "std.functional.foldr (func, [any], table)") + + - it works with an empty table: + expect (f (op.sum, 1, {})).to_be (1) + - it folds a binary function through a table: + expect (f (op.sum, {10000, 100, 10, 1})).to_be (10111) + - it folds from right to left: + expect (f (op.quot, 10, {10000, 100})).to_be (10000 / (100 / 10)) + - it supports eliding init argument: + expect (f (op.quot, {10000, 100, 10})).to_be (10000 / (100 / 10)) - describe id: + - before: + f = M.id + - it returns argument unchanged: + expect (f (true)).to_be (true) + expect (f {1, 1, 2, 3}).to_equal {1, 1, 2, 3} + - it returns multiple arguments unchanged: + expect ({f (1, "two", false)}).to_equal {1, "two", false} + + +- describe lambda: + - before: + f = M.lambda + + - context with bad arguments: + badargs.diagnose (f, "std.functional.lambda (string)") + + examples {["it diagnoses bad lambda string"] = function () + expect (select (2, f "foo")).to_be "invalid lambda string 'foo'" + end} + examples {["it diagnoses an uncompilable expression"] = function () + expect (select (2, f "||+")).to_be "invalid lambda string '||+'" + expect (select (2, f "=")).to_be "invalid lambda string '='" + end} + + - context with argument format: + - it returns a function: + expect (prototype (f "|x| 1+x")).to_be "function" + - it compiles to a working Lua function: + fn = f "||42" + expect (fn ()).to_be (42) + - it propagates argument values: + fn = f "|...| {...}" + expect (fn (1,2,3)).to_equal {1,2,3} + - context with expression format: + - it returns a function: + expect (prototype (f "_")).to_be "function" + - it compiles to a working Lua function: + fn = f "=42" + expect (fn ()).to_be (42) + - it sets auto-argument values: + fn = f "_*_" + expect (fn (42)).to_be (1764) + - it sets numeric auto-argument values: + fn = f "_1+_2+_3" + expect (fn (1, 2, 5)).to_be (8) - describe map: + - before: + elements = {"a", "b", "c", "d", "e"} + inverse = require "std.table".invert (elements) + + f = M.map + + - context with bad arguments: + badargs.diagnose (f, "std.functional.map (func, [func], any*)") + + - it works with an empty table: + expect (f (M.id, ipairs, {})).to_equal {} + - it iterates through elements: + expect (f (M.id, ipairs, elements)).to_equal (elements) + expect (f (M.id, pairs, inverse)).to_contain.a_permutation_of (elements) + - it passes all iteration result values to map function: + t = {} + f (function (k, v) t[k] = v end, pairs, elements) + expect (t).to_equal (elements) + - it returns a list of mapped single return value iterator results: + expect (f (function (e) return e:match "[aeiou]" end, base.ielems, elements)). + to_equal {"a", "e"} + expect (f (function (e) return e .. "x" end, base.elems, elements)). + to_contain.a_permutation_of {"ax", "bx", "cx", "dx", "ex"} + - it returns a table of mapped key:value iterator results: + t = {"first", second=2, last="three"} + expect (f (function (k, v) return type (v) == "string" end, pairs, t)). + to_contain.a_permutation_of {true, false, true} + expect (f (function (k, v) return k % 2 == 0 end, ipairs, elements)). + to_equal {false, true, false, true, false} + - it supports key:value results from mapping function: + expect (f (function (k, v) return v, k end, pairs, elements)). + to_equal (inverse) + - it defaults to pairs iteration: + t = {"first", second=2, last="three"} + expect (f (function (k, v) return type (v) == "string" end, t)). + to_contain.a_permutation_of {true, false, true} + + +- describe map_with: + - before: + t = {{1, 2, 3}, {4, 5}} + fn = function (...) return select ("#", ...) end + + f = M.map_with + + - context with bad arguments: + badargs.diagnose (f, "std.functional.map_with (func, table of tables)") + + - it works for an empty table: + expect (f (fn, {})).to_equal ({}) + - it returns a table: + u = f (fn, t) + expect (type (u)).to_be "table" + - it creates a new table: + old = t + u = f (fn, t) + expect (t).to_equal (old) + expect (u).not_to_equal (old) + expect (t).to_equal {{1, 2, 3}, {4, 5}} + - it maps a function over a list of argument lists: + expect (f (fn, t)).to_equal {3, 2} + - it discards hash-part arguments: + expect (f (fn, {{1,x=2,3}, {4,5,y="z"}})).to_equal {2, 2} + - it maps a function over a table of argument lists: + expect (f (fn, {a={1,2,3}, b={4,5}})).to_equal {a=3, b=2} - describe memoize: + - before: + f = M.memoize + + memfn = f (function (x) + if x then return {x} else return nil, "bzzt" end + end) + + - context with bad arguments: + badargs.diagnose (f, "std.functional.memoize (func, ?func)") + + - it propagates multiple return values: + expect (select (2, memfn (false))).to_be "bzzt" + - it returns the same object for the same arguments: + t = memfn (1) + expect (memfn (1)).to_be (t) + - it returns a different object for different arguments: + expect (memfn (1)).not_to_be (memfn (2)) + - it returns the same object for table valued arguments: + t = memfn {1, 2, 3} + expect (memfn {1, 2, 3}).to_be (t) + t = memfn {foo = "bar", baz = "quux"} + expect (memfn {foo = "bar", baz = "quux"}).to_be (t) + expect (memfn {baz = "quux", foo = "bar"}).to_be (t) + - it returns a different object for different table arguments: + expect (memfn {1, 2, 3}).not_to_be (memfn {1, 2}) + expect (memfn {1, 2, 3}).not_to_be (memfn {3, 1, 2}) + expect (memfn {1, 2, 3}).not_to_be (memfn {1, 2, 3, 4}) + - it accepts alternative normalization function: + normalize = function (...) return select ("#", ...) end + memfn = f (function (x) return {x} end, normalize) + expect (memfn "same").to_be (memfn "not same") + expect (memfn (1, 2)).to_be (memfn (false, "x")) + expect (memfn "one").not_to_be (memfn ("one", "two")) + + +- describe nop: + - before: + f = M.nop + - it accepts any number of arguments: + expect (f ()).to_be (nil) + expect (f (false)).to_be (nil) + expect (f (1, 2, 3, nil, "str", {}, f)).to_be (nil) + - it returns no values: + expect (f (1, "two", false)).to_be (nil) + + +- describe op: + - context with []: + - before: + f = M.op["[]"] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{2}, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{2}, 1})). + not_to_contain_error "was deprecated" + + - it dereferences a table: + expect (f ({}, 1)).to_be (nil) + expect (f ({"foo", "bar"}, 1)).to_be "foo" + expect (f ({foo = "bar"}, "foo")).to_be "bar" + + - context with +: + - before: + f = M.op["+"] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {2, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {2, 1})). + not_to_contain_error "was deprecated" + + - it returns the sum of its arguments: + expect (f (99, 2)).to_be (99 + 2) + + - context with -: + - before: + f = M.op["-"] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {2, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {2, 1})). + not_to_contain_error "was deprecated" + + - it returns the difference of its arguments: + expect (f (99, 2)).to_be (99 - 2) + + - context with *: + - before: + f = M.op["*"] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {2, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {2, 1})). + not_to_contain_error "was deprecated" + + - it returns the product of its arguments: + expect (f (99, 2)).to_be (99 * 2) + + - context with /: + - before: + f = M.op["/"] + + - it writes a deprecation warning on: + setdebug { deprecate = "nil" } + expect (capture (f, {2, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {2, 1})). + not_to_contain_error "was deprecated" + + - it returns the quotient of its arguments: + expect (f (99, 2)).to_be (99 / 2) + + - context with and: + - before: + f = M.op["and"] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {true, false})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {true, false})). + not_to_contain_error "was deprecated" + + - it returns the logical and of its arguments: + expect (f (false, false)).to_be (false) + expect (f (false, true)).to_be (false) + expect (f (true, false)).to_be (false) + expect (f (true, true)).to_be (true) + - it supports truthy and falsey arguments: + expect (f ()).to_be (nil) + expect (f (0)).to_be (nil) + expect (f (nil, 0)).to_be (nil) + expect (f (0, "false")).to_be ("false") + + - context with or: + - before: + f = M.op["or"] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {true, false})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {true, false})). + not_to_contain_error "was deprecated" + + - it returns the logical or of its arguments: + expect (f (false, false)).to_be (false) + expect (f (false, true)).to_be (true) + expect (f (true, false)).to_be (true) + expect (f (true, true)).to_be (true) + - it supports truthy and falsey arguments: + expect (f ()).to_be (nil) + expect (f (0)).to_be (0) + expect (f (nil, 0)).to_be (0) + expect (f (0, "false")).to_be (0) + + - context with not: + - before: + f = M.op["not"] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {true})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {true})). + not_to_contain_error "was deprecated" + + - it returns the logical not of its argument: + expect (f (false)).to_be (true) + expect (f (true)).to_be (false) + - it supports truthy and falsey arguments: + expect (f ()).to_be (true) + expect (f (0)).to_be (false) + + - context with ==: + - before: + f = M.op["=="] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {2, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {2, 1})). + not_to_contain_error "was deprecated" + + - it returns true if the arguments are equal: + expect (f ()).to_be (true) + expect (f ("foo", "foo")).to_be (true) + - it returns false if the arguments are unequal: + expect (f (1)).to_be (false) + expect (f ("foo", "bar")).to_be (false) + + - context with ~=: + - before: + f = M.op["~="] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {2, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {2, 1})). + not_to_contain_error "was deprecated" + + - it returns false if the arguments are equal: + expect (f (1, 1)).to_be (false) + expect (f ("foo", "foo")).to_be (false) + - it returns true if the arguments are unequal: + expect (f (1, 2)).to_be (true) + expect (f ("foo", "bar")).to_be (true) + expect (f ({}, {})).to_be (true) + + +- describe reduce: + - before: + op = require "std.operator" + + f = M.reduce + + - context with bad arguments: + badargs.diagnose (f, "std.functional.reduce (func, any, [func], any*)") + + - it works with an empty table: + expect (f (op.sum, 2, ipairs, {})).to_be (2) + - it calls a binary function over single return value iterator results: + expect (f (op.sum, 2, base.ielems, {3})). + to_be (2 + 3) + expect (f (op.prod, 2, base.ielems, {3, 4})). + to_be (2 * 3 * 4) + - it calls a binary function over key:value iterator results: + expect (f (op.sum, 2, base.ielems, {3})).to_be (2 + 3) + expect (f (op.prod, 2, base.ielems, {3, 4})).to_be (2 * 3 * 4) + - it reduces elements from left to right: + expect (f (op.pow, 2, base.ielems, {3, 4})).to_be ((2 ^ 3) ^ 4) + - it passes all iterator results to accumulator function: + expect (f (rawset, {}, {"one", two=5})).to_equal {"one", two=5} + + +- describe zip: + - before: + tt = {{1, 2}, {3, 4}, {5, 6}} + + f = M.zip + + - context with bad arguments: + badargs.diagnose (f, "std.functional.zip (table)") + + - it works for an empty table: + expect (f {}).to_equal {} + - it is the inverse of itself: + expect (f (f (tt))).to_equal (tt) + - it transposes rows and columns: + expect (f (tt)).to_equal {{1, 3, 5}, {2, 4, 6}} + expect (f {x={a=1, b=2}, y={a=3, b=4}, z={b=5}}). + to_equal {a={x=1, y=3}, b={x=2,y=4,z=5}} + + +- describe zip_with: + - before: + tt = {{1, 2}, {3, 4}, {5}} + fn = function (...) return tonumber (table.concat {...}) end + + f = M.zip_with + - context with bad arguments: + badargs.diagnose (f, "std.functional.zip_with (function, table of tables)") -- describe metamethod: + - it works for an empty table: + expect (f (fn, {})).to_equal {} + - it returns a table: + expect (type (f (fn, tt))).to_be "table" + - it returns the result in a new table: + expect (f (fn, tt)).not_to_be (tt) + - it does not perturb the argument list: + m = f (fn, tt) + expect (tt).to_equal {{1, 2}, {3, 4}, {5}} + - it combines column entries with a function: + expect (f (fn, tt)).to_equal {135, 24} + - it discards hash-part arguments: + expect (f (fn, {{1,2}, x={3,4}, {[2]=5}})).to_equal {1, 25} + - it combines matching key entries with a function: + expect (f (fn, {{a=1,b=2}, {a=3,b=4}, {b=5}})). + to_equal {a=13, b=245} diff --git a/specs/io_spec.yaml b/specs/io_spec.yaml index 33ab3df..0be7e1c 100644 --- a/specs/io_spec.yaml +++ b/specs/io_spec.yaml @@ -3,12 +3,15 @@ before: | this_module = "std.io" global_table = "_G" - extend_base = { "catdir", "catfile", "die", "monkey_patch", + extend_base = { "catdir", "catfile", "die", "dirname", "monkey_patch", "process_files", "readlines", "shell", "slurp", "splitdir", "warn", "writelines" } + dirsep = string.match (package.config, "^([^\n]+)\n") + M = require (this_module) + specify std.io: - context when required: - context by name: @@ -32,104 +35,320 @@ specify std.io: - describe catdir: + - before: | + f = M.catdir + + - context with bad arguments: + badargs.diagnose (f, "std.io.catdir (string*)") + + - it treats initial empty string as root directory: + expect (f ("")).to_be (dirsep) + expect (f ("", "")).to_be (dirsep) + expect (f ("", "root")).to_be (dirsep .. "root") + - it returns a single argument unchanged: + expect (f ("hello")).to_be "hello" + - it joins multiple arguments with platform directory separator: + expect (f ("one", "two")).to_be ("one" .. dirsep .. "two") + expect (f ("1", "2", "3", "4", "5")). + to_be (table.concat ({"1", "2", "3", "4", "5"}, dirsep)) - describe catfile: + - before: + f = M.catfile + + - context with bad arguments: + badargs.diagnose (f, "std.io.catfile (string*)") + + - it treats initial empty string as root directory: + expect (f ("", "")).to_be (dirsep) + expect (f ("", "root")).to_be (dirsep .. "root") + - it returns a single argument unchanged: + expect (f ("")).to_be "" + expect (f ("hello")).to_be "hello" + - it joins multiple arguments with platform directory separator: + expect (f ("one", "two")).to_be ("one" .. dirsep .. "two") + expect (f ("1", "2", "3", "4", "5")). + to_be (table.concat ({"1", "2", "3", "4", "5"}, dirsep)) - describe die: - - before: + - before: | script = [[require "std.io".die "By 'eck!"]] - - it outputs a message to stderr: - expect (luaproc (script)).to_fail_with "By 'eck!\n" - - it ignores `prog.line` without `prog.file` or `prog.name`: + + f = M.die + + - context with bad arguments: + badargs.diagnose (f, "std.io.die (string, ?any*)") + + - it outputs a message to stderr: | + expect (luaproc (script)).to_fail_while_matching ": By 'eck!\n" + - it ignores `prog.line` without `prog.file` or `prog.name`: | script = [[prog = { line = 125 };]] .. script - expect (luaproc (script)).to_fail_with "By 'eck!\n" - - it ignores `opts.line` without `opts.program`: + expect (luaproc (script)).to_fail_while_matching ": By 'eck!\n" + - it ignores `opts.line` without `opts.program`: | script = [[opts = { line = 99 };]] .. script - expect (luaproc (script)).to_fail_with "By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": By 'eck!\n" - it prefixes `prog.name` if any: | script = [[prog = { name = "name" };]] .. script - expect (luaproc (script)).to_fail_with "name: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": name: By 'eck!\n" - it appends `prog.line` if any, to `prog.name`: | script = [[prog = { line = 125, name = "name" };]] .. script - expect (luaproc (script)).to_fail_with "name:125: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": name:125: By 'eck!\n" - it prefixes `prog.file` if any: | script = [[prog = { file = "file" };]] .. script - expect (luaproc (script)).to_fail_with "file: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": file: By 'eck!\n" - it appends `prog.line` if any, to `prog.name`: | script = [[prog = { file = "file", line = 125 };]] .. script - expect (luaproc (script)).to_fail_with "file:125: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": file:125: By 'eck!\n" - it prefers `prog.name` to `prog.file` or `opts.program`: | script = [[ prog = { file = "file", name = "name" } opts = { program = "program" } ]] .. script - expect (luaproc (script)).to_fail_with "name: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": name: By 'eck!\n" - it appends `prog.line` if any to `prog.name` over anything else: | script = [[ prog = { file = "file", line = 125, name = "name" } opts = { line = 99, program = "program" } ]] .. script - expect (luaproc (script)).to_fail_with "name:125: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": name:125: By 'eck!\n" - it prefers `prog.file` to `opts.program`: | script = [[ prog = { file = "file" }; opts = { program = "program" } ]] .. script - expect (luaproc (script)).to_fail_with "file: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": file: By 'eck!\n" - it appends `prog.line` if any to `prog.file` over using `opts`: | script = [[ prog = { file = "file", line = 125 } opts = { line = 99, program = "program" } ]] .. script - expect (luaproc (script)).to_fail_with "file:125: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": file:125: By 'eck!\n" - it prefixes `opts.program` if any: | script = [[opts = { program = "program" };]] .. script - expect (luaproc (script)).to_fail_with "program: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": program: By 'eck!\n" - it appends `opts.line` if any, to `opts.program`: | script = [[opts = { line = 99, program = "program" };]] .. script - expect (luaproc (script)).to_fail_with "program:99: By 'eck!\n" + expect (luaproc (script)).to_fail_while_matching ": program:99: By 'eck!\n" + + +- describe dirname: + - before: + f = M.dirname + path = table.concat ({"", "one", "two", "three"}, dirsep) + + - context with bad arguments: + badargs.diagnose (f, "std.io.dirname (string)") + + - it removes final separator and following: + expect (f (path)).to_be (table.concat ({"", "one", "two"}, dirsep)) - describe monkey_patch: - before: - f = M.monkey_patch - mt = {} - t = { + namespace = {} + + f = M.monkey_patch + + - context with bad arguments: + badargs.diagnose (f, "std.io.monkey_patch (?table)") + + - it returns the monkey_patched io entry from namespace: + namespace = {} + expect (f (namespace)).to_be (namespace.io) + - it injects std.io apis into the given namespace: + namespace = {} + f (namespace) + for _, api in ipairs (extend_base) do + expect (namespace.io[api]).to_be (M[api]) + end + - it installs file methods: + mt = { "file metatable" } + io = f { io = { - stdin = setmetatable ({}, mt), - stdout = setmetatable ({}, mt), - stderr = setmetatable ({}, mt), - }, + stdin = setmetatable ({ "stdin" }, mt), + stdout = setmetatable ({ "stdout" }, mt), + stderr = setmetatable ({ "stderr" }, mt) + } } - - it installs readlines metamethod: - f (t) expect (mt.readlines).to_be (M.readlines) - - it installs writelines metamethod: - f (t) expect (mt.writelines).to_be (M.writelines) - - it diagnoses non-table argument: - expect (f "bad").to_error "table expected" - describe process_files: + - before: + name = "Makefile" + names = {"Makefile", "config.log", "config.status", "build-aux/config.ld"} + ascript = [[ + require "std.io".process_files (function (a) print (a) end) + ]] + lscript = [[ + require "std.io".process_files ("=print (_1)") + ]] + iscript = [[ + require "std.io".process_files (function (_, i) print (i) end) + ]] + catscript = [[ + require "std.io".process_files (function () io.write (io.input ():read "*a") end) + ]] + + f = M.process_files + + - context with bad arguments: | + badargs.diagnose (f, "std.io.process_files (func)") + + examples { + ["it diagnoses non-file 'arg' elements"] = function () + expect (luaproc (ascript, "not-an-existing-file")).to_contain_error.any_of { + "cannot open file 'not-an-existing-file'", -- Lua 5.2 + "bad argument #1 to 'input' (not-an-existing-file:", -- Lua 5.1 + } + end + } + + - it defaults to `-` if no arguments were passed: + expect (luaproc (ascript)).to_output "-\n" + - it iterates over arguments with supplied function: + expect (luaproc (ascript, name)).to_output (name .. "\n") + expect (luaproc (ascript, names)). + to_output (table.concat (names, "\n") .. "\n") + - it passes argument numbers to supplied function: + expect (luaproc (iscript, names)).to_output "1\n2\n3\n4\n" + - it sets each file argument as the default input: + expect (luaproc (catscript, name)).to_output (concat_file_content (name)) + expect (luaproc (catscript, names)). + to_output (concat_file_content (unpack (names))) + - it processes io.stdin if no arguments were passed: + ## FIXME: where does that closing newline come from?? + expect (luaproc (catscript, nil, "some\nlines\nof input")).to_output "some\nlines\nof input\n" + - it processes io.stdin for `-` argument: + ## FIXME: where does that closing newline come from?? + expect (luaproc (catscript, "-", "some\nlines\nof input")).to_output "some\nlines\nof input\n" - describe readlines: + - before: | + name = "Makefile" + h = io.open (name) + lines = {} for l in h:lines () do lines[#lines + 1] = l end + h:close () + + defaultin = io.input () + + f, badarg = init (M, this_module, "readlines") + - after: + if io.type (defaultin) ~= "closed file" then io.input (defaultin) end + + - context with bad arguments: | + badargs.diagnose (f, "std.io.readlines (?file|string)") + + examples { + ["it diagnoses non-existent file"] = function () + expect (f "not-an-existing-file"). + to_raise "bad argument #1 to 'std.io.readlines' (" -- system dependent error message + end + } + closed = io.open (name, "r") closed:close () + examples { + ["it diagnoses closed file argument"] = function () + expect (f (closed)).to_raise (badarg (1, "?file|string", "closed file")) + end + } + + - it closes file handle upon completion: + h = io.open (name) + expect (io.type (h)).not_to_be "closed file" + f (h) + expect (io.type (h)).to_be "closed file" + - it reads lines from an existing named file: + expect (f (name)).to_equal (lines) + - it reads lines from an open file handle: + expect (f (io.open (name))).to_equal (lines) + - it reads from default input stream with no arguments: + io.input (name) + expect (f ()).to_equal (lines) - describe shell: + - before: + f = M.shell + + - context with bad arguments: + badargs.diagnose (f, "std.io.shell (string)") + + - it returns the output from a shell command string: + expect (f [[printf '%s\n' 'foo' 'bar']]).to_be "foo\nbar\n" - describe slurp: + - before: | + name = "Makefile" + h = io.open (name) + content = h:read "*a" + h:close () + + defaultin = io.input () + f, badarg = init (M, this_module, "slurp") + - after: + if io.type (defaultin) ~= "closed file" then io.input (defaultin) end + + - context with bad arguments: | + badargs.diagnose (f, "std.io.slurp (?file|string)") + + examples { + ["it diagnoses non-existent file"] = function () + expect (f "not-an-existing-file"). + to_raise "bad argument #1 to 'std.io.slurp' (" -- system dependent error message + end + } + closed = io.open (name, "r") closed:close () + examples { + ["it diagnoses closed file argument"] = function () + expect (f (closed)).to_raise (badarg (1, "?file|string", "closed file")) + end + } + + - it reads content from an existing named file: + expect (f (name)).to_be (content) + - it reads content from an open file handle: + expect (f (io.open (name))).to_be (content) + - it closes file handle upon completion: + h = io.open (name) + expect (io.type (h)).not_to_be "closed file" + f (h) + expect (io.type (h)).to_be "closed file" + - it reads from default input stream with no arguments: + io.input (name) + expect (f ()).to_be (content) - describe splitdir: + - before: + f = M.splitdir + + - context with bad arguments: + badargs.diagnose (f, "std.io.splitdir (string)") + + - it returns a filename as a one element list: + expect (f ("hello")).to_equal {"hello"} + - it splits root directory in two empty elements: + expect (f (dirsep)).to_equal {"", ""} + - it returns initial empty string for absolute path: + expect (f (dirsep .. "root")).to_equal {"", "root"} + - it returns multiple components split at platform directory separator: + expect (f ("one" .. dirsep .. "two")).to_equal {"one", "two"} + expect (f (table.concat ({"1", "2", "3", "4", "5"}, dirsep))). + to_equal {"1", "2", "3", "4", "5"} - describe warn: - before: script = [[require "std.io".warn "Ayup!"]] + f = M.warn + + - context with bad arguments: + badargs.diagnose (f, "std.io.warn (string, ?any*)") + - it outputs a message to stderr: expect (luaproc (script)).to_output_error "Ayup!\n" - it ignores `prog.line` without `prog.file`, `prog.name` or `opts.program`: @@ -179,3 +398,42 @@ specify std.io: - describe writelines: + - before: | + name = os.tmpname () + h = io.open (name, "w") + lines = M.readlines (io.open "Makefile") + + defaultout = io.output () + f, badarg = init (M, this_module, "writelines") + - after: + if io.type (defaultout) ~= "closed file" then io.output (defaultout) end + h:close () + os.remove (name) + + - context with bad arguments: | + badargs.diagnose (f, "std.io.writelines (?file|string|number, ?string|number*)") + + closed = io.open (name, "r") closed:close () + examples { + ["it diagnoses closed file argument"] = function () + expect (f (closed)).to_raise (badarg (1, "?file|string|number", "closed file")) + end + } + + - it does not close the file handle upon completion: + expect (io.type (h)).not_to_be "closed file" + f (h, "foo") + expect (io.type (h)).not_to_be "closed file" + - it writes lines to an open file handle: + f (h, unpack (lines)) + h:flush () + expect (M.readlines (io.open (name))).to_equal (lines) + - it accepts number valued arguments: + f (h, 1, 2, 3) + h:flush () + expect (M.readlines (io.open (name))).to_equal {"1", "2", "3"} + - it writes to default output stream with non-file first argument: + io.output (h) + f (unpack (lines)) + h:flush () + expect (M.readlines (io.open (name))).to_equal (lines) diff --git a/specs/list_spec.yaml b/specs/list_spec.yaml index 3ebf355..7a90aa0 100644 --- a/specs/list_spec.yaml +++ b/specs/list_spec.yaml @@ -1,77 +1,112 @@ before: - Object = require "std.object" - List = require "std.list" + this_module = "std.list" + global_table = "_G" + + exported_apis = { "append", "compare", "concat", "cons", "depair", + "elems", "enpair", "filter", "flatten", "foldl", + "foldr", "index_key", "index_value", "map", + "map_with", "project", "relems", "rep", "reverse", + "shape", "sub", "tail", "transpose", "zip_with" } + + M = require (this_module) + + List = M {} l = List {"foo", "bar", "baz"} + specify std.list: - context when required: - context by name: - it does not touch the global table: expect (show_apis {added_to="_G", by="std.list"}). to_equal {} + - it exports the documented apis: + t = {} + for k in pairs (M) do t[#t + 1] = k end + expect (t).to_contain.a_permutation_of (exported_apis) + + - context via the std module: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by="std"}). + to_equal {} - describe construction: - context from List clone method: - it constructs a new list: l = List:clone {} expect (l).not_to_be (List) - expect (Object.type (l)).to_be "List" + expect (prototype (l)).to_be "List" - it reuses the List metatable: l, m = List:clone {"l"}, List:clone {"m"} expect (getmetatable (l)).to_be (getmetatable (m)) - - it initialises list with constructor parameters: + - it initialises List with constructor parameters: m = List:clone {"foo", "bar", "baz"} expect (m).to_equal (l) - it serves as a prototype for new instances: - obj = l:clone {} - expect (Object.type (obj)).to_be "List" - expect (obj).to_equal (l) - expect (getmetatable (obj)).to_be (getmetatable (l)) + m = l:clone {} + expect (prototype (m)).to_be "List" + expect (m).to_equal (l) + expect (getmetatable (m)).to_be (getmetatable (l)) # List {args} is just syntactic sugar for List:clone {args} - context from List object prototype: - - it constructs a new list: + - it constructs a new List: l = List {} expect (l).not_to_be (List) - expect (Object.type (l)).to_be "List" + expect (prototype (l)).to_be "List" - it reuses the List metatable: l, m = List {"l"}, List {"m"} expect (getmetatable (l)).to_be (getmetatable (m)) - - it initialises list with constructor parameters: + - it initialises List with constructor parameters: m = List {"foo", "bar", "baz"} expect (m).to_equal (l) - it serves as a prototype for new instances: - obj = l {} - expect (Object.type (obj)).to_be "List" - expect (obj).to_equal (l) - expect (getmetatable (obj)).to_be (getmetatable (l)) + m = l {} + expect (prototype (m)).to_be "List" + expect (m).to_equal (l) + expect (getmetatable (m)).to_be (getmetatable (l)) - describe metatable propagation: - it reuses the metatable for List constructed objects: - obj = List {"foo", "bar"} - expect (getmetatable (obj)).to_be (getmetatable (l)) + m = List {"foo", "bar"} + expect (getmetatable (m)).to_be (getmetatable (l)) - describe append: - - context when called as a list object method: - - it returns a list object: - l = l:append ("quux") - expect (Object.type (l)).to_be "List" - - it works for an empty list: - l = List {} - expect (l:append ("quux")).to_equal (List {"quux"}) - - it appends an item to a list: - expect (l:append ("quux")). + - before: + f = M.append + + - context with bad arguments: + badargs.diagnose (f, "std.list.append (List, any)") + + - context as a module function: + - it returns a List object: + expect (prototype (f (l, "quux"))).to_be "List" + - it works for an empty List: + expect (f (List {}, "quux")).to_equal (List {"quux"}) + - it appends an item to a List: + expect (f (l, "quux")). to_equal (List {"foo", "bar", "baz", "quux"}) - - context when called as a list metamethod: - - it returns a list object: - l = l + "quux" - expect (Object.type (l)).to_be "List" + + - context as an object method: + - before: + f = l.append + + - it returns a List object: + expect (prototype (f (l, "quux"))).to_be "List" + - it works for an empty List: + expect (f (List {}, "quux")).to_equal (List {"quux"}) + - it appends an item to a List: + expect (f (l, "quux")). + to_equal (List {"foo", "bar", "baz", "quux"}) + + - context as a List metamethod: + - it returns a List object: + expect (prototype (l + "quux")).to_be "List" - it works for an empty list: - l = List {} - expect (l + "quux").to_equal (List {"quux"}) + expect (List {} + "quux").to_equal (List {"quux"}) - it appends an item to a list: expect (l + "quux"). to_equal (List {"foo", "bar", "baz", "quux"}) @@ -80,139 +115,286 @@ specify std.list: - describe compare: - before: a, b = List {"foo", "bar"}, List {"foo", "baz"} - - context when called as a list object method: - - it returns -1 when the first list is less than the second: | - expect (a:compare {"foo", "baz"}).to_be (-1) - expect (a:compare (List {"foo", "baz"})).to_be (-1) + + f = M.compare + + - context with bad arguments: + badargs.diagnose (f, "std.list.compare (List, List|table)") + + - context as a module function: + - it returns -1 when the first list is less than the second: + expect (f (a, {"foo", "baz"})).to_be (-1) + expect (f (a, List {"foo", "baz"})).to_be (-1) + - it returns -1 when the second list has additional elements: + expect (f (List {"foo"}, {"foo", "bar"})).to_be (-1) + expect (f (List {"foo"}, List {"foo", "bar"})).to_be (-1) + - it returns 0 when two lists are the same: + expect (f (a, {"foo", "bar"})).to_be (0) + expect (f (a, List {"foo", "bar"})).to_be (0) + - it returns +1 when the first list is greater than the second: + expect (f (a, {"baz", "quux"})).to_be (1) + expect (f (a, List {"baz", "quux"})).to_be (1) + - it returns +1 when the first list has additional elements: + expect (f (a, {"foo"})).to_be (1) + expect (f (a, List {"foo"})).to_be (1) + - it compares numerically when both arguments can be coerced: + a, b = List {"1", "2", "3"}, List {"1", "2", "10"} + expect (f (a, b)).to_be (-1) + + - context as an object method: + - before: + f = a.compare + + - it returns -1 when the first list is less than the second: + expect (f (a, {"foo", "baz"})).to_be (-1) + expect (f (a, List {"foo", "baz"})).to_be (-1) - it returns -1 when the second list has additional elements: | b = List {"foo"} - expect (b:compare {"foo", "bar"}).to_be (-1) + expect (f (b, {"foo", "bar"})).to_be (-1) expect (List {"foo"}:compare (List {"foo", "bar"})).to_be (-1) - - it returns 0 when two lists are the same: | - expect (a:compare {"foo", "bar"}).to_be (0) - expect (a:compare (List {"foo", "bar"})).to_be (0) - - it returns +1 when the first list is greater than the second: | - expect (a:compare {"baz", "quux"}).to_be (1) - expect (a:compare (List {"baz", "quux"})).to_be (1) - - it returns +1 when the first list has additional elements: | - expect (a:compare {"foo"}).to_be (1) - expect (a:compare (List {"foo"})).to_be (1) - - context when called as a '<' list metamethod: + - it returns 0 when two lists are the same: + expect (f (a, {"foo", "bar"})).to_be (0) + expect (f (a, List {"foo", "bar"})).to_be (0) + - it returns +1 when the first list is greater than the second: + expect (f (a, {"baz", "quux"})).to_be (1) + expect (f (a, List {"baz", "quux"})).to_be (1) + - it returns +1 when the first list has additional elements: + expect (f (a, {"foo"})).to_be (1) + expect (f (a, List {"foo"})).to_be (1) + - it compares numerically when both arguments can be coerced: + a, b = List {"1", "2", "3"}, List {"1", "2", "10"} + expect (f (a, b)).to_be (-1) + + - context as a '<' List metamethod: - it succeeds when the first list is less than the second: expect (a < b).to_be (true) - it fails when the first list is not less than the second: expect (a < a).to_be (false) expect (b < a).to_be (false) - - context when called as a '>' list metamethod: + - it compares numerically when both arguments can be coerced: + a, b = List {"1", "2", "3"}, List {"1", "2", "10"} + expect (a < b).to_be (true) + + - context as a '>' List metamethod: - it succeeds when the first list is greater than the second: expect (b > a).to_be (true) - it fails when the first list is not greater than the second: expect (b > b).to_be (false) expect (a > b).to_be (false) - - context when called as a '<=' list metamethod: + - it compares numerically when both arguments can be coerced: + a, b = List {"1", "2", "3"}, List {"1", "2", "10"} + expect (a > b).to_be (false) + + - context as a '<=' List metamethod: - it succeeds when the first list is less than or equal to the second: expect (a <= b).to_be (true) expect (a <= a).to_be (true) - it fails when the first list is not less than or equal to the second: expect (b <= a).to_be (false) - - context when called as a '>=' list metamethod: + - it compares numerically when both arguments can be coerced: + a, b = List {"1", "2", "3"}, List {"1", "2", "10"} + expect (a <= b).to_be (true) + + - context as a '>=' List metamethod: - it succeeds when the first list is greater than or equal to the second: expect (b >= a).to_be (true) expect (b >= b).to_be (true) - it fails when the first list is not greater than or equal to the second: expect (a >= b).to_be (false) + - it compares numerically when both arguments can be coerced: + a, b = List {"1", "2", "3"}, List {"1", "2", "10"} + expect (a >= b).to_be (false) - describe concat: - - before: l = List {"foo", "bar"} + - before: + l = List {"foo", "bar"} - - context when called as a list object method: - - it returns a list object: - l = l:concat (List {"baz"}) - expect (Object.type (l)).to_be "List" - - it works for an empty list: - l = List {} - expect (l:concat (List {"baz"})).to_equal (List {"baz"}) - - it concatenates lists: - expect (l:concat (List {"baz", "quux"})). + f = M.concat + + - context with bad arguments: + badargs.diagnose (f, "std.list.concat (List, List|table*)") + + - context as a module function: + - it returns a List object: + expect (prototype (f (l, l))).to_be "List" + - it works for an empty List: + expect (f (List {}, {"baz"})).to_equal (List {"baz"}) + expect (f (List {}, List {"baz"})).to_equal (List {"baz"}) + - it concatenates Lists: + expect (f (l, {"baz", "quux"})). to_equal (List {"foo", "bar", "baz", "quux"}) - expect (l:concat (List {"baz"}, List {"quux"})). + expect (f (l, List {"baz", "quux"})). + to_equal (List {"foo", "bar", "baz", "quux"}) + expect (f (l, {"baz"}, {"quux"})). + to_equal (List {"foo", "bar", "baz", "quux"}) + expect (f (l, List {"baz"}, List {"quux"})). + to_equal (List {"foo", "bar", "baz", "quux"}) + + - context as an object method: + - before: + f = l.concat + + - it returns a List object: + expect (prototype (f (l, l))).to_be "List" + - it works for an empty List: + expect (f (List {}, {"baz"})).to_equal (List {"baz"}) + expect (f (List {}, List {"baz"})).to_equal (List {"baz"}) + - it concatenates Lists: + expect (f (l, {"baz", "quux"})). + to_equal (List {"foo", "bar", "baz", "quux"}) + expect (f (l, List {"baz", "quux"})). + to_equal (List {"foo", "bar", "baz", "quux"}) + expect (f (l, {"baz"}, {"quux"})). + to_equal (List {"foo", "bar", "baz", "quux"}) + expect (f (l, List {"baz"}, List {"quux"})). + to_equal (List {"foo", "bar", "baz", "quux"}) + + # Beware that .. operations are right associative + - context as a List metamethod: + - it returns a List object: + expect (prototype (l .. List {"baz"})).to_be "List" + - it works for an empty List: + expect (List {} .. {"baz"}).to_equal (List {"baz"}) + expect (List {} .. List {"baz"}).to_equal (List {"baz"}) + - it concatenates Lists: + expect (l .. {"baz", "quux"}). to_equal (List {"foo", "bar", "baz", "quux"}) - - context whne called as a list metamethod: - - it returns a list object: - l = l .. List {"baz"} - expect (Object.type (l)).to_be "List" - - it works for an empty list: - l = List {} - expect (l .. List {"baz"}).to_equal (List {"baz"}) - - it concatenates lists: expect (l .. List {"baz", "quux"}). to_equal (List {"foo", "bar", "baz", "quux"}) + expect ({"baz"} .. {"quux"} .. l). + to_equal (List {"baz", "quux", "foo", "bar"}) expect (l .. List {"baz"} .. List {"quux"}). to_equal (List {"foo", "bar", "baz", "quux"}) - describe cons: - - context when called as a list object method: - - it returns a list object: - l = l:cons "quux" - expect (Object.type (l)).to_be "List" - - it works for empty lists: - l = List {} - expect (l:cons "quux").to_equal (List {"quux"}) - - it prepends an item to a list: - expect (l:cons "quux"). - to_equal (List {"quux", "foo", "bar", "baz"}) + - before: + f = M.cons + + - context with bad arguments: + badargs.diagnose (f, "std.list.cons (List, any)") + + - context as a module function: + - it returns a List object: + expect (prototype (f (l, "x"))).to_be "List" + - it prepends an item to a List: + expect (f (l, "x")).to_equal (List {"x", "foo", "bar", "baz"}) + - it works for empty Lists: + expect (f (List {}, "x")).to_equal (List {"x"}) + + - context as an object method: + - before: + f = l.cons + + - it returns a List object: + expect (prototype (f (l, "x"))).to_be "List" + - it prepends an item to a List: + expect (f (l, "x")).to_equal (List {"x", "foo", "bar", "baz"}) + - it works for empty Lists: + expect (f (List {}, "x")).to_equal (List {"x"}) - describe depair: - before: + l = List {List {1, "first"}, List {2, "second"}, List {"third", 4}} t = {"first", "second", third = 4} - l = List.enpair (t) - - it diagnoses an argument that is not a list of lists: - - context when called as a list object method: + - context as a module function: + - before: + f = M.depair + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + - it returns a primitive table: - expect (Object.type (l:depair ())).to_be "table" - - it works with an empty list: + expect (prototype (f (l))).to_be "table" + - it works with an empty List: l = List {} - expect (l:depair ()).to_equal {} + expect (f (l)).to_equal {} - it is the inverse of enpair: - expect (l:depair ()).to_equal (t) + expect (f (l)).to_equal (t) + + - context as an object method: + - before: + f = l.depair + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it returns a primitive table: + expect (prototype (f (l))).to_be "table" + - it works with an empty List: + expect (f (List {})).to_equal {} + - it is the inverse of enpair: + expect (f (l)).to_equal (t) - describe elems: - - it is an iterator over list members: - t = {} - for e in List.elems (l) do table.insert (t, e) end - expect (t).to_equal {"foo", "bar", "baz"} - - it works for an empty list: - t = {} - for e in List.elems (List {}) do table.insert (t, e) end - expect (t).to_equal {} - - it can be called from the list module: - t = {} - for e in List.elems (l) do table.insert (t, e) end - expect (t).to_equal {"foo", "bar", "baz"} - - it can be called as a list object method: - t = {} - for e in l:elems () do table.insert (t, e) end - expect (t).to_equal {"foo", "bar", "baz"} + - context as a module function: + - before: + f = M.elems + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{}})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{}})).not_to_contain_error "was deprecated" + + - it is an iterator over List members: + t = {} + for e in f (l) do table.insert (t, e) end + expect (t).to_equal {"foo", "bar", "baz"} + - it works for an empty List: + t = {} + for e in f (List {}) do table.insert (t, e) end + expect (t).to_equal {} + + - context as an object method: + - before: + f = l.elems + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it is an iterator over List members: + t = {} + for e in l:elems () do table.insert (t, e) end + expect (t).to_equal {"foo", "bar", "baz"} + - it works for an empty List: + t, l = {}, List {} + for e in l:elems () do table.insert (t, e) end + expect (t).to_equal {} - describe enpair: - before: t = {"first", "second", third = 4} + f = M.enpair + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {t})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {t})).not_to_contain_error "was deprecated" - - it diagnoses a missing argument: - - it diagnoses a non-table argument: - - it returns a list object: - expect (Object.type (List.enpair (t))).to_be "List" - - it works for an empty table: - expect (List.enpair {}).to_equal (List {}) - - it turns a table into a list of pairs: - expect (List.enpair (t)). - to_equal (List {List {1, "first"}, List {2, "second"}, List {"third", 4}}) + - context as a module function: + - it returns a List object: + expect (prototype (f (t))).to_be "List" + - it works for an empty table: + expect (f {}).to_equal (List {}) + - it turns a table into a List of pairs: + expect (f (t)). + to_equal (List {List {1, "first"}, List {2, "second"}, List {"third", 4}}) - describe filter: @@ -220,108 +402,428 @@ specify std.list: l = List {"foo", "bar", "baz", "quux"} p = function (e) return (e:match "a" ~= nil) end - - context when called as a list object method: - - it returns a list object: - m = l:filter (p) - expect (Object.type (m)).to_be "List" - - it works for an empty list: - l = List {} - expect (l:filter (p)).to_equal (List {}) - - it filters a list according to a predicate: - expect (l:filter (p)).to_equal (List {"bar", "baz"}) + - context as a module function: + - before: + f = M.filter + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {p, l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {p, l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (p, l))).to_be "List" + - it works for an empty List: + expect (f (p, List {})).to_equal (List {}) + - it filters a List according to a predicate: + expect (f (p, l)).to_equal (List {"bar", "baz"}) + + - context as an object method: + - before: + f = l.filter + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, p})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, p})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l, p))).to_be "List" + - it works for an empty List: + expect (f (List {}, p)).to_equal (List {}) + - it filters a List according to a predicate: + expect (f (l, p)).to_equal (List {"bar", "baz"}) - describe flatten: - before: l = List {List {List {"one"}}, "two", List {List {"three"}, "four"}} - - context when called as a list object method: - - it returns a list object: - m = List.flatten (l) - expect (Object.type (m)).to_be "List" - - it works for an empty list: + - context as a module function: + - before: + f = M.flatten + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it works for an empty List: l = List {} - expect (l:flatten ()).to_equal (List {}) - - it flattens a list: - expect (l:flatten ()). + expect (f (l)).to_equal (List {}) + - it flattens a List: + expect (f (l)). + to_equal (List {"one", "two", "three", "four"}) + + - context as an object method: + - before: + f = l.flatten + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it works for an empty List: + l = List {} + expect (f (l)).to_equal (List {}) + - it flattens a List: + expect (f (l)). to_equal (List {"one", "two", "three", "four"}) - describe foldl: - before: - op = (require "std.functional").op - l = List {1, 10, 100} - - - context when called as a list object method: - - it works with an empty list: + op = require "std.operator" + l = List {3, 4} + + - context as a module function: + - before: + f = M.foldl + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {op.sum, 1, l})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {op.sum, 1, l})). + not_to_contain_error "was deprecated" + + - context with a table: + - it works with an empty table: + expect (f (op.sum, 10000, {})).to_be (10000) + - it folds a binary function through a table: + expect (f (op.sum, 10000, {1, 10, 100})).to_be (10111) + - it folds from left to right: + expect (f (op.pow, 2, {3, 4})).to_be ((2 ^ 3) ^ 4) + + - context with a List: + - it works with an empty List: + expect (f (op.sum, 10000, List {})).to_be (10000) + - it folds a binary function through a List: + expect (f (op.sum, 10000, List {1, 10, 100})). + to_be (10111) + - it folds from left to right: + expect (f (op.pow, 2, List {3, 4})).to_be ((2 ^ 3) ^ 4) + + - context as an object method: + - before: + f = l.foldl + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, op.sum, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, op.sum, 1})). + not_to_contain_error "was deprecated" + + - it works with an empty List: l = List {} - expect (l:foldl (op["+"], 10000)).to_be (10000) - - it folds a binary function through a list: - expect (l:foldl (op["+"], 10000)).to_be (10111) + expect (f (l, op.sum, 2)).to_be (2) + - it folds a binary function through a List: + expect (f (l, op.sum, 2)).to_be (9) + - it folds from left to right: + expect (f (l, op.pow, 2)).to_be ((2 ^ 3) ^ 4) - describe foldr: - before: - op = (require "std.functional").op - l = List {1, 10, 100} - - - context when called as a list object method: - - it works with an empty list: + op = require "std.operator" + l = List {10000, 100} + + - context as a module function: + - before: + f = M.foldr + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {op.sum, 1, {10}})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {op.sum, 1, {10}})). + not_to_contain_error "was deprecated" + + - context with a table: + - it works with an empty table: + expect (f (op.sum, 10000, {})).to_be (10000) + - it folds a binary function through a table: + expect (f (op.sum, 10000, {1, 10, 100})).to_be (10111) + - it folds from right to left: + expect (f (op.quot, 10, {10000, 100})).to_be (10000 / (100 / 10)) + + - context with a List: + - it works with an empty List: + expect (f (op.sum, 10000, List {})).to_be (10000) + - it folds a binary function through a List: + expect (f (op.sum, 10000, List {1, 10, 100})). + to_be (10111) + - it folds from right to left: + expect (f (op.quot, 10, List {10000, 100})). + to_be (10000 / (100 / 10)) + + - context as an object method: + - before: + f = l.foldr + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, op.sum, 1})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, op.sum, 1})). + not_to_contain_error "was deprecated" + + - it works with an empty List: l = List {} - expect (l:foldl (op["/"], 1)).to_be (1) - - it folds a binary function through a list: - expect (l:foldl (op["/"], 10000)).to_be (10) + expect (f (l, op.sum, 10)).to_be (10) + - it folds a binary function through a List: + expect (f (l, op.sum, 10)).to_be (10110) + - it folds from right to left: + expect (f (l, op.quot, 10)).to_be (10000 / (100 / 10)) - describe index_key: + - context as a module function: + - before: + f = M.index_key + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {1, List {{1}}})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {1, List {{1}}})). + not_to_contain_error "was deprecated" + + - it makes a map of matched table field values to table List offsets: + l = List {{a = "b", c = "d"}, {e = "x", f = "g"}, {a = "x"}} + t = f ("a", l) + expect (t).to_equal {b = 1, x = 3} + for k, v in pairs (t) do + expect (k).to_equal (l[v]["a"]) + end + - it captures only the last matching List offset: + l = List {{a = "b"}, {a = "x"}, {a = "b"}} + t = f ("a", l) + expect (t.b).not_to_be (1) + expect (t.x).to_be (2) + expect (t.b).to_be (3) + - it produces incomplete indices when faced with repeated matching table values: + l = List {{1, 2, 3}, {2}, {2, 1, 3, 2, 1}} + expect (f (1, l)).to_equal {1, 3} + expect (f (2, l)).to_equal {3, 1} + expect (f (3, l)).to_equal {nil, nil, 3} + + - context as an object method: + - before: + f = l.index_key + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, 1})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, 1})).not_to_contain_error "was deprecated" + + - it makes a map of matched table field values to table List offsets: + l = List {{a = "b", c = "d"}, {e = "x", f = "g"}, {a = "x"}} + t = l:index_key "a" + expect (t).to_equal {b = 1, x = 3} + for k, v in pairs (t) do + expect (k).to_equal (l[v]["a"]) + end + - it captures only the last matching List offset: + l = List {{a = "b"}, {a = "x"}, {a = "b"}} + t = l:index_key "a" + expect (t.b).not_to_be (1) + expect (t.x).to_be (2) + expect (t.b).to_be (3) + - it produces incomplete indices when faced with repeated matching table values: + l = List {{1, 2, 3}, {2}, {2, 1, 3, 2, 1}} + expect (l:index_key (1)).to_equal {1, 3} + expect (l:index_key (2)).to_equal {3, 1} + expect (l:index_key (3)).to_equal {nil, nil, 3} - describe index_value: + - context as a module function: + - before: + f = M.index_value + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {1, List {{1}}})). + to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {1, List {{1}}})). + not_to_contain_error "was deprecated" + + - it makes a table of matched table field values to table List references: + l = List {{a = "b", c = "d"}, {e = "x", f = "g"}, {a = "x"}} + t = f ("a", l) + expect (t).to_equal {b = l[1], x = l[3]} + for k, v in pairs (t) do + expect (k).to_equal (v["a"]) + end + - it captures only the last matching List offset: + l = List {{a = "b"}, {a = "x"}, {a = "b"}} + t = f ("a", l) + expect (t.b).not_to_be (l[1]) + expect (t.x).to_be (l[2]) + expect (t.b).to_be (l[3]) + - it produces incomplete indices when faced with repeated matching table values: + l = List {{1, 2, 3}, {2}, {2, 1, 3, 2, 1}} + expect (f (1, l)).to_equal {l[1], l[3]} + expect (f (2, l)).to_equal {l[3], l[1]} + expect (f (3, l)).to_equal {nil, nil, l[3]} + + - context as an object method: + - before: + l = List {{1}} + + f = l.index_value + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, 1})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, 1})).not_to_contain_error "was deprecated" + + - it makes a table of matched table field values to table List references: + l = List {{a = "b", c = "d"}, {e = "x", f = "g"}, {a = "x"}} + t = l:index_value "a" + expect (t).to_equal {b = l[1], x = l[3]} + for k, v in pairs (t) do + expect (k).to_equal (v["a"]) + end + - it captures only the last matching List offset: + l = List {{a = "b"}, {a = "x"}, {a = "b"}} + t = l:index_value "a" + expect (t.b).not_to_be (l[1]) + expect (t.x).to_be (l[2]) + expect (t.b).to_be (l[3]) + - it produces incomplete indices when faced with repeated matching table values: + l = List {{1, 2, 3}, {2}, {2, 1, 3, 2, 1}} + expect (l:index_value (1)).to_equal {l[1], l[3]} + expect (l:index_value (2)).to_equal {l[3], l[1]} + expect (l:index_value (3)).to_equal {nil, nil, l[3]} - describe map: - before: l = List {1, 2, 3, 4, 5} - f = function (n) return n * n end - - - context when called as a list object method: - - it returns a list object: - m = l:map (f) - expect (Object.type (m)).to_be "List" - - it works for an empty list: - l = List {} - expect (l:map (f)).to_equal (List {}) - - it creates a new list: + sq = function (n) return n * n end + + - context as a module function: + - before: + f, badarg = init (M, this_module, "map") + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {sq, l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {sq, l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (sq, l))).to_be "List" + - it works for an empty List: + expect (f (sq, List {})).to_equal (List {}) + - it creates a new List: o = l - m = l:map (f) + m = f (sq, l) expect (l).to_equal (o) expect (m).not_to_equal (o) expect (l).to_equal (List {1, 2, 3, 4, 5}) - - it maps a function over a list: - expect (l:map (f)).to_equal (List {1, 4, 9, 16, 25}) + - it maps a function over a List: + expect (f (sq, l)).to_equal (List {1, 4, 9, 16, 25}) + + - context as an object method: + - before: + f = l.map + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, sq})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, sq})).not_to_contain_error "was deprecated" + + - it returns a List object: + m = f (l, sq) + expect (prototype (m)).to_be "List" + - it works for an empty List: + expect (f (List {}, sq)).to_equal (List {}) + - it creates a new List: + o = l + m = f (l, sq) + expect (l).to_equal (o) + expect (m).not_to_equal (o) + expect (l).to_equal (List {1, 2, 3, 4, 5}) + - it maps a function over a List: + expect (f (l, sq)).to_equal (List {1, 4, 9, 16, 25}) - describe map_with: - before: l = List {List {1, 2, 3}, List {4, 5}} - f = function (...) return select ("#", ...) end - - - it diagnoses an argument that is not a list of lists: - - context when called as a list object method: - - it returns a list object: - m = l:map_with (f) - expect (Object.type (m)).to_be "List" - - it works for an empty list: + fn = function (...) return select ("#", ...) end + + - context as a module function: + - before: + f = M.map_with + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {fn, l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {fn, l})).not_to_contain_error "was deprecated" + + - it returns a List object: + m = f (fn, l) + expect (prototype (m)).to_be "List" + - it creates a new List: + o = l + m = f (fn, l) + expect (l).to_equal (o) + expect (m).not_to_equal (o) + expect (l).to_equal (List {List {1, 2, 3}, List {4, 5}}) + - it maps a function over a List: + expect (f (fn, l)).to_equal (List {3, 2}) + - it works for an empty List: l = List {} - expect (l:map_with (f)).to_equal (List {}) - - it creates a new list: + expect (f (fn, l)).to_equal (List {}) + + - context as an object method: + - before: + f = l.map_with + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, fn})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, fn})).not_to_contain_error "was deprecated" + + - it returns a List object: + m = f (l, fn) + expect (prototype (m)).to_be "List" + - it creates a new List: o = l - m = l:map_with (f) + m = f (l, fn) expect (l).to_equal (o) expect (m).not_to_equal (o) expect (l).to_equal (List {List {1, 2, 3}, List {4, 5}}) - - it maps a function over a list: - expect (l:map_with (f)).to_equal (List {3, 2}) + - it maps a function over a List: + expect (f (l, fn)).to_equal (List {3, 2}) + - it works for an empty List: + l = List {} + expect (f (l, fn)).to_equal (List {}) - describe project: @@ -332,114 +834,406 @@ specify std.list: {first = "1st", second = "2nd", third = "3rd"}, } - - it diagnoses an argument that is not a list of tables: - - context when called as a list object method: - - it returns a list object: - p = l:project ("third") - expect (Object.type (p)).to_be "List" - - it works with an empty list: - l = List {} - expect (l:project ("third")).to_equal (List {}) - - it projects a list of fields from a list of tables: - expect (l:project ("third")). - to_equal (List {true, 3, "3rd"}) + - context as a module function: + - before: + f = M.project + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {"third", l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {"third", l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f ("third", l))).to_be "List" + - it works with an empty List: + expect (f ("third", List {})).to_equal (List {}) + - it projects a List of fields from a List of tables: + expect (f ("third", l)).to_equal (List {true, 3, "3rd"}) + - it projects fields with a falsey value correctly: + expect (f ("first", l)).to_equal (List {false, 1, "1st"}) + + - context as an object method: + - before: + f = l.project + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, "third"})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, "third"})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l, "third"))).to_be "List" + - it works with an empty List: + expect (f (List {}, "third")).to_equal (List {}) + - it projects a List of fields from a List of tables: + expect (f (l, "third")).to_equal (List {true, 3, "3rd"}) - it projects fields with a falsey value correctly: - expect (l:project ("first")). - to_equal (List {false, 1, "1st"}) + expect (f (l, "first")).to_equal (List {false, 1, "1st"}) - describe relems: - - it is a reverse iterator over list members: - t = {} - for e in List.relems (l) do table.insert (t, e) end - expect (t).to_equal {"baz", "bar", "foo"} - - it works for an empty list: - t = {} - for e in List.relems (List {}) do table.insert (t, e) end - expect (t).to_equal {} - - it can be called from the list module: - t = {} - for e in List.relems (l) do table.insert (t, e) end - expect (t).to_equal {"baz", "bar", "foo"} - - it can be called as a list object method: - t = {} - for e in l:relems () do table.insert (t, e) end - expect (t).to_equal {"baz", "bar", "foo"} + - context as a module function: + - before: + f = M.relems + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it is a reverse iterator over List members: + t = {} + for e in f (l) do table.insert (t, e) end + expect (t).to_equal {"baz", "bar", "foo"} + - it works for an empty List: + t = {} + for e in f (List {}) do table.insert (t, e) end + expect (t).to_equal {} + + - context as an object method: + - before: + f = l.relems + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it is a reverse iterator over List members: + t = {} + for e in l:relems () do table.insert (t, e) end + expect (t).to_equal {"baz", "bar", "foo"} + - it works for an empty List: + t, l = {}, List {} + for e in l:relems () do table.insert (t, e) end + expect (t).to_equal {} - describe rep: - - before: l = List {"foo", "bar"} + - before: + l = List {"foo", "bar"} - - context when called as a list object method: - - it returns a list object: - expect (Object.type (l:rep (3))).to_be "List" - - it works for an empty list: - l = List {} - expect (l:rep (99)).to_equal (List {}) - - it repeats the contents of a list: - expect (l:rep (3)). + f = M.rep + + - context with bad arguments: + badargs.diagnose (f, "std.list.rep (List, int)") + + - context as a module function: + - it returns a List object: + expect (prototype (f (l, 3))).to_be "List" + - it works for an empty List: + expect (f (List {}, 99)).to_equal (List {}) + - it repeats the contents of a List: + expect (f (l, 3)). + to_equal (List {"foo", "bar", "foo", "bar", "foo", "bar"}) + + - context as an object method: + - before: + f = l.rep + + - it returns a List object: + expect (prototype (f (l, 3))).to_be "List" + - it works for an empty List: + expect (f (List {}, 99)).to_equal (List {}) + - it repeats the contents of a List: + expect (f (l, 3)). to_equal (List {"foo", "bar", "foo", "bar", "foo", "bar"}) - describe reverse: - - before: l = List {"foo", "bar", "baz", "quux"} + - before: + l = List {"foo", "bar", "baz", "quux"} - - context when called as a list object method: - - it returns a list object: - expect (Object.type (l:reverse ())).to_be "List" - - it works for an empty list: + - context as a module function: + - before: + f = M.reverse + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{}})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{}})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it works for an empty List: l = List {} - expect (l:reverse ()).to_equal (List {}) - - it makes a new reversed list: + expect (f (l)).to_equal (List {}) + - it makes a new reversed List: + m = l + expect (f (l)). + to_equal (List {"quux", "baz", "bar", "foo"}) + expect (l).to_equal (List {"foo", "bar", "baz", "quux"}) + expect (l).to_be (m) + + - context as an object method: + - before: + f = l.reverse + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it works for an empty List: + expect (f (List {})).to_equal (List {}) + - it makes a new reversed List: m = l - expect (l:reverse ()). + expect (f (l)). to_equal (List {"quux", "baz", "bar", "foo"}) expect (l).to_equal (List {"foo", "bar", "baz", "quux"}) expect (l).to_be (m) - describe shape: + - before: + l = List {1, 2, 3, 4, 5, 6} + + - context as a module function: + - before: + f = M.shape + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{0}, l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{0}, l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f ({2, 3}, l))).to_be "List" + - it works for an empty List: + expect (f ({0}, List {})).to_equal (List {}) + - it returns the result in a new List object: + expect (f ({2, 3}, l)).not_to_be (l) + - it does not perturb the argument List: + f ({2, 3}, l) + expect (l).to_equal (List {1, 2, 3, 4, 5, 6}) + - it reshapes a List according to given dimensions: + expect (f ({2, 3}, l)). + to_equal (List {List {1, 2, 3}, List {4, 5, 6}}) + expect (f ({3, 2}, l)). + to_equal (List {List {1, 2}, List {3, 4}, List {5, 6}}) + - it treats 0-valued dimensions as an indefinite number: + expect (f ({2, 0}, l)). + to_equal (List {List {1, 2, 3}, List {4, 5, 6}}) + expect (f ({0, 2}, l)). + to_equal (List {List {1, 2}, List {3, 4}, List {5, 6}}) + + - context as an object method: + - before: + f = l.shape + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, {0}})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, {0}})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l, {2, 3}))).to_be "List" + - it works for an empty List: + expect (f (List {}, {0})).to_equal (List {}) + - it returns the result in a new List object: + expect (f (l, {2, 3})):not_to_be (l) + - it does not perturb the argument List: + f (l, {2, 3}) + expect (l).to_equal (List {1, 2, 3, 4, 5, 6}) + - it reshapes a List according to given dimensions: + expect (f (l, {2, 3})). + to_equal (List {List {1, 2, 3}, List {4, 5, 6}}) + expect (f (l, {3, 2})). + to_equal (List {List {1, 2}, List {3, 4}, List {5, 6}}) + - it treats 0-valued dimensions as an indefinite number: + expect (f (l, {2, 0})). + to_equal (List {List {1, 2, 3}, List {4, 5, 6}}) + expect (f (l, {0, 2})). + to_equal (List {List {1, 2}, List {3, 4}, List {5, 6}}) - describe sub: - - before: l = List {1, 2, 3, 4, 5, 6, 7} - - - context when called as a list object method: - - it returns a list object: | - expect (Object.type (l:sub (1, 1))).to_be "List" - - it makes a list from a subrange of another list: | - expect (l:sub (2, 5)).to_equal (List {2, 3, 4, 5}) - - it truncates the result if 'to' argument is too large: | - expect (l:sub (5, 10)).to_equal (List {5, 6, 7}) - - it defaults 'to' to the end of the list: | - expect (l:sub (5)).to_equal (List {5, 6, 7}) - - it defaults 'from' to the beginning of the list: | - expect (l:sub ()).to_equal (l) - - it returns an empty list when 'from' is greater than 'to': | - expect (l:sub (2, 1)).to_equal (List {}) - - it counts from the end of the list for a negative 'from' argument: | - expect (l:sub (-3)).to_equal (List {5, 6, 7}) - - it counts from the end of the list for a negative 'to' argument: | - expect (l:sub (-5, -2)).to_equal (List {3, 4, 5, 6}) + - before: + l = List {1, 2, 3, 4, 5, 6, 7} + + f = M.sub + + - context with bad arguments: + badargs.diagnose (f, "std.list.sub (List, ?int, ?int)") + + - context as a module function: + - it returns a List object: + expect (prototype (f (l, 1, 1))).to_be "List" + - it makes a List from a subrange of another List: + expect (f (l, 2, 5)).to_equal (List {2, 3, 4, 5}) + - it truncates the result if 'to' argument is too large: + expect (f (l, 5, 10)).to_equal (List {5, 6, 7}) + - it defaults 'to' to the end of the List: + expect (f (l, 5)).to_equal (List {5, 6, 7}) + - it defaults 'from' to the beginning of the List: + expect (f (l)).to_equal (l) + - it returns an empty List when 'from' is greater than 'to': + expect (f (l, 2, 1)).to_equal (List {}) + - it counts from the end of the List for a negative 'from' argument: + expect (f (l, -3)).to_equal (List {5, 6, 7}) + - it counts from the end of the List for a negative 'to' argument: + expect (f (l, -5, -2)).to_equal (List {3, 4, 5, 6}) + + - context as an object method: + - before: + f = l.sub + + - it returns a List object: + expect (prototype (f (l, 1, 1))).to_be "List" + - it makes a List from a subrange of another List: + expect (f (l, 2, 5)).to_equal (List {2, 3, 4, 5}) + - it truncates the result if 'to' argument is too large: + expect (f (l, 5, 10)).to_equal (List {5, 6, 7}) + - it defaults 'to' to the end of the List: + expect (f (l, 5)).to_equal (List {5, 6, 7}) + - it defaults 'from' to the beginning of the List: + expect (f (l)).to_equal (l) + - it returns an empty List when 'from' is greater than 'to': + expect (f (l, 2, 1)).to_equal (List {}) + - it counts from the end of the List for a negative 'from' argument: + expect (f (l, -3)).to_equal (List {5, 6, 7}) + - it counts from the end of the List for a negative 'to' argument: + expect (f (l, -5, -2)).to_equal (List {3, 4, 5, 6}) - describe tail: - - before: l = List {1, 2, 3, 4, 5, 6, 7} - - - context when called as a list object method: - - it returns a list object: | - expect (Object.type (l:tail ())).to_be "List" - - it makes a new list with the first element removed: | - expect (l:tail ()).to_equal (List {2, 3, 4, 5, 6, 7}) - - it works for an empty list: | - l = List {} - expect (l:tail ()).to_equal (List {}) - - it returns an empty list when passed a list with one element: | - l = List {1} - expect (l:tail ()).to_equal (List {}) + - before: + l = List {1, 2, 3, 4, 5, 6, 7} + + f = M.tail + + - context with bad arguments: + badargs.diagnose (f, "std.list.tail (List)") + + - context as a module function: + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it makes a new List with the first element removed: + expect (f (l)).to_equal (List {2, 3, 4, 5, 6, 7}) + - it works for an empty List: + expect (f (List {})).to_equal (List {}) + - it returns an empty List when passed a List with one element: + expect (f (List {1})).to_equal (List {}) + + - context as an object method: + - before: + f = l.tail + + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it makes a new List with the first element removed: + expect (f (l)).to_equal (List {2, 3, 4, 5, 6, 7}) + - it works for an empty List: + expect (f (List {})).to_equal (List {}) + - it returns an empty List when passed a List with one element: + expect (f (List {1})).to_equal (List {}) - describe transpose: + - before: + l = List {List {1, 2}, List {3, 4}, List {5, 6}} + + - context as a module function: + - before: + f = M.transpose + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it works for an empty List: + expect (f (List {})).to_equal (List {}) + - it returns the result in a new List object: + expect (f (l)).not_to_be (l) + - it does not perturb the argument List: + m = f (l) + expect (l).to_equal (List {List {1, 2}, List {3, 4}, List {5, 6}}) + - it transposes rows and columns: + expect (f (l)).to_equal (List {List {1, 3, 5}, List {2, 4, 6}}) + + - context as an object method: + - before: + f = l.transpose + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l))).to_be "List" + - it works for an empty List: + expect (f (List {})).to_equal (List {}) + - it returns the result in a new List object: + expect (f (l)).not_to_be (l) + - it does not perturb the argument List: + m = f (l) + expect (l).to_equal (List {List {1, 2}, List {3, 4}, List {5, 6}}) + - it transposes rows and columns: + expect (f (l)). + to_equal (List {List {1, 3, 5}, List {2, 4, 6}}) - describe zip_with: + - before: + l = List {List {1, 2}, List {3, 4}, List {5}} + fn = function (...) return tonumber (table.concat {...}) end + + - context as a module function: + - before: + f = M.zip_with + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, fn})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, fn})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l, fn))).to_be "List" + - it works for an empty List: + expect (f (List {}, fn)).to_equal (List {}) + - it returns the result in a new List object: + expect (f (l, fn)):not_to_be (l) + - it does not perturb the argument List: + m = f (l, fn) + expect (l).to_equal (List {List {1, 2}, List {3, 4}, List {5}}) + - it combines column entries with a function: + expect (f (l, fn)).to_equal (List {135, 24}) + + - context as an object method: + - before: + f = l.zip_with + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {l, fn})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {l, fn})).not_to_contain_error "was deprecated" + + - it returns a List object: + expect (prototype (f (l, fn))).to_be "List" + - it works for an empty List: + expect (f (List {}, fn)).to_equal (List {}) + - it returns the result in a new List object: + expect (f (l, fn)):not_to_be (l) + - it does not perturb the argument List: + m = f (l, fn) + expect (l).to_equal (List {List {1, 2}, List {3, 4}, List {5}}) + - it combines column entries with a function: + expect (f (l, fn)).to_equal (List {135, 24}) diff --git a/specs/math_spec.yaml b/specs/math_spec.yaml index 8d05107..86e58e5 100644 --- a/specs/math_spec.yaml +++ b/specs/math_spec.yaml @@ -1,4 +1,4 @@ -before: | +before: base_module = "math" this_module = "std.math" global_table = "_G" @@ -7,6 +7,7 @@ before: | M = require (this_module) + specify std.math: - context when required: - context by name: @@ -30,19 +31,69 @@ specify std.math: - describe floor: + - before: + f = M.floor + + - context with bad arguments: + badargs.diagnose (f, "std.math.floor (number, ?int)") + + - it rounds to the nearest smaller integer: + expect (f (1.2)).to_be (1) + expect (f (1.9)).to_be (1) + expect (f (999e-2)).to_be (9) + expect (f (999e-3)).to_be (0) + - it rounds down to specified number of decimal places: + expect (f (1.2345, 0)).to_be (1.0) + expect (f (1.2345, 1)).to_be (1.2) + expect (f (1.2345, 2)).to_be (1.23) + expect (f (9.9999, 2)).to_be (9.99) + expect (f (99999e-3, 3)).to_be (99999e-3) + expect (f (99999e-4, 3)).to_be (9999e-3) + expect (f (99999e-5, 3)).to_be (999e-3) - describe monkey_patch: - before: - f = M.monkey_patch - t = { - math = {}, - } - f (t) - - it installs math.floor function: - expect (t.math.floor).to_be (M.floor) - - it diagnoses non-table argument: - expect (f "bad").to_error "table expected" + f = M.monkey_patch + + - context with bad arguments: + badargs.diagnose (f, "std.math.monkey_patch (?table)") + + - it returns the monkey_patched math entry namespace: + namespace = {} + expect (f (namespace)).to_be (namespace.math) + - it injects std.math apis into the given namespace: + namespace = {} + f (namespace) + for _, api in ipairs (extend_base) do + expect (namespace.math[api]).to_be (M[api]) + end - describe round: + - before: + f = M.round + + - context with bad arguments: + badargs.diagnose (f, "std.math.round (number, ?int)") + + - it rounds to the nearest integer: + expect (f (1.2)).to_be (1) + expect (f (1.9)).to_be (2) + expect (f (949e-2)).to_be (9) + expect (f (999e-2)).to_be (10) + - it rounds to specified number of decimal places: + expect (f (1.234, 0)).to_be (1.0) + expect (f (5.678, 0)).to_be (6.0) + expect (f (1.234, 1)).to_be (1.2) + expect (f (5.678, 1)).to_be (5.7) + expect (f (1.234, 2)).to_be (1.23) + expect (f (5.678, 2)).to_be (5.68) + expect (f (9.999, 2)).to_be (10) + expect (f (11111e-2, 3)).to_be (11111e-2) + expect (f (99999e-2, 3)).to_be (99999e-2) + expect (f (11111e-3, 3)).to_be (11111e-3) + expect (f (99999e-3, 3)).to_be (99999e-3) + expect (f (11111e-4, 3)).to_be (1111e-3) + expect (f (99999e-4, 3)).to_be (10) + expect (f (99999e-5, 3)).to_be (1) diff --git a/specs/object_spec.yaml b/specs/object_spec.yaml index cc12538..a4d6603 100644 --- a/specs/object_spec.yaml +++ b/specs/object_spec.yaml @@ -3,6 +3,12 @@ before: obj = Object {"foo", "bar", baz="quux"} prototype = Object.prototype + function copy (t) + local r = {} + for k, v in pairs (t) do r[k] = v end + return r + end + specify std.object: - context when required: - context by name: @@ -53,6 +59,18 @@ specify std.object: p = Portal {} expect (prototype (p)).to_be "Demon" expect (prototype (p {})).to_be "Demon" + - it recognizes a file object: + h = io.open (os.tmpname ()) + expect (prototype (h)).to_be "file" + h:close () + expect (prototype (h)).to_be "closed file" + - it recognizes a primitive object: + expect (prototype (nil)).to_be "nil" + expect (prototype (false)).to_be "boolean" + expect (prototype (0.0)).to_be "number" + expect (prototype "0.0").to_be "string" + expect (prototype (function () end)).to_be "function" + expect (prototype {}).to_be "table" - context when called as an object method: - it reports the type stored in the object's metatable: expect (o:prototype ()).to_be "Object" @@ -74,9 +92,6 @@ specify std.object: - describe instantiation from a prototype: - - before: - totable = (require "std.table").totable - - context when _init is nil: - before: Array = Object { @@ -84,20 +99,21 @@ specify std.object: "foo", "bar", "baz", } Array._init = nil + - it contains user-defined fields: - expect (totable (Array)). + expect (copy (Array)). to_equal {"foo", "bar", "baz"} - it sets array part of instance object from positional parameters: array = Array {"first", "second", "third"} - expect (totable (array)). + expect (copy (array)). to_equal {"first", "second", "third"} - it uses prototype values for missing positional parameters: array = Array {"first", "second"} - expect (totable (array)). + expect (copy (array)). to_equal {"first", "second", "baz"} - it merges surplas positional parameters: array = Array {"first", "second", "third", "fourth"} - expect (totable (array)). + expect (copy (array)). to_equal {"first", "second", "third", "fourth"} - context when _init is an empty table: @@ -108,7 +124,7 @@ specify std.object: "first", "second", "third", } - it contains user-defined fields: - expect (totable (Prototype)). + expect (copy (Prototype)). to_equal {"first", "second", "third"} - it ignores positional parameters: | instance = Prototype {"foo", "bar"} @@ -124,19 +140,19 @@ specify std.object: errout = "no errors", } - it contains user-defined fields: - expect (totable (Process)). + expect (copy (Process)). to_equal {status = -1, output = "empty", errout = "no errors"} - it sets user-defined fields from positional parameters: proc = Process {0, "output", "diagnostics"} - expect (totable (proc)). + expect (copy (proc)). to_equal {status = 0, output = "output", errout = "diagnostics"} - it uses prototype values for missing positional parameters: proc = Process {0, "output"} - expect (totable (proc)). + expect (copy (proc)). to_equal {status = 0, output = "output", errout = "no errors"} - it discards surplus positional parameters: proc = Process {0, "output", "diagnostics", "garbage"} - expect (totable (proc)). + expect (copy (proc)). to_equal { status = 0, output = "output", errout = "diagnostics" } - context when _init is a function: @@ -248,36 +264,22 @@ specify std.object: expect (getmetatable (instance)).to_be (getmetatable (Derived)) - context with custom metamethods: - before: - compare = require "std.list".compare bag = Object { _type = "bag", - __lt = function (a, b) return compare (a, b) < 0 end, + __lt = function (a, b) return a[1] < b[1] end, } - it has it's own metatable: expect (getmetatable (bag)).not_to_be (root_mt) - it propagates prototype metatable to derived instances: instance = bag {} expect (getmetatable (instance)).to_be (getmetatable (bag)) - - it supports __lt calls: + - it supports __lt calls: | a, b = bag {"a"}, bag {"b"} expect (a < b).to_be (true) expect (a < a).to_be (false) expect (a > b).to_be (false) -- describe __totable: - - before: - totable = (require "std.table").totable - Derived = Object {_type = "Derived", "one", "two", three = true} - - - it returns a table: - expect (prototype (totable (Derived))).to_be "table" - - it contains all non-hidden fields of object: - expect (totable (Derived)).to_contain.all_of {"one", "two", "three"} - - it does not contain any hidden fields of object: - expect (totable (Derived)).to_equal {"one", "two", three = true} - - - describe __tostring: - before: obj = Object {_type = "Derived", "one", "two", "three"} diff --git a/specs/operator_spec.yaml b/specs/operator_spec.yaml new file mode 100644 index 0000000..1b66084 --- /dev/null +++ b/specs/operator_spec.yaml @@ -0,0 +1,227 @@ +before: | + this_module = "std.operator" + global_table = "_G" + + M = require (this_module) + +specify std.operator: +- context when required: + - context by name: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + to_equal {} + + - context via the std module: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by="std"}). + to_equal {} + + +- describe concat: + - before: + f = M.concat + + - it stringifies its arguments: + expect (f (1, "")).to_be "1" + expect (f ("", 2)).to_be "2" + - it concatenates its arguments: + expect (f (1, 2)).to_be "12" + +- describe get: + - before: + f = M.get + + - it dereferences a table: + expect (f ({}, 1)).to_be (nil) + expect (f ({"foo", "bar"}, 1)).to_be "foo" + expect (f ({foo = "bar"}, "foo")).to_be "bar" + +- describe set: + - before: + f = M.set + + - it sets a table entry: + expect (f ({}, 1, 42)).to_equal {42} + expect (f ({}, "foo", 42)).to_equal {foo=42} + - it overwrites an existing entry: + expect (f ({1, 2}, 1, 42)).to_equal {42, 2} + expect (f ({foo="bar", baz="quux"}, "foo", 42)). + to_equal {foo=42, baz="quux"} + +- describe sum: + - before: + f = M.sum + + - it returns the sum of its arguments: + expect (f (99, 2)).to_be (99 + 2) + +- describe diff: + - before: + f = M.diff + + - it returns the difference of its arguments: + expect (f (99, 2)).to_be (99 - 2) + +- describe prod: + - before: + f = M.prod + + - it returns the product of its arguments: + expect (f (99, 2)).to_be (99 * 2) + +- describe quot: + - before: + f = M.quot + + - it returns the quotient of its arguments: + expect (f (99, 2)).to_be (99 / 2) + +- describe mod: + - before: + f = M.mod + + - it returns the modulus of its arguments: + expect (f (99, 2)).to_be (99 % 2) + +- describe pow: + - before: + f = M.pow + + - it returns the power of its arguments: + expect (f (99, 2)).to_be (99 ^ 2) + +- describe conj: + - before: + f = M.conj + + - it returns the logical and of its arguments: + expect (f (false, false)).to_be (false) + expect (f (false, true)).to_be (false) + expect (f (true, false)).to_be (false) + expect (f (true, true)).to_be (true) + - it supports truthy and falsey arguments: + expect (f ()).to_be (nil) + expect (f (0)).to_be (nil) + expect (f (nil, 0)).to_be (nil) + expect (f (0, "false")).to_be ("false") + +- describe disj: + - before: + f = M.disj + + - it returns the logical or of its arguments: + expect (f (false, false)).to_be (false) + expect (f (false, true)).to_be (true) + expect (f (true, false)).to_be (true) + expect (f (true, true)).to_be (true) + - it supports truthy and falsey arguments: + expect (f ()).to_be (nil) + expect (f (0)).to_be (0) + expect (f (nil, 0)).to_be (0) + expect (f (0, "false")).to_be (0) + +- describe neg: + - before: + f = M.neg + + - it returns the logical not of its argument: + expect (f (false)).to_be (true) + expect (f (true)).to_be (false) + - it supports truthy and falsey arguments: + expect (f ()).to_be (true) + expect (f (0)).to_be (false) + +- describe eq: + - before: + f = M.eq + + - it returns true if the arguments are equal: + expect (f ()).to_be (true) + expect (f ("foo", "foo")).to_be (true) + - it returns false if the arguments are unequal: + expect (f (1)).to_be (false) + expect (f ("foo", "bar")).to_be (false) + +- describe neq: + - before: + f = M.neq + + - it returns false if the arguments are equal: + expect (f (1, 1)).to_be (false) + expect (f ("foo", "foo")).to_be (false) + - it returns true if the arguments are unequal: + expect (f (1)).to_be (true) + expect (f ("foo", "bar")).to_be (true) + expect (f ({}, {})).to_be (true) + +- describe lt: + - before: + f = M.lt + + - it returns true if the arguments are in ascending order: + expect (f (1, 2)).to_be (true) + expect (f ("a", "b")).to_be (true) + - it returns false if the arguments are not in ascending order: + expect (f (2, 2)).to_be (false) + expect (f (3, 2)).to_be (false) + expect (f ("b", "b")).to_be (false) + expect (f ("c", "b")).to_be (false) + - it supports __lt metamethods: + List = require "std.list" {} + expect (f (List {1, 2, 3}, List {1, 2, 3, 4})).to_be (true) + expect (f (List {1, 2, 3}, List {1, 2, 3})).to_be (false) + expect (f (List {1, 2, 4}, List {1, 2, 3})).to_be (false) + +- describe lte: + - before: + f = M.lte + + - it returns true if the arguments are not in descending order: + expect (f (1, 2)).to_be (true) + expect (f (2, 2)).to_be (true) + expect (f ("a", "b")).to_be (true) + expect (f ("b", "b")).to_be (true) + - it returns false if the arguments are in descending order: + expect (f (3, 2)).to_be (false) + expect (f ("c", "b")).to_be (false) + - it supports __lte metamethods: + List = require "std.list" {} + expect (f (List {1, 2, 3}, List {1, 2, 3, 4})).to_be (true) + expect (f (List {1, 2, 3}, List {1, 2, 3})).to_be (true) + expect (f (List {1, 2, 4}, List {1, 2, 3})).to_be (false) + +- describe gt: + - before: + f = M.gt + + - it returns true if the arguments are in descending order: + expect (f (2, 1)).to_be (true) + expect (f ("b", "a")).to_be (true) + - it returns false if the arguments are not in descending order: + expect (f (2, 2)).to_be (false) + expect (f (2, 3)).to_be (false) + expect (f ("b", "b")).to_be (false) + expect (f ("b", "c")).to_be (false) + - it supports __lt metamethods: + List = require "std.list" {} + expect (f (List {1, 2, 3, 4}, List {1, 2, 3})).to_be (true) + expect (f (List {1, 2, 3}, List {1, 2, 3})).to_be (false) + expect (f (List {1, 2, 3}, List {1, 2, 4})).to_be (false) + +- describe gte: + - before: + f = M.gte + + - it returns true if the arguments are not in ascending order: + expect (f (2, 1)).to_be (true) + expect (f (2, 2)).to_be (true) + expect (f ("b", "a")).to_be (true) + expect (f ("b", "b")).to_be (true) + - it returns false if the arguments are in ascending order: + expect (f (2, 3)).to_be (false) + expect (f ("b", "c")).to_be (false) + - it supports __lte metamethods: + List = require "std.list" {} + expect (f (List {1, 2, 3, 4}, List {1, 2, 3})).to_be (true) + expect (f (List {1, 2, 3}, List {1, 2, 3})).to_be (true) + expect (f (List {1, 2, 3}, List {1, 2, 4})).to_be (false) diff --git a/specs/optparse_spec.yaml b/specs/optparse_spec.yaml index feae149..70f874e 100644 --- a/specs/optparse_spec.yaml +++ b/specs/optparse_spec.yaml @@ -8,7 +8,7 @@ specify std.optparse: help = [[ parseme (stdlib spec) 0α1 - Copyright © 2014 Gary V. Vaughan + Copyright © 2015 Gary V. Vaughan This test program comes with ABSOLUTELY NO WARRANTY. Usage: parseme [] ... @@ -58,42 +58,32 @@ specify std.optparse: to_match ("^Usage: parseme .*Banner .*Long .*Options:.*" .. "Footer .*/issues>%.") - it diagnoses incorrect input text: - expect (OptionParser "garbage in").to_error "argument must match" + expect (OptionParser "garbage in").to_raise "argument must match" - describe parser: - before: | - f = os.tmpname () - - function parse (arglist) - local d = f:gsub ("/[^/]*$", "", 1) - local h = io.open (f, "w") - - h:write ([[ - package.path = "]] .. package.path .. [[" - local OptionParser = require 'std.optparse' - local help = [=[]] .. help .. [[]=] - help = help:match ("^[%s\n]*(.-)[%s\n]*$") - - local parser = OptionParser (help) - local arg, opts = parser:parse (_G.arg) - - o = {} - for k, v in pairs (opts) do - table.insert (o, k .. " = " .. tostring (v)) - end - if #o > 0 then - table.sort (o) - print ("opts = { " .. table.concat (o, ", ") .. " }") - end - if #arg > 0 then - print ("args = { " .. table.concat (arg, ", ") .. " }") - end - ]]) - h:close () - - return hell.spawn {arg[-1], f, unpack (arglist)} - end - - after: os.remove (f) + code = [[ + package.path = "]] .. package.path .. [[" + local OptionParser = require 'std.optparse' + local help = [=[]] .. help .. [[]=] + help = help:match ("^[%s\n]*(.-)[%s\n]*$") + + local parser = OptionParser (help) + local arg, opts = parser:parse (_G.arg) + + o = {} + for k, v in pairs (opts) do + table.insert (o, k .. " = " .. tostring (v)) + end + if #o > 0 then + table.sort (o) + print ("opts = { " .. table.concat (o, ", ") .. " }") + end + if #arg > 0 then + print ("args = { " .. table.concat (arg, ", ") .. " }") + end + ]] + parse = bind (luaproc, {code}) - it responds to --version with version text: expect (parse {"--version"}). @@ -240,20 +230,21 @@ specify std.optparse: end - it prefers `prog.name` to `opts.program`: | code = [[prog = { file = "file", name = "name" }]] - expect (runscript (code)).to_fail_with "name: By 'eck!\n" + expect (runscript (code)).to_fail_while_matching ": name: By 'eck!\n" - it prefers `prog.file` to `opts.program`: | code = [[prog = { file = "file" }]] - expect (runscript (code)).to_fail_with "file: By 'eck!\n" + expect (runscript (code)).to_fail_while_matching ": file: By 'eck!\n" - it appends `prog.line` if any to `prog.file` over using `opts`: | code = [[ prog = { file = "file", line = 125 }; opts.line = 99]] - expect (runscript (code)).to_fail_with "file:125: By 'eck!\n" + expect (runscript (code)). + to_fail_while_matching ": file:125: By 'eck!\n" - it prefixes `opts.program` if any: | - expect (runscript ("")).to_fail_with "program: By 'eck!\n" + expect (runscript ("")).to_fail_while_matching ": program: By 'eck!\n" - it appends `opts.line` if any, to `opts.program`: | code = [[opts.line = 99]] expect (runscript (code)). - to_fail_with "program:99: By 'eck!\n" + to_fail_while_matching ": program:99: By 'eck!\n" - context with io.warn: - before: | @@ -286,13 +277,8 @@ specify std.optparse: - describe parser:on: - before: | - f = os.tmpname () - function parseargs (onargstr, arglist) - local d = f:gsub ("/[^/]*$", "", 1) - local h = io.open (f, "w") - - h:write ([[ + code = [[ package.path = "]] .. package.path .. [[" local OptionParser = require 'std.optparse' local help = [=[]] .. help .. [[]=] @@ -315,12 +301,10 @@ specify std.optparse: if #arg > 0 then print ("args = { " .. table.concat (arg, ", ") .. " }") end - ]]) - h:close () + ]] - return hell.spawn {arg[-1], f, unpack (arglist)} + return luaproc (code, arglist) end - - after: os.remove (f) - it recognises short options: expect (parseargs ([["x"]], {"-x"})). diff --git a/specs/package_spec.yaml b/specs/package_spec.yaml index 184cd00..2a4832e 100644 --- a/specs/package_spec.yaml +++ b/specs/package_spec.yaml @@ -38,58 +38,68 @@ specify std.package: - describe find: - - before: path = table.concat ({"begin", "m%ddl.", "end"}, M.pathsep) - - it diagnoses missing arguments: | - expect (M.find ()).to_error "bad argument #1 to find" - expect (M.find (path)).to_error "bad argument #2 to find" + - before: | + path = table.concat ({"begin", "m%ddl.", "end"}, M.pathsep) + + f = M.find + + - context with bad arguments: + badargs.diagnose (f, "std.package.find (string, string, ?int, ?boolean|:plain)") + - it returns nil for unmatched element: - expect (M.find (path, "unmatchable")).to_be (nil) + expect (f (path, "unmatchable")).to_be (nil) - it returns the element index for a matched element: - expect (M.find (path, "end")).to_be (3) + expect (f (path, "end")).to_be (3) - it returns the element text for a matched element: - i, element = M.find (path, "e.*n") + i, element = f (path, "e.*n") expect ({i, element}).to_equal {1, "begin"} - it accepts a search start element argument: - i, element = M.find (path, "e.*n", 2) + i, element = f (path, "e.*n", 2) expect ({i, element}).to_equal {3, "end"} - it works with plain text search strings: - expect (M.find (path, "m%ddl.")).to_be (nil) - i, element = M.find (path, "%ddl.", 1, ":plain") + expect (f (path, "m%ddl.")).to_be (nil) + i, element = f (path, "%ddl.", 1, ":plain") expect ({i, element}).to_equal {2, "m%ddl."} - describe insert: - - it diagnoses missing arguments: | - expect (M.insert ()).to_error "bad argument #1 to insert" - expect (M.insert (path)).to_error "wrong number of arguments" + - before: + f = M.insert + + - context with bad arguments: + badargs.diagnose (f, "std.package.insert (string, [int], string)") + - it appends by default: - expect (M.insert (path, "new")). + expect (f (path, "new")). to_be (M.normalize ("begin", "middle", "end", "new")) - it prepends with pos set to 1: - expect (M.insert (path, 1, "new")). + expect (f (path, 1, "new")). to_be (M.normalize ("new", "begin", "middle", "end")) - it can insert in the middle too: - expect (M.insert (path, 2, "new")). + expect (f (path, 2, "new")). to_be (M.normalize ("begin", "new", "middle", "end")) - expect (M.insert (path, 3, "new")). + expect (f (path, 3, "new")). to_be (M.normalize ("begin", "middle", "new", "end")) - it normalizes the returned path: path = table.concat ({"begin", "middle", "end"}, M.pathsep) - expect (M.insert (path, "new")). + expect (f (path, "new")). to_be (M.normalize ("begin", "middle", "end", "new")) - expect (M.insert (path, 1, "./x/../end")). + expect (f (path, 1, "./x/../end")). to_be (M.normalize ("end", "begin", "middle")) - describe mappath: - - before: + - before: | expected = require "std.string".split (path, M.pathsep) - - it diagnoses bad arguments: | - expect (M.mappath ()).to_error "bad argument #1 to mappath" - expect (M.mappath ("")).to_error "bad argument #2 to mappath" + + f = M.mappath + + - context with bad arguments: + badargs.diagnose (f, "std.package.mappath (string, function, ?any*)") + - it calls a function with each path element: t = {} - M.mappath (path, function (e) t[#t + 1] = e end) + f (path, function (e) t[#t + 1] = e end) expect (t).to_equal (expected) - it passes additional arguments through: | reversed = {} @@ -97,70 +107,75 @@ specify std.package: table.insert (reversed, expected[i]) end t = {} - M.mappath (path, function (e, pos) table.insert (t, pos, e) end, 1) + f (path, function (e, pos) table.insert (t, pos, e) end, 1) expect (t).to_equal (reversed) - describe normalize: - - it diagnoses bad arguments: - expect (M.normalize ()).to_error "wrong number of arguments" + - before: + f = M.normalize + + - context with bad arguments: + badargs.diagnose (f, "std.package.normalize (string*)") - context with a single element: - it strips redundant . directories: - expect (M.normalize "./x/./y/.").to_be (catfile (".", "x", "y")) + expect (f "./x/./y/.").to_be (catfile (".", "x", "y")) - it strips redundant .. directories: - expect (M.normalize "../x/../y/z/..").to_be (catfile ("..", "y")) + expect (f "../x/../y/z/..").to_be (catfile ("..", "y")) - it normalizes / to platform dirsep: - expect (M.normalize "/foo/bar").to_be (catfile ("", "foo", "bar")) + expect (f "/foo/bar").to_be (catfile ("", "foo", "bar")) - it normalizes ? to platform path_mark: - expect (M.normalize "?.lua"). + expect (f "?.lua"). to_be (catfile (".", M.path_mark .. ".lua")) - it strips redundant trailing /: - expect (M.normalize "/foo/bar/").to_be (catfile ("", "foo", "bar")) + expect (f "/foo/bar/").to_be (catfile ("", "foo", "bar")) - it inserts missing ./ for relative paths: for _, path in ipairs {"x", "./x"} do - expect (M.normalize (path)).to_be (catfile (".", "x")) + expect (f (path)).to_be (catfile (".", "x")) end - - context with multiple elements: - it strips redundant . directories: - expect (M.normalize ("./x/./y/.", "x")). + expect (f ("./x/./y/.", "x")). to_be (catpath (catfile (".", "x", "y"), catfile (".", "x"))) - it strips redundant .. directories: - expect (M.normalize ("../x/../y/z/..", "x")). + expect (f ("../x/../y/z/..", "x")). to_be (catpath (catfile ("..", "y"), catfile (".", "x"))) - it normalizes / to platform dirsep: - expect (M.normalize ("/foo/bar", "x")). + expect (f ("/foo/bar", "x")). to_be (catpath (catfile ("", "foo", "bar"), catfile (".", "x"))) - it normalizes ? to platform path_mark: - expect (M.normalize ("?.lua", "x")). + expect (f ("?.lua", "x")). to_be (catpath (catfile (".", M.path_mark .. ".lua"), catfile (".", "x"))) - it strips redundant trailing /: - expect (M.normalize ("/foo/bar/", "x")). + expect (f ("/foo/bar/", "x")). to_be (catpath (catfile ("", "foo", "bar"), catfile (".", "x"))) - it inserts missing ./ for relative paths: for _, path in ipairs {"x", "./x"} do - expect (M.normalize (path, "a")). + expect (f (path, "a")). to_be (catpath (catfile (".", "x"), catfile (".", "a"))) end - - it eliminates all but the first equivalent elements: - expect (M.normalize (catpath ("1", "x", "2", "./x", "./2", "./x/../x"))). + expect (f (catpath ("1", "x", "2", "./x", "./2", "./x/../x"))). to_be (catpath ("./1", "./x", "./2")) - describe remove: - - it diagnoses bad arguments: | - expect (M.remove ()).to_error "bad argument #1 to remove" + - before: + f = M.remove + + - context with bad arguments: + badargs.diagnose (f, "std.package.remove (string, ?int)") + - it removes the last item by default: - expect (M.remove (path)).to_be (M.normalize ("begin", "middle")) + expect (f (path)).to_be (M.normalize ("begin", "middle")) - it pops the first item with pos set to 1: - expect (M.remove (path, 1)).to_be (M.normalize ("middle", "end")) + expect (f (path, 1)).to_be (M.normalize ("middle", "end")) - it can remove from the middle too: - expect (M.remove (path, 2)).to_be (M.normalize ("begin", "end")) + expect (f (path, 2)).to_be (M.normalize ("begin", "end")) - it does not normalize the returned path: path = table.concat ({"begin", "middle", "end"}, M.pathsep) - expect (M.remove (path)). + expect (f (path)). to_be (table.concat ({"begin", "middle"}, M.pathsep)) diff --git a/specs/set_spec.yaml b/specs/set_spec.yaml index e401aef..ac87faf 100644 --- a/specs/set_spec.yaml +++ b/specs/set_spec.yaml @@ -1,7 +1,6 @@ before: Set = require "std.set" - prototype = (require "std.object").prototype - totable = (require "std.table").totable + prototype = require "std.object".prototype s = Set {"foo", "bar", "bar"} specify std.set: @@ -62,8 +61,6 @@ specify std.set: expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members of the first that are not in the second: expect (Set.difference (r, s)).to_equal (Set {"foo"}) - - it coerces a table argument to a set: - expect (Set.difference (r, {"bar"})).to_equal (Set {"baz", "foo"}) - context when called as a set metamethod: - it returns a set object: expect (prototype (r - s)).to_be "Set" @@ -73,8 +70,6 @@ specify std.set: expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members of the first that are not in the second: expect (r - s).to_equal (Set {"foo"}) - - it coerces a table argument to a set: - expect (r - {"bar"}).to_equal (Set {"baz", "foo"}) - describe elems: @@ -149,9 +144,6 @@ specify std.set: - it returns a set containing members common to both arguments: expect (Set.intersection (r, s)). to_equal (Set {"bar", "baz"}) - - it coerces a table argument to a set: - expect (Set.intersection (r, {"bar", "quux"})). - to_equal (Set {"bar"}) - context when called as a set metamethod: - it returns a set object: q = r * s @@ -162,8 +154,6 @@ specify std.set: expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members common to both arguments: expect (r * s).to_equal (Set {"bar", "baz"}) - - it coerces a table argument to a set: - expect (r * {"bar", "quux"}).to_equal (Set {"bar"}) - describe member: @@ -201,9 +191,6 @@ specify std.set: - it fails when set does not contain all elements of another: s = s + Set {"quux"} expect (Set.proper_subset (r, s)).to_be (false) - - it coerces a table argument to a set: - expect (Set.proper_subset (s, {"foo", "bar", "baz"})).to_be (true) - expect (Set.proper_subset (s, {"foo"})).to_be (false) - context when called as a set metamethod: - it succeeds when set contains all elements of another: expect (s < r).to_be (true) @@ -229,9 +216,6 @@ specify std.set: - it fails when set does not contain all elements of another: s = s + Set {"quux"} expect (Set.subset (r, s)).to_be (false) - - it coerces a table argument to a set: - expect (Set.subset (s, {"foo", "bar", "baz"})).to_be (true) - expect (Set.subset (s, {"foo"})).to_be (false) - context when called as a set metamethod: - it succeeds when set contains all elements of another: expect (s <= r).to_be (true) @@ -259,9 +243,6 @@ specify std.set: - it returns a set containing members in only one argument set: expect (Set.symmetric_difference (r, s)). to_equal (Set {"foo", "quux"}) - - it coerces a table argument to a set: - expect (Set.symmetric_difference (r, {"bar"})). - to_equal (Set {"baz", "foo"}) - context when called as a set metamethod: - it returns a set object: expect (prototype (r / s)).to_be "Set" @@ -271,8 +252,6 @@ specify std.set: expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members in only one argument set: expect (r / s).to_equal (Set {"foo", "quux"}) - - it coerces a table argument to a set: - expect (r / {"bar"}).to_equal (Set {"baz", "foo"}) - describe union: @@ -290,9 +269,6 @@ specify std.set: - it returns a set containing members in only one argument set: expect (Set.union (r, s)). to_equal (Set {"foo", "bar", "baz", "quux"}) - - it coerces a table argument to a set: - expect (Set.union (r, {"quux"})). - to_equal (Set {"foo", "bar", "baz", "quux"}) - context when called as a set metamethod: - it returns a set object: expect (prototype (r + s)).to_be "Set" @@ -302,23 +278,6 @@ specify std.set: expect (s).to_equal (Set {"bar", "baz", "quux"}) - it returns a set containing members in only one argument set: expect (r + s).to_equal (Set {"foo", "bar", "baz", "quux"}) - - it coerces a table argument to a set: - expect (r + {"quux"}). - to_equal (Set {"foo", "bar", "baz", "quux"}) - - -- describe __totable: - - before: - s = Set {"foo", "bar", "baz"} - - - it returns a table: - expect (prototype (totable (s))).to_be "table" - - it contains all non-hidden fields of object: - expect (totable (s)).to_contain.all_of {"foo", "bar", "baz"} - - it contains fields of set in order: - expect (totable (s)).to_equal {"bar", "baz", "foo"} - - it does not contain any hidden fields of object: - expect (totable (s)).to_equal {"bar", "baz", "foo"} - describe __tostring: diff --git a/specs/spec_helper.lua.in b/specs/spec_helper.lua similarity index 57% rename from specs/spec_helper.lua.in rename to specs/spec_helper.lua index 99a0fae..b5dc3b9 100644 --- a/specs/spec_helper.lua.in +++ b/specs/spec_helper.lua @@ -1,14 +1,65 @@ -local hell = require "specl.shell" local inprocess = require "specl.inprocess" +local hell = require "specl.shell" local std = require "specl.std" -package.path = std.package.normalize ("lib/?.lua", package.path) +badargs = require "specl.badargs" +unpack = table.unpack or unpack + +local top_srcdir = os.getenv "top_srcdir" or "." +local top_builddir = os.getenv "top_builddir" or "." + +package.path = std.package.normalize ( + top_builddir .. "/lib/?.lua", + top_builddir .. "/lib/?/init.lua", + top_srcdir .. "/lib/?.lua", + top_srcdir .. "/lib/?/init.lua", + package.path + ) + +-- Allow user override of LUA binary used by hell.spawn, falling +-- back to environment PATH search for "lua" if nothing else works. +local LUA = os.getenv "LUA" or "lua" + + +-- Tweak _DEBUG without tripping over Specl nested environments. +setdebug = require "std.debug"._setdebug + + +-- Wrap up badargs function in a succinct single call. +function init (M, mname, fname) + local name = (mname .. "." .. fname):gsub ("^%.", "") + return M[fname], function (...) return badargs.format (name, ...) end +end + + +-- A copy of base.lua:prototype, so that an unloadable base.lua doesn't +-- prevent everything else from working. +function prototype (o) + return (getmetatable (o) or {})._type or io.type (o) or type (o) +end + + +function nop () end + + +-- Error message specifications use this to shorten argument lists. +-- Copied from functional.lua to avoid breaking all tests if functional +-- cannot be loaded correctly. +function bind (f, fix) + return function (...) + local arg = {} + for i, v in pairs (fix) do + arg[i] = v + end + local i = 1 + for _, v in pairs {...} do + while arg[i] ~= nil do i = i + 1 end + arg[i] = v + end + return f (unpack (arg)) + end +end --- Substitute configured LUA so that hell.spawn doesn't pick up --- a different Lua binary to the one used by Specl itself. If --- we could rely on luaposix availability `posix.getenv` would --- be a nicer way to find this... -local LUA = "@LUA@" local function mkscript (code) local f = os.tmpname () @@ -18,16 +69,41 @@ local function mkscript (code) return f end -function luaproc (code) + +--- Run some Lua code with the given arguments and input. +-- @string code valid Lua code +-- @tparam[opt={}] string|table arg single argument, or table of +-- arguments for the script invocation. +-- @string[opt] stdin standard input contents for the script process +-- @treturn specl.shell.Process|nil status of resulting process if +-- execution was successful, otherwise nil +function luaproc (code, arg, stdin) local f = mkscript (code) - local proc = hell.spawn { - LUA, f; - env = { LUA_PATH=package.path, LUA_INIT="", LUA_INIT_5_2="" }, - } + if type (arg) ~= "table" then arg = {arg} end + local cmd = {LUA, f, unpack (arg)} + -- inject env and stdin keys separately to avoid truncating `...` in + -- cmd constructor + cmd.env = { LUA_PATH=package.path, LUA_INIT="", LUA_INIT_5_2="" } + cmd.stdin = stdin + local proc = hell.spawn (cmd) os.remove (f) return proc end + +--- Concatenate the contents of listed existing files. +-- @string ... names of existing files +-- @treturn string concatenated contents of those files +function concat_file_content (...) + local t = {} + for _, name in ipairs {...} do + h = io.open (name) + t[#t + 1] = h:read "*a" + end + return table.concat (t) +end + + local function tabulate_output (code) local proc = luaproc (code) if proc.status ~= 0 then return error (proc.errout) end @@ -90,7 +166,9 @@ function show_apis (argt) local M = require "]] .. not_in .. [[" for k in pairs (M) do - if from[k] ~= M[k] then print (k) end + -- M[1] is typically the module namespace name, don't match + -- that! + if k ~= 1 and from[k] ~= M[k] then print (k) end end ]]) @@ -123,10 +201,6 @@ function show_apis (argt) end --- Not local, so that it is available in spec examples. -totable = (require "std.table").totable - - -- Stub inprocess.capture if necessary; new in Specl 12. capture = inprocess.capture or function (f, arg) return nil, nil, f (unpack (arg or {})) end @@ -135,7 +209,6 @@ capture = inprocess.capture or do -- Custom matcher for set size and set membership. - local set = require "std.set" local util = require "specl.util" local matchers = require "specl.matchers" @@ -163,7 +236,7 @@ do matchers.have_member = Matcher { function (self, actual, expect) - return set.member (actual, expect) + return actual[expect] ~= nil end, actual = "set", @@ -177,4 +250,7 @@ do util.concat (alternatives, util.QUOTED) .. ", " end, } + + -- Alias that doesn't tickle sc_error_message_uppercase. + matchers.raise = matchers.error end diff --git a/specs/specs.mk b/specs/specs.mk index 0f5aa9b..591b61c 100644 --- a/specs/specs.mk +++ b/specs/specs.mk @@ -1,17 +1,6 @@ # Specl specs make rules. -## ------------ ## -## Environment. ## -## ------------ ## - -## !!WARNING!! When bootstrap.conf:buildreq specl setting requires specl -## 12 or higher, remove this entire Environment section! - -specs_path = $(abs_builddir)/specs/?.lua -SPECL_ENV = LUA_PATH="$(specs_path);$(std_path);$(LUA_PATH)" LUA_INIT= LUA_INIT_5_2= - - ## ------ ## ## Specs. ## ## ------ ## @@ -24,7 +13,6 @@ SPECL_OPTS = --unicode ## affected. specl_SPECS = \ - $(srcdir)/specs/base_spec.yaml \ $(srcdir)/specs/container_spec.yaml \ $(srcdir)/specs/debug_spec.yaml \ $(srcdir)/specs/functional_spec.yaml \ @@ -32,6 +20,7 @@ specl_SPECS = \ $(srcdir)/specs/list_spec.yaml \ $(srcdir)/specs/math_spec.yaml \ $(srcdir)/specs/object_spec.yaml \ + $(srcdir)/specs/operator_spec.yaml \ $(srcdir)/specs/optparse_spec.yaml \ $(srcdir)/specs/package_spec.yaml \ $(srcdir)/specs/set_spec.yaml \ @@ -43,9 +32,7 @@ specl_SPECS = \ $(NOTHING_ELSE) EXTRA_DIST += \ - $(srcdir)/specs/spec_helper.lua.in \ + $(srcdir)/specs/spec_helper.lua \ $(NOTHING_ELSE) -specl-check-local: specs/spec_helper.lua - include build-aux/specl.mk diff --git a/specs/std_spec.yaml b/specs/std_spec.yaml index f6477f5..f1d428d 100644 --- a/specs/std_spec.yaml +++ b/specs/std_spec.yaml @@ -1,89 +1,325 @@ -before: - std = require "std" +before: | + this_module = "std" + global_table = "_G" + + exported_apis = { "assert", "barrel", "elems", "eval", "getmetamethod", + "ielems", "ipairs", "ireverse", "monkey_patch", "pairs", + "require", "ripairs", "tostring", "version" } + + -- Tables with iterator metamethods used by various examples. + __pairs = setmetatable ({ content = "a string" }, { + __pairs = function (t) + return function (x, n) + if n < #x.content then + return n+1, string.sub (x.content, n+1, n+1) + end + end, t, 0 + end, + }) + __index = setmetatable ({ content = "a string" }, { + __index = function (t, n) + if n <= #t.content then + return t.content:sub (n, n) + end + end, + __len = function (t) return #t.content end, + }) + + M = require (this_module) + specify std: -- describe lazy loading: +- context when required: + - it does not touch the global table: + expect (show_apis {added_to=global_table, by=this_module}). + to_equal {} + - it exports the documented apis: + t = {} + for k in pairs (M) do t[#t + 1] = k end + expect (t).to_contain.a_permutation_of (exported_apis) + +- context when lazy loading: - it has no submodules on initial load: - expect (std).to_equal { - barrel = std.barrel, - monkey_patch = std.monkey_patch, - version = std.version, - } + for _, v in pairs (M) do + expect (type (v)).not_to_be "table" + end - it loads submodules on demand: - lazy = std.set + lazy = M.set expect (lazy).to_be (require "std.set") - it loads submodule functions on demand: - expect (std.object.prototype (std.set {"Lazy"})). + expect (M.object.prototype (M.set {"Lazy"})). to_be "Set" +- describe assert: + - before: + f = M.assert + + - context with bad arguments: + badargs.diagnose (f, "std.assert (?any, ?string, ?any*)") + + - context when it does not trigger: + - it has a truthy initial argument: + expect (f (1)).not_to_raise "any error" + expect (f (true)).not_to_raise "any error" + expect (f "yes").not_to_raise "any error" + expect (f (false == false)).not_to_raise "any error" + - it returns the initial argument: + expect (f (1)).to_be (1) + expect (f (true)).to_be (true) + expect (f "yes").to_be "yes" + expect (f (false == false)).to_be (true) + - context when it triggers: + - it has a falsey initial argument: + expect (f ()).to_raise () + expect (f (false)).to_raise () + expect (f (1 == 0)).to_raise () + - it throws an optional error string: + expect (f (false, "ah boo")).to_raise "ah boo" + - it plugs specifiers with string.format: | + expect (f (nil, "%s %d: %q", "here", 42, "a string")). + to_raise (string.format ("%s %d: %q", "here", 42, "a string")) + + - describe barrel: - before: - f = std.barrel - io_mt = {} - t = { + mt = { "file metatable" } + namespace = { io = { - stdin = setmetatable ({}, io_mt), - stdout = setmetatable ({}, io_mt), - stderr = setmetatable ({}, io_mt), + stdin = setmetatable ({}, mt), + stdout = setmetatable ({}, mt), + stderr = setmetatable ({}, mt), }, - math = {}, - table = {}, } - f (t) + + f = M.barrel + + f (namespace) + + - context with bad arguments: + badargs.diagnose (f, "std.barrel (?table)") + + - it installs std monkey patches: + for _, api in ipairs (exported_apis) do + if type (M[api]) == "function" and + api ~= "barrel" and api ~= "monkey_patch" + then + expect (namespace[api]).to_be (M[api]) + end + end - it installs std.io monkey patches: - expect (io_mt.readlines).to_be (std.io.readlines) - expect (io_mt.writelines).to_be (std.io.writelines) + for _, api in ipairs { "catdir", "catfile", "die", "monkey_patch", + "process_files", "readlines", "shell", "slurp", "splitdir", "warn", + "writelines" } + do + expect (namespace.io[api]).to_be (M.io[api]) + end + expect (mt.readlines).to_be (M.io.readlines) + expect (mt.writelines).to_be (M.io.writelines) - it installs std.math monkey patches: - expect (t.math.floor).to_be (std.math.floor) + for _, api in ipairs { "floor", "monkey_patch", "round" } do + expect (namespace.math[api]).to_be (M.math[api]) + end - it installs std.string monkey patches: # FIXME: string metatable monkey-patches leak out! mt = getmetatable "" - expect (mt.__append).to_be (std.string.__append) - expect (mt.__concat).to_be (std.string.__concat) - expect (mt.__index).to_be (std.string.__index) - expect (t.assert).to_be (std.string.assert) - expect (t.tostring).to_be (std.string.tostring) + expect (mt.__concat).to_be (M.string.__concat) + expect (mt.__index).to_be (M.string.__index) + + for _, api in ipairs { "__concat", "__index", "caps", "chomp", + "escape_pattern", "escape_shell", "finds", "format", "ltrim", + "monkey_patch", "numbertosi", "ordinal_suffix", "pad", "pickle", + "prettytostring", "render", "rtrim", "split", "tfind", "trim", + "wrap" } + do + expect (namespace.string[api]).to_be (M.string[api]) + end - it installs std.table monkey patches: - expect (t.table.sort).to_be (std.table.sort) - - it scribbles into the supplied namespace: - expect (t).should_equal { - assert = std.string.assert, - bind = std.functional.bind, - collect = std.functional.collect, - compose = std.functional.compose, - curry = std.functional.curry, - die = std.io.die, - eval = std.functional.eval, - filter = std.functional.filter, - fold = std.functional.fold, - id = std.functional.id, - ileaves = std.tree.ileaves, - inodes = std.tree.inodes, - io = t.io, - leaves = std.tree.leaves, - map = std.functional.map, - math = t.math, - memoize = std.functional.memoize, - metamethod = std.table.metamethod, - nodes = std.tree.nodes, - op = std.functional.op, - pack = std.table.pack, - pickle = std.string.pickle, - prettytostring = std.string.prettytostring, - render = std.string.render, - require_version = std.string.require_version, - ripairs = std.table.ripairs, - table = t.table, - tostring = std.string.tostring, - totable = std.table.totable, - warn = std.io.warn, - } - - it diagnoses non-table argument: - expect (f "bad").to_error "table expected" + for _, api in ipairs { "clone", "clone_select", "depair", "empty", + "enpair", "flatten", "insert", "invert", "keys", "len", "maxn", + "merge", "merge_select", "monkey_patch", "new", "pack", "project", + "shape", "size", "sort", "values" } + do + expect (namespace.table[api]).to_be (M.table[api]) + end + - it scribbles backwards compatibility apis: + for api, fn in pairs { + bind = M.functional.bind, + collect = M.functional.collect, + compose = M.functional.compose, + curry = M.functional.curry, + die = M.io.die, + filter = M.functional.filter, + fold = M.functional.fold, + id = M.functional.id, + ileaves = M.tree.ileaves, + inodes = M.tree.inodes, + leaves = M.tree.leaves, + map = M.functional.map, + metamethod = M.getmetamethod, + nodes = M.tree.nodes, + op = M.operator, + pack = M.table.pack, + pickle = M.string.pickle, + prettytostring = M.string.prettytostring, + render = M.string.render, + require_version = M.require, + warn = M.io.warn, + } do + expect (namespace[api]).to_be (fn) + end + +- describe elems: + - before: + f = M.elems + + - context with bad arguments: + badargs.diagnose (f, "std.elems (table)") + + - it is an iterator over table values: + t = {} + for e in f {"foo", bar = "baz", 42} do + t[#t + 1] = e + end + expect (t).to_contain.a_permutation_of {"foo", "baz", 42} + - it respects __pairs metamethod: | + t = {} + for v in f (__pairs) do t[#t + 1] = v end + expect (t). + to_contain.a_permutation_of {"a", " ", "s", "t", "r", "i", "n", "g"} + - it works for an empty list: + t = {} + for e in f {} do t[#t + 1] = e end + expect (t).to_equal {} + + +- describe eval: + - before: + f = M.eval + + - context with bad arguments: + badargs.diagnose (f, "std.eval (string)") + + - it diagnoses invalid lua: + # Some internal error when eval tries to call uncompilable "=" code. + expect (f "=").to_raise () + - it evaluates a string of lua code: + expect (f "math.min (2, 10)").to_be (math.min (2, 10)) + + +- describe getmetamethod: + - before: + f = M.getmetamethod + + - context with bad arguments: + badargs.diagnose (f, "std.getmetamethod (object|table, string)") + + - context with a table: + - before: + method = function () end + t = setmetatable ({}, { _type = "table", _method = method }) + - it returns nil for missing metamethods: + expect (f (t, "not a metamethod on t")).to_be (nil) + - it returns nil for non-function metatable entries: + expect (f (t, "_type")).to_be (nil) + - it returns a method from the metatable: + expect (f (t, "_method")).to_be (method) + + - context with an object: + - before: + Object = require "std.object" + objmethod = function () end + obj = Object { + _type = "DerivedObject", + _method = objmethod, + } + - it returns nil for missing metamethods: + expect (f (obj, "not a metamethod on obj")).to_be (nil) + - it returns nil for non-function metatable entries: + expect (f (obj, "_type")).to_be (nil) + - it returns a method from the metatable: + expect (f (obj, "_method")).to_be (objmethod) + + +- describe ielems: + - before: + f = M.ielems + + - context with bad arguments: + badargs.diagnose (f, "std.ielems (table)") + + - it is an iterator over integer-keyed table values: + t = {} + for e in f {"foo", 42} do + t[#t + 1] = e + end + expect (t).to_equal {"foo", 42} + - it ignores the dictionary part of a table: + t = {} + for e in f {"foo", 42; bar = "baz", qux = "quux"} do + t[#t + 1] = e + end + expect (t).to_equal {"foo", 42} + - it respects __len metamethod: + t = {} + for v in f (__index) do t[#t + 1] = v end + expect (t).to_equal {"a", " ", "s", "t", "r", "i", "n", "g"} + - it works for an empty list: + t = {} + for e in f {} do t[#t + 1] = e end + expect (t).to_equal {} + + +- describe ipairs: + - before: + f = M.ipairs + + - context with bad arguments: + badargs.diagnose (f, "std.ipairs (table)") + + - it is an iterator over integer-keyed table values: + t = {} + for i, v in f {"foo", 42} do + t[i] = v + end + expect (t).to_equal {"foo", 42} + - it ignores the dictionary part of a table: + t = {} + for i, v in f {"foo", 42; bar = "baz", qux = "quux"} do + t[i] = v + end + expect (t).to_equal {"foo", 42} + - it respects __len metamethod: + t = {} + for k, v in f (__index) do t[k] = v end + expect (t).to_equal {"a", " ", "s", "t", "r", "i", "n", "g"} + - it works for an empty list: + t = {} + for i, v in f {} do t[i] = v end + expect (t).to_equal {} + + +- describe ireverse: + - before: + f = M.ireverse + + - context with bad arguments: + badargs.diagnose (f, "std.ireverse (table)") + + - it returns a new list: + t = {1, 2, 5} + expect (f (t)).not_to_be (t) + - it reverses the elements relative to the original list: + expect (f {1, 2, "five"}).to_equal {"five", 2, 1} + - it ignores the dictionary part of a table: + expect (f {1, 2, "five"; a = "b", c = "d"}).to_equal {"five", 2, 1} + - it respects __len metamethod: + expect (f (__index)).to_equal {"g", "n", "i", "r", "t", "s", " ", "a"} + - it works for an empty list: + expect (f {}).to_equal {} + - describe monkey_patch: - before: - f = std.monkey_patch io_mt = {} t = { io = { @@ -94,21 +330,182 @@ specify std: math = {}, table = {}, } + + f = M.monkey_patch + f (t) - - it installs std.io monkey patches: - expect (io_mt.readlines).to_be (std.io.readlines) - expect (io_mt.writelines).to_be (std.io.writelines) - - it installs std.math monkey patches: - expect (t.math.floor).to_be (std.math.floor) - - it installs std.string monkey patches: - # FIXME: string metatable monkey-patches leak out! - mt = getmetatable "" - expect (mt.__append).to_be (std.string.__append) - expect (mt.__concat).to_be (std.string.__concat) - expect (mt.__index).to_be (std.string.__index) - expect (t.assert).to_be (std.string.assert) - expect (t.tostring).to_be (std.string.tostring) - - it installs std.table monkey patches: - expect (t.table.sort).to_be (std.table.sort) - - it diagnoses non-table argument: - expect (f "bad").to_error "table expected" + + - context with bad arguments: + badargs.diagnose (f, "std.monkey_patch (?table)") + + - it installs std module functions: + for _, v in ipairs (exported_apis) do + if type (M[v]) == "function" and v ~= "barrel" and v ~= "monkey_patch" then + expect (t[v]).to_be (M[v]) + end + end + + +- describe pairs: + - before: + f = M.pairs + + - context with bad arguments: + badargs.diagnose (f, "std.pairs (table)") + + - it is an iterator over all table values: + t = {} + for k, v in f {"foo", bar = "baz", 42} do + t[k] = v + end + expect (t).to_equal {"foo", bar = "baz", 42} + - it respects __pairs metamethod: | + t = {} + for k, v in f (__pairs) do t[k] = v end + expect (t). + to_contain.a_permutation_of {"a", " ", "s", "t", "r", "i", "n", "g"} + - it works for an empty list: + t = {} + for k, v in f {} do t[k] = v end + expect (t).to_equal {} + + +- describe require: + - before: + f = M.require + + - context with bad arguments: + badargs.diagnose (f, "std.require (string, ?string, ?string, ?string)") + + - it diagnoses non-existent module: + expect (f ("module-not-exists", "", "")).to_raise "module-not-exists" + - it diagnoses module too old: + expect (f ("std", "9999", "9999")). + to_raise "require 'std' with at least version 9999," + - it diagnoses module too new: + expect (f ("std", "0", "0")). + to_raise "require 'std' with version less than 0," + - context when the module version is compatible: + - it returns the module table: + expect (f ("std", "0", "9999")).to_be (require "std") + - it places no upper bound by default: + expect (f ("std", "41")).to_be (require "std") + - it places no lower bound by default: + expect (f "std").to_be (require "std") + - it uses _VERSION when version field is nil: + std = require "std" + M._VERSION, M.version = M.version, M._VERSION + expect (f ("std", "41", "9999")).to_be (require "std") + M._VERSION, M.version = M.version, M._VERSION + - context with semantic versioning: + - before: + std = require "std" + ver = std.version + std.version = "1.2.3" + - after: + std.version = ver + - it diagnoses module too old: + expect (f ("std", "1.2.4")). + to_raise "require 'std' with at least version 1.2.4," + expect (f ("std", "1.3")). + to_raise "require 'std' with at least version 1.3," + expect (f ("std", "2.1.2")). + to_raise "require 'std' with at least version 2.1.2," + expect (f ("std", "2")). + to_raise "require 'std' with at least version 2," + expect (f ("std", "1.2.10")). + to_raise "require 'std' with at least version 1.2.10," + - it diagnoses module too new: + expect (f ("std", nil, "1.2.2")). + to_raise "require 'std' with version less than 1.2.2," + expect (f ("std", nil, "1.1")). + to_raise "require 'std' with version less than 1.1," + expect (f ("std", nil, "1.1.2")). + to_raise "require 'std' with version less than 1.1.2," + expect (f ("std", nil, "1")). + to_raise "require 'std' with version less than 1," + - it returns modules with version in range: + expect (f ("std")).to_be (std) + expect (f ("std", "1")).to_be (std) + expect (f ("std", "1.2.3")).to_be (std) + expect (f ("std", nil, "2")).to_be (std) + expect (f ("std", nil, "1.3")).to_be (std) + expect (f ("std", nil, "1.2.10")).to_be (std) + expect (f ("std", "1.2.3", "1.2.4")).to_be (std) + - context with several numbers in version string: + - before: + std = require "std" + ver = std.version + std.version = "standard library for Lua 5.3 / 41.0.0" + - after: + std.version = ver + - it diagnoses module too old: + expect (f ("std", "42")).to_raise () + - it diagnoses module too new: + expect (f ("std", nil, "40")).to_raise () + - it returns modules with version in range: + expect (f ("std")).to_be (std) + expect (f ("std", "1")).to_be (std) + expect (f ("std", "41")).to_be (std) + expect (f ("std", nil, "42")).to_be (std) + expect (f ("std", "41", "42")).to_be (std) + + +- describe ripairs: + - before: + f = M.ripairs + + - context with bad arguments: + badargs.diagnose (f, "std.ripairs (table)") + + - it returns a function, the table and a number: + fn, t, i = f {1, 2, 3} + expect ({type (fn), t, type (i)}).to_equal {"function", {1, 2, 3}, "number"} + - it iterates over the array part of a table: + t, u = {1, 2, 3; a=4, b=5, c=6}, {} + for i, v in f (t) do u[i] = v end + expect (u).to_equal {1, 2, 3} + - it returns elements in reverse order: + t, u = {"one", "two", "five"}, {} + for _, v in f (t) do u[#u + 1] = v end + expect (u).to_equal {"five", "two", "one"} + - it respects __len metamethod: + t = {} + for i, v in f (__index) do t[i] = v end + expect (t).to_equal {"a", " ", "s", "t", "r", "i", "n", "g"} + t = {} + for _, v in f (__index) do t[#t + 1] = v end + expect (t).to_equal {"g", "n", "i", "r", "t", "s", " ", "a"} + - it works with the empty list: + t = {} + for k, v in f {} do t[k] = v end + expect (t).to_equal {} + + +- describe tostring: + - before: + f = M.tostring + + - context with bad arguments: + badargs.diagnose (f, "std.tostring (?any)") + + - it renders primitives exactly like system tostring: + expect (f (nil)).to_be (tostring (nil)) + expect (f (false)).to_be (tostring (false)) + expect (f (42)).to_be (tostring (42)) + expect (f (f)).to_be (tostring (f)) + expect (f "a string").to_be "a string" + - it renders empty tables as a pair of braces: + expect (f {}).to_be ("{}") + - it renders table array part compactly: + expect (f {"one", "two", "five"}). + to_be '{1=one,2=two,3=five}' + - it renders a table dictionary part compactly: + expect (f { one = true, two = 2, three = {3}}). + to_be '{one=true,three={1=3},two=2}' + - it renders table keys in table.sort order: + expect (f { one = 3, two = 5, three = 4, four = 2, five = 1 }). + to_be '{five=1,four=2,one=3,three=4,two=5}' + - it renders keys with invalid symbol names compactly: + expect (f { _ = 0, word = 0, ["?"] = 1, ["a-key"] = 1, ["[]"] = 1 }). + to_be '{?=1,[]=1,_=0,a-key=1,word=0}' diff --git a/specs/strbuf_spec.yaml b/specs/strbuf_spec.yaml index efdff04..6cbf72e 100644 --- a/specs/strbuf_spec.yaml +++ b/specs/strbuf_spec.yaml @@ -71,15 +71,3 @@ specify std.strbuf: b = b .. "baz" expect (object.type (b)).to_be "StrBuf" expect (tostring (b)).to_be "foobarbaz" - - -- describe __totable: - - before: - totable = (require "std.table").totable - - - it returns a table: - expect (object.type (totable (b))).to_be "table" - - it contains all non-hidden fields of object: - expect (totable (b)).to_contain.all_of {"foo", "bar"} - - it does not contain any hidden fields of object: - expect (totable (b)).to_equal {"foo", "bar"} diff --git a/specs/string_spec.yaml b/specs/string_spec.yaml index 205ff4f..321a134 100644 --- a/specs/string_spec.yaml +++ b/specs/string_spec.yaml @@ -1,18 +1,17 @@ -before: | +before: base_module = "string" this_module = "std.string" global_table = "_G" - extend_base = { "__append", "__concat", "__index", - "assert", "caps", "chomp", "escape_pattern", - "escape_shell", "finds", "format", "ltrim", - "monkey_patch", "numbertosi", "ordinal_suffix", - "pad", "pickle", "prettytostring", "render", - "require_version", "rtrim", "split", "tfind", - "tostring", "trim", "wrap" } + extend_base = { "__concat", "__index", + "caps", "chomp", "escape_pattern", "escape_shell", + "finds", "format", "ltrim", "monkey_patch", + "numbertosi", "ordinal_suffix", "pad", "pickle", + "prettytostring", "render", "rtrim", "split", + "tfind", "trim", "wrap" } + deprecations = { "assert", "require_version", "tostring" } M = require (this_module) - getmetatable ("").__append = M.__append getmetatable ("").__concat = M.__concat getmetatable ("").__index = M.__index @@ -29,8 +28,12 @@ specify std.string: expect (show_apis {added_to=base_module, by=this_module}). to_equal {} - it contains apis from the core string table: + apis = require "std.base".copy (extend_base) + for _, v in ipairs (deprecations) do + apis[#apis + 1] = v + end expect (show_apis {from=base_module, not_in=this_module}). - to_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (apis) - context via the std module: - it does not touch the global table: @@ -47,11 +50,11 @@ specify std.string: - it stringifies non-string arguments: argument = { "a table" } expect (subject .. argument). - to_be (string.format ("%s%s", subject, M.tostring (argument))) + to_be (string.format ("%s%s", subject, require "std".tostring (argument))) - it stringifies nil arguments: argument = nil expect (subject .. argument). - to_be (string.format ("%s%s", subject, M.tostring (argument))) + to_be (string.format ("%s%s", subject, require "std".tostring (argument))) - it does not perturb the original subject: original = subject newstring = subject .. " concatenate something" @@ -59,11 +62,45 @@ specify std.string: - describe assert: + - before: + f = M.assert + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {"std.string"})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {"std.string"})).not_to_contain_error "was deprecated" + + - context when it does not trigger: + - it has a truthy initial argument: + expect (f (1)).not_to_raise "any error" + expect (f (true)).not_to_raise "any error" + expect (f "yes").not_to_raise "any error" + expect (f (false == false)).not_to_raise "any error" + - it returns the initial argument: + expect (f (1)).to_be (1) + expect (f (true)).to_be (true) + expect (f "yes").to_be "yes" + expect (f (false == false)).to_be (true) + - context when it triggers: + - it has a falsey initial argument: + expect (f ()).to_raise () + expect (f (false)).to_raise () + expect (f (1 == 0)).to_raise () + - it throws an optional error string: + expect (f (false, "ah boo")).to_raise "ah boo" + - it plugs specifiers with string.format: | + expect (f (nil, "%s %d: %q", "here", 42, "a string")). + to_raise (string.format ("%s %d: %q", "here", 42, "a string")) - describe caps: - before: f = M.caps + + - context with bad arguments: + badargs.diagnose (f, "std.string.caps (string)") + - it capitalises words of a string: target = "A String \n\n" expect (f (subject)).to_be (target) @@ -75,15 +112,16 @@ specify std.string: original = subject newstring = f (subject) expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") - describe chomp: - before: - f = M.chomp target = "a string \n" + f = M.chomp + + - context with bad arguments: + badargs.diagnose (f, "std.string.chomp (string)") + - it removes a single trailing newline from a string: expect (f (subject)).to_be (target) - it does not change a string with no trailing newline: @@ -95,20 +133,19 @@ specify std.string: original = subject newstring = f (subject) expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") - describe escape_pattern: - - before: | - f = M.escape_pattern - + - before: magic = {} meta = "^$()%.[]*+-?" for i = 1, string.len (meta) do magic[meta:sub (i, i)] = true end + f = M.escape_pattern + + - context with bad arguments: + badargs.diagnose (f, "std.string.escape_pattern (string)") - context with each printable ASCII char: - before: @@ -127,14 +164,15 @@ specify std.string: original = subject newstring = f (subject) expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") - describe escape_shell: - before: f = M.escape_shell + + - context with bad arguments: + badargs.diagnose (f, "std.string.escape_shell (string)") + - context with each printable ASCII char: - before: subject, target = "", "" @@ -153,14 +191,18 @@ specify std.string: newstring = f (subject) expect (subject).to_be (original) - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") + expect (f ()).to_raise ("string expected") + expect (f {"a table"}).to_raise ("string expected") - describe finds: - before: subject = "abcd" f = M.finds + + - context with bad arguments: + badargs.diagnose (f, "std.string.finds (string, string, ?int, ?boolean|:plain)") + - context given a complex nested list: - before: target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } @@ -181,16 +223,17 @@ specify std.string: original = subject newstring = f (subject, "...") expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") -# FIXME: This looks like a misfeature to me, let's remove it! - describe format: - - before: | - subject = "string: %s, number: %d" + - before: + subject = "string=%s, number=%d" + f = M.format + + - context with bad arguments: + badargs.diagnose (f, "std.string.format (string, ?any*)") + - it returns a single argument without attempting formatting: expect (f (subject)).to_be (subject) - it is available as a string metamethod: @@ -199,15 +242,17 @@ specify std.string: original = subject newstring = f (subject) expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f (nil, "arg")).to_error ("string expected") - expect (f ({"a table"}, "arg")).to_error ("string expected") - describe ltrim: - before: subject = " \t\r\n a short string \t\r\n " + f = M.ltrim + + - context with bad arguments: + badargs.diagnose (f, "std.string.ltrim (string, ?string)") + - it removes whitespace from the start of a string: target = "a short string \t\r\n " expect (f (subject)).to_equal (target) @@ -221,39 +266,38 @@ specify std.string: original = subject newstring = f (subject, "%W") expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") - describe monkey_patch: - before: - f = M.monkey_patch - t = {} - f (t) - - it installs append metamethod: - # FIXME: string metatable monkey-patches leak out! - mt = getmetatable "" - expect (mt.__append).to_be (M.__append) - - it installs concat metamethod: + f = M.monkey_patch + + - context with bad arguments: + badargs.diagnose (f, "std.string.monkey_patch (?table)") + + - it returns the monkey_patched namespace: + namespace = {} + expect (f (namespace)).to_be (namespace.string) + - it injects std.string apis into given namespace: + namespace = {} + f (namespace) + for _, api in ipairs (extend_base) do + expect (namespace.string[api]).to_be (M[api]) + end + - it installs string metamethods: # FIXME: string metatable monkey-patches leak out! mt = getmetatable "" expect (mt.__concat).to_be (M.__concat) - - it installs index metamethod: - # FIXME: string metatable monkey-patches leak out! - mt = getmetatable "" expect (mt.__index).to_be (M.__index) - - it installs the assert function: - expect (t.assert).to_be (M.assert) - - it installs the tostring function: - expect (t.tostring).to_be (M.tostring) - - it diagnoses non-table argument: - expect (f "bad").to_error "table expected" - describe numbertosi: - before: f = M.numbertosi + + - context with bad arguments: + badargs.diagnose (f, "std.string.numbertosi (number|string)") + - it returns a number using SI suffixes: target = {"1e-9", "1y", "1z", "1a", "1f", "1p", "1n", "1mu", "1m", "1", "1k", "1M", "1G", "1T", "1P", "1E", "1Z", "1Y", "1e9"} @@ -265,14 +309,15 @@ specify std.string: expect (subject).to_equal (target) - it coerces string arguments to a number: expect (f "1000").to_be "1k" - - "it diagnoses non-numeric arguments": - expect (f ()).to_error ("attempt to perform arithmetic") - expect (f {"a table"}).to_error ("number expected") - describe ordinal_suffix: - before: f = M.ordinal_suffix + + - context with bad arguments: + badargs.diagnose (f, "std.string.ordinal_suffix (int|string)") + - it returns the English suffix for a number: subject, target = {}, {} for n = -120, 120 do @@ -288,16 +333,17 @@ specify std.string: expect (subject).to_equal (target) - it coerces string arguments to a number: expect (f "-91").to_be "st" - - "it diagnoses non-numeric arguments": - expect (f ()).to_error ("number expected") - expect (f {"a table"}).to_error ("number expected") - describe pad: - before: width = 20 + f = M.pad + - context with bad arguments: + badargs.diagnose (f, "std.string.pad (string, int, ?string)") + - context when string is shorter than given width: - before: subject = "short string" @@ -330,20 +376,42 @@ specify std.string: original = subject newstring = f (subject, width) expect (subject).to_be (original) - - "it coerces non-string arguments to a string": - argument = { "a table " } - expect (f (argument, width)).to_contain (M.tostring (argument)) - - "it diagnoses non-numeric width arguments": - expect (f (subject, nil)).to_error ("number expected") - expect (f (subject, {"a table"})).to_error ("number expected") - describe pickle: + - before: + loadstring = loadstring or load + function unpickle (s) return loadstring ("return " .. s) () end + t = {1, {{2, 3}, 4, {5}}} + f = M.pickle + - it converts a primitive to a representative string: + expect (f (nil)).to_be "nil" + expect (f (false)).to_be "false" + expect (f (42)).to_be "42" + expect (f "string").to_be '"string"' + - it returns a loadable string that results in the original value: + expect (unpickle (f (nil))).to_be (nil) + expect (unpickle (f (false))).to_be (false) + expect (unpickle (f (42))).to_be (42) + expect (unpickle (f "string")).to_be "string" + - it converts a table to a representative string: + expect (f {"table", 42}).to_be '{[1]="table",[2]=42}' + - it returns a loadable string that results in the original table: + expect (unpickle (f {"table", 42})).to_equal {"table", 42} + - it converts a nested table to a representative string: + expect (f (t)). + to_be "{[1]=1,[2]={[1]={[1]=2,[2]=3},[2]=4,[3]={[1]=5}}}" + - it returns a loadable string that results in the original nested table: + expect (unpickle (f (t))).to_equal (t) - describe prettytostring: - before: f = M.prettytostring + + - context with bad arguments: + badargs.diagnose (f, "std.string.prettytostring (?any, ?string, ?string)") + - it renders nil exactly like system tostring: expect (f (nil)).to_be (tostring (nil)) - it renders booleans exactly like system tostring: @@ -378,15 +446,101 @@ specify std.string: - describe render: + - before: + term = function (s) return function () return s end end + pair = function (_, _, _, i, v) return i .. "=" .. v end + sep = function (_, i, _, j) return (i and j) and "," or "" end + r = function (x) + return M.render (x, term "{", term "}", tostring, pair, sep) + end + t = {1, {{2, 3}, 4, {5}}} + + f = M.render + + - context with bad arguments: + badargs.diagnose (f, "std.string.render (?any, func, func, func, func, func, ?table)") + + - it converts a primitive to a representative string: + expect (r (nil)).to_be "nil" + expect (r (false)).to_be "false" + expect (r (42)).to_be "42" + expect (r ("string")).to_be "string" + - it converts a table to a representative string: + expect (r ({"table", 42})).to_be '{1=table,2=42}' + - it converts a nested table to a representative string: + expect (r (t)). + to_be "{1=1,2={1={1=2,2=3},2=4,3={1=5}}}" + - it converts a recursive table to a representative string: + t[1] = t + expect (r (t)). + to_be ("{1="..tostring (t)..",2={1={1=2,2=3},2=4,3={1=5}}}") - describe require_version: + - before: + f = M.require_version + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {"std.string"})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {"std.string"})).not_to_contain_error "was deprecated" + + - it diagnoses non-existent module: + expect (f ("module-not-exists", "", "")).to_raise "module-not-exists" + - it diagnoses module too old: + expect (f ("std", "9999", "9999")).to_raise () + - it diagnoses module too new: + expect (f ("std", "0", "0")).to_raise () + - context when the module version is compatible: + - it returns the module table: + expect (f ("std", "0", "9999")).to_be (require "std") + - it places no upper bound by default: + expect (f ("std", "41")).to_be (require "std") + - it places no lower bound by default: + expect (f "std").to_be (require "std") + - it uses _VERSION when version field is nil: + std = require "std" + std._VERSION, std.version = std.version, std._VERSION + expect (f ("std", "41", "9999")).to_be (require "std") + std._VERSION, std.version = std.version, std._VERSION + - context with semantic versioning: + - before: + std = require "std" + ver = std.version + std.version = "1.2.3" + - after: + std.version = ver + - it diagnoses module too old: + expect (f ("std", "1.2.4")).to_raise () + expect (f ("std", "1.3")).to_raise () + expect (f ("std", "2.1.2")).to_raise () + expect (f ("std", "2")).to_raise () + expect (f ("std", "1.2.10")).to_raise () + - it diagnoses module too new: + expect (f ("std", nil, "1.2.2")).to_raise () + expect (f ("std", nil, "1.1")).to_raise () + expect (f ("std", nil, "1.1.2")).to_raise () + expect (f ("std", nil, "1")).to_raise () + - it returns modules with version in range: + expect (f ("std")).to_be (std) + expect (f ("std", "1")).to_be (std) + expect (f ("std", "1.2.3")).to_be (std) + expect (f ("std", nil, "2")).to_be (std) + expect (f ("std", nil, "1.3")).to_be (std) + expect (f ("std", nil, "1.2.10")).to_be (std) + expect (f ("std", "1.2.3", "1.2.4")).to_be (std) - describe rtrim: - before: subject = " \t\r\n a short string \t\r\n " + f = M.rtrim + + - context with bad arguments: + badargs.diagnose (f, "std.string.rtrim (string, ?string)") + - it removes whitespace from the end of a string: target = " \t\r\n a short string" expect (f (subject)).to_equal (target) @@ -400,16 +554,21 @@ specify std.string: original = subject newstring = f (subject, "%W") expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") - describe split: - before: target = { "first", "the second one", "final entry" } subject = table.concat (target, ", ") + f = M.split + + - context with bad arguments: + badargs.diagnose (f, "std.string.split (string, ?string)") + + - it falls back to "%s+" when no pattern is given: + expect (f (subject)). + to_equal {"first,", "the", "second", "one,", "final", "entry"} - it returns a one-element list for an empty string: expect (f ("", ", ")).to_equal {""} - it makes a table of substrings delimited by a separator: @@ -439,15 +598,17 @@ specify std.string: - it takes a Lua pattern as a separator: expect (f (subject, "%s+")). to_equal {"first,", "the", "second", "one,", "final", "entry"} - - it diagnoses non-string arguments: - expect (f (nil, ",")).to_error ("string expected") - expect (f ({"a table"}, ",")).to_error ("string expected") - describe tfind: - before: subject = "abc" + f = M.tfind + + - context with bad arguments: + badargs.diagnose (f, "std.string.tfind (string, string, ?int, ?boolean|:plain)") + - it creates a list of pattern captures: target = { 1, 3, { "a", "b", "c" } } expect ({f (subject, "(.)(.)(.)")}).to_equal (target) @@ -467,18 +628,49 @@ specify std.string: original = subject newstring = f (subject, "...") expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") - describe tostring: + - before: + f = M.tostring + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {"std.string"})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {"std.string"})).not_to_contain_error "was deprecated" + + - it renders primitives exactly like system tostring: + expect (f (nil)).to_be (tostring (nil)) + expect (f (false)).to_be (tostring (false)) + expect (f (42)).to_be (tostring (42)) + expect (f (f)).to_be (tostring (f)) + expect (f "a string").to_be "a string" + - it renders empty tables as a pair of braces: + expect (f {}).to_be ("{}") + - it renders table array part compactly: + expect (f {"one", "two", "five"}). + to_be '{1=one,2=two,3=five}' + - it renders a table dictionary part compactly: + expect (f { one = true, two = 2, three = {3}}). + to_be '{one=true,three={1=3},two=2}' + - it renders table keys in table.sort order: + expect (f { one = 3, two = 5, three = 4, four = 2, five = 1 }). + to_be '{five=1,four=2,one=3,three=4,two=5}' + - it renders keys with invalid symbol names compactly: + expect (f { _ = 0, word = 0, ["?"] = 1, ["a-key"] = 1, ["[]"] = 1 }). + to_be '{?=1,[]=1,_=0,a-key=1,word=0}' - describe trim: - before: subject = " \t\r\n a short string \t\r\n " + f = M.trim + + - context with bad arguments: + badargs.diagnose (f, "std.string.trim (string, ?string)") + - it removes whitespace from each end of a string: target = "a short string" expect (f (subject)).to_equal (target) @@ -492,37 +684,39 @@ specify std.string: original = subject newstring = f (subject, "%W") expect (subject).to_be (original) - - "it diagnoses non-string arguments": - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") - describe wrap: - before: subject = "This is a collection of Lua libraries for Lua 5.1 " .. "and 5.2. The libraries are copyright by their authors 2000" .. - "-2013 (see the AUTHORS file for details), and released und" .. + "-2015 (see the AUTHORS file for details), and released und" .. "er the MIT license (the same license as Lua itself). There" .. " is no warranty." + f = M.wrap + + - context with bad arguments: + badargs.diagnose (f, "std.string.wrap (string, ?int, ?int, ?int)") + - it inserts newlines to wrap a string: target = "This is a collection of Lua libraries for Lua 5.1 a" .. "nd 5.2. The libraries are\ncopyright by their authors 2000" .. - "-2013 (see the AUTHORS file for details), and\nreleased un" .. + "-2015 (see the AUTHORS file for details), and\nreleased un" .. "der the MIT license (the same license as Lua itself). Ther" .. "e is no\nwarranty." expect (f (subject)).to_be (target) - it honours a column width parameter: target = "This is a collection of Lua libraries for Lua 5.1 a" .. "nd 5.2. The libraries\nare copyright by their authors 2000" .. - "-2013 (see the AUTHORS file for\ndetails), and released un" .. + "-2015 (see the AUTHORS file for\ndetails), and released un" .. "der the MIT license (the same license as Lua\nitself). The" .. "re is no warranty." expect (f (subject, 72)).to_be (target) - it supports indenting by a fixed number of columns: target = " This is a collection of Lua libraries for L" .. "ua 5.1 and 5.2. The\n libraries are copyright by th" .. - "eir authors 2000-2013 (see the\n AUTHORS file for d" .. + "eir authors 2000-2015 (see the\n AUTHORS file for d" .. "etails), and released under the MIT license\n (the " .. "same license as Lua itself). There is no warranty." expect (f (subject, 72, 8)).to_be (target) @@ -530,7 +724,7 @@ specify std.string: - before: target = " This is a collection of Lua libraries for Lua 5" .. ".1 and 5.2.\n The libraries are copyright by their author" .. - "s 2000-2013 (see\n the AUTHORS file for details), and rel" .. + "s 2000-2015 (see\n the AUTHORS file for details), and rel" .. "eased under the MIT\n license (the same license as Lua it" .. "self). There is no\n warranty." - it can indent the first line differently: @@ -542,8 +736,8 @@ specify std.string: newstring = f (subject, 55, 5) expect (subject).to_be (original) - it diagnoses indent greater than line width: - expect (f (subject, 10, 12)).to_error ("less than the line width") - expect (f (subject, 99, 99)).to_error ("less than the line width") + expect (f (subject, 10, 12)).to_raise ("less than the line width") + expect (f (subject, 99, 99)).to_raise ("less than the line width") - it diagnoses non-string arguments: - expect (f ()).to_error ("string expected") - expect (f {"a table"}).to_error ("string expected") + expect (f ()).to_raise ("string expected") + expect (f {"a table"}).to_raise ("string expected") diff --git a/specs/table_spec.yaml b/specs/table_spec.yaml index e0f72cf..4ed1003 100644 --- a/specs/table_spec.yaml +++ b/specs/table_spec.yaml @@ -3,13 +3,16 @@ before: | this_module = "std.table" global_table = "_G" - extend_base = { "clone", "clone_rename", "clone_select", "empty", - "invert", "keys", "merge", "merge_select", - "metamethod", "monkey_patch", "new", "pack", - "ripairs", "size", "sort", "totable", "values" } + extend_base = { "clone", "clone_select", "depair", "empty", + "enpair", "flatten", "insert", "invert", "keys", + "len", "maxn", "merge", "merge_select", + "monkey_patch", "new", "okeys", "pack", "project", + "remove", "shape", "size", "sort", "values" } + deprecations = { "clone_rename", "metamethod", "ripairs", "totable" } M = require "std.table" + specify std.table: - context when required: - context by name: @@ -20,8 +23,12 @@ specify std.table: expect (show_apis {added_to=base_module, by=this_module}). to_equal {} - it contains apis from the core table table: + apis = require "std.base".copy (extend_base) + for _, v in ipairs (deprecations) do + apis[#apis + 1] = v + end expect (show_apis {from=base_module, not_in=this_module}). - to_contain.a_permutation_of (extend_base) + to_contain.a_permutation_of (apis) - context via the std module: - it does not touch the global table: @@ -34,7 +41,12 @@ specify std.table: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } withmt = setmetatable (M.clone (subject), {"meta!"}) - f = M.clone + + f = M.clone + + - context with bad arguments: + badargs.diagnose (f, "std.table.clone (table, [table], ?boolean|:nometa)") + - it does not just return the subject: expect (f (subject)).not_to_be (subject) - it does copy the subject: @@ -51,11 +63,11 @@ specify std.table: - it copies the metatable by default: expect (getmetatable (f (withmt))).to_be (getmetatable (withmt)) - it treats non-table arg2 as nometa parameter: - expect (getmetatable (f (withmt, "nometa"))).to_be (nil) + expect (getmetatable (f (withmt, ":nometa"))).to_be (nil) - it treats table arg2 as a map parameter: expect (getmetatable (f (withmt, {}))).to_be (getmetatable (withmt)) - it supports 3 arguments with nometa as arg3: - expect (getmetatable (f (withmt, {}, "nometa"))).to_be (nil) + expect (getmetatable (f (withmt, {}, ":nometa"))).to_be (nil) - context when renaming some keys: - it renames during cloning: @@ -64,23 +76,20 @@ specify std.table: - it does not perturb the value in the renamed key field: expect (f (subject, {k1 = "newkey"}).newkey).to_be (subject.k1) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") - - describe clone_rename: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } - f = M.clone_rename - - it writes a deprecation warning to standard error on first call: | - _, err = capture (f, {{}, subject}) - if err ~= nil then - -- skip this test when using Specl < 12 capture stub - expect (err).to_contain "clone_rename is deprecated" - end - _, err = capture (f, {{}, subject}) - expect (err).to_be (nil) + + fname = "clone_rename" + f = M[fname] + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{}, subject})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{}, subject})).not_to_contain_error "was deprecated" + - it copies the subject: expect (f ({}, subject)).to_copy (subject) - it only makes a shallow copy: @@ -95,15 +104,19 @@ specify std.table: expect (f ({k1 = "newkey"}, subject).newkey).to_be (subject.k1) - it diagnoses non-table arguments: - expect (f {}).to_error ("table expected") - expect (f ({}, "foo")).to_error ("table expected") + expect (f {}).to_raise ("table expected") + expect (f ({}, "foo")).to_raise ("table expected") - describe clone_select: - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } withmt = setmetatable (M.clone (subject), {"meta!"}) - f = M.clone_select + + f = M.clone_select + + - context with bad arguments: + badargs.diagnose (f, "std.table.clone_select (table, [table], ?boolean|:nometa)") - it does not just return the subject: expect (f (subject)).not_to_be (subject) @@ -121,22 +134,40 @@ specify std.table: - context with metatables: - it treats non-table arg2 as nometa parameter: - expect (getmetatable (f (withmt, "nometa"))).to_be (nil) + expect (getmetatable (f (withmt, ":nometa"))).to_be (nil) - it treats table arg2 as a map parameter: expect (getmetatable (f (withmt, {}))).to_be (getmetatable (withmt)) expect (getmetatable (f (withmt, {"k1"}))).to_be (getmetatable (withmt)) - it supports 3 arguments with nometa as arg3: - expect (getmetatable (f (withmt, {}, "nometa"))).to_be (nil) - expect (getmetatable (f (withmt, {"k1"}, "nometa"))).to_be (nil) + expect (getmetatable (f (withmt, {}, ":nometa"))).to_be (nil) + expect (getmetatable (f (withmt, {"k1"}, ":nometa"))).to_be (nil) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") + +- describe depair: + - before: + t = {"first", "second", third = 4} + l = M.enpair (t) + + f = M.depair + + - context with bad arguments: + badargs.diagnose (f, "std.table.depair (list of lists)") + + - it returns a primitive table: + expect (prototype (f (l))).to_be "table" + - it works with an empty table: + expect (f {}).to_equal {} + - it is the inverse of enpair: + expect (f (l)).to_equal (t) - describe empty: - before: f = M.empty + + - context with bad arguments: + badargs.diagnose (f, "std.table.empty (table)") + - it returns true for an empty table: expect (f {}).to_be (true) expect (f {nil}).to_be (true) @@ -144,15 +175,93 @@ specify std.table: expect (f {"stuff"}).to_be (false) expect (f {{}}).to_be (false) expect (f {false}).to_be (false) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") + + +- describe enpair: + - before: + t = {"first", "second", third = 4} + l = M.enpair (t) + + f = M.enpair + + - context with bad arguments: + badargs.diagnose (f, "std.table.enpair (table)") + + - it returns a table: + expect (prototype (f (t))).to_be "table" + - it works for an empty table: + expect (f {}).to_equal {} + - it turns a table into a table of pairs: + expect (f (t)).to_equal {{1, "first"}, {2, "second"}, {"third", 4}} + - it is the inverse of depair: + expect (f (t)).to_equal (l) + + +- describe flatten: + - before: + t = {{{"one"}}, "two", {{"three"}, "four"}} + + f = M.flatten + + - context with bad arguments: + badargs.diagnose (f, "std.table.flatten (table)") + + - it returns a table: + expect (type (f (t))).to_be "table" + - it works for an empty table: + expect (f {}).to_equal {} + - it flattens a nested table: + expect (f (t)).to_equal {"one", "two", "three", "four"} + + +- describe insert: + - before: + f, badarg = init (M, this_module, "insert") + + - context with bad arguments: + badargs.diagnose (f, "std.table.insert (table, [int], any)") + + examples { + ["it diagnoses more than 2 arguments with no pos"] = function () + pending "#issue 76" + expect (f ({}, false, false)).to_raise (badarg (3)) + end + } + examples { + ["it diagnoses out of bounds pos arguments"] = function () + expect (f ({}, 0, "x")).to_raise "position 0 out of bounds" + expect (f ({}, 2, "x")).to_raise "position 2 out of bounds" + expect (f ({1}, 5, "x")).to_raise "position 5 out of bounds" + end + } + + - it returns the modified table: + t = {} + expect (f (t, 1)).to_be (t) + - it append a new element at the end by default: + expect (f ({1, 2}, "x")).to_equal {1, 2, "x"} + - it fills holes by default: + expect (f ({1, 2, [5]=3}, "x")).to_equal {1, 2, "x", [5]=3} + - it respects __len when appending: + t = setmetatable ({1, 2, [5]=3}, {__len = function () return 42 end}) + expect (f (t, "x")).to_equal {1, 2, [5]=3, [43]="x"} + - it moves other elements up if necessary: + expect (f ({1, 2}, 1, "x")).to_equal {"x", 1, 2} + expect (f ({1, 2}, 2, "x")).to_equal {1, "x", 2} + expect (f ({1, 2}, 3, "x")).to_equal {1, 2, "x"} + - it inserts a new element according to pos argument: + expect (f ({}, 1, "x")).to_equal {"x"} - describe invert: - before: subject = { k1 = 1, k2 = 2, k3 = 3 } - f = M.invert + + f = M.invert + + - context with bad arguments: + badargs.diagnose (f, "std.table.invert (table)") + - it returns a new table: expect (f (subject)).not_to_be (subject) - it inverts keys and values in the returned table: @@ -162,15 +271,17 @@ specify std.table: - it seems to copy a list of 1..n numbers: subject = { 1, 2, 3 } expect (f (subject)).to_copy (subject) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") - describe keys: - before: subject = { k1 = 1, k2 = 2, k3 = 3 } - f = M.keys + + f = M.keys + + - context with bad arguments: + badargs.diagnose (f, "std.table.keys (table)") + - it returns an empty list when subject is empty: expect (f {}).to_equal {} - it makes a list of table keys: @@ -182,9 +293,44 @@ specify std.table: -- returned table will have all 10000 keys in the same order... for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).not_to_equal (subject) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") + + +- describe len: + - before: + f = M.len + + - context with bad arguments: + badargs.diagnose (f, "std.table.len (table)") + + - it returns the length of a table: + expect (f {"a", "b", "c"}).to_be (3) + expect (f {1, 2, 5, a=10, 3}).to_be (4) + - it works with an empty table: + expect (f {}).to_be (0) + - it ignores elements after a hole: + expect (f {1, 2, [5]=3}).to_be (2) + - it respects __len metamethod: + t = setmetatable ({1, 2, [5]=3}, {__len = function () return 42 end}) + expect (f (t)).to_be (42) + + +- describe maxn: + - before: + f = M.maxn + + - context with bad arguments: + badargs.diagnose (f, "std.table.maxn (table)") + + - it returns the largest numeric key of a table: + expect (f {"a", "b", "c"}).to_be (3) + expect (f {1, 2, 5, a=10, 3}).to_be (4) + - it works with an empty table: + expect (f {}).to_be (0) + - it ignores holes: + expect (f {1, 2, [5]=3}).to_be (5) + - it ignores __len metamethod: + t = setmetatable ({1, 2, [5]=3}, {__len = function () return 42 end}) + expect (f (t)).to_be (5) - describe merge: @@ -193,11 +339,22 @@ specify std.table: t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } t1mt = setmetatable (M.clone (t1), {"meta!"}) - f = M.merge - target = {} for k, v in pairs (t1) do target[k] = v end for k, v in pairs (t2) do target[k] = v end + + f, badarg = init (M, this_module, "merge") + + - context with bad arguments: + badargs.diagnose (f, "std.table.merge (table, table, [table], ?boolean|:nometa)") + + examples { + ["it diagnoses more than 2 arguments with no pos"] = function () + pending "#issue 76" + expect (f ({}, {}, ":nometa", false)).to_raise (badarg (4)) + end + } + - it does not create a whole new table: expect (f (t1, t2)).to_be (t1) - it does not change t1 when t2 is empty: @@ -219,13 +376,13 @@ specify std.table: expect (getmetatable (f ({}, t1mt))).to_be (getmetatable (t1mt)) expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) - it treats non-table arg3 as nometa parameter: - expect (getmetatable (f ({}, t1mt, "nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, ":nometa"))).to_be (nil) - it treats table arg3 as a map parameter: expect (getmetatable (f ({}, t1mt, {}))).to_be (getmetatable (t1mt)) expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) - it supports 4 arguments with nometa as arg4: - expect (getmetatable (f ({}, t1mt, {}, "nometa"))).to_be (nil) - expect (getmetatable (f ({}, t1mt, {"k1"}, "nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, {}, ":nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, {"k1"}, ":nometa"))).to_be (nil) - context when renaming some keys: - it renames during merging: @@ -234,10 +391,6 @@ specify std.table: - it does not perturb the value in the renamed key field: expect (f ({}, t1, {k1 = "newkey"}).newkey).to_be (t1.k1) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f ("foo", "bar")).to_error ("table expected") - - describe merge_select: - before: | @@ -247,11 +400,22 @@ specify std.table: t1mt = setmetatable (M.clone (t1), {"meta!"}) t2 = { ["if"] = true, [tablekey] = false, _ = "underscore", k3 = t1.k1 } t2keys = { "if", tablekey, "_", "k3" } - f = M.merge_select - target = {} for k, v in pairs (t1) do target[k] = v end for k, v in pairs (t2) do target[k] = v end + + f, badarg = init (M, this_module, "merge_select") + + - context with bad arguments: + badargs.diagnose (f, "std.table.merge_select (table, table, [table], ?boolean|:nometa)") + + examples { + ["it diagnoses more than 2 arguments with no pos"] = function () + pending "#issue 76" + expect (f ({}, {}, ":nometa", false)).to_raise (badarg (4)) + end + } + - it does not create a whole new table: expect (f (t1, t2)).to_be (t1) - it does not change t1 when t2 is empty: @@ -277,36 +441,65 @@ specify std.table: expect (getmetatable (f ({}, t1mt))).to_be (getmetatable (t1mt)) expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) - it treats non-table arg3 as nometa parameter: - expect (getmetatable (f ({}, t1mt, "nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, ":nometa"))).to_be (nil) - it treats table arg3 as a map parameter: expect (getmetatable (f ({}, t1mt, {}))).to_be (getmetatable (t1mt)) expect (getmetatable (f ({}, t1mt, {"k1"}))).to_be (getmetatable (t1mt)) - it supports 4 arguments with nometa as arg4: - expect (getmetatable (f ({}, t1mt, {}, "nometa"))).to_be (nil) - expect (getmetatable (f ({}, t1mt, {"k1"}, "nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, {}, ":nometa"))).to_be (nil) + expect (getmetatable (f ({}, t1mt, {"k1"}, ":nometa"))).to_be (nil) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f ("foo", "bar")).to_error ("table expected") + +- describe metamethod: + - before: + Object = require "std.object" + objmethod = function () end + obj = Object { + _type = "DerivedObject", + _method = objmethod, + } + + f = M.metamethod + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{}, subject})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{}, subject})).not_to_contain_error "was deprecated" + + - it returns nil for missing metamethods: + expect (f (obj, "not a method on obj")).to_be (nil) + - it returns nil for non-function metatable entries: + expect (f (obj, "_type")).to_be (nil) + - it returns a method from the metatable: + expect (f (obj, "_method")).to_be (objmethod) - describe monkey_patch: - before: - f = M.monkey_patch - t = { - table = {}, - } - f (t) - - it installs table.sort function: - expect (t.table.sort).to_be (M.sort) - - it diagnoses non-table argument: - expect (f "bad").to_error "table expected" + f = M.monkey_patch + + - context with bad arguments: + badargs.diagnose (f, "std.table.monkey_patch (?table)") + + - it returns the monkey_patched table entry from namespace: + namespace = {} + expect (f (namespace)).to_be (namespace.table) + - it injects std.table apis into given namespace: + namespace = {} + f (namespace) + for _, api in ipairs (extend_base) do + expect (namespace.table[api]).to_be (M[api]) + end - describe new: - before: f = M.new + - context with bad arguments: + badargs.diagnose (f, "std.table.new (?any, ?table)") + - context when not setting a default: - before: default = nil - it returns a new table when nil is passed: @@ -336,28 +529,166 @@ specify std.table: default = { "unique object" } t = f (default) expect (t[1]).to_be (default) - - it diagnoses non-tables/non-nil in the second argument: - expect (f (nil, "foo")).to_error ("table expected") + + +- describe okeys: + - before: + subject = { "v1", k1 = 1, "v2", k2 = 2, "v3", k3 = 3, [10]="v10" } + + f = M.okeys + + - context with bad arguments: + badargs.diagnose (f, "std.table.okeys (table)") + + - it returns an empty list when subject is empty: + expect (f {}).to_equal {} + - it makes an ordered list of table keys: + expect (f (subject)). + to_equal {1, 2, 3, 10, "k1", "k2", "k3"} - describe pack: + - before: + unpack = unpack or table.unpack + t = {"one", "two", "five"} + f = M.pack + - it creates an empty table with no arguments: + expect (f ()).to_equal {} + - it creates a table with arguments as elements: + expect (f ("one", "two", "five")).to_equal (t) + - it is the inverse operation to unpack: + expect (f (unpack (t))).to_equal (t) + + +- describe project: + - before: + l = { + {first = false, second = true, third = true}, + {first = 1, second = 2, third = 3}, + {first = "1st", second = "2nd", third = "3rd"}, + } + + f = M.project + + - context with bad arguments: + badargs.diagnose (f, "std.table.project (any, list of tables)") + + - it returns a table: + expect (prototype (f ("third", l))).to_be "table" + - it works with an empty table: + expect (f ("third", {})).to_equal {} + - it projects a table of fields from a table of tables: + expect (f ("third", l)).to_equal {true, 3, "3rd"} + - it projects fields with a falsey value correctly: + expect (f ("first", l)).to_equal {false, 1, "1st"} + + +- describe remove: + - before: + f = M.remove + + - context with bad arguments: + badargs.diagnose (f, "std.table.remove (table, ?int)") + + examples { + ["it diagnoses out of bounds pos arguments"] = function () + expect (f ({1}, 0)).to_raise "position 0 out of bounds" + expect (f ({1}, 3)).to_raise "position 3 out of bounds" + expect (f ({1}, 5)).to_raise "position 5 out of bounds" + end + } + + - it returns the removed element: + t = {"one", "two", "five"} + expect (f ({"one", 2, 5}, 1)).to_be "one" + - it removes an element from the end by default: + expect (f {1, 2, "five"}).to_be "five" + - it ignores holes: + t = {"second", "first", [5]="invisible"} + expect (f (t)).to_be "first" + expect (f (t)).to_be "second" + - it respects __len when defaulting pos: + t = setmetatable ({1, 2, [43]="invisible"}, {__len = function () return 42 end}) + expect (f (t)).to_be (nil) + expect (f (t)).to_be (nil) + expect (t).to_equal {1, 2, [43]="invisible"} + - it moves other elements down if necessary: + t = {1, 2, 5, "third", "first", "second", 42} + expect (f (t, 5)).to_be "first" + expect (t).to_equal {1, 2, 5, "third", "second", 42} + expect (f (t, 5)).to_be "second" + expect (t).to_equal {1, 2, 5, "third", 42} + expect (f (t, 4)).to_be "third" + expect (t).to_equal {1, 2, 5, 42} - describe ripairs: + - before: + f = M.ripairs + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{}, subject})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{}, subject})).not_to_contain_error "was deprecated" + + - it returns a function, the table and a number: + fn, t, i = f {1, 2, 3} + expect ({type (fn), t, type (i)}).to_equal {"function", {1, 2, 3}, "number"} + - it iterates over a array part of a table: + t, u = {1, 2, 3; a=4, b=5, c=6}, {} + for i, v in f (t) do u[i] = v end + expect (u).to_equal {1, 2, 3} + - it returns elements in reverse order: + t, u = {"one", "two", "five"}, {} + for _, v in f (t) do u[#u + 1] = v end + expect (u).to_equal {"five", "two", "one"} + + +- describe shape: + - before: + l = {1, 2, 3, 4, 5, 6} + + f = M.shape + + - context with bad arguments: + badargs.diagnose (f, "std.table.shape (table, table)") + + - it returns a table: + expect (prototype (f ({2, 3}, l))).to_be "table" + - it works for an empty table: + expect (f ({0}, {})).to_equal ({}) + - it returns the result in a new table: + expect (f ({2, 3}, l)).not_to_be (l) + - it does not perturb the argument table: + f ({2, 3}, l) + expect (l).to_equal {1, 2, 3, 4, 5, 6} + - it reshapes a table according to given dimensions: + expect (f ({2, 3}, l)). + to_equal ({{1, 2, 3}, {4, 5, 6}}) + expect (f ({3, 2}, l)). + to_equal ({{1, 2}, {3, 4}, {5, 6}}) + - it treats 0-valued dimensions as an indefinite number: + expect (f ({2, 0}, l)). + to_equal ({{1, 2, 3}, {4, 5, 6}}) + expect (f ({0, 2}, l)). + to_equal ({{1, 2}, {3, 4}, {5, 6}}) - describe size: - before: | -- - 1 - --------- 2 ---------- -- 3 -- subject = { "one", { { "two" }, "three" }, four = 5 } + f = M.size + + - context with bad arguments: + badargs.diagnose (f, "std.table.size (table)") + - it counts the number of keys in a table: expect (f (subject)).to_be (3) - it counts no keys in an empty table: expect (f {}).to_be (0) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") - describe sort: @@ -365,24 +696,51 @@ specify std.table: subject = { 5, 2, 4, 1, 0, 3 } target = { 0, 1, 2, 3, 4, 5 } cmp = function (a, b) return a < b end - f = M.sort + + f = M.sort + + - context with bad arguments: + badargs.diagnose (f, "std.table.sort (table, ?function)") + - it sorts elements in place: f (subject, cmp) expect (subject).to_equal (target) - it returns the sorted table: expect (f (subject, cmp)).to_equal (target) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") - describe totable: + - before: + t = {"one", "two", "five"} + mt = { _type = "MockObject", + __totable = function (self) return self.content end } + + f = M.totable + + - it writes a deprecation warning: + setdebug { deprecate = "nil" } + expect (capture (f, {{}})).to_contain_error "was deprecated" + setdebug { deprecate = false } + expect (capture (f, {{}})).not_to_contain_error "was deprecated" + + - it calls object's __totable metamethod: + object = setmetatable ({content = t}, mt) + expect (f (object)).to_be (t) + - it returns a table with no __totable metamethod unchanged: + t = {content = t} + object = setmetatable (t, { _type = "Thing" }) + expect (f (object)).to_be (t) - describe values: - before: subject = { k1 = {1}, k2 = {2}, k3 = {3} } - f = M.values + + f = M.values + + - context with bad arguments: + badargs.diagnose (f, "std.table.values (table)") + - it returns an empty list when subject is empty: expect (f {}).to_equal {} - it makes a list of table values: @@ -393,6 +751,3 @@ specify std.table: -- is this a good test? or just requiring an implementation quirk? for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).to_equal (subject) - - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") diff --git a/specs/tree_spec.yaml b/specs/tree_spec.yaml index 0d9da21..025d7fb 100644 --- a/specs/tree_spec.yaml +++ b/specs/tree_spec.yaml @@ -7,7 +7,6 @@ before: | specify std.tree: - before: prototype = (require "std.object").prototype - totable = (require "std.table").totable t = {foo="foo", fnord={branch={bar="bar", baz="baz"}}, quux="quux"} tr = Tree (t) @@ -28,7 +27,7 @@ specify std.tree: expect (tr).not_to_be (Tree) expect (prototype (tr)).to_be "Tree" - it turns a table argument into a tree: - expect (prototype (Tree (tr))).to_be "Tree" + expect (prototype (Tree (t))).to_be "Tree" - it does not turn table argument values into sub-Trees: expect (prototype (tr["fnord"])).to_be "table" - it understands branched nodes: @@ -58,8 +57,8 @@ specify std.tree: expect (subject).to_equal (target) expect (subject).to_be (subject) - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "foo").to_error ("table expected") + expect (f ()).to_raise ("table expected") + expect (f "foo").to_raise ("table expected") - describe ileaves: @@ -93,8 +92,8 @@ specify std.tree: end expect (l).to_equal {"one", "three", "five"} - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "string").to_error ("table expected") + expect (f ()).to_raise ("table expected") + expect (f "string").to_raise ("table expected") - describe inodes: @@ -179,8 +178,8 @@ specify std.tree: {"leaf", {2}, subject[2]}, -- five, {"join", {}, subject}} -- } - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "string").to_error ("table expected") + expect (f ()).to_raise ("table expected") + expect (f "string").to_raise ("table expected") - describe leaves: @@ -216,8 +215,8 @@ specify std.tree: expect (l).to_contain. a_permutation_of {"one", 2, "three", 4, "bar", "five"} - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "string").to_error ("table expected") + expect (f ()).to_raise ("table expected") + expect (f "string").to_raise ("table expected") - describe merge: @@ -246,8 +245,8 @@ specify std.tree: expect (m.k3).to_be (t2.k3) expect (m.k3).not_to_be (original.k3) - it diagnoses non-table arguments: - expect (f (nil, {})).to_error ("table expected") - expect (f ({}, nil)).to_error ("table expected") + expect (f (nil, {})).to_raise ("table expected") + expect (f ({}, nil)).to_raise ("table expected") - describe nodes: @@ -355,8 +354,8 @@ specify std.tree: {"leaf", {3}, subject[{3}]}, -- 3rd, {"join", {}, subject[{}]}} -- } - it diagnoses non-table arguments: - expect (f ()).to_error ("table expected") - expect (f "string").to_error ("table expected") + expect (f ()).to_raise ("table expected") + expect (f "string").to_raise ("table expected") - describe __index: @@ -397,13 +396,6 @@ specify std.tree: tr[{"foo", "branch", "baz"}] = "leaf2" expect (tr).to_equal (Tree {foo=Tree {branch=Tree {bar="leaf1", baz="leaf2"}}}) -- describe __totable: - - it returns a table: - expect (prototype (totable (tr))).to_be "table" - - it contains all non-hidden fields of object: - expect (totable (tr)).to_contain. - all_of {"foo", branch={bar="bar", baz="baz"}, "quux"} - - describe __tostring: - it returns a string: expect (prototype (tostring (tr))).to_be "string" diff --git a/stdlib-40-1.rockspec b/stdlib-41.0.0-1.rockspec similarity index 89% rename from stdlib-40-1.rockspec rename to stdlib-41.0.0-1.rockspec index d0ee09f..ece0b06 100644 --- a/stdlib-40-1.rockspec +++ b/stdlib-41.0.0-1.rockspec @@ -1,5 +1,5 @@ package = "stdlib" -version = "40-1" +version = "41.0.0-1" description = { detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://lua-stdlib.github.io/lua-stdlib", @@ -7,11 +7,11 @@ description = { summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v40", - url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v40.zip", + dir = "lua-stdlib-release-v41.0.0", + url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.0.0.zip", } dependencies = { - "lua >= 5.1", + "lua >= 5.1, < 5.4", } external_dependencies = nil build = { @@ -26,6 +26,7 @@ build = { ["std.list"] = "lib/std/list.lua", ["std.math"] = "lib/std/math.lua", ["std.object"] = "lib/std/object.lua", + ["std.operator"] = "lib/std/operator.lua", ["std.optparse"] = "lib/std/optparse.lua", ["std.package"] = "lib/std/package.lua", ["std.set"] = "lib/std/set.lua", diff --git a/travis.yml.in b/travis.yml.in index d39c34d..5a683a5 100644 --- a/travis.yml.in +++ b/travis.yml.in @@ -1,70 +1,134 @@ -# Lua is not officially supported, but an erlang environment will do. -language: erlang +language: c env: global: - - PACKAGE=@PACKAGE@ - - ROCKSPEC=$PACKAGE-git-1.rockspec - - LUAROCKS_CONFIG=build-aux/luarocks-config.lua - - LUAROCKS_BASE=luarocks-2.1.2 - - LUAROCKS="$LUA $HOME/bin/luarocks" + - _COMPILE="libtool --mode=compile --tag=CC gcc" + - _CFLAGS="-O2 -Wall -DLUA_COMPAT_ALL -DLUA_USE_LINUX" + - _INSTALL="libtool --mode=install install -p" + - _LINK="libtool --mode=link --tag=CC gcc" + - _LIBS="-lm -Wl,-E -ldl -lreadline" + + - prefix=/usr/local + - bindir=$prefix/bin + - incdir=$prefix/include + - libdir=$prefix/lib matrix: - - LUA=lua5.1 LUA_INCDIR=/usr/include/lua5.1 LUA_SUFFIX=5.1 - - LUA=lua5.2 LUA_INCDIR=/usr/include/lua5.2 LUA_SUFFIX=5.2 - - LUA=luajit-2.0.0-beta9 LUA_INCDIR=/usr/include/luajit-2.0 LUA_SUFFIX=5.1 + - LUA=lua5.3 + - LUA=lua5.2 + - LUA=lua5.1 + - LUA=luajit -# Tool setup. -install: + +before_install: # Put back the links for libyaml, which are missing on recent Travis VMs - test -f /usr/lib/libyaml.so || sudo find /usr/lib -name 'libyaml*' -exec ln -s {} /usr/lib \; - - sudo apt-get install help2man - - sudo apt-get install luajit - - sudo apt-get install libluajit-5.1-dev - - sudo apt-get install lua5.1 - - sudo apt-get install liblua5.1-dev - - sudo apt-get install lua5.2 - - sudo apt-get install liblua5.2-dev - # Install a recent luarocks release locally for everything else. - - wget http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz - - tar zxvpf $LUAROCKS_BASE.tar.gz - # LuaRocks configure --with-lua argument is just a prefix! - - ( cd $LUAROCKS_BASE; - ./configure - --prefix=$HOME --with-lua=/usr --lua-version=$LUA_SUFFIX - --lua-suffix=$LUA_SUFFIX --with-lua-include=$LUA_INCDIR; - make build; - make install; ) - -# Configure and build. + + # Fetch Lua sources. + - cd $TRAVIS_BUILD_DIR + - 'if test lua5.3 = "$LUA"; then + curl http://www.lua.org/work/lua-5.3.0-rc3.tar.gz | tar xz; + cd lua-5.3.0; + fi' + - 'if test lua5.2 = "$LUA"; then + curl http://www.lua.org/ftp/lua-5.2.3.tar.gz | tar xz; + cd lua-5.2.3; + fi' + - 'if test lua5.1 = "$LUA"; then + curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz; + cd lua-5.1.5; + fi' + + # Unpack, compile and install Lua. + - 'if test luajit = "$LUA"; then + curl http://luajit.org/download/LuaJIT-2.0.3.tar.gz | tar xz; + cd LuaJIT-2.0.3; + make && sudo make install; + for header in lua.h luaconf.h lualib.h lauxlib.h luajit.h lua.hpp; do + if test -f /usr/local/include/luajit-2.0/$header; then + sudo ln -s /usr/local/include/luajit-2.0/$header /usr/local/include/$header; + fi; + done; + else + for src in src/*.c; do + test src/lua.c = "$src" || test src/luac.c = "$src" || eval $_COMPILE $_CFLAGS -c $src; + done; + eval $_LINK -o lib$LUA.la -version-info 0:0:0 -rpath $libdir *.lo; + sudo mkdir -p $libdir; + eval sudo $_INSTALL lib$LUA.la $libdir/lib$LUA.la; + + eval $_COMPILE $_CFLAGS -c src/lua.c; + eval $_LINK -static -o $LUA lua.lo lib$LUA.la $_LIBS; + sudo mkdir -p $bindir; + eval sudo $_INSTALL $LUA $bindir/$LUA; + + sudo mkdir -p $incdir; + for header in lua.h luaconf.h lualib.h lauxlib.h lua.hpp; do + if test -f src/$header; then + eval sudo $_INSTALL src/$header $incdir/$header; + fi; + done; + fi' + + # Fetch LuaRocks. + - cd $TRAVIS_BUILD_DIR + - 'git clone https://github.com/keplerproject/luarocks.git luarocks-2.2.0' + - cd luarocks-2.2.0 + - git checkout v2.2.0 + + # Compile and install luarocks. + - if test luajit = "$LUA"; then + ./configure --lua-suffix=jit; + else + ./configure; + fi + - 'make build && sudo make install' + + # Tidy up file droppings. + - cd $TRAVIS_BUILD_DIR + - rm -rf lua-5.3.0 lua-5.2.3 lua-5.1.5 LuaJIT-2.0.3 luarocks-2.2.0 + + +install: + # Use Lua 5.3 compatible rocks, where available. + - 'for rock in @EXTRA_ROCKS@""; do + if test -z "$rock"; then break; fi; + if luarocks list | grep "^$rock$" >/dev/null; then continue; fi; + sudo luarocks install --server=http://rocks.moonscript.org/manifests/gvvaughan $rock; + done' + + # Fudge timestamps on release branches. + - 'if test -f configure; then + test -f aclocal.m4 && touch aclocal.m4; + sleep 1; touch Makefile.in; + sleep 1; test -f config.h.in && touch config.h.in; + sleep 1; touch configure; + fi' + + # Build from rockspec. + - export ROCKSPEC=@PACKAGE@-@VERSION@-1.rockspec + - 'test -f "$ROCKSPEC" || ROCKSPEC=@PACKAGE@-git-1.rockspec' + - sudo luarocks make $ROCKSPEC LUA="$LUA" + + # Clean up files created by root + - sudo git clean -dfx + - sudo rm -rf slingshot /tmp/ldoc + + script: - # Initial bootstrap to build luarocks-config.lua, before we've - # installed our rocks. - - ./bootstrap --skip-rock-checks - - ./configure LUA="$LUA" - - make $LUAROCKS_CONFIG - LUA="$LUA" LUA_INCDIR="$LUA_INCDIR" V=1 - || cat $LUAROCKS_CONFIG config.log - - # Set Lua and Shell paths up for local luarocks tree. - # this package depends on will be installed. - - eval `$LUAROCKS path` - - export PATH=`pwd`/luarocks/bin:$PATH - - # Install extra rocks into $LUAROCKS_CONFIG rocks tree. - @EXTRA_ROCKS@ - - # Make git rockspec for this @PACKAGE@ - - make rockspecs LUAROCKS="$LUAROCKS" V=1 - || { $LUAROCKS path; cat $ROCKSPEC; } - - # The git rockspec will rerun bootstrap, and check any rock versions - # in bootstrap.conf:buildreq this time. - - $LUAROCKS make $ROCKSPEC LUA="$LUA" - - # Run self-tests in the `luarocks make` build tree. - - LUA_PATH=`pwd`'/lib/?.lua;'"${LUA_PATH-;}" - LUA_CPATH=`pwd`'/ext/?.so;'"${LUA_CPATH-;}" - LUA_INIT= LUA_INIT_5_2= - make check V=1 + - test -f configure || ./bootstrap --verbose + - test -f Makefile || ./configure --disable-silent-rules LUA="$LUA" + - make + - make check V=1 + + +# Run sanity checks on CI server, ignoring buggy automakes. +after_success: + - '{ _assign="="; + if grep local-checks-to-skip build-aux/sanity-cfg.mk >/dev/null; then + _assign="+="; + fi; + printf "local-checks-to-skip %s sc_vulnerable_makefile_CVE-2012-3386\n" "$_assign"; + } >> build-aux/sanity-cfg.mk' + - 'make syntax-check || : this will usually fail on the release branch' From 6d4307418a49392f677fbba45f287f04da6799d0 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Fri, 30 Jan 2015 17:58:02 +0000 Subject: [PATCH 28/34] Release v41.1.0. Signed-off-by: Gary V. Vaughan --- .travis.yml | 4 +- ChangeLog | 261 +++++++++++++ Makefile.am | 8 +- Makefile.in | 67 ++-- NEWS | 70 ++++ aclocal.m4 | 53 +-- build-aux/install-sh | 366 ++++++++---------- build-aux/missing | 2 +- configure | 41 +- configure.ac | 2 +- doc/classes/std.container.html | 8 +- doc/classes/std.list.html | 10 +- doc/classes/std.object.html | 28 +- doc/classes/std.optparse.html | 44 +-- doc/classes/std.set.html | 8 +- doc/classes/std.strbuf.html | 90 ++--- doc/classes/std.tree.html | 34 +- doc/index.html | 6 +- doc/modules/std.debug.html | 78 ++-- doc/modules/std.functional.html | 36 +- doc/modules/std.html | 60 +-- doc/modules/std.io.html | 38 +- doc/modules/std.math.html | 10 +- doc/modules/std.operator.html | 12 +- doc/modules/std.package.html | 36 +- doc/modules/std.strict.html | 14 +- doc/modules/std.string.html | 114 +++--- doc/modules/std.table.html | 136 ++++--- lib/std.lua | 13 +- lib/std.lua.in | 13 +- lib/std/base.lua | 30 +- lib/std/container.lua | 2 +- lib/std/debug.lua | 356 ++++++++++------- lib/std/debug_init/init.lua | 11 +- lib/std/functional.lua | 21 +- lib/std/io.lua | 18 +- lib/std/list.lua | 6 +- lib/std/math.lua | 8 +- lib/std/package.lua | 40 +- lib/std/set.lua | 29 +- lib/std/strbuf.lua | 109 ++++-- lib/std/string.lua | 26 +- lib/std/table.lua | 27 +- lib/std/tree.lua | 44 +-- m4/ax_lua.m4 | 3 +- specs/debug_spec.yaml | 351 +++++++++++++++-- specs/io_spec.yaml | 27 +- specs/math_spec.yaml | 8 +- specs/package_spec.yaml | 8 + specs/spec_helper.lua | 55 ++- specs/std_spec.yaml | 22 ++ specs/strbuf_spec.yaml | 86 +++- specs/string_spec.yaml | 8 +- specs/table_spec.yaml | 27 +- ...0.0-1.rockspec => stdlib-41.1.0-1.rockspec | 6 +- travis.yml.in | 2 +- 56 files changed, 1981 insertions(+), 1011 deletions(-) rename stdlib-41.0.0-1.rockspec => stdlib-41.1.0-1.rockspec (94%) diff --git a/.travis.yml b/.travis.yml index f514a51..14dd40e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ before_install: # Fetch Lua sources. - cd $TRAVIS_BUILD_DIR - 'if test lua5.3 = "$LUA"; then - curl http://www.lua.org/work/lua-5.3.0-rc3.tar.gz | tar xz; + curl http://www.lua.org/ftp/lua-5.3.0.tar.gz | tar xz; cd lua-5.3.0; fi' - 'if test lua5.2 = "$LUA"; then @@ -107,7 +107,7 @@ install: fi' # Build from rockspec. - - export ROCKSPEC=stdlib-41.0.0-1.rockspec + - export ROCKSPEC=stdlib-41.1.0-1.rockspec - 'test -f "$ROCKSPEC" || ROCKSPEC=stdlib-git-1.rockspec' - sudo luarocks make $ROCKSPEC LUA="$LUA" diff --git a/ChangeLog b/ChangeLog index 5c7ebe3..a4f5d48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,266 @@ +2015-01-30 Gary V. Vaughan + + Release version 41.1.0 + * NEWS.md: Record release date. + + package: normalize leaves valid /../.. sequences unmolested. + * specs/package_spec.yaml (normalize): Add examples of correct + behaviour with multiple .. directories. + * lib/std/package.lua (normalize): Detect redundant .. components + correctly, and only remove them when it's safe to do so. + * NEWS.md (Bug fixes): Update. + + slingshot: sync with upstream. + * slingshot: Sync with upstream. + * .travis.yml: Regenerate. + + configury: bump release version to 41.1.0. + * configure.ac (AC_INIT): Bump release version to 41.1.0. + + table: new unpack method that behaves consistently across Lua versions. + * specs/table_spec.yaml (unpack): Specify behaviours for unpack, + especially when dealing with holes. + * lib/std/base.lua (unpack): Wrapper for the core function, but + defaulting the final index argument to table.maxn. + * lib/std/table.lua (unpack): Export from here. Add LDocs. + * lib/std/debug.lua, lib/std/functional.lua, lib/std/list.lua: Use + safer base.unpack. + * specs/spec_helper.lua (maxn, unpack): Make safe versions + available to spec examples. + * specs/debug_spec.yaml: Simplify id implementation. + * NEWS.md (New features): Update. + + debug: unpack to maxn (t) for equivalence between Lua versions. + luajit alone stops unpacking at the first nil valued index, so + we have to pass explicit limits to make it behave like Lua 5.1 + through 5.3. + * lib/std/debug.lua (argscheck): unpack from 1 to maxn (results). + * specs/debug_spec.yaml (argscheck): Adjust id implementation to + calculate maximum numeric index and unpack all results up to + that value. + + debug: support variant return type lists with argscheck. + Sometimes we need to say `returns an int or nil,errmsg', the + syntax is `=> int or nil, string`, because `=> ?int, string` will + wrongly accept, say, `3, "oh noes!"`. + * specs/debug_spec.yaml (argscheck): Specify behaviours with + variant return type lists. + * lib/std/debug.lua (argscheck): Parse all variants and add them + to the accepted type list permutations table. + Update LDocs. + * NEWS.md (New features): Update. + +2015-01-29 Gary V. Vaughan + + refactor: store parameter dots property against each permuted list. + Rather than deciding whether a typelist has continuation dots in + the last position once for the entire table of permuted type match + lists, add it to each permutation with continuation dots. + * lib/std/debug.lua (markdots): Simplify. + (permute): Call it for each new permutation row. + (projectuniq): New function to select and de-deduplicate all + values from the table of permuted type lists at a given index. + (diagnose): Rewrite to work with new format permutations. + (argscheck): Simplify accordingly. + (match): Remove allargs parameter, and always check all arguments. + (merge, HAS_DOTS): Remove. No longer used. + +2015-01-28 Gary V. Vaughan + + refactor: clean up maxvalues calculation in debug.argscheck. + * lib/std/debug.lua (stripellipsis): Remove. + (markdots): New function encapsulating stripellipsis, maxvalue + calculation and optional normalization. + (argscheck): Simplify accordingly. + + debug: argscheck supports return type checking. + Close #89 + * specs/spec_helper.lua (badargs.result): Fallback implementation + until next Specl release. + (init): Use it to return a `badresult` function. + * specs/debug_spec.yaml: Specifiy behaviours with return type + checking. + * lib/std/debug.lua (toomanyargmsg): Factor this... + (toomanymsg): ...into this more general function. + (M): Adjust accordingly. + (resulterror): New function modelled after argerror, but tailored + for result type mismatch error reporting. + (has_dots): Symbol to name use of math.huge for denoting an + ellipsis was stripped from the type list. + (stripellipsis): New function. + (diagnose): Refactored to take a vtable of arguments instead of an + ever longer list of parameters. + (argscheck): Build a vtable to call diagnose for argument type + checking. + Add another diagnose() with a separate vtable for result type + checking. + Update LDocs. + * NEWS.md (New features): Update. + +2015-01-27 Gary V. Vaughan + + refactor: separate argscheck inner wrapper into its own function. + * lib/std/debug.lua (empty): New function. + (diagnose): New function... + (argscheck): ...factored out of here. + +2015-01-26 Gary V. Vaughan + + tree: don't argcheck metamethods. + Lua will not call metamethods unless the metatables are compatible, + so don't waste time rechecking the argument types. + * lib/std/tree.lua (__index, __newindex): Remove superfluous + argscheck invocations. + + set: don't argcheck metamethods. + Lua will not call metamethods unless the metatables are compatible, + so don't waste time rechecking the argument types. + * lib/std/set.lua (__add, __sub, __mul, __div, __le, __lt) + (__tostring): Remove superfluous argscheck invocations. + + debug: more accurate too many arguments diagnostics. + Close #76 + * specs/debug_spec.yaml (argscheck): Specify behaviour when + arguments match by skipping bracketed optional parameters, but + for one unmatched argument at the end. + * lib/std/debug.lua (permutations): Rename function from this + noun... + (permute): ...to this verb. + (argscheck): Use the matching permutation to decide whether + too many arguments were passed, unless the last parameter has + an ellipsis denoting any number of matching arguments are allowed. + * NEWS.md (Bug fixes): Update. + + debug: process [final|parm|types] without nil substitution hack. + * specs/debug_spec.yaml (argscheck): Specify behaviours for + bracketed final parameter more thoroughly. + * lib/std/debug.lua (argscheck): Remove hack of replacing + brackets in bracketed last parameter by 'or nil'; we really + run permutations without a bracketed final parameter now. + (permutations): Simplify accordingly; we don't need all the + sentinel gunk to track final argument nils now. + (normalize): Simplify, and fix a related bug where nils could + get dropped from the type list by a double increment. + * lib/std/functional.lua (bind): This really is a '?any...', + requiring explicit nils, and not a [any...] optional argument. + * specs/debug_spec.yaml: Adjust badargs calls as necessary. + * specs/io_spec.yaml (writelines): Now that this implementation + is a step ahead of the current Specl release generator, manually + write out bad argument examples. + * NEWS.md: Update. + + debug: argscheck accepts bracketed final parameter. + * specs/debug_spec.yaml (argscheck): Add examples for bracketed + final parameters. + * lib/std/debug.lua (argscheck): Handle bracketed final parameter + and satisfy new specs. Adjust all callers accordingly. + * NEWS.md (New features): Update. + + debug: use trailing `...` instead of `*` with argscheck. + * specs/debug_spec.yaml (argscheck): Add specifications for + continuation argument behavious with `...`. + * lib/std/debug.lua (argscheck): Use `...` instead of `*` as the + syntax for optional repeats of the final parameter type. Adjust + all callers. + * NEWS.md (Incompatible changes): Update. + + refactor: change `types` symbol name to `argtypes`. + * lib/std/debug.lua (argscheck): Change `types` symbol name to + `argtypes`. + +2015-01-25 Gary V. Vaughan + + debug: argcheck requires leading ? for argtypes, to match specl. + Close #90 + * specs/debug_spec.yaml (argcheck): Change to leading `?` over + previous trailing `?` style. + * lib/std.lua.in, lib/std/container.lua, lib/std/debug.lua, + lib/std/functional.lua, lib/std/io.lua, lib/std/list.lua, + lib/std/math.lua, lib/std/package.lua, lib/std/string.lua, + lib/std/table.lua, lib/std/tree.lua: Adjust accordingly. + + strbuf: document and test functional copying style. + Close #85 + * lib/std/strbuf.lua: Improve LDocs. + * specs/strbuf_spec.yaml: Add example of functional copying. + + strbuf: support lazy stringification and concat anything. + * specs/strbuf_spec.yaml: Specify correct behaviours, and add + lazy stringification example. + * lib/std/strbuf.lua (__concat): Simply insert a reference. + (__tostring): Make a table of stringified elements, and concat + those instead of the object elements proper. + * NEWS.md: Update. + + strbuf: allow concatenation of StrBuf objects. + * specs/strbuf_spec.yaml: Specify new behaviours. + * lib/std/strbuf.lua (concat): New function, handles concatenation + of StrBuf objects as well as strings. + * NEWS.md: Update. + + strbuf: deprecate strbuf.tostring. + * specs/strbuf_spec.yaml: Specify deprecation messages from + strbuf.tostring. + * lib/std/strbuf.lua (StrBuf.tostring): Deprecate. + * NEWS.md: Update. + + refactor: rearrange strbuf.lua idiomatically. + * lib/std/strbuf.lua: Rearrange declarations idiomatically. + + maint: support strict mode. + Close #92 + * lib/std/base.lua (loadstring): Use rawget to fetch loadstring + from _G, to bypass strict mode checks on Lua > 5.2 where + _G.loadstring is nil. + * lib/std/debug.lua (getfenv): Likewise, for Lua > 5.2 where + there is no _G.fgetenv. + * lib/std/debug_init/init.lua (_DEBUG): Likewise, for cases where + caller did not preload _G._DEBUG. + * NEWS.md: Updated. + Reported by Gergely Risko + +2015-01-19 Gary V. Vaughan + + std: barrel and monkey_patch return module table. + Closes #93 + In order for things like `std = require "std".barrel ()` to work + as documented, these methods must return their parent module + table, i.e. in this case, the `std` table. + * specs/io_spec.yaml (monkey_patch): Specify correct behaviour. + * specs/math_spec.yaml (monkey_patch): Likewise. + * specs/string_spec.yaml (monkey_patch): Likewise. + * specs/table_spec.yaml (money_patch): Likewise. + * specs/std_spec.yaml (barrel, monkey_patch): Likewise. + * lib/std.lua.in (barrel, monkey_patch): Return parent module + able. + * lib/std/io.lua, lib/std/math.lua, lib/std/string.lua, + lib/std/table.lua (monkey_patch): Likewise. + * NEWS.md (Bug fixes): Update. + Reported by Reuben Thomas + +2015-01-14 Gary V. Vaughan + + slingshot: sync with upstream for working Lua 5.3.0 final support. + * slingshot: Sync with upstream. + * .travis.yml: Regenerate. + + slingshot: sync with upstream for Lua 5.3.0 final support. + * slingshot: Sync with upstream. + * .travis.yml: Regenerate. + +2015-01-14 Gergely Risko + + base: remove spurious case reference from base module. + * lib/std/base.lua: Remove spurious reference to case from + export table. That function has long since moved to std.functional. + 2015-01-03 Gary V. Vaughan + maint: post-release administrivia. + * NEWS: Add header line for next release. + * .prev-version: Record previous version. + * ./local.mk (old_NEWS_hash): Auto-update. + Release version 41.0.0 * NEWS.md: Record release date. diff --git a/Makefile.am b/Makefile.am index eb5bd80..23a5bc7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -80,10 +80,10 @@ install-exec-hook: $(install_exec_hooks) # actually moves such files aside anyway, so we just remove them from # the installation directory. remove-luaexec-lafiles: - @for la in $(luaexec_LTLIBRARIES); do \ - f=`echo "$$la" |sed 's|^.*/||'`; \ - echo rm -f $(luaexecdir)/$$f; \ - rm -f $(luaexecdir)/$$f; \ + @for la in $(luaexec_LTLIBRARIES); do \ + f=`echo "$$la" |sed 's|^.*/||'`; \ + echo rm -f $(DESTDIR)$(luaexecdir)/$$f; \ + rm -f $(DESTDIR)$(luaexecdir)/$$f; \ done diff --git a/Makefile.in b/Makefile.in index 12b6d44..f28b200 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -119,7 +119,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -180,22 +190,17 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -DIST_COMMON = $(srcdir)/local.mk $(srcdir)/specs/specs.mk \ - $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk \ - INSTALL NEWS README AUTHORS ChangeLog $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(top_srcdir)/build-aux/config.ld.in \ - $(dist_bin_SCRIPTS) $(dist_classes_DATA) $(dist_doc_DATA) \ - $(dist_lua_DATA) $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ - $(dist_modules_DATA) COPYING build-aux/install-sh \ - build-aux/missing $(top_srcdir)/build-aux/install-sh \ - $(top_srcdir)/build-aux/missing subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lua.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(dist_bin_SCRIPTS) $(dist_classes_DATA) \ + $(dist_doc_DATA) $(dist_lua_DATA) $(dist_luastd_DATA) \ + $(dist_luastddebug_DATA) $(dist_modules_DATA) \ + $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d @@ -259,6 +264,13 @@ DATA = $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ $(dist_modules_DATA) $(doc_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(srcdir)/build-aux/rockspecs.mk $(srcdir)/build-aux/specl.mk \ + $(srcdir)/local.mk $(srcdir)/specs/specs.mk \ + $(top_srcdir)/build-aux/config.ld.in \ + $(top_srcdir)/build-aux/install-sh \ + $(top_srcdir)/build-aux/missing AUTHORS COPYING ChangeLog \ + INSTALL NEWS README build-aux/install-sh build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -511,7 +523,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/local.mk $(srcdir)/specs echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -521,7 +532,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; -$(srcdir)/local.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk: +$(srcdir)/local.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck @@ -883,15 +894,15 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) @@ -927,17 +938,17 @@ distcheck: dist esac chmod -R a-w $(distdir) chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_inst + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build \ - && ../configure \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=.. --prefix="$$dc_install_base" \ + --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ @@ -1140,6 +1151,8 @@ uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ uninstall-docDATA uninstall-hook uninstall-libLTLIBRARIES \ uninstall-luaexecLTLIBRARIES +.PRECIOUS: Makefile + LUA_PATH ?= ; LUA_CPATH ?= ; @@ -1199,10 +1212,10 @@ install-exec-hook: $(install_exec_hooks) # actually moves such files aside anyway, so we just remove them from # the installation directory. remove-luaexec-lafiles: - @for la in $(luaexec_LTLIBRARIES); do \ - f=`echo "$$la" |sed 's|^.*/||'`; \ - echo rm -f $(luaexecdir)/$$f; \ - rm -f $(luaexecdir)/$$f; \ + @for la in $(luaexec_LTLIBRARIES); do \ + f=`echo "$$la" |sed 's|^.*/||'`; \ + echo rm -f $(DESTDIR)$(luaexecdir)/$$f; \ + rm -f $(DESTDIR)$(luaexecdir)/$$f; \ done uninstall-hook: $(uninstall_hooks) diff --git a/NEWS b/NEWS index 7284b9d..3e608f8 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,75 @@ # Stdlib NEWS - User visible changes +## Noteworthy changes in release 41.1.0 (2015-01-30) [stable] + +### New features + + - Anything that responds to `tostring` can be appended to a `std.strbuf`: + + ```lua + local a, b = StrBuf { "foo", "bar" }, StrBuf { "baz", "quux" } + a = a .. b --> "foobarbazquux" + ``` + + - `std.strbuf` stringifies lazily, so adding tables to a StrBuf + object, and then changing the content of them before calling + `tostring` also changes the contents of the buffer. See LDocs for + an example. + + - `debug.argscheck` accepts square brackets around final optional + parameters, which is distinct to the old way of appending `?` or + `|nil` in that no spurious "or nil" is reported for type mismatches + against a final bracketed argument. + + - `debug.argscheck` can also check types of function return values, when + specified as: + + ```lua + fn = argscheck ("fname (?any...) => int, table or nil, string", fname) + ``` + + Optional results can be marked with brackets, and an ellipsis following + the final type denotes any additional results must match that final + type specification. Alternative result type groups are separated by "or". + + - New `table.unpack (t, [i, [j]])` function that defaults j to + `table.maxn (t)`, even on luajit which stops before the first nil + valued numeric index otherwise. + +### Deprecations + + - `std.strbuf.tostring` has been deprecated in favour of `tostring`. + Why write `std.strbuf.tostring (sb)` or `sb:tostring ()` when it is + more idiomatic to write `tostring (sb)`? + +### Bug fixes + + - `std.barrel` and the various `monkey_patch` functions now return + their parent module table as documented. + + - stdlib modules are all `std.strict` compliant; require "std.strict" + before requiring other modules no longer raises an error. + + - `debug.argscheck` can now diagnose when there are too many arguments, + even in the case where the earlier arguments match parameters by + skipping bracketed optionals, and the total number of arguments is + still less than the absolute maximum allowed if optionals are counted + too. + + - `package.normalize` now leaves valid ./../../ path prefixes unmolested. + +### Incompatible changes + + - `debug.argscheck` requires nil parameter type `?` notation to be + prepended to match Specl and TypedLua syntax. `?` suffixes are a + syntax error. + + - `debug.argscheck` uses `...` instead of `*` appended to the final element + if all unmatched argument types should match. The trailing `*` syntax + was confusing, because it was easy to misread it as "followed by zero-or- + more of this type". + + ## Noteworthy changes in release 41.0.0 (2015-01-03) [beta] ### New features diff --git a/aclocal.m4 b/aclocal.m4 index 267246d..dfb1151 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.14.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.14' +[am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.14.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.14.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -103,15 +103,14 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -201,8 +200,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl @@ -275,7 +274,11 @@ to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi -fi]) +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further @@ -304,7 +307,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -315,7 +318,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then +if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; @@ -325,7 +328,7 @@ if test x"${install_sh}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -346,7 +349,7 @@ AC_SUBST([am__leading_dot])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -385,7 +388,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -416,7 +419,7 @@ AC_DEFUN([_AM_IF_OPTION], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -497,7 +500,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -557,7 +560,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -585,7 +588,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -604,7 +607,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/build-aux/install-sh b/build-aux/install-sh index 377bb86..0b0fdcb 100755 --- a/build-aux/install-sh +++ b/build-aux/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-11-20.07; # UTC +scriptversion=2013-12-25.23; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -41,19 +41,15 @@ scriptversion=2011-11-20.07; # UTC # This script is compatible with the BSD install script, but was written # from scratch. +tab=' ' nl=' ' -IFS=" "" $nl" +IFS=" $tab$nl" -# set DOITPROG to echo to test this script +# Set DOITPROG to "echo" to test this script. -# Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi +doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. @@ -68,17 +64,6 @@ mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - posix_mkdir= # Desired mode of installed file. @@ -97,7 +82,7 @@ dir_arg= dst_arg= copy_on_change=false -no_target_directory= +is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE @@ -137,46 +122,57 @@ while test $# -ne 0; do -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift;; + shift;; -s) stripcmd=$stripprog;; - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; - -T) no_target_directory=true;; + -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; - --) shift - break;; + --) shift + break;; - -*) echo "$0: invalid option: $1" >&2 - exit 1;; + -*) echo "$0: invalid option: $1" >&2 + exit 1;; *) break;; esac shift done +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. @@ -207,6 +203,15 @@ if test $# -eq 0; then exit 0 fi +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 @@ -223,16 +228,16 @@ if test -z "$dir_arg"; then *[0-7]) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw='% 200' + u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw=,u+rw + u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac @@ -269,41 +274,15 @@ do # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - + dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi @@ -314,74 +293,74 @@ do if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; esac if $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else @@ -391,53 +370,51 @@ do # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; esac - eval "$initialize_posix_glob" - oIFS=$IFS IFS=/ - $posix_glob set -f + set -f set fnord $dstdir shift - $posix_glob set +f + set +f IFS=$oIFS prefixes= for d do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ done if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi fi fi @@ -472,15 +449,12 @@ do # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - + set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then @@ -493,24 +467,24 @@ do # to itself, or perhaps because mv is so ancient that it does not # support -f. { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 diff --git a/build-aux/missing b/build-aux/missing index db98974..f62bbae 100755 --- a/build-aux/missing +++ b/build-aux/missing @@ -3,7 +3,7 @@ scriptversion=2013-10-28.13; # UTC -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify diff --git a/configure b/configure index 5240374..dd6d535 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 41.0.0. +# Generated by GNU Autoconf 2.69 for stdlib 41.1.0. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='41.0.0' -PACKAGE_STRING='stdlib 41.0.0' +PACKAGE_VERSION='41.1.0' +PACKAGE_STRING='stdlib 41.1.0' PACKAGE_BUGREPORT='http://github.com/lua-stdlib/lua-stdlib/issues' PACKAGE_URL='' @@ -1216,7 +1216,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 41.0.0 to adapt to many kinds of systems. +\`configure' configures stdlib 41.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1282,7 +1282,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 41.0.0:";; + short | recursive ) echo "Configuration of stdlib 41.1.0:";; esac cat <<\_ACEOF @@ -1362,7 +1362,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 41.0.0 +stdlib configure 41.1.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1379,7 +1379,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 41.0.0, which was +It was created by stdlib $as_me 41.1.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1759,11 +1759,11 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. $as_echo "## ------------------------- ## -## Configuring stdlib 41.0.0 ## +## Configuring stdlib 41.1.0 ## ## ------------------------- ##" echo -am__api_version='1.14' +am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -1935,8 +1935,8 @@ test "$program_suffix" != NONE && ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in @@ -1955,7 +1955,7 @@ else $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi -if test x"${install_sh}" != xset; then +if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; @@ -2249,7 +2249,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='41.0.0' + VERSION='41.1.0' cat >>confdefs.h <<_ACEOF @@ -2283,8 +2283,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # mkdir_p='$(MKDIR_P)' -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' @@ -2341,6 +2341,7 @@ END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi + # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; @@ -2406,7 +2407,8 @@ $as_echo_n "checking $_ax_check_text... " >&6; } if $LUA 2>/dev/null -e ' function norm (v) - i,j=v:match "(%d+)%.(%d+)" if i then return 100 * i + j end + i,j=v:match "(%d+)%.(%d+)" + if i then return 100 * tonumber (i) + tonumber (j) end end v, toobig=norm (_VERSION), norm "5.4" or math.huge os.exit ((v >= norm ("5.1") and v < toobig) and 0 or 1)'; then : @@ -2439,7 +2441,8 @@ fi if $ax_cv_pathless_LUA 2>/dev/null -e ' function norm (v) - i,j=v:match "(%d+)%.(%d+)" if i then return 100 * i + j end + i,j=v:match "(%d+)%.(%d+)" + if i then return 100 * tonumber (i) + tonumber (j) end end v, toobig=norm (_VERSION), norm "5.4" or math.huge os.exit ((v >= norm ("5.1") and v < toobig) and 0 or 1)'; then : @@ -3457,7 +3460,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 41.0.0, which was +This file was extended by stdlib $as_me 41.1.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3510,7 +3513,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 41.0.0 +stdlib config.status 41.1.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index fe6dc3d..2037fe5 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [41.0.0], [http://github.com/lua-stdlib/lua-stdlib/issues]) +AC_INIT([stdlib], [41.1.0], [http://github.com/lua-stdlib/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 09ccb87..9b66d95 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - stdlib 41.0.0 Reference + stdlib 41.1.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-03 18:38:43 +Last updated 2015-01-30 17:57:09
    diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 5d9c2d5..7018850 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - stdlib 41.0.0 Reference + stdlib 41.1.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-03 18:38:43 +Last updated 2015-01-30 17:57:09
    diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index 6571276..4960517 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - stdlib 41.0.0 Reference + stdlib 41.1.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-03 18:38:43 +Last updated 2015-01-30 17:57:09
    diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html index aef1c22..e910610 100644 --- a/doc/classes/std.optparse.html +++ b/doc/classes/std.optparse.html @@ -3,7 +3,7 @@ - stdlib 41.0.0 Reference + stdlib 41.1.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-03 18:38:43 +Last updated 2015-01-30 17:57:09
    diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index d4fb328..f213df5 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - stdlib 41.0.0 Reference + stdlib 41.1.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-03 18:38:43 +Last updated 2015-01-30 17:57:09
    diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index c03f0c4..9ed5da5 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - stdlib 41.0.0 Reference + stdlib 41.1.0 Reference @@ -24,7 +24,7 @@
    @@ -615,6 +688,160 @@

    Usage:

    _DEBUG = { argcheck = false, level = 9 }
    + + +

    Fields

    + +
    +
    + + extramsg_toomany +
    +
    + Format a too many things error. + + +
      +
    • bad + string + the thing there are too many of +
    • +
    • expected + int + maximum number of bad things expected +
    • +
    • actual + int + actual number of bad things that triggered the error +
    • +
    + + + +

    See also:

    + + +

    Usage:

    +
      +
      +   if maxn (argt) > 7 then
      +     argerror ("sevenses", 8, extramsg_toomany ("argument", 7, maxn (argt)))
      +   end
      +
    + +
    +
    + + getfenv +
    +
    + Extend debug.getfenv to unwrap functables correctly. + + +
      +
    • fn + int, function or functable + target function, or stack level +
    • +
    + + + + + +
    +
    + + resulterror +
    +
    + Raise a bad result error. + Like argerror for bad results. This function does not + return. The level argument behaves just like the core error + function. + + +
      +
    • name + string + function to callout in error message +
    • +
    • i + int + argument number +
    • +
    • extramsg + string + additional text to append to message inside parentheses + (optional) +
    • +
    • level + int + call stack level to blame for the error + (default 1) +
    • +
    + + + + +

    Usage:

    +
      +
      + local function slurp (file)
      +   local h, err = input_handle (file)
      +   if h == nil then argerror ("std.io.slurp", 1, err, 2) end
      +   ...
      +
    + +
    +
    + + setfenv +
    +
    + Extend debug.setfenv to unwrap functables correctly. + + +
      +
    • fn + function or functable + target function +
    • +
    • env + table + new function environment +
    • +
    + + + + + +
    +
    + + typesplit +
    +
    + Split a typespec string into a table of normalized type names. + + +
      +
    • either + string or table + "?bool|:nometa" or {"boolean", ":nometa"} +
    • +
    + + + + +
    @@ -623,7 +850,7 @@

    Usage:

    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index 2975322..a1a6bde 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.html b/doc/modules/std.html index 75cf55c..6b4d078 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index 3d7a493..8294c56 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index f24de2e..1564650 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.operator.html b/doc/modules/std.operator.html index 3f93a7f..3920271 100644 --- a/doc/modules/std.operator.html +++ b/doc/modules/std.operator.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index b3d0c5c..972cb2f 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index 0db6a76..bc19eb7 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index 8c2efda..3a01a2f 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index d289b9c..99af92e 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - stdlib 41.1.1 Reference + stdlib 41.2.0 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-01-31 12:47:39 +Last updated 2015-03-08 20:42:58
    diff --git a/lib/std.lua b/lib/std.lua index b897adf..93d4b3a 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -151,6 +151,7 @@ M = { -- @treturn table *t*, the table being iterated over -- @treturn int *index*, the previous iteration index -- @see ielems + -- @see npairs -- @see pairs -- @usage -- -- length of sequence @@ -176,13 +177,13 @@ M = { -- for e in rielems (l) do process (e) end ireverse = X ("ireverse (table)", base.ireverse), - --- Return named metamethod, if any, otherwis `nil`. + --- Return named metamethod, if any, otherwise `nil`. -- @function getmetamethod - -- @tparam table t table to get metamethod of - -- @string n name of metamethod to get + -- @param x item to act on + -- @string n name of metamethod to lookup -- @treturn function|nil metamethod function, or `nil` if no metamethod -- @usage lookup = std.getmetamethod (require "std.object", "__index") - getmetamethod = X ("getmetamethod (object|table, string)", base.getmetamethod), + getmetamethod = X ("getmetamethod (?any, string)", base.getmetamethod), --- Overwrite core methods and metamethods with `std` enhanced versions. -- @@ -194,6 +195,18 @@ M = { -- @usage local std = require "std".monkey_patch () monkey_patch = X ("monkey_patch (?table)", monkey_patch), + --- Ordered iterator for integer keyed values. + -- Like ipairs, but does not stop until the largest integer key. + -- @function npairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table t + -- @see ipairs + -- @see rnpairs + -- @usage + -- for i,v in npairs {"one", nil, "three"} do ... end + npairs = X ("npairs (table)", base.npairs), + --- Enhance core `pairs` to respect `__pairs` even in Lua 5.1. -- @function pairs -- @tparam table t a table @@ -228,9 +241,24 @@ M = { -- @treturn function iterator function -- @treturn table *t* -- @treturn number `#t + 1` + -- @see ipairs + -- @see rnpairs -- @usage for i, v = ripairs (t) do ... end ripairs = X ("ripairs (table)", base.ripairs), + --- An iterator like npairs, but in reverse. + -- Apart from the order of the elments returned, this function follows + -- the same rules as @{npairs} for determining first and last elements. + -- @function rnpairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table t + -- @see npairs + -- @see ripairs + -- @usage + -- for i,v in rnpairs {"one", nil, "three"} do ... end + rnpairs = X ("rnpairs (table)", base.rnpairs), + --- Enhance core `tostring` to render table contents as a string. -- @function tostring -- @param x object to convert to string @@ -240,7 +268,7 @@ M = { -- print (std.tostring {foo="bar","baz"}) tostring = X ("tostring (?any)", base.tostring), - version = "General Lua libraries / 41.1.0", + version = "General Lua libraries / 41.1.1", } diff --git a/lib/std.lua.in b/lib/std.lua.in index 3724ad3..925a750 100644 --- a/lib/std.lua.in +++ b/lib/std.lua.in @@ -151,6 +151,7 @@ M = { -- @treturn table *t*, the table being iterated over -- @treturn int *index*, the previous iteration index -- @see ielems + -- @see npairs -- @see pairs -- @usage -- -- length of sequence @@ -176,13 +177,13 @@ M = { -- for e in rielems (l) do process (e) end ireverse = X ("ireverse (table)", base.ireverse), - --- Return named metamethod, if any, otherwis `nil`. + --- Return named metamethod, if any, otherwise `nil`. -- @function getmetamethod - -- @tparam table t table to get metamethod of - -- @string n name of metamethod to get + -- @param x item to act on + -- @string n name of metamethod to lookup -- @treturn function|nil metamethod function, or `nil` if no metamethod -- @usage lookup = std.getmetamethod (require "std.object", "__index") - getmetamethod = X ("getmetamethod (object|table, string)", base.getmetamethod), + getmetamethod = X ("getmetamethod (?any, string)", base.getmetamethod), --- Overwrite core methods and metamethods with `std` enhanced versions. -- @@ -194,6 +195,18 @@ M = { -- @usage local std = require "std".monkey_patch () monkey_patch = X ("monkey_patch (?table)", monkey_patch), + --- Ordered iterator for integer keyed values. + -- Like ipairs, but does not stop until the largest integer key. + -- @function npairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table t + -- @see ipairs + -- @see rnpairs + -- @usage + -- for i,v in npairs {"one", nil, "three"} do ... end + npairs = X ("npairs (table)", base.npairs), + --- Enhance core `pairs` to respect `__pairs` even in Lua 5.1. -- @function pairs -- @tparam table t a table @@ -228,9 +241,24 @@ M = { -- @treturn function iterator function -- @treturn table *t* -- @treturn number `#t + 1` + -- @see ipairs + -- @see rnpairs -- @usage for i, v = ripairs (t) do ... end ripairs = X ("ripairs (table)", base.ripairs), + --- An iterator like npairs, but in reverse. + -- Apart from the order of the elments returned, this function follows + -- the same rules as @{npairs} for determining first and last elements. + -- @function rnpairs + -- @tparam table t a table + -- @treturn function iterator function + -- @treturn table t + -- @see npairs + -- @see ripairs + -- @usage + -- for i,v in rnpairs {"one", nil, "three"} do ... end + rnpairs = X ("rnpairs (table)", base.rnpairs), + --- Enhance core `tostring` to render table contents as a string. -- @function tostring -- @param x object to convert to string diff --git a/lib/std/base.lua b/lib/std/base.lua index aa76597..5f2139f 100644 --- a/lib/std/base.lua +++ b/lib/std/base.lua @@ -27,9 +27,9 @@ local dirsep = string.match (package.config, "^(%S+)\n") local loadstring = rawget (_G, "loadstring") or load -local function argerror (name, i, extramsg, level) +local function raise (bad, to, name, i, extramsg, level) level = level or 1 - local s = string.format ("bad argument #%d to '%s'", i, name) + local s = string.format ("bad %s #%d %s '%s'", bad, i, to, name) if extramsg ~= nil then s = s .. " (" .. extramsg .. ")" end @@ -37,6 +37,12 @@ local function argerror (name, i, extramsg, level) end +local function argerror (name, i, extramsg, level) + level = level or 1 + raise ("argument", "to", name, i, extramsg, level + 1) +end + + local function assert (expect, fmt, arg1, ...) local msg = (arg1 ~= nil) and string.format (fmt, arg1, ...) or fmt or "" return expect or error (msg, 2) @@ -103,21 +109,6 @@ local function unpack (t, i, j) end -local function collect (ifn, ...) - local argt = {...} - if not callable (ifn) then - ifn, argt = ipairs, {ifn, ...} - end - - local r = {} - for k, v in ifn (unpack (argt)) do - if v == nil then k, v = #r + 1, k end - r[k] = v - end - return r -end - - local function compare (l, m) local lenl, lenm = len (l), len (m) for i = 1, math.min (lenl, lenm) do @@ -271,6 +262,41 @@ local function merge (dest, src) end +local function npairs (t) + local i, n = 0, maxn (t) + return function (t) + i = i + 1 + if i <= n then return i, t[i] end + end, + t, i +end + + +local function collect (ifn, ...) + local argt, r = {...}, {} + if not callable (ifn) then + ifn, argt = npairs, {ifn, ...} + end + + -- How many return values from ifn? + local arity = 1 + for e, v in ifn (unpack (argt)) do + if v then arity, r = 2, {} break end + -- Build an arity-1 result table on first pass... + r[#r + 1] = e + end + + if arity == 2 then + -- ...oops, it was arity-2 all along, start again! + for k, v in ifn (unpack (argt)) do + r[k] = v + end + end + + return r +end + + local function prototype (o) return (getmetatable (o) or {})._type or io.type (o) or type (o) end @@ -346,6 +372,18 @@ local function ripairs (t) end +local function rnpairs (t) + local oob = maxn (t) + 1 + + return function (t, n) + n = n - 1 + if n > 0 then + return n, t[n] + end + end, t, oob +end + + local function split (s, sep) local r, patt = {} if sep == "" then @@ -373,7 +411,7 @@ local _require = require local function require (module, min, too_big, pattern) local m = _require (module) - local v = (m.version or m._VERSION or ""):match (pattern or "([%.%d]+)%D*$") + local v = tostring (m.version or m._VERSION or ""):match (pattern or "([%.%d]+)%D*$") if min then assert (vcompare (v, min) >= 0, "require '" .. module .. "' with at least version " .. min .. ", but found version " .. v) @@ -404,6 +442,7 @@ return { keysort = keysort, merge = merge, okeys = okeys, + raise = raise, -- std.lua -- assert = assert, @@ -412,8 +451,10 @@ return { ielems = ielems, ipairs = ipairs, ireverse = ireverse, + npairs = npairs, pairs = pairs, ripairs = ripairs, + rnpairs = rnpairs, require = require, tostring = tostring, diff --git a/lib/std/container.lua b/lib/std/container.lua index 2b682c3..3136d4e 100644 --- a/lib/std/container.lua +++ b/lib/std/container.lua @@ -203,7 +203,7 @@ local M = { if _DEBUG.argcheck then - local toomanyargmsg = debug.toomanyargmsg + local argerror, extramsg_toomany = debug.argerror, debug.extramsg_toomany M.__call = function (self, x, ...) local mt = getmetatable (self) @@ -216,7 +216,7 @@ if _DEBUG.argcheck then -- it just refers back to the object being called: `Container {"x"}. argcheck (name, 1, "table", x) if next (argt) then - error (toomanyargmsg (name, 1, 1 + maxn (argt)), 2) + argerror (name, 2, extramsg_toomany ("argument", 1, 1 + maxn (argt)), 2) end end diff --git a/lib/std/debug.lua b/lib/std/debug.lua index c6512cd..9657846 100644 --- a/lib/std/debug.lua +++ b/lib/std/debug.lua @@ -32,13 +32,14 @@ local debug_init = require "std.debug_init" local base = require "std.base" -local _DEBUG = debug_init._DEBUG -local argerror = base.argerror -local unpack = base.unpack -local split, tostring = base.split, base.tostring +local _DEBUG = debug_init._DEBUG +local argerror, raise = base.argerror, base.raise +local prototype, unpack = base.prototype, base.unpack +local copy, split, tostring = base.copy, base.split, base.tostring local insert, last, len, maxn = base.insert, base.last, base.len, base.maxn local ipairs, pairs = base.ipairs, base.pairs + local M @@ -71,11 +72,6 @@ local function DEPRECATED (version, name, extramsg, fn) end ---- Extend `debug.setfenv` to unwrap functables correctly. --- @tparam function|functable fn target function --- @tparam table env new function environment --- @treturn function *fn* - local _setfenv = debug.setfenv local function setfenv (fn, env) @@ -105,144 +101,214 @@ local function setfenv (fn, env) end ---- Extend `debug.getfenv` to unwrap functables correctly. --- @tparam int|function|functable fn target function, or stack level --- @treturn table environment of *fn* -local getfenv = rawget (_G, "getfenv") or function (fn) +local _getfenv = rawget (_G, "getfenv") + +local getfenv = function (fn) + fn = fn or 1 + -- Unwrap functable: if type (fn) == "table" then fn = fn.call or (getmetatable (fn) or {}).__call - elseif type (fn) == "number" then - fn = debug.getinfo (fn + 1, "f").func end - local name, env - local up = 0 - repeat - up = up + 1 - name, env = debug.getupvalue (fn, up) - until name == '_ENV' or name == nil - return env + if _getfenv then + if type (fn) == "number" then fn = fn + 1 end + + -- Stack frame count is critical here, so ensure we don't optimise one + -- away in LuaJIT... + return _getfenv (fn), nil + + else + if type (fn) == "number" then + fn = debug.getinfo (fn + 1, "f").func + end + + local name, env + local up = 0 + repeat + up = up + 1 + name, env = debug.getupvalue (fn, up) + until name == '_ENV' or name == nil + return env + end +end + + +local function resulterror (name, i, extramsg, level) + level = level or 1 + raise ("result", "from", name, i, extramsg, level + 1) end -local function toomanymsg (bad, to, name, expect, actual) - local s = "bad %s #%d %s '%s' (no more than %d %s%s expected, got %d)" - return s:format (bad, expect + 1, to, name, expect, bad, expect == 1 and "" or "s", actual) +local function extramsg_toomany (bad, expected, actual) + local s = "no more than %d %s%s expected, got %d" + return s:format (expected, bad, expected == 1 and "" or "s", actual) end -local argcheck, argscheck -- forward declarations +--- Strip trailing ellipsis from final argument if any, storing maximum +-- number of values that can be matched directly in `t.maxvalues`. +-- @tparam table t table to act on +-- @string v element added to *t*, to match against ... suffix +-- @treturn table *t* with ellipsis stripped and maxvalues field set +local function markdots (t, v) + return (v:gsub ("%.%.%.$", function () t.dots = true return "" end)) +end -if _DEBUG.argcheck then - local copy, prototype = base.copy, base.prototype +--- Calculate permutations of type lists with and without [optionals]. +-- @tparam table t a list of expected types by argument position +-- @treturn table set of possible type lists +local function permute (t) + if t[#t] then t[#t] = t[#t]:gsub ("%]%.%.%.$", "...]") end + + local p = {{}} + for i, v in ipairs (t) do + local optional = v:match "%[(.+)%]" - local function resulterror (name, i, extramsg, level) - level = level or 1 - local s = string.format ("bad result #%d from '%s'", i, name) - if extramsg ~= nil then - s = s .. " (" .. extramsg .. ")" + if optional == nil then + -- Append non-optional type-spec to each permutation. + for b = 1, #p do + insert (p[b], markdots (p[b], v)) + end + else + -- Duplicate all existing permutations, and add optional type-spec + -- to the unduplicated permutations. + local o = #p + for b = 1, o do + p[b + o] = copy (p[b]) + insert (p[b], markdots (p[b], optional)) + end end - error (s, level + 1) end + return p +end - --- Concatenate a table of strings using ", " and " or " delimiters. - -- @tparam table alternatives a table of strings - -- @treturn string string of elements from alternatives delimited by ", " - -- and " or " - local function concat (alternatives) - if len (alternatives) > 1 then - local t = copy (alternatives) - local top = table.remove (t) - t[#t] = t[#t] .. " or " .. top - alternatives = t + +local function typesplit (types) + if type (types) == "string" then + types = split (types:gsub ("%s+or%s+", "|"), "%s*|%s*") + end + local r, seen, add_nil = {}, {}, false + for _, v in ipairs (types) do + local m = v:match "^%?(.+)$" + if m then + add_nil, v = true, m + end + if not seen[v] then + r[#r + 1] = v + seen[v] = true end - return table.concat (alternatives, ", ") end + if add_nil then + r[#r + 1] = "nil" + end + return r +end - --- Normalize a list of type names. - -- @tparam table t list of type names, leading "?" as required - -- @treturn table a new list with "?" stripped, "nil" appended if so, - -- and with duplicates stripped. - local function normalize (t) - local r, seen, add_nil = {}, {}, false - for _, v in ipairs (t) do - local m = v:match "^%?(.+)$" - if m then - add_nil, v = true, m - end - if not seen[v] then - r[#r + 1] = v - seen[v] = true +local function projectuniq (fkey, tt) + -- project + local t = {} + for _, u in ipairs (tt) do + t[#t + 1] = u[fkey] + end + + -- split and remove duplicates + local r, s = {}, {} + for _, e in ipairs (t) do + for _, v in ipairs (typesplit (e)) do + if s[v] == nil then + r[#r + 1], s[v] = v, true end end - if add_nil then - r[#r + 1] = "nil" - end - return r end + return r +end - --- Ordered iterator for integer keyed values. - -- Like ipairs, but does not stop at the first nil value. - -- @tparam table t a table - -- @treturn function iterator function - -- @treturn table t - -- @usage - -- for i,v in argpairs {"one", nil, "three"} do print (i, v) end - local function argpairs (t) - local i, max = 0, 0 - for k in pairs (t) do - if type (k) == "number" and k > max then max = k end - end - return function (t) - i = i + 1 - if i <= max then return i, t[i] end - end, - t, true +local function parsetypes (types) + local r, permutations = {}, permute (types) + for i = 1, #permutations[1] do + r[i] = projectuniq (i, permutations) end + r.dots = permutations[1].dots + return r +end - --- Strip trailing ellipsis from final argument if any, storing maximum - -- number of values that can be matched directly in `t.maxvalues`. - -- @tparam table t table to act on - -- @string v element added to *t*, to match against ... suffix - -- @treturn table *t* with ellipsis stripped and maxvalues field set - local function markdots (t, v) - return (v:gsub ("%.%.%.$", function () t.dots = true return "" end)) +--- Concatenate a table of strings using ", " and " or " delimiters. +-- @tparam table alternatives a table of strings +-- @treturn string string of elements from alternatives delimited by ", " +-- and " or " +local function concat (alternatives) + if len (alternatives) > 1 then + local t = copy (alternatives) + local top = table.remove (t) + t[#t] = t[#t] .. " or " .. top + alternatives = t end + return table.concat (alternatives, ", ") +end - --- Calculate permutations of type lists with and without [optionals]. - -- @tparam table t a list of expected types by argument position - -- @treturn table set of possible type lists - local function permute (t) - if t[#t] then t[#t] = t[#t]:gsub ("%]%.%.%.$", "...]") end +local function extramsg_mismatch (expectedtypes, actual, index) + local actualtype = prototype (actual) + + -- Tidy up actual type for display. + if actualtype == "nil" then + actualtype = "no value" + elseif actualtype == "string" and actual:sub (1, 1) == ":" then + actualtype = actual + elseif type (actual) == "table" and next (actual) == nil then + local matchstr = "," .. table.concat (expectedtypes, ",") .. "," + if actualtype == "table" and matchstr == ",#list," then + actualtype = "empty list" + elseif actualtype == "table" or matchstr:match ",#" then + actualtype = "empty " .. actualtype + end + end - local p = {{}} - for i, v in ipairs (t) do - local optional = v:match "%[(.+)%]" + if index then + actualtype = actualtype .. " at index " .. tostring (index) + end - if optional == nil then - -- Append non-optional type-spec to each permutation. - for b = 1, #p do - insert (p[b], markdots (p[b], v)) - end + -- Tidy up expected types for display. + local expectedstr = expectedtypes + if type (expectedtypes) == "table" then + local t = {} + for i, v in ipairs (expectedtypes) do + if v == "func" then + t[i] = "function" + elseif v == "bool" then + t[i] = "boolean" + elseif v == "any" then + t[i] = "any value" + elseif v == "file" then + t[i] = "FILE*" + elseif not index then + t[i] = v:match "(%S+) of %S+" or v else - -- Duplicate all existing permutations, and add optional type-spec - -- to the unduplicated permutations. - local o = #p - for b = 1, o do - p[b + o] = copy (p[b]) - insert (p[b], markdots (p[b], optional)) - end + t[i] = v end end - return p + expectedstr = (concat (t) .. " expected"): + gsub ("#table", "non-empty table"): + gsub ("#list", "non-empty list"): + gsub ("(%S+ of [^,%s]-)s? ", "%1s "): + gsub ("(%S+ of [^,%s]-)s?,", "%1s,"): + gsub ("(s, [^,%s]-)s? ", "%1s "): + gsub ("(s, [^,%s]-)s?,", "%1s,"): + gsub ("(of .-)s? or ([^,%s]-)s? ", "%1s or %2s ") end + return expectedstr .. ", got " .. actualtype +end + + +local argcheck, argscheck -- forward declarations + +if _DEBUG.argcheck then --- Return index of the first mismatch between types and values, or `nil`. -- @tparam table typelist a list of expected types @@ -261,60 +327,6 @@ if _DEBUG.argcheck then end - --- Format a type mismatch error. - -- @tparam table expectedtypes a table of matchable types - -- @string actual the actual argument to match with - -- @number[opt] index erroring container element index - -- @treturn string formatted *extramsg* for this mismatch for @{argerror} - local function formaterror (expectedtypes, actual, index) - local actualtype = prototype (actual) - - -- Tidy up actual type for display. - if actualtype == "nil" then - actualtype = "no value" - elseif actualtype == "string" and actual:sub (1, 1) == ":" then - actualtype = actual - elseif type (actual) == "table" and next (actual) == nil then - local matchstr = "," .. table.concat (expectedtypes, ",") .. "," - if actualtype == "table" and matchstr == ",#list," then - actualtype = "empty list" - elseif actualtype == "table" or matchstr:match ",#" then - actualtype = "empty " .. actualtype - end - end - - if index then - actualtype = actualtype .. " at index " .. tostring (index) - end - - -- Tidy up expected types for display. - local expectedstr = expectedtypes - if type (expectedtypes) == "table" then - local t = {} - for i, v in ipairs (expectedtypes) do - if v == "func" then - t[i] = "function" - elseif v == "any" then - t[i] = "any value" - elseif v == "file" then - t[i] = "FILE*" - elseif not index then - t[i] = v:match "(%S+) of %S+" or v - else - t[i] = v - end - end - expectedstr = concat (t): - gsub ("#table", "non-empty table"): - gsub ("#list", "non-empty list"): - gsub ("(%S+ of %S+)", "%1s"): - gsub ("(%S+ of %S+)ss", "%1s") - end - - return expectedstr .. " expected, got " .. actualtype - end - - --- Compare *check* against type of *actual* -- @string check extended type name expected -- @param actual object being typechecked @@ -330,6 +342,8 @@ if _DEBUG.argcheck then local actualtype = type (actual) if check == actualtype then return true + elseif check == "bool" and actualtype == "boolean" then + return true elseif check == "#table" then if actualtype == "table" and next (actual) then return true @@ -375,33 +389,13 @@ if _DEBUG.argcheck then end - local function projectuniq (fkey, tt) - -- project - local t = {} - for _, u in ipairs (tt) do - t[#t + 1] = u[fkey] - end - - -- split and remove duplicates - local r, s = {}, {} - for _, e in ipairs (t) do - for _, v in ipairs (normalize (split (e, "|"))) do - if s[v] == nil then - r[#r + 1], s[v] = v, true - end - end - end - return r - end - - local function empty (t) return not next (t) end -- Pattern to normalize: [types...] to [types]... local last_pat = "^%[([^%]%.]+)%]?(%.*)%]?" --- Diagnose mismatches between *valuelist* and type *permutations*. - -- @tparam table valuelist normalized list of actual values to be checked + -- @tparam table valuelist list of actual values to be checked -- @tparam table argt table of precalculated values and handler functiens local function diagnose (valuelist, argt) local permutations = argt.permutations @@ -421,7 +415,7 @@ if _DEBUG.argcheck then -- Report an error for all possible types at bestmismatch index. local i, expected = bestmismatch if t.dots and i > #t then - expected = normalize (split (t[#t], "|")) + expected = typesplit (t[#t]) else expected = projectuniq (i, permutations) end @@ -436,7 +430,7 @@ if _DEBUG.argcheck then if contents and type (valuelist[i]) == "table" then for k, v in pairs (valuelist[i]) do if not checktype (contents, v) then - argt.badtype (i, formaterror (expected, v, k), 3) + argt.badtype (i, extramsg_mismatch (expected, v, k), 3) end end end @@ -444,20 +438,20 @@ if _DEBUG.argcheck then -- Otherwise the argument type itself was mismatched. if t.dots or #t >= maxn (valuelist) then - argt.badtype (i, formaterror (expected, valuelist[i]), 3) + argt.badtype (i, extramsg_mismatch (expected, valuelist[i]), 3) end end local n, t = maxn (valuelist), t or permutations[1] if t and t.dots == nil and n > #t then - error (argt.badcount (#t, n), 3) + argt.badtype (#t + 1, extramsg_toomany (argt.bad, #t, n), 3) end end function argcheck (name, i, expected, actual, level) level = level or 2 - expected = normalize (split (expected, "|")) + expected = typesplit (expected) -- Check actual has one of the types from expected local ok = false @@ -472,7 +466,7 @@ if _DEBUG.argcheck then if ok and contents and type (actual) == "table" then for k, v in pairs (actual) do if not checktype (contents, v) then - argerror (name, i, formaterror (expected, v, k), level + 1) + argerror (name, i, extramsg_mismatch (expected, v, k), level + 1) end end end @@ -480,13 +474,13 @@ if _DEBUG.argcheck then end if not ok then - argerror (name, i, formaterror (expected, actual), level + 1) + argerror (name, i, extramsg_mismatch (expected, actual), level + 1) end end -- Pattern to extract: fname ([types]?[, types]*) - local args_pat = "([%w_][%.%d%w_]*)%s+%(%s*(.*)%s*%)" + local args_pat = "^%s*([%w_][%.%:%d%w_]*)%s*%(%s*(.*)%s*%)" function argscheck (decl, inner) -- Parse "fname (argtype, argtype, argtype...)". @@ -494,17 +488,18 @@ if _DEBUG.argcheck then if argtypes == "" then argtypes = {} elseif argtypes then - argtypes = split (argtypes, ",%s*") + argtypes = split (argtypes, "%s*,%s*") else - fname = decl:match "([%w_][%.%d%w_]*)" + fname = decl:match "^%s*([%w_][%.%:%d%w_]*)" end -- Precalculate vtables once to make multiple calls faster. local input, output = { - badcount = function (...) - return toomanymsg ("argument", "to", fname, ...) - end, - badtype = function (...) argerror (fname, ...) end, + bad = "argument", + badtype = function (i, extramsg, level) + level = level or 1 + argerror (fname, i, extramsg, level + 1) + end, permutations = permute (argtypes), } @@ -524,17 +519,23 @@ if _DEBUG.argcheck then table.sort (permutations, function (a, b) return #a > #b end) output = { - badcount = function (...) - return toomanymsg ("result", "from", fname, ...) - end, - badtype = function (...) resulterror (fname, ...) end, + bad = "result", + badtype = function (i, extramsg, level) + level = level or 1 + resulterror (fname, i, extramsg, level + 1) + end, permutations = permutations, } end return function (...) + local argt = {...} + + -- Don't check type of self if fname has a ':' in it. + if fname:find (":") then table.remove (argt, 1) end + -- Diagnose bad inputs. - diagnose ({...}, input) + diagnose (argt, input) -- Propagate outer environment to inner function. local x = math.max -- ??? getfenv(1) fails if we remove this ??? @@ -698,6 +699,8 @@ M = { -- @int i argument number -- @string[opt] extramsg additional text to append to message inside parentheses -- @int[opt=1] level call stack level to blame for the error + -- @see resulterror + -- @see extramsg_mismatch -- @usage -- local function slurp (file) -- local h, err = input_handle (file) @@ -713,12 +716,17 @@ M = { -- -- format = argscheck ("string.format (string, ?any...)", string.format) -- + -- A colon in the function name indicates that the argument type list does + -- not have a type for `self`: + -- + -- format = argscheck ("string:format (?any...)", string.format) + -- -- If an argument can be omitted entirely, then put its type specification -- in square brackets: -- -- insert = argscheck ("table.insert (table, [int], ?any)", table.insert) -- - -- Similarly returt types can be checked with the same list syntax as + -- Similarly return types can be checked with the same list syntax as -- arguments: -- -- len = argscheck ("string.len (string) => int", string.len) @@ -738,6 +746,69 @@ M = { -- end) argscheck = argscheck, + --- Format a type mismatch error. + -- @function extramsg_mismatch + -- @string expected a pipe delimited list of matchable types + -- @param actual the actual argument to match with + -- @number[opt] index erroring container element index + -- @treturn string formatted *extramsg* for this mismatch for @{argerror} + -- @see argerror + -- @see resulterror + -- @usage + -- if fmt ~= nil and type (fmt) ~= "string" then + -- argerror ("format", 1, extramsg_mismatch ("?string", fmt)) + -- end + extramsg_mismatch = function (expected, actual, index) + return extramsg_mismatch (typesplit (expected), actual, index) + end, + + --- Format a too many things error. + -- @string bad the thing there are too many of + -- @int expected maximum number of *bad* things expected + -- @int actual actual number of *bad* things that triggered the error + -- @see argerror + -- @see resulterror + -- @see extramsg_mismatch + -- @usage + -- if maxn (argt) > 7 then + -- argerror ("sevenses", 8, extramsg_toomany ("argument", 7, maxn (argt))) + -- end + extramsg_toomany = extramsg_toomany, + + --- Extend `debug.getfenv` to unwrap functables correctly. + -- @tparam int|function|functable fn target function, or stack level + -- @treturn table environment of *fn* + getfenv = getfenv, + + --- Compact permutation list into a list of valid types at each argument. + -- Eliminate bracketed types by combining all valid types at each position + -- for all permutations of *typelist*. + -- @function parsetypes + -- @tparam list types a normalized list of type names + -- @treturn list valid types for each positional parameter + parsetypes = parsetypes, + + --- Raise a bad result error. + -- Like @{argerror} for bad results. This function does not + -- return. The `level` argument behaves just like the core `error` + -- function. + -- @string name function to callout in error message + -- @int i argument number + -- @string[opt] extramsg additional text to append to message inside parentheses + -- @int[opt=1] level call stack level to blame for the error + -- @usage + -- local function slurp (file) + -- local h, err = input_handle (file) + -- if h == nil then argerror ("std.io.slurp", 1, err, 2) end + -- ... + resulterror = resulterror, + + --- Extend `debug.setfenv` to unwrap functables correctly. + -- @tparam function|functable fn target function + -- @tparam table env new function environment + -- @treturn function *fn* + setfenv = setfenv, + --- Print a debugging message to `io.stderr`. -- Display arguments passed through `std.tostring` and separated by tab -- characters when `_DEBUG` is `true` and *n* is 1 or less; or `_DEBUG.level` @@ -752,19 +823,6 @@ M = { -- say (2, "_DEBUG table contents:", _DEBUG) say = say, - --- Format a standard "too many arguments" error message. - -- @fixme remove this wart! - -- @function toomanyargmsg - -- @string name function name - -- @number expect maximum number of arguments accepted - -- @number actual number of arguments received - -- @treturn string standard "too many arguments" error message - -- @usage - -- if table.maxn {...} > 1 then - -- io.stderr:write ("module.fname", 7, table.maxn {...}) - -- ... - toomanyargmsg = function (...) return toomanymsg ("argument", "to", ...) end, - --- Trace function calls. -- Use as debug.sethook (trace, "cr"), which is done automatically -- when `_DEBUG.call` is set. @@ -776,6 +834,12 @@ M = { -- local debug = require "std.debug" trace = trace, + --- Split a typespec string into a table of normalized type names. + -- @tparam string|table either `"?bool|:nometa"` or `{"boolean", ":nometa"}` + -- @treturn table a new list with duplicates removed and leading "?"s + -- replaced by a "nil" element + typesplit = typesplit, + -- Private: _setdebug = function (t) @@ -803,6 +867,21 @@ local metatable = { end, } + + +--[[ =========== ]]-- +--[[ Deprecated. ]]-- +--[[ =========== ]]-- + + +M.toomanyargmsg = DEPRECATED ("41.2.0", "debug.toomanyargmsg", + "use 'debug.extramsg_toomany' instead", + function (name, expect, actual) + local s = "bad argument #%d to '%s' (no more than %d argument%s expected, got %d)" + return s:format (expect + 1, name, expect, expect == 1 and "" or "s", actual) + end) + + return setmetatable (M, metatable) diff --git a/lib/std/functional.lua b/lib/std/functional.lua index c9ce357..b20a8bc 100644 --- a/lib/std/functional.lua +++ b/lib/std/functional.lua @@ -11,16 +11,17 @@ local base = require "std.base" local debug = require "std.debug" -local ielems, ipairs, ireverse, len, pairs, unpack = - base.ielems, base.ipairs, base.ireverse, base.len, base.pairs, base.unpack -local callable, reduce = base.callable, base.reduce +local ielems, ipairs, ireverse, npairs, pairs = + base.ielems, base.ipairs, base.ireverse, base.npairs, base.pairs +local callable, copy, len, reduce, unpack = + base.callable, base.copy, base.len, base.reduce, base.unpack local loadstring = loadstring or load local function bind (fn, ...) - local argt = {...} - if type (argt[1]) == "table" and argt[2] == nil then - argt = argt[1] + local bound = {...} + if type (bound[1]) == "table" and bound[2] == nil then + bound = bound[1] else io.stderr:write (debug.DEPRECATIONMSG ("39", "multi-argument 'std.functional.bind'", @@ -28,17 +29,13 @@ local function bind (fn, ...) end return function (...) - local arg = {} - for i, v in pairs (argt) do - arg[i] = v - end - local i = 1 - for _, v in ipairs {...} do - while arg[i] ~= nil do i = i + 1 end - arg[i] = v - end - return fn (unpack (arg)) - end + local argt, i = copy (bound), 1 + for _, v in npairs {...} do + while argt[i] ~= nil do i = i + 1 end + argt[i], i = v, i + 1 + end + return fn (unpack (argt)) + end end @@ -52,19 +49,15 @@ end local function compose (...) - local arg = {...} - local fns, n = arg, #arg - for i = 1, n do - local f = fns[i] - end + local fns = {...} return function (...) - local arg = {...} - for i = 1, n do - arg = {fns[i] (unpack (arg))} - end - return unpack (arg) - end + local argt = {...} + for _, fn in npairs (fns) do + argt = {fn (unpack (argt))} + end + return unpack (argt) + end end @@ -94,26 +87,44 @@ end local function filter (pfn, ifn, ...) - local argt = {...} + local argt, r = {...}, {} if not callable (ifn) then ifn, argt = pairs, {ifn, ...} end local nextfn, state, k = ifn (unpack (argt)) + local t = {nextfn (state, k)} -- table of iteration 1 + local arity = #t -- How many return values from ifn? + + if arity == 1 then + local v = t[1] + while v ~= nil do -- until iterator returns nil + if pfn (unpack (t)) then -- pass all iterator results to p + r[#r + 1] = v + end + + t = {nextfn (state, v)} -- maintain loop invariant + v = t[1] - local r = {} -- new results table - while t[1] ~= nil do -- until iterator returns nil - k = t[1] - if pfn (unpack (t)) then -- pass all iterator results to p - if t[2] ~= nil then - r[k] = t[2] -- k,v = t[1],t[2] - else - r[#r + 1] = k -- k,v = #r + 1,t[1] + if #t > 1 then -- unless we discover arity is not 1 after all + arity, r = #t, {} break end end - t = {nextfn (state, k)} -- maintain loop invariant end + + if arity > 1 then + -- No need to start over here, because either: + -- (i) arity was never 1, and the original value of t is correct + -- (ii) arity used to be 1, but we only consumed nil values, so the + -- current t with arity > 1 is the correct next value to use + while t[1] ~= nil do + local k = t[1] + if pfn (unpack (t)) then r[k] = t[2] end + t = {nextfn (state, k)} + end + end + return r end @@ -201,7 +212,7 @@ end, id) local function map (mapfn, ifn, ...) - local argt = {...} + local argt, r = {...}, {} if not callable (ifn) or not next (argt) then ifn, argt = pairs, {ifn, ...} end @@ -209,15 +220,26 @@ local function map (mapfn, ifn, ...) local nextfn, state, k = ifn (unpack (argt)) local mapargs = {nextfn (state, k)} - local r = {} + local arity = 1 while mapargs[1] ~= nil do - k = mapargs[1] local d, v = mapfn (unpack (mapargs)) - if v == nil then d, v = #r + 1, d end if v ~= nil then - r[d] = v + arity, r = 2, {} break + end + r[#r + 1] = d + mapargs = {nextfn (state, mapargs[1])} + end + + if arity > 1 then + -- No need to start over here, because either: + -- (i) arity was never 1, and the original value of mapargs is correct + -- (ii) arity used to be 1, but we only consumed nil values, so the + -- current mapargs with arity > 1 is the correct next value to use + while mapargs[1] ~= nil do + local k, v = mapfn (unpack (mapargs)) + r[k] = v + mapargs = {nextfn (state, mapargs[1])} end - mapargs = {nextfn (state, k)} end return r end @@ -275,7 +297,7 @@ local M = { -- @return `true` if *x* can be called, otherwise `false` -- @usage -- if callable (functable) then functable (args) end - callable = X ("callable (any)", callable), + callable = X ("callable (?any)", callable), --- A rudimentary case statement. -- Match *with* against keys in *branches* table. @@ -299,7 +321,7 @@ local M = { --- Collect the results of an iterator. -- @function collect - -- @func[opt=std.ipairs] ifn iterator function + -- @func[opt=std.npairs] ifn iterator function -- @param ... *ifn* arguments -- @treturn table of results from running *ifn* on *args* -- @see filter diff --git a/lib/std/io.lua b/lib/std/io.lua index 85ac7aa..056d7cc 100644 --- a/lib/std/io.lua +++ b/lib/std/io.lua @@ -149,7 +149,7 @@ M = { -- @see catfile -- @usage dirpath = catdir ("", "absolute", "directory") catdir = X ("catdir (string...)", function (...) - return table.concat ({...}, dirsep):gsub("^$", dirsep) + return (table.concat ({...}, dirsep):gsub("^$", dirsep)) end), --- Concatenate one or more directories and a filename into a path. @@ -180,7 +180,7 @@ M = { -- truncated -- @usage dir = dirname "/base/subdir/filename" dirname = X ("dirname (string)", function (path) - return path:gsub (catfile ("", "[^", "]*$"), "") + return (path:gsub (catfile ("", "[^", "]*$"), "")) end), --- Overwrite core `io` methods with `std` enhanced versions. diff --git a/lib/std/list.lua b/lib/std/list.lua index fc169e3..ad04c06 100644 --- a/lib/std/list.lua +++ b/lib/std/list.lua @@ -438,9 +438,9 @@ M.relems = DEPRECATED ("41", "'std.list.relems'", m.relems = DEPRECATED ("41", "'std.list:relems'", relems) M.reverse = DEPRECATED ("41", "'std.list.reverse'", - "use 'std.ireverse' instead", reverse) + "compose 'std.list' and 'std.ireverse' instead", reverse) m.reverse = DEPRECATED ("41", "'std.list:reverse'", - "use 'std.ireverse' instead", reverse) + "compose 'std.list' and 'std.ireverse' instead", reverse) M.shape = DEPRECATED ("41", "'std.list.shape'", "use 'std.table.shape' instead", shape) diff --git a/m4/ax_lua.m4 b/m4/ax_lua.m4 index d1545dd..8da0a07 100644 --- a/m4/ax_lua.m4 +++ b/m4/ax_lua.m4 @@ -51,7 +51,7 @@ # # If MINIMUM-VERSION is supplied, then only Lua interpreters with a # version number greater or equal to MINIMUM-VERSION will be accepted. If -# TOO-BIG- VERSION is also supplied, then only Lua interpreters with a +# TOO-BIG-VERSION is also supplied, then only Lua interpreters with a # version number greater or equal to MINIMUM-VERSION and less than # TOO-BIG-VERSION will be accepted. # @@ -66,12 +66,13 @@ # luaexecdir Directory to install Lua modules. # pkgluaexecdir $luaexecdir/$PACKAGE # -# These paths a found based on $prefix, $exec_prefix, Lua's package.path, -# and package.cpath. The first path of package.path beginning with $prefix -# is selected as luadir. The first path of package.cpath beginning with -# $exec_prefix is used as luaexecdir. This should work on all reasonable -# Lua installations. If a path cannot be determined, a default path is -# used. Of course, the user can override these later when invoking make. +# These paths are found based on $prefix, $exec_prefix, Lua's +# package.path, and package.cpath. The first path of package.path +# beginning with $prefix is selected as luadir. The first path of +# package.cpath beginning with $exec_prefix is used as luaexecdir. This +# should work on all reasonable Lua installations. If a path cannot be +# determined, a default path is used. Of course, the user can override +# these later when invoking make. # # luadir Default: $prefix/share/lua/$LUA_VERSION # luaexecdir Default: $exec_prefix/lib/lua/$LUA_VERSION @@ -151,8 +152,8 @@ # # LICENSE # -# Copyright (c) 2014 Reuben Thomas -# Copyright (c) 2013 Tim Perkins +# Copyright (c) 2015 Reuben Thomas +# Copyright (c) 2014 Tim Perkins # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -180,7 +181,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 28 +#serial 38 dnl ========================================================================= dnl AX_PROG_LUA([MINIMUM-VERSION], [TOO-BIG-VERSION], @@ -188,6 +189,10 @@ dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_PROG_LUA], [ + dnl Check for required tools. + AC_REQUIRE([AC_PROG_GREP]) + AC_REQUIRE([AC_PROG_SED]) + dnl Make LUA a precious variable. AC_ARG_VAR([LUA], [The Lua interpreter, e.g. /usr/bin/lua5.1]) @@ -201,12 +206,14 @@ AC_DEFUN([AX_PROG_LUA], [AC_PATH_PROGS([LUA], [_AX_LUA_INTERPRETER_LIST], [:])]) ax_display_LUA='lua' - dnl At least check if this is a Lua interpreter. - AC_MSG_CHECKING([if $LUA is a Lua interpreter]) - _AX_LUA_CHK_IS_INTRP([$LUA], - [AC_MSG_RESULT([yes])], - [ AC_MSG_RESULT([no]) - AC_MSG_ERROR([not a Lua interpreter]) + AS_IF([test "x$LUA" != 'x:'], + [ dnl At least check if this is a Lua interpreter. + AC_MSG_CHECKING([if $LUA is a Lua interpreter]) + _AX_LUA_CHK_IS_INTRP([$LUA], + [AC_MSG_RESULT([yes])], + [ AC_MSG_RESULT([no]) + AC_MSG_ERROR([not a Lua interpreter]) + ]) ]) ], [ dnl A version check is needed. @@ -254,18 +261,26 @@ AC_DEFUN([AX_PROG_LUA], m4_default([$4], [AC_MSG_ERROR([cannot find suitable Lua interpreter])]) ], [ dnl Query Lua for its version number. - AC_CACHE_CHECK([for $ax_display_LUA version], [ax_cv_lua_version], - [ ax_cv_lua_version=`$LUA -e 'print(_VERSION:match "(%d+%.%d+)")'` ]) + AC_CACHE_CHECK([for $ax_display_LUA version], + [ax_cv_lua_version], + [ dnl Get the interpreter version in X.Y format. This should work for + dnl interpreters version 5.0 and beyond. + ax_cv_lua_version=[`$LUA -e ' + -- return a version number in X.Y format + local _, _, ver = string.find(_VERSION, "^Lua (%d+%.%d+)") + print(ver)'`] + ]) AS_IF([test "x$ax_cv_lua_version" = 'x'], [AC_MSG_ERROR([invalid Lua version number])]) AC_SUBST([LUA_VERSION], [$ax_cv_lua_version]) - AC_SUBST([LUA_SHORT_VERSION], [`echo "$LUA_VERSION" | sed 's|\.||'`]) + AC_SUBST([LUA_SHORT_VERSION], [`echo "$LUA_VERSION" | $SED 's|\.||'`]) dnl The following check is not supported: dnl At times (like when building shared libraries) you may want to know dnl which OS platform Lua thinks this is. - AC_CACHE_CHECK([for $ax_display_LUA platform], [ax_cv_lua_platform], - [ax_cv_lua_platform=`$LUA -e "print('unknown')"`]) + AC_CACHE_CHECK([for $ax_display_LUA platform], + [ax_cv_lua_platform], + [ax_cv_lua_platform=[`$LUA -e 'print("unknown")'`]]) AC_SUBST([LUA_PLATFORM], [$ax_cv_lua_platform]) dnl Use the values of $prefix and $exec_prefix for the corresponding @@ -290,12 +305,12 @@ AC_DEFUN([AX_PROG_LUA], ax_cv_lua_luadir="$LUA_PREFIX/share/lua/$LUA_VERSION" dnl Try to find a path with the prefix. - _AX_LUA_FND_PRFX_PTH([$LUA], [$ax_lua_prefix], [package.path]) + _AX_LUA_FND_PRFX_PTH([$LUA], [$ax_lua_prefix], [script]) AS_IF([test "x$ax_lua_prefixed_path" != 'x'], [ dnl Fix the prefix. - _ax_strip_prefix=`echo "$ax_lua_prefix" | sed 's|.|.|g'` + _ax_strip_prefix=`echo "$ax_lua_prefix" | $SED 's|.|.|g'` ax_cv_lua_luadir=`echo "$ax_lua_prefixed_path" | \ - sed "s,^$_ax_strip_prefix,$LUA_PREFIX,"` + $SED "s|^$_ax_strip_prefix|$LUA_PREFIX|"` ]) ]) AC_SUBST([luadir], [$ax_cv_lua_luadir]) @@ -317,12 +332,12 @@ AC_DEFUN([AX_PROG_LUA], dnl Try to find a path with the prefix. _AX_LUA_FND_PRFX_PTH([$LUA], - [$ax_lua_exec_prefix], [package.cpath]) + [$ax_lua_exec_prefix], [module]) AS_IF([test "x$ax_lua_prefixed_path" != 'x'], [ dnl Fix the prefix. - _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | sed 's|.|.|g'` + _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | $SED 's|.|.|g'` ax_cv_lua_luaexecdir=`echo "$ax_lua_prefixed_path" | \ - sed "s,^$_ax_strip_prefix,$LUA_EXEC_PREFIX,"` + $SED "s|^$_ax_strip_prefix|$LUA_EXEC_PREFIX|"` ]) ]) AC_SUBST([luaexecdir], [$ax_cv_lua_luaexecdir]) @@ -336,7 +351,7 @@ AC_DEFUN([AX_PROG_LUA], dnl AX_WITH_LUA is now the same thing as AX_PROG_LUA. AC_DEFUN([AX_WITH_LUA], [ - AC_MSG_WARN([[$0 is deprecated, please use AX_PROG_LUA]]) + AC_MSG_WARN([[$0 is deprecated, please use AX_PROG_LUA instead]]) AX_PROG_LUA ]) @@ -346,8 +361,19 @@ dnl _AX_LUA_CHK_IS_INTRP(PROG, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_IS_INTRP], [ - dnl Just print _VERSION because all Lua interpreters have this global. - AS_IF([$1 -e "print('Hello ' .. _VERSION .. '!')" >/dev/null 2>&1], + dnl A minimal Lua factorial to prove this is an interpreter. This should work + dnl for Lua interpreters version 5.0 and beyond. + _ax_lua_factorial=[`$1 2>/dev/null -e ' + -- a simple factorial + function fact (n) + if n == 0 then + return 1 + else + return n * fact(n-1) + end + end + print("fact(5) is " .. fact(5))'`] + AS_IF([test "$_ax_lua_factorial" = 'fact(5) is 120'], [$2], [$3]) ]) @@ -358,37 +384,70 @@ dnl [ACTION-IF-TRUE], [ACTION-IF-FALSE]) dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_VER], [ - AS_IF([$1 2>/dev/null -e ' - function norm (v) - i,j=v:match "(%d+)%.(%d+)" - if i then return 100 * tonumber (i) + tonumber (j) end - end - v, toobig=norm (_VERSION), norm "$3" or math.huge - os.exit ((v >= norm ("$2") and v < toobig) and 0 or 1)'], - [$4], [$5]) + dnl Check that the Lua version is within the bounds. Only the major and minor + dnl version numbers are considered. This should work for Lua interpreters + dnl version 5.0 and beyond. + _ax_lua_good_version=[`$1 -e ' + -- a script to compare versions + function verstr2num(verstr) + local _, _, majorver, minorver = string.find(verstr, "^(%d+)%.(%d+)") + if majorver and minorver then + return tonumber(majorver) * 100 + tonumber(minorver) + end + end + local minver = verstr2num("$2") + local _, _, trimver = string.find(_VERSION, "^Lua (.*)") + local ver = verstr2num(trimver) + local maxver = verstr2num("$3") or 1e9 + if minver <= ver and ver < maxver then + print("yes") + else + print("no") + end'`] + AS_IF([test "x$_ax_lua_good_version" = "xyes"], + [$4], [$5]) ]) dnl ========================================================================= -dnl _AX_LUA_FND_PRFX_PTH(PROG, PREFIX, LUA-PATH-VARIABLE) +dnl _AX_LUA_FND_PRFX_PTH(PROG, PREFIX, SCRIPT-OR-MODULE-DIR) dnl ========================================================================= AC_DEFUN([_AX_LUA_FND_PRFX_PTH], [ - dnl Invokes the Lua interpreter PROG to print the path variable - dnl LUA-PATH-VARIABLE, usually package.path or package.cpath. Paths are - dnl then matched against PREFIX. Then ax_lua_prefixed_path is set to the - dnl shortest sub path beginning with PREFIX up to the last directory - dnl that does not contain a '?', if any. - - ax_lua_prefixed_path=`$1 2>/dev/null -e ' - $3:gsub ("(@<:@^;@:>@+)", - function (p) - p = p:gsub ("%?.*$", ""):gsub ("/@<:@^/@:>@*$", "") - if p:match ("^$2") and (not shortest or #shortest > #p) then - shortest = p + dnl Get the script or module directory by querying the Lua interpreter, + dnl filtering on the given prefix, and selecting the shallowest path. If no + dnl path is found matching the prefix, the result will be an empty string. + dnl The third argument determines the type of search, it can be 'script' or + dnl 'module'. Supplying 'script' will perform the search with package.path + dnl and LUA_PATH, and supplying 'module' will search with package.cpath and + dnl LUA_CPATH. This is done for compatibility with Lua 5.0. + + ax_lua_prefixed_path=[`$1 -e ' + -- get the path based on search type + local searchtype = "$3" + local paths = "" + if searchtype == "script" then + paths = (package and package.path) or LUA_PATH + elseif searchtype == "module" then + paths = (package and package.cpath) or LUA_CPATH + end + -- search for the prefix + local prefix = "'$2'" + local minpath = "" + local mindepth = 1e9 + string.gsub(paths, "(@<:@^;@:>@+)", + function (path) + path = string.gsub(path, "%?.*$", "") + path = string.gsub(path, "/@<:@^/@:>@*$", "") + if string.find(path, prefix) then + local depth = string.len(string.gsub(path, "@<:@^/@:>@", "")) + if depth < mindepth then + minpath = path + mindepth = depth + end end end) - print (shortest or "")'` + print(minpath)'`] ]) @@ -409,9 +468,10 @@ AC_DEFUN([AX_LUA_HEADERS], AC_ARG_VAR([LUA_INCLUDE], [The Lua includes, e.g. -I/usr/include/lua5.1]) dnl Some default directories to search. - LUA_SHORT_VERSION=`echo "$LUA_VERSION" | sed 's|\.||'` + LUA_SHORT_VERSION=`echo "$LUA_VERSION" | $SED 's|\.||'` m4_define_default([_AX_LUA_INCLUDE_LIST], [ /usr/include/lua$LUA_VERSION \ + /usr/include/lua-$LUA_VERSION \ /usr/include/lua/$LUA_VERSION \ /usr/include/lua$LUA_SHORT_VERSION \ /usr/local/include/lua$LUA_VERSION \ @@ -453,16 +513,19 @@ AC_DEFUN([AX_LUA_HEADERS], done ]) - AS_IF([test "x$ac_cv_header_lua_h" = 'xyes' && test "x$cross_compiling" != 'xyes'], + AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], [ dnl Make a program to print LUA_VERSION defined in the header. - dnl TODO This probably shouldn't be a runtime test. - - AC_CACHE_CHECK([for Lua header version], - [ax_cv_lua_header_version], - [ _ax_lua_saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" - AC_RUN_IFELSE( - [ AC_LANG_SOURCE([[ + dnl TODO It would be really nice if we could do this without compiling a + dnl program, then it would work when cross compiling. But I'm not sure how + dnl to do this reliably. For now, assume versions match when cross compiling. + + AS_IF([test "x$cross_compiling" != 'xyes'], + [ AC_CACHE_CHECK([for Lua header version], + [ax_cv_lua_header_version], + [ _ax_lua_saved_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" + AC_RUN_IFELSE( + [ AC_LANG_SOURCE([[ #include #include #include @@ -472,27 +535,27 @@ int main(int argc, char ** argv) exit(EXIT_SUCCESS); } ]]) + ], + [ ax_cv_lua_header_version=`./conftest$EXEEXT p | \ + $SED -n "s|^Lua \(@<:@0-9@:>@\{1,\}\.@<:@0-9@:>@\{1,\}\).\{0,\}|\1|p"` + ], + [ax_cv_lua_header_version='unknown']) + CPPFLAGS=$_ax_lua_saved_cppflags + ]) + + dnl Compare this to the previously found LUA_VERSION. + AC_MSG_CHECKING([if Lua header version matches $LUA_VERSION]) + AS_IF([test "x$ax_cv_lua_header_version" = "x$LUA_VERSION"], + [ AC_MSG_RESULT([yes]) + ax_header_version_match='yes' ], - [ ax_cv_lua_header_version=`./conftest$EXEEXT p | \ - sed "s|^Lua \(.*\)|\1|" | \ - grep -E -o "^@<:@0-9@:>@+\.@<:@0-9@:>@+"` - ], - [ax_cv_lua_header_version='unknown']) - CPPFLAGS=$_ax_lua_saved_cppflags - ]) - - dnl Compare this to the previously found LUA_VERSION. - AC_MSG_CHECKING([if Lua header version matches $LUA_VERSION]) - AS_IF([test "x$ax_cv_lua_header_version" = "x$LUA_VERSION"], - [ AC_MSG_RESULT([yes]) - ax_header_version_match='yes' + [ AC_MSG_RESULT([no]) + ax_header_version_match='no' + ]) ], - [ AC_MSG_RESULT([no]) - ax_header_version_match='no' + [ AC_MSG_WARN([cross compiling so assuming header version number matches]) + ax_header_version_match='yes' ]) - ], - [ - ax_header_version_match='yes' ]) dnl Was LUA_INCLUDE specified? @@ -508,7 +571,7 @@ int main(int argc, char ** argv) dnl AX_LUA_HEADERS_VERSION no longer exists, use AX_LUA_HEADERS. AC_DEFUN([AX_LUA_HEADERS_VERSION], [ - AC_MSG_WARN([[$0 is deprecated, please use AX_LUA_HEADERS]]) + AC_MSG_WARN([[$0 is deprecated, please use AX_LUA_HEADERS instead]]) ]) @@ -564,14 +627,15 @@ AC_DEFUN([AX_LUA_LIBS], _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" AC_SEARCH_LIBS([lua_load], - [ lua$LUA_VERSION \ - lua$LUA_SHORT_VERSION \ - lua-$LUA_VERSION \ - lua-$LUA_SHORT_VERSION \ - lua], - [_ax_found_lua_libs='yes'], - [_ax_found_lua_libs='no'], - [$_ax_lua_extra_libs]) + [ lua$LUA_VERSION \ + lua$LUA_SHORT_VERSION \ + lua-$LUA_VERSION \ + lua-$LUA_SHORT_VERSION \ + lua \ + ], + [_ax_found_lua_libs='yes'], + [_ax_found_lua_libs='no'], + [$_ax_lua_extra_libs]) LIBS=$_ax_lua_saved_libs AS_IF([test "x$ac_cv_search_lua_load" != 'xno' && diff --git a/specs/debug_spec.yaml b/specs/debug_spec.yaml index 3ab069e..9a8757e 100644 --- a/specs/debug_spec.yaml +++ b/specs/debug_spec.yaml @@ -4,8 +4,9 @@ before: | global_table = "_G" extend_base = { "DEPRECATED", "DEPRECATIONMSG", "argcheck", "argerror", - "argscheck", "say", "toomanyargmsg", "trace", - "_setdebug" } + "argscheck", "extramsg_mismatch", "extramsg_toomany", + "getfenv", "parsetypes", "resulterror", "setfenv", "say", + "toomanyargmsg", "typesplit", "trace", "_setdebug" } M = require (this_module) @@ -131,6 +132,38 @@ specify std.debug: expect (luaproc (mkscript (2))).to_match_error "^%S+:5:.*deprecated" +- describe resulterror: + - before: | + function mkstack (level) + return string.format ([[ + _DEBUG = true -- line 1 + local debug = require "std.debug" -- line 2 + function ohnoes () -- line 3 + debug.resulterror ("ohnoes", 1, nil, %s) -- line 4 + end -- line 5 + function caller () -- line 6 + local r = ohnoes () -- line 7 + return "not a tail call" -- line 8 + end -- line 9 + caller () -- line 10 + ]], tostring (level)) + end + + f = M.resulterror + + - it blames the call site by default: | + expect (luaproc (mkstack ())).to_contain_error ":4: bad result" + - it honors optional call stack level reporting: | + expect (luaproc (mkstack (1))).to_contain_error ":4: bad result" + expect (luaproc (mkstack (2))).to_contain_error ":7: bad result" + - it reports the calling function name: + expect (f ('expect', 1)).to_raise "'expect'" + - it reports the argument number: | + expect (f ('expect', 12345)).to_raise "#12345" + - it reports extra message in parentheses: + expect (f ('expect', 1, "extramsg")).to_raise " (extramsg)" + + - describe argerror: - before: | function mkstack (level) @@ -241,18 +274,21 @@ specify std.debug: - context with primitives: - it diagnoses missing types: + expect (fn ("bool", nil)).to_raise "boolean expected, got no value" expect (fn ("boolean", nil)).to_raise "boolean expected, got no value" expect (fn ("file", nil)).to_raise "FILE* expected, got no value" expect (fn ("number", nil)).to_raise "number expected, got no value" expect (fn ("string", nil)).to_raise "string expected, got no value" expect (fn ("table", nil)).to_raise "table expected, got no value" - it diagnoses mismatched types: + expect (fn ("bool", {0})).to_raise "boolean expected, got table" expect (fn ("boolean", {0})).to_raise "boolean expected, got table" expect (fn ("file", {0})).to_raise "FILE* expected, got table" expect (fn ("number", {0})).to_raise "number expected, got table" expect (fn ("string", {0})).to_raise "string expected, got table" expect (fn ("table", false)).to_raise "table expected, got boolean" - it matches types: + expect (fn ("bool", true)).not_to_raise "any error" expect (fn ("boolean", true)).not_to_raise "any error" expect (fn ("file", io.stderr)).not_to_raise "any error" expect (fn ("number", 1)).not_to_raise "any error" @@ -283,10 +319,15 @@ specify std.debug: expect (fn (":foo", ":foo")).not_to_raise "any error" - context with callable types: - it diagnoses missing types: + expect (fn ("func", nil)).to_raise "function expected, got no value" expect (fn ("function", nil)).to_raise "function expected, got no value" - it diagnoses mismatched types: + expect (fn ("func", {0})).to_raise "function expected, got table" expect (fn ("function", {0})).to_raise "function expected, got table" - it matches types: + expect (fn ("func", function () end)).not_to_raise "any error" + expect (fn ("func", setmetatable ({}, {__call = function () end}))). + not_to_raise "any error" expect (fn ("function", function () end)).not_to_raise "any error" expect (fn ("function", setmetatable ({}, {__call = function () end}))). not_to_raise "any error" @@ -737,6 +778,21 @@ specify std.debug: expect (wrapped ("foo", 1, 2)).to_be "MAGIC" expect (wrapped ("foo", 1, 2, 5)).to_be "MAGIC" + - context when omitting self type: + - before: + me = { + wrapped = f ("me:inner (string)", mkmagic) + } + _, badarg, badresult = init (M, "", "me:inner") + - it diagnoses missing arguments: + expect (me:wrapped ()).to_raise (badarg (1, "string")) + - it diagnoses wrong argument types: + expect (me:wrapped (false)).to_raise (badarg (1, "string", "boolean")) + - it diagnoses too many arguments: + expect (me:wrapped ("foo", false)).to_raise (badarg (2)) + - it accepts correct argument types: + expect (me:wrapped ("foo")).to_be "MAGIC" + - context with too many args: - before: wrapped = f ("inner ([string], int)", mkmagic) @@ -933,6 +989,82 @@ specify std.debug: expect ({wrapped ("one", 2)}).to_equal {"one", 2} +- describe extramsg_mismatch: + - before: + f = M.extramsg_mismatch + + - it returns the expected types: + expect (f "nil").to_contain "nil expected, " + expect (f "bool").to_contain "boolean expected, " + expect (f "?bool").to_contain "boolean or nil expected, " + expect (f "string|table").to_contain "string or table expected, " + - it returns expected container types: + expect (f ("table of int", nil, 1)).to_contain "table of ints expected, " + expect (f ("table of int|bool", nil, 1)). + to_contain "table of ints or booleans expected, " + expect (f ("table of int|bool|string", nil, 1)). + to_contain "table of ints, booleans or strings expected, " + expect (f ("table of int|bool|string|table", nil, 1)). + to_contain "table of ints, booleans, strings or tables expected, " + - it returns the actual type: + expect (f ("int")).to_contain ", got no value" + expect (f ("int", false)).to_contain ", got boolean" + expect (f ("int", {})).to_contain ", got empty table" + - it returns table field type: + expect (f ("table of int", nil, 1)).to_contain ", got no value at index 1" + expect (f ("table of int", "two", 2)).to_contain ", got string at index 2" + expect (f ("table of int|bool", "five", 3)).to_contain ", got string at index 3" + + +- describe extramsg_toomany: + - before: + f = M.extramsg_toomany + + - it returns the expected thing: + expect (f ("mojo", 1, 2)).to_contain "no more than 1 mojo" + - it uses singular thing when 1 is expected: + expect (f ("argument", 1, 2)).to_contain "no more than 1 argument" + - it uses plural thing otherwise: + expect (f ("thing", 0, 3)).to_contain "no more than 0 things" + expect (f ("result", 2, 3)).to_contain "no more than 2 results" + - it returns the actual count: + expect (f ("bad", 0, 1)).to_contain ", got 1" + expect (f ("bad", 99, 999)).to_contain ", got 999" + + +- context function environments: + - before: + env = { + tostring = function (x) return '"' .. tostring (x) .. '"' end, + } + fn = function (x) return tostring (x) end + ft = setmetatable ({}, { __call = function (_, ...) return fn (...) end }) + + - describe getfenv: + - before: + f = M.getfenv + - it returns a table: + expect (type (f (fn))).to_be "table" + - it gets a function execution environment: + M.setfenv (fn, env) + expect (f (fn)).to_be (env) + - it understands functables: + M.setfenv (ft, env) + expect (f (ft)).to_be (env) + + - describe setfenv: + - before: + f = M.setfenv + - it returns the passed function: + expect (f (fn, env)).to_be (fn) + - it sets a function execution environment: + f (fn, env) + expect (fn (42)).to_be '"42"' + - it understands functables: + f (ft, env) + expect (fn (5)).to_be '"5"' + + - describe say: - before: | function mkwrap (k, v) diff --git a/specs/functional_spec.yaml b/specs/functional_spec.yaml index f4b8a27..619c251 100644 --- a/specs/functional_spec.yaml +++ b/specs/functional_spec.yaml @@ -57,6 +57,9 @@ specify std.functional: expect (f (div, {100}) (25)).to_be (4) - it supports out of order extra arguments: expect (f (op.pow, {[2] = 3}) (2)).to_be (8) + - it propagates nil arguments correctly: + expect ({f (M.id, {[2]="b", [4]="d"}) (nil, 3, 5, 6, nil)}). + to_equal {nil, "b", 3, "d", 5, 6, nil} - it supports the legacy api: expect (f (math.min) (2, 3, 4)).to_be (2) expect (f (math.min, 1, 0) (2, 3, 4)).to_be (0) @@ -84,6 +87,10 @@ specify std.functional: } do expect (f (v)).to_be (pcall (v, {}) and M.nop or nil) end + - it returns 'nil' for uncallable arguments: + expect (f ()).to_be (nil) + expect (f {}).to_be (nil) + expect (f "").to_be (nil) - describe case: - before: @@ -137,8 +144,10 @@ specify std.functional: - it collects a table of key:value iterator results: t = {"first", second="two", last=3} expect (f (pairs, t)).to_equal (t) - - it defaults to ipairs iteration: - expect (f {1, 2, [5]=5, a="b", c="d"}).to_equal {1, 2} + - it propagates nil arguments correctly: + expect (f {"a", nil, nil, "d", "e"}).to_equal {"a", [4]="d", [5]="e"} + - it defaults to npairs iteration: + expect (f {1, 2, [5]=5, a="b", c="d"}).to_equal {1, 2, [5]=5} - describe compose: @@ -150,6 +159,9 @@ specify std.functional: - it composes a single function correctly: expect (f (M.id) (1)).to_be (1) + - it propagates nil arguments correctly: + expect ({f (M.id) (1, nil, nil, 4)}).to_equal {1, nil, nil, 4} + expect ({f (M.id, M.id) (1, nil, nil, 4)}).to_equal {1, nil, nil, 4} - it composes functions in the correct order: expect (f (math.sin, math.cos) (1)). to_be (math.cos (math.sin (1))) @@ -226,7 +238,7 @@ specify std.functional: - describe filter: - before: elements = {"a", "b", "c", "d", "e"} - inverse = require "std.table".invert (elements) + inverse = {a=1, b=2, c=3, d=4, e=5} f = M.filter @@ -238,6 +250,9 @@ specify std.functional: - it iterates through element keys: expect (f (M.id, base.ielems, elements)).to_equal {"a", "b", "c", "d", "e"} expect (f (M.id, base.elems, inverse)).to_contain.a_permutation_of {1, 2, 3, 4, 5} + - it propagates nil arguments correctly: + t = {"a", nil, nil, "d", "e"} + expect (f (M.id, base.npairs, t)).to_equal (t) - it passes all iteration result values to filter predicate: t = {} f (function (k, v) t[k] = v end, pairs, elements) @@ -371,7 +386,7 @@ specify std.functional: - describe map: - before: elements = {"a", "b", "c", "d", "e"} - inverse = require "std.table".invert (elements) + inverse = {a=1, b=2, c=3, d=4, e=5} f = M.map @@ -383,6 +398,11 @@ specify std.functional: - it iterates through elements: expect (f (M.id, ipairs, elements)).to_equal (elements) expect (f (M.id, pairs, inverse)).to_contain.a_permutation_of (elements) + - it propagates nil arguments correctly: + t = {"a", nil, nil, "d", "e"} + expect (f (M.id, base.npairs, t)).to_equal (t) + t = {nil, nil, 3, 4} + expect (f (M.id, base.npairs, t)).to_equal (t) - it passes all iteration result values to map function: t = {} f (function (k, v) t[k] = v end, pairs, elements) @@ -685,6 +705,12 @@ specify std.functional: - it calls a binary function over key:value iterator results: expect (f (op.sum, 2, base.ielems, {3})).to_be (2 + 3) expect (f (op.prod, 2, base.ielems, {3, 4})).to_be (2 * 3 * 4) + - it propagates nil arguments correctly: + function set (t, k, v) t[k] = tostring (v) return t end + expect (f (set, {}, base.npairs, {1, nil, nil, "a", false})). + to_equal {"1", "nil", "nil", "a", "false"} + expect (f (set, {}, base.npairs, {nil, nil, "3"})). + to_equal {"nil", "nil", "3"} - it reduces elements from left to right: expect (f (op.pow, 2, base.ielems, {3, 4})).to_be ((2 ^ 3) ^ 4) - it passes all iterator results to accumulator function: diff --git a/specs/std_spec.yaml b/specs/std_spec.yaml index d119ad7..32ec591 100644 --- a/specs/std_spec.yaml +++ b/specs/std_spec.yaml @@ -3,8 +3,9 @@ before: | global_table = "_G" exported_apis = { "assert", "barrel", "elems", "eval", "getmetamethod", - "ielems", "ipairs", "ireverse", "monkey_patch", "pairs", - "require", "ripairs", "tostring", "version" } + "ielems", "ipairs", "ireverse", "monkey_patch", "npairs", + "pairs", "require", "ripairs", "rnpairs", "tostring", + "version" } -- Tables with iterator metamethods used by various examples. __pairs = setmetatable ({ content = "a string" }, { @@ -228,7 +229,7 @@ specify std: f = M.getmetamethod - context with bad arguments: - badargs.diagnose (f, "std.getmetamethod (object|table, string)") + badargs.diagnose (f, "std.getmetamethod (?any, string)") - context with a table: - before: @@ -368,6 +369,31 @@ specify std: end +- describe npairs: + - before: + f = M.npairs + + - context with bad arguments: + badargs.diagnose (f, "std.npairs (table)") + + - it is an iterator over integer-keyed table values: + t = {} + for i, v in f {"foo", 42, nil, nil, "five"} do + t[i] = v + end + expect (t).to_equal {"foo", 42, nil, nil, "five"} + - it ignores the dictionary part of a table: + t = {} + for i, v in f {"foo", 42, nil, nil, "five"; bar = "baz", qux = "quux"} do + t[i] = v + end + expect (t).to_equal {"foo", 42, nil, nil, "five"} + - it works for an empty list: + t = {} + for i, v in f {} do t[i] = v end + expect (t).to_equal {} + + - describe pairs: - before: f = M.pairs @@ -504,6 +530,31 @@ specify std: expect (t).to_equal {} +- describe rnpairs: + - before: + f = M.rnpairs + + - context with bad arguments: + badargs.diagnose (f, "std.rnpairs (table)") + + - it returns a function, the table and a number: + fn, t, i = f {1, 2, nil, nil, 3} + expect ({type (fn), t, type (i)}). + to_equal {"function", {1, 2, nil, nil, 3}, "number"} + - it iterates over the array part of a table: + t, u = {1, 2, nil, nil, 3; a=4, b=5, c=6}, {} + for i, v in f (t) do u[i] = v end + expect (u).to_equal {1, 2, nil, nil, 3} + - it returns elements in reverse order: + t, u, i = {"one", "two", nil, nil, "five"}, {}, 1 + for _, v in f (t) do u[i], i = v, i + 1 end + expect (u).to_equal {"five", nil, nil, "two", "one"} + - it works with the empty list: + t = {} + for k, v in f {} do t[k] = v end + expect (t).to_equal {} + + - describe tostring: - before: f = M.tostring diff --git a/stdlib-41.1.1-1.rockspec b/stdlib-41.2.0-1.rockspec similarity index 94% rename from stdlib-41.1.1-1.rockspec rename to stdlib-41.2.0-1.rockspec index e03f46f..82423c5 100644 --- a/stdlib-41.1.1-1.rockspec +++ b/stdlib-41.2.0-1.rockspec @@ -1,5 +1,5 @@ package = "stdlib" -version = "41.1.1-1" +version = "41.2.0-1" description = { detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://lua-stdlib.github.io/lua-stdlib", @@ -7,8 +7,8 @@ description = { summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v41.1.1", - url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.1.1.zip", + dir = "lua-stdlib-release-v41.2.0", + url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.2.0.zip", } dependencies = { "lua >= 5.1, < 5.4", diff --git a/travis.yml.in b/travis.yml.in index f27c9c9..b1762c8 100644 --- a/travis.yml.in +++ b/travis.yml.in @@ -3,7 +3,7 @@ language: c env: global: - _COMPILE="libtool --mode=compile --tag=CC gcc" - - _CFLAGS="-O2 -Wall -DLUA_COMPAT_ALL -DLUA_USE_LINUX" + - _CFLAGS="-O2 -Wall -DLUA_COMPAT_ALL -DLUA_COMPAT_5_2 -DLUA_USE_LINUX" - _INSTALL="libtool --mode=install install -p" - _LINK="libtool --mode=link --tag=CC gcc" - _LIBS="-lm -Wl,-E -ldl -lreadline" @@ -12,6 +12,10 @@ env: - bindir=$prefix/bin - incdir=$prefix/include - libdir=$prefix/lib + + - _inst=$TRAVIS_BUILD_DIR/_inst + - luadir=$_inst/share/lua + - luaexecdir=$_inst/lib/lua matrix: - LUA=lua5.3 - LUA=lua5.2 @@ -32,8 +36,8 @@ before_install: cd lua-5.3.0; fi' - 'if test lua5.2 = "$LUA"; then - curl http://www.lua.org/ftp/lua-5.2.3.tar.gz | tar xz; - cd lua-5.2.3; + curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz; + cd lua-5.2.4; fi' - 'if test lua5.1 = "$LUA"; then curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz; @@ -106,10 +110,14 @@ install: sleep 1; touch configure; fi' - # Build from rockspec. - - export ROCKSPEC=@PACKAGE@-@VERSION@-1.rockspec - - 'test -f "$ROCKSPEC" || ROCKSPEC=@PACKAGE@-git-1.rockspec' - - sudo luarocks make $ROCKSPEC LUA="$LUA" + # Build from rockspec, forcing uninstall of older luarocks installed + # above when testing the git rockspec, both for enforcing backwards + # compatibility by default, and for ease of maintenance. + - if test -f '@PACKAGE@-@VERSION@-1.rockspec'; then + sudo luarocks make '@PACKAGE@-@VERSION@-1.rockspec' LUA="$LUA"; + else + sudo luarocks make --force '@PACKAGE@-git-1.rockspec' LUA="$LUA"; + fi # Clean up files created by root - sudo git clean -dfx @@ -117,10 +125,22 @@ install: script: + # Reconfigure for in-tree test install. - test -f configure || ./bootstrap --verbose - - test -f Makefile || ./configure --disable-silent-rules LUA="$LUA" + - ./configure --prefix="$_inst" --disable-silent-rules LUA="$LUA" + + # Verify luarocks installation. + - make installcheck || make installcheck V=1 + + # Verify local build. - make - - make check V=1 + - make check || make check V=1 + + # Verify configured installation. + - make install prefix="$_inst" luadir="$luadir" luaexecdir="$luaexecdir" + - LUA_PATH="$luadir/?.lua;$luadir/?/init.lua;;" + LUA_CPATH="$luaexecdir/?.so;;" + make installcheck V=1 # Run sanity checks on CI server, ignoring buggy automakes. From 3edc639806bbca87b915264d2c3dea8baa5b4fea Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Mon, 7 Aug 2017 21:47:02 -0700 Subject: [PATCH 31/34] maint: release v41.2.1 with proper version information. * lib/std.lua (version): Set to 41.2.1. * stdlib-41.2.1-1.rockspec (version): Likewise. * NEWS (Bug fixes): Update accordingly. Signed-off-by: Gary V. Vaughan --- NEWS | 7 +++++++ lib/std.lua | 2 +- stdlib-41.2.0-1.rockspec => stdlib-41.2.1-1.rockspec | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) rename stdlib-41.2.0-1.rockspec => stdlib-41.2.1-1.rockspec (94%) diff --git a/NEWS b/NEWS index 7bab1c4..09ae12f 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,12 @@ # Stdlib NEWS - User visible changes +## Noteworthy changes in release 41.2.1 (2017-08-07) [stable] + +### Bug fixes + + - `std.version` reports the correct release again. + + ## Noteworthy changes in release 41.2.0 (2015-03-08) [stable] ### New features diff --git a/lib/std.lua b/lib/std.lua index 93d4b3a..b85b567 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -268,7 +268,7 @@ M = { -- print (std.tostring {foo="bar","baz"}) tostring = X ("tostring (?any)", base.tostring), - version = "General Lua libraries / 41.1.1", + version = "General Lua libraries / 41.2.1", } diff --git a/stdlib-41.2.0-1.rockspec b/stdlib-41.2.1-1.rockspec similarity index 94% rename from stdlib-41.2.0-1.rockspec rename to stdlib-41.2.1-1.rockspec index 82423c5..3ec5639 100644 --- a/stdlib-41.2.0-1.rockspec +++ b/stdlib-41.2.1-1.rockspec @@ -1,5 +1,5 @@ package = "stdlib" -version = "41.2.0-1" +version = "41.2.1-1" description = { detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://lua-stdlib.github.io/lua-stdlib", @@ -7,8 +7,8 @@ description = { summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v41.2.0", - url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.2.0.zip", + dir = "lua-stdlib-release-v41.2.1", + url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.2.1.zip", } dependencies = { "lua >= 5.1, < 5.4", From cf300f4c53b5e043fd8ec19f934d22e59724263d Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Mon, 3 Sep 2018 17:50:34 -0700 Subject: [PATCH 32/34] Release v41.2.2. Signed-off-by: Gary V. Vaughan --- .travis.yml | 4 +-- NEWS | 7 +++++ configure | 30 +++++++++---------- configure.ac | 4 +-- doc/classes/std.container.html | 6 ++-- doc/classes/std.list.html | 6 ++-- doc/classes/std.object.html | 6 ++-- doc/classes/std.optparse.html | 6 ++-- doc/classes/std.set.html | 6 ++-- doc/classes/std.strbuf.html | 6 ++-- doc/classes/std.tree.html | 6 ++-- doc/index.html | 6 ++-- doc/modules/std.debug.html | 6 ++-- doc/modules/std.functional.html | 6 ++-- doc/modules/std.html | 6 ++-- doc/modules/std.io.html | 6 ++-- doc/modules/std.math.html | 6 ++-- doc/modules/std.operator.html | 6 ++-- doc/modules/std.package.html | 6 ++-- doc/modules/std.strict.html | 6 ++-- doc/modules/std.string.html | 6 ++-- doc/modules/std.table.html | 6 ++-- lib/std.lua | 2 +- lib/std/version.lua | 1 + ...2.1-1.rockspec => stdlib-41.2.2-1.rockspec | 8 ++--- 25 files changed, 86 insertions(+), 78 deletions(-) create mode 100644 lib/std/version.lua rename stdlib-41.2.1-1.rockspec => stdlib-41.2.2-1.rockspec (93%) diff --git a/.travis.yml b/.travis.yml index 8593705..e65925a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -113,8 +113,8 @@ install: # Build from rockspec, forcing uninstall of older luarocks installed # above when testing the git rockspec, both for enforcing backwards # compatibility by default, and for ease of maintenance. - - if test -f 'stdlib-41.2.0-1.rockspec'; then - sudo luarocks make 'stdlib-41.2.0-1.rockspec' LUA="$LUA"; + - if test -f 'stdlib-41.2.2-1.rockspec'; then + sudo luarocks make 'stdlib-41.2.2-1.rockspec' LUA="$LUA"; else sudo luarocks make --force 'stdlib-git-1.rockspec' LUA="$LUA"; fi diff --git a/NEWS b/NEWS index 09ae12f..7bd2b78 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,12 @@ # Stdlib NEWS - User visible changes +## Noteworthy changes in release 41.2.2 (2018-09-03) [stable] + +### New Features + + - Initial support for Lua 5.4 + + ## Noteworthy changes in release 41.2.1 (2017-08-07) [stable] ### Bug fixes diff --git a/configure b/configure index a2fbb61..3cb1dc0 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 41.2.0. +# Generated by GNU Autoconf 2.69 for stdlib 41.2.2. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='stdlib' PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='41.2.0' -PACKAGE_STRING='stdlib 41.2.0' +PACKAGE_VERSION='41.2.2' +PACKAGE_STRING='stdlib 41.2.2' PACKAGE_BUGREPORT='http://github.com/lua-stdlib/lua-stdlib/issues' PACKAGE_URL='' @@ -1216,7 +1216,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures stdlib 41.2.0 to adapt to many kinds of systems. +\`configure' configures stdlib 41.2.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1282,7 +1282,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 41.2.0:";; + short | recursive ) echo "Configuration of stdlib 41.2.2:";; esac cat <<\_ACEOF @@ -1362,7 +1362,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -stdlib configure 41.2.0 +stdlib configure 41.2.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1379,7 +1379,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by stdlib $as_me 41.2.0, which was +It was created by stdlib $as_me 41.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -1759,7 +1759,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. $as_echo "## ------------------------- ## -## Configuring stdlib 41.2.0 ## +## Configuring stdlib 41.2.2 ## ## ------------------------- ##" echo @@ -2249,7 +2249,7 @@ fi # Define the identity of the package. PACKAGE='stdlib' - VERSION='41.2.0' + VERSION='41.2.2' cat >>confdefs.h <<_ACEOF @@ -2546,7 +2546,7 @@ $as_echo "no" >&6; } fi - _ax_check_text="whether $LUA version >= 5.1, < 5.4" + _ax_check_text="whether $LUA version >= 5.1, < 5.5" { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 $as_echo_n "checking $_ax_check_text... " >&6; } @@ -2561,7 +2561,7 @@ $as_echo_n "checking $_ax_check_text... " >&6; } local minver = verstr2num("5.1") local _, _, trimver = string.find(_VERSION, "^Lua (.*)") local ver = verstr2num(trimver) - local maxver = verstr2num("5.4") or 1e9 + local maxver = verstr2num("5.5") or 1e9 if minver <= ver and ver < maxver then print("yes") else @@ -2579,7 +2579,7 @@ fi ax_display_LUA=$LUA else - _ax_check_text="for a Lua interpreter with version >= 5.1, < 5.4" + _ax_check_text="for a Lua interpreter with version >= 5.1, < 5.5" { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 $as_echo_n "checking $_ax_check_text... " >&6; } if ${ax_cv_pathless_LUA+:} false; then : @@ -2616,7 +2616,7 @@ fi local minver = verstr2num("5.1") local _, _, trimver = string.find(_VERSION, "^Lua (.*)") local ver = verstr2num(trimver) - local maxver = verstr2num("5.4") or 1e9 + local maxver = verstr2num("5.5") or 1e9 if minver <= ver and ver < maxver then print("yes") else @@ -3612,7 +3612,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by stdlib $as_me 41.2.0, which was +This file was extended by stdlib $as_me 41.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3665,7 +3665,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -stdlib config.status 41.2.0 +stdlib config.status 41.2.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index fd116ac..9511e38 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl along with this program. If not, see . dnl Initialise autoconf and automake -AC_INIT([stdlib], [41.2.0], [http://github.com/lua-stdlib/lua-stdlib/issues]) +AC_INIT([stdlib], [41.2.2], [http://github.com/lua-stdlib/lua-stdlib/issues]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) @@ -29,7 +29,7 @@ AM_INIT_AUTOMAKE([-Wall]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) dnl Check for programs -AX_PROG_LUA([5.1], [5.4]) +AX_PROG_LUA([5.1], [5.5]) AC_PATH_PROG([LDOC], [ldoc], [:]) AC_PATH_PROG([SPECL], [specl], [:]) AC_PROG_EGREP diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index 5e902a6..acdfc83 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index 85f7652..c29ce85 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index 776f5fa..65dc357 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html index f46f42b..757d8dc 100644 --- a/doc/classes/std.optparse.html +++ b/doc/classes/std.optparse.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index e89ec4f..0344303 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index dd5cb82..22c5c94 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index 12cdf27..0a64c23 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/index.html b/doc/index.html index 9a0e491..9a1556f 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html index f3a3e9d..052f34c 100644 --- a/doc/modules/std.debug.html +++ b/doc/modules/std.debug.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index a1a6bde..f5eeda1 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.html b/doc/modules/std.html index 6b4d078..40f7de8 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index 8294c56..f69b83a 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index 1564650..8fd2b94 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.operator.html b/doc/modules/std.operator.html index 3920271..0ebf53f 100644 --- a/doc/modules/std.operator.html +++ b/doc/modules/std.operator.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index 972cb2f..c1d7e16 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index bc19eb7..ff52f9e 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index 3a01a2f..e04aad9 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index 99af92e..2184872 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -3,7 +3,7 @@ - stdlib 41.2.0 Reference + stdlib 41.2.2 Reference @@ -24,7 +24,7 @@
    generated by LDoc 1.4.3 -Last updated 2015-03-08 20:42:58 +Last updated 2018-09-03 17:48:42
    diff --git a/lib/std.lua b/lib/std.lua index b85b567..31b1311 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -268,7 +268,7 @@ M = { -- print (std.tostring {foo="bar","baz"}) tostring = X ("tostring (?any)", base.tostring), - version = "General Lua libraries / 41.2.1", + version = "General Lua libraries / 41.2.2", } diff --git a/lib/std/version.lua b/lib/std/version.lua new file mode 100644 index 0000000..0dc347a --- /dev/null +++ b/lib/std/version.lua @@ -0,0 +1 @@ +return "General Lua libraries / 41.2.2" diff --git a/stdlib-41.2.1-1.rockspec b/stdlib-41.2.2-1.rockspec similarity index 93% rename from stdlib-41.2.1-1.rockspec rename to stdlib-41.2.2-1.rockspec index 3ec5639..7be7654 100644 --- a/stdlib-41.2.1-1.rockspec +++ b/stdlib-41.2.2-1.rockspec @@ -1,5 +1,5 @@ package = "stdlib" -version = "41.2.1-1" +version = "41.2.2-1" description = { detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", homepage = "http://lua-stdlib.github.io/lua-stdlib", @@ -7,11 +7,11 @@ description = { summary = "General Lua Libraries", } source = { - dir = "lua-stdlib-release-v41.2.1", - url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.2.1.zip", + dir = "lua-stdlib-release-v41.2.2", + url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.2.2.zip", } dependencies = { - "lua >= 5.1, < 5.4", + "lua >= 5.1, < 5.5", } external_dependencies = nil build = { From 4e5686f7fcbd754a97f4a81bf532433594438a90 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Tue, 4 Sep 2018 08:59:13 -0700 Subject: [PATCH 33/34] specs: adjust for spurious failures. * specs/std_spec.yaml (std.barrel): Force lazy-loading of sub-modules instead of failing due to differences in not yet lazy-loaded keys. (std.require): make sure to unset std._VERSION after test completion. * specs/string_spec.yaml (std.require_version): Likewise. Signed-off-by: Gary V. Vaughan --- specs/std_spec.yaml | 13 ++++++++++--- specs/string_spec.yaml | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/specs/std_spec.yaml b/specs/std_spec.yaml index 32ec591..6a88d8d 100644 --- a/specs/std_spec.yaml +++ b/specs/std_spec.yaml @@ -101,8 +101,15 @@ specify std: # Ideally, `.to_be (M)`, except that M is cloned from a nested context # by Specl to prevent us from affecting any other examples, thus the - # address is different by now. + # address is different by now. Also, we have to force lazy-loading in + # our copy of M to match apis already loaded in barrel. - it returns std module table: + t = f(namespace) + for k, v in pairs(t) do + if type(v) ~= 'function' then + _ = M[k] + end + end expect (f (namespace)).to_equal (M) - it installs std monkey patches: for _, api in ipairs (exported_apis) do @@ -442,9 +449,9 @@ specify std: expect (f "std").to_be (require "std") - it uses _VERSION when version field is nil: std = require "std" - M._VERSION, M.version = M.version, M._VERSION + M._VERSION, M.version = M.version, nil expect (f ("std", "41", "9999")).to_be (require "std") - M._VERSION, M.version = M.version, M._VERSION + M._VERSION, M.version = nil, M._VERSION - context with semantic versioning: - before: std = require "std" diff --git a/specs/string_spec.yaml b/specs/string_spec.yaml index 00fb422..7ac10ba 100644 --- a/specs/string_spec.yaml +++ b/specs/string_spec.yaml @@ -503,9 +503,9 @@ specify std.string: expect (f "std").to_be (require "std") - it uses _VERSION when version field is nil: std = require "std" - std._VERSION, std.version = std.version, std._VERSION + std._VERSION, std.version = std.version, nil expect (f ("std", "41", "9999")).to_be (require "std") - std._VERSION, std.version = std.version, std._VERSION + std._VERSION, std.version = nil, std._VERSION - context with semantic versioning: - before: std = require "std" From 58414c5fe459bbb317b95ea118cbbe61704ac588 Mon Sep 17 00:00:00 2001 From: "Gary V. Vaughan" Date: Sun, 16 Sep 2018 17:38:48 -0700 Subject: [PATCH 34/34] maint: modernize distribution and initial Lua 5.4 support * .travis.yml: Drastically simplified with hererocks. * COPYING, NEWS, README, specs: Renamed from these... * LICENSE.md, NEWS.md, README.md, spec: ...to these. * .autom4te.config, ChangeLog, GNUmakefile, INSTALL, Makefile.am, Makefile.in, aclocal.m4, bootstrap, bootstrap.conf, build-aux/gitlog-to-changelog, build-aux/install-sh, build-aux/missing, build-aux/mkrockspecs, build-aux/release.mk, build-aux/rockspecs.mk, build-aux/sanity-cfg.mk, build-aux/sanity.mk, build-aux/specl.mk, configure, configure.ac, local.mk, m4/ax_lua.m4, rockspec.conf, specs/specs.mk, travis.yml.in: Remove autotools infrastructure. * spec/io_spec.yaml (process_files): Use NEWS.md and README.md in examples instead of config.log and config.status, which don't exist any more! * Makefile: New file to replace autotools. * spec/spec_helper.lua (concat_file_content): Add missing local. * build-aux/config.ld.in: Modernize. * build-aux/config.ld: Regenerate. * doc/classes/std.container.html, doc/classes/std.list.html, doc/classes/std.object.html, doc/classes/std.optparse.html, doc/classes/std.set.html, doc/classes/std.strbuf.html, doc/classes/std.tree.html, doc/index.html, doc/ldoc.css, doc/modules/std.debug.html, doc/modules/std.functional.html, doc/modules/std.html, doc/modules/std.io.html, doc/modules/std.math.html, doc/modules/std.operator.html, doc/modules/std.package.html, doc/modules/std.strict.html, doc/modules/std.string.html, doc/modules/std.table.html: Regenerate with latest LDoc. * stdlib-41.2.2-1.rockspec: Reformat. Signed-off-by: Gary V. Vaughan --- .autom4te.cfg | 4 - .travis.yml | 163 +- ChangeLog | 7370 -------------------------- GNUmakefile | 82 - INSTALL | 370 -- COPYING => LICENSE.md | 9 +- Makefile | 50 + Makefile.am | 109 - Makefile.in | 1244 ----- NEWS => NEWS.md | 2 +- README => README.md | 8 +- aclocal.m4 | 741 --- bootstrap | 5796 -------------------- bootstrap.conf | 72 - build-aux/config.ld | 48 + build-aux/config.ld.in | 24 +- build-aux/gitlog-to-changelog | 432 -- build-aux/install-sh | 501 -- build-aux/missing | 215 - build-aux/mkrockspecs | 463 -- build-aux/release.mk | 393 -- build-aux/rockspecs.mk | 116 - build-aux/sanity-cfg.mk | 3 - build-aux/sanity.mk | 1114 ---- build-aux/specl.mk | 71 - configure | 4242 --------------- configure.ac | 40 - doc/classes/std.container.html | 45 +- doc/classes/std.list.html | 43 +- doc/classes/std.object.html | 152 +- doc/classes/std.optparse.html | 116 +- doc/classes/std.set.html | 47 +- doc/classes/std.strbuf.html | 40 +- doc/classes/std.tree.html | 139 +- doc/index.html | 22 +- doc/ldoc.css | 20 +- doc/modules/std.debug.html | 119 +- doc/modules/std.functional.html | 147 +- doc/modules/std.html | 115 +- doc/modules/std.io.html | 76 +- doc/modules/std.math.html | 14 +- doc/modules/std.operator.html | 85 +- doc/modules/std.package.html | 45 +- doc/modules/std.strict.html | 18 +- doc/modules/std.string.html | 156 +- doc/modules/std.table.html | 172 +- local.mk | 158 - m4/ax_lua.m4 | 664 --- rockspec.conf | 16 - {specs => spec}/container_spec.yaml | 0 {specs => spec}/debug_spec.yaml | 0 {specs => spec}/functional_spec.yaml | 0 {specs => spec}/io_spec.yaml | 2 +- {specs => spec}/list_spec.yaml | 0 {specs => spec}/math_spec.yaml | 0 {specs => spec}/object_spec.yaml | 0 {specs => spec}/operator_spec.yaml | 0 {specs => spec}/optparse_spec.yaml | 0 {specs => spec}/package_spec.yaml | 0 {specs => spec}/set_spec.yaml | 0 {specs => spec}/spec_helper.lua | 2 +- {specs => spec}/std_spec.yaml | 0 {specs => spec}/strbuf_spec.yaml | 0 {specs => spec}/string_spec.yaml | 0 {specs => spec}/table_spec.yaml | 0 {specs => spec}/tree_spec.yaml | 0 specs/specs.mk | 38 - stdlib-41.2.2-1.rockspec | 81 +- travis.yml.in | 154 - 69 files changed, 943 insertions(+), 25425 deletions(-) delete mode 100644 .autom4te.cfg delete mode 100644 ChangeLog delete mode 100644 GNUmakefile delete mode 100644 INSTALL rename COPYING => LICENSE.md (70%) create mode 100644 Makefile delete mode 100644 Makefile.am delete mode 100644 Makefile.in rename NEWS => NEWS.md (99%) rename README => README.md (89%) delete mode 100644 aclocal.m4 delete mode 100755 bootstrap delete mode 100644 bootstrap.conf create mode 100644 build-aux/config.ld delete mode 100755 build-aux/gitlog-to-changelog delete mode 100755 build-aux/install-sh delete mode 100755 build-aux/missing delete mode 100755 build-aux/mkrockspecs delete mode 100644 build-aux/release.mk delete mode 100644 build-aux/rockspecs.mk delete mode 100644 build-aux/sanity-cfg.mk delete mode 100644 build-aux/sanity.mk delete mode 100644 build-aux/specl.mk delete mode 100755 configure delete mode 100644 configure.ac delete mode 100644 local.mk delete mode 100644 m4/ax_lua.m4 delete mode 100644 rockspec.conf rename {specs => spec}/container_spec.yaml (100%) rename {specs => spec}/debug_spec.yaml (100%) rename {specs => spec}/functional_spec.yaml (100%) rename {specs => spec}/io_spec.yaml (99%) rename {specs => spec}/list_spec.yaml (100%) rename {specs => spec}/math_spec.yaml (100%) rename {specs => spec}/object_spec.yaml (100%) rename {specs => spec}/operator_spec.yaml (100%) rename {specs => spec}/optparse_spec.yaml (100%) rename {specs => spec}/package_spec.yaml (100%) rename {specs => spec}/set_spec.yaml (100%) rename {specs => spec}/spec_helper.lua (99%) rename {specs => spec}/std_spec.yaml (100%) rename {specs => spec}/strbuf_spec.yaml (100%) rename {specs => spec}/string_spec.yaml (100%) rename {specs => spec}/table_spec.yaml (100%) rename {specs => spec}/tree_spec.yaml (100%) delete mode 100644 specs/specs.mk delete mode 100644 travis.yml.in diff --git a/.autom4te.cfg b/.autom4te.cfg deleted file mode 100644 index f47eaee..0000000 --- a/.autom4te.cfg +++ /dev/null @@ -1,4 +0,0 @@ -# Disable the autom4te.cache directory. -begin-language: "Autoconf-without-aclocal-m4" -args: --no-cache -end-language: "Autoconf-without-aclocal-m4" diff --git a/.travis.yml b/.travis.yml index e65925a..cab15a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,157 +1,38 @@ -language: c +language: python -env: - global: - - _COMPILE="libtool --mode=compile --tag=CC gcc" - - _CFLAGS="-O2 -Wall -DLUA_COMPAT_ALL -DLUA_COMPAT_5_2 -DLUA_USE_LINUX" - - _INSTALL="libtool --mode=install install -p" - - _LINK="libtool --mode=link --tag=CC gcc" - - _LIBS="-lm -Wl,-E -ldl -lreadline" - - - prefix=/usr/local - - bindir=$prefix/bin - - incdir=$prefix/include - - libdir=$prefix/lib +sudo: false - - _inst=$TRAVIS_BUILD_DIR/_inst - - luadir=$_inst/share/lua - - luaexecdir=$_inst/lib/lua +env: matrix: - - LUA=lua5.3 - - LUA=lua5.2 - - LUA=lua5.1 - - LUA=luajit + - VLUA="lua=5.4" + - VLUA="lua=5.3" + - VLUA="lua=5.2" + - VLUA="lua=5.1" + - VLUA="luajit=2.1" + - VLUA="luajit=2.0" before_install: - # Put back the links for libyaml, which are missing on recent Travis VMs - - test -f /usr/lib/libyaml.so || - sudo find /usr/lib -name 'libyaml*' -exec ln -s {} /usr/lib \; - - sudo apt-get install help2man - - # Fetch Lua sources. - - cd $TRAVIS_BUILD_DIR - - 'if test lua5.3 = "$LUA"; then - curl http://www.lua.org/ftp/lua-5.3.0.tar.gz | tar xz; - cd lua-5.3.0; - fi' - - 'if test lua5.2 = "$LUA"; then - curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz; - cd lua-5.2.4; - fi' - - 'if test lua5.1 = "$LUA"; then - curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz; - cd lua-5.1.5; - fi' - - # Unpack, compile and install Lua. - - 'if test luajit = "$LUA"; then - curl http://luajit.org/download/LuaJIT-2.0.3.tar.gz | tar xz; - cd LuaJIT-2.0.3; - make && sudo make install; - for header in lua.h luaconf.h lualib.h lauxlib.h luajit.h lua.hpp; do - if test -f /usr/local/include/luajit-2.0/$header; then - sudo ln -s /usr/local/include/luajit-2.0/$header /usr/local/include/$header; - fi; - done; - else - for src in src/*.c; do - test src/lua.c = "$src" || test src/luac.c = "$src" || eval $_COMPILE $_CFLAGS -c $src; - done; - eval $_LINK -o lib$LUA.la -version-info 0:0:0 -rpath $libdir *.lo; - sudo mkdir -p $libdir; - eval sudo $_INSTALL lib$LUA.la $libdir/lib$LUA.la; - - eval $_COMPILE $_CFLAGS -c src/lua.c; - eval $_LINK -static -o $LUA lua.lo lib$LUA.la $_LIBS; - sudo mkdir -p $bindir; - eval sudo $_INSTALL $LUA $bindir/$LUA; - - sudo mkdir -p $incdir; - for header in lua.h luaconf.h lualib.h lauxlib.h lua.hpp; do - if test -f src/$header; then - eval sudo $_INSTALL src/$header $incdir/$header; - fi; - done; - fi' - - # Fetch LuaRocks. - - cd $TRAVIS_BUILD_DIR - - 'git clone https://github.com/keplerproject/luarocks.git luarocks-2.2.0' - - cd luarocks-2.2.0 - - git checkout v2.2.0 - - # Compile and install luarocks. - - if test luajit = "$LUA"; then - ./configure --lua-suffix=jit; - else - ./configure; - fi - - 'make build && sudo make install' - - # Tidy up file droppings. - - cd $TRAVIS_BUILD_DIR - - rm -rf lua-5.3.0 lua-5.2.3 lua-5.1.5 LuaJIT-2.0.3 luarocks-2.2.0 + - pip install hererocks + - hererocks here --luarocks 3 --$VLUA + - export PATH=$PWD/here/bin:$PATH + - hererocks tools --luajit=2.0 + - export PATH=$PATH:$PWD/tools/bin install: - # Use Lua 5.3 compatible rocks, where available. - - 'for rock in ansicolors ldoc specl""; do - if test -z "$rock"; then break; fi; - if luarocks list | grep "^$rock$" >/dev/null; then continue; fi; - sudo luarocks install --server=http://rocks.moonscript.org/manifests/gvvaughan $rock; - done' - - # Fudge timestamps on release branches. - - 'if test -f configure; then - test -f aclocal.m4 && touch aclocal.m4; - sleep 1; touch Makefile.in; - sleep 1; test -f config.h.in && touch config.h.in; - sleep 1; touch configure; - fi' - - # Build from rockspec, forcing uninstall of older luarocks installed - # above when testing the git rockspec, both for enforcing backwards - # compatibility by default, and for ease of maintenance. - - if test -f 'stdlib-41.2.2-1.rockspec'; then - sudo luarocks make 'stdlib-41.2.2-1.rockspec' LUA="$LUA"; - else - sudo luarocks make --force 'stdlib-git-1.rockspec' LUA="$LUA"; - fi - - # Clean up files created by root - - sudo git clean -dfx - - sudo rm -rf slingshot /tmp/ldoc - + - luarocks --lua-dir=$PWD/tools --tree=$PWD/tools install ansicolors + - luarocks --lua-dir=$PWD/tools --tree=$PWD/tools install specl + - luarocks --lua-dir=$PWD/tools --tree=$PWD/tools install luacov script: - # Reconfigure for in-tree test install. - - test -f configure || ./bootstrap --verbose - - ./configure --prefix="$_inst" --disable-silent-rules LUA="$LUA" - - # Verify luarocks installation. - - make installcheck || make installcheck V=1 - - # Verify local build. - - make - - make check || make check V=1 - - # Verify configured installation. - - make install prefix="$_inst" luadir="$luadir" luaexecdir="$luaexecdir" - - LUA_PATH="$luadir/?.lua;$luadir/?/init.lua;;" - LUA_CPATH="$luaexecdir/?.so;;" - make installcheck V=1 - + - make all + - luarocks make + - make check SPECL_OPTS='-vfreport --coverage' -# Run sanity checks on CI server, ignoring buggy automakes. after_success: - - '{ _assign="="; - if grep local-checks-to-skip build-aux/sanity-cfg.mk >/dev/null; then - _assign="+="; - fi; - printf "local-checks-to-skip %s sc_vulnerable_makefile_CVE-2012-3386\n" "$_assign"; - } >> build-aux/sanity-cfg.mk' - - 'make syntax-check || : this will usually fail on the release branch' + - tail luacov.report.out + - bash <(curl -s https://codecov.io/bash) -f luacov.report.out notifications: slack: aspirinc:JyWeNrIdS0J5nf2Pn2BS1cih diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index d56eb2e..0000000 --- a/ChangeLog +++ /dev/null @@ -1,7370 +0,0 @@ -2015-03-08 Gary V. Vaughan - - Release version 41.2.0 - * NEWS.md: Record release date. - - configury: bump release revision to 41.2.0. - * configure.ac (AC_INIT): Bump release revision to 41.2.0. - * .travis.yml: Regenerate. - - io: don't leak extra results from implementation details. - * lib/std/io.lua (dirname): Return parenthesised results from - internal gsub calls to prevent unexpected additional values - leaking. - * NEWS.md (Bug fixes): Update. - - doc: don't tell LDoc that resulterror is called argerror! - - debug: deprecate `toomanyargmsg` for `extramsg_toomany`. - * specs/debug_spec.yaml (extramsg_toomany): Add examples for - correct behaviours of new api. - * lib/std/debug.lua (toomanyargmsg): Deprecate. - (extramsg_toomany): New function, satisfies specified behaviours. - * lib/std/container.lua: Use extramsg_toomany api. - * NEWS.md (New features, Deprecations): Update. - - debug: refactor and export debug.resulterror. - * specs/debug_spec.yaml (resulterror): Add examples of behaviours - for resulterror. - * lib/std/base.lua (raise): New function factored out of... - (argerror): ...this. Adjust accordingly. - * lib/std/debug.lua (resulterror): Rewrite over base.raise. - Move out of _DEBUG.argcheck guard. - Export as resulterror. - * NEWS.md (New features): Update. - - debug: export formaterror as extramsg_mismatch. - * specs/debug_spec.yaml (extramsg_mismatch): Add examples for - correct behaviours of extramsg_mismatch. - * lib/std/debug.lua (formaterror): Rename from this... - (extramsg_mismatch): ...to this. Move out of _DEBUG.argcheck - guard. - (prototype, concat): Move above position of first call in file. - * NEWS.md (New features): Update. - - debug: accept "bool" as a typename alias for "boolean". - * specs/debug_spec.yaml: Add examples for behaviour when given - "bool" in lieu of "boolean". - * lib/std/debug.lua (formaterror, checktype): Accept "bool" as an - alias for "boolean" in a type specification. - * NEWS.md (Bug fixes): Update. - - debug: skip `self` typecheck when fname contains a colon. - * specs/debug_spec.yaml (argscheck): Specify behaviours for colon - delimited function name. - * lib/std/debug.lua (argscheck): Drop `self` argument before - checking types of remaining arguments when the function name - contains a colon. - * NEWS.md (New features): Update. - - debug: export a new function to parse type table. - Close #91 - * lib/std/debug.lua (normalize): Rename from this... - (typesplit): ...to this. Move to outer scope, so it will be - visible even if _DEBUG.argcheck is false. - ((markdots, permute, projectuniq): Move to outer scope. - (parsetypes): New function. - (parsetypes, typesplit): Export as public APIs. - * specs/debug_spec.yaml (extendbase): Add parsetypes and - typesplit. - - debug: improve argscheck patterns. - * lib/std/debug.lua (args_pat, argscheck): Improve patterns. - - slingshot: sync with upstream, for git rockspec fixes. - * slingshot: Sync with upstream. - * stdlib-git-1.rockspec: Regenerate. - - debug: maintain stack frame depth parity with LuaJIT. - * lib/std/debug.lua (getfenv): Be careful not to let the LuaJIT - optimizer eliminate a stack frame, and mess up the depth count. - - slingshot: sync with upstream, for Lua 5.2.4 update. - * slingshot: Sync with upstream. - * .travis.yml: Regenerate. - - debug: adjust numeric args for getfenv wrapper for Lua 5.1. - * lib/std/debug.lua (getfenv): When calling core getfenv from - our wrapper, make sure to add one to numeric args to compensate - for the extra stack frame. - -2015-02-27 Gary V. Vaughan - - debug: export portable getfenv and setfenv implementations. - * specs/debug_spec.yaml (getfenv, setfenv): Add examples of - behaviour of these functions. - * lib/std/debug.lua (getfenv): Fix a bug that prevented - unwrapping of functables on Lua 5.1 and LuaJIT. - (getfenv, setfenv): Export as public APIs. - * NEWS.md (New features): Update. - - functional: callable returns falsey for nil argument. - * specs/functional_spec.yaml (callable): Specify correct behaviour - for uncallable argument. - * lib/std/functional.lua (callable): Don't raise an argument error - for a nil argument, just return nil like any other uncallable. - * NEWS.md (Bugs fixed): Update. - - functional: add examples to show reduce handling nil arguments. - * specs/functional_spec.yaml (reduce): Add examples to show - behaviours with nil arguments. - -2015-02-27 Reuben Thomas - - std/io.lua: adjust catdir's return to 1 value - -2015-02-26 Gary V. Vaughan - - functional: ensure map propagates nil arguments. - * specs/functional_spec.yaml (map): Add examples to show - behaviours with nil arguments. - * lib/std/functional.lua (map): Detect iterator arity when - collecting result table. - * NEWS.md (Bug fixes): Update. - - functional: ensure filter propagates nil arguments. - * specs/functional_spec.yaml (filter): Add example to show - behaviour with nil arguments. - * lib/std/functional.lua (filter): Detect iterator arity when - collecting result table. - * NEWS.md (Bug fixes): Update. - - functional: ensure collect propagates nil arguments. - * specs/functional_spec.yaml (collect): Add examples to show - behaviours with nil arguments. - * lib/std/functional.lua (collect): Use npairs as a default - iterator. - Detect iterator arity when collecting result table. - * NEWS.md (Bug fixes): Update. - (Incompatible changes): Note change of default iterator. - - functional: ensure compose propagates nil arguments. - * specs/functional_spec.yaml (compose): Add examples to show - behaviours with nil arguments. - * lib/std/functional.lua (compose): Simplify. - * NEWS.md (Bug fixes): Update. - - functional: ensure bind propagates nil arguments. - * specs/functional_spec.yaml (bind): Add example to show - behaviours with nil arguments. - * lib/std/functional.lua (bind): Simplify. - * NEWS.md (Bug fixes): Update. - - std: new npairs and rnpairs iterators. - * specs/std_spec.yaml (npairs, rnpairs): Specify correct - behaviour for these new iterators. - * lib/std/debug.lua (argpairs): Move from here... - * lib/std/base.lua (npairs): ...to here. - (rnpairs): New function. - * lib/std.lua.in (npairs, rnpairs): Reexport from here. - * NEWS.md (New features): Update. - - std: fix argscheck declaration for std.getmetamethod. - * lib/std.lua.in (getmetamethod): This function works on anything - the Lua can add a metatable to. Adjust LDocs and argscheck - declaration to support that. - * specs/std_spec.yaml (getmetamethod): Adjust badargs parameters - accordingly. - * NEWS.md (Bug fixes): Update. - -2015-02-26 Gary V. Vaughan - - Merge pull request #96 from lua-stdlib/fix-require-version - base: require does not work with non-string module version fields - -2015-02-26 Gary V. Vaughan - - maint: fix .gitignore problems. - Close #97. - * .gitignore: Some versions of git disallow !re-include inside a - directory that has been excluded. Add a trailing '/*' to support - those versions. - (/build-aux/config.ld.in): Re-include this source file. - (/doc/config.ld): Remove exclusion of no longer generated file, - now that config.ld is also kept in build-aux. - Reported by Reuben Thomas - -2015-02-25 Reuben Thomas - - base: require does not work with non-string module version fields - Simple fix: run “tostring” on the version field. - - It may be desired to refuse certain types. The motivating case here is - that std.optparse has version set to number 0. - -2015-02-06 Gary V. Vaughan - - list: std.ireverse is not a full replacement for list.reverse. - * lib/std/list.lua (reverse): Describe a full replacement - with functional.compose in deprecation warning message. - Reported by Reuben Thomas - -2015-01-31 Gary V. Vaughan - - maint: post-release administrivia. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 41.1.1 - * NEWS.md: Record release date. - - configury: bump release version to 41.1.1. - * configure.ac (AC_INIT): Bump release version to 41.1.1. - * .travis.yml: Regenerate. - - std: fix an infinite loop in std.barrel() with Lua 5.3. - Close #94 - * lib/std/base.lua (maxn): This function is called from any - function wrapped by debug.argscheck, which calls debug.diagnose. - Calling std.barrel monkey-patches the global pairs function, - so we can't call that from here, otherwise it will in turn use - the monkey-patched pairs, which calls debug.diagnose to check - for argument errors before the original maxn call has finished. - Reported by Reuben Thomas - -2015-01-30 Gary V. Vaughan - - doc: add missing parameter LDoc for debug:markdots. - * lib/std/debug.lua (markdots): Add missing LDocs for v parameter. - - maint: post-release administrivia. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 41.1.0 - * NEWS.md: Record release date. - - package: normalize leaves valid /../.. sequences unmolested. - * specs/package_spec.yaml (normalize): Add examples of correct - behaviour with multiple .. directories. - * lib/std/package.lua (normalize): Detect redundant .. components - correctly, and only remove them when it's safe to do so. - * NEWS.md (Bug fixes): Update. - - slingshot: sync with upstream. - * slingshot: Sync with upstream. - * .travis.yml: Regenerate. - - configury: bump release version to 41.1.0. - * configure.ac (AC_INIT): Bump release version to 41.1.0. - - table: new unpack method that behaves consistently across Lua versions. - * specs/table_spec.yaml (unpack): Specify behaviours for unpack, - especially when dealing with holes. - * lib/std/base.lua (unpack): Wrapper for the core function, but - defaulting the final index argument to table.maxn. - * lib/std/table.lua (unpack): Export from here. Add LDocs. - * lib/std/debug.lua, lib/std/functional.lua, lib/std/list.lua: Use - safer base.unpack. - * specs/spec_helper.lua (maxn, unpack): Make safe versions - available to spec examples. - * specs/debug_spec.yaml: Simplify id implementation. - * NEWS.md (New features): Update. - - debug: unpack to maxn (t) for equivalence between Lua versions. - luajit alone stops unpacking at the first nil valued index, so - we have to pass explicit limits to make it behave like Lua 5.1 - through 5.3. - * lib/std/debug.lua (argscheck): unpack from 1 to maxn (results). - * specs/debug_spec.yaml (argscheck): Adjust id implementation to - calculate maximum numeric index and unpack all results up to - that value. - - debug: support variant return type lists with argscheck. - Sometimes we need to say `returns an int or nil,errmsg', the - syntax is `=> int or nil, string`, because `=> ?int, string` will - wrongly accept, say, `3, "oh noes!"`. - * specs/debug_spec.yaml (argscheck): Specify behaviours with - variant return type lists. - * lib/std/debug.lua (argscheck): Parse all variants and add them - to the accepted type list permutations table. - Update LDocs. - * NEWS.md (New features): Update. - -2015-01-29 Gary V. Vaughan - - refactor: store parameter dots property against each permuted list. - Rather than deciding whether a typelist has continuation dots in - the last position once for the entire table of permuted type match - lists, add it to each permutation with continuation dots. - * lib/std/debug.lua (markdots): Simplify. - (permute): Call it for each new permutation row. - (projectuniq): New function to select and de-deduplicate all - values from the table of permuted type lists at a given index. - (diagnose): Rewrite to work with new format permutations. - (argscheck): Simplify accordingly. - (match): Remove allargs parameter, and always check all arguments. - (merge, HAS_DOTS): Remove. No longer used. - -2015-01-28 Gary V. Vaughan - - refactor: clean up maxvalues calculation in debug.argscheck. - * lib/std/debug.lua (stripellipsis): Remove. - (markdots): New function encapsulating stripellipsis, maxvalue - calculation and optional normalization. - (argscheck): Simplify accordingly. - - debug: argscheck supports return type checking. - Close #89 - * specs/spec_helper.lua (badargs.result): Fallback implementation - until next Specl release. - (init): Use it to return a `badresult` function. - * specs/debug_spec.yaml: Specifiy behaviours with return type - checking. - * lib/std/debug.lua (toomanyargmsg): Factor this... - (toomanymsg): ...into this more general function. - (M): Adjust accordingly. - (resulterror): New function modelled after argerror, but tailored - for result type mismatch error reporting. - (has_dots): Symbol to name use of math.huge for denoting an - ellipsis was stripped from the type list. - (stripellipsis): New function. - (diagnose): Refactored to take a vtable of arguments instead of an - ever longer list of parameters. - (argscheck): Build a vtable to call diagnose for argument type - checking. - Add another diagnose() with a separate vtable for result type - checking. - Update LDocs. - * NEWS.md (New features): Update. - -2015-01-27 Gary V. Vaughan - - refactor: separate argscheck inner wrapper into its own function. - * lib/std/debug.lua (empty): New function. - (diagnose): New function... - (argscheck): ...factored out of here. - -2015-01-26 Gary V. Vaughan - - tree: don't argcheck metamethods. - Lua will not call metamethods unless the metatables are compatible, - so don't waste time rechecking the argument types. - * lib/std/tree.lua (__index, __newindex): Remove superfluous - argscheck invocations. - - set: don't argcheck metamethods. - Lua will not call metamethods unless the metatables are compatible, - so don't waste time rechecking the argument types. - * lib/std/set.lua (__add, __sub, __mul, __div, __le, __lt) - (__tostring): Remove superfluous argscheck invocations. - - debug: more accurate too many arguments diagnostics. - Close #76 - * specs/debug_spec.yaml (argscheck): Specify behaviour when - arguments match by skipping bracketed optional parameters, but - for one unmatched argument at the end. - * lib/std/debug.lua (permutations): Rename function from this - noun... - (permute): ...to this verb. - (argscheck): Use the matching permutation to decide whether - too many arguments were passed, unless the last parameter has - an ellipsis denoting any number of matching arguments are allowed. - * NEWS.md (Bug fixes): Update. - - debug: process [final|parm|types] without nil substitution hack. - * specs/debug_spec.yaml (argscheck): Specify behaviours for - bracketed final parameter more thoroughly. - * lib/std/debug.lua (argscheck): Remove hack of replacing - brackets in bracketed last parameter by 'or nil'; we really - run permutations without a bracketed final parameter now. - (permutations): Simplify accordingly; we don't need all the - sentinel gunk to track final argument nils now. - (normalize): Simplify, and fix a related bug where nils could - get dropped from the type list by a double increment. - * lib/std/functional.lua (bind): This really is a '?any...', - requiring explicit nils, and not a [any...] optional argument. - * specs/debug_spec.yaml: Adjust badargs calls as necessary. - * specs/io_spec.yaml (writelines): Now that this implementation - is a step ahead of the current Specl release generator, manually - write out bad argument examples. - * NEWS.md: Update. - - debug: argscheck accepts bracketed final parameter. - * specs/debug_spec.yaml (argscheck): Add examples for bracketed - final parameters. - * lib/std/debug.lua (argscheck): Handle bracketed final parameter - and satisfy new specs. Adjust all callers accordingly. - * NEWS.md (New features): Update. - - debug: use trailing `...` instead of `*` with argscheck. - * specs/debug_spec.yaml (argscheck): Add specifications for - continuation argument behavious with `...`. - * lib/std/debug.lua (argscheck): Use `...` instead of `*` as the - syntax for optional repeats of the final parameter type. Adjust - all callers. - * NEWS.md (Incompatible changes): Update. - - refactor: change `types` symbol name to `argtypes`. - * lib/std/debug.lua (argscheck): Change `types` symbol name to - `argtypes`. - -2015-01-25 Gary V. Vaughan - - debug: argcheck requires leading ? for argtypes, to match specl. - Close #90 - * specs/debug_spec.yaml (argcheck): Change to leading `?` over - previous trailing `?` style. - * lib/std.lua.in, lib/std/container.lua, lib/std/debug.lua, - lib/std/functional.lua, lib/std/io.lua, lib/std/list.lua, - lib/std/math.lua, lib/std/package.lua, lib/std/string.lua, - lib/std/table.lua, lib/std/tree.lua: Adjust accordingly. - - strbuf: document and test functional copying style. - Close #85 - * lib/std/strbuf.lua: Improve LDocs. - * specs/strbuf_spec.yaml: Add example of functional copying. - - strbuf: support lazy stringification and concat anything. - * specs/strbuf_spec.yaml: Specify correct behaviours, and add - lazy stringification example. - * lib/std/strbuf.lua (__concat): Simply insert a reference. - (__tostring): Make a table of stringified elements, and concat - those instead of the object elements proper. - * NEWS.md: Update. - - strbuf: allow concatenation of StrBuf objects. - * specs/strbuf_spec.yaml: Specify new behaviours. - * lib/std/strbuf.lua (concat): New function, handles concatenation - of StrBuf objects as well as strings. - * NEWS.md: Update. - - strbuf: deprecate strbuf.tostring. - * specs/strbuf_spec.yaml: Specify deprecation messages from - strbuf.tostring. - * lib/std/strbuf.lua (StrBuf.tostring): Deprecate. - * NEWS.md: Update. - - refactor: rearrange strbuf.lua idiomatically. - * lib/std/strbuf.lua: Rearrange declarations idiomatically. - - maint: support strict mode. - Close #92 - * lib/std/base.lua (loadstring): Use rawget to fetch loadstring - from _G, to bypass strict mode checks on Lua > 5.2 where - _G.loadstring is nil. - * lib/std/debug.lua (getfenv): Likewise, for Lua > 5.2 where - there is no _G.fgetenv. - * lib/std/debug_init/init.lua (_DEBUG): Likewise, for cases where - caller did not preload _G._DEBUG. - * NEWS.md: Updated. - Reported by Gergely Risko - -2015-01-19 Gary V. Vaughan - - std: barrel and monkey_patch return module table. - Closes #93 - In order for things like `std = require "std".barrel ()` to work - as documented, these methods must return their parent module - table, i.e. in this case, the `std` table. - * specs/io_spec.yaml (monkey_patch): Specify correct behaviour. - * specs/math_spec.yaml (monkey_patch): Likewise. - * specs/string_spec.yaml (monkey_patch): Likewise. - * specs/table_spec.yaml (money_patch): Likewise. - * specs/std_spec.yaml (barrel, monkey_patch): Likewise. - * lib/std.lua.in (barrel, monkey_patch): Return parent module - able. - * lib/std/io.lua, lib/std/math.lua, lib/std/string.lua, - lib/std/table.lua (monkey_patch): Likewise. - * NEWS.md (Bug fixes): Update. - Reported by Reuben Thomas - -2015-01-14 Gary V. Vaughan - - slingshot: sync with upstream for working Lua 5.3.0 final support. - * slingshot: Sync with upstream. - * .travis.yml: Regenerate. - - slingshot: sync with upstream for Lua 5.3.0 final support. - * slingshot: Sync with upstream. - * .travis.yml: Regenerate. - -2015-01-14 Gergely Risko - - base: remove spurious case reference from base module. - * lib/std/base.lua: Remove spurious reference to case from - export table. That function has long since moved to std.functional. - -2015-01-03 Gary V. Vaughan - - maint: post-release administrivia. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 41.0.0 - * NEWS.md: Record release date. - - maint: don't use math.pow, which some Lua 5.3 builds don't support. - When compiled without -DLUA_COMPAT_5_2, Lua 5.3 removes a good - chunk of the math library, including math.pow. - * lib/std.lua.in (eval): Use math.min in LDocs usage. - * specs/functional_spec.yaml (bind, curry, eval): Instead of - math.pow, use math.min where sensible, otherwise std.operator.pow. - * specs/operator_spec.yaml (pow): Compare with result calculated - using ^ infix operator. - * specs/std_spec.yaml (eval): Use math.min over math.pow. - - std: ireverse only operates on the proper sequence part. - * lib/std/base.lua (ireverse): Ignore any holes in the argument - table, returning only the reversed proper sequence part. - * NEWS.md: Update. - - std: make ripairs respect contiguous integer keys like ipairs. - * lib/std/base.lua (ripairs): Start from lowest contiguous integer - key with a nil value, and iterate backwards to 1. - * NEWS.md: Update. - - std: revert std.ipairs to return all contiguous key pairs 1..n. - Now that Lua 5.3 returned to an ipairs implementation that returns - contiguous key-value pairs from 1..n, where n is the last non-nil - integer key, stdlib can do the same for simpler compliance with - all supported Lua versions. - * lib/std/base.lua (ipairs): Simplify accordingly. - * lib/std.lua.in (ipairs): Update LDocs accordingly. - * NEWS.md: Update. - - maint: commit git rockspec to master branch. - * .gitignore: Allow git rockspecs. - * stdlib-git-1.rockspec: New file. - - configury: add ansicolors to travis_extra_rocks. - * bootstrap.conf (buildreq): Bump Specl requirement to 14.1.0. - (travis_extra_rocks): Add ansicolors for color specl output. - * .travis.yml: Regenerate. - - maint: add 5.3 to compatibility statement. - * README.md: Add 5.3 to compatibility statement. - * specs/std_spec.yaml (std.version): Update accordingly. - - maint: update copyrights. - * COPYING, README.md, bootstrap.conf, configure.ac, local.mk, - specs/optparse_spec.yaml, specs/string_spec.yaml: Add 2015 to - copyright statement. - - rockspec: Lua 5.4 and higher not yet supported. - * rockspec.conf (dependencies): Add lua < 5.4 constraint. - - io: pass io.die message as an error() string. - * lib/std/io.lua (warnfmt): New function factored out of warn(). - Adjust callers. - (die): Pass result of warnfmt to error instead of writing directly - to stderr. - * specs/io_spec.yaml, specs/optparse_spec.yaml: Adjust - specifications accordingly. - * NEWS.md: Update. - - specs: support Lua 5.3 variants of core error messages. - * specs/container_spec.yaml, specs/debug_spec.ymal: Also accept - slightly different error message formats from Lua 5.3 core. - - slingshot: sync with upstream, for Lua 5.3.0 compatibility. - * slingshot: Sync with upstream. - * bootstrap: Update from slingshot. - * NEWS: Move from here... - * NEWS.md: ...to here. Reformat as Markdown and update. - * local.mk (old_NEWS_hash): Update. - * .gitignore: Add NEWS. - * .travis.yml: Regenerate. - -2014-12-29 Gary V. Vaughan - - string: consistent numbertosi output in Lua 5.3. - * lib/std/string.lua (numbertosi): Be careful to output an - integer even when handling a number ('double') in Lua 5.3. - - maint: 5.3 uses load instead of loadstring. - * lib/std/base.lua (loadstring): Set to load if loadstring is not - available. - * lib/std/functional.lua (loadstring): Likewise. - - maint: preliminary Lua 5.3.0 compatibility. - * configure.ac (AX_PROG_LUA): Accept Lua 5.3 interpreters. - * lib/std/io.lua (setmetatable): Define locally to - debug.setmetatable for resetting FILE* metatable in given - namespace. - * lib/std/base.lua, lib/std/debug.lua, lib/std/functional.lua, - lib/std/list.lua, lib/std/package.lua (unpack): Set to either - table.unpack or _G.unpack to satisfy Lua 5.1, 5.2 and 5.3. - * specs/spec_helper.lua (unpack): Set appropriately for all - supported Lua releases. - * NEWS: Update. - -2014-12-24 Gary V. Vaughan - - specs: use correct Specl > 13 arity for bad argument errors. - Now that Specl's badargs module is generating examples with - the correct messages, we can now say 'no more than 0 arguments'. - * lib/std/debug.lua (toomanyargmsg): Return singular 'argument' - in error message only for exactly 1 expected argument, otherwise - plural. - * bootstrap.conf (buildreq): Bump specl requirement. - - refactor: rename operator.deref to operator.get. - * specs/operator_spec.yaml (deref): Rename from this... - (get): ...to this. - * lib/std/operator.lua (deref): Rename from this... - (get): ...to this. - Adjust all callers. - * NEWS: Update. - - functional: generalize reduce to any table. - * specs/functional_spec.yaml (reduce): Specify optional iterator - argument defaulting to std.pairs. - Specify requirement for std.ielems when ignoring reduced table - keys. - * specs/operator_spec.yaml (set): Specify behaviours for a new - table element setting operator. - * specs/container_spec.yaml: Use appropriate iterator functions - for new reduce API. - * lib/std/functional.lua (reduce): Diagnose optional iterator - argument to std.pairs. - (fold): Copy old reduce implementation into deprecated call. - * lib/std.lua.in (barrel): Adjust accordingly. - * lib/std/base.lua (reduce): Default optional iterator argument - to std.pairs. - Pass all iterator results to accumulator function. - Adjust all clients. - * lib/std/operator.lua (set): Implement according to new specs. - * NEWS: Update. - - functional: improve lambda expressiveness. - * specs/functional_spec.yaml: Specify new behaviours with omitted - optional '=', and '_' alias argument. - * lib/std/functional.lua (lambda): Strip more useless whitespace - in parsing to improve memoize cache hits. - Support omitting leading '=' when first non-whitespace of lambda - string is '_'. - Add '_' alias to '_1' for lambda string compiled expressions. - Update LDocs. - - doc: show release version in LDocs column headings. - * build-aux/config.ld.in (project): Add release version. - -2014-12-21 Gary V. Vaughan - - string: don't return spurious additional values. - * lib/std/base.lua (escape_pattern): Wrap gsub return value in - parens to strip all but the first string return value. - * lib/std/string.lua (caps, chomp, escape_shell, ltrim, rtrim) - (trim): Likewise. - - io: add dirname function again. - * specs/io_spec.yaml (dirname): Specify behaviour of a new - function to discard the final path separator in a string and all - that follows. - * lib/std/io.lua (M.dirname): Implement it. - * NEWS: Update. - - vector: remove unneeded module. - On second thoughts, this is not necessary. Adding methods to core - table would give us the API benefits, and posix.curses.chstr is a - much easier way of handling arrays of attributed strings. - * lib/std/vector.lua: Remove. - * build-aux/config.ld.in (file): Remove lib/std/vector.lua. - * local.mk (dist_luastd_DATA): Likewise. - (dist_classes_DATA): Remove doc/classes/std.vector.html. - * specs/vector_spec.yaml: Remove. - * specs/string_spec.yaml (render): Remove vector examples. - * specs/specs.mk (specl_SPECS): Remove specs/vector_spec.yaml. - * NEWS: Remove vector references. - -2014-12-16 Gary V. Vaughan - - configury: adopt semantic versioning. - * configure.ac (AC_INIT): Set version to 41.0.0. - -2014-11-05 Gary V. Vaughan - - maint: fix bitrot in README. - * README.md: Update. - -2014-10-05 Gary V. Vaughan - - specs: simplify bad argument checking with specl.badargs. - * specs/spec_helper.lua (badargs): Expose specl.badargs to the - example execution environment. - (badarg, init): Remove. Superseded by badargs.init. - * specs/debug_spec.yaml, specs/string_spec.yaml: Use badargs.init - instead of init. - * specs/functional_spec.yaml, specs/io_spec.yaml, - specs/list_spec.yaml, specs/math_spec.yaml, - specs/package_spec.yaml, specs/std_spec.yaml, - specs/table_spec.yaml: Use badargs.diagnose to write bad argument - diagnostics examples automatically. - * bootstrap.conf (buildreq): Use moonscript rocks server URLs. - - travis: remove temporary specl-git-1.rockspec dependency. - * .travis.yml (script): Regenerate from travis.yml.n. - -2014-10-01 Gary V. Vaughan - - slingshot: sync with upstream for SPECL_ENV improvements. - * slingshot: Sync with upstream. - * specs/specs.mk: Simplify accordingly. - * specs/spec_helper.lua (package.path): Set according to slingshot - recommendations. - * bootstrap.conf: Require latest specl, and tidy accordingly. - - functional: fill unbound arguments in order with bind. - * lib/std/functional (bind): When filling unbound arguments, be - sure to traverse the remaining arguments *in* order! - - debug: improve argscheck parsing patterns. - * lib/std/debug.lua (argscheck): Strip leading and trailing - whitespace from argument type list. - Allow commas without trailing whitespace. - Allow periods in `fname` pattern. - - travis: reformat .travis.yml. - * .travis.yml: Reformat. - - travis: use specl-git-1.rockspec from specl git master branch. - * .travis.yml (script): Adjust specl-git-1.rockspec URL. - - refactor: rationalize deprecation interfaces. - Tracking one deprecation warning per deprecated function is - fiddly and confusing. Change the semantics to this: by - default calling deprecated API fires a warning message; turn - off the messages with `_DEBUG.deprecate = false`; elide - deprecated APIs entirely with `_DEBUG.deprecate = true`. - Easy and useful :) - * lib/std/debug_init/init.lua (_ARGCHECK): Remove. Adjust all - callers to use _DEBUG.argcheck instead. - (_DEBUG): Always a table, with fields initialised according to - global _DEBUG if necessary. Simplify all callers accordingly. - * lib/std/debug.lua (setcompat, getcompat): Remove. - (DEPRECATIONMSG): If _DEBUG.deprecate is nil, always return a - deprecation message, otherwise the empty string. - (DEPRECATED): If _DEBUG.deprecate is truthy, don't return a - function at all. - (_setdebug): New private function. A reliable way to jigger the - _DEBUG table contents, without worrying about nested specl - environments. - * specs/spec_helper.lua (setdebug): Import std.debug._setdebug - into the outermost execution environment. - * specs/debug_spec.yaml (extend_base): Add _setdebug. - Adjust other behaviour specs to match saner _DEBUG.deprecate - semantics. - * specs/functional_spec.yaml, specs/list_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml: Adjust deprecation - warning behaviour examples to match new semantics. - * NEWS: Update. - -2014-09-04 Gary V. Vaughan - - tree: use argscheck on exported apis. - * lib/std/tree.lua: Move LDocs and add argschecks to returned - Tree object function declarations. - - set: check for strict Set type arguments. - Since we have type checking to help maintain correctness, don't - undermine ourselves and add complexity by adding type coercions - and looser type safety. When we're using Set's, passing a table - instead of a Set is probably an error, so treat it as one! - * specs/set_spec.yaml: Remove specifications for type coercions. - * lib/std/set.lua: Remove type coercions and require strict Set - arguments everywhere. - Add type checks to metamethods. - * NEWS: Update. - - strbuf: use argscheck on exported apis. - * lib/std/strbuf.lua: Move LDocs and add argschecks to returned - StrBuf object declarations. - * HACKING: Update. - - set: use argscheck on exported apis. - * lib/std/set.lua: Move LDocs and add argschecks to returned Set - object declaration. - * HACKING: Add items about best practices for `debug.argscheck`. - -2014-09-03 Gary V. Vaughan - - refactor: simplify primitive std.set functions. - * lib/std/set.lua (insert, delete): Return results of calling - rawset. - - refactor: simplify string.render and clients. - * lib/std/base.lua (render): Use `cb` suffix for callback - parameter names. - Rename j and w locals to k_ and v_, as they represent the values - of k and v resp. from the previous iteration. - Remove unrelated Haskell comments. - * lib/std/string.lua (prettytostring): Likewise. - * lib/std/container.lua (__tostring): Manually unroll render - invocation with base.tostring functions plugged in. - -2014-09-02 Gary V. Vaughan - - refactor: factor away std.container.__pairs. - Object pairs iteration shouldn't rely on slow in-order traversal, - we only care about key order when printing. - * lib/std/container.lua (__pairs): Remove. By the time this is - called, private keys are already moved into the metatable, and - the client would be using ipairs and okeys for ordered traversal. - (__tostring): Use ipairs and okeys here, because we do care about - ordering. - - std: use numeric keys first ordering when stringifying a table. - Closes #81. - * specs/table_spec.yaml (okeys): Specify behaviours of a new - ordered keys function. - * lib/std/container.lua (__pairs): Factor key sorting algorithm - from here... - * lib/std/base.lua (keysort): New function. ...to here. - (okeys): Use keysort to extract a sorted key list from a table. - * lib/std/table.lua (okeys): Re-export from here. - * lib/std/base.lua (render): Simplify accordingly, and always - sort keys nicely as a pleasant side-effect. - * NEWS: Update. - -2014-09-01 Gary V. Vaughan - - doc: Use LDoc @object type for std.vector. - Closes #65. - * lib/std/vector.lua: Improve documentation. - -2014-08-31 Gary V. Vaughan - - doc: use LDoc @object type for std.tree. - * lib/std/tree.lua: Improve documentation. - - doc: use LDoc @object type for std.strbuf. - * lib/std/strbuf.lua: Improve documentation. - - doc: use LDoc @object type for std.list - * lib/std/list.lua: Improve documentation. - - refactor: upgrade OptionParser implementation to a std.object. - * lib/std/optparse.lua (OptionParser): Reimplement as a std.object, - and simplify accordingly. - - doc: use LDoc @object type for std.set. - * lib/std/set.lua: Improve documentation. - - doc: use LDoc @object type for std.container. - * lib/std/container.lua: Improve documentation. - - doc: use LDoc @object type for std.object. - * build-aux/config.ld.in (object): New type for documenting - objects. - * lib/std/object.lua: Improve documentation. - - doc: add prototype chains to object LDocs. - * lib/std/list.lua, lib/std/set.lua, lib/std/strbuf.lua, - lib/std/tree.lua, lib/std/vector.lua: LDocument prototype chains. - - doc: simplify and clarify container and object LDocs. - * lib/std/object.lua, lib/std/container.lua: Simplify and clarify - LDocs. - - doc: fix a broken cross-reference. - * lib/std/container.lua (std.container): Now that we're not - documenting inherited methods, reference std.object.__call from - the prototype object. - * HACKING: Document rationale for slimming LDocs in this way. - - debug: argcheck accepts objects as valid table type arguments. - Closes #84. - Really, table is the base type of object (or strictly speaking, - container), and its almost always desirable to be able to pass - objects to functions that operate on tables. - * specs/debug_spec.yaml (argcheck): Specify this behaviour when - an object argument is given where a table is required. - * lib/std/debug.lua (argcheck): Accept any object argument - where a table parameter is expected. - -2014-08-30 Gary V. Vaughan - - table: deprecate totable. - Closes #74. - * specs/container_spec.yaml (tablification): Remove specs. - * specs/object_spec.yaml (copy): Use this new function instead of - `totable`. - * specs/object_spec.yaml, specs/set_spec.yaml, - specs/strbuf_spec.yaml, specs/tree_spec.yaml (__totable): Remove. - * specs/table_spec.yaml (totable): Deprecate this function. - * specs/spec_helper.lua (totable): Remove. - * lib/std/table.lua (totable): Likewise. - * lib/std/base.lua (totable): Remove implementation. - * lib/std.lua.in (barrel): Remove "table.totable". - * lib/std/container.lua (__totable): Remove. - (__pairs): Return elements in order, omitting private elements. - (__tostring): Use it to concatenate elements in order. - (__call, instantiate, mapfields): Iterate with `next` to fetch - raw elements, rather than ordered object __pairs elements. - * lib/std/object (__totable): Remove reference. - * lib/std/set.lua (__totable): Remove. - (__tostring): Fetch keys for display using std.pairs. - * lib/std/string.lua (pickle): Likewise. - * NEWS: Update. - -2014-08-29 Gary V. Vaughan - - doc: overhaul LDocs for std.table. - * lib/std/table.lua: Tidy up LDocs, and add @usage examples. - -2014-08-28 Gary V. Vaughan - - table: add remove for orthogonality with insert. - * specs/table_spec.yaml (remove): Specify expected behaviour. - * lib/std/table.lua (remove): Implement specified behaviors. - * NEWS: Update. - - refactor: modules can only require std.base and std.debug. - * lib/std/table.lua (totable): Move implementation from here... - * lib/std/base.lua (totable): ...to here. - * lib/std/string.lua: Import core implementation from std.base - instead of argcheck wrapper from std.table. - * lib/std/io.lua (dirsep, catfile): Move implementations from - here... - * lib/std/string.lua (escape_pattern): ...here... - * lib/std/table.lua (invert): ... and here... - * lib/std/base.lua (dirsep, catfile, invert): ...to here. - * lib/std/package.lua: Import core implementations from std.base - instead eof argcheck wrappers from user interface files. - * lib/std/list.lua, lib/std/tree.lua (func): Remove spurious - require. - * lib/std/set.lua, lib/std/tree.lua, lib/std/vector.lua - (container): Fold into Container prototype constructor. - * lib/std/list.lua, lib/std/strbuf.lua (object): Fold into - Object prototype constructor. - * lib/std/string.lua (strbuf): Fold into StrBuf prototype - constructor. - * lib/std/math.lua (debug): Fold into X definition. - * HACKING: Add a description of how to use `require` - idiomatically in stdlib source. - - table: ensure there is always a maxn function. - * specs/table_spec.yaml (maxn): Specify behaviour of maxn. - (len): Add missing specifications. - * specs/std_spec.yaml (barrel): Add maxn to list of monkey_patch - apis from std.table. - * lib/std/base.lua (maxn): Use core table.maxn if available, or - else define our own. - * lib/std/container.lua, lib/std/debug.lua: Use it! - * lib/std/table.lua (maxn): Export it. - * NEWS: Update. - - refactor: make all monkey_patch functions work the same. - * specs/std_spec.yaml, specs/io_spec.yaml, specs/math_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml (monkey_patch): - Specify injection of all exported apis into the given namespace. - * lib/std/base.lua (copy): Support an optional `dest` argument. - (merge): Like copy, but don't overwrite pre-existing entries at - the same key. - * lib/std.lua.in, lib/std/io.lua, lib/std/math.lua, - lib/std/string.lua, lib/std/table.lua: Use merge and copy to - simplify tracking and injecting monkey_patches. - * specs/std_specl.yaml (barrel): Specify behaviour of running all - monkey_patch functions, and recreating the legacy global api by - additionally injecting those functions. - * lib/std.lua.in (barrel): Update to meet tighter specifications. - * HACKING: Note about global hygiene and use of monkey_patch (). - * NEWS: Update. - -2014-08-27 Gary V. Vaughan - - package: tidy up LDocs, and remove unnecessary M references. - * lib/std/package.lua (pathsub, find): Remove spurious `M.` - prefixes. - (mappath_callback): Rename from this... - (mappathcb): ...to this. - * HACKING: Add LDoc style notes. - - functional: remove std.operator expansions from lambda. - There's no good reason to clog up the lambda functable with a copy - of std.operator, when we can just pass the operators without - interposing lambda if we need to. - * lib/std/functional.lua (lambda): Remove std.operator expansions. - * NEWS: Update. - - operator: more RSI-reducing operator function name changes. - * specs/operator_spec.yaml (cons, length): Remove - just pass - `table.pack` or `table.len` instead, resp. - (["and"], ["or"], ["not"]): Rename these... - (conj, disj, neg): ...to these. - * lib/std/operator.lua: Likewise. - Give full and proper LDocs for each function. - * lib/std/functional.lua (M.op): Update deprecation redirections. - * NEWS: Update. - - refactor: reorder function definitions in base.lua. - * lib/std/base.lua: Rather than mostly random order, subject to - interdepencies, put functions in asciibetical order as far as - possible while avoiding forward declarations. - * HACKING: Update. - - table: diagnose insert out of bounds arguments on all Lua. - * specs/table_spec.yaml (insert): Adjust errors to include out of - bounds position. - * lib/std/debug.lua (argerror): Move implementation from here... - * lib/std/base.lua (argerror): ...to here. - (insert): Use it to diagnose out of bounds arguments. - * NEWS: Update. - - table: add missing specs for table.insert, and correct argtypes. - * specs/table_spec.yaml (insert): Specify behaviours. - * lib/std/table.lua (insert): Don't double import. - (M): Don't allow nil valued final argument. - - table: new insert method. - * specs/table_spec.yaml (insert, len): Specify behaviours. - * lib/std/base.lua (insert, last): New functions that - respect `__len` when calculating table length. - (len): Use callable to extract __len metamethod. - * HACKING: New file to document coding style and design choices. - * lib/std/base.lua, lib/std/container.lua, lib/std/debug.lua, - lib/std/io.lua, lib/std/list.lua, lib/std/optparse.lua, - lib/std/strbuf.lua, lib/std/string.lua, lib/std/table.lua, - lib/std/tree.lua, lib/std/vector.lua: Follow HACKING rules for - use of len and insert. - * NEWS: Update. - - refactor: assorted simplifications to std.table. - * lib/std/table.lua (merge_allfields): Use `nil` for unspecified - `map` argument, and when `nil` use a faster inner loop for - copying. - (merge_namedfields): Use `nil` for unspecified `keys` argument. - (clone): Unroll into export table. - (depair, keys): Use ipairs and dummy variable, rather than ielems. - (pack): Remove duplicate definition. - - refactor: remove arglen, duplicates table.maxn functionality. - * specs/debug_spec.yaml (arglen): Remove specifications. - * lib/std/debug.lua (arglen): Remove. - * lib/std/container.lua (M.__call), lib/std/debug.lua (match) - (argcheck): Change all callers to use table.maxn instead. - -2014-08-26 Gary V. Vaughan - - operator: use non-RSI inducing operator function names. - * lib/std/operator.lua ([".."], ["[]"], ["{}"], ["#"], ["+"]) - (["-"], ["*"], ["/"], ["%"], ["^"], ["=="], ["~="], ["<"], ["<="]) - ([">"], [">="]): Rename from these... - (concat, deref, cons, length, sum, diff, prod, quot, mod, pow, eq) - (neq, lt, lte, gt, gte): ...to these. - (['""']): Remove. Just pass the tostring function. - (["~"]): Remove. Just pass string.find. - Adjust all callers. - * NEWS: Update. - - functional: deprecate functional.op properly. - * specs/functional_spec.yaml (op): Specify deprecation warnings - when using old functional.op API. - * lib/std/functional.lua (M.op): Deprecate old APIs. - * NEWS: Update. - - refactor: modernize std/debug.lua. - * lib/std/debug.lua: Reorder declarations and LDocs to match - latest style. - - std: commit missed change to lib/std.lua.in. - * lib/std.lua.in (X): Update export call to argscheck. - - doc: improve LDoc usage examples in std.debug. - * lib/std/debug (DEPRECATIONMSG, DEPRECATED): Improve LDoc usage - examples. - - refactor: merge debug.argscheck and debug.export. - * lib/std/debug.lua (argscheck): Remove. - (export): Rename to argscheck. - Adjust all callers. - - refactor: merge lib/std/base files into std.base. - * lib/std/base/functional.lua (callable, collect, reduce): Move - from here... - * lib/std/base/string.lua (copy, render, split): ...here... - * lib/std/base/tree.lua (leaves): ...and here... - * lib/std/base.lua (callable, collect, reduce, copy, render) - (split, leaves): ...to here. - Adjust all callers. - * lib/std/base/functional.lua, lib/std/base/string.lua, - lib/std/base/tree.lua: Remove files. - * local.mk (luastdbasedir, dist_luastdbase_DATA): Remove. - - refactor: std.vector simplifications. - * lib/std/vector.lua: Fix usage examples to use `avector` instead - of `anvector`. - (set): Factor away use of debug.argscheck. - - refactor: simplify export implementation and api. - * specs/debug_spec.yaml (export): specify behaviours with - explicit arguments instead of introspection. - * lib/std/debug.lua (export): expect explicit declaration string - with argument types, and inner function. - (whatpath, getinfo): Remove unused introspection functions. - * lib/std.lua.in, lib/std/base/string.lua, lib/std/functional.lua, - lib/std/io.lua, lib/std/list.lua, lib/std/math.lua, - lib/std/package.lua, lib/std/string.lua, lib/std/table.lua: - Move LDocs and export declarations to module table constructors. - - refactor: remove obsolete __ipairs specs. - stdlib no longer supports __ipairs metamethods. - * specs/vector_spec.yaml (__ipairs): Remove. - - list: remove workaround for old module metadata layout. - * lib/std/list.lua (transpose): Remove workaround for old module - data layout. - - refactor: simplify functional.memoize. - * lib/std/functional.lua (memoize): Remove spurious require and - associated comment. - -2014-08-25 Gary V. Vaughan - - refactor: use toomanyargmsg function instead of toomanyarg_fmt string. - * lib/std/debug.lua (toomanyarg_fmt): Remove. - (toomanyargmsg): A replacement function that returns the formatted - string. Adjust all callers. - * specs/debug_spec.yaml (extend_base): Adjust accordingly. - - refactor: factor getcompat and setcompat out of debug api. - * specs/debug_spec.yaml (getcompat, setcompat): Remove. - * lib/std/debug.lua (DEPRECATIONMSG): Use getcompat and setcompat - internally, returning an empty string if necessary. - (DEPRECATED): Don't use getcompat or setcompat now that - DEPRECATIONMSG does that. - (M): Remove getcompat and setcompat. - * lib/std/functional.lua (bind): Simplify. - - refactor: move DEPRECATED, export et.al. from `base` to `debug`. - * specs/base_spec.yaml (export, DEPRECATED): Move from here... - * specs/debug_spec.yaml (export, DEPRECATED): ...to here. - * specs/base_spec.yaml: Remove unused file. - * specs/specs.mk (specl_SPECS): Remove specs/base_spec.yaml. - * lib/std/base.lua (DEPRECATED, DEPRECATIONMSG, argcheck) - (argerror, arglen, argscheck, export, getcompat, setcompat) - (toomanyarg_fmt): Move from here... - * lib/std/debug.lua (DEPRECATED, DEPRECATIONMSG, argcheck) - (argerror, arglen, argscheck, export, getcompat, setcompat) - (toomanyarg_fmt): ...to here. Adjust all callers. - * lib/std/base.lua (argpairs, checktype, concat, formaterror) - (getfenv, getinfo, match, merge, normalize, permutations) - (setfenv, whatpath): Move from here... - * lib/std/debug.lua (argpairs, checktype, concat, formaterror) - (getfenv, getinfo, match, merge, normalize, permutations) - (setfenv, whatpath): ...to here, but elide their definitions - if _DEBUG.argcheck is false, or equivalent. - * NEWS: Update. - - refactor: break std.debug dependency on std.functional and std.string. - * specs/debug.spec (say): Specify usage of std.tostring. - * lib/std/debug.lua (tabify): Remove. - (say) Manually unroll functional compose sequence, formerly - knows as tabify. - (trace): Manually unroll and consequently remove string.rep call. - - base: support module name override with std.base.export. - * lib/std/base/list.lua (compare): Move from here... - * lib/std/base.lua (compare): ...to here. - * lib/std/base/list.lua: Remove. - * local.mk (dist_luastdbase_DATA): Remove lib/std/base/list.lua. - * lib/std/list.lua (M.compare): Provide explicit module name - argument. - * lib/std/base.lua (export): If an explicit module name was - passed, use that instead of reverse engineering it from the - source file containing an exported function. - -2014-08-24 Gary V. Vaughan - - base: remove export table metadata. - * lib/std/base.lua: Remove export table metadata. - - refactor: simplify std.require, and improve error diagnostics. - Closes #78. - * specs/std_spec.yaml (require): Specify better diagnostics on - failure. - * lib/std/list.lua (compare): Move from here... - * lib/std/base/list.lua (compare): ...to here. - * local.mk (dist_luastdbase_DATA): Add lib/std/base/list.lua. - * lib/std/base.lua: Break dependency on "std.list". - (require): Use base.list.compare directly, and show verbose - diagnostics on failure. - (module_version, version_to_list): Remove; no longer used. - * NEWS: Update. - - refactor: remove spurious comments from base.lua. - * lib/std/base.lua: Remove spurious comments. - -2014-08-23 Gary V. Vaughan - - maint: fix a typo in std.lua.in. - * lib/std.lua.in (export): Import this symbol correctly. - - refactor: simplify use of export by looking up local functions. - Prior to this changeset, export worked by creating an argument - checking wrapper function when called with an inner function, a - destination table containing metadata and the argument spec - string. The metadata leaked out into the library interface, as - well as other assorted clunkiness. Clean up and simplify the - whole thing. - * specs/spec_helper.lua (badarg): Adjust to produce consolidated - error messages. - * specs/functional_spec.yaml, specs/list_spec.yaml, - specs/std_spec.yaml: Remove element `1` from expected entries in - export table, now that metadata isn't leaked. - * specs/base_spec.yaml (DEPRECATED, export): Remove argument - checking specifications. - * lib/std/base.lua (getinfo): New functions. Use `debug.getinfo` - to lookup a local function in the given scope given only its - name. - (whatpath): Cross reference the package.path and function source - file from `debug.getinfo` to reverse engineer the module path - passed to require that was used to load this function. - (export): Remove all vestiges of hard-coded module metadata from - the destination table, and passing of an inner function; instead - look everything up using introspection and the new functions - above. Don't stash the result in a table parameter, return it. - Adjust all callers. - (copy, render, split): Move from here... - * lib/std/base/string.lua (copy, render, split): New file. ...to - here, so that base.whatpath reports the correct module path. - * local.mk (dist_luastdbase_DATA): Add lib/std/base/string.lua. - * lib/std/container.lua, lib/std/debug.lua, - lib/std/functional.lua, lib/std/io.lua, lib/std/list.lua, - lib/std/math.lua, lib/std/package.lua, lib/std/string.lua, - lib/std/table.lua (M): Remove metadata, rebuild after exported - functions' local declarations. - * NEWS: Update. - -2014-08-21 Gary V. Vaughan - - functional: have callable return the function rather than a bool. - * specs/functional_spec.yaml (callable): Adjust to check that - return values are the actual function. - * lib/std/base/functional.lua (callable): Return the actual - function. - - specs: break dependency on M[1], M[2] in badarg. - That is, polluting the exported module tables with the module - name (M = {"std.base"}) and object name (M = {"std.list", "List"}) - for argument error message text generation is ugly. - * specs/spec_helper.lua (badarg): Require an explicit module - name arg, and use it instead of relying on M[1]. - * specs/base_spec.yaml, specs/debug_spec.yaml, - specs/functional_spec.yaml, specs/io_spec.yaml, - specs/list_spec.yaml, specs/math_spec.yaml, - specs/package_spec.yaml, specs/std_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml: Pass the explicit - module name arg to badarg calls. - * specs/list_spec.yaml: The goal is not to output different - error messages when called with ':' syntax than with '.' syntax. - Move module function argument check specifications into higher - scope; remove object method argument check specifications - entirely. - -2014-08-18 Gary V. Vaughan - - maint: prepare lib/std/list.lua for deprecation-apocalypse! - Almost half of lib/std/list.lua is only there to take care of - warning about deprecated usage. - * lib/std/list.lua: Group all deprecation support code in one - huge block ready for quick and easy annihilation in due course. - - refactor: move list.depair and list.enpair into std.table. - * specs/table_spec.yaml (depair, enpair): Specify full behaviours. - * specs/list_spec.yaml (depair, enpair): Specify deprecation - warnings. - * lib/std/list.lua (depair, enpair): Move from here... - * lib/std/table.lua (depair, enpair): ...to here. - * NEWS: Update. - -2014-08-18 Gary V. Vaughan - - Revert "list: exchange parameter order for list.cons." - This reverts commit 1b290ee40f638b03a4dd4b3c4f5b8faa6cdd2479. - - - Conflicts: - lib/std/list.lua - specs/list_spec.yaml - -2014-08-18 Gary V. Vaughan - - maint: disable specl rock version check by bootstrap. - Specl 13 is not released yet, but we're relying on some fixes - it has. - * bootstrap.conf (buildreq): Disable specl temporarily. - - travis: use unreleased specl rockspec. - * .travis.yml (script): Use specl-git-1.rockspec from github. - - refactor: move `list.project` to `table.project`. - * specs/table_spec.yaml (project): Specify behaviours of project. - * specs/list_spec.yaml (project): Specify deprecation warnings. - * lib/std/list.lua (project): Move from here... - * lib/std/table.lua (project): ...to here. - * NEWS: Update. - - refactor: move `list.shape` to `table.shape`. - * specs/table_spec.yaml (shape): Specify full behaviours. - * specs/list_spec.yaml (shape): Specify deprecation warnings. - * lib/std/list.lua (shape): Move from here... - * lib/std/table.lua (shape): ...to here. - * NEWS: Update. - -2014-08-18 Gary V. Vaughan - - refactor: move list.flatten to table.flatten. - * specs/list_spec.yaml (flatten): Specify deprecation warnings. - * specs/functional_spec.yaml (flatten): Move from here... - * specs/table_spec.yaml (flatten): ...to here. - * lib/std/list.lua (flatten): Move from here... - * lib/std/table.lua (fatten): ...to here. - * lib/std/functional.lua (collect): Move core from here... - * lib/std/base/functional.lua (collect): ...to here. - - * specs/list_spec.yaml (flatten): Deprecated properly. - * lib/std/list.lua (flatten): Wrap object method in deprecation - warning. - -2014-08-18 Gary V. Vaughan - - list: deprecate filter in favour of functional.filter. - * specs/list_spec.yaml (filter): Specify deprecation messages. - * lib/std/list.lua (filter): Deprecated. - * NEWS: Update. - - list: properly deprecate `list.map` to match NEWS. - * specs/list_spec.yaml (map): Deprecated properly. - * lib/std/base/functional.lua (map): Move from here... - * lib/std/functional.lua (map): ...back to here. - * lib/std/list.lua (map): Reinstate deprecated version of this - function locally, for simplicity. - - doc: document list.cons arguments in the correct order. - * lib/std/list.lua (cons): Fix LDoc to display parameters in the - correct order. - - list: export all apis for automatic argument type checking. - * specs/list_spec.yaml: Specify argument checking of all apis. - * lib/std/functional.lua (map): Move core function from here... - * lib/std/base/functional.lua (map): ...to here. - * lib/std/list.lua (project, map, map_with, transpose): Use it. - (m): Collect exported object methods here. - (List.__index): Set to m. - - refactor: simplify deprecation specs. - * lib/std/base.lua (DEPRECATED): Use `name` as the key into the - table for recording whether each deprecation message has been - output yet... it's more likely to be unique than the inner - function address, which might be shared between a module function - and object method. - * specs/functional_spec.yaml, specs/list_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml: Simplify - specifications for deprecation warning. - - specs: fix os.execute thinko. - * specs/spec_helper.lua (LUA): No need to repeat ourselves by - looking for lua in the PATH with which and again at runtime. - - configury: use static specs/spec_helper.lua. - No need to generate this file just to substitute @LUA@, just - use os.getenv "LUA" in a static file instead. - * specs/spec_helper.lua.in: Move from here... - * specs/spec_helper.lua: New file. ...to here. - (LUA): Set from LUA environment, or call `which lua` or just rely - on path search for "lua". - * .gitignore: Remove specs/spec_helper.lua. - * configure.ac (AC_CONFIG_FILES): Remove specs/spec_helper.lua - generator. - * specs/specs.mk (specs_path, spec-check-local): Remove. - (SPECL_ENV): Simplify. - (EXTRA_DIST): Adjust. - * specs/io_spec.yaml (process_files, readlines, slurp) - (writelines): Don't rely on specs/spec_helper.lua being in the - builddir, in case of VPATH builds. - - travis: add .slackid for slack notifications. - * .slackid: New file. - * .travis.yml: Regenerate. - - slingshot: sync with upstream, for slack notifications. - * slingshot: Sync with upstream. - * .travis.yml: Regenerate. - - maint: remove stale files from .gitignore. - * .gitignore: Remove unused /m4/ax_compare_version.m4. - -2014-08-17 Gary V. Vaughan - - refactor: use to_raise matcher alias consistently. - Slingshot sanity checks flag strings with an initial capital - following 'error' as bad style. Rather than switch off that - check, use a matcher alias. - * build-aux/sanity-cfg.mk (sc_error_message_uppercase): Remove - spec-files from regexp. - specs/base_spec.yaml, specs/container_spec.yaml, - specs/debug_spec.yaml, specs/functional_spec.yaml, - specs/io_spec.yaml, specs/list_spec.yaml, specs/math_spec.yaml, - specs/optparse_spec.yaml, specs/package_spec.yaml, - specs/std_spec.yaml, specs/string_spec.yaml, - specs/table_spec.yaml, specs/tree_spec.yaml, - specs/vector_spec.yaml: s/to_error/to_raise/ - s/not_to_raise ()/not_to_raise "any error"/ - - refactor: simplify argument error specifications. - * specs/spec_helper.lua.in (toomanyarg): Remove. - (badarg): Now file local, and treats one or two numeric args as - a `too many arguments` error request. - (init): Prebind badarg module and function names. - * lib/std/base.lua: Add M[1] for error message matching. - * specs/container_spec.yaml (construction): Unroll non-generated - bad argument error messages. - * specs/base_spec.yaml, specs/debug_spec.yaml, - specs/functional_spec.yaml, specs/io_spec.yaml, - specs/list_spec.yaml, specs/math_spec.yaml, - specs/package_spec.yaml, specs/std_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml: Simplify argument - error specifications. - -2014-08-16 Gary V. Vaughan - - base: support zero argument exports. - * specs/base_spec.yaml (export): Remove specification for zero - argument export error. - * lib/std/base.lua (export): Remove zero argument error. - * specs/base_spec.yaml (export): Specify argument checking of - zero argument exports. - * lib/std/base.lua (export): Support zero arguments. - - base: ensure export errors report callsite in stack trace. - * specs/base_spec.yaml (export): Finish and simplify mkstack(). - Specify callsite line numbers in export errors. - * lib/std/base.lua (formaterror): Allow expectedtypes to be a - string. - (export): Use it to generate error messages. - (export): Set levels correctly for correct callsite reporting. - -2014-08-15 Gary V. Vaughan - - refactor: move list.flatten to functional.flatten. - * lib/std/list.lua (flatten): Deprecate. - * lib/std/functional.lua (flatten): Export from here. - * specs/list_spec.yaml, specs/functional_spec.yaml: Adjust. - * NEWS: Update. - - refactor: merge most of std.base.functional back into functional. - * lib/std/base/functional.lua: Remove comment about needing to - wait until deprecated access points are gone before merging. - (foldl, foldr, memoize, nop): Move from here... - * lib/std/functional.lua (foldl, foldr, memoize, nop): ...to here. - * lib/std/list.lua (foldl, foldr): Keep a file local copy of - these functions to satisfy deprecated access points. - - refactor: share leaves implementation from new std.base.tree. - * lib/std/base.lua (leaves): Move from here... - * lib/std/base/tree.lua (leaves): New file. ...to here. - * local.mk (dist_luastdbase_DATA): Add lib/std/base/tree.lua. - * lib/std/io.lua, lib/std/list.lua, lib/std/tree.lua: Adjust. - - refactor: use new functional apis in std.tree. - * lib/std/tree.lua (reduce, operator): Use these... - (fold, op): ...instead of these. - - functional: new zip and zip_with replace list transpose and zip_with. - * specs/functional_spec.yaml (zip, zip_with): Specify behaviour - of new general zip and zip_with apis. - * lib/std/functional.lua (zip, zip_with): New functions. - * lib/std/list.lua (transpose, zip_with): Deprecate. - * specs/list_spec.yaml (transpose, zip_with): Specify deprecation - warning behaviours. - * NEWS: Update. - -2014-08-14 Gary V. Vaughan - - list: deprecate list.map. - * specs/list_spec.yaml (map): Specify output of deprecation - warning on first call. - * specs/debug_spec.yaml (debug, say): Use functional.map for - mkwrap instead of deprecated list.map. - * lib/std/list.lua (map): Deprecate. - * NEWS: Update. - - functional: support default iterators where possible. - * specs/functional_spec.yaml (collect, filter, map): Specify - behaviours when iterator argument is omitted. - * lib/std/functional.lua (collect): Default iterator to ipairs. - (filter, map): Default iterator to pairs. - * NEWS: Update. - - functional: new callable module function. - * specs/functional_spec.yaml (callable): Specify correct behaviour - for new callable function. - * lib/std/functional.lua (iscallable): Move from here... - * lib/std/base/functional.lua (callable): ...to here. Adjust all - callers. - * lib/std/functional.lua (M.callable): Reexport as a public api. - * NEWS: Update. - - functional: improve LDocs for consistency and clarity. - * lib/std/functional.lua: Be consistent with parameter names in - all functions. - Be consistent with usage example formats. - Be consistent with lambda string quoting in examples. - -2014-08-13 Gary V. Vaughan - - functional: replace list.map_with using new functional.map_with. - * specs/functional_spec.yaml (map_with): Specify behaviour of - improved map_with implementation that handles tables. - * lib/std/functional.lua (map_with): Improved implementation of - `list.map_with`. - * lib/std/list.lua (map_with): Deprecate. - * specs/list_spec.yaml (map_with): Adjust accordingly. - * NEWS: Update. - - list: factor out manual argument checking. - * lib/std/list.lua (depair, map_with, project, transpose) - (zip_with): Use new "container of thing" support in export type- - lists to replace manual checks. - (_ARGCHECK): Remove. No longer used. - * specs/list_spec.yaml (depair, map_with, project, transpose) - (zip_with): Adjust error expectations accordingly. - - debug: support "container of homogenous_thing" in argcheck. - * specs/debug_spec.yaml (argcheck): Specify behaviours when - checking for combinations of "List of table" variations. - * lib/std/base.lua (formaterror): Add optional index parameter, - and diagnose errors that use it with new "type at index N" - format; otherwise, simplify "List of table" strings in - expectedtypes to just "List" when the error is in the outer - type matching. - (checktype): Abstracted out of `argcheck`. - (argcheck): Simplify accordingly. - Detect and diagnose element mismatches with "List of table" - expected types. - (export): Likewise. - (typeof): Factored out entirely. - - list: update LDocs. - * lib/std/list.lua: Add @function and @static keywords. - - list: base.export module functions for improved argchecks. - * lib/std/list.lua (_functions): Rename from this... - (M): ...to this. Add a module name entry for export. - * specs/list_spec.yaml (exported_apis): Adjust accordingly. - (append, compare, concat, filter, flatten, map, project, rep) - (sub, tail, transpose, zip_with): Modernize badarg error - specifications. Specify "too many arguments" error behaviours. - * lib/std/list.lua (cons): Store in M; adjust getcompat/setcompat - id. - (map_with, project, transpose, zip_with): Use export for improved - argchecks. - (append, compare, concat, depair, enpair, filter, flatten, map) - (rep, shape, sub, tail): Likewise. Remove manual argcheck calls. - - specs: specify `std.list` apis. - * specs/list_spec.yaml (std.list): Add specs for exported apis, - and global table hygiene. - - string: remove unused local. - * lib/std/string.lua (render): Remove unused local. - - refactor: split out base functions for `std.functional`. - * lib/std/base.lua (foldl, foldr, memoize, nop, reduce): Move - from here... - * lib/std/base/functional.lua (foldl, foldr, memoize, nop) - (reduce): New file. ...to here. - * lib/std/functional.lua, lib/std/list.lua: Adjust imports - accordingly. - * local.mk (luastdbasedir, dist_luastdbase_DATA): Install new - file correctly. - - refactor: move list.foldl and list.foldr to std.functional. - Move the documented location for foldl and foldr from list.lua - to functional.lua, modernizing specs as we go. Keep the old - access points, with a deprecation warning. - * lib/std/list.lua (foldl, foldr): Move from here... - * lib/std/base.lua (foldl, foldr): ...to here. - * lib/std/functional.lua (reduce): Move from here... - * lib/std/base.lua (reduce): ...to here, where foldl and foldr - can use it. - * specs/list_spec.yaml (foldl, foldr): Copy from here... - * specs/functional_spec.yaml (foldl, foldr): ...to here. - * specs/base_spec.yaml (before): Don't depend on the location of - implementation of nop. - * NEWS: Update. - - travis: add slack notifications. - * .travis.yml (notifications): Add slack. - -2014-08-11 Gary V. Vaughan - - refactor: move lambda back to std.functional. - * lib/std.lua.in (lambda): Move from here... - * lib/std/base.lua (lamba): ...and here... - * lib/std/functional.lua (lambda): ...to here. - * specs/functional_spec.yaml, specs/std_spec.yaml: Adjust - accordingly. - * lib/std/base.lua (tostring): Unroll lambda calls. - * lib/std/operator.lua ("#"): Move implementation from here... - * lib/std/base.lua (len): ...to here. Adjust all callers. - (_len): Remove. - (operator): Remove unused require statement - * lib/std/list.lua (transpose): Unroll lambda call. - * NEWS: Update. - - functional: new `cond` function. - * specs/functional_spec.yaml (cond): Specify behaviour of a new - cond function. - * lib/std/functional.lua (cond): Satisfy specified behaviours. - * NEWS: Update. - - functional: process non-function branch values with case. - * specs/functional_spec.yaml (case): Specify behaviours with new - functable and non-callable branch values. - * lib/std/functional.lua (case): Call functables as if they were - regular functions, and return non-callable values directly. - * NEWS: Update. - - specs: add exported api specification to functional_spec.yaml. - * specs/functional_spec.yaml (std.functional): Specify exported - apis. - - refactor: functional.eval issues a deprecation warning. - * specs/functional_spec.yaml (eval): Specify deprecation warning. - * lib/std/functional.lua (eval): Deprecated. - * NEWS: Update. - - refactor: move memoize back to std.functional. - * specs/std_spec.yaml (memoize): Move from here... - * specs/functional_spec.yaml (memoize): ...to here. - * lib/std.lua.in (memoize): Move from here... - * lib/std/functional.lua (memoize): ...to here. - * NEWS: Update. - - refactor: move case back to std.functional. - * specs/std_spec.yaml (case): Move from here... - * specs/functional_spec.yaml (case): ...to here. - * lib/std/base.lua (case): Move implementation from here.. - * lib/std.lua.in (case): ...and argcheck wrapper from here... - * lib/std/functional.lua (case): ...to here. - * lib/std/package.lua (path_sub): Decouple from std.functional by - comparing manually rather than using functional.case. - -2014-08-07 Gary V. Vaughan - - functional: rename fold to reduce. - * specs/functional_spec.yaml (fold): Remove argument checking - specifications. - Add deprecation warning specification. - (reduce): Specify identical behaviour to old fold api. - * lib/std/functional.lua (fold): Rename from this... - (reduce): ...to this. - (fold): Show a deprecation warning on first use. - * specs/container_spec.yaml (construction): Adjust. - * lib/std/list.lua (foldl, foldr): Use functional.reduce instead - of deprecated functional.fold. - * lib/std.lua.in (barrel): Install _G.fold from - `std.functional.reduce`. - * specs/std_spec.yaml (barrel): Adjust. - * NEWS: Update. - - functional: map supports key:value remapping functions. - * specs/functional_spec.yaml (map): Specify behaviour of passing - all iteration return values to mapping function; and remapping - when mapping function returns a key:value pair. - * lib/std/functional.lua (map): Collect all iteration return - values and propagate them to the mapping callback function. - If there are two values returned from the callback, treat them as - a key and value for setting in the results table. - * NEWS: Update. - - functional: fold supports multi-return iterators. - * specs/functional_spec.yaml (fold): Specify behaviour with - iterators that return multiple values. - * lib/std/functional.lua (fold): Collect all values returned by - iterator and operate on the last one of those. - * specs/container_spec.yaml (construction): Fold dereferences - automatically, no need to manually dereference any more. - * NEWS: Update. - - doc: add LDoc Type section for callback function signatures. - * lib/std.lua.in (normalizecb): Document signature of memoize - callback function. - (memoize): Set type of *normalize* argument to new `normalizecb` - signature. - * lib/std/functional.lua (predicate): Document signature for a - predicate function. - (filter): Set type of *p* argument to new `predicate` signature. - * lib/std/io.lua (fileprocessor): Document signature of - process_files callback function. - (process_files): Set type of *fn* to new `fileprocessor` function. - * lib/std/string.lua (opentablecb, closetablecb, elementcb) - (paircb, separatorcb): Document signature for render callback - functions. - (render): Set type of callback functions accordingly. - * lib/std/table.lua (comparator): Document signature of sort - comparison function. - (sort): Set type of *c* argument to new `comparator` signature. - - functional: filter supports multi-parameter predicates. - * specs/functional_spec.yaml (filter): Specify behaviours when - called with an iterator that returns multiple values, and - predicate that accepts multiple parameters. - * lib/std/functional.lua (filter): Collect all results from - iterator function, and propagate them all to the predicate call. - * NEWS: Update. - - functional: collect creates tables from multi-return iterators. - * specs/functional_spec.yaml (collect): Differentiate behaviours - of calling collect with single return versus multiple return - iterators. - * lib/std/functional.lua (collect): Inject new elements into the - collected values table using key:value pairs when the iterator - returns more than one value. - * NEWS: Update. - - maint: bump copyright years. - * README.md: Bump copyright years to include 2014. - - maint: Update AUTHORS file. - * AUTHORS: Update. - - maint: use fully qualified api names in all deprecation messages. - * specs/list_spec.yaml (elems, index_key, index_value, relems) - (reverse, :depair, :map_with, :transpose, :zip_with): Specify - fully qualified api name in deprecation message. - * specs/string_spec.yaml (assert, require_version, tostring): - Likewise. - * specs/table_spec.yaml (clone_rename, metamethod, ripairs): - Likewise. - * lib/std/list.lua (elems, index_key, index_value, relems) - (reverse, :depair, :map_with, :transpose, :zip_with): Add `std.` - prefix to deprecation messages. - * lib/std/string.lua (assert, require_version, tostring): - Likewise. - * lib/table.lua (clone_rename, metamethod, ripairs): Likewise. - - functional: report bind api deprecations correctly. - * specs/functional.yaml (bind): Specify deprecation warning - behaviour when called with the legacy multi-argument parameter - passing. - * lib/std/functional.lua (bind): Use new getcompat/setcompat - internal apis to report deprecation of legacy calling convention. - - base: unwrap functables before calling debug.setenv on Lua 5.1. - * lib/std/base.lua (setfenv): Unwrap functables unconditionally, - before delegating to `debug.setfenv` or Lua 5.2 emulation. - - base: propagate environments through export argcheck wrappers. - * lib/std/base.lua (debug): Rename from this... - (debug_init): ...to this. - (_ARGCHECK, _DEBUG): Adjust accordingly. - (getfenv, setfenv): Compatibility functions for Lua 5.2. - (export): When returning argchecking wrapper function, propagate - the wrapper's function environment to the inner function. - * specs/base_spec.yaml (export): Adjust mkmagic not to rely on - out-of-scope MAGIC table. - -2014-08-05 Gary V. Vaughan - - list: exchange parameter order for list.cons. - Closes #72. - * specs/list_spec.yaml (cons): Modernize specifications. - Specify deprecation warning behaviour when calling cons with - arguments in legacy order. - * lib/std/list.lua (cons): If arguments appear to be in the - wrong order, issue a deprecation warning and rewrite them into - the correct order. - * NEWS: Update. - - refactor: break apart base.DEPRECATED for component reuse. - * lib/std/base.lua (DEPRECATIONMSG, getcompat, setcompat): New - functions, factored out of... - (DEPRECATED): ...here. Simplify accordingly. - - refactor: use std.ipairs and std.pairs everywhere internally. - * lib/std/container.lua, lib/std/functional.lua, lib/std/io.lua, - lib/std/list.lua, lib/std/optparse.lua, lib/std/package.lua, - lib/std/set.lua, lib/std/string.lua, lib/std/table.lua, - lib/std/tree.lua, lib/std/vector.lua: Import and use `base.ipairs` - and `base.pairs` everywhere - * NEWS: Update. - - specs: capture list.map_with deprecation warning. - * specs/list_spec.yaml (map_with): Modernize specifications for - argument checking, split module function and object method - specifications, and capture deprecation warning for list:map_with - on first invocation. - - std: remove __ipairs support in favour of 1..#t iteration. - * specs/std_spec.yaml (ipairs, ireverse, ripairs): Adjust - specifications to verify treatment of __len metamethod, and - ignore __ipairs metamethod. - * lib/base.lua (ipairs): Using __len if available, or # operator - otherwise, iterate over elments 1..#t. - (unwrap__ipairs): Remove. Simplifications above make this - function superfluous. - (ripairs, ireverse): Adjust accordingly. - * lib/std/vector.lua (core_metatable.__ipairs) - (alien_functions.__ipairs): Remove. - * lib/std.lua.in (ipairs, ireverse, ripairs): Update LDocs. - * NEWS: Update. - -2014-08-04 Gary V. Vaughan - - refactor: factor away math.pow. - Upcoming Lua 5.3 deprecates `math.pow` in favour of the `^` - operator. We can easily eliminate stdlib's references to - `math.pow` for future compatibility. - * lib/std/operator.lua ("^"): Use `^` rather than `math.pow`. - * lib/std/functional.lua (bind, fold): Use "^" lambda function - instead of `math.pow` in LDocs. - -2014-08-02 Gary V. Vaughan - - refactor: simplify deprecation management. - Closes #73. - * specs/base_spec.yaml (DEPRECATED): Specify behaviours of an - improved internal deprecation API. - * specs/list_spec.yaml (elems, index_key, index_value, relems) - (reverse): Specify default deprecation behaviours. - * specs/string_spec.yaml (assert, require_version, tostring): - Likewise. - * specs/table_spec.yaml (clone_rename, metamethod, ripairs): - Likewise. - * lib/std/debug.lua (_DEBUG): Document new compat field. - * lib/std/base.lua (_DEBUG): Set from debug_init.lua. - (deprecate): Rename from this... - (DEPRECATED): ...to this, and improve API. - * lib/std/functional.lua (bind): Use it to mark the old bind - API as deprecated since release 39. - * lib/std/list.lua (elems, index_key, index_value, relems) - (reverse): Collect in a new section and deprecate with the - improved API. - * lib/std/string.lua (assert, require_version, tostring): - Likewise. - * lib/std/table.lua (clone_rename, metamethod, ripairs): - Likewise. - * build-aux/sanity-cfg.mk (exclude_file_name_regexp): Don't choke - on error specs in specs/list_spec.yaml - * NEWS (Deprecations): Collect deprecated API NEWS for this - release. - - string: reference totable correctly in string.pickle. - Closes #79. - * lib/std/string.lua (totable): Set to table.totable. - Reported by Simon Cozens. - - list: specify shape method behaviours. - * specs/list_spec.yaml (shape): Specify method behaviours. - - list: specify list.zip_with, and fix revealed bugs. - * specs/list_spec.yaml (zip_with): Specify behaviour of zip_with - method. - * lib/std/list.lua (zip_with): Call list.map with correctly - * ordered arguments. - * NEWS: Update. - - list: specify list.transpose, and fix revealed bugs. - * specs/list_spec.yaml (transpose): Specify behaviour of transpose - method. - * lib/std/list.lua (transpose): Handle empty list argument. - Call list.map with correctly ordered arguments. - * NEWS: Update. - - maint: reinstate specl package.path workaround for luarocks bug. - Now that we're supporting LuaRocks' `init.lua suffixed filenames - get installed to an init installation directory` bug again, we - must adjust Specl's in-tree package.path to accommodate. - * specs/spec_helper.lua.in (package.path): Add "lib/?/init.lua". - * local.mk (std_path): Likewise - - specs: don't rely on `_G.arg[-1]:match "/lua[0-9.]*$"` - When `specs/optparse_spec.yaml` came over from Specl, I forgot to - upgrade the direct `hell.spawn` invocations to nicely abstracted - `spec_helper.lua:luaproc` calls. - * specs/optparse_spec.yaml (parser): Replace hell.spawn calls - with luaproc calls, so that Lua interpreter is set correctly. - -2014-07-31 Gary V. Vaughan - - slingshot: sync with upstream for upload and moonscript support. - * slingshot: Sync with upstream. - * bootstrap.conf (slingshot_files): Delete removed - ax_compare_version.m4. - * README.md (Installation): Show moonscript rocks repo. - * .travis.yml: Regenerate. - -2014-07-29 Gary V. Vaughan - - std: `std.require` now matches last dot-delimited version number. - * specs/std_spec.yaml (require): Specify behaviours when a version - string contains more than one substring with dot-delimited digits. - * lib/std/base.lua (module_version): Anchor the version matching - pattern at the end of the string. - * lib/std.lua.in (require): Improve LDocs accordingly. - * NEWS: Update. - - maint: reinstate LuaRocks init install bug workaround. - Latest LuaRocks still has the bug where Lua source files ending - in `init.lua` are installed to a subdirectory. Put back the - workaround I removed prematurely. - * lib/std/debug_init.lua: Move from here... - * lib/std/debug_init/init.lua: ...to here. - * local.mk (dist_luastd_DATA): Remove lib/std/debug_init.lua. - (dist_luastddebug_DATA): Add lib/std/debug_init/init.lua. - -2014-07-25 Gary V. Vaughan - - spec: modernize and normalize std specs. - * specs/std_spec.yaml: Reduce redundancy, and update to modern - style with fully argchecked apis. - * lib/std.lua.in (barrel): Scribble deprecated functions into - global namespace. - - doc: improve LDocs for std.lua. - * lib/std.lua.in: Tidy up and normalize LDocs. - - refactor: move `table.metamethod` to `std.getmetamethod`. - Be more in keeping with the style of core Lua. - * lib/std/table.lua (metamethod): Deprecate. - * lib/std.lua.in (getmetamethod): Export from here instead. - * specs/table_spec.yaml, specs/std_spec.yaml: Adjust accordingly. - * NEWS: Update. - - refactor: move `std.string.tostring` to `std.tostring`. - * lib/std/string.lua (render, tostring): Move from here... - * lib/std/base.lua (render, tostring): ...to here, with argchecks - removed. - * lib/std/string.lua (render): Re-export base.render from here. - (tostring): Re-export base.tostring with a deprecation notice. - * lib/std.lua.in (tostring): Re-export base.tostring from here. - (memoize): Simplify accordingly. - * specs/debug_spec.yaml, specs/string_spec.yaml, - specs/std_spec.yaml: Adjust accordingly. - * NEWS: Update. - - refactor: relocate std.lua contents to std.base and std. - * specs/lua_spec.yaml: Remove. All specs moved from here... - * specs/std_spec.yaml: ...to here. - * specs/specs.mk (specl_SPECS): Remove specs/lua_spec.yaml. - * lib/std/operator.lua (getmetamethod): Remove to break a - require loop. - * lib/std/lua.lua (assert, case, elems, eval, ielems, ipairs) - (ireverse, lambda, memoize, pairs, require, ripairs): Move from - here... - * lib/std/base.lua (assert, case, elems, eval, ielems, ipairs) - (ireverse, lambda, memoize, pairs, require, ripairs): ...to here, - removing argchecks... - * lib/std.lua.in (assert, case, elems, eval, ielems, ipairs) - (ireverse, lambda, memoize, pairs, require, ripairs): ...and - re-export from here with argcheck wrappers. - (barrel, monkey_patch): Adjust accordingly. - * lib/std/functional.lua (filter, fold, map): Adjust LDocs. - (case, eval, memoize): Re-export with argcheck wrappers. - * lib/std/string.lua (assert, require_version): Deprecate. - * build-aux/config.ld.in (file): Remove lib/std/lua.lua. - * local.mk (dist_luastd_DATA): Remove lib/std/lua.lua. - * specs/functional_spec.yaml (fold): Adjust require imports. - * NEWS: Update. - -2014-07-24 Gary V. Vaughan - - refactor: move `table.ripairs` to `lua.ripairs`. - * specs/table_spec.yaml (ripairs): Specify deprecation warning - on first use. - * specs/lua_spec.yaml (ripairs): Specify all behaviours for - ripairs. - * lib/std/base.lua (ripairs): Shared core functionality for - ripairs, respecting `__ipairs` metamethod even on Lua 5.1. - * lib/std/table.lua (ripairs): Use it, with a deprecation - warning on first use. - * lib/std/lua.lua (ripairs): Re-export it from here with full - argchecks. - * NEWS: Update. - -2014-07-23 Gary V. Vaughan - - refactor: replace `list.reverse` with `lua.ireverse`. - * specs/lua_spec.yaml (ireverse): Specify behaviour of new - ireverse function. - * specs/list_spec.yaml (relems, reverse): Specify new deprecated - behaviours of these functions. - * lib/std/list.lua (relems, reverse): Deprecated. - * lib/std/base.lua (ireverse): New `__ipairs` aware generator of - new reversed array-part of any table. - * lib/std/lua.lua (ireverse): Export `base.ireverse`. - (monkey_patch): Inject ireverse into given namespace. - * specs/std_spec.yaml (monkey_patch): Adjust accordingly. - * NEWS: Updated. - -2014-07-21 Gary V. Vaughan - - operator: break a require loop. - * lib/std/base.lua: Remove unused `require "std.operator"` to - break a require loop. - - operator: make '#' operator Lua 5.1 compatible. - * specs/operator_spec.yaml (#): Specify behaviour of # operator. - * lib/std/operator.lua (#): If there's a `__len` metamethod, call - it manually before falling back to actual `#` operator. - -2014-07-18 Gary V. Vaughan - - doc: improve render LDocs @usage examples. - * lib/std/string.lua (render, render_separator): Improve LDocs - @usage examples. - - doc: add missing @function to prettytostring LDocs. - * lib/std/string.lua (prettytostring): Add missing @function. - - refactor: move assert and require from std.string to std.lua. - * specs/string_spec.yaml (assert, require): Move from here... - * specs/lua_spec.yaml (assert, require): ...to here. - * lib/std/string.lua (assert, module_version, require, - version_to_list): Move from here... - * lib/std/lua.lua (assert, module_version, require, - version_to_list): ...to here. - * lib/std/string.lua (assert): Propagate invocations to std.lua, - with a deprecation warning. - * NEWS: Update. - - refactor: decouple std.lua from other modules. - * lib/std/lua.lua (wrapiterator): Move from here... - * lib/std/base.lua (wrapiterator): ...to here. - (ielems): Non-argchecked implementation. - * lib/std/lua.lua (ielems): Use it. - * lib/std/debug.lua, lib/std/list.lua, lib/std/set.lua, - lib/std/tree.lua: Use base.ielems internally. - * lib/std/functional.lua (case, eval, lambda, memoize): Load - std.lua on demand when these functions are called rather than - depending on it at require time. - * lib/std/table.lua: Remove unused std.lua requirement. - - lua: add a monkey_patch function. - * specs/lua_spec.yaml (monkey_patch): Specify behaviour of lua - monkey_patch function. - * lib/std/lua.lua (monkey_patch): Install lua functions into the - given namespace. - * lib/std/std.lua.in (monkey_patch): Add lua.monkey_patch - invocation. - (barrel): Remove double injection of `std.lua` functions. - * specs/std_spec.yaml (barrel): Add new 'std.lua' functions. - -2014-07-17 Gary V. Vaughan - - Merge branch 'waffle-iron-master' - -2014-07-17 Making GitHub Delicious. - - add waffle.io badge - -2014-07-17 Gary V. Vaughan - - lua: support __ipairs and __pairs metamethods on Lua 5.1. - * specs/lua_spec.yaml (ipairs, pairs): Specify portable behaviour - for new functions. - * lib/std/lua.lua (ipairs, pairs): New functions that support - __ipairs and __pairs metamethods, even on Lua 5.1. - (ielems, elems): Improve LDocs and argchecks. - * specs/lua_spec.yaml (elems, ielems): Adjust error message specs. - * NEWS: Update. - - debug: argcheck accepts a List object for a list parameter. - * specs/debug_spec.yaml (argcheck): Remove specifications for - mismatch errors between list parameters and List arguments. - * lib/std/base.lua (argcheck): Accept an empty List object for a - - refactor: simplify list.flatten implementation. - * lib/std/list.lua (flatten): Simplify. - - container: don't rewrap existing modulefunction functables. - * lib/std/container.lua (modulefunction): When re-exporting - module functions from another module, don't wrap inside another - functable. - -2014-07-16 Gary V. Vaughan - - list: deprecate list.elems module function. - * lib/std/list.lua (elems): Deprecate. - * specs/list_spec.yaml (elems): Specify deprecation warning - behaviour. - - refactor: consolidate and speed-up ielems and elems functions. - * specs/table_spec.yaml (elems, ielems): Move from here... - * specs/lua_spec.yaml (elems, ielems): ...to here. - * specs/functional_spec.yaml (fold): Adjust ielems import. - * lib/std/base.lua (ielems): Remove. - * lib/std/table.lua (elems, ielems): Remove. - * lib/std/lua.lua (elems, ielems): Wrap ipairs and pairs, taking - care to honor __ipairs and __pairs metamethods, for a noticeable - speedup. - * lib/std/debug.lua, lib/std/list.lua, lib/std/tree.lua: Adjust - ielems imports and examples. - * build-aux/sanity-cfg.mk (sc_error_message_uppercase): Add - specs/lua_spec.yaml. - * NEWS: Update. - -2014-07-14 Gary V. Vaughan - - refactor: move language features to a new `std.lua` module. - * specs/functional_spec.yaml (case, eval, lambda, memoize): Move - from here... - * specs/lua_spec.yaml: New file. ...to here. - * specs/std_spec.yaml: Adjust accordingly. - * specs/specs.mk (specl_SPECS): Add specs/lua_spec.yaml. - * build-aux/config.ld.in (file): Add lib/std/lua.lua. - * lib/std/base.lua (lambda): Move from here... - * lib/std/lua.lua (lambda): New file. ...to here. - * local.mk (dist_luastd_DATA): Add lib/std/lua.lua. - * lib/std/functional.lua (case, eval, lambda, memoize): Move from - here... - * lib/std/lua.lua (case, eval, lambda, memoize): ...to here. - * lib/std/string.lua (pickle): Adjust LDocs eval cross reference. - * NEWS: Update. - -2014-07-11 Gary V. Vaughan - - maint: revert automatic lambda string compilation. - * lib/std/base.lua (lambda): Core Lua APIs require actual - functions, so to be useful for passing lambda strings to core - APIs and stdlib APIs alike, return a raw function rather than a - functable. - (argcheck): Don't accept a compilable lambda string where a - function argument is expected. - * lib/std/debug.lua (lambda, argcheck): Adjust LDocs. - * lib/std/functional.lua: Likewise. - (bind, case, collect, compose, curry, filter, fold, map) - (memoize): Remove lambda argument compilation. - * lib/std/io.lua (process_files): Likewise. - * lib/std/list.lua (filter, foldl, foldr, map, map_with) - (zip_with): Likewise. - * lib/std/package.lua (mappath): Likewise. - * lib/std/string.lua (render): Likewise. - * lib/std/table.lua (sort): Likewise. - * specs/debug_spec.yaml, specs/functional_spec.yaml, - specs/io_spec.yaml, specs/list_spec.yaml, - specs/package_spec.yaml, specs/string_spec.yaml, - specs/table_spec.yaml: Adjust lambda specs. - * NEWS: Update. - - specs: don't load std.object for std.list spec examples. - * specs/spec_helper.lua.in (prototype): Copied from - lib/std/base.lua. - * specs/list_spec.yaml: Don't load 'std.object', use prototype - from spec_helper. - - base: provide better errors from exported object methods. - * specs/base_spec.yaml (export): Specify behaviour of exported - object methods. - * lib/std/base.lua (export): Use separator ':' between module name - and method name when dealing with methods, as opposed to '.' when - dealing with functions. - Count method arguments starting at '0' for self in error messages. - * build-aux/sanity-cfg.mk (sc_error_message_uppercase): Add - specs/base_spec.yaml. - -2014-07-10 Gary V. Vaughan - - doc: object and container _functions fields are optional. - * lib/std/container.lua (Container): _functions field is optional. - * lib/std/object.lua (Object): Likewise. - - doc: clarify use of compiled lambda strings. - * lib/std/functional.lua (Lambda): Add LDocs cross-references, - and a usage example with call field. - (lambda): Fix usage example not to show calling core Lua - table.sort with a functable! - - refactor: simplify std.base.lambda. - * lib/std/base.lua (lambda): Use `unpack` unconditionally. - Save lambda string in Lambda object. - - doc: add LDocs for functional.lambda return functables. - * lib/std/functional.lua (Lambda): Add LDocs. - (lambda): Document return type correctly. - - doc: improve debug module LDocs. - * lib/std/debug.lua (_DEBUG): Document default field values. - (argerror): Document interaction between function and lambda - strings. - - doc: improve functional module LDocs. - * lib/std/functional.lua: Improve module header LDocs. - - functional: make nop an official functional method. - * specs/functional_spec.yaml (nop): Specify behaviour of new nop - module method. - * specs/spec_helper.lua.in (nop): Remove one-off nop declaration. - * specs/string_spec.yaml (finds): Specify in-situ nop. - * specs/base_spec.yaml (std.base): Likewise. - * lib/std/base.lua (nop): Declare an official nop function. - * lib/std/functional.lua (nop): Re-export std.base.nop. - * NEWS: Update. - -2014-07-09 Gary V. Vaughan - - maint: clean up NEWS. - * NEWS: Update bitrotted recent entries to match reality. - - std: accept lamda strings as an alternative to functions. - * specs/functional_spec.yaml, specs/io_spec.yaml, - specs/list_spec.yaml, specs/package_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml: Specify behaviours - of API calls that accept functions when given a lambda string - instead. - * lib/std/functional.lua (Lambda, lambda): Move from here... - * lib/std/base.lua (Lambda, lamba): ...to here. - (Lambda): Save arguments in table fields. - (argcheck): Accept a valid lambda string in lieu of a Lua - function. - * lib/std/table.lua (sort): When passed a lambda string, pass the - associated function to core table.sort. - * lib/std/functional.lua (bind, case, collect, curry, filter) - (fold, map, memoize): Accept lamda strings in lieu of Lua - functions. - * lib/std/io.lua (process_files): Likewise. - * lib/std/list.lua (filter, foldl, foldr, map, map_with) - (zip_with): Likewise. - * lib/std/string.lua (render): Likewise. - * NEWS: Update. - - specs: add specifications for std.operator. - * specs/operator_spec.yaml: New file. Specify behaviours for - operator functions. - * specs/specs.mk (specl_SPECS): Add specs/operator_spec.yaml. - -2014-07-08 Gary V. Vaughan - - refactor: factor functional.op into new std.operator module. - * lib/std/functional.lua (op): Move from here... - * lib/std/operator.lua (M): ...to here. - (M[".."], M["{}"], M[#"], M["~"], M["%"], M["^"]): New operators. - * local.mk (dist_luastd_DATA): Add lib/std/operator.lua. - * build-aux/config.ld.in (files): Likewise. - * local.mk (dist_module_DATA): Add std.operator.html. - * NEWS: Update. - -2014-07-07 Gary V. Vaughan - - functional: new lambda function. - Support compiling an anonymous Lua function from a "lambda string". - * specs/functional_spec.yaml (lambda): Specify behaviour for a - new lambda function. - * lib/std/functional.lua (lambda): Satisfy specification. - * NEWS: Update. - - functional: support multiple return values with memoize. - * specs/functional_spec.yaml (memoize): Specify behaviour when - passed a function with multiple return values. - * lib/std/functional.lua (memoize): Save return values from - wrapped function as a table, and unpack it when called again with - the same arguments. - * NEWS: Update. - -2014-07-04 Gary V. Vaughan - - doc: fix functional.op LDocs. - * lib/std/functional.lua (op): Workaround LDoc's inability to - render non-alphanumeric @field names. - - functional: support relational operators in op table. - * lib/std/functional.lua (op): Add `<`, `<=`, `>` and `>=`. - * NEWS: Update. - - specs: avoid tickling sc_error_message_uppercase sanity check. - * specs/spec_helper.lua.in (raise): An alias to the error matcher - to subvert matching `error` followed by `"[A-Z]` that prevents - make dist from completing. - * specs/container_spec.yaml (construction): Use the raise alias. - - reformat: order functional module functions asciibetically. - * lib/std/functional.lua: Reorder module functions asciibetically. - - specs: don't pass a Tree to object constructor. - * specs/tree_spec.yaml (construction): Don't pass a Tree to an - object constructor. - - refactor: use a function to export container module methods. - * specs/spec_helper.lua.in (badarg, toomanyarg): Format - appropriately when module name is not given. - * specs/container_spec.yaml (construction) - Update to latest style: - Add argcheck behaviour examples. - * lib/std/base.lua (olen): Rename from this... - (arglen): ...to this. - (M): Export arglen and toomanyarg_fmt. - * lib/std/container.lua (M): Add module name at element 1. - (__tostring, __totable): Reformat these... - (M.__tostring, M.__totable): ...as local table function - declarations. - (M.__call): When _ARGCHECK is not disabled, diagnose argument - type errors in table _init styl objects, to satisfy newly - specified behaviours. - (mapfields): Upgrade to base export declaration (for overhead - free argcheck calls with _DEBUG=false) and simplify accordingly. - -2014-07-03 Gary V. Vaughan - - maint: rename array to vector. - In mathematics "array" suggests the possibility of multiple - dimensions, and while one can simulate that with a std.array - of std.arrays, the name "vector" is a better fit for what this - class supports. - * lib/std/array.lua, specs/array_spec.yaml: Move from here... - * lib/std/vector.lua, specs/vector_spec.yaml: ...to here. - Rename symbols accordingly. - * build-aux/config.ld.in (file): Adjust accordingly. - * local.mk (dist_luastd_DATA, dist_classes_DATA): Likewise. - * specs/specs.mk (specl_SPECS): Likewise. - * specs/string_spec.yaml (render): Adjust Array using example to - Vector. - - refactor: use a function to export table apis. - * specs/table_spec.yaml (clone, clone_select, elems, empty) - (ielems, invert, keys, merge, merge_select, metamethod) - (monkey_patch, new, pack, ripairs, size, totable, values): - Update to latest style: - Add "too many argument" behaviour checks. - Simplify and standardise argument error message comparisons. - * lib/std/table.lua (M): Add module name at element 1. - (clone, clone_select, elems, empty, ielems, invert, keys) - (merge, merge_select, metamethod, monkey_patch, new, pack) - (ripairs, size, totable, values): Upgrade to base export - declarations (for overhead free argcheck calls with _DEBUG=false) - and simplify accordingly. - - maint: settle on calling std api calls `Module Functions`. - * lib/std/debug.lua, lib/std/io.lua, lib/std/package.lua, - lib/std/table.lua, lib/std/tree.lua: Consolidate comment section - header as "Module Functions.". - -2014-07-02 Gary V. Vaughan - - maint: don't flag `Lua` strings as invalid errors in spec-files. - * build-aux/sanity-cfg.mk (exclude_file_name_regexp): Add - specs/debug_spec.yaml. - - debug: finish support for nil arguments in exported functions. - Because luajit (legitimately) stops counting on the first nil - value in a list, where Lua 5.1 and 5.2 keep counting, we have - to do our own size calculations on argument vectors to be - consistent. - * lib/std/base.lua (olen): Return the largest integer key from a - table. - (match, export): Use it to ignore `nil` elements in the argument - list when counting the number of arguments. - - debug: support nil arguments in functions declared with export. - * lib/std/base.lua (opairs): Like ipairs, but does not stop at - the first nil value. - -2014-07-01 Gary V. Vaughan - - refactor: use a function to export string apis. - * specs/string_spec.yaml (__concat, __index, assert, caps, chomp) - (escape_pattern, escape_shell, finds, format, ltrim, monkey_patch) - (numbertosi, ordinal_suffix, pad, pickle, prettytostring, render) - (require, require_version, rtrim, split, tfind, tostring, trim) - (wrap): Update to latest style: - Add "too many argument" behaviour checks. - Simplify and standardise argument error message comparisons. - * lib/std/string.lua (M): Add module name at element 1. - (__concat, __index, assert, caps, chomp, escape_pattern) - (escape_shell, finds, format, ltrim, monkey_patch, numbertosi) - (ordinal_suffix, pad, pickle, prettytostring, render, require) - (require_version, rtrim, split, tfind, tostring, trim): Upgrade - to base.export declarations (for overhead free argcheck calls - with _DEBUG = false) and simplify accordingly. - - refactor: simplify caps, chomp, escape_pattern and escape_shell. - * lib/std/string.lua (caps, chomp, escape_pattern, escape_shell): - Remove extraneous parens around return argument. - Use Lua :-method call sugar to shorten gsub invocations. - - refactor: rename string.require_version to string.require. - * specs/string_spec.yaml (require): A copy of the require_version - specs. - (require_version): Also check for deprecation warning on first - use. - (monkey_patch): Check that new `require` function is written into - the given namespace. - * specs/std_spec.yaml (barrel): Likewise. - (monkey_patch): Check that the deprecated `require_version` is - still written into the global namespace. - * lib/std/string.lua (require_version): Rename from this... - (require): ...to this. - (require_version): A deprecated copy of `string.require`. - * NEWS: Update. - - refactor: simplify std.string.require_version. - * lib/std/string.lua (version_to_list, module_version): Factored - out of require_version, rather than defining new temporary local - functions on each invocation of require_version. - (require_version): Simplify accordingly. - - refactor: simplify std.string.tfind. - * lib/std/string.lua (tpack): Factored out of tfind, rather than - defining a new temporary local pack function on every invocation. - (tfind): Simplify accordingly. - - refactor: simplify std.string.format. - * lib/std/string.lua (format): Simplify. - - refactor: simplify std.string.assert. - * lib/std/string.lua (assert): Simplify. - - refactor: no need for the underscore in local _floor. - There's no clash between M.floor and local floor now we're using - `export` to declare api calls. - * lib/std/math.lua (_floor): Rename from this... - (floor): ...to this. Adjust all callers. - - refactor: use a function to export package apis. - * specs/package_spec.yaml (find, insert, mappath, normalize) - (remove): Update to latest style. - Add "too many argument" behaviour checks. - Simplify and standardise argument error message comparisons. - * lib/std/package.lua (M): Add module name at element 1. - (find, insert, mappath, normalize, remove): Upgrade to - base.export declarations (for overhead free argcheck calls with - _DEBUG = false) and simplify accordingly. - (package): Improve LDocs. - - specs: work around luajit argument counting gotcha. - Luajit truncates a variadic function call's argument list at - the first nil! - * specs/base_spec.yaml (export): Don't pass nil part way through - a variadic function call's argument list. - - base: support optional arguments in export type declarations. - The algorithm is approximately to collect every possible - permutation of argument type-spec list with and without any - optional arguments. An optional argument in the last position - must match the given type or nil, so that the permutation with - the final optional removed matches, allowing an uncaught - mismatched type at that position. Then we try to match the - actual arguments against each permutation until one passes, - otherwise diagnose the mismatch, reporting that any type - at the mismatched index from all permutations is required. - * specs/base_spec.yaml (export): Specify behaviours when called - with a declaration containing an optional argument wrappend in - square brackets. - * lib/std/base.lua (match, formaterror): New functions; factored - out of argcheck. - (copy, match, normalize, permutations): New functions; support - classification of matchable argument type-specs. - (export): Use them to implement optional arguments in export - type declarations to satisfy new specifications. - - doc: improve strict LDocs. - * lib/std/strict.lua: Improve LDocs. - - doc: correct parameter descriptions on debug.argscheck. - * lib/std/debug.lua (argscheck): Improve LDocs. - - specs: decouple spec_helper.lua from std.table and std.functional. - * specs/spec_helper.lua.in (bind): Use our own implmentation of - bind, otherwise if std.functional becomes unloadable, the whole - specl suite is unusable. - (totable): Likewise for std.table.totable. - (set): No need to rely on std.set, when a simple table index - dereference works equally well. - - refactor: use a function to export io apis. - * specs/io_spec.yaml (catdir, catfile, die, monkey_patch) - (process_files, readlines, shell, slurp, splitdir, warn) - (writelines): Update to latest style. - Add "too many argument" behaviour checks. - Simplify and standardise argument error message comparisons. - * lib/std/io.lua (M): Add module name at element 1. - (catdir, catfile, die, monkey_patch, process_files, readlines) - (shell, slurp, splitdir, warn, writelines): Upgrade to - base.export declarations (for overhead free argcheck calls with - _DEBUG = false) and simplify accordingly. - (catdir, catfile, die, monkey_patch, process_files, readlines) - (shell, slurp, splitdir, warn, writelines): Improve LDocs. - * NEWS: Update. - - debug: revert export of trace. - Both because the argument check wrapper is not properly tail-call - eliminated by Lua 5.1, and because as a core function callback - the function signature is fixed already, there's no good reason - to check arguments on debug.trace. - * specs/debug_spec.yaml (trace): Remove argument check behaviour - specifications. - * lib/std/debug.lua (trace): Remove the export wrapper. - -2014-06-30 Gary V. Vaughan - - debug: revert export of argerror, argcheck and argscheck. - Annoyingly, Lua 5.1 misses an obvious tail call elimination when - _DEBUG.argcheck is set, so the deep call to error gets the wrong - level, and reports argument errors in the wrong functions!! Rather - than uglify the code to remove the tail-calls and do a recount, - or add a fudge factor when Lua 5.1 is detected, it's cleaner to - remove the argchecking wrappers of the 3 affected functions -- at - least until we're ready to drop Lua 5.1 support entirely. - * specs/debug_spec.yaml (argerror, argcheck, argscheck): Mark the - argument checking behaviours as pending. - * lib/std/debug.lua (argerror, argcheck, argscheck): Comment out - the argument checking wrappers, and call the bare functions. - -2014-06-13 Gary V. Vaughan - - debug: improve argcheck list semantics. - Following the principle of least surprise, make a new `#list` - check type that has the same behaviour as `list` did previously, - for orthogonality with `#table`, and add a new `list` - implementation for orthogonality with `table`. - * specs/debug_spec.yaml (argcheck): Specify behaviours of `list` - and `#list` with new semantics. - * lib/std/debug.lua (argcheck): Update LDocs. - * lib/std/base.lua (argcheck): Count the elements of a `list` - and ensure that number is not greater than the result of the - length operator -- i.e. the table has no holes, and no non- - integer keys. - When building a type-mismatch error, write `empty list` where - appropriate. - * lib/std/debug.lua (argcheck): Make the 2nd argument a `#list`. - - refactor: use export function to simplify debug argchecks. - * lib/std/debug.lua (argcheck, argerror, argscheck, trace): Add - argument checking. - * specs/debug_spec.yaml: Adjust. - - refactor: use a string specifier instead of a table for export. - * specs/base_spec.yaml (export): Specify behaviours of export - function, particularly with argument errors. - * lib/std/base.lua (export): In place of an export name and a - table of expected argument types, parse a single `decl` argument - into an export name and table of argument types. - Support specified argument error behaviours. - * lib/std/math.lua (floor, monkey_patch, round): Simplify - accordingly. - * lib/std/functional.lua (bind, case, collect, compose, curry) - (eval, filter, fold, map, memoize): Likewise. - - refactor: use pipe-delimited strings for argcheck type lists. - * specs/debug_spec.yaml (argcheck, argscheck): Adjust for - pipe-delimited string instead of table of strings. - * lib/std/base (argcheck): Use base.split to make a table from - expected argument. - * lib/std/array.lua, lib/std/container.lua, lib/std/debug.lua, - lib/std/io.lua, lib/std/list.lua, lib/std/package.lua, - lib/std/string.lua, lib/std/table.lua: Adjust argcheck and - argscheck types argument accordingly. - - refactor: use a function to simplify bad argument specs. - * specs/spec_helper.lua.in (badarg, toomanyarg): Assemble a - suitable error string from arguments. - * specs/function_spec.yaml, specs/math_spec.yaml: Simplify - accordingly. - - refactor: use a function to export functional apis. - * lib/std/base.lua (argcheck): Accept "func" as an alias for - "function". - (export): When the last types element ends with "*", check type - of remaining unchecked args against it. - If there is no "*" mark in the types list, and more arguments are - passed than types entries, throw a "too many arguments" error. - Return the unwrapped function argument, so it can be captured - back into a local by the caller. - * specs/functional_spec.yaml (case, curry, eval, memoize): Check - these fixed argument functions throw a "too many arguments" error - when called with too many arguments. - * specs/math_spec.yaml (floor, monkey_patch, round): Likewise. - * lib/std/functional.lua (bind, case, collect, compose, curry) - (eval, filter, fold, map, memoize): Use base.export for - conditional argument checking. Simplify accordingly. - (functional): Rename from this... - (M): ...to this. - - refactor: use a function to export math apis. - * lib/std/base.lua (export): New function. Add a function to the - module export table, with or without argument checking as - appropriate. - * lib/std/math.lua (floor, monkey_path, round): Simplify - accordingly. - (M): Store the module prefix at index 1, for export argerror - calls. - * specs/spec_helper.lua.in (show_apis): Ignore module prefix at - index 1 of export table. - * specs/math_spec.yaml (round): Correct a typo in argerrors. - - list: deprecate index_key and index_value. - * specs/list_spec.yaml (index_key, index_value): Check that the - functions issue a depraction warning on first use. - * lib/std/list.lua (index_key, index_value): Add deprecation - warning with base.deprecate. - * NEWS (Incompatible changes): Update. - - table: add elems and ielems module functions. - * specs/table_spec.yaml (elems, ielems): Specify behaviour of - new iterators. - * lib/std/table.lua (elems): Iterate over all values of a table, - for orthogonality with std.list and std.set. - (ielems): Expose base.ielems in a type checking wrapper. - * NEWS: Update. - - doc: disable LDoc backtick references. - * build-aux/config.ld.in (backtick_references): Set to false, so - we can write fixed-width font words in LDoc comments. - -2014-06-10 Gary V. Vaughan - - list: prefer numeric comparison to asciibetical in compare. - Close #60. - * lib/std/list.lua (compare): If tonumber can make numbers out - of both arguments, use those results in preference to strings. - * specs/list_spec.yaml (compare): Specify behaviours with elements - that can be coerced to numbers. - * specs/string_spec.yaml (require_string): Remove pending #60 - commands. Add some more happy path examples. - -2014-06-09 Gary V. Vaughan - - refactor: differentiate module tables and prototype objects. - It turns out that documentation and code is much clearer when - we differentiate between `list` (the module table for `std.list`) - and `List` (the prototype List object), because that makes it - explicit whether we're calling a module function (`list.append`) - or performing an operation with the prototype (`List.clone {}`). - As a bonus, we gain a bit of speed by cloning the prototype - object from the module table, by virtue of not having a - `_functions` table to administer. - * lib/std/array.lua, lib/std/base.lua, lib/std/container.lua, - lib/std/debug.lua, lib/std/functional.lua, lib/std/io.lua, - lib/std/list.lua, lib/std/math.lua, lib/std/object.lua, - lib/std/optparse.lua, lib/std/set.lua, lib/std/strbuf.lua, - lib/std/string.lua, lib/std/table.lua, lib/std/tree.lua: Always - use the module table or prototype object as appropriate. Make - sure the LDocs don't contradict us. - - doc: add functional.memoize usage example. - * lib/std/functional.lua (memoize): Add a usage example. - - doc: fix some errors in functional usage docs. - * lib/std/functional.lua (collect): list.relems requires a List. - (map, filter, fold): list.elems requires a List. - - refactor: set local _ARGCHECK instead of dereferencing debug_init. - * lib/std/array.lua, lib/std/base.lua, lib/std/function.lua, - lib/std/io.lua, lib/std/list.lua, lib/std/package.lua, - lib/std/string.lua, lib/std/table.lua: Set local _ARGCHECK - instead of importing std.debug_init and dereferencing it all the - time. - - refactor: string.split is an argchecking base.split. - * lib/std/base.lua (split): Remove argument checking. - * lib/std/string.lua (split): Re-export base.split when we are - not argchecking, otherwise check types and call base.split when - successful. - - refactor: table.metamethod is an argchecking base.getmetamethod. - * lib/std/base.lua (metamethod): Rename from this... - (getmetamethod): ...to this, and remove argument checking. - Adjust export table. - * lib/std/table.lua (metamethod): Re-export base.getmetamethod - when we are not argchecking, otherwise check types and call - base.getmetamethod when successful. - * lib/std/object.lua (clone): Adjust. - * lib/std/string.lua (render): Likewise. - - refactor: list.elems is an argument checking base.ielem wrapper. - Functions in std.base are for internal use, and so all callers - have already validated arguments, so we shouldn't waste time - rechecking types on every call to base.elems. - Also this means list.elems can be strict about only accepting - List objects, and catch accidental table passing earlier. - * lib/std/base.lua (elems): Move from here... - (ielems): ...to here, and remove argument checking. Adjust - export table. - * lib/std/list.lua (elems): Re-export base.ielems when we are not - argchecking, otherwise check types and call base.ielems when - successful. - * lib/std/debug.lua (tabify): Use non-argchecked base.ielems. - * lib/std/list.lua (concat, depair, filter, foldl, map) - (map_with): Likewise. - * lib/std/set.lua (Set._init): Likewise. - * lib/std/table.lua (merge_namedfields): Likewise. - * lib/std/tree.lua (Tree.__index): Likewise. - * specs/functional_spec.yaml (fold): Use List objects - consistently. - * specs/list_spec.yaml (elems): Adjust error message - expectations. - - list: add argchecks. - * specs/list_spec.yaml (append, compare, concat, cons, depair) - (elems, enpair, filter, flatten, foldl, foldr, index_key) - (index_value, map, map_with, project, relems, rep, reverse) - (shape, sub, tail, traspose, zip_with): Specify behaviours for - missing or wrong type arguments. - 8 specs/object_spec.yaml: Decouple from list implementation - details. - * lib/std/list.lua (append, compare, concat, cons, depair) - (elems, enpair, filter, flatten, foldl, foldr, index_key) - (index_value, map, map_with, project, relems, rep, reverse) - (shape, sub, tail, traspose, zip_with): Check argument types - when not disabled by _DEBUG. - * build-aux/sanity-cfg.mk: Disable bogus failures when rejecting - uppercase error messages with lib/std/list.lua. - -2014-06-08 Gary V. Vaughan - - refactor: use list copying constructor to simplify list.append. - * lib/std/list.lua (append): Use implicit copy of argument object - constructor rather than slower __call constructor and explicit - unpack of argument elements. - - list: index_value and index_key return raw tables. - * specs/list_spec.yaml (index_key, index_value): Specify proper - behaviours. - * lib/std/list.lua (index_key, index_value): A non-contiguous - set of valid results cannot be represented as a std.list object, - so return a raw table. - -2014-06-07 Gary V. Vaughan - - doc: improve object LDocs, and add usage examples. - * lib/std/object.lua: Add usage examples to apis. - (clone): Normally we'd use the __call metamethod to clone from a - given object, so mark the LDocs for clone as @static because it - is primarily a module function. - (prototype): Mark the function documentation as @static, and add - equivalent method documentation. - - doc: add usage examples to container LDocs. - * lib/std/container.lua (__call, __tostring, __totable): Add - usage examples to LDocs. - - container: argcheck apis. - * lib/std/container.lua (mapfields, __call, __tostring) - (__totable): While it would be extremely convoluted to dig out - the functions behind these apis to call them with non-object - initial arguments, add type checking for completeness. - - doc: add usage examples to array LDocs. - * lib/std.array.lua: Add usage examples to LDocs. - - doc: move stringification functions to their own section. - * lib/std/string.lua (render, tostring, prettytostring, pickle): - Move to a new 'Stringification Functions' section. - - string: split on whitespace by default. - * specs/string_spec.yaml (split): Add an example with no explicit - split-pattern argument. - * lib/std/base.lua (split): Default split-pattern to `%s+` when - no argument provided. - * lib/std/string.lua (split): LDocs cite `%s+` as the default - pattern instead of `%s*`. - * NEWS: Update. - -2014-06-06 Gary V. Vaughan - - std: use argcheck instead of assert for type checking. - * specs/std_spec.yaml (barrel, monkey_patch): Make bad argument - examples more specific. - * lib/std.lua.in (barrel, monkey_patch): Use argcheck calls for - type checking insntead of assert. - - debug: support trailing "?" in place of separate "nil" in argcheck. - * specs/debug_spec.yaml (argcheck): Specify behaviour of trailing - "?" in type specifiers. - * lib/std/base.lua (argcheck): Strip trailing "?" from acceptable - argument types, appending a "nil" entry to the list if any "?" - is stripped. - * lib/std/base.lua, lib/std/debug.lua, lib/std/functional.lua, - lib/std/math.lua, lib/std/package.lua, lib/std/string.lua, - lib/std/table.lua: Adjust all callers to use trailing "?" instead - of separate explicit "nil" in type list. - - string: add argchecks and improve LDocs. - * specs/string_spec.yaml (assert, caps, chomp, escape_pattern) - (escape_shell, finds, format, ltrim, monkey_patch, numbertosi) - (ordinal_suffix, pad, prettytostring, render, require_version) - (rtrim, split, tfind, trim, wrap): Specify behaviours with bad - or missing arguments. - * lib/std/string.lua (assert, caps, chomp, escape_pattern) - (escape_shell, finds, format, ltrim, monkey_patch, numbertosi) - (ordinal_suffix, pad, prettytostring, render, require_version) - (rtrim, split, tfind, trim, wrap): Use argcheck or argscheck to - ensure argument types are validated when _DEBUG is not `false`. - Improve LDocs with @usage examples and parameter types. - * NEWS: Update. - - specs: add missing std.string specs. - * specs/string_spec.yaml (assert, pickle, render, require_version) - (tostring): Specify behaviour of these calls. - (require_version): Add pending examples for newly discovered - issue with non-numeric ordering. - -2014-06-05 Gary V. Vaughan - - string: fix number extraction in require_version. - * lib/std/string.lua (require_version): Change the match pattern - to actually extract the numeric part of the version string. - Also update LDocs to cite correct module._VERSION (with an under- - score). - * NEWS: Update. - - tree: remove std.object dependency. - No need to pull in all of std.object when loading std.tree. - * lib/std/tree.lua: Use base.prototype directly instead of via - re-exported object.prototype, which allows complete removal of - std.object dependency. - While we're here, use imported functions from locals to speed up - access a tiny bit. - - tree: remove std.list dependency requirement. - No need to pull in all of std.list when loading std.tree, just - for the foldl function. - * lib/std/tree.lua (__index): Use func.fold and base.elems from - existing required modules instead of list.foldl. - - string: remove unused string.__append metamethod. - The __append metamethod was added in commit 7a548ba, but only - ever had one client in the defunct std.lcs module which was - removed in commet 5f0a8af. - * lib/std/string.lua (__append): Remove. No longer required. - * specs/string_spec.yaml: Remove __append examples and references. - - refactor: put api and helper functions in sections. - * lib/std/array.lua, lib/std/container.lua, lib/std/io.lua, - lib/std/optparse.lua, lib/std/package.lua, lib/std/set.lua, - lib/std/string.lua, lib/std/table.lua, lib/std/tree.lua: To make - it clear that user-facing code ("api functions") need argument - checking, but internal code ("helper functions") does not, - explicitly separate those kinds of functions, and add some - block headers. - - array: remove duplicate nested argcheck, correctly this time. - * lib/std/array.lua: Where a function or metamethod is called via - `dispatch`, which already checks that the first argument is an - Array object, don't recheck type of self. If that leaves only - arguments of type "any" then don't spend any time checking - argument types at all. - - array: remove duplicate nested argcheck. - * lib/std/array.lua (dispatch): Remove duplicate nested argcheck. - The dispatched to functions already run a full argscheck, so no - need to check again here. - - maint: minimize overhead with argchecks disabled. - * lib/std/array.lua (__call): Wrap argchecking block in - `if debug._ARGCHECK`. - * lib/std/functional.lua (compose): Likewise. - * lib/std/io.lua (catdir, catfile): Likewise. - * lib/std/package.lua (normalize, insert): Likewise. - * lib/std/base.lua (split): Use argscheck instead of assert. - * lib/std/math.lua (monkey_patch): Likewise. - * specs/math_spec.yaml (monkey_patch): Adjust bad argument - behaviours. - - table: complete specs and improve LDocs. - * lib/std/table.lua (clone, clone_select, empty, invert, keys) - (merge, merge_select, monkey_patch, new, pack, ripairs, size) - (sort, totable, values): Add argcheck calls, and improve LDocs - with usage examples & cross-references. - (clone, clone_select, merge, merge_select): Minimise overhead - when argchecking is disabled by wrapping complex argument - checking in `if init._ARGCHECK`. - * specs/table_spec.yaml (pack, ripairs, totable): Add missing - specifications. - (clone, clone_select, empty, invert, keys, merge, merge_select) - (monkey_patch, new, size, sort, values): Improve specs to match - argcheck behaviours. - -2014-06-04 Gary V. Vaughan - - refactor: move _ARGCHECK calculation into std.debug_init. - * lib/std/base.lua (_ARGCHECK): Move from here... - * lib/std/debug_init.lua (M._ARGCHECK): ...to here. - Adjust clients. - - maint: remove workaround for legacy LuaRocks bug. - * local.mk (dist_luastddebug_DATA): Move - lib/std/debug_init/init.lua from here... - (dist_luastd_DATA): ...to lib/std/debug_init.lua. - (luastddebugdir, dit_luastddebug_DATA): Remove. - - doc: consolidate LDoc headers for core extension modules. - * lib/std/debug.lua, lib/std/io.lua, lib/std/math.lua, - lib/std/package.lua, lib/std/string.lua, lib/std/table.lua: - Consolidate LDoc headers for consistency. - -2014-06-03 Gary V. Vaughan - - package: check api call argument types, and improve LDocs. - * specs/package_spec.yaml (find, insert, mappath, normalize) - (remove): Specify bad argument behaviours. - * lib/std/package.lua (find, insert, mappath, normalize) - (remove): Use argscheck to diagnose bad arguments. - Add usage examples to LDocs. - - debug: support ":foo" parameter types with argcheck. - * specs/debug_spec.yaml (argcheck): Specify behaviours of using - ":foo" as a parameter type. - * lib/std/base.lua (argcheck): Implement ":foo" parameter checking. - * lib/std/debug.lua (argcheck): Update LDocs. - - refactor: reduce module dependencies of std.debug. - * lib/std/debug.lua: Remove std.io dependency by using core - file:write instead of std.io.writelines. - Remove std.list dependency by using lighter functional.map instead - of list.map. - Remove unused std.object dependency. - (tabify): Instead of a deeply nested in-situ call to list.map - and others, functionally compose an equivalent and use that to - simplify. - - maint: use "int" argcheck type as appropriate. - * lib/std/array.lua, lib/std/functional.lua: Use "int" parameter - type with argcheck as appropriate. - * lib/std/debug.lua (argscheck): Adjust usage example. - * specs/array_spec.yaml, specs/functional_spec.yaml: Adjust. - - math: check api call argument types. - * specs/math_spec.yaml (floor, round): Specify bad argument - behaviours. - * lib/std/math.yaml (floor, round): Use argscheck to diagnose - bad arguments. - - debug: support "int" parameter type with argcheck. - * specs/debug_spec.yaml (argcheck): Specify behaviours of using - "int" as a parameter type. - * lib/std/base.lua (argcheck): Implement "int" parameter checking. - - math: complete specs and improve LDocs. - * lib/std/math.lua (floor, monkey_patch, round): Improve LDocs - with usage examples. - * specs/io_spec.yaml (floor, round): Add missing specifications. - - maint: add an LDoc module header to private std.base module. - * lib/std/base.lua: Add LDoc module header. - - refactor: move split implementation from string to base. - Decouple std.io from std.string (and hence std.table, std.list, - std.functional, std.object, and std.container) by moving - implementation of split into lib/std/base.lua. - * lib/std/string.lua (split): Move from here... - * lib/std/base.lua (base): ...to here, and export. - * lib/std/string.lua: Re-export base.split as string.split. - * lib/std/io.lua: Don't pull all of string.lua and it's - dependencies into memory; use base.split instead of string.split. - - maint: use 2 blank lines between function definitions. - * lib/std/package.lua, lib/std/strict.lua, lib/std/string.lua: - Use 2 blank lines between function definitions. - - debug: complete specs and improve LDocs. - * lib/std/debug.lua (__call, _DEBUG, argcheck, argerror) - (argscheck, say, trace): Improve LDocs with usage examples and - cross-references. - * specs/debug_spec.yaml (_DEBUG): Remove. _DEBUG behaviours are - specified in the api calls that are affected by it. - (say, trace): Add missing specificatons. - - specs: account for different error messages between 5.1 and 5.2. - * specs/io_spec.yaml (process_files): Accept either of the - error message formats for passing a non-existent file to io.input - for Lua 5.1 or Lua 5.2. - -2014-06-02 Gary V. Vaughan - - std: improve LDocs. - * lib/std.lua.in: Improve LDocs with usage examples and - clearer language. - - io: complete specs and improve LDocs. - * lib/std/io.lua (catdir, catfile, die, monkey_patch) - (process_files, readlines, shell, slurp, splitdir, warn) - (writelines): Improve LDocs with usage examples and cross- - references. - * specs/io_spec.yaml (catdir, catfile, die, monkey_patch) - (process_files, readlines, shell, slurp, splitdir, warn) - (writelines): Add missing specificatons. - * specs/spec_helper.yaml (concat_file_content): New function to - support new specifications. - (luaproc): Support subprocess arguments and standard input. - -2014-06-01 Gary V. Vaughan - - object: enhance prototype to recognize file objects. - * specs/object_spec.yaml (prototype): Specify results of passing - file handles and Lua primitives to prototype. - * lib/std/object.lua (prototype): Improve LDocs. - * lib/std/base.lua (prototype): Enhance implementation to meet - new specifications. - * NEWS: Update. - - io: use argcheck for api functions. - * specs/io_spec.yaml (catdir, catfile, die, monkey_patch) - (process_files, readlines, shell, slurp, splitdir, warn) - (writelines): Specify argument type mismatch messages. - * lib/std/io.lua (catdir, catfile, die, monkey_patch) - (process_files, readlines, shell, slurp, splitdir, warn) - (writelines): Call argcheck to validate arguments and meet - specifications. - -2014-05-31 Gary V. Vaughan - - debug: add file object matching to argcheck. - * specs/debug_spec.yaml (argcheck): Specify behaviour when - matching against a file type argument. - * lib/std/debug.lua (argcheck): Add LDocs for file type. - * lib/std/base.lua (argcheck): When the required type is "file" - use io.type () to ensure that an open file object argument was - passed. - - io: don't pull in tree and dependencies with `require "io"`. - * lib/std/io.lua (tree): Remove requirement. - (base): Replace with much lighter module. - (writelines): Call base.leaves instead of tree.ileaves. In - addition to reducing coupling, this also saves another round - of `argscheck`ing, and a callstack frame. - -2014-05-30 Gary V. Vaughan - - array: support ipairs iteration over elements. - * specs/array_spec.yaml (__ipairs): Specify behaviour of ipairs - with arrays. - * lib/std/array.lua (core_metatable.__ipairs) - (alien_metatable.__ipairs): Implement ipairs support for table - and alien.buffer managed table elements. - - maint: demonstrate new and legacy bind api correctly. - Seems like I was confused over which functional.bind api was the - old, and which was the new. Correct that. - * specs/functional_spec.yaml (bind): Swap examples of new bind - api labelled legacy and vice versa. - * NEWS: Update. - -2014-05-29 Gary V. Vaughan - - refactor: merge std.base_array into std.array. - Instead of a one-way degrading from alien.buffer managed elements - to table managed elements with a sub-type, combine both sets of - optimised methods and metamethods back into a single `std.array` - container, which decides with each clone operation how to manage - elements of the named type. - * specs/array_spec.yaml: Specify behaviours for Array object that - dispatches module function calls at runtime, and assigns - optimized methods and metamethods on cloned objects according to - element type. - * lib/std/base_array.lua (pop, push, realloc, set, shift, unshift) - (__index, __newindex, __len, __tostring): Move from here... - * lib/std/array.lua (core_functions.pop, core_functions.push) - (core_functions.realloc, core_functions.set, core_functions.shift) - (core_functions.unshift, core_metatable.__index) - (core_metatable.__newindex, core_metatable.__len) - (core_metatable.__tostring: ...to here. - (pop, push, realloc, set, shift, unshift, __index, __newindex): - Move from here... - (alien_functions.pop, alien_functions.push, alien_functions.set) - (alien_functions.realloc, alien_functions,shift) - (alien_functions.unshift, alien_metatable.__index) - (alien_metatable.__newindex): ...to here. - (core_metatable.__call): Clone a new Array object, setting the - method and metatables with functions optimised for alien.buffer - or Lua table based element management according to availability of - alien, and element type name. - (dispatch): New runtime virtual table dispatch function. - (Array): Dispatch module functions at runtime based on element - type. - * lib/std/base_array.lua: Remove. - * local.mk (dist_luastd_DATA): Remove lib/std/base_array.lua. - * specs/base_array_spec.yaml: Remove. - * specs/specs.mk (specl_SPECS): Remove specs/base_array_spec.yaml. - * NEWS: Update. - - functional: complete specs and improve LDocs. - * lib/std/functional.lua (bind, case, curry, compose, eval) - (collect, map, filter, fold): Improve LDocs with usage examples, - and cross-references. - * specs/functional_spec.yaml (collect, compose, curry, eval) - (filter, fold, id, map, memoize): Add missing specifications. - - debug: argcheck can match functable with "function". - * specs/debug_spec.yaml (argcheck): Specify correct behaviour - when matching a functable against a "function" argument. - * lib/std/base.lua (argcheck): Allow functables when a "function" - type argument is required. - * lib/std/debug.lua (argcheck): Update LDocs. - - functional: bind should not require respecifying fixed args. - * specs/functional_spec.yaml (bind): Move incumbent examples to - a new legacy example. Rewrite original examples with new api. - Add specifications for behaviour when not all arguments are - given in the call to the bound function. - * lib/std/functional.lua (bind): Fill initial argument positions - from original bind arguments, and then propagate final call - arguments into non-fixed parameter positions. - * NEWS: Update. - - functional: use argscheck for api functions. - * specs/functional_spec.yaml (metamethod): Remove. This method - has moved to std.table. - (bind, case, collect, compose, curry, eval, filter, fold, map) - (memoize): Specify behaviour with missing or wrong type - arguments. - * lib/std/functional.yaml (bind, case, collect, compose, curry) - (eval, filter, fold, map, memoize): Add argscheck calls to - validate arguments when _DEBUG or _DEBUG.argcheck are not false. - - refactor: omit spurious parentheses around require result dereferences. - * lib/std/container.lua, lib/std/object.lua, lib/std/set.lua, - lib/std/string.lua, lib/std/tree.lua, specs/container_spec.yaml, - specs/list_spec.yaml, specs/object_spec.yaml, - specs/set_spec.yaml, specs/spec_helper.lua.in: Omit spurious - parentheses around require result dereferences. - - base: use argscheck for api functions. - * specs/base_spec.yaml (deprecate), specs/list_spec.yaml (elems): - Specify bad argument behaviours. - * specs/table_spec.yaml (metamethod): Add missing specifications, - including bad argument behaviours. - * lib/std/base.lua (deprecate, elems, metamethod): Use argscheck - to implement specified behaviours. - - refactor: don't pull in all of debug's dependencies for array. - * lib/std/array.lua, lib/std/base_array.lua: Import argcheck and - argscheck from std.base. - - refactor: move argscheck et.al. into std.base module. - Unfortunately, debug.say is a very high level function that pulls - in a lot of other modules, modules that we'd like to be able to - add debug.argscheck to... since argscheck has almost no pre- - requisites, move it into the base module where it can then be - available everywhere else. - * lib/std/container.lua (prototype): Move from here... - * lib/std/base.lua (prototype): ...to here. - * lib/std/debug.lua (concat, argerror, argcheck, argscheck): - Move from here... - * lib/std/base.lua (concat, argerror, argcheck, argscheck): ...to - here. - Be sure to disable argument checking if _DEBUG or _DEBUG.argcheck - are false. - -2014-05-27 Reuben Thomas - - functional.lua: add missing parameter name to docstring - -2014-05-24 Gary V. Vaughan - - alien: remove surplus std.alien module. - * lib/std/array.lua: Factor away dependencies on std.alien. - (__call): Instead of an _init call built for container.__call, - we now use a custom __call metamethod that returns a base_array - object that is optimized for Lua table buffers when the element - type is not recognized (either because there is no alien module - installed, or it does not support buffers of the given type), or - else builds an alien.buffer optimised object and returns that. - * lib/std/alien.lua, specs/alien_spec.yaml: Remove. - * build-aux/config.ld.in (file): Remove lib/std/alien.lua. - * local.mk (dist_luastd_DATA): Likewise. - (dist_modules_DATA): Remove doc/modules/std.alien.html. - * specs/specs.mk (specl_SPECS): Remove specs/alien_spec.yaml. - - base_array: non-alien capable base class for std.array. - * specs/base_array_spec.yaml: New file. Specify behaviour for - base_array. - * specs/specs.mk (specl_SPECS): Add specs/base_array_spec.yaml. - * lib/std/base_array.lua: New file. Implement base_array class to - satisfy specification. - * local.mk (dist_luastd_DATA): Add lib/std/base_array.lua. - - debug: argcheck "any" does not match `nil`. - * specs/debug_spec.yaml (argcheck): Passing a nil argument does - not satisfy the "any" spec. - * lib/debug.lua (argcheck): Require non-nil argument before - setting passing status for an "any" spec. - (argscheck): Remove "any" shortcut. - -2014-05-21 Gary V. Vaughan - - optparse: fix another global symbol leak. - * lib/std/optparse.lua (on): Declare `key` as a local variable. - - optparse: fix a global symbol leak. - * lib/std/optparse.lua (on): Declare `normal` as a local variable. - * NEWS (Bug fixes): Updated. - - configury: don't require specific git version. - * bootstrap.conf (buildreq): Don't set a git version number, or - else `GIT=true ./bootstrap` doesn't work. - - slingshot: sync with upstream. - * slingshot: Sync with upstream for grep GNUism fix. - -2014-05-20 Gary V. Vaughan - - array: support simultaneous alien and Lua array objects. - * lib/std/array.lua (alien_type): A set of valid types for - arrays to be implemented with alien.array. - (topointer): Default offset to 1. - (setzero): Use memset for alien arrays, direct element buffer - copying for Lua arrays. - (shift, unshift): Use memmove for manipulating alien.arrays, or - else table.insert and table.remove for Lua tables. - (copy): Remove. - (clone): Use memmove for copying elements between same-size - element alien arrays, direct element buffer copying otherwise. - (_init): Simplify accordingly. - - array: a new Object based array for queue and stack-like ops. - * specs/array_spec.yaml: New file. Specify base behaviours for a - new array object. - * specs/specs.mk (specl_SPECS): Add specs/array_spec.yaml. - * lib/std/array.lua: New file. Implement specified behaviours. - * build-aux/config.ld.in (files): Add lib/std/array.lua. - * local.mk (dist_classes_DATA): Add doc/std.array.html. - (dist_luastd_DATA): Add lib/std/array.lua. - * NEWS: Update. - - debug: fix argerror diagnostics on luajit. - Luajit seems to treat `return error` (where error never returns - anyway) as subject to some kind of optimisation that loses a call - stack level by the time `error` looks up the line number for the - targetted level. Removing the `return` results in the same call - stack frame reference in luajit, 5.2 and 5.1. - * lib/std/debug.lua (argerror): Drop the extraneous `return` - statement. - - debug: fix argcheck diagnostics on Lua 5.1. - Lua 5.2 seems to treat `return argerror` (where argerror never - returns anyway) as subject to some kind of optimisation that loses - a call stack level by the time control flow reaches the `error` - call inside. Removing the `return` results in the same call stack - frame reference in 5.2 and 5.1, but requires incrementing the - level for the correct result. - * lib/std/debug.lua (argcheck): Drop the extraneous `return` - statement, and increment `level` before calling `argerror`. - -2014-05-19 Gary V. Vaughan - - alien: implement a subset of alien to simplify wrappers. - * specs/alien_spec.yaml: Specify behaviour for a useful subset - of the alien APIs. - * specs/specs.mk (specl_SPECS): Add specs/alien_spec.yaml. - * local.mk (dist_modules_DATA): Add doc/modules/std.alien.html. - * lib/std/alien.lua: New file, provide pure Lua implementation - of alien.array, alien.memmove and alien.memset. - * build-aux/config.ld.in (files): Add lib/std/alien.lua. - * local.mk (dist_luastd_DATA): Add lib/std/alien.lua. - - debug: make sure to use debug.getinfo (). - * lib/std/debug.lua (trace): Use debug.getinfo instead of bare - getinfo. - * NEWS: Update. - - debug: add argcheck APIs. - * specs/debug_spec.yaml (argcheck, argerror, argscheck): Specify - behaviour of argument checking functions based on luaL_argerror - and luaL_argcheck, for standardised argument error diagnostics. - * lib/std/debug.lua: Tidy up LDocs. - (argcheck, argerror, argscheck): New functions to satisfy the - specifications. - * NEWS: Update. - -2014-05-01 Gary V. Vaughan - - maint: post-release administrivia. - * configure.ac (AC_INIT): Bump version to 41. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 40 - * NEWS: Record release date. - - refactor: remove unused `std.modules`. - * lib/std/modules.lua: Remove. - * local.mk (dist_luastd_DATA): Adjust. - - refactor: use `t[#t + 1] = v` rather than `table.insert (t, v)`. - Save a function call by factoring away calls to table.insert. - * lib/std/container.lua, lib/std/functional.lua, lib/std/io.lua, - lib/std/list.lua, lib/std/optparse.lua, lib/std/set.lua, - lib/std/strbuf.lua, lib/std/string.lua, lib/std/table.lua, - lib/std/tree.lua: Substitute accordingly. - - refactor: factor out merge_allfields and merge_namedfields. - * lib/std/table (clone, merge): Move shared functionality from - here... - (merge_allfields): ...to here. - (clone_select, merge_select): Move shared funtionality from - here... - (merge_namedfields): ...to here. - - refactor: move leaves and ileaves from base to tree module. - * lib/std/base.lua (ileaves, leaves): Move from here... - * lib/std/tree.lua (ileaves, leaves): ...to here. - * lib/std/base.lua (_leaves): Rename from this... - (leaves): ...to this. - * lib/std/list.lua (flatten): Adjust. - - refactor: move unshared methods out of std.base. - * lib/std/base.lua (merge): Move from here... - * lib/std/table.lua (merge): ...to here. - * lib/std/base.lua (append, compare, concat): Move from here... - * lib/std/list.lua (append, compare, concat): ...to here. - * specs/object_spec.yaml (std.object): Adjust. - - refactor: remove deprecated methods. - * lib/std/base.lua (new, metatable): Remove. - (concat, M): Simplify accordingly. - * lib/std/functional.lua: No need to require std.base. - * lib/std/set.lua (_functions): Move into object declaration, - removing `new`. - * lib/std/strbuf.lua (new): Remove. - * lib/std/tree.lua (new): Remove. - * NEWS: Update. - - tree: allow objects as keys. - * lib/std/tree.lua (Tree.__index): Only fold key list when key - parameter is a raw list, and not when it is a std.object derived - table. - (Tree.__newindex): Only descend the key list creating sub-Trees - when key parameter is a raw list, and not when it is a std.object - derived table. - * NEWS: Update. - - functional: generalize memoize with normalization parameter. - * lib/std/functional.lua (memoize): Don't rely on tostring - having been monkey-patched to std.string.tostring already, but - also don't automatically load all of std.string into memory - unless memoize is called without a normalization function. - * NEWS: Update. - - list: remove deprecated methods. - * lib/std/list.lua: Remove indexKey, indexValue, mapWith, zipWith, - new and slice. - * NEWS: Update. - - specs: std.table.pack is present for any supported Lua release. - * specs/table_spec.yaml (extend_base): List "pack" unconditionally. - - specs: Lua 5.1 does not call tostring on format "%s" arguments. - * specs/string_spec.yaml (..): Explicitly stringify nil argument. - -2014-04-26 Gary V. Vaughan - - std: barrel of monkey(patche)s! - Close #56. - Segregate monkey patching into module functions that have to - be called explicitly. - * lib/std.lua.in: Don't clobber any core metatables, or change - any global symbols on load. - * specs/io_spec.lua (monkey_patch): Specify behaviour of - std.io.monkey_patch function. - * lib/std/io.lua (monkey_patch): Add readlines and writelines - methods to core file objects. - (processFiles): Remove. - * specs/math_spec.lua (monkey_patch): Specify behaviour of - std.math.monkey_patch function. - * lib/std/math.lua (monkey_patch): Overwrite core math.floor. - * specs/string_spec.lua (monkey_patch): Specify behaviour of - std.string.monkey_patch function. - * lib/std/string.lua (monkey_patch): Overwrite core assert and - tostring functions, and add methods and metamethods to core - string objects. - (escapePattern, escapeShell, ordinalSuffix): Remove. - * specs/table_spec.lua (monkey_patch): Specify behaviour of - std.table.monkey_patch function. - * lib/std/table.lua (monkey_patch): Overwrite core table.sort. - * specs/table_spec.lua (barrel, monkey_patch): Specify behaviour - of std.barrel and std.monkey_patch functions. - * lib/std.lua.in (monkey_patch): New function for patching core - symbols and metatables by calling submodule `monkey_patch` - functions. - (barrel): New function for scribbling all over the given - namespace, as well as installing all std monkey_patches. - * specs/debug_spec.yaml, specs/functional_spec.yaml, - specs/io_spec.yaml, specs/math_spec.yaml, specs/package_spec.yaml, - specs/std_spec.yaml, specs/string_spec.yaml, specs/table_spec.yaml, - specs/tree_spec.yaml: Update to reflect removal of default - monkey patching. - - refactor: move `metamethod` from `functional` to `table` module. - * lib/std/functional.lua (metamethod): Move from here... - * lib/std/base.lua (metamethod): ...to here; and... - * lib/std/table.lua (metamethod): ...re-export from here. - Break dependency on `std.functional`. - Adjust all callers. - * NEWS: Update. - - refactor: move clone and clone_rename back into std.table. - * lib/std/base.lua (clone, clone_rename): Move from here... - * lib/std/table.lua (clone, clone_rename): ...to here. - - refactor: break std.container dependency on std.base. - * lib/std/container.lua (instantiate): New function; a faster - equivalent to `merge (clone (proto), t or {})`. - Adjust all callers. - - specs: fix a garbage-in, garbage-out example. - Close #44. - * specs/tree_spec.yaml (tostring): The assumption that tostring - should recurse by itself, or that the Tree constructor should - massage subtables on instantiation were both flawed. Fix the - input to be properly nested tree, and `tostring` will indeed - output a properly nested tree. - -2014-04-25 Gary V. Vaughan - - docs: add missing doc for nometa arg of merge_select. - * lib/std/table.lua (merge_select): Add missing nometa doc. - - table: add merge_select, and support map and nometa args to merge. - Close #56. - * specs/table_spec.yaml (extend_base): Add merge_select. - (merge): Specify behaviour of new `map` and `nometa` args. - (merge_select): Specify behaviour of new `merge_select` api. - (clone, clone_select): Refactor for clarity and orthogonality. - * lib/std/base.lua (merge): Rewrite to support clone-like `map` - and `nometa` parameters, according to improved specifications. - (clone): Rewrite as a call to `merge`. - * lib/std/table.lua (merge_select): New `clone_select` like api - satisfying specs. - (clone_select): Rewrite as a call to `merge_select`. - * NEWS: Update. - -2014-04-23 Gary V. Vaughan - - maint: post-release administrivia. - * configure.ac (AC_INIT): Bump release number to 40. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 39 - * NEWS: Record release date. - - string: leave global string metatable alone. - Close #30. - * lib/std/string.lua (__append, __concat, __index): Move these - metamethods together at the start of the file, and store them in - the returned module table rather than setting them in the global - string metatable. - Improve header comments, to describe namespace issues. - * lib/std.lua.in: Set string metatable elements from string module - as before. - * specs/string_spec.yaml: Adjust to compensate for changes in - returned string module table. - * NEWS: Update. - - specs: no need to explicitly require spec_helper any more. - Since Specl 11, every spec-file automatically loads the - spec_helper.lua from the same directory, if any. - * specs/container_spec.yaml, specs/debug_spec.yaml, - specs/functional_spec.yaml, specs/io_spec.yaml, - specs/list_spec.yaml, specs/math_spec.yaml, - specs/object_spec.yaml, specs/optparse_spec.yaml, - specs/package_spec.yaml, specs/set_spec.yaml, - specs/strbuf_spec.yaml, specs/string_spec.yaml, - specs/table_spec.yaml, specs/tree_spec.yaml: Remove explicit - `require "spec_helper"`. - - specs: take advantage of improvements to Specl DSL. - * specs/container_spec.yaml, specs/debug_spec.yaml, - specs/functional_spec.yaml, specs/io_spec.yaml, - specs/list_spec.yaml, specs/math_spec.yaml, - specs/object_spec.yaml, specs/optparse_spec.yaml, - specs/package_spec.yaml, specs/set_spec.yaml, - specs/std_spec.yaml, specs/strbuf_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml, - specs/tree_spec.yaml: Use `not_to_` instead of `should_not`, - `to_` instead of `should_` and `to_copy` instead of - `should_equal` plus `should_not_be`. - -2014-04-22 Gary V. Vaughan - - maint: update raw urls to new github url scheme. - * README.md: Use new `raw.githubusercontent.com` url scheme - throughout. - - maint: regenerate spec_helper.lua for `make check` if necessary. - * specs/specs.mk (specl-check-local): Add dependency on - specs/spec_helper.lua, so that it is regenerated before the main - `check-local` body is executed if necessary. - - specs: capture stub should return nil to match Specl 12. - * specs/spec_helper.lua.in (capture): Return `nil` for stdout - and stderr to match Specl 12 API. - * specs/table_spec.yaml (clone_rename): Test for `nil`. - - specs: skip deprecation warning expectation when Specl < 12. - * specs/table_spec.yaml (clone_rename): Skip deprecation warning - expectation when the ""-returning stub is being used. - - specs: return empty out and err values from `capture` stub. - * specs/spec_helper.lua.in (table.clone_rename): Return empty - strings for stderr and stdout from fallback stubbed `capture` - implementation. - - specs: elide clone_rename deprecation warning, with Specl 12. - Fix #54. - * specs/spec_helper.lua.in (capture): Stub inprocess.capture if - installed Specl is too old to implement it. - * specs/table_spec.yaml (clone_rename): Wrap clone_rename in - inprocess.capture to elide deprecation warning on stderr. - - refactor: restore alphabetical ordering to table specs. - * specs/table_spec.yaml (clone_rename): Move back into alpha- - betical order. - -2014-04-21 Gary V. Vaughan - - maint: move repository to its own project. - * README.md, configure.ac, rockspec.conf, - * specs/optparse_spec.yaml: Replace rrthomas with lua-stdlib. - - specs: ignore local LUA_INIT and LUA_INIT_5_2 settings. - Fix #53. - * specs/specs.mk (SPECL_ENV): Until the next Specl release is - available, manually reset LUA_INIT and LUA_INIT_5_2. - * bootstrap.conf (buildreq): Add a reminder to clean up after - Specl 12. - -2014-04-21 Reuben Thomas - - Reverse order of arguments to functional.compose; closes #52 - -2014-04-21 Gary V. Vaughan - - tree: return tree root from tree[{}]. - Fix #41. - * specs/tree_spec.yaml (returns tree root for an empty list): New - specification. - * lib/std/tree.lua (__index): Allow empty list as a valid key. - * specs/tree_spec.yaml (std.tree): Remove pending call for - newly passing examples. - * NEWS: Update. - - table: no need to pull all of std.list into memory. - * lib/std/table (elems): Capture base.elems in a local. - (clone_select): Use it. - -2014-04-21 Reuben Thomas - - Modify API of functional.bind, and add spec; closes #48 - - Add a missing require to table.lua - - Add clone_select, closing #50. - - Don’t imply that clone requires its nometa argument to be the literal `true`, thereby blessing our use of string "nometa" argument. - - Remove comment that gives a false impression that the behaviour is there to support backwards-compatibility, whereas in fact it’s necessary for the current API. - -2014-04-21 Gary V. Vaughan - - container: discard unmapped positional parameters. - Fix #35. - * lib/std/container.lua (mapfields): When `map` argument is - given, discard unmapped positional parameters. - (metatable._init): Remove to imply a `nil` value (copy all - fields), because `{}` now discards all positional parameters. - (metatable.__call): Reverse type check of `_init`, so that - mapfields is still called when _init is `nil`. - * specs/object_spec.yaml (std.object): Remove pending call from - newly passing examples. - * NEWS: Update. - - tree: always return nil for non-existent key path. - Fix #39. - * lib/std/functional.lua (function.op["[]"]): Return nil instead - of dereferencing a nil valued table argument. - * specs/tree_spec.yaml (std.tree): Remove pending call prior to - newly passing example. - - functional: handle false valued elements correctly in `map`. - Fix #34. - * lib/std/functional.lua (map): Also insert `false` values into - the results table. - * specs/list_spec.yaml (std.list): Remove pending call from newly - passing example. - -2014-04-16 Gary V. Vaughan - - table: fold `clone_rename` into `clone`. - * specs/table_spec.yaml (std.table): Specify new behaviour with - optional `map` argument. - * lib/std/base.lua (clone): Implement new behaviours. - * lib/std/table.lua (clone_rename): Add deprecation warning, and - move out of the LDoc export table. - (clone): Update doc-comments. - * NEWS: Update. - - base: provide a deprecation mechanism for gentle API upgrades. - * specs/base_spec.yaml: New file. Specify behaviour for a - deprecation wrapper. - * specs/specs.mk (specl_SPECS): Add base_spec.yaml. - * lib/std/base.lua (deprecate): New function. Implement the - specification. - - maint: remove trailing whitespace in NEWS. - * NEWS: Remove trailing whitespace. - - specs: set package.path for in tree specl calls. - Specl 11 works well when called directly in a project root dir, - eg. `specl -freport -v1`, but only if the package path is set - appropriately in each `spec_helper.lua` or similar. - * specs/spec_helper.lua.in: Use `package.normalize` to safely - inject ./lib/?.lua into the head of package.path. - -2014-04-15 Reuben Thomas - - Fix a comment typo - - Fix a comment typo - -2014-04-15 Gary V. Vaughan - - slingshot: sync with upstream. - * slingshot: Sync with latest upstream master. - * bootstrap: Update from slingshot. - * .travis.yml: Regenerate. - - specs: update custom matchers for Specl 11. - * bootstrap.conf (buildreq): Bump specl minimum version to 11. - * specs/spec_helper.lua (matchers.have_size, matchers.have_member): - Matcher object functions require an initial `self` parameter. - (matchers.fail_with): Remove. - - specs: fix a typo; there is no 'a' in should_output. - * specs/optparse_spec.yaml: Fix a typo. - -2014-04-14 Reuben Thomas - - Fix a comment typo - - Fix documentation of table.clone_rename: the parameters got swapped during the earlier re-org - -2014-02-06 Gary V. Vaughan - - package: new path management apis. - * specs/package_spec.yaml: Specify behaviour of new apis. - * lib/std/io.lua (pathsep): Recalculate rather than introduce a - require loop with std.package. - * lib/std/package.lua (find, insert, mappath, normalize, remove): - New functions for maintaining clean pathstrings. - * NEWS: Update. - - functional: new `case` module function. - * specs/functional_spec.yaml: Add specifications for a `case` - function. - * lib/std/functional.lua (case): New function. - * NEWS: Update. - -2014-02-05 Gary V. Vaughan - - optparse: simplify default option setting. - * specs/optparse_spec.yaml: Specify behaviour of new option - defaults parameter. - * lib/std/optparse.lua (parser): Add an optional default options - parameter. - * NEWS: Update. - -2014-02-03 Gary V. Vaughan - - configury: use a sentinel file for multi-target rules. - With thanks to - http://stackoverflow.com/questions/17216048/parallel-gnu-make-and-rules-that-create-several-targets-at-once - * local.mk (ldoc_DEPS): Remove. - $(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): - Depend on sentinel file. - ($(srcdir)/doc): Make and populate doc tree atomically for - parallel make. - - configury: be nicer to parallel make. - * local.mk ($(srcdir)/doc): Factor out of... - ($(dist_doc_DATA)): ...here. - (ldoc_DEPS): Add $(srcdir)/doc. - -2014-02-01 Gary V. Vaughan - - optparse: fix a parse error with unhandled opt in combined options. - * specs/optparse_spec.yaml: Add specifications for behaviour - when encountering unhandled options in various circumstances. - * lib/std/optparse.lua (normalise): Meet specifications. - * NEWS: Update. - - specs: remove last vestiges of optparse's specl origins. - * specs/optparse_spec.yaml (std.optparse): Update category, bug - address, and copyright to be stdlib appropriate. - -2014-01-30 Gary V. Vaughan - - maint: post-release administrivia. - * configure.ac (AC_INIT): Bump release number to 39. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 38 - * NEWS: Record release date. - - specs: commit new have_size matcher. - * specs/spec_helper.lua.in (matchers.have_size): New matcher - used by std.string.split specs. - * configure.ac (AC_CONFIG_FILES): Remove write permission from - generated spec_helper so I don't edit the wrong file next time. - - specs: remove trailing whitespace. - * specs/optparse_spec.yaml: Remove trailing whitespace. - - NEWS: reword a doubled 'to' to satisfy sanity checks. - * NEWS: Reword a doubled 'to'. - - string: split now splits on consecutive whitespace by default. - * lib/std/string.lua (split): Improve LDocs. - Remove @todo. We now have whitespace default split pattern unless - otherwise specified, just like Python. I didn't consider Perl, - because my brain starts to haemorrhage whenever I do that. :-p - * specs/string_spec.yaml (split): Remove spec for string `sep` - argument now that it is optional. - * NEWS: Update. - - string: simplify and speed up `std.string.split`. - * lib/std/string.lua (split): It's a bit more code, but it is - much easier to understand, and it's a lot faster now! - * specs/string_spec.yaml (split): Uncomment pending infinite loop - fix. - * NEWS: Update. - - specs: more comprehensive specs for std.string.split. - * specs/string_spec.yaml (split): Add a lot more specs. - Empty separator causes an infinite loop with the current - implementation. - -2014-01-28 Gary V. Vaughan - - specs: use Specl 10 `a_permutation_of` adaptor for tighter specs. - * specs/tree_spec.yaml: Use `a_permutation_of` instead of - `all_of` to enforce some reordering of only the specified - elements. - - specs: use a custom matcher to specify process status and error. - * specs/spec_helper.lua.in (matchers.fail_with): Custom matcher - to specify process non-zero exit as well as stderr content. - * specs/io_spec.yaml (io.die), specs/optparse_spec.yaml (io.die): - Use it to ensure that in addition to the correct error output, - the exit status is non-zero. - - optparse: integrate with `io.die` and `io.warn`. - * specs/io_spec.yaml: Additional specs for what to do when - `opts.program` and/or `opts.line` are set. - * specs/optparse_spec.yaml (io.die, io.warn): New specs how to - behave when `io.die` or `io.warn` are called after a successful - `parser:parse` call. - * lib/std/io.lua (warn): Implement specified behaviour for new - `opts.line` and `opts.warn` specs. - * lib/std/optparse.lua: Add LDocs for new behaviour. - (parser:parse): Set a metatable on the returned opts table so - than `opts.program` etc. can be found by `io.die` and `io.warn`. - * NEWS: Update. - - io: fix actual and latent bugs in `io.die` and `io.warn`. - * specs/spec_helper.lua.in (luaproc): Factor out of - `tabulate_output`. - (tabulate_output): Adjust. - * specs/io_spec.lua (die, warn): Add new behaviour examples. - * lib/std/io.lua (warn): Adjust to work properly with new specs. - * NEWS: Update. - -2014-01-23 Gary V. Vaughan - - container: inline calls to `empty`. - * lib/std/container (mapfields, metatable._init): Replace - `not empty` with `next`. - (empty): Remove. - - container: drastically simplify and speed up `prototype`. - * lib/std/container.lua (prototype): Inline metaentry, and - simplify. - (metatable.__tostring): Use it. - (metaentry): Remove. - * NEWS: Update. - - container: inline `filter` to only caller. - * lib/std/container.lua (filter): Remove from here. - (metatable.__totable): Inline `filter` here. - - container: cleanup, speedup and bonus bugfix. - * lib/std/container.lua (mapfields): Factored out of - `metatable.__call` and optimised for speed. - (metatable.__call): Adjust accordingly. - (empty): Copied from table.empty to avoind introducing a require - loop. - (modulefunction): Wrap argument in a functable for easily - recognising what not to copy during cloning. - (metatable): Simplify. - * lib/std/object.lua: Import mapfields from Containec, but unwrap - it along with Container.prototype before saving in the Object - metatable for faster access. - Add appropriate LDocs. - * NEWS: Update. - - container: distinguish between the two `functions` tables. - One is the core of Container with metatable as its metatable; the - other is metatable._functions, and is just a list of unpropagated - method functions. We don't want to give the latter a __tostring - metamethod or printing gets very weird. - * lib/std/container.lua (metatable._functions): Make a nometa - clone of the table we return. - * NEWS: Update. - -2014-01-21 Gary V. Vaughan - - configury: update rockspecs in buildreq. - * bootstrap.conf (buildreq): LDoc is now available in the required - version from the official luarocks repo. - - travis: remove unrelease ldoc workarounds. - * .travis.yml: Regenerate, to delete local patches for LDoc. - - doc: vastly improve optparse LDocs. - * lib/std/optparse.lua: Vastly improve optparse LDocs. - * NEWS: Update. - -2014-01-20 Reuben Thomas - - optparse.lua: move "default" options to bottom of help - A more standard position. - -2014-01-19 Gary V. Vaughan - - maint: post-release administrivia. - * configure: Bump revision to 38. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 37 - * NEWS: Record release date. - - doc: keep config.ld out of doc/ for LuaRocks docdir install. - * doc/config.ld.in: Move from here... - * build-aux/config.ld.in: ...to here. - * configure.a (AC_CONFIG_FILES): Adjust. - * local.mk ($(dist_lua_DATA)): Adjust. - * NEWS: Update. - - refactor: rearrange methods and functions for backwards compatibility. - * lib/std/list.lua: Make use of `_function` table to reinstate - backwards compatible module functions. - - maint: retract release 36. - Release 36 intentionally, but unnecessarily, broke backwards - compatibility in list, set, strbuf and tree. Reinstate - compatibility with v35 and earlier where possible. - * lib/std/list.lua (list.filter, list.foldl, list.foldr) - (list.indexKey, list.indexValue, list.map, list.mapWith) - (list.new, list.project, list.shape, list.zipWith): Accept - parameters in the original v35 order. - * lib/std/set.lua, lib/std/strbuf.lua, lib/std/tree.lua (new): - Reinstate for undocumented backwards compatibility. - * News: Update. - - object: share metatables more aggressively. - * lib/std/container.lua (clone): Don't create a new metatable - unnecessarily just because the base object has a `_function` - element -- which is not copied in any case. - - string: use new syntax for List instantiation. - * lib/std/string.lua: List is an Object now. - (split): Use `List` instead of `list`. - (require_version): Use new syntax for List instantiation. - - Revert "maint: post-release administrivia." - This reverts commit 846fd4e578cf8a57c8268979c9fbd2495b0e7b5b. - -2014-01-17 Gary V. Vaughan - - maint: post-release administrivia. - * configure.ac (AC_INIT): Bump version to 38. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 37 - * NEWS: Record release date. - - specs: make sure hell.spawn uses the same Lua as Specl examples. - * slingshot: Sync with upstream, for build-aux/specs.mk fix. - * configure.ac (AC_CONFIG_FILES): Add specs/spec_helper.lua. - * specs/spec_helper.lua: Move from here... - * specs/spec_helper.lua.in: ...to here. - * .gitignore: Add spec_helper.lua. - * specs/specs.mk (SPECL_ENV): Add $builddir/specs to LUA_PATH - for generated spec_helper.lua. - * specs/spec_helper.lua.in (LUA): Don't dig through `_G.arg`, - wait for configure substitution. - - specs: remove duplicate examples. - * specs/math_spec.yaml: forgot to remove the old namespace - corruption tests from this file when adding new check in 3507e84. - - specs: compatibility with Specl < 11. - * specs/specs.mk (specl_SPECS): Move std_spec.yaml to the end of - the list, where symbol leaks don't affect subsequent examples. - - specs: compensate for table.pack differences between Lua 5.1/5.2. - * specs/table_spec (before): Make sure `extend_base` and - `enhance_base` reflect whether core table library has a `pack` - entry. - - std: lazy load submodules on demand. - * specs/std_spec.yaml: New specifications for lazy loading. - * specs/specs.mk (specl_SPECS): Add specs/std_spec.yaml. - * lib/std.lua.in (std.__index): Implement it. - * NEWS: Update. - - doc: add the package name and version to html doc page titles. - * doc/config.ld: Move from here... - * doc/config.ld.in: ...to here. Add a title setting incorporating - @PACKAGE@ and @VERSION@. - * configure.ac (AC_CONFIG_FILES): Add doc/config.ld. - * .gitignore: Add doc/config.ld. - Suggested by Dirk Laurie - - maint: plug symbol leaks with working specifications. - * specs/spec_helper.lua (show_apis): New function. Compare table - entries in a sub-process, to support tracking namespace changes - when requiring modules by various means. - * specs/functional_spec.yaml: New file. Use it to ensure - "std.functional" doesn't leak symbols. - * specs/debug_spec.yaml, specs/functional_spec.yaml, - specs/io_spec.yaml, specs/list_spec.yaml, specs/math_spec.yaml, - specs/object_spec.yaml, specs/optparse_spec.yaml, - specs/package_spec.yaml, specs/set_spec.yaml, - specs/spec_helper.lua, specs/specs.mk, specs/strbuf_spec.yaml, - specs/string_spec.yaml, specs/table_spec.yaml, - specs/tree_spec.yaml: Rewrite specs that check symbol leaks - using show_apis(). - * lib/std/base.lua (new): Don't forget the forward declaration. - * lib/std/set.lua (proper_subset): Likewise. - * NEWS: Update. - Reported by Dirk Laurie - - rockspecs: update detailed description text. - * rockspec.conf (description.detailed): Remove mention of regexps - and getopt. Add mention of civilised option parsing. - - maint: cosmetic fix to imported module list. - * lib/std/modules.lua: Replace `getopt` with `optparse`. - - maint: workaround a luarocks bug handling debug_init.lua. - LuaRocks misinstalls build.modules entries ending in `init.lua`, - so rearrange the source tree and Automake rules so that - `require "std.debug_init"` still works as before even though - the file ends up in the wrong directory after installation. - * lib/std/debug_init.lua: Move from here... - * lib/std/debug_init/init.lua: ...to here. - * slingshot: upgrade for `.../init.lua` handling in mkrockspecs. - * local.mk (dist_luastd_DATA): Remove lib/std/debug_init.lua. - (dist_luastddebug_DATA): New installation dir. Add - lib/std/debug_init/init.lua. - - optparse: replace getopt with an easier to use option parser. - * specs/optparse_spec.yaml: Specify behaviour for a civilised - option parsing API. - * lib/std/optparse.lua: New module. - * lib/std/getopt.lua: Remove. - * doc/config.ld (file), local.mk (dist_luastd_DATA): Adjust. - * specs/getopt_spec.yaml: Remove. - * local.mk (dist_modules_DATA, dist_classes_DATA): Adjust. - * specs/specs.mk (specl_SPECS): Likewise. - * build-aux/sanity-cfg.mk: New file. Don't fail sanity checks on - account of 'OptionParser' in optparse.lua error message. - * NEWS: Update. - -2014-01-17 Reuben Thomas - - string.lua: fix a missing close paren in a docstring - -2014-01-16 Gary V. Vaughan - - slingshot: resync for `mkrockspecs --repository` support. - * slingshot: Sync with upstream. - * local.mk (mkrockspecs_args): Add `--repository lua-stdlib`. - * .travis.yml: Regenerate. - -2014-01-15 Gary V. Vaughan - - slingshot: sync with upstream, for bootstrap git detection fix. - * slingshot: Sync with upstream. - * bootstrap: Sync with slingshot. - - maint: post-release administrivia. - * NEWS: Add header line for next release. - * configure.ac: Bump version number to 37. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 36 - * NEWS: Record release date. - -2014-01-13 Gary V. Vaughan - - configury: use explicit lists instead of $(wildcard ...). - * local.mk (dist_classes_DATA, dist_modules_DATA): Only GNU make - supports $(wildcard ...) expressions, and Automake complains - every time it sees one. List files explicitly. - ($(dist_doc_DATA)): Add $(dist_classes_DATA) and - $(dist_modules_DATA) to LHS of this rule so that make knows it - has to run LDoc to create those files. - - slingshot: resync for subdirectory bootstrap fix. - * slingshot: Sync with upstream. - - slingshot: sync with upstream, for rockspecs in $buildreq. - * slingshot: Sync with upstream. - * bootstrap: Sync with slingshot. - * configure.ac (SPECL_MIN): Remove. - * bootstrap.conf (buildreq): Add ldoc and specl rockspecs. - * .travis.yml: Regenerate, but manually splice in the LDoc-1.4.0 - luarocks install while waiting for a luarocks release. - -2014-01-05 Gary V. Vaughan - - slingshot: sync with upstream. - Fix the annoying contest.sed file dropping bug. - * slingshot: Sync with upstream. - * bootstrap: Sync with slingshot. - - doc: distribute ldoc classes and modules documentation. - * local.mk (filesdir, dist_files_DATA): Rename from these... - (classesdir, dist_classes_DATA): ...to these. - (dist_classes_DATA, dist_modules_DATA): Use correct paths in - gmake wildcard expression. - -2014-01-04 Gary V. Vaughan - - maint: update copyright notices to include 2014. - * .x-update-copyright: New file. Exclude files not owned by this - project from update-copyright rules. - * boootstrap.conf, configure.ac, local.mk: Bump copyright year. - - travis: horrid workaround for crashy LDoc master vs apt-get luarocks. - * slingshot: Sync for Travis fixes. - * .travis.yml: Temporary code to fetch a custom stable version of - LDoc that doesn't crash on stdlib doc-comments. - - maint: fix copyright attribution in COPYING. - * COPYING: Correct year and authors in copyright statement. - - slingshot: sync with upstream and simplify accordingly. - * slingshot: Sync with upstream. - * bootstrap: Update from slingshot. - * configure.ac (AM_INIT_AUTOMAKE): Remove 'foreign'. Slingshot - now handles missing README automatically. - * bootstrap.slingshot: Remove. No longer required. - * bootstrap.conf: Remove bootstrap.slingshot source boilerplate. - (stdlib_force_changelog): Remove. Automated by slingshot now. - * INSTALL: Remove. Autotools copies in the canonical version - automatically. - * COPYING: New file, with MIT License, to avoid Autotools - copying over a standard GPLv3 COPYING boilerplate. - * .gitignore: Update. - - slingshot: sync with upstream, and update copyright years. - * slingshot: Update, particularly for update-copyright support. - * bootstrap, bootstrap.slingshot: Update from slingshot. - -2014-01-01 Gary V. Vaughan - - slingshot: sync with upstream. - * slingshot: Sync with latest upstream, particularly for Travis fixes. - * .travis.yml: Regenerate. Plus temporary patch to run gvvaughan/next - branch of LDoc during integration until stevedonovan/master is fixed. - -2013-12-11 Gary V. Vaughan - - tree: derive from std.container. - * specs/tree_spec.yaml: Replace object methods with module - functions throughout. - Add specs for inheritted functionality. - * lib/std/tree.lua: Rewrite as a derivative of std.container. - Change object methods to Container style module functions. - * NEWS: Update. - - doc: update object constructor _function documentation. - * lib/std/container.lua: Update module doc-comment to reflect - simplification of passing module functions in _functions table. - (std.container): Update _function description. - * lib/std/object.lua (std.object): Likewise. - * lib/std/set.lua (std.set): Likewise. - - specs: improve expectation description. - * specs/set_spec.yaml: Write "shows the type name" instead of - "contains the type". - -2013-12-10 Gary V. Vaughan - - refactor: automatically fill method functions form _functions table. - * lib/std/container.lua (metatable.__call): Copy entries from - newly passed _functions table to object. - * lib/std/set.lua (Set): Delete manual copy of method functions. - - set: derive from std.container, keys no longer clash with method names. - * specs/set_spec.yaml: Replace object methods with prototype - functions through out. - Check that set elements with the same name as a prototype - function behave properly. - * lib/std/set.lua: Rewrite as a derivative of std.container. - Change object methods to Container style prototype functions. - * NEWS: Update. - - list: remove trailing whitespace. - * lib/std/list.lua: Remove trailing whitespace. - - container: new module for objects that use [] to access contents. - * specs/container_spec.yaml: Specify behaviour of Container - objects. - * specs/specs.mk (specl_SPECS): Add specs/container_spec.yaml. - * specs/object_spec.yaml: Remove duplicate tests. - * doc/config.ld (file), local.mk (dist_luastd_DATA): Add - lib/std/container.lua. - * lib/std/container.lua: New file. Implement Container objects. - They have no methods, so that __index can be used for accessing - contents instead. - * lib/std/object.lua: Vastly improved doc-comments. - Simplify drastically in light of Container implementation. - * NEWS: Update. - -2013-12-09 Gary V. Vaughan - - Revert "maint: move lua extension sources to $top_srcdir/ext." - This reverts commit 4d51ca63a1eedd3759201db8b3df850a658856e6. - - I have no idea why I thought moving Lua libraries from the lib - tree to the Lua C extensions ext tree seemed like a good idea. - Undo the damage. - * ext/: Rename back to lib/. - * local.mk (std_path, dist_lua_DATA, dist_luastd_DATA) - (mkrockspecs_args, EXTRA_DIST, dist_files_DATA) - (dist_modules_DATA): Adjust. - * doc/config.ld (file): Adjust. - * .gitignore: Update. - -2013-12-09 Gary V. Vaughan - - table: add string support to totable function. - * ext/std/table.lua (totable): When passed a string, return a - table of each character in the string. - * NEWS: Update. - - specs: simplify the tree merge specs. - * specs/tree_spec.yaml (tree merge): comparing non-leaf nodes - is not a fair test, better to set k3 to a different string - that can be tested before and after the merge without worrying - about whether a table node is coerced to a tree node. - -2013-11-28 Gary V. Vaughan - - specs: don't assume in order traversal by tree.nodes. - * specs/tree_spec.yaml (node): Use `should_contain.all_of` - in place of `should_equal` to avoid enforcing a particular - traversal order. - - tree: fix broken tests, and improve doc-comments (Fixes #40) - * specs/tree_spec.yaml (inodes, nodes): Be sure to clone iterator - returned paths before storing. Some corrections to the expected - results. - Remove pending "see issue #40" instances. - (merge): Fix tests. Remove pending "see issue #40" instances. - * ext/std/tree.lua (nodes): Much improved doc-comment. - (merge): Assert the arguments are actual tree nodes, because - raw tables do not work! - - doc: update doc-comments for latest LDoc master. - * doc/config.ld (metamethod): Delete. Metamethods are now - separated out automatically. - * ext/std/list.lua: Describe use of object methods as module - functions. - Update doc-comments. - * ext/std/object.lua, ext/std/set.lua, ext/std/strbuf.lua, - ext/std/strict.lua, ext/std/tree.lua: Update doc-comments. - -2013-11-27 Gary V. Vaughan - - tree: add specl specs, and fix simple API inconsistencies. - * specs/tree_spec.yaml: New file. Examples of how tree APIs - should behave. - * specs/specs.mk (specl_SPECS): Add specs/tree_spec.yaml. - * ext/std/base.lua (ileaves, leaves): Report non-table arguments. - * ext/std/tree.lua (clone, inodes, nodes, merge): Likewise. - - string: report assert failures from assert caller level. - * ext/std/string.lua (assert): Call error with level 2, to report - errors from the assert caller not assert itself. - - tree: fix argument order for list.foldl call. - The argument order for list.foldl changed in 9fe27bb, but one - call site wasn't updated to match. - * ext/std/tree.lua (metatable.__index): Use new argument order - for list.foldl call. - -2013-11-26 Reuben Thomas - - Remove some spurious comment markers in docstrings. - These were introduced by commit 31b314c835 converting doc-comments to - LDoc 1.4. - -2013-11-26 Gary V. Vaughan - - travis: replace recently missing links for libyaml - Rerunning previously passing integration test shows that the - multilibbed libyaml libraries are no longer available from - /usr/lib alongside other libs - maybe an OS upgrade, or an - upstream packaging error? - * .travis.yml (install): Remove libyaml-dev reinstall. - Run a shell find command to link the multilib libyaml libs - back into /usr/lib. If this command starts failing in future - then it should mean libyaml has moved back to the proper place - and we're failing to relink it manually, so this workaround - can be removed. - - maint: install libyaml-dev for Travis. - Seems recent tests have been failing because libyaml-dev is no - longer installed by default. - * .travis.yml (install): Add libyaml-dev which pulls in libyaml. - - doc: distinguish object and class methods in object doc-comments. - * ext/std/object.lua (clone): Rename first argument to self, and - remove associated @param as a hint to LDoc. - (stringify, totable): Likewise. - (metatable): Document important fields. - (metatable.__call): Add documentation. - - doc: use a more topographical ordering for document sidebar. - Now that the latest LDoc doesn't enforce strict alphabetical - ordering, reorder the documentation into a more topographical - order for easier reading. - * doc/config.ld (file): Reorder for clarity. - - doc: separate camelCaseCompat methods to avoid LDoc warnings. - Using the @export feature of LDoc provides the flexibility to - change the exported functions from a single table, but we also - have to be careful not to sweep up undocumented access points - in the same table, otherwise LDoc correctly warns us that those - functions have no doc-comments. - * ext/std/getopt.lua (getOpt, processArgs, usageInfo): Move - to a separate table, and merge back into the module table before - return. - * ext/std/io.lua (processFiles): Likewise. - * ext/std/list.lua (indexKey, indexValue, mapWith, zipWith): - Likewise. - * ext/std/string.lua (escapePattern, escapeShell, ordinalSuffix): - Likewise. - - doc: markup std.string.escape_string correctly for LDoc. - * ext/std/string.lua (escape_string): Add missing leading hyphen. - - doc: LDoc master now handles local references differently. - * .travis.yml (install): Switch to github master rockspec. - * ext/std/list.lua (enpair, depair, __concat, __add): Adjust - @see argument. - * ext/std/object.lua (__totable, __tostring): Likewise. - * ext/std/set.lua (__add, __sub, __mul, __div, __le, __lt): - Likewise. - * ext/std/strbuf.lua (__concat, __tostring): Likewise. - -2013-11-18 Gary V. Vaughan - - doc: point to updated online LDoc documentation. - * README.md (Documentation): Refer to latest LDoc docs. - - maint: remove last references to luadoc. - * local.mk (dist_doc_DATA): Remove luadoc.css. Add ldoc.css. - - travis: use unofficial ldoc 1.4.0 release candidate. - We're using features from the release candidate already, so - temporarily point the travis installer to that rockspec while - waiting for an official release. - * .travis.yml: Adjust ldoc rockspec location. - - list: fix broken specs. - * ext/std/list.lua (depair): Needs to be the inverse operation of - enpair, which requires returning a bare table, and not a List - object. - - .gitignore: ignore ldoc output, not luadoc output. - * .gitignore: Remove /doc/luadoc.css. Add /doc/ldoc.css. - - getopt: revert an accidental comment deletion. - * ext/std/getopt.lua (makeOptions): Revert accidental deletion. - - doc: convert doc-comments to LDoc 1.4. - * doc/config.ld: New file. Configuration for LDoc. - * local.mk (EXTRA_DIST): Add it. - (dist_doc_DATA): Remove Luadoc files. Add LDoc files. - ($(dist_doc_DATA)): Invoke LDoc. - * configure.ac (SS_CONFIG_TRAVIS): Request ldoc instead of luadoc. - * .travis.yml: Regenerate. - * .gitignore: Adjust. - * ext/std.lua.in, ext/std/base.lua, ext/std/debug.lua, - ext/std/functional.lua, ext/std/getopt.lua, ext/std/io.lua, - ext/std/list.lua, ext/std/math.lua, ext/std/modules.lua, - ext/std/object.lua, ext/std/package.lua, ext/std/set.lua, - ext/std/strbuf.lua, ext/std/strict.lua, ext/std/string.lua, - ext/std/table.lua, ext/std/tree.lua: Convert doc-comment syntax to - richer LDoc 1.4 format. - -2013-11-15 Gary V. Vaughan - - maint: move lua extension sources to $top_srcdir/ext. - For consistency with other Lua projects I maintain, rename the - lib directory to ext. - * lib/: Rename to ext/. - * local.mk (std_path, dist_lua_DATA, dist_luastd_DATA) - (mkrockspecs_args, EXTRA_DIST, dist_doc_DATA, dist_files_DATA) - (dist_modules_DATA): Adjust. - * .gitignore: Update. - - bootstrap: drop 'lua-' prefix from project name. - * configure.ac (AC_INIT): Set name to 'stdlib'. - * .travis.yml: Regenerate. - -2013-09-15 Gary V. Vaughan - - slingshot: sync with upstream. - * slingshot: Update to latest revision, particularly to get the - fix for release announcement content. - * bootstrap: Upgrade from latest slingshot. - * .travis.yml: Regenerate. - -2013-06-27 Gary V. Vaughan - - list: std.list returns the List prototype object. - Removing the separation between List prototype and the module - table that used to wrap it, for consistency with the other - Object specialisations. We break backwards compatibilitf here - though because the argument ordering used to be different for - several functions depending on whether they were called through - the module table, or as List methods. The List method ordering - (i.e. list argument first) wins out here, because that is a - prerequisite of being able to call object methods with the Lua - : syntax. - * specs/list_spec.yaml: Remove examples of constructing a List - from the module table, and with the `new` command. - * lib/std/list.lua: Much simplified by removal of the module - table. - (filter, foldl, foldr, index_key, index_value, map, map_with) - (project, shape, zip_with): The list operand is always first - now, whether called with a `.' or a `:'. - Adjust all callers. - (new): Remove. Adjust all callers. - * NEWS: Update. - - strbuf: std.strbuf returns the strbuf prototype object. - Fix some latent bugs caused by the artificial separation between - the metatable of strbuf and strbuf.StrBuf, by removing the - distinction between the two. `require "std.strbuf"` returns the - actual StrBuf object, ready to go! - * specs/strbuf_spec.yaml: Remove examples of constructing a StrBuf - from the module table, and with the `new` command. - * lib/std/strbuf.lua: No need to wrap the StrBuf prototype in an - additional layer of abstraction to return a module table containing - the StrBuf prototype. Just return StrBuf directly. - (strbuf.new): Remove. - Adjust all callers. - - set: std.set returns the Set prototype object. - Fix some latent bugs caused by the artificial separation between - the metatable of set and set.Set, by removing the distinction - between the two. `require "std.set" returns the actual Set object, - ready to go! - * specs/set_spec.yaml: remove examples of constructing a set from - the module table, and with the `new` command. - * lib/std/set.lua: No need to wrap the Set prototype in an - additional layer of abstraction to return a module table containing - the Set prototype. Just return Set directly. - (set.new): Remove. - Adjust all callers. - - object: std.object returns the root object. - Fix some latent bugs caused by the artificial separation between - the metatable of object and object.Object, by removing the - distinction between the two. `require "std.object"` returns the - actual root object, ready to go! - * specs/object_spec.yaml: Remove examples of constructing an - object from the object module table and the `new` method. - * lib/std/object.lua: No need to wrap the root object in an - additional layer of abstraction to return a module table containing - the root object. Just return the root object directly. - (object.new): Remove. - Adjust all callers. - * NEWS: Update. - - object: don't assume object metatable __index is always a table. - * lib/std/object.lua (clone): Only merge new object metatable - methods when both metatables have a table type __index entry. - (metatable:__call): Let Lua do the lookup for an object clone - function, incase __index is a function. - - object: be consistent with various object constructors. - * specs/object_spec.yaml: Specify behaviour for Object:clone {} - and object.new () constructors, with single table initialiser and - parameter list respectively, plus the Object {} and object () - syntactic sugars for each. - * specs/list_spec.yaml, specs/set_spec.yaml, - specs/strbuf_spec.yaml: Likewise for other objects to make sure - all are consistent. - * lib/std/list.lua, lib/std/set.lua, lib/std/strbuf.lua: Implement - the specified behaviours. - - object: fix __lt and __le support with shared metatables. - * specs/object_spec.yaml: Specify desired behaviour with new - examples for metatable sharing. - * lib/std/object.lua (metaentry): New helper function. - (object_type, clone, stringify, totable): Factor out of root - object initialiser. - (clone): Maintain separation between "_" prefixed fields, kept - in the new object metatable, and everything else in the object. - If the newly instantiated object requires a new metatable to - support the additional "_" prefixed keys, create it, otherwise - share the prototype's metatable. - Additionally, when creating a new metatable, be sure to merge - in __index methods from the prototype metatable. - (Object): Much simplified! - (metatable): Set type, methods and metamethods for root object. - * lib/std/list.lua (methods, metalist, new): Refactored from - these... - (List, new): ...to these, also simplifed accordingly. - * lib/std/set.lua (M, metaset, new): Refactored from these... - (M, new): ...to this, much simplified. - * specs/list_spec.yaml, specs/set_spec.yaml: Add more examples - to specify metatable propagation behaviour, and refactor for - clarity and consistency. - * NEWS: Update. - - set: share metatable so that __le and __lt work. - * specs/set_spec.yaml: Many more examples, in particular to check - behaviour of __le and __lt comprehensively. - * lib/std/set.lua (metaset): New metatable shared by all sets. - (new): Adjust. - * NEWS: Update. - - travis: regenerate .travis.yml. - * .travis.yml: specl-8 is out, so don't try to work around it - any more! - - specs: update spec_helper for Grand Renaming II™. - * specs/spec_helper.lua: Fix table_ext reference for name change - to straight table. - -2013-05-29 Gary V. Vaughan - - object: __tostring should call __totable metamethod, not method. - * lib/std/object.lua (new.__tostring): Because we have to set a - separate metatable for objects that have __lt or __le metamethods, - self:__totable () is not always the same as getmetatable (self). - __totable (self). Use the longhand so that __tostring calls the - right function in both cases. - -2013-05-22 Gary V. Vaughan - - travis: use specl from git until specl 8 is released. - * .travis.yml: Fetch the rockspec from github. Install it. - - list: derive from `std.object`. - * specs/list_spec.yaml: Describe expected behaviour of list as an - Object. - * specs/specs.mk (specl_SPECS): Add specs/list_spec.yaml. - * lib/std/list.lua (metalist): __lt and __le metamethods only - work if both objects share the same metatable... this one for - list objects. - (new): Return a new Object, with metalist as the metatable, - and _clone doctored to propagate the metalist metatable. - (M): Return a callable table that forwards module calls to the - `new` function. - * NEWS: Update. - - object: be sure to run tostring on array elements before table.concat. - * lib/std/object.lua (new.__tostring): table.concat requires that - all elements already be strings, so call tostring on the array - part of the object table before passing to table.concat. - - object: respond to tostring() with stringified table of non-hidden fields. - Rather than add individual __tostring metamethods to every object - type, implement a general stringification algorithm in the base - object, to return the type followed by the array part of the object, - and then the dictionary part of the object. - * specs/object_spec.yaml (__tostring): Describe desired behaviour. - * specs/set_spec.yaml (__tostring): Likewise. - * lib/std/object.lua: Don't overwrite core table functions with - std.base. Adjust all callers. - (new.__tostring): return stringification of non-hidden fields. - * lib/std/set.lua (new.__tostring): Remove. Inheritted base object - metamethod is equivalent. - - configury: specl 8 required for stdlib compatible objects. - * configure.ac (SPECL_MIN): Bump to Specl 8. Earlier versions use - an incompatible object system, which crash when fed recently - enhanced stdlib objects. - - string: prettyprint valid symbol keys without spurious quoting. - * specs/string_spec.yaml (prettytostring): Remove quoting from - examples with valid symbols as keys. Add an example with some - invalid symbol names as table keys. - * lib/std/string.lua (prettytostring): Skip the key quoting - code unless a key is not a string, or contains any non-word - character. - - string: display prettyprinted table keys in table.sort order. - When comparing actual and expected output in unit tests, or with - Specl matchers, it's quite difficult to write robust examples when - the output of prettyprint is randomised for tables. This commit - ensures that table keys are always output in the same order. - * specs/string_spec.yaml (prettytostring): Examples of desired - behaviour for string.prettytostring. - * lib/std/string.lua (render): Use a sorted list of keys to - determine the order in which they are output. - * NEWS: Update. - - object: __totable and __index support. - Provide object.type, analagously to io.type. - * specs/object_spec.yaml (__totable): Specify desired - behaviour. - * specs/set_spec.yaml (__totable): Likewise. - * specs/strbuf_spec.yaml (__totable): Likewise. - * lib/std/object.lua (typeof): Rename from this... - (M.type): ...to this, to support e.g. object:type (). - (new.__totable): Return a table of non `_` prefixed object - elements. - (new.__index): Defer to methods in M, when the object itself has - none. - * lib/std/getopt.lua (argtype): Set of valid argtype keys. - (getopt): Comparing an Option's type field to nil doesn't work, - because of the Object:type () method it shadows. Instead check - for a value not in the argtype set. - (usageinfo): Reorder type tests to avoid the same Object:type() - problem. - * lib/std/set.lua: Use object.type instead of object.typeof. - * specs/object_spec.yaml, specs/set_spec.yaml, - specs/strbuf_spec.yaml: Adjust. - * NEWS: Update. - - maint: The Grand Renaming II™ - use `require "std.string"` etc. - Now that individual modules are loaded from the std subdirectory, - remove the spurious "_ext" suffix so that `require "std.io_ext"` - is not needed any more. - * lib/std/debug_ext.lua, specs/debug_ext_spec.yaml, - lib/std/io_ext.lua, specs/io_ext_spec.yaml, - lib/std/math_ext.lua, specs/math_ext_spec.yaml, - lib/std/package_ext.lua, specs/package_ext_spec.yaml, - lib/std/string_ext.lua, specs/string_ext_spec.yaml, - lib/std/table_ext.lua, specs/table_ext_spec.yaml: Rename from - these... - * lib/std/debug.lua, specs/debug_spec.yaml, lib/std/io.lua, - specs/io_spec.yaml, lib/std/math.lua, specs/math_spec.yaml, - lib/std/package.lua, specs/package_spec.yaml, lib/std/string.lua, - specs/string_spec.yaml, lib/std/table.lua, specs/table_spec.yaml: - ...to these. Adjust all require calls. - * specs/io_spec.yaml, specs/string_spec.yaml, specs/table_spec.yaml - (extensions): Add some missing apis. - * lib/std.lua.in, lib/std/modules.lua: Adjust and simplify. - * specs/specs.mk (specl_SPECS): Adjust. - * local.mk (dist_luastd_DATA): Adjust. - * NEWS: Update. - - object: don't trigger table metamethods for type lookup. - * lib/std/object.lua (typeof): When looking up the type of an - object table with no _type field, don't use __index metamethod. - -2013-05-19 Gary V. Vaughan - - configury: support non-autotool LuaRocks installation. - * slingshot: Sync with upstream. - * local.mk (mkrockspecs_args): Add --module-dir so that latest - mkrockspecs will use the LuaRocks builtin build.type. - * std/std.lua.in, std/base.lua, std/debug_ext.lua, - std/debug_init.lua, std/functional.lua, std/getopt.lua, - std/io_ext.lua, std/list.lua, std/math_ext.lua, std/modules.lua, - std/oject.lua, std/package_ext.lua, std/set.lua, - std/strbuf.lua, std/strict.lua, std/string_ext.lua, - std/table_ext.lua, std/tree.lua: Move from here... - * lib/std.lua.in, lib/std/base.lua, lib/std/debug_ext.lua, - lib/std/debug_init.lua, lib/std/functional.lua, lib/std/getopt.lua, - lib/std/io_ext.lua, lib/std/list.lua, lib/std/math_ext.lua, - lib/std/modules.lua, lib/std/oject.lua, lib/std/package_ext.lua, - lib/std/set.lua, lib/std/strbuf.lua, lib/std/strict.lua, - lib/std/string_ext.lua, lib/std/table_ext.lua, lib/std/tree.lua: - ...to here. - * local.mk (std_path): Adjust. - * std/.gitignore: Remove. Consolidate into... - * .gitignore: ...here. - * std/std.mk: Remove. Consolidate into... - * local.mk: ...hore. - * NEWS: Update. - -2013-05-16 Gary V. Vaughan - - NEWS: fix poor grammar in set to object entry. - * NEWS: Fix poor grammar in set to object entry. - - object: rename object.Object to object.new for consistency. - * std/object.lua (Object): Rename from this... - (new): ...to this. Adjust all callers. - * specs/object_spec.yaml: Adjust. - * NEWS: Update. - -2013-05-15 Gary V. Vaughan - - set: derive from `std.object.Object`. - * specs/set_spec.yaml: Describe expected behaviour of set as an - Object. - * specs/spec_helper.lua (have_member): New custom Specl matcher. - * specs/specs.mk (specl_SPECS): Add specs/set_spec.yaml. - (EXTRA_DIST): Add specs/spec_helper.lua. - * std/set.lua (delete, insert): Return the modified set. - (difference, intersection, propersubset, subset) - (symmetric_difference, union): Coerce a table in argument 2 to a - set. - (new): Return a new Object, with metamethods rolled in. - (M): Return a callable table that forwards module calls to the - `new` function. - * NEWS: Update. - - strbuf: derive from `std.object.Object`. - * specs/strbuf_spec.yaml: Describe expected behaviour of strbuf as - an Object. - * specs/specs.mk (specl_SPECS): Add specs/strbuf_spec.yaml. - * std/strbuf.lua (new): Return a new Object, with metamethods and - object methods rolled in. - (M): Return a callable table that forwards module calls to the - `new` function. - * NEWS: Update. - -2013-05-14 Gary V. Vaughan - - object: bake in inherited object type names. - * specs/object_spec.yaml: New file. Examples of how typed objects - should behave. - * specs/specs.mk (specl_SPECS): Add specs/object_spec.yaml. - * std/table_ext.lua (clone, clone_rename, merge): Move from here... - * std/base.lua (clone, clone_rename, merge): ...to here. - * std/table_ext.lua (M.clone, M.clone_rename, M.merge): Re-export - implementations from `std.base`. - * std/object.lua (Object._type): Name the `type` of this object. - (typeof): Insepet the type of an object, falling back on system - type for non-objectes. - Return the public interface table, with a `__call`able metatable - that delegates to Object for instantiation. - - configury: bump minimum specl version to release 7. - Specl 6 has a bug in `should_contain` matcher that makes the - package_ext checks fail spuriously. - * configure.ac (SPECL_MIN): Bump to 7. - -2013-05-12 Gary V. Vaughan - - string_ext: make escape_pattern compatible with Lua 5.2. - Lua 5.2 complains of an illegal character if a non-pattern meta - character is preceded by a '%'. - * std/string_ext.lua (escape_pattern): Escape only meta-chars. - * specs/string_ext_spec.yaml (escape_pattern): Adjust example - code to match. - * NEWS: Update. - - refactor: move base.lua methods to more appropriate modules. - Move things around to remove more trampling of _G, and break the - remaining dependency loops, so that modules can all be required - independently. - * std/list.lua (M.append, M.compare, M.concat, M.elems, M.ileaves) - (M.leaves, M.new): Move from here... - * std/base.lua (M.append, M.compare, M.concat, M.elems, M.ileaves) - (M.leaves, M.new): ..to here, for breaking remaining dependency loops. - * std/list.lua (M.append, M.compare, M.concat, M.elems, M.new): - Import from base, and reexport. - * std/base.lua (_G.inodes, _G.nodes): Move from here... - * std/tree.lua (M.inodes, M.nodes): ...to here. - (M.leaves, M.ileaves): Import from base, and reexport. - * std/base.lua (_G.pack, _G.ripairs, _G.totable): Move from here... - * std/table_ext.lua (M.pack, M.ripairs, M.totable): ...to here. - * specs/table_ext_spec.yaml (pack, ripairs, totable): Add pending - example descriptions. - * std/base.lua (_G.metamethod, _G.id, _G.bind, _G.curry, _G.compose) - (_G.memoize, _G.eval, _G.collect, _G.map, _G.filter, _G.fold, _G.op): - Move from here... - * std/functional.lua (M.metamethod, M.id, M.bind, M.curry, M.compose) - (M.memoize, M.eval, M.collect, M.map, M.filter, M.fold, M.op): - New new module. ...to here. - * std/modules.lua: Add std.functional. - * std/std.mk (nobase_dist_lua_DATA): Add std/functional.lua. - * std/base.lua (_G.die, _G.warn): Move from here... - * std/io_ext.lua (M.die, M.warn): ...to here. - * std/std.lua.in: Reexport all recently modularized APIs into _G. - * std/getopt.lua: Explicitly import used modules. - * std/set.lua, std/strbuf.lua: Rearrange definitions to match other - modules. - * std/string_ext.lua: Require std.functional for metamethod(). - (_tostring): Be explicit when saving a handle for _G.tostring. - * NEWS: Update. - - debug_ext: use correct require dependencies. - * std/debug_ext.lua (say): Be explicit about the use of enhanced - string.tostring. - Be sure to require "list" before using its methods. - -2013-05-11 Gary V. Vaughan - - configury: bump release number to 36. - * configure.ac (AC_INIT): Bump release number to 36. - - maint: no need to gitignore files we no longer generate. - * .gitignore: Remove luarocks-config.lua and release-notes-* from - ignore list. - -2013-05-06 Gary V. Vaughan - - slingshot: Update. - * slingshot: Update. - * configure.ac (AC_INIT): Package name has to match gnulib repo- - name for generated rockspecs to find the tag zipballs. - * .gitignore: Move /stdlib-*.tar.gz to /lua-stdlib-*.tar.gz. - * .travis.yml: Regenerate. - - travis: make the lua5.1 hacked luadoc executable. - * slingshot: Upgrade. - * .travis.yml: Regenerate. - - travis: don't install luadocs twice. - * slingshot: Update. - * .travis.yml: Regenerate. - - travis: update slingshot, for better luadoc handling. - * slingshot: Update. - * configure.ac: Adjust. - * .travis.yml: Regenerate. - -2013-05-05 Gary V. Vaughan - - Revert "travis: force luadoc to run only using Lua 5.1." - This reverts commit d54819f8b58988b10f8a298746abc28ce30b41c8. - - travis: force luadoc to run only using Lua 5.1. - * slingshot: Update. - * configure.ac (EXTRA_ROCKS): Ugly hack to inject the interpreter - substitution without requiring a locally modified travis.yml.in. - * .travis.yml: Regenerate. - - slingshot: update. - * slingshot: Update. - * bootstrap.slingshot: Manually update. - * bootstrap.conf (slingshot_files): Add m4/slingshot.m4. - * configure.ac: Adjust. - * .travis.yml: Regenerate. - - travis: install luadoc before running luarocks make. - * configure.ac (EXTRA_ROCKS): Add luadoc. - * .travis.yml: Regenerate. - - slingshot: update. - - travis: regenerate .travis.yml. - * .travis.yml: Regenerate. - - travis: specify EXTRA_ROCKS correctly. - * configure.ac (EXTRA_ROCKS): Add lyaml rock. - * .travis.yml: Regenerate. - - slingshot: use the public slingshot url. - * slingshot: Update. - * bootstrap.slingshot: Sync from upstream. - - maint: post-release administrivia. - * NEWS: Add header line for next release. - * .prev-version: Record previous version. - * ./local.mk (old_NEWS_hash): Auto-update. - - Release version 35 - * NEWS: Record release date. - - slingshot: sync with upstream. - * .gitmodules: Remove. Slingshot regenerates on demand. - * .gitignore: Ignore .gitmodules. - * slingshot: Update. - * bootstrap.slingshot: Copied from slingshot, for clean checkout - bootstrapping before slingshot subproject is populated. - * bootstrap.conf: Adjust. - - maint: collect previous release notes into NEWS. - * NEWS: new file, required for the Slingshot release process. - * local.mk (old_NEWS_hash): Update. - - formatting: fix whitespace errors flagged by slingshot syntax-check. - * INSTALL, specs/debug_ext_spec.yaml: Remove trailing blank lines. - * specs/io_ext_spec.yaml, specs/match_ext_spec.yaml, - specs/table_ext_spec.yaml: Remove trailing spaces. - * std/std.mk: Remove SPACE-TAB sequence. - - configury: adopt slingshot release mechanism. - * GNUmakefile, Makefile.am, build-aux/mkrockspecs, - m4/ax_compare_version.m4, m4/ax_lua.m4, m4/ax_with_prog.m4: - Remove. These files are handled by slingshot now. - * bootstrap: New file. Copied from slingshot subproject. - * bootstrap.conf (stdlib_copy_slingshot): Install missing slingshot - files. - * configure.ac: Adjust to drive slingshot processes. - * local.mk: New file. Project local make rules. - * rockspec.conf: New file. Slingshot rockspec template. - * specs/specs.mk: Simplified. - * .gitignore: Update. - * .travis.yml: Regenerate. - - slingshot: add slingshot as a git submodule. - * .gitmodules: New file. - * slingshot: New submodule. - -2013-04-30 Gary V. Vaughan - - configury: there is no distinct top_srcdir with non-recursive make. - * std/std.mk (dist_doc_DATA, dist_files_DATA, dist_modules_DATA): - Use plain $(srcdir). - - std: don't overwrite lua library tables. - Overwriting a global library table causes hard-to-debug problems - when the C part of Lua is holding references to the original - (overwritten) table. - * std/std.lua.in: When injecting new entry points into a core - library, do it an entry at a time to avoid breaking references to - the original address in the core. This fixes a problem with the - `package.path` and `package.cpath` being lost when set from - LUA_INIT, among many other potential issues. - -2013-04-13 Reuben Thomas - - Remove non-core modules, which go into separate lua-rrtlib for ad-hoc modules - -2013-04-11 Gary V. Vaughan - - specs: upgrade to Specl 5. - * specs/string_ext_spec.yaml, specs/table_ext_spec.yaml: Update - all 'should_error' matchers to saner Specl 5 ordering. - * specs/specs.mk (SPECL_MIN): Bump to 5. - - getopt: also requires io_ext module to be loaded. - * std/getopt.lua: Load io_ext into a local table. - -2013-04-10 Gary V. Vaughan - - configury: install correctly with configure or luarocks. - For the classic './configure; make; make install' to work we need - to install to '$luadir' as discovered by ax_lua.m4. But we also - need to install directly to luarocks '$(LUADIR)' otherwise the - stdlib source files are not copied onto the LUA_PATH properly by - 'luarocks make stdlib-*-1.rockspec'. - * mkrockspecs.lua: Move from here... - * build-aux/mkrockspecs: ...to here. - * GNUmakefile (rockspecs): Adjust accordingly. - * build-aux/mkrockspecs: Synchronise with the version that loads - a template, interpolates the variables and writes out the result. - * rockspecs.lua (build.install_command): Pass luadir to ensure - installation to the correct directory for luarocks. - * stdlib.rockspec.in: Remove. - * bootstrap: New script to call autoreconf for compatibility with - new build-aux/mkrockspecs. - * GNUmakefile (Makefile.in): Use it. - -2013-04-08 Gary V. Vaughan - - docs: point to github pages documentation. - * README.md (Documentation): Point to github pages documentation. - - docs: fix stupid typo. - * README.md (Installation): That would be luarOCKS not luarCOKS :-$ - - maint: correct git master installation instructions. - * README.md (Installation): Provide working instructions for - installing git master with Luarocks. - Liberal use of additional useful links. - -2013-04-07 Reuben Thomas - - README.md: simplify installation instructions, and other minor tweaks - -2013-04-07 Gary V. Vaughan - - maint: remove spurious LUA override in Travis CI build. - * .travis.yml (script): No need to force Lua 5.1 when running - initial make now that we fixed up luadocs. - - docs: we need to autoreconf a master branch github checkout. - * README.md (Installation): Show missing autoreconf invocation. - -2013-04-07 Gary V. Vaughan - - Revert "maint: support rerunning check-local in multiple lua environments." - This reverts commit e052c045cfc5b837e2dcb36db2e1cd34791a3c69. - - Conflicts: - Makefile.am - -2013-04-07 Gary V. Vaughan - - docs: rename README to README.md for github display goodness. - * README: Move from here... - * README.md: ...to here. - * Makefile.am (EXTRA_DIST): Add README.md. - - maint: tweak luadoc wrapper to work with Travis CI. - * .travis.yml (script): luadoc is a shell wrapper that calls the - wrong lua, so make a copy, patch it to call a compatible lua binary, - and run that instead. - - maint: run luadoc in a Lua 5.1 environment for Travis CI. - * .travis.yml (script): luadoc only works with Lua 5.1, so set the - execution environment up carefully for it to run correctly. - - maint: make luadoc available to Travis CI. - * .travis.yml (install): Install a system luarocks, and a luadoc - binary that uses it. - - maint: don't forget to make std/std.lua for Travis CI. - * .travis.yml (script): Run a full make to ensure std.lua is - generated in time for running mkrockspecs.lua! - - configury: don't hardcode specl, use $(SPECL) everywhere. - * specs/specs.mk (specs-check-local): Use $(SPECL), because bare - specl may not be on PATH, or otherwise correctly enabled. - * .travis.yml (script): Always call make with V=1 for better - logging. - - maint: install help2man for Travis CI specl build. - * .travis.yml (script): specl-v4 build currently fails when trying - to regenerate specl.1.in, so install help2man until that bug is - fixed. - - maint: set LUA_PATH for specl build with Travis CI. - * .travis.yml (script): Make sure local specl install can find - ansicolors and lyaml in local luarocks tree. - - maint: remove unnecessary manual ansicolors installation for Travis CI. - * .travis.yml: The previous error was caused by a bug in specl - release 3, not a lack of ansicolors. Remove the bogus ansicolors - installation now that specl-v4 is released. - - maint: make sure ansicolors is installed for Travis CI. - * .travis.yml (script): Install ansicolors to local luarocks tree. - - maint: make sure specl is installed for Travis CI. - * .travis.yml (script): Install specl, and use it for make check. - - configury: respect `make V=0` in rockspecs rule. - * GNUmakefile (rockspecs): Be quieter by default. - - std: strip leading "std." from global namespaces. - * std/std.lua.in: Before injecting symbols into the global - namespace, strip off the leading "std." added by std.modules.lua. - - configury: use uninstalled stdlib again. Again. (issue #24) - * specs/specs.mk (std_path): Move from here... - * Makefile.am (std_path): ...to here. - (LUA_ENV): Make sure to set this so that mkrockspecs rule uses - uninstalled stdlib again. - * specs/specs.mk (SPECL_ENV): Simplify accordingly. - - configury: fix a typo in luarocks-config.lua generation. - * GNUmakefile (luarocks-config.lua): Only one e in 'echo'. - - maint: integration with Travis CI system. - * .travis.yml: configure, build and test with each of Lua 5.1, - Lua 5.2 and luajit. - * GNUmakefile (luarocks-config.lua): Set interpreter environment - variables for luarocks invocations. - * mkrockspecs.lua: Invoke luarocks via user LUAROCKS setting. - * stdlib.rockspec.in (build.build_command): Pass LUA as a - configure precious variable so that recent ax-lua.m4 uses it as - passed instead of running the hardcoded search for a lua binary. - * README: Add travis build status badge markup. Plus some - indentation corrections for correct markdown code rendering. - -2013-04-01 Gary V. Vaughan - - docs: improved installation instructions. - * README: improve installation instructions. - - maint: The Grand Renaming™ - use `require "std.list"` etc. - * Makefile.am (SPEC_ENV, SPECL, SPECL_MIN, SPECS, MULTICHECK) - (check-local, src_spec): Split out from here... - * specs/specs.mk (SPECL_ENV, SPECL, SPECL_MIN, specl_SPECS) - (MULTICHECK, specs-check-local, std_path): New file. ...to here. - * Makefile.am (SOURCES, dist_data_DATA, dist_doc_DATA) - (dist_files_DATA, dist_modules_DATA): Split out from here... - * std/std.mk (nobase_dist_lua_DATA, dist_lua_DATA, std/std.lua) - (dist_doc_DATA, dist_files_DATA, dist_modules_DATA): New file. - ...to here. - * specs/debug_ext_spec.yaml, specs/getopt_spec.yaml, - specs/io_ext_spec.yaml, specs/math_ext_spec.yaml, - specs/package_ext_spec.yaml, specs/string_ext_spec.yaml, - specs/table_ext_spec.yaml: Adjust require calls. - * src/base.lua, src/bin.lua, src/debug_ext.lua, src/debug_init.lua, - src/fstable.lua, src/getopt.lua, src/io_ext.lua, src/lcs.lua, - src/list.lua, src/math_ext.lua, src/mbox.lua, src/modules.lua, - src/object.lua, src/package_ext.lua, src/parser.lua, src/set.lua, - src/std.lua.in, src/strbuf.lua, src/strict.lua, src/string_ext.lua, - src/table_ext.lua, src/tree.lua, src/xml.lua: Move from here... - * std/base.lua, std/bin.lua, std/debug_ext.lua, std/debug_init.lua, - std/fstable.lua, std/getopt.lua, std/io_ext.lua, std/lcs.lua, - std/list.lua, std/math_ext.lua, std/mbox.lua, std/modules.lua, - std/object.lua, std/package_ext.lua, std/parser.lua, std/set.lua, - std/std.lua.in, std/strbuf.lua, std/strict.lua, std/string_ext.lua, - std/table_ext.lua, std/tree.lua, std/xml.lua: ...to here. Adjust - require calls. - * std/modules.lua: Add "std." prefix. - * std/std.lua.in: Strip "std." prefix before injecting required - symbols into global namespace. - -2013-03-29 Gary V. Vaughan - - maint: support rerunning check-local in multiple lua environments. - * .luamultienv: Example multienv runner. - * Makefile.am (SPECL): Allow overriding. - (MULTICHECK): Location of multicheck script. - (check-local): Run multicheck without looping, if present. - - getopt: ensure we find _G.arg from Specl nested setfenv environments. (issue #27) - Although only necessary for Lua 5.1, this fix is harmless for Lua - 5.2, and we support both! - * src/getopt.lua (processArgs): Use only fully qualified _G.arg - references, for Lua 5.1 Specl compatibility. - Fixes issue #27. - -2013-03-29 Reuben Thomas - - getopt: instead of parsing undefined options, stop at first non-option - This is a configurable behaviour in C getopt, and does what I actually - wanted in the first place. If the other behaviour has a use case, it - can be reinstated later. - -2013-03-26 Gary V. Vaughan - - string_ext: propagate string metamethods correctly. (issue #26) - * specs/string_ext_spec.yaml (describe caps, describe chomp) - (describe escape_pattern, describe escape_shell, describe finds) - (describe format, describe ltrim, describe pad, describe rtrim) - (describe split, describe tfind, describe trim, describe wrap): - Add new specifications for metamethods. - * src/string_ext.lua (M): Declare at the beginning, and then - copy function references in at the end. - (__index metamethod): Delegate to M for unknown metamethods, now - that it carries all string functions too. - Fixes issue #26. - - refactor: eliminate forward declarations by reordering string_ext.lua. - * src/string_ext.lua (split): Move above require_version, the - earliest caller. Declare as a local. Rewove forward declaration. - (finds): Move above split, the earliest caller. - (tfind): Move above finds, the earliest caller. - (format): Move above assert, the earliest caller. Declare as - local. Remove forward declaration. - - refactor: don't over simplify specs/string_ext_spec.yaml. - * specs/string_ext_spec.yaml (context by name): Add back - accidentally deleted line. - - refactor: simplify specs/string_ext_spec.yaml. - * specs/string_ext_spec.yaml (context by name): Unroll a function. - (it adds extension apis to the global table): Remove debug code. - - std: propagate methods into global environment correctly. (issue #25) - * specs/string_ext_spec.yaml (keywords): List of methods that - should propagate into the global environment. - (it propagates keywords to the global environment): New - specification. - * src/std.lua.in: Propagate global methods correctly. - Fixes issue #25. - - configury: mkrockspecs uses uninstalled stdlib again. (issue #24) - * GNUmakefile (ROCKSPEC_ENV): Default to same value as LUA_ENV. - (MKROCKSPECS): Now uses lua-stdlib from the build tree, not the - previously installed version. - -2013-03-25 Gary V. Vaughan - - debug_ext: don't perturb the global environment by default. - For backwards compatibility, `require "std"` will still write - symbols into the global environment, but when loaded directly be - much more hygienic and return everything in a table, like most - other modules: - * src/debug_ext.lua (M): Return a table of previous debug_ext - globals. - * src/debug_init.lua: Wrap _DEBUG in a returned table, but - initialize from _G._DEBUG when first loaded. - * specs/debug_ext_spec.yaml: New specs. Specify behaviour of - loading just debug_ext, or indirectly via `require "std"`. - Add pending examples for remaining debug_ext APIs. - * Makefile.am (SPECS): Add specs/debug_ext_spec.yaml. - - math_ext: don't perturb the global environment by default. - For backwards compatibility, `require "std"` will still write - symbols into the global environment, but when loaded directly be - much more hygienic and return everything in a table, like most - other modules: - * src/math_ext.lua (M): Return a table of previous math_ext - globals. - * specs/math_ext_spec.yaml: New specs. Specify behaviour of - loading just math_ext, or indirectly via `require "std"`. - Add pending examples for remaining math_ext APIs. - - io_ext: don't perturb the global environment by default. - For backwards compatibility, `require "std"` will still write - symbols into the global environment, but when loaded directly be - much more hygienic and return everything in a table, like most - other modules: - * src/io_ext.lua (M): Return a table of previous io_ext globals. - (file_metatable): Move from here... - * src/std.lua.in: ...to here. - * specs/io_ext_spec.yaml: New specs. Specify behaviour of loading - just io_ext, or indirectly via `require "std"`. - Add pending examples for remaining io_ext APIs. - - refactor: move leaves and ileaves from base to list. - Break another dependency loop. - * src/base.lua (_leaves, _G.ileaves, _G.leaves): Move from here... - * src/list.lua (_leaves, ileaves, leaves): ...to here. - (M): Adjust. - * src/io_ext.lua: For ileaves, `require "list"` instead of "base". - (writelines): Adjust. - * src/tree.lua (M): Re-export list.ileaves and list.leaves as - tree.ileaves and tree.leaves. - * src/std.lua (_G): Re-export list.ileaves and list.leaves to the - global environment. - - string_ext: don't perturb the global environment by default. - For backwards compatibility, `require "std"` will still write - symbols into the global namespace, but when loaded directly be - much more hygienic and return everything in a table, like most - other modules: - * src/base.lua: Don't depend on list or string_ext modules to - break a depndency loop. - (_G.require_version, _G.render, _G.tostring, _G._tostring) - (_G.prettytostring, _G.pickle, _G.assert): Move these "stringy" - functions from here... - * src/string_ext.lua: ...to here, breaking another dependency - loop. - (M): Define module symbols in this table and return it. - * specs/string_ext_spec.yaml: Add pending examples for the - relocated APIs. - * src/std.lua.in: Inject string_ext module symbols into global - string namespace, and newly relocated base functions directly - into _G. - * src/debug_ext.lua, src/getopt.lua, src/xml.lua: Use required - string_ext return value from a local table. - * specs/string_ext_spec.yaml: Specify new behaviour, being - careful about `require "std"` side-effects. - - table_ext: don't perturb the global environment by default. - For backwards compatibility, `require "std"` will still write - symbols into the global namespace, but when loaded directly be - much more hygienic and return everything in a table, like most - other modules: - * src/table_ext.lua (unextended): Remove. - (M): Include core lua table.sort function as M._sort, and - return M. - * src/std.lua.in: Inject table_ext module symbols into global - namespace. - * specs/table_ext_spec.yaml: Specify new behaviour, being - careful about `require "std"` side-effects in global namespace.. - * src/base.lua, src/fstable.lua, src/getopt.lua, src/object.lua, - src/string_ext.lua: Save "table_ext" import into a local table and - call APIs directly from there. - - package_ext: don't perturb the global environment by default. - For backwards compatibility, `require "std"` will still write - symbols into the global namespace, but when loaded directly be - much more hygienic and return everything in a table, like most - other modules: - * src/package_ext.lua (M): Define module symbols in this table - and return it. - * src/std.lua.in: Inject package_ext module symbols into global - namespace. - * specs/package_ext_spec.yaml: Specify new behaviour, being - careful about `require "std"` side-effects. - - configury: bump release number to 35. - * configure.ac (AC_INIT): Bump release number to 35. - -2013-03-24 Gary V. Vaughan - - configury: warn if `make check` needs a newer Specl. - * Makefile.am (SPECL_MIN): Oldest release capable of running our - spec files. - (check-local): If actual Specl version is older than SPECL_MIN - show a diagnostic rather than try to run the specs. - - maint: move GNU make only rules to GNUmakefile. - * Makefile.am (SPECL_OPTS, specl_verbose_, specl_verbose_0) - (specl_verbose_1): Move from here... - * GNUmakefile: ...to here. - (specl_verbose_1): Now that Specl-3 passes --verbose on to the - selected formatter to handle, explicitly request the long-form - report formatter for `make check V=1`. - - maint: revert premature merge of pull request #23. - Reverse apply 5508adb. - -2013-03-23 Reuben Thomas - - README: make formatting consistent - - GNUmakefile: change to using a separate checkout for release branch - -2013-03-15 Reuben Thomas - - Merge pull request #23 from rrthomas/gary/ext-hygiene - package_ext: don't perturb the global environment by default. - -2013-03-15 Gary V. Vaughan - - package_ext: don't perturb the global environment by default. - For backwards compatibility, `require "std"` will still write - symbols into the global namespace, but when loaded directly be - much more hygienic and return everything in a table, like most - other modules: - * src/package_ext.lua (M): Define module symbols in this table - and return it. - * src/std.lua.in: Inject package_ext module symbols into global - namespace. - * specs/package_ext_spec.yaml: Specify new behaviour, being - careful about `require "std"` side-effects. - - string_ext: fix a bad assumption in a spec example. - Running string.format in the expectation `should` uses the core - Lua string.format which doesn't prettify tables, but we're - comparing it to the string_ext `..` operator which uses the std - enhanced string.format, and that *does* prettify tables. - * specs/string_ext_spec.yaml (stringifies non-string arguments): - Manually expand the the stringified table in should to match the - std prettified table stringification. - - list: fix standalone loading of string_ext module. - This fix reenables simple 'require "string_ext"' without an additional - 'require "std"'. - * src/string_ext.lua: Load the list module, which is used in split(). - Store APIs from `require "strbuf"`. - -2013-03-14 Gary V. Vaughan - - list: fix standalone loading of list module. - This fix reenables simple 'require "getopt"' without an additional - 'require "std"'. - * src/list.lua (new): Add a forward declaration. - (sub, concat, rep, reverse, transpose, enpair, flatten, shape) - (indexKey, indexValue): Use new, rather than list.new. - * src/getopt.lua (processArgs): Call local 'getOpt' function. Global - getopt.getOpt may never exist! - -2013-03-09 Reuben Thomas - - README: mention all extra dependencies of fstable - - getopt: remove the need for ugly getopt.Option constructor - -2013-03-09 Gary V. Vaughan - - maint: support 'make check V=1' and 'SPECL_OPTS=-v make check'. - * Makefile.am (SPECL_OPTS): Unless set in the environment already, - pass -v to specl according to whether or not V=1 was given to make. - (check-local): Use it. - -2013-03-09 Reuben Thomas - - getopt: allow parsing of undefined options; useful for programs which wrap other programs - -2013-03-07 Gary V. Vaughan - - specs: update to cleaner Specl-2 YAML spec format. - * specs/getopt_spec.lua, specs/package_ext_spec.lua, - specs/string_ext_spec.lua, specs/table_ext_spec.lua: Rename from - these... - * specs/getopt_spec.yaml, specs/package_ext_spec.yaml, - specs/string_ext_spec.yaml, specs/table_ext_spec.yaml: ...to - these. Reformat as YAML. - * Makeflie.am (SPECS): Remove old _spec.lua filenames, and add - new _spec.yaml filenames. - -2013-03-06 Gary V. Vaughan - - specs: allow for package.config differences in Lua 5.1. - * specs/package_ext_spec.lua (it splits package.config up): Allow - for optional trailing \n present in 5.2 but not 5.1. - -2013-02-27 Gary V. Vaughan - - configury: bump release number to 34. - * configure.ac (AC_INIT): Bump release number to 34. - - specs: rely on installed specl rather than shipping our own. - * specs/specl, specs/lib/specl.lua: Remove. - * Makefile.am (EXTRA_DIST): Adjust accordingly. - (lib_spec): Remove. - (SPEC_ENV): Adjust accordingly. - (SPECS): Add $(srcdir) prefix for distcheck. - (check-local): Run listed SPECS using installed specl. - - maint: don't checkout master again before running woger. - * GNUmakefile (check-in-release): Move current_branch save and - restore from here... - (release): ...to here. - - maint: mkrockspecs simplifications. - * luarocks-config.lua.in: Remove. - * configure.ac (AC_CONFIG_FILES): Remove luarocks-config.lua. - * GNUmakefile (luarocks-config.lua): Make on demand. - * Makefile.am (rockspecs): Move from here... - * GNUmakefile (rockspecs): ...to here. - (WOGER_ENV, WOGER_OUT): Factored out of release rule. - (release): Simplify accordingly. - - maint: don't forget to distribute GNUmakefile. - * Makeflie.am (EXTRA_DIST): Add GNUmakefile. - -2013-02-25 Gary V. Vaughan - - io_ext: remove spurious access to global 'prog' variable. - * src/io_ext.lua (processFiles): The supplied function receives - a copy of each file name, so no need to make assumptions about - global variables in here. - -2013-02-23 Gary V. Vaughan - - specs: add a skeleton specl spec for getopt module. - * src/getopt.lua (test): Remove. - * specs/getopt_spec.lua: Reimplement as specs. - * Makefile.am (SPECS): Add spects/getopt_spec.lua. - * specs/getopt_spec.lua): More specs for default option overrides. - * src/getopt.lua (processArgs): Fix a small scoping bug uncovered - by the new specs. - - getopt: don't display the full help for option errors. - * src/getopt.lua (processArgs): Show the error and a short help - message for option errors, and save the full blown help screens - for '--help'. - (usage): Simplify concatenations slightly. - - getopt: support GNU style --help and --version output. - * src/getopt.lua (usage): Take arguments from the prog parameter - instead of inspecting global variables. - If present, wrap paragraphs from prog.description and display - between purpose and option table. - (version): New function. Display version info according to prog. - version and prog.copyright. - (processArgs): Use it. - * template.lua: Update. - * specs/specl: Update. - - getopt: insert a blank line between usage and purpose. - - getopt: move options and prog out of the global namespace. - * src/getopt.lua (usage): Require prog as a parameter with options - inside it. - (processArgs): Likewise. - * template.lua: Update. - - getopt: only add default help and version when user supplied none. - * src/getopt.lua (makeOptions): Make two passes through the option - list. The first to collect all option declarations, and the second - to make an index. - (appendOpt): Factor out, and add a nodupes parameter to prevent - addition option specs being added when any of the option letters - they use have been claimed already. - Use it to only add default help and version options when the user - didn't specify their own already. - - getopt: format long and short options properly. - * src/getopt.lua (fmtOpt): Display two leading dashes for long - options. - (usageInfo): Indent past the short option column where only a - long option is being displayed. - - getopt: move Option out of the global namespace. - * src/getopt.lua (_G.Option): Rename from this... - (Option): ...to this local declaration. - (M): Export Option as a new public interface. - Remove TODO. - * template.lua, specs/specl: Update. - -2013-02-22 Reuben Thomas - - Fix some spec failures in string.wrap, and one error in a spec. - - string_ext.lua: fix a reference to string.sub. - -2013-02-22 Gary V. Vaughan - - string_ext: prefer snake_case to camelCase APIs. - * src/string_ext.lua (escapePattern, escapeShell, ordinalSuffix): - Rename from these... - (escape_pattern, escape_shell, ordinal_suffix): ...to these. - (M): Continue to support camelCase calls for backwards compatibility. - * specs/string_ext_spec.lua: Update. - Add specs to ensure camelCase APIs continue to work. - - maint: update string_ext to use Lua 5.2 style modules. - * src/string_ext.lua: Save unextended string table, returning - that after injecting stdlib extensions. - * specs/string_ext_spec.lua (context when requiring the module): A - few new specifications for requiring string_ext. - - specs: add missing specs for string.finds and string.tfind. - * specs/string_ext_spec.lua (describe string.finds (), describe - string.tfind ()): New specs for these APIs. - - specl: ensure that failing to meet specs kills make distcheck. - * specs/lib/specl.lua (run): Return true unless there are - expectation failures. - * specs/specl: Exit with non-zero status for with expectation - failures. - - string_ext: bail out early with fatal type mismatch errors. - * src/string_ext.lua (wrap): Rather than letting the guts of wrap - choke unpredictably later on, assert the required types at the - outset. - (tfind): Likewise. These currently bubble up to finds and split - as well. - - specl: update ordinalSuffix () error specs to match the new error messages. - * specs/string_ext_spec.lua (describe string.ordinalSuffix): Make the - expectations match reality. - -2013-02-22 Reuben Thomas - - Fix ordinalSuffix for negative arguments (issue #20). - - string_ext.lua: use Lua terminology "pattern" rather than "regex" - -2013-02-22 Gary V. Vaughan - - specs: add specl specification for string_ext module. - * specs/string_ext_spec.lua: New file. Specl specs for - string_ext. - * Makefile.am (SPECS): Add specs/string_ext_spec.lua. - - specl: sync from upstream. - * specs/lib/specl.lua: Upgrade to the latest upstream, where the - contain and match matchers are not broken! - - string_ext: don't use math.mod, which doesn't exist in Lua 5.2. - * string_ext.lua (ordinalSuffix): Use '%' operator instead of - math.mod, which is compatible with Lua 5.1 and 5.2. - - maint: move maintainer rules into GNUmakefile. - * Makefile.am: Move maintainer rules from here... - * GNUmakefile.am: New file. ...to here. - Automatically autoreconf the directory if configure is missing. - - configury: make sure WOGER has a default value. - * Makefile.am (WOGER): Set it to 'woger' by default. - - configury: bump release number to 33. - * configure.ac (AC_INIT): Bump release number to 33. - -2013-02-21 Gary V. Vaughan - - configury: make the release rules more robust. - * Makefile.am (GIT, GIT_REMOTE, LN_S): Set as macros that can be - overridden during testing. - Adjust all callers. - (tag-release, check-in-release): Move the push commands that - publish changes upstream from here... - (release): ...to here. - (check-in-release): Rather than rely on having a parallel checkout - in a particular sibling directory, just switch branches from here - temorarily. - (unpack-distcheck-release): Once in the relase branch, overwrite - the previous release with the tarball from distcheck. - - configury: bump release number to 32. - * configure.ac (AC_INIT): Bump release number to 32. - - specs: add specl specification for package_ext module. - * specs/package_ext_spec.lua: New file. Specl specs for - package_ext. - * Makefile.am (SPECS): Add specs/package_ext_spec.lua. - - maint: update package_ext to use Lua 5.2 style modules. - * src/package_ext.lua: Save unextended package table, returning - that after injecting stdlib extensions. - - specs: specify return of the unextended module from table_ext. - * specs/table_ext_spec.lua (context when requiring the module): A - few new specifications for requiring table_ext. - - maint: update table_ext.lua to use Lua 5.2 style modules. - * src/table_ext.lua: Save unextended package table, returning that - after injecting stdlib extensions. - Declare everything locally. - (M): Public interface. - - specl: new specification testing framework. - * specs/lib/specl.lua: New file for specification testing. - * specs/specl: New file. Command line wrapper for specl.lua. - * specs/table_ext_spec.lua: New file. Specl tests for - src/table_ext.lua. - * Makefile.am (src_spec, lib_spec): Lua search path strings for - directories in the source tree. - (LUA_ENV): Adjust. - (SPEC_ENV): New macro. Set Lua environment for calling specl. - (SPECS): New macro. A list of specs/*_spec.lua files. - (EXTRA_DIST): Add new specification testing files. - (check-local): Hook the specl tests into the Automake test - framework. - - bugfix: make sure getopt.opt is updated in the module table. - Fix a bug preventing visibility of getopt.opt after port to Lua - 5.2 style modues. - * src/getopt.lua (M): Add opt table. Move declaration above... - (processArgs): ...here, and update M.opt instead of undeclared - opt variable. - Merge other public entry points into M table before returning. - - configury: use static list of SOURCES instead of $(filter)ing. - * Makefile.am (SOURCES): Remove the GNU Make extensions used to - dynamically build the list, and just list each file statically. - -2013-02-20 Reuben Thomas - - Makefile.am: bump version to 31. - - list.lua: rename slice to sub, for compatibility with strings. - - list.lua: add list methods. - - Makefile.am: re-add explicit setting for release notes file, which we can once more prepare ahead of time - - Makefile.am: no longer need to re-bootstrap after checking in release files. - -2013-02-18 Reuben Thomas - - m4/ax_lua.m4: get latest version; no code changes, but some pleasing spelling corrections. - - list.lua: allow list.new to take no arguments to create an empty list. - The previous commit relied on this behaviour; oops. - - list.lua: make all methods that return lists make them with list.new, not {}. - Also rename result variables consistently to r, not, in some cases, m. - -2013-02-17 Reuben Thomas - - Makefile.am: checking out release branch in same directory doesn't work; use another directory. - - Makefile.am: since git clean deletes release notes file, don't supply it to woger (which will prompt for release notes). - - Makefile.am: need to git clean directories too. - - Makefile.am: run git clean to ensure we can check out the release branch. - - Makefile.am: only supply std.lua once (fixes make distcheck in some setups) - -2013-02-15 Reuben Thomas - - Makefile.am: copy a couple of fixes from luaposix. - - rockspecs.lua: add luarocks include path to configure command. - - Makefile.am: remove reference to defunct stdlib.rockspec.in - - rockspecs.lua: remove lrexlib-specific comment - -2013-02-12 Gary V. Vaughan - - maint: bump version to 30. - * configure.ac (AC_INIT): Bump version to 30. - -2013-02-12 Gary V. Vaughan - - Merge pull request #14 from gvvaughan/pull-request/move-to-lua52-module-style - Pull request/move to lua52 module style - -2013-02-12 Gary V. Vaughan - - configury: make sure we build std.lua when necessary. - Using wildcard for SOURCES before std.lua has been built now that - configure no longer makes it for us, means standard make or - luarocks install after building from a fresh checkout results in - std.lua not being built or installed. - * Makefile.am (SOURCES): Add src/std.lua. - -2013-02-12 Gary V. Vaughan - - Merge pull request #12 from gvvaughan/pull-request/fix-luadocs-hard-dependency - configury: fix hard dependency on luadocs. - - Merge pull request #11 from gvvaughan/pull-request/use-uninstalled-stdlib - configury: load local std modules as expected by mkrockspecs.lua. - -2013-02-11 Reuben Thomas - - parser.lua: update to current stdlib and Lua 5.2, fixing a couple of small bugs - Remove a debugging line accidentally left in before. - - base.lua: fix die; previously produced rubbish! - -2013-02-11 Gary V. Vaughan - - maint: update parser to use lua 5.2 style modules. - * src/parser.lua: Simply return the Parser object. - - maint: update object to use lua 5.2 style modules. - * src/object.lua: Simply return the callable Object table. - Adjust all callers. - - maint: update setbuf to use lua 5.2 style modules. - * src/strbuf.lua: Declare everything locally, and return a table - of interfaces, per lua 5.2 module style. - Adjust all callers. - - maint: update mbox to use lua 5.2 style modules. - * src/mbox.lua: Declare parse locally, and return a table with a - reference, per lua 5.2 module style. - - maint: update lcs to use lua 5.2 style modules. - * src/lcs.lua: Declare longestCommonSubseq locally, and return a - table containing a reference to it, per lua 5.2 module style. - - maint: update getopt to use lua 5.2 style modules. - * src/getopt.lua: Declare everything locally, and return a table - of interfaces, per lua 5.2 module style. - - maint: update fstable to use lua 5.2 style modules. - * src/fstable.lua: Declare everything locally, and return a table - of interfaces, per lua 5.2 module style. - - maint: update bin to use lua 5.2 style modules. - * src/bin.lua: Declare everything locally, and return a table of - interfaces, per lua 5.2 module style. - - maint: update trees to lua 5.2 style modules. - * src/tree.lua: Declare everything locally, and return a table of - interfaces, per lua 5.2 module style. - - maint: update lists to use lua 5.2 style modules. - * src/list.lua: Declare everything locally, and return a table of - interfaces, per lua 5.2 module style. - Adjust all callers. - - maint: update sets to use lua 5.2 style modules. - This is backwards compatible with lua 5.1, and allows use of sets - with the strict module loaded, which raised a bogus error before. - * src/std.lua.in (version): Return this in the module namespace. - Require the bundle of "std" modules into the global namespace. - * src/set.lua: Declare everything locally, and return a table - of interfaces, per lua 5.2 module style. - - configury: fix hard dependency on luadocs. - * m4/ax_with_prog.m4: New file. - * configure.ac (AX_WITH_PROG): Use it to find a luadocs binary. - * Makefile.am ($(dist_doc_DATA)): Use the substituted binary. - * rockspecs.lua: Remove insertion of luadocs dependency. - - * configury: load local std modules as expected by mkrockspecs.lua. - Rather than having to manually update the installed lua-stdlib - behind luarocks' back, let the mkrockspecs.lua script find the - modules it was written for in the source tree. - * Makefile.am (LUA_PATH): Default to compiled-in search path. - (LUA_ENV): Load modules from the source tree instead of potentially - outdated versions from the lua installation. - (rockspecs): Run lua with LUA_ENV set. - -2013-02-09 Reuben Thomas - - rockspecs.lua: add luadoc as a dependency for git rockspec. - -2013-02-08 Reuben Thomas - - rockspecs.lua: fix build command for building from git. - - mkrockspecs.lua: whitespace fix. - - Add a rockspec for building from git, and machinery for building variant rockspecs. - - tree.lua: add tree.merge. - - set.lua: fix broken elems iterator (issue #10) - - strict.lua: tweak formatting to match other modules - - base.lua: note availability of original tostring as _tostring. - -2013-02-07 Reuben Thomas - - set.lua: add missing dependency on list.lua - - Avoid rebuilding documentation in distributed sources, so users don't need luadoc installed. - -2013-02-06 Reuben Thomas - - Makefile.am: some more fixups to release-by-git. - - .gitignore: we have reverted from zip to tgz tarballs. - - Makefile.am: don't try to rebuild documentation if not necessary (doesn't work in VPATH build, so breaks distcheck). - - Makefile.am: distcheck is really a dependency of check-in-release, not of release. - - stdlib.rockspec.in: correct name of git tag to source release tag. - - Makefile.am: check in sources before trying to check them out for test build. - - Fix issue #8: members with the same names as class methods cause problems. - - Bump version to 29. - - Makefile.am: add check-in-release to push release files to git. - - Makefile.am: enable building of documentation from git checkout. - - Change to building (with LuaRocks) direct from git, not releasing a zip. - - README: update installation instructions and mention GitHub, not LuaForge. - - Update to latest ax_lua.m4. - -2013-02-05 Reuben Thomas - - README: Make Lua 5.2 compatibility definite, and update copyright years. - -2012-12-23 Reuben Thomas - - stdlib.rockspec.in: remove redundant dir setting - -2012-10-30 Reuben Thomas - - .gitignore: add luarocks directory - -2012-10-28 Reuben Thomas - - Add testing of luarock against uploaded archive before mailing announcement - - base.lua: user simpler default require_version pattern that works in more cases - -2012-10-28 Reuben Thomas - - Generate Lua version in rockspec from that in configure.ac - Bump version to 28 - - Use newer ax_lua.m4 - - Tweak pattern used to substitute MD5 sum into rockspec to be - compatible with gnulib syntax checks, should we ever use them. - -2012-10-28 Reuben Thomas - - Bump version to 28, and simplify slightly, requiring automake 1.11 - -2012-10-15 Reuben Thomas - - base.lua: move a documentation stanza to a more apt location - -2012-10-04 Reuben Thomas - - release: fix call to woger to generate correct URLs - -2012-10-03 Reuben Thomas - - rockspec: fix homepage URL - - Makefile.am: really distribute all docs - - rockspec: fix download URL (thanks, Hisham Muhammad) - -2012-10-01 Reuben Thomas - - base.lua: add require_version - -2012-09-26 Reuben Thomas - - Make build_command in rockspec more robust. - - Install documentation with 'make install' and from luarocks. - -2012-09-22 Reuben Thomas - - Rename table.indices to table.keys, and use term 'keys' more. - -2012-09-21 Reuben Thomas - - getopt.lua: output usage information to stdout, not stderr - - configure.ac: bump version to 27 - - configure.ac: accept Lua 5.2 - -2012-09-18 Reuben Thomas - - getopt.lua: remove func member of Option; simply gather all option values into a list - - getopt.lua: improve some comments and remove a redundant require - -2012-09-17 Reuben Thomas - - set.lua: fix last commit: elements should be elems - - base.lua: remove a spurious blank line - - set.lua: revert elements iterator to being pairs; leaves is wrong! - -2012-09-12 Reuben Thomas - - Turn on debugging by default and tweak what the global debug function does. - -2012-09-12 Reuben Thomas - - I misunderstood what finds did, and didn't spot that it was needed for split! - Revert "string_ext: remove finds; map should be used with string.find instead" - - This reverts commit 5a62e3ee7ad2514b681ff6f348c43b797088b089. - -2012-09-11 Reuben Thomas - - string_ext: remove finds; map should be used with string.find instead - -2012-09-06 Reuben Thomas - - Remove string.gsubs: the order of substitutions was undefined, and map can be used just as well. - -2012-07-06 Reuben Thomas - - build: Check MD5 sum of rockspec against tarball before releasing - -2012-05-31 Reuben Thomas - - object: fix an incorrect simplification in the previous commit. - - object: add the ability to have a constructor function. - -2012-05-31 Reuben Thomas - - Tweak a couple of table functions. - Rename table.rearrange to the more descriptive table.clone_rename, and - clarify the documentation. - - Make table.merge not clone its left-hand argument, but modify it, as - the user has reason to expect. - -2012-05-31 Reuben Thomas - - parser.lua: fix call to renamed method. - -2012-05-29 Reuben Thomas - - object.lua: fix inconsistency and missing HTML close tag in doc comments. - -2012-02-22 Reuben Thomas - - base.lua: Fix minor formatting variation. - - Merge pull request #5 from gvvaughan/pull-request/for-fame-and-glory - AUTHORS: Add myself. - -2012-02-22 Gary V. Vaughan - - base.lua: new memoize function. - * src/base.lua (memoize): Memoize a single result function by - wrapping it in a functable. - -2012-02-22 Reuben Thomas - - Update URL to point to github. - - Reformat some code to make lua-mode happier (most of the time, sigh). - -2012-02-22 Gary V. Vaughan - - AUTHORS: Add myself. - * AUTHORS: List the few small contributions I've made. - -2012-02-18 Reuben Thomas - - Update rockspec for github. - - Makefile.am: Update call to woger. - - Makefile.am: Update call to woger. - - Makefile.am: Update call to woger. - - Makefile.am: Update call to woger. - - Makefile.am: Update call to woger. - - Makefile.am: Update call to woger. - - Makefile.am: Update call to woger. - - Rename set.elements to set.elems for consistency with list.elems. - -2012-01-21 Reuben Thomas - - base.lua: add missing require of strbuf. - - strict.lua: improve error message. - -2012-01-19 Reuben Thomas - - Add leaves, ileaves and inodes tree iterators; simplify nodes slightly. - Use ileaves to simplify flatten. - - Rename io.writeline to io.writelines and allow it to flatten table - arguments. - - Use list.elems instead of ipairs in several places. - - Fix FIXME in set: use leaves as elements to return only the key. - -2012-01-18 Reuben Thomas - - src/io_ext.lua: Improve docstring for readlines. - -2012-01-17 Reuben Thomas - - string_ext: fix new string.__concat metamethod to run tostring on both args, thus avoiding infinite recursion. - - string_ext: add __concat metamethod for strings which runs tostring. - Reformat some code to please lua-mode and add some missing quotes in a - comment. - -2012-01-09 Reuben Thomas - - io_ext: Add slurp; use it in various places. - -2011-12-16 Reuben Thomas - - Bump version to 26. - -2011-12-16 Reuben Thomas - - Merge pull request #1 from gvvaughan/patch-1 - tree: fix bugs when using a list of tables as keys - - Thanks for this. I don't currently have another use case than Zile to test with. - -2011-12-16 Gary V. Vaughan - - tree: fix bugs when using a list of tables as keys - To be fully general, tree should allow table keys so that it's - possible to write: - $ lua -lstd - > t, k1, k2 = tree.new(), {key='a'}, {key='b'} - > t[{"k1", "k2"}] = "string keys"; t[{k1, k2}] = "table keys" - > = t[{"k1", "k2"}], t[{k1, k2}] - string keys table keys - This patch fixes 3 bugs that prevent that from working. - * src/tree.lua (metatable.__newindex): Detect subtrees correctly - by comparing against the tree metatable, rather than assuming any - "table" type is a correct match. - Use rawset to insert a new node without triggering the __index - metamethod. - (metatable.__index): Don't recurse into table key members, only - the list entries to be folded, by checking whether the table has - a length first - for t[{k1, k2}], {k1, k2} is a list (with length) - and should be folded, but k1 (k1 = {key='a'}) is not a list and - should not. - -2011-09-30 Reuben Thomas - - io_ext: unset prog.file at the end of io.processFiles - -2011-09-27 Reuben Thomas - - getopt: improve output and conformance to best practice - Make the short option for -version be -V, not -v. - - Remove short option -? for -help. - - In help, show short options first, so that display is easier to read. - - Remove publicly Options constructor, as it’s not needed externally. - -2011-09-19 Reuben Thomas - - Makefile.am: tweak rockspec's deps. - - src/.gitignore: add std.lua. - - Bump version to 25. - - std.lua: add a version string to the std module - - list: add list.compare, and __le and __lt metamethods. - - Makefile.am: make release message shorter and more precise. - - Makefile.am: distribute rockspec source. - - .gitignore: ignore correct zip name. - - configury: rename project to stdlib for consistency and to make luarocks happy. - - Make rockspec on release. - - Bump version to 24. - - string_ext.lua: fix old call of findl (is now called tfind). - -2011-09-17 Reuben Thomas - - Makefile.am: fix getting summary description, and reminder message output by make release. - - rockspec: Keep old name (stdlib) for the rock. - Also fix LuaForge URL, which of course hasn’t changed. - - .gitignore: Add Makefile. - - Build system: autotoolize and generate rockspec. - -2011-09-11 Reuben Thomas - - Rename findl to tfind to conform to lrexlib. - Also fix a bug in the LuaDoc documentation of the return values. - -2011-09-07 Reuben Thomas - - Remove posix_ext module (is going in luaposix instead). - Update documentation about LuaDoc. - - Add posix.creat. - -2011-09-02 Reuben Thomas - - Fix typo. - - Add a new module with some binary to number/string conversion routines. - - Add simple string buffers and use them for default table tostring. - - Fix mode on .gitignore. - - Remove some non-LuaDoc markup. - -2011-08-19 Reuben Thomas - - Fixup. - - Add some more LuaDoc stuff. - - Partial conversion of documentation to LuaDoc. - -2011-06-06 Reuben Thomas - - Push tags, but don’t tag until we’ve successfully released. - - Update woger call to new keyword style. - - Add fstable module for storing tables as file trees. - - Replace reference to ldoc with one to LuaDoc. - - Convert documentation to LuaDoc, and retire ldoc. - -2011-06-05 Reuben Thomas - - Add index.html. - -2011-05-22 Reuben Thomas - - Fix faulty ldoc tags. - -2011-05-21 Reuben Thomas - - Fix return code on --help to be 0. - Make dieWithUsage into plain usage, and don’t exit at end. - -2011-05-19 Reuben Thomas - - Add some missing param tags. - -2011-05-03 Reuben Thomas - - Comment out strict from default set to make co-existence with other code easier. - - Fix calls to writeLine to be to writeline. - -2011-05-02 Reuben Thomas - - Add readlines and writeline to file handle metatable. - - Fix capitalization of readlines and writeline in docstrings. - -2011-04-15 David Favro - - Fixed bug: ldoc used writeLine() rather than writeline(). - -2011-04-12 Reuben Thomas - - Always return nil on error, not -1. - -2011-04-04 Reuben Thomas - - Rename readLines to readlines and writeLine to writeline. - -2011-03-23 Reuben Thomas - - Only set _DEBUG to false if it’s not already initialised. - -2011-03-19 Reuben Thomas - - Fix splitdir. - -2011-03-12 Reuben Thomas - - Initialise _DEBUG early so that it can be overridden by app and still be strict.lua-compatible. - - Shorten a TODO. - -2011-03-09 Reuben Thomas - - Restore modules.lua as holding standard list, to un-break std.lua. - - Allow mk1file to generate customized sets of modules, with the standard set as the default. - -2011-03-08 Reuben Thomas - - Remove unnecessary posix. prefix. - - Correct name of package_ext. - - Remove redundant comments. - - Update documentation of standard set, and add prerequisites. - - Merge branch 'origin' of github.com:rrthomas/lua-stdlib into origin - - Remove posix_ext and object from standard set. - -2011-03-07 Reuben Thomas - - Remove posix prefix from function calls. - - Add euidaccess. - - Improve a comment. - - Merge branch 'origin' of github.com:rrthomas/lua-stdlib into origin - - Add __index method to allow OO syntax use of methods. - Add delete method. - -2011-03-01 Reuben Thomas - - Reverse order of list methods for convenient OO use. - - Merge from HEAD. - -2011-02-26 Reuben Thomas - - In future, make zip distros. - - Fix message. - - Use package.dirsep once more. - - Put package.config reflexion into a new package_ext module. - - Make message clearer. - - Leave dist tarball in source dir, not above. - - Add tarball to .gitignore. - - Add sensible access to package.config. - - Bump copyright year. - - Bump copyright year. - - Use undocumented package.config to get platform’s directory separator. - -2011-02-08 Reuben Thomas - - Improve release target to tag releases. - -2011-02-07 Reuben Thomas - - Fix missing math. prefix, and swap incorrect sign in sub. Thanks to Bob Chapman. - -2010-12-14 Reuben Thomas - - Speed up math.floor for case where p is 0 or absent (thanks, Lukáš Procházka). - -2010-12-09 Reuben Thomas - - Change rules from using CVS to using git. - - Reinstate string __index metamethod fallback so that OO uses of strings work. - Switch argument order of ltrim, rtrim and trim so they work in OO - syntax. - - Point to tree.clone for deep copies. - -2010-10-12 Reuben Thomas - - Restore 'dubious' but used string metamethod fallback. - -2010-10-09 Reuben Thomas - - Move .cvsignore's to .gitignore's. - -2010-10-08 Reuben Thomas - - Fix typo in io.catfile. - - Add commit that seems to be missing from import from CVS. - - Add new posix_ext module. - - Add posix_ext to list. - - Remove spurious full stop. - -2010-10-07 Reuben Thomas - - Add catfile and fix catdir to return `/' when necessary. - -2010-10-06 Reuben Thomas - - Fix permissions. - -2010-06-20 rrt - - Remove dubious metamethod fallback for string.__index. - -2010-06-13 rrt - - Fix and simplify tree.__newindex: there was a variable name typo, and sub-tables should also be initialised to trees, as otherwise the relevant metamethods are not called. - - Fix an incompatibility with strict.lua. - -2010-06-11 rrt - - Simplify nodes iterator and make it more efficient; thanks to Alistair Turnbull for the hint. - - Simplify, generalise and rename (from treeIter to nodes) tree iterator. - - Whitespace correction. - - Simplify implementation of empty, using next as per manual. - -2010-06-09 rrt - - Rename table.subscript to op["[]"], and move table.deepclone and table.lookup into a new module, tree, as the clone method and __index metamethod respectively. The tree module also has a constructor, new, and a __newindex metamethod. - Rename table.newDefault to table.new. - - Fix writeLine and add an explanatory comment. - - Make the set metatable a local variable. - -2010-06-08 rrt - - Add Lua distribution’s strict.lua to standard modules. - - Have a single list of modules in modules.lua and use it to load them in std.lua and generate the single-file version in mk1file, which latter is now a Lua script. - -2010-06-07 rrt - - Fix list.foldl, list.foldr, and the fold iterator combinator. - Simplify the op table functions to be exactly the primitive operators, - not list versions thereof. - - (Possibly) improve the commented-out simpler version of treeIter. - -2010-06-07 rrt - - Remove table.subscripts function: it’s easily replaced by subscript plus string.split, as in its definition. - -2010-06-07 rrt - - Initialise _DEBUG to nil so stdlib works with strict.lua. - Rename debug.traceCall to debug.trace (more Lua-ish). - - Use math.max rather than just (incorrectly) max. - - Improve some documentation. - -2010-06-02 rrt - - Remove redundant redefinition of print (it already calls tostring). - Fix op table so that base can require list without breaking; fixes - FIXME. - - Remove lcs module from std set. - Update FIXME about autogeneration of mk1file to make it more precise. - - Bump copyright year to 2010. - -2010-03-18 rrt - - Add missing dependency on list. - -2009-09-14 rrt - - Improve formatting slightly. - -2009-09-07 rrt - - Avoid using removed function io.changeSuffix. - - Remove rex module altogether. - - Don’t need pcre_rex any more. - Remove FIXME about external dependencies as we no longer have any, nor - intend to. - - Remove need for rex_pcre in xml. - Remove xml, rex, parser and mbox from standard list of libraries. - - Remove dependency on lposix; in the process remove addSuffix and changeSuffix, as they reliedon basename and dirname, and it wasn't worth reimplementing them as they're not used. - - Add explanatory comment. - -2009-08-31 rrt - - Add requirement of posix and copyright notice to output. - - Add lua-posix to list of dependencies. - -2009-08-24 rrt - - Fix basename and dirname calls - - Remove basename and dirname as they are now implemented in lposix. - Rename pathConcat to catdir and pathSplitDir to splitdir and make them - behave like the corresponding Perl functions. - - Add FIXME. - -2009-03-20 rrt - - Use the original _floor in round rather than chaining via floor for a bit of extra speed; thanks to David Kantowitz. - -2009-03-16 rrt - - Update 'usage' message. - - Make 'make release' do 'make dist' - - Simplify assert. - -2009-03-15 rrt - - Simplify string.format. - - Remove string.join, which is the same as table.concat. Thanks to David Kantowitz for spotting it. - -2009-03-14 rrt - - Add support for not cloning metatables. - -2009-03-13 rrt - - Check no outstanding changes and tag release. - - Fix typo. - - Update copyright year. - - Fix variable substitution in release target. - - Ignore release-notes-* - - Add release target, and exclude release notes from tarball. - - Copy metatables in deepclone, so that it does what it says. Patch from David Kantowitz. - -2009-02-19 rrt - - Add final newline for neatness. - - In the single file, make the special "require" function local so that other files can be required after the single-file std. - - Update object module to correspond with Lua Gems version. - -2008-09-04 rrt - - Fix Diego Nehab's name. Sorry Diego! Thanks to Shmuel Zeigerman for pointing out my error. - -2008-09-04 rrt - - Fix set.difference. - Add set.symmetric_difference. - - Make s * t do intersection for sets, and s / t do symmetric - difference, as in Modula 3 and (at least for *) "Programming in Lua". - -2008-09-04 rrt - - Fix equal. Thanks to report from Jiutian Yanling. - -2008-07-28 niklas - - Cope with nil values in map. - -2008-07-27 niklas - - Fix elems and relems - - Fix make dist; $REL -> ${REL}, add --exclude for .#*, and no longer exclude template-rrt.lua, which no longer lives in the tree. - -2008-06-20 niklas - - Add collect, from Patrick Walton, to run an iterator and collect the results in a table. - As a result, rewrite all the table functionals to be iterator - functionals (in base) and reimplement the list functionals in terms of - them. Add two iterators for lists, elems and relems, that return only - the elements and not the indices, in order to implement the list - functionals. - - A couple of old fixes where the Lua 5.1 table count is used (#). - - Simplify ripairs slightly. - - Fix a comment typo. - -2008-03-28 rrt - - Add some TODOs to make the prog structure a bit more sensible. - -2008-03-04 rrt - - Make a note to compare pathSplit and pathConcat with Perl equivalents. - - Add TODO to use LuaDoc instead. - -2008-03-03 rrt - - Add Makefile with dist target - - Fix typo in comment. - - No dependency on LFS. - - No longer have any sort of dependency on bitlib. - - Remove _INTEGER_BITS and unneeded dependency - - Update date and prerequisites. - -2008-03-01 rrt - - Require external deps before neutering "require". - - We may add bit to stdlib, but it's not currently there, nor is it actually used by anything in stdlib. - - rex is not an external dependency - - Simplify length function. - - Use LFS for length() function. - -2008-01-19 niklas - - Add pathSplit and pathConcat from nancy. - -2008-01-12 rrt - - Make calls to find and gsub get the function from the pattern, meaning that in theory they could work with other regex engines than Lua's. - - Remove pointless object notation on a string. - -2007-11-19 rrt - - Now that INTEGER_BITS is added to the math namespace, no need to prefix it with _. - - Note that bitlib is needed. - -2007-10-06 rrt - - Rename 'permute' to the more accurate 'rearrange' - - Update some comments to match changes in the Lua Gem about this code. - -2007-10-05 rrt - - Fix from Roberto Ierusalimschy. - -2007-05-11 rrt - - Fix up single-file stdlib - - Clarify TODO. - -2007-04-26 rrt - - Tidy length slightly. - - Clarify documentation a little further - - Ignore built docs - - Format prerequisites to allow for more than one! - Explain ldoc better. - - Revert to plain implementation of length to avoid using POSIX library which is currently unmaintained. - -2007-04-25 rrt - - Clear up uses of old vararg "arg" syntax (thanks Matt). - -2007-03-01 rrt - - Add list.rep - - Add FIXME for commented-out require - - Make join cope with empty lists. - - Remove default separator in string.split, and hence a TODO. - Add string.join. - -2007-02-25 rrt - - Mention the dependency on lrexlib. - -2007-02-24 rrt - - Use __append metamethod, not __concat, which was wrong - - Add __append metamethod and constructor for LCS - - Add __append metamethod for LCS - - Set had been left rather broken; fix it up. - - Remove no-longer-needed LCS method. Thanks to Enrico Tassi for noticing it. - -2007-02-22 rrt - - Cosmetic changes to finds (comments and a variable rename) for clarity. - Use list.flatten (l) instead of list.concat (unpack (l)) in split to - avoid overflowing the parameter stack (with the unpack) when splitting - large strings. Clarify the comment for this code. - -2007-02-21 rrt - - Fix indexKey and indexValue: the function passed to table.process wasn't returning the accumulator as it should have. - -2007-02-20 rrt - - Make a note to find better names for enpair and depair, which are useful but confusing. Something like pairsToTable and tableToPairs? - -2007-01-26 rrt - - Add missing dirname and basename - -2007-01-05 rrt - - Sync with reality. - -2007-01-04 rrt - - Document. - Set rex = rex_pcre, so that we actually have the functions we expect - under "rex". - - Now that lrexlib no longer has a Lua component or a default library, add a library to load it (currently just require rex_pcre). - -2006-12-06 rrt - - Remove TODOs that apply to lrexlib. - -2006-11-27 rrt - - Use non-list-capable math.max correctly - -2006-11-20 rrt - - Fix from Jerôme Vuarand to string subscription that deals with oldmetas that are functions. - -2006-11-08 rrt - - Stop string subscription operator from hiding other methods. - -2006-11-05 rrt - - Note that rex is now an external dependency. - - Note problem with external dependencies. - - Sort out adding to module metatables. - - Add a FIXME - - As 5.1 has all the metamethods we need, rewrite LCS to use them. Hence, no need for wrapper string.lcs. - Remove named string concat, need for which is mostly obviated by - concat metamethod. - - Remove @module from list of tags to add, as we already have it. - - Clarify Reuben's role. - - Remove rex.lua, now imported from lrexlib - - No longer need to lift std modules into global environment as they are already there. - - Remove std/ prefix for module files, and no longer include std.lua, which does nothing. - - Remove std directory, having all modules at the root, and with root names (no "std." prefix), so that stdlib can rely on external libraries, and the namespace is simplified. - - file.lua is no more - - Rewrite io.length using posix.stat and move it to io.lua. - - Move TODO from rex.lua - -2006-11-03 rrt - - No longer mention defunct bit.lua. - - Remove listable and listabled functions. This wasn't really that useful, and could confuse. - -2006-11-01 rrt - - Correct @function to @func - - Really cope with multiple params under a single @param. - - Add template for std-using scripts. - - Clarify gmatch metamethod - - Cope with multiple params under a single @param, by insisting on the : at the end. - -2006-10-30 rrt - - Fix list.concat (thanks to Avi Yagodnick for reporting the bug). - -2006-10-28 niklas - - Remove require loops by commenting out looping requires. This needs fixing properly (by permitting them). - Where possible without further change, remove the "std" prefix from - module declarations. - - Where possible, remove module prefixes from function definitions. - - Use ... in more places. - - Move pathSubscript to table.lua. - - Move assert.lua's contents to base.lua (we can't have a module called - assert, and this is in the base library in any case). - - Move function forms of operators to base.lua. - - Make headings of modules consistent (add @module lines). - - Remove io.exists, as it's dodgy, and posix.stat is much better. - Lighterweight environments are probably going to roll their own - anyway. - - Remove "zip" and "unzip" aliases for list.transpose. Add a note to the - documentation instead. - - In io.lua, remove some io. prefixes (that don't make the code less - clear) as we're already in io, and instead prefix type with _G (oops, - that's ugly). - - Improve changeSuffix, and make it use posix.dirname and - posix.basename. - - Add two functions to list module: flatten and shape, to flatten and - reshape arbitrarily nested lists. - - Add a paragraph of documentation to the top of the rex module in - preparation for lrexlib 1.20 (rex.lua will leave stdlib and move to - lrexlib). - - Add rex.gmatch (as well as adding a metatable method for rex objects). - - Update set.lua to current practices, including the (still - commented-out) metamethods. - - Probable bug-fixing in string module obscured by removal of string. - prefix from function definitions and calls. - - Make redefinitions of existing functions more consistent, and fix some - faulty ones. - - Add deepclone to table from Jamie Webb's code. - -2006-10-08 rrt - - Update to match stdlib. Remove revision history as it's in CVS, and replace version number with CVS Revision tag. - - table.getn --> # - -2006-09-30 rrt - - Remove io.readDir, as it is replaced by posix.dir. - - Remove io.dirname, as it is replaced by posix.dirname. - - Fix changeSuffix to work with paths containing dots by only operating on basename, not the whole file name. - -2006-09-18 rrt - - Fix ordering of deps - -2006-07-14 rrt - - Escape quotes and apostrophes in string.escapeShell. - - Escape square brackets too in string.escapeShell. - -2006-04-25 rrt - - Prepend redefinition of require to the output. - - Use string methods rather than functions so that the functions here work on regexs as well. Add a note to make the whole API work properly with regexs as well as Lua patterns. - - Add TODO - - Reformat and improve comments. - -2006-04-24 rrt - - Simplify assignment of retry. - - Correct name of table.filterItem (was table.mapItem). - -2006-04-15 rrt - - Reformat. - - Use variadic bit.or. - - Add table.filter and table.filterItem. Add list.filterItem and implement list.filter in terms of it. - - Fix more bugs, patch from Shmuel Zeigerman. - Call rex:flags() to inject flags into rex table. - - Remove unnecessary local line from gmatch, and initialise st to 1, not 0 (thanks to Shmuel Zeigerman). - -2006-04-09 rrt - - Reorganise libraries with simpler names - - Move all modules out of string - - Reflect simplified structure - - Move all modules out of io - - Rename io.getopt to getopt - - Rename string.xml to xml - - Add utility to make a single file stdlib - - Use env to run script and reverse Changelog order - - Rename algorithm.lcs to lcs - -2006-04-09 rrt - - Rewrite string.split to be regex-system-neutral. - Change string.findl to return from and to in list form, not {from = f, - to = t}. - - Update string.regex to Lua 5.1 vararg syntax. - - Make io.exists use stat if available. - - Add io.dirname. - -2006-04-09 rrt - - Update Lua code from Shmuel's version and write gmatch in Lua. - - Update concat to Lua 5.1 vararg syntax. - Remove flatten alias for concat, as concat doesn't flatten. - - Update to 5.1 vararg syntax - -2006-03-30 rrt - - string.gfind is now string.gmatch. - - Reactivate tests, but make them conditional on running in debug mode. - - Improve installation instructions. - - Fix mailing list address. - - Update to match reality. - - Fix handling of global arg table. - - Use new form of message-less error. - -2006-03-29 rrt - - Deal with C modules like Lua modules. - - Don't mention require for Lua 4 any more. - - Rename modules *-ext to *_ext to avoid problem with version number parser in require. - - Simplify adding functions to global table. - -2006-03-28 rrt - - Add module calls everywhere, and do some necessary renaming to avoid clashes - -2006-03-22 rrt - - Use module and require in properly 5.1-compatible way, and change module names to work better with 5.1. - This should all still work fine with 5.0 using compat-5.1.lua. - -2006-02-03 rrt - - More fixes and tests from Shmuel Zeigerman. - -2006-01-28 rrt - - Add tests from Shmuel Zeigerman, reorganised somewhat. They are run when the module is loaded. - - Rename sub to cap for clarity (Shmuel Zeigerman). - -2006-01-26 rrt - - More fixes from Shmuel to mimic string.gsub better. - -2006-01-24 rrt - - Fix endless loop when pattern is .* (bug reported by Shmuel Zeigerman). - - Cope with capture being false (Shmuel Zeigerman). - - Fix bug when n == 0 (thanks Shmuel Zeigerman), and tidy up. - -2006-01-23 rrt - - Fix from Shmuel Zeigerman to match string.gsub better: when the pattern contains no captures, pass the entire match to the replacement function. - -2006-01-21 rrt - - More bug fixes; thanks to Shmuel Zeigerman for reporting the bugs and in one case giving the fix. - - Fix bugs with %n replacements in rex.gsub - - Make rex.gsub a full gsub for rex. - -2006-01-19 rrt - - Don't escape & in entities - - Improve rex.gsub - -2006-01-16 rrt - - Escape <, > and & in XML output. - -2005-11-23 rrt - - Replace deepipairs with treeIter to iterate properly over trees. - -2005-11-22 rrt - - Remove table.filterItem, as it really only works for lists. Inline the function in list.filter. - Add table.map. - - Add XML output, assuming Lua tables created by luaexpat. - -2005-11-21 rrt - - Add generic printing framework, and use it to add prettytostring. - -2005-11-18 rrt - - Use table.process to implement list processing functions. - - Add generic table-processing function table.process and action functions for map, filter &c. - - Add two iterators: ripairs which is like ipairs, but in reverse, and deepipairs, which recurses into nested tables. - -2005-11-09 rrt - - Remove import. - - Update year to 2005. - - import has been removed. - - Fix bogus version in history - - Remove import, and instead use 5.1-style require (tested with compat-5.1.lua). - Assume a LUA_DIR of "/", hence rename files accordingly. - -2005-09-04 rrt - - Fix string.ltrim and string.rtrim to return only the advertised return value. - Fix string.trim to do what it says on the tin; it was completely - broken. - -2004-09-08 rrt - - Fix assert when called with only one argument: arg has the value {n=0} when there are no variadic arguments, not nil as I assumed. - -2004-02-17 rrt - - Comment the constructor. - - Check error return when loading file, so that if file is not found we don't abort immediately so that all LUA_PATH entries are checked. - -2004-02-04 rrt - - Tidy up abstract syntax rules: there's now only one per production. - Keep action functions for more complex rules. Looks as though we only - ever have one or the other (because simple rules don't take into - account any housekeeping info) so perhaps simplify this again. - - Make lists not have a ty field, but just be lists of whatever they - contain. - - Return false instead of nil for empty parse trees, so as not to upset - ipairs iterations over lists. - -2004-02-04 rrt - - Tidy up the code, mostly by shortening the names of frequently-used variables. - - Allow import to report errors during importing. - -2004-02-03 rrt - - Added Diego Nahab for his mbox parser. - - Added Diego Nahab's mbox parser. - -2004-02-03 rrt - - Rework the API: now has a single method exposed, parse, and the other methods have been moved inside parse as local functions. The constructor no longer takes a token list. - Also, provide support for producing an abstract parse tree rather than - the (default) concrete one. - - Full details in the all-new documentation. - -2004-02-03 rrt - - Clarify note about import and add TODO about markup tags. - -2004-02-01 rrt - - Massacre the object implementation, reverting to implementing sets as simple tables, which seems to be better for general use. A lot of the code in this file is now non-functional; I'll be making it work later, integrating it with Jamie Webb's code. The module may get folded back into table. - - Make list.map and list.filter work on lists that have nil elements. - - Fix __call metamethod. - - writeLine -> io.writeLine - - Fix io.writeLine (somehow two lines had become swapped). - - writeLine -> io.writeLine - - Various modifications prompted by Jamie Webb's submission of his own standard library. So far I have assimilated improvements that map directly on to existing code, and also removed some functions that didn't seem to be that useful. Looking at the code again provoked other miscellaneous improvements. - -2004-01-31 rrt - - In the previous commit, which had a bogus log message, I fixed io.readDir: split --> string.split. - In this one, I improved the formatting of io.readDir slightly. - - Improve spacing of comments. - - If -version is given and no command-line args, then terminate after showing the version message. - - Explain that although import is used internally, users should use require (as in README) and why. - - Removed bit._INTEGER_BITS, because it's the same as math._INTEGER_BITS. I suspect I meant to do this ages ago. - - Added a few more people I thought of. - - Formalise the README: this project is no longer just mine. - Add a list of AUTHORS: the first contributions have arrived. - - This script was trivial and wrong. - - Added math.floor and math.round, based on code from Johann Hibschman. - - Add math.floor and math.round, based on code from Johann Hibschman. - - Fix pickle: format->string.format (thanks to Johann Hibschman). - -2004-01-28 rrt - - Default the from and to parameters of list.slice to the start and end of the list respectively. - - Add primitive way to cope with missing non-standard C libraries, and a TODO to deal with missing C libraries properly. - - Fix table.newDefault to use correct name for __index metamethod. - - Improve module description in first line. - - Fix tostring to work on self-referential tables. - -2004-01-27 rrt - - Corrected misnaming of functions and added documentation. - -2004-01-26 rrt - - Add string.format extension to make it not try to format if there is only one argument. - -2004-01-25 rrt - - Update to Lua 5. This is an old change which I forgot to check in; ldoc is *not* the way forward for stdlib documentation. This checkin is just for completeness. - -2004-01-10 rrt - - *** empty log message *** - -2004-01-10 rrt - - Change "returns" lines to "@returns" for better LuaDoc-ness. - Add string.tonumbersi. - - Minor corrections and LuaDocification of some other comments. - -2003-10-22 rrt - - More Lua 5 tweaks, and a couple of minor bugfixes. - -2003-10-20 rrt - - Oops; added file with incorrect name; re-add with correct name. - - Add "import" from LTN 11 to overcome require's problem with circular dependencies. - Remove string.next, as string.gfind provides an equivalent iterator. - - More renaming for consistency, and move more code around. This introduced the first cyclic dependency between modules since I moved to Lua 5, and I've had to cure this with a C include-style trick, since Lua 5 require just overflows the stack when there's a recursive call of require. - - Add an iterator for the values in a set, and use it; methods are now organised into those that access the data structure and those that call other methods. - -2003-10-19 rrt - - Objectify the implementation, and add LuaDoc-style markup to the comments. - - Write methods outside object prototype (i.e. in more consistent form for stdlib). - -2003-10-18 rrt - - Rename std.data.logic to std.bit, as it extends the C bit library. - - Make a namespace for list routines. - - Fix bug in curry properly. - - Finish renaming in io.io. Update TODO for getopt in std.lua. - - Re-add mistakenly removed logic (I confused the ability to take multiple args with the ability to take lists). - - assert lives again! math added to hold math function extensions. - - Remove logic (no longer needed; _INTEGER_BITS moved to math, band &c. already work on lists). Various other movements and renaming of modules. - - Routines moves to std.list and std.base. - - More renaming. Remove boolean routines for when bitlib is not present. There's no excuse in Lua 5! - - Use ipairs instead of table.getn loops. - - Use pairs () instead of deprecated for "i, v in t" form. - - Rename table routines. Simplify compose. - - Renamed some libraries for Lua 5-ification reasons. - -2003-10-17 rrt - - Fix a minor bug and remove some debugging code. - -2003-10-17 rrt - - A new module (and family): algorithm, with first member algorithm.lcs, which implements the longest common subsequence algorithm needed for diff. - std.object has been reworked, and now fits much better with Lua 5, - although the interface to it is pretty much the same as before. - - Some other Lua 5-isation has been done, but not much; there's still a - lot left to do in std.data in particular. - -2003-10-13 rrt - - Fix call to writeLine (now io.writeLine). - -2003-09-27 rrt - - More Lua 5-ification changes, mostly to the io modules this time. - -2003-09-25 uid30086 - - Another round of changes for Lua 5-ification. This completes the changes to the string library (used to be the text library), and adds std.rex (complements my C rex library). Other changes are mostly to accomodate this; a few extras have snuck in. - -2003-09-24 rrt - - First set of changes moving to Lua 5-like naming conventions for the libraries. - -2003-09-14 rrt - - Use math.mod rather than bit.mod for wider compatibility. - - Wrap notes field of prog structure before output. - -2003-09-12 rrt - - More changes to update to Lua 5.0. Nearly there now, I think, as I have several scripts working! - -2003-09-11 rrt - - Another few search-and-replace function names to update to Lua 5. Mostly string functions this time. - -2003-09-09 rrt - - More search-and-replace and wholesale code removal (notably POSIX getopt) for Lua 5. - - Another swathe of Lua 5 updates. Now my little script that I'm testing nearly works, which means that quite a lot of the code in the libraries is at least vaguely correct! - -2003-09-08 rrt - - A slew of updates in the march to Lua-5-ify the libraries. I've just been working on a particular small script and changing things "on demand", and I've not even managed to make the script work yet, so there's almost certainly a lot of work still to go. - -2003-06-03 rrt - - Convert to Lua 5.0, and some slight tidying. - - Do TODOs for Lua 5 (use "le" tagmethod -- will have to become a metamethod) and ability to force a function to return only one result. - - Update std.patch40 to std.patch50 for Lua 5. Now none of the other modules need it. - - Make readDir return an unsorted list of files. Unfortunately, -U isn't supported by ls on all platforms. - -2003-03-13 rrt - - Update to match new directory structure (rather overdue!). - -2003-01-05 rrt - - Use endOfLine in chomp and wrap. - -2002-10-17 rrt - - Removed std.logic; now folded into std.data.logic - - std.logic now merged into std.data.logic. - - Merge the two logic modules. - -2002-09-28 rrt - - Add tabulate function to use tabulator methods, and use it. - -2002-09-10 rrt - - Sigh. New bnot didn't work. Next time I'll think and test rather better before straying from the path of righteousness. - - I was being very dim about bnot. Oops. Roberto pointed it out. I hang my head in shame. - - Revert to previous version to avoid losing precision (specifically, LSB). - -2002-09-09 rrt - - Shorter implementation of bxor, and bnot thanks to a remark by Paul Hsieh on lual (Message-Id: <0H26009OMQ9J59@mta5.snfc21.pbi.net>). - Kept band (as the primitive to make bxor) and bor (because de - Morganising it would involve a call to bnot and two to band, hence - making it three times slower). - -2002-09-08 rrt - - Poor man's logic functions (for those who can't use bitlib). Also calculate the number of bits in the word. - - Add std.logic - -2002-09-06 rrt - - Improve layout of usage message when no command line options (don't have trailing blank line). - -2002-09-05 rrt - - Add withFileOrHandle, which takes a filename, handle or uses a default handle, opens the file if appropriate, and passes the handle to a given function. - Use it to generalise readLines and readFile. - - It's tempting to generalise writeLine too, but writeLine ("foo", "bar") is - ambiguous: do we want to write "foo" and "bar" to _OUTPUT, or "bar" to - file "foo"? - -2002-09-05 rrt - - Make patches work with any version that starts with "Lua 4.0", to cope with 4.0.1 and any future point releases. - Replace unpack with a recursive version (based on code from John - Belmonte) that copes with any number of values. - - Change "key" to "index" everywhere for consistency. - - Improve comments for tinvert - - Change intersect tag method to division, and add TODO to implement proper subset tagmethod in Lua 5.0. - - Rename intersect to setintersect for consistency, and define setunion (= merge). - -2002-08-28 rrt - - Allow stringifier methods again, but they are now only used by tostring. Allows more cosmetic stringification, while not stopping pickling from working. - -2002-08-27 rrt - - Don't need stringify and pickler tables any more, and tostring and pickle can be simplified. They both use tabulator where necessary. - - Remove interaction between pickle and tostring, which is no longer needed, as they both now use tabulator methods where necessary. - - Add tabulator method table for turning arbitrary objects (typically tagged userdata) into tables. Use this to finally fix tostring and pickle. Oh, yes. - -2002-08-23 rrt - - A last gamble. Then I'll have to sit down and work it out again. - - Another desperate attempt. - - Fix up. I hope. This is starting to drive me insane. - - Typo. - - Fix default case for pickling. - - Fix typo. - - More fixes. - - More fixes to pickling. I got in a pickle with this one. - - Make pickling work properly on numbers and nil by having a "self" parameter for stringifier and pickler functions. They're more like classes now. - - Fix buglet (can't concat to nil). - - Make pickle work for numbers and nil. - - Add tinvert, and update some comments to LDoc format. - -2002-08-22 rrt - - Correct call of warn to expand arg list. - -2002-08-15 rrt - - Add utility for making zip dist of stdlib. - - Add empty to test whether a table is. - - Fix paths for new directory structure and get rid of one or two gremlins. - - Finish editing std.cfg into new form (configuration file with require implementation tacked on the end) and rename it. - - Update some TODOs. - - Rename std->modules and remove stray std.lua - -2002-08-14 rrt - - Standardize code style, and make changes (mostly to the comments) to prepare for renaming to std.config, as per John's suggestion. This file will only secondarily contain require, and will typically be built into the Lua system anyway. When we move to Lua 5.0, require will disappear, anyway. - - John Belmonte's replacement require implementation (5.0-compatible). - - Reorganise directory structure to a flat directory, to cope with Lua 5.0 require patterns (so that the libraries can be loaded without making assumptions about directory separators). - -2002-08-13 rrt - - Add the format library to text. - - Fix buglet in warn. - - Move some functions to format.lua to avoid dependency loop text<->assert and to make way for the new pretty printing functions described in a big TODO in format.lua. - Override format in text, so that if it's only passed one argument, it - just returns it. - - Use capability of warn to take format arguments. - -2002-08-13 rrt - - Rename affirm to assert, and pass its arguments to the new format function. - Remove the *f functions (which called format); these were unused. Now - warn, die and assert can all take format arguments. - - affirm->assert in file.lua - -2002-08-13 rrt - - Correct punctuation. - -2002-08-12 rrt - - Fix a typo loading pickle.lua in text.lua - Make pickle escape characters in strings that need it - - Restructure stringifying so that functions in stringifier can produce either a string or a table of stringified index = stringified value pairs. - Use this to write a simple pickle function that can pickle anything - that tostring can stringify. pickle and tostring are now effectively - just different renderers for the functions in stringifier. - - Fix spacing in comments. - - Allow new tostring methods to be registered. - - *** empty log message *** - - Debug defaultTable so it uses the initial value given rather than always creating an empty table. - - Add defaultTable to macro. - Move lookup to macro, reimplement it in terms of foldl and subscript, - and reimplement pathSubscript in terms of it. - - Add a logic module to extend band, bor and bxor to lists (just listable them). - - Comment list.lua in ldoc format. The other modules will probably follow. - - Include the new macro module. - - Move pathSubscript out of table.lua to avoid a circular dependency, into the new macro.lua module, which also includes some material moved from global.lua. - -2002-08-01 rrt - - Move print from assert to debug. This not only makes sense, but breaks a recursive dependency between assert and text/text. - -2002-07-30 rrt - - Remove require for now-defunct time.lua, and tidy up the TODOs. - - Correct endofLine -> endOfLine again; this must have crept back in with the last diff. Using CVS everywhere rather than manual copying will be a Good Thing in this respect! - -2002-07-29 rrt - - Generalised daySuffix to ordinalSuffix. Still English-specific :-( - -2002-07-27 rrt - - Improve comment for mapIter - -2002-07-26 rrt - - Add constant, a constant function generator. - - Use pathSubscript in methodify to allow more convenient macroization of tables. - - A simple documentation extracter, relying completely on specially formatted comments. There's no documentation at the moment except the patterns in the program, which should be obvious! I'll ldocify all the code shortly and check in instructions with it. - This tool is provisional, and subject to improvement. The TODOs in the - file indicate some of my first thoughts in that direction. - -2002-07-24 rrt - - Move methodify to table.lua where it belongs (it has nothing to do with lists!) - - Allow scripts to have no arguments. If you want to display help when just the script is run with no arguments, you'll have to do it manually. - - Throw away stderr from shell commands (we don't expect the output to clutter up the screen; it's always possible to capture it by adding a redirection to the command, which will override the one we add). - - Add subscript, which exposes [] as a function. - -2002-06-22 rrt - - Correct endofLine -> endOfLine - - Initial revision diff --git a/GNUmakefile b/GNUmakefile deleted file mode 100644 index f477d0a..0000000 --- a/GNUmakefile +++ /dev/null @@ -1,82 +0,0 @@ -# Maintainer rules. -# -# Copyright (C) 2013-2015 Gary V. Vaughan -# Written by Gary V. Vaughan, 2013 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -ME = GNUmakefile - -# If the user runs GNU make but didn't ./configure yet, do it for them. -dont-forget-to-bootstrap = $(wildcard Makefile.in) - -ifeq ($(dont-forget-to-bootstrap),) - -## Don't redo any pedantic rock version checks, incase they derail -## a subdirectory bootstrap of slingshot. - -%:: - @echo '$(ME): rebootstrap' - @test -f Makefile.in || ./bootstrap --skip-rock-checks - @test -f Makefile || ./configure - $(MAKE) $@ - -else - - -include build-aux/release.mk -include build-aux/sanity.mk - -# Run sanity checks as part of distcheck. -distcheck: $(local-check) - - -## ------------------------- ## -## Copyright Notice Updates. ## -## ------------------------- ## - -# If you want to set UPDATE_COPYRIGHT_* environment variables, -# for the build-aux/update-copyright script: set the assignments -# in this variable in local.mk. -update_copyright_env ?= - -# Run this rule once per year (usually early in January) -# to update all FSF copyright year lists in your project. -# If you have an additional project-specific rule, -# add it in local.mk along with a line 'update-copyright: prereq'. -# By default, exclude all variants of COPYING; you can also -# add exemptions (such as ChangeLog..* for rotated change logs) -# in the file .x-update-copyright. -.PHONY: update-copyright -update-copyright: - $(AM_V_GEN)grep -l -w Copyright \ - $$(export VC_LIST_EXCEPT_DEFAULT=COPYING && $(VC_LIST_EXCEPT)) \ - | $(update_copyright_env) xargs $(srcdir)/build-aux/$@ - - -## ------ ## -## Specl. ## -## ------ ## - -# Use 'make check V=1' for verbose output, or set SPECL_OPTS to -# pass alternative options to specl command. - -SPECL_OPTS ?= -SPECL_OPTS += $(specl_verbose_$(V)) -specl_verbose_ = $(specl_verbose_$(AM_DEFAULT_VERBOSITY)) -specl_verbose_0 = -specl_verbose_1 = --verbose --formatter=report - - -endif diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 2099840..0000000 --- a/INSTALL +++ /dev/null @@ -1,370 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, -Inc. - - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. - -Basic Installation -================== - - Briefly, the shell command `./configure && make && make install' -should configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - - The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type `make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root - privileges. - - 5. Optionally, type `make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type `make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide `make - distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, `make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. - - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - HP-UX `make' updates targets which have the same time stamps as -their prerequisites, which makes it generally unusable when shipped -generated files such as `configure' are involved. Use GNU `make' -instead. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf limitation. Until the limitation is lifted, you can use -this workaround: - - CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. diff --git a/COPYING b/LICENSE.md similarity index 70% rename from COPYING rename to LICENSE.md index ec03e04..c2b4620 100644 --- a/COPYING +++ b/LICENSE.md @@ -1,10 +1,4 @@ -This software comprises files that are copyright their respective -authors (see the AUTHORS file for details), and distributed under -the terms of the MIT license (the same license as Lua itself), -unless noted otherwise in the body of that file. - -==================================================================== -Copyright (C) 2002-2015 stdlib authors +Copyright (C) 2002-2018 stdlib authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -24,4 +18,3 @@ MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -==================================================================== diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fefe092 --- /dev/null +++ b/Makefile @@ -0,0 +1,50 @@ +# Lua Standard Libraries for Lua 5.1, 5.2, 5.3 & 5.4 +# Copyright (C) 2002-2018 stdlib authors + +LDOC = ldoc +LUA = lua +MKDIR = mkdir -p +SED = sed +SPECL = specl + +VERSION = 41.2.2 + +luadir = lib/std +SOURCES = \ + $(luadir).lua \ + $(luadir)/base.lua \ + $(luadir)/container.lua \ + $(luadir)/debug.lua \ + $(luadir)/debug_init/init.lua \ + $(luadir)/functional.lua \ + $(luadir)/io.lua \ + $(luadir)/list.lua \ + $(luadir)/math.lua \ + $(luadir)/object.lua \ + $(luadir)/operator.lua \ + $(luadir)/optparse.lua \ + $(luadir)/package.lua \ + $(luadir)/set.lua \ + $(luadir)/strbuf.lua \ + $(luadir)/strict.lua \ + $(luadir)/string.lua \ + $(luadir)/table.lua \ + $(luadir)/tree.lua \ + $(NOTHING_ELSE) + +all: + +doc: build-aux/config.ld $(SOURCES) + $(LDOC) -c build-aux/config.ld . + +build-aux/config.ld: build-aux/config.ld.in + $(SED) -e "s,@PACKAGE_VERSION@,$(VERSION)," '$<' > '$@' + + +CHECK_ENV = LUA=$(LUA) + +check: $(SOURCES) + LUA=$(LUA) $(SPECL) --unicode $(SPECL_OPTS) spec/*_spec.yaml + + +.FORCE: diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 4ade870..0000000 --- a/Makefile.am +++ /dev/null @@ -1,109 +0,0 @@ -# Non-recursive Make rules. -# -# Copyright (C) 2013-2015 Gary V. Vaughan -# Written by Gary V. Vaughan, 2013 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -## ------------ ## -## Environment. ## -## ------------ ## - -LUA_PATH ?= ; -LUA_CPATH ?= ; - -SPECL_ENV = -CHECK_ENV = -INSTALLCHECK_ENV = - - -## ---------- ## -## Bootstrap. ## -## ---------- ## - -ACLOCAL_AMFLAGS = -I m4 - -AM_CPPFLAGS = $(LUA_INCLUDE) - - -## ------------- ## -## Declarations. ## -## ------------- ## - -EXTRA_DIST = -EXTRA_LTLIBRARIES = -CLEANFILES = -DISTCLEANFILES = -MAINTAINERCLEANFILES = -NOTHING_ELSE = - -bin_SCRIPTS = -check_local = -dist_bin_SCRIPTS = -dist_lua_DATA = -doc_DATA = -installcheck_local = -install_exec_hooks = remove-luaexec-lafiles -uninstall_hooks = uninstall-luaexec-modules -lib_LTLIBRARIES = -luaexec_LTLIBRARIES = -man_MANS = -save_release_files = - -include local.mk -include build-aux/rockspecs.mk - - -## ------------ ## -## Local Tests. ## -## ------------ ## - -check-local: $(check_local) - - -## ------------- ## -## Installation. ## -## ------------- ## - -installcheck-local: $(installcheck_local) - -install-exec-hook: $(install_exec_hooks) - -# Neither Lua itself, nor LuaRocks can use .la files, and LuaRocks -# actually moves such files aside anyway, so we just remove them from -# the installation directory. -remove-luaexec-lafiles: - @for la in $(luaexec_LTLIBRARIES); do \ - f=`echo "$$la" |sed 's|^.*/||'`; \ - echo rm -f $(DESTDIR)$(luaexecdir)/$$f; \ - rm -f $(DESTDIR)$(luaexecdir)/$$f; \ - done - - -## --------------- ## -## Uninstallation. ## -## --------------- ## - -uninstall-hook: $(uninstall_hooks) - -# We removed the .la files from luaexecdir, so the standard uninstall, -# with libtool --mode=uninstall, can't find everything anymore. -uninstall-luaexec-modules: - @for la in $(luaexec_LTLIBRARIES); do \ - base=`echo "$$la" \ - |sed 's|^.*/\(.*\)\.la|\1|'`; \ - echo rm -f $(DESTDIR)$(luaexecdir)/$$base.so; \ - rm -f $(DESTDIR)$(luaexecdir)/$$base.so; \ - done diff --git a/Makefile.in b/Makefile.in deleted file mode 100644 index 1082e7c..0000000 --- a/Makefile.in +++ /dev/null @@ -1,1244 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Non-recursive Make rules. -# -# Copyright (C) 2013-2015 Gary V. Vaughan -# Written by Gary V. Vaughan, 2013 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Local Make rules. -# -# Copyright (C) 2013-2015 Gary V. Vaughan -# Written by Gary V. Vaughan, 2013 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Specl specs make rules. - -# Slingshot specl rules for make. - -# This file is distributed with Slingshot, and licensed under the -# terms of the MIT license reproduced below. - -# ==================================================================== # -# Copyright (C) 2013-2015 Gary V. Vaughan # -# # -# Permission is hereby granted, free of charge, to any person # -# obtaining a copy of this software and associated documentation # -# files (the "Software"), to deal in the Software without restriction, # -# including without limitation the rights to use, copy, modify, merge, # -# publish, distribute, sublicense, and/or sell copies of the Software, # -# and to permit persons to whom the Software is furnished to do so, # -# subject to the following conditions: # -# # -# The above copyright notice and this permission notice shall be # -# included in all copies or substantial portions of the Software. # -# # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # -# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # -# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # -# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -# ==================================================================== # - -# To use this file create a list of your spec files in specl_SPECS -# and then include this make fragment. - -# Slingshot rockspec rules for make. - -# This file is distributed with Slingshot, and licensed under the -# terms of the MIT license reproduced below. - -# ==================================================================== # -# Copyright (C) 2013-2015 Reuben Thomas and Gary V. Vaughan # -# # -# Permission is hereby granted, free of charge, to any person # -# obtaining a copy of this software and associated documentation # -# files (the "Software"), to deal in the Software without restriction, # -# including without limitation the rights to use, copy, modify, merge, # -# publish, distribute, sublicense, and/or sell copies of the Software, # -# and to permit persons to whom the Software is furnished to do so, # -# subject to the following conditions: # -# # -# The above copyright notice and this permission notice shall be # -# included in all copies or substantial portions of the Software. # -# # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # -# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # -# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # -# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -# ==================================================================== # - -# This file is suitable for use from a portable Makefile, you might -# include it into the top-level Makefile.am with: -# -# include build-aux/rockspecs.mk - - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lua.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(dist_bin_SCRIPTS) $(dist_classes_DATA) \ - $(dist_doc_DATA) $(dist_lua_DATA) $(dist_luastd_DATA) \ - $(dist_luastddebug_DATA) $(dist_modules_DATA) \ - $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = build-aux/config.ld -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(luaexecdir)" \ - "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" \ - "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" \ - "$(DESTDIR)$(luastddebugdir)" "$(DESTDIR)$(modulesdir)" \ - "$(DESTDIR)$(docdir)" -LTLIBRARIES = $(lib_LTLIBRARIES) $(luaexec_LTLIBRARIES) -SCRIPTS = $(bin_SCRIPTS) $(dist_bin_SCRIPTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -DATA = $(dist_classes_DATA) $(dist_doc_DATA) $(dist_lua_DATA) \ - $(dist_luastd_DATA) $(dist_luastddebug_DATA) \ - $(dist_modules_DATA) $(doc_DATA) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in \ - $(srcdir)/build-aux/rockspecs.mk $(srcdir)/build-aux/specl.mk \ - $(srcdir)/local.mk $(srcdir)/specs/specs.mk \ - $(top_srcdir)/build-aux/config.ld.in \ - $(top_srcdir)/build-aux/install-sh \ - $(top_srcdir)/build-aux/missing AUTHORS COPYING ChangeLog \ - INSTALL NEWS README build-aux/install-sh build-aux/missing -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDOC = @LDOC@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -LUA = @LUA@ -LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ -LUA_PLATFORM = @LUA_PLATFORM@ -LUA_PREFIX = @LUA_PREFIX@ -LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ -LUA_VERSION = @LUA_VERSION@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SPECL = @SPECL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -am__leading_dot = @am__leading_dot@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -luadir = @luadir@ -luaexecdir = @luaexecdir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgluadir = @pkgluadir@ -pkgluaexecdir = @pkgluaexecdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -SPECL_ENV = -CHECK_ENV = LUA='$(LUA)' PACKAGE_STRING='$(PACKAGE_STRING)' \ - abs_top_builddir='$(abs_top_builddir)' \ - abs_top_srcdir='$(abs_top_srcdir)' \ - top_builddir='$(top_builddir)' top_srcdir='$(top_srcdir)' \ - $(NOTHING_ELSE) -INSTALLCHECK_ENV = LUA='$(LUA)' PACKAGE_STRING='$(PACKAGE_STRING)' \ - installcheck='true' $(NOTHING_ELSE) -ACLOCAL_AMFLAGS = -I m4 -AM_CPPFLAGS = $(LUA_INCLUDE) -EXTRA_DIST = $(srcdir)/specs/spec_helper.lua $(NOTHING_ELSE) \ - $(specl_SPECS) $(NOTHING_ELSE) build-aux/config.ld.in \ - lib/std.lua.in $(NOTHING_ELSE) $(mkrockspecs) \ - $(package_rockspec) $(rockspec_conf) $(NOTHING_ELSE) -EXTRA_LTLIBRARIES = -CLEANFILES = -DISTCLEANFILES = $(luarocks_config) $(NOTHING_ELSE) -MAINTAINERCLEANFILES = -NOTHING_ELSE = -bin_SCRIPTS = -check_local = specl-check-local -dist_bin_SCRIPTS = -dist_lua_DATA = lib/std.lua $(NOTHING_ELSE) -doc_DATA = -installcheck_local = specl-installcheck-local -install_exec_hooks = remove-luaexec-lafiles -uninstall_hooks = uninstall-luaexec-modules -lib_LTLIBRARIES = -luaexec_LTLIBRARIES = -man_MANS = -save_release_files = $(scm_rockspec) -std_path = $(abs_srcdir)/lib/?.lua;$(abs_srcdir)/lib/?/init.lua -LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" -old_NEWS_hash = d41d8cd98f00b204e9800998ecf8427e -update_copyright_env = \ - UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ - UPDATE_COPYRIGHT_USE_INTERVALS=1 \ - UPDATE_COPYRIGHT_FORCE=1 - -classesdir = $(docdir)/classes -modulesdir = $(docdir)/modules -dist_doc_DATA = $(srcdir)/doc/index.html $(srcdir)/doc/ldoc.css -dist_classes_DATA = $(srcdir)/doc/classes/std.container.html \ - $(srcdir)/doc/classes/std.list.html \ - $(srcdir)/doc/classes/std.object.html \ - $(srcdir)/doc/classes/std.optparse.html \ - $(srcdir)/doc/classes/std.set.html \ - $(srcdir)/doc/classes/std.strbuf.html \ - $(srcdir)/doc/classes/std.tree.html $(NOTHING_ELSE) -dist_modules_DATA = $(srcdir)/doc/modules/std.html \ - $(srcdir)/doc/modules/std.debug.html \ - $(srcdir)/doc/modules/std.functional.html \ - $(srcdir)/doc/modules/std.io.html \ - $(srcdir)/doc/modules/std.math.html \ - $(srcdir)/doc/modules/std.operator.html \ - $(srcdir)/doc/modules/std.package.html \ - $(srcdir)/doc/modules/std.strict.html \ - $(srcdir)/doc/modules/std.string.html \ - $(srcdir)/doc/modules/std.table.html $(NOTHING_ELSE) -SPECL_OPTS = --unicode -specl_SPECS = \ - $(srcdir)/specs/container_spec.yaml \ - $(srcdir)/specs/debug_spec.yaml \ - $(srcdir)/specs/functional_spec.yaml \ - $(srcdir)/specs/io_spec.yaml \ - $(srcdir)/specs/list_spec.yaml \ - $(srcdir)/specs/math_spec.yaml \ - $(srcdir)/specs/object_spec.yaml \ - $(srcdir)/specs/operator_spec.yaml \ - $(srcdir)/specs/optparse_spec.yaml \ - $(srcdir)/specs/package_spec.yaml \ - $(srcdir)/specs/set_spec.yaml \ - $(srcdir)/specs/strbuf_spec.yaml \ - $(srcdir)/specs/string_spec.yaml \ - $(srcdir)/specs/table_spec.yaml \ - $(srcdir)/specs/tree_spec.yaml \ - $(srcdir)/specs/std_spec.yaml \ - $(NOTHING_ELSE) - -luastddir = $(luadir)/std -dist_luastd_DATA = \ - lib/std/base.lua \ - lib/std/container.lua \ - lib/std/debug.lua \ - lib/std/functional.lua \ - lib/std/io.lua \ - lib/std/list.lua \ - lib/std/math.lua \ - lib/std/object.lua \ - lib/std/operator.lua \ - lib/std/optparse.lua \ - lib/std/package.lua \ - lib/std/set.lua \ - lib/std/strbuf.lua \ - lib/std/strict.lua \ - lib/std/string.lua \ - lib/std/table.lua \ - lib/std/tree.lua \ - $(NOTHING_ELSE) - - -# For bugwards compatibility with LuaRocks 2.1, while ensuring that -# `require "std.debug_init"` continues to work, we have to install -# the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. -# When LuaRocks works again, move this file back to dist_luastd_DATA -# above and rename to debug_init.lua. -luastddebugdir = $(luastddir)/debug_init -dist_luastddebug_DATA = \ - lib/std/debug_init/init.lua \ - $(NOTHING_ELSE) - -mkrockspecs_args = --module-dir $(srcdir)/lib --repository lua-stdlib -luarocks_config = build-aux/luarocks-config.lua -rockspec_conf = $(srcdir)/rockspec.conf -mkrockspecs = $(srcdir)/build-aux/mkrockspecs -package_rockspec = $(srcdir)/$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec -scm_rockspec = $(PACKAGE)-git-$(rockspec_revision).rockspec - -# If you need a different rockspec revision, override this on the make -# command line: -# -# make rockspecs rockspec_revision=2 -rockspec_revision = 1 -LUAROCKS = luarocks -MKROCKSPECS = $(MKROCKSPECS_ENV) $(LUA) $(mkrockspecs) -ROCKSPECS_DEPS = \ - $(luarocks_config) \ - $(mkrockspecs) \ - $(rockspec_conf) \ - $(NOTHING_ELSE) - -set_LUA_BINDIR = LUA_BINDIR=`which $(LUA) |$(SED) 's|/[^/]*$$||'` -LUA_INCDIR = `cd $$LUA_BINDIR/../include && pwd` -LUA_LIBDIR = `cd $$LUA_BINDIR/../lib && pwd` -all: all-am - -.SUFFIXES: -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/local.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; -$(srcdir)/local.mk $(srcdir)/specs/specs.mk $(srcdir)/build-aux/specl.mk $(srcdir)/build-aux/rockspecs.mk $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): -build-aux/config.ld: $(top_builddir)/config.status $(top_srcdir)/build-aux/config.ld.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(INSTALL) $(INSTALL_STRIP_FLAG) $$list '$(DESTDIR)$(libdir)'"; \ - $(INSTALL) $(INSTALL_STRIP_FLAG) $$list "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -install-luaexecLTLIBRARIES: $(luaexec_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(luaexec_LTLIBRARIES)'; test -n "$(luaexecdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(luaexecdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(luaexecdir)" || exit 1; \ - echo " $(INSTALL) $(INSTALL_STRIP_FLAG) $$list '$(DESTDIR)$(luaexecdir)'"; \ - $(INSTALL) $(INSTALL_STRIP_FLAG) $$list "$(DESTDIR)$(luaexecdir)"; \ - } - -uninstall-luaexecLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(luaexec_LTLIBRARIES)'; test -n "$(luaexecdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(luaexecdir)/$$f'"; \ - rm -f "$(DESTDIR)$(luaexecdir)/$$f"; \ - done - -clean-luaexecLTLIBRARIES: - -test -z "$(luaexec_LTLIBRARIES)" || rm -f $(luaexec_LTLIBRARIES) - @list='$(luaexec_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -install-binSCRIPTS: $(bin_SCRIPTS) - @$(NORMAL_INSTALL) - @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n' \ - -e 'h;s|.*|.|' \ - -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) { files[d] = files[d] " " $$1; \ - if (++n[d] == $(am__install_max)) { \ - print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ - else { print "f", d "/" $$4, $$1 } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 's,.*/,,;$(transform)'`; \ - dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) -install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) - @$(NORMAL_INSTALL) - @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n' \ - -e 'h;s|.*|.|' \ - -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) { files[d] = files[d] " " $$1; \ - if (++n[d] == $(am__install_max)) { \ - print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ - else { print "f", d "/" $$4, $$1 } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-dist_binSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 's,.*/,,;$(transform)'`; \ - dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) -install-dist_classesDATA: $(dist_classes_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_classes_DATA)'; test -n "$(classesdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(classesdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(classesdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(classesdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(classesdir)" || exit $$?; \ - done - -uninstall-dist_classesDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_classes_DATA)'; test -n "$(classesdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(classesdir)'; $(am__uninstall_files_from_dir) -install-dist_docDATA: $(dist_doc_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ - done - -uninstall-dist_docDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) -install-dist_luaDATA: $(dist_lua_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_lua_DATA)'; test -n "$(luadir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(luadir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(luadir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(luadir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(luadir)" || exit $$?; \ - done - -uninstall-dist_luaDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_lua_DATA)'; test -n "$(luadir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(luadir)'; $(am__uninstall_files_from_dir) -install-dist_luastdDATA: $(dist_luastd_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_luastd_DATA)'; test -n "$(luastddir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(luastddir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(luastddir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(luastddir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(luastddir)" || exit $$?; \ - done - -uninstall-dist_luastdDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_luastd_DATA)'; test -n "$(luastddir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(luastddir)'; $(am__uninstall_files_from_dir) -install-dist_luastddebugDATA: $(dist_luastddebug_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_luastddebug_DATA)'; test -n "$(luastddebugdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(luastddebugdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(luastddebugdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(luastddebugdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(luastddebugdir)" || exit $$?; \ - done - -uninstall-dist_luastddebugDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_luastddebug_DATA)'; test -n "$(luastddebugdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(luastddebugdir)'; $(am__uninstall_files_from_dir) -install-dist_modulesDATA: $(dist_modules_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(modulesdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(modulesdir)" || exit $$?; \ - done - -uninstall-dist_modulesDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_modules_DATA)'; test -n "$(modulesdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(modulesdir)'; $(am__uninstall_files_from_dir) -install-docDATA: $(doc_DATA) - @$(NORMAL_INSTALL) - @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ - done - -uninstall-docDATA: - @$(NORMAL_UNINSTALL) - @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local -check: check-am -all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(luaexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(classesdir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(luadir)" "$(DESTDIR)$(luastddir)" "$(DESTDIR)$(luastddebugdir)" "$(DESTDIR)$(modulesdir)" "$(DESTDIR)$(docdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-luaexecLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-dist_classesDATA install-dist_docDATA \ - install-dist_luaDATA install-dist_luastdDATA \ - install-dist_luastddebugDATA install-dist_modulesDATA \ - install-docDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binSCRIPTS install-dist_binSCRIPTS \ - install-libLTLIBRARIES install-luaexecLTLIBRARIES - @$(NORMAL_INSTALL) - $(MAKE) $(AM_MAKEFLAGS) install-exec-hook -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: installcheck-local - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ - uninstall-dist_classesDATA uninstall-dist_docDATA \ - uninstall-dist_luaDATA uninstall-dist_luastdDATA \ - uninstall-dist_luastddebugDATA uninstall-dist_modulesDATA \ - uninstall-docDATA uninstall-libLTLIBRARIES \ - uninstall-luaexecLTLIBRARIES - @$(NORMAL_INSTALL) - $(MAKE) $(AM_MAKEFLAGS) uninstall-hook -.MAKE: check-am install-am install-exec-am install-strip uninstall-am - -.PHONY: all all-am am--refresh check check-am check-local clean \ - clean-generic clean-libLTLIBRARIES clean-luaexecLTLIBRARIES \ - cscopelist-am ctags-am dist dist-all dist-bzip2 dist-gzip \ - dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \ - distclean distclean-generic distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-binSCRIPTS install-data \ - install-data-am install-dist_binSCRIPTS \ - install-dist_classesDATA install-dist_docDATA \ - install-dist_luaDATA install-dist_luastdDATA \ - install-dist_luastddebugDATA install-dist_modulesDATA \ - install-docDATA install-dvi install-dvi-am install-exec \ - install-exec-am install-exec-hook install-html install-html-am \ - install-info install-info-am install-libLTLIBRARIES \ - install-luaexecLTLIBRARIES install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installcheck-local installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ - uninstall-am uninstall-binSCRIPTS uninstall-dist_binSCRIPTS \ - uninstall-dist_classesDATA uninstall-dist_docDATA \ - uninstall-dist_luaDATA uninstall-dist_luastdDATA \ - uninstall-dist_luastddebugDATA uninstall-dist_modulesDATA \ - uninstall-docDATA uninstall-hook uninstall-libLTLIBRARIES \ - uninstall-luaexecLTLIBRARIES - -.PRECIOUS: Makefile - - -LUA_PATH ?= ; -LUA_CPATH ?= ; -specl-check-local: $(specl_SPECS) - $(CHECK_ENV) $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) -specl-installcheck-local: $(specl_SPECS) - $(INSTALLCHECK_ENV) $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) - -# In order to avoid regenerating std.lua at configure time, which -# causes the documentation to be rebuilt and hence requires users to -# have ldoc installed, put std/std.lua in as a Makefile dependency. -# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) -lib/std.lua: lib/std.lua.in - ./config.status --file=$@ - -$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(srcdir)/doc - -$(srcdir)/doc: $(dist_lua_DATA) $(dist_luastd_DATA) - test -d $@ || mkdir $@ - $(LDOC) -c build-aux/config.ld -d $(abs_srcdir)/doc . - -$(luarocks_config): Makefile.am - @test -d build-aux || mkdir build-aux - $(AM_V_GEN){ \ - $(set_LUA_BINDIR); \ - echo 'rocks_trees = { "$(abs_srcdir)/luarocks" }'; \ - echo 'variables = {'; \ - echo ' LUA = "$(LUA)",'; \ - echo ' LUA_BINDIR = "'$$LUA_BINDIR'",'; \ - echo ' LUA_INCDIR = "'$(LUA_INCDIR)'",'; \ - echo ' LUA_LIBDIR = "'$(LUA_LIBDIR)'",'; \ - echo '}'; \ - } > '$@' - -$(package_rockspec): $(ROCKSPECS_DEPS) - $(AM_V_at)rm -f '$@' 2>/dev/null || : - $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(mkrockspecs_args) \ - $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' - $(AM_V_at)$(LUAROCKS) lint '$@' - -$(scm_rockspec): $(ROCKSPECS_DEPS) - $(AM_V_at)rm '$@' 2>/dev/null || : - $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(mkrockspecs_args) \ - $(PACKAGE) git 1 > '$@' - $(AM_V_at)$(LUAROCKS) lint '$@' - -.PHONY: rockspecs -rockspecs: - $(AM_V_at)rm -f *.rockspec - $(AM_V_at)$(MAKE) $(package_rockspec) $(scm_rockspec) - -check-local: $(check_local) - -installcheck-local: $(installcheck_local) - -install-exec-hook: $(install_exec_hooks) - -# Neither Lua itself, nor LuaRocks can use .la files, and LuaRocks -# actually moves such files aside anyway, so we just remove them from -# the installation directory. -remove-luaexec-lafiles: - @for la in $(luaexec_LTLIBRARIES); do \ - f=`echo "$$la" |sed 's|^.*/||'`; \ - echo rm -f $(DESTDIR)$(luaexecdir)/$$f; \ - rm -f $(DESTDIR)$(luaexecdir)/$$f; \ - done - -uninstall-hook: $(uninstall_hooks) - -# We removed the .la files from luaexecdir, so the standard uninstall, -# with libtool --mode=uninstall, can't find everything anymore. -uninstall-luaexec-modules: - @for la in $(luaexec_LTLIBRARIES); do \ - base=`echo "$$la" \ - |sed 's|^.*/\(.*\)\.la|\1|'`; \ - echo rm -f $(DESTDIR)$(luaexecdir)/$$base.so; \ - rm -f $(DESTDIR)$(luaexecdir)/$$base.so; \ - done - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/NEWS b/NEWS.md similarity index 99% rename from NEWS rename to NEWS.md index 7bd2b78..2649118 100644 --- a/NEWS +++ b/NEWS.md @@ -1,6 +1,6 @@ # Stdlib NEWS - User visible changes -## Noteworthy changes in release 41.2.2 (2018-09-03) [stable] +## Noteworthy changes in release 41.2.2 (2018-09-16) [stable] ### New Features diff --git a/README b/README.md similarity index 89% rename from README rename to README.md index d5a82a5..77230ab 100644 --- a/README +++ b/README.md @@ -9,10 +9,10 @@ by the [stdlib project][github] [![Stories in Ready](https://badge.waffle.io/lua-stdlib/lua-stdlib.png?label=ready&title=Ready)](https://waffle.io/lua-stdlib/lua-stdlib) -This is a collection of Lua libraries for Lua 5.1, 5.2 and 5.3. The -libraries are copyright by their authors 2000-2015 (see the AUTHORS -file for details), and released under the MIT license (the same -license as Lua itself). There is no warranty. +This is a collection of Lua libraries for Lua 5.1 (including LuaJIT), 5.2, +5.3 and 5.4. The libraries are copyright by their authors 2000-2018, and +released under the MIT license (the same license as Lua itself). There is +no warranty. Stdlib has no prerequisites beyond a standard Lua system. diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index dfb1151..0000000 --- a/aclocal.m4 +++ /dev/null @@ -1,741 +0,0 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([m4/ax_lua.m4]) diff --git a/bootstrap b/bootstrap deleted file mode 100755 index 0b70e37..0000000 --- a/bootstrap +++ /dev/null @@ -1,5796 +0,0 @@ -#! /bin/sh -## DO NOT EDIT - This file generated from build-aux/bootstrap.in -## by inline-source v2014-01-03.01 - -# Bootstrap an Autotooled package from checked-out sources. -# Written by Gary V. Vaughan, 2010 - -# Copyright (C) 2010-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Originally written by Paul Eggert. The canonical version of this -# script is maintained as build-aux/bootstrap in gnulib, however, to -# be useful to your project, you should place a copy of it under -# version control in the top-level directory of your project. The -# intent is that all customization can be done with a bootstrap.conf -# file also maintained in your version control; gnulib comes with a -# template build-aux/bootstrap.conf to get you started. - -# Please report bugs or propose patches to bug-gnulib@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# Most GNUish projects do not keep all of the generated Autotool -# files under version control, but running all of the right tools -# with the right arguments, in the correct order to regenerate -# all of those files in readiness for configuration and building -# can be surprisingly involved! Many projects have a 'bootstrap' -# script under version control to invoke Autotools and perform -# other assorted book-keeping with version numbers and the like. -# -# This bootstrap script aims to probe the configure.ac and top -# Makefile.am of your project to automatically determine what -# the correct ordering and arguments are and then run the tools for -# you. In order to use it, you can generate an initial standalone -# script with: -# -# gl/build-aux/inline-source gl/build-aux/bootstrap.in > bootstrap -# -# You should then store than script in version control for other -# developers in you project. It will give you instructions about -# how to keep it up to date if the sources change. -# -# See gl/doc/bootstrap.texi for documentation on how to write -# a bootstrap.conf to customize it for your project's -# idiosyncracies. - - -## ================================================================== ## -## ## -## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ## -## ## -## ================================================================== ## - -## ------------------------------- ## -## User overridable command paths. ## -## ------------------------------- ## - -# All uppercase denotes values stored in the environment. These -# variables should generally be overridden by the user - however, we do -# set them to 'true' in some parts of this script to prevent them being -# called at the wrong time by other tools that we call ('autoreconf', -# for example). -# -# We also allow 'LIBTOOLIZE', 'M4', 'SHA1SUM' and some others to be -# overridden, and export the result for child processes, but they are -# handled by the function 'func_find_tool' and not defaulted in this -# section. - -: ${ACLOCAL="aclocal"} -: ${AUTOCONF="autoconf"} -: ${AUTOHEADER="autoheader"} -: ${AUTOM4TE="autom4te"} -: ${AUTOHEADER="autoheader"} -: ${AUTOMAKE="automake"} -: ${AUTOPOINT="autopoint"} -: ${AUTORECONF="autoreconf"} -: ${CMP="cmp"} -: ${CONFIG_SHELL="/bin/sh"} -: ${DIFF="diff"} -: ${GIT="git"} -: ${LN_S="ln -s"} -: ${RM="rm"} - -export ACLOCAL -export AUTOCONF -export AUTOHEADER -export AUTOM4TE -export AUTOHEADER -export AUTOMAKE -export AUTOPOINT -export AUTORECONF -export CONFIG_SHELL - - -: ${LUAROCKS="luarocks"} - -export LUAROCKS - - -## -------------- ## -## Configuration. ## -## -------------- ## - -# A newline delimited list of triples of programs (that respond to -# --version), the minimum version numbers required (or just '-' in the -# version field if any version will be sufficient) and homepage URLs -# to help locate missing packages. -buildreq= - -# Name of a file containing instructions on installing missing packages -# required in 'buildreq'. -buildreq_readme=README-hacking - -# These are extracted from AC_INIT in configure.ac, though you can -# override those values in 'bootstrap.conf' if you prefer. -build_aux= -macro_dir= -package= -package_name= -package_version= -package_bugreport= - -# These are extracted from 'gnulib-cache.m4', or else fall-back -# automatically on the gnulib defaults; unless you set the values -# manually in 'bootstrap.conf'. -doc_base= -gnulib_mk= -gnulib_name= -local_gl_dir= -source_base= -tests_base= - -# The list of gnulib modules required at 'gnulib-tool' time. If you -# check 'gnulib-cache.m4' into your repository, then this list will be -# extracted automatically. -gnulib_modules= - -# Extra gnulib files that are not in modules, which override files of -# the same name installed by other bootstrap tools. -gnulib_non_module_files=" - build-aux/compile - build-aux/install-sh - build-aux/mdate-sh - build-aux/texinfo.tex - build-aux/depcomp - build-aux/config.guess - build-aux/config.sub - doc/INSTALL -" - -# Relative path to the local gnulib submodule, and url to the upstream -# git repository. If you have a gnulib entry in your .gitmodules file, -# these values are ignored. -gnulib_path= -gnulib_url= - -# Additional gnulib-tool options to use. -gnulib_tool_options=" - --no-changelog -" - -# bootstrap removes any macro-files that are not included by aclocal.m4, -# except for files listed in this variable that are always kept. -gnulib_precious=" - gnulib-tool.m4 -" - -# When truncating long commands for display, always allow at least this -# many characters before truncating. -min_cmd_len=160 - -# The command to download all .po files for a specified domain into -# a specified directory. Fill in the first %s is the domain name, and -# the second with the destination directory. Use rsync's -L and -r -# options because the latest/%s directory and the .po files within are -# all symlinks. -po_download_command_format=\ -"rsync --delete --exclude '*.s1' -Lrtvz \ -'translationproject.org::tp/latest/%s/' '%s'" - -# Other locale categories that need message catalogs. -extra_locale_categories= - -# Additional xgettext options to use. Gnulib might provide you with an -# extensive list of additional options to append to this, but gettext -# 0.16.1 and newer appends them automaticaly, so you can safely ignore -# the complaints from 'gnulib-tool' if your $configure_ac states: -# -# AM_GNU_GETTEXT_VERSION([0.16.1]) -xgettext_options=" - --flag=_:1:pass-c-format - --flag=N_:1:pass-c-format -" - -# Package copyright holder for gettext files. Defaults to FSF if unset. -copyright_holder= - -# File that should exist in the top directory of a checked out hierarchy, -# but not in a distribution tarball. -checkout_only_file= - -# Whether to use copies instead of symlinks by default (if set to true, -# the --copy option has no effect). -copy=false - -# Set this to ".cvsignore .gitignore" in 'bootstrap.conf' if you want -# those files to be generated in directories like 'lib/', 'm4/', and 'po/', -# or set it to "auto" to make this script select what to use based -# on what version control system (if any) is used in the source directory. -# Or set it to "none" to ignore VCS ignore files entirely. Default is -# "auto". -vc_ignore= - - -# List of slingshot files to link into stdlib tree before autotooling. -slingshot_files=$slingshot_files - -# Relative path to the local slingshot submodule, and url to the upsream -# git repository. If you have a slingshot entry in your .gitmodules file, -# these values are ignored. -slingshot_path=$slingshot_path -slingshot_url=$slingshot_url - -# NOTE: slingshot bootstrap will check rockspecs listed in $buildreq, -# according to the URL part of a specification triple ending in -# `.rockspec`. - - -## ------------------- ## -## External Libraries. ## -## ------------------- ## - -# Source required external libraries: -# Set a version string for this script. -scriptversion=2014-01-03.01; # UTC - -# General shell script boiler plate, and helper functions. -# Written by Gary V. Vaughan, 2004 - -# Copyright (C) 2004-2014 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. - -# As a special exception to the GNU General Public License, if you distribute -# this file as part of a program or library that is built using GNU Libtool, -# you may include this file under the same distribution terms that you use -# for the rest of that program. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# Evaluate this file near the top of your script to gain access to -# the functions and variables defined here: -# -# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh -# -# If you need to override any of the default environment variable -# settings, do that before evaluating this file. - - -## -------------------- ## -## Shell normalisation. ## -## -------------------- ## - -# Some shells need a little help to be as Bourne compatible as possible. -# Before doing anything else, make sure all that help has been provided! - -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac -fi - -# NLS nuisances: We save the old values in case they are required later. -_G_user_locale= -_G_safe_locale= -for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test set = \"\${$_G_var+set}\"; then - save_$_G_var=\$$_G_var - $_G_var=C - export $_G_var - _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" - _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" - fi" -done - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Make sure IFS has a sensible default -sp=' ' -nl=' -' -IFS="$sp $nl" - -# There are apparently some retarded systems that use ';' as a PATH separator! -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - - -## ------------------------- ## -## Locate command utilities. ## -## ------------------------- ## - - -# func_executable_p FILE -# ---------------------- -# Check that FILE is an executable regular file. -func_executable_p () -{ - test -f "$1" && test -x "$1" -} - - -# func_path_progs PROGS_LIST CHECK_FUNC [PATH] -# -------------------------------------------- -# Search for either a program that responds to --version with output -# containing "GNU", or else returned by CHECK_FUNC otherwise, by -# trying all the directories in PATH with each of the elements of -# PROGS_LIST. -# -# CHECK_FUNC should accept the path to a candidate program, and -# set $func_check_prog_result if it truncates its output less than -# $_G_path_prog_max characters. -func_path_progs () -{ - _G_progs_list=$1 - _G_check_func=$2 - _G_PATH=${3-"$PATH"} - - _G_path_prog_max=0 - _G_path_prog_found=false - _G_save_IFS=$IFS; IFS=$PATH_SEPARATOR - for _G_dir in $_G_PATH; do - IFS=$_G_save_IFS - test -z "$_G_dir" && _G_dir=. - for _G_prog_name in $_G_progs_list; do - for _exeext in '' .EXE; do - _G_path_prog=$_G_dir/$_G_prog_name$_exeext - func_executable_p "$_G_path_prog" || continue - case `"$_G_path_prog" --version 2>&1` in - *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; - *) $_G_check_func $_G_path_prog - func_path_progs_result=$func_check_prog_result - ;; - esac - $_G_path_prog_found && break 3 - done - done - done - IFS=$_G_save_IFS - test -z "$func_path_progs_result" && { - echo "no acceptable sed could be found in \$PATH" >&2 - exit 1 - } -} - - -# We want to be able to use the functions in this file before configure -# has figured out where the best binaries are kept, which means we have -# to search for them ourselves - except when the results are already set -# where we skip the searches. - -# Unless the user overrides by setting SED, search the path for either GNU -# sed, or the sed that truncates its output the least. -test -z "$SED" && { - _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for _G_i in 1 2 3 4 5 6 7; do - _G_sed_script=$_G_sed_script$nl$_G_sed_script - done - echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed - _G_sed_script= - - func_check_prog_sed () - { - _G_path_prog=$1 - - _G_count=0 - printf 0123456789 >conftest.in - while : - do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo '' >> conftest.nl - "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break - diff conftest.out conftest.nl >/dev/null 2>&1 || break - _G_count=`expr $_G_count + 1` - if test "$_G_count" -gt "$_G_path_prog_max"; then - # Best one so far, save it but keep looking for a better one - func_check_prog_result=$_G_path_prog - _G_path_prog_max=$_G_count - fi - # 10*(2^10) chars as input seems more than enough - test 10 -lt "$_G_count" && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out - } - - func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin - rm -f conftest.sed - SED=$func_path_progs_result -} - - -# Unless the user overrides by setting GREP, search the path for either GNU -# grep, or the grep that truncates its output the least. -test -z "$GREP" && { - func_check_prog_grep () - { - _G_path_prog=$1 - - _G_count=0 - _G_path_prog_max=0 - printf 0123456789 >conftest.in - while : - do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo 'GREP' >> conftest.nl - "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break - diff conftest.out conftest.nl >/dev/null 2>&1 || break - _G_count=`expr $_G_count + 1` - if test "$_G_count" -gt "$_G_path_prog_max"; then - # Best one so far, save it but keep looking for a better one - func_check_prog_result=$_G_path_prog - _G_path_prog_max=$_G_count - fi - # 10*(2^10) chars as input seems more than enough - test 10 -lt "$_G_count" && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out - } - - func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin - GREP=$func_path_progs_result -} - - -## ------------------------------- ## -## User overridable command paths. ## -## ------------------------------- ## - -# All uppercase variable names are used for environment variables. These -# variables can be overridden by the user before calling a script that -# uses them if a suitable command of that name is not already available -# in the command search PATH. - -: ${CP="cp -f"} -: ${ECHO="printf %s\n"} -: ${EGREP="$GREP -E"} -: ${FGREP="$GREP -F"} -: ${LN_S="ln -s"} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} - - -## -------------------- ## -## Useful sed snippets. ## -## -------------------- ## - -sed_dirname='s|/[^/]*$||' -sed_basename='s|^.*/||' - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s|\([`"$\\]\)|\\\1|g' - -# Same as above, but do not quote variable references. -sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' - -# Sed substitution that converts a w32 file name or path -# that contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-'\' parameter expansions in output of sed_double_quote_subst that -# were '\'-ed in input to the same. If an odd number of '\' preceded a -# '$' in input to sed_double_quote_subst, that '$' was protected from -# expansion. Since each input '\' is now two '\'s, look for any number -# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. -_G_bs='\\' -_G_bs2='\\\\' -_G_bs4='\\\\\\\\' -_G_dollar='\$' -sed_double_backslash="\ - s/$_G_bs4/&\\ -/g - s/^$_G_bs2$_G_dollar/$_G_bs&/ - s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g - s/\n//g" - - -## ----------------- ## -## Global variables. ## -## ----------------- ## - -# Except for the global variables explicitly listed below, the following -# functions in the '^func_' namespace, and the '^require_' namespace -# variables initialised in the 'Resource management' section, sourcing -# this file will not pollute your global namespace with anything -# else. There's no portable way to scope variables in Bourne shell -# though, so actually running these functions will sometimes place -# results into a variable named after the function, and often use -# temporary variables in the '^_G_' namespace. If you are careful to -# avoid using those namespaces casually in your sourcing script, things -# should continue to work as you expect. And, of course, you can freely -# overwrite any of the functions or variables defined here before -# calling anything to customize them. - -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -# Allow overriding, eg assuming that you follow the convention of -# putting '$debug_cmd' at the start of all your functions, you can get -# bash to show function call trace with: -# -# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name -debug_cmd=${debug_cmd-":"} -exit_cmd=: - -# By convention, finish your script with: -# -# exit $exit_status -# -# so that you can set exit_status to non-zero if you want to indicate -# something went wrong during execution without actually bailing out at -# the point of failure. -exit_status=$EXIT_SUCCESS - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath=$0 - -# The name of this program. -progname=`$ECHO "$progpath" |$SED "$sed_basename"` - -# Make sure we have an absolute progpath for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` - progdir=`cd "$progdir" && pwd` - progpath=$progdir/$progname - ;; - *) - _G_IFS=$IFS - IFS=${PATH_SEPARATOR-:} - for progdir in $PATH; do - IFS=$_G_IFS - test -x "$progdir/$progname" && break - done - IFS=$_G_IFS - test -n "$progdir" || progdir=`pwd` - progpath=$progdir/$progname - ;; -esac - - -## ----------------- ## -## Standard options. ## -## ----------------- ## - -# The following options affect the operation of the functions defined -# below, and should be set appropriately depending on run-time para- -# meters passed on the command line. - -opt_dry_run=false -opt_quiet=false -opt_verbose=false - -# Categories 'all' and 'none' are always available. Append any others -# you will pass as the first argument to func_warning from your own -# code. -warning_categories= - -# By default, display warnings according to 'opt_warning_types'. Set -# 'warning_func' to ':' to elide all warnings, or func_fatal_error to -# treat the next displayed warning as a fatal error. -warning_func=func_warn_and_continue - -# Set to 'all' to display all warnings, 'none' to suppress all -# warnings, or a space delimited list of some subset of -# 'warning_categories' to display only the listed warnings. -opt_warning_types=all - - -## -------------------- ## -## Resource management. ## -## -------------------- ## - -# This section contains definitions for functions that each ensure a -# particular resource (a file, or a non-empty configuration variable for -# example) is available, and if appropriate to extract default values -# from pertinent package files. Call them using their associated -# 'require_*' variable to ensure that they are executed, at most, once. -# -# It's entirely deliberate that calling these functions can set -# variables that don't obey the namespace limitations obeyed by the rest -# of this file, in order that that they be as useful as possible to -# callers. - - -# require_term_colors -# ------------------- -# Allow display of bold text on terminals that support it. -require_term_colors=func_require_term_colors -func_require_term_colors () -{ - $debug_cmd - - test -t 1 && { - # COLORTERM and USE_ANSI_COLORS environment variables take - # precedence, because most terminfo databases neglect to describe - # whether color sequences are supported. - test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} - - if test 1 = "$USE_ANSI_COLORS"; then - # Standard ANSI escape sequences - tc_reset='' - tc_bold=''; tc_standout='' - tc_red=''; tc_green='' - tc_blue=''; tc_cyan='' - else - # Otherwise trust the terminfo database after all. - test -n "`tput sgr0 2>/dev/null`" && { - tc_reset=`tput sgr0` - test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` - tc_standout=$tc_bold - test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` - test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` - test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` - test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` - test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` - } - fi - } - - require_term_colors=: -} - - -# require_rockspecs_req -# --------------------- -# Remove rockspecs from $buildreq, and add them to $rockspecs_req. -require_rockspecs_req=slingshot_require_rockspecs_req -slingshot_require_rockspecs_req () -{ - $debug_cmd - - test -n "$rockspecs_req" || { - _G_non_rockspecs= - - set dummy $buildreq; shift - - while test $# -gt 2; do - case $3 in - *.rockspec) - func_append rockspecs_req " $1 $2 $3" - ;; - [a-z]*://*) - func_append _G_non_rockspecs " $1 $2 $3" - ;; - *) func_fatal_error "\ -'$3' from the buildreq table in -'bootstrap.conf' does not look like the URL for downloading -$1. Please ensure that buildreq is a strict newline -delimited list of triples; 'program min-version url'." - ;; - esac - shift; shift; shift - done - - buildreq=$_G_non_rockspecs - } - - require_rockspecs_req=: -} - - -# require_slingshot_dotgitmodules -# ------------------------------- -# Ensure we have a '.gitmodules' file, with appropriate 'slingshot' settings. -require_slingshot_dotgitmodules=slingshot_require_slingshot_dotgitmodules -slingshot_require_slingshot_dotgitmodules () -{ - $debug_cmd - - $require_git - - test true = "$GIT" || { - # A slingshot entry in .gitmodules always takes precedence. - _G_path=`$GIT config --file .gitmodules submodule.slingshot.path 2>/dev/null` - - test -n "$_G_path" || { - $require_vc_ignore_files - - func_verbose "adding slingshot entries to '.gitmodules'" - - test -n "$slingshot_path" || slingshot_path=slingshot - test -n "$slingshot_url" || slingshot_url=git://github.com/gvvaughan/slingshot.git - - { - echo '[submodule "slingshot"]' - echo " path=$slingshot_path" - echo " url=$slingshot_url" - } >> .gitmodules - - test -n "$vc_ignore_files" \ - || func_insert_if_absent ".gitmodules" $vc_ignore_files - } - } - - require_slingshot_dotgitmodules=: -} - - -# require_slingshot_path -# require_slingshot_url -# ---------------------- -# Ensure 'slingshot_path' and 'slingshot_url' are set. -require_slingshot_path=slingshot_require_slingshot_dotgitmodules_parameters -require_slingshot_url=slingshot_require_slingshot_dotgitmodules_parameters -slingshot_require_slingshot_dotgitmodules_parameters () -{ - $debug_cmd - - $require_git - $require_slingshot_dotgitmodules - - test -f .gitmodules \ - || func_fatal_error "Unable to update '.gitmodules' with slingshot submodule" - - test true = "$GIT" || { - slingshot_path=`$GIT config --file=.gitmodules --get submodule.slingshot.path` - slingshot_url=`$GIT config --file=.gitmodules --get submodule.slingshot.url` - - func_verbose "slingshot_path='$slingshot_path'" - func_verbose "slingshot_url='$slingshot_url'" - } - - require_slingshot_path=: - require_slingshot_url=: -} - - -# require_slingshot_submodule -# --------------------------- -# Ensure that there is a current slingshot submodule. -require_slingshot_submodule=slingshot_require_slingshot_submodule -slingshot_require_slingshot_submodule () -{ - $debug_cmd - - $require_git - - if test true = "$GIT"; then - func_warning recommend \ - "No 'git' found; imported slingshot modules may be missing." - else - $require_slingshot_dotgitmodules - - if test -f .gitmodules; then - $require_slingshot_path - $require_slingshot_url - - if test -f "slingshot/src/mkrockspecs.in"; then - : All present and correct. - - else - trap slingshot_cleanup 1 2 13 15 - - shallow= - $GIT clone -h 2>&1 |func_grep_q -- --depth \ - && shallow='--depth 365' - - func_show_eval "$GIT clone $shallow '$slingshot_url' '$slingshot_path'" \ - slingshot_cleanup - - # FIXME: Solaris /bin/sh will try to execute '-' if any of - # these signals are caught after this. - trap - 1 2 13 15 - fi - - # Make sure we've checked out the correct revision of slingshot. - func_show_eval "$GIT submodule init -- $slingshot_path" \ - && func_show_eval "$GIT submodule update -- $slingshot_path" \ - || func_fatal_error "Unable to update slingshot submodule." - fi - fi - - require_slingshot_submodule=: -} - - -# require_bootstrap_uptodate -# -------------------------- -# Complain if the version of bootstrap in the build-aux directory differs -# from the one we are running. -require_bootstrap_uptodate=slingshot_require_bootstrap_uptodate -slingshot_require_bootstrap_uptodate () -{ - $debug_cmd - - $require_slingshot_submodule - - _G_slingshot_bootstrap=slingshot/bootstrap - - rm -f $progname.new - - if test -f "$_G_slingshot_bootstrap"; then - if func_cmp_s "$progpath" "$_G_slingshot_bootstrap"; then - func_verbose "bootstrap script up to date" - else - cp -f $_G_slingshot_bootstrap $progname.new - func_warning upgrade "\ -An updated slingshot bootstrap script is ready for you in -'$progname.new'. After you've verified that you want the -changes, you can update with: - mv -f $progname.new $progname - ./$progname - -Or you can disable this check permanently by adding the -following to 'bootstrap.conf': - require_bootstrap_uptodate=:" - fi - else - func_warning upgrade "\ -Your slingshot submodule appears to be damagedi, so I can't tell -whether your bootstrap has gone out of sync. Please check for -and undo any local changes, or revert to the slingshot revision -you were using previously, and rerun this script." - fi - - require_bootstrap_uptodate=: -} - - -# slingshot_cleanup -# ----------------- -# Recursively delete everything at $slingshot_path. -slingshot_cleanup () -{ - $debug_cmd - - $require_slingshot_path - - _G_status=$? - $RM -fr $slingshot_path - exit $_G_status -} - - -## ----------------- ## -## Function library. ## -## ----------------- ## - -# This section contains a variety of useful functions to call in your -# scripts. Take note of the portable wrappers for features provided by -# some modern shells, which will fall back to slower equivalents on -# less featureful shells. - - -# func_append VAR VALUE -# --------------------- -# Append VALUE onto the existing contents of VAR. - - # We should try to minimise forks, especially on Windows where they are - # unreasonably slow, so skip the feature probes when bash or zsh are - # being used: - if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then - : ${_G_HAVE_ARITH_OP="yes"} - : ${_G_HAVE_XSI_OPS="yes"} - # The += operator was introduced in bash 3.1 - case $BASH_VERSION in - [12].* | 3.0 | 3.0*) ;; - *) - : ${_G_HAVE_PLUSEQ_OP="yes"} - ;; - esac - fi - - # _G_HAVE_PLUSEQ_OP - # Can be empty, in which case the shell is probed, "yes" if += is - # useable or anything else if it does not work. - test -z "$_G_HAVE_PLUSEQ_OP" \ - && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ - && _G_HAVE_PLUSEQ_OP=yes - -if test yes = "$_G_HAVE_PLUSEQ_OP" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_append () - { - $debug_cmd - - eval "$1+=\$2" - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_append () - { - $debug_cmd - - eval "$1=\$$1\$2" - } -fi - - -# func_append_quoted VAR VALUE -# ---------------------------- -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -if test yes = "$_G_HAVE_PLUSEQ_OP"; then - eval 'func_append_quoted () - { - $debug_cmd - - func_quote_for_eval "$2" - eval "$1+=\\ \$func_quote_for_eval_result" - }' -else - func_append_quoted () - { - $debug_cmd - - func_quote_for_eval "$2" - eval "$1=\$$1\\ \$func_quote_for_eval_result" - } -fi - - -# func_append_uniq VAR VALUE -# -------------------------- -# Append unique VALUE onto the existing contents of VAR, assuming -# entries are delimited by the first character of VALUE. For example: -# -# func_append_uniq options " --another-option option-argument" -# -# will only append to $options if " --another-option option-argument " -# is not already present somewhere in $options already (note spaces at -# each end implied by leading space in second argument). -func_append_uniq () -{ - $debug_cmd - - eval _G_current_value='`$ECHO $'$1'`' - _G_delim=`expr "$2" : '\(.\)'` - - case $_G_delim$_G_current_value$_G_delim in - *"$2$_G_delim"*) ;; - *) func_append "$@" ;; - esac -} - - -# func_arith TERM... -# ------------------ -# Set func_arith_result to the result of evaluating TERMs. - test -z "$_G_HAVE_ARITH_OP" \ - && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ - && _G_HAVE_ARITH_OP=yes - -if test yes = "$_G_HAVE_ARITH_OP"; then - eval 'func_arith () - { - $debug_cmd - - func_arith_result=$(( $* )) - }' -else - func_arith () - { - $debug_cmd - - func_arith_result=`expr "$@"` - } -fi - - -# func_basename FILE -# ------------------ -# Set func_basename_result to FILE with everything up to and including -# the last / stripped. -if test yes = "$_G_HAVE_XSI_OPS"; then - # If this shell supports suffix pattern removal, then use it to avoid - # forking. Hide the definitions single quotes in case the shell chokes - # on unsupported syntax... - _b='func_basename_result=${1##*/}' - _d='case $1 in - */*) func_dirname_result=${1%/*}$2 ;; - * ) func_dirname_result=$3 ;; - esac' - -else - # ...otherwise fall back to using sed. - _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' - _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` - if test "X$func_dirname_result" = "X$1"; then - func_dirname_result=$3 - else - func_append func_dirname_result "$2" - fi' -fi - -eval 'func_basename () -{ - $debug_cmd - - '"$_b"' -}' - - -# func_dirname FILE APPEND NONDIR_REPLACEMENT -# ------------------------------------------- -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -eval 'func_dirname () -{ - $debug_cmd - - '"$_d"' -}' - - -# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT -# -------------------------------------------------------- -# Perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# For efficiency, we do not delegate to the functions above but instead -# duplicate the functionality here. -eval 'func_dirname_and_basename () -{ - $debug_cmd - - '"$_b"' - '"$_d"' -}' - - -# func_echo ARG... -# ---------------- -# Echo program name prefixed message. -func_echo () -{ - $debug_cmd - - _G_message=$* - - func_echo_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_IFS - $ECHO "$progname: $_G_line" - done - IFS=$func_echo_IFS -} - - -# func_echo_all ARG... -# -------------------- -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - - -# func_echo_infix_1 INFIX ARG... -# ------------------------------ -# Echo program name, followed by INFIX on the first line, with any -# additional lines not showing INFIX. -func_echo_infix_1 () -{ - $debug_cmd - - $require_term_colors - - _G_infix=$1; shift - _G_indent=$_G_infix - _G_prefix="$progname: $_G_infix: " - _G_message=$* - - # Strip color escape sequences before counting printable length - for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" - do - test -n "$_G_tc" && { - _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` - _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` - } - done - _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes - - func_echo_infix_1_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_infix_1_IFS - $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 - _G_prefix=$_G_indent - done - IFS=$func_echo_infix_1_IFS -} - - -# func_error ARG... -# ----------------- -# Echo program name prefixed message to standard error. -func_error () -{ - $debug_cmd - - $require_term_colors - - func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 -} - - -# func_fatal_error ARG... -# ----------------------- -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - $debug_cmd - - func_error "$*" - exit $EXIT_FAILURE -} - - -# func_grep EXPRESSION FILENAME -# ----------------------------- -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $debug_cmd - - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_len STRING -# --------------- -# Set func_len_result to the length of STRING. STRING may not -# start with a hyphen. - test -z "$_G_HAVE_XSI_OPS" \ - && (eval 'x=a/b/c; - test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ - && _G_HAVE_XSI_OPS=yes - -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_len () - { - $debug_cmd - - func_len_result=${#1} - }' -else - func_len () - { - $debug_cmd - - func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` - } -fi - - -# func_mkdir_p DIRECTORY-PATH -# --------------------------- -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - $debug_cmd - - _G_directory_path=$1 - _G_dir_list= - - if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then - - # Protect directory names starting with '-' - case $_G_directory_path in - -*) _G_directory_path=./$_G_directory_path ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$_G_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - _G_dir_list=$_G_directory_path:$_G_dir_list - - # If the last portion added has no slash in it, the list is done - case $_G_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` - done - _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` - - func_mkdir_p_IFS=$IFS; IFS=: - for _G_dir in $_G_dir_list; do - IFS=$func_mkdir_p_IFS - # mkdir can fail with a 'File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$_G_dir" 2>/dev/null || : - done - IFS=$func_mkdir_p_IFS - - # Bail out if we (or some other process) failed to create a directory. - test -d "$_G_directory_path" || \ - func_fatal_error "Failed to create '$1'" - fi -} - - -# func_mktempdir [BASENAME] -# ------------------------- -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, BASENAME is the basename for that directory. -func_mktempdir () -{ - $debug_cmd - - _G_template=${TMPDIR-/tmp}/${1-$progname} - - if test : = "$opt_dry_run"; then - # Return a directory name, but don't create it in dry-run mode - _G_tmpdir=$_G_template-$$ - else - - # If mktemp works, use that first and foremost - _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` - - if test ! -d "$_G_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - _G_tmpdir=$_G_template-${RANDOM-0}$$ - - func_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$_G_tmpdir" - umask $func_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$_G_tmpdir" || \ - func_fatal_error "cannot create temporary directory '$_G_tmpdir'" - fi - - $ECHO "$_G_tmpdir" -} - - -# func_normal_abspath PATH -# ------------------------ -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -func_normal_abspath () -{ - $debug_cmd - - # These SED scripts presuppose an absolute path with a trailing slash. - _G_pathcar='s|^/\([^/]*\).*$|\1|' - _G_pathcdr='s|^/[^/]*||' - _G_removedotparts=':dotsl - s|/\./|/|g - t dotsl - s|/\.$|/|' - _G_collapseslashes='s|/\{1,\}|/|g' - _G_finalslash='s|/*$|/|' - - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` - while :; do - # Processed it all yet? - if test / = "$func_normal_abspath_tpath"; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result"; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - - -# func_notquiet ARG... -# -------------------- -# Echo program name prefixed message only when not in quiet mode. -func_notquiet () -{ - $debug_cmd - - $opt_quiet || func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - - -# func_relative_path SRCDIR DSTDIR -# -------------------------------- -# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. -func_relative_path () -{ - $debug_cmd - - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=$func_dirname_result - if test -z "$func_relative_path_tlibdir"; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done - - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test -n "$func_stripname_result"; then - func_append func_relative_path_result "/$func_stripname_result" - fi - - # Normalisation. If bindir is libdir, return '.' else relative path. - if test -n "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - fi - - test -n "$func_relative_path_result" || func_relative_path_result=. - - : -} - - -# func_quote_for_eval ARG... -# -------------------------- -# Aesthetically quote ARGs to be evaled later. -# This function returns two values: -# i) func_quote_for_eval_result -# double-quoted, suitable for a subsequent eval -# ii) func_quote_for_eval_unquoted_result -# has all characters that are still active within double -# quotes backslashified. -func_quote_for_eval () -{ - $debug_cmd - - func_quote_for_eval_unquoted_result= - func_quote_for_eval_result= - while test 0 -lt $#; do - case $1 in - *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; - *) - _G_unquoted_arg=$1 ;; - esac - if test -n "$func_quote_for_eval_unquoted_result"; then - func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" - else - func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" - fi - - case $_G_unquoted_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and variable expansion - # for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_quoted_arg=\"$_G_unquoted_arg\" - ;; - *) - _G_quoted_arg=$_G_unquoted_arg - ;; - esac - - if test -n "$func_quote_for_eval_result"; then - func_append func_quote_for_eval_result " $_G_quoted_arg" - else - func_append func_quote_for_eval_result "$_G_quoted_arg" - fi - shift - done -} - - -# func_quote_for_expand ARG -# ------------------------- -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - $debug_cmd - - case $1 in - *[\\\`\"]*) - _G_arg=`$ECHO "$1" | $SED \ - -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; - *) - _G_arg=$1 ;; - esac - - case $_G_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_arg=\"$_G_arg\" - ;; - esac - - func_quote_for_expand_result=$_G_arg -} - - -# func_stripname PREFIX SUFFIX NAME -# --------------------------------- -# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_stripname () - { - $debug_cmd - - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary variable first. - func_stripname_result=$3 - func_stripname_result=${func_stripname_result#"$1"} - func_stripname_result=${func_stripname_result%"$2"} - }' -else - func_stripname () - { - $debug_cmd - - case $2 in - .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; - *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; - esac - } -fi - - -# func_show_eval CMD [FAIL_EXP] -# ----------------------------- -# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - $debug_cmd - - _G_cmd=$1 - _G_fail_exp=${2-':'} - - func_quote_for_expand "$_G_cmd" - eval "func_notquiet $func_quote_for_expand_result" - - $opt_dry_run || { - eval "$_G_cmd" - _G_status=$? - if test 0 -ne "$_G_status"; then - eval "(exit $_G_status); $_G_fail_exp" - fi - } -} - - -# func_show_eval_locale CMD [FAIL_EXP] -# ------------------------------------ -# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - $debug_cmd - - _G_cmd=$1 - _G_fail_exp=${2-':'} - - $opt_quiet || { - func_quote_for_expand "$_G_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - $opt_dry_run || { - eval "$_G_user_locale - $_G_cmd" - _G_status=$? - eval "$_G_safe_locale" - if test 0 -ne "$_G_status"; then - eval "(exit $_G_status); $_G_fail_exp" - fi - } -} - - -# func_tr_sh -# ---------- -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - $debug_cmd - - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} - - -# func_verbose ARG... -# ------------------- -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $debug_cmd - - $opt_verbose && func_echo "$*" - - : -} - - -# func_warn_and_continue ARG... -# ----------------------------- -# Echo program name prefixed warning message to standard error. -func_warn_and_continue () -{ - $debug_cmd - - $require_term_colors - - func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 -} - - -# func_warning CATEGORY ARG... -# ---------------------------- -# Echo program name prefixed warning message to standard error. Warning -# messages can be filtered according to CATEGORY, where this function -# elides messages where CATEGORY is not listed in the global variable -# 'opt_warning_types'. -func_warning () -{ - $debug_cmd - - # CATEGORY must be in the warning_categories list! - case " $warning_categories " in - *" $1 "*) ;; - *) func_internal_error "invalid warning category '$1'" ;; - esac - - _G_category=$1 - shift - - case " $opt_warning_types " in - *" $_G_category "*) $warning_func ${1+"$@"} ;; - esac -} - - -# func_sort_ver VER1 VER2 -# ----------------------- -# 'sort -V' is not generally available. -# Note this deviates from the version comparison in automake -# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a -# but this should suffice as we won't be specifying old -# version formats or redundant trailing .0 in bootstrap.conf. -# If we did want full compatibility then we should probably -# use m4_version_compare from autoconf. -func_sort_ver () -{ - $debug_cmd - - printf '%s\n%s\n' "$1" "$2" \ - | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n -} - -# func_lt_ver PREV CURR -# --------------------- -# Return true if PREV and CURR are in the correct order according to -# func_sort_ver, otherwise false. Use it like this: -# -# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." -func_lt_ver () -{ - $debug_cmd - - test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` -} - - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: -#! /bin/sh - -# Set a version string for this script. -scriptversion=2014-01-07.03; # UTC - -# A portable, pluggable option parser for Bourne shell. -# Written by Gary V. Vaughan, 2010 - -# Copyright (C) 2010-2014 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# This file is a library for parsing options in your shell scripts along -# with assorted other useful supporting features that you can make use -# of too. -# -# For the simplest scripts you might need only: -# -# #!/bin/sh -# . relative/path/to/funclib.sh -# . relative/path/to/options-parser -# scriptversion=1.0 -# func_options ${1+"$@"} -# eval set dummy "$func_options_result"; shift -# ...rest of your script... -# -# In order for the '--version' option to work, you will need to have a -# suitably formatted comment like the one at the top of this file -# starting with '# Written by ' and ending with '# warranty; '. -# -# For '-h' and '--help' to work, you will also need a one line -# description of your script's purpose in a comment directly above the -# '# Written by ' line, like the one at the top of this file. -# -# The default options also support '--debug', which will turn on shell -# execution tracing (see the comment above debug_cmd below for another -# use), and '--verbose' and the func_verbose function to allow your script -# to display verbose messages only when your user has specified -# '--verbose'. -# -# After sourcing this file, you can plug processing for additional -# options by amending the variables from the 'Configuration' section -# below, and following the instructions in the 'Option parsing' -# section further down. - -## -------------- ## -## Configuration. ## -## -------------- ## - -# You should override these variables in your script after sourcing this -# file so that they reflect the customisations you have added to the -# option parser. - -# The usage line for option parsing errors and the start of '-h' and -# '--help' output messages. You can embed shell variables for delayed -# expansion at the time the message is displayed, but you will need to -# quote other shell meta-characters carefully to prevent them being -# expanded when the contents are evaled. -usage='$progpath [OPTION]...' - -# Short help message in response to '-h' and '--help'. Add to this or -# override it after sourcing this library to reflect the full set of -# options your script accepts. -usage_message="\ - --debug enable verbose shell tracing - -W, --warnings=CATEGORY - report the warnings falling in CATEGORY [all] - -v, --verbose verbosely report processing - --version print version information and exit - -h, --help print short or long help message and exit -" - -# Additional text appended to 'usage_message' in response to '--help'. -long_help_message=" -Warning categories include: - 'all' show all warnings - 'none' turn off all the warnings - 'error' warnings are treated as fatal errors" - -# Help message printed before fatal option parsing errors. -fatal_help="Try '\$progname --help' for more information." - - - -## ------------------------- ## -## Hook function management. ## -## ------------------------- ## - -# This section contains functions for adding, removing, and running hooks -# to the main code. A hook is just a named list of of function, that can -# be run in order later on. - -# func_hookable FUNC_NAME -# ----------------------- -# Declare that FUNC_NAME will run hooks added with -# 'func_add_hook FUNC_NAME ...'. -func_hookable () -{ - $debug_cmd - - func_append hookable_fns " $1" -} - - -# func_add_hook FUNC_NAME HOOK_FUNC -# --------------------------------- -# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must -# first have been declared "hookable" by a call to 'func_hookable'. -func_add_hook () -{ - $debug_cmd - - case " $hookable_fns " in - *" $1 "*) ;; - *) func_fatal_error "'$1' does not accept hook functions." ;; - esac - - eval func_append ${1}_hooks '" $2"' -} - - -# func_remove_hook FUNC_NAME HOOK_FUNC -# ------------------------------------ -# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. -func_remove_hook () -{ - $debug_cmd - - eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' -} - - -# func_run_hooks FUNC_NAME [ARG]... -# --------------------------------- -# Run all hook functions registered to FUNC_NAME. -# It is assumed that the list of hook functions contains nothing more -# than a whitespace-delimited list of legal shell function names, and -# no effort is wasted trying to catch shell meta-characters or preserve -# whitespace. -func_run_hooks () -{ - $debug_cmd - - case " $hookable_fns " in - *" $1 "*) ;; - *) func_fatal_error "'$1' does not support hook funcions.n" ;; - esac - - eval _G_hook_fns=\$$1_hooks; shift - - for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' - - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift - done - - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result -} - - - -## --------------- ## -## Option parsing. ## -## --------------- ## - -# In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, remove any -# options that you action, and then pass back the remaining unprocessed -# options in '_result', escaped suitably for -# 'eval'. Like this: -# -# my_options_prep () -# { -# $debug_cmd -# -# # Extend the existing usage message. -# usage_message=$usage_message' -# -s, --silent don'\''t print informational messages -# ' -# -# func_quote_for_eval ${1+"$@"} -# my_options_prep_result=$func_quote_for_eval_result -# } -# func_add_hook func_options_prep my_options_prep -# -# -# my_silent_option () -# { -# $debug_cmd -# -# # Note that for efficiency, we parse as many options as we can -# # recognise in a loop before passing the remainder back to the -# # caller on the first unrecognised argument we encounter. -# while test $# -gt 0; do -# opt=$1; shift -# case $opt in -# --silent|-s) opt_silent=: ;; -# # Separate non-argument short options: -# -s*) func_split_short_opt "$_G_opt" -# set dummy "$func_split_short_opt_name" \ -# "-$func_split_short_opt_arg" ${1+"$@"} -# shift -# ;; -# *) set dummy "$_G_opt" "$*"; shift; break ;; -# esac -# done -# -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result -# } -# func_add_hook func_parse_options my_silent_option -# -# -# my_option_validation () -# { -# $debug_cmd -# -# $opt_silent && $opt_verbose && func_fatal_help "\ -# '--silent' and '--verbose' options are mutually exclusive." -# -# func_quote_for_eval ${1+"$@"} -# my_option_validation_result=$func_quote_for_eval_result -# } -# func_add_hook func_validate_options my_option_validation -# -# You'll alse need to manually amend $usage_message to reflect the extra -# options you parse. It's preferable to append if you can, so that -# multiple option parsing hooks can be added safely. - - -# func_options [ARG]... -# --------------------- -# All the functions called inside func_options are hookable. See the -# individual implementations for details. -func_hookable func_options -func_options () -{ - $debug_cmd - - func_options_prep ${1+"$@"} - eval func_parse_options \ - ${func_options_prep_result+"$func_options_prep_result"} - eval func_validate_options \ - ${func_parse_options_result+"$func_parse_options_result"} - - eval func_run_hooks func_options \ - ${func_validate_options_result+"$func_validate_options_result"} - - # save modified positional parameters for caller - func_options_result=$func_run_hooks_result -} - - -# func_options_prep [ARG]... -# -------------------------- -# All initialisations required before starting the option parse loop. -# Note that when calling hook functions, we pass through the list of -# positional parameters. If a hook function modifies that list, and -# needs to propogate that back to rest of this script, then the complete -# modified list must be put in 'func_run_hooks_result' before -# returning. -func_hookable func_options_prep -func_options_prep () -{ - $debug_cmd - - # Option defaults: - opt_verbose=false - opt_warning_types= - - func_run_hooks func_options_prep ${1+"$@"} - - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result -} - - -# func_parse_options [ARG]... -# --------------------------- -# The main option parsing loop. -func_hookable func_parse_options -func_parse_options () -{ - $debug_cmd - - func_parse_options_result= - - # this just eases exit handling - while test $# -gt 0; do - # Defer to hook functions for initial option parsing, so they - # get priority in the event of reusing an option name. - func_run_hooks func_parse_options ${1+"$@"} - - # Adjust func_parse_options positional parameters to match - eval set dummy "$func_run_hooks_result"; shift - - # Break out of the loop if we already parsed every option. - test $# -gt 0 || break - - _G_opt=$1 - shift - case $_G_opt in - --debug|-x) debug_cmd='set -x' - func_echo "enabling shell trace mode" - $debug_cmd - ;; - - --no-warnings|--no-warning|--no-warn) - set dummy --warnings none ${1+"$@"} - shift - ;; - - --warnings|--warning|-W) - test $# = 0 && func_missing_arg $_G_opt && break - case " $warning_categories $1" in - *" $1 "*) - # trailing space prevents matching last $1 above - func_append_uniq opt_warning_types " $1" - ;; - *all) - opt_warning_types=$warning_categories - ;; - *none) - opt_warning_types=none - warning_func=: - ;; - *error) - opt_warning_types=$warning_categories - warning_func=func_fatal_error - ;; - *) - func_fatal_error \ - "unsupported warning category: '$1'" - ;; - esac - shift - ;; - - --verbose|-v) opt_verbose=: ;; - --version) func_version ;; - -\?|-h) func_usage ;; - --help) func_help ;; - - # Separate optargs to long options (plugins may need this): - --*=*) func_split_equals "$_G_opt" - set dummy "$func_split_equals_lhs" \ - "$func_split_equals_rhs" ${1+"$@"} - shift - ;; - - # Separate optargs to short options: - -W*) - func_split_short_opt "$_G_opt" - set dummy "$func_split_short_opt_name" \ - "$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-v*|-x*) - func_split_short_opt "$_G_opt" - set dummy "$func_split_short_opt_name" \ - "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; - esac - done - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result -} - - -# func_validate_options [ARG]... -# ------------------------------ -# Perform any sanity checks on option settings and/or unconsumed -# arguments. -func_hookable func_validate_options -func_validate_options () -{ - $debug_cmd - - # Display all warnings if -W was not given. - test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - - func_run_hooks func_validate_options ${1+"$@"} - - # Bail if the options were screwed! - $exit_cmd $EXIT_FAILURE - - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result -} - - - - -# slingshot_options_prep -# ---------------------- -# Preparation for additional slingshot option parsing. -slingshot_options_prep () -{ - $debug_cmd - - # Option defaults: - opt_skip_rock_checks=false - # opt_luarocks_tree default in *unset*! - - # Extend the existing usage message. - usage_message=$usage_message' -Slingshot Options: - - --luarocks-tree=DIR - check a non-default tree for prerequisite rocks - --skip-rock-checks - ignore Lua rocks in bootstrap.conf:buildreq' - - func_quote_for_eval ${1+"$@"} - slingshot_options_prep_result=$func_quote_for_eval_result -} -func_add_hook func_options_prep slingshot_options_prep - - -# slingshot_parse_options OPT... -# ------------------------------ -# Called at the end of each main option parse loop to process any -# additional slingshot options. -slingshot_parse_options () -{ - $debug_cmd - - # Perform our own loop to consume as many options as possible in - # each iteration. - while test $# -gt 0; do - _G_opt=$1 - shift - case $_G_opt in - --luarocks-tree) - test $# = 0 && func_missing_arg $_G_opt && break - opt_luarocks_tree=$1 - shift - ;; - - --skip-rock-checks) - opt_skip_rock_checks=: - ;; - - # Separate optargs to long options (plugins may need this): - --*=*) func_split_equals "$_G_opt" - set dummy "$func_split_equals_lhs" \ - "$func_split_equals_rhs" ${1+"$@"} - shift - ;; - - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; - esac - done - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - slingshot_parse_options_result=$func_quote_for_eval_result -} -func_add_hook func_parse_options slingshot_parse_options - - -# slingshot_option_validation -# --------------------------- -# Flag any inconsistencies in users' selection of slingshot options. -slingshot_option_validation () -{ - $debug_cmd - - test -z "$opt_luarocks_tree" \ - || test -d "$opt_luarocks_tree" \ - || func_fatal_help "$opt_luarocks_tree: not a directory" -} -func_add_hook func_validate_options slingshot_option_validation - - -## ----------------- ## -## Helper functions. ## -## ----------------- ## - -# This section contains the helper functions used by the rest of the -# hookable option parser framework in ascii-betical order. - - -# func_fatal_help ARG... -# ---------------------- -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - $debug_cmd - - eval \$ECHO \""Usage: $usage"\" - eval \$ECHO \""$fatal_help"\" - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - - -# func_help -# --------- -# Echo long help message to standard output and exit. -func_help () -{ - $debug_cmd - - func_usage_message - $ECHO "$long_help_message" - exit 0 -} - - -# func_missing_arg ARGNAME -# ------------------------ -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - $debug_cmd - - func_error "Missing argument for '$1'." - exit_cmd=exit -} - - -# func_split_equals STRING -# ------------------------ -# Set func_split_equals_lhs and func_split_equals_rhs shell variables after -# splitting STRING at the '=' sign. -test -z "$_G_HAVE_XSI_OPS" \ - && (eval 'x=a/b/c; - test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ - && _G_HAVE_XSI_OPS=yes - -if test yes = "$_G_HAVE_XSI_OPS" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_split_equals () - { - $debug_cmd - - func_split_equals_lhs=${1%%=*} - func_split_equals_rhs=${1#*=} - test "x$func_split_equals_lhs" = "x$1" \ - && func_split_equals_rhs= - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_split_equals () - { - $debug_cmd - - func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` - func_split_equals_rhs= - test "x$func_split_equals_lhs" = "x$1" \ - || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` - } -fi #func_split_equals - - -# func_split_short_opt SHORTOPT -# ----------------------------- -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -if test yes = "$_G_HAVE_XSI_OPS" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_split_short_opt () - { - $debug_cmd - - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"} - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_split_short_opt () - { - $debug_cmd - - func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` - func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` - } -fi #func_split_short_opt - - -# func_usage -# ---------- -# Echo short help message to standard output and exit. -func_usage () -{ - $debug_cmd - - func_usage_message - $ECHO "Run '$progname --help |${PAGER-more}' for full usage" - exit 0 -} - - -# func_usage_message -# ------------------ -# Echo short help message to standard output. -func_usage_message () -{ - $debug_cmd - - eval \$ECHO \""Usage: $usage"\" - echo - $SED -n 's|^# || - /^Written by/{ - x;p;x - } - h - /^Written by/q' < "$progpath" - echo - eval \$ECHO \""$usage_message"\" -} - - -# func_version -# ------------ -# Echo version message to standard output and exit. -func_version () -{ - $debug_cmd - - printf '%s\n' "$progname $scriptversion" - $SED -n ' - /(C)/!b go - :more - /\./!{ - N - s|\n# | | - b more - } - :go - /^# Written by /,/# warranty; / { - s|^# || - s|^# *$|| - s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| - p - } - /^# Written by / { - s|^# || - p - } - /^warranty; /q' < "$progpath" - - exit $? -} - - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: -#! /bin/sh - -# Extract macro arguments from autotools input with GNU M4. -# Written by Gary V. Vaughan, 2010 -# -# Copyright (C) 2010-2014 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# Make sure we've evaluated scripts we depend on. -test -z "$progpath" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/funclib.sh -test extract-trace = "$progname" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/options-parser - -# Set a version string. -scriptversion=2014-12-03.16; # UTC - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. - - -# slingshot_copy FILENAME SRCDIR DESTDIR -# -------------------------------------- -# If option '--copy' was specified, or soft-linking SRCFILE to DESTFILE -# fails, then try to copy SRCFILE to DESTFILE (making sure to update the -# timestamp so that a series of files with dependencies can be copied -# in the right order that their timestamps won't trigger rebuilds). -slingshot_copy () -{ - $debug_cmd - - slingshot_srcfile=`echo "$2/$1" |sed -e 's|/\./|/|g'` - slingshot_destfile=`echo "$3/$1" |sed -e 's|/\./|/|g'` - - $opt_force || { - # Nothing to do if the files are already identical. - if func_cmp_s "$slingshot_srcfile" "$slingshot_destfile"; then - func_verbose "'$slingshot_destfile' is up to date." - return 0 - fi - } - - # Require --force to remove existing $slingshot_destfile. - $opt_force && $RM "$slingshot_destfile" - test -f "$slingshot_destfile" && { - func_warn_and_continue "'$slingshot_destfile' exists: use '--force' to overwrite" - return 0 - } - - # Be careful to support 'func_copy dir/target srcbase destbase'. - func_dirname "$slingshot_destfile" - func_mkdir_p "$func_dirname_result" - - # Copy or link according to '--copy' option. - if $opt_copy; then - slingshot_copycmd=$CP - slingshot_copy_type=copying - else - slingshot_copycmd=$LN_S - slingshot_copy_type=linking - - func_relative_path "$3" "$2" - slingshot_srcfile=$func_relative_path_result/$1 - fi - slingshot_copy_msg="$slingshot_copy_type file '$slingshot_destfile'" - $opt_verbose && \ - slingshot_copy_msg="$slingshot_copy_type $slingshot_srcfile $3" - - if $opt_dry_run || { - ( umask 0 - $slingshot_copycmd "$slingshot_srcfile" "$slingshot_destfile" - ) >/dev/null 2>&1 - } - then - echo "$slingshot_copy_msg" - else - func_error "$slingshot_copy_type '$2/$1' to '$3/' failed" - return 1 - fi -} - - -# slingshot_rockspec_error -# ------------------------ -# Called by zile_check_rockspecs for missing rocks. -slingshot_rockspec_error () -{ - $debug_cmd - - _G_strippedver=`expr "$_G_reqver" : '=*\(.*\)'` - func_error "\ -Prerequisite LuaRock '$_G_rock $_G_strippedver' not found. Please install it." - - rockspecs_uptodate_result=false -} - - -## ------ ## -## Usage. ## -## ------ ## - -# Run './extract-trace --help' for help with using this script from the -# command line. -# -# Or source first 'options-parser' and then this file into your own -# scripts in order to make use of the function and variable framework -# they define, and also to avoid the overhead of forking to run this -# script in its own process on every call. - - - -## ----------------- ## -## Helper functions. ## -## ----------------- ## - -# This section contains the helper functions used by the rest of -# 'extract-trace'. - - -# func_autoconf_configure MAYBE-CONFIGURE-FILE -# -------------------------------------------- -# Ensure that MAYBE-CONFIGURE-FILE is the name of a file in the current -# directory that contains an uncommented call to AC_INIT. -func_autoconf_configure () -{ - $debug_cmd - - _G_sed_no_comment=' - s|#.*$|| - s|^dnl .*$|| - s| dnl .*$||' - _G_ac_init= - - # If we were passed a genuine file, make sure it calls AC_INIT. - test -f "$1" \ - && _G_ac_init=`$SED "$_G_sed_no_comment" "$1" |$GREP AC_INIT` - - # Otherwise it is not a genuine Autoconf input file. - test -n "$_G_ac_init" - _G_status=$? - - test 0 -ne "$_G_status" \ - && func_verbose "'$1' not using Autoconf" - - (exit $_G_status) -} - - -# func_tool_version_output CMD [FATAL-ERROR-MSG] -# ---------------------------------------------- -# Attempt to run 'CMD --version', discarding errors. The output can be -# ignored by redirecting stdout, and this function used simply to test -# whether the command exists and exits normally when passed a -# '--version' argument. -# When FATAL-ERROR-MSG is given, then this function will display the -# message and exit if running 'CMD --version' returns a non-zero exit -# status. -func_tool_version_output () -{ - $debug_cmd - - _G_cmd=$1 - _G_fatal_error_msg=$2 - - # Some tools, like 'git2cl' produce thousands of lines of output - # unless stdin is /dev/null - in that case we want to return - # successfully without saving all of that output. Other tools, - # such as 'help2man' exit with a non-zero status when stdin comes - # from /dev/null, so we re-execute without /dev/null if that - # happens. This means that occasionally, the output from both calls - # ends up in the result, but the alternative would be to discard the - # output from one call, and hope the other produces something useful. - { $_G_cmd --version /dev/null - _G_status=$? - - test 0 -ne "$_G_status" && test -n "$_G_fatal_error_msg" \ - && func_fatal_error "$_G_fatal_error_msg" - - (exit $_G_status) -} - - -# func_tool_version_number CMD [FATAL-ERROR-MSG] -# ---------------------------------------------- -# Pass arguments to func_tool_version_output, but set -# $func_tool_version_number_result to the last dot delimited digit string -# on the first line of output. -func_tool_version_number () -{ - $debug_cmd - - _G_verout=`func_tool_version_output "$@"` - _G_status=$? - - # A version number starts with a digit following a space on the first - # line of output from `--version`. - _G_verout=`echo "$_G_verout" |sed 1q` - if test -n "$_G_verout"; then - _G_vernum=`expr "$_G_verout" : '.* \([0-9][^ ]*\)'` - fi - - if test -n "$_G_vernum"; then - printf '%s\n' "$_G_vernum" - else - printf '%s\n' "$_G_verout" - fi - - (exit $_G_status) -} - - -# func_find_tool ENVVAR NAMES... -# ------------------------------ -# Search for a required program. Use the value of ENVVAR, if set, -# otherwise find the first of the NAMES that can be run (i.e., -# supports --version). If found, set ENVVAR to the program name, -# die otherwise. -func_find_tool () -{ - $debug_cmd - - _G_find_tool_envvar=$1 - shift - _G_find_tool_names=$@ - eval "_G_find_tool_res=\$$_G_find_tool_envvar" - if test -n "$_G_find_tool_res"; then - _G_find_tool_error_prefix="\$$find_tool_envvar: " - else - _G_find_tool_res= - _G_bestver= - for _G_prog - do - _G_find_tool_save_IFS=$IFS - IFS=: - for _G_dir in $PATH; do - IFS=$_G_find_tool_save_IFS - _G_progpath=$_G_dir/$_G_prog - test -r "$_G_progpath" && { - _G_curver=`func_tool_version_number $_G_progpath` - case $_G_bestver,$_G_curver in - ,) - # first non--version responsive prog sticks! - test -n "$_G_progpath" || _G_find_tool_res=$_G_progpath - ;; - ,*) - # first --version responsive prog beats non--version responsive! - _G_find_tool_res=$_G_progpath - _G_bestver=$_G_curver - ;; - *,*) - # another --version responsive prog must be newer to beat previous one! - test "x$_G_curver" = "x$_G_bestver" \ - || func_lt_ver "$_G_curver" "$_G_bestver" \ - || { - _G_find_tool_res=$_G_progpath - _G_bestver=$_G_curver - } - ;; - esac - } - done - IFS=$_G_find_tool_save_IFS - done - fi - if test -n "$_G_find_tool_res"; then - func_tool_version_number >/dev/null $_G_find_tool_res "\ -${_G_find_tool_error_prefix}Cannot run '$_G_find_tool_res --version'" - - # Make sure the result is exported to the environment for children - # to use. - eval "$_G_find_tool_envvar=\$_G_find_tool_res" - eval "export $_G_find_tool_envvar" - else - func_error "\ -One of these is required: - $_G_find_tool_names" - fi -} - - - -## -------------------- ## -## Resource management. ## -## -------------------- ## - -# This section contains definitions for functions that each ensure a -# particular resource (a file, or a non-empty configuration variable for -# example) is available, and if appropriate to extract default values -# from pertinent package files. Where a variable already has a non- -# empty value (as set by the package's 'bootstrap.conf'), that value is -# used in preference to deriving the default. Call them using their -# associated 'require_*' variable to ensure that they are executed, at -# most, once. -# -# It's entirely deliberate that calling these functions can set -# variables that don't obey the namespace limitations obeyed by the rest -# of this file, in order that that they be as useful as possible to -# callers. - - -# require_configure_ac -# -------------------- -# Ensure that there is a 'configure.ac' or 'configure.in' file in the -# current directory that contains an uncommented call to AC_INIT, and -# that '$configure_ac' contains its name. -require_configure_ac=func_require_configure_ac -func_require_configure_ac () -{ - $debug_cmd - - test -z "$configure_ac" \ - && func_autoconf_configure configure.ac && configure_ac=configure.ac - test -z "$configure_ac" \ - && func_autoconf_configure configure.in && configure_ac=configure.in - test -z "$configure_ac" \ - || func_verbose "found '$configure_ac'" - - require_configure_ac=: -} - - -# require_gnu_m4 -# -------------- -# Search for GNU M4, and export it in $M4. -require_gnu_m4=func_require_gnu_m4 -func_require_gnu_m4 () -{ - $debug_cmd - - test -n "$M4" || { - # Find the first m4 binary that responds to --version. - func_find_tool M4 gm4 gnum4 m4 - } - - test -n "$M4" || func_fatal_error "\ -Please install GNU M4, or 'export M4=/path/to/gnu/m4'." - - func_verbose "export M4='$M4'" - - # Make sure the search result is visible to subshells - export M4 - - require_gnu_m4=: -} - - -## --------------- ## -## Core functions. ## -## --------------- ## - -# This section contains the high level functions used when calling this -# file as a script. 'func_extract_trace' is probably the only one that you -# won't want to replace if you source this file into your own script. - - -# func_extract_trace MACRO_NAMES [FILENAME]... -# -------------------------------------------- -# set '$func_extract_trace_result' to a colon delimited list of arguments -# to any of the comma separated list of MACRO_NAMES in FILENAME. If no -# FILENAME is given, then '$configure_ac' is assumed. -func_extract_trace () -{ - $debug_cmd - - $require_configure_ac - $require_gnu_m4 - - _G_m4_traces=`$ECHO "--trace=$1" |$SED 's%,% --trace=%g'` - _G_re_macros=`$ECHO "($1)" |$SED 's%,%|%g'` - _G_macros="$1"; shift - test $# -gt 0 || { - set dummy $configure_ac - shift - } - - # Generate an error if the first file is missing - <"$1" - - # Sadly, we can't use 'autom4te' tracing to extract macro arguments, - # because it complains about things we want to ignore at bootstrap - # time - like missing m4_include files; AC_PREREQ being newer than - # the installed autoconf; and returns nothing when tracing - # 'AM_INIT_AUTOMAKE' when aclocal hasn't been generated yet. - # - # The following tries to emulate a less persnickety version of (and - # due to not having to wait for Perl startup on every invocation, - # it's probably faster too): - # - # autom4te --language=Autoconf --trace=$my_macro:\$% "$@" - # - # First we give a minimal set of macro declarations to M4 to prime - # it for reading Autoconf macros, while still providing some of the - # functionality generally used at m4-time to supply dynamic - # arguments to Autocof functions, but without following - # 'm4_s?include' files. - _G_mini=' - # Initialisation. - m4_changequote([,]) - m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))]) - m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])]) - - # Disable these macros. - m4_undefine([m4_dnl]) - m4_undefine([m4_include]) - m4_undefine([m4_m4exit]) - m4_undefine([m4_m4wrap]) - m4_undefine([m4_maketemp]) - - # Copy and rename macros not handled by "m4 --prefix". - m4_define([dnl], [m4_builtin([dnl])]) - m4_copy([m4_define], [m4_defun]) - m4_rename([m4_ifelse], [m4_if]) - m4_ifdef([m4_mkstemp], [m4_undefine([m4_mkstemp])]) - m4_rename([m4_patsubst], [m4_bpatsubst]) - m4_rename([m4_regexp], [m4_bregexp]) - - # "m4sugar.mini" - useful m4-time macros for dynamic arguments. - # If we discover packages that need more m4 macros defined in - # order to bootstrap correctly, add them here: - m4_define([m4_bmatch], - [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2], - [m4_if(m4_bregexp([$1], [$2]), -1, - [$0([$1], m4_shift3($@))], [$3])])]) - m4_define([m4_ifndef], [m4_ifdef([$1], [$3], [$2])]) - m4_define([m4_ifset], - [m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])]) - m4_define([m4_require], [$1]) - m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))]) - - # "autoconf.mini" - things from autoconf macros we care about. - m4_copy([m4_defun], [AC_DEFUN]) - - # Dummy definitions for the macros we want to trace. - # AM_INIT_AUTOMAKE at least produces no trace without this. - ' - - _G_save=$IFS - IFS=, - for _G_macro in $_G_macros; do - IFS=$_G_save - func_append _G_mini "AC_DEFUN([$_G_macro])$nl" - done - IFS=$_G_save - - # We discard M4's stdout, but the M4 trace output from reading our - # "autoconf.mini" followed by any other files passed to this - # function is then scanned by sed to transform it into a colon - # delimited argument list assigned to a shell variable. - _G_transform='s|#.*$||; s|^dnl .*$||; s| dnl .*$||;' - - # Unfortunately, alternation in regexp addresses doesn't work in at - # least BSD (and hence Mac OS X) sed, so we have to append a capture - # and print block for each traced macro to the sed transform script. - _G_save=$IFS - IFS=, - for _G_macro in $_G_macros; do - IFS=$_G_save - func_append _G_transform ' - /^m4trace: -1- '"$_G_macro"'/ { - s|^m4trace: -1- '"$_G_macro"'[([]*|| - s|], [[]|:|g - s|[])]*$|:| - s|\(.\):$|\1| - p - }' - done - IFS=$_G_save - - # Save the command pipeline results for further use by callers of - # this function. - func_extract_trace_result=`$ECHO "$_G_mini" \ - |$M4 -daq --prefix $_G_m4_traces - "$@" 2>&1 1>/dev/null \ - |$SED -n -e "$_G_transform"` -} - - -# func_extract_trace_first MACRO_NAMES [FILENAME]... -# -------------------------------------------------- -# Exactly like func_extract_trace, except that only the first argument -# to the first invocation of one of the comma separated MACRO_NAMES is -# returned in '$func_extract_trace_first_result'. -func_extract_trace_first () -{ - $debug_cmd - - func_extract_trace ${1+"$@"} - func_extract_trace_first_result=`$ECHO "$func_extract_trace_result" \ - |$SED -e 's|:.*$||g' -e 1q` -} - - -# func_main [ARG]... -# ------------------ -func_main () -{ - $debug_cmd - - # Configuration. - usage='$progname MACRO_NAME FILE [...]' - - long_help_message=' -The first argument to this program is the name of an autotools macro -whose arguments you want to extract by examining the files listed in the -remaining arguments using the same tool that Autoconf and Automake use, -GNU M4. - -The arguments are returned separated by colons, with each traced call -on a separate line.' - - # Option processing. - func_options "$@" - eval set dummy "$func_options_result"; shift - - # Validate remaining non-option arguments. - test $# -gt 1 \ - || func_fatal_help "not enough arguments" - - # Pass non-option arguments to extraction function. - func_extract_trace "$@" - - # Display results. - test -n "$func_extract_trace_result" \ - && $ECHO "$func_extract_trace_result" - - # The End. - exit $EXIT_SUCCESS -} - - -## --------------------------- ## -## Actually perform the trace. ## -## --------------------------- ## - -# Only call 'func_main' if this script was called directly. -test extract-trace = "$progname" && func_main "$@" - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "20/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: - -# Set a version string for *this* script. -scriptversion=2014-11-04.13; # UTC - - -## ------------------- ## -## Hookable functions. ## -## ------------------- ## - -# After 'bootstrap.conf' has been sourced, execution proceeds by calling -# 'func_bootstrap'. Wherever a function is decorated with -# 'func_hookable func_name', you will find a matching 'func_run_hooks -# func_name', which executes all functions added with 'func_add_hook -# func_name my_func'. -# -# You might notice that many of these functions begin with a series of -# '$require_foo' lines. See the docu-comments at the start of the -# 'Resource management' section for a description of what these are. - - -# func_bootstrap [ARG]... -# ----------------------- -# All the functions called inside func_bootstrap are hookable. See the -# the individual implementations for details. -func_bootstrap () -{ - $debug_cmd - - # Save the current positional parameters to prevent them being - # corrupted by calls to 'set' in 'func_init'. - func_quote_for_eval ${1+"$@"} - _G_saved_positional_parameters=$func_quote_for_eval_result - - # Initialisation. - func_init - - # Option processing. - eval func_options "$_G_saved_positional_parameters" - - # Post-option preparation. - func_prep - - # Reconfigure the package. - func_reconfigure - - # Ensure .version is up-to-date. - func_update_dotversion - - # Finalisation. - func_fini -} - - -# func_init -# --------- -# Any early initialisations can be hooked to this function. Consider -# whether you can hook onto 'func_prep' instead, because if you hook -# any slow to execute code in here, it will also add to the time before -# './bootstrap --version' can respond. -func_hookable func_init -func_init () -{ - $debug_cmd - - func_run_hooks func_init -} - - -# func_prep -# --------- -# Function to perform preparation for remaining bootstrap process. If -# your hooked code relies on the outcome of 'func_options' hook it here -# rather than to 'func_init'. -# -# All the functions called inside func_prep are hookable. See the -# individual implementations for details. -func_hookable func_prep -func_prep () -{ - $debug_cmd - - $require_buildtools_uptodate - $require_checkout_only_file - - $require_gnulib_merge_changelog - - # Report the results of SED and GREP searches from funclib.sh. - func_verbose "GREP='$GREP'" - func_verbose "SED='$SED'" - - # fetch update files from the translation project - func_update_translations - - func_run_hooks func_prep -} - - -# func_update_translations -# ------------------------ -# Update package po files and translations. -func_hookable func_update_translations -func_update_translations () -{ - $debug_cmd - - $opt_skip_po || { - test -d po && { - $require_package - - func_update_po_files po $package || exit $? - } - - func_run_hooks func_update_translations - } -} - - -# func_reconfigure -# ---------------- -# Reconfigure the current package by running the appropriate autotools in a -# suitable order. -func_hookable func_reconfigure -func_reconfigure () -{ - $debug_cmd - - $require_automake_options - - # Automake (without 'foreign' option) requires that NEWS & README exist. - case " $automake_options " in - " foreign ") ;; - *) - func_ensure_NEWS - func_ensure_README - ;; - esac - - # Ensure ChangeLog presence. - if test -n "$gnulib_modules"; then - func_ifcontains "$gnulib_modules" gitlog-to-changelog \ - func_ensure_changelog - else - $require_gnulib_cache - if $SED -n '/^gl_MODULES(\[/,/^])$/p' $gnulib_cache 2>/dev/null | - func_grep_q gitlog-to-changelog - then - func_ensure_changelog - fi - fi - - # Released 'autopoint' has the tendency to install macros that have - # been obsoleted in current 'gnulib', so run this before 'gnulib-tool'. - func_autopoint - - # Autoreconf runs 'aclocal' before 'libtoolize', which causes spurious - # warnings if the initial 'aclocal' is confused by the libtoolized - # (or worse: out-of-date) macro directory. - func_libtoolize - - # If you need to do anything after 'gnulib-tool' is done, but before - # 'autoreconf' runs, you don't need to override this whole function, - # because 'func_gnulib_tool' is hookable. - func_gnulib_tool - - func_autoreconf - - func_run_hooks func_reconfigure -} - - -# func_gnulib_tool -# ---------------- -# Run 'gnulib-tool' to fetch gnulib modules into the current package. -# -# It's assumed that since you are using gnulib's 'bootstrap' script, -# you're also using gnulib elsewhere in your package. If not, then -# you can replace this function in 'bootstrap.conf' with: -# -# func_gnulib_tool () { :; } -# -# (although the function returns immediately if $gnulib_tool is set to -# true in any case). -func_hookable func_gnulib_tool -func_gnulib_tool () -{ - $debug_cmd - - $require_gnulib_tool - $require_libtoolize - - test true = "$gnulib_tool" || { - # bootstrap.conf written for gnulib bootstrap expects - # gnulib_tool_option_extras to which --no-changelog is appended, - # but libtool bootstrap expects you to append to gnulib_tool_options - # so that you can override the --no-changelog default: make sure we - # support both styles so users can migrate between them easily. - gnulib_tool_all_options="$gnulib_tool_options $gnulib_tool_option_extras" - - if test -n "$gnulib_modules"; then - $require_gnulib_cache - $require_gnulib_tool_base_options - - gnulib_mode=--import - - # Try not to pick up any stale values from 'gnulib-cache.m4'. - rm -f "$gnulib_cache" - - test -n "$gnulib_tool_base_options" \ - && func_append_uniq gnulib_tool_all_options " $gnulib_tool_base_options" - test -n "$gnulib_mk" \ - && func_append_uniq gnulib_tool_all_options " --makefile-name=$gnulib_mk" - test -n "$tests_base" && { - func_append_uniq gnulib_tool_all_options " --tests-base=$tests_base" - func_append_uniq gnulib_tool_all_options " --with-tests" - } - else - - # 'gnulib_modules' and others are cached in 'gnulib-cache.m4': - # Use 'gnulib --update' to fetch gnulib modules. - gnulib_mode=--update - fi - - # Add a sensible default libtool option to gnulib_tool_options. - # The embedded echo is to squash whitespace before globbing. - case `echo " "$gnulib_tool_all_options" "` in - *" --no-libtool "*|*" --libtool "*) ;; - *) if test true = "$LIBTOOLIZE"; then - func_append_uniq gnulib_tool_all_options " --no-libtool" - else - func_append_uniq gnulib_tool_all_options " --libtool" - fi - ;; - esac - - $opt_copy || func_append_uniq gnulib_tool_all_options " --symlink" - - func_append_uniq gnulib_tool_all_options " $gnulib_mode" - func_append gnulib_tool_all_options " $gnulib_modules" - - # The embedded echo is to squash whitespace before display. - gnulib_cmd=`echo $gnulib_tool $gnulib_tool_all_options` - - func_show_eval "$gnulib_cmd" 'exit $?' - - # Use 'gnulib-tool --copy-file' to install non-module files. - func_install_gnulib_non_module_files - } - - func_run_hooks func_gnulib_tool -} - - -# func_fini -# --------- -# Function to perform all finalisation for the bootstrap process. -func_hookable func_fini -func_fini () -{ - $debug_cmd - - func_gettext_configuration - func_clean_dangling_symlinks - func_clean_unused_macros - func_skip_po_recommendation - - func_run_hooks func_fini - - $require_bootstrap_uptodate - - func_echo "Done. Now you can run './configure'." -} - - -# func_gettext_configuration -# -------------------------- -# Edit configuration values into po/Makevars. -func_hookable func_gettext_configuration -func_gettext_configuration () -{ - $debug_cmd - - $require_autopoint - - test true = "$AUTOPOINT" || { - $require_copyright_holder - $require_extra_locale_categories - $require_package_bugreport - - # Escape xgettext options for sed Makevars generation below. - # We have to delete blank lines in a separate script so that we don't - # append \\\ to the penultimate line, and then delete the last empty - # line, which messes up the variable substitution later in this - # function. Note that adding a literal \\\ requires double escaping - # here, once for the execution subshell, and again for the assignment, - # which is why there are actually 12 (!!) backslashes in the script. - _G_xgettext_options=`echo "$xgettext_options$nl" |$SED '/^$/d' |$SED ' - $b - s|$| \\\\\\\\\\\\|'` - - # Create gettext configuration. - func_echo "Creating po/Makevars from po/Makevars.template ..." - $RM -f po/Makevars - $SED ' - /^EXTRA_LOCALE_CATEGORIES *=/s|=.*|= '"$extra_locale_categories"'| - /^COPYRIGHT_HOLDER *=/s|=.*|= '"$copyright_holder"'| - /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$package_bugreport"'| - /^XGETTEXT_OPTIONS *=/{ - s|$| \\| - a\ - '"$_G_xgettext_options"' \\\ - $${end_of_xgettext_options+} - } - ' po/Makevars.template >po/Makevars || exit 1 - } - - func_run_hooks func_gettext_configuration -} - - - -## The section title above is chosen for what section of bootstrap -## these functions will be merged to, so that the invocations of -## `func_add_hook` are guaranteed not to be executed until after -## the hook management functions are defined. - - -# slingshot_split_buildreq -# ------------------------ -# For convenience, let the user add rockspec requirements to $buildreq. -# Note that this is for *build-time* requirements (e.g. ldoc), so that -# make can complete without error. You should add *run-time* rockspec -# requirements (e.g. stdlib) to rockspec.conf. -slingshot_split_buildreq () -{ - $debug_cmd - - $require_rockspecs_req -} -func_add_hook func_init slingshot_split_buildreq - - -# slingshot_check_rockspecs -# ------------------------- -# Check build-time rockspecs from $buildreq are uptodate. -# It would be nice if we could rely on luarock binaries to respond to -# `--version` like GNU apps, but there is no reliable consensus, so we -# have to check installed luarock versions directly, and warn the user -# if the apps we're checking for are not somewhere along PATH. -slingshot_check_rockspecs () -{ - $debug_cmd - - $opt_skip_rock_checks && return - - $require_rockspecs_req - - _G_req= - rockspecs_uptodate_result=: - - set dummy $rockspecs_req; shift - while test $# -gt 0; do - _G_rock=$1; shift - _G_reqver=$1; shift - _G_url=$1; shift - - func_append _G_req " $_G_rock $_G_url" - - # Honor $APP variables ($LDOC, $SPECL, etc.) - _G_appvar=`echo $_G_rock |tr '[a-z]' '[A-Z]'` - eval "_G_rock=\${$_G_appvar-$_G_rock}" - - # Trust the user will ensure the binaries will arive at the - # specified location before they are needed if they set these. - if eval 'test -n "${'$_G_appvar'+set}"'; then - eval test -f '"${'$_G_appvar'}"' \ - || eval 'func_warning settings "\ -not checking whether $'$_G_appvar' has version $_G_reqver; -configure or make may fail because you set $_G_appvar, but -$'$_G_appvar' does not yet exist!"' - else - _G_instver=`$LUAROCKS ${opt_luarocks_tree+--tree=$opt_luarocks_tree} \ - show $_G_rock 2>/dev/null \ - |sed -n '/^'"$_G_rock"' .* - /{s/^'"$_G_rock"' \(.*\) - .*$/\1/p;}'` - - if test -z "$_G_instver"; then - slingshot_rockspec_error - else - func_verbose "found '$_G_rock' version $_G_instver." - - case $_G_reqver in - =*) - test "x$_G_reqver" = "x=$_G_instver" || slingshot_rockspec_error - ;; - *) - func_lt_ver "$_G_reqver" "$_G_instver" || slingshot_rockspec_error - ;; - esac - fi - fi - done - - $rockspecs_uptodate_result || { - func_strtable 0 10 48 \ - "Program" "Rockspec_URL" $_G_req - func_fatal_error "Missing rocks: -$func_strtable_result -Install missing rockspecs with: - $LUAROCKS ${opt_luarocks_tree+--tree=$opt_luarocks_tree }install \$Rockspec_URL -and then rerun bootstrap with the --luarocks-tree option set -appropriately, or if you're sure that the missing rocks will -be installed before running make by exporting: - APPNAME=/path/to/app. -" - } -} -func_add_hook func_prep slingshot_check_rockspecs - - -# slingshot_copy_files -# -------------------- -# Update files from slingshot subproject. -slingshot_copy_files () -{ - $debug_cmd - - $require_package - - test slingshot = "$package" || { - func_check_configuration slingshot_files - - $require_slingshot_submodule - - # Make sure we have the latest mkrockspecs - # (the rebootstrap rule in slingshot/GNUmakefile autoruns). - make -C slingshot build-aux/mkrockspecs - - # Update in-tree links. - for file in $slingshot_files; do - func_dirname_and_basename "./$file" - slingshot_copy "$func_basename_result" \ - "slingshot/$func_dirname_result" "$func_dirname_result" - done - } -} -func_add_hook func_prep slingshot_copy_files - - -# slingshot_ensure_changelog -# -------------------------- -# Slingshot project probably won't have a gnulib_modules list. -# So we redo the ChangeLog check against slingshot_files. -slingshot_ensure_changelog () -{ - $debug_cmd - - if test -n "$slingshot_files"; then - func_ifcontains "$slingshot_files" build-aux/gitlog-to-changelog \ - func_ensure_changelog - fi - - return 0 -} -func_add_hook func_prep slingshot_ensure_changelog - - -# slingshot_update_travis_yml -# --------------------------- -# When 'travis.yml.in' is listed in $slingshot_files, complain if -# regenerating '.travis.yml' would change it. -slingshot_update_travis_yml () -{ - $debug_cmd - - $require_git - - _G_travis_yml_in=travis.yml.in - _G_travis_yml_out=.travis.yml - - rm -f "$_G_travis_yml_out.new" - - test true = "$GIT" || { - case " "`echo $slingshot_files`" " in - *" travis.yml.in "*) - # Remove trailing blanks so as not to trip sc_trailing_blank in syntax check - test -f "$_G_travis_yml_in" && { - $slingshot_require_travis_extra_rocks - - eval `grep '^ *PACKAGE=' configure | sed 1q` - eval `grep '^ *VERSION=' configure | sed 1q` - - cat "$_G_travis_yml_in" | - sed 's| *$||' | - sed "s|@EXTRA_ROCKS@|`echo $travis_extra_rocks`|g" | - sed "s|@PACKAGE@|$PACKAGE|g" | - sed "s|@VERSION@|$VERSION|g" - - if test -f .slackid; then - read slackid < .slackid - printf '%s\n' '' 'notifications:' " slack: $slackid" - fi - } > "$_G_travis_yml_out.new" - - if test -f "$_G_travis_yml_out"; then - if func_cmp_s "$_G_travis_yml_out" "$_G_travis_yml_out.new"; then - func_verbose "$_G_travis_yml_out is up to date" - rm -f "$_G_travis_yml_out.new" - else - func_warning upgrade "\ -An updated $_G_travis_yml_out script is ready for you in -'$_G_travis_yml_out.new'. After you've verified that you want -the changes, you can update with: - mv -f $_G_travis_yml_out.new $_G_travis_yml_out" - fi - else - func_verbose "creating '$_G_travis_yml_out'" - mv -f "$_G_travis_yml_out.new" "$_G_travis_yml_out" - fi - ;; - esac - } -} -func_add_hook func_fini slingshot_update_travis_yml - - -# slingshot_check_rockstree_path -# ------------------------------ -# Show a warning at the end of bootstrap if --luarocks-tree was passed -# set, but $opt_luarocks_tree/bin is not in the command PATH. -slingshot_check_rockstree_path () -{ - $debug_cmd - - test -z "$rockspecs_req" || { - case :$PATH: in - *:$opt_luarocks_tree/bin:*) ;; - *) func_warning recommend \ - "If configure or make fail, try adding $opt_luarocks_tree/bin to PATH" ;; - esac - } -} -func_add_hook func_fini slingshot_check_rockstree_path - - -## --------------- ## -## Core functions. ## -## --------------- ## - -# This section contains the main functions called from the 'Hookable -# functions' (shown above), and are the ones you're most likely -# to want to replace with your own implementations in 'bootstrap.conf'. - - -# func_autopoint -# -------------- -# If this package uses gettext, then run 'autopoint'. -func_autopoint () -{ - $debug_cmd - - $require_autopoint - - test true = "$AUTOPOINT" \ - || func_show_eval "$AUTOPOINT --force" 'exit $?' -} - - -# func_libtoolize -# --------------- -# If this package uses libtool, then run 'libtoolize'. -func_libtoolize () -{ - $debug_cmd - - $require_libtoolize - - test true = "$LIBTOOLIZE" || { - _G_libtoolize_options= - $opt_copy && func_append _G_libtoolize_options " --copy" - $opt_force && func_append _G_libtoolize_options " --force" - $opt_verbose || func_append _G_libtoolize_options " --quiet" - func_show_eval "$LIBTOOLIZE$_G_libtoolize_options" 'exit $?' - } -} - - -# func_gnulib_tool_copy_file SRC DEST -# ----------------------------------- -# Copy SRC, a path relative to the gnulib sub-tree, to DEST, a path -# relative to the top-level source directory using gnulib-tool so that -# any patches or replacements in $local_gl_dir are applied. -func_gnulib_tool_copy_file () -{ - $debug_cmd - - $require_gnulib_tool - $require_patch - - if test true = "$gnulib_tool"; then - # If gnulib-tool is not available (e.g. bootstrapping in a - # distribution tarball), make sure that at least we have some - # version of the required file already in place. - test -f "$2" || func_fatal_error "\ -Can't find, copy or download '$2', a required -gnulib supplied file, please provide the location of a -complete 'gnulib' tree by setting 'gnulib_path' in your -'bootstrap.conf' or with the '--gnulib-srcdir' option - -or else specify the location of your 'git' binary by -setting 'GIT' in the environment so that a fresh -'gnulib' submodule can be cloned." - else - $require_gnulib_copy_cmd - - $gnulib_copy_cmd $1 $2 2>/dev/null || { - $require_gnulib_path - - func_error "'$gnulib_path/$1' does not exist" - return 1 - } - fi -} - - -# func_install_gnulib_non_module_files -# ------------------------------------ -# Get additional non-module files from gnulib, overriding existing files. -func_install_gnulib_non_module_files () -{ - $debug_cmd - - $require_build_aux - $require_gnulib_tool - - test -n "$gnulib_non_module_files" && { - maybe_exit_cmd=: - - for file in $gnulib_non_module_files; do - case $file in - */COPYING*) dest=COPYING;; - */INSTALL) dest=INSTALL;; - build-aux/missing) dest= - func_warning settings "\ -Please remove build-aux/missing from gnulib_module_files in -'bootstrap.conf', as it may clash with Automake's version." - ;; - build-aux/*) dest=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;; - *) dest=$file;; - esac - - # Be sure to show all copying errors before bailing out - test -z "$dest" \ - || func_gnulib_tool_copy_file "$file" "$dest" \ - || maybe_exit_cmd="exit $EXIT_FAILURE" - done - - $maybe_exit_cmd - } -} - - -# func_ensure_changelog -# --------------------- -# Even with 'gitlog-to-changelog' generated ChangeLogs, automake -# will not run to completion with no ChangeLog file. -func_ensure_changelog () -{ - $debug_cmd - - test -f ChangeLog && mv -f ChangeLog ChangeLog~ - - cat >ChangeLog <<'EOT' -## ---------------------- ## -## DO NOT EDIT THIS FILE! ## -## ---------------------- ## - -ChangeLog is generated by gitlog-to-changelog. -EOT - - _G_message="creating dummy 'ChangeLog'" - test -f ChangeLog~ \ - && func_append _G_message ' (backup in ChangeLog~)' - func_verbose "$_G_message" - - return 0 -} - - -# func_ensure_NEWS -# ---------------- -# Without AM_INIT_AUTOMAKE([foreign]), automake will not run to -# completion with no NEWS file, even though NEWS.md or NEWS.txt -# is often preferable. -func_ensure_NEWS () -{ - $debug_cmd - - test -f NEWS || { - _G_NEWS= - for _G_news in NEWS.txt NEWS.md NEWS.rst; do - test -f "$_G_news" && break - done - - test -f "$_G_news" && $LN_S $_G_news NEWS - func_verbose "$LN_S $_G_news NEWS" - } - - return 0 -} - - -# func_ensure_README -# ------------------ -# Without AM_INIT_AUTOMAKE([foreign]), automake will not run to -# completion with no README file, even though README.md or README.txt -# is often preferable. -func_ensure_README () -{ - $debug_cmd - - test -f README || { - _G_README= - for _G_readme in README.txt README.md README.rst; do - test -f "$_G_readme" && break - done - - test -f "$_G_readme" && $LN_S $_G_readme README - func_verbose "$LN_S $_G_readme README" - } - - return 0 -} - - -# func_autoreconf [SUBDIR] -# ------------------------ -# Being careful not to re-run 'autopoint' or 'libtoolize', and not to -# try to run 'autopoint', 'libtoolize' or 'autoheader' on packages that -# don't use them, defer to 'autoreconf' for execution of the remaining -# autotools to bootstrap this package. -# -# Projects with multiple trees to reconfigure can hook another call to -# this function onto func_reconfigure: -# -# my_autoreconf_foo () -# { -# func_autoreconf foo -# } -# func_add_hook func_reconfigure my_autoreconf_foo -func_autoreconf () -{ - $debug_cmd - - $require_autoheader - $require_build_aux # automake and others put files in here - $require_macro_dir # aclocal and others put files in here - - # We ran these manually already, and autoreconf won't exec ':' - save_AUTOPOINT=$AUTOPOINT; AUTOPOINT=true - save_LIBTOOLIZE=$LIBTOOLIZE; LIBTOOLIZE=true - - _G_autoreconf_options= - $opt_copy || func_append _G_autoreconf_options " --symlink" - $opt_force && func_append _G_autoreconf_options " --force" - $opt_verbose && func_append _G_autoreconf_options " --verbose" - func_show_eval "$AUTORECONF$_G_autoreconf_options --install${1+ $1}" 'exit $?' - - AUTOPOINT=$save_AUTOPOINT - LIBTOOLIZE=$save_LIBTOOLIZE -} - - -# func_check_configuration VARNAME [CONFIGURE_MACRO] -# -------------------------------------------------- -# Exit with a suitable diagnostic for an important configuration change -# that needs to be made before bootstrap can run correctly. -func_check_configuration () -{ - $debug_cmd - - $require_configure_ac - - eval 'test -n "$'$1'"' || { - _G_error_msg="please set '$1' in 'bootstrap.conf'" - if test -n "$configure_ac" && test -n "$2"; then - func_append _G_error_msg " -or add the following (or similar) to your '$configure_ac': -$2" - fi - - func_fatal_error "$_G_error_msg" - } -} - - -# func_clean_dangling_symlinks -# ---------------------------- -# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some -# gnulib-populated directories. Such .m4 files would cause aclocal to -# fail. The following requires GNU find 4.2.3 or newer. Considering -# the usual portability constraints of this script, that may seem a very -# demanding requirement, but it should be ok. Ignore any failure, -# which is fine, since this is only a convenience to help developers -# avoid the relatively unusual case where a symlinked-to .m4 file is -# git-removed from gnulib between successive runs of this script. -func_clean_dangling_symlinks () -{ - $debug_cmd - - $require_macro_dir - $require_source_base - - func_verbose "cleaning dangling symlinks" - - find "$macro_dir" "$source_base" \ - -depth \( -name '*.m4' -o -name '*.[ch]' \) \ - -type l -xtype l -delete > /dev/null 2>&1 -} - - -# func_clean_unused_macros -# ------------------------ -# Autopoint can result in over-zealously adding macros into $macro_dir -# even though they are not actually used, for example tests to help -# build the 'intl' directory even though you have specified -# 'AM_GNU_GETTEXT([external])' in your configure.ac. This function -# looks removes any macro files that can be found in gnulib, but -# are not 'm4_include'd by 'aclocal.m4'. -func_clean_unused_macros () -{ - $debug_cmd - - $require_gnulib_path - $require_macro_dir - - test -n "$gnulib_path" && test -f aclocal.m4 && { - aclocal_m4s=`find . -name aclocal.m4 -print` - - # We use 'ls|grep' instead of 'ls *.m4' to avoid exceeding - # command line length limits in some shells. - for file in `cd "$macro_dir" && ls -1 |$GREP '\.m4$'`; do - - # Remove a macro file when aclocal.m4 does not m4_include it... - func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \ - || test ! -f "$gnulib_path/m4/$file" || { - - # ...and there is an identical file in gnulib... - if func_cmp_s "$gnulib_path/m4/$file" "$macro_dir/$file"; then - - # ...and it's not in the precious list ('echo' is needed - # here to squash whitespace for the match expression). - case " "`echo $gnulib_precious`" " in - *" $file "*) ;; - *) rm -f "$macro_dir/$file" - func_verbose \ - "removing unused gnulib file '$macro_dir/$file'" - esac - fi - } - done - } -} - - -# func_skip_po_recommendation -# --------------------------- -# If there is a po directory, and '--skip-po' wasn't passed, let the -# user know that they can use '--skip-po' on subsequent invocations. -func_skip_po_recommendation () -{ - $debug_cmd - - test ! -d po \ - || $opt_skip_po \ - || func_warning recommend "\ -If your pofiles are up-to-date, you can rerun bootstrap -as '$progname --skip-po' to avoid redownloading." -} - - -# func_update_dotversion -# ---------------------- -# Even with 'gitlog-to-changelog' generated ChangeLogs, automake -# will not run to completion with no ChangeLog file. -func_update_dotversion () -{ - $debug_cmd - - test -f "$build_aux/git-version-gen" && { - _G_message="updating .version" - test -f .version && { - mv .version .version~ - func_append _G_message " (backup in .version~)" - } - func_verbose "updating .version" - - $build_aux/git-version-gen dummy-arg > .version - } -} - - - -## -------------------- ## -## Resource management. ## -## -------------------- ## - -# This section contains definitions for functions that each ensure a -# particular resource (a file, or a non-empty configuration variable for -# example) is available, and if appropriate to extract default values -# from pertinent package files. Where a variable already has a non- -# empty value (as set by the package's 'bootstrap.conf'), that value is -# used in preference to deriving the default. Call them using their -# associated 'require_*' variable to ensure that they are executed, at -# most, once. - - -# require_checkout_only_file -# -------------------------- -# Bail out if this package only bootstraps properly from a repository -# checkout. -require_checkout_only_file=func_require_checkout_only_file -func_require_checkout_only_file () -{ - $debug_cmd - - $opt_force || { - test -n "$checkout_only_file" && test ! -f "$checkout_only_file" \ - && func_fatal_error "\ -Bootstrapping from a non-checked-out distribution is risky. -If you wish to bootstrap anyway, use the '--force' option." - } - - require_checkout_only_file=: -} - - -# require_aclocal_amflags -# ----------------------- -# Ensure '$aclocal_amflags' has a sensible default, extracted from -# 'Makefile.am' if necessary. -require_aclocal_amflags=func_require_aclocal_amflags -func_require_aclocal_amflags () -{ - $debug_cmd - - $require_makefile_am - - _G_sed_extract_aclocal_amflags='s|#.*$|| - /^[ ]*ACLOCAL_AMFLAGS[ ]*=/ { - s|^.*=[ ]*\(.*\)|aclocal_amflags="\1"| - p - }' - - _G_aclocal_flags_cmd=`$SED -n "$_G_sed_extract_aclocal_amflags" \ - "$makefile_am"` - eval "$_G_aclocal_flags_cmd" - - func_verbose "ACLOCAL_AMFLAGS='$aclocal_amflags'" - - require_aclocal_amflags=: -} - - -# require_autoheader -# ------------------ -# Skip autoheader if it's not needed. -require_autoheader=func_require_autoheader -func_require_autoheader () -{ - $debug_cmd - - test true = "$AUTOHEADER" || { - func_extract_trace AC_CONFIG_HEADERS - test -n "$func_extract_trace_result" \ - || func_extract_trace AC_CONFIG_HEADER - - test -n "$func_extract_trace_result" || { - AUTOHEADER=true - - func_verbose "export AUTOHEADER='$AUTOHEADER'" - - # Make sure the search result is visible to subshells - export AUTOHEADER - } - } - - require_autoheader=: -} - - -# require_automake_options -# ------------------------ -# Extract options from AM_AUTOMAKE_INIT. -require_automake_options=func_require_automake_options -func_require_automake_options () -{ - $debug_cmd - - func_extract_trace AM_INIT_AUTOMAKE - automake_options=$func_extract_trace_result - - require_automake_options=: -} - - -# require_autopoint -# ----------------- -# Skip autopoint if it's not needed. -require_autopoint=func_require_autopoint -func_require_autopoint () -{ - $debug_cmd - - test true = "$AUTOPOINT" || { - func_extract_trace AM_GNU_GETTEXT_VERSION - - test -n "$func_extract_trace_result" || { - AUTOPOINT=true - - func_verbose "export AUTOPOINT='$AUTOPOINT'" - - # Make sure the search result is visible to subshells - export AUTOPOINT - } - } - - require_autopoint=: -} - - -# require_bootstrap_uptodate -# -------------------------- -# Complain if the version of bootstrap in the gnulib directory differs -# from the one we are running. - -func_require_bootstrap_uptodate () -{ - $debug_cmd - - $require_build_aux - - _G_bootstrap_sources=" - $build_aux/bootstrap.in - $build_aux/extract-trace - $build_aux/funclib.sh - $build_aux/options-parser - " - - _G_missing_bootstrap_sources=false - for _G_src in $_G_bootstrap_sources; do - test -f "$_G_src" || _G_missing_bootstrap_sources=: - done - - if $_G_missing_bootstrap_sources; then - func_warning upgrade "\ -Please add bootstrap to your gnulib_modules list in -'bootstrap.conf', so that I can tell you when there are -updates available." - else - rm -f bootstrap.new - $build_aux/inline-source $build_aux/bootstrap.in > bootstrap.new - - if func_cmp_s "$progpath" bootstrap.new; then - rm -f bootstrap.new - func_verbose "bootstrap script up to date" - else - chmod 555 bootstrap.new - func_warning upgrade "\ -An updated bootstrap script has been generated for you in -'bootstrap.new'. After you've verified that you want -the changes, you can update with: - mv -f bootstrap.new $progname - ./$progname - -Or you can disable this check permanently by adding the -following to 'bootstrap.conf': - require_bootstrap_uptodate=:" - fi - fi - - require_bootstrap_uptodate=: -} - - -# require_build_aux -# ----------------- -# Ensure that '$build_aux' is set, and if it doesn't already point to an -# existing directory, create one. -require_build_aux=func_require_build_aux -func_require_build_aux () -{ - $debug_cmd - - test -n "$build_aux" || { - func_extract_trace_first AC_CONFIG_AUX_DIR - build_aux=$func_extract_trace_first_result - func_check_configuration build_aux \ - "AC_CONFIG_AUX_DIR([name of a directory for build scripts])" - - func_verbose "build_aux='$build_aux'" - } - - $require_vc_ignore_files - - # If the build_aux directory doesn't exist, create it now, and mark it - # as ignored for the VCS. - if test ! -d "$build_aux"; then - func_show_eval "mkdir '$build_aux'" - - test -n "$vc_ignore_files" \ - || func_insert_if_absent "$build_aux" $vc_ignore_files - fi - - require_build_aux=: -} - - -# require_buildreq_autobuild -# -------------------------- -# Try to find whether the bootstrap requires autobuild. -require_buildreq_autobuild=func_require_buildreq_autobuild -func_require_buildreq_autobuild () -{ - $debug_cmd - - $require_macro_dir - - test -f "$macro_dir/autobuild.m4" \ - || printf '%s\n' "$buildreq" |func_grep_q '^[ ]*autobuild' \ - || { - func_extract_trace AB_INIT - test -n "$func_extract_trace_result" && { - func_append buildreq 'autobuild - http://josefsson.org/autobuild/ -' - func_verbose "auto-adding 'autobuild' to build requirements" - } - } - - require_buildreq_autobuild=: -} - - -# require_buildreq_autoconf -# require_buildreq_autopoint -# require_buildreq_libtoolize -# --------------------------- -# Try to find the minimum compatible version of autoconf/libtool -# required to bootstrap successfully, and add it to '$buildreq'. -for tool in autoconf libtoolize autopoint; do - b=$tool - v=require_buildreq_${tool} - f=func_$v - case $tool in - autoconf) m=AC_PREREQ ;; - libtoolize) m=LT_PREREQ; b=libtool ;; - autopoint) m=AM_GNU_GETTEXT_VERSION b=gettext ;; - esac - - eval $v'='$f' - '$f' () - { - $debug_cmd - - # The following is ignored if undefined, but might be necessary - # in order for `func_find_tool` to run. - ${require_'$tool'-:} - - printf '\''%s\n'\'' "$buildreq" |func_grep_q '\''^[ ]*'$tool\'' || { - func_extract_trace '$m' - _G_version=$func_extract_trace_result - test -n "$_G_version" && { - func_append buildreq "\ - '$tool' $_G_version http://www.gnu.org/s/'$b' -" - func_verbose \ - "auto-adding '\'$tool'-$_G_version'\'' to build requirements" - } - } - - '$v'=: - } -' -done - - -# require_buildreq_automake -# ------------------------- -# Try to find the minimum compatible version of automake required to -# bootstrap successfully, and add it to '$buildreq'. -require_buildreq_automake=func_require_buildreq_automake -func_require_buildreq_automake () -{ - $debug_cmd - - # if automake is not already listed in $buildreq... - printf '%s\n' "$buildreq" |func_grep_q automake || { - func_extract_trace AM_INIT_AUTOMAKE - - # ...and AM_INIT_AUTOMAKE is declared... - test -n "$func_extract_trace_result" && { - automake_version=`$ECHO "$func_extract_trace_result" \ - |$SED -e 's|[^0-9]*||' -e 's| .*$||'` - test -n "$automake_version" || automake_version=- - - func_append buildreq "\ - automake $automake_version http://www.gnu.org/s/automake -" - func_verbose \ - "auto-adding 'automake-$automake_version' to build requirements" - } - } - - require_buildreq_automake=: -} - - -# require_buildreq_patch -# ---------------------- -# Automatically add a patch build-requirement if there are diff files -# in $local_gl_dir. -require_buildreq_patch=func_require_buildreq_patch -func_require_buildreq_patch () -{ - $debug_cmd - - $require_local_gl_dir - - # This ensures PATCH is set appropriately by the time - # func_check_versions enforces $buildreq. - $require_patch - - # If patch is not already listed in $buildreq... - printf '%s\n' "$buildreq" |func_grep_q '^[ ]*patch' || { - # The ugly find invocation is necessary to exit with non-zero - # status for old find binaries that don't support -exec fully. - if test ! -d "$local_gl_dir" \ - || find "$local_gl_dir" -name "*.diff" -exec false {} \; ; then : - else - func_append buildreq 'patch - http://www.gnu.org/s/patch -' - fi - } - - require_buildreq_patch=: -} - - -# require_buildtools_uptodate -# --------------------------- -# Ensure all the packages listed in BUILDREQS are available on the build -# machine at the minimum versions or better. -require_buildtools_uptodate=func_require_buildtools_uptodate -func_require_buildtools_uptodate () -{ - $debug_cmd - - $require_buildreq_autobuild - $require_buildreq_autoconf - $require_buildreq_automake - $require_buildreq_libtoolize - $require_buildreq_autopoint - $require_buildreq_patch - - test -n "$buildreq" && { - _G_error_hdr= - - func_check_versions $buildreq - $func_check_versions_result || { - test -n "$buildreq_readme" \ - && test -f "$buildreq_readme" \ - && _G_error_hdr="\ -$buildreq_readme explains how to obtain these prerequisite programs: -" - func_strtable 0 11 12 36 \ - "Program" "Min_version" "Homepage" $buildreq - func_fatal_error "$_G_error_hdr$func_strtable_result" - } - } - - require_buildtools_uptodate=: -} - - -# require_copyright_holder -# ------------------------ -# Ensure there is a sensible non-empty default value in '$copyright_holder'. -require_copyright_holder=func_require_copyright_holder -func_require_copyright_holder () -{ - $debug_cmd - - test -n "$copyright_holder" || { - copyright_holder='Free Software Foundation, Inc.' - func_warning settings "\ -Please set copyright_holder explicitly in 'bootstrap.conf'; -defaulting to '$copyright_holder'." - } - - require_copyright_holder=: -} - - -# require_doc_base -# ---------------- -# Ensure doc_base has a sensible value, extracted from 'gnulib-cache.m4' -# if possible, otherwise letting 'gnulib-tool' pick a default. -require_doc_base=func_require_doc_base -func_require_doc_base () -{ - $debug_cmd - - $require_gnulib_cache - - test -f "$gnulib_cache" && test -z "$doc_base" && { - func_extract_trace_first "gl_DOC_BASE" "$gnulib_cache" - doc_base=$func_extract_trace_first_result - - test -n "$doc_base" && func_verbose "doc_base='$doc_base'" - } - - require_doc_base=: -} - - -# require_dotgitmodules -# --------------------- -# Ensure we have a '.gitmodules' file, with appropriate 'gnulib' settings. -require_dotgitmodules=func_require_dotgitmodules -func_require_dotgitmodules () -{ - $debug_cmd - - $require_git - - test true = "$GIT" || { - # A gnulib entry in .gitmodules always takes precedence. - _G_path=`$GIT config --file .gitmodules submodule.gnulib.path 2>/dev/null` - - test -n "$_G_path" || { - $require_vc_ignore_files - - func_verbose "creating '.gitmodules'" - - # If the .gitmodules file doesn't exist, create it now, and mark - # it as ignored for the VCS. - test -n "$gnulib_path" || gnulib_path=gnulib - test -n "$gnulib_url" || gnulib_url=git://git.sv.gnu.org/gnulib - - { - echo '[submodule "gnulib"]' - echo " path = $gnulib_path" - echo " url = $gnulib_url" - } >> .gitmodules - - test -n "$vc_ignore_files" \ - || func_insert_if_absent ".gitmodules" $vc_ignore_files - } - } - - require_dotgitmodules=: -} - - -# require_extra_locale_categories -# ------------------------------- -# Ensure there is a default value in '$extra_locale_categories' -require_extra_locale_categories=func_require_extra_locale_categories -func_require_extra_locale_categories () -{ - $debug_cmd - - # Defaults to empty, so run with whatever value may have been set in - # 'bootstrap.conf'. - require_extra_locale_categories=: -} - - -# require_git -# ----------- -# Ignore git if it's not available, or we're not in a git checkout tree. -require_git=func_require_git -func_require_git () -{ - $debug_cmd - - $opt_skip_git && GIT=true - - test true = "$GIT" || { - if test -d .git/.; then - ($GIT --version) >/dev/null 2>&1 || GIT=true - fi - } - - func_verbose "GIT='$GIT'" - - require_git=: -} - - -# require_gnulib_cache -# -------------------- -# Ensure there is a non-empty default for '$gnulib_cache', and that it -# names an existing file. -require_gnulib_cache=func_require_gnulib_cache -func_require_gnulib_cache () -{ - $debug_cmd - - $require_macro_dir - - test -n "$gnulib_cache" \ - || gnulib_cache=$macro_dir/gnulib-cache.m4 - - func_verbose "found '$gnulib_cache'" - - require_gnulib_cache=: -} - - -# require_gnulib_copy_cmd -# ----------------------- -# Only calculate the options for copying files with gnulib once. -require_gnulib_copy_cmd=func_require_gnulib_copy_cmd -func_require_gnulib_copy_cmd () -{ - $debug_cmd - - $require_gnulib_tool - $require_gnulib_tool_base_options - - gnulib_copy_cmd="$gnulib_tool $gnulib_tool_base_options --copy-file" - $opt_copy || func_append gnulib_copy_cmd " --symlink" - $opt_quiet || func_append gnulib_copy_cmd " --verbose" - - require_gnulib_copy_cmd=: -} - - -# require_gnulib_merge_changelog -# ------------------------------ -# See if we can use gnulib's git-merge-changelog merge driver. -require_gnulib_merge_changelog=func_require_gnulib_merge_changelog -func_require_gnulib_merge_changelog () -{ - $debug_cmd - - test -f ChangeLog && { - $require_git - - func_grep_q '^\(/\|\)ChangeLog$' .gitignore || test true = "$GIT" || { - if $GIT config merge.merge-changelog.driver >/dev/null; then - : - elif (git-merge-changelog --version) >/dev/null 2>&1; then - func_echo "initializing git-merge-changelog driver" - $GIT config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' - $GIT config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' - else - func_warning recommend \ - "Consider installing git-merge-changelog from gnulib." - fi - } - } - - require_gnulib_merge_changelog=: -} - - -# require_gnulib_mk -# ----------------- -# Ensure gnulib_mk has a sensible value, extracted from 'gnulib-cache.m4' -# if possible, otherwise letting 'gnulib-tool' pick a default. -require_gnulib_mk=func_require_gnulib_mk -func_require_gnulib_mk () -{ - $debug_cmd - - $require_gnulib_cache - - test -f "$gnulib_cache" && test -z "$gnulib_mk" && { - func_extract_trace_first "gl_MAKEFILE_NAME" "$gnulib_cache" - gnulib_mk=$func_extract_trace_first_result - - test -n "$gnulib_mk" && func_verbose "gnulib_mk='$gnulib_mk'" - } - - require_gnulib_mk=: -} - - -# require_gnulib_name -# ------------------- -# Ensure gnulib_name has a sensible value, extracted from 'gnulib-cache.m4' -# if possible, otherwise letting 'gnulib-tool' pick a default. -require_gnulib_name=func_require_gnulib_name -func_require_gnulib_name () -{ - $debug_cmd - - $require_gnulib_cache - - test -f "$gnulib_cache" && test -z "$gnulib_name" && { - func_extract_trace_first "gl_LIB" "$gnulib_cache" - gnulib_name=$func_extract_trace_first_result - - test -n "$gnulib_name" && func_verbose "gnulib_name='$gnulib_name'" - } - - require_gnulib_name=: -} - - -# require_gnulib_path -# require_gnulib_url -# ------------------- -# Ensure 'gnulib_path' and 'gnulib_url' are set. -require_gnulib_path=func_require_dotgitmodules_parameters -require_gnulib_url=func_require_dotgitmodules_parameters -func_require_dotgitmodules_parameters () -{ - $debug_cmd - - $require_git - - test true = "$GIT" && { - # If we can't find git (or if the user specified '--skip-git'), - # then use an existing gnulib directory specified with - # '--gnulib-srcdir' if possible. - test -n "$gnulib_path" \ - || test ! -x "$opt_gnulib_srcdir/gnulib-tool" \ - || gnulib_path=$opt_gnulib_srcdir - } - - - $require_dotgitmodules - - test -f .gitmodules && { - # Extract the parameters with sed, since git may be missing - test -n "$gnulib_path" \ - || gnulib_path=`$SED -e '/^.submodule "gnulib".$/,${ - /[ ]*path *= */{ - s|[ ]*||g;s|^[^=]*=||;p - } - } - d' .gitmodules |$SED 1q` - test -n "$gnulib_url" \ - || gnulib_url=`$SED -e '/^.submodule "gnulib".$/,${ - /[ ]*url *= */{ - s|[ ]*||g;s|^[^=]*=||;p - } - } - d' .gitmodules |$SED 1q` - - func_verbose "gnulib_path='$gnulib_path'" - func_verbose "gnulib_url='$gnulib_url'" - } - - require_gnulib_path=: - require_gnulib_url=: -} - - -# require_gnulib_submodule -# ------------------------ -# Ensure that there is a current gnulib submodule at '$gnulib_path'. -require_gnulib_submodule=func_require_gnulib_submodule -func_require_gnulib_submodule () -{ - $debug_cmd - - $require_git - - if test true = "$GIT"; then - func_warning recommend \ - "No 'git' found; imported gnulib modules may be outdated." - else - $require_gnulib_path - $require_gnulib_url - - if test -f .gitmodules && test -f "$gnulib_path/gnulib-tool"; then - : All present and correct. - - elif test -n "$opt_gnulib_srcdir"; then - # Older git can't clone into an empty directory. - rmdir "$gnulib_path" 2>/dev/null - func_show_eval "$GIT clone --reference '$opt_gnulib_srcdir' \ - '$gnulib_url' '$gnulib_path'" \ - || func_fatal_error "Unable to fetch gnulib submodule." - - # Without --gnulib-srcdir, and no existing checked out submodule, we - # create a new shallow clone of the remote gnulib repository. - else - trap func_cleanup_gnulib 1 2 13 15 - - shallow= - $GIT clone -h 2>&1 |func_grep_q -- --depth \ - && shallow='--depth 365' - - func_show_eval "$GIT clone $shallow '$gnulib_url' '$gnulib_path'" \ - func_cleanup_gnulib - - # FIXME: Solaris /bin/sh will try to execute '-' if any of - # these signals are caught after this. - trap - 1 2 13 15 - fi - - # Make sure we've checked out the correct revision of gnulib. - func_show_eval "$GIT submodule init -- $gnulib_path" \ - && func_show_eval "$GIT submodule update -- $gnulib_path" \ - || func_fatal_error "Unable to update gnulib submodule." - fi - - require_gnulib_submodule=: -} - - -# require_gnulib_tool -# ------------------- -# Ensure that '$gnulib_tool' is set, and points to an executable file, -# or else fall back to using the binary 'true' if the main gnulib -# files appear to have been imported already. -require_gnulib_tool=func_require_gnulib_tool -func_require_gnulib_tool () -{ - $debug_cmd - - test true = "$gnulib_tool" || { - $require_gnulib_submodule - $require_gnulib_path - - test -n "$gnulib_tool" \ - || gnulib_tool=$gnulib_path/gnulib-tool - - test -x "$gnulib_tool" || { - gnulib_tool=true - func_warning recommend \ - "No 'gnulib-tool' found; gnulib modules may be missing." - } - - test true = "$gnulib_tool" \ - || func_verbose "found '$gnulib_tool'" - } - - require_gnulib_tool=: -} - - -# require_gnulib_tool_base_options -# -------------------------------- -# Ensure that '$gnulib_tool_base_options' contains all the base options -# required according to user configuration from bootstrap.conf. -require_gnulib_tool_base_options=func_require_gnulib_tool_base_options -func_require_gnulib_tool_base_options () -{ - $debug_cmd - - $require_gnulib_tool - - gnulib_tool_base_options= - - test true = "$gnulib_tool" || { - # 'gnulib_modules' and others are maintained in 'bootstrap.conf': - # Use 'gnulib --import' to fetch gnulib modules. - $require_build_aux - test -n "$build_aux" \ - && func_append_uniq gnulib_tool_base_options " --aux-dir=$build_aux" - $require_macro_dir - test -n "$macro_dir" \ - && func_append_uniq gnulib_tool_base_options " --m4-base=$macro_dir" - $require_doc_base - test -n "$doc_base" \ - && func_append_uniq gnulib_tool_base_options " --doc-base=$doc_base" - $require_gnulib_name - test -n "$gnulib_name" \ - && func_append_uniq gnulib_tool_base_options " --lib=$gnulib_name" - $require_local_gl_dir - test -n "$local_gl_dir" \ - && func_append_uniq gnulib_tool_base_options " --local-dir=$local_gl_dir" - $require_source_base - test -n "$source_base" \ - && func_append_uniq gnulib_tool_base_options " --source-base=$source_base" - } - - require_gnulib_tool_base_options=: -} - - -# require_libtoolize -# ------------------ -# Skip libtoolize if it's not needed. -require_libtoolize=func_require_libtoolize -func_require_libtoolize () -{ - $debug_cmd - - # Unless we're not searching for libtool use by this package, set - # LIBTOOLIZE to true if none of 'LT_INIT', 'AC_PROG_LIBTOOL' and - # 'AM_PROG_LIBTOOL' are used in configure. - test true = "$LIBTOOLIZE" || { - func_extract_trace LT_INIT - test -n "$func_extract_trace_result" || func_extract_trace AC_PROG_LIBTOOL - test -n "$func_extract_trace_result" || func_extract_trace AM_PROG_LIBTOOL - test -n "$func_extract_trace_result" || LIBTOOLIZE=true - } - - test -n "$LIBTOOLIZE" || { - # Find libtoolize, named glibtoolize in Mac Ports, but prefer - # user-installed libtoolize to ancient glibtoolize shipped by - # Apple with Mac OS X when Mac Ports is not installed. - func_find_tool LIBTOOLIZE libtoolize glibtoolize - } - - test -n "$LIBTOOLIZE" || func_fatal_error "\ -Please install GNU Libtool, or 'export LIBTOOLIZE=/path/to/libtoolize'." - - func_verbose "export LIBTOOLIZE='$LIBTOOLIZE'" - - # Make sure the search result is visible to subshells - export LIBTOOLIZE - - require_libtoolize=: -} - - -# require_local_gl_dir -# -------------------- -# Ensure local_gl_dir has a sensible value, extracted from 'gnulib-cache.m4' -# if possible, otherwise letting 'gnulib-tool' pick a default. -require_local_gl_dir=func_require_local_gl_dir -func_require_local_gl_dir () -{ - $debug_cmd - - $require_gnulib_cache - - test -f "$gnulib_cache" && test -z "$local_gl_dir" && { - func_extract_trace_first "gl_LOCAL_DIR" "$gnulib_cache" - local_gl_dir=$func_extract_trace_first_result - - test -n "$local_gl_dir" && func_verbose "local_gl_dir='$local_gl_dir'" - } - - require_local_gl_dir=: -} - - -# require_macro_dir -# ----------------- -# Ensure that '$macro_dir' is set, and if it doesn't already point to an -# existing directory, create one. -require_macro_dir=func_require_macro_dir -func_require_macro_dir () -{ - $debug_cmd - - # Sometimes this is stored in 'configure.ac'. - test -n "$macro_dir" || { - # AC_CONFIG_MACRO_DIRS takes a space delimited list of directories, - # but we only care about the first one in bootstrap. - func_extract_trace_first AC_CONFIG_MACRO_DIRS - macro_dir=`expr "x$func_extract_trace_first_result" : 'x\([^ ]*\)'` - } - test -n "$macro_dir" || { - func_extract_trace_first AC_CONFIG_MACRO_DIR - macro_dir=$func_extract_trace_first_result - } - - # Otherwise we might find it in 'Makefile.am'. - test -n "$macro_dir" || { - $require_aclocal_amflags - - # Take the argument following the first '-I', if any. - _G_minus_I_seen=false - for _G_arg in $aclocal_amflags; do - case $_G_minus_I_seen,$_G_arg in - :,*) macro_dir=$_G_arg; break ;; - *,-I) _G_minus_I_seen=: ;; - *,-I*) macro_dir=`expr x$_G_arg : 'x-I\(.*\)$'`; break ;; - esac - done - } - - func_verbose "macro_dir='$macro_dir'" - - func_check_configuration macro_dir \ - "AC_CONFIG_MACRO_DIRS([name of a directory for configure m4 files])" - - $require_vc_ignore_files - - # If the macro_dir directory doesn't exist, create it now, and mark it - # as ignored for the VCS. - if test ! -d "$macro_dir"; then - mkdir "$macro_dir" || func_permissions_error "$macro_dir" - - test -n "$vc_ignore_files" \ - || func_insert_if_absent "$macro_dir" $vc_ignore_files - fi - - require_macro_dir=: -} - - -# require_makefile_am -# ------------------- -# Ensure there is a 'Makefile.am' in the current directory. -require_makefile_am=func_require_makefile_am -func_require_makefile_am () -{ - $debug_cmd - - test -n "$makefile_am" \ - || makefile_am=Makefile.am - - <"$makefile_am" - - func_verbose "found '$makefile_am'" - - require_makefile_am=: -} - - -# require_package -# --------------- -# Ensure that '$package' contains a sensible default value. -require_package=func_require_package -func_require_package () -{ - $debug_cmd - - test -n "$package" || { - $require_package_name - - package=`echo "$package_name" \ - |$SED -e 's/GNU //' \ - -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` - } - - func_verbose "package='$package'" - - require_package=: -} - - -# require_package_bugreport -# ------------------------- -# Ensure that this has a sensible value, extracted from 'configure.ac' -# if appropriate (and possible!). -require_package_bugreport=func_require_package_bugreport -func_require_package_bugreport () -{ - $debug_cmd - - func_extract_trace AC_INIT - - save_ifs=$IFS - IFS=: - set dummy $func_extract_trace_result - IFS=$save_ifs - shift - - test -n "$package_bugreport" || package_bugreport=$3 - func_check_configuration package_bugreport \ - "AC_INIT([$package_name], [$package_version], [bug-$package@gnu.org])" - func_verbose "package_bugreport='$package_bugreport'" - - require_package_bugreport=: -} - - -# require_package_name -# -------------------- -# Ensure that this has a sensible value, extracted from 'configure.ac' -# if appropriate (and possible!). -require_package_name=func_require_package_name -func_require_package_name () -{ - $debug_cmd - - func_extract_trace AC_INIT - - save_ifs=$IFS - IFS=: - set dummy $func_extract_trace_result - IFS=$save_ifs - shift - - test -n "$package_name" || package_name=$1 - func_check_configuration package_name \ - "AC_INIT([name of your package], [package version number])" - func_verbose "package_name='$package_name'" - - require_package_name=: -} - - -# require_package_version -# ----------------------- -# Ensure that this has a sensible value, extracted from 'configure.ac' -# if appropriate (and possible!). While we might have set all the -# parameters extracted from AC_INIT at once, 'package_version' in -# particular is not necessarily available as early as the others, since -# 'git-version-gen' is often involved, and until then we can't rely on -# getting a correct version number from an AC_INIT extraction. -require_package_version=func_require_package_version -func_require_package_version () -{ - $debug_cmd - - func_extract_trace AC_INIT - - save_ifs=$IFS - IFS=: - set dummy $func_extract_trace_result - IFS=$save_ifs - shift - - test -n "$package_version" || package_version=$2 - test -n "$package_version" || { - # The embedded echo is to squash whitespace before globbing. - case " "`echo $gnulib_modules`" " in - *" git-version-gen "*) - func_fatal_error "\ -cannot \$require_package_version in bootstrap.conf before -func_gnulib_tool has installed the 'git-version-gen' script." - ;; - *) - func_check_configuration package_version \ - "AC_INIT([name of your package], [package version number])" - ;; - esac - } - func_verbose "package_version='$package_version'" - - require_package_version=: -} - - -# require_patch -# ------------- -# Find patch, according to the PATCH environment variable, or else -# searching the user's PATH. -require_patch=func_require_patch -func_require_patch () -{ - $debug_cmd - - test -n "$PATCH" || { - # Find a patch program, preferring gpatch, which is usually better - # than the vendor patch. - func_find_tool PATCH gpatch patch - } - - test -n "$PATCH" || func_fatal_error "\ -Please install GNU Patch, or 'export PATCH=/path/to/gnu/patch'." - - func_verbose "export PATCH='$PATCH'" - - # Make sure the search result is visible to subshells - export PATCH - - require_patch=: -} - - -# require_source_base -# ------------------- -# Ensure that source_base has a sensible value, extracted from -# 'gnulib-cache.m4' if possible. -require_source_base=func_require_source_base -func_require_source_base () -{ - $debug_cmd - - $require_gnulib_cache - - test -f "$gnulib_cache" && test -z "$source_base" && { - func_extract_trace_first "gl_SOURCE_BASE" "$gnulib_cache" - - source_base=$func_extract_trace_first_result - - func_verbose "source_base='$source_base'" - } - - require_source_base=: -} - - -# require_vc_ignore_files -# ----------------------- -# Ensure that '$vc_ignore' has been processed to list VCS ignore files -# in '$vc_ignore_files' -require_vc_ignore_files=func_require_vc_ignore_files -func_require_vc_ignore_files () -{ - $debug_cmd - - test -n "$vc_ignore" || vc_ignore=auto - - if test auto = "$vc_ignore" && test -z "$vc_ignore_files"; then - vc_ignore_files= - test -d .git && vc_ignore_files=.gitignore - test -d CVS && vc_ignore_files="$vc_ignore_files .cvsignore" - else - vc_ignore_files=$vc_ignore - fi - - func_verbose "vc_ignore_files='$vc_ignore_files'" - - require_vc_ignore_files=: -} - - -## ----------------- ## -## Helper functions. ## -## ----------------- ## - -# This section contains the helper functions used by the rest of 'bootstrap'. - -# func_len STRING -# --------------- -# STRING may not start with a hyphen. -if (eval 'x=123; test x${#x} = "x3"') 2>/dev/null -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_len () - { - $debug_cmd - - func_len_result=${#1} - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_len () - { - $debug_cmd - - func_len_result=`expr "$1" : ".*" 2>/dev/null || echo 0` - } -fi - - -# func_unset VAR -# -------------- -# Portably unset VAR. -# In some shells, an 'unset VAR' statement leaves a non-zero return -# status if VAR is already unset, which might be problematic if the -# statement is used at the end of a function (thus poisoning its return -# value) or when 'set -e' is active (causing even a spurious abort of -# the script in this case). -func_unset () -{ - { eval $1=; unset $1; } -} -unset=func_unset - - -# func_cmp_s FILE1 FILE2 -# ---------------------- -# Return non-zero exit status unless FILE1 and FILE2 are identical, without -# any output at all, even error messages. -func_cmp_s () -{ - $debug_cmd - - # This function relies on non-zero exit status, which will cause the - # program to exit when running in 'set -e' mode. - $CMP "$@" >/dev/null 2>&1 -} - - -# func_grep_q EXPRESSION [FILENAME..] -# ----------------------------------- -# Check whether EXPRESSION matches any line of any listed FILENAME, -# without any output at all, even error messages. -func_grep_q () -{ - $debug_cmd - - # This function relies on non-zero exit status, which will cause the - # program to exit when running in 'set -e' mode. - $GREP "$@" >/dev/null 2>&1 -} - - -# func_ifcontains LIST MEMBER YES-CMD [NO-CMD] -# -------------------------------------------- -# If whitespace-separated LIST contains MEMBER then execute YES-CMD, -# otherwise if NO-CMD was given, execute that. -func_ifcontains () -{ - $debug_cmd - - _G_wslist=$1 - _G_member=$2 - _G_yes_cmd=$3 - _G_no_cmd=${4-":"} - - _G_found=false - for _G_item in $_G_wslist; do - test "x$_G_item" = "x$_G_member" && { - _G_found=: - break - } - done - if $_G_found; then - eval "$_G_yes_cmd" - _G_status=$? - else - eval "$_G_no_cmd" - _G_status=$? - fi - - test 0 -eq "$_G_status" || exit $_G_status -} - - -# func_strpad STR WIDTH CHAR -# -------------------------- -# Trim STR, or pad with CHAR to force a total length of WIDTH. -func_strpad () -{ - $debug_cmd - - _G_width=`expr "$2" - 1` - func_strpad_result=`$ECHO "$1" |$SED ' - :a - s|^.\{0,'"$_G_width"'\}$|&'"$3"'| - ta - '` -} - - -# func_strrpad STR WIDTH CHAR -# --------------------------- -# Trim STR, or right-justify-pad with CHAR to force a total length of -# WIDTH. -func_strrpad () -{ - $debug_cmd - - _G_width=`expr "$2" - 1` - func_strrpad_result=`$ECHO "$1" |$SED ' - :a - s|^.\{0,'"$_G_width"'\}$|'"$3"'&| - ta - '` -} - - -# func_strrow INDENT FIELD WIDTH [FIELDn WIDTHn]... -# ------------------------------------------------- -# Return a string containing each FIELD left justified to WIDTH, with -# the whole thing indented by INDENT spaces. This function is used to -# render one row of aligned columns for a table by func_strtable(). -func_strrow () -{ - $debug_cmd - - func_strrow_linelen=$1; shift - - _G_row= - while test $# -gt 0; do - func_strrow_linelen=`expr $func_strrow_linelen + $2` - func_strpad "$1" $2 " " - func_append _G_row "$func_strpad_result" - shift; shift - done - - func_strrpad "$_G_row" $func_strrow_linelen " " - func_strrow_result=$func_strrpad_result -} - - -# func_strtable INDENT WIDTH1...WIDTHn HEADER1...HEADERn FIELD1...FIELDn -# ---------------------------------------------------------------------- -# Generate a string of newline-separated rows arranged in lined-up -# columns of the given WIDTHs, with the entire table indented by INDENT -# spaces. The number of columns is determined by the number of integer -# valued WIDTH arguments following INDENT. The next set (i.e. a number -# of arguments equal to the number of WIDTH arguments) of fields are -# treated as the table's column HEADERs, and are separated from the -# remainder of the table by an indented row of '-' characters. Remaining -# arguments are each aligned below the next available header, wrapping -# to a new row as necessary. Finally another row of '-' characters is -# added to mark the end of the table. -# -# For example an unindented 3 column table with 2 rows of data would be -# generated by this call: -# -# func_strtable 3 20 10 25 \ -# Header1 Header2 Header3 \ -# Row1Col1 Row1Col2 Row1Col3 \ -# Row2Col1 Row2Col2 Row2Col3 -# -# returning the following string: -# -# " Header1 Header2 Header3 -# ------------------------------------------------------- -# Row1Col1 Row1Col2 Row1Col3 -# Row2Col1 Row2Col2 Row2Col3 -# -------------------------------------------------------" -func_strtable () -{ - $debug_cmd - - # Save the indent value, we'll need it for each row we render. - _G_indent=$1; shift - - # Collect remaining numeric args into a list for reuse between - # members of each row when we call func_strrow later. - _G_widths=$1; shift - while test 0 -lt `expr "$1" : '[1-9][0-9]*$'`; do - func_append _G_widths " $1"; shift - done - - # Extract the same number of positional parameters as there are - # width elements - we'll do the header rows separately so that - # we can insert a divider line. - _G_header=$_G_indent - for _G_width in $_G_widths; do - func_append _G_header " $1 $_G_width"; shift - done - func_strrow $_G_header - - # Strip off the indent, and make a divider with '-' chars, then - # reindent. - _G_divider=`$ECHO "$func_strrow_result" \ - |$SED 's|[^ ]|-|g - :a - s|- |--|g - ta - '` - - # Append the header and divider to the running result. - func_append func_strtable_result "\ -$func_strrow_result -$_G_divider -" - - # The remaining rows are zipped between the width values we - # unwound earlier just like the header row above. - while test $# -gt 0; do - _G_row=$_G_indent - for _G_width in $_G_widths; do - func_append _G_row " $1 $_G_width"; shift - done - func_strrow $_G_row - func_append func_strtable_result "\ -$func_strrow_result -" - done - - # Mark the end of the table with a final divider line. - func_append func_strtable_result "$_G_divider" -} - - -# func_internal_error ARG... -# -------------------------- -# Echo program name prefixed message to standard error, and exit. -func_internal_error () -{ - func_fatal_error "\ -INTERNAL: " ${1+"$@"} " - Please report this bug to 'bug-gnulib@gnu.org' - in as much detail as possible." -} - - -# func_permissions_error FILE-OR-DIRECTORY -# ---------------------------------------- -# Echo program name prefixed permissions error message to standard -# error, and exit. -func_permissions_error () -{ - $debug_cmd - - func_fatal_error "Failed to create '$1', check permissions." -} - - -# func_show_eval CMD [FAIL_EXP] -# ----------------------------- -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - $debug_cmd - - $require_term_colors - - _G_cmd=$1 - _G_fail_exp=${2-':'} - - ${opt_silent-'false'} || { - func_quote_for_eval $_G_cmd - eval func_truncate_cmd $func_quote_for_eval_result - func_echo "running: $tc_bold$func_truncate_cmd_result$tc_reset" - } - - ${opt_dry_run-'false'} || { - eval "$_G_cmd" - _G_status=$? - test 0 -eq "$_G_status" || eval "(exit $_G_status); $_G_fail_exp" - } -} - - -# func_truncate_cmd CMD [ARG]... -# ------------------------------ -# For unreasonably long commands (such as a gnulib-tool invocation with -# the full module list for import), truncate CMD after the second non- -# option ARG. -func_truncate_cmd () -{ - $debug_cmd - - _G_last_arg_opt_p=false - func_truncate_cmd_result= - - set dummy "$@"; shift - - while test $# -gt 0; do - _G_opt=$1; shift - - test -n "$func_truncate_cmd_result" \ - && func_append func_truncate_cmd_result ' ' - func_append func_truncate_cmd_result "$_G_opt" - - func_len "x$func_truncate_cmd_result" - - case $_G_opt in - -*) _G_last_arg_opt_p=: ;; - *) $_G_last_arg_opt_p \ - || test "$min_cmd_len" -gt "$func_len_result" \ - || break - _G_last_arg_opt_p=false - ;; - esac - done - - test $# -gt 0 && func_append func_truncate_cmd_result "..." -} - - -# func_gitignore_entries FILE... -# ------------------------------ -# Strip blank and comment lines to leave significant entries. -func_gitignore_entries () -{ - $debug_cmd - - $SED -e '/^#/d' -e '/^$/d' "$@" -} - - -# func_insert_if_absent STR FILE... -# --------------------------------- -# If $STR is not already on a line by itself in $FILE, insert it, at the -# start. Entries are inserted at the start of the ignore list to ensure -# existing entries starting with ! are not overridden. Such entries -# support whilelisting exceptions after a more generic blacklist pattern. -# sorting the new contents of the file and replacing $FILE with the result. -func_insert_if_absent () -{ - $debug_cmd - - str=$1 - shift - - for file - do - test -f "$file" || touch "$file" - - duplicate_entries=`func_gitignore_entries "$file" |sort |uniq -d` - test -n "$duplicate_entries" \ - && func_error "duplicate entries in $file: " $duplicate_entries - - func_grep_q "^$str\$" "$file" \ - || func_verbose "inserting '$str' into '$file'" - - linesold=`func_gitignore_entries "$file" |wc -l` - linesnew=`{ $ECHO "$str"; cat "$file"; } \ - |func_gitignore_entries |sort -u |wc -l` - test "$linesold" -eq "$linesnew" \ - || { $SED "1i\\$nl$str$nl" "$file" >"$file"T && mv "$file"T "$file"; } \ - || func_permissions_error "$file" - done -} - - -# func_get_version APP -# -------------------- -# echo the version number (if any) of APP, which is looked up along your -# PATH. -func_get_version () -{ - $debug_cmd - - _G_app=$1 - - # Rather than uncomment the sed script in-situ, strip the comments - # programatically before passing the result to $SED for evaluation. - sed_get_version=`$ECHO '# extract version within line - s|.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| - t done - - # extract version at start of line - s|^\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| - t done - - d - - :done - # the following essentially does s|5.005|5.5| - s|\.0*\([1-9]\)|.\1|g - p - q' \ - |$SED '/^[ ]*#.*$/d'` - - func_tool_version_output $_G_app >/dev/null - _G_status=$? - - test 0 -ne "$_G_status" \ - || $_G_app --version 2>&1 |$SED -n "$sed_get_version" - - (exit $_G_status) -} - - -# func_check_tool APP -# ------------------- -# Search PATH for an executable at APP. -func_check_tool () -{ - $debug_cmd - - func_check_tool_result= - - case $1 in - *[\\/]*) - test -x "$1" && func_check_tool_result=$1 - ;; - *) - save_IFS=$IFS - IFS=${PATH_SEPARATOR-:} - for _G_check_tool_path in $PATH; do - IFS=$save_IFS - if test -x "$_G_check_tool_path/$1"; then - func_check_tool_result=$_G_check_tool_path/$1 - break - fi - done - IFS=$save_IFS - ;; - esac -} - - -# func_check_versions APP1 VER1 URL1 ...[APPN VERN URLN] -# ------------------------------------------------------ -func_check_versions () -{ - $debug_cmd - - func_check_versions_result=: - - while test $# -gt 0; do - _G_app=$1; shift - _G_reqver=$1; shift - _G_url=$1; shift - - # Diagnose bad buildreq formatting. - case $_G_url in - [a-z]*://*) ;; # looks like a url - *) func_fatal_error "\ -'$_G_url' from the buildreq table in -'bootstrap.conf' does not look like the URL for downloading -$_G_app. Please ensure that buildreq is a strict newline -delimited list of triples; 'program min-version url'." - ;; - esac - - # Honor $APP variables ($TAR, $AUTOCONF, etc.) - _G_appvar=`echo $_G_app |tr '[a-z]' '[A-Z]'` - test TAR = "$_G_appvar" && _G_appvar=AMTAR - eval "_G_app=\${$_G_appvar-$_G_app}" - - # Fail if no version specified, but the program can't be found. - if test x- = "x$_G_reqver"; then - func_check_tool $_G_app - if test -z "$func_check_tool_result"; then - func_error "Prerequisite '$_G_app' not not found. Please install it, or -'export $_G_appvar=/path/to/$_G_app'." - func_check_versions_result=false - else - func_verbose "found '$func_check_tool_result' for $_G_appvar." - fi - else - _G_instver=`func_get_version $_G_app` - - # Fail if --version didn't work. - if test -z "$_G_instver"; then - func_error "Prerequisite '$_G_app' not found. Please install it, or -'export $_G_appvar=/path/to/$_G_app'." - func_check_versions_result=false - - # Fail if a newer version than what we have is required. - else - func_verbose "found '$_G_app' version $_G_instver." - - case $_G_reqver in - =*) - # If $buildreq version starts with '=', version must - # match the installed program exactly. - test "x$_G_reqver" = "x=$_G_instver" || { - func_error "\ - '$_G_app' version == $_G_instver is too old - 'exactly $_G_app-$_G_reqver is required" - func_check_versions_result=false - } - ;; - *) - # Otherwise, anything that is not older is a match. - func_lt_ver "$_G_reqver" "$_G_instver" || { - func_error "\ - '$_G_app' version == $_G_instver is too old - '$_G_app' version >= $_G_reqver is required" - func_check_versions_result=false - } - ;; - esac - fi - fi - done -} - - -# func_cleanup_gnulib -# ------------------- -# Recursively delete everything below the path in the global variable -# GNULIB_PATH. -func_cleanup_gnulib () -{ - $debug_cmd - - _G_status=$? - $RM -fr "$gnulib_path" - exit $_G_status -} - - -# func_download_po_files SUBDIR DOMAIN -# ------------------------------------ -func_download_po_files () -{ - $debug_cmd - - func_echo "getting translations into $1 for $2..." - _G_cmd=`printf "$po_download_command_format" "$2" "$1"` - eval "$_G_cmd" -} - - -# func_update_po_files PO_DIR DOMAIN -# ---------------------------------- -# Mirror .po files to $po_dir/.reference and copy only the new -# or modified ones into $po_dir. Also update $po_dir/LINGUAS. -# Note po files that exist locally only are left in $po_dir but will -# not be included in LINGUAS and hence will not be distributed. -func_update_po_files () -{ - $debug_cmd - - # Directory containing primary .po files. - # Overwrite them only when we're sure a .po file is new. - _G_po_dir=$1 - _G_domain=$2 - - # Mirror *.po files into this dir. - # Usually contains *.s1 checksum files. - _G_ref_po_dir=$_G_po_dir/.reference - - test -d "$_G_ref_po_dir" || mkdir $_G_ref_po_dir || return - func_download_po_files $_G_ref_po_dir $_G_domain \ - && ls "$_G_ref_po_dir"/*.po 2>/dev/null \ - |$SED -e 's|.*/||' -e 's|\.po$||' > "$_G_po_dir/LINGUAS" || return - - # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6+. - func_find_tool SHA1SUM sha1sum gsha1sum shasum sha1 - - test -n "$SHA1SUM" || func_fatal_error "\ -Please install GNU Coreutils, or 'export SHA1SUM=/path/to/sha1sum'." - - _G_langs=`cd $_G_ref_po_dir && echo *.po|$SED 's|\.po||g'` - test '*' = "$_G_langs" && _G_langs=x - for _G_po in $_G_langs; do - case $_G_po in x) continue;; esac - _G_new_po=$_G_ref_po_dir/$_G_po.po - _G_cksum_file=$_G_ref_po_dir/$_G_po.s1 - if ! test -f "$_G_cksum_file" || - ! test -f "$_G_po_dir/$_G_po.po" || - ! $SHA1SUM -c "$_G_cksum_file" \ - < "$_G_new_po" > /dev/null; then - echo "updated $_G_po_dir/$_G_po.po..." - cp "$_G_new_po" "$_G_po_dir/$_G_po.po" \ - && $SHA1SUM < "$_G_new_po" > "$_G_cksum_file" || return - fi - done -} - - - -## --------------- ## -## Option parsing. ## -## --------------- ## - -# Hook in the functions to make sure our own options are parsed during -# the option parsing loop. - -usage='$progpath [OPTION]...' - -# Short help message in response to '-h'. Add to this in 'bootstrap.conf' -# if you accept any additional options. -usage_message="Common Bootstrap Options: - -c, --copy copy files instead of creating symbolic links. - --debug enable verbose shell tracing - -n, --dry-run print commands rather than running them - -f, --force attempt to bootstrap even if the sources seem not - to have been checked out. - --gnulib-srcdir=DIRNAME - specify a local directory where gnulib sources - reside. Use this if you already have the gnulib - sources on your machine, and don't want to waste - your bandwidth downloading them again. Defaults to - \$GNULIB_SRCDIR. - --no-warnings equivalent to '-Wnone' - --skip-git do not fetch files from remote repositories - --skip-po do not download po files. - -v, --verbose verbosely report processing - --version print version information and exit - -W, --warnings=CATEGORY - report the warnings falling in CATEGORY [all] - -h, --help print short or long help message and exit -" - -# Additional text appended to 'usage_message' in response to '--help'. -long_help_message=$long_help_message" - 'recommend' show warnings about missing recommended packages - 'settings' show warnings about missing '$progname.conf' settings - 'upgrade' show warnings about out-dated files - -If the file '$progname.conf' exists in the same directory as this -script, its contents are read as shell variables to configure the -bootstrap. - -For build prerequisites, environment variables like \$AUTOCONF and -\$AMTAR are honored. - -Running without arguments will suffice in most cases. -" - -# Warning categories used by 'bootstrap', append others if you use them -# in your 'bootstrap.conf'. -warning_categories='recommend settings upgrade' - - -# bootstrap_options_prep [ARG]... -# ------------------------------- -# Preparation for options parsed by Bootstrap. -bootstrap_options_prep () -{ - $debug_cmd - - # Option defaults: - opt_copy=${copy-'false'} - opt_dry_run=false - opt_force=false - opt_gnulib_srcdir=$GNULIB_SRCDIR - opt_skip_git=false - opt_skip_po=false - - # Pass back the list of options we consumed. - func_quote_for_eval ${1+"$@"} - bootstrap_options_prep_result=$func_quote_for_eval_result -} -func_add_hook func_options_prep bootstrap_options_prep - - -# bootstrap_parse_options [ARG]... -# -------------------------------- -# Provide handling for Bootstrap specific options. -bootstrap_parse_options () -{ - $debug_cmd - - # Perform our own loop to consume as many options as possible in - # each iteration. - while test $# -gt 0; do - _G_opt=$1 - shift - case $_G_opt in - --dry-run|--dryrun|-n) - opt_dry_run=: ;; - --copy|-c) opt_copy=: ;; - --force|-f) opt_force=: ;; - - --gnulib-srcdir) - test $# = 0 && func_missing_arg $_G_opt && break - opt_gnulib_srcdir=$1 - shift - ;; - - --skip-git|--no-git) - opt_skip_git=: - ;; - - --skip-po|--no-po) - opt_skip_po=: - ;; - - # Separate non-argument short options: - -c*|-f*|-n*) - func_split_short_opt "$_G_opt" - set dummy "$func_split_short_opt_name" \ - "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; - esac - done - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - bootstrap_parse_options_result=$func_quote_for_eval_result -} -func_add_hook func_parse_options bootstrap_parse_options - - -# bootstrap_validate_options [ARG]... -# ----------------------------------- -# Perform any sanity checks on option settings and/or unconsumed -# arguments. -bootstrap_validate_options () -{ - $debug_cmd - - # Validate options. - test $# -gt 0 \ - && func_fatal_help "too many arguments" - - # Pass back the (empty) list of unconsumed options. - func_quote_for_eval ${1+"$@"} - bootstrap_validate_options_result=$func_quote_for_eval_result -} -func_add_hook func_validate_options bootstrap_validate_options - - -## -------------------------------------------------- ## -## Source package customisations in 'bootstrap.conf'. ## -## -------------------------------------------------- ## - -# Override the default configuration, if necessary. -# Make sure that bootstrap.conf is sourced from the current directory -# if we were invoked as "sh bootstrap". -case $0 in - */*) test -r "$0.conf" && . "$0.conf" ;; - *) test -r "$0.conf" && . ./"$0.conf" ;; -esac - - -## ------------------------------- ## -## Actually perform the bootstrap. ## -## ------------------------------- ## - -func_bootstrap ${1+"$@"} - -# The End. -exit ${exit_status-$EXIT_SUCCESS} - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "500/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: diff --git a/bootstrap.conf b/bootstrap.conf deleted file mode 100644 index ae8a642..0000000 --- a/bootstrap.conf +++ /dev/null @@ -1,72 +0,0 @@ -# bootstrap.conf (Stdlib) version 2015-01-03 -# -# Copyright (C) 2013-2015 Gary V. Vaughan -# Written by Gary V. Vaughan, 2013 - -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html. - - -## -------------- ## -## Configuration. ## -## -------------- ## - -# List of programs, minimum versions, and software urls required to -# bootstrap, maintain and release this project. - -buildreq=' - git - http://git-scm.com - ldoc 1.4.2 http://rocks.moonscript.org/manifests/steved/ldoc-1.4.2-1.rockspec - specl 14.1.0 http://rocks.moonscript.org/manifests/gvvaughan/specl-14.1.0-1.rockspec -' - -# List of slingshot files to link into stdlib tree before autotooling. -slingshot_files=' - .autom4te.cfg - GNUmakefile - Makefile.am - build-aux/do-release-commit-and-tag - build-aux/gitlog-to-changelog - build-aux/mkrockspecs - build-aux/release.mk - build-aux/rockspecs.mk - build-aux/sanity.mk - build-aux/specl.mk - build-aux/update-copyright - m4/ax_lua.m4 - travis.yml.in -' - -# Prequisite rocks that need to be installed for travis builds to work. -travis_extra_rocks=' - ansicolors - ldoc - specl -' - -# No need to do any gnulib-tooling here. -gnulib_tool=true - - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "# bootstrap.conf (Stdlib) version " -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "$" -# End: diff --git a/build-aux/config.ld b/build-aux/config.ld new file mode 100644 index 0000000..856fa87 --- /dev/null +++ b/build-aux/config.ld @@ -0,0 +1,48 @@ +-- -*- lua -*- +title = "stdlib 41.2.2 Reference" +project = "stdlib 41.2.2" +description = [[ +# Standard Lua Libraries + +This is a collection of Lua libraries for Lua 5.1 (including LuaJIT), +5.2, 5.3 and 5.4. Stdlib has no prerequisites beyond a standard Lua +system. + +## LICENSE + +The libraries are copyright by their authors 2000-2018, and released under +the MIT license (the same license as Lua itself). There is no warranty. +]] + +dir = "../doc" + +file = { + -- Modules + "../lib/std.lua", + "../lib/std/debug.lua", + "../lib/std/functional.lua", + "../lib/std/io.lua", + "../lib/std/math.lua", + "../lib/std/operator.lua", + "../lib/std/package.lua", + "../lib/std/strict.lua", + "../lib/std/string.lua", + "../lib/std/table.lua", + "../lib/std/tree.lua", + + -- Classes + "../lib/std/container.lua", + "../lib/std/object.lua", + "../lib/std/list.lua", + "../lib/std/optparse.lua", + "../lib/std/set.lua", + "../lib/std/strbuf.lua", +} + +new_type ("object", "Objects", false, "Fields") + +format = "markdown" + +sort = true + +backtick_references = false diff --git a/build-aux/config.ld.in b/build-aux/config.ld.in index 7eff64d..0571ab7 100644 --- a/build-aux/config.ld.in +++ b/build-aux/config.ld.in @@ -1,8 +1,20 @@ -- -*- lua -*- -title = "@PACKAGE_STRING@ Reference" -project = "@PACKAGE_STRING@" -description = "Standard Lua Libraries" -dir = "." +title = "stdlib @PACKAGE_VERSION@ Reference" +project = "stdlib @PACKAGE_VERSION@" +description = [[ +# Standard Lua Libraries + +This is a collection of Lua libraries for Lua 5.1 (including LuaJIT), +5.2, 5.3 and 5.4. Stdlib has no prerequisites beyond a standard Lua +system. + +## LICENSE + +The libraries are copyright by their authors 2000-2018, and released under +the MIT license (the same license as Lua itself). There is no warranty. +]] + +dir = "../doc" file = { -- Modules @@ -30,5 +42,7 @@ file = { new_type ("object", "Objects", false, "Fields") format = "markdown" -backtick_references = false + sort = true + +backtick_references = false diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog deleted file mode 100755 index e02d34c..0000000 --- a/build-aux/gitlog-to-changelog +++ /dev/null @@ -1,432 +0,0 @@ -eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' - & eval 'exec perl -wS "$0" $argv:q' - if 0; -# Convert git log output to ChangeLog format. - -my $VERSION = '2012-07-29 06:11'; # UTC -# The definition above must lie within the first 8 lines in order -# for the Emacs time-stamp write hook (at end) to update it. -# If you change this file with Emacs, please let the write hook -# do its job. Otherwise, update this string manually. - -# Copyright (C) 2008-2013 Free Software Foundation, Inc. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Written by Jim Meyering - -use strict; -use warnings; -use Getopt::Long; -use POSIX qw(strftime); - -(my $ME = $0) =~ s|.*/||; - -# use File::Coda; # http://meyering.net/code/Coda/ -END { - defined fileno STDOUT or return; - close STDOUT and return; - warn "$ME: failed to close standard output: $!\n"; - $? ||= 1; -} - -sub usage ($) -{ - my ($exit_code) = @_; - my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); - if ($exit_code != 0) - { - print $STREAM "Try '$ME --help' for more information.\n"; - } - else - { - print $STREAM < ChangeLog - $ME -- -n 5 foo > last-5-commits-to-branch-foo - -SPECIAL SYNTAX: - -The following types of strings are interpreted specially when they appear -at the beginning of a log message line. They are not copied to the output. - - Copyright-paperwork-exempt: Yes - Append the "(tiny change)" notation to the usual "date name email" - ChangeLog header to mark a change that does not require a copyright - assignment. - Co-authored-by: Joe User - List the specified name and email address on a second - ChangeLog header, denoting a co-author. - Signed-off-by: Joe User - These lines are simply elided. - -In a FILE specified via --amend, comment lines (starting with "#") are ignored. -FILE must consist of pairs where SHA is a 40-byte SHA1 (alone on -a line) referring to a commit in the current project, and CODE refers to one -or more consecutive lines of Perl code. Pairs must be separated by one or -more blank line. - -Here is sample input for use with --amend=FILE, from coreutils: - -3a169f4c5d9159283548178668d2fae6fced3030 -# fix typo in title: -s/all tile types/all file types/ - -1379ed974f1fa39b12e2ffab18b3f7a607082202 -# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself. -# Change the author to be Paul. Note the escaped "@": -s,Jim .*>,Paul Eggert , - -EOF - } - exit $exit_code; -} - -# If the string $S is a well-behaved file name, simply return it. -# If it contains white space, quotes, etc., quote it, and return the new string. -sub shell_quote($) -{ - my ($s) = @_; - if ($s =~ m![^\w+/.,-]!) - { - # Convert each single quote to '\'' - $s =~ s/\'/\'\\\'\'/g; - # Then single quote the string. - $s = "'$s'"; - } - return $s; -} - -sub quoted_cmd(@) -{ - return join (' ', map {shell_quote $_} @_); -} - -# Parse file F. -# Comment lines (starting with "#") are ignored. -# F must consist of pairs where SHA is a 40-byte SHA1 -# (alone on a line) referring to a commit in the current project, and -# CODE refers to one or more consecutive lines of Perl code. -# Pairs must be separated by one or more blank line. -sub parse_amend_file($) -{ - my ($f) = @_; - - open F, '<', $f - or die "$ME: $f: failed to open for reading: $!\n"; - - my $fail; - my $h = {}; - my $in_code = 0; - my $sha; - while (defined (my $line = )) - { - $line =~ /^\#/ - and next; - chomp $line; - $line eq '' - and $in_code = 0, next; - - if (!$in_code) - { - $line =~ /^([0-9a-fA-F]{40})$/ - or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"), - $fail = 1, next; - $sha = lc $1; - $in_code = 1; - exists $h->{$sha} - and (warn "$ME: $f:$.: duplicate SHA1\n"), - $fail = 1, next; - } - else - { - $h->{$sha} ||= ''; - $h->{$sha} .= "$line\n"; - } - } - close F; - - $fail - and exit 1; - - return $h; -} - -# git_dir_option $SRCDIR -# -# From $SRCDIR, the --git-dir option to pass to git (none if $SRCDIR -# is undef). Return as a list (0 or 1 element). -sub git_dir_option($) -{ - my ($srcdir) = @_; - my @res = (); - if (defined $srcdir) - { - my $qdir = shell_quote $srcdir; - my $cmd = "cd $qdir && git rev-parse --show-toplevel"; - my $qcmd = shell_quote $cmd; - my $git_dir = qx($cmd); - defined $git_dir - or die "$ME: cannot run $qcmd: $!\n"; - $? == 0 - or die "$ME: $qcmd had unexpected exit code or signal ($?)\n"; - chomp $git_dir; - push @res, "--git-dir=$git_dir/.git"; - } - @res; -} - -{ - my $since_date; - my $format_string = '%s%n%b%n'; - my $amend_file; - my $append_dot = 0; - my $cluster = 1; - my $strip_tab = 0; - my $strip_cherry_pick = 0; - my $srcdir; - GetOptions - ( - help => sub { usage 0 }, - version => sub { print "$ME version $VERSION\n"; exit }, - 'since=s' => \$since_date, - 'format=s' => \$format_string, - 'amend=s' => \$amend_file, - 'append-dot' => \$append_dot, - 'cluster!' => \$cluster, - 'strip-tab' => \$strip_tab, - 'strip-cherry-pick' => \$strip_cherry_pick, - 'srcdir=s' => \$srcdir, - ) or usage 1; - - defined $since_date - and unshift @ARGV, "--since=$since_date"; - - # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/) - # that makes a correction in the log or attribution of that commit. - my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {}; - - my @cmd = ('git', - git_dir_option $srcdir, - qw(log --log-size), - '--pretty=format:%H:%ct %an <%ae>%n%n'.$format_string, @ARGV); - open PIPE, '-|', @cmd - or die ("$ME: failed to run '". quoted_cmd (@cmd) ."': $!\n" - . "(Is your Git too old? Version 1.5.1 or later is required.)\n"); - - my $prev_multi_paragraph; - my $prev_date_line = ''; - my @prev_coauthors = (); - while (1) - { - defined (my $in = ) - or last; - $in =~ /^log size (\d+)$/ - or die "$ME:$.: Invalid line (expected log size):\n$in"; - my $log_nbytes = $1; - - my $log; - my $n_read = read PIPE, $log, $log_nbytes; - $n_read == $log_nbytes - or die "$ME:$.: unexpected EOF\n"; - - # Extract leading hash. - my ($sha, $rest) = split ':', $log, 2; - defined $sha - or die "$ME:$.: malformed log entry\n"; - $sha =~ /^[0-9a-fA-F]{40}$/ - or die "$ME:$.: invalid SHA1: $sha\n"; - - # If this commit's log requires any transformation, do it now. - my $code = $amend_code->{$sha}; - if (defined $code) - { - eval 'use Safe'; - my $s = new Safe; - # Put the unpreprocessed entry into "$_". - $_ = $rest; - - # Let $code operate on it, safely. - my $r = $s->reval("$code") - or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n"; - - # Note that we've used this entry. - delete $amend_code->{$sha}; - - # Update $rest upon success. - $rest = $_; - } - - # Remove lines inserted by "git cherry-pick". - if ($strip_cherry_pick) - { - $rest =~ s/^\s*Conflicts:\n.*//sm; - $rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m; - } - - my @line = split "\n", $rest; - my $author_line = shift @line; - defined $author_line - or die "$ME:$.: unexpected EOF\n"; - $author_line =~ /^(\d+) (.*>)$/ - or die "$ME:$.: Invalid line " - . "(expected date/author/email):\n$author_line\n"; - - # Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog - # `(tiny change)' annotation. - my $tiny = (grep (/^Copyright-paperwork-exempt:\s+[Yy]es$/, @line) - ? ' (tiny change)' : ''); - - my $date_line = sprintf "%s %s$tiny\n", - strftime ("%F", localtime ($1)), $2; - - my @coauthors = grep /^Co-authored-by:.*$/, @line; - # Omit meta-data lines we've already interpreted. - @line = grep !/^(?:Signed-off-by:[ ].*>$ - |Co-authored-by:[ ] - |Copyright-paperwork-exempt:[ ] - )/x, @line; - - # Remove leading and trailing blank lines. - if (@line) - { - while ($line[0] =~ /^\s*$/) { shift @line; } - while ($line[$#line] =~ /^\s*$/) { pop @line; } - } - - # Record whether there are two or more paragraphs. - my $multi_paragraph = grep /^\s*$/, @line; - - # Format 'Co-authored-by: A U Thor ' lines in - # standard multi-author ChangeLog format. - for (@coauthors) - { - s/^Co-authored-by:\s*/\t /; - s/\s*/ - or warn "$ME: warning: missing email address for " - . substr ($_, 5) . "\n"; - } - - # If clustering of commit messages has been disabled, if this header - # would be different from the previous date/name/email/coauthors header, - # or if this or the previous entry consists of two or more paragraphs, - # then print the header. - if ( ! $cluster - || $date_line ne $prev_date_line - || "@coauthors" ne "@prev_coauthors" - || $multi_paragraph - || $prev_multi_paragraph) - { - $prev_date_line eq '' - or print "\n"; - print $date_line; - @coauthors - and print join ("\n", @coauthors), "\n"; - } - $prev_date_line = $date_line; - @prev_coauthors = @coauthors; - $prev_multi_paragraph = $multi_paragraph; - - # If there were any lines - if (@line == 0) - { - warn "$ME: warning: empty commit message:\n $date_line\n"; - } - else - { - if ($append_dot) - { - # If the first line of the message has enough room, then - if (length $line[0] < 72) - { - # append a dot if there is no other punctuation or blank - # at the end. - $line[0] =~ /[[:punct:]\s]$/ - or $line[0] .= '.'; - } - } - - # Remove one additional leading TAB from each line. - $strip_tab - and map { s/^\t// } @line; - - # Prefix each non-empty line with a TAB. - @line = map { length $_ ? "\t$_" : '' } @line; - - print "\n", join ("\n", @line), "\n"; - } - - defined ($in = ) - or last; - $in ne "\n" - and die "$ME:$.: unexpected line:\n$in"; - } - - close PIPE - or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; - # FIXME-someday: include $PROCESS_STATUS in the diagnostic - - # Complain about any unused entry in the --amend=F specified file. - my $fail = 0; - foreach my $sha (keys %$amend_code) - { - warn "$ME:$amend_file: unused entry: $sha\n"; - $fail = 1; - } - - exit $fail; -} - -# Local Variables: -# mode: perl -# indent-tabs-mode: nil -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "my $VERSION = '" -# time-stamp-format: "%:y-%02m-%02d %02H:%02M" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "'; # UTC" -# End: diff --git a/build-aux/install-sh b/build-aux/install-sh deleted file mode 100755 index 0b0fdcb..0000000 --- a/build-aux/install-sh +++ /dev/null @@ -1,501 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2013-12-25.23; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -tab=' ' -nl=' -' -IFS=" $tab$nl" - -# Set DOITPROG to "echo" to test this script. - -doit=${DOITPROG-} -doit_exec=${doit:-exec} - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -is_target_a_directory=possibly - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) - is_target_a_directory=always - dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) is_target_a_directory=never;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -# We allow the use of options -d and -T together, by making -d -# take the precedence; this is for compatibility with GNU install. - -if test -n "$dir_arg"; then - if test -n "$dst_arg"; then - echo "$0: target directory not allowed when installing a directory." >&2 - exit 1 - fi -fi - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call 'install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - if test $# -gt 1 || test "$is_target_a_directory" = always; then - if test ! -d "$dst_arg"; then - echo "$0: $dst_arg: Is not a directory." >&2 - exit 1 - fi - fi -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for 'test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test "$is_target_a_directory" = never; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - dstdir=`dirname "$dst"` - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - oIFS=$IFS - IFS=/ - set -f - set fnord $dstdir - shift - set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - set +f && - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/build-aux/missing b/build-aux/missing deleted file mode 100755 index f62bbae..0000000 --- a/build-aux/missing +++ /dev/null @@ -1,215 +0,0 @@ -#! /bin/sh -# Common wrapper for a few potentially missing GNU programs. - -scriptversion=2013-10-28.13; # UTC - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# Originally written by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" - exit 1 -fi - -case $1 in - - --is-lightweight) - # Used by our autoconf macros to check whether the available missing - # script is modern enough. - exit 0 - ;; - - --run) - # Back-compat with the calling convention used by older automake. - shift - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due -to PROGRAM being missing or too old. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal autoconf autoheader autom4te automake makeinfo - bison yacc flex lex help2man - -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" - exit 1 - ;; - -esac - -# Run the given program, remember its exit status. -"$@"; st=$? - -# If it succeeded, we are done. -test $st -eq 0 && exit 0 - -# Also exit now if we it failed (or wasn't found), and '--version' was -# passed; such an option is passed most likely to detect whether the -# program is present and works. -case $2 in --version|--help) exit $st;; esac - -# Exit code 63 means version mismatch. This often happens when the user -# tries to use an ancient version of a tool on a file that requires a -# minimum version. -if test $st -eq 63; then - msg="probably too old" -elif test $st -eq 127; then - # Program was missing. - msg="missing on your system" -else - # Program was found and executed, but failed. Give up. - exit $st -fi - -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software - -program_details () -{ - case $1 in - aclocal|automake) - echo "The '$1' program is part of the GNU Automake package:" - echo "<$gnu_software_URL/automake>" - echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/autoconf>" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - autoconf|autom4te|autoheader) - echo "The '$1' program is part of the GNU Autoconf package:" - echo "<$gnu_software_URL/autoconf/>" - echo "It also requires GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - esac -} - -give_advice () -{ - # Normalize program name to check for. - normalized_program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - - printf '%s\n' "'$1' is $msg." - - configure_deps="'configure.ac' or m4 files included by 'configure.ac'" - case $normalized_program in - autoconf*) - echo "You should only need it if you modified 'configure.ac'," - echo "or m4 files included by it." - program_details 'autoconf' - ;; - autoheader*) - echo "You should only need it if you modified 'acconfig.h' or" - echo "$configure_deps." - program_details 'autoheader' - ;; - automake*) - echo "You should only need it if you modified 'Makefile.am' or" - echo "$configure_deps." - program_details 'automake' - ;; - aclocal*) - echo "You should only need it if you modified 'acinclude.m4' or" - echo "$configure_deps." - program_details 'aclocal' - ;; - autom4te*) - echo "You might have modified some maintainer files that require" - echo "the 'autom4te' program to be rebuilt." - program_details 'autom4te' - ;; - bison*|yacc*) - echo "You should only need it if you modified a '.y' file." - echo "You may want to install the GNU Bison package:" - echo "<$gnu_software_URL/bison/>" - ;; - lex*|flex*) - echo "You should only need it if you modified a '.l' file." - echo "You may want to install the Fast Lexical Analyzer package:" - echo "<$flex_URL>" - ;; - help2man*) - echo "You should only need it if you modified a dependency" \ - "of a man page." - echo "You may want to install the GNU Help2man package:" - echo "<$gnu_software_URL/help2man/>" - ;; - makeinfo*) - echo "You should only need it if you modified a '.texi' file, or" - echo "any other file indirectly affecting the aspect of the manual." - echo "You might want to install the Texinfo package:" - echo "<$gnu_software_URL/texinfo/>" - echo "The spurious makeinfo call might also be the consequence of" - echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" - echo "want to install GNU make:" - echo "<$gnu_software_URL/make/>" - ;; - *) - echo "You might have modified some files without having the proper" - echo "tools for further handling them. Check the 'README' file, it" - echo "often tells you about the needed prerequisites for installing" - echo "this package. You may also peek at any GNU archive site, in" - echo "case some other package contains this missing '$1' program." - ;; - esac -} - -give_advice "$1" | sed -e '1s/^/WARNING: /' \ - -e '2,$s/^/ /' >&2 - -# Propagate the correct exit status (expected to be 127 for a program -# not found, 63 for a program that failed due to version mismatch). -exit $st - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/build-aux/mkrockspecs b/build-aux/mkrockspecs deleted file mode 100755 index 622d328..0000000 --- a/build-aux/mkrockspecs +++ /dev/null @@ -1,463 +0,0 @@ -#!/bin/sh -SH=--[[ # -*- mode: lua; -*- -## Slingshot rockspec generator. -## -## This file is distributed with Slingshot, and licensed under the -## terms of the MIT license reproduced below. - -## ==================================================================== -## Copyright (C) 2013-2015 Gary V. Vaughan -## -## Permission is hereby granted, free of charge, to any person -## obtaining a copy of this software and associated documentation -## files (the "Software"), to deal in the Software without restriction, -## including without limitation the rights to use, copy, modify, merge, -## publish, distribute, sublicense, and/or sell copies of the Software, -## and to permit persons to whom the Software is furnished to do so, -## subject to the following conditions: -## -## The above copyright notice and this permission notice shall be -## included in all copies or substantial portions of the Software. -## -## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- -## MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -## FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -## CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -## WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -## ==================================================================== - - -_lua_version_re='"Lua 5."[123]*' -_lua_binaries='lua lua5.3 lua53 lua5.2 lua52 luajit lua5.1 lua51' - -export LUA -export LUA_INIT -export LUA_INIT_5_2 -export LUA_INIT_5_3 -export LUA_PATH -export LUA_CPATH - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi - -# If LUA is not set, search PATH for something suitable. -test -n "$LUA" || { - # Check that the supplied binary is executable and returns a compatible - # Lua version number. - func_vercheck () - { - test -x "$1" && { - eval 'case `'$1' -e "print (_VERSION)" 2>/dev/null` in - '"$_lua_version_re"') LUA='$1' ;; - esac' - } - } - - progname=`echo "$0" |${SED-sed} 's|.*/||'` - - save_IFS="$IFS" - LUA= - for x in $_lua_binaries; do - IFS=: - for dir in $PATH; do - IFS="$save_IFS" - func_vercheck "$dir/$x" - test -n "$LUA" && break - done - IFS="$save_IFS" - test -n "$LUA" && break - e="${e+$e\n}$progname: command not found on PATH: $x" - done -} - -test -n "$LUA" || { - printf "${e+$e\n}$progname: retry after 'export LUA=/path/to/lua'\n" >&2 - exit 1 -} - -LUA_INIT= -LUA_INIT_5_2= -LUA_INIT_5_3= - -# Reexecute using the interpreter suppiled in LUA, or found above. -exec "$LUA" "$0" "$@" -]]SH - - ---[[ ============== ]]-- ---[[ Parse options. ]]-- ---[[ ============== ]]-- - -local usage = 'Usage: mkrockspecs [OPTIONS] PACKAGE VERSION [REVISION] [FILE]\n' - -prog = { - name = arg[0] and arg[0]:gsub (".*/", "") or "mkrockspecs", - - opts = {}, -} - --- Print an argument processing error message, and return non-zero exit --- status. -local function opterr (msg) - io.stderr:write (usage) - io.stderr:write (prog.name .. ": error: " .. msg .. ".\n") - io.stderr:write (prog.name .. ": Try '" .. prog.name .. " --help' for help,\n") - os.exit (2) -end - -local function setopt (optname, arglist, i) - local opt = arglist[i] - if i + 1 > #arglist then - opterr ("option '" .. opt .. "' requires an argument") - end - prog.opts[optname] = arglist[i + 1] - return i + 1 -end - -local function die (msg) - msg:gsub ("([^\n]+)\n?", - function () - io.stderr:write (prog.name .. ": error: " .. msg.. "\n") - end) - os.exit (1) -end - -prog["--help"] = function () - print (usage .. [[ - -Convert a YAML configuration file into a full rockspec. - -If FILE is provided, load it as the base configuration, otherwise if -there is a 'rockspec.conf' in the current directory use that, or else -wait for input on stdin. If FILE is '-', force reading base config- -uration from stdin. - -PACKAGE and VERSION are the package name and version number as defined -by 'configure.ac' or similar. REVISION is only required for a revised -rockspec if the default "-1" revision was released with errors. - - -b, --branch=BRANCH make git rockspec use BRANCH - -m, --module-dir=ROOT directory of lua-files for builtin build type - -r, --repository=REPO set the repository name (default=PACKAGE) - --help print this help, then exit - --version print version number, then exit - -Report bugs to http://github.com/gvvaughan/slingshot/issues.]]) - os.exit (0) -end - -prog["--version"] = function () - print [[mkrockspecs (slingshot) 8.0.0 -Written by Gary V. Vaughan , 2013 - -Copyright (C) 2013, Gary V. Vaughan -Slingshot comes with ABSOLUTELY NO WARRANTY. -See source files for individual license conditions.]] - os.exit (0) -end - -prog["-b"] = function (argl, i) return setopt ("branch", argl, i) end -prog["--branch"] = prog["-b"] - -prog["-m"] = function (argl, i) return setopt ("module_root", argl, i) end -prog["--module-dir"] = prog["-m"] - -prog["-r"] = function (argl, i) return setopt ("repository", argl, i) end -prog["--repository"] = prog["-r"] - -local nonopts -local i = 0 -while i < #arg do - i = i + 1 - local opt = arg[i] - - -- Collect remaining arguments not nonopts to save back into _G.arg later. - if type (nonopts) == "table" then - table.insert (nonopts, opt) - - -- Run prog.option handler. - elseif opt:sub (1,1) == "-" and type (prog[opt]) == "function" then - i = prog[opt] (arg, i) - - -- End of option arguments. - elseif opt == "--" then - nonopts = {} - - -- Diagnose unknown command line options. - elseif opt:sub (1, 1) == "-" then - opterr ("unrecognized option '" .. opt .. "'") - - -- First non-option argument marks the end of options. - else - nonopts = { opt } - end -end - --- put non-option args back into global arg table. -nonopts = nonopts or {} -nonopts[0] = arg[0] -_G.arg = nonopts - -if select ("#", ...) < 2 then - opterr ("only " .. select ("#", ...) .. " arguments provided") -end - -local package = arg[1] -local version = arg[2] -local revision = arg[3] or "1" -local conf = arg[4] or "rockspec.conf" - --- Unless set explicity, assume the repo is named after the package. -if prog.opts.repository == nil then - prog.opts.repository = package -end - - ---[[ ================= ]]-- ---[[ Helper functions. ]]-- ---[[ ================= ]]-- - -local ok, posix = pcall (require, "posix") - -files = {} - -if ok then - -- faster version if luaposix is available - function tree (root) - for f in posix.files (root) do - local path = root .. "/" .. f - if f:match ("%.lua$") then - table.insert (files, path) - elseif f == "." or f == ".." then - -- don't go into a loop - elseif posix.stat (path, "type") == "directory" then - tree (path) - end - end - end -else - -- fallback version that executes ls in subshells - function tree (root) - local p = io.popen ("ls -1 " .. root .. " 2>/dev/null") - - if p ~= nil then - local f = p:read "*l" - while f ~= nil do - if f:match ("%.lua$") then - table.insert (files, root .. "/" .. f) - else - tree (root .. "/" .. f) - end - f = p:read "*l" - end - end - end -end - -local function escape_pattern (s) - return (string.gsub (s, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0")) -end - -local function loadmap (root) - local map = {} - tree (root) - for _, f in ipairs (files) do - local m = f:match ("^" .. escape_pattern (root) .. "/(.*)%.lua") - map [m:gsub ("/", "."):gsub ("%.init$", "")] = f:gsub ("^%./", "") - end - return map -end - - ---[[ =================== ]]-- ---[[ Load configuration. ]]-- ---[[ =================== ]]-- - -local yaml = require "lyaml" - --- Slurp io.input (). -local function slurp () - h = io.input () - if h then - local s = h:read "*a" - h:close () - return s - end -end - -if conf == "-" then - io.input (io.stdin) -else - local h = io.open (conf) - if h then - io.input (conf) - h:close () - else - io.input (io.stdin) - end -end - -local spec = yaml.load (slurp ()) -local default = { source = {} } - --- url needn't be given if it is identical to homepage. -local url -if spec.source ~= nil then - url = spec.source.url -elseif spec.description ~= nil then - url = spec.description.homepage -else - die (conf .. ": could not find source.url or description.homepage") -end -url = url:gsub ("^[a-z]*://", ""):gsub ("%.git$", "") - --- Interpolate default values. -default.package = package -default.version = version .. "-" .. revision - -configure_flags = "" -if type (spec.external_dependencies) == "table" then - CPPFLAGS, LDFLAGS = "", "" - for name, vars in pairs (spec.external_dependencies) do - if vars.library then - CPPFLAGS = CPPFLAGS .. " -I$(" .. name .. "_INCDIR)" - LDFLAGS = LDFLAGS .. " -L$(" .. name .. "_LIBDIR)" - end - end - - if string.len (CPPFLAGS) > 0 then - configure_flags = configure_flags .. - "CPPFLAGS='" .. CPPFLAGS:gsub ("^%s", "") .. "'" .. - " LDFLAGS='" .. LDFLAGS:gsub ("^%s", "") .. "'" .. - " " - end -end - --- If we have a module root, use the luarocks "builtin" type. -if version ~= "scm" and version ~= "git" then - if prog.opts.module_root ~= nil then - default.build = { - type = "builtin", - modules = loadmap (prog.opts.module_root), - } - elseif spec.build ~= nil and spec.build.modules ~= nil then - default.build = { type = "builtin" } - end -end - -default.build = default.build or { - type = "command", - build_command = "./configure " .. - "LUA='$(LUA)' LUA_INCLUDE='-I$(LUA_INCDIR)' " .. configure_flags .. - "--prefix='$(PREFIX)' --libdir='$(LIBDIR)' --datadir='$(LUADIR)' " .. - "--datarootdir='$(PREFIX)' && make clean all", - install_command = "make install luadir='$(LUADIR)' luaexecdir='$(LIBDIR)'", - copy_directories = {}, -} - --- Additional spec-type dependent values. -spec.source = spec.source or {} -spec.build = spec.build or {} -if version ~= "scm" and version ~= "git" then - spec.source.url = "http://" .. url .. "/archive/release-v" .. version .. ".zip" - spec.source.dir = prog.opts.repository .. "-release-v" .. version -else - spec.source.url = "git://" .. url .. ".git" - spec.source.branch = prog.opts.branch - spec.build.modules = nil - default.build.build_command = "LUA='$(LUA)' ./bootstrap && " .. default.build.build_command -end - - --- Recursive merge, settings from spec take precedence. Elements of src --- overwrite equivalent keys in dest. -local function merge (dest, src) - for k, v in pairs (src) do - if type (v) == "table" then - dest[k] = merge (dest[k] or {}, src[k]) - else - dest[k] = src[k] - end - end - return dest -end - -spec = merge (default, spec) - - ---[[ ======= ]]-- ---[[ Output. ]]-- ---[[ ======= ]]-- - --- Recursively format X, with pretty printing. -local function format (x, indent) - indent = indent or "" - if type (x) == "table" then - if next (x) == nil then - return "{}" - else - local s = "{\n" - - -- Collect and sort non-numeric keys first. - keys = {} - for k in pairs (x) do - if type (k) ~= "number" then table.insert (keys, k) end - end - table.sort (keys, function (a, b) return tostring (a) < tostring (b) end) - - -- Display non-numeric key pairs in sort order. - for _, k in ipairs (keys) do - s = s .. indent - if k:match ("[^_%w]") then - -- wrap keys with non-%w chars in square brackets - s = s .. '["' .. k .. '"]' - else - s = s .. k - end - s = s .. " = " .. format (x[k], indent .. " ") .. ",\n" - end - - -- And numeric key pairs last. - for i, v in ipairs (x) do - s = s .. indent .. format (v, indent .. " ") .. ",\n" - end - return s..indent:sub (1, -3).."}" - end - elseif type (x) == "string" then - return string.format ("%q", x) - else - return tostring (x) - end -end - --- Use the standard order for known keys. -for _, k in ipairs { - "package", - "version", - "description", - "source", - "dependencies", - "external_dependencies", - "build", -} do - print (k .. " = " .. format (spec[k], " ")) - spec[k] = nil -end - --- Output anything left in the table at the end. -for i, v in pairs (spec) do - print (i .. " = " .. format (v, " ")) -end - -os.exit (0) diff --git a/build-aux/release.mk b/build-aux/release.mk deleted file mode 100644 index 13dce9a..0000000 --- a/build-aux/release.mk +++ /dev/null @@ -1,393 +0,0 @@ -# Slingshot release rules for GNU Make. - -# ====================================================================== -# Copyright (C) 2001-2015 Free Software Foundation, Inc. -# Originally by Jim Meyering, Simon Josefsson, Eric Blake, -# Akim Demaille, Gary V. Vaughan, and others. -# This version by Gary V. Vaughan, 2013. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# ====================================================================== - -NOTHING_ELSE ?= - - -## --------------- ## -## GNU Make magic. ## -## --------------- ## - -# This file uses GNU Make extensions. Include it from GNUmakefile with: -# -# include build-aux/release.mk - -# Make tar archive easier to reproduce. -export TAR_OPTIONS = --owner=0 --group=0 --numeric-owner - -# Helper variables. -_empty = -_sp = $(_empty) $(_empty) - -# member-check,VARIABLE,VALID-VALUES -# ---------------------------------- -# Check that $(VARIABLE) is in the space-separated list of VALID-VALUES, and -# return it. Die otherwise. -member-check = \ - $(strip \ - $(if $($(1)), \ - $(if $(findstring $(_sp),$($(1))), \ - $(error invalid $(1): '$($(1))', expected $(2)), \ - $(or $(findstring $(_sp)$($(1))$(_sp),$(_sp)$(2)$(_sp)), \ - $(error invalid $(1): '$($(1))', expected $(2)))), \ - $(error $(1) undefined))) - -include Makefile - -## --------- ## -## Defaults. ## -## --------- ## - -GIT ?= git -LUA ?= lua -LUAROCKS ?= luarocks -TAR ?= tar - -# Override this in cfg.mk if you are using a different format in your -# NEWS file. -today ?= $(shell date +%Y-%m-%d) - -# Old releases are stored here. -release_archive_dir ?= ../release - -# Override this in cfg.mk if you follow different procedures. -release-prep-hook ?= release-prep - -_build-aux ?= build-aux -my_distdir ?= $(PACKAGE)-$(VERSION) -prev_version_file ?= $(srcdir)/.prev-version -old_NEWS_hash-file ?= $(srcdir)/local.mk -gl_noteworthy_news_ = \#\# Noteworthy changes in release ?.? (????-??-??) [?] - -PREV_VERSION = $(shell cat $(prev_version_file) 2>/dev/null) -VERSION_REGEXP = $(subst .,\.,$(VERSION)) -PREV_VERSION_REGEXP = $(subst .,\.,$(PREV_VERSION)) - - -## ------------- ## -## Distribution. ## -## ------------- ## - -gitlog_to_changelog = $(srcdir)/build-aux/gitlog-to-changelog - -dist-hook: ChangeLog -.PHONY: ChangeLog -ChangeLog: - $(AM_V_GEN)if test -d '$(srcdir)/.git'; then \ - $(gitlog_to_changelog) $(gitlog_args) > '$@T'; \ - rm -f '$@'; mv '$@T' '$@'; \ - fi - -# Override this in GNUmakefile if you don't want to automatically -# redistribute all the maintainer support files (take care that -# Travis CI is finicky about this, and will likely need tweaking -# to cope with missing any of these if you decide to omit them). - -_travis_yml ?= .travis.yml travis.yml.in - -release_extra_dist ?= \ - .autom4te.cfg \ - GNUmakefile \ - bootstrap \ - bootstrap.conf \ - local.mk \ - $(_travis_yml) \ - $(NOTHING_ELSE) - -EXTRA_DIST += \ - $(_build-aux)/release.mk \ - $(gitlog_to_changelog) \ - $(release_extra_dist) \ - $(NOTHING_ELSE) - -all-am: $(_travis_yml) - - -## -------- ## -## Release. ## -## -------- ## - -# The vast majority of what follows is preparation -in the form -# of early bail-out if something is not right yet- for the final -# check-in-release-branch rule that makes the tip of the release -# branch match the contents of a 'make distcheck' tarball. - -# Validate and return $(RELEASE_TYPE), or die. -RELEASE_TYPES = alpha beta stable -release-type = $(call member-check,RELEASE_TYPE,$(RELEASE_TYPES)) - -# This will actually make the release, including sending release -# announcements, and pushing changes back to the origin. -# Use it like this, eg: -# make RELEASE_TYPE=beta -.PHONY: release -release: - $(AM_V_GEN)$(MAKE) $(release-type) - $(AM_V_GEN)$(MAKE) push - $(AM_V_GEN)$(MAKE) upload - $(AM_V_GEN)$(MAKE) mail - -submodule-checks ?= no-submodule-changes public-submodule-commit - -.PHONY: no-submodule-changes -no-submodule-changes: - $(AM_V_GEN)if test -d $(srcdir)/.git \ - && git --version >/dev/null 2>&1; then \ - diff=$$(cd $(srcdir) && git submodule -q foreach \ - git diff-index --name-only HEAD); \ - case $$diff in '') ;; \ - *) echo '$(ME): submodule files are locally modified:'; \ - echo "$$diff"; exit 1;; esac; \ - else \ - : ; \ - fi - -# Ensure that each sub-module commit we're using is public. -# Without this, it is too easy to tag and release code that -# cannot be built from a fresh clone. -.PHONY: public-submodule-commit -public-submodule-commit: - $(AM_V_GEN)if test -d $(srcdir)/.git \ - && git --version >/dev/null 2>&1; then \ - cd $(srcdir) && \ - git submodule --quiet foreach \ - 'test "$$(git rev-parse "$$sha1")" \ - = "$$(git merge-base origin "$$sha1")"' \ - || { echo '$(ME): found non-public submodule commit' >&2; \ - exit 1; }; \ - else \ - : ; \ - fi -# This rule has a high enough utility/cost ratio that it should be a -# dependent of "check" by default. However, some of us do occasionally -# commit a temporary change that deliberately points to a non-public -# submodule commit, and want to be able to use rules like "make check". -# In that case, run e.g., "make check gl_public_submodule_commit=" -# to disable this test. -gl_public_submodule_commit ?= public-submodule-commit -check: $(gl_public_submodule_commit) - -# These targets do all the file shuffling necessary for a release, but -# purely locally, so you can rewind and redo before pushing anything -# to origin or sending release announcements. Use it like this, eg: -# -# make beta -.PHONY: alpha beta stable -alpha beta stable: $(submodule-checks) - $(AM_V_GEN)test $@ = stable && \ - { echo $(VERSION) |$(EGREP) '^[0-9]+(\.[0-9]+)*$$' >/dev/null \ - || { echo "invalid version string: $(VERSION)" 1>&2; exit 1;};}\ - || : - $(AM_V_at)$(MAKE) prev-version-check - $(AM_V_at)$(MAKE) vc-diff-check - $(AM_V_at)$(MAKE) release-commit RELEASE_TYPE=$@ - $(AM_V_at)$(MAKE) news-check - $(AM_V_at)$(MAKE) distcheck - $(AM_V_at)$(MAKE) check - $(AM_V_at)$(MAKE) $(release-prep-hook) RELEASE_TYPE=$@ - $(AM_V_at)$(MAKE) check-in-release-branch - -prev-version-check: - $(AM_V_at)if test -z "`$(GIT) ls-files $(prev_version_file)`"; \ - then \ - echo "error: checked in $(prev_version_file) required." >&2; \ - exit 1; \ - fi - -# Abort the release if there are unchecked in changes remaining. -vc-diff-check: - $(AM_V_at)if ! $(GIT) diff --exit-code; then \ - $(GIT) diff >/dev/null; \ - echo "error: Some files are locally modified" >&2; \ - exit 1; \ - fi - -# Select which lines of NEWS are searched for $(news-check-regexp). -# This is a sed line number spec. The default says that we search -# only line 3 of NEWS for $(news-check-regexp), to match the behaviour -# of '$(_build-aux)/do-release-commit-and-tag'. -# If you want to search only lines 1-10, use "1,10". -news-check-lines-spec ?= 3 -news-check-regexp ?= '^\#\#.* $(VERSION_REGEXP) \($(today)\)' - -Makefile.in: NEWS - -NEWS: - $(AM_V_GEN)if test -f NEWS.md; then ln -s NEWS.md NEWS; \ - elif test -f NEWS.rst; then ln -s NEWS.rst NEWS; \ - elif test -f NEWS.txt; then ln -s NEWS.txt NEWS; \ - fi - -news-check: NEWS - $(AM_V_GEN)if $(SED) -n $(news-check-lines-spec)p $< \ - | $(EGREP) $(news-check-regexp) >/dev/null; then \ - :; \ - else \ - echo 'NEWS: $$(news-check-regexp) failed to match' 1>&2; \ - exit 1; \ - fi - -.PHONY: release-commit -release-commit: NEWS - $(AM_V_GEN)cd $(srcdir) \ - && $(_build-aux)/do-release-commit-and-tag \ - -C $(abs_builddir) $(VERSION) $(RELEASE_TYPE) - -define emit-commit-log - printf '%s\n' 'maint: post-release administrivia.' '' \ - '* NEWS: Add header line for next release.' \ - '* .prev-version: Record previous version.' \ - '* $(old_NEWS_hash-file) (old_NEWS_hash): Auto-update.' -endef - -.PHONY: release-prep -release-prep: $(scm_rockspec) - $(AM_V_GEN)$(MAKE) --no-print-directory -s announcement \ - > ~/announce-$(my_distdir) - $(AM_V_at)if test -d $(release_archive_dir); then \ - ln $(rel-files) $(release_archive_dir); \ - chmod a-w $(rel-files); \ - fi - $(AM_V_at)echo $(VERSION) > $(prev_version_file) - $(AM_V_at)$(MAKE) update-old-NEWS-hash - $(AM_V_at)perl -pi \ - -e '$$. == 3 and print "$(gl_noteworthy_news_)\n\n\n"' \ - `readlink $(srcdir)/NEWS 2>/dev/null || echo $(srcdir)/NEWS` - $(AM_V_at)msg=$$($(emit-commit-log)) || exit 1; \ - cd $(srcdir) && $(GIT) commit -s -m "$$msg" -a - @echo '**** Release announcement in ~/announce-$(my_distdir)' - -# Strip out copyright messages with years, so that changing those (e.g. -# with 'make update-copyight') doesn't change the old_NEWS_hash. -NEWS_hash = \ - $$(sed -n '/^\*.* $(PREV_VERSION_REGEXP) ([0-9-]*)/,$$p' \ - $(srcdir)/NEWS \ - | perl -0777 -pe 's/^Copyright.+?[12][0-9]{3}.+?\n//ms' \ - | md5sum - \ - | sed 's/ .*//') - -# Update the hash stored above. Do this after each release and -# for any corrections to old entries. - -old-NEWS-regexp = '^old_NEWS_hash[ \t]+?=[ \t]+' -update-old-NEWS-hash: NEWS - $(AM_V_GEN)if $(EGREP) $(old-NEWS-regexp) $(old_NEWS_hash-file); then \ - perl -pi -e 's/^(old_NEWS_hash[ \t]+:?=[ \t]+).*/$${1}'"$(NEWS_hash)/" \ - $(old_NEWS_hash-file); \ - else \ - printf '%s\n' '' "old_NEWS_hash = $(NEWS_hash)" \ - >> $(old_NEWS_hash-file); \ - fi - -ANNOUNCE_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' -ANNOUNCE_PRINT = $(ANNOUNCE_ENV) $(LUA) -l$(PACKAGE) -e - -_PRE = " https://raw.githubusercontent" -_POST = "/release-v$(VERSION)/$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec" -GITHUB_ROCKSPEC = (source.url:gsub ("^git://github", $(_PRE)):gsub ("%.git$$", $(_POST))) - -announcement: NEWS -# Not $(AM_V_GEN) since the output of this command serves as -# announcement message: else, it would start with " GEN announcement". - $(AM_V_at)printf '%s\n' \ - '# [ANN] $(PACKAGE_NAME) $(VERSION) released' \ - '' - $(AM_V_at)$(ANNOUNCE_PRINT) 'print (description.detailed)' - $(AM_V_at)printf '%s\n' '' \ - 'I am happy to announce release $(VERSION) of $(PACKAGE_NAME).' \ - '' - $(AM_V_at)$(ANNOUNCE_PRINT) \ - 'print ("$(PACKAGE_NAME)'\''s home page is at " .. description.homepage)' - $(AM_V_at)printf '\n' - $(AM_V_at)$(SED) -n \ - -e '/^\#\# Noteworthy changes in release $(PREV_VERSION)/q' \ - -e p NEWS |$(SED) -e 1,2d - $(AM_V_at)printf '%s\n' \ - 'Install it with LuaRocks, using:' '' \ - ' luarocks install $(PACKAGE) $(VERSION)' - $(AM_V_at)$(ANNOUNCE_PRINT) 'print ($(GITHUB_ROCKSPEC))' - - -branch = $(shell $(GIT) branch |$(SED) -ne '/^\* /{s///;p;q;}') -GCO = $(GIT) checkout -release-tarball = $(my_distdir).tar.gz - -# Anything in $(_save-files) is not removed after switching to the -# release branch, and is thus "in the release". Add addtional partial -# filenames to save in save_release_files, for example: -# save_release_files = RELEASE-NOTES- -_save-files = \ - $(release-tarball) \ - $(save_release_files) \ - $(NOTHING_ELSE) - - -list-to-rexp = $(SED) -e 's|^|(|' -e 's/|$$/)/' -git-clean-files = `printf -- '-e %s ' $(_save-files)` -grep-clean-files = `printf -- '%s|' $(_save-files) |$(list-to-rexp)` - -# Switch to (or create) 'release' branch, remove all files, except the -# newly generated dist tarball, then unpack the dist tarball and check -# in all the files it creates, and tag that as the next release. -# Github creates automatic zipballs of tagged git revisions, so we can -# safely use this tag in the rockspecs we distribute. -submodule-regexp ?= '^\[submodule "' -submodule-extract-spec ?= 's|^.*"\([^"]*\)".*$$|\1|' - -.PHONY: check-in-release-branch -check-in-release-branch: - $(AM_V_GEN)$(GCO) -b release v$(VERSION) 2>/dev/null || $(GCO) release - $(AM_V_at)$(GIT) pull origin release 2>/dev/null || true - $(AM_V_at)if $(EGREP) $(submodule-regexp) .gitmodules >/dev/null 2>&1; then \ - $(EGREP) $(submodule-regexp) .gitmodules \ - | $(SED) $(submodule-extract-spec) | xargs rm -rf; \ - fi - $(AM_V_at)$(GIT) clean -dfx $(git-clean-files) - $(AM_V_at)remove_re=$(grep-clean-files); \ - $(GIT) rm -f `$(GIT) ls-files |$(EGREP) -v "$$remove_re"` - $(AM_V_at)ln -s . '$(my_distdir)' - $(AM_V_at)$(TAR) zxf '$(release-tarball)' - $(AM_V_at)rm -f '$(my_distdir)' '$(release-tarball)' - $(AM_V_at)$(GIT) add . - $(AM_V_at)$(GIT) commit -s -a -m 'Release v$(VERSION).' - $(AM_V_at)$(GIT) tag -s -a -m 'Full source release v$(VERSION)' release-v$(VERSION) - $(AM_V_at)$(GCO) $(branch) - -.PHONY: push -push: - $(AM_V_at)$(GIT) push origin master - $(AM_V_at)$(GIT) push origin release - $(AM_V_at)$(GIT) push origin v$(VERSION) - $(AM_V_at)$(GIT) push origin release-v$(VERSION) - -.PHONY: upload -upload: rockspecs - $(AM_V_at)$(LUAROCKS) upload $${API_KEY+--api-key=$$API_KEY} \ - '$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec' - -announce_emails ?= lua-l@lists.lua.org - -.PHONY: mail -mail: rockspecs - $(AM_V_at)cat ~/announce-$(my_distdir) \ - | mail -s '[ANN] $(PACKAGE) $(VERSION) released' -- \ - $(announce_emails) diff --git a/build-aux/rockspecs.mk b/build-aux/rockspecs.mk deleted file mode 100644 index e64cab1..0000000 --- a/build-aux/rockspecs.mk +++ /dev/null @@ -1,116 +0,0 @@ -# Slingshot rockspec rules for make. - -# This file is distributed with Slingshot, and licensed under the -# terms of the MIT license reproduced below. - -# ==================================================================== # -# Copyright (C) 2013-2015 Reuben Thomas and Gary V. Vaughan # -# # -# Permission is hereby granted, free of charge, to any person # -# obtaining a copy of this software and associated documentation # -# files (the "Software"), to deal in the Software without restriction, # -# including without limitation the rights to use, copy, modify, merge, # -# publish, distribute, sublicense, and/or sell copies of the Software, # -# and to permit persons to whom the Software is furnished to do so, # -# subject to the following conditions: # -# # -# The above copyright notice and this permission notice shall be # -# included in all copies or substantial portions of the Software. # -# # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # -# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # -# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # -# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -# ==================================================================== # - - -## --------- ## -## LuaRocks. ## -## --------- ## - -# This file is suitable for use from a portable Makefile, you might -# include it into the top-level Makefile.am with: -# -# include build-aux/rockspecs.mk - -luarocks_config = build-aux/luarocks-config.lua -rockspec_conf = $(srcdir)/rockspec.conf -mkrockspecs = $(srcdir)/build-aux/mkrockspecs -package_rockspec = $(srcdir)/$(PACKAGE)-$(VERSION)-$(rockspec_revision).rockspec -scm_rockspec = $(PACKAGE)-git-$(rockspec_revision).rockspec - -# If you need a different rockspec revision, override this on the make -# command line: -# -# make rockspecs rockspec_revision=2 -rockspec_revision = 1 - -LUAROCKS = luarocks -MKROCKSPECS = $(MKROCKSPECS_ENV) $(LUA) $(mkrockspecs) - -ROCKSPECS_DEPS = \ - $(luarocks_config) \ - $(mkrockspecs) \ - $(rockspec_conf) \ - $(NOTHING_ELSE) - -set_LUA_BINDIR = LUA_BINDIR=`which $(LUA) |$(SED) 's|/[^/]*$$||'` -LUA_INCDIR = `cd $$LUA_BINDIR/../include && pwd` -LUA_LIBDIR = `cd $$LUA_BINDIR/../lib && pwd` - -$(luarocks_config): Makefile.am - @test -d build-aux || mkdir build-aux - $(AM_V_GEN){ \ - $(set_LUA_BINDIR); \ - echo 'rocks_trees = { "$(abs_srcdir)/luarocks" }'; \ - echo 'variables = {'; \ - echo ' LUA = "$(LUA)",'; \ - echo ' LUA_BINDIR = "'$$LUA_BINDIR'",'; \ - echo ' LUA_INCDIR = "'$(LUA_INCDIR)'",'; \ - echo ' LUA_LIBDIR = "'$(LUA_LIBDIR)'",'; \ - echo '}'; \ - } > '$@' - -$(package_rockspec): $(ROCKSPECS_DEPS) - $(AM_V_at)rm -f '$@' 2>/dev/null || : - $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(mkrockspecs_args) \ - $(PACKAGE) $(VERSION) $(rockspec_revision) > '$@' - $(AM_V_at)$(LUAROCKS) lint '$@' - -$(scm_rockspec): $(ROCKSPECS_DEPS) - $(AM_V_at)rm '$@' 2>/dev/null || : - $(AM_V_GEN)test -f '$@' || \ - $(MKROCKSPECS) $(mkrockspecs_args) \ - $(PACKAGE) git 1 > '$@' - $(AM_V_at)$(LUAROCKS) lint '$@' - -.PHONY: rockspecs -rockspecs: - $(AM_V_at)rm -f *.rockspec - $(AM_V_at)$(MAKE) $(package_rockspec) $(scm_rockspec) - - -## ------------- ## -## Distribution. ## -## ------------- ## - -EXTRA_DIST += \ - $(mkrockspecs) \ - $(package_rockspec) \ - $(rockspec_conf) \ - $(NOTHING_ELSE) - -save_release_files += $(scm_rockspec) - - -## ------------ ## -## Maintenance. ## -## ------------ ## - -DISTCLEANFILES += \ - $(luarocks_config) \ - $(NOTHING_ELSE) diff --git a/build-aux/sanity-cfg.mk b/build-aux/sanity-cfg.mk deleted file mode 100644 index 6bbf697..0000000 --- a/build-aux/sanity-cfg.mk +++ /dev/null @@ -1,3 +0,0 @@ -exclude_file_name_regexp--sc_error_message_uppercase = ^lib/std/(list|optparse).lua$$ - -EXTRA_DIST += build-aux/sanity-cfg.mk diff --git a/build-aux/sanity.mk b/build-aux/sanity.mk deleted file mode 100644 index 78bb125..0000000 --- a/build-aux/sanity.mk +++ /dev/null @@ -1,1114 +0,0 @@ -# Slingshot sanity checking rules for GNU Make. - -# ====================================================================== -# Copyright (C) 2001-2013 Free Software Foundation, Inc. -# Originally by Jim Meyering, Simon Josefsson, Eric Blake, -# Akim Demaille, Gary V. Vaughan, and others. -# This version by Gary V. Vaughan, 2013. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# ====================================================================== - -VC_LIST = $(GIT) ls-files - -# You can override this variable in cfg.mk to set your own regexp -# matching files to ignore. -VC_LIST_ALWAYS_EXCLUDE_REGEX ?= ^$$ - -# This is to preprocess robustly the output of $(VC_LIST), so that even -# when $(srcdir) is a pathological name like "....", the leading sed command -# removes only the intended prefix. -_dot_escaped_srcdir = $(subst .,\.,$(srcdir)) - -# Post-process $(VC_LIST) output, prepending $(srcdir)/, but only -# when $(srcdir) is not ".". -ifeq ($(srcdir),.) - _prepend_srcdir_prefix = -else - _prepend_srcdir_prefix = | sed 's|^|$(srcdir)/|' -endif - -# In order to be able to consistently filter "."-relative names, -# (i.e., with no $(srcdir) prefix), this definition is careful to -# remove any $(srcdir) prefix, and to restore what it removes. -_sc_excl = \ - $(or $(exclude_file_name_regexp--$@),^build-aux/sanity.mk$$|gnulib$$|^slingshot$$) -VC_LIST_EXCEPT = \ - $(VC_LIST) | sed 's|^$(_dot_escaped_srcdir)/||' \ - | if test -f $(srcdir)/.x-$@; then grep -vEf $(srcdir)/.x-$@; \ - else grep -Ev -e "$${VC_LIST_EXCEPT_DEFAULT-ChangeLog}"; fi \ - | grep -Ev -e '($(VC_LIST_ALWAYS_EXCLUDE_REGEX)|$(_sc_excl))' \ - $(_prepend_srcdir_prefix) - - -## --------------- ## -## Sanity checks. ## -## --------------- ## - --include $(srcdir)/$(_build-aux)/sanity-cfg.mk - -_cfg_mk := $(wildcard $(srcdir)/cfg.mk) - -# Collect the names of rules starting with 'sc_'. -syntax-check-rules := $(sort $(shell sed -n 's/^\(sc_[a-zA-Z0-9_-]*\):.*/\1/p' \ - $(srcdir)/$(ME) $(_cfg_mk) $(srcdir)/$(_build-aux)/*.mk)) -.PHONY: $(syntax-check-rules) - -ifeq ($(shell $(VC_LIST) >/dev/null 2>&1; echo $$?),0) - local-checks-available += $(syntax-check-rules) -else - local-checks-available += no-vc-detected -no-vc-detected: - @echo "No version control files detected; skipping syntax check" -endif -.PHONY: $(local-checks-available) - -# Arrange to print the name of each syntax-checking rule just before running it. -$(syntax-check-rules): %: %.m -sc_m_rules_ = $(patsubst %, %.m, $(syntax-check-rules)) -.PHONY: $(sc_m_rules_) -$(sc_m_rules_): - @echo $(patsubst sc_%.m, %, $@) - @date +%s.%N > .sc-start-$(basename $@) - -# Compute and print the elapsed time for each syntax-check rule. -sc_z_rules_ = $(patsubst %, %.z, $(syntax-check-rules)) -.PHONY: $(sc_z_rules_) -$(sc_z_rules_): %.z: % - @end=$$(date +%s.%N); \ - start=$$(cat .sc-start-$*); \ - rm -f .sc-start-$*; \ - awk -v s=$$start -v e=$$end \ - 'END {printf "%.2f $(patsubst sc_%,%,$*)\n", e - s}' < /dev/null - -# The patsubst here is to replace each sc_% rule with its sc_%.z wrapper -# that computes and prints elapsed time. -local-check := \ - $(patsubst sc_%, sc_%.z, \ - $(filter-out $(local-checks-to-skip), $(local-checks-available))) - -syntax-check: $(local-check) - -# _sc_search_regexp -# -# This macro searches for a given construct in the selected files and -# then takes some action. -# -# Parameters (shell variables): -# -# prohibit | require -# -# Regular expression (ERE) denoting either a forbidden construct -# or a required construct. Those arguments are exclusive. -# -# exclude -# -# Regular expression (ERE) denoting lines to ignore that matched -# a prohibit construct. For example, this can be used to exclude -# comments that mention why the nearby code uses an alternative -# construct instead of the simpler prohibited construct. -# -# in_vc_files | in_files -# -# grep-E-style regexp selecting the files to check. For in_vc_files, -# the regexp is used to select matching files from the list of all -# version-controlled files; for in_files, it's from the names printed -# by "find $(srcdir)". When neither is specified, use all files that -# are under version control. -# -# containing | non_containing -# -# Select the files (non) containing strings matching this regexp. -# If both arguments are specified then CONTAINING takes -# precedence. -# -# with_grep_options -# -# Extra options for grep. -# -# ignore_case -# -# Ignore case. -# -# halt -# -# Message to display before to halting execution. -# -# Finally, you may exempt files based on an ERE matching file names. -# For example, to exempt from the sc_space_tab check all files with the -# .diff suffix, set this Make variable: -# -# exclude_file_name_regexp--sc_space_tab = \.diff$ -# -# Note that while this functionality is mostly inherited via VC_LIST_EXCEPT, -# when filtering by name via in_files, we explicitly filter out matching -# names here as well. - -# Initialize each, so that envvar settings cannot interfere. -export require = -export prohibit = -export exclude = -export in_vc_files = -export in_files = -export containing = -export non_containing = -export halt = -export with_grep_options = - -# By default, _sc_search_regexp does not ignore case. -export ignore_case = -_ignore_case = $$(test -n "$$ignore_case" && printf %s -i || :) - -define _sc_say_and_exit - dummy=; : so we do not need a semicolon before each use; \ - { printf '%s\n' "$(ME): $$msg" 1>&2; exit 1; }; -endef - -define _sc_search_regexp - dummy=; : so we do not need a semicolon before each use; \ - \ - : Check arguments; \ - test -n "$$prohibit" && test -n "$$require" \ - && { msg='Cannot specify both prohibit and require' \ - $(_sc_say_and_exit) } || :; \ - test -z "$$prohibit" && test -z "$$require" \ - && { msg='Should specify either prohibit or require' \ - $(_sc_say_and_exit) } || :; \ - test -z "$$prohibit" && test -n "$$exclude" \ - && { msg='Use of exclude requires a prohibit pattern' \ - $(_sc_say_and_exit) } || :; \ - test -n "$$in_vc_files" && test -n "$$in_files" \ - && { msg='Cannot specify both in_vc_files and in_files' \ - $(_sc_say_and_exit) } || :; \ - test "x$$halt" != x \ - || { msg='halt not defined' $(_sc_say_and_exit) }; \ - \ - : Filter by file name; \ - if test -n "$$in_files"; then \ - files=$$(find $(srcdir) | grep -E "$$in_files" \ - | grep -Ev '$(_sc_excl)'); \ - else \ - files=$$($(VC_LIST_EXCEPT)); \ - if test -n "$$in_vc_files"; then \ - files=$$(echo "$$files" | grep -E "$$in_vc_files"); \ - fi; \ - fi; \ - \ - : Filter by content; \ - test -n "$$files" && test -n "$$containing" \ - && { files=$$(grep -l "$$containing" $$files); } || :; \ - test -n "$$files" && test -n "$$non_containing" \ - && { files=$$(grep -vl "$$non_containing" $$files); } || :; \ - \ - : Check for the construct; \ - if test -n "$$files"; then \ - if test -n "$$prohibit"; then \ - grep $$with_grep_options $(_ignore_case) -nE "$$prohibit" $$files \ - | grep -vE "$${exclude:-^$$}" \ - && { msg="$$halt" $(_sc_say_and_exit) } || :; \ - else \ - grep $$with_grep_options $(_ignore_case) -LE "$$require" $$files \ - | grep . \ - && { msg="$$halt" $(_sc_say_and_exit) } || :; \ - fi \ - else :; \ - fi || :; -endef - -sc_avoid_if_before_free: - @test -f $(srcdir)/$(_build-aux)/useless-if-before-free && \ - $(srcdir)/$(_build-aux)/useless-if-before-free \ - $(useless_free_options) \ - $$($(VC_LIST_EXCEPT) | grep -v useless-if-before-free) && \ - { echo '$(ME): found useless "if" before "free" above' 1>&2; \ - exit 1; } || : - -sc_cast_of_argument_to_free: - @prohibit='\&2; \ - exit 1; } || : - -# Error messages should not start with a capital letter -sc_error_message_uppercase: - @grep -nEA2 '[^rp]error *\(' $$($(VC_LIST_EXCEPT)) \ - | grep -E '"[A-Z]' \ - | grep -vE '"FATAL|"WARNING|"Java|"C#|PRIuMAX' && \ - { echo '$(ME): found capitalized error message' 1>&2; \ - exit 1; } || : - -# Error messages should not end with a period -sc_error_message_period: - @grep -nEA2 '[^rp]error *\(' $$($(VC_LIST_EXCEPT)) \ - | grep -E '[^."]\."' && \ - { echo '$(ME): found error message ending in period' 1>&2; \ - exit 1; } || : - -sc_file_system: - @prohibit=file''system \ - ignore_case=1 \ - halt='found use of "file''system"; spell it "file system"' \ - $(_sc_search_regexp) - -sc_makefile: - @prohibit=make''flie \ - ignore_case=1 \ - halt='found misspelled "make''flie"; use "makefile" instead' \ - $(_sc_search_regexp) - -# Don't use cpp tests of this symbol. All code assumes config.h is included. -sc_prohibit_have_config_h: - @prohibit='^# *if.*HAVE''_CONFIG_H' \ - halt='found use of HAVE''_CONFIG_H; remove' \ - $(_sc_search_regexp) - -# Nearly all .c files must include . However, we also permit this -# via inclusion of a package-specific header, if cfg.mk specified one. -# config_h_header must be suitable for grep -E. -config_h_header ?= -sc_require_config_h: - @require='^# *include $(config_h_header)' \ - in_vc_files='\.c$$' \ - halt='the above files do not include ' \ - $(_sc_search_regexp) - -# You must include before including any other header file. -# This can possibly be via a package-specific header, if given by cfg.mk. -sc_require_config_h_first: - @if $(VC_LIST_EXCEPT) | grep -l '\.c$$' > /dev/null; then \ - fail=0; \ - for i in $$($(VC_LIST_EXCEPT) | grep '\.c$$'); do \ - grep '^# *include\>' $$i | sed 1q \ - | grep -E '^# *include $(config_h_header)' > /dev/null \ - || { echo $$i; fail=1; }; \ - done; \ - test $$fail = 1 && \ - { echo '$(ME): the above files include some other header' \ - 'before ' 1>&2; exit 1; } || :; \ - else :; \ - fi - -sc_prohibit_HAVE_MBRTOWC: - @prohibit='\bHAVE_MBRTOWC\b' \ - halt="do not use $$prohibit; it is always defined" \ - $(_sc_search_regexp) - -# To use this "command" macro, you must first define two shell variables: -# h: the header name, with no enclosing <> or "" -# re: a regular expression that matches IFF something provided by $h is used. -define _sc_header_without_use - dummy=; : so we do not need a semicolon before each use; \ - h_esc=`echo '[<"]'"$$h"'[">]'|sed 's/\./\\\\./g'`; \ - if $(VC_LIST_EXCEPT) | grep -l '\.c$$' > /dev/null; then \ - files=$$(grep -l '^# *include '"$$h_esc" \ - $$($(VC_LIST_EXCEPT) | grep '\.c$$')) && \ - grep -LE "$$re" $$files | grep . && \ - { echo "$(ME): the above files include $$h but don't use it" \ - 1>&2; exit 1; } || :; \ - else :; \ - fi -endef - -# Prohibit the inclusion of assert.h without an actual use of assert. -sc_prohibit_assert_without_use: - @h='assert.h' re='\new(file => "/dev/stdin")->as_string'|sed 's/\?://g' -# Note this was produced by the above: -# _xa1 = \ -#x(((2n?)?re|c(har)?|n(re|m)|z)alloc|alloc_(oversized|die)|m(alloc|emdup)|strdup) -# But we can do better, in at least two ways: -# 1) take advantage of two "dup"-suffixed strings: -# x(((2n?)?re|c(har)?|n(re|m)|[mz])alloc|alloc_(oversized|die)|(mem|str)dup) -# 2) notice that "c(har)?|[mz]" is equivalent to the shorter and more readable -# "char|[cmz]" -# x(((2n?)?re|char|n(re|m)|[cmz])alloc|alloc_(oversized|die)|(mem|str)dup) -_xa1 = x(((2n?)?re|char|n(re|m)|[cmz])alloc|alloc_(oversized|die)|(mem|str)dup) -_xa2 = X([CZ]|N?M)ALLOC -sc_prohibit_xalloc_without_use: - @h='xalloc.h' \ - re='\<($(_xa1)|$(_xa2)) *\('\ - $(_sc_header_without_use) - -# Extract function names: -# perl -lne '/^(?:extern )?(?:void|char) \*?(\w+) *\(/ and print $1' lib/hash.h -_hash_re = \ -clear|delete|free|get_(first|next)|insert|lookup|print_statistics|reset_tuning -_hash_fn = \<($(_hash_re)) *\( -_hash_struct = (struct )?\<[Hh]ash_(table|tuning)\> -sc_prohibit_hash_without_use: - @h='hash.h' \ - re='$(_hash_fn)|$(_hash_struct)'\ - $(_sc_header_without_use) - -sc_prohibit_cloexec_without_use: - @h='cloexec.h' re='\<(set_cloexec_flag|dup_cloexec) *\(' \ - $(_sc_header_without_use) - -sc_prohibit_posixver_without_use: - @h='posixver.h' re='\' \ - halt='do not use HAVE''_FCNTL_H or O'_NDELAY \ - $(_sc_search_regexp) - -# FIXME: warn about definitions of EXIT_FAILURE, EXIT_SUCCESS, STREQ - -# Each nonempty ChangeLog line must start with a year number, or a TAB. -sc_changelog: - @prohibit='^[^12 ]' \ - in_vc_files='^ChangeLog$$' \ - halt='found unexpected prefix in a ChangeLog' \ - $(_sc_search_regexp) - -# Ensure that each .c file containing a "main" function also -# calls set_program_name. -sc_program_name: - @require='set_program_name *\(m?argv\[0\]\);' \ - in_vc_files='\.c$$' \ - containing='\
    /dev/null \ - && : || { die=1; echo $$i; } \ - done; \ - test $$die = 1 && \ - { echo 1>&2 '$(ME): the final line in each of the above is not:'; \ - echo 1>&2 'Exit something'; \ - exit 1; } || :; \ - fi - -sc_trailing_blank: - @prohibit='[ ]$$' \ - halt='found trailing blank(s)' \ - exclude='^Binary file .* matches$$' \ - $(_sc_search_regexp) - -# Match lines like the following, but where there is only one space -# between the options and the description: -# -D, --all-repeated[=delimit-method] print all duplicate lines\n -longopt_re = --[a-z][0-9A-Za-z-]*(\[?=[0-9A-Za-z-]*\]?)? -sc_two_space_separator_in_usage: - @prohibit='^ *(-[A-Za-z],)? $(longopt_re) [^ ].*\\$$' \ - halt='help2man requires at least two spaces between an option and its description'\ - $(_sc_search_regexp) - -# A regexp matching function names like "error_" that may be used -# to emit translatable messages. -_gl_translatable_diag_func_re ?= error_ - -# Look for diagnostics that aren't marked for translation. -# This won't find any for which error's format string is on a separate line. -sc_unmarked_diagnostics: - @prohibit='\<$(_gl_translatable_diag_func_re) *\([^"]*"[^"]*[a-z]{3}' \ - exclude='(_|ngettext ?)\(' \ - halt='found unmarked diagnostic(s)' \ - $(_sc_search_regexp) - -# Avoid useless parentheses like those in this example: -# #if defined (SYMBOL) || defined (SYM2) -sc_useless_cpp_parens: - @prohibit='^# *if .*defined *\(' \ - halt='found useless parentheses in cpp directive' \ - $(_sc_search_regexp) - -# List headers for which HAVE_HEADER_H is always true, assuming you are -# using the appropriate gnulib module. CAUTION: for each "unnecessary" -# #if HAVE_HEADER_H that you remove, be sure that your project explicitly -# requires the gnulib module that guarantees the usability of that header. -gl_assured_headers_ = \ - cd $(gnulib_dir)/lib && echo *.in.h|sed 's/\.in\.h//g' - -# Convert the list of names to upper case, and replace each space with "|". -az_ = abcdefghijklmnopqrstuvwxyz -AZ_ = ABCDEFGHIJKLMNOPQRSTUVWXYZ -gl_header_upper_case_or_ = \ - $$($(gl_assured_headers_) \ - | tr $(az_)/.- $(AZ_)___ \ - | tr -s ' ' '|' \ - ) -sc_prohibit_always_true_header_tests: - @or=$(gl_header_upper_case_or_); \ - re="HAVE_($$or)_H"; \ - prohibit='\<'"$$re"'\>' \ - halt=$$(printf '%s\n' \ - 'do not test the above HAVE_
    _H symbol(s);' \ - ' with the corresponding gnulib module, they are always true') \ - $(_sc_search_regexp) - -sc_prohibit_defined_have_decl_tests: - @prohibit='#[ ]*if(n?def|.*\[ (]+HAVE_DECL_' \ - halt='HAVE_DECL macros are always defined' \ - $(_sc_search_regexp) - -# ================================================================== -gl_other_headers_ ?= \ - intprops.h \ - openat.h \ - stat-macros.h - -# Perl -lne code to extract "significant" cpp-defined symbols from a -# gnulib header file, eliminating a few common false-positives. -# The exempted names below are defined only conditionally in gnulib, -# and hence sometimes must/may be defined in application code. -gl_extract_significant_defines_ = \ - /^\# *define ([^_ (][^ (]*)(\s*\(|\s+\w+)/\ - && $$2 !~ /(?:rpl_|_used_without_)/\ - && $$1 !~ /^(?:NSIG|ENODATA)$$/\ - && $$1 !~ /^(?:SA_RESETHAND|SA_RESTART)$$/\ - and print $$1 - -# Create a list of regular expressions matching the names -# of macros that are guaranteed to be defined by parts of gnulib. -define def_sym_regex - gen_h=$(gl_generated_headers_); \ - (cd $(gnulib_dir)/lib; \ - for f in *.in.h $(gl_other_headers_); do \ - test -f $$f \ - && perl -lne '$(gl_extract_significant_defines_)' $$f; \ - done; \ - ) | sort -u \ - | sed 's/^/^ *# *(define|undef) */;s/$$/\\>/' -endef - -# Don't define macros that we already get from gnulib header files. -sc_prohibit_always-defined_macros: - @if test -d $(gnulib_dir); then \ - case $$(echo all: | grep -l -f - Makefile) in Makefile);; *) \ - echo '$(ME): skipping $@: you lack GNU grep' 1>&2; exit 0;; \ - esac; \ - $(def_sym_regex) | grep -E -f - $$($(VC_LIST_EXCEPT)) \ - && { echo '$(ME): define the above via some gnulib .h file' \ - 1>&2; exit 1; } || :; \ - fi -# ================================================================== - -# Prohibit checked in backup files. -sc_prohibit_backup_files: - @$(VC_LIST) | grep '~$$' && \ - { echo '$(ME): found version controlled backup file' 1>&2; \ - exit 1; } || : - -# Require the latest GPL. -sc_GPL_version: - @prohibit='either ''version [^3]' \ - halt='GPL vN, N!=3' \ - $(_sc_search_regexp) - -# Require the latest GFDL. Two regexp, since some .texi files end up -# line wrapping between 'Free Documentation License,' and 'Version'. -_GFDL_regexp = (Free ''Documentation.*Version 1\.[^3]|Version 1\.[^3] or any) -sc_GFDL_version: - @prohibit='$(_GFDL_regexp)' \ - halt='GFDL vN, N!=3' \ - $(_sc_search_regexp) - -# Don't use Texinfo's @acronym{}. -# http://lists.gnu.org/archive/html/bug-gnulib/2010-03/msg00321.html -texinfo_suffix_re_ ?= \.(txi|texi(nfo)?)$$ -sc_texinfo_acronym: - @prohibit='@acronym\{' \ - in_vc_files='$(texinfo_suffix_re_)' \ - halt='found use of Texinfo @acronym{}' \ - $(_sc_search_regexp) - -cvs_keywords = \ - Author|Date|Header|Id|Name|Locker|Log|RCSfile|Revision|Source|State - -sc_prohibit_cvs_keyword: - @prohibit='\$$($(cvs_keywords))\$$' \ - halt='do not use CVS keyword expansion' \ - $(_sc_search_regexp) - -# This Perl code is slightly obfuscated. Not only is each "$" doubled -# because it's in a Makefile, but the $$c's are comments; we cannot -# use "#" due to the way the script ends up concatenated onto one line. -# It would be much more concise, and would produce better output (including -# counts) if written as: -# perl -ln -0777 -e '/\n(\n+)$/ and print "$ARGV: ".length $1' ... -# but that would be far less efficient, reading the entire contents -# of each file, rather than just the last two bytes of each. -# In addition, while the code below detects both blank lines and a missing -# newline at EOF, the above detects only the former. -# -# This is a perl script that is expected to be the single-quoted argument -# to a command-line "-le". The remaining arguments are file names. -# Print the name of each file that does not end in exactly one newline byte. -# I.e., warn if there are blank lines (2 or more newlines), or if the -# last byte is not a newline. However, currently we don't complain -# about any file that contains exactly one byte. -# Exit nonzero if at least one such file is found, otherwise, exit 0. -# Warn about, but otherwise ignore open failure. Ignore seek/read failure. -# -# Use this if you want to remove trailing empty lines from selected files: -# perl -pi -0777 -e 's/\n\n+$/\n/' files... -# -require_exactly_one_NL_at_EOF_ = \ - foreach my $$f (@ARGV) \ - { \ - open F, "<", $$f or (warn "failed to open $$f: $$!\n"), next; \ - my $$p = sysseek (F, -2, 2); \ - my $$c = "seek failure probably means file has < 2 bytes; ignore"; \ - my $$last_two_bytes; \ - defined $$p and $$p = sysread F, $$last_two_bytes, 2; \ - close F; \ - $$c = "ignore read failure"; \ - $$p && ($$last_two_bytes eq "\n\n" \ - || substr ($$last_two_bytes,1) ne "\n") \ - and (print $$f), $$fail=1; \ - } \ - END { exit defined $$fail } -sc_prohibit_empty_lines_at_EOF: - @perl -le '$(require_exactly_one_NL_at_EOF_)' $$($(VC_LIST_EXCEPT)) \ - || { echo '$(ME): empty line(s) or no newline at EOF' \ - 1>&2; exit 1; } || : - -# Make sure we don't use st_blocks. Use ST_NBLOCKS instead. -# This is a bit of a kludge, since it prevents use of the string -# even in comments, but for now it does the job with no false positives. -sc_prohibit_stat_st_blocks: - @prohibit='[.>]st_blocks' \ - halt='do not use st_blocks; use ST_NBLOCKS' \ - $(_sc_search_regexp) - -# Make sure we don't define any S_IS* macros in src/*.c files. -# They're already defined via gnulib's sys/stat.h replacement. -sc_prohibit_S_IS_definition: - @prohibit='^ *# *define *S_IS' \ - halt='do not define S_IS* macros; include ' \ - $(_sc_search_regexp) - -# Perl block to convert a match to FILE_NAME:LINENO:TEST, -# that is shared by two definitions below. -perl_filename_lineno_text_ = \ - -e ' {' \ - -e ' $$n = ($$` =~ tr/\n/\n/ + 1);' \ - -e ' ($$v = $$&) =~ s/\n/\\n/g;' \ - -e ' print "$$ARGV:$$n:$$v\n";' \ - -e ' }' - -prohibit_doubled_word_RE_ ?= \ - /\b(then?|[iao]n|i[fst]|but|f?or|at|and|[dt]o)\s+\1\b/gims -prohibit_doubled_word_ = \ - -e 'while ($(prohibit_doubled_word_RE_))' \ - $(perl_filename_lineno_text_) - -# Define this to a regular expression that matches -# any filename:dd:match lines you want to ignore. -# The default is to ignore no matches. -ignore_doubled_word_match_RE_ ?= ^$$ - -sc_prohibit_doubled_word: - @perl -n -0777 $(prohibit_doubled_word_) $$($(VC_LIST_EXCEPT)) \ - | grep -vE '$(ignore_doubled_word_match_RE_)' \ - | grep . && { echo '$(ME): doubled words' 1>&2; exit 1; } || : - -# A regular expression matching undesirable combinations of words like -# "can not"; this matches them even when the two words appear on different -# lines, but not when there is an intervening delimiter like "#" or "*". -# Similarly undesirable, "See @xref{...}", since an @xref should start -# a sentence. Explicitly prohibit any prefix of "see" or "also". -# Also prohibit a prefix matching "\w+ +". -# @pxref gets the same see/also treatment and should be parenthesized; -# presume it must *not* start a sentence. -bad_xref_re_ ?= (?:[\w,:;] +|(?:see|also)\s+)\@xref\{ -bad_pxref_re_ ?= (?:[.!?]|(?:see|also))\s+\@pxref\{ -prohibit_undesirable_word_seq_RE_ ?= \ - /(?:\bcan\s+not\b|$(bad_xref_re_)|$(bad_pxref_re_))/gims -prohibit_undesirable_word_seq_ = \ - -e 'while ($(prohibit_undesirable_word_seq_RE_))' \ - $(perl_filename_lineno_text_) -# Define this to a regular expression that matches -# any filename:dd:match lines you want to ignore. -# The default is to ignore no matches. -ignore_undesirable_word_sequence_RE_ ?= ^$$ - -sc_prohibit_undesirable_word_seq: - @perl -n -0777 $(prohibit_undesirable_word_seq_) \ - $$($(VC_LIST_EXCEPT)) \ - | grep -vE '$(ignore_undesirable_word_sequence_RE_)' | grep . \ - && { echo '$(ME): undesirable word sequence' >&2; exit 1; } || : - -_ptm1 = use "test C1 && test C2", not "test C1 -''a C2" -_ptm2 = use "test C1 || test C2", not "test C1 -''o C2" -# Using test's -a and -o operators is not portable. -# We prefer test over [, since the latter is spelled [[ in configure.ac. -sc_prohibit_test_minus_ao: - @prohibit='(\ /dev/null \ - || { fail=1; echo 1>&2 "$(ME): $$p uses proper_name_utf8"; }; \ - done; \ - test $$fail = 1 && \ - { echo 1>&2 '$(ME): the above do not link with any ICONV library'; \ - exit 1; } || :; \ - fi - -# Warn about "c0nst struct Foo const foo[]", -# but not about "char const *const foo" or "#define const const". -sc_redundant_const: - @prohibit='\bconst\b[[:space:][:alnum:]]{2,}\bconst\b' \ - halt='redundant "const" in declarations' \ - $(_sc_search_regexp) - -sc_const_long_option: - @prohibit='^ *static.*struct option ' \ - exclude='const struct option|struct option const' \ - halt='add "const" to the above declarations' \ - $(_sc_search_regexp) - -# Ensure that we don't accidentally insert an entry into an old NEWS block. -sc_immutable_NEWS: - @if test -f $(srcdir)/NEWS; then \ - test "$(NEWS_hash)" = '$(old_NEWS_hash)' && : || \ - { echo '$(ME): you have modified old NEWS' 1>&2; exit 1; }; \ - fi - -# Ensure that we use only the standard $(VAR) notation, -# not @...@ in Makefile.am, now that we can rely on automake -# to emit a definition for each substituted variable. -# However, there is still one case in which @VAR@ use is not just -# legitimate, but actually required: when augmenting an automake-defined -# variable with a prefix. For example, gettext uses this: -# MAKEINFO = env LANG= LC_MESSAGES= LC_ALL= LANGUAGE= @MAKEINFO@ -# otherwise, makeinfo would put German or French (current locale) -# navigation hints in the otherwise-English documentation. -# -# Allow the package to add exceptions via a hook in cfg.mk; -# for example, @PRAGMA_SYSTEM_HEADER@ can be permitted by -# setting this to ' && !/PRAGMA_SYSTEM_HEADER/'. -_makefile_at_at_check_exceptions ?= -sc_makefile_at_at_check: - @perl -ne '/\@\w+\@/' \ - -e ' && !/(\w+)\s+=.*\@\1\@$$/' \ - -e ''$(_makefile_at_at_check_exceptions) \ - -e 'and (print "$$ARGV:$$.: $$_"), $$m=1; END {exit !$$m}' \ - $$($(VC_LIST_EXCEPT) | grep -E '(^|/)(Makefile\.am|[^/]+\.mk)$$') \ - && { echo '$(ME): use $$(...), not @...@' 1>&2; exit 1; } || : - -sc_makefile_TAB_only_indentation: - @prohibit='^ [ ]{8}' \ - in_vc_files='akefile|\.mk$$' \ - halt='found TAB-8-space indentation' \ - $(_sc_search_regexp) - -sc_m4_quote_check: - @prohibit='(AC_DEFINE(_UNQUOTED)?|AC_DEFUN)\([^[]' \ - in_vc_files='(^configure\.ac|\.m4)$$' \ - halt='quote the first arg to AC_DEF*' \ - $(_sc_search_regexp) - -fix_po_file_diag = \ -'you have changed the set of files with translatable diagnostics;\n\ -apply the above patch\n' - -# Verify that all source files using _() (more specifically, files that -# match $(_gl_translatable_string_re)) are listed in po/POTFILES.in. -po_file ?= $(srcdir)/po/POTFILES.in -generated_files ?= $(srcdir)/lib/*.[ch] -_gl_translatable_string_re ?= \b(N?_|gettext *)\([^)"]*("|$$) -sc_po_check: - @if test -f $(po_file); then \ - grep -E -v '^(#|$$)' $(po_file) \ - | grep -v '^src/false\.c$$' | sort > $@-1; \ - files=; \ - for file in $$($(VC_LIST_EXCEPT)) $(generated_files); do \ - test -r $$file || continue; \ - case $$file in \ - *.m4|*.mk) continue ;; \ - *.?|*.??) ;; \ - *) continue;; \ - esac; \ - case $$file in \ - *.[ch]) \ - base=`expr " $$file" : ' \(.*\)\..'`; \ - { test -f $$base.l || test -f $$base.y; } && continue;; \ - esac; \ - files="$$files $$file"; \ - done; \ - grep -E -l '$(_gl_translatable_string_re)' $$files \ - | sed 's|^$(_dot_escaped_srcdir)/||' | sort -u > $@-2; \ - diff -u -L $(po_file) -L $(po_file) $@-1 $@-2 \ - || { printf '$(ME): '$(fix_po_file_diag) 1>&2; exit 1; }; \ - rm -f $@-1 $@-2; \ - fi - -# Sometimes it is useful to change the PATH environment variable -# in Makefiles. When doing so, it's better not to use the Unix-centric -# path separator of ':', but rather the automake-provided '$(PATH_SEPARATOR)'. -msg = 'Do not use ":" above; use $$(PATH_SEPARATOR) instead' -sc_makefile_path_separator_check: - @prohibit='PATH[=].*:' \ - in_vc_files='akefile|\.mk$$' \ - halt=$(msg) \ - $(_sc_search_regexp) - -v_etc_file = $(gnulib_dir)/lib/version-etc.c -sample-test = tests/sample-test -texi = doc/$(PACKAGE).texi -# Make sure that the copyright date in $(v_etc_file) is up to date. -# Do the same for the $(sample-test) and the main doc/.texi file. -sc_copyright_check: - @require='enum { COPYRIGHT_YEAR = '$$(date +%Y)' };' \ - in_files=$(v_etc_file) \ - halt='out of date copyright in $(v_etc_file); update it' \ - $(_sc_search_regexp) - @require='# Copyright \(C\) '$$(date +%Y)' Free' \ - in_vc_files=$(sample-test) \ - halt='out of date copyright in $(sample-test); update it' \ - $(_sc_search_regexp) - @require='Copyright @copyright\{\} .*'$$(date +%Y)' Free' \ - in_vc_files=$(texi) \ - halt='out of date copyright in $(texi); update it' \ - $(_sc_search_regexp) - -# #if HAVE_... will evaluate to false for any non numeric string. -# That would be flagged by using -Wundef, however gnulib currently -# tests many undefined macros, and so we can't enable that option. -# So at least preclude common boolean strings as macro values. -sc_Wundef_boolean: - @prohibit='^#define.*(yes|no|true|false)$$' \ - in_files='$(CONFIG_INCLUDE)' \ - halt='Use 0 or 1 for macro values' \ - $(_sc_search_regexp) - -# Even if you use pathmax.h to guarantee that PATH_MAX is defined, it might -# not be constant, or might overflow a stack. In general, use PATH_MAX as -# a limit, not an array or alloca size. -sc_prohibit_path_max_allocation: - @prohibit='(\balloca *\([^)]*|\[[^]]*)\bPATH_MAX' \ - halt='Avoid stack allocations of size PATH_MAX' \ - $(_sc_search_regexp) - -sc_vulnerable_makefile_CVE-2009-4029: - @prohibit='perm -777 -exec chmod a\+rwx|chmod 777 \$$\(distdir\)' \ - in_files='(^|/)Makefile\.in$$' \ - halt=$$(printf '%s\n' \ - 'the above files are vulnerable; beware of running' \ - ' "make dist*" rules, and upgrade to fixed automake' \ - ' see http://bugzilla.redhat.com/542609 for details') \ - $(_sc_search_regexp) - -sc_vulnerable_makefile_CVE-2012-3386: - @prohibit='chmod a\+w \$$\(distdir\)' \ - in_files='(^|/)Makefile\.in$$' \ - halt=$$(printf '%s\n' \ - 'the above files are vulnerable; beware of running' \ - ' "make distcheck", and upgrade to fixed automake' \ - ' see http://bugzilla.redhat.com/CVE-2012-3386 for details') \ - $(_sc_search_regexp) - - -## ------------- ## -## Distribution. ## -## ------------- ## - -EXTRA_DIST += \ - $(_build-aux)/sanity.mk \ - $(NOTHING_ELSE) diff --git a/build-aux/specl.mk b/build-aux/specl.mk deleted file mode 100644 index 530d961..0000000 --- a/build-aux/specl.mk +++ /dev/null @@ -1,71 +0,0 @@ -# Slingshot specl rules for make. - -# This file is distributed with Slingshot, and licensed under the -# terms of the MIT license reproduced below. - -# ==================================================================== # -# Copyright (C) 2013-2015 Gary V. Vaughan # -# # -# Permission is hereby granted, free of charge, to any person # -# obtaining a copy of this software and associated documentation # -# files (the "Software"), to deal in the Software without restriction, # -# including without limitation the rights to use, copy, modify, merge, # -# publish, distribute, sublicense, and/or sell copies of the Software, # -# and to permit persons to whom the Software is furnished to do so, # -# subject to the following conditions: # -# # -# The above copyright notice and this permission notice shall be # -# included in all copies or substantial portions of the Software. # -# # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- # -# MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE # -# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # -# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -# ==================================================================== # - -# To use this file create a list of your spec files in specl_SPECS -# and then include this make fragment. - -## ------ ## -## Specl. ## -## ------ ## - -CHECK_ENV += \ - LUA='$(LUA)' \ - PACKAGE_STRING='$(PACKAGE_STRING)' \ - abs_top_builddir='$(abs_top_builddir)' \ - abs_top_srcdir='$(abs_top_srcdir)' \ - top_builddir='$(top_builddir)' \ - top_srcdir='$(top_srcdir)' \ - $(NOTHING_ELSE) - -check_local += specl-check-local -specl-check-local: $(specl_SPECS) - $(CHECK_ENV) $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) - - -## ------------- ## -## Installation. ## -## ------------- ## - -INSTALLCHECK_ENV += \ - LUA='$(LUA)' \ - PACKAGE_STRING='$(PACKAGE_STRING)' \ - installcheck='true' \ - $(NOTHING_ELSE) - -installcheck_local += specl-installcheck-local -specl-installcheck-local: $(specl_SPECS) - $(INSTALLCHECK_ENV) $(SPECL_ENV) $(SPECL) $(SPECL_OPTS) $(specl_SPECS) - - -## ------------- ## -## Distribution. ## -## ------------- ## - -EXTRA_DIST += \ - $(specl_SPECS) \ - $(NOTHING_ELSE) diff --git a/configure b/configure deleted file mode 100755 index 3cb1dc0..0000000 --- a/configure +++ /dev/null @@ -1,4242 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for stdlib 41.2.2. -# -# Report bugs to . -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: http://github.com/lua-stdlib/lua-stdlib/issues about -$0: your system, including any error possibly output before -$0: this message. Then install a modern shell, or manually -$0: run the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='stdlib' -PACKAGE_TARNAME='stdlib' -PACKAGE_VERSION='41.2.2' -PACKAGE_STRING='stdlib 41.2.2' -PACKAGE_BUGREPORT='http://github.com/lua-stdlib/lua-stdlib/issues' -PACKAGE_URL='' - -ac_subst_vars='LTLIBOBJS -LIBOBJS -EGREP -SPECL -LDOC -pkgluaexecdir -luaexecdir -pkgluadir -luadir -LUA_EXEC_PREFIX -LUA_PREFIX -LUA_PLATFORM -LUA_SHORT_VERSION -LUA_VERSION -LUA -SED -GREP -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -' - ac_precious_vars='build_alias -host_alias -target_alias -LUA' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures stdlib 41.2.2 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/stdlib] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of stdlib 41.2.2:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - -Some influential environment variables: - LUA The Lua interpreter, e.g. /usr/bin/lua5.1 - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -stdlib configure 41.2.2 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by stdlib $as_me 41.2.2, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_aux_dir= -for ac_dir in build-aux "$srcdir"/build-aux; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - - - -$as_echo "## ------------------------- ## -## Configuring stdlib 41.2.2 ## -## ------------------------- ##" -echo - -am__api_version='1.15' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='stdlib' - VERSION='41.2.2' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - - - - - - - - - - if test "x$LUA" != 'x'; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LUA is a Lua interpreter" >&5 -$as_echo_n "checking if $LUA is a Lua interpreter... " >&6; } - - _ax_lua_factorial=`$LUA 2>/dev/null -e ' - -- a simple factorial - function fact (n) - if n == 0 then - return 1 - else - return n * fact(n-1) - end - end - print("fact(5) is " .. fact(5))'` - if test "$_ax_lua_factorial" = 'fact(5) is 120'; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - as_fn_error $? "not a Lua interpreter" "$LINENO" 5 - -fi - - _ax_check_text="whether $LUA version >= 5.1, < 5.5" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 -$as_echo_n "checking $_ax_check_text... " >&6; } - - _ax_lua_good_version=`$LUA -e ' - -- a script to compare versions - function verstr2num(verstr) - local _, _, majorver, minorver = string.find(verstr, "^(%d+)%.(%d+)") - if majorver and minorver then - return tonumber(majorver) * 100 + tonumber(minorver) - end - end - local minver = verstr2num("5.1") - local _, _, trimver = string.find(_VERSION, "^Lua (.*)") - local ver = verstr2num(trimver) - local maxver = verstr2num("5.5") or 1e9 - if minver <= ver and ver < maxver then - print("yes") - else - print("no") - end'` - if test "x$_ax_lua_good_version" = "xyes"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - as_fn_error $? "version is out of range for specified LUA" "$LINENO" 5 -fi - - ax_display_LUA=$LUA - -else - _ax_check_text="for a Lua interpreter with version >= 5.1, < 5.5" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking $_ax_check_text" >&5 -$as_echo_n "checking $_ax_check_text... " >&6; } -if ${ax_cv_pathless_LUA+:} false; then : - $as_echo_n "(cached) " >&6 -else - for ax_cv_pathless_LUA in lua lua5.2 lua52 lua5.1 lua51 lua50 none; do - test "x$ax_cv_pathless_LUA" = 'xnone' && break - - _ax_lua_factorial=`$ax_cv_pathless_LUA 2>/dev/null -e ' - -- a simple factorial - function fact (n) - if n == 0 then - return 1 - else - return n * fact(n-1) - end - end - print("fact(5) is " .. fact(5))'` - if test "$_ax_lua_factorial" = 'fact(5) is 120'; then : - -else - continue -fi - - - _ax_lua_good_version=`$ax_cv_pathless_LUA -e ' - -- a script to compare versions - function verstr2num(verstr) - local _, _, majorver, minorver = string.find(verstr, "^(%d+)%.(%d+)") - if majorver and minorver then - return tonumber(majorver) * 100 + tonumber(minorver) - end - end - local minver = verstr2num("5.1") - local _, _, trimver = string.find(_VERSION, "^Lua (.*)") - local ver = verstr2num(trimver) - local maxver = verstr2num("5.5") or 1e9 - if minver <= ver and ver < maxver then - print("yes") - else - print("no") - end'` - if test "x$_ax_lua_good_version" = "xyes"; then : - break -fi - - done - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_pathless_LUA" >&5 -$as_echo "$ax_cv_pathless_LUA" >&6; } - if test "x$ax_cv_pathless_LUA" = 'xnone'; then : - LUA=':' -else - # Extract the first word of "$ax_cv_pathless_LUA", so it can be a program name with args. -set dummy $ax_cv_pathless_LUA; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LUA+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $LUA in - [\\/]* | ?:[\\/]*) - ac_cv_path_LUA="$LUA" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LUA="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -LUA=$ac_cv_path_LUA -if test -n "$LUA"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LUA" >&5 -$as_echo "$LUA" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi - ax_display_LUA=$ax_cv_pathless_LUA - -fi - - - if test "x$LUA" = 'x:'; then : - as_fn_error $? "cannot find suitable Lua interpreter" "$LINENO" 5 - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA version" >&5 -$as_echo_n "checking for $ax_display_LUA version... " >&6; } -if ${ax_cv_lua_version+:} false; then : - $as_echo_n "(cached) " >&6 -else - ax_cv_lua_version=`$LUA -e ' - -- return a version number in X.Y format - local _, _, ver = string.find(_VERSION, "^Lua (%d+%.%d+)") - print(ver)'` - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_version" >&5 -$as_echo "$ax_cv_lua_version" >&6; } - if test "x$ax_cv_lua_version" = 'x'; then : - as_fn_error $? "invalid Lua version number" "$LINENO" 5 -fi - LUA_VERSION=$ax_cv_lua_version - - LUA_SHORT_VERSION=`echo "$LUA_VERSION" | $SED 's|\.||'` - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA platform" >&5 -$as_echo_n "checking for $ax_display_LUA platform... " >&6; } -if ${ax_cv_lua_platform+:} false; then : - $as_echo_n "(cached) " >&6 -else - ax_cv_lua_platform=`$LUA -e 'print("unknown")'` -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_platform" >&5 -$as_echo "$ax_cv_lua_platform" >&6; } - LUA_PLATFORM=$ax_cv_lua_platform - - - LUA_PREFIX='${prefix}' - - LUA_EXEC_PREFIX='${exec_prefix}' - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA script directory" >&5 -$as_echo_n "checking for $ax_display_LUA script directory... " >&6; } -if ${ax_cv_lua_luadir+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$prefix" = 'xNONE'; then : - ax_lua_prefix=$ac_default_prefix -else - ax_lua_prefix=$prefix -fi - - ax_cv_lua_luadir="$LUA_PREFIX/share/lua/$LUA_VERSION" - - - - ax_lua_prefixed_path=`$LUA -e ' - -- get the path based on search type - local searchtype = "script" - local paths = "" - if searchtype == "script" then - paths = (package and package.path) or LUA_PATH - elseif searchtype == "module" then - paths = (package and package.cpath) or LUA_CPATH - end - -- search for the prefix - local prefix = "'$ax_lua_prefix'" - local minpath = "" - local mindepth = 1e9 - string.gsub(paths, "([^;]+)", - function (path) - path = string.gsub(path, "%?.*$", "") - path = string.gsub(path, "/[^/]*$", "") - if string.find(path, prefix) then - local depth = string.len(string.gsub(path, "[^/]", "")) - if depth < mindepth then - minpath = path - mindepth = depth - end - end - end) - print(minpath)'` - - if test "x$ax_lua_prefixed_path" != 'x'; then : - _ax_strip_prefix=`echo "$ax_lua_prefix" | $SED 's|.|.|g'` - ax_cv_lua_luadir=`echo "$ax_lua_prefixed_path" | \ - $SED "s|^$_ax_strip_prefix|$LUA_PREFIX|"` - -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_luadir" >&5 -$as_echo "$ax_cv_lua_luadir" >&6; } - luadir=$ax_cv_lua_luadir - - pkgluadir=\${luadir}/$PACKAGE - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ax_display_LUA module directory" >&5 -$as_echo_n "checking for $ax_display_LUA module directory... " >&6; } -if ${ax_cv_lua_luaexecdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$exec_prefix" = 'xNONE'; then : - ax_lua_exec_prefix=$ax_lua_prefix -else - ax_lua_exec_prefix=$exec_prefix -fi - - ax_cv_lua_luaexecdir="$LUA_EXEC_PREFIX/lib/lua/$LUA_VERSION" - - - - ax_lua_prefixed_path=`$LUA -e ' - -- get the path based on search type - local searchtype = "module" - local paths = "" - if searchtype == "script" then - paths = (package and package.path) or LUA_PATH - elseif searchtype == "module" then - paths = (package and package.cpath) or LUA_CPATH - end - -- search for the prefix - local prefix = "'$ax_lua_exec_prefix'" - local minpath = "" - local mindepth = 1e9 - string.gsub(paths, "([^;]+)", - function (path) - path = string.gsub(path, "%?.*$", "") - path = string.gsub(path, "/[^/]*$", "") - if string.find(path, prefix) then - local depth = string.len(string.gsub(path, "[^/]", "")) - if depth < mindepth then - minpath = path - mindepth = depth - end - end - end) - print(minpath)'` - - if test "x$ax_lua_prefixed_path" != 'x'; then : - _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | $SED 's|.|.|g'` - ax_cv_lua_luaexecdir=`echo "$ax_lua_prefixed_path" | \ - $SED "s|^$_ax_strip_prefix|$LUA_EXEC_PREFIX|"` - -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_lua_luaexecdir" >&5 -$as_echo "$ax_cv_lua_luaexecdir" >&6; } - luaexecdir=$ax_cv_lua_luaexecdir - - pkgluaexecdir=\${luaexecdir}/$PACKAGE - - - - -fi - -# Extract the first word of "ldoc", so it can be a program name with args. -set dummy ldoc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LDOC+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $LDOC in - [\\/]* | ?:[\\/]*) - ac_cv_path_LDOC="$LDOC" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LDOC="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_LDOC" && ac_cv_path_LDOC=":" - ;; -esac -fi -LDOC=$ac_cv_path_LDOC -if test -n "$LDOC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDOC" >&5 -$as_echo "$LDOC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -# Extract the first word of "specl", so it can be a program name with args. -set dummy specl; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SPECL+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $SPECL in - [\\/]* | ?:[\\/]*) - ac_cv_path_SPECL="$SPECL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_SPECL="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_SPECL" && ac_cv_path_SPECL=":" - ;; -esac -fi -SPECL=$ac_cv_path_SPECL -if test -n "$SPECL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPECL" >&5 -$as_echo "$SPECL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - - -ac_config_files="$ac_config_files Makefile build-aux/config.ld" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -ac_script=' -:mline -/\\$/{ - N - s,\\\n,, - b mline -} -t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g -t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g -t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` - - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by stdlib $as_me 41.2.2, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -stdlib config.status 41.2.2 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "build-aux/config.ld") CONFIG_FILES="$CONFIG_FILES build-aux/config.ld" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - - -eval set X " :F $CONFIG_FILES " -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - - - - esac - -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 9511e38..0000000 --- a/configure.ac +++ /dev/null @@ -1,40 +0,0 @@ -dnl configure.ac -dnl -dnl Copyright (C) 2012-2015 Gary V. Vaughan -dnl Written by Gary V. Vaughan, 2012 -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published -dnl by the Free Software Foundation; either version 3, or (at your -dnl option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program. If not, see . - - -dnl Initialise autoconf and automake -AC_INIT([stdlib], [41.2.2], [http://github.com/lua-stdlib/lua-stdlib/issues]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_MACRO_DIR([m4]) - -AS_BOX([Configuring AC_PACKAGE_TARNAME AC_PACKAGE_VERSION]) -echo - -AM_INIT_AUTOMAKE([-Wall]) -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -dnl Check for programs -AX_PROG_LUA([5.1], [5.5]) -AC_PATH_PROG([LDOC], [ldoc], [:]) -AC_PATH_PROG([SPECL], [specl], [:]) -AC_PROG_EGREP -AC_PROG_SED - -dnl Generate output files -AC_CONFIG_FILES([Makefile build-aux/config.ld]) -AC_OUTPUT diff --git a/doc/classes/std.container.html b/doc/classes/std.container.html index acdfc83..221e4f4 100644 --- a/doc/classes/std.container.html +++ b/doc/classes/std.container.html @@ -37,7 +37,7 @@

    Contents

    Classes

    -
      +

      Modules

      -
        +
        • std
        • std.debug
        • std.functional
        • @@ -112,7 +112,7 @@

          Objects


          -

          Objects

          +

          Objects

          @@ -129,7 +129,7 @@

          Objects

          Fields:

          • _type - string + string object name (default "Container")
          • @@ -145,23 +145,22 @@

            See also:

            Usage:

              -
              - local std = require "std"
              - local Container = std.container {}
              -
              - local Graph = Container {
              -   _type = "Graph",
              -   _functions = {
              -     nodes = function (graph)
              -       local n = 0
              -       for _ in std.pairs (graph) do n = n + 1 end
              -       return n
              -     end,
              -   },
              - }
              - local g = Graph { "node1", "node2" }
              - --> 2
              - print (Graph.nodes (g))
              +
              local std = require "std"
              +local Container = std.container {}
              +
              +local Graph = Container {
              +  _type = "Graph",
              +  _functions = {
              +    nodes = function (graph)
              +      local n = 0
              +      for _ in std.pairs (graph) do n = n + 1 end
              +      return n
              +    end,
              +  },
              +}
              +local g = Graph { "node1", "node2" }
              +--> 2
              +print (Graph.nodes (g))
            @@ -171,8 +170,8 @@

            Usage:

            -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
            diff --git a/doc/classes/std.list.html b/doc/classes/std.list.html index c29ce85..0098775 100644 --- a/doc/classes/std.list.html +++ b/doc/classes/std.list.html @@ -39,7 +39,7 @@

            Contents

            Classes

            -
              +

              Modules

              -
                + @@ -265,9 +265,8 @@

                Returns:

                Usage:

                  -
                  - --> {1, 2, 3, {4, 5}, 6, 7}
                  - list.concat ({1, 2, 3}, {{4, 5}, 6, 7})
                  +
                  --> {1, 2, 3, {4, 5}, 6, 7}
                  +list.concat ({1, 2, 3}, {{4, 5}, 6, 7})
                @@ -301,9 +300,8 @@

                Returns:

                Usage:

                  -
                  - --> {"x", 1, 2, 3}
                  - list.cons ({1, 2, 3}, "x")
                  +
                  --> {"x", 1, 2, 3}
                  +list.cons ({1, 2, 3}, "x")
                @@ -338,9 +336,8 @@

                Returns:

                Usage:

                  -
                  - --> {1, 2, 3, 1, 2, 3, 1, 2, 3}
                  - list.rep ({1, 2, 3}, 3)
                  +
                  --> {1, 2, 3, 1, 2, 3, 1, 2, 3}
                  +list.rep ({1, 2, 3}, 3)
                @@ -384,9 +381,8 @@

                Returns:

                Usage:

                  -
                  - --> {3, 4, 5}
                  - list.sub ({1, 2, 3, 4, 5, 6}, 3, 5)
                  +
                  --> {3, 4, 5}
                  +list.sub ({1, 2, 3, 4, 5, 6}, 3, 5)
                @@ -417,14 +413,13 @@

                Returns:

                Usage:

                  -
                  - --> {3, {4, 5}, 6, 7}
                  - list.tail {{1, 2}, 3, {4, 5}, 6, 7}
                  +
                  --> {3, {4, 5}, 6, 7}
                  +list.tail {{1, 2}, 3, {4, 5}, 6, 7}
          -

          Metamethods

          +

          Metamethods

          @@ -474,7 +469,7 @@

          Parameters:

          a list
        • m - List or table + List or table another list, or table (hash part is ignored)
        @@ -564,8 +559,8 @@

        Usage:

        -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
        diff --git a/doc/classes/std.object.html b/doc/classes/std.object.html index 65dc357..24cb886 100644 --- a/doc/classes/std.object.html +++ b/doc/classes/std.object.html @@ -39,7 +39,7 @@

        Contents

        Classes

        -
          +

          Modules

          -
            +
            • std
            • std.debug
            • std.functional
            • @@ -137,7 +137,7 @@

              Metamethods


              -

              Objects

              +

              Objects

              @@ -154,16 +154,16 @@

              Objects

              Fields:

              • _init - table or function + table or function object initialisation (default {})
              • _functions - table + table module functions omitted when cloned
              • _type - string + string object name (default "Object")
              • @@ -178,36 +178,34 @@

                See also:

                Usage:

                  -
                • - -- `_init` can be a list of keys; then the unnamed `init_1` through
                  - -- `init_m` values from the argument table are assigned to the
                  - -- corresponding keys in `new_object`.
                  - local Process = Object {
                  -   _type = "Process",
                  -   _init = { "status", "out", "err" },
                  - }
                  - local process = Process {
                  -   procs[pid].status, procs[pid].out, procs[pid].err, -- auto assigned
                  -   command = pipeline[pid],                           -- manual assignment
                  - }
                • -
                • - -- Or it can be a function, in which the arguments passed to the
                  - -- prototype during cloning are simply handed to the `_init` function.
                  - local Bag = Object {
                  -   _type = "Bag",
                  -   _init = function (obj, ...)
                  -     for e in std.elems {...} do
                  -       obj[#obj + 1] = e
                  -     end
                  -     return obj
                  -   end,
                  - }
                  - local bag = Bag ("function", "arguments", "sent", "to", "_init")
                • +
                • -- `_init` can be a list of keys; then the unnamed `init_1` through
                  +-- `init_m` values from the argument table are assigned to the
                  +-- corresponding keys in `new_object`.
                  +local Process = Object {
                  +  _type = "Process",
                  +  _init = { "status", "out", "err" },
                  +}
                  +local process = Process {
                  +  procs[pid].status, procs[pid].out, procs[pid].err, -- auto assigned
                  +  command = pipeline[pid],                           -- manual assignment
                  +}
                • +
                • -- Or it can be a function, in which the arguments passed to the
                  +-- prototype during cloning are simply handed to the `_init` function.
                  +local Bag = Object {
                  +  _type = "Bag",
                  +  _init = function (obj, ...)
                  +    for e in std.elems {...} do
                  +      obj[#obj + 1] = e
                  +    end
                  +    return obj
                  +  end,
                  +}
                  +local bag = Bag ("function", "arguments", "sent", "to", "_init")
              -

              Functions

              +

              Functions

              Methods
              @@ -259,18 +257,17 @@

              See also:

              Usage:

                -
                - local object = require "std.object"  -- module table
                - local Object = object {}             -- root object
                - local o = Object {
                -   field_1 = "value_1",
                -   method_1 = function (self) return self.field_1 end,
                - }
                - print (o.field_1)                    --> value_1
                - o.field_2 = 2
                - function o:method_2 (n) return self.field_2 + n end
                - print (o:method_2 (2))               --> 4
                - os.exit (0)
                +
                local object = require "std.object"  -- module table
                +local Object = object {}             -- root object
                +local o = Object {
                +  field_1 = "value_1",
                +  method_1 = function (self) return self.field_1 end,
                +}
                +print (o.field_1)                    --> value_1
                +o.field_2 = 2
                +function o:method_2 (n) return self.field_2 + n end
                +print (o:method_2 (2))               --> 4
                +os.exit (0)
              @@ -301,15 +298,15 @@

              Usage:

              Parameters:

              • obj - table + table destination object
              • src - table + table fields to copy int clone
              • map - table + table key renames as {old_key=new_key, ...} (default {})
              • @@ -318,7 +315,7 @@

                Parameters:

                Returns:

                  - table + table obj with non-private fields from src merged, and a metatable with private fields (if any) merged, both sets of keys renamed according to map @@ -328,11 +325,10 @@

                  Returns:

                  Usage:

                    -
                    - myobject.mapfields = function (obj, src, map)
                    -   object.mapfields (obj, src, map)
                    -   ...
                    - end
                    +
                    myobject.mapfields = function (obj, src, map)
                    +  object.mapfields (obj, src, map)
                    +  ...
                    +end
                  @@ -348,7 +344,7 @@

                  Usage:

                  function.

                  Additionally, this function returns the results of ??? for - file objects, or type otherwise. + file objects, or type otherwise.

                  Parameters:

                  @@ -361,7 +357,7 @@

                  Parameters:

                  Returns:

                    - string + string type of x
                  @@ -369,32 +365,31 @@

                  Returns:

                  Usage:

                    -
                    - local Stack = Object {
                    -   _type = "Stack",
                    +        
                    local Stack = Object {
                    +  _type = "Stack",
                     
                    -   __tostring = function (self) ... end,
                    +  __tostring = function (self) ... end,
                     
                    -   __index = {
                    -     push = function (self) ... end,
                    -     pop  = function (self) ... end,
                    -   },
                    - }
                    - local stack = Stack {}
                    - assert (stack:prototype () == getmetatable (stack)._type)
                    +  __index = {
                    +    push = function (self) ... end,
                    +    pop  = function (self) ... end,
                    +  },
                    +}
                    +local stack = Stack {}
                    +assert (stack:prototype () == getmetatable (stack)._type)
                     
                    - local prototype = Object.prototype
                    - assert (prototype (stack) == getmetatable (stack)._type)
                    +local prototype = Object.prototype
                    +assert (prototype (stack) == getmetatable (stack)._type)
                     
                    - local h = io.open (os.tmpname (), "w")
                    - assert (prototype (h) == io.type (h))
                    +local h = io.open (os.tmpname (), "w")
                    +assert (prototype (h) == io.type (h))
                     
                    - assert (prototype {} == type {})
                    +assert (prototype {} == type {})
              -

              Metamethods

              +

              Metamethods

              @@ -429,9 +424,8 @@

              See also:

              Usage:

                -
                - local Object = require "std.object" {} -- not a typo!
                - new = Object {"initialisation", "elements"}
                +
                local Object = require "std.object" {} -- not a typo!
                +new = Object {"initialisation", "elements"}
              @@ -481,14 +475,14 @@

              Usage:

              Returns:

                - string + string stringified object representation

              See also:

              Usage:

              @@ -503,8 +497,8 @@

              Usage:

              -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
              diff --git a/doc/classes/std.optparse.html b/doc/classes/std.optparse.html index 757d8dc..40569e3 100644 --- a/doc/classes/std.optparse.html +++ b/doc/classes/std.optparse.html @@ -40,7 +40,7 @@

              Contents

              Classes

              -
                +

                Modules

                -
                  +
                  • std
                  • std.debug
                  • std.functional
                  • @@ -170,7 +170,7 @@

                    Methods


                    -

                    Objects

                    +

                    Objects

                    @@ -205,21 +205,21 @@

                    Fields:

                    initialisation function
                  • program - string + string the first word following "Usage:" from spec
                  • version - string + string the last white-space delimited word on the first line of text from spec
                  • versiontext - string + string everything preceding "Usage:" from spec, and which will be displayed by the version on_handler
                  • helptext - string + string everything including and following "Usage:" from spec string and which will be displayed by the help on_handler @@ -231,51 +231,50 @@

                    Fields:

                    Usage:

                      -
                      - local std = require "std"
                      +        
                      local std = require "std"
                       
                      - local optparser = std.optparse [[
                      - any text VERSION
                      - Additional lines of text to show when the --version
                      - option is passed.
                      +local optparser = std.optparse [[
                      +any text VERSION
                      +Additional lines of text to show when the --version
                      +option is passed.
                       
                      - Several lines or paragraphs are permitted.
                      +Several lines or paragraphs are permitted.
                       
                      - Usage: PROGNAME
                      +Usage: PROGNAME
                       
                      - Banner text.
                      +Banner text.
                       
                      - Optional long description text to show when the --help
                      - option is passed.
                      +Optional long description text to show when the --help
                      +option is passed.
                       
                      - Several lines or paragraphs of long description are permitted.
                      +Several lines or paragraphs of long description are permitted.
                       
                      - Options:
                      +Options:
                       
                      -   -b                       a short option with no long option
                      -       --long               a long option with no short option
                      -       --another-long       a long option with internal hypen
                      -   -v, --verbose            a combined short and long option
                      -   -n, --dryrun, --dry-run  several spellings of the same option
                      -   -u, --name=USER          require an argument
                      -   -o, --output=[FILE]      accept an optional argument
                      -       --version            display version information, then exit
                      -       --help               display this help, then exit
                      +  -b                       a short option with no long option
                      +      --long               a long option with no short option
                      +      --another-long       a long option with internal hypen
                      +  -v, --verbose            a combined short and long option
                      +  -n, --dryrun, --dry-run  several spellings of the same option
                      +  -u, --name=USER          require an argument
                      +  -o, --output=[FILE]      accept an optional argument
                      +      --version            display version information, then exit
                      +      --help               display this help, then exit
                       
                      - Footer text.  Several lines or paragraphs are permitted.
                      +Footer text.  Several lines or paragraphs are permitted.
                       
                      - Please report bugs at bug-list@yourhost.com
                      - ]]
                      +Please report bugs at bug-list@yourhost.com
                      +]]
                       
                      - -- Note that std.io.die and std.io.warn will only prefix messages
                      - -- with `parser.program` if the parser options are assigned back to
                      - -- `_G.opts`:
                      - _G.arg, _G.opts = optparser:parse (_G.arg)
                      +-- Note that std.io.die and std.io.warn will only prefix messages +-- with `parser.program` if the parser options are assigned back to +-- `_G.opts`: +_G.arg, _G.opts = optparser:parse (_G.arg)
                  • -

                    Functions

                    +

                    Functions

                    Methods
                    @@ -294,7 +293,7 @@

                    Functions

                    Parameters:

                    @@ -330,11 +329,11 @@

                    Usage:

                    Parameters:

                    • opt - string + string option name
                    • optarg - string + string option argument, must be a key in boolvals (default "1")
                    • @@ -370,11 +369,11 @@

                      Usage:

                      Parameters:

                      @@ -382,7 +381,7 @@

                      Parameters:

                      Returns:

                        - string + string optarg
                      @@ -414,7 +413,7 @@

                      Usage:

                      Parameters:

                      • arglist - table + table list of arguments
                      • i @@ -461,7 +460,7 @@

                        Usage:

                        Parameters:

                        • arglist - table + table list of arguments
                        • i @@ -525,7 +524,7 @@

                          Usage:

                          Parameters:

                          @@ -557,7 +556,7 @@

                          Parameters:

                          Parameters:

                          • arglist - table + table list of arguments
                          • i @@ -621,7 +620,7 @@

                            Usage:

                            Parameters:

                            • arglist - table + table list of arguments
                            • i @@ -672,7 +671,7 @@

                              Usage:

                    -

                    Tables

                    +

                    Tables

                    @@ -761,7 +760,7 @@

                    Fields:

                    -

                    Methods

                    +

                    Methods

                    @@ -805,9 +804,8 @@

                    Parameters:

                    Usage:

                      -
                      - -- Don't process any arguments after `--`
                      - parser:on ('--', parser.finished)
                      +
                      -- Don't process any arguments after `--`
                      +parser:on ('--', parser.finished)
                    @@ -822,7 +820,7 @@

                    Usage:

                    Parameters:

                    • arglist - table + table list of arguments
                    • i @@ -857,11 +855,11 @@

                      Returns:

                      Parameters:

                      • arglist - table + table list of arguments
                      • defaults - table + table table of default option values (optional)
                      • @@ -870,7 +868,7 @@

                        Parameters:

                        Returns:

                        1. - table + table a list of unrecognised arglist elements
                        2. opts @@ -887,8 +885,8 @@

                          Returns:

                          -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                          diff --git a/doc/classes/std.set.html b/doc/classes/std.set.html index 0344303..cce8a30 100644 --- a/doc/classes/std.set.html +++ b/doc/classes/std.set.html @@ -39,7 +39,7 @@

                          Contents

                          Classes

                          -
                            +

                            Modules

                            -
                              +
                              • std
                              • std.debug
                              • std.functional
                              • @@ -86,6 +86,10 @@

                                Prototype Chain

                                +

                                See also:

                                +

                                Objects

                                @@ -174,7 +178,7 @@

                                Metamethods


                                -

                                Objects

                                +

                                Objects

                                @@ -191,7 +195,7 @@

                                Objects

                                Fields:

                                • _type - string + string object name (default "Set")
                                • @@ -207,15 +211,14 @@

                                  See also:

                                  Usage:

                                    -
                                    - local std = require "std"
                                    - std.prototype (std.set) --> "Set"
                                    - os.exit (0)
                                    +
                                    local std = require "std"
                                    +std.prototype (std.set) --> "Set"
                                    +os.exit (0)
                                -

                                Functions

                                +

                                Functions

                                Methods
                                @@ -418,10 +421,9 @@

                                Returns:

                                Usage:

                                  -
                                  - for byte = 32,126 do
                                  -   set.insert (isprintable, string.char (byte))
                                  - end
                                  +
                                  for byte = 32,126 do
                                  +  set.insert (isprintable, string.char (byte))
                                  +end
                                @@ -492,13 +494,12 @@

                                Returns:

                                Usage:

                                  -
                                  - if set.proper_subset (a, b) then
                                  -   for e in set.elems (set.difference (b, a)) do
                                  -     set.delete (b, e)
                                  -   end
                                  - end
                                  - assert (set.equal (a, b))
                                  +
                                  if set.proper_subset (a, b) then
                                  +  for e in set.elems (set.difference (b, a)) do
                                  +    set.delete (b, e)
                                  +  end
                                  +end
                                  +assert (set.equal (a, b))
                                @@ -610,7 +611,7 @@

                                Usage:

                                -

                                Metamethods

                                +

                                Metamethods

                                @@ -854,8 +855,8 @@

                                Usage:

                                -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                diff --git a/doc/classes/std.strbuf.html b/doc/classes/std.strbuf.html index 22c5c94..91f0d1d 100644 --- a/doc/classes/std.strbuf.html +++ b/doc/classes/std.strbuf.html @@ -39,7 +39,7 @@

                                Contents

                                Classes

                                -
                                  +

                                  Modules

                                  -
                                    +
                                    • std
                                    • std.debug
                                    • std.functional
                                    • @@ -81,8 +81,7 @@

                                      Class std.strbuf

                                      local b = a:concat "b" -- mutate *a* print (a, b) --> ab ab local c = a {} .. "c" -- copy and append -print (a, c) --> ab abc - +print (a, c) --> ab abc

                                      Prototype Chain

                                      @@ -127,7 +126,7 @@

                                      Metamethods


                                      -

                                      Objects

                                      +

                                      Objects

                                      @@ -144,7 +143,7 @@

                                      Objects

                                      Fields:

                                      • _type - string + string object name (default "StrBuf")
                                      • @@ -159,20 +158,19 @@

                                        See also:

                                        Usage:

                                          -
                                          - local std = require "std"
                                          - local StrBuf = std.strbuf {}
                                          - local a = {1, 2, 3}
                                          - local b = {a, "five", "six"}
                                          - a = a .. 4
                                          - b = b:concat "seven"
                                          - print (a, b) --> 1234   1234fivesixseven
                                          - os.exit (0)
                                          +
                                          local std = require "std"
                                          +local StrBuf = std.strbuf {}
                                          +local a = {1, 2, 3}
                                          +local b = {a, "five", "six"}
                                          +a = a .. 4
                                          +b = b:concat "seven"
                                          +print (a, b) --> 1234   1234fivesixseven
                                          +os.exit (0)
                                      -

                                      Functions

                                      +

                                      Functions

                                      Methods
                                      @@ -208,7 +206,7 @@

                                      Usage:

                                      -

                                      Metamethods

                                      +

                                      Metamethods

                                      @@ -268,14 +266,14 @@

                                      Parameters:

                                      Returns:

                                        - string + string concatenation of buffer contents

                                      See also:

                                      Usage:

                                      @@ -290,8 +288,8 @@

                                      Usage:

                                      -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                      diff --git a/doc/classes/std.tree.html b/doc/classes/std.tree.html index 0a64c23..013c647 100644 --- a/doc/classes/std.tree.html +++ b/doc/classes/std.tree.html @@ -39,7 +39,7 @@

                                      Contents

                                      Classes

                                      -
                                        +

                                        Modules

                                        -
                                          +
                                          • std
                                          • std.debug
                                          • std.functional
                                          • @@ -86,6 +86,10 @@

                                            Prototype Chain

                                            +

                                            See also:

                                            +

                                            Objects

                                            @@ -138,7 +142,7 @@

                                            Metamethods


                                            -

                                            Objects

                                            +

                                            Objects

                                            @@ -152,7 +156,7 @@

                                            Objects

                                            Fields:

                                            • _type - string + string object name (default "Tree")
                                            • @@ -168,25 +172,24 @@

                                              See also:

                                              Usage:

                                                -
                                                - local std = require "std"
                                                - local Tree = std.tree {}
                                                - local tr = Tree {}
                                                - tr[{"branch1", 1}] = "leaf1"
                                                - tr[{"branch1", 2}] = "leaf2"
                                                - tr[{"branch2", 1}] = "leaf3"
                                                - print (tr[{"branch1"}])      --> Tree {leaf1, leaf2}
                                                - print (tr[{"branch1", 2}])   --> leaf2
                                                - print (tr[{"branch1", 3}])   --> nil
                                                - --> leaf1	leaf2	leaf3
                                                - for leaf in std.tree.leaves (tr) do
                                                -   io.write (leaf .. "\t")
                                                - end
                                                +
                                                local std = require "std"
                                                +local Tree = std.tree {}
                                                +local tr = Tree {}
                                                +tr[{"branch1", 1}] = "leaf1"
                                                +tr[{"branch1", 2}] = "leaf2"
                                                +tr[{"branch2", 1}] = "leaf3"
                                                +print (tr[{"branch1"}])      --> Tree {leaf1, leaf2}
                                                +print (tr[{"branch1", 2}])   --> leaf2
                                                +print (tr[{"branch1", 3}])   --> nil
                                                +--> leaf1	leaf2	leaf3
                                                +for leaf in std.tree.leaves (tr) do
                                                +  io.write (leaf .. "\t")
                                                +end
                                            -

                                            Functions

                                            +

                                            Functions

                                            Methods
                                            @@ -200,7 +203,7 @@

                                            Functions

                                            Parameters:

                                            • t - table + table tree or tree-like table
                                            • nometa @@ -212,7 +215,7 @@

                                              Parameters:

                                              Returns:

                                                - Tree or table + Tree or table a deep copy of tr
                                              @@ -224,11 +227,10 @@

                                              See also:

                                              Usage:

                                                -
                                                - tr = {"one", {two=2}, {{"three"}, four=4}}
                                                - copy = clone (tr)
                                                - copy[2].two=5
                                                - assert (tr[2].two == 2)
                                                +
                                                tr = {"one", {two=2}, {{"three"}, four=4}}
                                                +copy = clone (tr)
                                                +copy[2].two=5
                                                +assert (tr[2].two == 2)
                                              @@ -243,7 +245,7 @@

                                              Usage:

                                              Parameters:

                                              @@ -254,7 +256,7 @@

                                              Returns:

                                              function iterator function
                                            • - Tree or table + Tree or table the tree tr
                        @@ -267,12 +269,11 @@

                        See also:

                        Usage:

                          -
                          - --> t = {"one", "three", "five"}
                          - for leaf in ileaves {"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"}
                          - do
                          -   t[#t + 1] = leaf
                          - end
                          +
                          --> t = {"one", "three", "five"}
                          +for leaf in ileaves {"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"}
                          +do
                          +  t[#t + 1] = leaf
                          +end
                        @@ -290,7 +291,7 @@

                        Usage:

                        Parameters:

                        @@ -301,7 +302,7 @@

                        Returns:

                        function iterator function
                      • - tree or table + tree or table the tree, tr
                      • @@ -324,7 +325,7 @@

                        See also:

                        Parameters:

                        @@ -335,7 +336,7 @@

                        Returns:

                        function iterator function
                      • - table + table t
                      • @@ -348,13 +349,12 @@

                        See also:

                        Usage:

                          -
                          - for leaf in leaves {"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"}
                          - do
                          -   t[#t + 1] = leaf
                          - end
                          - --> t = {2, 4, "five", "foo", "one", "three"}
                          - table.sort (t, lambda "=tostring(_1) < tostring(_2)")
                          +
                          for leaf in leaves {"one", {two=2}, {{"three"}, four=4}}, foo="bar", "five"}
                          +do
                          +  t[#t + 1] = leaf
                          +end
                          +--> t = {2, 4, "five", "foo", "one", "three"}
                          +table.sort (t, lambda "=tostring(_1) < tostring(_2)")
                        @@ -369,11 +369,11 @@

                        Usage:

                        Parameters:

                        @@ -381,7 +381,7 @@

                        Parameters:

                        Returns:

                          - table + table t with nodes from u merged in
                        @@ -419,7 +419,7 @@

                        Usage:

                        Parameters:

                        @@ -430,7 +430,7 @@

                        Returns:

                        function iterator function
                      • - Tree or table + Tree or table the tree, tr
                      • @@ -442,28 +442,27 @@

                        See also:

                        Usage:

                          -
                          - -- tree = +-- node1
                          - --        |    +-- leaf1
                          - --        |    '-- leaf2
                          - --        '-- leaf 3
                          - tree = Tree { Tree { "leaf1", "leaf2"}, "leaf3" }
                          - for node_type, path, node in nodes (tree) do
                          -   print (node_type, path, node)
                          - end
                          - --> "branch"   {}      {{"leaf1", "leaf2"}, "leaf3"}
                          - --> "branch"   {1}     {"leaf1", "leaf"2")
                          - --> "leaf"     {1,1}   "leaf1"
                          - --> "leaf"     {1,2}   "leaf2"
                          - --> "join"     {1}     {"leaf1", "leaf2"}
                          - --> "leaf"     {2}     "leaf3"
                          - --> "join"     {}      {{"leaf1", "leaf2"}, "leaf3"}
                          - os.exit (0)
                          +
                          -- tree = +-- node1
                          +--        |    +-- leaf1
                          +--        |    '-- leaf2
                          +--        '-- leaf 3
                          +tree = Tree { Tree { "leaf1", "leaf2"}, "leaf3" }
                          +for node_type, path, node in nodes (tree) do
                          +  print (node_type, path, node)
                          +end
                          +--> "branch"   {}      {{"leaf1", "leaf2"}, "leaf3"}
                          +--> "branch"   {1}     {"leaf1", "leaf"2")
                          +--> "leaf"     {1,1}   "leaf1"
                          +--> "leaf"     {1,2}   "leaf2"
                          +--> "join"     {1}     {"leaf1", "leaf2"}
                          +--> "leaf"     {2}     "leaf3"
                          +--> "join"     {}      {{"leaf1", "leaf2"}, "leaf3"}
                          +os.exit (0)
                    -

                    Metamethods

                    +

                    Metamethods

                    @@ -537,8 +536,8 @@

                    Usage:

                    -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                    diff --git a/doc/index.html b/doc/index.html index 9a1556f..27f1588 100644 --- a/doc/index.html +++ b/doc/index.html @@ -30,7 +30,7 @@

                    stdlib 41.2.2

                    Modules

                    -
                      +

                      Classes

                      -
                        +
                        • std.tree
                        • std.container
                        • std.object
                        • @@ -58,7 +58,19 @@

                          Classes

                          -

                          Standard Lua Libraries

                          +

                          +

                          Standard Lua Libraries

                          + +

                          This is a collection of Lua libraries for Lua 5.1 (including LuaJIT), +5.2, 5.3 and 5.4. Stdlib has no prerequisites beyond a standard Lua +system.

                          + +

                          LICENSE

                          + +

                          The libraries are copyright by their authors 2000-2018, and released under +the MIT license (the same license as Lua itself). There is no warranty.

                          + +

                          Modules

                          @@ -138,8 +150,8 @@

                          Classes

                          -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                          diff --git a/doc/ldoc.css b/doc/ldoc.css index 7d74ca2..52c4ad2 100644 --- a/doc/ldoc.css +++ b/doc/ldoc.css @@ -28,7 +28,6 @@ del,ins { text-decoration: none; } li { - list-style: disc; margin-left: 20px; } caption,th { @@ -88,7 +87,7 @@ em { font-style: italic;} h1 { font-size: 1.5em; - margin: 0 0 20px 0; + margin: 20px 0 20px 0; } h2, h3, h4 { margin: 15px 0 10px 0; } h2 { font-size: 1.25em; } @@ -114,24 +113,18 @@ p.name { padding-top: 1em; } -pre.example { - background-color: rgb(245, 245, 245); - border: 1px solid silver; - padding: 10px; - margin: 10px 0 10px 0; - font-family: "Andale Mono", monospace; - font-size: .85em; -} - pre { background-color: rgb(245, 245, 245); - border: 1px solid silver; + border: 1px solid #C0C0C0; /* silver */ padding: 10px; margin: 10px 0 10px 0; overflow: auto; font-family: "Andale Mono", monospace; } +pre.example { + font-size: .85em; +} table.index { border: 1px #00007f; } table.index td { text-align: left; vertical-align: top; } @@ -291,6 +284,7 @@ a:target + * { background-color: #FF9; } + /* styles for prettification of source */ pre .comment { color: #558817; } pre .constant { color: #a8660d; } @@ -303,5 +297,7 @@ pre .number { color: #f8660d; } pre .operator { color: #2239a8; font-weight: bold; } pre .preprocessor, pre .prepro { color: #a33243; } pre .global { color: #800080; } +pre .user-keyword { color: #800080; } pre .prompt { color: #558817; } pre .url { color: #272fc2; text-decoration: underline; } + diff --git a/doc/modules/std.debug.html b/doc/modules/std.debug.html index 052f34c..a41a045 100644 --- a/doc/modules/std.debug.html +++ b/doc/modules/std.debug.html @@ -39,7 +39,7 @@

                          Contents

                          Modules

                          -
                            +

                            Classes

                            -
                              +
                              • std.tree
                              • std.container
                              • std.object
                              • @@ -180,7 +180,7 @@

                                Fields


                                -

                                Functions

                                +

                                Functions

                                Methods
                                @@ -197,15 +197,15 @@

                                Functions

                                Parameters:

                                • version - string + string first deprecation release version
                                • name - string + string function name for automatic warning message
                                • extramsg - string + string additional warning text (optional)
                                • @@ -240,15 +240,15 @@

                                  Usage:

                                  Parameters:

                                  • version - string + string first deprecation release version
                                  • name - string + string function name for automatic warning message
                                  • extramsg - string + string additional warning text (optional)
                                  • @@ -261,7 +261,7 @@

                                    Parameters:

                                    Returns:

                                      - string + string deprecation warning message, or empty string
                                    @@ -322,7 +322,7 @@

                                    Usage:

                                    Parameters:

                                    • name - string + string function to blame in error message
                                    • i @@ -330,7 +330,7 @@

                                      Parameters:

                                      argument number to blame in error message
                                    • expected - string + string specification for acceptable argument types
                                    • actual @@ -348,10 +348,9 @@

                                      Parameters:

                                      Usage:

                                        -
                                        - local function case (with, branches)
                                        -   argcheck ("std.functional.case", 2, "#table", branches)
                                        -   ...
                                        +
                                        local function case (with, branches)
                                        +  argcheck ("std.functional.case", 2, "#table", branches)
                                        +  ...
                                      @@ -369,7 +368,7 @@

                                      Usage:

                                      Parameters:

                                      • name - string + string function to callout in error message
                                      • i @@ -377,7 +376,7 @@

                                        Parameters:

                                        argument number
                                      • extramsg - string + string additional text to append to message inside parentheses (optional)
                                      • @@ -398,11 +397,10 @@

                                        See also:

                                        Usage:

                                          -
                                          - local function slurp (file)
                                          -   local h, err = input_handle (file)
                                          -   if h == nil then argerror ("std.io.slurp", 1, err, 2) end
                                          -   ...
                                          +
                                          local function slurp (file)
                                          +  local h, err = input_handle (file)
                                          +  if h == nil then argerror ("std.io.slurp", 1, err, 2) end
                                          +  ...
                                        @@ -451,7 +449,7 @@

                                        Usage:

                                        Parameters:

                                        • decl - string + string function type declaration string
                                        • inner @@ -465,11 +463,10 @@

                                          Parameters:

                                          Usage:

                                            -
                                            - local case = argscheck ("std.functional.case (?any, #table) => [any...]",
                                            -   function (with, branches)
                                            -     ...
                                            - end)
                                            +
                                            local case = argscheck ("std.functional.case (?any, #table) => [any...]",
                                            +  function (with, branches)
                                            +    ...
                                            +end)
                                          @@ -491,9 +488,8 @@

                                          See also:

                                          Usage:

                                            -
                                            - local debug = require "std.debug"
                                            - debug "oh noes!"
                                            +
                                            local debug = require "std.debug"
                                            +debug "oh noes!"
                                          @@ -508,7 +504,7 @@

                                          Usage:

                                          Parameters:

                                          • expected - string + string a pipe delimited list of matchable types
                                          • actual @@ -524,7 +520,7 @@

                                            Parameters:

                                            Returns:

                                              - string + string formatted extramsg for this mismatch for argerror
                                            @@ -537,10 +533,9 @@

                                            See also:

                                            Usage:

                                              -
                                              -   if fmt ~= nil and type (fmt) ~= "string" then
                                              -     argerror ("format", 1, extramsg_mismatch ("?string", fmt))
                                              -   end
                                              +
                                              if fmt ~= nil and type (fmt) ~= "string" then
                                              +  argerror ("format", 1, extramsg_mismatch ("?string", fmt))
                                              +end
                                            @@ -602,10 +597,9 @@

                                            Parameters:

                                            Usage:

                                              -
                                              - local _DEBUG = require "std.debug_init"._DEBUG
                                              - _DEBUG.level = 3
                                              - say (2, "_DEBUG table contents:", _DEBUG)
                                              +
                                              local _DEBUG = require "std.debug_init"._DEBUG
                                              +_DEBUG.level = 3
                                              +say (2, "_DEBUG table contents:", _DEBUG)
                                            @@ -623,7 +617,7 @@

                                            Usage:

                                            Parameters:

                                            @@ -633,14 +627,13 @@

                                            Parameters:

                                            Usage:

                                              -
                                              - _DEBUG = { call = true }
                                              - local debug = require "std.debug"
                                              +
                                              _DEBUG = { call = true }
                                              +local debug = require "std.debug"
                                -

                                Tables

                                +

                                Tables

                                @@ -690,7 +683,7 @@

                                Usage:

                                -

                                Fields

                                +

                                Fields

                                @@ -703,7 +696,7 @@

                                Fields

                                • bad - string + string the thing there are too many of
                                • expected @@ -727,10 +720,9 @@

                                  See also:

                                  Usage:

                                    -
                                    -   if maxn (argt) > 7 then
                                    -     argerror ("sevenses", 8, extramsg_toomany ("argument", 7, maxn (argt)))
                                    -   end
                                    +
                                    if maxn (argt) > 7 then
                                    +  argerror ("sevenses", 8, extramsg_toomany ("argument", 7, maxn (argt)))
                                    +end
                                  @@ -767,7 +759,7 @@

                                  Usage:

                                  • name - string + string function to callout in error message
                                  • i @@ -775,7 +767,7 @@

                                    Usage:

                                    argument number
                                  • extramsg - string + string additional text to append to message inside parentheses (optional)
                                  • @@ -791,11 +783,10 @@

                                    Usage:

                                    Usage:

                                      -
                                      - local function slurp (file)
                                      -   local h, err = input_handle (file)
                                      -   if h == nil then argerror ("std.io.slurp", 1, err, 2) end
                                      -   ...
                                      +
                                      local function slurp (file)
                                      +  local h, err = input_handle (file)
                                      +  if h == nil then argerror ("std.io.slurp", 1, err, 2) end
                                      +  ...
                                    @@ -813,7 +804,7 @@

                                    Usage:

                                    target function
                                  • env - table + table new function environment
                                  @@ -833,7 +824,7 @@

                                  Usage:

                                  @@ -849,8 +840,8 @@

                                  Usage:

                                  -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                  diff --git a/doc/modules/std.functional.html b/doc/modules/std.functional.html index f5eeda1..bb0c0c0 100644 --- a/doc/modules/std.functional.html +++ b/doc/modules/std.functional.html @@ -38,7 +38,7 @@

                                  Contents

                                  Modules

                                  -
                          - + - + @@ -166,7 +166,7 @@

                          Types


                          -

                          Functions

                          +

                          Functions

                          Methods
                          @@ -184,7 +184,7 @@

                          Parameters:

                          function to apply partially
                        • argt - table + table table of fn arguments to bind
                        • @@ -247,7 +247,7 @@

                          Parameters:

                          expression to match
                        • branches - table + table map possible matches to functions
                        • @@ -271,12 +271,11 @@

                          See also:

                          Usage:

                            -
                            - return case (type (object), {
                            -   table  = "table",
                            -   string = function ()  return "string" end,
                            -            function (s) error ("unhandled type: " .. s) end,
                            - })
                            +
                            return case (type (object), {
                            +  table  = "table",
                            +  string = function ()  return "string" end,
                            +           function (s) error ("unhandled type: " .. s) end,
                            +})
                          @@ -303,7 +302,7 @@

                          Parameters:

                          Returns:

                            - table + table of results from running ifn on args
                          @@ -316,9 +315,8 @@

                          See also:

                          Usage:

                            -
                            - --> {"a", "b", "c"}
                            - collect {"a", "b", "c", x=1, y=2, z=5}
                            +
                            --> {"a", "b", "c"}
                            +collect {"a", "b", "c", x=1, y=2, z=5}
                          @@ -356,9 +354,8 @@

                          Returns:

                          Usage:

                            -
                            - vpairs = compose (table.invert, ipairs)
                            - for v, i in vpairs {"a", "b", "c"} do process (v, i) end
                            +
                            vpairs = compose (table.invert, ipairs)
                            +for v, i in vpairs {"a", "b", "c"} do process (v, i) end
                          @@ -398,14 +395,13 @@

                          See also:

                          Usage:

                            -
                            - -- recursively calculate the nth triangular number
                            - function triangle (n)
                            -   return cond (
                            -     n <= 0, 0,
                            -     n == 1, 1,
                            -             function () return n + triangle (n - 1) end)
                            - end
                            +
                            -- recursively calculate the nth triangular number
                            +function triangle (n)
                            +  return cond (
                            +    n <= 0, 0,
                            +    n == 1, 1,
                            +            function () return n + triangle (n - 1) end)
                            +end
                          @@ -440,9 +436,8 @@

                          Returns:

                          Usage:

                            -
                            - add = curry (function (x, y) return x + y end, 2)
                            - incr, decr = add (1), add (-1)
                            +
                            add = curry (function (x, y) return x + y end, 2)
                            +incr, decr = add (1), add (-1)
                          @@ -473,7 +468,7 @@

                          Parameters:

                          Returns:

                            - table + table elements e for which pfn (e) is not "falsey".
                          @@ -486,15 +481,14 @@

                          See also:

                          Usage:

                            -
                            - --> {2, 4}
                            - filter (lambda '|e|e%2==0', std.elems, {1, 2, 3, 4})
                            +
                            --> {2, 4}
                            +filter (lambda '|e|e%2==0', std.elems, {1, 2, 3, 4})
                          - foldl (fn[, d=t[1]], t) + foldl (fn[, d=t[1], t)
                          Fold a binary function left associatively. @@ -510,10 +504,10 @@

                          Parameters:

                        • d initial left-most argument - (default t[1]) + (default t[1)
                        • t - table + table a table
                        • @@ -539,7 +533,7 @@

                          Usage:

                          - foldr (fn[, d=t[1]], t) + foldr (fn[, d=t[1], t)
                          Fold a binary function right associatively. @@ -555,10 +549,10 @@

                          Parameters:

                        • d initial right-most argument - (default t[1]) + (default t[1)
                        • t - table + table a table
                        • @@ -634,7 +628,7 @@

                          Returns:

                          Parameters:

                          @@ -650,10 +644,9 @@

                          Returns:

                          Usage:

                            -
                            - -- The following are equivalent:
                            - lambda '= _1 < _2'
                            - lambda '|a,b| a<b'
                            +
                            -- The following are equivalent:
                            +lambda '= _1 < _2'
                            +lambda '|a,b| a<b'
                          @@ -684,7 +677,7 @@

                          Parameters:

                          Returns:

                            - table + table results
                          @@ -698,9 +691,8 @@

                          See also:

                          Usage:

                            -
                            - --> {1, 4, 9, 16}
                            - map (lambda '=_1*_1', std.ielems, {1, 2, 3, 4})
                            +
                            --> {1, 4, 9, 16}
                            +map (lambda '=_1*_1', std.ielems, {1, 2, 3, 4})
                          @@ -719,7 +711,7 @@

                          Parameters:

                          map function
                        • tt - table + table a table of fn argument lists
                        • @@ -727,7 +719,7 @@

                          Parameters:

                          Returns:

                            - table + table new table of fn results
                          @@ -740,10 +732,9 @@

                          See also:

                          Usage:

                            -
                            - --> {"123", "45"}, {a="123", b="45"}
                            - conc = bind (map_with, {lambda '|...|table.concat {...}'})
                            - conc {{1, 2, 3}, {4, 5}}, conc {a={1, 2, 3, x="y"}, b={4, 5, z=6}}
                            +
                            --> {"123", "45"}, {a="123", b="45"}
                            +conc = bind (map_with, {lambda '|...|table.concat {...}'})
                            +conc {{1, 2, 3}, {4, 5}}, conc {a={1, 2, 3, x="y"}, b={4, 5, z=6}}
                          @@ -853,9 +844,8 @@

                          See also:

                          Usage:

                            -
                            - --> 2 ^ 3 ^ 4 ==> 4096
                            - reduce (std.operator.pow, 2, std.ielems, {3, 4})
                            +
                            --> 2 ^ 3 ^ 4 ==> 4096
                            +reduce (std.operator.pow, 2, std.ielems, {3, 4})
                          @@ -872,7 +862,7 @@

                          Usage:

                          Parameters:

                          @@ -880,7 +870,7 @@

                          Parameters:

                          Returns:

                            - table + table new table with lists of elements of the same key from tt
                          @@ -894,9 +884,8 @@

                          See also:

                          Usage:

                            -
                            - --> {{1, 3, 5}, {2, 4}}, {a={x=1, y=3, z=5}, b={x=2, y=4}}
                            - zip {{1, 2}, {3, 4}, {5}}, zip {x={a=1, b=2}, y={a=3, b=4}, z={a=5}}
                            +
                            --> {{1, 3, 5}, {2, 4}}, {a={x=1, y=3, z=5}, b={x=2, y=4}}
                            +zip {{1, 2}, {3, 4}, {5}}, zip {x={a=1, b=2}, y={a=3, b=4}, z={a=5}}
                          @@ -915,7 +904,7 @@

                          Parameters:

                          function
                        • tt - table + table table of tables
                        • @@ -923,7 +912,7 @@

                          Parameters:

                          Returns:

                            - table + table a new table of results from calls to fn with arguments made from all elements the same key in the original tables; effectively the "columns" in a simple list @@ -939,16 +928,14 @@

                            See also:

                            Usage:

                              -
                              - --> {"135", "24"}, {a="1", b="25"}
                              - conc = bind (zip_with, {lambda '|...|table.concat {...}'})
                              - conc {{1, 2}, {3, 4}, {5}}, conc {{a=1, b=2}, x={a=3, b=4}, {b=5}}
                              +
                              --> {"135", "24"}, {a="1", b="25"}
                              +conc = bind (zip_with, {lambda '|...|table.concat {...}'})
                              +conc {{1, 2}, {3, 4}, {5}}, conc {{a=1, b=2}, x={a=3, b=4}, {b=5}}
                          -

                          Types

                          - +

                          Types

                          @@ -969,7 +956,7 @@

                          Parameters:

                          Returns:

                            - string + string normalized arguments
                          @@ -977,9 +964,8 @@

                          Returns:

                          Usage:

                            -
                            - local normalize = function (name, value, props) return name end
                            - local intern = std.functional.memoize (mksymbol, normalize)
                            +
                            local normalize = function (name, value, props) return name end
                            +local intern = std.functional.memoize (mksymbol, normalize)
                          @@ -1010,9 +996,8 @@

                          Returns:

                          Usage:

                            -
                            - local predicate = lambda '|k,v|type(v)=="string"'
                            - local strvalues = filter (predicate, std.pairs, {name="Roberto", id=12345})
                            +
                            local predicate = lambda '|k,v|type(v)=="string"'
                            +local strvalues = filter (predicate, std.pairs, {name="Roberto", id=12345})
                          @@ -1022,8 +1007,8 @@

                          Usage:

                          -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                          diff --git a/doc/modules/std.html b/doc/modules/std.html index 40f7de8..4242564 100644 --- a/doc/modules/std.html +++ b/doc/modules/std.html @@ -39,7 +39,7 @@

                          Contents

                          Modules

                          -
                            +

                            Classes

                            -
                              +
                              • std.tree
                              • std.container
                              • std.object
                              • @@ -165,7 +165,7 @@

                                Metamethods


                                -

                                Functions

                                +

                                Functions

                                Methods
                                @@ -182,7 +182,7 @@

                                Parameters:

                                expression, expected to be truthy
                              • f - string + string format string (default "")
                              • @@ -202,9 +202,8 @@

                                Returns:

                                Usage:

                                  -
                                  - std.assert (expected ~= nil, "100% unexpected!")
                                  - std.assert (expected ~= nil, "%s unexpected!", expected)
                                  +
                                  std.assert (expected ~= nil, "100% unexpected!")
                                  +std.assert (expected ~= nil, "%s unexpected!", expected)
                                @@ -223,7 +222,7 @@

                                Usage:

                                Parameters:

                                • namespace - table + table where to install global functions (default _G)
                                • @@ -232,7 +231,7 @@

                                  Parameters:

                                  Returns:

                                    - table + table module table
                                  @@ -256,7 +255,7 @@

                                  Usage:

                                  Parameters:

                                  @@ -267,7 +266,7 @@

                                  Returns:

                                  function iterator function
                                • - table + table t, the table being iterated over
                                • key, the previous iteration key
                                • @@ -297,7 +296,7 @@

                                  Usage:

                                  Parameters:

                                  @@ -330,7 +329,7 @@

                                  Parameters:

                                  item to act on
                                • n - string + string name of metamethod to lookup
                                @@ -362,7 +361,7 @@

                                Usage:

                                Parameters:

                                @@ -373,7 +372,7 @@

                                Returns:

                                function iterator function
                              • - table + table t, the table being iterated over
                              • int @@ -409,7 +408,7 @@

                                Usage:

                                Parameters:

                                @@ -420,7 +419,7 @@

                                Returns:

                                function iterator function
                              • - table + table t, the table being iterated over
                              • int @@ -437,14 +436,13 @@

                                See also:

                                Usage:

                                  -
                                  - -- length of sequence
                                  - args = {"first", "second", nil, "last"}
                                  - --> 1=first
                                  - --> 2=second
                                  - for i, v in std.ipairs (args) do
                                  -   print (string.format ("%d=%s", i, v))
                                  - end
                                  +
                                  -- length of sequence
                                  +args = {"first", "second", nil, "last"}
                                  +--> 1=first
                                  +--> 2=second
                                  +for i, v in std.ipairs (args) do
                                  +  print (string.format ("%d=%s", i, v))
                                  +end
                                @@ -461,7 +459,7 @@

                                Usage:

                                Parameters:

                                @@ -469,7 +467,7 @@

                                Parameters:

                                Returns:

                                  - table + table a new table with integer keyed elements in reverse order with respect to t
                                @@ -483,9 +481,8 @@

                                See also:

                                Usage:

                                  -
                                  - local rielems = std.functional.compose (std.ireverse, std.ielems)
                                  - for e in rielems (l) do process (e) end
                                  +
                                  local rielems = std.functional.compose (std.ireverse, std.ielems)
                                  +for e in rielems (l) do process (e) end
                                @@ -503,7 +500,7 @@

                                Usage:

                                Parameters:

                                • namespace - table + table where to install global functions (default _G)
                                • @@ -512,7 +509,7 @@

                                  Parameters:

                                  Returns:

                                    - table + table the module table
                                  @@ -536,7 +533,7 @@

                                  Usage:

                                  Parameters:

                                  @@ -547,7 +544,7 @@

                                  Returns:

                                  function iterator function
                                • - table + table t
                                • @@ -575,7 +572,7 @@

                                  Usage:

                                  Parameters:

                                  @@ -586,7 +583,7 @@

                                  Returns:

                                  function iterator function
                                • - table + table t, the table being iterated over
                                • key, the previous iteration key
                                • @@ -618,21 +615,21 @@

                                  Usage:

                                  Parameters:

                                  • module - string + string module to require
                                  • min - string + string lowest acceptable version (optional)
                                  • too_big - string + string lowest version that is too big (optional)
                                  • pattern - string + string to match version in module.version or module._VERSION (default: "([%.%d]+)%D*$") (optional) @@ -644,9 +641,8 @@

                                    Parameters:

                                    Usage:

                                      -
                                      - -- posix.version == "posix library for Lua 5.2 / 32"
                                      - posix = require ("posix", "29")
                                      +
                                      -- posix.version == "posix library for Lua 5.2 / 32"
                                      +posix = require ("posix", "29")
                                    @@ -663,7 +659,7 @@

                                    Usage:

                                    Parameters:

                                    @@ -674,7 +670,7 @@

                                    Returns:

                                    function iterator function
                                  • - table + table t
                                  • number @@ -707,7 +703,7 @@

                                    Usage:

                                    Parameters:

                                    @@ -718,7 +714,7 @@

                                    Returns:

                                    function iterator function
                                  • - table + table t
                                  • @@ -753,7 +749,7 @@

                                    Parameters:

                                    Returns:

                                      - string + string compact string rendering of x
                                    @@ -761,14 +757,13 @@

                                    Returns:

                                    Usage:

                                      -
                                      - -- {1=baz,foo=bar}
                                      - print (std.tostring {foo="bar","baz"})
                                      +
                                      -- {1=baz,foo=bar}
                                      +print (std.tostring {foo="bar","baz"})
                              • -

                                Tables

                                +

                                Tables

                                @@ -796,8 +791,7 @@

                                Fields:

                                -

                                Metamethods

                                - +

                                Metamethods

                                @@ -813,7 +807,7 @@

                                Metamethods

                                Parameters:

                                @@ -821,7 +815,7 @@

                                Parameters:

                                Returns:

                                  - table or nil + table or nil the submodule that was loaded to satisfy the missing name, otherwise nil if nothing was found
                                @@ -830,9 +824,8 @@

                                Returns:

                                Usage:

                                  -
                                  - local std = require "std"
                                  - local prototype = std.object.prototype
                                  +
                                  local std = require "std"
                                  +local prototype = std.object.prototype
                                @@ -842,8 +835,8 @@

                                Usage:

                                -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                diff --git a/doc/modules/std.io.html b/doc/modules/std.io.html index f69b83a..40339e2 100644 --- a/doc/modules/std.io.html +++ b/doc/modules/std.io.html @@ -38,7 +38,7 @@

                                Contents

                                Modules

                                -
                                  +

                                  Classes

                                  -
                                    +
                                    • std.tree
                                    • std.container
                                    • std.object
                                    • @@ -145,7 +145,7 @@

                                      Types


                                      -

                                      Functions

                                      +

                                      Functions

                                      Methods
                                      @@ -159,7 +159,7 @@

                                      Functions

                                      Parameters:

                                      @@ -193,7 +193,7 @@

                                      Usage:

                                      Parameters:

                                      @@ -201,7 +201,7 @@

                                      Parameters:

                                      Returns:

                                        - string + string path
                                      @@ -231,7 +231,7 @@

                                      Usage:

                                      Parameters:

                                      • msg - string + string format string
                                      • ... @@ -263,7 +263,7 @@

                                        Usage:

                                        Parameters:

                                        @@ -271,7 +271,7 @@

                                        Parameters:

                                        Returns:

                                          - string + string a new path with the last dirsep and following truncated
                                        @@ -297,7 +297,7 @@

                                        Usage:

                                        Parameters:

                                        • namespace - table + table where to install global functions (default _G)
                                        • @@ -306,7 +306,7 @@

                                          Parameters:

                                          Returns:

                                            - table + table the std.io module table
                                          @@ -343,11 +343,10 @@

                                          Parameters:

                                          Usage:

                                            -
                                            - #! /usr/bin/env lua
                                            - -- minimal cat command
                                            - local io = require "std.io"
                                            - io.process_files (function () io.write (io.slurp ()) end)
                                            +
                                            #! /usr/bin/env lua
                                            +-- minimal cat command
                                            +local io = require "std.io"
                                            +io.process_files (function () io.write (io.slurp ()) end)
                                          @@ -363,7 +362,7 @@

                                          Usage:

                                          Parameters:

                                          • file - file or string + file or string file handle or name; if file is a file handle, that file is closed after reading (default io.input()) @@ -396,7 +395,7 @@

                                            Usage:

                                            Parameters:

                                            @@ -404,14 +403,14 @@

                                            Parameters:

                                            Returns:

                                              - string + string output, or nil if error

                                            See also:

                                            Usage:

                                            @@ -431,7 +430,7 @@

                                            Usage:

                                            Parameters:

                                            • file - file or string + file or string file handle or name; if file is a file handle, that file is closed after reading (default io.input()) @@ -507,7 +506,7 @@

                                              Usage:

                                              Parameters:

                                              • msg - string + string format string
                                              • ... @@ -525,13 +524,12 @@

                                                See also:

                                                Usage:

                                                  -
                                                  -   local OptionParser = require "std.optparse"
                                                  -   local parser = OptionParser "eg 0\nUsage: eg\n"
                                                  -   _G.arg, _G.opts = parser:parse (_G.arg)
                                                  -   if not _G.opts.keep_going then
                                                  -     require "std.io".warn "oh noes!"
                                                  -   end
                                                  +
                                                  local OptionParser = require "std.optparse"
                                                  +local parser = OptionParser "eg 0\nUsage: eg\n"
                                                  +_G.arg, _G.opts = parser:parse (_G.arg)
                                                  +if not _G.opts.keep_going then
                                                  +  require "std.io".warn "oh noes!"
                                                  +end
                                                @@ -552,7 +550,7 @@

                                                Parameters:

                                                (default io.output())
                                              • ... - string or number + string or number values to write (as for write)
                                              @@ -567,8 +565,7 @@

                                              Usage:

                                      -

                                      Types

                                      - +

                                      Types

                                      @@ -582,7 +579,7 @@

                                      Types

                                      Parameters:

                                      • filename - string + string filename
                                      • i @@ -596,11 +593,10 @@

                                        Parameters:

                                        Usage:

                                          -
                                          - local fileprocessor = function (filename, i)
                                          -   io.write (tostring (i) .. ":\n===\n" .. io.slurp (filename) .. "\n")
                                          - end
                                          - io.process_files (fileprocessor)
                                          +
                                          local fileprocessor = function (filename, i)
                                          +  io.write (tostring (i) .. ":\n===\n" .. io.slurp (filename) .. "\n")
                                          +end
                                          +io.process_files (fileprocessor)
                                        @@ -610,8 +606,8 @@

                                        Usage:

                                        -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                        diff --git a/doc/modules/std.math.html b/doc/modules/std.math.html index 8fd2b94..6448b9f 100644 --- a/doc/modules/std.math.html +++ b/doc/modules/std.math.html @@ -37,7 +37,7 @@

                                        Contents

                                        Modules

                                        -
                                          +

                                          Classes

                                          -
                                            +
                                            • std.tree
                                            • std.container
                                            • std.object
                                            • @@ -101,7 +101,7 @@

                                              Functions


                                              -

                                              Functions

                                              +

                                              Functions

                                              Methods
                                              @@ -151,7 +151,7 @@

                                              Usage:

                                              Parameters:

                                              • namespace - table + table where to install global functions (default _G)
                                              • @@ -160,7 +160,7 @@

                                                Parameters:

                                                Returns:

                                                  - table + table the module table
                                                @@ -214,8 +214,8 @@

                                                Usage:

                                                -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                                diff --git a/doc/modules/std.operator.html b/doc/modules/std.operator.html index 0ebf53f..bf6fec0 100644 --- a/doc/modules/std.operator.html +++ b/doc/modules/std.operator.html @@ -37,7 +37,7 @@

                                                Contents

                                                Modules

                                                -
                                                  +

                                                  Classes

                                                  -
                                                    +
                                                    • std.tree
                                                    • std.container
                                                    • std.object
                                                    • @@ -151,7 +151,7 @@

                                                      Functions


                                                      -

                                                      Functions

                                                      +

                                                      Functions

                                                      Methods
                                                      @@ -182,9 +182,8 @@

                                                      Returns:

                                                      Usage:

                                                        -
                                                        - --> "=> 1000010010"
                                                        - functional.foldl (concat, "=> ", {10000, 100, 10})
                                                        +
                                                        --> "=> 1000010010"
                                                        +functional.foldl (concat, "=> ", {10000, 100, 10})
                                                      @@ -216,9 +215,8 @@

                                                      Returns:

                                                      Usage:

                                                        -
                                                        - --> true
                                                        - functional.foldl (conj, {true, 1, "false"})
                                                        +
                                                        --> true
                                                        +functional.foldl (conj, {true, 1, "false"})
                                                      @@ -250,9 +248,8 @@

                                                      Returns:

                                                      Usage:

                                                        -
                                                        - --> 890
                                                        - functional.foldl (diff, {10000, 100, 10})
                                                        +
                                                        --> 890
                                                        +functional.foldl (diff, {10000, 100, 10})
                                                      @@ -284,9 +281,8 @@

                                                      Returns:

                                                      Usage:

                                                        -
                                                        - --> true
                                                        - functional.foldl (disj, {true, 1, false})
                                                        +
                                                        --> true
                                                        +functional.foldl (disj, {true, 1, false})
                                                      @@ -329,7 +325,7 @@

                                                      Returns:

                                                      Parameters:

                                                      • t - table + table a table
                                                      • k @@ -347,9 +343,8 @@

                                                        Returns:

                                                        Usage:

                                                          -
                                                          - --> 4
                                                          - functional.foldl (get, {1, {{2, 3, 4}, 5}}, {2, 1, 3})
                                                          +
                                                          --> 4
                                                          +functional.foldl (get, {1, {{2, 3, 4}, 5}}, {2, 1, 3})
                                                        @@ -493,9 +488,8 @@

                                                        Returns:

                                                        Usage:

                                                          -
                                                          - --> 3
                                                          - functional.foldl (mod, {65536, 100, 11})
                                                          +
                                                          --> 3
                                                          +functional.foldl (mod, {65536, 100, 11})
                                                        @@ -524,9 +518,8 @@

                                                        Returns:

                                                        Usage:

                                                          -
                                                          - --> {true, false, false, false}
                                                          - functional.bind (functional.map, {std.ielems, neg}) {false, true, 1, 0}
                                                          +
                                                          --> {true, false, false, false}
                                                          +functional.bind (functional.map, {std.ielems, neg}) {false, true, 1, 0}
                                                        @@ -558,10 +551,9 @@

                                                        Returns:

                                                        Usage:

                                                          -
                                                          - --> true
                                                          - local f = require "std.functional"
                                                          - table.empty (f.filter (f.bind (neq, {6}), std.ielems, {6, 6, 6})
                                                          +
                                                          --> true
                                                          +local f = require "std.functional"
                                                          +table.empty (f.filter (f.bind (neq, {6}), std.ielems, {6, 6, 6})
                                                        @@ -593,9 +585,8 @@

                                                        Returns:

                                                        Usage:

                                                          -
                                                          - --> 4096
                                                          - functional.foldl (pow, {2, 3, 4})
                                                          +
                                                          --> 4096
                                                          +functional.foldl (pow, {2, 3, 4})
                                                        @@ -627,9 +618,8 @@

                                                        Returns:

                                                        Usage:

                                                          -
                                                          - --> 10000000
                                                          - functional.foldl (prod, {10000, 100, 10})
                                                          +
                                                          --> 10000000
                                                          +functional.foldl (prod, {10000, 100, 10})
                                                        @@ -661,9 +651,8 @@

                                                        Returns:

                                                        Usage:

                                                          -
                                                          - --> 1000
                                                          - functional.foldr (quot, {10000, 100, 10})
                                                          +
                                                          --> 1000
                                                          +functional.foldr (quot, {10000, 100, 10})
                                                        @@ -678,7 +667,7 @@

                                                        Usage:

                                                        Parameters:

                                                        • t - table + table a table
                                                        • k @@ -692,7 +681,7 @@

                                                          Parameters:

                                                          Returns:

                                                            - table + table t
                                                          @@ -700,10 +689,9 @@

                                                          Returns:

                                                          Usage:

                                                            -
                                                            - -- destructive table merge:
                                                            - --> {"one", bar="baz", two=5}
                                                            - functional.reduce (set, {"foo", bar="baz"}, {"one", two=5})
                                                            +
                                                            -- destructive table merge:
                                                            +--> {"one", bar="baz", two=5}
                                                            +functional.reduce (set, {"foo", bar="baz"}, {"one", two=5})
                                                          @@ -735,9 +723,8 @@

                                                          Returns:

                                                          Usage:

                                                            -
                                                            - --> 10110
                                                            - functional.foldl (sum, {10000, 100, 10})
                                                            +
                                                            --> 10110
                                                            +functional.foldl (sum, {10000, 100, 10})
                                                          @@ -747,8 +734,8 @@

                                                          Usage:

                                                          -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                                          diff --git a/doc/modules/std.package.html b/doc/modules/std.package.html index c1d7e16..bdc11c6 100644 --- a/doc/modules/std.package.html +++ b/doc/modules/std.package.html @@ -39,7 +39,7 @@

                                                          Contents

                                                          Modules

                                                          -
                                                            +

                                                            Classes

                                                            -
                                                              +
                                                              • std.tree
                                                              • std.container
                                                              • std.object
                                                              • @@ -126,7 +126,7 @@

                                                                Types


                                                                -

                                                                Functions

                                                                +

                                                                Functions

                                                                Methods
                                                                @@ -140,11 +140,11 @@

                                                                Functions

                                                                Parameters:

                                                                • pathstrings - string + string pathsep delimited path elements
                                                                • patt - string + string a Lua pattern to search for in pathstrings
                                                                • init @@ -188,7 +188,7 @@

                                                                  Usage:

                                                                  Parameters:

                                                                  • pathstrings - string + string a package.path like string
                                                                  • pos @@ -198,7 +198,7 @@

                                                                    Parameters:

                                                                    (default n+1)
                                                                  • value - string + string new path element to insert
                                                                  @@ -206,7 +206,7 @@

                                                                  Parameters:

                                                                  Returns:

                                                                    - string + string a new string with the new element inserted
                                                                  @@ -229,7 +229,7 @@

                                                                  Usage:

                                                                  Parameters:

                                                                  • pathstrings - string + string a package.path like string
                                                                  • callback @@ -278,7 +278,7 @@

                                                                    Parameters:

                                                                    Returns:

                                                                      - string + string a single normalized pathsep delimited paths string
                                                                    @@ -301,7 +301,7 @@

                                                                    Usage:

                                                                    Parameters:

                                                                    • pathstrings - string + string a package.path like string
                                                                    • pos @@ -315,7 +315,7 @@

                                                                      Parameters:

                                                                      Returns:

                                                                        - string + string a new string with given element removed
                                                                      @@ -328,7 +328,7 @@

                                                                      Usage:

                                                                -

                                                                Tables

                                                                +

                                                                Tables

                                                                @@ -343,23 +343,23 @@

                                                                Tables

                                                                Fields:

                                                                • dirsep - string + string directory separator
                                                                • pathsep - string + string path separator
                                                                • path_mark - string + string string that marks substitution points in a path template
                                                                • execdir - string + string (Windows only) replaced by the executable's directory in a path
                                                                • igmark - string + string Mark to ignore all before it when building luaopen_ function name.
                                                                @@ -370,8 +370,7 @@

                                                                Fields:

                                                                -

                                                                Types

                                                                - +

                                                                Types

                                                                @@ -385,7 +384,7 @@

                                                                Types

                                                                Parameters:

                                                                • element - string + string an element from a pathsep delimited string of paths
                                                                • @@ -410,8 +409,8 @@

                                                                  Returns:

                                                                  -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                                                  diff --git a/doc/modules/std.strict.html b/doc/modules/std.strict.html index ff52f9e..73b72c1 100644 --- a/doc/modules/std.strict.html +++ b/doc/modules/std.strict.html @@ -37,7 +37,7 @@

                                                                  Contents

                                                                  Modules

                                                                  -
                                                                    +

                                                                    Classes

                                                                    -
                                                                      +
                                                                      • std.tree
                                                                      • std.container
                                                                      • std.object
                                                                      • @@ -91,7 +91,7 @@

                                                                        Functions


                                                                        -

                                                                        Functions

                                                                        +

                                                                        Functions

                                                                        Methods
                                                                        @@ -105,11 +105,11 @@

                                                                        Functions

                                                                        Parameters:

                                                                        @@ -130,11 +130,11 @@

                                                                        Parameters:

                                                                        Parameters:

                                                                        • t - table + table _G
                                                                        • n - string + string name of the variable being declared
                                                                        • v @@ -153,8 +153,8 @@

                                                                          Parameters:

                                                                          -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                                                          diff --git a/doc/modules/std.string.html b/doc/modules/std.string.html index e04aad9..02917b1 100644 --- a/doc/modules/std.string.html +++ b/doc/modules/std.string.html @@ -39,7 +39,7 @@

                                                                          Contents

                                                                          Modules

                                                                          -
                                                                            +

                                                                            Classes

                                                                            -
                                                                              +
                                                                              • std.tree
                                                                              • std.container
                                                                              • std.object
                                                                              • @@ -201,7 +201,7 @@

                                                                                Types


                                                                                -

                                                                                Functions

                                                                                +

                                                                                Functions

                                                                                Methods
                                                                                @@ -215,7 +215,7 @@

                                                                                Functions

                                                                                Parameters:

                                                                                @@ -223,7 +223,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string s with each word capitalized
                                                                                @@ -246,7 +246,7 @@

                                                                                Usage:

                                                                                Parameters:

                                                                                @@ -254,7 +254,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string s with any single trailing newline removed
                                                                                @@ -277,7 +277,7 @@

                                                                                Usage:

                                                                                Parameters:

                                                                                @@ -285,7 +285,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string s with active pattern characters escaped
                                                                                @@ -310,7 +310,7 @@

                                                                                Usage:

                                                                                Parameters:

                                                                                @@ -318,7 +318,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string s with active shell characters escaped
                                                                                @@ -341,11 +341,11 @@

                                                                                Usage:

                                                                                Parameters:

                                                                                • s - string + string target string
                                                                                • pattern - string + string pattern to match in s
                                                                                • init @@ -374,10 +374,9 @@

                                                                                  See also:

                                                                                  Usage:

                                                                                    -
                                                                                    - for t in std.elems (finds ("the target string", "%S+")) do
                                                                                    -   print (tostring (t.capt))
                                                                                    - end
                                                                                    +
                                                                                    for t in std.elems (finds ("the target string", "%S+")) do
                                                                                    +  print (tostring (t.capt))
                                                                                    +end
                                                                                  @@ -393,7 +392,7 @@

                                                                                  Usage:

                                                                                  Parameters:

                                                                                  • f - string + string format string
                                                                                  • ... @@ -427,11 +426,11 @@

                                                                                    Usage:

                                                                                    Parameters:

                                                                                    • s - string + string any string
                                                                                    • r - string + string leading pattern (default "%s+")
                                                                                    • @@ -440,7 +439,7 @@

                                                                                      Parameters:

                                                                                      Returns:

                                                                                        - string + string s with leading r stripped
                                                                                      @@ -466,7 +465,7 @@

                                                                                      Usage:

                                                                                      Parameters:

                                                                                      • namespace - table + table where to install global functions (default _G)
                                                                                      • @@ -475,7 +474,7 @@

                                                                                        Parameters:

                                                                                        Returns:

                                                                                          - table + table the module table
                                                                                        @@ -499,7 +498,7 @@

                                                                                        Usage:

                                                                                        Parameters:

                                                                                        @@ -507,7 +506,7 @@

                                                                                        Parameters:

                                                                                        Returns:

                                                                                          - string + string n simplifed using largest available SI suffix.
                                                                                        @@ -530,7 +529,7 @@

                                                                                        Usage:

                                                                                        Parameters:

                                                                                        @@ -538,7 +537,7 @@

                                                                                        Parameters:

                                                                                        Returns:

                                                                                          - string + string English suffix for n
                                                                                        @@ -546,9 +545,8 @@

                                                                                        Returns:

                                                                                        Usage:

                                                                                          -
                                                                                          - local now = os.date "*t"
                                                                                          - print ("%d%s day of the week", now.day, ordinal_suffix (now.day))
                                                                                          +
                                                                                          local now = os.date "*t"
                                                                                          +print ("%d%s day of the week", now.day, ordinal_suffix (now.day))
                                                                                        @@ -565,7 +563,7 @@

                                                                                        Usage:

                                                                                        Parameters:

                                                                                        • s - string + string a string to justify
                                                                                        • w @@ -574,7 +572,7 @@

                                                                                          Parameters:

                                                                                          left-justify)
                                                                                        • p - string + string string to pad with (default " ")
                                                                                        • @@ -583,7 +581,7 @@

                                                                                          Parameters:

                                                                                          Returns:

                                                                                            - string + string s justified to w characters wide
                                                                                          @@ -609,12 +607,12 @@

                                                                                          Parameters:

                                                                                          object to convert to string
                                                                                        • indent - string + string indent between levels (default "\t")
                                                                                        • spacing - string + string space before every line (default "")
                                                                                        • @@ -623,7 +621,7 @@

                                                                                          Parameters:

                                                                                          Returns:

                                                                                            - string + string pretty string rendering of x
                                                                                          @@ -671,7 +669,7 @@

                                                                                          Parameters:

                                                                                          separator rendering function
                                                                                        • roots - table + table accumulates table references to detect recursion (optional)
                                                                                        • @@ -687,12 +685,11 @@

                                                                                          Returns:

                                                                                          Usage:

                                                                                            -
                                                                                            - function tostring (x)
                                                                                            -   return render (x, lambda '="{"', lambda '="}"', tostring,
                                                                                            -                  lambda '=_4.."=".._5', lambda '= _4 and "," or ""',
                                                                                            -                  lambda '=","')
                                                                                            - end
                                                                                            +
                                                                                            function tostring (x)
                                                                                            +  return render (x, lambda '="{"', lambda '="}"', tostring,
                                                                                            +                 lambda '=_4.."=".._5', lambda '= _4 and "," or ""',
                                                                                            +                 lambda '=","')
                                                                                            +end
                                                                                          @@ -707,11 +704,11 @@

                                                                                          Usage:

                                                                                          Parameters:

                                                                                          • s - string + string any string
                                                                                          • r - string + string trailing pattern (default "%s+")
                                                                                          • @@ -720,7 +717,7 @@

                                                                                            Parameters:

                                                                                            Returns:

                                                                                              - string + string s with trailing r stripped
                                                                                            @@ -745,11 +742,11 @@

                                                                                            Usage:

                                                                                            Parameters:

                                                                                            • s - string + string to split
                                                                                            • sep - string + string separator pattern (default "%s+")
                                                                                            • @@ -780,11 +777,11 @@

                                                                                              Usage:

                                                                                              Parameters:

                                                                                              • s - string + string target string
                                                                                              • pattern - string + string pattern to match in s
                                                                                              • init @@ -808,7 +805,7 @@

                                                                                                Returns:

                                                                                                int end of match
                                                                                              • - table + table list of captured strings
                                                                                              • @@ -835,11 +832,11 @@

                                                                                                Usage:

                                                                                                Parameters:

                                                                                                • s - string + string any string
                                                                                                • r - string + string trailing pattern (default "%s+")
                                                                                                • @@ -848,7 +845,7 @@

                                                                                                  Parameters:

                                                                                                  Returns:

                                                                                                    - string + string s with leading and trailing r stripped
                                                                                                  @@ -871,7 +868,7 @@

                                                                                                  Usage:

                                                                                                  Parameters:

                                                                                                  • s - string + string a paragraph of text
                                                                                                  • w @@ -894,7 +891,7 @@

                                                                                                    Parameters:

                                                                                                    Returns:

                                                                                                      - string + string s wrapped to w columns
                                                                                                    @@ -907,7 +904,7 @@

                                                                                                    Usage:

                                                                                -

                                                                                Fields

                                                                                +

                                                                                Fields

                                                                                @@ -920,7 +917,7 @@

                                                                                Fields

                                                                                • s - string + string initial string
                                                                                • o @@ -933,9 +930,8 @@

                                                                                  Fields

                                                                                  Usage:

                                                                                    -
                                                                                    - local string = require "std.string".monkey_patch ()
                                                                                    - concatenated = "foo" .. {"bar"}
                                                                                    +
                                                                                    local string = require "std.string".monkey_patch ()
                                                                                    +concatenated = "foo" .. {"bar"}
                                                                                  @@ -949,11 +945,11 @@

                                                                                  Usage:

                                                                                  @@ -963,9 +959,8 @@

                                                                                  Usage:

                                                                                  Usage:

                                                                                    -
                                                                                    - getmetatable ("").__index = require "std.string".__index
                                                                                    - third = ("12345")[3]
                                                                                    +
                                                                                    getmetatable ("").__index = require "std.string".__index
                                                                                    +third = ("12345")[3]
                                                                                  @@ -998,8 +993,7 @@

                                                                                  Usage:

                                                                                -

                                                                                Types

                                                                                - +

                                                                                Types

                                                                                @@ -1013,7 +1007,7 @@

                                                                                Types

                                                                                Parameters:

                                                                                @@ -1021,7 +1015,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string close table rendering
                                                                                @@ -1055,7 +1049,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string element rendering
                                                                                @@ -1082,7 +1076,7 @@

                                                                                Usage:

                                                                                Parameters:

                                                                                @@ -1090,7 +1084,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string open table rendering
                                                                                @@ -1119,7 +1113,7 @@

                                                                                Usage:

                                                                                Parameters:

                                                                                • t - table + table table containing pair being rendered
                                                                                • key @@ -1129,11 +1123,11 @@

                                                                                  Parameters:

                                                                                  value part of key being rendered
                                                                                • keystr - string + string prerendered key
                                                                                • valuestr - string + string prerendered value
                                                                                @@ -1141,7 +1135,7 @@

                                                                                Parameters:

                                                                                Returns:

                                                                                  - string + string pair rendering
                                                                                @@ -1168,7 +1162,7 @@

                                                                                Usage:

                                                                                Parameters:

                                                                                • t - table + table table currently being rendered
                                                                                • pk @@ -1188,7 +1182,7 @@

                                                                                  Parameters:

                                                                                  Returns:

                                                                                    - string + string separator rendering
                                                                                  @@ -1206,8 +1200,8 @@

                                                                                  Usage:

                                                                                  -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                                                                  diff --git a/doc/modules/std.table.html b/doc/modules/std.table.html index 2184872..e4e2be4 100644 --- a/doc/modules/std.table.html +++ b/doc/modules/std.table.html @@ -38,7 +38,7 @@

                                                                                  Contents

                                                                                  Modules

                                                                                  -
                                                                                    +

                                                                                    Classes

                                                                                    -
                                                                                      +
                                                                                      • std.tree
                                                                                      • std.container
                                                                                      • std.object
                                                                                      • @@ -193,7 +193,7 @@

                                                                                        Types


                                                                                        -

                                                                                        Functions

                                                                                        +

                                                                                        Functions

                                                                                        Methods
                                                                                        @@ -209,11 +209,11 @@

                                                                                        Functions

                                                                                        Parameters:

                                                                                        • t - table + table source table
                                                                                        • map - table + table table of {old_key=new_key, ...} (default {})
                                                                                        • @@ -257,11 +257,11 @@

                                                                                          Usage:

                                                                                          Parameters:

                                                                                          • t - table + table source table
                                                                                          • keys - table + table list of keys to copy (default {})
                                                                                          • @@ -275,7 +275,7 @@

                                                                                            Parameters:

                                                                                            Returns:

                                                                                              - table + table copy of fields in selection from t, also sharing t's metatable unless nometa
                                                                                            @@ -304,7 +304,7 @@

                                                                                            Usage:

                                                                                            Parameters:

                                                                                            @@ -312,7 +312,7 @@

                                                                                            Parameters:

                                                                                            Returns:

                                                                                              - table + table a flat table with keys and values from ls
                                                                                            @@ -324,9 +324,8 @@

                                                                                            See also:

                                                                                            Usage:

                                                                                              -
                                                                                              - --> {a=1, b=2, c=3}
                                                                                              - depair {{"a", 1}, {"b", 2}, {"c", 3}}
                                                                                              +
                                                                                              --> {a=1, b=2, c=3}
                                                                                              +depair {{"a", 1}, {"b", 2}, {"c", 3}}
                                                                                            @@ -341,7 +340,7 @@

                                                                                            Usage:

                                                                                            Parameters:

                                                                                            @@ -357,7 +356,7 @@

                                                                                            Returns:

                                                                                            Usage:

                                                                                              -
                                                                                              if empty (t) then error "ohnoes" end
                                                                                              +
                                                                                              if empty (t) then error "ohnoes" end
                                                                                            @@ -372,7 +371,7 @@

                                                                                            Usage:

                                                                                            Parameters:

                                                                                            @@ -380,7 +379,7 @@

                                                                                            Parameters:

                                                                                            Returns:

                                                                                              - table + table a new list of pairs containing {{i1, v1}, ..., {in, vn}}
                                                                                            @@ -392,9 +391,8 @@

                                                                                            See also:

                                                                                            Usage:

                                                                                              -
                                                                                              - --> {{1, "a"}, {2, "b"}, {3, "c"}}
                                                                                              - enpair {"a", "b", "c"}
                                                                                              +
                                                                                              --> {{1, "a"}, {2, "b"}, {3, "c"}}
                                                                                              +enpair {"a", "b", "c"}
                                                                                            @@ -409,7 +407,7 @@

                                                                                            Usage:

                                                                                            Parameters:

                                                                                            @@ -417,7 +415,7 @@

                                                                                            Parameters:

                                                                                            Returns:

                                                                                              - table + table a list of all non-table elements of t
                                                                                            @@ -425,9 +423,8 @@

                                                                                            Returns:

                                                                                            Usage:

                                                                                              -
                                                                                              - --> {1, 2, 3, 4, 5}
                                                                                              - flatten {{1, {{2}, 3}, 4}, 5}
                                                                                              +
                                                                                              --> {1, 2, 3, 4, 5}
                                                                                              +flatten {{1, {{2}, 3}, 4}, 5}
                                                                                            @@ -445,7 +442,7 @@

                                                                                            Usage:

                                                                                            Parameters:

                                                                                            • t - table + table a table
                                                                                            • pos @@ -461,7 +458,7 @@

                                                                                              Parameters:

                                                                                              Returns:

                                                                                                - table + table t
                                                                                              @@ -469,9 +466,8 @@

                                                                                              Returns:

                                                                                              Usage:

                                                                                                -
                                                                                                - --> {1, "x", 2, 3, "y"}
                                                                                                - insert (insert ({1, 2, 3}, 2, "x"), "y")
                                                                                                +
                                                                                                --> {1, "x", 2, 3, "y"}
                                                                                                +insert (insert ({1, 2, 3}, 2, "x"), "y")
                                                                                              @@ -486,7 +482,7 @@

                                                                                              Usage:

                                                                                              Parameters:

                                                                                              @@ -494,7 +490,7 @@

                                                                                              Parameters:

                                                                                              Returns:

                                                                                                - table + table inverted table {v=k, ...}
                                                                                              @@ -502,9 +498,8 @@

                                                                                              Returns:

                                                                                              Usage:

                                                                                                -
                                                                                                - --> {a=1, b=2, c=3}
                                                                                                - invert {"a", "b", "c"}
                                                                                                +
                                                                                                --> {a=1, b=2, c=3}
                                                                                                +invert {"a", "b", "c"}
                                                                                              @@ -519,7 +514,7 @@

                                                                                              Usage:

                                                                                              Parameters:

                                                                                              @@ -527,7 +522,7 @@

                                                                                              Parameters:

                                                                                              Returns:

                                                                                                - table + table list of keys from t
                                                                                              @@ -555,7 +550,7 @@

                                                                                              Usage:

                                                                                              Parameters:

                                                                                              @@ -586,7 +581,7 @@

                                                                                              Usage:

                                                                                              Parameters:

                                                                                              @@ -602,9 +597,8 @@

                                                                                              Returns:

                                                                                              Usage:

                                                                                                -
                                                                                                - --> 42
                                                                                                - maxn {"a", b="c", 99, [42]="x", "x", [5]=67}
                                                                                                +
                                                                                                --> 42
                                                                                                +maxn {"a", b="c", 99, [42]="x", "x", [5]=67}
                                                                                              @@ -619,15 +613,15 @@

                                                                                              Usage:

                                                                                              Parameters:

                                                                                              • t - table + table destination table
                                                                                              • u - table + table table with fields to merge
                                                                                              • map - table + table table of {old_key=new_key, ...} (default {})
                                                                                              • @@ -641,7 +635,7 @@

                                                                                                Parameters:

                                                                                                Returns:

                                                                                                  - table + table t with fields from u merged in
                                                                                                @@ -671,15 +665,15 @@

                                                                                                Usage:

                                                                                                Parameters:

                                                                                                • t - table + table destination table
                                                                                                • u - table + table table with fields to merge
                                                                                                • keys - table + table list of keys to copy (default {})
                                                                                                • @@ -693,7 +687,7 @@

                                                                                                  Parameters:

                                                                                                  Returns:

                                                                                                    - table + table copy of fields in selection from t, also sharing t's metatable unless nometa
                                                                                                  @@ -722,7 +716,7 @@

                                                                                                  Usage:

                                                                                                  Parameters:

                                                                                                  • namespace - table + table where to install global functions (default _G)
                                                                                                  • @@ -731,7 +725,7 @@

                                                                                                    Parameters:

                                                                                                    Returns:

                                                                                                      - table + table the module table
                                                                                                    @@ -758,7 +752,7 @@

                                                                                                    Parameters:

                                                                                                    (default nil)
                                                                                                  • t - table + table initial table (default {})
                                                                                                  • @@ -767,7 +761,7 @@

                                                                                                    Parameters:

                                                                                                    Returns:

                                                                                                      - table + table table whose unset elements are x
                                                                                                    @@ -790,7 +784,7 @@

                                                                                                    Usage:

                                                                                                    Parameters:

                                                                                                    @@ -798,7 +792,7 @@

                                                                                                    Parameters:

                                                                                                    Returns:

                                                                                                      - table + table ordered list of keys from t
                                                                                                    @@ -839,9 +833,8 @@

                                                                                                    Returns:

                                                                                                    Usage:

                                                                                                      -
                                                                                                      - --> {1, 2, "ax"}
                                                                                                      - pack (("ax1"):find "(%D+)")
                                                                                                      +
                                                                                                      --> {1, 2, "ax"}
                                                                                                      +pack (("ax1"):find "(%D+)")
                                                                                                    @@ -859,7 +852,7 @@

                                                                                                    Parameters:

                                                                                                    field to project
                                                                                                  • tt - table + table a list of tables
                                                                                                  @@ -867,7 +860,7 @@

                                                                                                  Parameters:

                                                                                                  Returns:

                                                                                                    - table + table list of fkey fields from tt
                                                                                                  @@ -875,9 +868,8 @@

                                                                                                  Returns:

                                                                                                  Usage:

                                                                                                    -
                                                                                                    - --> {1, 3, "yy"}
                                                                                                    - project ("xx", {{"a", xx=1, yy="z"}, {"b", yy=2}, {"c", xx=3}, {xx="yy"})
                                                                                                    +
                                                                                                    --> {1, 3, "yy"}
                                                                                                    +project ("xx", {{"a", xx=1, yy="z"}, {"b", yy=2}, {"c", xx=3}, {xx="yy"})
                                                                                                  @@ -894,7 +886,7 @@

                                                                                                  Usage:

                                                                                                  Parameters:

                                                                                                  • t - table + table a table
                                                                                                  • pos @@ -914,10 +906,9 @@

                                                                                                    Returns:

                                                                                                    Usage:

                                                                                                      -
                                                                                                      - --> {1, 2, 5}
                                                                                                      - t = {1, 2, "x", 5}
                                                                                                      - remove (t, 3) == "x" and t
                                                                                                      +
                                                                                                      --> {1, 2, 5}
                                                                                                      +t = {1, 2, "x", 5}
                                                                                                      +remove (t, 3) == "x" and t
                                                                                                    @@ -944,11 +935,11 @@

                                                                                                    Usage:

                                                                                                    Parameters:

                                                                                                    @@ -963,9 +954,8 @@

                                                                                                    Returns:

                                                                                                    Usage:

                                                                                                      -
                                                                                                      - --> {{"a", "b"}, {"c", "d"}, {"e", "f"}}
                                                                                                      - shape ({3, 2}, {"a", "b", "c", "d", "e", "f"})
                                                                                                      +
                                                                                                      --> {{"a", "b"}, {"c", "d"}, {"e", "f"}}
                                                                                                      +shape ({3, 2}, {"a", "b", "c", "d", "e", "f"})
                                                                                                    @@ -980,7 +970,7 @@

                                                                                                    Usage:

                                                                                                    Parameters:

                                                                                                    @@ -996,9 +986,8 @@

                                                                                                    Returns:

                                                                                                    Usage:

                                                                                                      -
                                                                                                      - --> 3
                                                                                                      - size {foo = true, bar = true, baz = false}
                                                                                                      +
                                                                                                      --> 3
                                                                                                      +size {foo = true, bar = true, baz = false}
                                                                                                    @@ -1013,7 +1002,7 @@

                                                                                                    Usage:

                                                                                                    Parameters:

                                                                                                    • t - table + table unsorted table
                                                                                                    • c @@ -1048,7 +1037,7 @@

                                                                                                      Usage:

                                                                                                      Parameters:

                                                                                                      • t - table + table table to act on
                                                                                                      • i @@ -1073,7 +1062,7 @@

                                                                                                        Returns:

                                                                                                        Usage:

                                                                                                          -
                                                                                                          return unpack (results_table)
                                                                                                          +
                                                                                                          return unpack (results_table)
                                                                                                        @@ -1088,7 +1077,7 @@

                                                                                                        Usage:

                                                                                                        Parameters:

                                                                                                        @@ -1096,7 +1085,7 @@

                                                                                                        Parameters:

                                                                                                        Returns:

                                                                                                          - table + table list of values in t
                                                                                                        @@ -1108,15 +1097,13 @@

                                                                                                        See also:

                                                                                                        Usage:

                                                                                                          -
                                                                                                          - --> {"a", "c", 42}
                                                                                                          - values {"a", b="c", [-1]=42}
                                                                                                          +
                                                                                                          --> {"a", "c", 42}
                                                                                                          +values {"a", b="c", [-1]=42}
                                                                                        -

                                                                                        Types

                                                                                        - +

                                                                                        Types

                                                                                        @@ -1152,9 +1139,8 @@

                                                                                        See also:

                                                                                        Usage:

                                                                                          -
                                                                                          - local reversor = function (a, b) return a > b end
                                                                                          - sort (t, reversor)
                                                                                          +
                                                                                          local reversor = function (a, b) return a > b end
                                                                                          +sort (t, reversor)
                                                                                        @@ -1164,8 +1150,8 @@

                                                                                        Usage:

                                                                                        -generated by LDoc 1.4.3 -Last updated 2018-09-03 17:48:42 +generated by LDoc 1.4.6 +Last updated 2018-09-16 19:20:25
                                                                                        diff --git a/local.mk b/local.mk deleted file mode 100644 index e3fdc97..0000000 --- a/local.mk +++ /dev/null @@ -1,158 +0,0 @@ -# Local Make rules. -# -# Copyright (C) 2013-2015 Gary V. Vaughan -# Written by Gary V. Vaughan, 2013 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -## ------------ ## -## Environment. ## -## ------------ ## - -std_path = $(abs_srcdir)/lib/?.lua;$(abs_srcdir)/lib/?/init.lua -LUA_ENV = LUA_PATH="$(std_path);$(LUA_PATH)" - - -## ---------- ## -## Bootstrap. ## -## ---------- ## - -old_NEWS_hash = d41d8cd98f00b204e9800998ecf8427e - -update_copyright_env = \ - UPDATE_COPYRIGHT_HOLDER='(Gary V. Vaughan|Reuben Thomas)' \ - UPDATE_COPYRIGHT_USE_INTERVALS=1 \ - UPDATE_COPYRIGHT_FORCE=1 - - -## ------------- ## -## Declarations. ## -## ------------- ## - -classesdir = $(docdir)/classes -modulesdir = $(docdir)/modules - -dist_doc_DATA = -dist_classes_DATA = -dist_modules_DATA = - -include specs/specs.mk - - -## ------ ## -## Build. ## -## ------ ## - -dist_lua_DATA += \ - lib/std.lua \ - $(NOTHING_ELSE) - -luastddir = $(luadir)/std - -dist_luastd_DATA = \ - lib/std/base.lua \ - lib/std/container.lua \ - lib/std/debug.lua \ - lib/std/functional.lua \ - lib/std/io.lua \ - lib/std/list.lua \ - lib/std/math.lua \ - lib/std/object.lua \ - lib/std/operator.lua \ - lib/std/optparse.lua \ - lib/std/package.lua \ - lib/std/set.lua \ - lib/std/strbuf.lua \ - lib/std/strict.lua \ - lib/std/string.lua \ - lib/std/table.lua \ - lib/std/tree.lua \ - $(NOTHING_ELSE) - -# For bugwards compatibility with LuaRocks 2.1, while ensuring that -# `require "std.debug_init"` continues to work, we have to install -# the former `$(luadir)/std/debug_init.lua` to `debug_init/init.lua`. -# When LuaRocks works again, move this file back to dist_luastd_DATA -# above and rename to debug_init.lua. - -luastddebugdir = $(luastddir)/debug_init - -dist_luastddebug_DATA = \ - lib/std/debug_init/init.lua \ - $(NOTHING_ELSE) - -# In order to avoid regenerating std.lua at configure time, which -# causes the documentation to be rebuilt and hence requires users to -# have ldoc installed, put std/std.lua in as a Makefile dependency. -# (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) -lib/std.lua: lib/std.lua.in - ./config.status --file=$@ - - -## Use a builtin rockspec build with root at $(srcdir)/lib, and note -## the github repository doesn't have the same name as the rockspec! -mkrockspecs_args = --module-dir $(srcdir)/lib --repository lua-stdlib - - -## ------------- ## -## Distribution. ## -## ------------- ## - -EXTRA_DIST += \ - build-aux/config.ld.in \ - lib/std.lua.in \ - $(NOTHING_ELSE) - - -## -------------- ## -## Documentation. ## -## -------------- ## - - -dist_doc_DATA += \ - $(srcdir)/doc/index.html \ - $(srcdir)/doc/ldoc.css - -dist_classes_DATA += \ - $(srcdir)/doc/classes/std.container.html \ - $(srcdir)/doc/classes/std.list.html \ - $(srcdir)/doc/classes/std.object.html \ - $(srcdir)/doc/classes/std.optparse.html \ - $(srcdir)/doc/classes/std.set.html \ - $(srcdir)/doc/classes/std.strbuf.html \ - $(srcdir)/doc/classes/std.tree.html \ - $(NOTHING_ELSE) - -dist_modules_DATA += \ - $(srcdir)/doc/modules/std.html \ - $(srcdir)/doc/modules/std.debug.html \ - $(srcdir)/doc/modules/std.functional.html \ - $(srcdir)/doc/modules/std.io.html \ - $(srcdir)/doc/modules/std.math.html \ - $(srcdir)/doc/modules/std.operator.html \ - $(srcdir)/doc/modules/std.package.html \ - $(srcdir)/doc/modules/std.strict.html \ - $(srcdir)/doc/modules/std.string.html \ - $(srcdir)/doc/modules/std.table.html \ - $(NOTHING_ELSE) - -## Parallel make gets confused when one command ($(LDOC)) produces -## multiple targets (all the html files above), so use the presence -## of the doc directory as a sentinel file. -$(dist_doc_DATA) $(dist_classes_DATA) $(dist_modules_DATA): $(srcdir)/doc - -$(srcdir)/doc: $(dist_lua_DATA) $(dist_luastd_DATA) - test -d $@ || mkdir $@ - $(LDOC) -c build-aux/config.ld -d $(abs_srcdir)/doc . diff --git a/m4/ax_lua.m4 b/m4/ax_lua.m4 deleted file mode 100644 index 8da0a07..0000000 --- a/m4/ax_lua.m4 +++ /dev/null @@ -1,664 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_lua.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PROG_LUA[([MINIMUM-VERSION], [TOO-BIG-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# AX_LUA_HEADERS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# AX_LUA_LIBS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# AX_LUA_READLINE[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] -# -# DESCRIPTION -# -# Detect a Lua interpreter, optionally specifying a minimum and maximum -# version number. Set up important Lua paths, such as the directories in -# which to install scripts and modules (shared libraries). -# -# Also detect Lua headers and libraries. The Lua version contained in the -# header is checked to match the Lua interpreter version exactly. When -# searching for Lua libraries, the version number is used as a suffix. -# This is done with the goal of supporting multiple Lua installs (5.1 and -# 5.2 side-by-side). -# -# A note on compatibility with previous versions: This file has been -# mostly rewritten for serial 18. Most developers should be able to use -# these macros without needing to modify configure.ac. Care has been taken -# to preserve each macro's behavior, but there are some differences: -# -# 1) AX_WITH_LUA is deprecated; it now expands to the exact same thing as -# AX_PROG_LUA with no arguments. -# -# 2) AX_LUA_HEADERS now checks that the version number defined in lua.h -# matches the interpreter version. AX_LUA_HEADERS_VERSION is therefore -# unnecessary, so it is deprecated and does not expand to anything. -# -# 3) The configure flag --with-lua-suffix no longer exists; the user -# should instead specify the LUA precious variable on the command line. -# See the AX_PROG_LUA description for details. -# -# Please read the macro descriptions below for more information. -# -# This file was inspired by Andrew Dalke's and James Henstridge's -# python.m4 and Tom Payne's, Matthieu Moy's, and Reuben Thomas's ax_lua.m4 -# (serial 17). Basically, this file is a mash-up of those two files. I -# like to think it combines the best of the two! -# -# AX_PROG_LUA: Search for the Lua interpreter, and set up important Lua -# paths. Adds precious variable LUA, which may contain the path of the Lua -# interpreter. If LUA is blank, the user's path is searched for an -# suitable interpreter. -# -# If MINIMUM-VERSION is supplied, then only Lua interpreters with a -# version number greater or equal to MINIMUM-VERSION will be accepted. If -# TOO-BIG-VERSION is also supplied, then only Lua interpreters with a -# version number greater or equal to MINIMUM-VERSION and less than -# TOO-BIG-VERSION will be accepted. -# -# The Lua version number, LUA_VERSION, is found from the interpreter, and -# substituted. LUA_PLATFORM is also found, but not currently supported (no -# standard representation). -# -# Finally, the macro finds four paths: -# -# luadir Directory to install Lua scripts. -# pkgluadir $luadir/$PACKAGE -# luaexecdir Directory to install Lua modules. -# pkgluaexecdir $luaexecdir/$PACKAGE -# -# These paths are found based on $prefix, $exec_prefix, Lua's -# package.path, and package.cpath. The first path of package.path -# beginning with $prefix is selected as luadir. The first path of -# package.cpath beginning with $exec_prefix is used as luaexecdir. This -# should work on all reasonable Lua installations. If a path cannot be -# determined, a default path is used. Of course, the user can override -# these later when invoking make. -# -# luadir Default: $prefix/share/lua/$LUA_VERSION -# luaexecdir Default: $exec_prefix/lib/lua/$LUA_VERSION -# -# These directories can be used by Automake as install destinations. The -# variable name minus 'dir' needs to be used as a prefix to the -# appropriate Automake primary, e.g. lua_SCRIPS or luaexec_LIBRARIES. -# -# If an acceptable Lua interpreter is found, then ACTION-IF-FOUND is -# performed, otherwise ACTION-IF-NOT-FOUND is preformed. If ACTION-IF-NOT- -# FOUND is blank, then it will default to printing an error. To prevent -# the default behavior, give ':' as an action. -# -# AX_LUA_HEADERS: Search for Lua headers. Requires that AX_PROG_LUA be -# expanded before this macro. Adds precious variable LUA_INCLUDE, which -# may contain Lua specific include flags, e.g. -I/usr/include/lua5.1. If -# LUA_INCLUDE is blank, then this macro will attempt to find suitable -# flags. -# -# LUA_INCLUDE can be used by Automake to compile Lua modules or -# executables with embedded interpreters. The *_CPPFLAGS variables should -# be used for this purpose, e.g. myprog_CPPFLAGS = $(LUA_INCLUDE). -# -# This macro searches for the header lua.h (and others). The search is -# performed with a combination of CPPFLAGS, CPATH, etc, and LUA_INCLUDE. -# If the search is unsuccessful, then some common directories are tried. -# If the headers are then found, then LUA_INCLUDE is set accordingly. -# -# The paths automatically searched are: -# -# * /usr/include/luaX.Y -# * /usr/include/lua/X.Y -# * /usr/include/luaXY -# * /usr/local/include/luaX.Y -# * /usr/local/include/lua-X.Y -# * /usr/local/include/lua/X.Y -# * /usr/local/include/luaXY -# -# (Where X.Y is the Lua version number, e.g. 5.1.) -# -# The Lua version number found in the headers is always checked to match -# the Lua interpreter's version number. Lua headers with mismatched -# version numbers are not accepted. -# -# If headers are found, then ACTION-IF-FOUND is performed, otherwise -# ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then -# it will default to printing an error. To prevent the default behavior, -# set the action to ':'. -# -# AX_LUA_LIBS: Search for Lua libraries. Requires that AX_PROG_LUA be -# expanded before this macro. Adds precious variable LUA_LIB, which may -# contain Lua specific linker flags, e.g. -llua5.1. If LUA_LIB is blank, -# then this macro will attempt to find suitable flags. -# -# LUA_LIB can be used by Automake to link Lua modules or executables with -# embedded interpreters. The *_LIBADD and *_LDADD variables should be used -# for this purpose, e.g. mymod_LIBADD = $(LUA_LIB). -# -# This macro searches for the Lua library. More technically, it searches -# for a library containing the function lua_load. The search is performed -# with a combination of LIBS, LIBRARY_PATH, and LUA_LIB. -# -# If the search determines that some linker flags are missing, then those -# flags will be added to LUA_LIB. -# -# If libraries are found, then ACTION-IF-FOUND is performed, otherwise -# ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then -# it will default to printing an error. To prevent the default behavior, -# set the action to ':'. -# -# AX_LUA_READLINE: Search for readline headers and libraries. Requires the -# AX_LIB_READLINE macro, which is provided by ax_lib_readline.m4 from the -# Autoconf Archive. -# -# If a readline compatible library is found, then ACTION-IF-FOUND is -# performed, otherwise ACTION-IF-NOT-FOUND is performed. -# -# LICENSE -# -# Copyright (c) 2015 Reuben Thomas -# Copyright (c) 2014 Tim Perkins -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 38 - -dnl ========================================================================= -dnl AX_PROG_LUA([MINIMUM-VERSION], [TOO-BIG-VERSION], -dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ========================================================================= -AC_DEFUN([AX_PROG_LUA], -[ - dnl Check for required tools. - AC_REQUIRE([AC_PROG_GREP]) - AC_REQUIRE([AC_PROG_SED]) - - dnl Make LUA a precious variable. - AC_ARG_VAR([LUA], [The Lua interpreter, e.g. /usr/bin/lua5.1]) - - dnl Find a Lua interpreter. - m4_define_default([_AX_LUA_INTERPRETER_LIST], - [lua lua5.2 lua52 lua5.1 lua51 lua50]) - - m4_if([$1], [], - [ dnl No version check is needed. Find any Lua interpreter. - AS_IF([test "x$LUA" = 'x'], - [AC_PATH_PROGS([LUA], [_AX_LUA_INTERPRETER_LIST], [:])]) - ax_display_LUA='lua' - - AS_IF([test "x$LUA" != 'x:'], - [ dnl At least check if this is a Lua interpreter. - AC_MSG_CHECKING([if $LUA is a Lua interpreter]) - _AX_LUA_CHK_IS_INTRP([$LUA], - [AC_MSG_RESULT([yes])], - [ AC_MSG_RESULT([no]) - AC_MSG_ERROR([not a Lua interpreter]) - ]) - ]) - ], - [ dnl A version check is needed. - AS_IF([test "x$LUA" != 'x'], - [ dnl Check if this is a Lua interpreter. - AC_MSG_CHECKING([if $LUA is a Lua interpreter]) - _AX_LUA_CHK_IS_INTRP([$LUA], - [AC_MSG_RESULT([yes])], - [ AC_MSG_RESULT([no]) - AC_MSG_ERROR([not a Lua interpreter]) - ]) - dnl Check the version. - m4_if([$2], [], - [_ax_check_text="whether $LUA version >= $1"], - [_ax_check_text="whether $LUA version >= $1, < $2"]) - AC_MSG_CHECKING([$_ax_check_text]) - _AX_LUA_CHK_VER([$LUA], [$1], [$2], - [AC_MSG_RESULT([yes])], - [ AC_MSG_RESULT([no]) - AC_MSG_ERROR([version is out of range for specified LUA])]) - ax_display_LUA=$LUA - ], - [ dnl Try each interpreter until we find one that satisfies VERSION. - m4_if([$2], [], - [_ax_check_text="for a Lua interpreter with version >= $1"], - [_ax_check_text="for a Lua interpreter with version >= $1, < $2"]) - AC_CACHE_CHECK([$_ax_check_text], - [ax_cv_pathless_LUA], - [ for ax_cv_pathless_LUA in _AX_LUA_INTERPRETER_LIST none; do - test "x$ax_cv_pathless_LUA" = 'xnone' && break - _AX_LUA_CHK_IS_INTRP([$ax_cv_pathless_LUA], [], [continue]) - _AX_LUA_CHK_VER([$ax_cv_pathless_LUA], [$1], [$2], [break]) - done - ]) - dnl Set $LUA to the absolute path of $ax_cv_pathless_LUA. - AS_IF([test "x$ax_cv_pathless_LUA" = 'xnone'], - [LUA=':'], - [AC_PATH_PROG([LUA], [$ax_cv_pathless_LUA])]) - ax_display_LUA=$ax_cv_pathless_LUA - ]) - ]) - - AS_IF([test "x$LUA" = 'x:'], - [ dnl Run any user-specified action, or abort. - m4_default([$4], [AC_MSG_ERROR([cannot find suitable Lua interpreter])]) - ], - [ dnl Query Lua for its version number. - AC_CACHE_CHECK([for $ax_display_LUA version], - [ax_cv_lua_version], - [ dnl Get the interpreter version in X.Y format. This should work for - dnl interpreters version 5.0 and beyond. - ax_cv_lua_version=[`$LUA -e ' - -- return a version number in X.Y format - local _, _, ver = string.find(_VERSION, "^Lua (%d+%.%d+)") - print(ver)'`] - ]) - AS_IF([test "x$ax_cv_lua_version" = 'x'], - [AC_MSG_ERROR([invalid Lua version number])]) - AC_SUBST([LUA_VERSION], [$ax_cv_lua_version]) - AC_SUBST([LUA_SHORT_VERSION], [`echo "$LUA_VERSION" | $SED 's|\.||'`]) - - dnl The following check is not supported: - dnl At times (like when building shared libraries) you may want to know - dnl which OS platform Lua thinks this is. - AC_CACHE_CHECK([for $ax_display_LUA platform], - [ax_cv_lua_platform], - [ax_cv_lua_platform=[`$LUA -e 'print("unknown")'`]]) - AC_SUBST([LUA_PLATFORM], [$ax_cv_lua_platform]) - - dnl Use the values of $prefix and $exec_prefix for the corresponding - dnl values of LUA_PREFIX and LUA_EXEC_PREFIX. These are made distinct - dnl variables so they can be overridden if need be. However, the general - dnl consensus is that you shouldn't need this ability. - AC_SUBST([LUA_PREFIX], ['${prefix}']) - AC_SUBST([LUA_EXEC_PREFIX], ['${exec_prefix}']) - - dnl Lua provides no way to query the script directory, and instead - dnl provides LUA_PATH. However, we should be able to make a safe educated - dnl guess. If the built-in search path contains a directory which is - dnl prefixed by $prefix, then we can store scripts there. The first - dnl matching path will be used. - AC_CACHE_CHECK([for $ax_display_LUA script directory], - [ax_cv_lua_luadir], - [ AS_IF([test "x$prefix" = 'xNONE'], - [ax_lua_prefix=$ac_default_prefix], - [ax_lua_prefix=$prefix]) - - dnl Initialize to the default path. - ax_cv_lua_luadir="$LUA_PREFIX/share/lua/$LUA_VERSION" - - dnl Try to find a path with the prefix. - _AX_LUA_FND_PRFX_PTH([$LUA], [$ax_lua_prefix], [script]) - AS_IF([test "x$ax_lua_prefixed_path" != 'x'], - [ dnl Fix the prefix. - _ax_strip_prefix=`echo "$ax_lua_prefix" | $SED 's|.|.|g'` - ax_cv_lua_luadir=`echo "$ax_lua_prefixed_path" | \ - $SED "s|^$_ax_strip_prefix|$LUA_PREFIX|"` - ]) - ]) - AC_SUBST([luadir], [$ax_cv_lua_luadir]) - AC_SUBST([pkgluadir], [\${luadir}/$PACKAGE]) - - dnl Lua provides no way to query the module directory, and instead - dnl provides LUA_PATH. However, we should be able to make a safe educated - dnl guess. If the built-in search path contains a directory which is - dnl prefixed by $exec_prefix, then we can store modules there. The first - dnl matching path will be used. - AC_CACHE_CHECK([for $ax_display_LUA module directory], - [ax_cv_lua_luaexecdir], - [ AS_IF([test "x$exec_prefix" = 'xNONE'], - [ax_lua_exec_prefix=$ax_lua_prefix], - [ax_lua_exec_prefix=$exec_prefix]) - - dnl Initialize to the default path. - ax_cv_lua_luaexecdir="$LUA_EXEC_PREFIX/lib/lua/$LUA_VERSION" - - dnl Try to find a path with the prefix. - _AX_LUA_FND_PRFX_PTH([$LUA], - [$ax_lua_exec_prefix], [module]) - AS_IF([test "x$ax_lua_prefixed_path" != 'x'], - [ dnl Fix the prefix. - _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | $SED 's|.|.|g'` - ax_cv_lua_luaexecdir=`echo "$ax_lua_prefixed_path" | \ - $SED "s|^$_ax_strip_prefix|$LUA_EXEC_PREFIX|"` - ]) - ]) - AC_SUBST([luaexecdir], [$ax_cv_lua_luaexecdir]) - AC_SUBST([pkgluaexecdir], [\${luaexecdir}/$PACKAGE]) - - dnl Run any user specified action. - $3 - ]) -]) - -dnl AX_WITH_LUA is now the same thing as AX_PROG_LUA. -AC_DEFUN([AX_WITH_LUA], -[ - AC_MSG_WARN([[$0 is deprecated, please use AX_PROG_LUA instead]]) - AX_PROG_LUA -]) - - -dnl ========================================================================= -dnl _AX_LUA_CHK_IS_INTRP(PROG, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) -dnl ========================================================================= -AC_DEFUN([_AX_LUA_CHK_IS_INTRP], -[ - dnl A minimal Lua factorial to prove this is an interpreter. This should work - dnl for Lua interpreters version 5.0 and beyond. - _ax_lua_factorial=[`$1 2>/dev/null -e ' - -- a simple factorial - function fact (n) - if n == 0 then - return 1 - else - return n * fact(n-1) - end - end - print("fact(5) is " .. fact(5))'`] - AS_IF([test "$_ax_lua_factorial" = 'fact(5) is 120'], - [$2], [$3]) -]) - - -dnl ========================================================================= -dnl _AX_LUA_CHK_VER(PROG, MINIMUM-VERSION, [TOO-BIG-VERSION], -dnl [ACTION-IF-TRUE], [ACTION-IF-FALSE]) -dnl ========================================================================= -AC_DEFUN([_AX_LUA_CHK_VER], -[ - dnl Check that the Lua version is within the bounds. Only the major and minor - dnl version numbers are considered. This should work for Lua interpreters - dnl version 5.0 and beyond. - _ax_lua_good_version=[`$1 -e ' - -- a script to compare versions - function verstr2num(verstr) - local _, _, majorver, minorver = string.find(verstr, "^(%d+)%.(%d+)") - if majorver and minorver then - return tonumber(majorver) * 100 + tonumber(minorver) - end - end - local minver = verstr2num("$2") - local _, _, trimver = string.find(_VERSION, "^Lua (.*)") - local ver = verstr2num(trimver) - local maxver = verstr2num("$3") or 1e9 - if minver <= ver and ver < maxver then - print("yes") - else - print("no") - end'`] - AS_IF([test "x$_ax_lua_good_version" = "xyes"], - [$4], [$5]) -]) - - -dnl ========================================================================= -dnl _AX_LUA_FND_PRFX_PTH(PROG, PREFIX, SCRIPT-OR-MODULE-DIR) -dnl ========================================================================= -AC_DEFUN([_AX_LUA_FND_PRFX_PTH], -[ - dnl Get the script or module directory by querying the Lua interpreter, - dnl filtering on the given prefix, and selecting the shallowest path. If no - dnl path is found matching the prefix, the result will be an empty string. - dnl The third argument determines the type of search, it can be 'script' or - dnl 'module'. Supplying 'script' will perform the search with package.path - dnl and LUA_PATH, and supplying 'module' will search with package.cpath and - dnl LUA_CPATH. This is done for compatibility with Lua 5.0. - - ax_lua_prefixed_path=[`$1 -e ' - -- get the path based on search type - local searchtype = "$3" - local paths = "" - if searchtype == "script" then - paths = (package and package.path) or LUA_PATH - elseif searchtype == "module" then - paths = (package and package.cpath) or LUA_CPATH - end - -- search for the prefix - local prefix = "'$2'" - local minpath = "" - local mindepth = 1e9 - string.gsub(paths, "(@<:@^;@:>@+)", - function (path) - path = string.gsub(path, "%?.*$", "") - path = string.gsub(path, "/@<:@^/@:>@*$", "") - if string.find(path, prefix) then - local depth = string.len(string.gsub(path, "@<:@^/@:>@", "")) - if depth < mindepth then - minpath = path - mindepth = depth - end - end - end) - print(minpath)'`] -]) - - -dnl ========================================================================= -dnl AX_LUA_HEADERS([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ========================================================================= -AC_DEFUN([AX_LUA_HEADERS], -[ - dnl Check for LUA_VERSION. - AC_MSG_CHECKING([if LUA_VERSION is defined]) - AS_IF([test "x$LUA_VERSION" != 'x'], - [AC_MSG_RESULT([yes])], - [ AC_MSG_RESULT([no]) - AC_MSG_ERROR([cannot check Lua headers without knowing LUA_VERSION]) - ]) - - dnl Make LUA_INCLUDE a precious variable. - AC_ARG_VAR([LUA_INCLUDE], [The Lua includes, e.g. -I/usr/include/lua5.1]) - - dnl Some default directories to search. - LUA_SHORT_VERSION=`echo "$LUA_VERSION" | $SED 's|\.||'` - m4_define_default([_AX_LUA_INCLUDE_LIST], - [ /usr/include/lua$LUA_VERSION \ - /usr/include/lua-$LUA_VERSION \ - /usr/include/lua/$LUA_VERSION \ - /usr/include/lua$LUA_SHORT_VERSION \ - /usr/local/include/lua$LUA_VERSION \ - /usr/local/include/lua-$LUA_VERSION \ - /usr/local/include/lua/$LUA_VERSION \ - /usr/local/include/lua$LUA_SHORT_VERSION \ - ]) - - dnl Try to find the headers. - _ax_lua_saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" - AC_CHECK_HEADERS([lua.h lualib.h lauxlib.h luaconf.h]) - CPPFLAGS=$_ax_lua_saved_cppflags - - dnl Try some other directories if LUA_INCLUDE was not set. - AS_IF([test "x$LUA_INCLUDE" = 'x' && - test "x$ac_cv_header_lua_h" != 'xyes'], - [ dnl Try some common include paths. - for _ax_include_path in _AX_LUA_INCLUDE_LIST; do - test ! -d "$_ax_include_path" && continue - - AC_MSG_CHECKING([for Lua headers in]) - AC_MSG_RESULT([$_ax_include_path]) - - AS_UNSET([ac_cv_header_lua_h]) - AS_UNSET([ac_cv_header_lualib_h]) - AS_UNSET([ac_cv_header_lauxlib_h]) - AS_UNSET([ac_cv_header_luaconf_h]) - - _ax_lua_saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -I$_ax_include_path" - AC_CHECK_HEADERS([lua.h lualib.h lauxlib.h luaconf.h]) - CPPFLAGS=$_ax_lua_saved_cppflags - - AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], - [ LUA_INCLUDE="-I$_ax_include_path" - break - ]) - done - ]) - - AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], - [ dnl Make a program to print LUA_VERSION defined in the header. - dnl TODO It would be really nice if we could do this without compiling a - dnl program, then it would work when cross compiling. But I'm not sure how - dnl to do this reliably. For now, assume versions match when cross compiling. - - AS_IF([test "x$cross_compiling" != 'xyes'], - [ AC_CACHE_CHECK([for Lua header version], - [ax_cv_lua_header_version], - [ _ax_lua_saved_cppflags=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" - AC_RUN_IFELSE( - [ AC_LANG_SOURCE([[ -#include -#include -#include -int main(int argc, char ** argv) -{ - if(argc > 1) printf("%s", LUA_VERSION); - exit(EXIT_SUCCESS); -} -]]) - ], - [ ax_cv_lua_header_version=`./conftest$EXEEXT p | \ - $SED -n "s|^Lua \(@<:@0-9@:>@\{1,\}\.@<:@0-9@:>@\{1,\}\).\{0,\}|\1|p"` - ], - [ax_cv_lua_header_version='unknown']) - CPPFLAGS=$_ax_lua_saved_cppflags - ]) - - dnl Compare this to the previously found LUA_VERSION. - AC_MSG_CHECKING([if Lua header version matches $LUA_VERSION]) - AS_IF([test "x$ax_cv_lua_header_version" = "x$LUA_VERSION"], - [ AC_MSG_RESULT([yes]) - ax_header_version_match='yes' - ], - [ AC_MSG_RESULT([no]) - ax_header_version_match='no' - ]) - ], - [ AC_MSG_WARN([cross compiling so assuming header version number matches]) - ax_header_version_match='yes' - ]) - ]) - - dnl Was LUA_INCLUDE specified? - AS_IF([test "x$ax_header_version_match" != 'xyes' && - test "x$LUA_INCLUDE" != 'x'], - [AC_MSG_ERROR([cannot find headers for specified LUA_INCLUDE])]) - - dnl Test the final result and run user code. - AS_IF([test "x$ax_header_version_match" = 'xyes'], [$1], - [m4_default([$2], [AC_MSG_ERROR([cannot find Lua includes])])]) -]) - -dnl AX_LUA_HEADERS_VERSION no longer exists, use AX_LUA_HEADERS. -AC_DEFUN([AX_LUA_HEADERS_VERSION], -[ - AC_MSG_WARN([[$0 is deprecated, please use AX_LUA_HEADERS instead]]) -]) - - -dnl ========================================================================= -dnl AX_LUA_LIBS([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ========================================================================= -AC_DEFUN([AX_LUA_LIBS], -[ - dnl TODO Should this macro also check various -L flags? - - dnl Check for LUA_VERSION. - AC_MSG_CHECKING([if LUA_VERSION is defined]) - AS_IF([test "x$LUA_VERSION" != 'x'], - [AC_MSG_RESULT([yes])], - [ AC_MSG_RESULT([no]) - AC_MSG_ERROR([cannot check Lua libs without knowing LUA_VERSION]) - ]) - - dnl Make LUA_LIB a precious variable. - AC_ARG_VAR([LUA_LIB], [The Lua library, e.g. -llua5.1]) - - AS_IF([test "x$LUA_LIB" != 'x'], - [ dnl Check that LUA_LIBS works. - _ax_lua_saved_libs=$LIBS - LIBS="$LIBS $LUA_LIB" - AC_SEARCH_LIBS([lua_load], [], - [_ax_found_lua_libs='yes'], - [_ax_found_lua_libs='no']) - LIBS=$_ax_lua_saved_libs - - dnl Check the result. - AS_IF([test "x$_ax_found_lua_libs" != 'xyes'], - [AC_MSG_ERROR([cannot find libs for specified LUA_LIB])]) - ], - [ dnl First search for extra libs. - _ax_lua_extra_libs='' - - _ax_lua_saved_libs=$LIBS - LIBS="$LIBS $LUA_LIB" - AC_SEARCH_LIBS([exp], [m]) - AC_SEARCH_LIBS([dlopen], [dl]) - LIBS=$_ax_lua_saved_libs - - AS_IF([test "x$ac_cv_search_exp" != 'xno' && - test "x$ac_cv_search_exp" != 'xnone required'], - [_ax_lua_extra_libs="$_ax_lua_extra_libs $ac_cv_search_exp"]) - - AS_IF([test "x$ac_cv_search_dlopen" != 'xno' && - test "x$ac_cv_search_dlopen" != 'xnone required'], - [_ax_lua_extra_libs="$_ax_lua_extra_libs $ac_cv_search_dlopen"]) - - dnl Try to find the Lua libs. - _ax_lua_saved_libs=$LIBS - LIBS="$LIBS $LUA_LIB" - AC_SEARCH_LIBS([lua_load], - [ lua$LUA_VERSION \ - lua$LUA_SHORT_VERSION \ - lua-$LUA_VERSION \ - lua-$LUA_SHORT_VERSION \ - lua \ - ], - [_ax_found_lua_libs='yes'], - [_ax_found_lua_libs='no'], - [$_ax_lua_extra_libs]) - LIBS=$_ax_lua_saved_libs - - AS_IF([test "x$ac_cv_search_lua_load" != 'xno' && - test "x$ac_cv_search_lua_load" != 'xnone required'], - [LUA_LIB="$ac_cv_search_lua_load $_ax_lua_extra_libs"]) - ]) - - dnl Test the result and run user code. - AS_IF([test "x$_ax_found_lua_libs" = 'xyes'], [$1], - [m4_default([$2], [AC_MSG_ERROR([cannot find Lua libs])])]) -]) - - -dnl ========================================================================= -dnl AX_LUA_READLINE([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ========================================================================= -AC_DEFUN([AX_LUA_READLINE], -[ - AX_LIB_READLINE - AS_IF([test "x$ac_cv_header_readline_readline_h" != 'x' && - test "x$ac_cv_header_readline_history_h" != 'x'], - [ LUA_LIBS_CFLAGS="-DLUA_USE_READLINE $LUA_LIBS_CFLAGS" - $1 - ], - [$2]) -]) diff --git a/rockspec.conf b/rockspec.conf deleted file mode 100644 index 397ad26..0000000 --- a/rockspec.conf +++ /dev/null @@ -1,16 +0,0 @@ -# stdlib rockspec configuration. - -description: - homepage: http://lua-stdlib.github.io/lua-stdlib - license: MIT/X11 - summary: General Lua Libraries - detailed: - stdlib is a library of modules for common programming tasks, - including list, table and functional operations, objects, - pickling, pretty-printing and command-line option parsing. - -dependencies: -- lua >= 5.1, < 5.4 - -source: - url: git://github.com/lua-stdlib/lua-stdlib.git diff --git a/specs/container_spec.yaml b/spec/container_spec.yaml similarity index 100% rename from specs/container_spec.yaml rename to spec/container_spec.yaml diff --git a/specs/debug_spec.yaml b/spec/debug_spec.yaml similarity index 100% rename from specs/debug_spec.yaml rename to spec/debug_spec.yaml diff --git a/specs/functional_spec.yaml b/spec/functional_spec.yaml similarity index 100% rename from specs/functional_spec.yaml rename to spec/functional_spec.yaml diff --git a/specs/io_spec.yaml b/spec/io_spec.yaml similarity index 99% rename from specs/io_spec.yaml rename to spec/io_spec.yaml index d35b5db..e46ca73 100644 --- a/specs/io_spec.yaml +++ b/spec/io_spec.yaml @@ -180,7 +180,7 @@ specify std.io: - describe process_files: - before: name = "Makefile" - names = {"Makefile", "config.log", "config.status", "build-aux/config.ld"} + names = {"Makefile", "NEWS.md", "README.md", "build-aux/config.ld"} ascript = [[ require "std.io".process_files (function (a) print (a) end) ]] diff --git a/specs/list_spec.yaml b/spec/list_spec.yaml similarity index 100% rename from specs/list_spec.yaml rename to spec/list_spec.yaml diff --git a/specs/math_spec.yaml b/spec/math_spec.yaml similarity index 100% rename from specs/math_spec.yaml rename to spec/math_spec.yaml diff --git a/specs/object_spec.yaml b/spec/object_spec.yaml similarity index 100% rename from specs/object_spec.yaml rename to spec/object_spec.yaml diff --git a/specs/operator_spec.yaml b/spec/operator_spec.yaml similarity index 100% rename from specs/operator_spec.yaml rename to spec/operator_spec.yaml diff --git a/specs/optparse_spec.yaml b/spec/optparse_spec.yaml similarity index 100% rename from specs/optparse_spec.yaml rename to spec/optparse_spec.yaml diff --git a/specs/package_spec.yaml b/spec/package_spec.yaml similarity index 100% rename from specs/package_spec.yaml rename to spec/package_spec.yaml diff --git a/specs/set_spec.yaml b/spec/set_spec.yaml similarity index 100% rename from specs/set_spec.yaml rename to spec/set_spec.yaml diff --git a/specs/spec_helper.lua b/spec/spec_helper.lua similarity index 99% rename from specs/spec_helper.lua rename to spec/spec_helper.lua index 9c60717..006657d 100644 --- a/specs/spec_helper.lua +++ b/spec/spec_helper.lua @@ -148,7 +148,7 @@ end function concat_file_content (...) local t = {} for _, name in ipairs {...} do - h = io.open (name) + local h = io.open (name) t[#t + 1] = h:read "*a" end return table.concat (t) diff --git a/specs/std_spec.yaml b/spec/std_spec.yaml similarity index 100% rename from specs/std_spec.yaml rename to spec/std_spec.yaml diff --git a/specs/strbuf_spec.yaml b/spec/strbuf_spec.yaml similarity index 100% rename from specs/strbuf_spec.yaml rename to spec/strbuf_spec.yaml diff --git a/specs/string_spec.yaml b/spec/string_spec.yaml similarity index 100% rename from specs/string_spec.yaml rename to spec/string_spec.yaml diff --git a/specs/table_spec.yaml b/spec/table_spec.yaml similarity index 100% rename from specs/table_spec.yaml rename to spec/table_spec.yaml diff --git a/specs/tree_spec.yaml b/spec/tree_spec.yaml similarity index 100% rename from specs/tree_spec.yaml rename to spec/tree_spec.yaml diff --git a/specs/specs.mk b/specs/specs.mk deleted file mode 100644 index 591b61c..0000000 --- a/specs/specs.mk +++ /dev/null @@ -1,38 +0,0 @@ -# Specl specs make rules. - - -## ------ ## -## Specs. ## -## ------ ## - -SPECL_OPTS = --unicode - -## For compatibility with Specl < 11, std_spec.yaml has to be -## last, so that when `require "std"` leaks symbols into the -## Specl global environment, subsequent example blocks are not -## affected. - -specl_SPECS = \ - $(srcdir)/specs/container_spec.yaml \ - $(srcdir)/specs/debug_spec.yaml \ - $(srcdir)/specs/functional_spec.yaml \ - $(srcdir)/specs/io_spec.yaml \ - $(srcdir)/specs/list_spec.yaml \ - $(srcdir)/specs/math_spec.yaml \ - $(srcdir)/specs/object_spec.yaml \ - $(srcdir)/specs/operator_spec.yaml \ - $(srcdir)/specs/optparse_spec.yaml \ - $(srcdir)/specs/package_spec.yaml \ - $(srcdir)/specs/set_spec.yaml \ - $(srcdir)/specs/strbuf_spec.yaml \ - $(srcdir)/specs/string_spec.yaml \ - $(srcdir)/specs/table_spec.yaml \ - $(srcdir)/specs/tree_spec.yaml \ - $(srcdir)/specs/std_spec.yaml \ - $(NOTHING_ELSE) - -EXTRA_DIST += \ - $(srcdir)/specs/spec_helper.lua \ - $(NOTHING_ELSE) - -include build-aux/specl.mk diff --git a/stdlib-41.2.2-1.rockspec b/stdlib-41.2.2-1.rockspec index 7be7654..2de8067 100644 --- a/stdlib-41.2.2-1.rockspec +++ b/stdlib-41.2.2-1.rockspec @@ -1,40 +1,57 @@ -package = "stdlib" -version = "41.2.2-1" +local _MODREV, _SPECREV = '41.2.2', '-1' + +package = 'stdlib' +version = _MODREV .. _SPECREV + description = { - detailed = "stdlib is a library of modules for common programming tasks, including list, table and functional operations, objects, pickling, pretty-printing and command-line option parsing.", - homepage = "http://lua-stdlib.github.io/lua-stdlib", - license = "MIT/X11", - summary = "General Lua Libraries", + summary = 'General Lua Libraries', + detailed = [[ + stdlib is a library of modules for common programming tasks, + including list, table and functional operations, objects, pickling, + pretty-printing and command-line option parsing. + ]], + homepage = 'http://lua-stdlib.github.io/lua-stdlib', + license = 'MIT/X11', } + source = { - dir = "lua-stdlib-release-v41.2.2", - url = "http://github.com/lua-stdlib/lua-stdlib/archive/release-v41.2.2.zip", + url = 'http://github.com/lua-stdlib/lua-stdlib/archive/v' .. _MODREV .. '.zip', + dir = 'lua-stdlib-' .. _MODREV, } + dependencies = { - "lua >= 5.1, < 5.5", + 'lua >= 5.1, < 5.5', } -external_dependencies = nil + build = { - modules = { - std = "lib/std.lua", - ["std.base"] = "lib/std/base.lua", - ["std.container"] = "lib/std/container.lua", - ["std.debug"] = "lib/std/debug.lua", - ["std.debug_init"] = "lib/std/debug_init/init.lua", - ["std.functional"] = "lib/std/functional.lua", - ["std.io"] = "lib/std/io.lua", - ["std.list"] = "lib/std/list.lua", - ["std.math"] = "lib/std/math.lua", - ["std.object"] = "lib/std/object.lua", - ["std.operator"] = "lib/std/operator.lua", - ["std.optparse"] = "lib/std/optparse.lua", - ["std.package"] = "lib/std/package.lua", - ["std.set"] = "lib/std/set.lua", - ["std.strbuf"] = "lib/std/strbuf.lua", - ["std.strict"] = "lib/std/strict.lua", - ["std.string"] = "lib/std/string.lua", - ["std.table"] = "lib/std/table.lua", - ["std.tree"] = "lib/std/tree.lua", - }, - type = "builtin", + type = 'builtin', + modules = { + std = 'lib/std.lua', + ['std.base'] = 'lib/std/base.lua', + ['std.container'] = 'lib/std/container.lua', + ['std.debug'] = 'lib/std/debug.lua', + ['std.debug_init'] = 'lib/std/debug_init/init.lua', + ['std.functional'] = 'lib/std/functional.lua', + ['std.io'] = 'lib/std/io.lua', + ['std.list'] = 'lib/std/list.lua', + ['std.math'] = 'lib/std/math.lua', + ['std.object'] = 'lib/std/object.lua', + ['std.operator'] = 'lib/std/operator.lua', + ['std.optparse'] = 'lib/std/optparse.lua', + ['std.package'] = 'lib/std/package.lua', + ['std.set'] = 'lib/std/set.lua', + ['std.strbuf'] = 'lib/std/strbuf.lua', + ['std.strict'] = 'lib/std/strict.lua', + ['std.string'] = 'lib/std/string.lua', + ['std.table'] = 'lib/std/table.lua', + ['std.tree'] = 'lib/std/tree.lua', + }, } + +if _MODREV == 'git' then + build.copy_directories = nil + + source = { + url = 'git://github.com/lua-stdlib/lua-stdlib.git', + } +end diff --git a/travis.yml.in b/travis.yml.in deleted file mode 100644 index b1762c8..0000000 --- a/travis.yml.in +++ /dev/null @@ -1,154 +0,0 @@ -language: c - -env: - global: - - _COMPILE="libtool --mode=compile --tag=CC gcc" - - _CFLAGS="-O2 -Wall -DLUA_COMPAT_ALL -DLUA_COMPAT_5_2 -DLUA_USE_LINUX" - - _INSTALL="libtool --mode=install install -p" - - _LINK="libtool --mode=link --tag=CC gcc" - - _LIBS="-lm -Wl,-E -ldl -lreadline" - - - prefix=/usr/local - - bindir=$prefix/bin - - incdir=$prefix/include - - libdir=$prefix/lib - - - _inst=$TRAVIS_BUILD_DIR/_inst - - luadir=$_inst/share/lua - - luaexecdir=$_inst/lib/lua - matrix: - - LUA=lua5.3 - - LUA=lua5.2 - - LUA=lua5.1 - - LUA=luajit - - -before_install: - # Put back the links for libyaml, which are missing on recent Travis VMs - - test -f /usr/lib/libyaml.so || - sudo find /usr/lib -name 'libyaml*' -exec ln -s {} /usr/lib \; - - sudo apt-get install help2man - - # Fetch Lua sources. - - cd $TRAVIS_BUILD_DIR - - 'if test lua5.3 = "$LUA"; then - curl http://www.lua.org/ftp/lua-5.3.0.tar.gz | tar xz; - cd lua-5.3.0; - fi' - - 'if test lua5.2 = "$LUA"; then - curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz; - cd lua-5.2.4; - fi' - - 'if test lua5.1 = "$LUA"; then - curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz; - cd lua-5.1.5; - fi' - - # Unpack, compile and install Lua. - - 'if test luajit = "$LUA"; then - curl http://luajit.org/download/LuaJIT-2.0.3.tar.gz | tar xz; - cd LuaJIT-2.0.3; - make && sudo make install; - for header in lua.h luaconf.h lualib.h lauxlib.h luajit.h lua.hpp; do - if test -f /usr/local/include/luajit-2.0/$header; then - sudo ln -s /usr/local/include/luajit-2.0/$header /usr/local/include/$header; - fi; - done; - else - for src in src/*.c; do - test src/lua.c = "$src" || test src/luac.c = "$src" || eval $_COMPILE $_CFLAGS -c $src; - done; - eval $_LINK -o lib$LUA.la -version-info 0:0:0 -rpath $libdir *.lo; - sudo mkdir -p $libdir; - eval sudo $_INSTALL lib$LUA.la $libdir/lib$LUA.la; - - eval $_COMPILE $_CFLAGS -c src/lua.c; - eval $_LINK -static -o $LUA lua.lo lib$LUA.la $_LIBS; - sudo mkdir -p $bindir; - eval sudo $_INSTALL $LUA $bindir/$LUA; - - sudo mkdir -p $incdir; - for header in lua.h luaconf.h lualib.h lauxlib.h lua.hpp; do - if test -f src/$header; then - eval sudo $_INSTALL src/$header $incdir/$header; - fi; - done; - fi' - - # Fetch LuaRocks. - - cd $TRAVIS_BUILD_DIR - - 'git clone https://github.com/keplerproject/luarocks.git luarocks-2.2.0' - - cd luarocks-2.2.0 - - git checkout v2.2.0 - - # Compile and install luarocks. - - if test luajit = "$LUA"; then - ./configure --lua-suffix=jit; - else - ./configure; - fi - - 'make build && sudo make install' - - # Tidy up file droppings. - - cd $TRAVIS_BUILD_DIR - - rm -rf lua-5.3.0 lua-5.2.3 lua-5.1.5 LuaJIT-2.0.3 luarocks-2.2.0 - - -install: - # Use Lua 5.3 compatible rocks, where available. - - 'for rock in @EXTRA_ROCKS@""; do - if test -z "$rock"; then break; fi; - if luarocks list | grep "^$rock$" >/dev/null; then continue; fi; - sudo luarocks install --server=http://rocks.moonscript.org/manifests/gvvaughan $rock; - done' - - # Fudge timestamps on release branches. - - 'if test -f configure; then - test -f aclocal.m4 && touch aclocal.m4; - sleep 1; touch Makefile.in; - sleep 1; test -f config.h.in && touch config.h.in; - sleep 1; touch configure; - fi' - - # Build from rockspec, forcing uninstall of older luarocks installed - # above when testing the git rockspec, both for enforcing backwards - # compatibility by default, and for ease of maintenance. - - if test -f '@PACKAGE@-@VERSION@-1.rockspec'; then - sudo luarocks make '@PACKAGE@-@VERSION@-1.rockspec' LUA="$LUA"; - else - sudo luarocks make --force '@PACKAGE@-git-1.rockspec' LUA="$LUA"; - fi - - # Clean up files created by root - - sudo git clean -dfx - - sudo rm -rf slingshot /tmp/ldoc - - -script: - # Reconfigure for in-tree test install. - - test -f configure || ./bootstrap --verbose - - ./configure --prefix="$_inst" --disable-silent-rules LUA="$LUA" - - # Verify luarocks installation. - - make installcheck || make installcheck V=1 - - # Verify local build. - - make - - make check || make check V=1 - - # Verify configured installation. - - make install prefix="$_inst" luadir="$luadir" luaexecdir="$luaexecdir" - - LUA_PATH="$luadir/?.lua;$luadir/?/init.lua;;" - LUA_CPATH="$luaexecdir/?.so;;" - make installcheck V=1 - - -# Run sanity checks on CI server, ignoring buggy automakes. -after_success: - - '{ _assign="="; - if grep local-checks-to-skip build-aux/sanity-cfg.mk >/dev/null; then - _assign="+="; - fi; - printf "local-checks-to-skip %s sc_vulnerable_makefile_CVE-2012-3386\n" "$_assign"; - } >> build-aux/sanity-cfg.mk' - - 'make syntax-check || : this will usually fail on the release branch'
                          Filter an iterator with a predicate.
                          foldl (fn[, d=t[1]], t)foldl (fn[, d=t[1], t) Fold a binary function left associatively.
                          foldr (fn[, d=t[1]], t)foldr (fn[, d=t[1], t) Fold a binary function right associatively.