From 02ad40eaae5a5cb7670587267244f813e5452274 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Tue, 4 Jul 2023 19:04:11 +0100
Subject: [PATCH] split_shell: add automated tests, and fix an obscure bug

---
 .tests/strings/split_shell.test.lua           | 60 +++++++++++++++++++
 .../utils/strings/split_shell.lua             | 18 ++++--
 2 files changed, 74 insertions(+), 4 deletions(-)
 create mode 100644 .tests/strings/split_shell.test.lua

diff --git a/.tests/strings/split_shell.test.lua b/.tests/strings/split_shell.test.lua
new file mode 100644
index 0000000..c477410
--- /dev/null
+++ b/.tests/strings/split_shell.test.lua
@@ -0,0 +1,60 @@
+local split_shell = require("worldeditadditions_core.utils.strings.split_shell")
+
+describe("split_shell", function()
+	it("should handle a single case x3", function()
+		assert.are.same(
+			{ "yay", "yay", "yay" },
+			split_shell("yay yay yay")
+		)
+	end)
+	
+	it("should handle double quotes simple", function()
+		assert.are.same(
+			{ "dirt", "snow block" },
+			split_shell("dirt \"snow block\"")
+		)
+	end)
+	
+	it("should handle an escaped double quote inside double quotes", function()
+		assert.are.same(
+			{ "yay", "yay\" yay", "yay" },
+			split_shell("yay \"yay\\\" yay\" yay")
+		)
+	end)
+	
+	it("should handle single quotes", function()
+		assert.are.same(
+			{ "yay", "yay", "yay" },
+			split_shell("yay 'yay' yay")
+		)
+	end)
+	
+	it("should handle single quotes again", function()
+		assert.are.same(
+			{ "yay", "inside quotes", "another" },
+			split_shell("yay 'inside quotes' another")
+		)
+	end)
+	
+	it("should handle single quotes inside double quotes", function()
+		assert.are.same(
+			{ "yay", "yay 'inside quotes' yay", "yay" },
+			split_shell("yay \"yay 'inside quotes' yay\" yay")
+		)
+	end)
+	
+	it("should handle single quotes and an escaped double quote inside double quotes", function()
+		assert.are.same(
+			{ "yay", "yay 'inside quotes' yay\"", "yay" },
+			split_shell("yay \"yay 'inside quotes' yay\\\"\" yay")
+		)
+	end)
+	
+	it("should handle a complex case", function()
+		assert.are.same(
+			{ "y\"ay", "yay", "in\"side quotes", "yay", "y\"ay" },
+			split_shell("y\"ay \"yay 'in\\\"side quotes' yay\" y\\\"ay")
+		)
+	end)
+	
+end)
\ No newline at end of file
diff --git a/worldeditadditions_core/utils/strings/split_shell.lua b/worldeditadditions_core/utils/strings/split_shell.lua
index ac0ea4a..33e349e 100644
--- a/worldeditadditions_core/utils/strings/split_shell.lua
+++ b/worldeditadditions_core/utils/strings/split_shell.lua
@@ -1,7 +1,16 @@
 -- worldeditadditions_core = { modpath="/home/sbrl/.minetest/worlds/Mod-Sandbox/worldmods/WorldEditAdditions/worldeditadditions_core/" }
-local wea_c = worldeditadditions_core
-local table_map = dofile(wea_c.modpath.."/utils/table/table_map.lua")
 
+local table_map, polyfill
+
+if minetest then
+	local wea_c = worldeditadditions_core
+	table_map = dofile(wea_c.modpath.."/utils/table/table_map.lua")
+	polyfill = wea_c
+else
+	table_map = require("worldeditadditions_core.utils.table.table_map")
+	polyfill = require("worldeditadditions_core.utils.strings.polyfill")
+end
+	
 local function is_whitespace(char)
 	return char:match("%s")
 end
@@ -13,6 +22,7 @@ local function split_shell(text, autotrim)
 	local acc = {}
 	local mode = "NORMAL"	-- NORMAL, INSIDE_QUOTES_SINGLE, INSIDE_QUOTES_DOUBLE
 	
+	print("\n\n\n\n\nDEBUG:split_shell START text", text, "autotrim", autotrim)
 	
 	for i=1,text_length do
 		local prevchar = ""
@@ -23,11 +33,11 @@ local function split_shell(text, autotrim)
 		if i < text_length then nextchar = text:sub(i+1, i+1) end
 		if i+1 < text_length then nextnextchar = text:sub(i+2, i+2) end
 		
-		-- print("mode", mode, "prevchar", prevchar, "curchar", curchar, "nextchar", nextchar)
+		print("mode", mode, "prevchar", prevchar, "curchar", curchar, "nextchar", nextchar)
 		
 		if mode == "NORMAL" then
 			if is_whitespace(curchar) and #acc > 0 then
-				local nextval = wea_c.trim(table.concat(acc, ""))
+				local nextval = polyfill.trim(table.concat(acc, ""))
 				if #nextval > 0 then
 					table.insert(result, table.concat(acc, ""))
 				end
