diff options
| author | 2025-01-17 11:20:17 -0500 | |
|---|---|---|
| committer | 2025-01-17 11:20:17 -0500 | |
| commit | 209310c561d89c9ed2040aa7053b320d32cc393c (patch) | |
| tree | cb26e18d275fa1d37afa903134e90e7c4c260484 /src | |
| parent | 27b5e13d75c58d5e32538a4b5aef65ab86f4bb38 (diff) | |
| download | libalabaster-209310c561d89c9ed2040aa7053b320d32cc393c.tar.gz libalabaster-209310c561d89c9ed2040aa7053b320d32cc393c.tar.bz2 libalabaster-209310c561d89c9ed2040aa7053b320d32cc393c.zip | |
all: Consider types and numerical limits
- Vastly improve tests.
- Change array/str/wstr APIs.
- Use ptrdiff_t instead of size_t in ring buffer.
- Make random seed thread-local.
- Log now uses a static thread-local buffer instead of a malloc'd buffer.
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.c | 244 | ||||
| -rw-r--r-- | src/lib.c | 19 | ||||
| -rw-r--r-- | src/log.c | 45 | ||||
| -rw-r--r-- | src/random.c | 4 | ||||
| -rw-r--r-- | src/ring_buffer.c | 68 | ||||
| -rw-r--r-- | src/str.c | 47 |
6 files changed, 220 insertions, 207 deletions
diff --git a/src/array.c b/src/array.c index 3236f67..6021a85 100644 --- a/src/array.c +++ b/src/array.c @@ -7,171 +7,159 @@ #define array(type) \ struct { \ - u32 size; \ + u32 count; \ u32 alloc; \ type *__sized_by(alloc) data; \ } -#define al_array_init(arr) ((arr).size = 0, (arr).alloc = 0, (arr).data = NULL) -#define al_array_item_size(arr) sizeof(*(arr).data) // NOLINT(bugprone-sizeof-expression) +#define al_array_init(array) ((array).count = 0, (array).alloc = 0, (array).data = NULL) -#define al_array_is_empty(arr) ((arr).size == 0) +#define al_array_offset(array, n) ((array).data + (n)) +#define al_array_at(array, i) ((array).data[i]) +#define al_array_last(array) al_array_at(array, (array).count - 1) -#define al_array_offset(arr, i) ((arr).data + (i)) - -#define al_array_at(arr, i) ((arr).data[i]) -#define al_array_last(arr) al_array_at(arr, (arr).size - 1) - -#define al_array_reserve(arr, size) \ - ((arr).alloc = _al_array_reserve((void *)&(arr).data, al_array_item_size(arr), (arr).alloc, size)) +#define al_array_item_size(array) sizeof(*(array).data) // NOLINT(bugprone-sizeof-expression) +#define al_array_reserve(array, count) \ + ((array).alloc = _al_array_reserve((void **)&(array).data, (array).alloc, ((count) * al_array_item_size(array)))) #define al_array_clone(dest, src) \ AL_MACRO_WRAP \ -({ \ +{ \ al_array_init(dest); \ - al_array_reserve(dest, (src).size); \ - (dest).size = (src).size; \ + al_array_reserve(dest, (src).count); \ + (dest).count = (src).count; \ al_memcpy(al_array_offset(dest, 0), al_array_offset(src, 0), \ - al_array_item_size(dest) * (dest).size); \ -}) + al_array_item_size(dest) * (dest).count); \ +} AL_MACRO_END #define al_array_copy(dest, src) \ AL_MACRO_WRAP \ -({ \ - al_array_reserve(dest, (src).size); \ - (dest).size = (src).size; \ +{ \ + al_array_reserve(dest, (src).count); \ + (dest).count = (src).count; \ al_memcpy(al_array_offset(dest, 0), al_array_offset(src, 0), \ - al_array_item_size(dest) * (dest).size); \ -}) + al_array_item_size(dest) * (dest).count); \ +} AL_MACRO_END -#define al_array_push(arr, item) \ -AL_MACRO_WRAP \ -({ \ - al_array_reserve(arr, (arr).size + 1); \ - al_array_at(arr, (arr).size++) = item; \ -}) +#define al_array_push(array, item) \ +AL_MACRO_WRAP \ +{ \ + al_array_reserve(array, (array).count + 1); \ + __typeof__(item) v = item; \ + (void)((array).data == &v); \ + al_array_at(array, (array).count++) = v; \ +} AL_MACRO_END -#define al_array_insert(arr, i, item) \ -AL_MACRO_WRAP \ -({ \ - if ((arr).size > i) { \ - al_array_reserve(arr, (arr).size + 1); \ - al_memmove(al_array_offset(arr, i + 1), al_array_offset(arr, i), \ - al_array_item_size(arr) * ((arr).size - i)); \ - (arr).size++; \ - } else { \ - al_array_reserve(arr, i + 1); \ - (arr).size = i + 1; \ - } \ - al_array_at(arr, i) = item; \ -}) +#define al_array_insert(array, i, item) \ +AL_MACRO_WRAP \ +{ \ + al_array_reserve(array, (array).count + 1); \ + if (i != (array).count - 1) { \ + al_memmove(al_array_offset(array, i + 1), al_array_offset(array, i), \ + al_array_item_size(array) * ((array).count - i)); \ + } \ + (array).count++; \ + __typeof__(item) v = item; \ + (void)((array).data == &v); \ + al_array_at(array, i) = v; \ +} AL_MACRO_END -#define al_array_pop(arr) al_array_at(arr, --(arr).size) -#define al_array_pop_at(arr, i, r) \ -AL_MACRO_WRAP \ -({ \ - r = al_array_at(arr, i); \ - al_array_remove_at(arr, i); \ -}) +#define al_array_pop(array) al_array_at(array, --(array).count) +#define al_array_pop_at(array, i, r) \ +AL_MACRO_WRAP \ +{ \ + r = al_array_at(array, i); \ + al_array_remove_at(array, i); \ +} AL_MACRO_END -#define al_array_remove(arr, elem) \ -AL_MACRO_WRAP \ -({ \ - for (u32 i = 0; i < (arr).size; i++) { \ - if (al_array_at(arr, i) == elem) { \ - al_array_remove_at(arr, i); \ - break; \ - } \ - } \ -}) +#define al_array_remove(array, elem) \ +AL_MACRO_WRAP \ +{ \ + for (u32 i = 0; i < (array).count; i++) { \ + if (al_array_at(array, i) == elem) { \ + al_array_remove_at(array, i); \ + break; \ + } \ + } \ +} AL_MACRO_END -#define al_array_check_remove(arr, elem, removed) \ -AL_MACRO_WRAP \ -({ \ - removed = false; \ - for (u32 i = 0; i < (arr).size; i++) { \ - if (al_array_at(arr, i) == elem) { \ - al_array_remove_at(arr, i); \ - removed = true; \ - break; \ - } \ - } \ -}) +#define al_array_check_remove(array, elem, removed) \ +AL_MACRO_WRAP \ +{ \ + removed = false; \ + for (u32 i = 0; i < (array).count; i++) { \ + if (al_array_at(array, i) == elem) { \ + al_array_remove_at(array, i); \ + removed = true; \ + break; \ + } \ + } \ +} AL_MACRO_END -#define al_array_remove_all(arr, elem) \ -AL_MACRO_WRAP \ -({ \ - for (u32 i = (arr).size; i-- > 0;) { \ - if (al_array_at(arr, i) == elem) { \ - al_array_remove_at(arr, i); \ - } \ - } \ -}) +#define al_array_remove_all(array, elem) \ +AL_MACRO_WRAP \ +{ \ + for (u32 i = (array).count; i-- > 0;) { \ + if (al_array_at(array, i) == elem) { \ + al_array_remove_at(array, i); \ + } \ + } \ +} AL_MACRO_END -#define al_array_remove_at(arr, i) \ -AL_MACRO_WRAP \ -({ \ - if (i == (arr).size - 1) { \ - (arr).size--; \ - } else { \ - al_memmove(al_array_offset(arr, i), al_array_offset(arr, i + 1), \ - al_array_item_size(arr) * (--(arr).size - i)); \ - } \ -}) +#define al_array_remove_at(array, i) \ +AL_MACRO_WRAP \ +{ \ + if (i == (array).count - 1) { \ + (array).count--; \ + } else { \ + al_memmove(al_array_offset(array, i), al_array_offset(array, i + 1), \ + al_array_item_size(array) * (--(array).count - i)); \ + } \ +} AL_MACRO_END -#define al_array_remove_range(arr, i, e) \ -AL_MACRO_WRAP \ -({ \ - if (e != (arr).size) { \ - al_memmove(al_array_offset(arr, i), al_array_offset(arr, e), \ - al_array_item_size(arr) * ((arr).size - e)); \ - } \ - (arr).size -= e - i; \ -}) +#define al_array_remove_range(array, start, end) \ +AL_MACRO_WRAP \ +{ \ + if (end != (array).count) { \ + al_memmove(al_array_offset(array, start), al_array_offset(array, end), \ + al_array_item_size(array) * ((array).count - end)); \ + } \ + (array).count -= end - start; \ +} AL_MACRO_END #ifdef AL_USE_STDLIB -#define al_array_sort(arr, type, cmp) AL_STDLIB_QSORT((arr).data, type, (arr).size, cmp) +#define al_array_sort(array, type, cmp) AL_STDLIB_QSORT((array).data, type, (array).count, cmp) #else -#define al_array_sort(arr, type, cmp) AL_INSERSION_SORT((arr).data, type, (arr).size, cmp) +#define al_array_sort(array, type, cmp) AL_INSERSION_SORT((array).data, type, (array).count, cmp) #endif -#define al_array_free(arr) \ - if ((arr).alloc) AL_ARRAY_FREE((arr).data) +#define al_array_free(array) \ + if ((array).alloc) AL_ARRAY_FREE((array).data) -#define al_array_foreach(arr, i, item) \ - for (u32 i = 0; (i < (arr).size && (item = al_array_at(arr, i), 1)); i++) +#define al_array_foreach(array, i, item) \ + for (u32 i = 0; (i < (array).count && (item = al_array_at(array, i), 1)); i++) -#define al_array_foreach_rev(arr, i, item) \ - for (u32 i = (arr).size; (i-- > 0 && (item = al_array_at(arr, i), 1));) +#define al_array_foreach_rev(array, i, item) \ + for (u32 i = (array).count; (i-- > 0 && (item = al_array_at(array, i), 1));) -#define al_array_foreach_ptr(arr, i, item) \ - for (u32 i = 0; (i < (arr).size && (item = al_array_offset(arr, i), 1)); i++) +#define al_array_foreach_ptr(array, i, item) \ + for (u32 i = 0; (i < (array).count && (item = al_array_offset(array, i), 1)); i++) -#define al_array_foreach_ptr_rev(arr, i, item) \ - for (u32 i = (arr).size; (i-- > 0 && (item = al_array_offset(arr, i), 1));) +#define al_array_foreach_ptr_rev(array, i, item) \ + for (u32 i = (array).count; (i-- > 0 && (item = al_array_offset(array, i), 1));) -#define al_array_remove_at_iter(arr, i) \ -AL_MACRO_WRAP \ -({ \ - al_array_remove_at(arr, i); \ - i--; \ -}) +#define al_array_remove_at_iter(array, i) \ +AL_MACRO_WRAP \ +{ \ + al_array_remove_at(array, i); \ + i--; \ +} AL_MACRO_END AL_UNUSED_FUNCTION_PUSH -static inline u32 _al_array_reserve(void **ptr, u32 item_size, u32 prev_size, u32 size) +static inline u32 _al_array_reserve(void **ptr, u32 prev_size, u32 size) { - if (size <= prev_size) { - return prev_size; - } - - size = size < al_grow_step ? al_next_power_of_two(size) : - (size + al_grow_step) & ~al_grow_step; - - *ptr = (!*ptr) ? AL_ARRAY_MALLOC(item_size * size) : AL_ARRAY_REALLOC(*ptr, item_size * size); - al_assert(*ptr); - - return size; + return al_default_growing_allocation(ptr, prev_size, size, AL_ARRAY_MALLOC, AL_ARRAY_REALLOC); } AL_UNUSED_FUNCTION_POP @@ -201,7 +201,24 @@ void al_set_alloc(void *(*malloc_func)(size_t), void *(*calloc_func)(size_t, siz } #endif -u32 al_grow_step = 0xfff; +u32 al_grow_step = 0x3fff; // 0b11111111111111 + +u32 al_default_growing_allocation(void **ptr, u32 prev_size, u32 size, + void *(*malloc_func)(size_t), void *(*realloc_func)(void *, size_t)) +{ + if (size <= prev_size) return prev_size; + al_assert(size > 0); + + size = size < al_grow_step ? al_next_power_of_two(size) : + al_add_wrap(size, al_grow_step, MAX_ALLOC_32) & ~al_grow_step; + // This should only happen after wrapping around MAX_ALLOC_32 (zero all possible bits). + if (size == 0) size = MAX_ALLOC_32; + + *ptr = (!*ptr) ? malloc_func(size) : realloc_func(*ptr, size); + al_assert(*ptr); + + return size; +} size_t al_page_size = 0x1000; void al_set_page_size(size_t size) @@ -1,14 +1,11 @@ #include "../include/al/log.h" +#include "../include/al/macros.h" //#define AL_LOG_SKIP -#define AL_LOG_USE_SECTION -#ifdef AL_LOG_USE_SECTION -#define AL_LOG_TEMPLATE "%s:%d %s(): %s -> (%s) " -#else #define AL_LOG_TEMPLATE "%s:%d %s(): %s -> " -#endif +#define AL_LOG_TEMPLATE_SECTION AL_LOG_TEMPLATE"(%s) " -#define AL_LOG_MESSAGE_MAX (AL_LOG_MESSAGE_SIZE - 1) // Space for newline. +#define AL_LOG_MESSAGE_MAX ((size_t)(AL_LOG_MESSAGE_SIZE - 1u)) // Space for newline. #ifndef AL_FORCE_DISABLE_OUTPUT static s32 (*_al_print)(void *, u8, char *) = NULL; @@ -23,39 +20,39 @@ void al_set_print(s32 (*print_func)(void *, u8, char *), void *userdata) static const char *levels[] = { "info", "warn", "error", "debug" }; #ifndef AL_LOG_SKIP -static char *get_message_buffer(u8 level, const char *section, const char *fmt, const char *name, const s32 line, const char *func, va_list args) +static __thread char messagebuf[AL_LOG_MESSAGE_SIZE]; + +static char *get_message_buffer(u8 level, const char *section, const char *name, const s32 line, const char *func, const char *fmt, va_list args) { - char *buffer = al_malloc(AL_LOG_MESSAGE_SIZE); s32 prefix = 0; -#ifdef AL_LOG_USE_SECTION - prefix = al_snprintf(buffer, AL_LOG_MESSAGE_MAX, AL_LOG_TEMPLATE, name, line, func, levels[level], section); -#else - (void)section; - prefix = al_snprintf(buffer, AL_LOG_MESSAGE_MAX, AL_LOG_TEMPLATE, name, line, func, levels[level]); -#endif - al_vsnprintf(buffer + prefix, AL_LOG_MESSAGE_MAX - prefix, fmt, args); - buffer[strcspn(buffer, "\r\n")] = '\0'; - return buffer; + if (!section) { + prefix = al_snprintf(messagebuf, AL_LOG_MESSAGE_MAX, AL_LOG_TEMPLATE, name, line, func, levels[level]); + } else { + prefix = al_snprintf(messagebuf, AL_LOG_MESSAGE_MAX, AL_LOG_TEMPLATE_SECTION, name, line, func, levels[level], section); + } + al_assert(prefix > 0); + al_vsnprintf(messagebuf + prefix, AL_LOG_MESSAGE_MAX - (size_t)prefix, fmt, args); + messagebuf[strcspn(messagebuf, "\r\n")] = '\0'; + return messagebuf; } #endif s32 _al_logv(u8 level, const char *section, const char *name, const s32 line, const char *func, const char *fmt, va_list args) { - if (!section) section = ""; #ifdef AL_LOG_SKIP s32 ret = 0; -#ifdef AL_LOG_USE_SECTION - ret += al_printf(AL_LOG_TEMPLATE, name, line, func, levels[level], section); -#else - ret += al_printf(AL_LOG_TEMPLATE, name, line, func, levels[level]); -#endif + if (!section) { + ret += al_printf(AL_LOG_TEMPLATE, name, line, func, levels[level]); + } else { + ret += al_printf(AL_LOG_TEMPLATE_SECTION, name, line, func, levels[level], section); + } ret += al_vprintf(fmt, args); if (strcspn(fmt, "\r\n") == al_strlen(fmt)) { ret += al_printf("\n"); } return ret; #else - return _al_print(_al_log_userdata, level, get_message_buffer(level, section, fmt, name, line, func, args)); + return _al_print(_al_log_userdata, level, get_message_buffer(level, section, name, line, func, fmt, args)); #endif } diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..1bbf152 --- /dev/null +++ b/src/random.c @@ -0,0 +1,4 @@ +#include "../include/al/random.h" + +u32 al_rand_seed = 1738; +__thread bool al_rand_set = false; diff --git a/src/ring_buffer.c b/src/ring_buffer.c index 1c39b7b..ded0138 100644 --- a/src/ring_buffer.c +++ b/src/ring_buffer.c @@ -3,9 +3,12 @@ #include "../include/al/macros.h" // https://github.com/MusicPlayerDaemon/MPD/blob/master/src/util/RingBuffer.hxx +// +// This is no longer an implementation of a "contiguous" ring buffer but I used this as reference. +// Wrapping is handled in read() and write(). // https://andrea.lattuada.me/blog/2019/the-design-and-implementation-of-a-lock-free-ring-buffer-with-contiguous-reservations.html -void al_ring_buffer_init(struct al_ring_buffer *buf, u8 *data, size_t length) +void al_ring_buffer_init(struct al_ring_buffer *buf, u8 *data, ptrdiff_t length) { buf->start = data; buf->end = data + length; @@ -20,7 +23,7 @@ static inline u8 *previous(struct al_ring_buffer *buf, u8 *ptr) return --ptr; } -static inline void add(struct al_ring_buffer *buf, u8 **v, u8 *ptr, size_t n) +static inline void add(struct al_ring_buffer *buf, u8 **v, u8 *ptr, ptrdiff_t n) { ptr += n; al_assert(ptr <= buf->end); @@ -28,14 +31,14 @@ static inline void add(struct al_ring_buffer *buf, u8 **v, u8 *ptr, size_t n) al_atomic_store(void)(v, ptr, AL_ATOMIC_RELEASE); } -size_t al_ring_buffer_space(struct al_ring_buffer *buf) +ptrdiff_t al_ring_buffer_space(struct al_ring_buffer *buf) { u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); u8 *rp = previous(buf, (u8 *)al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED)); return (wp <= rp) ? rp - wp : (buf->end - wp) + (rp - buf->start); } -u8 *al_ring_buffer_write_chunk(struct al_ring_buffer *buf, size_t *size) +u8 *al_ring_buffer_write_chunk(struct al_ring_buffer *buf, ptrdiff_t *size) { u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_ACQUIRE); u8 *rp = previous(buf, al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED)); @@ -43,19 +46,19 @@ u8 *al_ring_buffer_write_chunk(struct al_ring_buffer *buf, size_t *size) return wp; } -void al_ring_buffer_append(struct al_ring_buffer *buf, u8 *ptr, size_t n) +void al_ring_buffer_append(struct al_ring_buffer *buf, u8 *ptr, ptrdiff_t n) { add(buf, &buf->write, ptr, n); } -size_t al_ring_buffer_occupied(struct al_ring_buffer *buf) +ptrdiff_t al_ring_buffer_occupied(struct al_ring_buffer *buf) { u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED); u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); return (rp <= wp) ? wp - rp : (buf->end - rp) + (wp - buf->start); } -u8 *al_ring_buffer_read_chunk(struct al_ring_buffer *buf, size_t *size) +u8 *al_ring_buffer_read_chunk(struct al_ring_buffer *buf, ptrdiff_t *size) { u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_ACQUIRE); u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); @@ -63,24 +66,25 @@ u8 *al_ring_buffer_read_chunk(struct al_ring_buffer *buf, size_t *size) return rp; } -void al_ring_buffer_consume(struct al_ring_buffer *buf, u8 *ptr, size_t n) +void al_ring_buffer_consume(struct al_ring_buffer *buf, u8 *ptr, ptrdiff_t n) { add(buf, &buf->read, ptr, n); } -size_t al_ring_buffer_write(struct al_ring_buffer *buf, u8 *data, size_t n) +ptrdiff_t al_ring_buffer_write(struct al_ring_buffer *buf, u8 *data, ptrdiff_t n) { u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_ACQUIRE); u8 *rp = previous(buf, al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED)); - size_t size = MIN((wp <= rp ? rp : buf->end) - wp, (ptrdiff_t)n); + ptrdiff_t size, wrap; - al_memcpy(wp, data, size); + size = MIN((wp <= rp ? rp : buf->end) - wp, n); + al_memcpy(wp, data, (size_t)size); wp += size; if (wp >= buf->end) { - size_t wrap = MIN(rp - buf->start, (ptrdiff_t)(n - size)); - al_memcpy(buf->start, data + size, wrap); + wrap = MIN(rp - buf->start, n - size); + al_memcpy(buf->start, data + size, (size_t)wrap); wp = buf->start + wrap; size += wrap; } @@ -90,19 +94,20 @@ size_t al_ring_buffer_write(struct al_ring_buffer *buf, u8 *data, size_t n) return size; } -size_t al_ring_buffer_read(struct al_ring_buffer *buf, u8 *ptr, size_t n) +ptrdiff_t al_ring_buffer_read(struct al_ring_buffer *buf, u8 *ptr, ptrdiff_t n) { u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_ACQUIRE); u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); - size_t size = MIN((rp <= wp ? wp : buf->end) - rp, (ptrdiff_t)n); + ptrdiff_t size, wrap; - al_memcpy(ptr, rp, size); + size = MIN((rp <= wp ? wp : buf->end) - rp, n); + al_memcpy(ptr, rp, (size_t)size); rp += size; if (rp >= buf->end) { - size_t wrap = MIN(wp - buf->start, (ptrdiff_t)(n - size)); - al_memcpy(ptr + size, buf->start, wrap); + wrap = MIN(wp - buf->start, n - size); + al_memcpy(ptr + size, buf->start, (size_t)wrap); rp = buf->start + wrap; size += wrap; } @@ -112,27 +117,28 @@ size_t al_ring_buffer_read(struct al_ring_buffer *buf, u8 *ptr, size_t n) return size; } -size_t al_ring_buffer_peek(struct al_ring_buffer *buf, u8 *ptr, size_t offset, size_t n) +ptrdiff_t al_ring_buffer_peek(struct al_ring_buffer *buf, u8 *ptr, ptrdiff_t offset, ptrdiff_t n) { u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_RELAXED); u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); - ptrdiff_t size; + ptrdiff_t size, wrap; if (rp <= wp) { rp += offset; - size = MIN(wp - rp, (ptrdiff_t)n); - if (size < 0) + size = MIN(wp - rp, n); + if (size < 0) { return 0; + } - al_memcpy(ptr, rp, size); + al_memcpy(ptr, rp, (size_t)size); } else { rp += offset; - size = MIN(buf->end - rp, (ptrdiff_t)n); + size = MIN(buf->end - rp, n); if (size > 0) { - al_memcpy(ptr, rp, size); + al_memcpy(ptr, rp, (size_t)size); n -= size; rp = buf->start; } else { @@ -140,9 +146,9 @@ size_t al_ring_buffer_peek(struct al_ring_buffer *buf, u8 *ptr, size_t offset, s size = 0; } - ptrdiff_t wrap = MIN(wp - rp, (ptrdiff_t)n); + wrap = MIN(wp - rp, n); if (wrap > 0) { - al_memcpy(ptr + size, rp, wrap); + al_memcpy(ptr + size, rp, (size_t)wrap); size += wrap; } } @@ -150,16 +156,18 @@ size_t al_ring_buffer_peek(struct al_ring_buffer *buf, u8 *ptr, size_t offset, s return size; } -size_t al_ring_buffer_discard(struct al_ring_buffer *buf, size_t n) +ptrdiff_t al_ring_buffer_discard(struct al_ring_buffer *buf, ptrdiff_t n) { u8 *rp = al_atomic_load(void)(&buf->read, AL_ATOMIC_ACQUIRE); u8 *wp = al_atomic_load(void)(&buf->write, AL_ATOMIC_RELAXED); - size_t discard = MIN((rp <= wp ? wp : buf->end) - rp, (ptrdiff_t)n); + ptrdiff_t discard, wrap; + + discard = MIN((rp <= wp ? wp : buf->end) - rp, n); rp += discard; if (rp >= buf->end) { - size_t wrap = MIN(wp - buf->start, (ptrdiff_t)(n - discard)); + wrap = MIN(wp - buf->start, n - discard); rp = buf->start + wrap; discard += wrap; } @@ -1,18 +1,18 @@ #include "../include/al/str.h" // https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libc/stdlib/strtol.c;h=09d4333ed05f497ec00b7192204644349441e58d;hb=HEAD#l130 -s64 al_str_to_long(str *s, s32 base) +s64 al_str_to_long(str *s, u32 base, bool *error) { u64 ret = 0; u32 i = 0; - s32 neg = 0; + bool neg = 0; - while (al_isspace(al_str_at(s, i)) && i < s->len) { + while (al_isspace(al_str_at(s, i)) && i < s->length) { i++; } if (al_str_at(s, i) == '-') { - neg = 1; + neg = true; i++; } else if (al_str_at(s, i) == '+') { i++; @@ -24,41 +24,35 @@ s64 al_str_to_long(str *s, s32 base) i += 2; } - u64 cutoff = neg ? -(u64)INT64_MIN : INT64_MAX; - s32 add_limit = cutoff % (u64)base; - cutoff /= (u64)base; + u64 cutoff = neg ? ((u64)INT64_MAX + 1) : (u64)INT64_MAX; + u64 add_limit = cutoff % base; + cutoff /= base; - bool error = false; + *error = false; - for (; i < s->len; i++) { - char c = al_str_at(s, i); + for (; i < s->length; i++) { + uchar c = (uchar)al_str_at(s, i); if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else { // Character not valid for expressing a number. - error = true; + *error = true; break; } if (c >= base || ret > cutoff || (ret == cutoff && c > add_limit)) { // Either the character is invalid for the requested base or // attempting to add it would cause an overflow. - error = true; + *error = true; break; } ret = ret * base + c; } - if (error) { - ret = neg ? INT64_MIN : INT64_MAX; - } else if (neg) { - ret = -ret; - } - - return ret; + return neg ? -(s64)ret : (s64)ret; } bool al_str_get_line(str *buffer, char sep, str *line) @@ -70,17 +64,22 @@ bool al_str_get_line(str *buffer, char sep, str *line) *line = *buffer; } else { // Move to the start of the next line, if it exists. - line->data += line->len + 1; - if ((bytes = line->data - buffer->data) >= buffer->len) - return false; // No more lines. + line->data += line->length + 1; + if ((bytes = (u32)(line->data - buffer->data)) >= buffer->length) { + // No more lines. + return false; + } } - bytes = buffer->len - bytes; + if ((bytes = buffer->length - bytes) == 0) { + // buffer is completely empty. + return false; + } char *nl = (char *)al_memchr(line->data, sep, bytes); // If we couldn't find a separator, move to the end of the buffer. - line->len = !nl ? bytes : (u32)(nl - line->data); + line->length = !nl ? bytes : (u32)(nl - line->data); return true; } |