aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2026-01-31 10:50:42 +0100
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2026-01-31 10:50:42 +0100
commit2b539bfcd5e540ae4bbddd43c39b8d261f80484c (patch)
treeba469e6bde1dc1b5ada42e621ae92826e8ac1800
parentb1122284f1930b49d7a079c55344888fd0935626 (diff)
Fix #6198
-rw-r--r--core/strings/intern.odin11
-rw-r--r--core/strings/strings.odin95
2 files changed, 67 insertions, 39 deletions
diff --git a/core/strings/intern.odin b/core/strings/intern.odin
index 0b8ed173e..909510c7c 100644
--- a/core/strings/intern.odin
+++ b/core/strings/intern.odin
@@ -30,6 +30,7 @@ Inputs:
- m: A pointer to the Intern struct to be initialized
- allocator: The allocator for the Intern_Entry strings (Default: context.allocator)
- map_allocator: The allocator for the map of entries (Default: context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- err: An allocator error if one occured, `nil` otherwise
@@ -78,6 +79,7 @@ Returns an interned copy of the given text as a cstring, adding it to the map if
Inputs:
- m: A pointer to the Intern struct
- text: The string to be interned
+- loc: The caller location for debugging purposes (default: `#caller_location`)
NOTE: The returned cstring lives as long as the map entry lives
@@ -85,8 +87,8 @@ Returns:
- str: The interned cstring
- err: An allocator error if one occured, `nil` otherwise
*/
-intern_get_cstring :: proc(m: ^Intern, text: string) -> (str: cstring, err: runtime.Allocator_Error) {
- entry := _intern_get_entry(m, text) or_return
+intern_get_cstring :: proc(m: ^Intern, text: string, loc := #caller_location) -> (str: cstring, err: runtime.Allocator_Error) {
+ entry := _intern_get_entry(m, text, loc) or_return
return cstring(&entry.str[0]), nil
}
@@ -99,12 +101,13 @@ Sets and allocates the entry if it wasn't set yet
Inputs:
- m: A pointer to the Intern struct
- text: The string to be looked up or interned
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- new_entry: The interned cstring
- err: An allocator error if one occured, `nil` otherwise
*/
-_intern_get_entry :: proc(m: ^Intern, text: string) -> (new_entry: ^Intern_Entry, err: runtime.Allocator_Error) #no_bounds_check {
+_intern_get_entry :: proc(m: ^Intern, text: string, loc := #caller_location) -> (new_entry: ^Intern_Entry, err: runtime.Allocator_Error) #no_bounds_check {
if m.allocator.procedure == nil {
m.allocator = context.allocator
}
@@ -115,7 +118,7 @@ _intern_get_entry :: proc(m: ^Intern, text: string) -> (new_entry: ^Intern_Entry
}
entry_size := int(offset_of(Intern_Entry, str)) + len(text) + 1
- bytes := runtime.mem_alloc(entry_size, align_of(Intern_Entry), m.allocator) or_return
+ bytes := runtime.mem_alloc(entry_size, align_of(Intern_Entry), m.allocator, loc) or_return
new_entry = (^Intern_Entry)(raw_data(bytes))
new_entry.len = len(text)
diff --git a/core/strings/strings.odin b/core/strings/strings.odin
index bad0ac26a..cda12f9dc 100644
--- a/core/strings/strings.odin
+++ b/core/strings/strings.odin
@@ -764,6 +764,7 @@ Inputs:
- rune_offset: The starting rune index (default is 0). In runes, not bytes.
- rune_length: The number of runes to include in the substring (default is 0, which returns the remainder of the string). In runes, not bytes.
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The substring
@@ -805,6 +806,7 @@ Inputs:
- sep_save: A flag determining if the separator should be saved in the resulting substrings
- n: The maximum number of substrings to return, returns `nil` without alloc when `n=0`
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
NOTE: Allocation occurs for the array, the splits are all views of the original string.
@@ -869,6 +871,7 @@ Inputs:
- s: The string to split.
- sep: The separator string used to split the input string.
- allocator: (default is context.allocator).
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice of strings, each representing a part of the split string.
@@ -892,8 +895,8 @@ Output:
["aaa", "bbb", "ccc", "ddd", "eee"]
*/
-split :: proc(s, sep: string, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
- return _split(s, sep, 0, -1, allocator)
+split :: proc(s, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+ return _split(s, sep, 0, -1, allocator, loc)
}
/*
@@ -906,6 +909,7 @@ Inputs:
- sep: The separator string used to split the input string.
- n: The maximum amount of parts to split the string into.
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice of strings, each representing a part of the split string.
@@ -929,8 +933,8 @@ Output:
["aaa", "bbb", "ccc.ddd.eee"]
*/
-split_n :: proc(s, sep: string, n: int, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
- return _split(s, sep, 0, n, allocator)
+split_n :: proc(s, sep: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+ return _split(s, sep, 0, n, allocator, loc)
}
/*
@@ -942,6 +946,7 @@ Inputs:
- s: The string to split.
- sep: The separator string used to split the input string.
- allocator: (default is context.allocator).
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice of strings, each representing a part of the split string after the separator
@@ -965,8 +970,8 @@ Output:
["aaa.", "bbb.", "ccc.", "ddd.", "eee"]
*/
-split_after :: proc(s, sep: string, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
- return _split(s, sep, len(sep), -1, allocator)
+split_after :: proc(s, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+ return _split(s, sep, len(sep), -1, allocator, loc)
}
/*
@@ -979,6 +984,7 @@ Inputs:
- sep: The separator string used to split the input string.
- n: The maximum number of parts to split the string into.
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice of strings with `n` parts or fewer if there weren't
@@ -1002,8 +1008,8 @@ Output:
["aaa.", "bbb.", "ccc.ddd.eee"]
*/
-split_after_n :: proc(s, sep: string, n: int, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
- return _split(s, sep, len(sep), n, allocator)
+split_after_n :: proc(s, sep: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+ return _split(s, sep, len(sep), n, allocator, loc)
}
/*
@@ -1196,6 +1202,7 @@ Splits the input string at every line break `\n`.
Inputs:
- s: The input string to split.
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice (allocated) of the split string (slices into original string)
@@ -1217,9 +1224,9 @@ Output:
["a", "b", "c", "d", "e"]
*/
-split_lines :: proc(s: string, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+split_lines :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
sep :: "\n"
- lines := _split(s, sep, 0, -1, allocator) or_return
+ lines := _split(s, sep, 0, -1, allocator, loc) or_return
for &line in lines {
line = _trim_cr(line)
}
@@ -1235,6 +1242,7 @@ Inputs:
- s: The input string to split.
- n: The number of parts to split into.
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice (allocated) of the split string (slices into original string)
@@ -1258,9 +1266,9 @@ Output:
["a", "b", "c\nd\ne"]
*/
-split_lines_n :: proc(s: string, n: int, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+split_lines_n :: proc(s: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
sep :: "\n"
- lines := _split(s, sep, 0, n, allocator) or_return
+ lines := _split(s, sep, 0, n, allocator, loc) or_return
for &line in lines {
line = _trim_cr(line)
}
@@ -1275,6 +1283,7 @@ Splits the input string at every line break `\n` leaving the `\n` in the resulti
Inputs:
- s: The input string to split.
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice (allocated) of the split string (slices into original string), with `\n` included
@@ -1298,9 +1307,9 @@ Output:
["a\n", "b\n", "c\n", "d\n", "e"]
*/
-split_lines_after :: proc(s: string, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+split_lines_after :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
sep :: "\n"
- lines := _split(s, sep, len(sep), -1, allocator) or_return
+ lines := _split(s, sep, len(sep), -1, allocator, loc) or_return
for &line in lines {
line = _trim_cr(line)
}
@@ -1317,6 +1326,7 @@ Inputs:
- s: The input string to split.
- n: The number of parts to split into.
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The slice (allocated) of the split string (slices into original string), with `\n` included
@@ -1340,9 +1350,9 @@ Output:
["a\n", "b\n", "c\nd\ne"]
*/
-split_lines_after_n :: proc(s: string, n: int, allocator := context.allocator) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
+split_lines_after_n :: proc(s: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error {
sep :: "\n"
- lines := _split(s, sep, len(sep), n, allocator) or_return
+ lines := _split(s, sep, len(sep), n, allocator, loc) or_return
for &line in lines {
line = _trim_cr(line)
}
@@ -1976,6 +1986,7 @@ Inputs:
- s: The string to repeat
- count: The number of times to repeat `s`
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The concatenated repeated string
@@ -2023,6 +2034,7 @@ Inputs:
- old: The substring to replace
- new: The substring to replace `old` with
- allocator: The allocator to use for the new string (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- output: The modified string
@@ -2047,8 +2059,8 @@ Output:
*/
-replace_all :: proc(s, old, new: string, allocator := context.allocator) -> (output: string, was_allocation: bool) {
- return replace(s, old, new, -1, allocator)
+replace_all :: proc(s, old, new: string, allocator := context.allocator, loc := #caller_location) -> (output: string, was_allocation: bool) {
+ return replace(s, old, new, -1, allocator, loc)
}
/*
@@ -2062,6 +2074,7 @@ Inputs:
- new: The replacement string
- n: The number of instances to replace (if `n < 0`, no limit on the number of replacements)
- allocator: (default: context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- output: The modified string
@@ -2140,6 +2153,7 @@ Inputs:
- key: The substring to be removed
- n: The number of instances to remove (if `n < 0`, no limit on the number of removes)
- allocator: (default: context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- output: The modified string
@@ -2165,8 +2179,8 @@ Output:
abcabc false
*/
-remove :: proc(s, key: string, n: int, allocator := context.allocator) -> (output: string, was_allocation: bool) {
- return replace(s, key, "", n, allocator)
+remove :: proc(s, key: string, n: int, allocator := context.allocator, loc := #caller_location) -> (output: string, was_allocation: bool) {
+ return replace(s, key, "", n, allocator, loc)
}
/*
@@ -2178,6 +2192,7 @@ Inputs:
- s: The input string
- key: The substring to be removed
- allocator: (default: context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- output: The modified string
@@ -2201,8 +2216,8 @@ Output:
abcabc false
*/
-remove_all :: proc(s, key: string, allocator := context.allocator) -> (output: string, was_allocation: bool) {
- return remove(s, key, -1, allocator)
+remove_all :: proc(s, key: string, allocator := context.allocator, loc := #caller_location) -> (output: string, was_allocation: bool) {
+ return remove(s, key, -1, allocator, loc)
}
// Returns true if is an ASCII space character ('\t', '\n', '\v', '\f', '\r', ' ')
@@ -2672,6 +2687,7 @@ Inputs:
- s: The input string
- substrs: An array of substrings used for splitting
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: An array of strings, or nil on empty substring or no matches
@@ -2805,6 +2821,7 @@ Inputs:
- s: The input string
- replacement: The string used to replace invalid UTF-8 characters
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: A new string with invalid UTF-8 characters replaced
@@ -2825,10 +2842,10 @@ Output:
Hello?
*/
-scrub :: proc(s: string, replacement: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
+scrub :: proc(s: string, replacement: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
str := s
b: Builder
- builder_init(&b, 0, len(s), allocator) or_return
+ builder_init(&b, 0, len(s), allocator, loc) or_return
has_error := false
cursor := 0
@@ -2865,6 +2882,7 @@ Reverses the input string `s`
Inputs:
- s: The input string
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: A reversed version of the input string
@@ -2910,6 +2928,7 @@ Inputs:
- s: The input string
- tab_size: The number of spaces to use for each tab character
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: A new string with tab characters expanded to the specified tab size
@@ -2932,7 +2951,7 @@ Output:
abc1 abc2 abc3
*/
-expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
+expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
if tab_size <= 0 {
panic("tab size must be positive")
}
@@ -2942,7 +2961,7 @@ expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator) ->
}
b: Builder
- builder_init(&b, allocator) or_return
+ builder_init(&b, allocator, loc) or_return
writer := to_writer(&b)
str := s
column: int
@@ -3038,22 +3057,23 @@ Inputs:
- length: The desired length of the centered string, in runes
- pad: The string used for padding on both sides
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: A new string centered within a field of the specified length
- err: An optional allocator error if one occured, `nil` otherwise
*/
-centre_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
+centre_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
n := rune_count(str)
if n >= length || pad == "" {
- return clone(str, allocator)
+ return clone(str, allocator, loc)
}
remains := length-n
pad_len := rune_count(pad)
b: Builder
- builder_init(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator) or_return
+ builder_init(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator, loc) or_return
w := to_writer(&b)
@@ -3074,22 +3094,23 @@ Inputs:
- length: The desired length of the left-justified string
- pad: The string used for padding on the right side
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: A new string left-justified within a field of the specified length
- err: An optional allocator error if one occured, `nil` otherwise
*/
-left_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
+left_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
n := rune_count(str)
if n >= length || pad == "" {
- return clone(str, allocator)
+ return clone(str, allocator, loc)
}
remains := length-n
pad_len := rune_count(pad)
b: Builder
- builder_init(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator) or_return
+ builder_init(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator, loc) or_return
w := to_writer(&b)
@@ -3109,22 +3130,23 @@ Inputs:
- length: The desired length of the right-justified string
- pad: The string used for padding on the left side
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: A new string right-justified within a field of the specified length
- err: An optional allocator error if one occured, `nil` otherwise
*/
-right_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
+right_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error {
n := rune_count(str)
if n >= length || pad == "" {
- return clone(str, allocator)
+ return clone(str, allocator, loc)
}
remains := length-n
pad_len := rune_count(pad)
b: Builder
- builder_init(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator) or_return
+ builder_init(&b, 0, len(str) + (remains/pad_len + 1)*len(pad), allocator, loc) or_return
w := to_writer(&b)
@@ -3169,6 +3191,7 @@ Splits a string into a slice of substrings at each instance of one or more conse
Inputs:
- s: The input string
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: A slice of substrings of the input string, or an empty slice if the input string only contains white space
@@ -3232,6 +3255,7 @@ Inputs:
- s: The input string
- f: A predicate function to determine the split points
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
NOTE: fields_proc makes no guarantee about the order in which it calls `f(r)`, it assumes that `f` always returns the same value for a given `r`
@@ -3315,6 +3339,7 @@ NOTE: Does not perform internal allocation if length of string `b`, in runes, is
Inputs:
- a, b: The two strings to compare
- allocator: (default is context.allocator)
+- loc: The caller location for debugging purposes (default: `#caller_location`)
Returns:
- res: The Levenshtein edit distance between the two strings