From 1e261cffddd9ec8189bcff89795d65a53af7bf42 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 6 Aug 2026 04:41:26 +0300 Subject: [PATCH 1/2] Switch all string.Trim* functinos to WireLib alternative Has better performance and will help avoid some problems --- .../base/preprocessor.lua | 71 +++---------------- .../gmod_wire_expression2/core/console.lua | 2 +- .../gmod_wire_expression2/core/e2lib.lua | 10 +-- .../gmod_wire_expression2/core/extpp.lua | 8 +-- .../gmod_wire_expression2/core/string.lua | 6 +- lua/entities/gmod_wire_target_finder.lua | 2 +- lua/entities/gmod_wire_turret.lua | 2 +- lua/weapons/gmod_tool/stools/wire_adv.lua | 2 +- .../gmod_tool/stools/wire_debugger.lua | 10 +-- lua/wire/client/text_editor/modes/zcpu.lua | 4 +- lua/wire/client/text_editor/texteditor.lua | 3 +- lua/wire/client/wire_filebrowser.lua | 10 +-- lua/wire/client/wire_listeditor.lua | 6 +- lua/wire/gates/string.lua | 3 +- lua/wire/stools/expression2.lua | 2 +- lua/wire/stools/friendslist.lua | 4 +- lua/wire/wireshared.lua | 57 +++++++++++++++ 17 files changed, 101 insertions(+), 101 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/base/preprocessor.lua b/lua/entities/gmod_wire_expression2/base/preprocessor.lua index 3a44320631..e308bc3500 100644 --- a/lua/entities/gmod_wire_expression2/base/preprocessor.lua +++ b/lua/entities/gmod_wire_expression2/base/preprocessor.lua @@ -64,7 +64,7 @@ local type_map = { } function PreProcessor:GetType(tp, trace) - tp = self:Trim(tp):lower() + tp = WireLib.Trim(tp):lower() local up = tp:upper() if tp == "normal" then @@ -83,61 +83,6 @@ function PreProcessor:HandlePPCommand(comment, col) end end -function PreProcessor:Trim(line) - local length = #line - local first - - for i = 1, length do - local b = string.byte(line, i) - - if b ~= 32 and (b < 9 or b > 13) then - first = i - break - end - end - - if not first then - return "" - end - - local last - - for i = length, 1, -1 do - local b = string.byte(line, i) - - if b ~= 32 and (b < 9 or b > 13) then - last = i - break - end - end - - return string.sub(line, first, last) -end - -function PreProcessor:TrimLeft(line) - for i = 1, #line do - local b = string.byte(line, i) - - if b ~= 32 and (b < 9 or b > 13) then - return string.sub(line, i) - end - end - - return "" -end - -function PreProcessor:TrimRight(line) - for i = #line, 1, -1 do - local b = string.byte(line, i) - - if b ~= 32 and (b < 9 or b > 13) then - return string.sub(line, 1, i) - end - end - - return "" -end - function PreProcessor:FindComments(line) local isinput = not self.blockcomment and not self.multilinestring and line:match("^@inputs") ~= nil local isoutput = not self.blockcomment and not self.multilinestring and line:match("^@outputs") ~= nil @@ -339,7 +284,7 @@ local directive_handlers = { ["persist"] = handleIO("persist"), ["trigger"] = function(self, value, trace) - local trimmed = PreProcessor.Trim(nil, value) + local trimmed = WireLib.Trim(value) if trimmed == "all" then if self.directives.trigger[1] ~= nil then self:Error("Directive (@trigger) conflicts with previous directives", trace) @@ -385,7 +330,7 @@ local directive_handlers = { end if CLIENT then - if #PreProcessor.Trim(nil, arg) > 0 then + if #WireLib.Trim(arg) > 0 then trace.start_col = trace.end_col + 1 trace.end_line = trace.start_line + 1 trace.end_col = 1 @@ -422,7 +367,7 @@ function PreProcessor:ParseDirectives(line) -- not a directive? if not directive then -- flag as "in code", if that is the case - if self:Trim(line) ~= "" then + if WireLib.Trim(line) ~= "" then self.incode = true end -- don't handle as a directive. @@ -488,7 +433,7 @@ function PreProcessor:Process(buffer, directives, ent) for i, line in ipairs(lines) do self.readline = i - line = self:TrimRight(line) + line = WireLib.TrimRight(line) line = self:RemoveComments(line) line = self:ParseDirectives(line) lines[i] = line @@ -545,7 +490,7 @@ function PreProcessor:ParsePorts(ports, startoffset) column2 = column + column2 local tr = Trace.new(self.readline, column2, self.readline, column2 + #var) - var = self:Trim(var) + var = WireLib.Trim(var) -- skip empty entries if var ~= "" then -- error on malformed variable names @@ -690,7 +635,7 @@ function PreProcessor:PP_else(args, trace) local state = table.remove(self.ifdefStack) if state == nil then self:Error("Found #else outside #ifdef/#ifndef block", trace) end - if self:Trim(args) ~= "" then self:Error("Must not pass an argument to #else", trace) end + if WireLib.Trim(args) ~= "" then self:Error("Must not pass an argument to #else", trace) end if self:Disabled() then table.insert(self.ifdefStack, false) @@ -703,7 +648,7 @@ function PreProcessor:PP_endif(args, trace) local state = table.remove(self.ifdefStack) if state == nil then self:Error("Found #endif outside #ifdef/#ifndef block", trace) end - if self:Trim(args) ~= "" then self:Error("Must not pass an argument to #endif", trace) end + if WireLib.Trim(args) ~= "" then self:Error("Must not pass an argument to #endif", trace) end end function PreProcessor:PP_error(args, trace) diff --git a/lua/entities/gmod_wire_expression2/core/console.lua b/lua/entities/gmod_wire_expression2/core/console.lua index c43a2250be..99254a8ef8 100644 --- a/lua/entities/gmod_wire_expression2/core/console.lua +++ b/lua/entities/gmod_wire_expression2/core/console.lua @@ -50,7 +50,7 @@ end local function getWhitelist(ply, cvar) local whitelist = {} - for _, v in ipairs(string.Split(string.Trim(ply:GetInfo(cvar)), ",")) do + for _, v in ipairs(string.Split(WireLib.Trim(ply:GetInfo(cvar)), ",")) do if v ~= "" then whitelist[v] = true end diff --git a/lua/entities/gmod_wire_expression2/core/e2lib.lua b/lua/entities/gmod_wire_expression2/core/e2lib.lua index 0ea5cd693f..5442c96691 100644 --- a/lua/entities/gmod_wire_expression2/core/e2lib.lua +++ b/lua/entities/gmod_wire_expression2/core/e2lib.lua @@ -855,7 +855,7 @@ do end function E2Lib.GetExtensionStatus(name) - name = name:Trim():lower() + name = WireLib.Trim(name):lower() return extensions.status[name] end @@ -885,7 +885,7 @@ do end function E2Lib.RegisterExtension(name, default, description, warning) - name = name:Trim():lower() + name = WireLib.Trim(name):lower() E2Lib.currentextension = name if extensions.status[ name ] == nil then @@ -903,7 +903,7 @@ do end function E2Lib.SetExtensionStatus( name, status ) - name = name:Trim():lower() + name = WireLib.Trim(name):lower() status = tobool( status ) extensions.status[ name ] = status if extensions.save then @@ -972,7 +972,7 @@ do end local name = args[ 1 ] if name then - name = name:Trim():lower() + name = WireLib.Trim(name):lower() if extensions.status[ name ] ~= nil then local status = tobool( cmd:find( "enable" ) ) if extensions.status[ name ] == status then @@ -1041,7 +1041,7 @@ do -- shared stuff local function makeAutoCompleteList( cmd, args ) - args = args:Trim():lower() + args = WireLib.Trim(args):lower() local status, list, tbl, j = tobool( cmd:find( "enable" ) ), extensions.list, {}, 1 for i = 1, #list do local name = list[ i ] diff --git a/lua/entities/gmod_wire_expression2/core/extpp.lua b/lua/entities/gmod_wire_expression2/core/extpp.lua index f42fc5496c..c2acbabcad 100644 --- a/lua/entities/gmod_wire_expression2/core/extpp.lua +++ b/lua/entities/gmod_wire_expression2/core/extpp.lua @@ -106,17 +106,17 @@ local function parseAttributes(attributes, trace) if attributes ~= "" and attributes:sub(1, 1) == "[" and attributes:sub(-1, -1) == "]" then local attrs = { legacy = "false" } -- extpp can generate functions abiding by the new compiler. for _, tag in ipairs(attributes:sub(2, -2):Split(",")) do - local k = tag:lower():Trim() + local k = WireLib.Trim(tag:lower()) if k:find("=", 1, true) then -- [xyz = 567, event = "Tick"] -- e2function number foo() local key, value = unpack(k:Split("="), 1, 2) - attrs[key:lower():Trim()] = value:Trim() + attrs[WireLib.Trim(key:lower())] = WireLib.Trim(value) elseif not ValidAttributes[k] then ErrorNoHalt("Invalid attribute fed to ExtPP: " .. k .. " " .. trace .. "\n") else - attrs[tag:lower():Trim()] = "true" + attrs[WireLib.Trim(tag:lower())] = "true" end end @@ -126,7 +126,7 @@ end --- Compact lua code to a single line to avoid changing lua's tracebacks. local function compact(lua) - return (lua:Trim():gsub("\n\t*", " ")) + return (WireLib.Trim(lua):gsub("\n\t*", " ")) end ---@param contents string diff --git a/lua/entities/gmod_wire_expression2/core/string.lua b/lua/entities/gmod_wire_expression2/core/string.lua index c7c6774b25..bbdd868689 100644 --- a/lua/entities/gmod_wire_expression2/core/string.lua +++ b/lua/entities/gmod_wire_expression2/core/string.lua @@ -233,15 +233,15 @@ __e2setcost(2) -- E2Lib.PreProcessor trimming functions are much more efficient than regular ones, so it's better to use them e2function string string:trim() - return E2Lib.PreProcessor.Trim(nil, this) + return WireLib.Trim(this) end e2function string string:trimLeft() - return E2Lib.PreProcessor.TrimLeft(nil, this) + return WireLib.TrimLeft(this) end e2function string string:trimRight() - return E2Lib.PreProcessor.TrimRight(nil, this) + return WireLib.TrimRight(this) end --[[******************************************************************************]]-- diff --git a/lua/entities/gmod_wire_target_finder.lua b/lua/entities/gmod_wire_target_finder.lua index c5a6b9ba3c..cbf86edea7 100644 --- a/lua/entities/gmod_wire_target_finder.lua +++ b/lua/entities/gmod_wire_target_finder.lua @@ -284,7 +284,7 @@ local function CheckPlayers(self, contact, tab) if not isOneOf(contact:GetName(), tab.PlayerName, tab.CaseSen) then return false end -- Check if the player's steamid/steamid64 matches the SteamIDs - if tab.SteamName:Trim() ~= "" then + if WireLib.Trim(tab.SteamName) ~= "" then local contact_steamid, contact_steamid64 = contact:SteamID(), contact:SteamID64() if not (isOneOf(contact_steamid, tab.SteamName, tab.CaseSen) or isOneOf(contact_steamid64, tab.SteamName, tab.CaseSen)) then diff --git a/lua/entities/gmod_wire_turret.lua b/lua/entities/gmod_wire_turret.lua index 98a2f9cf14..551a0cee34 100644 --- a/lua/entities/gmod_wire_turret.lua +++ b/lua/entities/gmod_wire_turret.lua @@ -132,7 +132,7 @@ function ENT:SetNumBullets( numbullets ) end function ENT:SetTracer( tracer ) - tracer = string.Trim(tracer) + tracer = WireLib.Trim(tracer) self.tracer = TracerEnabled:GetBool() and ValidTracers[tracer] and tracer or "" end diff --git a/lua/weapons/gmod_tool/stools/wire_adv.lua b/lua/weapons/gmod_tool/stools/wire_adv.lua index 1272cc31f7..137c12bc40 100644 --- a/lua/weapons/gmod_tool/stools/wire_adv.lua +++ b/lua/weapons/gmod_tool/stools/wire_adv.lua @@ -1109,7 +1109,7 @@ elseif CLIENT then local w = 0 local h = 0 for i=1,#lines do - lines[i] = string.Trim(lines[i]) + lines[i] = WireLib.Trim(lines[i]) local ww, hh = surface.GetTextSize( lines[i] ) w = math.max(w,ww) h = h + hh + 2 diff --git a/lua/weapons/gmod_tool/stools/wire_debugger.lua b/lua/weapons/gmod_tool/stools/wire_debugger.lua index 7cf2f3536e..07d29add9a 100644 --- a/lua/weapons/gmod_tool/stools/wire_debugger.lua +++ b/lua/weapons/gmod_tool/stools/wire_debugger.lua @@ -359,12 +359,12 @@ if (CLIENT) then local ExplodeLines = string.Explode("\n", Line) for Index, ExplodeLine in ipairs(ExplodeLines) do --break it into multible lines for 1 entry - if string.Trim(ExplodeLine) ~= "" then + if WireLib.Trim(ExplodeLine) ~= "" then local XPos = 0 if(Index > 1) then if dgb_orient_vert then --if the string is not the first and it is vertical, line it up acordingly - if(string.Trim(ExplodeLine) == "OUT:" or string.Trim(ExplodeLine) == "IN:") then + if(WireLib.Trim(ExplodeLine) == "OUT:" or WireLib.Trim(ExplodeLine) == "IN:") then XPos = 17 else XPos = 42 @@ -379,7 +379,7 @@ if (CLIENT) then end local TrimLine = { - LineText = string.Trim(ExplodeLine), + LineText = WireLib.Trim(ExplodeLine), OffsetPos = { XPos, Line_Count*14 } --move the next text down some for each line } table.insert(CurEntry.Lines, TrimLine ) @@ -410,7 +410,7 @@ if (CLIENT) then local TextWidth for _, Entry in ipairs(Entries) do for _, Line in ipairs(Entry.Lines) do - TextWidth = surface.GetTextSize(string.Trim(Line.LineText)) + TextWidth = surface.GetTextSize(WireLib.Trim(Line.LineText)) TextWidth = TextWidth+Line.OffsetPos[1] --offset it with the text's offset if(TextWidth > LongestWidth) then @@ -442,7 +442,7 @@ if (CLIENT) then for _, Entry in ipairs(Entries) do for _, Line in ipairs(Entry.Lines) do draw.Text({ - text = string.Trim(Line.LineText) or "", + text = WireLib.Trim(Line.LineText) or "", font = "Default", pos = { Line.OffsetPos[1]+10, 250*MoveBox+10+Line.OffsetPos[2] }, color = Entry.TextColor diff --git a/lua/wire/client/text_editor/modes/zcpu.lua b/lua/wire/client/text_editor/modes/zcpu.lua index 787d035881..49083cc806 100644 --- a/lua/wire/client/text_editor/modes/zcpu.lua +++ b/lua/wire/client/text_editor/modes/zcpu.lua @@ -220,7 +220,7 @@ function EDITOR:SyntaxColorLine(row) if self:NextPattern("^[a-zA-Z0-9_@.]+:") then tokenname = "label" elseif self:NextPattern("^[a-zA-Z0-9_@.]+") then - local sstr = string.upper(self.tokendata:Trim()) + local sstr = string.upper(WireLib.Trim(self.tokendata)) if opcodeTable[sstr] then tokenname = "opcode" elseif registersTable[sstr] then @@ -282,7 +282,7 @@ function EDITOR:SyntaxColorLine(row) tokenname = "normal" end elseif self:NextPattern("^[a-zA-Z0-9_@.#]+") then - local sstr = string.sub(string.upper(self.tokendata:Trim()),2) + local sstr = string.sub(string.upper(WireLib.Trim(self.tokendata)),2) if macroTable[sstr] then self:NextPattern(".*$") tokenname = "pmacro" diff --git a/lua/wire/client/text_editor/texteditor.lua b/lua/wire/client/text_editor/texteditor.lua index 6363e17acf..f6882db385 100644 --- a/lua/wire/client/text_editor/texteditor.lua +++ b/lua/wire/client/text_editor/texteditor.lua @@ -16,7 +16,6 @@ local string_gsub = string.gsub local string_rep = string.rep local string_byte = string.byte local string_format = string.format -local string_Trim = string.Trim local string_reverse = string.reverse local math_min = math.min local table_insert = table.insert @@ -237,7 +236,7 @@ function EDITOR:OpenContextMenu() for _, v in pairs( colors ) do local color = v[2][1] - if (prev_colors and prev_colors == color) or string_Trim(v[1]) == "" then + if (prev_colors and prev_colors == color) or WireLib.Trim(v[1]) == "" then str = str .. v[1] else prev_colors = color diff --git a/lua/wire/client/wire_filebrowser.lua b/lua/wire/client/wire_filebrowser.lua index 26c336431b..67b9a1b56f 100644 --- a/lua/wire/client/wire_filebrowser.lua +++ b/lua/wire/client/wire_filebrowser.lua @@ -57,7 +57,7 @@ local function PathFilter(Folder, TxtPanel, Root) end end - ValidFolder = string.Trim(ValidFolder) + ValidFolder = WireLib.Trim(ValidFolder) --[[ if string.sub(ValidFolder, 0, 4) == ".svn" then -- Disallow access to .svn folders. (Not needed.) ValidFolder = string.sub(ValidFolder, -4) @@ -74,7 +74,7 @@ local function PathFilter(Folder, TxtPanel, Root) end --]] - ValidFolder = string.Trim(ValidFolder, "/") + ValidFolder = WireLib.Trim(ValidFolder, "/") if IsValid(TxtPanel) then TxtPanel:SetText(ValidFolder) @@ -84,11 +84,11 @@ local function PathFilter(Folder, TxtPanel, Root) for i = 1, Dirs do if not file.IsDir(ConnectPathes(Root, ValidFolder), "GAME") then ValidFolder = string.GetPathFromFilename(ValidFolder) - ValidFolder = string.Trim(ValidFolder, "/") + ValidFolder = WireLib.Trim(ValidFolder, "/") end end - ValidFolder = string.Trim(ValidFolder, "/") + ValidFolder = WireLib.Trim(ValidFolder, "/") if ValidFolder == "" then return end return ValidFolder @@ -271,7 +271,7 @@ function PANEL:Init() if not path then return end path = string.sub(path, #self.m_strRootPath+1) - path = string.Trim(path, "/") + path = WireLib.Trim(path, "/") if not self.NotUserPressed then self.FolderPathText:SetText(path) diff --git a/lua/wire/client/wire_listeditor.lua b/lua/wire/client/wire_listeditor.lua index ca4fe9bc82..2397566e2a 100644 --- a/lua/wire/client/wire_listeditor.lua +++ b/lua/wire/client/wire_listeditor.lua @@ -79,7 +79,7 @@ local function ReadLine(filedata) if (char == "\n") then break end // line end line = line .. char end - line = string.Trim(line) + line = WireLib.Trim(line) if (not fileend and line == "") then continue end fileline = line @@ -95,9 +95,9 @@ local function ReadLine(filedata) local line = linetable[k] if (k == 1) then - line = string.Trim(line, "/") + line = WireLib.Trim(line, "/") end - line = string.Trim(line) + line = WireLib.Trim(line) linetable[k] = line end diff --git a/lua/wire/gates/string.lua b/lua/wire/gates/string.lua index e92afb325a..d41febd7a1 100644 --- a/lua/wire/gates/string.lua +++ b/lua/wire/gates/string.lua @@ -169,8 +169,7 @@ GateActions["string_trim"] = { inputtypes = { "STRING" }, outputtypes = { "STRING" }, output = function(gate, A) - if not A then A = "" end - return string.Trim(A) + return WireLib.Trim(A or "") end, label = function(Out, A) return string.format ("trim(%s) = %q", A, Out) diff --git a/lua/wire/stools/expression2.lua b/lua/wire/stools/expression2.lua index 55ab0ce58b..49bda2bec5 100644 --- a/lua/wire/stools/expression2.lua +++ b/lua/wire/stools/expression2.lua @@ -939,7 +939,7 @@ if CLIENT then name = string.sub(name, 1, -2) end - name = string.Trim(name) .. "..." + name = WireLib.Trim(name) .. "..." end function Expression2SetProgress(p, p2, w) diff --git a/lua/wire/stools/friendslist.lua b/lua/wire/stools/friendslist.lua index 852c80bc49..5c86405a9c 100644 --- a/lua/wire/stools/friendslist.lua +++ b/lua/wire/stools/friendslist.lua @@ -111,7 +111,7 @@ else local ret = {} for i=1,#t do - local str = string.Trim(t[i]) + local str = WireLib.Trim(t[i]) if string.match( str, "^STEAM_%d:%d:%d+$") ~= nil then ret[#ret+1] = str end @@ -220,7 +220,7 @@ else btn_add:SetText( "Add" ) function btn_add:DoClick() - local steamid = string.upper(string.Trim(txt:GetValue())) + local steamid = string.upper(WireLib.Trim(txt:GetValue())) if addSteamID( steamid ) then local ply = player.GetBySteamID( steamid ) diff --git a/lua/wire/wireshared.lua b/lua/wire/wireshared.lua index 7dc5d16458..0ff0c377f7 100644 --- a/lua/wire/wireshared.lua +++ b/lua/wire/wireshared.lua @@ -11,6 +11,7 @@ local Entity = Entity local string = string local string_gsub = string.gsub local string_char = string.char +local string_byte = string.byte local string_match = string.match local string_sub = string.sub local utf8_char = utf8.char @@ -76,6 +77,62 @@ function string.GetNormalizedFilepath( path ) -- luacheck: ignore return table.concat(tbl, "/") end +-- Cheaper string.Trim* functions +function WireLib.Trim(line) + local length = #line + local first + + for i = 1, length do + local b = string_byte(line, i) + + if b ~= 32 and (b < 9 or b > 13) then + first = i + break + end + end + + if not first then + return "" + end + + local last + + for i = length, 1, -1 do + local b = string_byte(line, i) + + if b ~= 32 and (b < 9 or b > 13) then + last = i + break + end + end + + return string_sub(line, first, last) +end + +function WireLib.TrimLeft(line) + for i = 1, #line do + local b = string_byte(line, i) + + if b ~= 32 and (b < 9 or b > 13) then + return string_sub(line, i) + end + end + + return "" +end + +function WireLib.TrimRight(line) + for i = #line, 1, -1 do + local b = string_byte(line, i) + + if b ~= 32 and (b < 9 or b > 13) then + return string_sub(line, 1, i) + end + end + + return "" +end + -- works like pairs() except that it iterates sorted by keys. -- criterion is optional and should be a function(a,b) returning whether a is less than b. (same as table.sort's criterions) function pairs_sortkeys(tbl, criterion) From 535f73cee90a141cac4a228147ad03c001d6f89b Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Thu, 6 Aug 2026 04:56:52 +0300 Subject: [PATCH 2/2] Fix github linter --- .github/workflows/preprocess.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preprocess.lua b/.github/workflows/preprocess.lua index b5ee115d6e..d5b940fc97 100644 --- a/.github/workflows/preprocess.lua +++ b/.github/workflows/preprocess.lua @@ -14,6 +14,7 @@ end -- Polyfills AddCSLuaFile = function() end _G.E2Lib = {} +_G.WireLib = {} _G.wire_expression_types = { VECTOR = {"v"}, VECTOR2 = {"xv2"}, VECTOR4 = {"xv4"}, STRING = {"s"}, @@ -33,7 +34,7 @@ _G.wire_expression_types = { if not unpack then unpack = table.unpack end function istable(t) return type(t) == "table" end -function string.Trim(s) +function WireLib.Trim(s) return string.match( s, "^%s*(.-)%s*$" ) or s end