1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27 #ifndef __G_STRING_H__
28 #define __G_STRING_H__
29
30 #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
31 #error "Only <glib.h> can be included directly."
32 #endif
33
34 #include <glib/gtypes.h>
35 #include <glib/gunicode.h>
36 #include <glib/gbytes.h>
37 #include <glib/gstrfuncs.h>
38 #include <glib/gutils.h> /* for G_CAN_INLINE */
39 #include <string.h>
40
41 G_BEGIN_DECLS
42
43 typedef struct _GString GString;
44
45 struct _GString
46 {
47 gchar *str;
48 gsize len;
49 gsize allocated_len;
50 };
51
52 GLIB_AVAILABLE_IN_ALL
53 GString* g_string_new (const gchar *init);
54 GLIB_AVAILABLE_IN_2_78
55 GString* g_string_new_take (gchar *init);
56 GLIB_AVAILABLE_IN_ALL
57 GString* g_string_new_len (const gchar *init,
58 gssize len);
59 GLIB_AVAILABLE_IN_ALL
60 GString* g_string_sized_new (gsize dfl_size);
61 GLIB_AVAILABLE_IN_ALL
62 gchar* (g_string_free) (GString *string,
63 gboolean free_segment);
64 GLIB_AVAILABLE_IN_2_76
65 gchar* g_string_free_and_steal (GString *string) G_GNUC_WARN_UNUSED_RESULT;
66
67 #if G_GNUC_CHECK_VERSION (2, 0) && (GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_76)
68
69 #define g_string_free(str, free_segment) \
70 (__builtin_constant_p (free_segment) ? \
71 ((free_segment) ? \
72 (g_string_free) ((str), (free_segment)) : \
73 g_string_free_and_steal (str)) \
74 : \
75 (g_string_free) ((str), (free_segment)))
76
77 #endif /* G_GNUC_CHECK_VERSION (2, 0) && (GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_76) */
78
79 GLIB_AVAILABLE_IN_2_34
80 GBytes* g_string_free_to_bytes (GString *string);
81 GLIB_AVAILABLE_IN_ALL
82 gboolean g_string_equal (const GString *v,
83 const GString *v2);
84 GLIB_AVAILABLE_IN_ALL
85 guint g_string_hash (const GString *str);
86 GLIB_AVAILABLE_IN_ALL
87 GString* g_string_assign (GString *string,
88 const gchar *rval);
89 GLIB_AVAILABLE_IN_ALL
90 GString* g_string_truncate (GString *string,
91 gsize len);
92 GLIB_AVAILABLE_IN_ALL
93 GString* g_string_set_size (GString *string,
94 gsize len);
95 GLIB_AVAILABLE_IN_ALL
96 GString* g_string_insert_len (GString *string,
97 gssize pos,
98 const gchar *val,
99 gssize len);
100 GLIB_AVAILABLE_IN_ALL
101 GString* g_string_append (GString *string,
102 const gchar *val);
103 GLIB_AVAILABLE_IN_ALL
104 GString* g_string_append_len (GString *string,
105 const gchar *val,
106 gssize len);
107 GLIB_AVAILABLE_IN_ALL
108 GString* g_string_append_c (GString *string,
109 gchar c);
110 GLIB_AVAILABLE_IN_ALL
111 GString* g_string_append_unichar (GString *string,
112 gunichar wc);
113 GLIB_AVAILABLE_IN_ALL
114 GString* g_string_prepend (GString *string,
115 const gchar *val);
116 GLIB_AVAILABLE_IN_ALL
117 GString* g_string_prepend_c (GString *string,
118 gchar c);
119 GLIB_AVAILABLE_IN_ALL
120 GString* g_string_prepend_unichar (GString *string,
121 gunichar wc);
122 GLIB_AVAILABLE_IN_ALL
123 GString* g_string_prepend_len (GString *string,
124 const gchar *val,
125 gssize len);
126 GLIB_AVAILABLE_IN_ALL
127 GString* g_string_insert (GString *string,
128 gssize pos,
129 const gchar *val);
130 GLIB_AVAILABLE_IN_ALL
131 GString* g_string_insert_c (GString *string,
132 gssize pos,
133 gchar c);
134 GLIB_AVAILABLE_IN_ALL
135 GString* g_string_insert_unichar (GString *string,
136 gssize pos,
137 gunichar wc);
138 GLIB_AVAILABLE_IN_ALL
139 GString* g_string_overwrite (GString *string,
140 gsize pos,
141 const gchar *val);
142 GLIB_AVAILABLE_IN_ALL
143 GString* g_string_overwrite_len (GString *string,
144 gsize pos,
145 const gchar *val,
146 gssize len);
147 GLIB_AVAILABLE_IN_ALL
148 GString* g_string_erase (GString *string,
149 gssize pos,
150 gssize len);
151 GLIB_AVAILABLE_IN_2_68
152 guint g_string_replace (GString *string,
153 const gchar *find,
154 const gchar *replace,
155 guint limit);
156 GLIB_AVAILABLE_IN_ALL
157 GString* g_string_ascii_down (GString *string);
158 GLIB_AVAILABLE_IN_ALL
159 GString* g_string_ascii_up (GString *string);
160 GLIB_AVAILABLE_IN_ALL
161 void g_string_vprintf (GString *string,
162 const gchar *format,
163 va_list args)
164 G_GNUC_PRINTF(2, 0);
165 GLIB_AVAILABLE_IN_ALL
166 void g_string_printf (GString *string,
167 const gchar *format,
168 ...) G_GNUC_PRINTF (2, 3);
169 GLIB_AVAILABLE_IN_ALL
170 void g_string_append_vprintf (GString *string,
171 const gchar *format,
172 va_list args)
173 G_GNUC_PRINTF(2, 0);
174 GLIB_AVAILABLE_IN_ALL
175 void g_string_append_printf (GString *string,
176 const gchar *format,
177 ...) G_GNUC_PRINTF (2, 3);
178 GLIB_AVAILABLE_IN_ALL
179 GString* g_string_append_uri_escaped (GString *string,
180 const gchar *unescaped,
181 const gchar *reserved_chars_allowed,
182 gboolean allow_utf8);
183
184 #ifdef G_CAN_INLINE
185
186 #if defined (_MSC_VER) && !defined (__clang__)
187 #pragma warning (push)
188 #pragma warning (disable : 4141) /* silence "warning C4141: 'inline' used more than once" */
189 #endif
190
191 #ifndef __GTK_DOC_IGNORE__
192
193 G_ALWAYS_INLINE
194 static inline GString*
195 g_string_append_c_inline (GString *gstring,
196 gchar c)
197 {
198 if (G_LIKELY (gstring != NULL &&
199 gstring->len + 1 < gstring->allocated_len))
200 {
201 gstring->str[gstring->len++] = c;
202 gstring->str[gstring->len] = 0;
203 }
204 else
205 g_string_insert_c (gstring, -1, c);
206 return gstring;
207 }
208
209 #define g_string_append_c(gstr,c) \
210 g_string_append_c_inline (gstr, c)
211
212 G_ALWAYS_INLINE
213 static inline GString *
214 g_string_append_len_inline (GString *gstring,
215 const char *val,
216 gssize len)
217 {
218 gsize len_unsigned;
219
220 if G_UNLIKELY (gstring == NULL)
221 return g_string_append_len (gstring, val, len);
222
223 if G_UNLIKELY (val == NULL)
224 return (len != 0) ? g_string_append_len (gstring, val, len) : gstring;
225
226 if (len < 0)
227 len_unsigned = strlen (val);
228 else
229 len_unsigned = (gsize) len;
230
231 if (G_LIKELY (gstring->len + len_unsigned < gstring->allocated_len))
232 {
233 char *end = gstring->str + gstring->len;
234 if (G_LIKELY (val + len_unsigned <= end || val > end + len_unsigned))
235 memcpy (end, val, len_unsigned);
236 else
237 memmove (end, val, len_unsigned);
238 gstring->len += len_unsigned;
239 gstring->str[gstring->len] = 0;
240 return gstring;
241 }
242 else
243 return g_string_insert_len (gstring, -1, val, len);
244 }
245
246 #define g_string_append_len(gstr, val, len) \
247 g_string_append_len_inline (gstr, val, len)
248
249 G_ALWAYS_INLINE
250 static inline GString *
251 g_string_truncate_inline (GString *gstring,
252 gsize len)
253 {
254 gstring->len = MIN (len, gstring->len);
255 gstring->str[gstring->len] = '\0';
256 return gstring;
257 }
258
259 #define g_string_truncate(gstr, len) \
260 g_string_truncate_inline (gstr, len)
261
262 #if G_GNUC_CHECK_VERSION (2, 0)
263
264 #define g_string_append(gstr, val) \
265 (__builtin_constant_p (val) ? \
266 G_GNUC_EXTENSION ({ \
267 const char * const __val = (val); \
268 g_string_append_len (gstr, __val, \
269 G_LIKELY (__val != NULL) ? \
270 (gssize) strlen (_G_STR_NONNULL (__val)) \
271 : (gssize) -1); \
272 }) \
273 : \
274 g_string_append_len (gstr, val, (gssize) -1))
275
276 #endif /* G_GNUC_CHECK_VERSION (2, 0) */
277
278 #endif /* __GTK_DOC_IGNORE__ */
279
280 #if defined (_MSC_VER) && !defined (__clang__)
281 #pragma warning (pop) /* #pragma warning (disable : 4141) */
282 #endif
283
284 #endif /* G_CAN_INLINE */
285
286 GLIB_DEPRECATED
287 GString *g_string_down (GString *string);
288 GLIB_DEPRECATED
289 GString *g_string_up (GString *string);
290
291 #define g_string_sprintf g_string_printf GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_string_printf)
292 #define g_string_sprintfa g_string_append_printf GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_string_append_printf)
293
294 G_END_DECLS
295
296 #endif /* __G_STRING_H__ */