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