Merge pull request #339 from dotbmp/master

"core:path" Path library and "core:strings" `split` Utilities
This commit is contained in:
gingerBill
2020-07-10 08:25:24 +01:00
committed by GitHub
5 changed files with 553 additions and 0 deletions
+150
View File
@@ -641,6 +641,7 @@ trim_space :: proc(s: string) -> string {
return trim_right_space(trim_left_space(s));
}
trim_left_null :: proc(s: string) -> string {
return trim_left_proc(s, is_null);
}
@@ -653,6 +654,155 @@ trim_null :: proc(s: string) -> string {
return trim_right_null(trim_left_null(s));
}
// returns a slice of sub-strings into `s`
// `allocator` is used only for the slice
// `skip_empty=true` does not return zero-length substrings
split :: proc{split_single, split_multi};
split_single :: proc(s, substr: string, skip_empty := false, allocator := context.temp_allocator) -> []string #no_bounds_check {
if s == "" || substr == "" do return nil;
sublen := len(substr);
shared := len(s) - sublen;
if shared <= 0 {
return nil;
}
// number, index, last
n, i, l := 0, 0, 0;
// count results
first_pass: for i <= shared {
if s[i:i+sublen] == substr {
if !skip_empty || i - l > 0 {
n += 1;
}
i += sublen;
l = i;
} else {
_, skip := utf8.decode_rune_in_string(s[i:]);
i += skip;
}
}
if !skip_empty || len(s) - l > 0 {
n += 1;
}
if n < 1 {
// no results
return nil;
}
buf := make([]string, n, allocator);
n, i, l = 0, 0, 0;
// slice results
second_pass: for i <= shared {
if s[i:i+sublen] == substr {
if !skip_empty || i - l > 0 {
buf[n] = s[l:i];
n += 1;
}
i += sublen;
l = i;
} else {
_, skip := utf8.decode_rune_in_string(s[i:]);
i += skip;
}
}
if !skip_empty || len(s) - l > 0 {
buf[n] = s[l:];
}
return buf;
}
split_multi :: proc(s: string, substrs: []string, skip_empty := false, allocator := context.temp_allocator) -> []string #no_bounds_check {
if s == "" || len(substrs) <= 0 {
return nil;
}
sublen := len(substrs[0]);
for substr in substrs[1:] {
sublen = min(sublen, len(substr));
}
shared := len(s) - sublen;
if shared <= 0 {
return nil;
}
// number, index, last
n, i, l := 0, 0, 0;
// count results
first_pass: for i <= shared {
for substr in substrs {
if s[i:i+sublen] == substr {
if !skip_empty || i - l > 0 {
n += 1;
}
i += sublen;
l = i;
continue first_pass;
}
}
_, skip := utf8.decode_rune_in_string(s[i:]);
i += skip;
}
if !skip_empty || len(s) - l > 0 {
n += 1;
}
if n < 1 {
// no results
return nil;
}
buf := make([]string, n, allocator);
n, i, l = 0, 0, 0;
// slice results
second_pass: for i <= shared {
for substr in substrs {
if s[i:i+sublen] == substr {
if !skip_empty || i - l > 0 {
buf[n] = s[l:i];
n += 1;
}
i += sublen;
l = i;
continue second_pass;
}
}
_, skip := utf8.decode_rune_in_string(s[i:]);
i += skip;
}
if !skip_empty || len(s) - l > 0 {
buf[n] = s[l:];
}
return buf;
}
// scrub scruvs invalid utf-8 characters and replaces them with the replacement string
// Adjacent invalid bytes are only replaced once
scrub :: proc(s: string, replacement: string, allocator := context.allocator) -> string {