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 trim method to string_rt #702

Merged
merged 3 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
type T dyn;

f<int> print<T>(T g) {
printf("%d", g);
return 0;
}

f<int> main() {
print(1);
print("string");
String test = String("String to be trimmed ");
printf("'%s'\n", test);
String trimmed = test.trim();
printf("'%s'\n", trimmed);
}
5 changes: 1 addition & 4 deletions src-bootstrap/util/common-util.spice
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ import "bootstrap/source-file-intf";
*/
public f<String> getLastFragment(const String &haystack, const string needle) {
const unsigned long index = haystack.rfind(needle);
if index == -1l {
return haystack;
}
return haystack.getSubstring(index + getRawLength(needle));
return index != -1l ? haystack.getSubstring(index + getRawLength(needle)) : haystack;
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/util/CommonUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ std::string CommonUtil::getLastFragment(const std::string &haystack, const std::
*/
std::string CommonUtil::trim(const std::string &input) {
const size_t first = input.find_first_not_of(' ');
if (std::string::npos == first)
if (first == std::string::npos)
return input;
const size_t last = input.find_last_not_of(' ');
return input.substr(first, (last - first + 1));
const size_t newLength = last - first + 1;
return input.substr(first, newLength);
}

/**
Expand Down
27 changes: 27 additions & 0 deletions std/runtime/string_rt.spice
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#![core.compiler.alwaysKeepOnNameCollision = true]

// Std imports
import "std/text/analysis";

// Link external functions
// We intentionally do not use the memory_rt here to avoid dependency circles
ext f<heap char*> malloc(unsigned long);
Expand Down Expand Up @@ -588,6 +591,7 @@ public f<String> String.getSubstring<IntLongShort>(unsigned IntLongShort startId
// Get substring
String substring = String("");
substring.reserve(length);
substring.length = length;
const unsigned long endIdx = startIdx + length;
for unsigned long charIndex = (unsigned long) startIdx; charIndex < endIdx; charIndex++ {
unsafe {
Expand All @@ -604,6 +608,29 @@ public f<String> String.getSubstring<IntLongShort>(unsigned IntLongShort startId
return substring;
}

/**
* Returns a new string without leading or trailing whitespaces.
*
* @return Trimmed string
*/
public f<String> String.trim() {
if this.length == 0l {
return String();
}
unsigned long startIdx = 0l;
unsigned long endIdx = this.length - 1l;

unsafe {
// Find first char that is not a whitespace
while isWhitespace(this.contents[startIdx]) { startIdx++; }
// Find last char that is not a whitespace
while isWhitespace(this.contents[endIdx]) { endIdx--; }
}

const unsigned long newLength = endIdx - startIdx + 1;
return this.getSubstring(startIdx, newLength);
}

/**
* Reserves `charCount` items
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,14 @@ attributes #2 = { nofree nounwind }
!30 = !DIDerivedType(tag: DW_TAG_member, name: "lng", scope: !28, file: !7, line: 2, baseType: !31, size: 64)
!31 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
!32 = !DIDerivedType(tag: DW_TAG_member, name: "str", scope: !28, file: !7, line: 3, baseType: !33, size: 192, align: 8, offset: 64)
!33 = !DICompositeType(tag: DW_TAG_structure_type, name: "String", scope: !7, file: !7, line: 18, size: 192, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !34, identifier: "struct.String")
!33 = !DICompositeType(tag: DW_TAG_structure_type, name: "String", scope: !7, file: !7, line: 21, size: 192, align: 8, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !34, identifier: "struct.String")
!34 = !{!35, !38, !40}
!35 = !DIDerivedType(tag: DW_TAG_member, name: "contents", scope: !33, file: !7, line: 19, baseType: !36, size: 64)
!35 = !DIDerivedType(tag: DW_TAG_member, name: "contents", scope: !33, file: !7, line: 22, baseType: !36, size: 64)
!36 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !37, size: 64)
!37 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
!38 = !DIDerivedType(tag: DW_TAG_member, name: "capacity", scope: !33, file: !7, line: 20, baseType: !39, size: 64, offset: 64)
!38 = !DIDerivedType(tag: DW_TAG_member, name: "capacity", scope: !33, file: !7, line: 23, baseType: !39, size: 64, offset: 64)
!39 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned)
!40 = !DIDerivedType(tag: DW_TAG_member, name: "length", scope: !33, file: !7, line: 21, baseType: !39, size: 64, offset: 128)
!40 = !DIDerivedType(tag: DW_TAG_member, name: "length", scope: !33, file: !7, line: 24, baseType: !39, size: 64, offset: 128)
!41 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !28, file: !7, line: 4, baseType: !42, size: 32, offset: 256)
!42 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!43 = !{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ f<int> main() {
dyn s2 = String("Hello");
dyn s3 = String("Hello!");
dyn s4 = String("Hello World!");
dyn s5 = String(" \n\tString to be trimmed \r ");

assert s1.isEmpty();
assert !s2.isEmpty();
Expand Down Expand Up @@ -40,6 +41,9 @@ f<int> main() {
assert !s4.startsWith("World");
assert s4.endsWith("!");
assert !s2.endsWith("!");
assert s5.trim() == "String to be trimmed";
assert s1.trim() == "";
assert s3.trim() == s3;

printf("All assertions passed!");
}
Loading