1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
|