From a20f6bddb75499f5cdd710f14578b768ebc4f0d8 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Thu, 5 Jan 2017 13:37:44 +0100 Subject: [PATCH] Restructure to allow using only a single table to create output. --- pretty.lua | 99 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/pretty.lua b/pretty.lua index d1726dd..30e6ac4 100644 --- a/pretty.lua +++ b/pretty.lua @@ -1,5 +1,15 @@ -local LIBRARY = require "library" + +-- Ensure loading library, if it exists, no matter where pretty.lua was loaded from. + +-- Load the library component +local LIBRARY +do + local thispath = ... and select('1', ...):match('.+%.') or '' + local was_loaded, library = pcall(require, thispath..'library') + LIBRARY = was_loaded and library or {} +end +-- local ERROR_UNKNOWN_TYPE = [[ [pretty]: Attempting to format unsupported value of type "%s". @@ -202,8 +212,8 @@ local function get_function_info (f) if info.builtin and LIBRARY[f] then info.name = LIBRARY[f].name - info.params[1] = LIBRARY[f].params - info.doc = LIBRARY[f].doc + info.params[1] = LIBRARY[f].para + info.doc = LIBRARY[f].docs end return info @@ -319,20 +329,20 @@ local function format_key_and_value_string_map (l, key, value, options, depth) l[#l+1] = key l[#l+1] = #key l[#l+1] = ' = ' - l[#l+1] = format_value(value, options, depth) + format_value(value, options, depth, l) end local function format_key_and_value_arbitr_map (l, key, value, options, depth) l[#l+1] = '[' - l[#l+1] = format_value(key, options, 'max') + format_value(key, options, 'max', l) l[#l+1] = ']' l[#l+1] = #l[#l-1] + 2 l[#l+1] = ' = ' - l[#l+1] = format_value(value, options, depth) + format_value(value, options, depth, l) end local function format_key_and_value_sequence (l, key, value, options, depth) - l[#l+1] = format_value(value, options, depth) + format_value(value, options, depth, l) end local TABLE_TYPE_TO_PAIR_FORMAT = { @@ -344,14 +354,14 @@ local TABLE_TYPE_TO_PAIR_FORMAT = { -- Formatting tables -local function format_single_line_map (t, options) +local function format_single_line_map (t, options, l) -- NOTE: Assumes that the input table was pre-checked with `is_single_line_table()` local key_value_pairs = get_key_value_pairs_in_proper_order(t) local table_type = get_table_type(t) local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_type] - local l = {'{ '} + l[#l+1] = '{ ' local top_before = #l for _, pair in ipairs(key_value_pairs) do @@ -368,17 +378,17 @@ local function format_single_line_map (t, options) if l[#l] == ', ' then l[#l] = nil end l[#l+1] = ' }' - return table.concat(l, '') end -local function format_map (t, options, depth) +local function format_map (t, options, depth, l) + -- TODO: l. local key_value_pairs = get_key_value_pairs_in_proper_order(t) local table_type = get_table_type(t) local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_type] -- Figure out the max key length - local l = {'{\n'} + l[#l+1] = '{\n' local top_before = #l for _, pair in pairs(key_value_pairs) do l[#l+1] = options.indent:rep(depth + 1) @@ -403,27 +413,27 @@ local function format_map (t, options, depth) l[#l+1] = '\n' l[#l+1] = options.indent:rep(depth) l[#l+1] = '}' - return table.concat(l, '') + end -function format_table (t, options, depth) +function format_table (t, options, depth, l) local table_type = get_table_type(t) -- Empty or exteeding max-depth? - if table_type == TABLE_TYPE_EMPTY then return '{}' - elseif depth ~= 'max' and depth >= options.max_depth then return '{...}' + if table_type == TABLE_TYPE_EMPTY then l[#l+1] = '{}'; return + elseif depth ~= 'max' and depth >= options.max_depth then l[#l+1] = '{...}'; return end -- Single line? - if is_single_line_table(t) then return format_single_line_map(t, options) end + if is_single_line_table(t) then format_single_line_map(t, options, l); return end - if depth == 'max' then return '{...}' end + if depth == 'max' then l[#l+1] = '{...}'; return end -- Normal table - return format_map(t, options, depth) + format_map(t, options, depth, l) end -local function format_string (str, options) +local function format_string (str, options, depth, l) -- TODO: Add option for escaping unicode characters. local is_long_string = (str:len() >= NR_CHARS_IN_LONG_STRING) @@ -460,41 +470,42 @@ local function format_string (str, options) -- Escape newline and tab if escape_newline_and_tab then str = str:gsub('\n', '\\n'):gsub('\t', '\\t') end - return left .. str .. right + l[#l+1] = left + l[#l+1] = str + l[#l+1] = right end -local function format_number (value, options) +local function format_number (value, options, depth, l) local shorthand = options.math_shorthand - if value ~= value then return shorthand and 'nan' or '0/0' - elseif value == 1/0 then return shorthand and 'inf' or '1/0' - elseif value == -1/0 then return shorthand and '-inf' or '-1/0' - else return tostring(value) + if value ~= value then l[#l+1] = shorthand and 'nan' or '0/0' + elseif value == 1/0 then l[#l+1] = shorthand and 'inf' or '1/0' + elseif value == -1/0 then l[#l+1] = shorthand and '-inf' or '-1/0' + else l[#l+1] = tostring(value) end end -local function format_coroutine (value) - return coroutine.status(value) .. ' coroutine: ' .. tostring(value):sub(9) +local function format_coroutine (value, options, depth, l) + l[#l+1] = coroutine.status(value) + l[#l+1] = ' coroutine: ' + l[#l+1] = tostring(value):sub(9) end -local function format_primitive (value) - return tostring(value) +local function format_primitive (value, options, depth, l) + l[#l+1] = tostring(value) end -local function format_string_defined_function (value, options, depth) +local function format_string_defined_function (value, options, depth, l) local info = get_function_info(value) - local function_str = get_full_function_str(info.source, info.linedefined, info.lastlinedefined) - return function_str + l[#l+1] = get_full_function_str(info.source, info.linedefined, info.lastlinedefined) end -local function format_function (value, options, depth) +local function format_function (value, options, depth, l) local info = get_function_info(value) if info.defined_how == 'string' then - return format_string_defined_function(value, options, depth) + return format_string_defined_function(value, options, depth, l) end - local l = {} - -- Build function signature if info.builtin then l[#l+1] = 'builtin ' end l[#l+1] = 'function (' @@ -519,7 +530,7 @@ local function format_function (value, options, depth) l[#l+1] = '\n\t--[[\n\tNative repr:' l[#l+1] = tostring(value) l[#l+1] = '\n\t' - l[#l+1] = format_value(info, options, depth + 1) + format_value(info, options, depth + 1, l) l[#l+1] = '--]]' else -- More info! -- @@ -567,15 +578,13 @@ local function format_function (value, options, depth) l[#l+1] = '\n' l[#l+1] = options.indent l[#l+1] = '-- up_values: ' - l[#l+1] = format_value(info.ups, options, depth + 1) + format_value(info.ups, options, depth + 1, l) end l[#l+1] = '\n\n' l[#l+1] = options.indent l[#l+1] = '...\nend' end - - return table.concat(l, '') end local TYPE_TO_FORMAT_FUNC = { @@ -592,10 +601,10 @@ local TYPE_TO_FORMAT_FUNC = { ['cdata'] = format_primitive, -- Luajit exclusive ? } -function format_value (value, options, depth) +function format_value (value, options, depth, l) local format_func = TYPE_TO_FORMAT_FUNC[type(value)] if format_func then - return format_func(value, options, depth) + format_func(value, options, depth, l) else error(ERROR_UNKNOWN_TYPE:format(type(value), tostring(value))) end @@ -604,10 +613,12 @@ end -------------------------------------------------------------------------------- local function pretty_format (value, options) + local l = {} local options = options or {} options.max_depth = options.max_depth or math.huge options.indent = options.indent or '\t' - return format_value(value, options, 0) + format_value(value, options, 0, l) + return table.concat(l, '') end return pretty_format