Blender V4.3
BLI_dynstr.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include <stdio.h>
11#include <stdlib.h> /* malloc */
12#include <string.h>
13
14#include "BLI_dynstr.h"
15#include "BLI_memarena.h"
16#include "BLI_string.h"
17#include "BLI_utildefines.h"
18#include "MEM_guardedalloc.h"
19
20/***/
21
22typedef struct DynStrElem DynStrElem;
23struct DynStrElem {
25
26 char *str;
27};
28
34
35/***/
36
38{
39 DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
40 ds->elems = ds->last = NULL;
41 ds->curlen = 0;
42 ds->memarena = NULL;
43
44 return ds;
45}
46
48{
49 DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
50 ds->elems = ds->last = NULL;
51 ds->curlen = 0;
53
54 return ds;
55}
56
57BLI_INLINE void *dynstr_alloc(DynStr *__restrict ds, size_t size)
58{
59 return ds->memarena ? BLI_memarena_alloc(ds->memarena, size) : malloc(size);
60}
61
62void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
63{
64 DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
65 int cstrlen = strlen(cstr);
66
67 dse->str = dynstr_alloc(ds, cstrlen + 1);
68 memcpy(dse->str, cstr, cstrlen + 1);
69 dse->next = NULL;
70
71 if (!ds->last) {
72 ds->last = ds->elems = dse;
73 }
74 else {
75 ds->last = ds->last->next = dse;
76 }
77
78 ds->curlen += cstrlen;
79}
80
81void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len)
82{
83 DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
84 int cstrlen = BLI_strnlen(cstr, len);
85
86 dse->str = dynstr_alloc(ds, cstrlen + 1);
87 memcpy(dse->str, cstr, cstrlen);
88 dse->str[cstrlen] = '\0';
89 dse->next = NULL;
90
91 if (!ds->last) {
92 ds->last = ds->elems = dse;
93 }
94 else {
95 ds->last = ds->last->next = dse;
96 }
97
98 ds->curlen += cstrlen;
99}
100
101void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args)
102{
103 char *str, fixed_buf[256];
104 size_t str_len;
105 str = BLI_vsprintfN_with_buffer(fixed_buf, sizeof(fixed_buf), &str_len, format, args);
107 if (str != fixed_buf) {
108 MEM_freeN(str);
109 }
110}
111
112void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format, ...)
113{
114 va_list args;
115 char *str, fixed_buf[256];
116 size_t str_len;
117 va_start(args, format);
118 str = BLI_vsprintfN_with_buffer(fixed_buf, sizeof(fixed_buf), &str_len, format, args);
119 va_end(args);
120 if (LIKELY(str)) {
122 if (str != fixed_buf) {
123 MEM_freeN(str);
124 }
125 }
126}
127
129{
130 return ds->curlen;
131}
132
133void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets)
134{
135 char *s;
136 const DynStrElem *dse;
137
138 for (s = rets, dse = ds->elems; dse; dse = dse->next) {
139 int slen = strlen(dse->str);
140
141 memcpy(s, dse->str, slen);
142
143 s += slen;
144 }
145 BLI_assert((s - rets) == ds->curlen);
146 rets[ds->curlen] = '\0';
147}
148
150{
151 char *rets = MEM_mallocN(ds->curlen + 1, "dynstr_cstring");
153 return rets;
154}
155
157{
158 if (ds->memarena) {
160 }
161 else {
162 for (DynStrElem *dse_next, *dse = ds->elems; dse; dse = dse_next) {
163 dse_next = dse->next;
164
165 free(dse->str);
166 free(dse);
167 }
168 }
169
170 ds->elems = ds->last = NULL;
171 ds->curlen = 0;
172}
173
175{
176 if (ds->memarena) {
178 }
179 else {
181 }
182
183 MEM_freeN(ds);
184}
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_INLINE
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...)
Definition BLI_dynstr.c:112
DynStr * BLI_dynstr_new_memarena(void)
Definition BLI_dynstr.c:47
char * BLI_dynstr_get_cstring(const DynStr *ds)
Definition BLI_dynstr.c:149
BLI_INLINE void * dynstr_alloc(DynStr *__restrict ds, size_t size)
Definition BLI_dynstr.c:57
void BLI_dynstr_free(DynStr *ds)
Definition BLI_dynstr.c:174
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len)
Definition BLI_dynstr.c:81
void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets)
Definition BLI_dynstr.c:133
void BLI_dynstr_clear(DynStr *ds)
Definition BLI_dynstr.c:156
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
Definition BLI_dynstr.c:62
void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args)
Definition BLI_dynstr.c:101
DynStr * BLI_dynstr_new(void)
Definition BLI_dynstr.c:37
int BLI_dynstr_get_len(const DynStr *ds)
Definition BLI_dynstr.c:128
A dynamically sized string ADT.
void BLI_kdtree_nd_ free(KDTree *tree)
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
void void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
char * BLI_vsprintfN_with_buffer(char *fixed_buf, size_t fixed_buf_size, size_t *result_len, const char *__restrict format, va_list args) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.c:909
#define LIKELY(x)
Read Guarded memory(de)allocation.
#define NULL
int len
#define str(s)
format
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
DynStrElem * next
Definition BLI_dynstr.c:24
char * str
Definition BLI_dynstr.c:26
MemArena * memarena
Definition BLI_dynstr.c:32
DynStrElem * last
Definition BLI_dynstr.c:30
int curlen
Definition BLI_dynstr.c:31
DynStrElem * elems
Definition BLI_dynstr.c:30