commit 58ec1e65dd8320654ce9ba920f6847270cddc384
parent 793139462e5134659ff54b99af7116be2e6e4dfc
Author: Robert Russell <robertrussell.72001@gmail.com>
Date: Thu, 23 Feb 2023 22:40:11 -0800
Flatten inc directory
Diffstat:
40 files changed, 529 insertions(+), 529 deletions(-)
diff --git a/Makefile b/Makefile
@@ -20,16 +20,16 @@ librcx.a: $(SRC:.c=.o)
.c.o:
$(CC) -c -o $@ $(CFLAGS) $<
-src/alloc.o: src/alloc.c inc/rcx/alloc.h inc/rcx/def.h inc/rcx/log.h inc/rcx/rcx.h inc/rcx/internal/util.h config.mk
-src/bench.o: src/bench.c inc/rcx/bench.h inc/rcx/def.h inc/rcx/log.h inc/rcx/rcx.h config.mk
-src/bits.o: src/bits.c inc/rcx/bits.h inc/rcx/def.h inc/rcx/rcx.h config.mk
-src/error.o: src/error.c inc/rcx/def.h inc/rcx/error.h inc/rcx/log.h inc/rcx/rcx.h config.mk
-src/log.o: src/log.c inc/rcx/def.h inc/rcx/log.h inc/rcx/rcx.h config.mk
-src/opt.o: src/opt.c inc/rcx/def.h inc/rcx/opt.h inc/rcx/rcx.h config.mk
-src/str.o: src/str.c inc/rcx/alloc.h inc/rcx/def.h inc/rcx/log.h inc/rcx/rcx.h inc/rcx/str.h config.mk
-src/unicode.o: src/unicode.c inc/rcx/def.h inc/rcx/rcx.h gen/ucattab.inc config.mk
-src/unix.o: src/unix.c inc/rcx/def.h inc/rcx/rcx.h inc/rcx/unix.h config.mk
-src/utf8.o: src/utf8.c inc/rcx/def.h inc/rcx/rcx.h inc/rcx/utf8.h config.mk
+src/alloc.o: src/alloc.c inc/alloc.h inc/def.h inc/log.h inc/rcx.h inc/internal/util.h config.mk
+src/bench.o: src/bench.c inc/bench.h inc/def.h inc/log.h inc/rcx.h config.mk
+src/bits.o: src/bits.c inc/bits.h inc/def.h inc/rcx.h config.mk
+src/error.o: src/error.c inc/def.h inc/error.h inc/log.h inc/rcx.h config.mk
+src/log.o: src/log.c inc/def.h inc/log.h inc/rcx.h config.mk
+src/opt.o: src/opt.c inc/def.h inc/opt.h inc/rcx.h config.mk
+src/str.o: src/str.c inc/alloc.h inc/def.h inc/log.h inc/rcx.h inc/str.h config.mk
+src/unicode.o: src/unicode.c inc/def.h inc/rcx.h gen/ucattab.inc config.mk
+src/unix.o: src/unix.c inc/def.h inc/rcx.h inc/unix.h config.mk
+src/utf8.o: src/utf8.c inc/def.h inc/rcx.h inc/utf8.h config.mk
gen/ucattab.inc: gen tool/ucattab gen/UnicodeData.txt
tool/ucattab gen/UnicodeData.txt > $@
@@ -43,9 +43,9 @@ gen:
tool/ucattab: tool/ucattab.c src/alloc.o src/log.o src/str.o
$(CC) -o $@ $(CFLAGS) $^
-install: librcx.a
+install: librcx.a uninstall
mkdir -p $(DESTDIR)$(INCPREFIX)
- cp -rf inc/rcx $(DESTDIR)$(INCPREFIX)/
+ cp -rf inc $(DESTDIR)$(INCPREFIX)/rcx
mkdir -p $(DESTDIR)$(LIBPREFIX)
cp -f librcx.a $(DESTDIR)$(LIBPREFIX)/
diff --git a/inc/all.h b/inc/all.h
@@ -0,0 +1,13 @@
+/* Everything except bench.h */
+#include "alloc.h"
+#include "bits.h"
+#include "deque.h"
+#include "error.h"
+#include "log.h"
+#include "opt.h"
+#include "rcx.h"
+#include "str.h"
+#include "unicode.h"
+#include "unix.h"
+#include "utf8.h"
+#include "vector.h"
diff --git a/inc/alloc.h b/inc/alloc.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "def.h"
+
+/* A consistently-named set of memory allocators: r_{,e}{,re}alloc{,n}{,z}
+ * e- => allocation failures are fatal
+ * re- => realloc-style allocator
+ * -n => array allocator (with overflow check)
+ * -z => new memory initialized to 0.
+ * All these allocators are interoperable with the stdlib allocators. The
+ * non-e variants all set errno to ENOMEM on failure. */
+void *r_alloc(usize size); /* aka malloc */
+void *r_allocz(usize size);
+void *r_allocn(usize len, usize size);
+void *r_allocnz(usize len, usize size); /* aka calloc */
+int r_realloc(void *p, usize size);
+int r_reallocz(void *p, usize osize, usize nsize);
+int r_reallocn(void *p, usize len, usize size);
+int r_reallocnz(void *p, usize olen, usize nlen, usize size);
+void *r_ealloc(usize size);
+void *r_eallocz(usize size);
+void *r_eallocn(usize len, usize size);
+void *r_eallocnz(usize len, usize size);
+int r_erealloc(void *p, usize size);
+int r_ereallocz(void *p, usize osize, usize nsize);
+int r_ereallocn(void *p, usize len, usize size);
+int r_ereallocnz(void *p, usize olen, usize nlen, usize size);
+
+void free(void *p);
diff --git a/inc/bench.h b/inc/bench.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "def.h"
+
+/*
+Usage:
+ void my_benchmark(u64 N) {
+ <initialization (not timed)>
+ r_bench_start();
+ for (u64 i = 0; i < N; i++) {
+ <code to benchmark>
+ }
+ r_bench_stop();
+ <cleanup (not timed)>
+ }
+ int main(void) {
+ r_bench("my benchmark", my_benchmark, 3000);
+ }
+Note that <code to benchmark> can contain calls to r_bench_stop and
+r_bench_start to pause and restart timing.
+*/
+
+void r_bench(char *name, void (*fn)(u64 N), u32 goalms);
+void r_bench_start(void);
+void r_bench_stop(void);
diff --git a/inc/bits.h b/inc/bits.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "def.h"
+
+int r_popcnt_8(u8 n);
+int r_popcnt_16(u16 n);
+int r_popcnt_32(u32 n);
+int r_popcnt_64(u64 n);
diff --git a/inc/rcx/def.h b/inc/def.h
diff --git a/inc/deque.h b/inc/deque.h
@@ -0,0 +1,122 @@
+#pragma once
+
+#include <string.h>
+
+#include "alloc.h"
+#include "def.h"
+
+/* Defaults */
+#define R_DEQUE_STATIC
+#define R_DEQUE_METHOD(name, prefix) JOIN(JOIN(prefix,_),name)
+#define R_DEQUE_MIN_BITS 3 /* 1<<3 = 8 elements */
+#define R_DEQUE_REALLOCN r_ereallocn
+#define R_DEQUE_FREE free
+
+#define R_DEQUE_TYPEDEF(D, T)\
+typedef struct D { \
+ T *arr; \
+ usize cap; /* Always a power of 2 for fast mod */ \
+ usize l; /* Left end of active region */ \
+ usize r; /* 1 past right end of active region */ \
+} D;
+
+/* Invariants:
+ * Empty iff l == cap && r == 0
+ * Full iff l == r */
+
+#define R_DEQUE_DECLARE(D, T, ...)\
+R_DEQUE_STATIC UNUSED void R_DEQUE_METHOD(free,##__VA_ARGS__)(D *d); \
+R_DEQUE_STATIC UNUSED usize R_DEQUE_METHOD(len,##__VA_ARGS__)(D *d); \
+R_DEQUE_STATIC UNUSED usize R_DEQUE_METHOD(cap,##__VA_ARGS__)(D *d); \
+R_DEQUE_STATIC UNUSED int R_DEQUE_METHOD(reserve,##__VA_ARGS__)(D *d, usize n); \
+R_DEQUE_STATIC UNUSED int R_DEQUE_METHOD(pushl,##__VA_ARGS__)(D *d, T e); \
+R_DEQUE_STATIC UNUSED int R_DEQUE_METHOD(pushr,##__VA_ARGS__)(D *d, T e); \
+R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(popl,##__VA_ARGS__)(D *d); \
+R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(popr,##__VA_ARGS__)(D *d); \
+R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(peekl,##__VA_ARGS__)(D *d); \
+R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(peekr,##__VA_ARGS__)(D *d); \
+R_DEQUE_STATIC UNUSED T *R_DEQUE_METHOD(idx,##__VA_ARGS__)(D *d, usize i);
+
+#define R_DEQUE_DEFINE(D, T, ...)\
+void R_DEQUE_METHOD(free,##__VA_ARGS__)(D *d) { \
+ R_DEQUE_FREE(d->arr); \
+ *d = (D){0}; \
+} \
+usize R_DEQUE_METHOD(len,##__VA_ARGS__)(D *d) { \
+ return d->l == d->r ? d->cap : (d->r - d->l) & (d->cap - 1); \
+} \
+usize R_DEQUE_METHOD(cap,##__VA_ARGS__)(D *d) { \
+ return d->cap; \
+} \
+int R_DEQUE_METHOD(reserve,##__VA_ARGS__)(D *d, usize n) { \
+ usize rem = d->cap - R_DEQUE_METHOD(len,##__VA_ARGS__)(d); \
+ if (n <= rem) \
+ return 0; \
+ usize need = n - rem; \
+ usize ncap = MAX(d->cap, 1<<R_DEQUE_MIN_BITS); \
+ while (need > ncap - d->cap) { \
+ ncap <<= 1; \
+ if (ncap == 0) \
+ return -1; /* Overflow */ \
+ } \
+ if (R_DEQUE_REALLOCN(&d->arr, ncap, sizeof *d->arr) < 0) \
+ return -1; \
+ if (d->l == d->cap) { \
+ d->l = ncap; /* Maintain invariant for empty deques */ \
+ } else if (d->r <= d->l) { \
+ /* Move as little as possible */ \
+ if (d->r <= d->cap - d->l) { \
+ memcpy(&d->arr[d->cap], &d->arr[0], d->r * sizeof *d->arr); \
+ d->r += d->cap; \
+ } else { \
+ usize m = d->cap - d->l; \
+ memcpy(&d->arr[ncap-m], &d->arr[d->l], m * sizeof *d->arr); \
+ d->l = ncap - m; \
+ } \
+ } \
+ d->cap = ncap; \
+ return 0; \
+} \
+int R_DEQUE_METHOD(pushl,##__VA_ARGS__)(D *d, T e) { \
+ if (R_DEQUE_METHOD(reserve,##__VA_ARGS__)(d, 1) < 0) \
+ return -1; \
+ d->l = (d->l - 1) & (d->cap - 1); \
+ d->arr[d->l] = e; \
+ return 0; \
+} \
+int R_DEQUE_METHOD(pushr,##__VA_ARGS__)(D *d, T e) { \
+ if (R_DEQUE_METHOD(reserve,##__VA_ARGS__)(d, 1) < 0) \
+ return -1; \
+ d->arr[d->r] = e; \
+ d->r = (d->r + 1) & (d->cap - 1); \
+ if (d->l == d->cap) \
+ d->l = 0; \
+ return 0; \
+} \
+T R_DEQUE_METHOD(popl,##__VA_ARGS__)(D *d) { \
+ T e = d->arr[d->l]; \
+ d->l = (d->l + 1) & (d->cap - 1); \
+ if (d->l == d->r) { \
+ d->l = d->cap; \
+ d->r = 0; \
+ } \
+ return e; \
+} \
+T R_DEQUE_METHOD(popr,##__VA_ARGS__)(D *d) { \
+ d->r = (d->r - 1) & (d->cap - 1); \
+ T e = d->arr[d->r]; \
+ if (d->l == d->r) { \
+ d->l = d->cap; \
+ d->r = 0; \
+ } \
+ return e; \
+} \
+T R_DEQUE_METHOD(peekl,##__VA_ARGS__)(D *d) { \
+ return d->arr[d->l]; \
+} \
+T R_DEQUE_METHOD(peekr,##__VA_ARGS__)(D *d) { \
+ return d->arr[(d->r - 1) & (d->cap - 1)]; \
+} \
+T *R_DEQUE_METHOD(idx,##__VA_ARGS__)(D *d, usize i) { \
+ return &d->arr[(d->l + i) & (d->cap - 1)]; \
+}
diff --git a/inc/error.h b/inc/error.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "def.h"
+
+#define R_ERR(e) ((e).code != 0)
+
+typedef struct RError RError;
+typedef struct RErrorSource RErrorSource;
+
+struct RErrorSource {
+ char *name;
+ /* Convert err to a string and write the result to buf, which must have
+ * length len >= 128. If the string does not fit in the given buffer,
+ * truncate in a source-specific manner (e.g., append an ellipsis). */
+ void (*to_string)(char *buf, usize len, RError err);
+ /* Free any data associated with err. This field can be NULL. */
+ void (*free)(RError err);
+};
+
+struct RError {
+ int code; /* 0 iff success */
+ RErrorSource *src;
+ union {
+ i64 i;
+ u64 u;
+ double f;
+ char *s;
+ void *p;
+ } u; /* Subject to source-specific semantics. */
+};
+
+void r_error_string(char *buf, usize len, RError err);
+void r_error_fatal(RError err);
+void r_error_drop(RError err);
diff --git a/inc/rcx/internal/util.h b/inc/internal/util.h
diff --git a/inc/rcx/log.h b/inc/log.h
diff --git a/inc/rcx/opt.h b/inc/opt.h
diff --git a/inc/rcx.h b/inc/rcx.h
@@ -0,0 +1,16 @@
+#pragma once
+
+/* TODO: consistency check: cast style: (void*) vs (void *) */
+
+#include <inttypes.h>
+#include <stddef.h>
+
+/* Standard headers that should be part of the language proper */
+#include <stdarg.h>
+#include <stdbool.h>
+#if __STDC_VERSION__ >= 201100L
+#include <stdalign.h>
+#include <stdnoreturn.h>
+#endif
+
+#include "def.h"
diff --git a/inc/rcx/all.h b/inc/rcx/all.h
@@ -1,13 +0,0 @@
-/* Everything except bench.h */
-#include "rcx/alloc.h"
-#include "rcx/bits.h"
-#include "rcx/deque.h"
-#include "rcx/error.h"
-#include "rcx/log.h"
-#include "rcx/opt.h"
-#include "rcx/rcx.h"
-#include "rcx/str.h"
-#include "rcx/unicode.h"
-#include "rcx/unix.h"
-#include "rcx/utf8.h"
-#include "rcx/vector.h"
diff --git a/inc/rcx/alloc.h b/inc/rcx/alloc.h
@@ -1,29 +0,0 @@
-#pragma once
-
-#include "rcx/def.h"
-
-/* A consistently-named set of memory allocators: r_{,e}{,re}alloc{,n}{,z}
- * e- => allocation failures are fatal
- * re- => realloc-style allocator
- * -n => array allocator (with overflow check)
- * -z => new memory initialized to 0.
- * All these allocators are interoperable with the stdlib allocators. The
- * non-e variants all set errno to ENOMEM on failure. */
-void *r_alloc(usize size); /* aka malloc */
-void *r_allocz(usize size);
-void *r_allocn(usize len, usize size);
-void *r_allocnz(usize len, usize size); /* aka calloc */
-int r_realloc(void *p, usize size);
-int r_reallocz(void *p, usize osize, usize nsize);
-int r_reallocn(void *p, usize len, usize size);
-int r_reallocnz(void *p, usize olen, usize nlen, usize size);
-void *r_ealloc(usize size);
-void *r_eallocz(usize size);
-void *r_eallocn(usize len, usize size);
-void *r_eallocnz(usize len, usize size);
-int r_erealloc(void *p, usize size);
-int r_ereallocz(void *p, usize osize, usize nsize);
-int r_ereallocn(void *p, usize len, usize size);
-int r_ereallocnz(void *p, usize olen, usize nlen, usize size);
-
-void free(void *p);
diff --git a/inc/rcx/bench.h b/inc/rcx/bench.h
@@ -1,25 +0,0 @@
-#pragma once
-
-#include "rcx/def.h"
-
-/*
-Usage:
- void my_benchmark(u64 N) {
- <initialization (not timed)>
- r_bench_start();
- for (u64 i = 0; i < N; i++) {
- <code to benchmark>
- }
- r_bench_stop();
- <cleanup (not timed)>
- }
- int main(void) {
- r_bench("my benchmark", my_benchmark, 3000);
- }
-Note that <code to benchmark> can contain calls to r_bench_stop and
-r_bench_start to pause and restart timing.
-*/
-
-void r_bench(char *name, void (*fn)(u64 N), u32 goalms);
-void r_bench_start(void);
-void r_bench_stop(void);
diff --git a/inc/rcx/bits.h b/inc/rcx/bits.h
@@ -1,8 +0,0 @@
-#pragma once
-
-#include "rcx/def.h"
-
-int r_popcnt_8(u8 n);
-int r_popcnt_16(u16 n);
-int r_popcnt_32(u32 n);
-int r_popcnt_64(u64 n);
diff --git a/inc/rcx/deque.h b/inc/rcx/deque.h
@@ -1,122 +0,0 @@
-#pragma once
-
-#include <string.h>
-
-#include "rcx/alloc.h"
-#include "rcx/def.h"
-
-/* Defaults */
-#define R_DEQUE_STATIC
-#define R_DEQUE_METHOD(name, prefix) JOIN(JOIN(prefix,_),name)
-#define R_DEQUE_MIN_BITS 3 /* 1<<3 = 8 elements */
-#define R_DEQUE_REALLOCN r_ereallocn
-#define R_DEQUE_FREE free
-
-#define R_DEQUE_TYPEDEF(D, T)\
-typedef struct D { \
- T *arr; \
- usize cap; /* Always a power of 2 for fast mod */ \
- usize l; /* Left end of active region */ \
- usize r; /* 1 past right end of active region */ \
-} D;
-
-/* Invariants:
- * Empty iff l == cap && r == 0
- * Full iff l == r */
-
-#define R_DEQUE_DECLARE(D, T, ...)\
-R_DEQUE_STATIC UNUSED void R_DEQUE_METHOD(free,##__VA_ARGS__)(D *d); \
-R_DEQUE_STATIC UNUSED usize R_DEQUE_METHOD(len,##__VA_ARGS__)(D *d); \
-R_DEQUE_STATIC UNUSED usize R_DEQUE_METHOD(cap,##__VA_ARGS__)(D *d); \
-R_DEQUE_STATIC UNUSED int R_DEQUE_METHOD(reserve,##__VA_ARGS__)(D *d, usize n); \
-R_DEQUE_STATIC UNUSED int R_DEQUE_METHOD(pushl,##__VA_ARGS__)(D *d, T e); \
-R_DEQUE_STATIC UNUSED int R_DEQUE_METHOD(pushr,##__VA_ARGS__)(D *d, T e); \
-R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(popl,##__VA_ARGS__)(D *d); \
-R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(popr,##__VA_ARGS__)(D *d); \
-R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(peekl,##__VA_ARGS__)(D *d); \
-R_DEQUE_STATIC UNUSED T R_DEQUE_METHOD(peekr,##__VA_ARGS__)(D *d); \
-R_DEQUE_STATIC UNUSED T *R_DEQUE_METHOD(idx,##__VA_ARGS__)(D *d, usize i);
-
-#define R_DEQUE_DEFINE(D, T, ...)\
-void R_DEQUE_METHOD(free,##__VA_ARGS__)(D *d) { \
- R_DEQUE_FREE(d->arr); \
- *d = (D){0}; \
-} \
-usize R_DEQUE_METHOD(len,##__VA_ARGS__)(D *d) { \
- return d->l == d->r ? d->cap : (d->r - d->l) & (d->cap - 1); \
-} \
-usize R_DEQUE_METHOD(cap,##__VA_ARGS__)(D *d) { \
- return d->cap; \
-} \
-int R_DEQUE_METHOD(reserve,##__VA_ARGS__)(D *d, usize n) { \
- usize rem = d->cap - R_DEQUE_METHOD(len,##__VA_ARGS__)(d); \
- if (n <= rem) \
- return 0; \
- usize need = n - rem; \
- usize ncap = MAX(d->cap, 1<<R_DEQUE_MIN_BITS); \
- while (need > ncap - d->cap) { \
- ncap <<= 1; \
- if (ncap == 0) \
- return -1; /* Overflow */ \
- } \
- if (R_DEQUE_REALLOCN(&d->arr, ncap, sizeof *d->arr) < 0) \
- return -1; \
- if (d->l == d->cap) { \
- d->l = ncap; /* Maintain invariant for empty deques */ \
- } else if (d->r <= d->l) { \
- /* Move as little as possible */ \
- if (d->r <= d->cap - d->l) { \
- memcpy(&d->arr[d->cap], &d->arr[0], d->r * sizeof *d->arr); \
- d->r += d->cap; \
- } else { \
- usize m = d->cap - d->l; \
- memcpy(&d->arr[ncap-m], &d->arr[d->l], m * sizeof *d->arr); \
- d->l = ncap - m; \
- } \
- } \
- d->cap = ncap; \
- return 0; \
-} \
-int R_DEQUE_METHOD(pushl,##__VA_ARGS__)(D *d, T e) { \
- if (R_DEQUE_METHOD(reserve,##__VA_ARGS__)(d, 1) < 0) \
- return -1; \
- d->l = (d->l - 1) & (d->cap - 1); \
- d->arr[d->l] = e; \
- return 0; \
-} \
-int R_DEQUE_METHOD(pushr,##__VA_ARGS__)(D *d, T e) { \
- if (R_DEQUE_METHOD(reserve,##__VA_ARGS__)(d, 1) < 0) \
- return -1; \
- d->arr[d->r] = e; \
- d->r = (d->r + 1) & (d->cap - 1); \
- if (d->l == d->cap) \
- d->l = 0; \
- return 0; \
-} \
-T R_DEQUE_METHOD(popl,##__VA_ARGS__)(D *d) { \
- T e = d->arr[d->l]; \
- d->l = (d->l + 1) & (d->cap - 1); \
- if (d->l == d->r) { \
- d->l = d->cap; \
- d->r = 0; \
- } \
- return e; \
-} \
-T R_DEQUE_METHOD(popr,##__VA_ARGS__)(D *d) { \
- d->r = (d->r - 1) & (d->cap - 1); \
- T e = d->arr[d->r]; \
- if (d->l == d->r) { \
- d->l = d->cap; \
- d->r = 0; \
- } \
- return e; \
-} \
-T R_DEQUE_METHOD(peekl,##__VA_ARGS__)(D *d) { \
- return d->arr[d->l]; \
-} \
-T R_DEQUE_METHOD(peekr,##__VA_ARGS__)(D *d) { \
- return d->arr[(d->r - 1) & (d->cap - 1)]; \
-} \
-T *R_DEQUE_METHOD(idx,##__VA_ARGS__)(D *d, usize i) { \
- return &d->arr[(d->l + i) & (d->cap - 1)]; \
-}
diff --git a/inc/rcx/error.h b/inc/rcx/error.h
@@ -1,34 +0,0 @@
-#pragma once
-
-#include "rcx/def.h"
-
-#define R_ERR(e) ((e).code != 0)
-
-typedef struct RError RError;
-typedef struct RErrorSource RErrorSource;
-
-struct RErrorSource {
- char *name;
- /* Convert err to a string and write the result to buf, which must have
- * length len >= 128. If the string does not fit in the given buffer,
- * truncate in a source-specific manner (e.g., append an ellipsis). */
- void (*to_string)(char *buf, usize len, RError err);
- /* Free any data associated with err. This field can be NULL. */
- void (*free)(RError err);
-};
-
-struct RError {
- int code; /* 0 iff success */
- RErrorSource *src;
- union {
- i64 i;
- u64 u;
- double f;
- char *s;
- void *p;
- } u; /* Subject to source-specific semantics. */
-};
-
-void r_error_string(char *buf, usize len, RError err);
-void r_error_fatal(RError err);
-void r_error_drop(RError err);
diff --git a/inc/rcx/rcx.h b/inc/rcx/rcx.h
@@ -1,16 +0,0 @@
-#pragma once
-
-/* TODO: consistency check: cast style: (void*) vs (void *) */
-
-#include <inttypes.h>
-#include <stddef.h>
-
-/* Standard headers that should be part of the language proper */
-#include <stdarg.h>
-#include <stdbool.h>
-#if __STDC_VERSION__ >= 201100L
-#include <stdalign.h>
-#include <stdnoreturn.h>
-#endif
-
-#include "rcx/def.h"
diff --git a/inc/rcx/str.h b/inc/rcx/str.h
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <stdarg.h>
-#include <stdbool.h>
-
-#include "rcx/def.h"
-
-char *r_str_dup(char *s);
-char *r_str_edup(char *s);
-
-char *r_str_cat(char *buf, usize len, ...);
-char *r_str_ecat(char *buf, usize len, ...);
-
-bool r_str_starts_with(char *s, char *sub);
-bool r_str_ends_with(char *s, char *sub);
-
-/* Return the number of the nonoverlapping occurences of sub in s. */
-usize r_str_count(char *s, char *sub);
-
-/* Split s into substrings separated by sep (which must be nonempty) and return
- * the number of separated substrings found. If n > 0, then fields must point
- * to an array of at least n strings; in this case, place at most n substrings
- * in fields, with the last substring being the unsplit remainder. Otherwise,
- * set *fields to an allocated array containing every separated substring in s.
- * If there is an allocation failure, set *fields to NULL and return 0. In
- * either case, the elements of *fields are pointers into s, and s will be
- * modified in order to null-terminate the substrings. */
-usize r_str_split(char ***fields, char *s, char *sep, usize n);
-
-int r_vaprintf(char **s, const char *fmt, va_list args);
-int r_aprintf(char **s, const char *fmt, ...);
diff --git a/inc/rcx/unicode.h b/inc/rcx/unicode.h
@@ -1,11 +0,0 @@
-#pragma once
-
-#include "rcx/def.h"
-
-/* TODO: idea:
-#define r_unicode_is_letter(r) (r_unicode_category(r)[0] == 'L')
-etc...
-Actually, this is wrong, because r_unicode_category can return NULL
-*/
-
-char *r_unicode_category(rune r);
diff --git a/inc/rcx/unix.h b/inc/rcx/unix.h
@@ -1,34 +0,0 @@
-#pragma once
-
-#include <sys/uio.h>
-
-#include "rcx/def.h"
-
-/* On success, read exactly len bytes from fd into buf and return 0. On failure
- * (i.e., any error except EINTR, or EOF before len bytes are read into buf),
- * return -1 and set errno in the same manner as read(2), or set errno to 0 in
- * the case of premature EOF. In either case, if n is not NULL, set *n to the
- * number of bytes actually read (which is less than len iff an error or
- * premature EOF occurred). */
-int r_read_all(usize *n, int fd, void *buf, usize len);
-
-/* On success, write exactly len bytes from buf to fd and return 0. On failure
- * (i.e, any error except EINTR), return -1 and set errno in the same manner as
- * write(2). In either case, if n is not NULL, set *n to the number of bytes
- * actually written (which is less than len iff an error occurred). */
-int r_write_all(usize *n, int fd, void *buf, usize len);
-
-/* Copy n bytes from (*iov, *niov) to dst. Increment the base pointer and
- * decrement the length in each iovec according to the number of bytes copied.
- * There must be at least n bytes in (*iov, *niov). */
-void r_iovec_gather(void *dst, struct iovec **iov, usize *niov, usize n);
-
-/* TODO */
-/* int r_readv_all(int fd, struct iovec **iov, usize *niov); */
-
-/* On success, write all bytes from (*iov, *niov) to fd and return 0. On
- * failure (i.e., any error except EINTR), return -1 and set errno in the same
- * manner as writev(2). In either case, increment the base pointer and
- * decrement the length in each iovec according to the number of bytes actually
- * written. */
-int r_writev_all(int fd, struct iovec **iov, usize *niov);
diff --git a/inc/rcx/utf8.h b/inc/rcx/utf8.h
@@ -1,21 +0,0 @@
-#pragma once
-
-#include "rcx/def.h"
-
-#define R_UTF8_SIZE 4
-
-/* Return the number of bytes needed to encode c, or 0 if c is an invalid
- * codepoint. If s is nonnull, then it must have length >=
- * r_utf8_encode(0, c), which is guaranteed to be at most R_UTF8_SIZE;
- * in this case, if c is a valid codepoint, then encode c into s. */
-usize r_utf8_encode(char *s, rune c);
-
-/* Decode the first rune in s and return the number of consumed bytes. If this
- * succeeds and c is nonnull, then set *c to the decoded rune. Otherwise, no
- * valid rune is legally encoded as a prefix of s; in this case, set *c to
- * RUNE_BAD if c is nonnull, and return n such that
- * - n = 0 iff s is null or an incomplete prefix of a valid rune;
- * - n > 0 iff the first min(n+1,slen) bytes of s are not a prefix of any
- * valid rune (but if n < slen, then s[n] might be the first byte of a
- * valid rune). */
-usize r_utf8_decode(rune *c, char *s, usize slen);
diff --git a/inc/rcx/vector.h b/inc/rcx/vector.h
@@ -1,144 +0,0 @@
-#pragma once
-
-#include <errno.h>
-#include <stdbool.h>
-#include <string.h>
-
-#include "rcx/alloc.h"
-#include "rcx/def.h"
-
-#include "rcx/internal/util.h"
-
-typedef struct {
- usize len;
- usize cap;
- maxalign arr[];
-} r_vector_generic_hdr_;
-
-#define R_VECTOR_HDR_(v) ((R_VECTOR_HDR_TYPE *)(v) - 1)
-
-/* Defaults */
-#define R_VECTOR_STATIC
-#define R_VECTOR_METHOD(name, prefix) JOIN(JOIN(prefix,_),name)
-#define R_VECTOR_NULL_TERM false
-#define R_VECTOR_MIN_CAP 8
-#define R_VECTOR_HDR_TYPE r_vector_generic_hdr_
-#define R_VECTOR_REALLOC r_erealloc
-#define R_VECTOR_FREE free
-
-#define R_VECTOR_DECLARE(T, ...)\
-R_VECTOR_STATIC UNUSED usize R_VECTOR_METHOD(len,##__VA_ARGS__)(T *v); \
-R_VECTOR_STATIC UNUSED usize R_VECTOR_METHOD(cap,##__VA_ARGS__)(T *v); \
-R_VECTOR_STATIC UNUSED void R_VECTOR_METHOD(free,##__VA_ARGS__)(T **v); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(resize,##__VA_ARGS__)(T **v, usize cap); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(reserve,##__VA_ARGS__)(T **v, usize n); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(ins,##__VA_ARGS__)(T **v, usize i, T e); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(insv,##__VA_ARGS__)(T **dst, usize i, T *src); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(insn,##__VA_ARGS__)(T **dst, usize i, T *src, usize n); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(push,##__VA_ARGS__)(T **v, T e); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(cat,##__VA_ARGS__)(T **dst, T *src); \
-R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(catn,##__VA_ARGS__)(T **dst, T *src, usize n); \
-R_VECTOR_STATIC UNUSED T R_VECTOR_METHOD(del,##__VA_ARGS__)(T **v, usize i); \
-R_VECTOR_STATIC UNUSED T R_VECTOR_METHOD(pop,##__VA_ARGS__)(T **v); \
-R_VECTOR_STATIC UNUSED T R_VECTOR_METHOD(peek,##__VA_ARGS__)(T **v);
-
-#define R_VECTOR_DEFINE(T, ...)\
-usize R_VECTOR_METHOD(len,##__VA_ARGS__)(T *v) { \
- return v ? R_VECTOR_HDR_(v)->len : 0; \
-} \
-usize R_VECTOR_METHOD(cap,##__VA_ARGS__)(T *v) { \
- return v ? R_VECTOR_HDR_(v)->cap : 0; \
-} \
-void R_VECTOR_METHOD(free,##__VA_ARGS__)(T **v) { \
- if (*v) \
- R_VECTOR_FREE(R_VECTOR_HDR_(*v)); \
- *v = 0; \
-} \
-int R_VECTOR_METHOD(resize,##__VA_ARGS__)(T **v, usize cap) { \
- if (cap == 0) { \
- R_VECTOR_METHOD(free,##__VA_ARGS__)(v); \
- } else { \
- cap = MAX(cap, R_VECTOR_MIN_CAP); \
- R_VECTOR_HDR_TYPE *h = *v ? R_VECTOR_HDR_(*v) : 0; \
- usize len = h ? h->len : 0; \
- usize arrsize = cap * sizeof (*v)[0]; \
- if (r_mul_will_overflow_(cap, sizeof (*v)[0]) \
- || sizeof *h > USIZE_MAX - arrsize) { \
- errno = ENOMEM; \
- return -1; \
- } \
- if (R_VECTOR_REALLOC(&h, sizeof *h + arrsize) < 0) \
- return -1; \
- h->len = MIN(len, cap - !!R_VECTOR_NULL_TERM); \
- h->cap = cap; \
- *v = (void *)(h + 1); \
- if (R_VECTOR_NULL_TERM) \
- memset(&(*v)[h->len], 0, sizeof (*v)[0]); \
- } \
- return 0; \
-} \
-int R_VECTOR_METHOD(reserve,##__VA_ARGS__)(T **v, usize n) { \
- R_VECTOR_HDR_TYPE *h = *v ? R_VECTOR_HDR_(*v) : 0; \
- usize rem = h ? h->cap - h->len - !!R_VECTOR_NULL_TERM : 0; \
- if (n > rem) { \
- usize need = n - rem; \
- usize cap = h ? h->cap + MAX(h->cap, need) \
- : need + !!R_VECTOR_NULL_TERM; \
- if ((h && cap < h->cap) || (R_VECTOR_NULL_TERM && cap == 0)) { \
- errno = ENOMEM; \
- return -1; \
- } \
- return R_VECTOR_METHOD(resize,##__VA_ARGS__)(v, cap); \
- } else { \
- return 0; \
- } \
-} \
-int R_VECTOR_METHOD(ins,##__VA_ARGS__)(T **v, usize i, T e) { \
- return R_VECTOR_METHOD(insn,##__VA_ARGS__)(v, i, &e, 1); \
-} \
-int R_VECTOR_METHOD(insv,##__VA_ARGS__)(T **dst, usize i, T *src) { \
- return R_VECTOR_METHOD(insn,##__VA_ARGS__)(dst, i, src, \
- R_VECTOR_METHOD(len,##__VA_ARGS__)(src)); \
-} \
-int R_VECTOR_METHOD(insn,##__VA_ARGS__)(T **dst, usize i, T *src, usize n) { \
- if (R_VECTOR_METHOD(reserve,##__VA_ARGS__)(dst, n)) \
- return -1; \
- usize m = R_VECTOR_HDR_(*dst)->len - i + !!R_VECTOR_NULL_TERM; \
- memmove(&(*dst)[i+n], &(*dst)[i], m * sizeof (*dst)[0]); \
- memcpy(&(*dst)[i], src, n * sizeof (*dst)[0]); \
- R_VECTOR_HDR_(*dst)->len += n; \
- return 0; \
-} \
-int R_VECTOR_METHOD(push,##__VA_ARGS__)(T **v, T e) { \
- return R_VECTOR_METHOD(catn,##__VA_ARGS__)(v, &e, 1); \
-} \
-int R_VECTOR_METHOD(cat,##__VA_ARGS__)(T **dst, T *src) { \
- return R_VECTOR_METHOD(catn,##__VA_ARGS__)(dst, \
- src, R_VECTOR_METHOD(len,##__VA_ARGS__)(src)); \
-} \
-int R_VECTOR_METHOD(catn,##__VA_ARGS__)(T **dst, T *src, usize n) { \
- return R_VECTOR_METHOD(insn,##__VA_ARGS__)(dst, \
- R_VECTOR_METHOD(len,##__VA_ARGS__)(*dst), src, n); \
-} \
-T R_VECTOR_METHOD(del,##__VA_ARGS__)(T **v, usize i) { \
- T e = (*v)[i]; \
- usize m = R_VECTOR_HDR_(*v)->len - i - 1 + !!R_VECTOR_NULL_TERM; \
- memmove(&(*v)[i], &(*v)[i+1], m * sizeof (*v)[0]); \
- R_VECTOR_HDR_(*v)->len -= 1; \
- return e; \
-} \
-T R_VECTOR_METHOD(pop,##__VA_ARGS__)(T **v) { \
- return R_VECTOR_METHOD(del,##__VA_ARGS__)(v, R_VECTOR_HDR_(*v)->len - 1); \
-} \
-T R_VECTOR_METHOD(peek,##__VA_ARGS__)(T **v) { \
- return (*v)[R_VECTOR_HDR_(*v)->len - 1]; \
-}
-
-/* TODO?
-deln
-clr => set length to 0 without resizing
-optionally take cmp function and define:
- sort => qsort wrapper
- bsearch => bsearch wrapper
- lsearch => linear search on unsorted array
-*/
diff --git a/inc/str.h b/inc/str.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <stdarg.h>
+#include <stdbool.h>
+
+#include "def.h"
+
+char *r_str_dup(char *s);
+char *r_str_edup(char *s);
+
+char *r_str_cat(char *buf, usize len, ...);
+char *r_str_ecat(char *buf, usize len, ...);
+
+bool r_str_starts_with(char *s, char *sub);
+bool r_str_ends_with(char *s, char *sub);
+
+/* Return the number of the nonoverlapping occurences of sub in s. */
+usize r_str_count(char *s, char *sub);
+
+/* Split s into substrings separated by sep (which must be nonempty) and return
+ * the number of separated substrings found. If n > 0, then fields must point
+ * to an array of at least n strings; in this case, place at most n substrings
+ * in fields, with the last substring being the unsplit remainder. Otherwise,
+ * set *fields to an allocated array containing every separated substring in s.
+ * If there is an allocation failure, set *fields to NULL and return 0. In
+ * either case, the elements of *fields are pointers into s, and s will be
+ * modified in order to null-terminate the substrings. */
+usize r_str_split(char ***fields, char *s, char *sep, usize n);
+
+int r_vaprintf(char **s, const char *fmt, va_list args);
+int r_aprintf(char **s, const char *fmt, ...);
diff --git a/inc/unicode.h b/inc/unicode.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "def.h"
+
+/* TODO: idea:
+#define r_unicode_is_letter(r) (r_unicode_category(r)[0] == 'L')
+etc...
+Actually, this is wrong, because r_unicode_category can return NULL
+*/
+
+char *r_unicode_category(rune r);
diff --git a/inc/unix.h b/inc/unix.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <sys/uio.h>
+
+#include "def.h"
+
+/* On success, read exactly len bytes from fd into buf and return 0. On failure
+ * (i.e., any error except EINTR, or EOF before len bytes are read into buf),
+ * return -1 and set errno in the same manner as read(2), or set errno to 0 in
+ * the case of premature EOF. In either case, if n is not NULL, set *n to the
+ * number of bytes actually read (which is less than len iff an error or
+ * premature EOF occurred). */
+int r_read_all(usize *n, int fd, void *buf, usize len);
+
+/* On success, write exactly len bytes from buf to fd and return 0. On failure
+ * (i.e, any error except EINTR), return -1 and set errno in the same manner as
+ * write(2). In either case, if n is not NULL, set *n to the number of bytes
+ * actually written (which is less than len iff an error occurred). */
+int r_write_all(usize *n, int fd, void *buf, usize len);
+
+/* Copy n bytes from (*iov, *niov) to dst. Increment the base pointer and
+ * decrement the length in each iovec according to the number of bytes copied.
+ * There must be at least n bytes in (*iov, *niov). */
+void r_iovec_gather(void *dst, struct iovec **iov, usize *niov, usize n);
+
+/* TODO */
+/* int r_readv_all(int fd, struct iovec **iov, usize *niov); */
+
+/* On success, write all bytes from (*iov, *niov) to fd and return 0. On
+ * failure (i.e., any error except EINTR), return -1 and set errno in the same
+ * manner as writev(2). In either case, increment the base pointer and
+ * decrement the length in each iovec according to the number of bytes actually
+ * written. */
+int r_writev_all(int fd, struct iovec **iov, usize *niov);
diff --git a/inc/utf8.h b/inc/utf8.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "def.h"
+
+#define R_UTF8_SIZE 4
+
+/* Return the number of bytes needed to encode c, or 0 if c is an invalid
+ * codepoint. If s is nonnull, then it must have length >=
+ * r_utf8_encode(0, c), which is guaranteed to be at most R_UTF8_SIZE;
+ * in this case, if c is a valid codepoint, then encode c into s. */
+usize r_utf8_encode(char *s, rune c);
+
+/* Decode the first rune in s and return the number of consumed bytes. If this
+ * succeeds and c is nonnull, then set *c to the decoded rune. Otherwise, no
+ * valid rune is legally encoded as a prefix of s; in this case, set *c to
+ * RUNE_BAD if c is nonnull, and return n such that
+ * - n = 0 iff s is null or an incomplete prefix of a valid rune;
+ * - n > 0 iff the first min(n+1,slen) bytes of s are not a prefix of any
+ * valid rune (but if n < slen, then s[n] might be the first byte of a
+ * valid rune). */
+usize r_utf8_decode(rune *c, char *s, usize slen);
diff --git a/inc/vector.h b/inc/vector.h
@@ -0,0 +1,144 @@
+#pragma once
+
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "alloc.h"
+#include "def.h"
+
+#include "internal/util.h"
+
+typedef struct {
+ usize len;
+ usize cap;
+ maxalign arr[];
+} r_vector_generic_hdr_;
+
+#define R_VECTOR_HDR_(v) ((R_VECTOR_HDR_TYPE *)(v) - 1)
+
+/* Defaults */
+#define R_VECTOR_STATIC
+#define R_VECTOR_METHOD(name, prefix) JOIN(JOIN(prefix,_),name)
+#define R_VECTOR_NULL_TERM false
+#define R_VECTOR_MIN_CAP 8
+#define R_VECTOR_HDR_TYPE r_vector_generic_hdr_
+#define R_VECTOR_REALLOC r_erealloc
+#define R_VECTOR_FREE free
+
+#define R_VECTOR_DECLARE(T, ...)\
+R_VECTOR_STATIC UNUSED usize R_VECTOR_METHOD(len,##__VA_ARGS__)(T *v); \
+R_VECTOR_STATIC UNUSED usize R_VECTOR_METHOD(cap,##__VA_ARGS__)(T *v); \
+R_VECTOR_STATIC UNUSED void R_VECTOR_METHOD(free,##__VA_ARGS__)(T **v); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(resize,##__VA_ARGS__)(T **v, usize cap); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(reserve,##__VA_ARGS__)(T **v, usize n); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(ins,##__VA_ARGS__)(T **v, usize i, T e); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(insv,##__VA_ARGS__)(T **dst, usize i, T *src); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(insn,##__VA_ARGS__)(T **dst, usize i, T *src, usize n); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(push,##__VA_ARGS__)(T **v, T e); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(cat,##__VA_ARGS__)(T **dst, T *src); \
+R_VECTOR_STATIC UNUSED int R_VECTOR_METHOD(catn,##__VA_ARGS__)(T **dst, T *src, usize n); \
+R_VECTOR_STATIC UNUSED T R_VECTOR_METHOD(del,##__VA_ARGS__)(T **v, usize i); \
+R_VECTOR_STATIC UNUSED T R_VECTOR_METHOD(pop,##__VA_ARGS__)(T **v); \
+R_VECTOR_STATIC UNUSED T R_VECTOR_METHOD(peek,##__VA_ARGS__)(T **v);
+
+#define R_VECTOR_DEFINE(T, ...)\
+usize R_VECTOR_METHOD(len,##__VA_ARGS__)(T *v) { \
+ return v ? R_VECTOR_HDR_(v)->len : 0; \
+} \
+usize R_VECTOR_METHOD(cap,##__VA_ARGS__)(T *v) { \
+ return v ? R_VECTOR_HDR_(v)->cap : 0; \
+} \
+void R_VECTOR_METHOD(free,##__VA_ARGS__)(T **v) { \
+ if (*v) \
+ R_VECTOR_FREE(R_VECTOR_HDR_(*v)); \
+ *v = 0; \
+} \
+int R_VECTOR_METHOD(resize,##__VA_ARGS__)(T **v, usize cap) { \
+ if (cap == 0) { \
+ R_VECTOR_METHOD(free,##__VA_ARGS__)(v); \
+ } else { \
+ cap = MAX(cap, R_VECTOR_MIN_CAP); \
+ R_VECTOR_HDR_TYPE *h = *v ? R_VECTOR_HDR_(*v) : 0; \
+ usize len = h ? h->len : 0; \
+ usize arrsize = cap * sizeof (*v)[0]; \
+ if (r_mul_will_overflow_(cap, sizeof (*v)[0]) \
+ || sizeof *h > USIZE_MAX - arrsize) { \
+ errno = ENOMEM; \
+ return -1; \
+ } \
+ if (R_VECTOR_REALLOC(&h, sizeof *h + arrsize) < 0) \
+ return -1; \
+ h->len = MIN(len, cap - !!R_VECTOR_NULL_TERM); \
+ h->cap = cap; \
+ *v = (void *)(h + 1); \
+ if (R_VECTOR_NULL_TERM) \
+ memset(&(*v)[h->len], 0, sizeof (*v)[0]); \
+ } \
+ return 0; \
+} \
+int R_VECTOR_METHOD(reserve,##__VA_ARGS__)(T **v, usize n) { \
+ R_VECTOR_HDR_TYPE *h = *v ? R_VECTOR_HDR_(*v) : 0; \
+ usize rem = h ? h->cap - h->len - !!R_VECTOR_NULL_TERM : 0; \
+ if (n > rem) { \
+ usize need = n - rem; \
+ usize cap = h ? h->cap + MAX(h->cap, need) \
+ : need + !!R_VECTOR_NULL_TERM; \
+ if ((h && cap < h->cap) || (R_VECTOR_NULL_TERM && cap == 0)) { \
+ errno = ENOMEM; \
+ return -1; \
+ } \
+ return R_VECTOR_METHOD(resize,##__VA_ARGS__)(v, cap); \
+ } else { \
+ return 0; \
+ } \
+} \
+int R_VECTOR_METHOD(ins,##__VA_ARGS__)(T **v, usize i, T e) { \
+ return R_VECTOR_METHOD(insn,##__VA_ARGS__)(v, i, &e, 1); \
+} \
+int R_VECTOR_METHOD(insv,##__VA_ARGS__)(T **dst, usize i, T *src) { \
+ return R_VECTOR_METHOD(insn,##__VA_ARGS__)(dst, i, src, \
+ R_VECTOR_METHOD(len,##__VA_ARGS__)(src)); \
+} \
+int R_VECTOR_METHOD(insn,##__VA_ARGS__)(T **dst, usize i, T *src, usize n) { \
+ if (R_VECTOR_METHOD(reserve,##__VA_ARGS__)(dst, n)) \
+ return -1; \
+ usize m = R_VECTOR_HDR_(*dst)->len - i + !!R_VECTOR_NULL_TERM; \
+ memmove(&(*dst)[i+n], &(*dst)[i], m * sizeof (*dst)[0]); \
+ memcpy(&(*dst)[i], src, n * sizeof (*dst)[0]); \
+ R_VECTOR_HDR_(*dst)->len += n; \
+ return 0; \
+} \
+int R_VECTOR_METHOD(push,##__VA_ARGS__)(T **v, T e) { \
+ return R_VECTOR_METHOD(catn,##__VA_ARGS__)(v, &e, 1); \
+} \
+int R_VECTOR_METHOD(cat,##__VA_ARGS__)(T **dst, T *src) { \
+ return R_VECTOR_METHOD(catn,##__VA_ARGS__)(dst, \
+ src, R_VECTOR_METHOD(len,##__VA_ARGS__)(src)); \
+} \
+int R_VECTOR_METHOD(catn,##__VA_ARGS__)(T **dst, T *src, usize n) { \
+ return R_VECTOR_METHOD(insn,##__VA_ARGS__)(dst, \
+ R_VECTOR_METHOD(len,##__VA_ARGS__)(*dst), src, n); \
+} \
+T R_VECTOR_METHOD(del,##__VA_ARGS__)(T **v, usize i) { \
+ T e = (*v)[i]; \
+ usize m = R_VECTOR_HDR_(*v)->len - i - 1 + !!R_VECTOR_NULL_TERM; \
+ memmove(&(*v)[i], &(*v)[i+1], m * sizeof (*v)[0]); \
+ R_VECTOR_HDR_(*v)->len -= 1; \
+ return e; \
+} \
+T R_VECTOR_METHOD(pop,##__VA_ARGS__)(T **v) { \
+ return R_VECTOR_METHOD(del,##__VA_ARGS__)(v, R_VECTOR_HDR_(*v)->len - 1); \
+} \
+T R_VECTOR_METHOD(peek,##__VA_ARGS__)(T **v) { \
+ return (*v)[R_VECTOR_HDR_(*v)->len - 1]; \
+}
+
+/* TODO?
+deln
+clr => set length to 0 without resizing
+optionally take cmp function and define:
+ sort => qsort wrapper
+ bsearch => bsearch wrapper
+ lsearch => linear search on unsorted array
+*/
diff --git a/src/alloc.c b/src/alloc.c
@@ -2,11 +2,11 @@
#include <stdlib.h>
#include <string.h>
-#include "rcx/alloc.h"
-#include "rcx/log.h"
-#include "rcx/rcx.h"
+#include "alloc.h"
+#include "log.h"
+#include "rcx.h"
-#include "rcx/internal/util.h"
+#include "internal/util.h"
void *
r_alloc(usize size) {
diff --git a/src/bench.c b/src/bench.c
@@ -6,9 +6,9 @@
#include <time.h>
#include <unistd.h>
-#include "rcx/bench.h"
-#include "rcx/log.h"
-#include "rcx/rcx.h"
+#include "bench.h"
+#include "log.h"
+#include "rcx.h"
#ifndef _POSIX_THREAD_CPUTIME
#error "Need CLOCK_PROCESS_CPUTIME_ID"
diff --git a/src/bits.c b/src/bits.c
@@ -1,5 +1,5 @@
-#include "rcx/bits.h"
-#include "rcx/rcx.h"
+#include "bits.h"
+#include "rcx.h"
/* popcnt functions are implemented with a divide and conquer strategy.
* See Henry Warren, Hacker's Delight, 2 ed., sec. 5.1. */
diff --git a/src/error.c b/src/error.c
@@ -1,8 +1,8 @@
#include <assert.h>
-#include "rcx/error.h"
-#include "rcx/log.h"
-#include "rcx/rcx.h"
+#include "error.h"
+#include "log.h"
+#include "rcx.h"
void
r_error_string(char *buf, usize len, RError err) {
diff --git a/src/log.c b/src/log.c
@@ -5,8 +5,8 @@
#include <time.h>
#include <unistd.h>
-#include "rcx/log.h"
-#include "rcx/rcx.h"
+#include "log.h"
+#include "rcx.h"
#define ISO8601_SIZE (sizeof "YYYY-MM-DDThh:mm:ssZ")
#define SGR(c) (use_color ? (c) : "")
diff --git a/src/opt.c b/src/opt.c
@@ -1,8 +1,8 @@
#include <assert.h>
#include <string.h>
-#include "cext/cext.h"
-#include "cext/opt.h"
+#include "rcx.h"
+#include "opt.h"
void
opt_init(opt_ctx *opt, int *argc, char **argv) {
diff --git a/src/str.c b/src/str.c
@@ -4,10 +4,10 @@
#include <stdio.h>
#include <string.h>
-#include "rcx/alloc.h"
-#include "rcx/log.h"
-#include "rcx/rcx.h"
-#include "rcx/str.h"
+#include "alloc.h"
+#include "log.h"
+#include "rcx.h"
+#include "str.h"
/* TODO: e-versions of every function that can fail */
diff --git a/src/unicode.c b/src/unicode.c
@@ -1,4 +1,4 @@
-#include "rcx/rcx.h"
+#include "rcx.h"
#include "../gen/ucattab.inc"
static char ucats[] =
diff --git a/src/unix.c b/src/unix.c
@@ -4,8 +4,8 @@
#include <sys/uio.h>
#include <unistd.h>
-#include "rcx/rcx.h"
-#include "rcx/unix.h"
+#include "rcx.h"
+#include "unix.h"
typedef isize (*IoOp)(int, void *, usize);
diff --git a/src/utf8.c b/src/utf8.c
@@ -1,5 +1,5 @@
-#include "rcx/rcx.h"
-#include "rcx/utf8.h"
+#include "rcx.h"
+#include "utf8.h"
#define SURROGATE_MIN 0xD800
#define SURROGATE_MAX 0xDFFF
diff --git a/tool/ucattab.c b/tool/ucattab.c
@@ -4,10 +4,10 @@
#include <stdlib.h>
#include <string.h>
-#include "rcx/alloc.h"
-#include "rcx/rcx.h"
-#include "rcx/log.h"
-#include "rcx/str.h"
+#include "alloc.h"
+#include "rcx.h"
+#include "log.h"
+#include "str.h"
#define NF 15 /* Number of fields in UnicodeData.txt */