blind reformat all files

This commit is contained in:
2025-03-21 21:24:46 +02:00
parent cf5b6602d5
commit 3c5cd9844d
11 changed files with 696 additions and 749 deletions

View File

@@ -33,11 +33,11 @@
#define SC_ARRAY_H #define SC_ARRAY_H
#include <assert.h> #include <assert.h>
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#define SC_ARRAY_VERSION "2.0.0" #define SC_ARRAY_VERSION "2.0.0"
@@ -98,8 +98,7 @@
break; \ break; \
} \ } \
_cap = (a)->cap == 0 ? 8 : (a)->cap * 2; \ _cap = (a)->cap == 0 ? 8 : (a)->cap * 2; \
_p = sc_array_realloc((a)->elems, \ _p = sc_array_realloc((a)->elems, _cap * sizeof(*((a)->elems))); \
_cap * sizeof(*((a)->elems))); \
if (_p == NULL) { \ if (_p == NULL) { \
(a)->oom = true; \ (a)->oom = true; \
break; \ break; \
@@ -151,7 +150,7 @@
size_t idx = (i); \ size_t idx = (i); \
assert(idx < (a)->size); \ assert(idx < (a)->size); \
\ \
const size_t _cnt = (a)->size - (idx) - 1; \ const size_t _cnt = (a)->size - (idx)-1; \
if (_cnt > 0) { \ if (_cnt > 0) { \
memmove(&((a)->elems[idx]), &((a)->elems[idx + 1]), \ memmove(&((a)->elems[idx]), &((a)->elems[idx + 1]), \
_cnt * sizeof(*((a)->elems))); \ _cnt * sizeof(*((a)->elems))); \

View File

@@ -62,7 +62,7 @@ uintptr_t la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, uintptr_t *defcook, unsigned int *flags,
const char *symname) { const char *symname) {
printf("la_symbind64(): symname = %s; sym->st_value = %p\n", symname, printf("la_symbind64(): symname = %s; sym->st_value = %p\n", symname,
(void*)sym->st_value); (void *)sym->st_value);
printf(" ndx = %u; flags = %#x", ndx, *flags); printf(" ndx = %u; flags = %#x", ndx, *flags);
printf("; refcook = %p; defcook = %p\n", refcook, defcook); printf("; refcook = %p; defcook = %p\n", refcook, defcook);
@@ -73,7 +73,7 @@ Elf64_Addr la_i86_gnu_pltenter(Elf64_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook, uintptr_t *refcook, uintptr_t *defcook,
La_x86_64_regs *regs, unsigned int *flags, La_x86_64_regs *regs, unsigned int *flags,
const char *symname, long *framesizep) { const char *symname, long *framesizep) {
printf("la_x86_64_gnu_pltenter(): %s (%p)\n", symname, (void*)sym->st_value); printf("la_x86_64_gnu_pltenter(): %s (%p)\n", symname, (void *)sym->st_value);
return sym->st_value; return sym->st_value;
} }

View File

@@ -7,5 +7,4 @@ typedef struct {
const char *command; const char *command;
} CompileCommand; } CompileCommand;
#endif // COMPILATION_H_ #endif // COMPILATION_H_

View File

@@ -14,14 +14,16 @@ HiloadResult memory_find_pointer(uptr ptr,
size_t *index) { size_t *index) {
for (size_t i = 0; i < sc_array_size(regions); i++) { for (size_t i = 0; i < sc_array_size(regions); i++) {
uptr start = regions->elems[i].region_start; uptr start = regions->elems[i].region_start;
// we assume a sorted region by start address, so we can do a quick discard here. // we assume a sorted region by start address, so we can do a quick discard
// very useful for relative vs absolute address checks // here. very useful for relative vs absolute address checks
if (ptr < start) return HILOAD_FAIL; if (ptr < start)
return HILOAD_FAIL;
uptr end = regions->elems[i].region_end; uptr end = regions->elems[i].region_end;
if (ptr_in_range(ptr, start, end)) { if (ptr_in_range(ptr, start, end)) {
if (index) if (index)
*index = i; *index = i;
sc_log_debug("Pointer match (%p) found in index: %u, range: %p - %p\n", ptr, i, start, end); sc_log_debug("Pointer match (%p) found in index: %u, range: %p - %p\n",
ptr, i, start, end);
return HILOAD_OK; return HILOAD_OK;
} }
} }

View File

@@ -1,9 +1,9 @@
#ifndef MEMORY_H_ #ifndef MEMORY_H_
#define MEMORY_H_ #define MEMORY_H_
#include "array.h"
#include "str.h" #include "str.h"
#include "types.h" #include "types.h"
#include "array.h"
#include <assert.h> #include <assert.h>
@@ -24,14 +24,15 @@ typedef struct {
const char *pathname; const char *pathname;
} MemoryRegion; } MemoryRegion;
sc_array_def(MemoryRegion, memreg); sc_array_def(MemoryRegion, memreg);
/* A pointer that can be used to place the memory regions into. Clears regions before use, but uses the same buffer. */ /* A pointer that can be used to place the memory regions into. Clears regions
* before use, but uses the same buffer. */
HiloadResult read_memory_maps_self(struct sc_array_memreg *regions); HiloadResult read_memory_maps_self(struct sc_array_memreg *regions);
/* Return index the pointer is found in */ /* Return index the pointer is found in */
HiloadResult memory_find_pointer(uptr ptr, struct sc_array_memreg* const regions, size_t *index); HiloadResult memory_find_pointer(uptr ptr,
struct sc_array_memreg *const regions,
size_t *index);
#endif // MEMORY_H_ #endif // MEMORY_H_

467
src/str.c
View File

@@ -35,60 +35,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "str.h" #include "str.h"
#include <errno.h>
#include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
// append to destination and return the end pointer // append to destination and return the end pointer
static inline static inline void *mem_append(void *dest, const void *src, const size_t n) {
void* mem_append(void* dest, const void* src, const size_t n)
{
return memcpy(dest, src, n) + n; return memcpy(dest, src, n) + n;
} }
// string deallocation // string deallocation
void str_free(const str s) void str_free(const str s) {
{ if (str_is_owner(s))
if(str_is_owner(s)) free((void *)s.ptr);
free((void*)s.ptr);
} }
// version of str_free() for str_auto macro // version of str_free() for str_auto macro
void str_free_auto(const str* const ps) void str_free_auto(const str *const ps) {
{ if (ps)
if(ps)
str_free(*ps); str_free(*ps);
} }
// memory allocation helpers // memory allocation helpers
#define ALLOC(n) \ #define ALLOC(n) \
({ \ ({ \
void* const ___p = malloc(n); \ void *const ___p = malloc(n); \
if(!___p) return ENOMEM; \ if (!___p) \
return ENOMEM; \
___p; \ ___p; \
}) })
#define REALLOC(p, n) \ #define REALLOC(p, n) \
({ \ ({ \
void* const ___p = realloc((p), (n)); \ void *const ___p = realloc((p), (n)); \
if(!___p) return ENOMEM; \ if (!___p) \
return ENOMEM; \
___p; \ ___p; \
}) })
// errno checker // errno checker
#define RETURN_ON_ERROR(expr) \ #define RETURN_ON_ERROR(expr) \
while((expr) < 0) do { const int __err = errno; if(__err != EINTR) return __err; } while(0) while ((expr) < 0) \
do { \
const int __err = errno; \
if (__err != EINTR) \
return __err; \
} while (0)
// swap // swap
void str_swap(str* const s1, str* const s2) void str_swap(str *const s1, str *const s2) {
{
const str tmp = *s1; const str tmp = *s1;
*s1 = *s2; *s1 = *s2;
@@ -96,98 +97,89 @@ void str_swap(str* const s1, str* const s2)
} }
// empty string // empty string
const char* const str_empty_string = ""; const char *const str_empty_string = "";
// string comparison --------------------------------------------------------------------- // string comparison
// compare two strings lexicographically // --------------------------------------------------------------------- compare
int str_cmp(const str s1, const str s2) // two strings lexicographically
{ int str_cmp(const str s1, const str s2) {
const size_t n1 = str_len(s1), n2 = str_len(s2); const size_t n1 = str_len(s1), n2 = str_len(s2);
// either string may be missing a null terminator, hence "memcmp" // either string may be missing a null terminator, hence "memcmp"
const int res = memcmp(str_ptr(s1), str_ptr(s2), (n1 < n2) ? n1 : n2); const int res = memcmp(str_ptr(s1), str_ptr(s2), (n1 < n2) ? n1 : n2);
if(res != 0 || n1 == n2) if (res != 0 || n1 == n2)
return res; return res;
return (n1 < n2) ? -1 : 1; return (n1 < n2) ? -1 : 1;
} }
// case-insensitive comparison // case-insensitive comparison
int str_cmp_ci(const str s1, const str s2) int str_cmp_ci(const str s1, const str s2) {
{
const size_t n1 = str_len(s1), n2 = str_len(s2); const size_t n1 = str_len(s1), n2 = str_len(s2);
// either string may be missing a null terminator, hence "strNcasecmp" // either string may be missing a null terminator, hence "strNcasecmp"
const int res = strncasecmp(str_ptr(s1), str_ptr(s2), (n1 < n2) ? n1 : n2); const int res = strncasecmp(str_ptr(s1), str_ptr(s2), (n1 < n2) ? n1 : n2);
if(res != 0 || n1 == n2) if (res != 0 || n1 == n2)
return res; return res;
return (n1 < n2) ? -1 : 1; return (n1 < n2) ? -1 : 1;
} }
// test for prefix // test for prefix
bool str_has_prefix(const str s, const str prefix) bool str_has_prefix(const str s, const str prefix) {
{
const size_t n = str_len(prefix); const size_t n = str_len(prefix);
return (n == 0) return (n == 0) ||
|| (str_len(s) >= n && memcmp(str_ptr(s), str_ptr(prefix), n) == 0); (str_len(s) >= n && memcmp(str_ptr(s), str_ptr(prefix), n) == 0);
} }
// test for suffix // test for suffix
bool str_has_suffix(const str s, const str suffix) bool str_has_suffix(const str s, const str suffix) {
{
const size_t n = str_len(suffix); const size_t n = str_len(suffix);
return (n == 0) return (n == 0) ||
|| (str_len(s) >= n && memcmp(str_end(s) - n, str_ptr(suffix), n) == 0); (str_len(s) >= n && memcmp(str_end(s) - n, str_ptr(suffix), n) == 0);
} }
// string constructors ----------------------------------------------------------------- // string constructors
// create a reference to the given range of chars // ----------------------------------------------------------------- create a
str str_ref_chars(const char* const s, const size_t n) // reference to the given range of chars
{ str str_ref_chars(const char *const s, const size_t n) {
return (s && n > 0) ? ((str){ s, str_ref_info(n) }) : str_null; return (s && n > 0) ? ((str){s, str_ref_info(n)}) : str_null;
} }
str str_ref_from_ptr(const char* const s) str str_ref_from_ptr(const char *const s) {
{
return s ? str_ref_chars(s, strlen(s)) : str_null; return s ? str_ref_chars(s, strlen(s)) : str_null;
} }
// take ownership of the given range of chars // take ownership of the given range of chars
str str_acquire_chars(const char* const s, const size_t n) str str_acquire_chars(const char *const s, const size_t n) {
{ if (!s)
if(!s)
return str_null; return str_null;
if(n == 0) if (n == 0) {
{ free((void *)s);
free((void*)s);
return str_null; return str_null;
} }
return (str){ s, str_owner_info(n) }; return (str){s, str_owner_info(n)};
} }
// take ownership of the given C string // take ownership of the given C string
str str_acquire(const char* const s) str str_acquire(const char *const s) {
{
return s ? str_acquire_chars(s, strlen(s)) : str_null; return s ? str_acquire_chars(s, strlen(s)) : str_null;
} }
// allocate a copy of the given string // allocate a copy of the given string
int str_dup_impl(str* const dest, const str s) int str_dup_impl(str *const dest, const str s) {
{
const size_t n = str_len(s); const size_t n = str_len(s);
if(n == 0) if (n == 0)
str_clear(dest); str_clear(dest);
else else {
{ char *const p = memcpy(ALLOC(n + 1), str_ptr(s), n);
char* const p = memcpy(ALLOC(n + 1), str_ptr(s), n);
p[n] = 0; p[n] = 0;
str_assign(dest, str_acquire_chars(p, n)); str_assign(dest, str_acquire_chars(p, n));
@@ -200,9 +192,7 @@ int str_dup_impl(str* const dest, const str s)
#define STR_MAX_FILE_SIZE (64 * 1024 * 1024 - 1) #define STR_MAX_FILE_SIZE (64 * 1024 * 1024 - 1)
#endif #endif
static static int get_file_size(const int fd, off_t *const size) {
int get_file_size(const int fd, off_t* const size)
{
// stat the file // stat the file
struct stat info; struct stat info;
@@ -211,8 +201,7 @@ int get_file_size(const int fd, off_t* const size)
*size = info.st_size; *size = info.st_size;
// only regular files are allowed // only regular files are allowed
switch(info.st_mode & S_IFMT) switch (info.st_mode & S_IFMT) {
{
case S_IFREG: case S_IFREG:
return (info.st_size > STR_MAX_FILE_SIZE) ? EFBIG : 0; return (info.st_size > STR_MAX_FILE_SIZE) ? EFBIG : 0;
case S_IFDIR: case S_IFDIR:
@@ -222,33 +211,27 @@ int get_file_size(const int fd, off_t* const size)
} }
} }
static static int read_from_fd(const int fd, void *p, off_t *const psize) {
int read_from_fd(const int fd, void* p, off_t* const psize) const void *const end = p + *psize;
{
const void* const end = p + *psize;
ssize_t n; ssize_t n;
do do {
{
RETURN_ON_ERROR(n = read(fd, p, end - p)); RETURN_ON_ERROR(n = read(fd, p, end - p));
p += n; p += n;
} while(n > 0 && p < end); } while (n > 0 && p < end);
*psize -= end - p; *psize -= end - p;
return 0; return 0;
} }
static static int read_from_fd_cont(const int fd, void *p, off_t *const psize) {
int read_from_fd_cont(const int fd, void* p, off_t* const psize) const void *end = p + *psize;
{
const void* end = p + *psize;
void *buf = p; void *buf = p;
ssize_t n; ssize_t n;
ssize_t nread = 0; ssize_t nread = 0;
do do {
{
RETURN_ON_ERROR(n = read(fd, p, end - p)); RETURN_ON_ERROR(n = read(fd, p, end - p));
p += n; p += n;
@@ -262,44 +245,36 @@ int read_from_fd_cont(const int fd, void* p, off_t* const psize)
end = buf + *psize; end = buf + *psize;
} }
} while(n > 0); } while (n > 0);
return 0; return 0;
} }
static int str_from_fd(const int fd, const off_t size, str *const dest) {
static if (size == 0) {
int str_from_fd(const int fd, const off_t size, str* const dest)
{
if(size == 0)
{
str_clear(dest); str_clear(dest);
return 0; return 0;
} }
char* buff = ALLOC(size + 1); char *buff = ALLOC(size + 1);
off_t n = size; off_t n = size;
const int err = read_from_fd(fd, buff, &n); const int err = read_from_fd(fd, buff, &n);
if(err != 0) if (err != 0) {
{
free(buff); free(buff);
return err; return err;
} }
if(n == 0) if (n == 0) {
{
free(buff); free(buff);
str_clear(dest); str_clear(dest);
return 0; return 0;
} }
if(n < size) if (n < size) {
{ char *const p = realloc(buff, n + 1);
char* const p = realloc(buff, n + 1);
if(!p) if (!p) {
{
free(buff); free(buff);
return ENOMEM; return ENOMEM;
} }
@@ -312,34 +287,28 @@ int str_from_fd(const int fd, const off_t size, str* const dest)
return 0; return 0;
} }
static static int str_from_stream_cont(const int fd, str *const dest, int *nmax) {
int str_from_stream_cont(const int fd, str* const dest, int *nmax)
{
const size_t start_size = 8192; const size_t start_size = 8192;
char* buff = ALLOC(start_size + 1); char *buff = ALLOC(start_size + 1);
off_t n = start_size; off_t n = start_size;
const int err = read_from_fd_cont(fd, buff, &n); const int err = read_from_fd_cont(fd, buff, &n);
if(err != 0) if (err != 0) {
{
free(buff); free(buff);
return err; return err;
} }
if(n == 0) if (n == 0) {
{
free(buff); free(buff);
str_clear(dest); str_clear(dest);
return 0; return 0;
} }
if(n < start_size) if (n < start_size) {
{ char *const p = realloc(buff, n + 1);
char* const p = realloc(buff, n + 1);
if(!p) if (!p) {
{
free(buff); free(buff);
return ENOMEM; return ENOMEM;
} }
@@ -352,8 +321,7 @@ int str_from_stream_cont(const int fd, str* const dest, int *nmax)
return 0; return 0;
} }
int str_from_file(str* const dest, const char* const file_name) int str_from_file(str *const dest, const char *const file_name) {
{
int fd; int fd;
RETURN_ON_ERROR(fd = open(file_name, O_CLOEXEC | O_RDONLY)); RETURN_ON_ERROR(fd = open(file_name, O_CLOEXEC | O_RDONLY));
@@ -361,15 +329,14 @@ int str_from_file(str* const dest, const char* const file_name)
off_t size = 0; off_t size = 0;
int err = get_file_size(fd, &size); int err = get_file_size(fd, &size);
if(err == 0) if (err == 0)
err = str_from_fd(fd, size, dest); err = str_from_fd(fd, size, dest);
close(fd); close(fd);
return err; return err;
} }
int str_from_stream(str* const dest, const char* const file_name, int *nread) int str_from_stream(str *const dest, const char *const file_name, int *nread) {
{
int fd; int fd;
RETURN_ON_ERROR(fd = open(file_name, O_CLOEXEC | O_RDONLY)); RETURN_ON_ERROR(fd = open(file_name, O_CLOEXEC | O_RDONLY));
@@ -390,30 +357,25 @@ int str_from_stream(str* const dest, const char* const file_name, int *nread)
return err; return err;
} }
// string composition ----------------------------------------------------------------------- // string composition
// -----------------------------------------------------------------------
// append string // append string
static inline static inline char *append_str(char *p, const str s) {
char* append_str(char* p, const str s)
{
return mem_append(p, str_ptr(s), str_len(s)); return mem_append(p, str_ptr(s), str_len(s));
} }
static static size_t total_length(const str *src, size_t count) {
size_t total_length(const str* src, size_t count)
{
size_t sum = 0; size_t sum = 0;
for(; count > 0; --count) for (; count > 0; --count)
sum += str_len(*src++); sum += str_len(*src++);
return sum; return sum;
} }
// concatenate strings // concatenate strings
int str_cat_range_impl(str* const dest, const str* src, size_t count) int str_cat_range_impl(str *const dest, const str *src, size_t count) {
{ if (!src) {
if(!src)
{
str_clear(dest); str_clear(dest);
return 0; return 0;
} }
@@ -421,19 +383,18 @@ int str_cat_range_impl(str* const dest, const str* src, size_t count)
// calculate total length // calculate total length
const size_t num = total_length(src, count); const size_t num = total_length(src, count);
if(num == 0) if (num == 0) {
{
str_clear(dest); str_clear(dest);
return 0; return 0;
} }
// allocate // allocate
char* const buff = ALLOC(num + 1); char *const buff = ALLOC(num + 1);
// copy bytes // copy bytes
char* p = buff; char *p = buff;
for(; count > 0; --count) for (; count > 0; --count)
p = append_str(p, *src++); p = append_str(p, *src++);
// null-terminate and assign // null-terminate and assign
@@ -443,13 +404,11 @@ int str_cat_range_impl(str* const dest, const str* src, size_t count)
} }
// writing to file descriptor // writing to file descriptor
int str_cpy_to_fd(const int fd, const str s) int str_cpy_to_fd(const int fd, const str s) {
{
size_t n = str_len(s); size_t n = str_len(s);
const void* p = str_ptr(s); const void *p = str_ptr(s);
while(n > 0) while (n > 0) {
{
ssize_t m; ssize_t m;
RETURN_ON_ERROR(m = write(fd, p, n)); RETURN_ON_ERROR(m = write(fd, p, n));
@@ -462,28 +421,22 @@ int str_cpy_to_fd(const int fd, const str s)
} }
// writing to byte stream // writing to byte stream
int str_cpy_to_stream(FILE* const stream, const str s) int str_cpy_to_stream(FILE *const stream, const str s) {
{
const size_t n = str_len(s); const size_t n = str_len(s);
return (n > 0 && fwrite(str_ptr(s), 1, n, stream) < n) ? EIO : 0; return (n > 0 && fwrite(str_ptr(s), 1, n, stream) < n) ? EIO : 0;
} }
// write iovec // write iovec
static static int write_iovec(const int fd, struct iovec *pv, unsigned nv) {
int write_iovec(const int fd, struct iovec* pv, unsigned nv) while (nv > 0) {
{
while(nv > 0)
{
ssize_t n; ssize_t n;
RETURN_ON_ERROR(n = writev(fd, pv, nv)); RETURN_ON_ERROR(n = writev(fd, pv, nv));
// discard items already written // discard items already written
for(; nv > 0; ++pv, --nv) for (; nv > 0; ++pv, --nv) {
{ if (n < (ssize_t)pv->iov_len) {
if(n < (ssize_t)pv->iov_len)
{
pv->iov_base += n; pv->iov_base += n;
pv->iov_len -= n; pv->iov_len -= n;
break; break;
@@ -497,87 +450,79 @@ int write_iovec(const int fd, struct iovec* pv, unsigned nv)
} }
// concatenate to file descriptor // concatenate to file descriptor
static static struct iovec *vec_append(struct iovec *const pv, const str s) {
struct iovec* vec_append(struct iovec* const pv, const str s) *pv = (struct iovec){(void *)str_ptr(s), str_len(s)};
{
*pv = (struct iovec){ (void*)str_ptr(s), str_len(s) };
return pv + 1; return pv + 1;
} }
static static struct iovec *vec_append_nonempty(struct iovec *const pv, const str s) {
struct iovec* vec_append_nonempty(struct iovec* const pv, const str s)
{
return str_is_empty(s) ? pv : vec_append(pv, s); return str_is_empty(s) ? pv : vec_append(pv, s);
} }
int str_cat_range_to_fd(const int fd, const str* src, size_t count) int str_cat_range_to_fd(const int fd, const str *src, size_t count) {
{ if (!src)
if(!src)
return 0; return 0;
struct iovec v[IOV_MAX]; struct iovec v[IOV_MAX];
while(count > 0) while (count > 0) {
{ struct iovec *p = vec_append_nonempty(v, *src++);
struct iovec* p = vec_append_nonempty(v, *src++);
while(--count > 0 && p < v + IOV_MAX) while (--count > 0 && p < v + IOV_MAX)
p = vec_append_nonempty(p, *src++); p = vec_append_nonempty(p, *src++);
const size_t n = p - v; const size_t n = p - v;
if(n == 0) if (n == 0)
break; break;
const int ret = write_iovec(fd, v, n); const int ret = write_iovec(fd, v, n);
if(ret != 0) if (ret != 0)
return ret; return ret;
} }
return 0; return 0;
} }
int str_cat_range_to_stream(FILE* const stream, const str* src, size_t count) int str_cat_range_to_stream(FILE *const stream, const str *src, size_t count) {
{ if (!src)
if(!src)
return 0; return 0;
int err = 0; int err = 0;
for(; count > 0 && err == 0; --count) for (; count > 0 && err == 0; --count)
err = str_cpy(stream, *src++); err = str_cpy(stream, *src++);
return err; return err;
} }
// join strings // join strings
int str_join_range_impl(str* const dest, const str sep, const str* src, size_t count) int str_join_range_impl(str *const dest, const str sep, const str *src,
{ size_t count) {
// test for simple cases // test for simple cases
if(str_is_empty(sep)) if (str_is_empty(sep))
return str_cat_range(dest, src, count); return str_cat_range(dest, src, count);
if(!src || count == 0) if (!src || count == 0) {
{
str_clear(dest); str_clear(dest);
return 0; return 0;
} }
if(count == 1) if (count == 1)
return str_cpy(dest, *src); return str_cpy(dest, *src);
// calculate total length // calculate total length
const size_t num = total_length(src, count) + str_len(sep) * (count - 1); const size_t num = total_length(src, count) + str_len(sep) * (count - 1);
// allocate // allocate
char* const buff = ALLOC(num + 1); char *const buff = ALLOC(num + 1);
// copy bytes // copy bytes
char* p = append_str(buff, *src++); char *p = append_str(buff, *src++);
while(--count > 0) while (--count > 0)
p = append_str(append_str(p, sep), *src++); p = append_str(append_str(p, sep), *src++);
// null-terminate and assign // null-terminate and assign
@@ -586,75 +531,72 @@ int str_join_range_impl(str* const dest, const str sep, const str* src, size_t c
return 0; return 0;
} }
int str_join_range_to_fd(const int fd, const str sep, const str* src, size_t count) int str_join_range_to_fd(const int fd, const str sep, const str *src,
{ size_t count) {
if(str_is_empty(sep)) if (str_is_empty(sep))
return str_cat_range(fd, src, count); return str_cat_range(fd, src, count);
if(!src || count == 0) if (!src || count == 0)
return 0; return 0;
if(count == 1) if (count == 1)
return str_cpy(fd, *src); return str_cpy(fd, *src);
struct iovec v[IOV_MAX]; struct iovec v[IOV_MAX];
struct iovec* p = vec_append_nonempty(v, *src++); struct iovec *p = vec_append_nonempty(v, *src++);
for(--count; count > 0; p = v) for (--count; count > 0; p = v) {
{
p = vec_append_nonempty(vec_append(p, sep), *src++); p = vec_append_nonempty(vec_append(p, sep), *src++);
while(--count > 0 && p < v + IOV_MAX - 1) while (--count > 0 && p < v + IOV_MAX - 1)
p = vec_append_nonempty(vec_append(p, sep), *src++); p = vec_append_nonempty(vec_append(p, sep), *src++);
const size_t n = p - v; const size_t n = p - v;
if(n == 0) if (n == 0)
break; break;
const int ret = write_iovec(fd, v, n); const int ret = write_iovec(fd, v, n);
if(ret != 0) if (ret != 0)
return ret; return ret;
} }
return 0; return 0;
} }
int str_join_range_to_stream(FILE* const stream, const str sep, const str* src, size_t count) int str_join_range_to_stream(FILE *const stream, const str sep, const str *src,
{ size_t count) {
if(str_is_empty(sep)) if (str_is_empty(sep))
return str_cat_range(stream, src, count); return str_cat_range(stream, src, count);
if(!src || count == 0) if (!src || count == 0)
return 0; return 0;
int err = str_cpy(stream, *src++); int err = str_cpy(stream, *src++);
while(--count > 0 && err == 0) while (--count > 0 && err == 0)
err = str_cat(stream, sep, *src++); err = str_cat(stream, sep, *src++);
return err; return err;
} }
// searching and sorting -------------------------------------------------------------------- // searching and sorting
// string partitioning // -------------------------------------------------------------------- string
bool str_partition(const str src, const str patt, str* const prefix, str* const suffix) // partitioning
{ bool str_partition(const str src, const str patt, str *const prefix,
str *const suffix) {
const size_t patt_len = str_len(patt); const size_t patt_len = str_len(patt);
if(patt_len > 0 && !str_is_empty(src)) if (patt_len > 0 && !str_is_empty(src)) {
{ const char *s = memmem(str_ptr(src), str_len(src), str_ptr(patt), patt_len);
const char* s = memmem(str_ptr(src), str_len(src), str_ptr(patt), patt_len);
if(s) if (s) {
{ if (prefix)
if(prefix)
str_assign(prefix, str_ref_chars(str_ptr(src), s - str_ptr(src))); str_assign(prefix, str_ref_chars(str_ptr(src), s - str_ptr(src)));
if(suffix) if (suffix) {
{
s += patt_len; s += patt_len;
str_assign(suffix, str_ref_chars(s, str_end(src) - s)); str_assign(suffix, str_ref_chars(s, str_end(src) - s));
} }
@@ -663,90 +605,85 @@ bool str_partition(const str src, const str patt, str* const prefix, str* const
} }
} }
if(prefix) if (prefix)
str_assign(prefix, str_ref(src)); str_assign(prefix, str_ref(src));
if(suffix) if (suffix)
str_clear(suffix); str_clear(suffix);
return false; return false;
} }
// comparison functions // comparison functions
int str_order_asc(const void* const s1, const void* const s2) int str_order_asc(const void *const s1, const void *const s2) {
{ return str_cmp(*(const str *)s1, *(const str *)s2);
return str_cmp(*(const str*)s1, *(const str*)s2);
} }
int str_order_desc(const void* const s1, const void* const s2) int str_order_desc(const void *const s1, const void *const s2) {
{ return -str_cmp(*(const str *)s1, *(const str *)s2);
return -str_cmp(*(const str*)s1, *(const str*)s2);
} }
int str_order_asc_ci(const void* const s1, const void* const s2) int str_order_asc_ci(const void *const s1, const void *const s2) {
{ return str_cmp_ci(*(const str *)s1, *(const str *)s2);
return str_cmp_ci(*(const str*)s1, *(const str*)s2);
} }
int str_order_desc_ci(const void* const s1, const void* const s2) int str_order_desc_ci(const void *const s1, const void *const s2) {
{ return -str_cmp_ci(*(const str *)s1, *(const str *)s2);
return -str_cmp_ci(*(const str*)s1, *(const str*)s2);
} }
// sorting // sorting
void str_sort_range(const str_cmp_func cmp, str* const array, const size_t count) void str_sort_range(const str_cmp_func cmp, str *const array,
{ const size_t count) {
if(array && count > 1) if (array && count > 1)
qsort(array, count, sizeof(array[0]), cmp); qsort(array, count, sizeof(array[0]), cmp);
} }
// searching // searching
const str* str_search_range(const str key, const str* const array, const size_t count) const str *str_search_range(const str key, const str *const array,
{ const size_t count) {
if(!array || count == 0) if (!array || count == 0)
return NULL; return NULL;
if(count == 1) if (count == 1)
return str_eq(key, array[0]) ? array : NULL; return str_eq(key, array[0]) ? array : NULL;
return bsearch(&key, array, count, sizeof(str), str_order_asc); return bsearch(&key, array, count, sizeof(str), str_order_asc);
} }
// partitioning // partitioning
size_t str_partition_range(bool (*pred)(const str), str* const array, const size_t count) size_t str_partition_range(bool (*pred)(const str), str *const array,
{ const size_t count) {
if(!array) if (!array)
return 0; return 0;
const str* const end = array + count; const str *const end = array + count;
str* p = array; str *p = array;
while(p < end && pred(*p)) while (p < end && pred(*p))
++p; ++p;
for(str* s = p + 1; s < end; ++s) for (str *s = p + 1; s < end; ++s)
if(pred(*s)) if (pred(*s))
str_swap(p++, s); str_swap(p++, s);
return p - array; return p - array;
} }
// unique partitioning // unique partitioning
size_t str_unique_range(str* const array, const size_t count) size_t str_unique_range(str *const array, const size_t count) {
{ if (!array || count == 0)
if(!array || count == 0)
return 0; return 0;
if(count == 1) if (count == 1)
return 1; return 1;
str_sort_range(str_order_asc, array, count); str_sort_range(str_order_asc, array, count);
const str* const end = array + count; const str *const end = array + count;
str* p = array; str *p = array;
for(str* s = array + 1; s < end; ++s) for (str *s = array + 1; s < end; ++s)
if(!str_eq(*p, *s) && (++p < s)) if (!str_eq(*p, *s) && (++p < s))
str_swap(p, s); str_swap(p, s);
return p + 1 - array; return p + 1 - array;
@@ -755,15 +692,14 @@ size_t str_unique_range(str* const array, const size_t count)
// string iterator function // string iterator function
#ifdef __STDC_UTF_32__ #ifdef __STDC_UTF_32__
char32_t str_cp_iterator_next(str_cp_iterator* const it) char32_t str_cp_iterator_next(str_cp_iterator *const it) {
{ if (it->curr >= it->end)
if(it->curr >= it->end)
return CPI_END_OF_STRING; return CPI_END_OF_STRING;
char32_t c; char32_t c;
const size_t n = mbrtoc32(&c, it->curr, it->end - it->curr, &it->state); const size_t n = mbrtoc32(&c, it->curr, it->end - it->curr, &it->state);
switch(n) // see https://en.cppreference.com/w/c/string/multibyte/mbrtoc32 switch (n) // see https://en.cppreference.com/w/c/string/multibyte/mbrtoc32
{ {
case 0: // null character (U+0000) is allowed case 0: // null character (U+0000) is allowed
++it->curr; ++it->curr;
@@ -782,54 +718,47 @@ char32_t str_cp_iterator_next(str_cp_iterator* const it)
#endif // ifdef __STDC_UTF_32__ #endif // ifdef __STDC_UTF_32__
// tokeniser // tokeniser
static inline static inline bool is_delim(const str_tok_state *const state, const char c) {
bool is_delim(const str_tok_state* const state, const char c)
{
return state->bits[(unsigned char)c >> 3] & (1 << (c & 0x7)); return state->bits[(unsigned char)c >> 3] & (1 << (c & 0x7));
} }
static inline static inline void set_bit(str_tok_state *const state, const char c) {
void set_bit(str_tok_state* const state, const char c)
{
state->bits[(unsigned char)c >> 3] |= (1 << (c & 0x7)); state->bits[(unsigned char)c >> 3] |= (1 << (c & 0x7));
} }
void str_tok_delim(str_tok_state* const state, const str delim_set) void str_tok_delim(str_tok_state *const state, const str delim_set) {
{
memset(state->bits, 0, sizeof(state->bits)); memset(state->bits, 0, sizeof(state->bits));
const char* const end = str_end(delim_set); const char *const end = str_end(delim_set);
for(const char* s = str_ptr(delim_set); s < end; ++s) for (const char *s = str_ptr(delim_set); s < end; ++s)
set_bit(state, *s); set_bit(state, *s);
} }
void str_tok_init(str_tok_state* const state, const str src, const str delim_set) void str_tok_init(str_tok_state *const state, const str src,
{ const str delim_set) {
state->src = str_ptr(src); state->src = str_ptr(src);
state->end = str_end(src); state->end = str_end(src);
str_tok_delim(state, delim_set); str_tok_delim(state, delim_set);
} }
bool str_tok(str* const dest, str_tok_state* const state) bool str_tok(str *const dest, str_tok_state *const state) {
{
// token start // token start
const char* begin = state->src; const char *begin = state->src;
while(begin < state->end && is_delim(state, *begin)) while (begin < state->end && is_delim(state, *begin))
++begin; ++begin;
if(begin == state->end) if (begin == state->end) {
{
str_clear(dest); str_clear(dest);
return false; return false;
} }
// token end // token end
const char* end = begin + 1; const char *end = begin + 1;
while(end < state->end && !is_delim(state, *end)) while (end < state->end && !is_delim(state, *end))
++end; ++end;
state->src = end; state->src = end;

215
src/str.h
View File

@@ -32,100 +32,108 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once #pragma once
#include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
// string type ---------------------------------------------------------------------------- // string type
typedef struct // ----------------------------------------------------------------------------
{ typedef struct {
const char* ptr; const char *ptr;
size_t info; size_t info;
} str; } str;
// NULL string // NULL string
#define str_null ((str){ 0, 0 }) #define str_null ((str){0, 0})
// helper macros // helper macros
#define str_ref_info(n) ((n) << 1) #define str_ref_info(n) ((n) << 1)
#define str_owner_info(n) (str_ref_info(n) | 1) #define str_owner_info(n) (str_ref_info(n) | 1)
// string properties ---------------------------------------------------------------------- // string properties
// length of the string // ---------------------------------------------------------------------- length
static inline // of the string
size_t str_len(const str s) { return s.info >> 1; } static inline size_t str_len(const str s) { return s.info >> 1; }
// pointer to the string // pointer to the string
static inline static inline const char *str_ptr(const str s) {
const char* str_ptr(const str s) extern const char *const str_empty_string;
{
extern const char* const str_empty_string;
return s.ptr ? s.ptr : str_empty_string; return s.ptr ? s.ptr : str_empty_string;
} }
// end of the string // end of the string
static inline static inline const char *str_end(const str s) {
const char* str_end(const str s) { return str_ptr(s) + str_len(s); } return str_ptr(s) + str_len(s);
}
// test if the string is empty // test if the string is empty
static inline static inline bool str_is_empty(const str s) { return str_len(s) == 0; }
bool str_is_empty(const str s) { return str_len(s) == 0; }
// test if the string is allocated on the heap // test if the string is allocated on the heap
static inline static inline bool str_is_owner(const str s) { return (s.info & 1) != 0; }
bool str_is_owner(const str s) { return (s.info & 1) != 0; }
// test if the string is a reference // test if the string is a reference
static inline static inline bool str_is_ref(const str s) { return !str_is_owner(s); }
bool str_is_ref(const str s) { return !str_is_owner(s); }
// string memory control ------------------------------------------------------------------- // string memory control
// free memory allocated for the string // ------------------------------------------------------------------- free
// memory allocated for the string
void str_free(const str s); void str_free(const str s);
// automatic cleanup // automatic cleanup
void str_free_auto(const str* const ps); void str_free_auto(const str *const ps);
#define str_auto str __attribute__((cleanup(str_free_auto))) #define str_auto str __attribute__((cleanup(str_free_auto)))
// string movements ----------------------------------------------------------------------- // string movements
// free target string, then assign the new value to it // ----------------------------------------------------------------------- free
static inline // target string, then assign the new value to it
void str_assign(str* const ps, const str s) { str_free(*ps); *ps = s; } static inline void str_assign(str *const ps, const str s) {
str_free(*ps);
*ps = s;
}
// move the string, resetting the source to str_null // move the string, resetting the source to str_null
static inline static inline str str_move(str *const ps) {
str str_move(str* const ps) { const str t = *ps; *ps = str_null; return t; } const str t = *ps;
*ps = str_null;
return t;
}
// pass ownership of the string // pass ownership of the string
static inline static inline str str_pass(str *const ps) {
str str_pass(str* const ps) { const str t = *ps; ps->info &= ~(size_t)1; return t; } const str t = *ps;
ps->info &= ~(size_t)1;
return t;
}
// swap two string objects // swap two string objects
void str_swap(str* const s1, str* const s2); void str_swap(str *const s1, str *const s2);
// string helpers -------------------------------------------------------------------------- // string helpers
// --------------------------------------------------------------------------
// reset the string to str_null // reset the string to str_null
static inline static inline void str_clear(str *const ps) { str_assign(ps, str_null); }
void str_clear(str* const ps) { str_assign(ps, str_null); }
// compare two strings lexicographically // compare two strings lexicographically
int str_cmp(const str s1, const str s2); int str_cmp(const str s1, const str s2);
// test if two strings match // test if two strings match
static inline static inline bool str_eq(const str s1, const str s2) {
bool str_eq(const str s1, const str s2) { return str_cmp(s1, s2) == 0; } return str_cmp(s1, s2) == 0;
}
// case-insensitive comparison // case-insensitive comparison
int str_cmp_ci(const str s1, const str s2); int str_cmp_ci(const str s1, const str s2);
// case-insensitive match // case-insensitive match
static inline static inline bool str_eq_ci(const str s1, const str s2) {
bool str_eq_ci(const str s1, const str s2) { return str_cmp_ci(s1, s2) == 0; } return str_cmp_ci(s1, s2) == 0;
}
// test for prefix // test for prefix
bool str_has_prefix(const str s, const str prefix); bool str_has_prefix(const str s, const str prefix);
@@ -133,11 +141,12 @@ bool str_has_prefix(const str s, const str prefix);
// test for suffix // test for suffix
bool str_has_suffix(const str s, const str suffix); bool str_has_suffix(const str s, const str suffix);
// string composition ------------------------------------------------------------------ // string composition
// ------------------------------------------------------------------
// implementation helpers // implementation helpers
int str_dup_impl(str* const dest, const str s); int str_dup_impl(str *const dest, const str s);
int str_cpy_to_fd(const int fd, const str s); int str_cpy_to_fd(const int fd, const str s);
int str_cpy_to_stream(FILE* const stream, const str s); int str_cpy_to_stream(FILE *const stream, const str s);
// copy string // copy string
#define str_cpy(dest, src) \ #define str_cpy(dest, src) \
@@ -148,9 +157,9 @@ int str_cpy_to_stream(FILE* const stream, const str s);
)((dest), (src)) )((dest), (src))
// implementation helpers // implementation helpers
int str_cat_range_impl(str* const dest, const str* src, size_t count); int str_cat_range_impl(str *const dest, const str *src, size_t count);
int str_cat_range_to_fd(const int fd, const str* src, size_t count); int str_cat_range_to_fd(const int fd, const str *src, size_t count);
int str_cat_range_to_stream(FILE* const stream, const str* src, size_t count); int str_cat_range_to_stream(FILE *const stream, const str *src, size_t count);
// concatenate range of strings // concatenate range of strings
#define str_cat_range(dest, src, count) \ #define str_cat_range(dest, src, count) \
@@ -162,15 +171,18 @@ int str_cat_range_to_stream(FILE* const stream, const str* src, size_t count);
// concatenate string arguments // concatenate string arguments
#define str_cat(dest, ...) \ #define str_cat(dest, ...) \
({ \ ({ \
const str args[] = { __VA_ARGS__ }; \ const str args[] = {__VA_ARGS__}; \
str_cat_range((dest), args, sizeof(args)/sizeof(args[0])); \ str_cat_range((dest), args, sizeof(args) / sizeof(args[0])); \
}) })
// implementation helpers // implementation helpers
int str_join_range_impl(str* const dest, const str sep, const str* src, size_t count); int str_join_range_impl(str *const dest, const str sep, const str *src,
int str_join_range_to_fd(const int fd, const str sep, const str* src, size_t count); size_t count);
int str_join_range_to_stream(FILE* const stream, const str sep, const str* src, size_t count); int str_join_range_to_fd(const int fd, const str sep, const str *src,
size_t count);
int str_join_range_to_stream(FILE *const stream, const str sep, const str *src,
size_t count);
// join strings around the separator // join strings around the separator
#define str_join_range(dest, sep, src, count) \ #define str_join_range(dest, sep, src, count) \
@@ -182,19 +194,21 @@ int str_join_range_to_stream(FILE* const stream, const str sep, const str* src,
// join string arguments around the separator // join string arguments around the separator
#define str_join(dest, sep, ...) \ #define str_join(dest, sep, ...) \
({ \ ({ \
const str args[] = { __VA_ARGS__ }; \ const str args[] = {__VA_ARGS__}; \
str_join_range((dest), (sep), args, sizeof(args)/sizeof(args[0])); \ str_join_range((dest), (sep), args, sizeof(args) / sizeof(args[0])); \
}) })
// constructors ---------------------------------------------------------------------------- // constructors
// ----------------------------------------------------------------------------
// string reference from a string literal // string reference from a string literal
#define str_lit(s) ((str){ "" s, str_ref_info(sizeof(s) - 1) }) #define str_lit(s) ((str){"" s, str_ref_info(sizeof(s) - 1)})
static inline static inline str str_ref_impl(const str s) {
str str_ref_impl(const str s) { return (str){ s.ptr, s.info & ~(size_t)1 }; } return (str){s.ptr, s.info & ~(size_t)1};
}
str str_ref_from_ptr(const char* const s); str str_ref_from_ptr(const char *const s);
// string reference from anything // string reference from anything
#define str_ref(s) \ #define str_ref(s) \
@@ -205,45 +219,51 @@ str str_ref_from_ptr(const char* const s);
)(s) )(s)
// create a reference to the given range of chars // create a reference to the given range of chars
str str_ref_chars(const char* const s, const size_t n); str str_ref_chars(const char *const s, const size_t n);
// take ownership of the given range of chars // take ownership of the given range of chars
str str_acquire_chars(const char* const s, const size_t n); str str_acquire_chars(const char *const s, const size_t n);
// take ownership of the given string // take ownership of the given string
str str_acquire(const char* const s); str str_acquire(const char *const s);
// string from file // string from file
int str_from_file(str* const dest, const char* const file_name); int str_from_file(str *const dest, const char *const file_name);
// read maximum nread bytes from file, write bytes read. 0 reads until EOS. // read maximum nread bytes from file, write bytes read. 0 reads until EOS.
int str_from_stream(str* const dest, const char* const file_name, int *nread); int str_from_stream(str *const dest, const char *const file_name, int *nread);
// searching and sorting -------------------------------------------------------------------- // searching and sorting
// string partitioning (substring search) // -------------------------------------------------------------------- string
bool str_partition(const str src, const str patt, str* const prefix, str* const suffix); // partitioning (substring search)
bool str_partition(const str src, const str patt, str *const prefix,
str *const suffix);
// comparison functions // comparison functions
typedef int (*str_cmp_func)(const void*, const void*); typedef int (*str_cmp_func)(const void *, const void *);
int str_order_asc(const void* const s1, const void* const s2); int str_order_asc(const void *const s1, const void *const s2);
int str_order_desc(const void* const s1, const void* const s2); int str_order_desc(const void *const s1, const void *const s2);
int str_order_asc_ci(const void* const s1, const void* const s2); int str_order_asc_ci(const void *const s1, const void *const s2);
int str_order_desc_ci(const void* const s1, const void* const s2); int str_order_desc_ci(const void *const s1, const void *const s2);
// sort array of strings // sort array of strings
void str_sort_range(const str_cmp_func cmp, str* const array, const size_t count); void str_sort_range(const str_cmp_func cmp, str *const array,
const size_t count);
// searching // searching
const str* str_search_range(const str key, const str* const array, const size_t count); const str *str_search_range(const str key, const str *const array,
const size_t count);
// partitioning // partitioning
size_t str_partition_range(bool (*pred)(const str), str* const array, const size_t count); size_t str_partition_range(bool (*pred)(const str), str *const array,
const size_t count);
// unique partitioning // unique partitioning
size_t str_unique_range(str* const array, const size_t count); size_t str_unique_range(str *const array, const size_t count);
// UTF-32 codepoint iterator ---------------------------------------------------------------- // UTF-32 codepoint iterator
// ----------------------------------------------------------------
#ifdef __STDC_UTF_32__ #ifdef __STDC_UTF_32__
#include <uchar.h> #include <uchar.h>
@@ -258,38 +278,37 @@ size_t str_unique_range(str* const array, const size_t count);
// implementation // implementation
#define for_each_cp(var, src, it) \ #define for_each_cp(var, src, it) \
for(str_cp_iterator it = str_make_cp_iterator(src); (var = str_cp_iterator_next(&it)) <= 0x10FFFFu;) for (str_cp_iterator it = str_make_cp_iterator(src); \
(var = str_cp_iterator_next(&it)) <= 0x10FFFFu;)
#define CAT1(x, y) CAT2(x, y) #define CAT1(x, y) CAT2(x, y)
#define CAT2(x, y) x ## y #define CAT2(x, y) x##y
typedef struct typedef struct {
{ const char *curr;
const char* curr; const char *const end;
const char* const end;
mbstate_t state; mbstate_t state;
} str_cp_iterator; } str_cp_iterator;
static inline static inline str_cp_iterator str_make_cp_iterator(const str s) {
str_cp_iterator str_make_cp_iterator(const str s) return (str_cp_iterator){.curr = str_ptr(s), .end = str_end(s)};
{
return (str_cp_iterator){ .curr = str_ptr(s), .end = str_end(s) };
} }
char32_t str_cp_iterator_next(str_cp_iterator* const it); char32_t str_cp_iterator_next(str_cp_iterator *const it);
#endif // ifdef __STDC_UTF_32__ #endif // ifdef __STDC_UTF_32__
// tokeniser -------------------------------------------------------------------------------- // tokeniser
typedef struct // --------------------------------------------------------------------------------
{ typedef struct {
unsigned char bits[32]; // 256 / 8 unsigned char bits[32]; // 256 / 8
const char *src, *end; const char *src, *end;
} str_tok_state; } str_tok_state;
void str_tok_init(str_tok_state* const state, const str src, const str delim_set); void str_tok_init(str_tok_state *const state, const str src,
bool str_tok(str* const dest, str_tok_state* const state); const str delim_set);
void str_tok_delim(str_tok_state* const state, const str delim_set); bool str_tok(str *const dest, str_tok_state *const state);
void str_tok_delim(str_tok_state *const state, const str delim_set);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -8,7 +8,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct {
struct sc_array_str names; struct sc_array_str names;
struct sc_array_ptr addresses; struct sc_array_ptr addresses;
@@ -16,7 +15,6 @@ typedef struct {
sc_array_def(SymbolInfos, syms); sc_array_def(SymbolInfos, syms);
struct dl_phdr_info; struct dl_phdr_info;
struct sc_array_memreg; struct sc_array_memreg;
HiloadResult hi_create_symbol_info(SymbolInfos *, HiloadResult hi_create_symbol_info(SymbolInfos *,

View File

@@ -1,8 +1,8 @@
#ifndef TYPES_H_ #ifndef TYPES_H_
#define TYPES_H_ #define TYPES_H_
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
typedef uint8_t u8; typedef uint8_t u8;
typedef uint16_t u16; typedef uint16_t u16;

View File

@@ -10,5 +10,5 @@ static int otherValue = 0;
int getNewValue(int x); int getNewValue(int x);
#pragma GCC visibility pop #pragma GCC visibility pop
} } // namespace minimal_lib
#endif // MINIMAL_LIB_H_ #endif // MINIMAL_LIB_H_