summaryrefslogtreecommitdiffstats
path: root/src/util.h
blob: 41c820358f3fab6be9931e8189f0213d6f48b298 (plain)
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