diff -Nru lua-penlight-1.7.0/appveyor.yml lua-penlight-1.9.2/appveyor.yml --- lua-penlight-1.7.0/appveyor.yml 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/appveyor.yml 2020-09-27 10:39:11.000000000 +0000 @@ -1,10 +1,13 @@ shallow_clone: true environment: + COVERALLS_REPO_TOKEN: + secure: /0zDn4cz8xWKQuHfzvAUwyeFSQfLSP+toDR3lRApwWoIeg9O1OvJTnXurB8cssW0 matrix: - LUA: "lua 5.1" - LUA: "lua 5.2" - LUA: "lua 5.3" + - LUA: "lua 5.4" - LUA: "luajit 2.0" - LUA: "luajit 2.0 --compat 5.2" - LUA: "luajit 2.1" @@ -15,13 +18,20 @@ - pip install hererocks - hererocks here --%LUA% -rlatest - call here\bin\activate + - luarocks install luacheck + - "if \"%LUA%\"==\"lua 5.4\" ( luarocks install bit32 )" - luarocks install luacov-coveralls build_script: - luarocks make test_script: + - luacheck . - lua run.lua tests --luacov + - lua run.lua examples on_success: - #- luacov-coveralls + # secure coveralls token not available on PR builds, only BRANCH builds + - "if not \"%COVERALLS_REPO_TOKEN%\"==\"\" ( + luacov-coveralls + )" diff -Nru lua-penlight-1.7.0/CHANGELOG.md lua-penlight-1.9.2/CHANGELOG.md --- lua-penlight-1.7.0/CHANGELOG.md 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/CHANGELOG.md 2020-09-27 10:39:11.000000000 +0000 @@ -1,5 +1,54 @@ # Changelog +see [CONTRIBUTING.md](CONTRIBUTING.md#release-instructions-for-a-new-version) for release instructions + +## 1.9.1 (2020-09-27) + + - fix: dir.walk [#350](https://github.com/lunarmodules/Penlight/pull/350) + + +## 1.9.1 (2020-09-24) + + - released to superseed the 1.9.0 version which was retagged in git after some + distro's already had picked it up. This version is identical to 1.8.1. + +## 1.8.1 (2020-09-24) (replacing a briefly released but broken 1.9.0 version) + +## Fixes + + - In `pl.class`, `_init` can now be inherited from grandparent (or older ancestor) classes. [#289](https://github.com/lunarmodules/Penlight/pull/289) + - Fixes `dir`, `lexer`, and `permute` to no longer use coroutines. [#344](https://github.com/lunarmodules/Penlight/pull/344) + +## 1.8.0 (2020-08-05) + +### New features + + - `pretty.debug` quickly dumps a set of values to stdout for debug purposes + +### Changes + + - `pretty.write`: now also sorts non-string keys [#319](https://github.com/lunarmodules/Penlight/pull/319) + - `stringx.count` has an extra option to allow overlapping matches + [#326](https://github.com/lunarmodules/Penlight/pull/326) + - added an extra changelog entry for `types.is_empty` on the 1.6.0 changelog, due + to additional fixed behaviour not called out appropriately [#313](https://github.com/lunarmodules/Penlight/pull/313) + - `path.packagepath` now returns a proper error message with names tried if + it fails + +### Fixes + + - Fix: `stringx.rfind` now properly works with overlapping matches + [#314](https://github.com/lunarmodules/Penlight/pull/314) + - Fix: `package.searchpath` (in module `pl.compat`) + [#328](https://github.com/lunarmodules/Penlight/pull/328) + - Fix: `path.isabs` now reports drive + relative-path as `false`, eg. "c:some/path" (Windows only) + - Fix: OpenResty coroutines, used by `dir.dirtree`, `pl.lexer`, `pl.permute`. If + available the original coroutine functions are now used [#329](https://github.com/lunarmodules/Penlight/pull/329) + - Fix: in `pl.strict` also predefine global `_PROMPT2` + - Fix: in `pl.strict` apply `tostring` to the given name, in case it is not a string. + - Fix: the lexer would not recognize numbers without leading zero; "-.123". + See [#315](https://github.com/lunarmodules/Penlight/issues/315) + ## 1.7.0 (2019-10-14) ### New features @@ -15,25 +64,25 @@ - `utils.quit`: exit message is no longer required, and closes the Lua state (on 5.2+). - `utils.assert_arg` and `utils.assert_string`: now return the validated value - `pl.compat`: now exports the `jit` and `jit52` flags - - `pretty.write`: now sorts the output for easier diffs [#293](https://github.com/Tieske/Penlight/pull/293) + - `pretty.write`: now sorts the output for easier diffs [#293](https://github.com/lunarmodules/Penlight/pull/293) ### Fixes - `utils.raise` changed the global `on_error`-level when passing in bad arguments - `utils.writefile` now checks and returns errors when writing - `compat.execute` now handles the Windows exitcode -1 properly - - `types.is_empty` would return true on spaces always, indepedent of the parameter + - `types.is_empty` would return true on spaces always, independent of the parameter - `types.to_bool` will now compare case-insensitive for the extra passed strings - `app.require_here` will now properly handle an absolute base path - `stringx.split` will no longer append an empty match if the number of requested - elements has already been reached [#295](https://github.com/Tieske/Penlight/pull/295) + elements has already been reached [#295](https://github.com/lunarmodules/Penlight/pull/295) - `path.common_prefix` and `path.relpath` return the result in the original casing - (only impacted Windows) [#297](https://github.com/Tieske/Penlight/pull/297) + (only impacted Windows) [#297](https://github.com/lunarmodules/Penlight/pull/297) - `dir.copyfile`, `dir.movefile`, and `dir.makepath` create the new file/path with the requested casing, and no longer force lowercase (only impacted Windows) - [#297](https://github.com/Tieske/Penlight/pull/297) - - added a missing assertion on `path.getmtime` [#291](https://github.com/Tieske/Penlight/pull/291) - - `stringx.rpartition` returned bad results on a not-found [#299](https://github.com/Tieske/Penlight/pull/299) + [#297](https://github.com/lunarmodules/Penlight/pull/297) + - added a missing assertion on `path.getmtime` [#291](https://github.com/lunarmodules/Penlight/pull/291) + - `stringx.rpartition` returned bad results on a not-found [#299](https://github.com/lunarmodules/Penlight/pull/299) ## 1.6.0 (2018-11-23) @@ -54,6 +103,7 @@ - Fixed `pl.import_into` not importing some Penlight modules (#268). - Fixed version number stuck at 1.5.2 (#260). - Fixed `types.is_empty` returning `true` on tables containing `false` key (#267). + - Fixed `types.is_empty` returning `false` if not a nil/table/string - Fixed `test.assertraise` throwing an error when passed an array with a function to call plus its arguments (#272). - Fixed `test.assertraise` not throwing an error when given function does not error but instead returns a string matching given error pattern. - Fixed placeholder expressions being evaluated with wrong precedence of binary and unary negation. diff -Nru lua-penlight-1.7.0/config.ld lua-penlight-1.9.2/config.ld --- lua-penlight-1.7.0/config.ld 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/config.ld 2020-09-27 10:39:11.000000000 +0000 @@ -1,5 +1,5 @@ project = 'Penlight' -description = 'Penlight Lua Libraries 1.7.0' +description = 'Penlight Lua Libraries 1.9.2' full_description = 'The documentation is available @{01-introduction.md|here}.' title = 'Penlight Documentation' dir = 'docs' diff -Nru lua-penlight-1.7.0/CONTRIBUTING.md lua-penlight-1.9.2/CONTRIBUTING.md --- lua-penlight-1.7.0/CONTRIBUTING.md 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/CONTRIBUTING.md 2020-09-27 10:39:11.000000000 +0000 @@ -14,7 +14,7 @@ If you have a more deeply-rooted problem with how the library is built or some of the stylistic decisions made in the code, it's best to -[create an issue](https://github.com/Tieske/Penlight/issues) before putting +[create an issue](https://github.com/lunarmodules/Penlight/issues) before putting the effort into a pull request. The same goes for new features - it might be best to check the project's direction, existing pull requests, and currently open and closed issues first. @@ -23,7 +23,7 @@ Here's how to go about contributing to Penlight: -1. [Fork the repository](https://github.com/Tieske/Penlight/fork) to +1. [Fork the repository](https://github.com/lunarmodules/Penlight/fork) to your Github account. 2. Create a *topical branch* - a branch whose name is succint but explains what you're doing, such as _"added-klingon-cloacking-device"_ - from `master` branch. @@ -34,8 +34,8 @@ If you wanna be a rockstar; -1. Update the [CHANGELOG.md](https://github.com/Tieske/Penlight/blob/master/CHANGELOG.md) file -2. [Add tests](https://github.com/Tieske/Penlight/tree/master/tests) that show the defect your fix repairs, or that tests your new feature +1. Update the [CHANGELOG.md](https://github.com/lunarmodules/Penlight/blob/master/CHANGELOG.md) file +2. [Add tests](https://github.com/lunarmodules/Penlight/tree/master/tests) that show the defect your fix repairs, or that tests your new feature Please note - if you want to change multiple things that don't depend on each other, make sure you check out the `master` branch again and create a different topical branch @@ -48,8 +48,10 @@ - update `./config.ld` with the new version number - create a new rockspec file for the version in `./rockspecs` - check the `./CHANGELOG.md` files for completeness + - commit the release related changes - render the documentation using `ldoc .` - - commit all the changes and create a PR + - commit the documentation as a separate commit + - push the release branch and create a PR - merge the PR - tag the release and push the tag to the github repo - upload the rockspec, and source rock files to LuaRocks diff -Nru lua-penlight-1.7.0/debian/changelog lua-penlight-1.9.2/debian/changelog --- lua-penlight-1.7.0/debian/changelog 2020-05-22 00:06:24.000000000 +0000 +++ lua-penlight-1.9.2/debian/changelog 2021-03-03 20:15:57.000000000 +0000 @@ -1,4 +1,28 @@ -lua-penlight (1.7.0-1ppa2~ubuntu20.04) focal; urgency=medium +lua-penlight (1.9.2-1ppa1~ubuntu20.04) focal; urgency=medium + + * Update focal to 1.9.2 + + -- Caleb Maclennan Wed, 03 Mar 2021 20:15:57 +0000 + +lua-penlight (1.9.2-1ppa1~ubuntu18.04) bionic; urgency=medium + + * Update bionic to 1.9.2 + + -- Caleb Maclennan Wed, 03 Mar 2021 20:08:50 +0000 + +lua-penlight (1.7.0-1ppa1~ubuntu20.10) groovy; urgency=medium + + * Initial release for Groovy + + -- Caleb Maclennan Wed, 03 Mar 2021 19:55:30 +0000 + +lua-penlight (1.7.0-1ppa2~ubuntu18.04) bionic; urgency=medium + + * Normalize version scheme + + -- Caleb Maclennan Mon, 25 May 2020 09:14:31 +0000 + +lua-penlight (1.7.0-1ppa2~ubuntu20.05) focal; urgency=medium * Fix doc packaging diff -Nru lua-penlight-1.7.0/debian/lua-penlight-dev.install lua-penlight-1.9.2/debian/lua-penlight-dev.install --- lua-penlight-1.7.0/debian/lua-penlight-dev.install 2020-05-21 23:52:11.000000000 +0000 +++ lua-penlight-1.9.2/debian/lua-penlight-dev.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - diff -Nru lua-penlight-1.7.0/debian/lua-penlight.install lua-penlight-1.9.2/debian/lua-penlight.install --- lua-penlight-1.7.0/debian/lua-penlight.install 2020-05-21 23:52:13.000000000 +0000 +++ lua-penlight-1.9.2/debian/lua-penlight.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ - -usr/share/lua/5.1/pl/Date.lua -usr/share/lua/5.1/pl/List.lua -usr/share/lua/5.1/pl/Map.lua -usr/share/lua/5.1/pl/MultiMap.lua -usr/share/lua/5.1/pl/OrderedMap.lua -usr/share/lua/5.1/pl/Set.lua -usr/share/lua/5.1/pl/app.lua -usr/share/lua/5.1/pl/array2d.lua -usr/share/lua/5.1/pl/class.lua -usr/share/lua/5.1/pl/compat.lua -usr/share/lua/5.1/pl/comprehension.lua -usr/share/lua/5.1/pl/config.lua -usr/share/lua/5.1/pl/data.lua -usr/share/lua/5.1/pl/dir.lua -usr/share/lua/5.1/pl/file.lua -usr/share/lua/5.1/pl/func.lua -usr/share/lua/5.1/pl/import_into.lua -usr/share/lua/5.1/pl/init.lua -usr/share/lua/5.1/pl/input.lua -usr/share/lua/5.1/pl/lapp.lua -usr/share/lua/5.1/pl/lexer.lua -usr/share/lua/5.1/pl/luabalanced.lua -usr/share/lua/5.1/pl/operator.lua -usr/share/lua/5.1/pl/path.lua -usr/share/lua/5.1/pl/permute.lua -usr/share/lua/5.1/pl/pretty.lua -usr/share/lua/5.1/pl/seq.lua -usr/share/lua/5.1/pl/sip.lua -usr/share/lua/5.1/pl/strict.lua -usr/share/lua/5.1/pl/stringio.lua -usr/share/lua/5.1/pl/stringx.lua -usr/share/lua/5.1/pl/tablex.lua -usr/share/lua/5.1/pl/template.lua -usr/share/lua/5.1/pl/test.lua -usr/share/lua/5.1/pl/text.lua -usr/share/lua/5.1/pl/types.lua -usr/share/lua/5.1/pl/url.lua -usr/share/lua/5.1/pl/utils.lua -usr/share/lua/5.1/pl/xml.lua -usr/share/lua/5.2/pl/Date.lua -usr/share/lua/5.2/pl/List.lua -usr/share/lua/5.2/pl/Map.lua -usr/share/lua/5.2/pl/MultiMap.lua -usr/share/lua/5.2/pl/OrderedMap.lua -usr/share/lua/5.2/pl/Set.lua -usr/share/lua/5.2/pl/app.lua -usr/share/lua/5.2/pl/array2d.lua -usr/share/lua/5.2/pl/class.lua -usr/share/lua/5.2/pl/compat.lua -usr/share/lua/5.2/pl/comprehension.lua -usr/share/lua/5.2/pl/config.lua -usr/share/lua/5.2/pl/data.lua -usr/share/lua/5.2/pl/dir.lua -usr/share/lua/5.2/pl/file.lua -usr/share/lua/5.2/pl/func.lua -usr/share/lua/5.2/pl/import_into.lua -usr/share/lua/5.2/pl/init.lua -usr/share/lua/5.2/pl/input.lua -usr/share/lua/5.2/pl/lapp.lua -usr/share/lua/5.2/pl/lexer.lua -usr/share/lua/5.2/pl/luabalanced.lua -usr/share/lua/5.2/pl/operator.lua -usr/share/lua/5.2/pl/path.lua -usr/share/lua/5.2/pl/permute.lua -usr/share/lua/5.2/pl/pretty.lua -usr/share/lua/5.2/pl/seq.lua -usr/share/lua/5.2/pl/sip.lua -usr/share/lua/5.2/pl/strict.lua -usr/share/lua/5.2/pl/stringio.lua -usr/share/lua/5.2/pl/stringx.lua -usr/share/lua/5.2/pl/tablex.lua -usr/share/lua/5.2/pl/template.lua -usr/share/lua/5.2/pl/test.lua -usr/share/lua/5.2/pl/text.lua -usr/share/lua/5.2/pl/types.lua -usr/share/lua/5.2/pl/url.lua -usr/share/lua/5.2/pl/utils.lua -usr/share/lua/5.2/pl/xml.lua -usr/share/lua/5.3/pl/Date.lua -usr/share/lua/5.3/pl/List.lua -usr/share/lua/5.3/pl/Map.lua -usr/share/lua/5.3/pl/MultiMap.lua -usr/share/lua/5.3/pl/OrderedMap.lua -usr/share/lua/5.3/pl/Set.lua -usr/share/lua/5.3/pl/app.lua -usr/share/lua/5.3/pl/array2d.lua -usr/share/lua/5.3/pl/class.lua -usr/share/lua/5.3/pl/compat.lua -usr/share/lua/5.3/pl/comprehension.lua -usr/share/lua/5.3/pl/config.lua -usr/share/lua/5.3/pl/data.lua -usr/share/lua/5.3/pl/dir.lua -usr/share/lua/5.3/pl/file.lua -usr/share/lua/5.3/pl/func.lua -usr/share/lua/5.3/pl/import_into.lua -usr/share/lua/5.3/pl/init.lua -usr/share/lua/5.3/pl/input.lua -usr/share/lua/5.3/pl/lapp.lua -usr/share/lua/5.3/pl/lexer.lua -usr/share/lua/5.3/pl/luabalanced.lua -usr/share/lua/5.3/pl/operator.lua -usr/share/lua/5.3/pl/path.lua -usr/share/lua/5.3/pl/permute.lua -usr/share/lua/5.3/pl/pretty.lua -usr/share/lua/5.3/pl/seq.lua -usr/share/lua/5.3/pl/sip.lua -usr/share/lua/5.3/pl/strict.lua -usr/share/lua/5.3/pl/stringio.lua -usr/share/lua/5.3/pl/stringx.lua -usr/share/lua/5.3/pl/tablex.lua -usr/share/lua/5.3/pl/template.lua -usr/share/lua/5.3/pl/test.lua -usr/share/lua/5.3/pl/text.lua -usr/share/lua/5.3/pl/types.lua -usr/share/lua/5.3/pl/url.lua -usr/share/lua/5.3/pl/utils.lua -usr/share/lua/5.3/pl/xml.lua diff -Nru lua-penlight-1.7.0/debian/lua_versions lua-penlight-1.9.2/debian/lua_versions --- lua-penlight-1.7.0/debian/lua_versions 2020-05-21 23:52:13.000000000 +0000 +++ lua-penlight-1.9.2/debian/lua_versions 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -5.1 -5.2 -5.3 diff -Nru lua-penlight-1.7.0/debian/patches/ignore_coverage_in_tests lua-penlight-1.9.2/debian/patches/ignore_coverage_in_tests --- lua-penlight-1.7.0/debian/patches/ignore_coverage_in_tests 2020-05-21 23:19:11.000000000 +0000 +++ lua-penlight-1.9.2/debian/patches/ignore_coverage_in_tests 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -Description: Don't do coverage reporting while running tests - See upstream bug https://github.com/Tieske/Penlight/issues/316 - . - lua-penlight (1.7.0-0ubuntu2) bionic; urgency=medium - . - * Patch tests to skip coverage reporting - (See https://github.com/Tieske/Penlight/issues/316) -Author: Caleb Maclennan - ---- -The information above should follow the Patch Tagging Guidelines, please -checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here -are templates for supplementary fields that you might want to add: - -Origin: , -Bug: -Bug-Debian: https://bugs.debian.org/ -Bug-Ubuntu: https://launchpad.net/bugs/ -Forwarded: -Reviewed-By: -Last-Update: 2020-01-31 - ---- /dev/null -+++ lua-penlight-1.7.0/patches/series -@@ -0,0 +1 @@ -+ignore_luacov_durring_test.patch ---- lua-penlight-1.7.0.orig/tests/test-app.lua -+++ lua-penlight-1.7.0/tests/test-app.lua -@@ -6,7 +6,7 @@ local asserteq = require 'pl.test'.asser - local quote = utils.quote_arg - - local _, cmd = app.lua() --cmd = cmd .. " " .. quote({"-lluacov", "-e", "package.path=[[./lua/?.lua;./lua/?/init.lua;]]..package.path"}) -+cmd = cmd .. " " .. quote({"-e", "package.path=[[./lua/?.lua;./lua/?/init.lua;]]..package.path"}) - - local function run_script(s, fname) - local tmpname = path.tmpname() diff -Nru lua-penlight-1.7.0/debian/patches/series lua-penlight-1.9.2/debian/patches/series --- lua-penlight-1.7.0/debian/patches/series 2020-05-21 23:19:11.000000000 +0000 +++ lua-penlight-1.9.2/debian/patches/series 2021-03-03 20:12:04.000000000 +0000 @@ -1 +0,0 @@ -ignore_coverage_in_tests diff -Nru lua-penlight-1.7.0/debian/trash lua-penlight-1.9.2/debian/trash --- lua-penlight-1.7.0/debian/trash 2020-05-22 00:06:24.000000000 +0000 +++ lua-penlight-1.9.2/debian/trash 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions -debian/lua-penlight.install -debian/lua-penlight-dev.install -debian/lua_versions diff -Nru lua-penlight-1.7.0/docs/classes/pl.Date.html lua-penlight-1.9.2/docs/classes/pl.Date.html --- lua-penlight-1.7.0/docs/classes/pl.Date.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/classes/pl.Date.html 2020-09-27 10:39:11.000000000 +0000 @@ -1039,7 +1039,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/classes/pl.List.html lua-penlight-1.9.2/docs/classes/pl.List.html --- lua-penlight-1.7.0/docs/classes/pl.List.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/classes/pl.List.html 2020-09-27 10:39:11.000000000 +0000 @@ -1436,7 +1436,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/classes/pl.Map.html lua-penlight-1.9.2/docs/classes/pl.Map.html --- lua-penlight-1.7.0/docs/classes/pl.Map.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/classes/pl.Map.html 2020-09-27 10:39:11.000000000 +0000 @@ -447,7 +447,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/classes/pl.MultiMap.html lua-penlight-1.9.2/docs/classes/pl.MultiMap.html --- lua-penlight-1.7.0/docs/classes/pl.MultiMap.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/classes/pl.MultiMap.html 2020-09-27 10:39:11.000000000 +0000 @@ -200,7 +200,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/classes/pl.OrderedMap.html lua-penlight-1.9.2/docs/classes/pl.OrderedMap.html --- lua-penlight-1.7.0/docs/classes/pl.OrderedMap.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/classes/pl.OrderedMap.html 2020-09-27 10:39:11.000000000 +0000 @@ -410,7 +410,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/classes/pl.Set.html lua-penlight-1.9.2/docs/classes/pl.Set.html --- lua-penlight-1.7.0/docs/classes/pl.Set.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/classes/pl.Set.html 2020-09-27 10:39:11.000000000 +0000 @@ -648,7 +648,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/seesubst.lua.html lua-penlight-1.9.2/docs/examples/seesubst.lua.html --- lua-penlight-1.7.0/docs/examples/seesubst.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/seesubst.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -167,7 +167,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/sipscan.lua.html lua-penlight-1.9.2/docs/examples/sipscan.lua.html --- lua-penlight-1.7.0/docs/examples/sipscan.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/sipscan.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -154,7 +154,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/symbols.lua.html lua-penlight-1.9.2/docs/examples/symbols.lua.html --- lua-penlight-1.7.0/docs/examples/symbols.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/symbols.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -340,7 +340,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/testclone.lua.html lua-penlight-1.9.2/docs/examples/testclone.lua.html --- lua-penlight-1.7.0/docs/examples/testclone.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/testclone.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -158,7 +158,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/test-cmp.lua.html lua-penlight-1.9.2/docs/examples/test-cmp.lua.html --- lua-penlight-1.7.0/docs/examples/test-cmp.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/test-cmp.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -123,7 +123,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/testconfig.lua.html lua-penlight-1.9.2/docs/examples/testconfig.lua.html --- lua-penlight-1.7.0/docs/examples/testconfig.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/testconfig.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -169,7 +169,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/test-data.lua.html lua-penlight-1.9.2/docs/examples/test-data.lua.html --- lua-penlight-1.7.0/docs/examples/test-data.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/test-data.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -365,7 +365,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/testglobal.lua.html lua-penlight-1.9.2/docs/examples/testglobal.lua.html --- lua-penlight-1.7.0/docs/examples/testglobal.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/testglobal.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -146,7 +146,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/testinputfields2.lua.html lua-penlight-1.9.2/docs/examples/testinputfields2.lua.html --- lua-penlight-1.7.0/docs/examples/testinputfields2.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/testinputfields2.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -129,7 +129,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/testinputfields.lua.html lua-penlight-1.9.2/docs/examples/testinputfields.lua.html --- lua-penlight-1.7.0/docs/examples/testinputfields.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/testinputfields.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -133,7 +133,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/test-listcallbacks.lua.html lua-penlight-1.9.2/docs/examples/test-listcallbacks.lua.html --- lua-penlight-1.7.0/docs/examples/test-listcallbacks.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/test-listcallbacks.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -131,7 +131,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/test-pretty.lua.html lua-penlight-1.9.2/docs/examples/test-pretty.lua.html --- lua-penlight-1.7.0/docs/examples/test-pretty.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/test-pretty.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -133,7 +133,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/test-symbols.lua.html lua-penlight-1.9.2/docs/examples/test-symbols.lua.html --- lua-penlight-1.7.0/docs/examples/test-symbols.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/test-symbols.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -202,7 +202,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/testxml.lua.html lua-penlight-1.9.2/docs/examples/testxml.lua.html --- lua-penlight-1.7.0/docs/examples/testxml.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/testxml.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -202,7 +202,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/examples/which.lua.html lua-penlight-1.9.2/docs/examples/which.lua.html --- lua-penlight-1.7.0/docs/examples/which.lua.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/examples/which.lua.html 2020-09-27 10:39:11.000000000 +0000 @@ -148,7 +148,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/index.html lua-penlight-1.9.2/docs/index.html --- lua-penlight-1.7.0/docs/index.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/index.html 2020-09-27 10:39:11.000000000 +0000 @@ -110,7 +110,7 @@
-

