You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.0 KiB
C

#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define SV_LIT(S) ((void)(S "LITERAL_CHECK"), (str_view_t) { S, sizeof(S) - 1 })
#define SV_NULL ((str_view_t) { NULL, 0 })
#define SB_NULL ((str_buf_t) { NULL, 0 })
#define SB_SCOPED(NAME) str_buf_t NAME __attribute__((cleanup(sb_free))) = SB_NULL
#define SV_PRI "%.*s"
#define SV_PRI_ARGS(S) (int)((S).len), (S).ptr
// String which is:
// - Not owned
// - Not necessarily heap-allocated
// - Not necessarily nul-terminated
typedef struct {
const char *ptr;
size_t len;
} str_view_t;
// String which is:
// - Owned
// - Heap-allocated
// - Nul-terminated
// The length does not include the nul terminator.
typedef struct {
char *ptr;
size_t len;
} str_buf_t;
static inline bool sv_is_null(str_view_t s) {
return !s.ptr;
}
static inline bool sv_is_empty(str_view_t s) {
return !s.len;
}
static inline bool sb_is_null(str_buf_t buf) {
return !buf.ptr;
}
static inline bool sb_is_empty(str_buf_t buf) {
return !buf.len;
}
static inline str_view_t sv_from_parts(const char *ptr, size_t len) {
return (str_view_t) { ptr, len };
}
static inline str_view_t sv_from_cstr(const char *ptr, size_t maxlen) {
size_t len;
len = strnlen(ptr, maxlen);
return sv_from_parts(ptr, len);
}
static inline str_view_t sv_from_cstr_unbounded(const char *ptr) {
size_t len = strlen(ptr);
return sv_from_parts(ptr, len);
}
static inline bool sv_eq(str_view_t s1, str_view_t s2) {
return (s1.len == s2.len) && ((!s1.ptr || !s2.ptr)
? (s1.ptr == s2.ptr)
: !memcmp(s1.ptr, s2.ptr, s1.len));
}
static inline str_view_t sv_substr(str_view_t s, size_t start, size_t end) {
if ((start > end) || (start > s.len) || (end > s.len))
return SV_NULL;
return sv_from_parts(s.ptr + start, end - start);
}
static inline str_view_t sb_view(str_buf_t buf) {
return sv_from_parts(buf.ptr, buf.len);
}
str_buf_t sb_from_sv(str_view_t s);
static inline void sb_free(str_buf_t *buf) {
free(buf->ptr);
buf->ptr = NULL;
buf->len = 0;
}