Browse Source

Builtin: Optimize misc helpers (#12377)

Also add formspec_escape unit test
Lars Müller 2 years ago
parent
commit
e8b2954586

+ 2 - 2
builtin/common/information_formspecs.lua

@@ -22,7 +22,6 @@ local LIST_FORMSPEC_DESCRIPTION = [[
 
 local F = core.formspec_escape
 local S = core.get_translator("__builtin")
-local check_player_privs = core.check_player_privs
 
 
 -- CHAT COMMANDS FORMSPEC
@@ -58,10 +57,11 @@ local function build_chatcommands_formspec(name, sel, copy)
 		.. "any entry in the list.").. "\n" ..
 		S("Double-click to copy the entry to the chat history.")
 
+	local privs = core.get_player_privs(name)
 	for i, data in ipairs(mod_cmds) do
 		rows[#rows + 1] = COLOR_BLUE .. ",0," .. F(data[1]) .. ","
 		for j, cmds in ipairs(data[2]) do
-			local has_priv = check_player_privs(name, cmds[2].privs)
+			local has_priv = privs[cmds[2].privs]
 			rows[#rows + 1] = ("%s,1,%s,%s"):format(
 				has_priv and COLOR_GREEN or COLOR_GRAY,
 				cmds[1], F(cmds[2].params))

+ 21 - 18
builtin/common/misc_helpers.lua

@@ -204,7 +204,7 @@ end
 
 --------------------------------------------------------------------------------
 function string:trim()
-	return (self:gsub("^%s*(.-)%s*$", "%1"))
+	return self:match("^%s*(.-)%s*$")
 end
 
 --------------------------------------------------------------------------------
@@ -245,16 +245,16 @@ function math.round(x)
 	return math.ceil(x - 0.5)
 end
 
-
+local formspec_escapes = {
+	["\\"] = "\\\\",
+	["["] = "\\[",
+	["]"] = "\\]",
+	[";"] = "\\;",
+	[","] = "\\,"
+}
 function core.formspec_escape(text)
-	if text ~= nil then
-		text = string.gsub(text,"\\","\\\\")
-		text = string.gsub(text,"%]","\\]")
-		text = string.gsub(text,"%[","\\[")
-		text = string.gsub(text,";","\\;")
-		text = string.gsub(text,",","\\,")
-	end
-	return text
+	-- Use explicit character set instead of dot here because it doubles the performance
+	return text and text:gsub("[\\%[%];,]", formspec_escapes)
 end
 
 
@@ -265,18 +265,21 @@ function core.wrap_text(text, max_length, as_table)
 		return as_table and {text} or text
 	end
 
-	for word in text:gmatch('%S+') do
-		local cur_length = #table.concat(line, ' ')
-		if cur_length > 0 and cur_length + #word + 1 >= max_length then
+	local line_length = 0
+	for word in text:gmatch("%S+") do
+		if line_length > 0 and line_length + #word + 1 >= max_length then
 			-- word wouldn't fit on current line, move to next line
-			table.insert(result, table.concat(line, ' '))
-			line = {}
+			table.insert(result, table.concat(line, " "))
+			line = {word}
+			line_length = #word
+		else
+			table.insert(line, word)
+			line_length = line_length + 1 + #word
 		end
-		table.insert(line, word)
 	end
 
-	table.insert(result, table.concat(line, ' '))
-	return as_table and result or table.concat(result, '\n')
+	table.insert(result, table.concat(line, " "))
+	return as_table and result or table.concat(result, "\n")
 end
 
 --------------------------------------------------------------------------------

+ 8 - 0
builtin/common/tests/misc_helpers_spec.lua

@@ -163,3 +163,11 @@ describe("table", function()
 		assert.equal(-1, table.indexof({"foo", "bar"}, "baz"))
 	end)
 end)
+
+describe("formspec_escape", function()
+	it("escapes", function()
+		assert.equal(nil, core.formspec_escape(nil))
+		assert.equal("", core.formspec_escape(""))
+		assert.equal("\\[Hello\\\\\\[", core.formspec_escape("[Hello\\["))
+	end)
+end)