2 * Copyright Neil Brown ©2015-2023 <neil@brown.name>
3 * May be distributed under terms of GPLv2 - see file:COPYING
5 * Assorted utility functions used by edlib
16 #define True ((bool)1)
17 #define False ((bool)0)
19 #define strstarts(s, prefix) (strncmp(s, prefix, sizeof(prefix)-1) == 0)
21 #define WERR (0xfffffffeu)
22 wint_t get_utf8(const char **cpp safe, const char *end);
23 char *safe put_utf8(char *buf safe, wchar_t ch);
24 int utf8_strlen(const char *s safe);
25 int utf8_strnlen(const char *s safe, int n);
26 int utf8_round_len(const char *text safe, int len);
27 int utf8_valid(const char *s safe);
28 static inline int utf8_bytes(wchar_t ch)
34 else if (ch < 0x10000)
36 else if (ch < 0x200000)
48 void buf_init(struct buf *b safe);
49 void buf_concat(struct buf *b safe, const char *s safe);
50 void buf_concat_len(struct buf *b safe, const char *s safe, int l);
51 void buf_append(struct buf *b safe, wchar_t wch);
52 void buf_append_byte(struct buf *b safe, char c);
53 void buf_resize(struct buf *b safe, int size);
54 static inline char *safe buf_final(struct buf *b safe)
59 static inline void buf_reinit(struct buf *b safe)
64 /* Formatting can be embedded in text strings in some places using
66 * SOH format-attributes STX the text ETX
67 * "the text" can contain nested SOH/STX/ETX sequences.
68 * The same can be done with
69 * < format-attributes> the text </a>
70 * but that is being phased out.
78 /* ACK is used as a no-op. */
82 /* Performance measurements.
96 void time_start(enum timetype);
97 void time_stop(enum timetype);
98 void time_start_key(const char *key safe);
99 void time_stop_key(const char *key safe);
101 extern bool debugger_is_present(void);
103 void stat_count(char *name safe);
105 void stat_free(void);
108 * Memory allocation tracking
116 struct list_head linkage;
119 #define MEMPOOL(_name) \
120 struct mempool mem ## _name = { \
122 .linkage = LIST_HEAD_INIT(mem ## _name.linkage), \
124 #define MEMPOOL_DECL(_name) struct mempool mem ## _name;
126 void *safe do_alloc(struct mempool *pool safe, int size, int zero);
127 void do_unalloc(struct mempool *pool safe, const void *obj, int size);
129 #define alloc(var, pool) \
130 do { var = do_alloc(&mem##pool, sizeof((var)[0]), 1); } while (0)
132 #define alloc_buf(size, pool) do_alloc(&mem##pool, size, 0)
133 #define alloc_zbuf(size, pool) do_alloc(&mem##pool, size, 1)
135 #define unalloc(var, pool) \
136 do { do_unalloc(&mem##pool, var, sizeof((var)[0])); (var)=NULL; } while (0)
138 #define unalloc_buf(var, size, pool) \
139 do { do_unalloc(&mem##pool, var, size); (var) = NULL; } while(0)
141 #define unalloc_str(var, pool) \
142 unalloc_buf(var, strlen(var)+1, pool)
144 #define unalloc_safe(var, pool) \
145 do { do_unalloc(&mem##pool, var, sizeof((var)[0])); (var)=safe_cast NULL; } while (0)
147 #define unalloc_buf_safe(var, size, pool) \
148 do { do_unalloc(&mem##pool, var, size); (var) = safe_cast NULL; } while(0)
150 #define unalloc_str_safe(var, pool) \
151 unalloc_buf_safe(var, strlen(var)+1, pool)
155 /* Sequentially set _attr to the an attr name, and _val to
156 * either the val (following ":") or NULL.
157 * _attr is valid up to : or , or < space and _val is valid up to , or <space
158 * _c is the start which will be updates, and _end is the end which
159 * must point to , or nul or a control char
161 #define foreach_attr(_attr, _val, _c, _end) \
162 for (_attr = _c, _val = afind_val(&_c, _end); \
164 _attr = _c, _val = afind_val(&_c, _end))
165 const char *afind_val(const char **cp safe, const char *end);
166 char *aupdate(char **cp safe, const char *v);
167 bool amatch(const char *a safe, const char *m safe);
168 bool aprefix(const char *a safe, const char *m safe);
169 long anum(const char *v safe);
171 #endif /* EDLIB_MISC */