Penlight Lua Libraries 1.7.0

+

Penlight Lua Libraries 1.9.2

The documentation is available here.

Libraries

@@ -382,7 +382,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/libraries/pl.app.html lua-penlight-1.9.2/docs/libraries/pl.app.html --- lua-penlight-1.7.0/docs/libraries/pl.app.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.app.html 2020-09-27 10:39:11.000000000 +0000 @@ -131,7 +131,7 @@ require_here (base) - add the current script's path to the Lua module path. + prefixes the current script's path to the Lua module path. appfile (file) @@ -183,19 +183,21 @@ require_here (base)
- add the current script's path to the Lua module path. + prefixes the current script's path to the Lua module path. Applies to both the source and the binary module paths. It makes it easy for the main file of a multi-file program to access its modules in the same directory. base allows these modules to be put in a specified subdirectory, to allow for cleaner deployment and resolve potential conflicts between a script name and its - library directory. + library directory.

+ +

Note: the path is prefixed, so it is searched first when requiring modules.

Parameters:

  • base string - optional base directory. + optional base directory (absolute, or relative path).
@@ -292,7 +294,7 @@
-- execute:  lua -lluacov -e 'print(_VERSION)' myscript.lua
 
 -- myscript.lua
-print(require("pl.app").lua()))  --> lua -lluacov -e 'print(_VERSION)'
+print(require("pl.app").lua()) --> "lua -lluacov -e 'print(_VERSION)'", "lua"
@@ -388,7 +390,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/libraries/pl.array2d.html lua-penlight-1.9.2/docs/libraries/pl.array2d.html --- lua-penlight-1.7.0/docs/libraries/pl.array2d.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.array2d.html 2020-09-27 10:39:11.000000000 +0000 @@ -1143,7 +1143,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/libraries/pl.class.html lua-penlight-1.9.2/docs/libraries/pl.class.html --- lua-penlight-1.7.0/docs/libraries/pl.class.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.class.html 2020-09-27 10:39:11.000000000 +0000 @@ -325,7 +325,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/libraries/pl.compat.html lua-penlight-1.9.2/docs/libraries/pl.compat.html --- lua-penlight-1.7.0/docs/libraries/pl.compat.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.compat.html 2020-09-27 10:39:11.000000000 +0000 @@ -181,8 +181,8 @@ unpack a table and return the elements. - package.searchpath (mod, path) - return the full path where a Lua module name would be matched. + package.searchpath (name, path[, sep[, rep]]) + return the full path where a file name would be matched. @@ -203,7 +203,10 @@ Lua 5.2+.

NOTE: Windows systems can use signed 32bit integer exitcodes. Posix systems - only use exitcodes 0-255, anything else is undefined. + only use exitcodes 0-255, anything else is undefined.

+ +

NOTE2: In Lua 5.2 and 5.3 a Windows exitcode of -1 would not properly be + returned, this function will return it properly for all versions.

Parameters:

@@ -484,22 +487,43 @@
- package.searchpath (mod, path) + package.searchpath (name, path[, sep[, rep]])
- return the full path where a Lua module name would be matched. + return the full path where a file name would be matched. + This function was introduced in Lua 5.2, so this compatibility version + will be injected in Lua 5.1 engines.

Parameters:

    -
  • mod - module name, possibly dotted +
  • name + string + file name, possibly dotted
  • path - a path in the same form as package.path or package.cpath + string + a path-template in the same form as package.path or package.cpath +
  • +
  • sep + string + template separate character to be replaced by path separator. Default: "." + (optional) +
  • +
  • rep + string + the path separator to use, defaults to system separator. Default; "/" on Unixes, "\" on Windows. + (optional)
+

Returns:

+
    +
  1. + on success: path of the file
  2. +
  3. + on failure: nil, error string listing paths tried
  4. +

See also:

@@ -516,7 +540,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/libraries/pl.comprehension.html lua-penlight-1.9.2/docs/libraries/pl.comprehension.html --- lua-penlight-1.7.0/docs/libraries/pl.comprehension.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.comprehension.html 2020-09-27 10:39:11.000000000 +0000 @@ -158,7 +158,7 @@
generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
diff -Nru lua-penlight-1.7.0/docs/libraries/pl.config.html lua-penlight-1.9.2/docs/libraries/pl.config.html --- lua-penlight-1.7.0/docs/libraries/pl.config.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.config.html 2020-09-27 10:39:11.000000000 +0000 @@ -220,7 +220,7 @@
  • smart try to deduce what kind of config file we have (default false)
  • -
  • variablilize make names into valid Lua identifiers (default true)
  • +
  • variabilize make names into valid Lua identifiers (default true)
  • convert_numbers try to convert values into numbers (default true)
  • trim_space ensure that there is no starting or trailing whitespace with values (default true)
  • trim_quotes remove quotes from strings (default false)
  • @@ -252,7 +252,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.data.html lua-penlight-1.9.2/docs/libraries/pl.data.html --- lua-penlight-1.7.0/docs/libraries/pl.data.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.data.html 2020-09-27 10:39:11.000000000 +0000 @@ -564,7 +564,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.dir.html lua-penlight-1.9.2/docs/libraries/pl.dir.html --- lua-penlight-1.7.0/docs/libraries/pl.dir.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.dir.html 2020-09-27 10:39:11.000000000 +0000 @@ -134,11 +134,11 @@ Return a list of all file names within an array which match a pattern. - getfiles (dir, mask) + getfiles (dirname, mask) return a list of all files in a directory which match a shell pattern. - getdirectories (dir) + getdirectories (dirname) return a list of all subdirectories of the directory. @@ -256,7 +256,7 @@
- getfiles (dir, mask) + getfiles (dirname, mask)
return a list of all files in a directory which match a shell pattern. @@ -264,7 +264,7 @@

Parameters:

    -
  • dir +
  • dirname string A directory. If not given, all files in current directory are returned.
  • @@ -282,14 +282,14 @@

    Raises:

    - dir and mask must be strings + dirname and mask must be strings
- getdirectories (dir) + getdirectories (dirname)
return a list of all subdirectories of the directory. @@ -297,7 +297,7 @@

