rufus-lua-win 5.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +69 -0
- data/Rakefile +1 -0
- data/lib/rufus/lua/win.rb +18 -0
- data/lib/rufus/lua/win/version.rb +7 -0
- data/rufus-lua-win.gemspec +23 -0
- data/vendor/lua/bin/liblua.dll +0 -0
- data/vendor/lua/lib/lua/LuaXml.lua +119 -0
- data/vendor/lua/lib/lua/alien.lua +250 -0
- data/vendor/lua/lib/lua/alien/core.dll +0 -0
- data/vendor/lua/lib/lua/alien/struct.dll +0 -0
- data/vendor/lua/lib/lua/base.lua +536 -0
- data/vendor/lua/lib/lua/bin.lua +20 -0
- data/vendor/lua/lib/lua/bit.dll +0 -0
- data/vendor/lua/lib/lua/cdlua.dll +0 -0
- data/vendor/lua/lib/lua/cdluacontextplus.dll +0 -0
- data/vendor/lua/lib/lua/cdluagl.dll +0 -0
- data/vendor/lua/lib/lua/cdluaim.dll +0 -0
- data/vendor/lua/lib/lua/cdluapdf.dll +0 -0
- data/vendor/lua/lib/lua/copas.lua +543 -0
- data/vendor/lua/lib/lua/coxpcall.lua +57 -0
- data/vendor/lua/lib/lua/date.lua +745 -0
- data/vendor/lua/lib/lua/debug_ext.lua +84 -0
- data/vendor/lua/lib/lua/debug_init.lua +2 -0
- data/vendor/lua/lib/lua/des56.dll +0 -0
- data/vendor/lua/lib/lua/dist/config.lua +109 -0
- data/vendor/lua/lib/lua/dist/constraints.lua +271 -0
- data/vendor/lua/lib/lua/dist/depends.lua +601 -0
- data/vendor/lua/lib/lua/dist/git.lua +307 -0
- data/vendor/lua/lib/lua/dist/init.lua +278 -0
- data/vendor/lua/lib/lua/dist/manifest.lua +225 -0
- data/vendor/lua/lib/lua/dist/package.lua +583 -0
- data/vendor/lua/lib/lua/dist/sys.lua +367 -0
- data/vendor/lua/lib/lua/dist/utils.lua +130 -0
- data/vendor/lua/lib/lua/ex.dll +0 -0
- data/vendor/lua/lib/lua/fstable.lua +116 -0
- data/vendor/lua/lib/lua/getopt.lua +273 -0
- data/vendor/lua/lib/lua/git.lua +5 -0
- data/vendor/lua/lib/lua/git/core.dll +0 -0
- data/vendor/lua/lib/lua/git/objects.lua +121 -0
- data/vendor/lua/lib/lua/git/pack.lua +316 -0
- data/vendor/lua/lib/lua/git/protocol.lua +188 -0
- data/vendor/lua/lib/lua/git/repo.lua +283 -0
- data/vendor/lua/lib/lua/git/util.lua +233 -0
- data/vendor/lua/lib/lua/gzio.dll +0 -0
- data/vendor/lua/lib/lua/gzip.lua +81 -0
- data/vendor/lua/lib/lua/iconv.dll +0 -0
- data/vendor/lua/lib/lua/imlua.dll +0 -0
- data/vendor/lua/lib/lua/imlua_fftw.dll +0 -0
- data/vendor/lua/lib/lua/imlua_jp2.dll +0 -0
- data/vendor/lua/lib/lua/imlua_process.dll +0 -0
- data/vendor/lua/lib/lua/imlua_process_omp.dll +0 -0
- data/vendor/lua/lib/lua/io_ext.lua +115 -0
- data/vendor/lua/lib/lua/iuplua.dll +0 -0
- data/vendor/lua/lib/lua/iuplua_mglplot.dll +0 -0
- data/vendor/lua/lib/lua/iuplua_pplot.dll +0 -0
- data/vendor/lua/lib/lua/iupluacd.dll +0 -0
- data/vendor/lua/lib/lua/iupluacontrols.dll +0 -0
- data/vendor/lua/lib/lua/iupluagl.dll +0 -0
- data/vendor/lua/lib/lua/iupluaim.dll +0 -0
- data/vendor/lua/lib/lua/iupluaimglib.dll +0 -0
- data/vendor/lua/lib/lua/iupluatuio.dll +0 -0
- data/vendor/lua/lib/lua/lanes-keeper.lua +302 -0
- data/vendor/lua/lib/lua/lanes.lua +591 -0
- data/vendor/lua/lib/lua/lanes/core.dll +0 -0
- data/vendor/lua/lib/lua/lcs.lua +55 -0
- data/vendor/lua/lib/lua/lemock.lua +659 -0
- data/vendor/lua/lib/lua/lfs.dll +0 -0
- data/vendor/lua/lib/lua/list.lua +375 -0
- data/vendor/lua/lib/lua/logging.lua +189 -0
- data/vendor/lua/lib/lua/logging/console.lua +22 -0
- data/vendor/lua/lib/lua/logging/email.lua +44 -0
- data/vendor/lua/lib/lua/logging/file.lua +55 -0
- data/vendor/lua/lib/lua/logging/rolling_file.lua +81 -0
- data/vendor/lua/lib/lua/logging/socket.lua +35 -0
- data/vendor/lua/lib/lua/logging/sql.lua +64 -0
- data/vendor/lua/lib/lua/loop/base.lua +68 -0
- data/vendor/lua/lib/lua/loop/cached.lua +312 -0
- data/vendor/lua/lib/lua/loop/collection/MapWithArrayOfKeys.lua +64 -0
- data/vendor/lua/lib/lua/loop/collection/ObjectCache.lua +39 -0
- data/vendor/lua/lib/lua/loop/collection/OrderedSet.lua +164 -0
- data/vendor/lua/lib/lua/loop/collection/PriorityQueue.lua +86 -0
- data/vendor/lua/lib/lua/loop/collection/UnorderedArray.lua +32 -0
- data/vendor/lua/lib/lua/loop/collection/UnorderedArraySet.lua +56 -0
- data/vendor/lua/lib/lua/loop/compiler/Arguments.lua +108 -0
- data/vendor/lua/lib/lua/loop/compiler/Conditional.lua +50 -0
- data/vendor/lua/lib/lua/loop/compiler/Expression.lua +215 -0
- data/vendor/lua/lib/lua/loop/component/base.lua +221 -0
- data/vendor/lua/lib/lua/loop/component/contained.lua +71 -0
- data/vendor/lua/lib/lua/loop/component/dynamic.lua +223 -0
- data/vendor/lua/lib/lua/loop/component/intercepted.lua +354 -0
- data/vendor/lua/lib/lua/loop/component/wrapped.lua +195 -0
- data/vendor/lua/lib/lua/loop/debug/Inspector.lua +521 -0
- data/vendor/lua/lib/lua/loop/debug/Matcher.lua +192 -0
- data/vendor/lua/lib/lua/loop/debug/Verbose.lua +266 -0
- data/vendor/lua/lib/lua/loop/debug/Viewer.lua +200 -0
- data/vendor/lua/lib/lua/loop/multiple.lua +105 -0
- data/vendor/lua/lib/lua/loop/object/Exception.lua +57 -0
- data/vendor/lua/lib/lua/loop/object/Publisher.lua +43 -0
- data/vendor/lua/lib/lua/loop/object/Wrapper.lua +39 -0
- data/vendor/lua/lib/lua/loop/scoped.lua +585 -0
- data/vendor/lua/lib/lua/loop/serial/FileStream.lua +48 -0
- data/vendor/lua/lib/lua/loop/serial/Serializer.lua +291 -0
- data/vendor/lua/lib/lua/loop/serial/SocketStream.lua +51 -0
- data/vendor/lua/lib/lua/loop/serial/StringStream.lua +47 -0
- data/vendor/lua/lib/lua/loop/simple.lua +75 -0
- data/vendor/lua/lib/lua/loop/table.lua +71 -0
- data/vendor/lua/lib/lua/loop/thread/CoSocket.lua +416 -0
- data/vendor/lua/lib/lua/loop/thread/IOScheduler.lua +170 -0
- data/vendor/lua/lib/lua/loop/thread/Scheduler.lua +327 -0
- data/vendor/lua/lib/lua/loop/thread/SocketScheduler.lua +88 -0
- data/vendor/lua/lib/lua/loop/thread/Timer.lua +54 -0
- data/vendor/lua/lib/lua/lpeg.dll +0 -0
- data/vendor/lua/lib/lua/ltn12.lua +292 -0
- data/vendor/lua/lib/lua/luaXML_lib.dll +0 -0
- data/vendor/lua/lib/lua/luacurl.dll +0 -0
- data/vendor/lua/lib/lua/luadoc/config.lua +34 -0
- data/vendor/lua/lib/lua/luadoc/doclet/debug.lua +46 -0
- data/vendor/lua/lib/lua/luadoc/doclet/formatter.lua +84 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html.lua +289 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html/file.lp +113 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html/function.lp +64 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html/index.lp +70 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html/luadoc.css +286 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html/menu.lp +55 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html/module.lp +109 -0
- data/vendor/lua/lib/lua/luadoc/doclet/html/table.lp +15 -0
- data/vendor/lua/lib/lua/luadoc/doclet/raw.lua +12 -0
- data/vendor/lua/lib/lua/luadoc/init.lua +58 -0
- data/vendor/lua/lib/lua/luadoc/lp.lua +130 -0
- data/vendor/lua/lib/lua/luadoc/taglet/standard.lua +495 -0
- data/vendor/lua/lib/lua/luadoc/taglet/standard/tags.lua +171 -0
- data/vendor/lua/lib/lua/luadoc/util.lua +233 -0
- data/vendor/lua/lib/lua/luagl.dll +0 -0
- data/vendor/lua/lib/lua/luaglu.dll +0 -0
- data/vendor/lua/lib/lua/luaidl.lua +113 -0
- data/vendor/lua/lib/lua/luaidl/lex.lua +793 -0
- data/vendor/lua/lib/lua/luaidl/pre.lua +149 -0
- data/vendor/lua/lib/lua/luaidl/sin.lua +3631 -0
- data/vendor/lua/lib/lua/luarocks/add.lua +108 -0
- data/vendor/lua/lib/lua/luarocks/admin_remove.lua +87 -0
- data/vendor/lua/lib/lua/luarocks/build.lua +330 -0
- data/vendor/lua/lib/lua/luarocks/build/builtin.lua +253 -0
- data/vendor/lua/lib/lua/luarocks/build/cmake.lua +54 -0
- data/vendor/lua/lib/lua/luarocks/build/command.lua +32 -0
- data/vendor/lua/lib/lua/luarocks/build/make.lua +92 -0
- data/vendor/lua/lib/lua/luarocks/cache.lua +85 -0
- data/vendor/lua/lib/lua/luarocks/cfg.lua +449 -0
- data/vendor/lua/lib/lua/luarocks/command_line.lua +163 -0
- data/vendor/lua/lib/lua/luarocks/deps.lua +654 -0
- data/vendor/lua/lib/lua/luarocks/dir.lua +69 -0
- data/vendor/lua/lib/lua/luarocks/download.lua +90 -0
- data/vendor/lua/lib/lua/luarocks/fetch.lua +321 -0
- data/vendor/lua/lib/lua/luarocks/fetch/cvs.lua +44 -0
- data/vendor/lua/lib/lua/luarocks/fetch/git.lua +81 -0
- data/vendor/lua/lib/lua/luarocks/fetch/git_file.lua +17 -0
- data/vendor/lua/lib/lua/luarocks/fetch/hg.lua +54 -0
- data/vendor/lua/lib/lua/luarocks/fetch/sscm.lua +42 -0
- data/vendor/lua/lib/lua/luarocks/fetch/svn.lua +53 -0
- data/vendor/lua/lib/lua/luarocks/fs.lua +40 -0
- data/vendor/lua/lib/lua/luarocks/fs/lua.lua +676 -0
- data/vendor/lua/lib/lua/luarocks/fs/unix.lua +88 -0
- data/vendor/lua/lib/lua/luarocks/fs/unix/tools.lua +325 -0
- data/vendor/lua/lib/lua/luarocks/fs/win32.lua +107 -0
- data/vendor/lua/lib/lua/luarocks/fs/win32/tools.lua +334 -0
- data/vendor/lua/lib/lua/luarocks/help.lua +101 -0
- data/vendor/lua/lib/lua/luarocks/index.lua +172 -0
- data/vendor/lua/lib/lua/luarocks/install.lua +151 -0
- data/vendor/lua/lib/lua/luarocks/list.lua +35 -0
- data/vendor/lua/lib/lua/luarocks/loader.lua +228 -0
- data/vendor/lua/lib/lua/luarocks/make.lua +71 -0
- data/vendor/lua/lib/lua/luarocks/make_manifest.lua +34 -0
- data/vendor/lua/lib/lua/luarocks/manif.lua +360 -0
- data/vendor/lua/lib/lua/luarocks/manif_core.lua +75 -0
- data/vendor/lua/lib/lua/luarocks/new_version.lua +141 -0
- data/vendor/lua/lib/lua/luarocks/pack.lua +205 -0
- data/vendor/lua/lib/lua/luarocks/path.lua +315 -0
- data/vendor/lua/lib/lua/luarocks/persist.lua +173 -0
- data/vendor/lua/lib/lua/luarocks/refresh_cache.lua +30 -0
- data/vendor/lua/lib/lua/luarocks/remove.lua +135 -0
- data/vendor/lua/lib/lua/luarocks/rep.lua +313 -0
- data/vendor/lua/lib/lua/luarocks/require.lua +6 -0
- data/vendor/lua/lib/lua/luarocks/search.lua +399 -0
- data/vendor/lua/lib/lua/luarocks/show.lua +138 -0
- data/vendor/lua/lib/lua/luarocks/site_config.lua +23 -0
- data/vendor/lua/lib/lua/luarocks/tools/patch.lua +712 -0
- data/vendor/lua/lib/lua/luarocks/tools/tar.lua +144 -0
- data/vendor/lua/lib/lua/luarocks/tools/zip.lua +245 -0
- data/vendor/lua/lib/lua/luarocks/type_check.lua +267 -0
- data/vendor/lua/lib/lua/luarocks/unpack.lua +151 -0
- data/vendor/lua/lib/lua/luarocks/util.lua +420 -0
- data/vendor/lua/lib/lua/luarocks/validate.lua +164 -0
- data/vendor/lua/lib/lua/luars232.dll +0 -0
- data/vendor/lua/lib/lua/luasql/mysql.dll +0 -0
- data/vendor/lua/lib/lua/luasql/postgres.dll +0 -0
- data/vendor/lua/lib/lua/luasql/sqlite3.dll +0 -0
- data/vendor/lua/lib/lua/luaunit.lua +601 -0
- data/vendor/lua/lib/lua/lxp.dll +0 -0
- data/vendor/lua/lib/lua/lxp/lom.lua +60 -0
- data/vendor/lua/lib/lua/math_ext.lua +27 -0
- data/vendor/lua/lib/lua/mbox.lua +53 -0
- data/vendor/lua/lib/lua/md5.lua +19 -0
- data/vendor/lua/lib/lua/md5/core.dll +0 -0
- data/vendor/lua/lib/lua/metalua.lua +0 -0
- data/vendor/lua/lib/lua/metalua/ast_to_string.mlua +553 -0
- data/vendor/lua/lib/lua/metalua/base.lua +104 -0
- data/vendor/lua/lib/lua/metalua/bytecode.lua +0 -0
- data/vendor/lua/lib/lua/metalua/clopts.mlua +204 -0
- data/vendor/lua/lib/lua/metalua/compiler.lua +3 -0
- data/vendor/lua/lib/lua/metalua/dollar.mlua +24 -0
- data/vendor/lua/lib/lua/metalua/extension/H-runtime.mlua +216 -0
- data/vendor/lua/lib/lua/metalua/extension/H.mlua +22 -0
- data/vendor/lua/lib/lua/metalua/extension/anaphoric.mlua +54 -0
- data/vendor/lua/lib/lua/metalua/extension/clist.mlua +149 -0
- data/vendor/lua/lib/lua/metalua/extension/continue.mlua +53 -0
- data/vendor/lua/lib/lua/metalua/extension/localin.mlua +2 -0
- data/vendor/lua/lib/lua/metalua/extension/log.mlua +39 -0
- data/vendor/lua/lib/lua/metalua/extension/match.mlua +374 -0
- data/vendor/lua/lib/lua/metalua/extension/ternary.mlua +10 -0
- data/vendor/lua/lib/lua/metalua/extension/trycatch.mlua +189 -0
- data/vendor/lua/lib/lua/metalua/extension/types-runtime.mlua +159 -0
- data/vendor/lua/lib/lua/metalua/extension/types.mlua +352 -0
- data/vendor/lua/lib/lua/metalua/extension/withdo.mlua +30 -0
- data/vendor/lua/lib/lua/metalua/extension/xglobal-runtime.lua +41 -0
- data/vendor/lua/lib/lua/metalua/extension/xglobal.mlua +20 -0
- data/vendor/lua/lib/lua/metalua/extension/xloop.mlua +100 -0
- data/vendor/lua/lib/lua/metalua/extension/xmatch.mlua +216 -0
- data/vendor/lua/lib/lua/metalua/metaloop.mlua +76 -0
- data/vendor/lua/lib/lua/metalua/mlc.lua +0 -0
- data/vendor/lua/lib/lua/metalua/mlc_xcall.lua +119 -0
- data/vendor/lua/lib/lua/metalua/mlp.lua +0 -0
- data/vendor/lua/lib/lua/metalua/package2.lua +101 -0
- data/vendor/lua/lib/lua/metalua/runtime.lua +3 -0
- data/vendor/lua/lib/lua/metalua/string2.lua +44 -0
- data/vendor/lua/lib/lua/metalua/table2.lua +372 -0
- data/vendor/lua/lib/lua/metalua/walk.mlua +304 -0
- data/vendor/lua/lib/lua/metalua/walk/bindings.mlua +41 -0
- data/vendor/lua/lib/lua/metalua/walk/id.mlua +186 -0
- data/vendor/lua/lib/lua/metalua/walk/scope.lua +54 -0
- data/vendor/lua/lib/lua/mime.lua +87 -0
- data/vendor/lua/lib/lua/mime/core.dll +0 -0
- data/vendor/lua/lib/lua/mobdebug.lua +1484 -0
- data/vendor/lua/lib/lua/modules.lua +16 -0
- data/vendor/lua/lib/lua/object.lua +56 -0
- data/vendor/lua/lib/lua/oil/Exception.lua +26 -0
- data/vendor/lua/lib/lua/oil/arch.lua +27 -0
- data/vendor/lua/lib/lua/oil/arch/basic/client.lua +29 -0
- data/vendor/lua/lib/lua/oil/arch/basic/common.lua +13 -0
- data/vendor/lua/lib/lua/oil/arch/basic/server.lua +27 -0
- data/vendor/lua/lib/lua/oil/arch/cooperative/common.lua +10 -0
- data/vendor/lua/lib/lua/oil/arch/cooperative/server.lua +16 -0
- data/vendor/lua/lib/lua/oil/arch/corba/client.lua +39 -0
- data/vendor/lua/lib/lua/oil/arch/corba/common.lua +58 -0
- data/vendor/lua/lib/lua/oil/arch/corba/intercepted/client.lua +9 -0
- data/vendor/lua/lib/lua/oil/arch/corba/intercepted/server.lua +9 -0
- data/vendor/lua/lib/lua/oil/arch/corba/server.lua +35 -0
- data/vendor/lua/lib/lua/oil/arch/ludo/byref.lua +18 -0
- data/vendor/lua/lib/lua/oil/arch/ludo/client.lua +19 -0
- data/vendor/lua/lib/lua/oil/arch/ludo/common.lua +18 -0
- data/vendor/lua/lib/lua/oil/arch/ludo/server.lua +19 -0
- data/vendor/lua/lib/lua/oil/arch/typed/client.lua +27 -0
- data/vendor/lua/lib/lua/oil/arch/typed/common.lua +9 -0
- data/vendor/lua/lib/lua/oil/arch/typed/server.lua +18 -0
- data/vendor/lua/lib/lua/oil/assert.lua +87 -0
- data/vendor/lua/lib/lua/oil/builder.lua +45 -0
- data/vendor/lua/lib/lua/oil/builder/basic/client.lua +31 -0
- data/vendor/lua/lib/lua/oil/builder/basic/common.lua +11 -0
- data/vendor/lua/lib/lua/oil/builder/basic/server.lua +13 -0
- data/vendor/lua/lib/lua/oil/builder/cooperative/common.lua +11 -0
- data/vendor/lua/lib/lua/oil/builder/cooperative/server.lua +11 -0
- data/vendor/lua/lib/lua/oil/builder/corba/client.lua +13 -0
- data/vendor/lua/lib/lua/oil/builder/corba/common.lua +24 -0
- data/vendor/lua/lib/lua/oil/builder/corba/gencode.lua +13 -0
- data/vendor/lua/lib/lua/oil/builder/corba/intercepted/client.lua +11 -0
- data/vendor/lua/lib/lua/oil/builder/corba/intercepted/server.lua +11 -0
- data/vendor/lua/lib/lua/oil/builder/corba/server.lua +13 -0
- data/vendor/lua/lib/lua/oil/builder/lua/client.lua +11 -0
- data/vendor/lua/lib/lua/oil/builder/lua/server.lua +12 -0
- data/vendor/lua/lib/lua/oil/builder/ludo/byref.lua +13 -0
- data/vendor/lua/lib/lua/oil/builder/ludo/client.lua +13 -0
- data/vendor/lua/lib/lua/oil/builder/ludo/common.lua +14 -0
- data/vendor/lua/lib/lua/oil/builder/ludo/server.lua +13 -0
- data/vendor/lua/lib/lua/oil/builder/typed/client.lua +16 -0
- data/vendor/lua/lib/lua/oil/builder/typed/server.lua +12 -0
- data/vendor/lua/lib/lua/oil/compat.lua +846 -0
- data/vendor/lua/lib/lua/oil/component.lua +1 -0
- data/vendor/lua/lib/lua/oil/corba/giop.lua +301 -0
- data/vendor/lua/lib/lua/oil/corba/giop/Codec.lua +1568 -0
- data/vendor/lua/lib/lua/oil/corba/giop/CodecGen.lua +589 -0
- data/vendor/lua/lib/lua/oil/corba/giop/Exception.lua +25 -0
- data/vendor/lua/lib/lua/oil/corba/giop/Indexer.lua +63 -0
- data/vendor/lua/lib/lua/oil/corba/giop/Listener.lua +343 -0
- data/vendor/lua/lib/lua/oil/corba/giop/Messenger.lua +228 -0
- data/vendor/lua/lib/lua/oil/corba/giop/Referrer.lua +180 -0
- data/vendor/lua/lib/lua/oil/corba/giop/Requester.lua +462 -0
- data/vendor/lua/lib/lua/oil/corba/idl.lua +597 -0
- data/vendor/lua/lib/lua/oil/corba/idl/Compiler.lua +133 -0
- data/vendor/lua/lib/lua/oil/corba/idl/Importer.lua +235 -0
- data/vendor/lua/lib/lua/oil/corba/idl/Indexer.lua +95 -0
- data/vendor/lua/lib/lua/oil/corba/idl/Registry.lua +1821 -0
- data/vendor/lua/lib/lua/oil/corba/idl/ir.lua +847 -0
- data/vendor/lua/lib/lua/oil/corba/idl/sysex.lua +21 -0
- data/vendor/lua/lib/lua/oil/corba/iiop/Profiler.lua +200 -0
- data/vendor/lua/lib/lua/oil/corba/intercepted/Listener.lua +158 -0
- data/vendor/lua/lib/lua/oil/corba/intercepted/Requester.lua +181 -0
- data/vendor/lua/lib/lua/oil/corba/services/event.lua +126 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/ConsumerAdmin.lua +50 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/EventFactory.lua +15 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/EventQueue.lua +37 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/ProxyPushConsumer.lua +75 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/ProxyPushSupplier.lua +62 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/SingleDeferredDispatcher.lua +60 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/SingleSynchronousDispatcher.lua +39 -0
- data/vendor/lua/lib/lua/oil/corba/services/event/SupplierAdmin.lua +50 -0
- data/vendor/lua/lib/lua/oil/corba/services/naming.lua +436 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Acceptor.lua +268 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Channels.lua +121 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Connector.lua +147 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Dispatcher.lua +99 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Proxies.lua +86 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Proxies/asynchronous.lua +56 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Proxies/protected.lua +17 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Proxies/synchronous.lua +17 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Proxies/utils.lua +29 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Receiver.lua +110 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Servants.lua +207 -0
- data/vendor/lua/lib/lua/oil/kernel/base/Sockets.lua +44 -0
- data/vendor/lua/lib/lua/oil/kernel/cooperative/Receiver.lua +139 -0
- data/vendor/lua/lib/lua/oil/kernel/intercepted/Listener.lua +47 -0
- data/vendor/lua/lib/lua/oil/kernel/intercepted/Requester.lua +58 -0
- data/vendor/lua/lib/lua/oil/kernel/lua/Dispatcher.lua +76 -0
- data/vendor/lua/lib/lua/oil/kernel/lua/Proxies.lua +69 -0
- data/vendor/lua/lib/lua/oil/kernel/typed/Dispatcher.lua +91 -0
- data/vendor/lua/lib/lua/oil/kernel/typed/Proxies.lua +153 -0
- data/vendor/lua/lib/lua/oil/kernel/typed/Servants.lua +137 -0
- data/vendor/lua/lib/lua/oil/ludo/Codec.lua +66 -0
- data/vendor/lua/lib/lua/oil/ludo/CodecByRef.lua +103 -0
- data/vendor/lua/lib/lua/oil/ludo/Listener.lua +151 -0
- data/vendor/lua/lib/lua/oil/ludo/Referrer.lua +72 -0
- data/vendor/lua/lib/lua/oil/ludo/Requester.lua +107 -0
- data/vendor/lua/lib/lua/oil/oo.lua +1 -0
- data/vendor/lua/lib/lua/oil/port.lua +1 -0
- data/vendor/lua/lib/lua/oil/properties.lua +57 -0
- data/vendor/lua/lib/lua/oil/verbose.lua +133 -0
- data/vendor/lua/lib/lua/package_ext.lua +15 -0
- data/vendor/lua/lib/lua/parser.lua +268 -0
- data/vendor/lua/lib/lua/pl/Date.lua +555 -0
- data/vendor/lua/lib/lua/pl/List.lua +613 -0
- data/vendor/lua/lib/lua/pl/Map.lua +113 -0
- data/vendor/lua/lib/lua/pl/MultiMap.lua +62 -0
- data/vendor/lua/lib/lua/pl/OrderedMap.lua +151 -0
- data/vendor/lua/lib/lua/pl/Set.lua +153 -0
- data/vendor/lua/lib/lua/pl/app.lua +165 -0
- data/vendor/lua/lib/lua/pl/array2d.lua +501 -0
- data/vendor/lua/lib/lua/pl/class.lua +180 -0
- data/vendor/lua/lib/lua/pl/comprehension.lua +286 -0
- data/vendor/lua/lib/lua/pl/config.lua +176 -0
- data/vendor/lua/lib/lua/pl/data.lua +606 -0
- data/vendor/lua/lib/lua/pl/dir.lua +475 -0
- data/vendor/lua/lib/lua/pl/file.lua +70 -0
- data/vendor/lua/lib/lua/pl/func.lua +376 -0
- data/vendor/lua/lib/lua/pl/init.lua +68 -0
- data/vendor/lua/lib/lua/pl/input.lua +173 -0
- data/vendor/lua/lib/lua/pl/lapp.lua +407 -0
- data/vendor/lua/lib/lua/pl/lexer.lua +456 -0
- data/vendor/lua/lib/lua/pl/luabalanced.lua +264 -0
- data/vendor/lua/lib/lua/pl/operator.lua +201 -0
- data/vendor/lua/lib/lua/pl/path.lua +398 -0
- data/vendor/lua/lib/lua/pl/permute.lua +63 -0
- data/vendor/lua/lib/lua/pl/platf/luajava.lua +101 -0
- data/vendor/lua/lib/lua/pl/pretty.lua +285 -0
- data/vendor/lua/lib/lua/pl/seq.lua +551 -0
- data/vendor/lua/lib/lua/pl/sip.lua +344 -0
- data/vendor/lua/lib/lua/pl/strict.lua +70 -0
- data/vendor/lua/lib/lua/pl/stringio.lua +158 -0
- data/vendor/lua/lib/lua/pl/stringx.lua +440 -0
- data/vendor/lua/lib/lua/pl/tablex.lua +817 -0
- data/vendor/lua/lib/lua/pl/template.lua +103 -0
- data/vendor/lua/lib/lua/pl/test.lua +135 -0
- data/vendor/lua/lib/lua/pl/text.lua +243 -0
- data/vendor/lua/lib/lua/pl/utils.lua +550 -0
- data/vendor/lua/lib/lua/pl/xml.lua +689 -0
- data/vendor/lua/lib/lua/profiler.dll +0 -0
- data/vendor/lua/lib/lua/re.lua +248 -0
- data/vendor/lua/lib/lua/rex_onig.dll +0 -0
- data/vendor/lua/lib/lua/rex_pcre.dll +0 -0
- data/vendor/lua/lib/lua/rex_posix.dll +0 -0
- data/vendor/lua/lib/lua/rings.dll +0 -0
- data/vendor/lua/lib/lua/serialize.lua +193 -0
- data/vendor/lua/lib/lua/set.lua +149 -0
- data/vendor/lua/lib/lua/socket.lua +133 -0
- data/vendor/lua/lib/lua/socket/core.dll +0 -0
- data/vendor/lua/lib/lua/socket/ftp.lua +281 -0
- data/vendor/lua/lib/lua/socket/http.lua +350 -0
- data/vendor/lua/lib/lua/socket/smtp.lua +251 -0
- data/vendor/lua/lib/lua/socket/tp.lua +123 -0
- data/vendor/lua/lib/lua/socket/url.lua +297 -0
- data/vendor/lua/lib/lua/ssl.dll +0 -0
- data/vendor/lua/lib/lua/ssl.lua +93 -0
- data/vendor/lua/lib/lua/ssl/https.lua +138 -0
- data/vendor/lua/lib/lua/stable.lua +28 -0
- data/vendor/lua/lib/lua/std.lua +16 -0
- data/vendor/lua/lib/lua/strbuf.lua +32 -0
- data/vendor/lua/lib/lua/strict.lua +45 -0
- data/vendor/lua/lib/lua/string_ext.lua +274 -0
- data/vendor/lua/lib/lua/table_ext.lua +117 -0
- data/vendor/lua/lib/lua/tar.lua +262 -0
- data/vendor/lua/lib/lua/task.dll +0 -0
- data/vendor/lua/lib/lua/tree.lua +81 -0
- data/vendor/lua/lib/lua/unicode.dll +0 -0
- data/vendor/lua/lib/lua/verbose_require.lua +11 -0
- data/vendor/lua/lib/lua/vstruct.lua +86 -0
- data/vendor/lua/lib/lua/vstruct/ast.lua +192 -0
- data/vendor/lua/lib/lua/vstruct/ast/Bitpack.lua +33 -0
- data/vendor/lua/lib/lua/vstruct/ast/Generator.lua +174 -0
- data/vendor/lua/lib/lua/vstruct/ast/IO.lua +45 -0
- data/vendor/lua/lib/lua/vstruct/ast/List.lua +56 -0
- data/vendor/lua/lib/lua/vstruct/ast/Name.lua +20 -0
- data/vendor/lua/lib/lua/vstruct/ast/Repeat.lua +23 -0
- data/vendor/lua/lib/lua/vstruct/ast/Root.lua +19 -0
- data/vendor/lua/lib/lua/vstruct/ast/Table.lua +65 -0
- data/vendor/lua/lib/lua/vstruct/cursor.lua +81 -0
- data/vendor/lua/lib/lua/vstruct/io.lua +45 -0
- data/vendor/lua/lib/lua/vstruct/io/a.lua +24 -0
- data/vendor/lua/lib/lua/vstruct/io/b.lua +28 -0
- data/vendor/lua/lib/lua/vstruct/io/bigendian.lua +21 -0
- data/vendor/lua/lib/lua/vstruct/io/c.lua +25 -0
- data/vendor/lua/lib/lua/vstruct/io/defaults.lua +24 -0
- data/vendor/lua/lib/lua/vstruct/io/endianness.lua +41 -0
- data/vendor/lua/lib/lua/vstruct/io/f.lua +129 -0
- data/vendor/lua/lib/lua/vstruct/io/hostendian.lua +21 -0
- data/vendor/lua/lib/lua/vstruct/io/i.lua +42 -0
- data/vendor/lua/lib/lua/vstruct/io/littleendian.lua +21 -0
- data/vendor/lua/lib/lua/vstruct/io/m.lua +62 -0
- data/vendor/lua/lib/lua/vstruct/io/p.lua +23 -0
- data/vendor/lua/lib/lua/vstruct/io/s.lua +27 -0
- data/vendor/lua/lib/lua/vstruct/io/seekb.lua +18 -0
- data/vendor/lua/lib/lua/vstruct/io/seekf.lua +18 -0
- data/vendor/lua/lib/lua/vstruct/io/seekto.lua +18 -0
- data/vendor/lua/lib/lua/vstruct/io/u.lua +54 -0
- data/vendor/lua/lib/lua/vstruct/io/x.lua +34 -0
- data/vendor/lua/lib/lua/vstruct/io/z.lua +63 -0
- data/vendor/lua/lib/lua/vstruct/lexer.lua +100 -0
- data/vendor/lua/lib/lua/vstruct/pack.lua +142 -0
- data/vendor/lua/lib/lua/vstruct/test.lua +47 -0
- data/vendor/lua/lib/lua/vstruct/test/basic.lua +73 -0
- data/vendor/lua/lib/lua/vstruct/test/common.lua +100 -0
- data/vendor/lua/lib/lua/vstruct/test/fp-bigendian.lua +56 -0
- data/vendor/lua/lib/lua/vstruct/test/fp-littleendian.lua +56 -0
- data/vendor/lua/lib/lua/vstruct/test/struct-test-gen.lua +1230 -0
- data/vendor/lua/lib/lua/vstruct/unpack.lua +126 -0
- data/vendor/lua/lib/lua/wx.dll +0 -0
- data/vendor/lua/lib/lua/xml.lua +75 -0
- data/vendor/lua/lib/lua/zip.dll +0 -0
- data/vendor/lua/lib/lua/zlib.dll +0 -0
- metadata +529 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
--- Python-style extended string library.
|
|
2
|
+
--
|
|
3
|
+
-- see 3.6.1 of the Python reference.
|
|
4
|
+
-- If you want to make these available as string methods, then say
|
|
5
|
+
-- `stringx.import()` to bring them into the standard `string` table.
|
|
6
|
+
--
|
|
7
|
+
-- See @{03-strings.md|the Guide}
|
|
8
|
+
--
|
|
9
|
+
-- Dependencies: `pl.utils`
|
|
10
|
+
-- @module pl.stringx
|
|
11
|
+
local utils = require 'pl.utils'
|
|
12
|
+
local string = string
|
|
13
|
+
local find = string.find
|
|
14
|
+
local type,setmetatable,getmetatable,ipairs,unpack = type,setmetatable,getmetatable,ipairs,unpack
|
|
15
|
+
local error,tostring = error,tostring
|
|
16
|
+
local gsub = string.gsub
|
|
17
|
+
local rep = string.rep
|
|
18
|
+
local sub = string.sub
|
|
19
|
+
local concat = table.concat
|
|
20
|
+
local escape = utils.escape
|
|
21
|
+
local ceil = math.ceil
|
|
22
|
+
local _G = _G
|
|
23
|
+
local assert_arg,usplit,list_MT = utils.assert_arg,utils.split,utils.stdmt.List
|
|
24
|
+
local lstrip
|
|
25
|
+
|
|
26
|
+
local function assert_string (n,s)
|
|
27
|
+
assert_arg(n,s,'string')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
local function non_empty(s)
|
|
31
|
+
return #s > 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
local function assert_nonempty_string(n,s)
|
|
35
|
+
assert_arg(n,s,'string',non_empty,'must be a non-empty string')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
local stringx = {}
|
|
39
|
+
|
|
40
|
+
--- does s only contain alphabetic characters?.
|
|
41
|
+
-- @param s a string
|
|
42
|
+
function stringx.isalpha(s)
|
|
43
|
+
assert_string(1,s)
|
|
44
|
+
return find(s,'^%a+$') == 1
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
--- does s only contain digits?.
|
|
48
|
+
-- @param s a string
|
|
49
|
+
function stringx.isdigit(s)
|
|
50
|
+
assert_string(1,s)
|
|
51
|
+
return find(s,'^%d+$') == 1
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
--- does s only contain alphanumeric characters?.
|
|
55
|
+
-- @param s a string
|
|
56
|
+
function stringx.isalnum(s)
|
|
57
|
+
assert_string(1,s)
|
|
58
|
+
return find(s,'^%w+$') == 1
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
--- does s only contain spaces?.
|
|
62
|
+
-- @param s a string
|
|
63
|
+
function stringx.isspace(s)
|
|
64
|
+
assert_string(1,s)
|
|
65
|
+
return find(s,'^%s+$') == 1
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
--- does s only contain lower case characters?.
|
|
69
|
+
-- @param s a string
|
|
70
|
+
function stringx.islower(s)
|
|
71
|
+
assert_string(1,s)
|
|
72
|
+
return find(s,'^[%l%s]+$') == 1
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
--- does s only contain upper case characters?.
|
|
76
|
+
-- @param s a string
|
|
77
|
+
function stringx.isupper(s)
|
|
78
|
+
assert_string(1,s)
|
|
79
|
+
return find(s,'^[%u%s]+$') == 1
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
--- concatenate the strings using this string as a delimiter.
|
|
83
|
+
-- @param self the string
|
|
84
|
+
-- @param seq a table of strings or numbers
|
|
85
|
+
-- @usage (' '):join {1,2,3} == '1 2 3'
|
|
86
|
+
function stringx.join (self,seq)
|
|
87
|
+
assert_string(1,self)
|
|
88
|
+
return concat(seq,self)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
--- does string start with the substring?.
|
|
92
|
+
-- @param self the string
|
|
93
|
+
-- @param s2 a string
|
|
94
|
+
function stringx.startswith(self,s2)
|
|
95
|
+
assert_string(1,self)
|
|
96
|
+
assert_string(2,s2)
|
|
97
|
+
return find(self,s2,1,true) == 1
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
local function _find_all(s,sub,first,last)
|
|
101
|
+
if sub == '' then return #s+1,#s end
|
|
102
|
+
local i1,i2 = find(s,sub,first,true)
|
|
103
|
+
local res
|
|
104
|
+
local k = 0
|
|
105
|
+
while i1 do
|
|
106
|
+
res = i1
|
|
107
|
+
k = k + 1
|
|
108
|
+
i1,i2 = find(s,sub,i2+1,true)
|
|
109
|
+
if last and i1 > last then break end
|
|
110
|
+
end
|
|
111
|
+
return res,k
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
--- does string end with the given substring?.
|
|
115
|
+
-- @param s a string
|
|
116
|
+
-- @param send a substring or a table of suffixes
|
|
117
|
+
function stringx.endswith(s,send)
|
|
118
|
+
assert_string(1,s)
|
|
119
|
+
if type(send) == 'string' then
|
|
120
|
+
return #s >= #send and s:find(send, #s-#send+1, true) and true or false
|
|
121
|
+
elseif type(send) == 'table' then
|
|
122
|
+
local endswith = stringx.endswith
|
|
123
|
+
for _,suffix in ipairs(send) do
|
|
124
|
+
if endswith(s,suffix) then return true end
|
|
125
|
+
end
|
|
126
|
+
return false
|
|
127
|
+
else
|
|
128
|
+
error('argument #2: either a substring or a table of suffixes expected')
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
-- break string into a list of lines
|
|
133
|
+
-- @param self the string
|
|
134
|
+
-- @param keepends (currently not used)
|
|
135
|
+
function stringx.splitlines (self,keepends)
|
|
136
|
+
assert_string(1,self)
|
|
137
|
+
local res = usplit(self,'[\r\n]')
|
|
138
|
+
-- we are currently hacking around a problem with utils.split (see stringx.split)
|
|
139
|
+
if #res == 0 then res = {''} end
|
|
140
|
+
return setmetatable(res,list_MT)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
local function tab_expand (self,n)
|
|
144
|
+
return (gsub(self,'([^\t]*)\t', function(s)
|
|
145
|
+
return s..(' '):rep(n - #s % n)
|
|
146
|
+
end))
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
--- replace all tabs in s with n spaces. If not specified, n defaults to 8.
|
|
150
|
+
-- with 0.9.5 this now correctly expands to the next tab stop (if you really
|
|
151
|
+
-- want to just replace tabs, use :gsub('\t',' ') etc)
|
|
152
|
+
-- @param self the string
|
|
153
|
+
-- @param n number of spaces to expand each tab, (default 8)
|
|
154
|
+
function stringx.expandtabs(self,n)
|
|
155
|
+
assert_string(1,self)
|
|
156
|
+
n = n or 8
|
|
157
|
+
if not self:find '\n' then return tab_expand(self,n) end
|
|
158
|
+
local res,i = {},1
|
|
159
|
+
for line in stringx.lines(self) do
|
|
160
|
+
res[i] = tab_expand(line,n)
|
|
161
|
+
i = i + 1
|
|
162
|
+
end
|
|
163
|
+
return table.concat(res,'\n')
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
--- find index of first instance of sub in s from the left.
|
|
167
|
+
-- @param self the string
|
|
168
|
+
-- @param sub substring
|
|
169
|
+
-- @param i1 start index
|
|
170
|
+
function stringx.lfind(self,sub,i1)
|
|
171
|
+
assert_string(1,self)
|
|
172
|
+
assert_string(2,sub)
|
|
173
|
+
local idx = find(self,sub,i1,true)
|
|
174
|
+
if idx then return idx else return nil end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
--- find index of first instance of sub in s from the right.
|
|
178
|
+
-- @param self the string
|
|
179
|
+
-- @param sub substring
|
|
180
|
+
-- @param first first index
|
|
181
|
+
-- @param last last index
|
|
182
|
+
function stringx.rfind(self,sub,first,last)
|
|
183
|
+
assert_string(1,self)
|
|
184
|
+
assert_string(2,sub)
|
|
185
|
+
local idx = _find_all(self,sub,first,last)
|
|
186
|
+
if idx then return idx else return nil end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
--- replace up to n instances of old by new in the string s.
|
|
190
|
+
-- if n is not present, replace all instances.
|
|
191
|
+
-- @param s the string
|
|
192
|
+
-- @param old the target substring
|
|
193
|
+
-- @param new the substitution
|
|
194
|
+
-- @param n optional maximum number of substitutions
|
|
195
|
+
-- @return result string
|
|
196
|
+
-- @return the number of substitutions
|
|
197
|
+
function stringx.replace(s,old,new,n)
|
|
198
|
+
assert_string(1,s)
|
|
199
|
+
assert_string(1,old)
|
|
200
|
+
return (gsub(s,escape(old),new:gsub('%%','%%%%'),n))
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
--- split a string into a list of strings using a delimiter.
|
|
204
|
+
-- @class function
|
|
205
|
+
-- @name split
|
|
206
|
+
-- @param self the string
|
|
207
|
+
-- @param re a delimiter (defaults to whitespace)
|
|
208
|
+
-- @param n maximum number of results
|
|
209
|
+
-- @usage #(('one two'):split()) == 2
|
|
210
|
+
-- @usage ('one,two,three'):split(',') == List{'one','two','three'}
|
|
211
|
+
-- @usage ('one,two,three'):split(',',2) == List{'one','two,three'}
|
|
212
|
+
function stringx.split(self,re,n)
|
|
213
|
+
local s = self
|
|
214
|
+
local plain = true
|
|
215
|
+
if not re then -- default spaces
|
|
216
|
+
s = lstrip(s)
|
|
217
|
+
plain = false
|
|
218
|
+
end
|
|
219
|
+
local res = usplit(s,re,plain,n)
|
|
220
|
+
if re and re ~= '' and find(s,re,-#re,true) then
|
|
221
|
+
res[#res+1] = ""
|
|
222
|
+
end
|
|
223
|
+
return setmetatable(res,list_MT)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
--- split a string using a pattern. Note that at least one value will be returned!
|
|
227
|
+
-- @param self the string
|
|
228
|
+
-- @param re a Lua string pattern (defaults to whitespace)
|
|
229
|
+
-- @return the parts of the string
|
|
230
|
+
-- @usage a,b = line:splitv('=')
|
|
231
|
+
function stringx.splitv (self,re)
|
|
232
|
+
assert_string(1,self)
|
|
233
|
+
return utils.splitv(self,re)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
local function copy(self)
|
|
237
|
+
return self..''
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
--- count all instances of substring in string.
|
|
241
|
+
-- @param self the string
|
|
242
|
+
-- @param sub substring
|
|
243
|
+
function stringx.count(self,sub)
|
|
244
|
+
assert_string(1,self)
|
|
245
|
+
local i,k = _find_all(self,sub,1)
|
|
246
|
+
return k
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
local function _just(s,w,ch,left,right)
|
|
250
|
+
local n = #s
|
|
251
|
+
if w > n then
|
|
252
|
+
if not ch then ch = ' ' end
|
|
253
|
+
local f1,f2
|
|
254
|
+
if left and right then
|
|
255
|
+
local ln = ceil((w-n)/2)
|
|
256
|
+
local rn = w - n - ln
|
|
257
|
+
f1 = rep(ch,ln)
|
|
258
|
+
f2 = rep(ch,rn)
|
|
259
|
+
elseif right then
|
|
260
|
+
f1 = rep(ch,w-n)
|
|
261
|
+
f2 = ''
|
|
262
|
+
else
|
|
263
|
+
f2 = rep(ch,w-n)
|
|
264
|
+
f1 = ''
|
|
265
|
+
end
|
|
266
|
+
return f1..s..f2
|
|
267
|
+
else
|
|
268
|
+
return copy(s)
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
--- left-justify s with width w.
|
|
273
|
+
-- @param self the string
|
|
274
|
+
-- @param w width of justification
|
|
275
|
+
-- @param ch padding character, default ' '
|
|
276
|
+
function stringx.ljust(self,w,ch)
|
|
277
|
+
assert_string(1,self)
|
|
278
|
+
assert_arg(2,w,'number')
|
|
279
|
+
return _just(self,w,ch,true,false)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
--- right-justify s with width w.
|
|
283
|
+
-- @param s the string
|
|
284
|
+
-- @param w width of justification
|
|
285
|
+
-- @param ch padding character, default ' '
|
|
286
|
+
function stringx.rjust(s,w,ch)
|
|
287
|
+
assert_string(1,s)
|
|
288
|
+
assert_arg(2,w,'number')
|
|
289
|
+
return _just(s,w,ch,false,true)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
--- center-justify s with width w.
|
|
293
|
+
-- @param s the string
|
|
294
|
+
-- @param w width of justification
|
|
295
|
+
-- @param ch padding character, default ' '
|
|
296
|
+
function stringx.center(s,w,ch)
|
|
297
|
+
assert_string(1,s)
|
|
298
|
+
assert_arg(2,w,'number')
|
|
299
|
+
return _just(s,w,ch,true,true)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
local function _strip(s,left,right,chrs)
|
|
303
|
+
if not chrs then
|
|
304
|
+
chrs = '%s'
|
|
305
|
+
else
|
|
306
|
+
chrs = '['..escape(chrs)..']'
|
|
307
|
+
end
|
|
308
|
+
if left then
|
|
309
|
+
local i1,i2 = find(s,'^'..chrs..'*')
|
|
310
|
+
if i2 >= i1 then
|
|
311
|
+
s = sub(s,i2+1)
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
if right then
|
|
315
|
+
local i1,i2 = find(s,chrs..'*$')
|
|
316
|
+
if i2 >= i1 then
|
|
317
|
+
s = sub(s,1,i1-1)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
return s
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
--- trim any whitespace on the left of s.
|
|
324
|
+
-- @param self the string
|
|
325
|
+
-- @param chrs default space, can be a string of characters to be trimmed
|
|
326
|
+
function stringx.lstrip(self,chrs)
|
|
327
|
+
assert_string(1,self)
|
|
328
|
+
return _strip(self,true,false,chrs)
|
|
329
|
+
end
|
|
330
|
+
lstrip = stringx.lstrip
|
|
331
|
+
|
|
332
|
+
--- trim any whitespace on the right of s.
|
|
333
|
+
-- @param s the string
|
|
334
|
+
-- @param chrs default space, can be a string of characters to be trimmed
|
|
335
|
+
function stringx.rstrip(s,chrs)
|
|
336
|
+
assert_string(1,s)
|
|
337
|
+
return _strip(s,false,true,chrs)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
--- trim any whitespace on both left and right of s.
|
|
341
|
+
-- @param self the string
|
|
342
|
+
-- @param chrs default space, can be a string of characters to be trimmed
|
|
343
|
+
function stringx.strip(self,chrs)
|
|
344
|
+
assert_string(1,self)
|
|
345
|
+
return _strip(self,true,true,chrs)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
-- The partition functions split a string using a delimiter into three parts:
|
|
349
|
+
-- the part before, the delimiter itself, and the part afterwards
|
|
350
|
+
local function _partition(p,delim,fn)
|
|
351
|
+
local i1,i2 = fn(p,delim)
|
|
352
|
+
if not i1 or i1 == -1 then
|
|
353
|
+
return p,'',''
|
|
354
|
+
else
|
|
355
|
+
if not i2 then i2 = i1 end
|
|
356
|
+
return sub(p,1,i1-1),sub(p,i1,i2),sub(p,i2+1)
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
--- partition the string using first occurance of a delimiter
|
|
361
|
+
-- @param self the string
|
|
362
|
+
-- @param ch delimiter
|
|
363
|
+
-- @return part before ch
|
|
364
|
+
-- @return ch
|
|
365
|
+
-- @return part after ch
|
|
366
|
+
function stringx.partition(self,ch)
|
|
367
|
+
assert_string(1,self)
|
|
368
|
+
assert_nonempty_string(2,ch)
|
|
369
|
+
return _partition(self,ch,stringx.lfind)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
--- partition the string p using last occurance of a delimiter
|
|
373
|
+
-- @param self the string
|
|
374
|
+
-- @param ch delimiter
|
|
375
|
+
-- @return part before ch
|
|
376
|
+
-- @return ch
|
|
377
|
+
-- @return part after ch
|
|
378
|
+
function stringx.rpartition(self,ch)
|
|
379
|
+
assert_string(1,self)
|
|
380
|
+
assert_nonempty_string(2,ch)
|
|
381
|
+
return _partition(self,ch,stringx.rfind)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
--- return the 'character' at the index.
|
|
385
|
+
-- @param self the string
|
|
386
|
+
-- @param idx an index (can be negative)
|
|
387
|
+
-- @return a substring of length 1 if successful, empty string otherwise.
|
|
388
|
+
function stringx.at(self,idx)
|
|
389
|
+
assert_string(1,self)
|
|
390
|
+
assert_arg(2,idx,'number')
|
|
391
|
+
return sub(self,idx,idx)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
--- return an interator over all lines in a string
|
|
395
|
+
-- @param self the string
|
|
396
|
+
-- @return an iterator
|
|
397
|
+
function stringx.lines (self)
|
|
398
|
+
assert_string(1,self)
|
|
399
|
+
local s = self
|
|
400
|
+
if not s:find '\n$' then s = s..'\n' end
|
|
401
|
+
return s:gmatch('([^\n]*)\n')
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
--- iniital word letters uppercase ('title case').
|
|
405
|
+
-- Here 'words' mean chunks of non-space characters.
|
|
406
|
+
-- @param self the string
|
|
407
|
+
-- @return a string with each word's first letter uppercase
|
|
408
|
+
function stringx.title(self)
|
|
409
|
+
return (self:gsub('(%S)(%S*)',function(f,r)
|
|
410
|
+
return f:upper()..r:lower()
|
|
411
|
+
end))
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
stringx.capitalize = stringx.title
|
|
415
|
+
|
|
416
|
+
local elipsis = '...'
|
|
417
|
+
local n_elipsis = #elipsis
|
|
418
|
+
|
|
419
|
+
--- return a shorted version of a string.
|
|
420
|
+
-- @param self the string
|
|
421
|
+
-- @param sz the maxinum size allowed
|
|
422
|
+
-- @param tail true if we want to show the end of the string (head otherwise)
|
|
423
|
+
function stringx.shorten(self,sz,tail)
|
|
424
|
+
if #self > sz then
|
|
425
|
+
if sz < n_elipsis then return elipsis:sub(1,sz) end
|
|
426
|
+
if tail then
|
|
427
|
+
local i = #self - sz + 1 + n_elipsis
|
|
428
|
+
return elipsis .. self:sub(i)
|
|
429
|
+
else
|
|
430
|
+
return self:sub(1,sz-n_elipsis) .. elipsis
|
|
431
|
+
end
|
|
432
|
+
end
|
|
433
|
+
return self
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
function stringx.import(dont_overload)
|
|
437
|
+
utils.import(stringx,string)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
return stringx
|
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
--- Extended operations on Lua tables.
|
|
2
|
+
--
|
|
3
|
+
-- See @{02-arrays.md.Useful_Operations_on_Tables|the Guide}
|
|
4
|
+
--
|
|
5
|
+
-- Dependencies: `pl.utils`
|
|
6
|
+
-- @module pl.tablex
|
|
7
|
+
local utils = require ('pl.utils')
|
|
8
|
+
local getmetatable,setmetatable,require = getmetatable,setmetatable,require
|
|
9
|
+
local append,remove = table.insert,table.remove
|
|
10
|
+
local min,max = math.min,math.max
|
|
11
|
+
local pairs,type,unpack,next,select,tostring = pairs,type,unpack,next,select,tostring
|
|
12
|
+
local function_arg = utils.function_arg
|
|
13
|
+
local Set = utils.stdmt.Set
|
|
14
|
+
local List = utils.stdmt.List
|
|
15
|
+
local Map = utils.stdmt.Map
|
|
16
|
+
local assert_arg = utils.assert_arg
|
|
17
|
+
|
|
18
|
+
local tablex = {}
|
|
19
|
+
|
|
20
|
+
-- generally, functions that make copies of tables try to preserve the metatable.
|
|
21
|
+
-- However, when the source has no obvious type, then we attach appropriate metatables
|
|
22
|
+
-- like List, Map, etc to the result.
|
|
23
|
+
local function setmeta (res,tbl,def)
|
|
24
|
+
local mt = getmetatable(tbl) or def
|
|
25
|
+
return setmetatable(res, mt)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
local function makelist (res)
|
|
29
|
+
return setmetatable(res,List)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
local function check_meta (val)
|
|
33
|
+
if type(val) == 'table' then return true end
|
|
34
|
+
return getmetatable(val)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
local function complain (idx,msg)
|
|
38
|
+
error(('argument %d is not %s'):format(idx,msg),3)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
local function assert_arg_indexable (idx,val)
|
|
42
|
+
local mt = check_meta(val)
|
|
43
|
+
if mt == true then return end
|
|
44
|
+
if not(mt and mt.__len and mt.__index) then
|
|
45
|
+
complain(idx,"indexable")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
local function assert_arg_iterable (idx,val)
|
|
50
|
+
local mt = check_meta(val)
|
|
51
|
+
if mt == true then return end
|
|
52
|
+
if not(mt and mt.__pairs) then
|
|
53
|
+
complain(idx,"iterable")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
local function assert_arg_writeable (idx,val)
|
|
58
|
+
local mt = check_meta(val)
|
|
59
|
+
if mt == true then return end
|
|
60
|
+
if not(mt and mt.__newindex) then
|
|
61
|
+
complain(idx,"writeable")
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
--- copy a table into another, in-place.
|
|
67
|
+
-- @param t1 destination table
|
|
68
|
+
-- @param t2 source (any iterable object)
|
|
69
|
+
-- @return first table
|
|
70
|
+
function tablex.update (t1,t2)
|
|
71
|
+
assert_arg_writeable(1,t1)
|
|
72
|
+
assert_arg_iterable(2,t2)
|
|
73
|
+
for k,v in pairs(t2) do
|
|
74
|
+
t1[k] = v
|
|
75
|
+
end
|
|
76
|
+
return t1
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
--- total number of elements in this table.
|
|
80
|
+
-- Note that this is distinct from `#t`, which is the number
|
|
81
|
+
-- of values in the array part; this value will always
|
|
82
|
+
-- be greater or equal. The difference gives the size of
|
|
83
|
+
-- the hash part, for practical purposes. Works for any
|
|
84
|
+
-- object with a __pairs metamethod.
|
|
85
|
+
-- @param t a table
|
|
86
|
+
-- @return the size
|
|
87
|
+
function tablex.size (t)
|
|
88
|
+
assert_arg_iterable(1,t)
|
|
89
|
+
local i = 0
|
|
90
|
+
for k in pairs(t) do i = i + 1 end
|
|
91
|
+
return i
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
--- make a shallow copy of a table
|
|
95
|
+
-- @param t an iterable source
|
|
96
|
+
-- @return new table
|
|
97
|
+
function tablex.copy (t)
|
|
98
|
+
assert_arg_iterable(1,t)
|
|
99
|
+
local res = {}
|
|
100
|
+
for k,v in pairs(t) do
|
|
101
|
+
res[k] = v
|
|
102
|
+
end
|
|
103
|
+
return res
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
--- make a deep copy of a table, recursively copying all the keys and fields.
|
|
107
|
+
-- This will also set the copied table's metatable to that of the original.
|
|
108
|
+
-- @param t A table
|
|
109
|
+
-- @return new table
|
|
110
|
+
function tablex.deepcopy(t)
|
|
111
|
+
if type(t) ~= 'table' then return t end
|
|
112
|
+
assert_arg_iterable(1,t)
|
|
113
|
+
local mt = getmetatable(t)
|
|
114
|
+
local res = {}
|
|
115
|
+
for k,v in pairs(t) do
|
|
116
|
+
if type(v) == 'table' then
|
|
117
|
+
v = tablex.deepcopy(v)
|
|
118
|
+
end
|
|
119
|
+
res[k] = v
|
|
120
|
+
end
|
|
121
|
+
setmetatable(res,mt)
|
|
122
|
+
return res
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
local abs, deepcompare = math.abs
|
|
126
|
+
|
|
127
|
+
--- compare two values.
|
|
128
|
+
-- if they are tables, then compare their keys and fields recursively.
|
|
129
|
+
-- @param t1 A value
|
|
130
|
+
-- @param t2 A value
|
|
131
|
+
-- @param ignore_mt if true, ignore __eq metamethod (default false)
|
|
132
|
+
-- @param eps if defined, then used for any number comparisons
|
|
133
|
+
-- @return true or false
|
|
134
|
+
function tablex.deepcompare(t1,t2,ignore_mt,eps)
|
|
135
|
+
local ty1 = type(t1)
|
|
136
|
+
local ty2 = type(t2)
|
|
137
|
+
if ty1 ~= ty2 then return false end
|
|
138
|
+
-- non-table types can be directly compared
|
|
139
|
+
if ty1 ~= 'table' then
|
|
140
|
+
if ty1 == 'number' and eps then return abs(t1-t2) < eps end
|
|
141
|
+
return t1 == t2
|
|
142
|
+
end
|
|
143
|
+
-- as well as tables which have the metamethod __eq
|
|
144
|
+
local mt = getmetatable(t1)
|
|
145
|
+
if not ignore_mt and mt and mt.__eq then return t1 == t2 end
|
|
146
|
+
for k1,v1 in pairs(t1) do
|
|
147
|
+
local v2 = t2[k1]
|
|
148
|
+
if v2 == nil or not deepcompare(v1,v2,ignore_mt,eps) then return false end
|
|
149
|
+
end
|
|
150
|
+
for k2,v2 in pairs(t2) do
|
|
151
|
+
local v1 = t1[k2]
|
|
152
|
+
if v1 == nil or not deepcompare(v1,v2,ignore_mt,eps) then return false end
|
|
153
|
+
end
|
|
154
|
+
return true
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
deepcompare = tablex.deepcompare
|
|
158
|
+
|
|
159
|
+
--- compare two arrays using a predicate.
|
|
160
|
+
-- @param t1 an array
|
|
161
|
+
-- @param t2 an array
|
|
162
|
+
-- @param cmp A comparison function
|
|
163
|
+
function tablex.compare (t1,t2,cmp)
|
|
164
|
+
assert_arg_indexable(1,t1)
|
|
165
|
+
assert_arg_indexable(2,t2)
|
|
166
|
+
if #t1 ~= #t2 then return false end
|
|
167
|
+
cmp = function_arg(3,cmp)
|
|
168
|
+
for k = 1,#t1 do
|
|
169
|
+
if not cmp(t1[k],t2[k]) then return false end
|
|
170
|
+
end
|
|
171
|
+
return true
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
--- compare two list-like tables using an optional predicate, without regard for element order.
|
|
175
|
+
-- @param t1 a list-like table
|
|
176
|
+
-- @param t2 a list-like table
|
|
177
|
+
-- @param cmp A comparison function (may be nil)
|
|
178
|
+
function tablex.compare_no_order (t1,t2,cmp)
|
|
179
|
+
assert_arg_indexable(1,t1)
|
|
180
|
+
assert_arg_indexable(2,t2)
|
|
181
|
+
if cmp then cmp = function_arg(3,cmp) end
|
|
182
|
+
if #t1 ~= #t2 then return false end
|
|
183
|
+
local visited = {}
|
|
184
|
+
for i = 1,#t1 do
|
|
185
|
+
local val = t1[i]
|
|
186
|
+
local gotcha
|
|
187
|
+
for j = 1,#t2 do if not visited[j] then
|
|
188
|
+
local match
|
|
189
|
+
if cmp then match = cmp(val,t2[j]) else match = val == t2[j] end
|
|
190
|
+
if match then
|
|
191
|
+
gotcha = j
|
|
192
|
+
break
|
|
193
|
+
end
|
|
194
|
+
end end
|
|
195
|
+
if not gotcha then return false end
|
|
196
|
+
visited[gotcha] = true
|
|
197
|
+
end
|
|
198
|
+
return true
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
--- return the index of a value in a list.
|
|
203
|
+
-- Like string.find, there is an optional index to start searching,
|
|
204
|
+
-- which can be negative.
|
|
205
|
+
-- @param t A list-like table (i.e. with numerical indices)
|
|
206
|
+
-- @param val A value
|
|
207
|
+
-- @param idx index to start; -1 means last element,etc (default 1)
|
|
208
|
+
-- @return index of value or nil if not found
|
|
209
|
+
-- @usage find({10,20,30},20) == 2
|
|
210
|
+
-- @usage find({'a','b','a','c'},'a',2) == 3
|
|
211
|
+
function tablex.find(t,val,idx)
|
|
212
|
+
assert_arg_indexable(1,t)
|
|
213
|
+
idx = idx or 1
|
|
214
|
+
if idx < 0 then idx = #t + idx + 1 end
|
|
215
|
+
for i = idx,#t do
|
|
216
|
+
if t[i] == val then return i end
|
|
217
|
+
end
|
|
218
|
+
return nil
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
--- return the index of a value in a list, searching from the end.
|
|
222
|
+
-- Like string.find, there is an optional index to start searching,
|
|
223
|
+
-- which can be negative.
|
|
224
|
+
-- @param t A list-like table (i.e. with numerical indices)
|
|
225
|
+
-- @param val A value
|
|
226
|
+
-- @param idx index to start; -1 means last element,etc (default 1)
|
|
227
|
+
-- @return index of value or nil if not found
|
|
228
|
+
-- @usage rfind({10,10,10},10) == 3
|
|
229
|
+
function tablex.rfind(t,val,idx)
|
|
230
|
+
assert_arg_indexable(1,t)
|
|
231
|
+
idx = idx or #t
|
|
232
|
+
if idx < 0 then idx = #t + idx + 1 end
|
|
233
|
+
for i = idx,1,-1 do
|
|
234
|
+
if t[i] == val then return i end
|
|
235
|
+
end
|
|
236
|
+
return nil
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
--- return the index (or key) of a value in a table using a comparison function.
|
|
241
|
+
-- @param t A table
|
|
242
|
+
-- @param cmp A comparison function
|
|
243
|
+
-- @param arg an optional second argument to the function
|
|
244
|
+
-- @return index of value, or nil if not found
|
|
245
|
+
-- @return value returned by comparison function
|
|
246
|
+
function tablex.find_if(t,cmp,arg)
|
|
247
|
+
assert_arg_iterable(1,t)
|
|
248
|
+
cmp = function_arg(2,cmp)
|
|
249
|
+
for k,v in pairs(t) do
|
|
250
|
+
local c = cmp(v,arg)
|
|
251
|
+
if c then return k,c end
|
|
252
|
+
end
|
|
253
|
+
return nil
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
--- return a list of all values in a table indexed by another list.
|
|
257
|
+
-- @param tbl a table
|
|
258
|
+
-- @param idx an index table (a list of keys)
|
|
259
|
+
-- @return a list-like table
|
|
260
|
+
-- @usage index_by({10,20,30,40},{2,4}) == {20,40}
|
|
261
|
+
-- @usage index_by({one=1,two=2,three=3},{'one','three'}) == {1,3}
|
|
262
|
+
function tablex.index_by(tbl,idx)
|
|
263
|
+
assert_arg_indexable(1,tbl)
|
|
264
|
+
assert_arg_indexable(2,idx)
|
|
265
|
+
local res = {}
|
|
266
|
+
for i = 1,#idx do
|
|
267
|
+
res[i] = tbl[idx[i]]
|
|
268
|
+
end
|
|
269
|
+
return setmeta(res,tbl,List)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
--- apply a function to all values of a table.
|
|
273
|
+
-- This returns a table of the results.
|
|
274
|
+
-- Any extra arguments are passed to the function.
|
|
275
|
+
-- @param fun A function that takes at least one argument
|
|
276
|
+
-- @param t A table
|
|
277
|
+
-- @param ... optional arguments
|
|
278
|
+
-- @usage map(function(v) return v*v end, {10,20,30,fred=2}) is {100,400,900,fred=4}
|
|
279
|
+
function tablex.map(fun,t,...)
|
|
280
|
+
assert_arg_iterable(1,t)
|
|
281
|
+
fun = function_arg(1,fun)
|
|
282
|
+
local res = {}
|
|
283
|
+
for k,v in pairs(t) do
|
|
284
|
+
res[k] = fun(v,...)
|
|
285
|
+
end
|
|
286
|
+
return setmeta(res,t)
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
--- apply a function to all values of a list.
|
|
290
|
+
-- This returns a table of the results.
|
|
291
|
+
-- Any extra arguments are passed to the function.
|
|
292
|
+
-- @param fun A function that takes at least one argument
|
|
293
|
+
-- @param t a table (applies to array part)
|
|
294
|
+
-- @param ... optional arguments
|
|
295
|
+
-- @return a list-like table
|
|
296
|
+
-- @usage imap(function(v) return v*v end, {10,20,30,fred=2}) is {100,400,900}
|
|
297
|
+
function tablex.imap(fun,t,...)
|
|
298
|
+
assert_arg_indexable(1,t)
|
|
299
|
+
fun = function_arg(1,fun)
|
|
300
|
+
local res = {}
|
|
301
|
+
for i = 1,#t do
|
|
302
|
+
res[i] = fun(t[i],...) or false
|
|
303
|
+
end
|
|
304
|
+
return setmeta(res,t,List)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
--- apply a named method to values from a table.
|
|
308
|
+
-- @param name the method name
|
|
309
|
+
-- @param t a list-like table
|
|
310
|
+
-- @param ... any extra arguments to the method
|
|
311
|
+
function tablex.map_named_method (name,t,...)
|
|
312
|
+
utils.assert_string(1,name)
|
|
313
|
+
assert_arg_indexable(2,t)
|
|
314
|
+
local res = {}
|
|
315
|
+
for i = 1,#t do
|
|
316
|
+
local val = t[i]
|
|
317
|
+
local fun = val[name]
|
|
318
|
+
res[i] = fun(val,...)
|
|
319
|
+
end
|
|
320
|
+
return setmeta(res,t,List)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
--- apply a function to all values of a table, in-place.
|
|
325
|
+
-- Any extra arguments are passed to the function.
|
|
326
|
+
-- @param fun A function that takes at least one argument
|
|
327
|
+
-- @param t a table
|
|
328
|
+
-- @param ... extra arguments
|
|
329
|
+
function tablex.transform (fun,t,...)
|
|
330
|
+
assert_arg_iterable(1,t)
|
|
331
|
+
fun = function_arg(1,fun)
|
|
332
|
+
for k,v in pairs(t) do
|
|
333
|
+
t[v] = fun(v,...)
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
--- generate a table of all numbers in a range
|
|
338
|
+
-- @param start number
|
|
339
|
+
-- @param finish number
|
|
340
|
+
-- @param step optional increment (default 1 for increasing, -1 for decreasing)
|
|
341
|
+
function tablex.range (start,finish,step)
|
|
342
|
+
if start == finish then return {start}
|
|
343
|
+
elseif start > finish then return {}
|
|
344
|
+
end
|
|
345
|
+
local res = {}
|
|
346
|
+
local k = 1
|
|
347
|
+
if not step then
|
|
348
|
+
if finish > start then step = finish > start and 1 or -1 end
|
|
349
|
+
end
|
|
350
|
+
for i=start,finish,step do res[k]=i; k=k+1 end
|
|
351
|
+
return res
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
--- apply a function to values from two tables.
|
|
355
|
+
-- @param fun a function of at least two arguments
|
|
356
|
+
-- @param t1 a table
|
|
357
|
+
-- @param t2 a table
|
|
358
|
+
-- @param ... extra arguments
|
|
359
|
+
-- @return a table
|
|
360
|
+
-- @usage map2('+',{1,2,3,m=4},{10,20,30,m=40}) is {11,22,23,m=44}
|
|
361
|
+
function tablex.map2 (fun,t1,t2,...)
|
|
362
|
+
assert_arg_iterable(1,t1)
|
|
363
|
+
assert_arg_iterable(2,t2)
|
|
364
|
+
fun = function_arg(1,fun)
|
|
365
|
+
local res = {}
|
|
366
|
+
for k,v in pairs(t1) do
|
|
367
|
+
res[k] = fun(v,t2[k],...)
|
|
368
|
+
end
|
|
369
|
+
return setmeta(res,t1,List)
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
--- apply a function to values from two arrays.
|
|
373
|
+
-- The result will be the length of the shortest array.
|
|
374
|
+
-- @param fun a function of at least two arguments
|
|
375
|
+
-- @param t1 a list-like table
|
|
376
|
+
-- @param t2 a list-like table
|
|
377
|
+
-- @param ... extra arguments
|
|
378
|
+
-- @usage imap2('+',{1,2,3,m=4},{10,20,30,m=40}) is {11,22,23}
|
|
379
|
+
function tablex.imap2 (fun,t1,t2,...)
|
|
380
|
+
assert_arg_indexable(2,t1)
|
|
381
|
+
assert_arg_indexable(3,t2)
|
|
382
|
+
fun = function_arg(1,fun)
|
|
383
|
+
local res,n = {},math.min(#t1,#t2)
|
|
384
|
+
for i = 1,n do
|
|
385
|
+
res[i] = fun(t1[i],t2[i],...)
|
|
386
|
+
end
|
|
387
|
+
return res
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
--- 'reduce' a list using a binary function.
|
|
391
|
+
-- @param fun a function of two arguments
|
|
392
|
+
-- @param t a list-like table
|
|
393
|
+
-- @return the result of the function
|
|
394
|
+
-- @usage reduce('+',{1,2,3,4}) == 10
|
|
395
|
+
function tablex.reduce (fun,t)
|
|
396
|
+
assert_arg_indexable(2,t)
|
|
397
|
+
fun = function_arg(1,fun)
|
|
398
|
+
local n = #t
|
|
399
|
+
local res = t[1]
|
|
400
|
+
for i = 2,n do
|
|
401
|
+
res = fun(res,t[i])
|
|
402
|
+
end
|
|
403
|
+
return res
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
--- apply a function to all elements of a table.
|
|
407
|
+
-- The arguments to the function will be the value,
|
|
408
|
+
-- the key and <i>finally</i> any extra arguments passed to this function.
|
|
409
|
+
-- Note that the Lua 5.0 function table.foreach passed the <i>key</i> first.
|
|
410
|
+
-- @param t a table
|
|
411
|
+
-- @param fun a function with at least one argument
|
|
412
|
+
-- @param ... extra arguments
|
|
413
|
+
function tablex.foreach(t,fun,...)
|
|
414
|
+
assert_arg_iterable(1,t)
|
|
415
|
+
fun = function_arg(2,fun)
|
|
416
|
+
for k,v in pairs(t) do
|
|
417
|
+
fun(v,k,...)
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
--- apply a function to all elements of a list-like table in order.
|
|
422
|
+
-- The arguments to the function will be the value,
|
|
423
|
+
-- the index and <i>finally</i> any extra arguments passed to this function
|
|
424
|
+
-- @param t a table
|
|
425
|
+
-- @param fun a function with at least one argument
|
|
426
|
+
-- @param ... optional arguments
|
|
427
|
+
function tablex.foreachi(t,fun,...)
|
|
428
|
+
assert_arg_indexable(1,t)
|
|
429
|
+
fun = function_arg(2,fun)
|
|
430
|
+
for i = 1,#t do
|
|
431
|
+
fun(t[i],i,...)
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
--- Apply a function to a number of tables.
|
|
437
|
+
-- A more general version of map
|
|
438
|
+
-- The result is a table containing the result of applying that function to the
|
|
439
|
+
-- ith value of each table. Length of output list is the minimum length of all the lists
|
|
440
|
+
-- @param fun a function of n arguments
|
|
441
|
+
-- @param ... n tables
|
|
442
|
+
-- @usage mapn(function(x,y,z) return x+y+z end, {1,2,3},{10,20,30},{100,200,300}) is {111,222,333}
|
|
443
|
+
-- @usage mapn(math.max, {1,20,300},{10,2,3},{100,200,100}) is {100,200,300}
|
|
444
|
+
-- @param fun A function that takes as many arguments as there are tables
|
|
445
|
+
function tablex.mapn(fun,...)
|
|
446
|
+
fun = function_arg(1,fun)
|
|
447
|
+
local res = {}
|
|
448
|
+
local lists = {...}
|
|
449
|
+
local minn = 1e40
|
|
450
|
+
for i = 1,#lists do
|
|
451
|
+
minn = min(minn,#(lists[i]))
|
|
452
|
+
end
|
|
453
|
+
for i = 1,minn do
|
|
454
|
+
local args,k = {},1
|
|
455
|
+
for j = 1,#lists do
|
|
456
|
+
args[k] = lists[j][i]
|
|
457
|
+
k = k + 1
|
|
458
|
+
end
|
|
459
|
+
res[#res+1] = fun(unpack(args))
|
|
460
|
+
end
|
|
461
|
+
return res
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
--- call the function with the key and value pairs from a table.
|
|
465
|
+
-- The function can return a value and a key (note the order!). If both
|
|
466
|
+
-- are not nil, then this pair is inserted into the result. If only value is not nil, then
|
|
467
|
+
-- it is appended to the result.
|
|
468
|
+
-- @param fun A function which will be passed each key and value as arguments, plus any extra arguments to pairmap.
|
|
469
|
+
-- @param t A table
|
|
470
|
+
-- @param ... optional arguments
|
|
471
|
+
-- @usage pairmap(function(k,v) return v end,{fred=10,bonzo=20}) is {10,20} _or_ {20,10}
|
|
472
|
+
-- @usage pairmap(function(k,v) return {k,v},k end,{one=1,two=2}) is {one={'one',1},two={'two',2}}
|
|
473
|
+
function tablex.pairmap(fun,t,...)
|
|
474
|
+
assert_arg_iterable(1,t)
|
|
475
|
+
fun = function_arg(1,fun)
|
|
476
|
+
local res = {}
|
|
477
|
+
for k,v in pairs(t) do
|
|
478
|
+
local rv,rk = fun(k,v,...)
|
|
479
|
+
if rk then
|
|
480
|
+
res[rk] = rv
|
|
481
|
+
else
|
|
482
|
+
res[#res+1] = rv
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
return res
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
local function keys_op(i,v) return i end
|
|
489
|
+
|
|
490
|
+
--- return all the keys of a table in arbitrary order.
|
|
491
|
+
-- @param t A table
|
|
492
|
+
function tablex.keys(t)
|
|
493
|
+
assert_arg_iterable(1,t)
|
|
494
|
+
return makelist(tablex.pairmap(keys_op,t))
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
local function values_op(i,v) return v end
|
|
498
|
+
|
|
499
|
+
--- return all the values of the table in arbitrary order
|
|
500
|
+
-- @param t A table
|
|
501
|
+
function tablex.values(t)
|
|
502
|
+
assert_arg_iterable(1,t)
|
|
503
|
+
return makelist(tablex.pairmap(values_op,t))
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
local function index_map_op (i,v) return i,v end
|
|
507
|
+
|
|
508
|
+
--- create an index map from a list-like table. The original values become keys,
|
|
509
|
+
-- and the associated values are the indices into the original list.
|
|
510
|
+
-- @param t a list-like table
|
|
511
|
+
-- @return a map-like table
|
|
512
|
+
function tablex.index_map (t)
|
|
513
|
+
assert_arg_indexable(1,t)
|
|
514
|
+
return setmetatable(tablex.pairmap(index_map_op,t),Map)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
local function set_op(i,v) return true,v end
|
|
518
|
+
|
|
519
|
+
--- create a set from a list-like table. A set is a table where the original values
|
|
520
|
+
-- become keys, and the associated values are all true.
|
|
521
|
+
-- @param t a list-like table
|
|
522
|
+
-- @return a set (a map-like table)
|
|
523
|
+
function tablex.makeset (t)
|
|
524
|
+
assert_arg_indexable(1,t)
|
|
525
|
+
return setmetatable(tablex.pairmap(set_op,t),Set)
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
--- combine two tables, either as union or intersection. Corresponds to
|
|
530
|
+
-- set operations for sets () but more general. Not particularly
|
|
531
|
+
-- useful for list-like tables.
|
|
532
|
+
-- @param t1 a table
|
|
533
|
+
-- @param t2 a table
|
|
534
|
+
-- @param dup true for a union, false for an intersection.
|
|
535
|
+
-- @usage merge({alice=23,fred=34},{bob=25,fred=34}) is {fred=34}
|
|
536
|
+
-- @usage merge({alice=23,fred=34},{bob=25,fred=34},true) is {bob=25,fred=34,alice=23}
|
|
537
|
+
-- @see tablex.index_map
|
|
538
|
+
function tablex.merge (t1,t2,dup)
|
|
539
|
+
assert_arg_iterable(1,t1)
|
|
540
|
+
assert_arg_iterable(2,t2)
|
|
541
|
+
local res = {}
|
|
542
|
+
for k,v in pairs(t1) do
|
|
543
|
+
if dup or t2[k] then res[k] = v end
|
|
544
|
+
end
|
|
545
|
+
if dup then
|
|
546
|
+
for k,v in pairs(t2) do
|
|
547
|
+
res[k] = v
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
return setmeta(res,t1,Map)
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
--- a new table which is the difference of two tables.
|
|
554
|
+
-- With sets (where the values are all true) this is set difference and
|
|
555
|
+
-- symmetric difference depending on the third parameter.
|
|
556
|
+
-- @param s1 a map-like table or set
|
|
557
|
+
-- @param s2 a map-like table or set
|
|
558
|
+
-- @param symm symmetric difference (default false)
|
|
559
|
+
-- @return a map-like table or set
|
|
560
|
+
function tablex.difference (s1,s2,symm)
|
|
561
|
+
assert_arg_iterable(1,s1)
|
|
562
|
+
assert_arg_iterable(2,s2)
|
|
563
|
+
local res = {}
|
|
564
|
+
for k,v in pairs(s1) do
|
|
565
|
+
if not s2[k] then res[k] = v end
|
|
566
|
+
end
|
|
567
|
+
if symm then
|
|
568
|
+
for k,v in pairs(s2) do
|
|
569
|
+
if not s1[k] then res[k] = v end
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
return setmeta(res,s1,Map)
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
--- A table where the key/values are the values and value counts of the table.
|
|
576
|
+
-- @param t a list-like table
|
|
577
|
+
-- @param cmp a function that defines equality (otherwise uses ==)
|
|
578
|
+
-- @return a map-like table
|
|
579
|
+
-- @see seq.count_map
|
|
580
|
+
function tablex.count_map (t,cmp)
|
|
581
|
+
assert_arg_indexable(1,t)
|
|
582
|
+
local res,mask = {},{}
|
|
583
|
+
cmp = function_arg(2,cmp)
|
|
584
|
+
local n = #t
|
|
585
|
+
for i = 1,#t do
|
|
586
|
+
local v = t[i]
|
|
587
|
+
if not mask[v] then
|
|
588
|
+
mask[v] = true
|
|
589
|
+
-- check this value against all other values
|
|
590
|
+
res[v] = 1 -- there's at least one instance
|
|
591
|
+
for j = i+1,n do
|
|
592
|
+
local w = t[j]
|
|
593
|
+
if cmp and cmp(v,w) or v == w then
|
|
594
|
+
res[v] = res[v] + 1
|
|
595
|
+
mask[w] = true
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
end
|
|
599
|
+
end
|
|
600
|
+
return setmetatable(res,Map)
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
--- filter a table's values using a predicate function
|
|
604
|
+
-- @param t a list-like table
|
|
605
|
+
-- @param pred a boolean function
|
|
606
|
+
-- @param arg optional argument to be passed as second argument of the predicate
|
|
607
|
+
function tablex.filter (t,pred,arg)
|
|
608
|
+
assert_arg_indexable(1,t)
|
|
609
|
+
pred = function_arg(2,pred)
|
|
610
|
+
local res,k = {},1
|
|
611
|
+
for i = 1,#t do
|
|
612
|
+
local v = t[i]
|
|
613
|
+
if pred(v,arg) then
|
|
614
|
+
res[k] = v
|
|
615
|
+
k = k + 1
|
|
616
|
+
end
|
|
617
|
+
end
|
|
618
|
+
return setmeta(res,t,List)
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
--- return a table where each element is a table of the ith values of an arbitrary
|
|
622
|
+
-- number of tables. It is equivalent to a matrix transpose.
|
|
623
|
+
-- @usage zip({10,20,30},{100,200,300}) is {{10,100},{20,200},{30,300}}
|
|
624
|
+
function tablex.zip(...)
|
|
625
|
+
return tablex.mapn(function(...) return {...} end,...)
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
local _copy
|
|
629
|
+
function _copy (dest,src,idest,isrc,nsrc,clean_tail)
|
|
630
|
+
idest = idest or 1
|
|
631
|
+
isrc = isrc or 1
|
|
632
|
+
local iend
|
|
633
|
+
if not nsrc then
|
|
634
|
+
nsrc = #src
|
|
635
|
+
iend = #src
|
|
636
|
+
else
|
|
637
|
+
iend = isrc + min(nsrc-1,#src-isrc)
|
|
638
|
+
end
|
|
639
|
+
if dest == src then -- special case
|
|
640
|
+
if idest > isrc and iend >= idest then -- overlapping ranges
|
|
641
|
+
src = tablex.sub(src,isrc,nsrc)
|
|
642
|
+
isrc = 1; iend = #src
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
for i = isrc,iend do
|
|
646
|
+
dest[idest] = src[i]
|
|
647
|
+
idest = idest + 1
|
|
648
|
+
end
|
|
649
|
+
if clean_tail then
|
|
650
|
+
tablex.clear(dest,idest)
|
|
651
|
+
end
|
|
652
|
+
return dest
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
--- copy an array into another one, resizing the destination if necessary. <br>
|
|
656
|
+
-- @param dest a list-like table
|
|
657
|
+
-- @param src a list-like table
|
|
658
|
+
-- @param idest where to start copying values from source (default 1)
|
|
659
|
+
-- @param isrc where to start copying values into destination (default 1)
|
|
660
|
+
-- @param nsrc number of elements to copy from source (default source size)
|
|
661
|
+
function tablex.icopy (dest,src,idest,isrc,nsrc)
|
|
662
|
+
assert_arg_indexable(1,dest)
|
|
663
|
+
assert_arg_indexable(2,src)
|
|
664
|
+
return _copy(dest,src,idest,isrc,nsrc,true)
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
--- copy an array into another one. <br>
|
|
668
|
+
-- @param dest a list-like table
|
|
669
|
+
-- @param src a list-like table
|
|
670
|
+
-- @param idest where to start copying values from source (default 1)
|
|
671
|
+
-- @param isrc where to start copying values into destination (default 1)
|
|
672
|
+
-- @param nsrc number of elements to copy from source (default source size)
|
|
673
|
+
function tablex.move (dest,src,idest,isrc,nsrc)
|
|
674
|
+
assert_arg_indexable(1,dest)
|
|
675
|
+
assert_arg_indexable(2,src)
|
|
676
|
+
return _copy(dest,src,idest,isrc,nsrc,false)
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
function tablex._normalize_slice(self,first,last)
|
|
680
|
+
local sz = #self
|
|
681
|
+
if not first then first=1 end
|
|
682
|
+
if first<0 then first=sz+first+1 end
|
|
683
|
+
-- make the range _inclusive_!
|
|
684
|
+
if not last then last=sz end
|
|
685
|
+
if last < 0 then last=sz+1+last end
|
|
686
|
+
return first,last
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
--- Extract a range from a table, like 'string.sub'.
|
|
690
|
+
-- If first or last are negative then they are relative to the end of the list
|
|
691
|
+
-- eg. sub(t,-2) gives last 2 entries in a list, and
|
|
692
|
+
-- sub(t,-4,-2) gives from -4th to -2nd
|
|
693
|
+
-- @param t a list-like table
|
|
694
|
+
-- @param first An index
|
|
695
|
+
-- @param last An index
|
|
696
|
+
-- @return a new List
|
|
697
|
+
function tablex.sub(t,first,last)
|
|
698
|
+
assert_arg_indexable(1,t)
|
|
699
|
+
first,last = tablex._normalize_slice(t,first,last)
|
|
700
|
+
local res={}
|
|
701
|
+
for i=first,last do append(res,t[i]) end
|
|
702
|
+
return setmeta(res,t,List)
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
--- set an array range to a value. If it's a function we use the result
|
|
706
|
+
-- of applying it to the indices.
|
|
707
|
+
-- @param t a list-like table
|
|
708
|
+
-- @param val a value
|
|
709
|
+
-- @param i1 start range (default 1)
|
|
710
|
+
-- @param i2 end range (default table size)
|
|
711
|
+
function tablex.set (t,val,i1,i2)
|
|
712
|
+
assert_arg_indexable(1,t)
|
|
713
|
+
i1,i2 = i1 or 1,i2 or #t
|
|
714
|
+
if utils.is_callable(val) then
|
|
715
|
+
for i = i1,i2 do
|
|
716
|
+
t[i] = val(i)
|
|
717
|
+
end
|
|
718
|
+
else
|
|
719
|
+
for i = i1,i2 do
|
|
720
|
+
t[i] = val
|
|
721
|
+
end
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
--- create a new array of specified size with initial value.
|
|
726
|
+
-- @param n size
|
|
727
|
+
-- @param val initial value (can be nil, but don't expect # to work!)
|
|
728
|
+
-- @return the table
|
|
729
|
+
function tablex.new (n,val)
|
|
730
|
+
local res = {}
|
|
731
|
+
tablex.set(res,val,1,n)
|
|
732
|
+
return res
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
--- clear out the contents of a table.
|
|
736
|
+
-- @param t a table
|
|
737
|
+
-- @param istart optional start position
|
|
738
|
+
function tablex.clear(t,istart)
|
|
739
|
+
istart = istart or 1
|
|
740
|
+
for i = istart,#t do remove(t) end
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
--- insert values into a table. <br>
|
|
744
|
+
-- insertvalues(t, [pos,] values) <br>
|
|
745
|
+
-- similar to table.insert but inserts values from given table "values",
|
|
746
|
+
-- not the object itself, into table "t" at position "pos".
|
|
747
|
+
function tablex.insertvalues(t, ...)
|
|
748
|
+
assert_arg(1,t,'table')
|
|
749
|
+
local pos, values
|
|
750
|
+
if select('#', ...) == 1 then
|
|
751
|
+
pos,values = #t+1, ...
|
|
752
|
+
else
|
|
753
|
+
pos,values = ...
|
|
754
|
+
end
|
|
755
|
+
if #values > 0 then
|
|
756
|
+
for i=#t,pos,-1 do
|
|
757
|
+
t[i+#values] = t[i]
|
|
758
|
+
end
|
|
759
|
+
local offset = 1 - pos
|
|
760
|
+
for i=pos,pos+#values-1 do
|
|
761
|
+
t[i] = values[i + offset]
|
|
762
|
+
end
|
|
763
|
+
end
|
|
764
|
+
return t
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
--- remove a range of values from a table.
|
|
768
|
+
-- @param t a list-like table
|
|
769
|
+
-- @param i1 start index
|
|
770
|
+
-- @param i2 end index
|
|
771
|
+
-- @return the table
|
|
772
|
+
function tablex.removevalues (t,i1,i2)
|
|
773
|
+
assert_arg(1,t,'table')
|
|
774
|
+
i1,i2 = tablex._normalize_slice(t,i1,i2)
|
|
775
|
+
for i = i1,i2 do
|
|
776
|
+
remove(t,i1)
|
|
777
|
+
end
|
|
778
|
+
return t
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
local _find
|
|
782
|
+
_find = function (t,value,tables)
|
|
783
|
+
for k,v in pairs(t) do
|
|
784
|
+
if v == value then return k end
|
|
785
|
+
end
|
|
786
|
+
for k,v in pairs(t) do
|
|
787
|
+
if not tables[v] and type(v) == 'table' then
|
|
788
|
+
tables[v] = true
|
|
789
|
+
local res = _find(v,value,tables)
|
|
790
|
+
if res then
|
|
791
|
+
res = tostring(res)
|
|
792
|
+
if type(k) ~= 'string' then
|
|
793
|
+
return '['..k..']'..res
|
|
794
|
+
else
|
|
795
|
+
return k..'.'..res
|
|
796
|
+
end
|
|
797
|
+
end
|
|
798
|
+
end
|
|
799
|
+
end
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
--- find a value in a table by recursive search.
|
|
803
|
+
-- @param t the table
|
|
804
|
+
-- @param value the value
|
|
805
|
+
-- @param exclude any tables to avoid searching
|
|
806
|
+
-- @usage search(_G,math.sin,{package.path}) == 'math.sin'
|
|
807
|
+
-- @return a fieldspec, e.g. 'a.b' or 'math.sin'
|
|
808
|
+
function tablex.search (t,value,exclude)
|
|
809
|
+
assert_arg_iterable(1,t)
|
|
810
|
+
local tables = {[t]=true}
|
|
811
|
+
if exclude then
|
|
812
|
+
for _,v in pairs(exclude) do tables[v] = true end
|
|
813
|
+
end
|
|
814
|
+
return _find(t,value,tables)
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
return tablex
|