From 65c2acb44719cd196c8c1baa821718975b1ad785 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Mon, 5 Jun 2017 22:34:23 +0200 Subject: [PATCH] Removed the possibility of the `'max'` depth value, refactored `format_table`, and added lots of asserts in rest of `pretty.lua` --- pretty.lua | 118 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 101 insertions(+), 17 deletions(-) diff --git a/pretty.lua b/pretty.lua index 316d883..053f432 100644 --- a/pretty.lua +++ b/pretty.lua @@ -125,6 +125,10 @@ local function smallest_secure_longform_string_level (str) -- 'Hello ]] World', we cannot use level-0 as this would result in -- '[[Hello ]] World]]', which could be an issue in certain applications. + -- Error checking + assert(type(str) == 'string') + + -- Do stuff local levels = { [1] = 1 } str:gsub('%]=*%]', function (m) levels[m:len()] = true end) return #levels - 1 @@ -158,6 +162,10 @@ local function get_key_value_pairs_in_proper_order (t) -- 3.1. String in alphanumeric order -- 3.2. Other wierdness. + -- Error checking + assert(type(t) == 'table') + + -- Do stuff local key_value_pairs = {} for key, value in pairs(t) do @@ -171,6 +179,11 @@ end local function fill_holes_in_key_value_pairs (key_value_pairs) -- NOTE: Assumes that all keys are numbers + + -- Error checking + assert(type(key_value_pairs) == 'table') + + -- Do stuff for i = 2, #key_value_pairs do for j = key_value_pairs[i-1][1] + 1, key_value_pairs[i][1] - 1 do key_value_pairs[#key_value_pairs+1] = { j, nil } @@ -180,12 +193,16 @@ local function fill_holes_in_key_value_pairs (key_value_pairs) end local function is_identifier(str) + -- TODO: Remove, Unused + -- An identier is defined in the lua reference guide return str:match('^[_%a][_%w]*$') and not RESERVED_LUA_WORDS[str] end local function contains_only_nice_string_keys (t) + -- TODO: Remove, Unused + -- A "nice" string is here defined is one following the rules of lua -- identifiers. @@ -198,6 +215,8 @@ local function contains_only_nice_string_keys (t) end local function contains_only_nice_number_indexes (t) + -- TODO: Remove, Unused + -- A "nice" index is here defined as one which would be visited when using -- ipairs: An integer larger than 1 and less than #t @@ -212,6 +231,11 @@ local function contains_only_nice_number_indexes (t) end local function escape_string (str) + + -- Error checking + assert(type(str) == 'string') + + -- Do stuff local l = {} for i = 1, #str do l[#l+1] = CHAR_TO_STR_REPR[str:byte(i)] @@ -219,16 +243,36 @@ local function escape_string (str) return table.concat(l, '') end -local function width_of_strings_in_l (l, start_i, end_i) +local function width_of_strings_in_l (l, start_i, stop_i) + + -- Argument fixing and Error Checking + assert(type(l) == 'table') + + local start_i, stop_i = start_i or 1, stop_i or #l + + assert(type(start_i) == 'number') + assert(type(start_i) == 'number') + + -- Do stuff local width = 0 - for i = start_i or 1, (end_i or #l) do + for i = start_i, stop_i do width = width + ((type(l[i]) ~= 'string') and 1 or #l[i]) end return width end local function ignore_alignment_info (l, start_i, stop_i) - for i = start_i or 1, stop_i or #l do + + -- Argument fixing and Error Checking + assert(type(l) == 'table') + + local start_i, stop_i = start_i or 1, stop_i or #l + + assert(type(start_i) == 'number') + assert(type(start_i) == 'number') + + -- Do stuff + for i = start_i, stop_i do if type(l[i]) == 'table' and l[i][1] == 'align' then l[i] = '' end @@ -236,8 +280,16 @@ local function ignore_alignment_info (l, start_i, stop_i) end local function fix_alignment (l, start_i, stop_i) + + -- Argument fixing and Error Checking + assert(type(l) == 'table') + local start_i, stop_i = start_i or 1, stop_i or #l + assert(type(start_i) == 'number') + assert(type(start_i) == 'number') + -- Do stuff + -- Find maximums local max = {} for i = start_i, stop_i do @@ -255,6 +307,13 @@ local function fix_alignment (l, start_i, stop_i) end local function fix_seperator_info (l, indent_char, max_depth) + + -- Error Checking + assert(type(l) == 'table') + assert(type(indent_char) == 'string') + assert(type(max_depth) == 'number') + -- Do stuff + local depth, inline_depth = 0, nil for i = 1, #l do --print(i, l[i], depth, inline_depth) @@ -277,6 +336,8 @@ end -- Identifyer stuff local function is_empty_table (value) + -- TODO: Remove. This is unused. + if type(value) ~= 'table' then error(('[pretty/internal]: Only tables allowed in function pretty.is_empty_table, but was given %s (%s)'):format(value, type(value)), 2) end @@ -284,11 +345,14 @@ local function is_empty_table (value) end local function get_table_type (value) + -- TODO: Remove. This is unused. + -- Determines table type: -- * Sequence: All keys are integer in the range 1..#value -- * Pure Map: #value == 0 -- * Mixed: Any other + if is_empty_table(value) then return TABLE_TYPE.EMPTY end local is_sequence = contains_only_nice_number_indexes(value) @@ -320,7 +384,7 @@ end local function format_key_and_value_arbitr_map (l, key, value, options, depth) local index_before_key = #l+1 l[#l+1] = '[' - format_value(key, options, 'max', l) -- TODO: Outphase the usage of the "max" depth thingy. + format_value(key, options, math.huge, l) l[#l+1] = ']' l[#l+1] = { 'align', 'key', width_of_strings_in_l(l, index_before_key) } l[#l+1] = ' = ' @@ -343,7 +407,13 @@ local TABLE_TYPE_TO_PAIR_FORMAT = { -- Formatting tables local function format_map (t, options, depth, l) - -- NOTE: Assumes that the input table was pre-checked with `is_single_line_table()` + -- TODO: Merge with `format_table`? + + -- Error Checking + assert(type(t) == 'table') + assert(type(options) == 'table' and type(depth) == 'number' and type(l) == 'table') + + -- Do stuff local table_info = l.info[t] or get_table_info(t) local key_value_pairs = get_key_value_pairs_in_proper_order(t) @@ -378,29 +448,43 @@ local function format_map (t, options, depth, l) end function format_table (t, options, depth, l) - local info = l.info[t] or {} - --local table_type = get_table_type(t) + -- Error Checking + + assert(type(t) == 'table') + assert(type(options) == 'table' and type(depth) == 'number' and type(l) == 'table') + + -- Do stuff + + local info = l.info[t] or {} if options.recursion == 'marked' and info.marker then l[#l+1], l[#l+2], l[#l+3] = '<', info.marker, '>' end - -- Empty or exteeding max-depth? - if info.type == TABLE_TYPE.EMPTY then l[#l+1] = '{}'; return - elseif depth ~= 'max' and depth >= options.max_depth or l.visited[t] then l[#l+1] = '{...}'; return + local already_visited = l.visited[t] + l.visited[t] = true + + if info.type == TABLE_TYPE.EMPTY then + -- Empty Map + l[#l+1] = '{}' + elseif depth >= options.max_depth or already_visited then + -- Already visited or above max depth + l[#l+1] = '{...}' + else + -- Just a normal table + return format_map(t, options, depth, l) end - - l.visited[t] = true - - if depth == 'max' then l[#l+1] = '{...}'; return end - - -- Normal table - format_map(t, options, depth, l) end local function format_string (str, options, depth, l) -- TODO: Add option for escaping unicode characters. + -- Error checking + assert( type(str) == 'string' ) + assert(type(options) == 'table' and type(depth) == 'number' and type(l) == 'table') + + -- Do work + local is_long_string = (str:len() >= NR_CHARS_IN_LONG_STRING) local newline_or_tab_index = str:find('[\n\t]') local single_quote_index = str:find('\'')