Initial commit

This commit is contained in:
4DBug
2026-10-07 13:03:05 -05:00
commit c2cf349390
17 changed files with 34877 additions and 0 deletions
+222
View File
@@ -0,0 +1,222 @@
if _G.__IMGUI_ENV then setfenv(1, _G.__IMGUI_ENV) end -- [Roblox] shared env, see init.lua
--- ImGui Sincerely
-- This is a minimal Lua impl of C-like sscanf, sprintf sub-set
-- Supports:
-- - %x, %X, %nx, %nX (where n is a number)
-- - %d, %nd (where n is a number)
-- - %f, %lf (very limited)
--
-- Returns items_matched instead of EOF on error
local _byte = string.byte
local CHAR_PERCENT = _byte'%'
local CHAR_DOT = _byte'.'
local CHAR_PLUS, CHAR_MINUS = _byte'+', _byte'-'
local CHAR_0, CHAR_9 = _byte'0', _byte'9'
local CHAR_a, CHAR_A = _byte'a', _byte'A'
local CHAR_d = _byte'd'
local CHAR_l = _byte'l'
local CHAR_f, CHAR_F = _byte'f', _byte'F'
local CHAR_x, CHAR_X = _byte'x', _byte'X'
local function isspace(c) return c == 32 or c == 9 end
local function isdigit(c) return c >= CHAR_0 and c <= CHAR_9 end
local function isxdigit(c) return isdigit(c) or (c >= CHAR_a and c <= CHAR_f) or (c >= CHAR_A and c <= CHAR_F) end
local function isdigit_under_base(c, base)
if base == 10 then return isdigit(c)
elseif base == 16 then return isxdigit(c)
end
end
local function hex_digit_to_int(c)
if c >= CHAR_0 and c <= CHAR_9 then return c - CHAR_0 end
if c >= CHAR_a and c <= CHAR_f then return c - CHAR_a + 10 end
if c >= CHAR_A and c <= CHAR_F then return c - CHAR_A + 10 end
end
-- we force this behavior by default
local function clamp_if_overflow(spec, val)
if spec == CHAR_d or spec == CHAR_x or spec == CHAR_X then
if val > INT_MAX then return INT_MAX end
if val < INT_MIN then return INT_MIN end
end
return val
end
--- @param buffer char[]
--- @param buffer_begin int
--- @param format string
--- @param result table # table to store parsed values
local function sscanf(buffer, buffer_begin, format, result)
local p = buffer_begin
local f = 1 -- format_begin
local format_len = #format
local assigned = 0
local items_matched = 0
while f <= format_len do
repeat
if isspace(_byte(format, f, f)) then
while isspace(buffer[p]) do
p = p + 1
end
f = f + 1
break
end
if _byte(format, f, f) ~= CHAR_PERCENT then
if buffer[p] == _byte(format, f, f) then
p = p + 1
f = f + 1
else
return items_matched
end
break
end
-- encountered % in fmt
f = f + 1
-- %%
if _byte(format, f, f) == CHAR_PERCENT then
if buffer[p] == CHAR_PERCENT then
p = p + 1
f = f + 1
else
return items_matched
end
break
end
-- handle optional width
local width = 0
while isdigit(_byte(format, f, f)) do
width = width * 10 + _byte(format, f, f) - CHAR_0
f = f + 1
end
if width == 0 then
width = math.huge
end
local spec = _byte(format, f, f)
local base
local is_float = false
if spec == CHAR_x or spec == CHAR_X then
base = 16
elseif spec == CHAR_d then
base = 10
elseif spec == CHAR_f or spec == CHAR_F then
is_float = true
elseif spec == CHAR_l then
f = f + 1
if _byte(format, f, f) == CHAR_f then
is_float = true -- TODO: distinguish from float?
else
return items_matched
end
else
return items_matched
end
f = f + 1
while isspace(buffer[p]) do
p = p + 1
end
local val
if is_float then
local sign = 1
if buffer[p] == CHAR_PLUS then
p = p + 1
elseif buffer[p] == CHAR_MINUS then
sign = -1
p = p + 1
end
-- inf, nan are not handled
local p_start = p
local int_part = 0
while isdigit(buffer[p]) do
int_part = int_part * 10 + (buffer[p] - CHAR_0)
p = p + 1
end
local frac_part = 0
local frac_div = 1
if buffer[p] == CHAR_DOT then
p = p + 1
while isdigit(buffer[p]) do
frac_part = frac_part * 10 + (buffer[p] - CHAR_0)
frac_div = frac_div * 10
p = p + 1
end
end
if p == p_start then
return items_matched
end
val = sign * (int_part + frac_part / frac_div)
else
local sign = 1
-- optional sign
if base == 10 then
if buffer[p] == CHAR_PLUS then
p = p + 1
width = width - 1
elseif buffer[p] == CHAR_MINUS then
sign = -1
p = p + 1
width = width - 1
end
end
local p_start = p
while width > 0 and buffer[p] and isdigit_under_base(buffer[p], base) do
p = p + 1
width = width - 1
end
if p == p_start then
-- failed to match
return items_matched
end
val = 0
while p_start < p do
local c = buffer[p_start]
p_start = p_start + 1
val = val * base + sign * hex_digit_to_int(c)
local old_val = val
val = clamp_if_overflow(spec, val)
if old_val ~= val then
break
end
end
end
result[assigned + 1] = val
assigned = assigned + 1
items_matched = items_matched + 1
until true
end
return items_matched
end
local function sprintf()
end
return sscanf