summaryrefslogtreecommitdiffstats
path: root/nselib/outlib.lua
diff options
context:
space:
mode:
Diffstat (limited to 'nselib/outlib.lua')
-rw-r--r--nselib/outlib.lua79
1 files changed, 79 insertions, 0 deletions
diff --git a/nselib/outlib.lua b/nselib/outlib.lua
new file mode 100644
index 0000000..3379256
--- /dev/null
+++ b/nselib/outlib.lua
@@ -0,0 +1,79 @@
+--- Helper functions for NSE script output
+--
+-- These functions are useful for ensuring output is consistently ordered
+-- between scans and following conventions for output formatting.
+--
+-- @author Daniel Miller
+-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
+-- @class module
+-- @name outlib
+
+local tableaux = require "tableaux"
+local keys = tableaux.keys
+
+local coroutine = require "coroutine"
+local wrap = coroutine.wrap
+local yield = coroutine.yield
+
+local table = require "table"
+local sort = table.sort
+local concat = table.concat
+
+local getmetatable = getmetatable
+local setmetatable = setmetatable
+local ipairs = ipairs
+
+local _ENV = {}
+
+--- Create a table that yields elements sorted by key when iterated over with pairs()
+--
+-- The returned table is like a sorted view of the original table; it should be
+-- treated as read-only, and any new data should be added to the original table
+-- instead.
+--@param t The table whose data should be used
+--@return out A table that can be passed to pairs() to get sorted results
+function sorted_by_key(t)
+ local out = {}
+ setmetatable(out, {
+ __pairs = function(_)
+ local order = keys(t)
+ sort(order)
+ return wrap(function()
+ for i,k in ipairs(order) do
+ yield(k, t[k])
+ end
+ end)
+ end
+ })
+ return out
+end
+
+local commasep = {
+ __tostring = function (t)
+ return concat(t, ", ")
+ end
+}
+
+--- Comma-separated list output
+--
+-- This adds a <code>__tostring</code> metamethod to a list (integer-indexed
+-- table) so that it will be formatted as a comma-separated list when converted
+-- to a string.
+-- @param t The table to format
+-- @param sep (Optional) list separator character, default: ", "
+function list_sep(t, sep)
+ -- Reuse closures and metatables as much as possible
+ local oldmt = getmetatable(t)
+ local newmt = sep and {
+ __tostring = function(tt)
+ return concat(tt, sep)
+ end} or commasep
+ -- Avoid clobbering old metatable or our static commasep table
+ if oldmt and oldmt ~= commasep then
+ oldmt.__tostring = newmt.__tostring
+ else
+ setmetatable(t, newmt)
+ end
+end
+
+return _ENV