-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathslice.c
More file actions
87 lines (79 loc) · 3.14 KB
/
Copy pathslice.c
File metadata and controls
87 lines (79 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "slice.h"
#include "math/math.h"
string_slice make_string_slice(const char* buf, size_t start, size_t length){
if (strlen(buf) <= start) return (string_slice){};
length = min(strlen(buf+start),length);
return (string_slice){.data = (char*)buf + start, .length = length };
}
void string_split(const char *str, char seek, void (*perform)(string_slice slice)){
if (!str) return;
uintptr_t cursor = 0;
char *point = (char*)str;
do {
char *new_point = (char*)seek_to(point, seek);
if (new_point == point) break;
size_t size = new_point-point-(*new_point || *(new_point-1) == '/' ? 1 : 0);
perform((string_slice){.data = (char*)str + cursor, size});
point = new_point;
cursor += size+1;
if (*point == 0) break;
} while(point);
}
bool string_splitter_advance(string_splitter *splitter){
if (!splitter->str || !splitter->seek) return false;
if (splitter->pointer >= splitter->length) return false;
string_slice current = string_splitter_remaining(splitter);
if (!current.length) return false;
string_slice remaining = slice_seek_to(current, splitter->seek);
size_t size = remaining.length ? (size_t)(remaining.data-current.data-(*remaining.data || *(remaining.data-1) == splitter->seek ? 1 : 0)) : current.length;
splitter->current = current;
splitter->current.length = size;
splitter->pointer += size+1;
if (!size && !splitter->allow_empty) return string_splitter_advance(splitter);
return true;
}
bool string_quick_split(char *str, char seek, string_slice *lhs, string_slice *rhs){
if (!lhs || !rhs) return false;
size_t full_size = strlen(str);
if (!full_size) return false;
char *new_point = (char*)seek_to(str, seek);
if (new_point == str) return false;
size_t size = new_point-str-(*new_point || *(new_point-1) == '/' ? 1 : 0);
*lhs = (string_slice){.data = str, .length = size};
*rhs = (string_slice){.data = str + size, .length = full_size-size};
return true;
}
#define is_ws(c,include_newline) (c==' '||(include_newline && c=='\n')||c=='\t'||c=='\r')
string_slice slice_trim_ws(string_slice slice, bool include_newline){
if (!slice.length || !slice.data) return slice;
string_slice new_slice = slice;
u32 i = 0;
for (; i < slice.length; i++){
char c = slice.data[i];
if (is_ws(c,include_newline)){
new_slice.data++;
new_slice.length--;
} else break;
}
for (u32 j = slice.length-1; j > i; j--){
char c = slice.data[j];
if (is_ws(c,include_newline)){
new_slice.length--;
} else break;
}
return new_slice;
}
string_slice slice_seek_to(string_slice slice, char character){
for (u64 i = 0; i < slice.length; i++)
if (slice.data[i] == character)
return (string_slice){slice.data+i+1,slice.length-i-1};
return (string_slice){};
}
bool slice_ends_with(string_slice slice, string_slice seek){
i32 diff = slice.length-seek.length;
if (diff < 0) return false;
for (u32 i = 0; i < seek.length; i++){
if (slice.data[i+diff] != seek.data[i]) return false;
}
return true;
}