Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WireLib.ParseEscapes #2752

Merged
merged 16 commits into from
Sep 18, 2023
4 changes: 1 addition & 3 deletions lua/entities/gmod_wire_value.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ function parsers.ANGLE( val )
return Angle(tonumber(p),tonumber(y),tonumber(r))
end
end
function parsers.STRING( val )
return string.gsub( tostring( val ), "\\[n0\\]", {["\\\\"] = "\\", ["\\n"] = "\n", ["\\0"] = "\0"} )
end
parsers.STRING = WireLib.ParseEscapes

function ENT:ParseValue( value, tp )
if parsers[tp] then
Expand Down
35 changes: 35 additions & 0 deletions lua/wire/wireshared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ local LocalPlayer = LocalPlayer
local Entity = Entity

local string = string
local string_gsub = string.gsub
local string_char = string.char
local string_match = string.match
local string_sub = string.sub
local utf8_char = utf8.char
local hook = hook

-- extra table functions
Expand Down Expand Up @@ -946,6 +951,36 @@ function WireLib.setLocalAng(ent, ang)
return ent:SetLocalAngles(ang)
end

local escapeChars = { n = "\n", r = "\r", t = "\t", ["\\"] = "\\", ["'"] = "'", ["\""] = "\"", a = "\a",
b = "\b", f = "\f", v = "\v" }

--- Replaces escape sequences with the appropriate character. Uses Lua escape sequences. Invalid sequences are skipped.
--- @param str string
function WireLib.ParseEscapes(str)
str = string_gsub(str, "\\(.?)([^\\]?[^\\]?[^\\]?[^\\]?[^\\]?[^\\]?[^\\]?}?)", function(i, arg)
if escapeChars[i] then
return escapeChars[i] .. arg
elseif i == "x" then
local num = string_match(arg, "^(%x%x)")
if not num then return false end
return string_char(tonumber(num, 16)) .. string_sub(arg, #num + 1)
elseif i >= "0" and i <= "9" then
local num = string_match(arg, "^(%d?%d?)")
if not num then return false end
local tonum = tonumber(i .. num)
return tonum < 256 and (string_char(tonum) .. string_sub(arg, #num + 1))
elseif i == "u" then
local num = string_match(arg, "^{(%x%x?%x?%x?%x?%x?)}")
if not num then return false end
local tonum = tonumber(num, 16)
return tonum <= 0x10ffff and utf8_char(tonum) .. string_sub(arg, #num + 3)
else
return false
end
end)
return str
end

-- Used by any applyForce function available to the user
-- Ensures that the force is within the range of a float, to prevent
-- physics engine crashes
Expand Down
Loading