diff options
| author | Ethan Werner <mail@ethanwerner.com> | 2026-10-10 20:55:33 +0000 |
|---|---|---|
| committer | Ethan Werner <mail@ethanwerner.com> | 2026-10-10 20:56:50 +0000 |
| commit | f8423ebea413605b42de23f5dd06c5479d3fa1dd (patch) | |
| tree | 2612a5eb026c59e7aae01f10a1cf62f2ee43042c /src/util.h | |
Diffstat (limited to 'src/util.h')
| -rw-r--r-- | src/util.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..41c8203 --- /dev/null +++ b/src/util.h @@ -0,0 +1,110 @@ +#ifndef LLSH_UTIL_H +#define LLSH_UTIL_H + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +/* ------------------------------------------------------------------ */ +/* Growable byte buffer (NUL-terminated on steal) */ +/* ------------------------------------------------------------------ */ + +typedef struct { + char *data; + size_t len; + size_t cap; +} xbuf; + +void xbuf_init(xbuf *b); +void xbuf_free(xbuf *b); +void xbuf_reset(xbuf *b); +void xbuf_put(xbuf *b, const char *s); +void xbuf_putn(xbuf *b, const char *s, size_t n); +void xbuf_push(xbuf *b, char c); +int xbuf_fmt(xbuf *b, const char *fmt, ...); +char *xbuf_steal(xbuf *b); /* NUL-terminated string; buffer reset */ + +/* curl write callback that appends to an xbuf (pass `&buf` as the userdata). */ +size_t xbuf_curl_write(char *data, size_t sz, size_t nm, void *ud); + +/* ------------------------------------------------------------------ */ +/* Strings */ +/* ------------------------------------------------------------------ */ + +char *xstrdup(const char *s); +char *xstrndup(const char *s, size_t n); +int xstreq(const char *a, const char *b); +/* Trim ASCII whitespace from [s, s+n): returns a pointer into s and sets + * *out_len (no copy). */ +const char *xtrim_span(const char *s, size_t n, size_t *out_len); +/* Rust str::trim whitespace set. */ +bool utf8_is_ws(uint32_t cp); +char *xstr_ltrim_dup(const char *s); +char *xstr_rtrim_dup(const char *s); +char *xstr_trim_dup(const char *s); +char *xstrjoin2(const char *a, const char *b); +#include <stdarg.h> +char *xvsnprintf(const char *fmt, va_list ap); +/* Variadic convenience wrapper: freshly allocated, printf-style. */ +char *xstrfmt(const char *fmt, ...); +/* UTF-8 aware helpers */ +size_t utf8_len(const char *s); /* codepoint count */ +size_t utf8_byte_len(const char *s, size_t max_points); +const char *utf8_next(const char *p, const char *end, size_t *cp); +size_t utf8_display_width(const char *s); /* CJK fullwidth aware */ +bool utf8_is_valid(const char *s, size_t len); + +/* ------------------------------------------------------------------ */ +/* String list */ +/* ------------------------------------------------------------------ */ + +typedef struct { + char **items; + size_t len; + size_t cap; +} strlist; + +void sl_init(strlist *l); +void sl_free(strlist *l); +void sl_push(strlist *l, char *owned); /* takes ownership */ +void sl_push_copy(strlist *l, const char *s); +char *sl_pop_front(strlist *l); /* NULL when empty */ + +/* ------------------------------------------------------------------ */ +/* Files */ +/* ------------------------------------------------------------------ */ + +int read_file_to_buf(const char *path, char **out, size_t *out_len, char **err); +int read_file_to_buf_limited(const char *path, size_t max_bytes, char **out, + size_t *out_len, char **err); +int write_file_from_buf(const char *path, const char *data, size_t len, char **err); +bool path_exists(const char *path); +/* Create `path` and any missing parent directories (0755). 0 on success. */ +int mkdir_p(const char *path); + +/* Expand a leading `~` / `~/...` against $HOME (like a shell). + * Returns a freshly allocated string. */ +char *expand_tilde(const char *s); + +/* Resolve the system CA certificate bundle to pass as CURLOPT_CAINFO. + * The statically linked vendored OpenSSL has no usable default cert path + * (its --prefix points into the vendor tree, where no bundle is installed), + * so without this libcurl cannot verify any TLS peer. Honors + * $SSL_CERT_FILE / $CURL_CA_BUNDLE, then probes the usual distro locations. + * Returns NULL when nothing readable is found. */ +const char *llsh_ca_bundle(void); + +/* ------------------------------------------------------------------ */ +/* Misc */ +/* ------------------------------------------------------------------ */ + +double now_secs(void); +void sleep_ms(unsigned long ms); +void *xmalloc(size_t n); +void *xrealloc(void *p, size_t n); +char *itoa_dup(long long v); +/* Format a double the way Rust's Display does for common values */ +char *dtoa_dup(double v); + +#endif |