summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Martin Michalec <martin@michalec.dev>2026-02-21 23:56:50 +0000
committerLibravatar Martin Michalec <martin@michalec.dev>2026-02-22 03:20:29 +0000
commit8efdd3d26969db25ec113e94c5d2bb66373efaa0 (patch)
tree07a75298484291e3fe1e3439ae3c4d517e098eb1
downloadstring-builder-8efdd3d26969db25ec113e94c5d2bb66373efaa0.tar.gz
add implementationHEADmaster
-rw-r--r--.gitmodules3
-rw-r--r--include/cmmm/string-builder.h99
-rw-r--r--src/string-builder.c41
m---------vendor/cmmm/dynamic-array0
4 files changed, 143 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4cce083
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
1[submodule "vendor/cmmm/dynamic-array"]
2 path = vendor/cmmm/dynamic-array
3 url = https://git.michalec.dev/dynamic-array
diff --git a/include/cmmm/string-builder.h b/include/cmmm/string-builder.h
new file mode 100644
index 0000000..42fb24a
--- /dev/null
+++ b/include/cmmm/string-builder.h
@@ -0,0 +1,99 @@
1#ifndef INCLUDED__CMMM__STRING_BUILDER__H
2#define INCLUDED__CMMM__STRING_BUILDER__H
3
4// #define CMMM__STRING_BUILDER__STRIP_VENDOR
5// #define CMMM__STRING_BUILDER__SHORT_NAMESPACE
6
7#include <stddef.h>
8#include <string.h>
9#include "cmmm/dynamic-array.h"
10
11#define CMMM__STRING_BUILDER struct string_builder *
12struct cmmm__string_builder {
13 union { char *items, *string; };
14 size_t count;
15 size_t capacity;
16};
17
18#define CMMM__STRING_BUILDER__APPEND_CHAR(SB, CHAR) \
19 CMMM__DYNAMIC_ARRAY__APPEND (SB, CHAR)
20
21#define CMMM__STRING_BUILDER__APPEND_BUF(SB, BUF, SIZE) \
22 CMMM__DYNAMIC_ARRAY__APPEND_MANY (SB, BUF, SIZE)
23
24#define CMMM__STRING_BUILDER__APPEND_CSTR(SB, CSTR) \
25 ({ \
26 const char *s = (CSTR); \
27 size_t n = strlen (s); \
28 CMMM__DYNAMIC_ARRAY__APPEND_MANY(SB, s, n); \
29 })
30
31#define CMMM__STRING_BUILDER__APPEND_CSTRS(SB, ...) \
32 cmmm__string_builder__append_cstrs (&(SB), __VA_ARGS__, NULL)
33
34#define CMMM__STRING_BUILDER__APPEND_STRING_VIEW(SB, SV) \
35 CMMM__DYNAMIC_ARRAY__APPEND_MANY(SB, (SV).beg, CMMM__STRING_VIEW__LENGTH (SV));
36
37#define CMMM__STRING_BUILDER__APPEND_NULL(SB) \
38 CMMM__DYNAMIC_ARRAY__APPEND (SB, '\0')
39
40#define CMMM__STRING_BUILDER__RESET(SB) CMMM__DYNAMIC_ARRAY__RESET (SB)
41#define CMMM__STRING_BUILDER__FREE( SB) CMMM__DYNAMIC_ARRAY__FREE ( SB)
42
43void cmmm__string_builder__append_ntimes (CMMM__STRING_BUILDER, char c, size_t n);
44void cmmm__string_builder__append_cstrs (CMMM__STRING_BUILDER, ...);
45void cmmm__string_builder__printf (CMMM__STRING_BUILDER, const char *format, ...);
46
47#ifdef CMMM__STRING_BUILDER__SHORT_NAMESPACE
48#define CMMM__SB_STRIP_VENDOR CMMM__STRING_BUILDER__STRIP_VENDOR
49#define CMMM__SB_SHORT_NAMESPACE CMMM__STRING_BUILDER__SHORT_NAMESPACE
50#define CMMM__SB CMMM__STRING_BUILDER
51#define cmmm__sb cmmm__string_builder
52#define CMMM__SB_APPEND_CHAR CMMM__STRING_BUILDER__APPEND_CHAR
53#define CMMM__SB_APPEND_BUF CMMM__STRING_BUILDER__APPEND_BUF
54#define CMMM__SB_APPEND_CSTR CMMM__STRING_BUILDER__APPEND_CSTR
55#define CMMM__SB_APPEND_CSTRS CMMM__STRING_BUILDER__APPEND_CSTRS
56#define CMMM__SB_APPEND_STRING_VIEW CMMM__STRING_BUILDER__APPEND_STRING_VIEW
57#define CMMM__SB_APPEND_NULL CMMM__STRING_BUILDER__APPEND_NULL
58#define CMMM__SB_RESET CMMM__STRING_BUILDER__RESET
59#define CMMM__SB_FREE CMMM__STRING_BUILDER__FREE
60#define cmmm__sb_append_ntimes cmmm__string_builder__append_ntimes
61#define cmmm__sb_append_cstrs cmmm__string_builder__append_cstrs
62#define cmmm__sb_printf cmmm__string_builder__printf
63#endif // CMMM__STRING_BUILDER__SHORT_NAMESPACE
64
65#ifdef CMMM__STRING_BUILDER__STRIP_VENDOR
66#define STRING_BUILDER__STRIP_VENDOR CMMM__STRING_BUILDER__STRIP_VENDOR
67#define STRING_BUILDER__SHORT_NAMESPACE CMMM__STRING_BUILDER__SHORT_NAMESPACE
68#define STRING_BUILDER CMMM__STRING_BUILDER
69#define STRING_BUILDER__APPEND_CHAR CMMM__STRING_BUILDER__APPEND_CHAR
70#define STRING_BUILDER__APPEND_BUF CMMM__STRING_BUILDER__APPEND_BUF
71#define STRING_BUILDER__APPEND_CSTR CMMM__STRING_BUILDER__APPEND_CSTR
72#define STRING_BUILDER__APPEND_CSTRS CMMM__STRING_BUILDER__APPEND_CSTRS
73#define STRING_BUILDER__APPEND_STRING_VIEW CMMM__STRING_BUILDER__APPEND_STRING_VIEW
74#define STRING_BUILDER__APPEND_NULL CMMM__STRING_BUILDER__APPEND_NULL
75#define STRING_BUILDER__RESET CMMM__STRING_BUILDER__RESET
76#define STRING_BUILDER__FREE CMMM__STRING_BUILDER__FREE
77#define string_builder__append_ntimes cmmm__string_builder__append_ntimes
78#define string_builder__append_cstrs cmmm__string_builder__append_cstrs
79#define string_builder__printf cmmm__string_builder__printf
80
81#ifdef CMMM__STRING_BUILDER__SHORT_NAMESPACE
82#define SB_STRIP_VENDOR CMMM__STRING_BUILDER__STRIP_VENDOR
83#define SB_SHORT_NAMESPACE CMMM__STRING_BUILDER__SHORT_NAMESPACE
84#define SB CMMM__STRING_BUILDER
85#define SB_APPEND_CHAR CMMM__STRING_BUILDER__APPEND_CHAR
86#define SB_APPEND_BUF CMMM__STRING_BUILDER__APPEND_BUF
87#define SB_APPEND_CSTR CMMM__STRING_BUILDER__APPEND_CSTR
88#define SB_APPEND_CSTRS CMMM__STRING_BUILDER__APPEND_CSTRS
89#define SB_APPEND_STRING_VIEW CMMM__STRING_BUILDER__APPEND_STRING_VIEW
90#define SB_APPEND_NULL CMMM__STRING_BUILDER__APPEND_NULL
91#define SB_RESET CMMM__STRING_BUILDER__RESET
92#define SB_FREE CMMM__STRING_BUILDER__FREE
93#define sb_append_ntimes cmmm__string_builder__append_ntimes
94#define sb_append_cstrs cmmm__string_builder__append_cstrs
95#define sb_printf cmmm__string_builder__printf
96#endif // CMMM__STRING_BUILDER__SHORT_NAMESPACE
97#endif // CMMM__STRING_BUILDER__STRIP_VENDOR
98
99#endif // INCLUDED__STRING_BUILDER__H
diff --git a/src/string-builder.c b/src/string-builder.c
new file mode 100644
index 0000000..0c53367
--- /dev/null
+++ b/src/string-builder.c
@@ -0,0 +1,41 @@
1#include "string-builder.h"
2#include <stdarg.h>
3#include <stdio.h>
4
5void
6string_builder__append_ntimes (STRING_BUILDER sb, char c, size_t n)
7{
8 DYNAMIC_ARRAY__ENSURE_CAPACITY (*sb, n);
9 memset (sb->items + sb->count, c, n);
10 sb->count += n;
11}
12
13void
14string_builder__append_cstrs (STRING_BUILDER sb, ...)
15{
16 va_list args;
17
18 va_start (args, sb);
19 const char *arg = va_arg (args, const char *);
20 while (arg) {
21 STRING_BUILDER__APPEND_CSTR(*sb, arg);
22 arg = va_arg (args, const char *);
23 } va_end (args);
24}
25
26void
27string_builder__printf (STRING_BUILDER sb, const char *format, ...)
28{
29 va_list args;
30
31 va_start (args, format);
32 int size = vsnprintf (NULL, 0, format, args);
33 va_end (args);
34 ASSERT (size >= 0);
35
36 DYNAMIC_ARRAY__ENSURE_CAPACITY (*sb, size + 1);
37 va_start (args, format);
38 vsnprintf (&sb->items[sb->count], size + 1, format, args);
39 va_end (args);
40 sb->count += size;
41}
diff --git a/vendor/cmmm/dynamic-array b/vendor/cmmm/dynamic-array
new file mode 160000
Subproject f6e9aa1f489f2aa052e2caa5748f8d081346b8b