From c8f64fde4f234979d5e9e586cf70174506267cfb Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 Nov 2024 17:23:51 -0600 Subject: [PATCH 1/3] slightly cleaner teal output --- tinytoml-0.0.1-1.rockspec | 29 -------------- tinytoml-0.0.2-1.rockspec | 34 ++++++++++++++++ tinytoml.lua | 71 ++++++++++++++++------------------ tinytoml.tl | 81 ++++++++++++++++++--------------------- tlconfig.lua | 4 ++ 5 files changed, 109 insertions(+), 110 deletions(-) delete mode 100644 tinytoml-0.0.1-1.rockspec create mode 100644 tinytoml-0.0.2-1.rockspec create mode 100644 tlconfig.lua diff --git a/tinytoml-0.0.1-1.rockspec b/tinytoml-0.0.1-1.rockspec deleted file mode 100644 index 0580217..0000000 --- a/tinytoml-0.0.1-1.rockspec +++ /dev/null @@ -1,29 +0,0 @@ -package = "tinytoml" -version = "0.0.1-1" - -source = { - url = "git://github.com/FourierTransformer/tinytoml.git", - tag = "0.0.1" -} - -description = { - summary = "A pure Lua TOML parser", - detailed = [[ - tinytoml is an easy to use TOML parser library for Lua. It can read in TOML files or load them from a string. - It supports all TOML 1.0.0 features including parsing strings, numbers, datetimes, arrays, inline-tables and even validating UTF-8 with good error messages if anything fails! - ]], - homepage = "https://github.com/FourierTransformer/tinytoml", - maintainer = "Fourier Transformer ", - license = "MIT" -} - -dependencies = { - "lua >= 5.1", -} - -build = { - type = "builtin", - modules = { - ["tinytoml"] = "tinytoml.lua" - }, -} diff --git a/tinytoml-0.0.2-1.rockspec b/tinytoml-0.0.2-1.rockspec new file mode 100644 index 0000000..3634384 --- /dev/null +++ b/tinytoml-0.0.2-1.rockspec @@ -0,0 +1,34 @@ +package = "tinytoml" +version = "0.0.2-1" + +source = { + url = "git://github.com/FourierTransformer/tinytoml.git", + tag = "0.0.2" +} + +description = { + summary = "A pure Lua TOML parser", + detailed = [[ + tinytoml is an easy to use TOML parser library for Lua. It can read in TOML files or load them from a string. + It supports all TOML 1.0.0 features including parsing strings, numbers, datetimes, arrays, inline-tables and even validating UTF-8 with good error messages if anything fails! + ]], + homepage = "https://github.com/FourierTransformer/tinytoml", + maintainer = "Fourier Transformer ", + license = "MIT" +} + +dependencies = { + "lua >= 5.1", +} + +build = { + type = "builtin", + modules = { + ["tinytoml"] = "tinytoml.lua" + }, + install = { + lua = { + ["tinytoml"] = "tinytoml.tl" + } + } +} diff --git a/tinytoml.lua b/tinytoml.lua index 582d803..2f1ac55 100644 --- a/tinytoml.lua +++ b/tinytoml.lua @@ -162,32 +162,27 @@ end local _unpack = unpack or table.unpack -local utf8char +local _tointeger = math.tointeger or tonumber -if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then - - utf8char = function(cp) - if cp < 128 then - return string.char(cp) - end - local suffix = cp % 64 - local c4 = 128 + suffix - cp = (cp - suffix) / 64 - if cp < 32 then - return string.char(192 + (cp), (c4)) - end - suffix = cp % 64 - local c3 = 128 + suffix - cp = (cp - suffix) / 64 - if cp < 16 then - return string.char(224 + (cp), c3, c4) - end - suffix = cp % 64 - cp = (cp - suffix) / 64 - return string.char(240 + (cp), 128 + (suffix), c3, c4) +local _utf8char = utf8 and utf8.char or function(cp) + if cp < 128 then + return string.char(cp) end -else - utf8char = utf8.char + local suffix = cp % 64 + local c4 = 128 + suffix + cp = (cp - suffix) / 64 + if cp < 32 then + return string.char(192 + (cp), (c4)) + end + suffix = cp % 64 + local c3 = 128 + suffix + cp = (cp - suffix) / 64 + if cp < 16 then + return string.char(224 + (cp), c3, c4) + end + suffix = cp % 64 + cp = (cp - suffix) / 64 + return string.char(240 + (cp), 128 + (suffix), c3, c4) end local function validate_utf8(input, toml_sub) @@ -307,7 +302,7 @@ local function handle_backslash_escape(sm) if (sm.match == "u" and #sm.ext == 4) or (sm.match == "U" and #sm.ext == 8) then - local codepoint_to_insert = utf8char(tonumber(sm.ext, 16)) + local codepoint_to_insert = _utf8char(tonumber(sm.ext, 16)) if not validate_utf8(codepoint_to_insert) then _error(sm, "Escaped UTF-8 sequence not valid UTF-8 character: \\" .. sm.match .. sm.ext, "string") end @@ -505,7 +500,7 @@ local function validate_integer(sm, value) if sm.match then if sm.match:find("^[-+]?0[%d_]") then _error(sm, "Integers can't start with a leading 0. Found integer: " .. sm.match, "integer") end sm.match = remove_underscores_number(sm, sm.match, "integer") - sm.value = tonumber(sm.match) + sm.value = _tointeger(sm.match) sm.value_type = "integer" return true end @@ -558,9 +553,9 @@ local function validate_datetime(sm, value) local hour, min, sec sm._, sm._, sm.match, hour, min, sec, sm.ext = value:find("^((%d%d):(%d%d):(%d%d))(.*)$") if sm.match then - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "local-time") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "local-time") end - if tonumber(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match, "local-time") end + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "local-time") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "local-time") end + if _tointeger(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match, "local-time") end if sm.ext ~= "" then if sm.ext:find("^%.%d+$") then sm.value_type = "time-local" @@ -578,7 +573,7 @@ local function validate_datetime(sm, value) local year, month, day sm._, sm._, sm.match, year_s, month_s, day_s = value:find("^((%d%d%d%d)%-(%d%d)%-(%d%d))$") if sm.match then - year, month, day = tonumber(year_s), tonumber(month_s), tonumber(day_s) + year, month, day = _tointeger(year_s), _tointeger(month_s), _tointeger(day_s) if month == 0 or month > 12 then _error(sm, "Month must be between 01-12. Found month: " .. month .. "in: " .. sm.match, "local-date") end if day == 0 or day > max_days_in_month[month] then _error(sm, "Too many days in the month. Found " .. day .. " days in month " .. month .. ", which only has " .. max_days_in_month[month] .. " days in: " .. sm.match, "local-date") end if month == 2 then @@ -607,10 +602,10 @@ local function validate_datetime(sm, value) value:find("^((%d%d%d%d)%-(%d%d)%-(%d%d)[Tt ](%d%d):(%d%d):(%d%d))(.*)$") if sm.match then - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match) end - if tonumber(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match) end - year, month, day = tonumber(year_s), tonumber(month_s), tonumber(day_s) + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match) end + if _tointeger(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match) end + year, month, day = _tointeger(year_s), _tointeger(month_s), _tointeger(day_s) if month == 0 or month > 12 then _error(sm, "Month must be between 01-12. Found month: " .. month .. "in: " .. sm.match) end if day == 0 or day > max_days_in_month[month] then _error(sm, "Too many days in the month. Found " .. day .. " days in month " .. month .. ", which only has " .. max_days_in_month[month] .. " days in: " .. sm.match, "local-datetime") end if month == 2 then @@ -632,8 +627,8 @@ local function validate_datetime(sm, value) return true elseif sm.ext:find("^%.%d+[+-]%d%d:%d%d$") then sm._, sm.end_seq, hour, min = sm.ext:find("^%.%d+[+-](%d%d):(%d%d)$") - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end sm.value_type = "datetime" sm.value = sm.type_conversion[sm.value_type](sm.match .. sm.ext:sub(1, 4)) return true @@ -643,8 +638,8 @@ local function validate_datetime(sm, value) return true elseif sm.ext:find("^[+-]%d%d:%d%d$") then sm._, sm.end_seq, hour, min = sm.ext:find("^[+-](%d%d):(%d%d)$") - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end sm.value_type = "datetime" sm.value = sm.type_conversion[sm.value_type](sm.match .. sm.ext) return true diff --git a/tinytoml.tl b/tinytoml.tl index 946cad9..fe7a662 100644 --- a/tinytoml.tl +++ b/tinytoml.tl @@ -162,32 +162,27 @@ end global unpack: function local _unpack = unpack or table.unpack -local utf8char: function(number): string - -if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then - -- from https://stackoverflow.com/a/26237757 - utf8char = function(cp: number): string - if cp < 128 then - return string.char(cp as integer) - end - local suffix = cp % 64 - local c4 = 128 + suffix - cp = (cp - suffix) / 64 - if cp < 32 then - return string.char(192 + (cp as integer), (c4 as integer)) - end - suffix = cp % 64 - local c3 = 128 + suffix - cp = (cp - suffix) / 64 - if cp < 16 then - return string.char(224 + (cp as integer), c3 as integer, c4 as integer) - end - suffix = cp % 64 - cp = (cp - suffix) / 64 - return string.char(240 + (cp as integer), 128 + (suffix as integer), c3 as integer, c4 as integer) - end -else - utf8char = utf8.char +local _tointeger = math.tointeger or tonumber as function(string): integer +-- function from https://stackoverflow.com/a/26237757 +local _utf8char = utf8 and utf8.char or function(cp: number): string + if cp < 128 then + return string.char(cp as integer) + end + local suffix = cp % 64 + local c4 = 128 + suffix + cp = (cp - suffix) / 64 + if cp < 32 then + return string.char(192 + (cp as integer), (c4 as integer)) + end + suffix = cp % 64 + local c3 = 128 + suffix + cp = (cp - suffix) / 64 + if cp < 16 then + return string.char(224 + (cp as integer), c3 as integer, c4 as integer) + end + suffix = cp % 64 + cp = (cp - suffix) / 64 + return string.char(240 + (cp as integer), 128 + (suffix as integer), c3 as integer, c4 as integer) end local function validate_utf8(input: string, toml_sub?: boolean): boolean, integer @@ -307,7 +302,7 @@ local function handle_backslash_escape(sm: StateMachine): string, boolean --if (sm.match == "x" and #sm.ext == 2) or -- hex escapes coming in toml 1.1.0, will need to update pattern in :find above as well if (sm.match == "u" and #sm.ext == 4) or (sm.match == "U" and #sm.ext == 8) then - local codepoint_to_insert = utf8char(tonumber(sm.ext, 16)) + local codepoint_to_insert = _utf8char(tonumber(sm.ext, 16)) if not validate_utf8(codepoint_to_insert) then _error(sm, "Escaped UTF-8 sequence not valid UTF-8 character: \\" .. sm.match .. sm.ext, "string") end @@ -505,7 +500,7 @@ local function validate_integer(sm: StateMachine, value: string): boolean if sm.match then if sm.match:find("^[-+]?0[%d_]") then _error(sm, "Integers can't start with a leading 0. Found integer: " .. sm.match, "integer") end sm.match = remove_underscores_number(sm, sm.match, "integer") - sm.value = tonumber(sm.match) + sm.value = _tointeger(sm.match) sm.value_type = "integer" return true end @@ -558,9 +553,9 @@ local function validate_datetime(sm: StateMachine, value: string): boolean local hour, min, sec: string, string, string sm._, sm._, sm.match, hour, min, sec, sm.ext = value:find("^((%d%d):(%d%d):(%d%d))(.*)$") as (integer, integer, string, string, string, string, string) if sm.match then - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "local-time") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "local-time") end - if tonumber(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match, "local-time") end + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "local-time") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "local-time") end + if _tointeger(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match, "local-time") end if sm.ext ~= "" then if sm.ext:find("^%.%d+$") then sm.value_type = "time-local" @@ -575,12 +570,12 @@ local function validate_datetime(sm: StateMachine, value: string): boolean end local year_s, month_s, day_s: string, string, string - local year, month, day: number, number, number + local year, month, day: integer, integer, integer sm._, sm._, sm.match, year_s, month_s, day_s = value:find("^((%d%d%d%d)%-(%d%d)%-(%d%d))$") as (integer, integer, string, string, string, string) if sm.match then - year, month, day = tonumber(year_s), tonumber(month_s), tonumber(day_s) + year, month, day = _tointeger(year_s), _tointeger(month_s), _tointeger(day_s) if month == 0 or month > 12 then _error(sm, "Month must be between 01-12. Found month: " .. month .. "in: " .. sm.match, "local-date") end - if day == 0 or day > max_days_in_month[month as integer] then _error(sm, "Too many days in the month. Found " .. day .. " days in month " .. month .. ", which only has " .. max_days_in_month[month as integer] .. " days in: " .. sm.match, "local-date") end + if day == 0 or day > max_days_in_month[month] then _error(sm, "Too many days in the month. Found " .. day .. " days in month " .. month .. ", which only has " .. max_days_in_month[month as integer] .. " days in: " .. sm.match, "local-date") end if month == 2 then local leap_year = (year % 4 == 0) and not(year % 100 == 0) or (year % 400 == 0) if leap_year == false then @@ -607,12 +602,12 @@ local function validate_datetime(sm: StateMachine, value: string): boolean value:find("^((%d%d%d%d)%-(%d%d)%-(%d%d)[Tt ](%d%d):(%d%d):(%d%d))(.*)$") as (integer, integer, string, string, string, string, string, string, string, string) if sm.match then - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match) end - if tonumber(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match) end - year, month, day = tonumber(year_s), tonumber(month_s), tonumber(day_s) + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match) end + if _tointeger(sec) > 60 then _error(sm, "Seconds must be less than 61. Found second: " .. sec .. "in: " .. sm.match) end + year, month, day = _tointeger(year_s), _tointeger(month_s), _tointeger(day_s) if month == 0 or month > 12 then _error(sm, "Month must be between 01-12. Found month: " .. month .. "in: " .. sm.match) end - if day == 0 or day > max_days_in_month[month as integer] then _error(sm, "Too many days in the month. Found " .. day .. " days in month " .. month .. ", which only has " .. max_days_in_month[month as integer] .. " days in: " .. sm.match, "local-datetime") end + if day == 0 or day > max_days_in_month[month] then _error(sm, "Too many days in the month. Found " .. day .. " days in month " .. month .. ", which only has " .. max_days_in_month[month as integer] .. " days in: " .. sm.match, "local-datetime") end if month == 2 then local leap_year = (year % 4 == 0) and not(year % 100 == 0) or (year % 400 == 0) if leap_year == false then @@ -632,8 +627,8 @@ local function validate_datetime(sm: StateMachine, value: string): boolean return true elseif sm.ext:find("^%.%d+[+-]%d%d:%d%d$") then sm._, sm.end_seq, hour, min = sm.ext:find("^%.%d+[+-](%d%d):(%d%d)$") as (integer, integer, string, string) - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end sm.value_type = "datetime" sm.value = sm.type_conversion[sm.value_type](sm.match .. sm.ext:sub(1, 4)) return true @@ -643,8 +638,8 @@ local function validate_datetime(sm: StateMachine, value: string): boolean return true elseif sm.ext:find("^[+-]%d%d:%d%d$") then sm._, sm.end_seq, hour, min = sm.ext:find("^[+-](%d%d):(%d%d)$") as (integer, integer, string, string) - if tonumber(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end - if tonumber(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(hour) > 23 then _error(sm, "Hours must be less than 24. Found hour: " .. hour .. "in: " .. sm.match, "offset-date-time") end + if _tointeger(min) > 59 then _error(sm, "Minutes must be less than 60. Found minute: " .. min .. "in: " .. sm.match, "offset-date-time") end sm.value_type = "datetime" sm.value = sm.type_conversion[sm.value_type](sm.match .. sm.ext) return true diff --git a/tlconfig.lua b/tlconfig.lua new file mode 100644 index 0000000..d3c82c8 --- /dev/null +++ b/tlconfig.lua @@ -0,0 +1,4 @@ +return { + gen_target = "5.1", + gen_compat = "off" +} \ No newline at end of file From 42436b3ed8219e601bb5bf83ac2aa34bc1fddbcb Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 Nov 2024 17:27:19 -0600 Subject: [PATCH 2/3] switching to latest v2.1 branch instead of rolling tag (which is out of date) --- .github/workflows/test-and-coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-and-coverage.yml b/.github/workflows/test-and-coverage.yml index 5ad3d31..b1c8269 100644 --- a/.github/workflows/test-and-coverage.yml +++ b/.github/workflows/test-and-coverage.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - lua: [lua=5.1, lua=5.2, lua=5.3, lua=5.4, luajit=2.0, luajit=@v2.1.ROLLING] + lua: [lua=5.1, lua=5.2, lua=5.3, lua=5.4, luajit=2.0, luajit=@v2.1] steps: - name: Fail on Draft PRs if: github.event.pull_request.draft == true From 8234c480f016bfa0f3d1a787b6c4753eaa0cf9e1 Mon Sep 17 00:00:00 2001 From: FourierTransformer Date: Mon, 4 Nov 2024 17:27:50 -0600 Subject: [PATCH 3/3] trying to enable on all PRs --- .github/workflows/test-and-coverage.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test-and-coverage.yml b/.github/workflows/test-and-coverage.yml index b1c8269..4cb5b0a 100644 --- a/.github/workflows/test-and-coverage.yml +++ b/.github/workflows/test-and-coverage.yml @@ -4,7 +4,6 @@ on: push: branches: [ main ] pull_request: - types: [review_requested, ready_for_review] jobs: test: