aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/strings.c
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2024-02-17 20:31:21 +0100
committerbfredl <bjorn.linse@gmail.com>2024-02-18 10:15:27 +0100
commitf25fcc68a34c2d51b0715fadc62cb50509de338b (patch)
tree39311fa4d0decc2551d4bcc488544d133df3764f /src/nvim/strings.c
parentb12d193b4a68242fb0c7e4f924c8abce3488e1c8 (diff)
downloadrneovim-f25fcc68a34c2d51b0715fadc62cb50509de338b.tar.gz
rneovim-f25fcc68a34c2d51b0715fadc62cb50509de338b.tar.bz2
rneovim-f25fcc68a34c2d51b0715fadc62cb50509de338b.zip
refactor(api): use an arena for mappings
Diffstat (limited to 'src/nvim/strings.c')
-rw-r--r--src/nvim/strings.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index c16b1f4ad0..06622a86b7 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -2166,6 +2166,47 @@ int kv_do_printf(StringBuilder *str, const char *fmt, ...)
return printed;
}
+String arena_printf(Arena *arena, const char *fmt, ...)
+ FUNC_ATTR_PRINTF(2, 3)
+{
+ size_t remaining = 0;
+ char *buf = NULL;
+ if (arena) {
+ if (!arena->cur_blk) {
+ alloc_block(arena);
+ }
+
+ // happy case, we can fit the printed string in the rest of the current
+ // block (one pass):
+ remaining = arena->size - arena->pos;
+ buf = arena->cur_blk + arena->pos;
+ }
+
+ va_list ap;
+ va_start(ap, fmt);
+ int printed = vsnprintf(buf, remaining, fmt, ap);
+ va_end(ap);
+
+ if (printed < 0) {
+ return (String)STRING_INIT;
+ }
+
+ // printed string didn't fit, allocate and try again
+ if ((size_t)printed >= remaining) {
+ buf = arena_alloc(arena, (size_t)printed + 1, false);
+ va_start(ap, fmt);
+ printed = vsnprintf(buf, (size_t)printed + 1, fmt, ap);
+ va_end(ap);
+ if (printed < 0) {
+ return (String)STRING_INIT;
+ }
+ } else {
+ arena->pos += (size_t)printed + 1;
+ }
+
+ return cbuf_as_string(buf, (size_t)printed);
+}
+
/// Reverse text into allocated memory.
///
/// @return the allocated string.