Parameters:

    -
  • dir +
  • dirname string A directory
  • @@ -607,7 +607,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.file.html lua-penlight-1.9.2/docs/libraries/pl.file.html --- lua-penlight-1.7.0/docs/libraries/pl.file.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.file.html 2020-09-27 10:39:11.000000000 +0000 @@ -294,7 +294,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.func.html lua-penlight-1.9.2/docs/libraries/pl.func.html --- lua-penlight-1.7.0/docs/libraries/pl.func.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.func.html 2020-09-27 10:39:11.000000000 +0000 @@ -453,7 +453,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.html lua-penlight-1.9.2/docs/libraries/pl.html --- lua-penlight-1.7.0/docs/libraries/pl.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.html 2020-09-27 10:39:11.000000000 +0000 @@ -132,7 +132,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.import_into.html lua-penlight-1.9.2/docs/libraries/pl.import_into.html --- lua-penlight-1.7.0/docs/libraries/pl.import_into.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.import_into.html 2020-09-27 10:39:11.000000000 +0000 @@ -135,7 +135,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.input.html lua-penlight-1.9.2/docs/libraries/pl.input.html --- lua-penlight-1.7.0/docs/libraries/pl.input.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.input.html 2020-09-27 10:39:11.000000000 +0000 @@ -329,7 +329,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.lapp.html lua-penlight-1.9.2/docs/libraries/pl.lapp.html --- lua-penlight-1.7.0/docs/libraries/pl.lapp.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.lapp.html 2020-09-27 10:39:11.000000000 +0000 @@ -375,7 +375,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.lexer.html lua-penlight-1.9.2/docs/libraries/pl.lexer.html --- lua-penlight-1.7.0/docs/libraries/pl.lexer.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.lexer.html 2020-09-27 10:39:11.000000000 +0000 @@ -517,7 +517,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.luabalanced.html lua-penlight-1.9.2/docs/libraries/pl.luabalanced.html --- lua-penlight-1.7.0/docs/libraries/pl.luabalanced.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.luabalanced.html 2020-09-27 10:39:11.000000000 +0000 @@ -142,7 +142,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.operator.html lua-penlight-1.9.2/docs/libraries/pl.operator.html --- lua-penlight-1.7.0/docs/libraries/pl.operator.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.operator.html 2020-09-27 10:39:11.000000000 +0000 @@ -812,7 +812,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.path.html lua-penlight-1.9.2/docs/libraries/pl.path.html --- lua-penlight-1.7.0/docs/libraries/pl.path.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.path.html 2020-09-27 10:39:11.000000000 +0000 @@ -121,18 +121,52 @@

    Path manipulation and file queries.

    This is modelled after Python's os.path library (10.1); see the Guide.

    +

    NOTE: the functions assume the paths being dealt with to originate + from the OS the application is running on. Windows drive letters are not + to be used when running on a Unix system for example. The one exception + is Windows paths to allow both forward and backward slashes (since Lua + also accepts those)

    +

    Dependencies: pl.utils, lfs

    Functions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -140,7 +174,7 @@ - + @@ -148,11 +182,11 @@ - + - + @@ -180,7 +214,7 @@ - + @@ -218,26 +252,6 @@

    Fields

    dir ()Lua iterator over the entries of a given directory.
    mkdir ()Creates a directory.
    rmdir ()Removes a directory.
    attrib ()Gets attributes.
    currentdir ()Get the working directory.
    link_attrib ()Gets symlink attributes.
    chdir ()Changes the working directory.
    isdir (P) is this a directory?
    isfile (P)is this a file?.is this a file?
    getsize (P)
    exists (P)does a path exist?.does a path exist?
    getatime (P)
    getmtime (P)Return the time of last modificationReturn the time of last modification as the number of seconds since the epoch.
    getctime (P)Return the system's ctime.Return the system's ctime as the number of seconds since the epoch.
    splitpath (P)
    isabs (P)is this an absolute path?.is this an absolute path?
    join (p1, p2, ...)
    - - - - - - - - - - - - - - - - - - - - @@ -259,6 +273,113 @@
    + + dir () +
    +
    + Lua iterator over the entries of a given directory. + Implicit link to luafilesystem.dir + + + + + + + +
    +
    + + mkdir () +
    +
    + Creates a directory. + Implicit link to luafilesystem.mkdir + + + + + + + +
    +
    + + rmdir () +
    +
    + Removes a directory. + Implicit link to luafilesystem.rmdir + + + + + + + +
    +
    + + attrib () +
    +
    + Gets attributes. + Implicit link to luafilesystem.attributes + + + + + + + +
    +
    + + currentdir () +
    +
    + Get the working directory. + Implicit link to luafilesystem.currentdir + + + + + + + +
    +
    + + link_attrib () +
    +
    + Gets symlink attributes. + Implicit link to luafilesystem.symlinkattributes + + + + + + + +
    +
    + + chdir () +
    +
    + Changes the working directory. + On Windows, if a drive is specified, it also changes the current drive. If + only specifying the drive, it will only switch drive, but not modify the path. + Implicit link to luafilesystem.chdir + + + + + + + +
    +
    isdir (P)
    @@ -284,7 +405,7 @@ isfile (P)
    - is this a file?. + is this a file?

    Parameters:

    @@ -326,7 +447,7 @@ exists (P)
    - does a path exist?. + does a path exist?

    Parameters:

    @@ -340,7 +461,7 @@

    Returns:

      - the file path if it exists, nil otherwise + the file path if it exists (either as file, directory, socket, etc), nil otherwise
    @@ -373,7 +494,7 @@ getmtime (P)
    - Return the time of last modification + Return the time of last modification as the number of seconds since the epoch.

    Parameters:

    @@ -394,7 +515,7 @@ getctime (P)
    - Return the system's ctime. + Return the system's ctime as the number of seconds since the epoch.

    Parameters:

    @@ -427,9 +548,30 @@ +

    Returns:

    +
      +
    1. + directory part
    2. +
    3. + file part
    4. +
    +

    Usage:

    +
      +
      local dir, file = path.splitpath("some/dir/myfile.txt")
      +assert(dir == "some/dir")
      +assert(file == "myfile.txt")
      +
      +local dir, file = path.splitpath("some/dir/")
      +assert(dir == "some/dir")
      +assert(file == "")
      +
      +local dir, file = path.splitpath("some_dir")
      +assert(dir == "")
      +assert(file == "some_dir")
      +
    @@ -479,14 +621,24 @@
    1. string - root part
    2. + root part (everything upto the "."", maybe empty)
    3. string - extension part (maybe empty)
    4. + extension part (including the ".", maybe empty)
    +

    Usage:

    +
      +
      local file_path, ext = path.splitext("/bonzo/dog_stuff/cat.txt")
      +assert(file_path == "/bonzo/dog_stuff/cat")
      +assert(ext == ".txt")
      +
      +local file_path, ext = path.splitext("")
      +assert(file_path == "")
      +assert(ext == "")
      +
    @@ -505,9 +657,24 @@ +

    Returns:

    +
      + + string + everything before the last dir-separator +
    +

    See also:

    + +

    Usage:

    +
      +
      path.dirname("/some/path/file.txt")   -- "/some/path"
      +path.dirname("file.txt")              -- "" (empty string)
      +
    @@ -526,9 +693,26 @@ +

    Returns:

    +
      + + string +
    + + +

    See also:

    + + +

    Usage:

    +
      +
      path.basename("/some/path/file.txt")  -- "file.txt"
      +path.basename("/some/path/file/")     -- "" (empty string)
      +
    @@ -547,9 +731,26 @@ +

    Returns:

    +
      + + string + + + +
    +

    See also:

    + +

    Usage:

    +
      +
      path.extension("/some/path/file.txt") -- ".txt"
      +path.extension("/some/path/file_txt") -- "" (empty string)
      +
    @@ -557,7 +758,7 @@ isabs (P)
    - is this an absolute path?. + is this an absolute path?

    Parameters:

    @@ -571,6 +772,16 @@ +

    Usage:

    +
      +
      path.isabs("hello/path")    -- false
      +path.isabs("/hello/path")   -- true
      +-- Windows;
      +path.isabs("hello\path")    -- false
      +path.isabs("\hello\path")   -- true
      +path.isabs("C:\hello\path") -- true
      +path.isabs("C:hello\path")  -- false
      +
    @@ -599,19 +810,37 @@ +

    Returns:

    +
      + string + the combined path +
    +

    Usage:

    +
      +
      path.join("/first","second","third")   -- "/first/second/third"
      +path.join("first","second/third")      -- "first/second/third"
      +path.join("/first","/second","third")  -- "/second/third"
      +
    +
    normcase (P)
    - normalize the case of a pathname. On Unix, this returns the path unchanged; - for Windows, it converts the path to lowercase, and it also converts forward slashes - to backward slashes. + +

    normalize the case of a pathname. On Unix, this returns the path unchanged, + for Windows it converts;

    + +
      +
    • the path to lowercase
    • +
    • forward slashes to backward slashes
    • +
    +

    Parameters:

    @@ -625,6 +854,12 @@ +

    Usage:

    +
      +
      path.normcase("/Some/Path/File.txt")
      +-- Windows: "\some\path\file.txt"
      +-- Others : "/Some/Path/File.txt"
      +
    @@ -633,7 +868,9 @@
    normalize a path name. - A//B, A/./B, and A/foo/../B all become A/B. + A//B, A/./B, and A/foo/../B all become A/B.

    + +

    An empty path results in '.'.

    Parameters:

    @@ -704,7 +941,7 @@
    Return a suitable full path to a new temporary file name. - unlike os.tmpnam(), it always gives you a writeable path (uses TEMP environment variable on Windows) + unlike os.tmpname(), it always gives you a writeable path (uses TEMP environment variable on Windows) @@ -733,6 +970,11 @@ +

    Returns:

    +
      + + the common prefix (Windows: separators will be normalized, casing will be original) +
    @@ -761,7 +1003,7 @@
  • on success: path of module, lua or binary
  • - on error: nil,error string
  • + on error: nil, error string listing paths tried @@ -773,77 +1015,6 @@
    - - dir -
    -
    - Lua iterator over the entries of a given directory. - Behaves like lfs.dir - - - - - - - -
    -
    - - mkdir -
    -
    - Creates a directory. - - - - - - - -
    -
    - - rmdir -
    -
    - Removes a directory. - - - - - - - -
    -
    - - currentdir -
    -
    - Get the working directory. - - - - - - - -
    -
    - - chdir -
    -
    - Changes the working directory. - - - - - - - -
    -
    is_windows
    @@ -892,7 +1063,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.permute.html lua-penlight-1.9.2/docs/libraries/pl.permute.html --- lua-penlight-1.7.0/docs/libraries/pl.permute.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.permute.html 2020-09-27 10:39:11.000000000 +0000 @@ -202,7 +202,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.pretty.html lua-penlight-1.9.2/docs/libraries/pl.pretty.html --- lua-penlight-1.7.0/docs/libraries/pl.pretty.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.pretty.html 2020-09-27 10:39:11.000000000 +0000 @@ -121,7 +121,7 @@

    Also provides a sandboxed Lua table reader and a function to present large numbers in human-friendly format.

    -

    Dependencies: pl.utils, pl.lexer, pl.stringx, debug

    +

    Dependencies: pl.utils, pl.lexer, pl.stringx, debug

    Functions

    @@ -143,6 +143,10 @@
    + + + + @@ -235,7 +239,13 @@ This function never fails, but may complain by returning an extra value. Normally puts out one item per line, using the provided indent; set the second parameter to an empty string - if you want output on one line. + if you want output on one line.

    + +

    NOTE: this is NOT a serialization function, not a full blown + debug function. Checkout out respectively the + serpent + or inspect + Lua modules for that if you need them.

    Parameters:

    @@ -298,6 +308,54 @@
    + + debug (...) +
    +
    + Dump a series of arguments to stdout for debug purposes. + This function is attached to the module table __call method, to make it + extra easy to access. So the full:

    + +
     print(require("pl.pretty").write({...}))
    +
    + +

    Can be shortened to:

    + +
     require"pl.pretty" (...)
    +
    + +

    Any nil entries will be printed as "<nil>" to make them explicit. + + +

    Parameters:

    +
      +
    • ... + the parameters to dump to stdout. +
    • +
    + + + + +

    Usage:

    +
      +
      -- example debug output
      +require"pl.pretty" ("hello", nil, "world", { bye = "world", true} )
      +
      +-- output:
      +{
      +  ["arg 1"] = "hello",
      +  ["arg 2"] = "<nil>",
      +  ["arg 3"] = "world",
      +  ["arg 4"] = {
      +    true,
      +    bye = "world"
      +  }
      +}
      +
    + +
    +
    number (num[, kind[, prec]])
    @@ -337,7 +395,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.seq.html lua-penlight-1.9.2/docs/libraries/pl.seq.html --- lua-penlight-1.7.0/docs/libraries/pl.seq.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.seq.html 2020-09-27 10:39:11.000000000 +0000 @@ -881,7 +881,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.sip.html lua-penlight-1.9.2/docs/libraries/pl.sip.html --- lua-penlight-1.7.0/docs/libraries/pl.sip.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.sip.html 2020-09-27 10:39:11.000000000 +0000 @@ -392,7 +392,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.strict.html lua-penlight-1.9.2/docs/libraries/pl.strict.html --- lua-penlight-1.7.0/docs/libraries/pl.strict.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.strict.html 2020-09-27 10:39:11.000000000 +0000 @@ -120,7 +120,7 @@

    Checks uses of undeclared global variables.

    All global variables must be 'declared' through a regular assignment (even assigning nil will do) in a main chunk before being used - anywhere or assigned to inside a function. Existing metatables __newindex and __index + anywhere or assigned to inside a function. Existing metatables __newindex and __index metamethods are respected.

    You can set any table to have strict behaviour using strict.module. Creating a new @@ -134,7 +134,7 @@

    Functions

    dirLua iterator over the entries of a given directory.
    mkdirCreates a directory.
    rmdirRemoves a directory.
    currentdirGet the working directory.
    chdirChanges the working directory.
    is_windows are we running Windows?
    Dump a Lua table out to a file or stdout.
    debug (...)Dump a series of arguments to stdout for debug purposes.
    number (num[, kind[, prec]]) Format large numbers nicely for human consumption.
    - + @@ -156,7 +156,7 @@
    - module (name[, mod[, predeclared]]) + module ([name[, mod[, predeclared]]])
    make an existing table strict. @@ -166,11 +166,12 @@
    • name string - name of table (optional) + name of table + (optional)
    • mod tab - table - if nil then we'll return a new table + the table to protect - if nil then we'll return a new table (optional)
    • predeclared @@ -192,6 +193,19 @@ +

      Usage:

      +
        +
        local M = { hello = "world" }
        +strict.module ("Awesome_Module", M, {
        +  Lua = true,  -- defines allowed keys
        +})
        +
        +assert(M.hello == "world")
        +assert(M.Lua == nil)       -- access allowed, but has no value yet
        +M.Lua = "Rocks"
        +assert(M.Lua == "Rocks")
        +M.not_allowed = "bad boy"  -- throws an error
        +
    @@ -208,9 +222,7 @@
    • T tab - - - + the table containing the tables to protect. Table T itself will NOT be protected.
    @@ -230,14 +242,12 @@

    Parameters:

    • mod - - - + tab + module table
    • name - - - + string + module name
    @@ -253,7 +263,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.stringio.html lua-penlight-1.9.2/docs/libraries/pl.stringio.html --- lua-penlight-1.7.0/docs/libraries/pl.stringio.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.stringio.html 2020-09-27 10:39:11.000000000 +0000 @@ -208,7 +208,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.stringx.html lua-penlight-1.9.2/docs/libraries/pl.stringx.html --- lua-penlight-1.7.0/docs/libraries/pl.stringx.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.stringx.html 2020-09-27 10:39:11.000000000 +0000 @@ -201,7 +201,7 @@
    - +
    module (name[, mod[, predeclared]])module ([name[, mod[, predeclared]]]) make an existing table strict.
    replace up to n instances of old by new in the string s.
    count (s, sub)count (s, sub[, allow_overlap]) count all instances of substring in string.
    @@ -259,7 +259,7 @@ title (s) - iniital word letters uppercase ('title case'). + inital word letters uppercase ('title case'). shorten (s, w, tail) @@ -462,6 +462,7 @@
    concatenate the strings using this string as a delimiter. + Note that the arguments are reversed from string.concat.

    Parameters:

    @@ -480,7 +481,7 @@

    Usage:

      -
      (' '):join {1,2,3} == '1 2 3'
      +
      stringx.join(' ', {1,2,3}) == '1 2 3'
    @@ -509,6 +510,11 @@
+

Returns:

+
    + + List of lines +
@@ -540,14 +546,19 @@ +

Returns:

+
    + + List +

Usage:

    -
  • #(('one two'):split()) == 2
  • -
  • ('one,two,three'):split(',') == List{'one','two','three'}
  • -
  • ('one,two,three'):split(',',2) == List{'one','two,three'}
  • +
  • #(stringx.split('one two')) == 2
  • +
  • stringx.split('one,two,three', ',') == List{'one','two','three'}
  • +
  • stringx.split('one,two,three', ',', 2) == List{'one','two,three'}
@@ -557,8 +568,7 @@
replace all tabs in s with tabsize spaces. If not specified, tabsize defaults to 8. - with 0.9.5 this now correctly expands to the next tab stop (if you really - want to just replace tabs, use :gsub('\t',' ') etc) + Tab stops will be honored.

Parameters:

@@ -573,9 +583,19 @@ +

Returns:

+
    + + expanded string +
+

Usage:

+
    +
  • stringx.expandtabs('\tone,two,three', 4)   == '    one,two,three'
  • +
  • stringx.expandtabs('  \tone,two,three', 4) == '    one,two,three'
  • +
@@ -612,6 +632,11 @@ +

Returns:

+
    + + start index, or nil if not found +
@@ -647,6 +672,11 @@ +

Returns:

+
    + + start index, or nil if not found +
@@ -658,7 +688,7 @@
replace up to n instances of old by new in the string s. - if n is not present, replace all instances. + If n is not present, replace all instances.

Parameters:

@@ -694,7 +724,7 @@
- count (s, sub) + count (s, sub[, allow_overlap])
count all instances of substring in string. @@ -710,11 +740,21 @@ string substring +
  • allow_overlap + bool + allow matches to overlap + (optional) +
  • +

    Usage:

    +
      +
      assert(stringx.count('banana', 'ana') == 1)
      +assert(stringx.count('banana', 'ana', true) == 2)
      +
    @@ -749,6 +789,10 @@ +

    Usage:

    +
      +
      stringx.ljust('hello', 10, '*') == '*****hello'
      +
    @@ -779,6 +823,10 @@ +

    Usage:

    +
      +
      stringx.rjust('hello', 10, '*') == 'hello*****'
      +
    @@ -809,6 +857,10 @@ +

    Usage:

    +
      +
      stringx.center('hello', 10, '*') == '**hello***'
      +
    @@ -924,6 +976,10 @@ +

    See also:

    +

    Usage:

      @@ -963,6 +1019,11 @@ +

      Usage:

      +
        +
      • {stringx.partition('a,b,c', ','))} == {'a', ',', 'b,c'}
      • +
      • {stringx.partition('abc', 'x'))} == {'abc', '', ''}
      • +
      @@ -997,6 +1058,11 @@ +

      Usage:

      +
        +
      • {stringx.rpartition('a,b,c', ','))} == {'a,b', ',', 'c'}
      • +
      • {stringx.rpartition('abc', 'x'))} == {'', '', 'abc'}
      • +
      @@ -1057,6 +1123,14 @@ +

      Usage:

      +
        +
        local line_no = 1
        +for line in stringx.lines(some_text) do
        +  print(line_no, line)
        +  line_no = line_no + 1
        +end
        +
      @@ -1064,7 +1138,7 @@ title (s)
      - iniital word letters uppercase ('title case'). + inital word letters uppercase ('title case'). Here 'words' mean chunks of non-space characters. @@ -1084,6 +1158,10 @@ +

      Usage:

      +
        +
        stringx.title("hello world") == "Hello World")
        +
      @@ -1154,7 +1232,7 @@
      generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
      diff -Nru lua-penlight-1.7.0/docs/libraries/pl.tablex.html lua-penlight-1.9.2/docs/libraries/pl.tablex.html --- lua-penlight-1.7.0/docs/libraries/pl.tablex.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.tablex.html 2020-09-27 10:39:11.000000000 +0000 @@ -433,12 +433,16 @@ a table
    • ... - extra arguments + extra arguments passed to fun
    +

    See also:

    + @@ -804,7 +808,10 @@
    modifies a table to be read only. This only offers weak protection. Tables can still be modified with - table.insert and rawset. + table.insert and rawset.

    + +

    NOTE: for Lua 5.1 length, pairs and ipairs will not work, since the + equivalent metamethods are only available in Lua 5.2 and newer.

    Parameters:

    @@ -818,7 +825,7 @@

    Returns:

      - the table read only. + the table read only (a proxy).
    @@ -1090,13 +1097,26 @@
  • cmp func - A comparison function + A comparison function; bool = cmp(t1_value, t2_value)
  • +

    Returns:

    +
      + + true or false +
    + +

    Usage:

    +
      +
      assert(tablex.compare({ 1, 2, 3 }, { 1, 2, 3 }, "=="))
       
      +assert(tablex.compare(
      +   {1,2,3, hello = "world"},  -- fields are not compared!
      +   {1,2,3}, function(v1, v2) return v1 == v2 end)
      +
    @@ -1191,7 +1211,7 @@ A value
  • idx - index to start; -1 means last element,etc (default 1) + index to start; -1 means last element,etc (default #t)
  • @@ -1214,7 +1234,12 @@ find_if (t, cmp, arg)
    - return the index (or key) of a value in a table using a comparison function. + return the index (or key) of a value in a table using a comparison function.

    + +

    NOTE: the 2nd return value of this function, the value returned + by the comparison function, has a limitation that it cannot be false. + Because if it is, then it indicates the comparison failed, and the + function will continue the search. See examples.

    Parameters:

    @@ -1237,11 +1262,34 @@
  • index of value, or nil if not found
  • - value returned by comparison function
  • + value returned by comparison function (cannot be false!) +

    Usage:

    +
      +
      -- using an operator
      +local lst = { "Rudolph", true, false, 15 }
      +local idx, cmp_result = tablex.rfind(lst, "==", "Rudolph")
      +assert(idx == 1)
      +assert(cmp_result == true)
      +
      +local idx, cmp_result = tablex.rfind(lst, "==", false)
      +assert(idx == 3)
      +assert(cmp_result == true)       -- looking up 'false' works!
      +
      +-- using a function returning the value looked up
      +local cmp = function(v1, v2) return v1 == v2 and v2 end
      +local idx, cmp_result = tablex.rfind(lst, cmp, "Rudolph")
      +assert(idx == 1)
      +assert(cmp_result == "Rudolph")  -- the value is returned
      +
      +-- NOTE: this fails, since 'false' cannot be returned!
      +local idx, cmp_result = tablex.rfind(lst, cmp, false)
      +assert(idx == nil)               -- looking up 'false' failed!
      +assert(cmp_result == nil)
      +
    @@ -1382,9 +1430,37 @@ +

    Returns:

    +
      + + a List with the results of the method (1st result only) +
    +

    Usage:

    +
      +
      local Car = {}
      +Car.__index = Car
      +function Car.new(car)
      +  return setmetatable(car or {}, Car)
      +end
      +Car.speed = 0
      +function Car:faster(increase)
      +  self.speed = self.speed + increase
      +  return self.speed
      +end
      +
      +local ferrari = Car.new{ name = "Ferrari" }
      +local lamborghini = Car.new{ name = "Lamborghini", speed = 50 }
      +local cars = { ferrari, lamborghini }
      +
      +assert(ferrari.speed == 0)
      +assert(lamborghini.speed == 50)
      +tablex.map_named_method("faster", cars, 10)
      +assert(ferrari.speed == 10)
      +assert(lamborghini.speed == 60)
      +
    @@ -1587,15 +1663,19 @@
  • fun func - a function with at least one argument + a function on the elements; function(value, key, ...)
  • ... - extra arguments + extra arguments passed to fun
  • +

    See also:

    + @@ -1893,7 +1973,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.template.html lua-penlight-1.9.2/docs/libraries/pl.template.html --- lua-penlight-1.7.0/docs/libraries/pl.template.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.template.html 2020-09-27 10:39:11.000000000 +0000 @@ -329,7 +329,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.test.html lua-penlight-1.9.2/docs/libraries/pl.test.html --- lua-penlight-1.7.0/docs/libraries/pl.test.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.test.html 2020-09-27 10:39:11.000000000 +0000 @@ -438,7 +438,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.text.html lua-penlight-1.9.2/docs/libraries/pl.text.html --- lua-penlight-1.7.0/docs/libraries/pl.text.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.text.html 2020-09-27 10:39:11.000000000 +0000 @@ -374,7 +374,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.types.html lua-penlight-1.9.2/docs/libraries/pl.types.html --- lua-penlight-1.7.0/docs/libraries/pl.types.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.types.html 2020-09-27 10:39:11.000000000 +0000 @@ -468,7 +468,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.url.html lua-penlight-1.9.2/docs/libraries/pl.url.html --- lua-penlight-1.7.0/docs/libraries/pl.url.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.url.html 2020-09-27 10:39:11.000000000 +0000 @@ -205,7 +205,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.utils.html lua-penlight-1.9.2/docs/libraries/pl.utils.html --- lua-penlight-1.7.0/docs/libraries/pl.utils.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.utils.html 2020-09-27 10:39:11.000000000 +0000 @@ -1260,7 +1260,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/libraries/pl.xml.html lua-penlight-1.9.2/docs/libraries/pl.xml.html --- lua-penlight-1.7.0/docs/libraries/pl.xml.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/libraries/pl.xml.html 2020-09-27 10:39:11.000000000 +0000 @@ -828,7 +828,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/01-introduction.md.html lua-penlight-1.9.2/docs/manual/01-introduction.md.html --- lua-penlight-1.7.0/docs/manual/01-introduction.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/01-introduction.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -836,7 +836,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/02-arrays.md.html lua-penlight-1.9.2/docs/manual/02-arrays.md.html --- lua-penlight-1.7.0/docs/manual/02-arrays.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/02-arrays.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -907,7 +907,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/03-strings.md.html lua-penlight-1.9.2/docs/manual/03-strings.md.html --- lua-penlight-1.7.0/docs/manual/03-strings.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/03-strings.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -390,7 +390,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/04-paths.md.html lua-penlight-1.9.2/docs/manual/04-paths.md.html --- lua-penlight-1.7.0/docs/manual/04-paths.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/04-paths.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -322,7 +322,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/05-dates.md.html lua-penlight-1.9.2/docs/manual/05-dates.md.html --- lua-penlight-1.7.0/docs/manual/05-dates.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/05-dates.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -260,7 +260,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/06-data.md.html lua-penlight-1.9.2/docs/manual/06-data.md.html --- lua-penlight-1.7.0/docs/manual/06-data.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/06-data.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -934,15 +934,11 @@
     points
    -
    - -

    (818344.1,-20389.7,-0.1),(818337.9,-20389.3,-0.1),(818332.5,-20387.8,-0.1)

    - -
    -,(818327.4,-20388,-0.1),(818322,-20387.7,-0.1),(818316.3,-20388.6,-0.1)
    -,(818309.7,-20389.4,-0.1),(818303.5,-20390.6,-0.1),(818295.8,-20388.3,-0.1)
    -,(818290.5,-20386.9,-0.1),(818285.2,-20386.1,-0.1),(818279.3,-20383.6,-0.1)
    -,(818274,-20381.2,-0.1),(818274,-20380.7,-0.1);
    +    (818344.1,-20389.7,-0.1),(818337.9,-20389.3,-0.1),(818332.5,-20387.8,-0.1)
    +    ,(818327.4,-20388,-0.1),(818322,-20387.7,-0.1),(818316.3,-20388.6,-0.1)
    +    ,(818309.7,-20389.4,-0.1),(818303.5,-20390.6,-0.1),(818295.8,-20388.3,-0.1)
    +    ,(818290.5,-20386.9,-0.1),(818285.2,-20386.1,-0.1),(818279.3,-20383.6,-0.1)
    +    ,(818274,-20381.2,-0.1),(818274,-20380.7,-0.1);
     

    Here is code to extract the points using pl.lexer:

    @@ -1630,7 +1626,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/07-functional.md.html lua-penlight-1.9.2/docs/manual/07-functional.md.html --- lua-penlight-1.7.0/docs/manual/07-functional.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/07-functional.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -827,7 +827,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/08-additional.md.html lua-penlight-1.9.2/docs/manual/08-additional.md.html --- lua-penlight-1.7.0/docs/manual/08-additional.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/08-additional.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -808,7 +808,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs/manual/09-discussion.md.html lua-penlight-1.9.2/docs/manual/09-discussion.md.html --- lua-penlight-1.7.0/docs/manual/09-discussion.md.html 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs/manual/09-discussion.md.html 2020-09-27 10:39:11.000000000 +0000 @@ -226,7 +226,7 @@
    generated by LDoc 1.4.6 -Last updated 2019-10-14 15:29:36 +Last updated 2020-09-27 12:38:25
    diff -Nru lua-penlight-1.7.0/docs_topics/06-data.md lua-penlight-1.9.2/docs_topics/06-data.md --- lua-penlight-1.7.0/docs_topics/06-data.md 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/docs_topics/06-data.md 2020-09-27 10:39:11.000000000 +0000 @@ -665,7 +665,7 @@ format which it was my task to maintain: points -(818344.1,-20389.7,-0.1),(818337.9,-20389.3,-0.1),(818332.5,-20387.8,-0.1) + (818344.1,-20389.7,-0.1),(818337.9,-20389.3,-0.1),(818332.5,-20387.8,-0.1) ,(818327.4,-20388,-0.1),(818322,-20387.7,-0.1),(818316.3,-20388.6,-0.1) ,(818309.7,-20389.4,-0.1),(818303.5,-20390.6,-0.1),(818295.8,-20388.3,-0.1) ,(818290.5,-20386.9,-0.1),(818285.2,-20386.1,-0.1),(818279.3,-20383.6,-0.1) diff -Nru lua-penlight-1.7.0/.editorconfig lua-penlight-1.9.2/.editorconfig --- lua-penlight-1.7.0/.editorconfig 1970-01-01 00:00:00.000000000 +0000 +++ lua-penlight-1.9.2/.editorconfig 2020-09-27 10:39:11.000000000 +0000 @@ -0,0 +1,22 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[*.lua] +indent_style = space +indent_size = 2 + +[kong/templates/nginx*] +indent_style = space +indent_size = 4 + +[*.template] +indent_style = space +indent_size = 4 + +[Makefile] +indent_style = tab diff -Nru lua-penlight-1.7.0/.gitignore lua-penlight-1.9.2/.gitignore --- lua-penlight-1.7.0/.gitignore 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/.gitignore 2020-09-27 10:39:11.000000000 +0000 @@ -1,2 +1,2 @@ luacov.stats.out - +*.rock diff -Nru lua-penlight-1.7.0/lua/pl/app.lua lua-penlight-1.9.2/lua/pl/app.lua --- lua-penlight-1.7.0/lua/pl/app.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/app.lua 2020-09-27 10:39:11.000000000 +0000 @@ -20,13 +20,15 @@ return utils.raise("No script name found") end ---- add the current script's path to the Lua module path. +--- prefixes the current script's path to the Lua module path. -- Applies to both the source and the binary module paths. It makes it easy for -- the main file of a multi-file program to access its modules in the same directory. -- `base` allows these modules to be put in a specified subdirectory, to allow for -- cleaner deployment and resolve potential conflicts between a script name and its -- library directory. --- @string base optional base directory. +-- +-- Note: the path is prefixed, so it is searched first when requiring modules. +-- @string base optional base directory (absolute, or relative path). -- @treturn string the current script's path with a trailing slash function app.require_here (base) local p = path.dirname(app.script_name()) @@ -101,7 +103,7 @@ -- -- execute: lua -lluacov -e 'print(_VERSION)' myscript.lua -- -- -- myscript.lua --- print(require("pl.app").lua())) --> lua -lluacov -e 'print(_VERSION)' +-- print(require("pl.app").lua()) --> "lua -lluacov -e 'print(_VERSION)'", "lua" function app.lua() local args = _G.arg if not args then diff -Nru lua-penlight-1.7.0/lua/pl/class.lua lua-penlight-1.9.2/lua/pl/class.lua --- lua-penlight-1.7.0/lua/pl/class.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/class.lua 2020-09-27 10:39:11.000000000 +0000 @@ -17,23 +17,29 @@ -- this trickery is necessary to prevent the inheritance of 'super' and -- the resulting recursive call problems. local function call_ctor (c,obj,...) - -- nice alias for the base class ctor - local base = rawget(c,'_base') - if base then - local parent_ctor = rawget(base,'_init') - while not parent_ctor do - base = rawget(base,'_base') - if not base then break end - parent_ctor = rawget(base,'_init') + local init = rawget(c,'_init') + local parent_with_init = rawget(c,'_parent_with_init') + + if parent_with_init then + if not init then -- inheriting an init + init = rawget(parent_with_init, '_init') + parent_with_init = rawget(parent_with_init, '_parent_with_init') end - if parent_ctor then + if parent_with_init then -- super() points to one above whereever _init came from rawset(obj,'super',function(obj,...) - call_ctor(base,obj,...) + call_ctor(parent_with_init,obj,...) end) end + else + -- Without this, calling super() where none exists will sometimes loop and stack overflow + rawset(obj,'super',nil) end - local res = c._init(obj,...) - rawset(obj,'super',nil) + + local res = init(obj,...) + if parent_with_init then -- If this execution of call_ctor set a super, unset it + rawset(obj,'super',nil) + end + return res end @@ -146,6 +152,7 @@ c.__index = c setmetatable(c,mt) if not plain then + if base and rawget(base,'_init') then c._parent_with_init = base end -- For super and inherited init c._init = nil end @@ -160,15 +167,12 @@ if not obj then obj = {} end setmetatable(obj,c) - if rawget(c,'_init') then -- explicit constructor + if rawget(c,'_init') or rawget(c,'_parent_with_init') then -- constructor exists local res = call_ctor(c,obj,...) if res then -- _if_ a ctor returns a value, it becomes the object... obj = res setmetatable(obj,c) end - elseif base and rawget(base,'_init') then -- default constructor - -- make sure that any stuff from the base class is initialized! - call_ctor(base,obj,...) end if base and rawget(base,'_post_init') then diff -Nru lua-penlight-1.7.0/lua/pl/compat.lua lua-penlight-1.9.2/lua/pl/compat.lua --- lua-penlight-1.7.0/lua/pl/compat.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/compat.lua 2020-09-27 10:39:11.000000000 +0000 @@ -38,13 +38,17 @@ -- -- NOTE: Windows systems can use signed 32bit integer exitcodes. Posix systems -- only use exitcodes 0-255, anything else is undefined. +-- +-- NOTE2: In Lua 5.2 and 5.3 a Windows exitcode of -1 would not properly be +-- returned, this function will return it properly for all versions. -- @param cmd a shell command -- @return true if successful -- @return actual return code function compat.execute(cmd) local res1,res2,res3 = os.execute(cmd) if res2 == "No error" and res3 == 0 and compat.is_windows then - -- os.execute bug in Lua 5.2+ not reporting -1 properly on Windows + -- os.execute bug in Lua 5.2/5.3 not reporting -1 properly on Windows + -- this was fixed in 5.4 res3 = -1 end if compat.lua51 and not compat.jit52 then @@ -141,6 +145,7 @@ end end + --- Global exported functions (for Lua 5.1 & LuaJIT) -- @section lua52 @@ -168,20 +173,48 @@ table.unpack = unpack -- luacheck: ignore end ---- return the full path where a Lua module name would be matched. --- @param mod module name, possibly dotted --- @param path a path in the same form as package.path or package.cpath +--- return the full path where a file name would be matched. +-- This function was introduced in Lua 5.2, so this compatibility version +-- will be injected in Lua 5.1 engines. +-- @string name file name, possibly dotted +-- @string path a path-template in the same form as package.path or package.cpath +-- @string[opt] sep template separate character to be replaced by path separator. Default: "." +-- @string[opt] rep the path separator to use, defaults to system separator. Default; "/" on Unixes, "\" on Windows. -- @see path.package_path -- @function package.searchpath +-- @return on success: path of the file +-- @return on failure: nil, error string listing paths tried if not package.searchpath then - local sep = package.config:sub(1,1) - function package.searchpath (mod,path) -- luacheck: ignore - mod = mod:gsub('%.',sep) + function package.searchpath (name,path,sep,rep) -- luacheck: ignore + if type(name) ~= "string" then + error(("bad argument #1 to 'searchpath' (string expected, got %s)"):format(type(path)), 2) + end + if type(path) ~= "string" then + error(("bad argument #2 to 'searchpath' (string expected, got %s)"):format(type(path)), 2) + end + if sep ~= nil and type(sep) ~= "string" then + error(("bad argument #3 to 'searchpath' (string expected, got %s)"):format(type(path)), 2) + end + if rep ~= nil and type(rep) ~= "string" then + error(("bad argument #4 to 'searchpath' (string expected, got %s)"):format(type(path)), 2) + end + sep = sep or "." + rep = rep or compat.dir_separator + do + local s, e = name:find(sep, nil, true) + while s do + name = name:sub(1, s-1) .. rep .. name:sub(e+1, -1) + s, e = name:find(sep, s + #rep + 1, true) + end + end + local tried = {} for m in path:gmatch('[^;]+') do - local nm = m:gsub('?',mod) + local nm = m:gsub('?', name) + tried[#tried+1] = nm local f = io.open(nm,'r') if f then f:close(); return nm end end + return nil, "\tno file '" .. table.concat(tried, "'\n\tno file '") .. "'" end end diff -Nru lua-penlight-1.7.0/lua/pl/config.lua lua-penlight-1.9.2/lua/pl/config.lua --- lua-penlight-1.7.0/lua/pl/config.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/config.lua 2020-09-27 10:39:11.000000000 +0000 @@ -93,7 +93,7 @@ -- @tab[opt] cnfg a configuration table that may contain these fields: -- -- * `smart` try to deduce what kind of config file we have (default false) --- * `variablilize` make names into valid Lua identifiers (default true) +-- * `variabilize` make names into valid Lua identifiers (default true) -- * `convert_numbers` try to convert values into numbers (default true) -- * `trim_space` ensure that there is no starting or trailing whitespace with values (default true) -- * `trim_quotes` remove quotes from strings (default false) @@ -136,7 +136,7 @@ local initial_digits = '^[%d%+%-]' local t = {} local top_t = t - local variablilize = check_cnfg ('variabilize',true) + local variabilize = check_cnfg ('variabilize',true) local list_delim = check_cnfg('list_delim',',') local convert_numbers = check_cnfg('convert_numbers',true) local convert_boolean = check_cnfg('convert_boolean',false) @@ -148,7 +148,7 @@ if list_delim == ' ' then list_delim = '%s+' end local function process_name(key) - if variablilize then + if variabilize then key = key:gsub('[^%w]','_') end return key diff -Nru lua-penlight-1.7.0/lua/pl/dir.lua lua-penlight-1.9.2/lua/pl/dir.lua --- lua-penlight-1.7.0/lua/pl/dir.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/dir.lua 2020-09-27 10:39:11.000000000 +0000 @@ -15,10 +15,11 @@ local os,pcall,ipairs,pairs,require,setmetatable = os,pcall,ipairs,pairs,require,setmetatable local remove = os.remove local append = table.insert -local wrap = coroutine.wrap -local yield = coroutine.yield local assert_arg,assert_string,raise = utils.assert_arg,utils.assert_string,utils.raise +local exists, isdir = path.exists, path.isdir +local sep = path.sep + local dir = {} local function makelist(l) @@ -65,13 +66,13 @@ return makelist(res) end -local function _listfiles(dir,filemode,match) +local function _listfiles(dirname,filemode,match) local res = {} local check = utils.choose(filemode,path.isfile,path.isdir) - if not dir then dir = '.' end - for f in ldir(dir) do + if not dirname then dirname = '.' end + for f in ldir(dirname) do if f ~= '.' and f ~= '..' then - local p = path.join(dir,f) + local p = path.join(dirname,f) if check(p) and (not match or match(f)) then append(res,p) end @@ -81,12 +82,12 @@ end --- return a list of all files in a directory which match a shell pattern. --- @string dir A directory. If not given, all files in current directory are returned. +-- @string dirname A directory. If not given, all files in current directory are returned. -- @string mask A shell pattern. If not given, all files are returned. -- @treturn {string} list of files --- @raise dir and mask must be strings -function dir.getfiles(dir,mask) - assert_dir(1,dir) +-- @raise dirname and mask must be strings +function dir.getfiles(dirname,mask) + assert_dir(1,dirname) if mask then assert_string(2,mask) end local match if mask then @@ -95,16 +96,16 @@ return path.normcase(f):find(mask) end end - return _listfiles(dir,true,match) + return _listfiles(dirname,true,match) end --- return a list of all subdirectories of the directory. --- @string dir A directory +-- @string dirname A directory -- @treturn {string} a list of directories -- @raise dir must be a a valid directory -function dir.getdirectories(dir) - assert_dir(1,dir) - return _listfiles(dir,false) +function dir.getdirectories(dirname) + assert_dir(1,dirname) + return _listfiles(dirname,false) end local alien,ffi,ffi_checked,CopyFile,MoveFile,GetLastError,win32_errors,cmd_tmpfile @@ -252,12 +253,12 @@ return file_op(false,src,dest,0) end -local function _dirfiles(dir,attrib) +local function _dirfiles(dirname,attrib) local dirs = {} local files = {} - for f in ldir(dir) do + for f in ldir(dirname) do if f ~= '.' and f ~= '..' then - local p = path.join(dir,f) + local p = path.join(dirname,f) local mode = attrib(p,'mode') if mode=='directory' then append(dirs,f) @@ -270,15 +271,6 @@ end -local function _walker(root,bottom_up,attrib) - local dirs,files = _dirfiles(root,attrib) - if not bottom_up then yield(root,dirs,files) end - for i,d in ipairs(dirs) do - _walker(root..path.sep..d,bottom_up,attrib) - end - if bottom_up then yield(root,dirs,files) end -end - --- return an iterator which walks through a directory tree starting at root. -- The iterator returns (root,dirs,files) -- Note that dirs and files are lists of names (i.e. you must say path.join(root,d) @@ -300,7 +292,28 @@ else attrib = path.link_attrib end - return wrap(function () _walker(root,bottom_up,attrib) end) + + local to_scan = { root } + local to_return = {} + local iter = function() + while #to_scan > 0 do + local current_root = table.remove(to_scan) + local dirs,files = _dirfiles(current_root, attrib) + for _, d in ipairs(dirs) do + table.insert(to_scan, current_root..path.sep..d) + end + if not bottom_up then + return current_root, dirs, files + else + table.insert(to_return, { current_root, dirs, files }) + end + end + if #to_return > 0 then + return utils.unpack(table.remove(to_return)) + end + end + + return iter end --- remove a whole directory tree. @@ -415,36 +428,54 @@ return true,faildirs,failfiles end + +-- each entry of the stack is an array with three items: +-- 1. the name of the directory +-- 2. the lfs iterator function +-- 3. the lfs iterator userdata +local function treeiter(iterstack) + local diriter = iterstack[#iterstack] + if not diriter then + return -- done + end + + local dirname = diriter[1] + local entry = diriter[2](diriter[3]) + if not entry then + table.remove(iterstack) + return treeiter(iterstack) -- tail-call to try next + end + + if entry ~= "." and entry ~= ".." then + entry = dirname .. sep .. entry + if exists(entry) then -- Just in case a symlink is broken. + local is_dir = isdir(entry) + if is_dir then + table.insert(iterstack, { entry, ldir(entry) }) + end + return entry, is_dir + end + end + + return treeiter(iterstack) -- tail-call to try next +end + + --- return an iterator over all entries in a directory tree -- @string d a directory -- @return an iterator giving pathname and mode (true for dir, false otherwise) -- @raise d must be a non-empty string function dir.dirtree( d ) assert( d and d ~= "", "directory parameter is missing or empty" ) - local exists, isdir = path.exists, path.isdir - local sep = path.sep local last = sub ( d, -1 ) if last == sep or last == '/' then d = sub( d, 1, -2 ) end - local function yieldtree( dir ) - for entry in ldir( dir ) do - if entry ~= "." and entry ~= ".." then - entry = dir .. sep .. entry - if exists(entry) then -- Just in case a symlink is broken. - local is_dir = isdir(entry) - yield( entry, is_dir ) - if is_dir then - yieldtree( entry ) - end - end - end - end - end + local iterstack = { {d, ldir(d)} } - return wrap( function() yieldtree( d ) end ) + return treeiter, iterstack end diff -Nru lua-penlight-1.7.0/lua/pl/lexer.lua lua-penlight-1.9.2/lua/pl/lexer.lua --- lua-penlight-1.7.0/lua/pl/lexer.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/lexer.lua 2020-09-27 10:39:11.000000000 +0000 @@ -20,11 +20,11 @@ -- See the Guide for further @{06-data.md.Lexical_Scanning|discussion} -- @module pl.lexer -local yield,wrap = coroutine.yield,coroutine.wrap local strfind = string.find local strsub = string.sub local append = table.insert + local function assert_arg(idx,val,tp) if type(val) ~= tp then error("argument "..idx.." must be "..tp, 2) @@ -33,11 +33,15 @@ local lexer = {} -local NUMBER1 = '^[%+%-]?%d+%.?%d*[eE][%+%-]?%d+' -local NUMBER2 = '^[%+%-]?%d+%.?%d*' -local NUMBER3 = '^0x[%da-fA-F]+' -local NUMBER4 = '^%d+%.?%d*[eE][%+%-]?%d+' -local NUMBER5 = '^%d+%.?%d*' +local NUMBER1 = '^[%+%-]?%d+%.?%d*[eE][%+%-]?%d+' +local NUMBER1a = '^[%+%-]?%d*%.%d+[eE][%+%-]?%d+' +local NUMBER2 = '^[%+%-]?%d+%.?%d*' +local NUMBER2a = '^[%+%-]?%d*%.%d+' +local NUMBER3 = '^0x[%da-fA-F]+' +local NUMBER4 = '^%d+%.?%d*[eE][%+%-]?%d+' +local NUMBER4a = '^%d*%.%d+[eE][%+%-]?%d+' +local NUMBER5 = '^%d+%.?%d*' +local NUMBER5a = '^%d*%.%d+' local IDEN = '^[%a_][%w_]*' local WSPACE = '^%s+' local STRING1 = "^(['\"])%1" -- empty string @@ -51,14 +55,14 @@ local plain_matches,lua_matches,cpp_matches,lua_keyword,cpp_keyword local function tdump(tok) - return yield(tok,tok) + return tok,tok end local function ndump(tok,options) if options and options.number then tok = tonumber(tok) end - return yield("number",tok) + return "number",tok end -- regular strings, single or double quotes; usually we want them @@ -67,7 +71,7 @@ if options and options.string then tok = tok:sub(2,-2) end - return yield("string",tok) + return "string",tok end -- long Lua strings need extra work to get rid of the quotes @@ -82,45 +86,45 @@ tok = tok:sub(2) end end - return yield("string",tok) + return "string",tok end local function chdump(tok,options) if options and options.string then tok = tok:sub(2,-2) end - return yield("char",tok) + return "char",tok end local function cdump(tok) - return yield('comment',tok) + return "comment",tok end local function wsdump (tok) - return yield("space",tok) + return "space",tok end local function pdump (tok) - return yield('prepro',tok) + return "prepro",tok end local function plain_vdump(tok) - return yield("iden",tok) + return "iden",tok end local function lua_vdump(tok) if lua_keyword[tok] then - return yield("keyword",tok) + return "keyword",tok else - return yield("iden",tok) + return "iden",tok end end local function cpp_vdump(tok) if cpp_keyword[tok] then - return yield("keyword",tok) + return "keyword",tok else - return yield("iden",tok) + return "iden",tok end end @@ -149,7 +153,9 @@ {NUMBER3,ndump}, {IDEN,plain_vdump}, {NUMBER1,ndump}, + {NUMBER1a,ndump}, {NUMBER2,ndump}, + {NUMBER2a,ndump}, {STRING1,sdump}, {STRING2,sdump}, {STRING3,sdump}, @@ -158,45 +164,60 @@ end matches = plain_matches end - local function lex(first_arg) - local line_nr = 0 - local next_line = file and file:read() - local sz = file and 0 or #s - local idx = 1 - - -- res is the value used to resume the coroutine. - local function handle_requests(res) - while res do - local tp = type(res) - -- insert a token list - if tp == 'table' then - res = yield('','') - for _,t in ipairs(res) do - res = yield(t[1],t[2]) - end - elseif tp == 'string' then -- or search up to some special pattern - local i1,i2 = strfind(s,res,idx) - if i1 then - local tok = strsub(s,i1,i2) - idx = i2 + 1 - res = yield('',tok) - else - res = yield('','') - idx = sz + 1 - end - else - res = yield(line_nr,idx) - end + + local line_nr = 0 + local next_line = file and file:read() + local sz = file and 0 or #s + local idx = 1 + + local tlist_i + local tlist + + local first_hit = true + + local function iter(res) + local tp = type(res) + + if tlist then -- returning the inserted token list + local cur = tlist[tlist_i] + if cur then + tlist_i = tlist_i + 1 + return cur[1], cur[2] + else + tlist = nil end end - handle_requests(first_arg) - if not file then line_nr = 1 end + if tp == 'string' then -- search up to some special pattern + local i1,i2 = strfind(s,res,idx) + if i1 then + local tok = strsub(s,i1,i2) + idx = i2 + 1 + return '', tok + else + idx = sz + 1 + return '', '' + end + + elseif tp == 'table' then -- insert a token list + tlist_i = 1 + tlist = res + return '', '' + + elseif tp ~= 'nil' then -- return position + return line_nr, idx + + else -- look for next token + if first_hit then + if not file then line_nr = 1 end + first_hit = false + end - while true do if idx > sz then if file then - if not next_line then return end + if not next_line then + return -- past the end of file, done + end s = next_line line_nr = line_nr + 1 next_line = file:read() @@ -205,9 +226,7 @@ end idx, sz = 1, #s else - while true do - handle_requests(yield()) - end + return -- past the end of input, done end end @@ -219,23 +238,27 @@ if i1 then local tok = strsub(s,i1,i2) idx = i2 + 1 - local res + local ret1, ret2 if not (filter and filter[fun]) then lexer.finished = idx > sz - res = fun(tok, options, findres) + ret1, ret2 = fun(tok, options, findres) end if not file and tok:find("\n") then -- Update line number. local _, newlines = tok:gsub("\n", {}) line_nr = line_nr + newlines end - handle_requests(res) - break + if ret1 then + return ret1, ret2 -- found a match + else + return iter() -- tail-call to try again + end end end end end - return wrap(lex) + + return iter end local function isstring (s) @@ -321,7 +344,9 @@ {NUMBER3,ndump}, {IDEN,lua_vdump}, {NUMBER4,ndump}, + {NUMBER4a,ndump}, {NUMBER5,ndump}, + {NUMBER5a,ndump}, {STRING1,sdump}, {STRING2,sdump}, {STRING3,sdump}, @@ -371,7 +396,9 @@ {NUMBER3,ndump}, {IDEN,cpp_vdump}, {NUMBER4,ndump}, + {NUMBER4a,ndump}, {NUMBER5,ndump}, + {NUMBER5a,ndump}, {CHAR1,chdump}, {CHAR2,chdump}, {CHAR3,chdump}, diff -Nru lua-penlight-1.7.0/lua/pl/path.lua lua-penlight-1.9.2/lua/pl/path.lua --- lua-penlight-1.7.0/lua/pl/path.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/path.lua 2020-09-27 10:39:11.000000000 +0000 @@ -2,6 +2,12 @@ -- -- This is modelled after Python's os.path library (10.1); see @{04-paths.md|the Guide}. -- +-- NOTE: the functions assume the paths being dealt with to originate +-- from the OS the application is running on. Windows drive letters are not +-- to be used when running on a Unix system for example. The one exception +-- is Windows paths to allow both forward and backward slashes (since Lua +-- also accepts those) +-- -- Dependencies: `pl.utils`, `lfs` -- @module pl.path @@ -10,45 +16,59 @@ local sub = string.sub local getenv = os.getenv local tmpnam = os.tmpname -local attributes, currentdir, link_attrib local package = package local append, concat, remove = table.insert, table.concat, table.remove local utils = require 'pl.utils' local assert_string,raise = utils.assert_string,utils.raise -local attrib -local path = {} - local res,lfs = _G.pcall(_G.require,'lfs') -if res then - attributes = lfs.attributes - currentdir = lfs.currentdir - link_attrib = lfs.symlinkattributes -else +if not res then error("pl.path requires LuaFileSystem") end -attrib = attributes -path.attrib = attrib -path.link_attrib = link_attrib +local attrib = lfs.attributes +local currentdir = lfs.currentdir +local link_attrib = lfs.symlinkattributes + +local path = {} --- Lua iterator over the entries of a given directory. --- Behaves like `lfs.dir` +-- Implicit link to [`luafilesystem.dir`](https://keplerproject.github.io/luafilesystem/manual.html#reference) +-- @function dir path.dir = lfs.dir --- Creates a directory. +-- Implicit link to [`luafilesystem.mkdir`](https://keplerproject.github.io/luafilesystem/manual.html#reference) +-- @function mkdir path.mkdir = lfs.mkdir --- Removes a directory. +-- Implicit link to [`luafilesystem.rmdir`](https://keplerproject.github.io/luafilesystem/manual.html#reference) +-- @function rmdir path.rmdir = lfs.rmdir ----- Get the working directory. +--- Gets attributes. +-- Implicit link to [`luafilesystem.attributes`](https://keplerproject.github.io/luafilesystem/manual.html#reference) +-- @function attrib +path.attrib = attrib + +--- Get the working directory. +-- Implicit link to [`luafilesystem.currentdir`](https://keplerproject.github.io/luafilesystem/manual.html#reference) +-- @function currentdir path.currentdir = currentdir +--- Gets symlink attributes. +-- Implicit link to [`luafilesystem.symlinkattributes`](https://keplerproject.github.io/luafilesystem/manual.html#reference) +-- @function link_attrib +path.link_attrib = link_attrib + --- Changes the working directory. +-- On Windows, if a drive is specified, it also changes the current drive. If +-- only specifying the drive, it will only switch drive, but not modify the path. +-- Implicit link to [`luafilesystem.chdir`](https://keplerproject.github.io/luafilesystem/manual.html#reference) +-- @function chdir path.chdir = lfs.chdir - --- is this a directory? -- @string P A file path function path.isdir(P) @@ -59,7 +79,7 @@ return attrib(P,'mode') == 'directory' end ---- is this a file?. +--- is this a file? -- @string P A file path function path.isfile(P) assert_string(1,P) @@ -84,9 +104,9 @@ return attrib(P,'size') end ---- does a path exist?. +--- does a path exist? -- @string P A file path --- @return the file path if it exists, nil otherwise +-- @return the file path if it exists (either as file, directory, socket, etc), nil otherwise function path.exists(P) assert_string(1,P) return attrib(P,'mode') ~= nil and P @@ -99,14 +119,14 @@ return attrib(P,'access') end ---- Return the time of last modification +--- Return the time of last modification as the number of seconds since the epoch. -- @string P A file path function path.getmtime(P) assert_string(1,P) return attrib(P,'modification') end ----Return the system's ctime. +---Return the system's ctime as the number of seconds since the epoch. -- @string P A file path function path.getctime(P) assert_string(1,P) @@ -120,16 +140,19 @@ path.is_windows = utils.is_windows -local other_sep --- !constant sep is the directory separator for this platform. +local sep, other_sep, seps +-- constant sep is the directory separator for this platform. +-- constant dirsep is the separator in the PATH environment variable if path.is_windows then path.sep = '\\'; other_sep = '/' path.dirsep = ';' + seps = { ['/'] = true, ['\\'] = true } else path.sep = '/' path.dirsep = ':' + seps = { ['/'] = true } end -local sep = path.sep +sep = path.sep --- are we running Windows? -- @class field @@ -146,6 +169,20 @@ --- given a path, return the directory part and a file part. -- if there's no directory part, the first value will be empty -- @string P A file path +-- @return directory part +-- @return file part +-- @usage +-- local dir, file = path.splitpath("some/dir/myfile.txt") +-- assert(dir == "some/dir") +-- assert(file == "myfile.txt") +-- +-- local dir, file = path.splitpath("some/dir/") +-- assert(dir == "some/dir") +-- assert(file == "") +-- +-- local dir, file = path.splitpath("some_dir") +-- assert(dir == "") +-- assert(file == "some_dir") function path.splitpath(P) assert_string(1,P) local i = #P @@ -182,14 +219,22 @@ --- given a path, return the root part and the extension part. -- if there's no extension part, the second value will be empty -- @string P A file path --- @treturn string root part --- @treturn string extension part (maybe empty) +-- @treturn string root part (everything upto the "."", maybe empty) +-- @treturn string extension part (including the ".", maybe empty) +-- @usage +-- local file_path, ext = path.splitext("/bonzo/dog_stuff/cat.txt") +-- assert(file_path == "/bonzo/dog_stuff/cat") +-- assert(ext == ".txt") +-- +-- local file_path, ext = path.splitext("") +-- assert(file_path == "") +-- assert(ext == "") function path.splitext(P) assert_string(1,P) local i = #P local ch = at(P,i) while i > 0 and ch ~= '.' do - if ch == sep or ch == other_sep then + if seps[ch] then return P,'' end i = i - 1 @@ -204,6 +249,11 @@ --- return the directory part of a path -- @string P A file path +-- @treturn string everything before the last dir-separator +-- @see splitpath +-- @usage +-- path.dirname("/some/path/file.txt") -- "/some/path" +-- path.dirname("file.txt") -- "" (empty string) function path.dirname(P) assert_string(1,P) local p1 = path.splitpath(P) @@ -212,6 +262,11 @@ --- return the file part of a path -- @string P A file path +-- @treturn string +-- @see splitpath +-- @usage +-- path.basename("/some/path/file.txt") -- "file.txt" +-- path.basename("/some/path/file/") -- "" (empty string) function path.basename(P) assert_string(1,P) local _,p2 = path.splitpath(P) @@ -220,21 +275,33 @@ --- get the extension part of a path. -- @string P A file path +-- @treturn string +-- @see splitext +-- @usage +-- path.extension("/some/path/file.txt") -- ".txt" +-- path.extension("/some/path/file_txt") -- "" (empty string) function path.extension(P) assert_string(1,P) local _,p2 = path.splitext(P) return p2 end ---- is this an absolute path?. +--- is this an absolute path? -- @string P A file path +-- @usage +-- path.isabs("hello/path") -- false +-- path.isabs("/hello/path") -- true +-- -- Windows; +-- path.isabs("hello\path") -- false +-- path.isabs("\hello\path") -- true +-- path.isabs("C:\hello\path") -- true +-- path.isabs("C:hello\path") -- false function path.isabs(P) assert_string(1,P) - if path.is_windows then - return at(P,1) == '/' or at(P,1)=='\\' or at(P,2)==':' - else - return at(P,1) == '/' + if path.is_windows and at(P,2) == ":" then + return seps[at(P,3)] ~= nil end + return seps[at(P,1)] ~= nil end --- return the path resulting from combining the individual paths. @@ -243,6 +310,11 @@ -- @string p1 A file path -- @string p2 A file path -- @string ... more file paths +-- @treturn string the combined path +-- @usage +-- path.join("/first","second","third") -- "/first/second/third" +-- path.join("first","second/third") -- "first/second/third" +-- path.join("/first","/second","third") -- "/second/third" function path.join(p1,p2,...) assert_string(1,p1) assert_string(2,p2) @@ -263,21 +335,28 @@ return p1..p2 end ---- normalize the case of a pathname. On Unix, this returns the path unchanged; --- for Windows, it converts the path to lowercase, and it also converts forward slashes --- to backward slashes. +--- normalize the case of a pathname. On Unix, this returns the path unchanged, +-- for Windows it converts; +-- +-- * the path to lowercase +-- * forward slashes to backward slashes -- @string P A file path +-- @usage path.normcase("/Some/Path/File.txt") +-- -- Windows: "\some\path\file.txt" +-- -- Others : "/Some/Path/File.txt" function path.normcase(P) assert_string(1,P) if path.is_windows then - return (P:lower():gsub('/','\\')) + return P:gsub('/','\\'):lower() else return P end end --- normalize a path name. --- `A//B`, `A/./B`, and `A/foo/../B` all become `A/B`. +-- `A//B`, `A/./B`, and `A/foo/../B` all become `A/B`. +-- +-- An empty path results in '.'. -- @string P a file path function path.normpath(P) assert_string(1,P) @@ -287,13 +366,13 @@ if P:match '^\\\\' then -- UNC anchor = '\\\\' P = P:sub(3) - elseif at(P, 1) == '/' or at(P, 1) == '\\' then + elseif seps[at(P, 1)] then anchor = '\\' P = P:sub(2) elseif at(P, 2) == ':' then anchor = P:sub(1, 2) P = P:sub(3) - if at(P, 1) == '/' or at(P, 1) == '\\' then + if seps[at(P, 1)] then anchor = anchor..'\\' P = P:sub(2) end @@ -384,7 +463,7 @@ ---Return a suitable full path to a new temporary file name. --- unlike os.tmpnam(), it always gives you a writeable path (uses TEMP environment variable on Windows) +-- unlike os.tmpname(), it always gives you a writeable path (uses TEMP environment variable on Windows) function path.tmpname () local res = tmpnam() -- On Windows if Lua is compiled using MSVC14 os.tmpname @@ -399,6 +478,7 @@ --- return the largest common prefix path of two paths. -- @string path1 a file path -- @string path2 a file path +-- @return the common prefix (Windows: separators will be normalized, casing will be original) function path.common_prefix (path1,path2) assert_string(1,path1) assert_string(2,path2) @@ -431,16 +511,15 @@ -- either be a Lua file or a shared library. -- @string mod name of the module -- @return on success: path of module, lua or binary --- @return on error: nil,error string +-- @return on error: nil, error string listing paths tried function path.package_path(mod) assert_string(1,mod) - local res - mod = mod:gsub('%.',sep) - res = package.searchpath(mod,package.path) + local res, err1, err2 + res, err1 = package.searchpath(mod,package.path) if res then return res,true end - res = package.searchpath(mod,package.cpath) + res, err2 = package.searchpath(mod,package.cpath) if res then return res,false end - return raise 'cannot find module on path' + return raise ('cannot find module on path\n' .. err1 .. "\n" .. err2) end diff -Nru lua-penlight-1.7.0/lua/pl/permute.lua lua-penlight-1.9.2/lua/pl/permute.lua --- lua-penlight-1.7.0/lua/pl/permute.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/permute.lua 2020-09-27 10:39:11.000000000 +0000 @@ -6,48 +6,65 @@ local utils = require 'pl.utils' local copy = tablex.deepcopy local append = table.insert -local coroutine = coroutine -local resume = coroutine.resume local assert_arg = utils.assert_arg local permute = {} --- PiL, 9.3 - -local permgen -permgen = function (a, n, fn) - if n == 0 then - fn(a) - else - for i=1,n do - -- put i-th element as the last one - a[n], a[i] = a[i], a[n] - - -- generate all permutations of the other elements - permgen(a, n - 1, fn) - - -- restore i-th element - a[n], a[i] = a[i], a[n] - - end - end -end --- an iterator over all permutations of the elements of a list. -- Please note that the same list is returned each time, so do not keep references! -- @param a list-like table -- @return an iterator which provides the next permutation as a list -function permute.iter (a) +function permute.iter(a) assert_arg(1,a,'table') - local n = #a - local co = coroutine.create(function () permgen(a, n, coroutine.yield) end) - return function () -- iterator - local _, res = resume(co) - return res + + local t = #a + local stack = { 1 } + local function iter() + local h = #stack + local n = t - h + 1 + + local i = stack[h] + if i > t then + return + end + + if n == 0 then + table.remove(stack) + h = h - 1 + + stack[h] = stack[h] + 1 + return a + + elseif i <= n then + + -- put i-th element as the last one + a[n], a[i] = a[i], a[n] + + -- generate all permutations of the other elements + table.insert(stack, 1) + + else + + table.remove(stack) + h = h - 1 + + n = n + 1 + i = stack[h] + + -- restore i-th element + a[n], a[i] = a[i], a[n] + + stack[h] = stack[h] + 1 + end + return iter() -- tail-call end + + return iter end + --- construct a table containing all the permutations of a list. -- @param a list-like table -- @return a table of tables @@ -55,8 +72,9 @@ function permute.table (a) assert_arg(1,a,'table') local res = {} - local n = #a - permgen(a,n,function(t) append(res,copy(t)) end) + for t in permute.iter(a) do + append(res,copy(t)) + end return res end diff -Nru lua-penlight-1.7.0/lua/pl/pretty.lua lua-penlight-1.9.2/lua/pl/pretty.lua --- lua-penlight-1.7.0/lua/pl/pretty.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/pretty.lua 2020-09-27 10:39:11.000000000 +0000 @@ -170,6 +170,12 @@ -- extra value. Normally puts out one item per line, using -- the provided indent; set the second parameter to an empty string -- if you want output on one line. +-- +-- *NOTE:* this is NOT a serialization function, not a full blown +-- debug function. Checkout out respectively the +-- [serpent](https://github.com/pkulchenko/serpent) +-- or [inspect](https://github.com/kikito/inspect.lua) +-- Lua modules for that if you need them. -- @tab tbl Table to serialize to a string. -- @string[opt] space The indent to use. -- Defaults to two spaces; pass an empty string for no indentation. @@ -254,7 +260,12 @@ ordered_keys[#ordered_keys + 1] = k end end - table.sort(ordered_keys) + table.sort(ordered_keys, function (a, b) + if type(a) == type(b) and type(a) == 'string' then + return a < b + end + return type(a) == 'boolean' or (type(b) ~= 'boolean' and type(a) == 'table') + end) local function write_entry (key, val) local tkey = type(key) local numkey = tkey == 'number' @@ -310,6 +321,49 @@ end end +--- Dump a series of arguments to stdout for debug purposes. +-- This function is attached to the module table `__call` method, to make it +-- extra easy to access. So the full: +-- +-- print(require("pl.pretty").write({...})) +-- +-- Can be shortened to: +-- +-- require"pl.pretty" (...) +-- +-- Any `nil` entries will be printed as `""` to make them explicit. +-- @param ... the parameters to dump to stdout. +-- @usage +-- -- example debug output +-- require"pl.pretty" ("hello", nil, "world", { bye = "world", true} ) +-- +-- -- output: +-- { +-- ["arg 1"] = "hello", +-- ["arg 2"] = "", +-- ["arg 3"] = "world", +-- ["arg 4"] = { +-- true, +-- bye = "world" +-- } +-- } +function pretty.debug(...) + local n = select("#", ...) + local t = { ... } + for i = 1, n do + local value = t[i] + if value == nil then + value = "" + end + t[i] = nil + t["arg " .. i] = value + end + + print(pretty.write(t)) + return true +end + + local memp,nump = {'B','KiB','MiB','GiB'},{'','K','M','B'} local function comma (val) @@ -353,4 +407,8 @@ end end -return pretty +return setmetatable(pretty, { + __call = function(self, ...) + return self.debug(...) + end +}) diff -Nru lua-penlight-1.7.0/lua/pl/strict.lua lua-penlight-1.9.2/lua/pl/strict.lua --- lua-penlight-1.7.0/lua/pl/strict.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/strict.lua 2020-09-27 10:39:11.000000000 +0000 @@ -1,7 +1,7 @@ --- Checks uses of undeclared global variables. -- All global variables must be 'declared' through a regular assignment -- (even assigning `nil` will do) in a main chunk before being used --- anywhere or assigned to inside a function. Existing metatables `__newindex` and `__index` +-- anywhere or assigned to inside a function. Existing metatables `__newindex` and `__index` -- metamethods are respected. -- -- You can set any table to have strict behaviour using `strict.module`. Creating a new @@ -23,10 +23,21 @@ end --- make an existing table strict. --- @string name name of table (optional) --- @tab[opt] mod table - if `nil` then we'll return a new table +-- @string[opt] name name of table +-- @tab[opt] mod the table to protect - if `nil` then we'll return a new table -- @tab[opt] predeclared - table of variables that are to be considered predeclared. -- @return the given table, or a new table +-- @usage +-- local M = { hello = "world" } +-- strict.module ("Awesome_Module", M, { +-- Lua = true, -- defines allowed keys +-- }) +-- +-- assert(M.hello == "world") +-- assert(M.Lua == nil) -- access allowed, but has no value yet +-- M.Lua = "Rocks" +-- assert(M.Lua == "Rocks") +-- M.not_allowed = "bad boy" -- throws an error function strict.module (name,mod,predeclared) local mt, old_newindex, old_index, old_index_type, global if predeclared then @@ -80,7 +91,7 @@ end local msg = "variable '"..n.."' is not declared" if name then - msg = msg .. " in '"..name.."'" + msg = msg .. " in '"..tostring(name).."'" end error(msg, 2) end @@ -92,7 +103,7 @@ --- make all tables in a table strict. -- So `strict.make_all_strict(_G)` prevents monkey-patching -- of any global table --- @tab T +-- @tab T the table containing the tables to protect. Table `T` itself will NOT be protected. function strict.make_all_strict (T) for k,v in pairs(T) do if type(v) == 'table' and v ~= T then @@ -102,7 +113,11 @@ end --- make a new module table which is closed to further changes. +-- @tab mod module table +-- @string name module name function strict.closed_module (mod,name) + -- No clue to what this is useful for? see tests + -- Deprecate this and remove??? local M = {} mod = mod or {} local mt = getmetatable(mod) @@ -117,8 +132,7 @@ end if not rawget(_G,'PENLIGHT_NO_GLOBAL_STRICT') then - strict.module(nil,_G,{_PROMPT=true,__global=true}) + strict.module(nil,_G,{_PROMPT=true,_PROMPT2=true,__global=true}) end return strict - diff -Nru lua-penlight-1.7.0/lua/pl/stringx.lua lua-penlight-1.9.2/lua/pl/stringx.lua --- lua-penlight-1.7.0/lua/pl/stringx.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/stringx.lua 2020-09-27 10:39:11.000000000 +0000 @@ -129,9 +129,10 @@ -- @section lists --- concatenate the strings using this string as a delimiter. +-- Note that the arguments are reversed from `string.concat`. -- @string s the string -- @param seq a table of strings or numbers --- @usage (' '):join {1,2,3} == '1 2 3' +-- @usage stringx.join(' ', {1,2,3}) == '1 2 3' function stringx.join(s,seq) assert_string(1,s) return concat(seq,s) @@ -144,6 +145,7 @@ -- Splitting an empty string results in an empty list. -- @string s the string. -- @bool[opt] keep_ends include line ends. +-- @return List of lines function stringx.splitlines(s, keep_ends) assert_string(1, s) local res = {} @@ -179,9 +181,10 @@ -- @string s the string -- @string[opt] re a delimiter (defaults to whitespace) -- @int[opt] n maximum number of results --- @usage #(('one two'):split()) == 2 --- @usage ('one,two,three'):split(',') == List{'one','two','three'} --- @usage ('one,two,three'):split(',',2) == List{'one','two,three'} +-- @return List +-- @usage #(stringx.split('one two')) == 2 +-- @usage stringx.split('one,two,three', ',') == List{'one','two','three'} +-- @usage stringx.split('one,two,three', ',', 2) == List{'one','two,three'} function stringx.split(s,re,n) assert_string(1,s) local plain = true @@ -199,10 +202,12 @@ end --- replace all tabs in s with tabsize spaces. If not specified, tabsize defaults to 8. --- with 0.9.5 this now correctly expands to the next tab stop (if you really --- want to just replace tabs, use :gsub('\t',' ') etc) +-- Tab stops will be honored. -- @string s the string -- @int tabsize[opt=8] number of spaces to expand each tab +-- @return expanded string +-- @usage stringx.expandtabs('\tone,two,three', 4) == ' one,two,three' +-- @usage stringx.expandtabs(' \tone,two,three', 4) == ' one,two,three' function stringx.expandtabs(s,tabsize) assert_string(1,s) tabsize = tabsize or 8 @@ -214,7 +219,7 @@ --- Finding and Replacing -- @section find -local function _find_all(s,sub,first,last) +local function _find_all(s,sub,first,last,allow_overlap) first = first or 1 last = last or #s if sub == '' then return last+1,last-first+1 end @@ -225,7 +230,11 @@ if last and i2 > last then break end res = i1 k = k + 1 - i1,i2 = find(s,sub,i2+1,true) + if allow_overlap then + i1,i2 = find(s,sub,i1+1,true) + else + i1,i2 = find(s,sub,i2+1,true) + end end return res,k end @@ -235,6 +244,7 @@ -- @string sub substring -- @int[opt] first first index -- @int[opt] last last index +-- @return start index, or nil if not found function stringx.lfind(s,sub,first,last) assert_string(1,s) assert_string(2,sub) @@ -252,14 +262,15 @@ -- @string sub substring -- @int[opt] first first index -- @int[opt] last last index +-- @return start index, or nil if not found function stringx.rfind(s,sub,first,last) assert_string(1,s) assert_string(2,sub) - return (_find_all(s,sub,first,last)) + return (_find_all(s,sub,first,last,true)) end --- replace up to n instances of old by new in the string s. --- if n is not present, replace all instances. +-- If n is not present, replace all instances. -- @string s the string -- @string old the target substring -- @string new the substitution @@ -275,9 +286,13 @@ --- count all instances of substring in string. -- @string s the string -- @string sub substring -function stringx.count(s,sub) +-- @bool[opt] allow_overlap allow matches to overlap +-- @usage +-- assert(stringx.count('banana', 'ana') == 1) +-- assert(stringx.count('banana', 'ana', true) == 2) +function stringx.count(s,sub,allow_overlap) assert_string(1,s) - local _,k = _find_all(s,sub,1) + local _,k = _find_all(s,sub,1,false,allow_overlap) return k end @@ -311,6 +326,7 @@ -- @string s the string -- @int w width of justification -- @string[opt=' '] ch padding character +-- @usage stringx.ljust('hello', 10, '*') == '*****hello' function stringx.ljust(s,w,ch) assert_string(1,s) assert_arg(2,w,'number') @@ -321,6 +337,7 @@ -- @string s the string -- @int w width of justification -- @string[opt=' '] ch padding character +-- @usage stringx.rjust('hello', 10, '*') == 'hello*****' function stringx.rjust(s,w,ch) assert_string(1,s) assert_arg(2,w,'number') @@ -331,6 +348,7 @@ -- @string s the string -- @int w width of justification -- @string[opt=' '] ch padding character +-- @usage stringx.center('hello', 10, '*') == '**hello***' function stringx.center(s,w,ch) assert_string(1,s) assert_arg(2,w,'number') @@ -404,12 +422,13 @@ -- @string[opt='%s'] re a Lua string pattern (defaults to whitespace) -- @return the parts of the string -- @usage a,b = line:splitv('=') +-- @see utils.splitv function stringx.splitv(s,re) assert_string(1,s) return utils.splitv(s,re) end --- The partition functions split a string using a delimiter into three parts: +-- The partition functions split a string using a delimiter into three parts: -- the part before, the delimiter itself, and the part afterwards local function _partition(p,delim,fn) local i1,i2 = fn(p,delim) @@ -427,6 +446,8 @@ -- @return part before ch -- @return ch -- @return part after ch +-- @usage {stringx.partition('a,b,c', ','))} == {'a', ',', 'b,c'} +-- @usage {stringx.partition('abc', 'x'))} == {'abc', '', ''} function stringx.partition(s,ch) assert_string(1,s) assert_nonempty_string(2,ch) @@ -439,6 +460,8 @@ -- @return part before ch -- @return ch -- @return part after ch +-- @usage {stringx.rpartition('a,b,c', ','))} == {'a,b', ',', 'c'} +-- @usage {stringx.rpartition('abc', 'x'))} == {'', '', 'abc'} function stringx.rpartition(s,ch) assert_string(1,s) assert_nonempty_string(2,ch) @@ -465,16 +488,23 @@ --- return an iterator over all lines in a string -- @string s the string -- @return an iterator +-- @usage +-- local line_no = 1 +-- for line in stringx.lines(some_text) do +-- print(line_no, line) +-- line_no = line_no + 1 +-- end function stringx.lines(s) assert_string(1,s) if not s:find '\n$' then s = s..'\n' end return s:gmatch('([^\n]*)\n') end ---- iniital word letters uppercase ('title case'). +--- inital word letters uppercase ('title case'). -- Here 'words' mean chunks of non-space characters. -- @string s the string -- @return a string with each word's first letter uppercase +-- @usage stringx.title("hello world") == "Hello World") function stringx.title(s) assert_string(1,s) return (s:gsub('(%S)(%S*)',function(f,r) diff -Nru lua-penlight-1.7.0/lua/pl/tablex.lua lua-penlight-1.9.2/lua/pl/tablex.lua --- lua-penlight-1.7.0/lua/pl/tablex.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/tablex.lua 2020-09-27 10:39:11.000000000 +0000 @@ -167,7 +167,14 @@ -- @within Comparing -- @array t1 an array -- @array t2 an array --- @func cmp A comparison function +-- @func cmp A comparison function; `bool = cmp(t1_value, t2_value)` +-- @return true or false +-- @usage +-- assert(tablex.compare({ 1, 2, 3 }, { 1, 2, 3 }, "==")) +-- +-- assert(tablex.compare( +-- {1,2,3, hello = "world"}, -- fields are not compared! +-- {1,2,3}, function(v1, v2) return v1 == v2 end) function tablex.compare (t1,t2,cmp) assert_arg_indexable(1,t1) assert_arg_indexable(2,t2) @@ -193,14 +200,16 @@ for i = 1,#t1 do local val = t1[i] local gotcha - for j = 1,#t2 do if not visited[j] then - local match - if cmp then match = cmp(val,t2[j]) else match = val == t2[j] end - if match then - gotcha = j - break + for j = 1,#t2 do + if not visited[j] then + local match + if cmp then match = cmp(val,t2[j]) else match = val == t2[j] end + if match then + gotcha = j + break + end end - end end + end if not gotcha then return false end visited[gotcha] = true end @@ -234,7 +243,7 @@ -- @within Finding -- @array t A list-like table -- @param val A value --- @param idx index to start; -1 means last element,etc (default 1) +-- @param idx index to start; -1 means last element,etc (default `#t`) -- @return index of value or nil if not found -- @usage rfind({10,10,10},10) == 3 function tablex.rfind(t,val,idx) @@ -249,12 +258,38 @@ --- return the index (or key) of a value in a table using a comparison function. +-- +-- *NOTE*: the 2nd return value of this function, the value returned +-- by the comparison function, has a limitation that it cannot be `false`. +-- Because if it is, then it indicates the comparison failed, and the +-- function will continue the search. See examples. -- @within Finding -- @tab t A table -- @func cmp A comparison function -- @param arg an optional second argument to the function -- @return index of value, or nil if not found --- @return value returned by comparison function +-- @return value returned by comparison function (cannot be `false`!) +-- @usage +-- -- using an operator +-- local lst = { "Rudolph", true, false, 15 } +-- local idx, cmp_result = tablex.rfind(lst, "==", "Rudolph") +-- assert(idx == 1) +-- assert(cmp_result == true) +-- +-- local idx, cmp_result = tablex.rfind(lst, "==", false) +-- assert(idx == 3) +-- assert(cmp_result == true) -- looking up 'false' works! +-- +-- -- using a function returning the value looked up +-- local cmp = function(v1, v2) return v1 == v2 and v2 end +-- local idx, cmp_result = tablex.rfind(lst, cmp, "Rudolph") +-- assert(idx == 1) +-- assert(cmp_result == "Rudolph") -- the value is returned +-- +-- -- NOTE: this fails, since 'false' cannot be returned! +-- local idx, cmp_result = tablex.rfind(lst, cmp, false) +-- assert(idx == nil) -- looking up 'false' failed! +-- assert(cmp_result == nil) function tablex.find_if(t,cmp,arg) assert_arg_iterable(1,t) cmp = function_arg(2,cmp) @@ -323,6 +358,28 @@ -- @string name the method name -- @array t a list-like table -- @param ... any extra arguments to the method +-- @return a `List` with the results of the method (1st result only) +-- @usage +-- local Car = {} +-- Car.__index = Car +-- function Car.new(car) +-- return setmetatable(car or {}, Car) +-- end +-- Car.speed = 0 +-- function Car:faster(increase) +-- self.speed = self.speed + increase +-- return self.speed +-- end +-- +-- local ferrari = Car.new{ name = "Ferrari" } +-- local lamborghini = Car.new{ name = "Lamborghini", speed = 50 } +-- local cars = { ferrari, lamborghini } +-- +-- assert(ferrari.speed == 0) +-- assert(lamborghini.speed == 50) +-- tablex.map_named_method("faster", cars, 10) +-- assert(ferrari.speed == 10) +-- assert(lamborghini.speed == 60) function tablex.map_named_method (name,t,...) utils.assert_string(1,name) assert_arg_indexable(2,t) @@ -339,7 +396,8 @@ -- Any extra arguments are passed to the function. -- @func fun A function that takes at least one argument -- @tab t a table --- @param ... extra arguments +-- @param ... extra arguments passed to `fun` +-- @see tablex.foreach function tablex.transform (fun,t,...) assert_arg_iterable(1,t) fun = function_arg(1,fun) @@ -432,8 +490,9 @@ -- Note that the Lua 5.0 function table.foreach passed the _key_ first. -- @within Iterating -- @tab t a table --- @func fun a function with at least one argument --- @param ... extra arguments +-- @func fun a function on the elements; `function(value, key, ...)` +-- @param ... extra arguments passed to `fun` +-- @see tablex.transform function tablex.foreach(t,fun,...) assert_arg_iterable(1,t) fun = function_arg(2,fun) @@ -871,8 +930,8 @@ -- @tab t the table -- @param value the value -- @array[opt] exclude any tables to avoid searching --- @usage search(_G,math.sin,{package.path}) == 'math.sin' -- @return a fieldspec, e.g. 'a.b' or 'math.sin' +-- @usage search(_G,math.sin,{package.path}) == 'math.sin' function tablex.search (t,value,exclude) assert_arg_iterable(1,t) local tables = {[t]=true} @@ -920,8 +979,11 @@ --- modifies a table to be read only. -- This only offers weak protection. Tables can still be modified with -- `table.insert` and `rawset`. +-- +-- *NOTE*: for Lua 5.1 length, pairs and ipairs will not work, since the +-- equivalent metamethods are only available in Lua 5.2 and newer. -- @tab t the table --- @return the table read only. +-- @return the table read only (a proxy). function tablex.readonly(t) local mt = { __index=t, diff -Nru lua-penlight-1.7.0/lua/pl/utils.lua lua-penlight-1.9.2/lua/pl/utils.lua --- lua-penlight-1.7.0/lua/pl/utils.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/lua/pl/utils.lua 2020-09-27 10:39:11.000000000 +0000 @@ -18,7 +18,7 @@ local _function_factories = {} -local utils = { _VERSION = "1.7.0" } +local utils = { _VERSION = "1.9.2" } for k, v in pairs(compat) do utils[k] = v end --- Some standard patterns diff -Nru lua-penlight-1.7.0/.luacheckrc lua-penlight-1.9.2/.luacheckrc --- lua-penlight-1.7.0/.luacheckrc 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/.luacheckrc 2020-09-27 10:39:11.000000000 +0000 @@ -2,6 +2,9 @@ redefined = false max_line_length = false +globals = { + "ngx", +} not_globals = { "string.len", diff -Nru lua-penlight-1.7.0/penlight-scm-2.rockspec lua-penlight-1.9.2/penlight-scm-2.rockspec --- lua-penlight-1.7.0/penlight-scm-2.rockspec 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/penlight-scm-2.rockspec 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -package = "penlight" -version = "scm-2" - -source = { - url = "git://github.com/Tieske/Penlight.git", - branch = "master" -} - -description = { - summary = "Lua utility libraries loosely based on the Python standard libraries", - homepage = "http://tieske.github.io/Penlight", - license = "MIT/X11", - maintainer = "thijs@thijsschreijer.nl", - detailed = [[ -Penlight is a set of pure Lua libraries for making it easier to work with common tasks like -iterating over directories, reading configuration files and the like. Provides functional operations -on tables and sequences. -]] -} - -dependencies = { - "luafilesystem" -} - -build = { - type = "builtin", - modules = { - ["pl"] = "lua/pl/init.lua", - ["pl.strict"] = "lua/pl/strict.lua", - ["pl.dir"] = "lua/pl/dir.lua", - ["pl.operator"] = "lua/pl/operator.lua", - ["pl.input"] = "lua/pl/input.lua", - ["pl.config"] = "lua/pl/config.lua", - ["pl.seq"] = "lua/pl/seq.lua", - ["pl.stringio"] = "lua/pl/stringio.lua", - ["pl.text"] = "lua/pl/text.lua", - ["pl.test"] = "lua/pl/test.lua", - ["pl.tablex"] = "lua/pl/tablex.lua", - ["pl.app"] = "lua/pl/app.lua", - ["pl.stringx"] = "lua/pl/stringx.lua", - ["pl.lexer"] = "lua/pl/lexer.lua", - ["pl.utils"] = "lua/pl/utils.lua", - ["pl.compat"] = "lua/pl/compat.lua", - ["pl.sip"] = "lua/pl/sip.lua", - ["pl.permute"] = "lua/pl/permute.lua", - ["pl.pretty"] = "lua/pl/pretty.lua", - ["pl.class"] = "lua/pl/class.lua", - ["pl.List"] = "lua/pl/List.lua", - ["pl.data"] = "lua/pl/data.lua", - ["pl.Date"] = "lua/pl/Date.lua", - ["pl.luabalanced"] = "lua/pl/luabalanced.lua", - ["pl.comprehension"] = "lua/pl/comprehension.lua", - ["pl.path"] = "lua/pl/path.lua", - ["pl.array2d"] = "lua/pl/array2d.lua", - ["pl.func"] = "lua/pl/func.lua", - ["pl.lapp"] = "lua/pl/lapp.lua", - ["pl.file"] = "lua/pl/file.lua", - ['pl.template'] = "lua/pl/template.lua", - ["pl.Map"] = "lua/pl/Map.lua", - ["pl.MultiMap"] = "lua/pl/MultiMap.lua", - ["pl.OrderedMap"] = "lua/pl/OrderedMap.lua", - ["pl.Set"] = "lua/pl/Set.lua", - ["pl.xml"] = "lua/pl/xml.lua", - ["pl.url"] = "lua/pl/url.lua", - ["pl.types"] = "lua/pl/types.lua", - ["pl.import_into"] = "lua/pl/import_into.lua" - }, - copy_directories = {"docs", "tests"} -} diff -Nru lua-penlight-1.7.0/penlight-scm-3.rockspec lua-penlight-1.9.2/penlight-scm-3.rockspec --- lua-penlight-1.7.0/penlight-scm-3.rockspec 1970-01-01 00:00:00.000000000 +0000 +++ lua-penlight-1.9.2/penlight-scm-3.rockspec 2020-09-27 10:39:11.000000000 +0000 @@ -0,0 +1,69 @@ +package = "penlight" +version = "scm-3" + +source = { + url = "git://github.com/lunarmodules/Penlight.git", + branch = "master" +} + +description = { + summary = "Lua utility libraries loosely based on the Python standard libraries", + homepage = "https://lunarmodules.github.io/Penlight", + license = "MIT/X11", + maintainer = "thijs@thijsschreijer.nl", + detailed = [[ +Penlight is a set of pure Lua libraries for making it easier to work with common tasks like +iterating over directories, reading configuration files and the like. Provides functional operations +on tables and sequences. +]] +} + +dependencies = { + "luafilesystem" +} + +build = { + type = "builtin", + modules = { + ["pl"] = "lua/pl/init.lua", + ["pl.strict"] = "lua/pl/strict.lua", + ["pl.dir"] = "lua/pl/dir.lua", + ["pl.operator"] = "lua/pl/operator.lua", + ["pl.input"] = "lua/pl/input.lua", + ["pl.config"] = "lua/pl/config.lua", + ["pl.seq"] = "lua/pl/seq.lua", + ["pl.stringio"] = "lua/pl/stringio.lua", + ["pl.text"] = "lua/pl/text.lua", + ["pl.test"] = "lua/pl/test.lua", + ["pl.tablex"] = "lua/pl/tablex.lua", + ["pl.app"] = "lua/pl/app.lua", + ["pl.stringx"] = "lua/pl/stringx.lua", + ["pl.lexer"] = "lua/pl/lexer.lua", + ["pl.utils"] = "lua/pl/utils.lua", + ["pl.compat"] = "lua/pl/compat.lua", + ["pl.sip"] = "lua/pl/sip.lua", + ["pl.permute"] = "lua/pl/permute.lua", + ["pl.pretty"] = "lua/pl/pretty.lua", + ["pl.class"] = "lua/pl/class.lua", + ["pl.List"] = "lua/pl/List.lua", + ["pl.data"] = "lua/pl/data.lua", + ["pl.Date"] = "lua/pl/Date.lua", + ["pl.luabalanced"] = "lua/pl/luabalanced.lua", + ["pl.comprehension"] = "lua/pl/comprehension.lua", + ["pl.path"] = "lua/pl/path.lua", + ["pl.array2d"] = "lua/pl/array2d.lua", + ["pl.func"] = "lua/pl/func.lua", + ["pl.lapp"] = "lua/pl/lapp.lua", + ["pl.file"] = "lua/pl/file.lua", + ['pl.template'] = "lua/pl/template.lua", + ["pl.Map"] = "lua/pl/Map.lua", + ["pl.MultiMap"] = "lua/pl/MultiMap.lua", + ["pl.OrderedMap"] = "lua/pl/OrderedMap.lua", + ["pl.Set"] = "lua/pl/Set.lua", + ["pl.xml"] = "lua/pl/xml.lua", + ["pl.url"] = "lua/pl/url.lua", + ["pl.types"] = "lua/pl/types.lua", + ["pl.import_into"] = "lua/pl/import_into.lua" + }, + copy_directories = {"docs", "tests"} +} diff -Nru lua-penlight-1.7.0/README.md lua-penlight-1.9.2/README.md --- lua-penlight-1.7.0/README.md 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/README.md 2020-09-27 10:39:11.000000000 +0000 @@ -1,8 +1,10 @@ # Penlight Lua Libraries -[![Build Status](https://travis-ci.org/Tieske/Penlight.svg?branch=master)](https://travis-ci.org/Tieske/Penlight) -[![Coverage Status](https://coveralls.io/repos/github/Tieske/Penlight/badge.svg?branch=master)](https://coveralls.io/github/Tieske/Penlight?branch=master) -[![AppVeyor status](https://ci.appveyor.com/api/projects/status/d59xoj32dbiylaq3/branch/master?svg=true)](https://ci.appveyor.com/project/Tieske/penlight/branch/master) +[![Travis-CI Status](https://travis-ci.org/lunarmodules/Penlight.svg?branch=master)](https://travis-ci.org/lunarmodules/Penlight) +[![Coverage Status](https://coveralls.io/repos/github/lunarmodules/Penlight/badge.svg)](https://coveralls.io/github/lunarmodules/Penlight) +[![AppVeyor status](https://ci.appveyor.com/api/projects/status/4jxg4ruktwi00up2/branch/master?svg=true)](https://ci.appveyor.com/project/Tieske/penlight-ta1gi/branch/master) + + ## Why a new set of libraries? @@ -59,7 +61,7 @@ ## License -Penlight is distributed under the [MIT license](https://github.com/Tieske/Penlight/blob/master/LICENSE.md) +Penlight is distributed under the [MIT license](LICENSE.md). ## Installation @@ -83,7 +85,7 @@ ## Contributing -Contributions are most welcome, please check the [contribution guidelines](https://github.com/Tieske/Penlight/blob/master/CONTRIBUTING.md). +Contributions are most welcome, please check the [contribution guidelines](CONTRIBUTING.md). ## Running tests @@ -91,5 +93,4 @@ ## History -For a complete history of the development of Penlight, please check the -[changelog](https://github.com/Tieske/Penlight/blob/master/CHANGELOG.md). +For a complete history of the development of Penlight, please check the [changelog](CHANGELOG.md). diff -Nru lua-penlight-1.7.0/rockspecs/penlight-1.8.0-1.rockspec lua-penlight-1.9.2/rockspecs/penlight-1.8.0-1.rockspec --- lua-penlight-1.7.0/rockspecs/penlight-1.8.0-1.rockspec 1970-01-01 00:00:00.000000000 +0000 +++ lua-penlight-1.9.2/rockspecs/penlight-1.8.0-1.rockspec 2020-09-27 10:39:11.000000000 +0000 @@ -0,0 +1,70 @@ +package = "penlight" +version = "1.8.0-1" + +source = { + url = "git://github.com/Tieske/Penlight.git", + branch = "1.8.0" +} + +description = { + summary = "Lua utility libraries loosely based on the Python standard libraries", + homepage = "http://tieske.github.io/Penlight", + license = "MIT/X11", + maintainer = "thijs@thijsschreijer.nl", + detailed = [[ +Penlight is a set of pure Lua libraries for making it easier to work with common tasks like +iterating over directories, reading configuration files and the like. Provides functional operations +on tables and sequences. +]] +} + +dependencies = { + "luafilesystem", +} + +build = { + type = "builtin", + modules = { + ["pl.strict"] = "lua/pl/strict.lua", + ["pl.dir"] = "lua/pl/dir.lua", + ["pl.operator"] = "lua/pl/operator.lua", + ["pl.input"] = "lua/pl/input.lua", + ["pl.config"] = "lua/pl/config.lua", + ["pl.compat"] = "lua/pl/config.lua", + ["pl.seq"] = "lua/pl/seq.lua", + ["pl.stringio"] = "lua/pl/stringio.lua", + ["pl.text"] = "lua/pl/text.lua", + ["pl.test"] = "lua/pl/test.lua", + ["pl.tablex"] = "lua/pl/tablex.lua", + ["pl.app"] = "lua/pl/app.lua", + ["pl.stringx"] = "lua/pl/stringx.lua", + ["pl.lexer"] = "lua/pl/lexer.lua", + ["pl.utils"] = "lua/pl/utils.lua", + ["pl.sip"] = "lua/pl/sip.lua", + ["pl.permute"] = "lua/pl/permute.lua", + ["pl.pretty"] = "lua/pl/pretty.lua", + ["pl.class"] = "lua/pl/class.lua", + ["pl.List"] = "lua/pl/List.lua", + ["pl.data"] = "lua/pl/data.lua", + ["pl.Date"] = "lua/pl/Date.lua", + ["pl.init"] = "lua/pl/init.lua", + ["pl.luabalanced"] = "lua/pl/luabalanced.lua", + ["pl.comprehension"] = "lua/pl/comprehension.lua", + ["pl.path"] = "lua/pl/path.lua", + ["pl.array2d"] = "lua/pl/array2d.lua", + ["pl.func"] = "lua/pl/func.lua", + ["pl.lapp"] = "lua/pl/lapp.lua", + ["pl.file"] = "lua/pl/file.lua", + ['pl.template'] = "lua/pl/template.lua", + ["pl.Map"] = "lua/pl/Map.lua", + ["pl.MultiMap"] = "lua/pl/MultiMap.lua", + ["pl.OrderedMap"] = "lua/pl/OrderedMap.lua", + ["pl.Set"] = "lua/pl/Set.lua", + ["pl.xml"] = "lua/pl/xml.lua", + ["pl.url"] = "lua/pl/url.lua", + ["pl.import_into"] = "lua/pl/import_into.lua", + ["pl.types"] = "lua/pl/types.lua", + }, + copy_directories = {"docs", "tests"} +} + diff -Nru lua-penlight-1.7.0/rockspecs/penlight-1.8.1-1.rockspec lua-penlight-1.9.2/rockspecs/penlight-1.8.1-1.rockspec --- lua-penlight-1.7.0/rockspecs/penlight-1.8.1-1.rockspec 1970-01-01 00:00:00.000000000 +0000 +++ lua-penlight-1.9.2/rockspecs/penlight-1.8.1-1.rockspec 2020-09-27 10:39:11.000000000 +0000 @@ -0,0 +1,70 @@ +package = "penlight" +version = "1.8.1-1" + +source = { + url = "git://github.com/lunarmodules/Penlight.git", + tag = "1.8.1" +} + +description = { + summary = "Lua utility libraries loosely based on the Python standard libraries", + homepage = "https://lunarmodules.github.io/Penlight", + license = "MIT/X11", + maintainer = "thijs@thijsschreijer.nl", + detailed = [[ +Penlight is a set of pure Lua libraries for making it easier to work with common tasks like +iterating over directories, reading configuration files and the like. Provides functional operations +on tables and sequences. +]] +} + +dependencies = { + "luafilesystem", +} + +build = { + type = "builtin", + modules = { + ["pl.strict"] = "lua/pl/strict.lua", + ["pl.dir"] = "lua/pl/dir.lua", + ["pl.operator"] = "lua/pl/operator.lua", + ["pl.input"] = "lua/pl/input.lua", + ["pl.config"] = "lua/pl/config.lua", + ["pl.compat"] = "lua/pl/config.lua", + ["pl.seq"] = "lua/pl/seq.lua", + ["pl.stringio"] = "lua/pl/stringio.lua", + ["pl.text"] = "lua/pl/text.lua", + ["pl.test"] = "lua/pl/test.lua", + ["pl.tablex"] = "lua/pl/tablex.lua", + ["pl.app"] = "lua/pl/app.lua", + ["pl.stringx"] = "lua/pl/stringx.lua", + ["pl.lexer"] = "lua/pl/lexer.lua", + ["pl.utils"] = "lua/pl/utils.lua", + ["pl.sip"] = "lua/pl/sip.lua", + ["pl.permute"] = "lua/pl/permute.lua", + ["pl.pretty"] = "lua/pl/pretty.lua", + ["pl.class"] = "lua/pl/class.lua", + ["pl.List"] = "lua/pl/List.lua", + ["pl.data"] = "lua/pl/data.lua", + ["pl.Date"] = "lua/pl/Date.lua", + ["pl.init"] = "lua/pl/init.lua", + ["pl.luabalanced"] = "lua/pl/luabalanced.lua", + ["pl.comprehension"] = "lua/pl/comprehension.lua", + ["pl.path"] = "lua/pl/path.lua", + ["pl.array2d"] = "lua/pl/array2d.lua", + ["pl.func"] = "lua/pl/func.lua", + ["pl.lapp"] = "lua/pl/lapp.lua", + ["pl.file"] = "lua/pl/file.lua", + ['pl.template'] = "lua/pl/template.lua", + ["pl.Map"] = "lua/pl/Map.lua", + ["pl.MultiMap"] = "lua/pl/MultiMap.lua", + ["pl.OrderedMap"] = "lua/pl/OrderedMap.lua", + ["pl.Set"] = "lua/pl/Set.lua", + ["pl.xml"] = "lua/pl/xml.lua", + ["pl.url"] = "lua/pl/url.lua", + ["pl.import_into"] = "lua/pl/import_into.lua", + ["pl.types"] = "lua/pl/types.lua", + }, + copy_directories = {"docs", "tests"} +} + diff -Nru lua-penlight-1.7.0/rockspecs/penlight-1.9.1-1.rockspec lua-penlight-1.9.2/rockspecs/penlight-1.9.1-1.rockspec --- lua-penlight-1.7.0/rockspecs/penlight-1.9.1-1.rockspec 1970-01-01 00:00:00.000000000 +0000 +++ lua-penlight-1.9.2/rockspecs/penlight-1.9.1-1.rockspec 2020-09-27 10:39:11.000000000 +0000 @@ -0,0 +1,70 @@ +package = "penlight" +version = "1.9.1-1" + +source = { + url = "git://github.com/lunarmodules/Penlight.git", + tag = "1.9.1" +} + +description = { + summary = "Lua utility libraries loosely based on the Python standard libraries", + homepage = "https://lunarmodules.github.io/Penlight", + license = "MIT/X11", + maintainer = "thijs@thijsschreijer.nl", + detailed = [[ +Penlight is a set of pure Lua libraries for making it easier to work with common tasks like +iterating over directories, reading configuration files and the like. Provides functional operations +on tables and sequences. +]] +} + +dependencies = { + "luafilesystem", +} + +build = { + type = "builtin", + modules = { + ["pl.strict"] = "lua/pl/strict.lua", + ["pl.dir"] = "lua/pl/dir.lua", + ["pl.operator"] = "lua/pl/operator.lua", + ["pl.input"] = "lua/pl/input.lua", + ["pl.config"] = "lua/pl/config.lua", + ["pl.compat"] = "lua/pl/config.lua", + ["pl.seq"] = "lua/pl/seq.lua", + ["pl.stringio"] = "lua/pl/stringio.lua", + ["pl.text"] = "lua/pl/text.lua", + ["pl.test"] = "lua/pl/test.lua", + ["pl.tablex"] = "lua/pl/tablex.lua", + ["pl.app"] = "lua/pl/app.lua", + ["pl.stringx"] = "lua/pl/stringx.lua", + ["pl.lexer"] = "lua/pl/lexer.lua", + ["pl.utils"] = "lua/pl/utils.lua", + ["pl.sip"] = "lua/pl/sip.lua", + ["pl.permute"] = "lua/pl/permute.lua", + ["pl.pretty"] = "lua/pl/pretty.lua", + ["pl.class"] = "lua/pl/class.lua", + ["pl.List"] = "lua/pl/List.lua", + ["pl.data"] = "lua/pl/data.lua", + ["pl.Date"] = "lua/pl/Date.lua", + ["pl.init"] = "lua/pl/init.lua", + ["pl.luabalanced"] = "lua/pl/luabalanced.lua", + ["pl.comprehension"] = "lua/pl/comprehension.lua", + ["pl.path"] = "lua/pl/path.lua", + ["pl.array2d"] = "lua/pl/array2d.lua", + ["pl.func"] = "lua/pl/func.lua", + ["pl.lapp"] = "lua/pl/lapp.lua", + ["pl.file"] = "lua/pl/file.lua", + ['pl.template'] = "lua/pl/template.lua", + ["pl.Map"] = "lua/pl/Map.lua", + ["pl.MultiMap"] = "lua/pl/MultiMap.lua", + ["pl.OrderedMap"] = "lua/pl/OrderedMap.lua", + ["pl.Set"] = "lua/pl/Set.lua", + ["pl.xml"] = "lua/pl/xml.lua", + ["pl.url"] = "lua/pl/url.lua", + ["pl.import_into"] = "lua/pl/import_into.lua", + ["pl.types"] = "lua/pl/types.lua", + }, + copy_directories = {"docs", "tests"} +} + diff -Nru lua-penlight-1.7.0/rockspecs/penlight-1.9.2-1.rockspec lua-penlight-1.9.2/rockspecs/penlight-1.9.2-1.rockspec --- lua-penlight-1.7.0/rockspecs/penlight-1.9.2-1.rockspec 1970-01-01 00:00:00.000000000 +0000 +++ lua-penlight-1.9.2/rockspecs/penlight-1.9.2-1.rockspec 2020-09-27 10:39:11.000000000 +0000 @@ -0,0 +1,70 @@ +package = "penlight" +version = "1.9.2-1" + +source = { + url = "git://github.com/lunarmodules/Penlight.git", + tag = "1.9.2" +} + +description = { + summary = "Lua utility libraries loosely based on the Python standard libraries", + homepage = "https://lunarmodules.github.io/Penlight", + license = "MIT/X11", + maintainer = "thijs@thijsschreijer.nl", + detailed = [[ +Penlight is a set of pure Lua libraries for making it easier to work with common tasks like +iterating over directories, reading configuration files and the like. Provides functional operations +on tables and sequences. +]] +} + +dependencies = { + "luafilesystem", +} + +build = { + type = "builtin", + modules = { + ["pl.strict"] = "lua/pl/strict.lua", + ["pl.dir"] = "lua/pl/dir.lua", + ["pl.operator"] = "lua/pl/operator.lua", + ["pl.input"] = "lua/pl/input.lua", + ["pl.config"] = "lua/pl/config.lua", + ["pl.compat"] = "lua/pl/config.lua", + ["pl.seq"] = "lua/pl/seq.lua", + ["pl.stringio"] = "lua/pl/stringio.lua", + ["pl.text"] = "lua/pl/text.lua", + ["pl.test"] = "lua/pl/test.lua", + ["pl.tablex"] = "lua/pl/tablex.lua", + ["pl.app"] = "lua/pl/app.lua", + ["pl.stringx"] = "lua/pl/stringx.lua", + ["pl.lexer"] = "lua/pl/lexer.lua", + ["pl.utils"] = "lua/pl/utils.lua", + ["pl.sip"] = "lua/pl/sip.lua", + ["pl.permute"] = "lua/pl/permute.lua", + ["pl.pretty"] = "lua/pl/pretty.lua", + ["pl.class"] = "lua/pl/class.lua", + ["pl.List"] = "lua/pl/List.lua", + ["pl.data"] = "lua/pl/data.lua", + ["pl.Date"] = "lua/pl/Date.lua", + ["pl.init"] = "lua/pl/init.lua", + ["pl.luabalanced"] = "lua/pl/luabalanced.lua", + ["pl.comprehension"] = "lua/pl/comprehension.lua", + ["pl.path"] = "lua/pl/path.lua", + ["pl.array2d"] = "lua/pl/array2d.lua", + ["pl.func"] = "lua/pl/func.lua", + ["pl.lapp"] = "lua/pl/lapp.lua", + ["pl.file"] = "lua/pl/file.lua", + ['pl.template'] = "lua/pl/template.lua", + ["pl.Map"] = "lua/pl/Map.lua", + ["pl.MultiMap"] = "lua/pl/MultiMap.lua", + ["pl.OrderedMap"] = "lua/pl/OrderedMap.lua", + ["pl.Set"] = "lua/pl/Set.lua", + ["pl.xml"] = "lua/pl/xml.lua", + ["pl.url"] = "lua/pl/url.lua", + ["pl.import_into"] = "lua/pl/import_into.lua", + ["pl.types"] = "lua/pl/types.lua", + }, + copy_directories = {"docs", "tests"} +} + diff -Nru lua-penlight-1.7.0/tests/lua/mod52.lua lua-penlight-1.9.2/tests/lua/mod52.lua --- lua-penlight-1.7.0/tests/lua/mod52.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/lua/mod52.lua 2020-09-27 10:39:11.000000000 +0000 @@ -10,9 +10,17 @@ function answer () -- of course, you don't have the usual global environment available -- so define it as a local up above, or use utils.import(_G). + + local versioned_errors = { + ["1"] = "attempt to call global 'print'", + ["2"] = "attempt to call global 'print'", + ["3"] = "attempt to call a nil value", + ["4"] = "attempt to call a nil value", + } + local expected = versioned_errors[LUA_VERSION:match("Lua 5.(%d)")] test.assertraise(function() print 'hello' - end,(LUA_VERSION~="Lua 5.3") and "attempt to call global 'print'" or "attempt to call a nil value") + end, expected) -- but all the Penlight modules are available return pretty.write(utils.split '10 20 30', '') diff -Nru lua-penlight-1.7.0/tests/test-app.lua lua-penlight-1.9.2/tests/test-app.lua --- lua-penlight-1.7.0/tests/test-app.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-app.lua 2020-09-27 10:39:11.000000000 +0000 @@ -6,7 +6,7 @@ local quote = utils.quote_arg local _, cmd = app.lua() -cmd = cmd .. " " .. quote({"-lluacov", "-e", "package.path=[[./lua/?.lua;./lua/?/init.lua;]]..package.path"}) +cmd = cmd .. " " .. quote({"-e", "package.path=[[./lua/?.lua;./lua/?/init.lua;]]..package.path"}) local function run_script(s, fname) local tmpname = path.tmpname() diff -Nru lua-penlight-1.7.0/tests/test-class.lua lua-penlight-1.9.2/tests/test-class.lua --- lua-penlight-1.7.0/tests/test-class.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-class.lua 2020-09-27 10:39:11.000000000 +0000 @@ -27,6 +27,10 @@ self.eee = 1 end +function B:foo2 () + self.g = 8 +end + asserteq(B(),{a=1,b=2}) -- can continue this chain @@ -47,6 +51,77 @@ c:foo() asserteq(c,{a=1,b=2,c=3,eee=1}) + +-- test indirect inherit + +D = class(C) + +E = class(D) + +function E:_init () + self:super() + self.e = 4 +end + +function E:foo () + -- recommended way to call inherited version of method... + self.eeee = 5 + C.foo(self) +end + +F = class(E) + +function F:_init () + self:super() + self.f = 6 +end + +f = F() +f:foo() +f:foo2() -- Test : invocation inherits this function from all the way up in B + +asserteq(f,{a=1,b=2,c=3,eee=1,e=4,eeee=5,f=6,g=8}) + +-- Test that inappropriate calls to super() fail gracefully + +G = class() -- Class with no init + +H = class(G) -- Class with an init that wrongly calls super() + +function H:_init() + self:super() -- Notice: G has no _init +end + +I = class(H) -- Inherits the init with a bad super +J = class(I) -- Grandparent-inits the init with a bad super + +K = class(J) -- Has an init, which calls the init with a bad super + +function K:_init() + self:super() +end + +local function createG() + return G() +end + +local function createH() -- Wrapper function for pcall + return H() +end + +local function createJ() + return J() +end + +local function createK() + return K() +end + +assert(pcall(createG)) -- Should succeed +assert(not pcall(createH)) -- These three should fail +assert(not pcall(createJ)) +assert(not pcall(createK)) + --- class methods! assert(c:is_a(C)) assert(c:is_a(B)) diff -Nru lua-penlight-1.7.0/tests/test-compat.lua lua-penlight-1.9.2/tests/test-compat.lua --- lua-penlight-1.7.0/tests/test-compat.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-compat.lua 2020-09-27 10:39:11.000000000 +0000 @@ -15,3 +15,15 @@ local f, err = compat.load(code_generator) asserteq(err, nil) asserteq(f(), "Hello World!") + + +-- package.searchpath +if compat.lua51 and not compat.jit then + assert(package.searchpath("pl.compat", package.path):match("lua[/\\]pl[/\\]compat")) + + local path = "some/?/nice.path;another/?.path" + local ok, err = package.searchpath("my.file.name", path, ".", "/") + asserteq(err, "\tno file 'some/my/file/name/nice.path'\n\tno file 'another/my/file/name.path'") + local ok, err = package.searchpath("my/file/name", path, "/", ".") + asserteq(err, "\tno file 'some/my.file.name/nice.path'\n\tno file 'another/my.file.name.path'") +end \ No newline at end of file diff -Nru lua-penlight-1.7.0/tests/test-lexer.lua lua-penlight-1.9.2/tests/test-lexer.lua --- lua-penlight-1.7.0/tests/test-lexer.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-lexer.lua 2020-09-27 10:39:11.000000000 +0000 @@ -137,3 +137,10 @@ iter() iter() asserteq(lexer.lineno(iter), 3) + +do -- numbers without leading zero; ".123" + local s = 'hello = +.234' + test_scan(s, {space=true}, {number=true}, { + {'iden', 'hello'}, {'=', '='}, {'number', .234} + }) +end diff -Nru lua-penlight-1.7.0/tests/test-path2.lua lua-penlight-1.9.2/tests/test-path2.lua --- lua-penlight-1.7.0/tests/test-path2.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-path2.lua 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -local path = require 'pl.path' -local test = require 'pl.test' -local asserteq = test.asserteq - -function slash (p) - return (p:gsub('\\','/')) -end - - --- path.relpath - - -local testpath = '/a/B/c' - -function try (p,r) - asserteq(slash(path.relpath(p,testpath)),r) -end - -try('/a/B/c/one.lua','one.lua') -try('/a/B/c/bonZO/two.lua','bonZO/two.lua') -try('/a/B/three.lua','../three.lua') -try('/a/four.lua','../../four.lua') -try('one.lua','one.lua') -try('../two.lua','../two.lua') - - --- path.common_prefix - - -asserteq(slash(path.common_prefix("../anything","../anything/goes")),"../anything") -asserteq(slash(path.common_prefix("../anything/goes","../anything")),"../anything") -asserteq(slash(path.common_prefix("../anything/goes","../anything/goes")),"../anything") -asserteq(slash(path.common_prefix("../anything/","../anything/")),"../anything") -asserteq(slash(path.common_prefix("../anything","../anything")),"..") -asserteq(slash(path.common_prefix("/hello/world","/hello/world/filename.doc")),"/hello/world") -asserteq(slash(path.common_prefix("/hello/filename.doc","/hello/filename.doc")),"/hello") -if path.is_windows then - asserteq(path.common_prefix("c:\\hey\\there","c:\\hey"),"c:\\hey") -end diff -Nru lua-penlight-1.7.0/tests/test-path.lua lua-penlight-1.9.2/tests/test-path.lua --- lua-penlight-1.7.0/tests/test-path.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-path.lua 2020-09-27 10:39:11.000000000 +0000 @@ -9,76 +9,190 @@ print(quote(s1),quote(s2)) end -function testpath(pth,p1,p2,p3) - local dir,rest = path.splitpath(pth) - local name,ext = path.splitext(rest) - asserteq(dir,p1) - asserteq(name,p2) - asserteq(ext,p3) +function slash (p) + return (p:gsub('\\','/')) end -testpath ([[/bonzo/dog_stuff/cat.txt]],[[/bonzo/dog_stuff]],'cat','.txt') -testpath ([[/bonzo/dog/cat/fred.stuff]],'/bonzo/dog/cat','fred','.stuff') -testpath ([[../../alice/jones]],'../../alice','jones','') -testpath ([[alice]],'','alice','') -testpath ([[/path-to/dog/]],[[/path-to/dog]],'','') +-- path.currentdir +do + local cp = path.currentdir() + path.chdir("docs") + asserteq(path.currentdir(), cp .. path.sep .. "docs") + path.chdir("..") + asserteq(path.currentdir(), cp) +end +-- path.isdir asserteq( path.isdir( "docs" ), true ) asserteq( path.isdir( "docs/index.html" ), false ) +-- path.isfile asserteq( path.isfile( "docs" ), false ) asserteq( path.isfile( "docs/index.html" ), true ) -local norm = path.normpath -local p = norm '/a/b' +-- path.exists +asserteq( path.exists( "docs"), "docs") +asserteq( path.exists( "docs/index.html"), "docs/index.html") + + +do -- path.splitpath & path.splitext + function testpath(pth,p1,p2,p3) + local dir,rest = path.splitpath(pth) + local name,ext = path.splitext(rest) + asserteq(dir,p1) + asserteq(name,p2) + asserteq(ext,p3) + end + + testpath ([[/bonzo/dog_stuff/cat.txt]],[[/bonzo/dog_stuff]],'cat','.txt') + testpath ([[/bonzo/dog/cat/fred.stuff]],'/bonzo/dog/cat','fred','.stuff') + testpath ([[../../alice/jones]],'../../alice','jones','') + testpath ([[alice]],'','alice','') + testpath ([[/path-to/dog/]],[[/path-to/dog]],'','') + + asserteq({path.splitpath("some/dir/myfile.txt")}, {"some/dir", "myfile.txt"}) + asserteq({path.splitpath("some/dir/")}, {"some/dir", ""}) + asserteq({path.splitpath("some_dir")}, {"", "some_dir"}) + + asserteq({path.splitext("/bonzo/dog_stuff/cat.txt")}, {"/bonzo/dog_stuff/cat", ".txt"}) + asserteq({path.splitext("cat.txt")}, {"cat", ".txt"}) + asserteq({path.splitext("cat")}, {"cat", ""}) + asserteq({path.splitext(".txt")}, {"", ".txt"}) + asserteq({path.splitext("")}, {"", ""}) +end + + +-- TODO: path.abspath + +-- TODO: path.dirname + +-- TODO: path.basename + +-- TODO: path.extension + + +do -- path.isabs + asserteq(path.isabs("/hello/path"), true) + asserteq(path.isabs("hello/path"), false) + asserteq(path.isabs("./hello/path"), false) + asserteq(path.isabs("../hello/path"), false) + if path.is_windows then + asserteq(path.isabs("c:/"), true) + asserteq(path.isabs("c:/hello/path"), true) + asserteq(path.isabs("c:"), false) + asserteq(path.isabs("c:hello/path"), false) + asserteq(path.isabs("c:./hello/path"), false) + asserteq(path.isabs("c:../hello/path"), false) + end +end + + +do -- path.join + assert(path.join("somepath",".") == "somepath"..path.sep..".") + assert(path.join(".","readme.txt") == "."..path.sep.."readme.txt") + assert(path.join("/a_dir", "abs_path/") == "/a_dir"..path.sep.."abs_path/") + assert(path.join("a_dir", "/abs_path/") == "/abs_path/") + assert(path.join("a_dir", "/abs_path/", "/abs_path2/") == "/abs_path2/") + assert(path.join("a_dir", "/abs_path/", "not_abs_path2/") == "/abs_path/not_abs_path2/") + assert(path.join("a_dir", "/abs_path/", "not_abs_path2/", "/abs_path3/", "not_abs_path4/") == "/abs_path3/not_abs_path4/") + assert(path.join("first","second","third") == "first"..path.sep.."second"..path.sep.."third") + assert(path.join("first","second","") == "first"..path.sep.."second"..path.sep) + assert(path.join("first","","third") == "first"..path.sep.."third") + assert(path.join("","second","third") == "second"..path.sep.."third") + assert(path.join("","") == "") +end + + +do -- path.normcase + if path.iswindows then + asserteq('c:\\hello\\world', 'c:\\hello\\world') + asserteq('C:\\Hello\\wORLD', 'c:\\hello\\world') + asserteq('c:/hello/world', 'c:\\hello\\world') + else + asserteq('/Hello/wORLD', '/Hello/wORLD') + end +end + + +do -- path.normpath + local norm = path.normpath + local p = norm '/a/b' + + asserteq(norm '/a/fred/../b',p) + asserteq(norm '/a//b',p) + + function testnorm(p1,p2) + asserteq(norm(p1):gsub('\\','/'), p2) + end + + testnorm('a/b/..','a') + testnorm('a/b/../..','.') + testnorm('a/b/../c/../../d','d') + testnorm('a/.','a') + testnorm('a/./','a') + testnorm('a/b/.././..','.') + testnorm('../../a/b','../../a/b') + testnorm('../../a/b/../../','../..') + testnorm('../../a/b/../c','../../a/c') + testnorm('./../../a/b/../c','../../a/c') + testnorm('a/..b', 'a/..b') + testnorm('./a', 'a') + testnorm('a/.', 'a') + testnorm('a/', 'a') + testnorm('/a', '/a') + testnorm('', ".") + + if path.is_windows then + testnorm('C://a', 'C:/a') + testnorm('C:/../a', 'C:/../a') + asserteq(norm [[\a\.\b]], p) + -- UNC paths + asserteq(norm [[\\bonzo\..\dog]], [[\\dog]]) + asserteq(norm [[\\?\c:\bonzo\dog\.\]], [[\\?\c:\bonzo\dog]]) + else + testnorm('//a', '//a') + testnorm('///a', '/a') + end + + asserteq(norm '1/2/../3/4/../5',norm '1/3/5') + asserteq(norm '1/hello/../3/hello/../HELLO',norm '1/3/HELLO') +end + + +do -- path.relpath + local testpath = '/a/B/c' + + function try (p,r) + asserteq(slash(path.relpath(p,testpath)),r) + end + + try('/a/B/c/one.lua','one.lua') + try('/a/B/c/bonZO/two.lua','bonZO/two.lua') + try('/a/B/three.lua','../three.lua') + try('/a/four.lua','../../four.lua') + try('one.lua','one.lua') + try('../two.lua','../two.lua') +end + + +-- TODO: path.expanduser + +-- TODO: path.tmpname -asserteq(norm '/a/fred/../b',p) -asserteq(norm '/a//b',p) -function testnorm(p1,p2) - asserteq(norm(p1):gsub('\\','/'), p2) +do -- path.common_prefix + asserteq(slash(path.common_prefix("../anything","../anything/goes")),"../anything") + asserteq(slash(path.common_prefix("../anything/goes","../anything")),"../anything") + asserteq(slash(path.common_prefix("../anything/goes","../anything/goes")),"../anything") + asserteq(slash(path.common_prefix("../anything/","../anything/")),"../anything") + asserteq(slash(path.common_prefix("../anything","../anything")),"..") + asserteq(slash(path.common_prefix("/hello/world","/hello/world/filename.doc")),"/hello/world") + asserteq(slash(path.common_prefix("/hello/filename.doc","/hello/filename.doc")),"/hello") + if path.is_windows then + asserteq(path.common_prefix("c:\\hey\\there","c:\\hey"),"c:\\hey") + asserteq(path.common_prefix("c:/HEy/there","c:/hEy"),"c:\\hEy") -- normalized separators, original casing + end end -testnorm('a/b/..','a') -testnorm('a/b/../..','.') -testnorm('a/b/../c/../../d','d') -testnorm('a/.','a') -testnorm('a/./','a') -testnorm('a/b/.././..','.') -testnorm('../../a/b','../../a/b') -testnorm('../../a/b/../../','../..') -testnorm('../../a/b/../c','../../a/c') -testnorm('./../../a/b/../c','../../a/c') -testnorm('a/..b', 'a/..b') -testnorm('./a', 'a') -testnorm('a/.', 'a') -testnorm('a/', 'a') -testnorm('/a', '/a') - -if path.is_windows then - testnorm('C://a', 'C:/a') - testnorm('C:/../a', 'C:/../a') - asserteq(norm [[\a\.\b]], p) - -- UNC paths - asserteq(norm [[\\bonzo\..\dog]], [[\\dog]]) - asserteq(norm [[\\?\c:\bonzo\dog\.\]], [[\\?\c:\bonzo\dog]]) -else - testnorm('//a', '//a') - testnorm('///a', '/a') -end - -asserteq(norm '1/2/../3/4/../5',norm '1/3/5') - -assert(path.join("somepath",".") == "somepath"..path.sep..".") -assert(path.join(".","readme.txt") == "."..path.sep.."readme.txt") -assert(path.join("/a_dir", "abs_path/") == "/a_dir"..path.sep.."abs_path/") -assert(path.join("a_dir", "/abs_path/") == "/abs_path/") -assert(path.join("a_dir", "/abs_path/", "/abs_path2/") == "/abs_path2/") -assert(path.join("a_dir", "/abs_path/", "not_abs_path2/") == "/abs_path/not_abs_path2/") -assert(path.join("a_dir", "/abs_path/", "not_abs_path2/", "/abs_path3/", "not_abs_path4/") == "/abs_path3/not_abs_path4/") -assert(path.join("first","second","third") == "first"..path.sep.."second"..path.sep.."third") -assert(path.join("first","second","") == "first"..path.sep.."second"..path.sep) -assert(path.join("first","","third") == "first"..path.sep.."third") -assert(path.join("","second","third") == "second"..path.sep.."third") -assert(path.join("","") == "") +-- TODO: path.package_path diff -Nru lua-penlight-1.7.0/tests/test-pretty.lua lua-penlight-1.9.2/tests/test-pretty.lua --- lua-penlight-1.7.0/tests/test-pretty.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-pretty.lua 2020-09-27 10:39:11.000000000 +0000 @@ -84,6 +84,12 @@ t1[1],t1[2] = t2,t2 asserteq( pretty.write(t1,""), [[{{},{}}]] ) +-- Check that write correctly print table with non number or string as keys + +t1 = { [true] = "boolean", a = "a", b = "b", [1] = 1, [0] = 0 } +asserteq( pretty.write(t1,""), [[{1,["true"]="boolean",a="a",b="b",[0]=0}]] ) + + -- Check number formatting asserteq(pretty.write({1/0, -1/0, 0/0, 1, 1/2}, ""), "{Inf,-Inf,NaN,1,0.5}") @@ -92,3 +98,8 @@ else asserteq(pretty.write({1.0}, ""), "{1}") end + +do -- issue #203, item 3 + local t = {}; t[t] = 1 + pretty.write(t) -- should not crash +end diff -Nru lua-penlight-1.7.0/tests/test-strict.lua lua-penlight-1.9.2/tests/test-strict.lua --- lua-penlight-1.7.0/tests/test-strict.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-strict.lua 2020-09-27 10:39:11.000000000 +0000 @@ -42,9 +42,103 @@ +-- module +do + local testmodule = { + hello = function() return "supremacy" end + } + -- make strict and allow extra field "world" + strict.module("my_test", testmodule, { world = true }) + + test.asserteq(testmodule.hello(), "supremacy") + test.assertraise(function() + print(testmodule.not_allowed_key) + end, "variable 'not_allowed_key' is not declared in 'my_test'") + + test.asserteq(testmodule.world, nil) + testmodule.world = "supremacy" + test.asserteq(testmodule.world, "supremacy") + + + -- table with a __newindex method + local mod1 = strict.module("mod1", setmetatable( + { + hello = "world", + }, { + __newindex = function(self, key, value) + if key == "Lua" then + rawset(self, key, value) + end + end, + } + )) + test.asserteq(mod1.hello, "world") + mod1.Lua = "hello world" + test.asserteq(mod1.Lua, "hello world") + test.assertraise(function() + print(mod1.not_allowed_key) + end, "variable 'not_allowed_key' is not declared in 'mod1'") + + + -- table with a __index method + local mod1 = strict.module("mod1", setmetatable( + { + hello = "world", + }, { + __index = function(self, key) + if key == "Lua" then + return "rocks" + end + end, + } + )) + test.asserteq(mod1.hello, "world") + test.asserteq(mod1.Lua, "rocks") + test.assertraise(function() + print(mod1.not_allowed_key) + end, "variable 'not_allowed_key' is not declared in 'mod1'") + + + -- table with a __index table + local mod1 = strict.module("mod1", setmetatable( + { + hello = "world", + }, { + __index = { + Lua = "rocks!" + } + } + )) + test.asserteq(mod1.hello, "world") + test.asserteq(mod1.Lua, "rocks!") + test.assertraise(function() + print(mod1.not_allowed_key) + end, "variable 'not_allowed_key' is not declared in 'mod1'") + +end + + +do + -- closed_module + -- what does this do? this does not seem a usefull function??? + + local testmodule = { + hello = function() return "supremacy" end + } + local M = strict.closed_module(testmodule, "my_test") + + -- read acces to original is granted, but not to the new one + test.asserteq(testmodule.hello(), "supremacy") + test.assertraise(function() + print(M.hello()) + end, "variable 'hello' is not declared in 'my_test'") + + -- write access to both is granted + testmodule.world = "domination" + M.world = "domination" + + -- read acces to set field in original is granted, but not set + test.asserteq(testmodule.world, nil) + test.asserteq(M.world, "domination") - - - - - +end diff -Nru lua-penlight-1.7.0/tests/test-stringx.lua lua-penlight-1.9.2/tests/test-stringx.lua --- lua-penlight-1.7.0/tests/test-stringx.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-stringx.lua 2020-09-27 10:39:11.000000000 +0000 @@ -39,6 +39,12 @@ asserteq(T(stringx.islower'aMz'), T(false)) asserteq(T(stringx.islower'a z'), T(true)) +-- isupper +asserteq(T(stringx.isupper''), T(false)) +asserteq(T(stringx.isupper'AZ'), T(true)) +asserteq(T(stringx.isupper'AmZ'), T(false)) +asserteq(T(stringx.isupper'A Z'), T(true)) + -- startswith local startswith = stringx.startswith asserteq(T(startswith('', '')), T(true)) @@ -81,6 +87,9 @@ asserteq(endswith('dollar.txt',{'.dot','.txt'}),true) asserteq(endswith('dollar.rtxt',{'.dot','.txt'}),false) +-- join +asserteq(stringx.join(' ', {1,2,3}), '1 2 3') + -- splitlines asserteq(stringx.splitlines(''), {}) asserteq(stringx.splitlines('a'), {'a'}) @@ -125,6 +134,7 @@ asserteq(T(stringx.rfind('abcbcbbc', 'bc', 3, 4)), T(nil)) asserteq(T(stringx.rfind('abcbcbbc', 'bc', 3, 5)), T(4)) asserteq(T(stringx.rfind('abcbcbbc', 'bc', nil, 5)), T(4)) +asserteq(T(stringx.rfind('banana', 'ana')), T(4)) -- replace asserteq(T(stringx.replace('', '', '')), T('')) @@ -161,6 +171,9 @@ asserteq(T(stringx.count(' ', '')), T(2)) --infinite loop]] asserteq(T(stringx.count('a..c', '.')), T(2)) -- pattern chars asserteq(T(stringx.count('a1c', '%d')), T(0)) -- pattern chars +asserteq(T(stringx.count('Anna Anna Anna', 'Anna')), T(3)) -- no overlap +asserteq(T(stringx.count('banana', 'ana', false)), T(1)) -- no overlap +asserteq(T(stringx.count('banana', 'ana', true)), T(2)) -- overlap -- ljust asserteq(T(stringx.ljust('', 0)), T('')) @@ -235,6 +248,9 @@ -- more +asserteq({stringx.splitv("hello dolly")}, {"hello", "dolly"}) + + -- partition -- as per str.partition in Python, delimiter must be non-empty; -- interpreted as a plain string @@ -256,6 +272,7 @@ asserteq(T(stringx.at('a', 1)), T('a')) asserteq(T(stringx.at('ab', 2)), T('b')) asserteq(T(stringx.at('abcd', -1)), T('d')) +asserteq(T(stringx.at('abcd', 10)), T('')) -- not found -- lines local function merge(it, ...) @@ -268,6 +285,9 @@ asserteq(merge(stringx.lines('ab')), {'ab'}) asserteq(merge(stringx.lines('ab\ncd')), {'ab', 'cd'}) +asserteq(stringx.capitalize("hello world"), "Hello World") +asserteq(stringx.title("hello world"), "Hello World") + -- shorten -- The returned string is always equal or less to the given size. asserteq(T(stringx.shorten('', 0)), T'') diff -Nru lua-penlight-1.7.0/tests/test-tablex.lua lua-penlight-1.9.2/tests/test-tablex.lua --- lua-penlight-1.7.0/tests/test-tablex.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-tablex.lua 2020-09-27 10:39:11.000000000 +0000 @@ -207,3 +207,142 @@ asserteq(tablex.reduce('-', {}), nil) asserteq(tablex.reduce('-', {1,2,3,4,5}), -13) asserteq(tablex.reduce('-', {1,2,3,4,5}, 1), -14) + + +-- tablex.compare +do + asserteq(tablex.compare({},{}, "=="), true) + asserteq(tablex.compare({1,2,3}, {1,2,3}, "=="), true) + asserteq(tablex.compare({1,"hello",3}, {1,2,3}, "=="), false) + asserteq(tablex.compare( + {1,2,3, hello = "world"}, + {1,2,3}, + function(v1, v2) return v1 == v2 end), + true) -- only compares the list part +end + + +-- tablex.rfind +do + local rfind = tablex.rfind + local lst = { "Rudolph", "the", "red-nose", "raindeer" } + asserteq(rfind(lst, "Santa"), nil) + asserteq(rfind(lst, "raindeer", -2), nil) + asserteq(rfind(lst, "raindeer"), 4) + asserteq(rfind(lst, "Rudolph"), 1) + asserteq(rfind(lst, "the", -3), 2) + asserteq(rfind(lst, "the", -30), nil) + asserteq(rfind({10,10,10},10), 3) +end + + +-- tablex.find_if +do + local fi = tablex.find_if + local lst = { "Rudolph", true, false, 15 } + asserteq({fi(lst, "==", "Rudolph")}, {1, true}) + asserteq({fi(lst, "==", true)}, {2, true}) + asserteq({fi(lst, "==", false)}, {3, true}) + asserteq({fi(lst, "==", 15)}, {4, true}) + + local cmp = function(v1, v2) return v1 == v2 and v2 end + asserteq({fi(lst, cmp, "Rudolph")}, {1, "Rudolph"}) + asserteq({fi(lst, cmp, true)}, {2, true}) + asserteq({fi(lst, cmp, false)}, {}) -- 'false' cannot be returned! + asserteq({fi(lst, cmp, 15)}, {4, 15}) +end + + +-- tablex.map_named_method +do + local Car = {} + Car.__index = Car + function Car.new(car) + return setmetatable(car or {}, Car) + end + Car.speed = 0 + function Car:faster(increase) + self.speed = self.speed + (increase or 1) + return self.speed + end + function Car:slower(self, decrease) + self.speed = self.speed - (decrease or 1) + return self.speed + end + + local ferrari = Car.new{ name = "Ferrari" } + local lamborghini = Car.new{ name = "Lamborghini", speed = 50 } + local cars = { ferrari, lamborghini } + + asserteq(ferrari.speed, 0) + asserteq(lamborghini.speed, 50) + asserteq(tablex.map_named_method("faster", cars, 10), {10, 60}) + asserteq(ferrari.speed, 10) + asserteq(lamborghini.speed, 60) + +end + + +-- tablex.foreach +do + local lst = { "one", "two", "three", hello = "world" } + tablex.foreach(lst, function(v, k, sep) + lst[k] = tostring(k) .. sep .. v + end, " = ") + asserteq(lst, {"1 = one", "2 = two", "3 = three", hello = "hello = world"}) +end + + +-- tablex.foreachi +do + local lst = { "one", "two", "three", hello = "world" } + tablex.foreachi(lst, function(v, k, sep) + lst[k] = tostring(k) .. sep .. v + end, " = ") + asserteq(lst, {"1 = one", "2 = two", "3 = three", hello = "world"}) +end + + +-- tablex.new +asserteq(tablex.new(3, "hi"), { "hi", "hi", "hi" }) + + +-- tablex.search +do + local t = { + penlight = { + battery = { + type = "AA", + capacity = "1500mah", + }, + }, + hello = { + world = { + also = "AA" + } + } + } + asserteq(tablex.search(t, "1500mah"), "penlight.battery.capacity") + asserteq(tablex.search(t, "AA", {t.penlight} ), "hello.world.also") + asserteq(tablex.search(t, "xxx"), nil) +end + + +-- tablex.readonly +do + local ro = tablex.readonly { 1,2,3, hello = "world" } + asserteq(pcall(function() ro.hello = "hi there" end), false) + asserteq(getmetatable(ro), false) + + if not utils.lua51 then + asserteq(#ro, 3) + + local r = {} + for k,v in pairs(ro) do r[k] = v end + asserteq(r, { 1,2,3, hello = "world" }) + + r = {} + for k,v in ipairs(ro) do r[k] = v end + asserteq(r, { 1,2,3 }) + end +end diff -Nru lua-penlight-1.7.0/tests/test-types.lua lua-penlight-1.9.2/tests/test-types.lua --- lua-penlight-1.7.0/tests/test-types.lua 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/tests/test-types.lua 2020-09-27 10:39:11.000000000 +0000 @@ -85,7 +85,16 @@ asserteq(types.is_empty(" ",true),true) asserteq(types.is_empty(" "),false) asserteq(types.is_empty(true),true) -asserteq(types.is_empty(42),true) +-- Numbers +asserteq(types.is_empty(0), true) +asserteq(types.is_empty(20), true) +-- Booleans +asserteq(types.is_empty(false), true) +asserteq(types.is_empty(true), true) +-- Functions +asserteq(types.is_empty(print), true) +-- Userdata +--asserteq(types.is_empty(newproxy()), true) --newproxy was removed in Lua 5.2 -- a more relaxed kind of truthiness.... asserteq(types.to_bool('yes'),true) diff -Nru lua-penlight-1.7.0/.travis.yml lua-penlight-1.9.2/.travis.yml --- lua-penlight-1.7.0/.travis.yml 2019-10-14 13:43:03.000000000 +0000 +++ lua-penlight-1.9.2/.travis.yml 2020-09-27 10:39:11.000000000 +0000 @@ -5,6 +5,7 @@ - LUA="lua 5.1" - LUA="lua 5.2" - LUA="lua 5.3" + - LUA="lua 5.4" - LUA="luajit 2.0" - LUA="luajit 2.0 --compat 5.2" - LUA="luajit 2.1" @@ -15,14 +16,15 @@ - hererocks here -r^ --$LUA - source here/bin/activate - luarocks install luacheck + - luarocks install luacov-coveralls install: - luarocks make - - luarocks install luacov-coveralls script: - luacheck . - lua run.lua tests --luacov + - lua run.lua examples after_success: - luacov-coveralls