-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathos_sb.h
153 lines (129 loc) · 3.27 KB
/
os_sb.h
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef OSSB_INCLUDE_OS_SB_H
#define OSSB_INCLUDE_OS_SB_H
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#ifndef OSSBDEF
#ifdef OSSB_STATIC
#define OSSBDEF static
#else
#define OSSBDEF extern
#endif
#endif
#ifndef OSSB_INITIAL_CAPACITY
#define OSSB_INITIAL_CAPACITY (256)
#endif
#ifndef OSSB_FACTOR
#define OSSB_FACTOR (2)
#endif
typedef struct
{
char *buffer;
size_t capacity;
size_t length;
} os_string_builder_t;
OSSBDEF os_string_builder_t sb_new(void);
OSSBDEF os_string_builder_t sb_from_cstr(char *str);
OSSBDEF os_string_builder_t sb_append_cstr(os_string_builder_t sb, char *str);
OSSBDEF os_string_builder_t sb_append_format(os_string_builder_t sb,
char *format, ...);
OSSBDEF os_string_builder_t sb_end(os_string_builder_t sb);
OSSBDEF os_string_builder_t sb_reset(os_string_builder_t sb);
OSSBDEF char *sb_as_cstr(os_string_builder_t sb);
OSSBDEF os_string_builder_t sb_free(os_string_builder_t sb);
#ifndef OSSB_REALLOC
#define OSSB_REALLOC realloc
#endif
#ifndef OSSB_FREE
#define OSSB_FREE free
#endif
static void *sb__realloc(void *ptr, size_t size);
static void sb__free(void *ptr);
#endif
#ifdef OS_SB_IMPLEMENTATION
static void *sb__realloc(void *ptr, size_t size)
{
return OSSB_REALLOC(ptr, size);
}
static void sb__free(void *ptr)
{
OSSB_FREE(ptr);
}
OSSBDEF os_string_builder_t sb_new(void)
{
return (os_string_builder_t) {
.buffer = NULL,
.capacity = 0,
.length = 0,
};
}
OSSBDEF os_string_builder_t sb_from_cstr(char *str)
{
os_string_builder_t sb = sb_new();
sb = sb_append_cstr(sb, str);
return sb;
}
OSSBDEF os_string_builder_t sb_append_cstr(os_string_builder_t sb, char *str)
{
size_t length = strlen(str);
if (sb.length + length >= sb.capacity)
{
size_t new_capacity = sb.capacity == 0 ? OSSB_INITIAL_CAPACITY
: sb.capacity * OSSB_FACTOR;
while (sb.length + length >= new_capacity)
{
new_capacity *= OSSB_FACTOR;
}
sb.buffer = sb__realloc(sb.buffer, new_capacity);
if (NULL == sb.buffer)
{
exit(1);
}
sb.capacity = new_capacity;
}
memcpy(sb.buffer + sb.length, str, length);
sb.length += length;
return sb;
}
OSSBDEF os_string_builder_t sb_end(os_string_builder_t sb)
{
if (sb.length + 1 >= sb.capacity)
{
size_t new_capacity = sb.capacity == 0 ? OSSB_INITIAL_CAPACITY
: sb.capacity * OSSB_FACTOR;
while (sb.length + 1 >= new_capacity)
{
new_capacity *= OSSB_FACTOR;
}
sb.buffer = sb__realloc(sb.buffer, new_capacity);
if (NULL == sb.buffer)
{
exit(1);
}
sb.capacity = new_capacity;
}
sb.buffer[sb.length++] = '\0';
return sb;
}
OSSBDEF os_string_builder_t sb_reset(os_string_builder_t sb)
{
sb.length = 0;
return sb;
}
OSSBDEF char *sb_as_cstr(os_string_builder_t sb)
{
return sb.buffer;
}
OSSBDEF os_string_builder_t sb_free(os_string_builder_t sb)
{
if (sb.buffer)
{
sb__free(sb.buffer);
sb.buffer = NULL;
}
sb.length = 0;
sb.capacity = 0;
return sb;
}
#endif