Skip to content

Add remaining SV.h functions + test file #70

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions nob.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const char *test_names[] = {
"da_append",
"sb_appendf",
"da_foreach",
"nob_sv_test",
};
#define test_names_count ARRAY_LEN(test_names)

Expand Down
152 changes: 152 additions & 0 deletions nob.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
Expand Down Expand Up @@ -612,6 +613,25 @@ Nob_String_View nob_sv_from_parts(const char *data, size_t count);
// nob_sb_to_sv() enables you to just view Nob_String_Builder as Nob_String_View
#define nob_sb_to_sv(sb) nob_sv_from_parts((sb).items, (sb).count)

Nob_String_View nob_sv_take_left_while(Nob_String_View sv, bool (*predicate)(char x));
Nob_String_View nob_sv_chop_by_sv(Nob_String_View *sv, Nob_String_View thicc_delim);
bool nob_sv_try_chop_by_delim(Nob_String_View *sv, char delim, Nob_String_View *chunk);
Nob_String_View nob_sv_chop_right(Nob_String_View *sv, size_t n);
Nob_String_View nob_sv_chop_left_while(Nob_String_View *sv, bool (*predicate)(char x));
bool nob_sv_index_of(Nob_String_View sv, char c, size_t *index);
bool nob_sv_eq_ignorecase(Nob_String_View a, Nob_String_View b);
uint64_t nob_sv_to_u64(Nob_String_View sv);
uint64_t nob_sv_chop_u64(Nob_String_View *sv);

#define SV(cstr_lit) nob_sv_from_parts(cstr_lit, sizeof(cstr_lit) - 1)
#define SV_STATIC(cstr_lit) \
{ \
sizeof(cstr_lit) - 1, \
(cstr_lit) \
}

#define SV_NULL nob_sv_from_parts(NULL, 0)

// printf macros for String_View
#ifndef SV_Fmt
#define SV_Fmt "%.*s"
Expand Down Expand Up @@ -1762,6 +1782,109 @@ bool nob_sv_end_with(Nob_String_View sv, const char *cstr)
return false;
}

Nob_String_View nob_sv_take_left_while(Nob_String_View sv, bool (*predicate)(char x)) {
size_t i = 0;
while (i < sv.count && predicate(sv.data[i])) {
i += 1;
}
return nob_sv_from_parts(sv.data, i);
}

Nob_String_View nob_sv_chop_by_sv(Nob_String_View *sv, Nob_String_View thicc_delim) {
Nob_String_View window = nob_sv_from_parts(sv->data, thicc_delim.count);
size_t i = 0;
while (i + thicc_delim.count < sv->count && !(nob_sv_eq(window, thicc_delim))) {
i++;
window.data++;
}

Nob_String_View result = nob_sv_from_parts(sv->data, i);

if (i + thicc_delim.count == sv->count) {
// include last <thicc_delim.count> characters if they aren't
// equal to thicc_delim
result.count += thicc_delim.count;
}

// Chop!
sv->data += i + thicc_delim.count;
sv->count -= i + thicc_delim.count;

return result;
}

bool nob_sv_try_chop_by_delim(Nob_String_View *sv, char delim, Nob_String_View *chunk) {
size_t i = 0;
while (i < sv->count && sv->data[i] != delim) {
i += 1;
}

Nob_String_View result = nob_sv_from_parts(sv->data, i);

if (i < sv->count) {
sv->count -= i + 1;
sv->data += i + 1;
if (chunk) {
*chunk = result;
}
return true;
}

return false;
}

Nob_String_View nob_sv_chop_right(Nob_String_View *sv, size_t n) {
if (n > sv->count) {
n = sv->count;
}

Nob_String_View result = nob_sv_from_parts(sv->data + sv->count - n, n);

sv->count -= n;

return result;
}

Nob_String_View nob_sv_chop_left_while(Nob_String_View *sv, bool (*predicate)(char x)) {
size_t i = 0;
while (i < sv->count && predicate(sv->data[i])) {
i += 1;
}
return nob_sv_chop_left(sv, i);
}

bool nob_sv_index_of(Nob_String_View sv, char c, size_t *index) {
size_t i = 0;
while (i < sv.count && sv.data[i] != c) {
i += 1;
}

if (i < sv.count) {
if (index) {
*index = i;
}
return true;
} else {
return false;
}
}

bool nob_sv_eq_ignorecase(Nob_String_View a, Nob_String_View b) {
if (a.count != b.count) {
return false;
}

char x, y;
for (size_t i = 0; i < a.count; i++) {
x = 'A' <= a.data[i] && a.data[i] <= 'Z' ? a.data[i] + 32 : a.data[i];

y = 'A' <= b.data[i] && b.data[i] <= 'Z' ? b.data[i] + 32 : b.data[i];

if (x != y)
return false;
}
return true;
}

bool nob_sv_starts_with(Nob_String_View sv, Nob_String_View expected_prefix)
{
Expand All @@ -1773,6 +1896,26 @@ bool nob_sv_starts_with(Nob_String_View sv, Nob_String_View expected_prefix)
return false;
}

uint64_t nob_sv_to_u64(Nob_String_View sv) {
uint64_t result = 0;

for (size_t i = 0; i < sv.count && isdigit(sv.data[i]); ++i) {
result = result * 10 + (uint64_t)sv.data[i] - '0';
}

return result;
}

uint64_t nob_sv_chop_u64(Nob_String_View *sv) {
uint64_t result = 0;
while (sv->count > 0 && isdigit(*sv->data)) {
result = result * 10 + *sv->data - '0';
sv->count -= 1;
sv->data += 1;
}
return result;
}

// RETURNS:
// 0 - file does not exists
// 1 - file exists
Expand Down Expand Up @@ -2033,6 +2176,15 @@ int closedir(DIR *dirp)
#define sv_end_with nob_sv_end_with
#define sv_from_cstr nob_sv_from_cstr
#define sv_from_parts nob_sv_from_parts
#define sv_take_left_while nob_sv_take_left_while
#define sv_chop_by_sv nob_sv_chop_by_sv
#define sv_try_chop_by_delim nob_sv_try_chop_by_delim
#define sv_chop_right nob_sv_chop_right
#define sv_chop_left_while nob_sv_chop_left_while
#define sv_index_of nob_sv_index_of
#define sv_eq_ignorecase nob_sv_eq_ignorecase
#define sv_to_u64 nob_sv_to_u64
#define sv_chop_u64 nob_sv_chop_u64
#define sb_to_sv nob_sb_to_sv
#define win32_error_message nob_win32_error_message
#endif // NOB_STRIP_PREFIX
Expand Down
Loading