Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'origin' of git://github.com/rrthomas/lua-stdlib

* 'origin' of git://github.com/rrthomas/lua-stdlib: (38 commits)
  Add testing of luarock against uploaded archive before mailing announcement
  base.lua: user simpler default require_version pattern that works in more cases
  Generate Lua version in rockspec from that in configure.ac
  Bump version to 28, and simplify slightly, requiring automake 1.11
  base.lua: move a documentation stanza to a more apt location
  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)
  base.lua: add require_version
  Make build_command in rockspec more robust.
  Install documentation with 'make install' and from luarocks.
  Rename table.indices to table.keys, and use term 'keys' more.
  getopt.lua: output usage information to stdout, not stderr
  configure.ac: bump version to 27
  configure.ac: accept Lua 5.2
  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
  ...
  • Loading branch information...
commit e43cb8e5f0eb43835afec4a9782b8e9b90fb98e4 2 parents f3c09fd + 5162dec
@drahosp drahosp authored
View
1  .gitignore
@@ -8,6 +8,7 @@
/configure
/config.log
/config.status
+/luarocks-config.lua
/release-notes-*
/stdlib-*.zip
/*.rockspec
View
3  AUTHORS
@@ -23,3 +23,6 @@ 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.
View
36 Makefile.am
@@ -4,31 +4,43 @@ ACLOCAL_AMFLAGS = -I m4
SOURCES = $(wildcard src/*.lua)
dist_data_DATA = $(SOURCES)
+
+dist_doc_DATA = \
+ src/index.html \
+ src/luadoc.css
+filesdir = $(docdir)/files
+dist_files_DATA = $(wildcard src/files/*.html)
+modulesdir = $(docdir)/modules
+dist_modules_DATA = $(wildcard src/modules/*.html)
+
EXTRA_DIST = \
src/std.lua.in \
- src/index.html \
- src/luadoc.css \
- $(PACKAGE).rockspec.in \
- $(wildcard src/files/*.html) \
- $(wildcard src/modules/*.html)
+ $(PACKAGE).rockspec.in
DISTCLEANFILES = $(PACKAGE).rockspec
ROCKSPEC = $(PACKAGE)-$(VERSION)-1.rockspec
-$(ROCKSPEC): $(PACKAGE).rockspec dist
- sed -e 's/@MD5@/'`$(MD5SUM) $(distdir).zip | cut -d " " -f 1`'/g' < $(PACKAGE).rockspec > $@
-
html: $(SOURCES)
cd src && luadoc *.lua
ChangeLog:
git2cl > ChangeLog
-release: distcheck $(ROCKSPEC)
+WOGER_ARGS = package=$(PACKAGE) package_name=$(PACKAGE_NAME) archive=stdlib-$(VERSION).zip version=$(VERSION) description="`LUA_INIT= LUA_PATH='$(abs_srcdir)/?.rockspec.in' $(LUA) -l$(PACKAGE) -e 'print (description.summary)'`" notes=release-notes-$(VERSION) dist_type=zip github_user=rrthomas
+
+# Depend on distcheck so that 'make release' runs distcheck before
+# making the rockspec, so the release archive MD5sum is correct in the
+# rockspec
+$(ROCKSPEC): $(PACKAGE).rockspec distcheck
+ sed -e 's/_MD5_/'`$(MD5SUM) $(distdir).zip | cut -d " " -f 1`'/g' < $(PACKAGE).rockspec > $@
+
+release: $(ROCKSPEC)
+ grep md5 $(ROCKSPEC) | sed -e 's/[^"]*"\([0-9a-f]\+\)",/\1 $(distdir).zip/' | md5sum --check - && \
git diff --exit-code && \
git push && \
- 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) dist_type=zip github_user=rrthomas
- git tag -a -m "Release tag" rel-`echo $(VERSION) | sed -e 's/\./-/g'` && \
+ woger github $(WOGER_ARGS) && \
+ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks --tree=$(abs_srcdir)/luarocks build $(ROCKSPEC) && \
+ woger lua $(WOGER_ARGS) && \
+ git tag -a -m "Release tag" v$(VERSION) && \
git push --tags
- @cat release-notes-$(VERSION) && echo && echo "Now upload to LuaForge, and fix the download URL in and send the rockspec!"
View
2  README
@@ -1,7 +1,7 @@
Standard Lua libraries
----------------------
- by the stdlib project (http://luaforge.net/projects/stdlib/)
+ by the stdlib project (http://github.com/rrthomas/lua-stdlib/)
This is a collection of Lua libraries for Lua 5.1, with provisional
View
15 configure.ac
@@ -1,20 +1,19 @@
dnl Process this file with autoconf to produce a configure script
-AC_INIT(stdlib, 26, rrt@sc3d.org)
+dnl Initialise autoconf and automake
+AC_INIT(stdlib, 28, rrt@sc3d.org)
AC_CONFIG_AUX_DIR([build-aux])
-
AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-zip])
+AM_SILENT_RULES([yes])
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-dnl Lua 5.1
-AX_PROG_LUA(501)
-AC_SUBST(LUA)
+dnl Lua
+AC_SUBST([LUA_MIN_VERSION], [5.1])
+AX_PROG_LUA([$LUA_MIN_VERSION], [5.3])
dnl md5sum
AX_WITH_PROG([MD5SUM], [md5sum], [false])
dnl Generate output files
AC_CONFIG_MACRO_DIR(m4)
-AC_CONFIG_FILES(Makefile $PACKAGE.rockspec src/std.lua)
+AC_CONFIG_FILES(Makefile $PACKAGE.rockspec luarocks-config.lua src/std.lua)
AC_OUTPUT
View
3  luarocks-config.lua.in
@@ -0,0 +1,3 @@
+rocks_trees = {
+ "@abs_srcdir@/luarocks"
+}
View
177 m4/ax_compare_version.m4
@@ -0,0 +1,177 @@
+# ===========================================================================
+# 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 <toolan@ele.uri.edu>
+#
+# 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
View
119 m4/ax_lua.m4
@@ -6,7 +6,6 @@
#
# AX_WITH_LUA
# AX_PROG_LUA [(MIN-VERSION, [TOO-BIG-VERSION])]
-# AX_LUA_VERSION (MIN-VERSION, [TOO-BIG-VERSION])
# AX_LUA_HEADERS
# AX_LUA_HEADERS_VERSION (MIN-VERSION, [TOO-BIG-VERSION])
# AX_LUA_LIBS
@@ -21,28 +20,25 @@
# AX_WITH_LUA searches for a Lua interpreter and defines LUA if found.
#
# AX_PROG_LUA searches for a Lua interpreter in the given version range,
-# if any, and defines LUA if found, or stops with an error if not.
-#
-# AX_LUA_VERSION checks that the version of Lua is at least MIN-VERSION
-# and less than TOO-BIG-VERSION, if given.
+# if any (at least MIN-VERSION and less than TOO-BIG-VERSION, if given),
+# and defines LUA if found, or stops with an error if not. Versions are
+# given in the same format as output by the Lua interpreter, and may be
+# just a prefix, e.g. "5.1.4", "5.2" or "5".
#
# AX_LUA_HEADERS searches for Lua headers and defines HAVE_LUA_H and
# HAVE_LUALIB_H if found, and defines LUA_INCLUDE to the preprocessor
# flags needed, if any.
#
# AX_LUA_HEADERS_VERSION checks that the Lua headers' version is at least
-# MIN-VERSION, and less than TOO-BIG-VERSION, if given.
+# MIN-VERSION, and less than TOO-BIG-VERSION, if given. Versions are given
+# in the same format as LUA_VERSION_NUM in lua.h), e.g. 501 for Lua 5.1.
+# The revision (e.g. the "3" in "5.1.3") is ignored.
#
# AX_LUA_LIBS searches for Lua libraries and defines LUA_LIB if found.
#
# AX_LUA_READLINE configures Lua to be built with readline support, if
# available. This macro requires AX_LIB_READLINE.
#
-# Versions are specified as three-digit integers whose first digit is the
-# major version and last two are the minor version (the same format as
-# LUA_VERSION_NUM in lua.h); e.g. 501 for Lua 5.1. The revision (e.g. the
-# "3" in "5.1.3") is ignored.
-#
# The following options are added by these macros:
#
# --with-lua-suffix=ARG Lua binaries and library files are
@@ -50,7 +46,7 @@
#
# LICENSE
#
-# Copyright (c) 2011 Reuben Thomas <rrt@sc3d.org>
+# Copyright (c) 2012 Reuben Thomas <rrt@sc3d.org>
# Copyright (c) 2009 Matthieu Moy <Matthieu.Moy@imag.fr>
# Copyright (c) 2009 Tom Payne <twpayne@gmail.com>
#
@@ -80,7 +76,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 14
+#serial 17
dnl Helper function to declare extra options
AC_DEFUN([_AX_LUA_OPTS],
@@ -90,66 +86,38 @@ AC_DEFUN([_AX_LUA_OPTS],
AC_DEFUN([AX_WITH_LUA],
[_AX_LUA_OPTS
- if test "x$LUA" = x; then
+ if test -z "$LUA"; then
AC_PATH_PROG(LUA, lua$with_lua_suffix)
fi])dnl
AC_DEFUN([AX_PROG_LUA],
- [lua_min_version=$1
- lua_max_version=$2
- AX_WITH_LUA
+ [AX_WITH_LUA
if test -z "$LUA"; then
AC_MSG_FAILURE([Lua not found])
fi
- if test -n "$lua_min_version"; then
- AX_LUA_VERSION($lua_min_version, $lua_max_version)
- fi
- AC_SUBST(LUA)])dnl
-
-dnl Helper function to parse minimum & maximum versions
-AC_DEFUN([_AX_LUA_VERSIONS],
- [lua_min_version=$1
- lua_max_version=$2
- if test "x$lua_min_version" = x; then
- lua_min_version=0
- fi
- if test "x$lua_max_version" = x; then
- lua_max_version=$(($lua_min_version + 1))
- fi])
-
-AC_DEFUN([AX_LUA_VERSION],
- [_AX_LUA_OPTS
- _AX_LUA_VERSIONS($1, $2)
- AC_MSG_CHECKING([Lua version is in range $1 <= v < $2])
- if test "x$LUA" != x; then
- lua_text_version=$(LUA_INIT= $LUA -e 'print(_VERSION)' 2>&1 | cut -d' ' -f2)
- case $lua_text_version in
- 5.2*)
- lua_version=502
- ;;
- 5.1*)
- lua_version=501
- ;;
- 5.0*)
- lua_version=500
- ;;
- 4.0*)
- lua_version=400
- ;;
- *)
- lua_version=-1
- ;;
- esac
- if test $lua_version -ge "$lua_min_version" && test $lua_version -lt "$lua_max_version"; then
+ if test -n "$1"; then
+ if test -z "$2"; then
+ AC_MSG_CHECKING([Lua version is $1])
+ else
+ AC_MSG_CHECKING([Lua version is in range $1 <= v < $2])
+ fi
+ lua_version=$(LUA_INIT= $LUA -e 'print(_VERSION)' 2>&1 | cut -d' ' -f2)
+ if test -z "$2"; then
+ AX_COMPARE_VERSION([$lua_version], [eq0], [$1])
+ else
+ AX_COMPARE_VERSION([$lua_version], [ge], [$1])
+ if $ax_compare_version; then
+ AX_COMPARE_VERSION($lua_version, [lt], "$2")
+ fi
+ fi
+ if $ax_compare_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_FAILURE([Lua version not in desired range.])
fi
- else
- AC_MSG_RESULT([no])
- AC_MSG_FAILURE([Lua version not in desired range.])
- fi])dnl
+ fi
+ AC_SUBST(LUA)])dnl
AC_DEFUN([AX_LUA_HEADERS],
[_AX_LUA_OPTS
@@ -158,20 +126,13 @@ AC_DEFUN([AX_LUA_HEADERS],
AC_CHECK_HEADERS([lua.h lualib.h])
CPPFLAGS="$LUA_OLD_CPPFLAGS"])dnl
-AC_DEFUN([AX_LUA_LIBS],
- [_AX_LUA_OPTS
- AC_CHECK_LIB([m], [exp], [lua_extra_libs="$lua_extra_libs -lm"], [])
- AC_CHECK_LIB([dl], [dlopen], [lua_extra_libs="$lua_extra_libs -ldl"], [])
- AC_CHECK_LIB([lua$with_lua_suffix],
- [lua_call],
- [LUA_LIB="$LUA_LIB -llua$with_lua_suffix $lua_extra_libs"],
- [],
- [$LUA_LIB $lua_extra_libs])])dnl
-
AC_DEFUN([AX_LUA_HEADERS_VERSION],
[_AX_LUA_OPTS
- _AX_LUA_VERSIONS($1, $2)
- AC_MSG_CHECKING([lua.h version is in range $1 <= v < $2])
+ lua_max_version=$2
+ if test -z "$lua_max_version"; then
+ lua_max_version=$(( $1 + 1 ))
+ fi
+ AC_MSG_CHECKING([lua.h version is in range $1 <= v < $lua_max_version])
LUA_OLD_LIBS="$LIBS"
LIBS="$LIBS $LUA_LIB"
LUA_OLD_CPPFLAGS="$CPPFLAGS"
@@ -183,7 +144,7 @@ AC_DEFUN([AX_LUA_HEADERS_VERSION],
int main()
{
printf("(found %s, %d)... ", LUA_VERSION, LUA_VERSION_NUM);
- if (LUA_VERSION_NUM >= $lua_min_version && LUA_VERSION_NUM < $lua_max_version)
+ if (LUA_VERSION_NUM >= $1 && LUA_VERSION_NUM < $lua_max_version)
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
}
@@ -194,6 +155,16 @@ int main()
LIBS="$LUA_OLD_LIBS"
CPPFLAGS="$LUA_OLD_CPPFLAGS"])dnl
+AC_DEFUN([AX_LUA_LIBS],
+ [_AX_LUA_OPTS
+ AC_CHECK_LIB([m], [exp], [lua_extra_libs="$lua_extra_libs -lm"], [])
+ AC_CHECK_LIB([dl], [dlopen], [lua_extra_libs="$lua_extra_libs -ldl"], [])
+ AC_CHECK_LIB([lua$with_lua_suffix],
+ [lua_load],
+ [LUA_LIB="$LUA_LIB -llua$with_lua_suffix $lua_extra_libs"],
+ [],
+ [$LUA_LIB $lua_extra_libs])])dnl
+
AC_DEFUN([AX_LUA_READLINE],
[AX_LIB_READLINE
if test -n "$ac_cv_header_readline_readline_h" && test -n "$ac_cv_header_readline_history_h"; then
View
127 src/base.lua
@@ -14,6 +14,30 @@ require "string_ext"
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 <code>module.version</code> or
+-- <code>module.VERSION</code> (default: <code>".*[%.%d]+"</code>
+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
@@ -274,6 +298,23 @@ function _G.compose (...)
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
@@ -296,6 +337,13 @@ function _G.ripairs (t)
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)
@@ -332,14 +380,6 @@ function _G.inodes (tr)
return _nodes (ipairs, tr)
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 _leaves (it, tr)
local function visit (n)
if type (n) == "table" then
@@ -464,44 +504,33 @@ 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
+_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
View
5 src/debug_ext.lua
@@ -33,13 +33,14 @@ function say (n, ...)
end
---
--- debug.say is also available as the global function <code>debug</code>
+-- The global function <code>debug</code> is an abbreviation for
+-- <code>debug.say (1, ...)</code>
-- @class function
-- @name debug
-- @see say
getmetatable (_M).__call =
function (self, ...)
- say (...)
+ say (1, ...)
end
--- Trace function calls
View
4 src/debug_init.lua
@@ -1,2 +1,2 @@
--- Debugging is off by default
-_G._DEBUG = _G._DEBUG or false
+-- Debugging is on by default
+_G._DEBUG = true
View
34 src/getopt.lua
@@ -26,7 +26,6 @@ require "base"
require "list"
require "string_ext"
require "object"
-require "io_ext"
--- Perform argument processing
@@ -56,16 +55,14 @@ function getOpt (argIn, options)
return nil
end
end
- if o.func then
- return o.func (arg, oldarg)
- end
return arg or 1 -- make sure arg has a value
end
- -- parse an option
+
local function parseOpt (opt, arg)
local o = options.name[opt]
if o ~= nil then
- optOut[o.name[1]] = getArg (o, opt, arg, optOut[o.name[1]])
+ 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
@@ -95,10 +92,7 @@ end
-- @field type type of argument (if any): <code>Req</code>(uired),
-- <code>Opt</code>(ional)
-- @field var descriptive name for the argument
--- @field func optional function (newarg, oldarg) to convert argument
--- into actual argument, (if omitted, argument is left as it
--- is)
-_G.Option = Object {_init = {"name", "desc", "type", "var", "func"}}
+_G.Option = Object {_init = {"name", "desc", "type", "var"}}
--- Options table constructor: adds lookup tables for the option names
local function makeOptions (t)
@@ -183,8 +177,6 @@ end
--- Emit a usage message.
function usage ()
- local name = prog.name
- prog.name = nil
local usage, purpose, notes = "[OPTION]... [FILE]...", "", ""
if prog.usage then
usage = prog.usage
@@ -200,9 +192,9 @@ function usage ()
notes = notes .. prog.notes
end
end
- warn (getopt.usageInfo ("Usage: " .. name .. " " .. usage .. purpose,
- options)
- .. notes)
+ io.writelines (getopt.usageInfo ("Usage: " .. prog.name .. " " .. usage .. purpose,
+ options)
+ .. notes)
end
@@ -217,7 +209,7 @@ function processArgs ()
local errors
_G.arg, opt, errors = getopt.getOpt (arg, options)
if (opt.version or opt.help) and prog.banner then
- io.stderr:write (prog.banner .. "\n")
+ io.writelines (prog.banner)
end
if #errors > 0 or opt.help then
local name = prog.name
@@ -241,13 +233,9 @@ _G.options = nil
-- A small and hopefully enlightening example:
if type (_DEBUG) == "table" and _DEBUG.std then
- function out (o)
- return o or io.stdout
- end
-
options = makeOptions ({
Option {{"verbose", "v"}, "verbosely list files"},
- Option {{"output", "o"}, "dump to FILE", "Opt", "FILE", out},
+ Option {{"output", "o"}, "dump to FILE", "Opt", "FILE"},
Option {{"name", "n"}, "only dump USER's files", "Req", "USER"},
})
@@ -267,11 +255,11 @@ if type (_DEBUG) == "table" and _DEBUG.std then
prog = {name = "foobar"} -- for errors
-- Example runs:
test {"foo", "-v"}
- -- options={verbose=1} args={1=foo}
+ -- 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=file (0x????????)} args={}
+ -- options={name={"baz"},version={1},output={1}} args={}
test {"-foo"}
-- unrecognized option `-foo'
-- Usage: foobar [OPTION]... [FILE]...
View
64 src/object.lua
@@ -1,19 +1,26 @@
--- Prototype-based objects
-- <ul>
--- <li>Create an object/class:</li>
--- <ul>
--- <li><code>object/class = prototype {value, ...; field = value ...}</code></li>
--- <li>An object's metatable is itself.</li>
--- <li>In the initialiser, unnamed values are assigned to the fields
--- given by <code>_init</code> (assuming the default
--- <code>_clone</code>).</li>
--- <li>Private fields and methods start with "<code>_</code>".</li>
--- </ul>
--- <li>Access an object field: <code>object.field</code></li>
--- <li>Call an object method: <code>object:method (...)</code></li>
--- <li>Call a class method: <code>Class.method (object, ...)</li>
--- <li>Add a field: <code>object.field = x</code></li>
--- <li>Add a method: <code>function object:method (...) ... end</code></li>
+-- <li>Create an object/class:</li>
+-- <ul>
+-- <li>Either, if the <code>_init</code> field is a list:
+-- <ul>
+-- <li><code>object/Class = prototype {value, ...; field = value, ...}</code></li>
+-- <li>Named values are assigned to the corresponding fields, and unnamed values
+-- to the fields given by <code>_init</code>.</li>
+-- </ul>
+-- <li>Or, if the <code>_init</code> field is a function:
+-- <ul>
+-- <li><code>object/Class = prototype (value, ...)</code></li>
+-- <li>The given values are passed as arguments to the <code>_init</code> function.</li>
+-- </ul>
+-- <li>An object's metatable is itself.</li>
+-- <li>Private fields and methods start with "<code>_</code>".</li>
+-- </ul>
+-- <li>Access an object field: <code>object.field</code></li>
+-- <li>Call an object method: <code>object:method (...)</code></li>
+-- <li>Call a class method: <code>Class.method (object, ...)</code></li>
+-- <li>Add a field: <code>object.field = x</code></li>
+-- <li>Add a method: <code>function object:method (...) ... end</code></li>
-- </li>
module ("object", package.seeall)
@@ -23,24 +30,27 @@ require "table_ext"
--- Root object
-- @class table
-- @name Object
--- @field _init list of fields to be initialised by the
--- constructor: assuming the default _clone, the
--- numbered values in an object constructor are
--- assigned to the fields given in <code>_init</code>
--- @field _clone object constructor which takes initial values for
--- fields in <code>_init</code>
+-- @field _init constructor method or list of fields to be initialised by the
+-- constructor
+-- @field _clone object constructor which provides the behaviour for <code>_init</code>
+-- documented above
_G.Object = {
_init = {},
- _clone = function (self, values)
- local object = table.merge (self, table.rearrange (self._init, values))
- return setmetatable (object, object)
- end,
+ _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,
+ -- First (...) gets first element of list
+ return (...)._clone (...)
+ end,
}
setmetatable (Object, Object)
View
7 src/parser.lua
@@ -102,8 +102,8 @@ Parser = Object {_init = {"grammar"}}
--- Parser constructor
-- @param grammar parser grammar
-- @return parser
-function Parser:_clone (grammar)
- local init = table.permute (self._init, grammar)
+function Parser:_init (grammar)
+ local init = table.clone_rename (self._init, grammar)
-- Reformat the abstract syntax rules
for rname, rule in pairs (init.grammar) do
if name ~= "lexemes" then
@@ -130,8 +130,7 @@ function Parser:_clone (grammar)
end
end
end
- local object = table.merge (self, init)
- return setmetatable (object, object)
+ return table.merge (self, init)
end
--- Parse a token list.
View
3  src/set.lua
@@ -42,7 +42,8 @@ function new (l)
end
--- Iterator for sets
-elems = leaves
+-- TODO: Make the iterator return only the key
+elems = pairs
-- High level methods (representation-independent)
View
25 src/string_ext.lua
@@ -229,31 +229,6 @@ function finds (s, p, init, plain)
return l
end
---- Perform multiple calls to gsub.
--- @param s string to call gsub on
--- @param sub <code>{pattern1=replacement1 ...}</code>
--- @param n upper limit on replacements (default: infinite)
--- @return result string
--- @return number of replacements made
-function gsubs (s, sub, n)
- local r = 0
- for i, v in pairs (sub) do
- local rep
- if n ~= nil then
- s, rep = gsub (s, i, v, n)
- r = r + rep
- n = n - rep
- if n == 0 then
- break
- end
- else
- s, rep = i.gsub (s, i, v)
- r = r + rep
- end
- end
- return s, r
-end
-
--- Split a string at a given separator.
-- FIXME: Consider Perl and Python versions.
-- @param s string to split
View
43 src/table_ext.lua
@@ -32,10 +32,10 @@ function size (t)
return n
end
---- Make the list of indices of a table.
+--- Make the list of keys of a table.
-- @param t table
--- @return list of indices
-function indices (t)
+-- @return list of keys
+function keys (t)
local u = {}
for i, v in pairs (t) do
insert (u, i)
@@ -65,19 +65,6 @@ function invert (t)
return u
end
---- Rearrange some indices of a table.
--- @param m table <code>{old_index=new_index, ...}</code>
--- @param t table to rearrange
--- @return rearranged table
-function rearrange (m, t)
- local r = clone (t)
- for i, v in pairs (m) do
- r[v] = t[i]
- r[i] = nil
- end
- return r
-end
-
--- Make a shallow copy of a table, including any metatable (for a
-- deep copy, use tree.clone).
-- @param t table
@@ -94,18 +81,28 @@ function clone (t, nometa)
return u
end
---- Merge two tables.
--- If there are duplicate fields, u's will be used. The metatable of
--- the returned table is that of t.
+--- Clone a table, renaming some keys.
+-- @param map table <code>{old_key=new_key, ...}</code>
+-- @param t table to copy
+-- @return copy of table
+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. <code>u</code> is merged into <code>t</code>.
-- @param t first table
-- @param u second table
--- @return merged table
+-- @return first table
function merge (t, u)
- local r = clone (t)
for i, v in pairs (u) do
- r[i] = v
+ t[i] = v
end
- return r
+ return t
end
--- Make a table with a default value for unset keys.
View
4 src/tree.lua
@@ -14,7 +14,7 @@ end
--- Tree <code>__index</code> metamethod.
-- @param tr tree
--- @param i non-table, or list of indices <code>{i<sub>1</sub> ...
+-- @param i non-table, or list of keys <code>{i<sub>1</sub> ...
-- i<sub>n</sub>}</code>
-- @return <code>tr[i]...[i<sub>n</sub>]</code> if i is a table, or
-- <code>tr[i]</code> otherwise
@@ -32,7 +32,7 @@ end
-- Sets <code>tr[i<sub>1</sub>]...[i<sub>n</sub>] = v</code> if i is a
-- table, or <code>tr[i] = v</code> otherwise
-- @param tr tree
--- @param i non-table, or list of indices <code>{i<sub>1</sub> ...
+-- @param i non-table, or list of keys <code>{i<sub>1</sub> ...
-- i<sub>n</sub>}</code>
-- @param v value
function metatable.__newindex (tr, i, v)
View
13 stdlib.rockspec.in
@@ -1,8 +1,8 @@
package="stdlib"
version="@VERSION@-1"
source = {
- url = "http://luaforge.net/frs/download.php/@FRS@/@PACKAGE@-@VERSION@.zip",
- md5 = "@MD5@",
+ url = "https://github.com/downloads/rrthomas/lua-stdlib/@PACKAGE@-@VERSION@.zip",
+ md5 = "_MD5_",
dir = "@PACKAGE@-@VERSION@"
}
description = {
@@ -12,14 +12,15 @@ description = {
including list, table and functional operations, regexps, objects,
pickling, pretty-printing and getopt.
]],
- homepage = "http://luaforge.net/projects/stdlib/",
+ homepage = "http://github.com/rrthomas/lua-stdlib/",
license = "MIT/X11"
}
dependencies = {
- "lua >= 5.1"
+ "lua >= @LUA_MIN_VERSION@"
}
build = {
type = "command",
- build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR)",
- install_command = "make install"
+ build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make",
+ install_command = "make install",
+ copy_directories = {}
}
Please sign in to comment.
Something went wrong with that request. Please try again.