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
41G_BEGIN_DECLS
42
43typedef struct _GString GString;
44
45struct _GString
46{
47 gchar *str;
48 gsize len;
49 gsize allocated_len;
50};
51
52GLIB_AVAILABLE_IN_ALL
53GString* g_string_new (const gchar *init);
54GLIB_AVAILABLE_IN_2_78
55GString* g_string_new_take (gchar *init);
56GLIB_AVAILABLE_IN_ALL
57GString* g_string_new_len (const gchar *init,
58 gssize len);
59GLIB_AVAILABLE_IN_ALL
60GString* g_string_sized_new (gsize dfl_size);
61GLIB_AVAILABLE_IN_2_86
62GString *g_string_copy (GString *string);
63GLIB_AVAILABLE_IN_ALL
64gchar* (g_string_free) (GString *string,
65 gboolean free_segment);
66GLIB_AVAILABLE_IN_2_76
67gchar* g_string_free_and_steal (GString *string) G_GNUC_WARN_UNUSED_RESULT;
68
69#if G_GNUC_CHECK_VERSION (2, 0) && (GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_76)
70
71#if !defined(__cplusplus) || !G_GNUC_CHECK_VERSION (6, 1) || G_GNUC_CHECK_VERSION (7, 3)
72
73#define g_string_free(str, free_segment) \
74 (__builtin_constant_p (free_segment) ? \
75 ((free_segment) ? \
76 (g_string_free) ((str), (free_segment)) : \
77 g_string_free_and_steal (str)) \
78 : \
79 (g_string_free) ((str), (free_segment)))
80
81#endif /* !defined(__cplusplus) || !G_GNUC_CHECK_VERSION (6, 1) || G_GNUC_CHECK_VERSION (7, 3) */
82
83#endif /* G_GNUC_CHECK_VERSION (2, 0) && (GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_76) */
84
85GLIB_AVAILABLE_IN_2_34
86GBytes* g_string_free_to_bytes (GString *string);
87GLIB_AVAILABLE_IN_ALL
88gboolean g_string_equal (const GString *v,
89 const GString *v2);
90GLIB_AVAILABLE_IN_ALL
91guint g_string_hash (const GString *str);
92GLIB_AVAILABLE_IN_ALL
93GString* g_string_assign (GString *string,
94 const gchar *rval);
95GLIB_AVAILABLE_IN_ALL
96GString* g_string_truncate (GString *string,
97 gsize len);
98GLIB_AVAILABLE_IN_ALL
99GString* g_string_set_size (GString *string,
100 gsize len);
101GLIB_AVAILABLE_IN_ALL
102GString* g_string_insert_len (GString *string,
103 gssize pos,
104 const gchar *val,
105 gssize len);
106GLIB_AVAILABLE_IN_ALL
107GString* g_string_append (GString *string,
108 const gchar *val);
109GLIB_AVAILABLE_IN_ALL
110GString* g_string_append_len (GString *string,
111 const gchar *val,
112 gssize len);
113GLIB_AVAILABLE_IN_ALL
114GString* g_string_append_c (GString *string,
115 gchar c);
116GLIB_AVAILABLE_IN_ALL
117GString* g_string_append_unichar (GString *string,
118 gunichar wc);
119GLIB_AVAILABLE_IN_ALL
120GString* g_string_prepend (GString *string,
121 const gchar *val);
122GLIB_AVAILABLE_IN_ALL
123GString* g_string_prepend_c (GString *string,
124 gchar c);
125GLIB_AVAILABLE_IN_ALL
126GString* g_string_prepend_unichar (GString *string,
127 gunichar wc);
128GLIB_AVAILABLE_IN_ALL
129GString* g_string_prepend_len (GString *string,
130 const gchar *val,
131 gssize len);
132GLIB_AVAILABLE_IN_ALL
133GString* g_string_insert (GString *string,
134 gssize pos,
135 const gchar *val);
136GLIB_AVAILABLE_IN_ALL
137GString* g_string_insert_c (GString *string,
138 gssize pos,
139 gchar c);
140GLIB_AVAILABLE_IN_ALL
141GString* g_string_insert_unichar (GString *string,
142 gssize pos,
143 gunichar wc);
144GLIB_AVAILABLE_IN_ALL
145GString* g_string_overwrite (GString *string,
146 gsize pos,
147 const gchar *val);
148GLIB_AVAILABLE_IN_ALL
149GString* g_string_overwrite_len (GString *string,
150 gsize pos,
151 const gchar *val,
152 gssize len);
153GLIB_AVAILABLE_IN_ALL
154GString* g_string_erase (GString *string,
155 gssize pos,
156 gssize len);
157GLIB_AVAILABLE_IN_2_68
158guint g_string_replace (GString *string,
159 const gchar *find,
160 const gchar *replace,
161 guint limit);
162GLIB_AVAILABLE_IN_ALL
163GString* g_string_ascii_down (GString *string);
164GLIB_AVAILABLE_IN_ALL
165GString* g_string_ascii_up (GString *string);
166GLIB_AVAILABLE_IN_ALL
167void g_string_vprintf (GString *string,
168 const gchar *format,
169 va_list args)
170 G_GNUC_PRINTF(2, 0);
171GLIB_AVAILABLE_IN_ALL
172void g_string_printf (GString *string,
173 const gchar *format,
174 ...) G_GNUC_PRINTF (2, 3);
175GLIB_AVAILABLE_IN_ALL
176void g_string_append_vprintf (GString *string,
177 const gchar *format,
178 va_list args)
179 G_GNUC_PRINTF(2, 0);
180GLIB_AVAILABLE_IN_ALL
181void g_string_append_printf (GString *string,
182 const gchar *format,
183 ...) G_GNUC_PRINTF (2, 3);
184GLIB_AVAILABLE_IN_ALL
185GString* g_string_append_uri_escaped (GString *string,
186 const gchar *unescaped,
187 const gchar *reserved_chars_allowed,
188 gboolean allow_utf8);
189
190#ifdef G_CAN_INLINE
191
192#if defined (_MSC_VER) && !defined (__clang__)
193#pragma warning (push)
194#pragma warning (disable : 4141) /* silence "warning C4141: 'inline' used more than once" */
195#endif
196
197#ifndef __GTK_DOC_IGNORE__
198
199G_ALWAYS_INLINE
200static inline GString*
201g_string_append_c_inline (GString *gstring,
202 gchar c)
203{
204 if (G_LIKELY (gstring != NULL &&
205 gstring->len + 1 < gstring->allocated_len))
206 {
207 gstring->str[gstring->len++] = c;
208 gstring->str[gstring->len] = 0;
209 }
210 else
211 g_string_insert_c (string: gstring, pos: -1, c);
212 return gstring;
213}
214
215#define g_string_append_c(gstr,c) \
216 g_string_append_c_inline (gstr, c)
217
218G_ALWAYS_INLINE
219static inline GString *
220g_string_append_len_inline (GString *gstring,
221 const char *val,
222 gssize len)
223{
224 gsize len_unsigned;
225
226 if G_UNLIKELY (gstring == NULL)
227 return g_string_append_len (string: gstring, val, len);
228
229 if G_UNLIKELY (val == NULL)
230 return (len != 0) ? g_string_append_len (string: gstring, val, len) : gstring;
231
232 if (len < 0)
233 len_unsigned = strlen (s: val);
234 else
235 len_unsigned = (gsize) len;
236
237 if (G_LIKELY (len_unsigned < gstring->allocated_len - gstring->len))
238 {
239 char *end = gstring->str + gstring->len;
240 if (G_LIKELY (val + len_unsigned <= end || val >= end + len_unsigned))
241 memcpy (dest: end, src: val, n: len_unsigned);
242 else
243 memmove (dest: end, src: val, n: len_unsigned);
244 gstring->len += len_unsigned;
245 gstring->str[gstring->len] = 0;
246 return gstring;
247 }
248 else
249 return g_string_insert_len (string: gstring, pos: -1, val, len);
250}
251
252#define g_string_append_len(gstr, val, len) \
253 g_string_append_len_inline (gstr, val, len)
254
255G_ALWAYS_INLINE
256static inline GString *
257g_string_truncate_inline (GString *gstring,
258 gsize len)
259{
260 gstring->len = MIN (len, gstring->len);
261 gstring->str[gstring->len] = '\0';
262 return gstring;
263}
264
265#define g_string_truncate(gstr, len) \
266 g_string_truncate_inline (gstr, len)
267
268#if G_GNUC_CHECK_VERSION (2, 0)
269
270#define g_string_append(gstr, val) \
271 (__builtin_constant_p (val) ? \
272 G_GNUC_EXTENSION ({ \
273 const char * const __val = (val); \
274 g_string_append_len (gstr, __val, \
275 G_LIKELY (__val != NULL) ? \
276 (gssize) strlen (_G_STR_NONNULL (__val)) \
277 : (gssize) -1); \
278 }) \
279 : \
280 g_string_append_len (gstr, val, (gssize) -1))
281
282#endif /* G_GNUC_CHECK_VERSION (2, 0) */
283
284#endif /* __GTK_DOC_IGNORE__ */
285
286#if defined (_MSC_VER) && !defined (__clang__)
287#pragma warning (pop) /* #pragma warning (disable : 4141) */
288#endif
289
290#endif /* G_CAN_INLINE */
291
292GLIB_DEPRECATED
293GString *g_string_down (GString *string);
294GLIB_DEPRECATED
295GString *g_string_up (GString *string);
296
297#define g_string_sprintf g_string_printf GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_string_printf)
298#define g_string_sprintfa g_string_append_printf GLIB_DEPRECATED_MACRO_IN_2_26_FOR(g_string_append_printf)
299
300G_END_DECLS
301
302#endif /* __G_STRING_H__ */
303