From 2010c9bc19ac66b653ae9f7369c9c1580e8d4946 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Fri, 22 Dec 2023 16:51:27 +0000 Subject: [PATCH 1/7] fully implement splittext and add test --- .../DMProject/Tests/Text/Splittext.dm | 39 ++++++++++++++ .../Procs/Native/DreamProcNativeRoot.cs | 53 +++++++++++++++---- 2 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 Content.Tests/DMProject/Tests/Text/Splittext.dm diff --git a/Content.Tests/DMProject/Tests/Text/Splittext.dm b/Content.Tests/DMProject/Tests/Text/Splittext.dm new file mode 100644 index 0000000000..3a7bf26cf4 --- /dev/null +++ b/Content.Tests/DMProject/Tests/Text/Splittext.dm @@ -0,0 +1,39 @@ +/proc/list_equal_asert(list/A, list/B) + ASSERT(length(A) == length(B)) + for (var/i = 1; i <= length(A); i++) + ASSERT(A[i] == B[i]) + +/proc/RunTest() + var/test_text = "The average of 1, 2, 3, 4, 5 is: 3" + var/list/test1 = splittext(test_text, " ") + var/list/test1_expected = list("The","average","of","1,","2,","3,","4,","5","is:","3") + list_equal_asert(test1, test1_expected) + + var/list/test2 = splittext(test_text, " ", 5) + var/test2_expected = list("average","of","1,","2,","3,","4,","5","is:","3") + list_equal_asert(test2, test2_expected) + + var/list/test3 = splittext(test_text, " ", 5, 10) + var/test3_expected = list("avera") + list_equal_asert(test3, test3_expected) + + var/list/test4 = splittext(test_text, " ", 10, 20) + var/test4_expected = list("ge","of","1,","2") + list_equal_asert(test4, test4_expected) + + var/list/test5 = splittext(test_text, " ", 10, 20, 1) + var/test5_expected = list("ge"," ","of"," ","1,"," ","2") + list_equal_asert(test5, test5_expected) + + //it's regex time + var/test6 = splittext(test_text, regex(@"\d")) + var/test6_expected = list("The average of ",", ",", ",", ",", "," is: ","") + list_equal_asert(test6, test6_expected) + + var/test7 = splittext(test_text, regex(@"\d"), 5, 30) + var/test7_expected = list("average of ",", ",", ",", ",", "," ") + list_equal_asert(test7, test7_expected) + + var/test8 = splittext(test_text, regex(@"\d"), 5, 30, 1) + var/test8_expected = list("average of ","1",", ","2",", ","3",", ","4",", ","5"," ") + list_equal_asert(test8, test8_expected) \ No newline at end of file diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index 224e5b5ea2..1cb12ceb4d 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -2361,22 +2361,57 @@ public static DreamValue NativeProc_splicetext_char(NativeProc.Bundle bundle, Dr [DreamProc("splittext")] [DreamProcParameter("Text", Type = DreamValueTypeFlag.String)] [DreamProcParameter("Delimiter", Type = DreamValueTypeFlag.String)] + [DreamProcParameter("Start", Type = DreamValueTypeFlag.Float, DefaultValue = 1)] + [DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 0)] + [DreamProcParameter("include_delimiters", Type = DreamValueTypeFlag.Float, DefaultValue = 0)] public static DreamValue NativeProc_splittext(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) { if (!bundle.GetArgument(0, "Text").TryGetValueAsString(out var text)) { return new DreamValue(bundle.ObjectTree.CreateList()); } - var arg2 = bundle.GetArgument(1, "Delimiter"); - if (!arg2.TryGetValueAsString(out var delimiter)) { - if (!arg2.Equals(DreamValue.Null)) { - return new DreamValue(bundle.ObjectTree.CreateList()); + int start = 0; + int end = 0; + if(bundle.GetArgument(2, "Start").TryGetValueAsInteger(out start)) + start -= 1; //1-indexed + if(bundle.GetArgument(3, "End").TryGetValueAsInteger(out end)) + if(end == 0) + end = text.Length; + else + end -= 1; //1-indexed + bool include_delimiters = bundle.GetArgument(4, "include_delimiters").IsTruthy(); + + if(start > 0 || end < text.Length) + text = text[Math.Max(start,0)..Math.Min(end, text.Length)]; + + var delim = bundle.GetArgument(1, "Delimiter"); //can either be a regex or string + + if (delim.TryGetValueAsDreamObject(out var regexObject)) { + if(include_delimiters) { + var values = new List(); + int pos = 0; + foreach (Match m in regexObject.Regex.Matches(text)) { + values.Add(text.Substring(pos, m.Index - pos)); + values.Add(m.Value); + pos = m.Index + m.Length; + } + values.Add(text.Substring(pos)); + return new DreamValue(bundle.ObjectTree.CreateList(values.ToArray())); + } else { + return new DreamValue(bundle.ObjectTree.CreateList(regexObject.Regex.Split(text))); } + } else if (delim.TryGetValueAsString(out var delimiter)) { + string[] splitText; + if(include_delimiters) { + //basically split on delimeter, and then add the delimiter back in after each split (except the last one) + splitText= text.Split(delimiter); + splitText = splitText.SelectMany((s, index) => index < splitText.Length - 1 ? new List { s, delimiter } : new List { s }).ToArray(); + } else { + splitText = text.Split(delimiter); + } + return new DreamValue(bundle.ObjectTree.CreateList(splitText)); + } else { + return new DreamValue(bundle.ObjectTree.CreateList()); } - - string[] splitText = text.Split(delimiter); - DreamList list = bundle.ObjectTree.CreateList(splitText); - - return new DreamValue(list); } private static void OutputToStatPanel(DreamManager dreamManager, DreamConnection connection, DreamValue name, DreamValue value) { From 55d2cd85dbc1fcd1c48b9a8a601e488145e37262 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Sat, 6 Jan 2024 11:30:52 +0000 Subject: [PATCH 2/7] test list comparison --- Content.Tests/DMProject/Tests/Text/Splittext.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Content.Tests/DMProject/Tests/Text/Splittext.dm b/Content.Tests/DMProject/Tests/Text/Splittext.dm index 3a7bf26cf4..130c1aaf49 100644 --- a/Content.Tests/DMProject/Tests/Text/Splittext.dm +++ b/Content.Tests/DMProject/Tests/Text/Splittext.dm @@ -1,7 +1,6 @@ /proc/list_equal_asert(list/A, list/B) ASSERT(length(A) == length(B)) - for (var/i = 1; i <= length(A); i++) - ASSERT(A[i] == B[i]) + ASSERT(A ~= B) /proc/RunTest() var/test_text = "The average of 1, 2, 3, 4, 5 is: 3" From 1f61892bc95229a2636f1060ffdde1b269406c16 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Sat, 6 Jan 2024 11:31:17 +0000 Subject: [PATCH 3/7] fix include_delimiters --- OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index 1cb12ceb4d..58d7d66567 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -2378,7 +2378,9 @@ public static DreamValue NativeProc_splittext(NativeProc.Bundle bundle, DreamObj end = text.Length; else end -= 1; //1-indexed - bool include_delimiters = bundle.GetArgument(4, "include_delimiters").IsTruthy(); + bool includeDelimiters = false; + if(bundle.GetArgument(4, "include_delimiters").TryGetValueAsInteger(out var include_delimiters_int)) + includeDelimiters = include_delimiters_int != 0; //idk why BYOND doesn't just use truthiness, but it doesn't, so... if(start > 0 || end < text.Length) text = text[Math.Max(start,0)..Math.Min(end, text.Length)]; @@ -2386,7 +2388,7 @@ public static DreamValue NativeProc_splittext(NativeProc.Bundle bundle, DreamObj var delim = bundle.GetArgument(1, "Delimiter"); //can either be a regex or string if (delim.TryGetValueAsDreamObject(out var regexObject)) { - if(include_delimiters) { + if(includeDelimiters) { var values = new List(); int pos = 0; foreach (Match m in regexObject.Regex.Matches(text)) { @@ -2401,7 +2403,7 @@ public static DreamValue NativeProc_splittext(NativeProc.Bundle bundle, DreamObj } } else if (delim.TryGetValueAsString(out var delimiter)) { string[] splitText; - if(include_delimiters) { + if(includeDelimiters) { //basically split on delimeter, and then add the delimiter back in after each split (except the last one) splitText= text.Split(delimiter); splitText = splitText.SelectMany((s, index) => index < splitText.Length - 1 ? new List { s, delimiter } : new List { s }).ToArray(); From 422bfeb3a5f97084de7c20a149324f5c7b585a1b Mon Sep 17 00:00:00 2001 From: amylizzle Date: Sat, 6 Jan 2024 14:52:39 +0000 Subject: [PATCH 4/7] array instead of linq --- OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index 58d7d66567..c926153451 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -2406,7 +2406,13 @@ public static DreamValue NativeProc_splittext(NativeProc.Bundle bundle, DreamObj if(includeDelimiters) { //basically split on delimeter, and then add the delimiter back in after each split (except the last one) splitText= text.Split(delimiter); - splitText = splitText.SelectMany((s, index) => index < splitText.Length - 1 ? new List { s, delimiter } : new List { s }).ToArray(); + string[] longerSplitText = new string[splitText.Length * 2 - 1]; + for(int i = 0; i < splitText.Length; i++) { + longerSplitText[i * 2] = splitText[i]; + if(i < splitText.Length - 1) + longerSplitText[i * 2 + 1] = delimiter; + } + splitText = longerSplitText; } else { splitText = text.Split(delimiter); } From 834e327db3a673047bfd23f498c6cb1e8f4ebdf6 Mon Sep 17 00:00:00 2001 From: Amy <3855802+amylizzle@users.noreply.github.com> Date: Sun, 7 Jan 2024 10:37:18 +0000 Subject: [PATCH 5/7] Update OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs Co-authored-by: wixoa --- OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index c926153451..b111ac6325 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -2379,8 +2379,8 @@ public static DreamValue NativeProc_splittext(NativeProc.Bundle bundle, DreamObj else end -= 1; //1-indexed bool includeDelimiters = false; - if(bundle.GetArgument(4, "include_delimiters").TryGetValueAsInteger(out var include_delimiters_int)) - includeDelimiters = include_delimiters_int != 0; //idk why BYOND doesn't just use truthiness, but it doesn't, so... + if(bundle.GetArgument(4, "include_delimiters").TryGetValueAsInteger(out var includeDelimitersInt)) + includeDelimiters = includeDelimitersInt != 0; //idk why BYOND doesn't just use truthiness, but it doesn't, so... if(start > 0 || end < text.Length) text = text[Math.Max(start,0)..Math.Min(end, text.Length)]; From 2e721e8f31e4d382be49624092b3acc1a43ccea3 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Sun, 7 Jan 2024 10:40:11 +0000 Subject: [PATCH 6/7] duh --- .../DMProject/Tests/Text/Splittext.dm | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Content.Tests/DMProject/Tests/Text/Splittext.dm b/Content.Tests/DMProject/Tests/Text/Splittext.dm index 130c1aaf49..276ebe841f 100644 --- a/Content.Tests/DMProject/Tests/Text/Splittext.dm +++ b/Content.Tests/DMProject/Tests/Text/Splittext.dm @@ -1,38 +1,34 @@ -/proc/list_equal_asert(list/A, list/B) - ASSERT(length(A) == length(B)) - ASSERT(A ~= B) - /proc/RunTest() var/test_text = "The average of 1, 2, 3, 4, 5 is: 3" var/list/test1 = splittext(test_text, " ") var/list/test1_expected = list("The","average","of","1,","2,","3,","4,","5","is:","3") - list_equal_asert(test1, test1_expected) + test1 ~= test1_expected var/list/test2 = splittext(test_text, " ", 5) var/test2_expected = list("average","of","1,","2,","3,","4,","5","is:","3") - list_equal_asert(test2, test2_expected) + test2 ~= test2_expected var/list/test3 = splittext(test_text, " ", 5, 10) var/test3_expected = list("avera") - list_equal_asert(test3, test3_expected) + test3 ~= test3_expected var/list/test4 = splittext(test_text, " ", 10, 20) var/test4_expected = list("ge","of","1,","2") - list_equal_asert(test4, test4_expected) + test4 ~= test4_expected var/list/test5 = splittext(test_text, " ", 10, 20, 1) var/test5_expected = list("ge"," ","of"," ","1,"," ","2") - list_equal_asert(test5, test5_expected) + test5 ~= test5_expected //it's regex time var/test6 = splittext(test_text, regex(@"\d")) var/test6_expected = list("The average of ",", ",", ",", ",", "," is: ","") - list_equal_asert(test6, test6_expected) + test6 ~= test6_expected var/test7 = splittext(test_text, regex(@"\d"), 5, 30) var/test7_expected = list("average of ",", ",", ",", ",", "," ") - list_equal_asert(test7, test7_expected) + test7 ~= test7_expected var/test8 = splittext(test_text, regex(@"\d"), 5, 30, 1) var/test8_expected = list("average of ","1",", ","2",", ","3",", ","4",", ","5"," ") - list_equal_asert(test8, test8_expected) \ No newline at end of file + test8 ~= test8_expected \ No newline at end of file From b16f156bd8be58d0b4d74f9420060781c7efe111 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Sun, 7 Jan 2024 17:34:10 +0000 Subject: [PATCH 7/7] I am dum --- Content.Tests/DMProject/Tests/Text/Splittext.dm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Content.Tests/DMProject/Tests/Text/Splittext.dm b/Content.Tests/DMProject/Tests/Text/Splittext.dm index 276ebe841f..da2d898418 100644 --- a/Content.Tests/DMProject/Tests/Text/Splittext.dm +++ b/Content.Tests/DMProject/Tests/Text/Splittext.dm @@ -2,33 +2,33 @@ var/test_text = "The average of 1, 2, 3, 4, 5 is: 3" var/list/test1 = splittext(test_text, " ") var/list/test1_expected = list("The","average","of","1,","2,","3,","4,","5","is:","3") - test1 ~= test1_expected + ASSERT(test1 ~= test1_expected) var/list/test2 = splittext(test_text, " ", 5) var/test2_expected = list("average","of","1,","2,","3,","4,","5","is:","3") - test2 ~= test2_expected + ASSERT(test2 ~= test2_expected) var/list/test3 = splittext(test_text, " ", 5, 10) var/test3_expected = list("avera") - test3 ~= test3_expected + ASSERT(test3 ~= test3_expected) var/list/test4 = splittext(test_text, " ", 10, 20) var/test4_expected = list("ge","of","1,","2") - test4 ~= test4_expected + ASSERT(test4 ~= test4_expected) var/list/test5 = splittext(test_text, " ", 10, 20, 1) var/test5_expected = list("ge"," ","of"," ","1,"," ","2") - test5 ~= test5_expected + ASSERT(test5 ~= test5_expected) //it's regex time var/test6 = splittext(test_text, regex(@"\d")) var/test6_expected = list("The average of ",", ",", ",", ",", "," is: ","") - test6 ~= test6_expected + ASSERT(test6 ~= test6_expected) var/test7 = splittext(test_text, regex(@"\d"), 5, 30) var/test7_expected = list("average of ",", ",", ",", ",", "," ") - test7 ~= test7_expected + ASSERT(test7 ~= test7_expected) var/test8 = splittext(test_text, regex(@"\d"), 5, 30, 1) var/test8_expected = list("average of ","1",", ","2",", ","3",", ","4",", ","5"," ") - test8 ~= test8_expected \ No newline at end of file + ASSERT(test8 ~= test8_expected) \ No newline at end of file