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 : : /*
28 : : * MT safe
29 : : */
30 : :
31 : : #include "config.h"
32 : :
33 : : #include <stdarg.h>
34 : : #include <stdlib.h>
35 : : #include <stdio.h>
36 : : #include <string.h>
37 : : #include <ctype.h>
38 : :
39 : : #include "gstring.h"
40 : : #include "guriprivate.h"
41 : : #include "gprintf.h"
42 : : #include "gutilsprivate.h"
43 : :
44 : :
45 : : /**
46 : : * GString:
47 : : * @str: points to the character data. It may move as text is added.
48 : : * The @str field is null-terminated and so
49 : : * can be used as an ordinary C string.
50 : : * @len: contains the length of the string, not including the
51 : : * terminating nul byte.
52 : : * @allocated_len: the number of bytes that can be stored in the
53 : : * string before it needs to be reallocated. May be larger than @len.
54 : : *
55 : : * A `GString` is an object that handles the memory management of a C string.
56 : : *
57 : : * The emphasis of `GString` is on text, typically UTF-8. Crucially, the "str" member
58 : : * of a `GString` is guaranteed to have a trailing nul character, and it is therefore
59 : : * always safe to call functions such as `strchr()` or `strdup()` on it.
60 : : *
61 : : * However, a `GString` can also hold arbitrary binary data, because it has a "len" member,
62 : : * which includes any possible embedded nul characters in the data. Conceptually then,
63 : : * `GString` is like a `GByteArray` with the addition of many convenience methods for
64 : : * text, and a guaranteed nul terminator.
65 : : */
66 : :
67 : : static void
68 : 1354492 : g_string_expand (GString *string,
69 : : gsize len)
70 : : {
71 : : /* Detect potential overflow */
72 : 1354492 : if G_UNLIKELY ((G_MAXSIZE - string->len - 1) < len)
73 : 1 : g_error ("adding %" G_GSIZE_FORMAT " to string would overflow", len);
74 : :
75 : 1354491 : string->allocated_len = g_nearest_pow (string->len + len + 1);
76 : : /* If the new size is bigger than G_MAXSIZE / 2, only allocate enough
77 : : * memory for this string and don't over-allocate.
78 : : */
79 : 1354491 : if (string->allocated_len == 0)
80 : 0 : string->allocated_len = string->len + len + 1;
81 : :
82 : 1354491 : string->str = g_realloc (string->str, string->allocated_len);
83 : 1354491 : }
84 : :
85 : : static inline void
86 : 22495035 : g_string_maybe_expand (GString *string,
87 : : gsize len)
88 : : {
89 : 22495035 : if (G_UNLIKELY (len >= string->allocated_len - string->len))
90 : 185420 : g_string_expand (string, len);
91 : 22495035 : }
92 : :
93 : : /**
94 : : * g_string_sized_new: (constructor)
95 : : * @dfl_size: the default size of the space allocated to hold the string
96 : : *
97 : : * Creates a new #GString, with enough space for @dfl_size
98 : : * bytes. This is useful if you are going to add a lot of
99 : : * text to the string and don't want it to be reallocated
100 : : * too often.
101 : : *
102 : : * Returns: (transfer full): the new #GString
103 : : */
104 : : GString *
105 : 1169083 : g_string_sized_new (gsize dfl_size)
106 : : {
107 : 1169083 : GString *string = g_slice_new (GString);
108 : :
109 : 1169083 : string->allocated_len = 0;
110 : 1169083 : string->len = 0;
111 : 1169083 : string->str = NULL;
112 : :
113 : 1169083 : g_string_expand (string, MAX (dfl_size, 64));
114 : 1169083 : string->str[0] = 0;
115 : :
116 : 1169083 : return string;
117 : : }
118 : :
119 : : /**
120 : : * g_string_new: (constructor)
121 : : * @init: (nullable): the initial text to copy into the string, or %NULL to
122 : : * start with an empty string
123 : : *
124 : : * Creates a new #GString, initialized with the given string.
125 : : *
126 : : * Returns: (transfer full): the new #GString
127 : : */
128 : : GString *
129 : 947308 : g_string_new (const gchar *init)
130 : : {
131 : : GString *string;
132 : :
133 : 947308 : if (init == NULL || *init == '\0')
134 : 901700 : string = g_string_sized_new (2);
135 : : else
136 : : {
137 : : size_t len;
138 : :
139 : 45608 : len = strlen (init);
140 : 45608 : string = g_string_sized_new (len + 2);
141 : :
142 : 45608 : g_string_append_len (string, init, len);
143 : : }
144 : :
145 : 947308 : return string;
146 : : }
147 : :
148 : : /**
149 : : * g_string_new_take: (constructor)
150 : : * @init: (nullable) (transfer full): initial text used as the string.
151 : : * Ownership of the string is transferred to the #GString.
152 : : * Passing %NULL creates an empty string.
153 : : *
154 : : * Creates a new #GString, initialized with the given string.
155 : : *
156 : : * After this call, @init belongs to the #GString and may no longer be
157 : : * modified by the caller. The memory of @init has to be dynamically
158 : : * allocated and will eventually be freed with g_free().
159 : : *
160 : : * Returns: (transfer full): the new #GString
161 : : *
162 : : * Since: 2.78
163 : : */
164 : : GString *
165 : 4 : g_string_new_take (gchar *init)
166 : : {
167 : : GString *string;
168 : :
169 : 4 : if (init == NULL)
170 : : {
171 : 2 : return g_string_new (NULL);
172 : : }
173 : :
174 : 2 : string = g_slice_new (GString);
175 : :
176 : 2 : string->str = init;
177 : 2 : string->len = strlen (string->str);
178 : 2 : string->allocated_len = string->len + 1;
179 : :
180 : 2 : return string;
181 : 2 : }
182 : :
183 : : /**
184 : : * g_string_new_len: (constructor)
185 : : * @init: initial contents of the string
186 : : * @len: length of @init to use
187 : : *
188 : : * Creates a new #GString with @len bytes of the @init buffer.
189 : : * Because a length is provided, @init need not be nul-terminated,
190 : : * and can contain embedded nul bytes.
191 : : *
192 : : * Since this function does not stop at nul bytes, it is the caller's
193 : : * responsibility to ensure that @init has at least @len addressable
194 : : * bytes.
195 : : *
196 : : * Returns: (transfer full): a new #GString
197 : : */
198 : : GString *
199 : 47804 : g_string_new_len (const gchar *init,
200 : : gssize len)
201 : : {
202 : : GString *string;
203 : :
204 : 47804 : if (len < 0)
205 : 1013 : return g_string_new (init);
206 : : else
207 : : {
208 : 46791 : string = g_string_sized_new (len);
209 : :
210 : 46791 : if (init)
211 : 2 : g_string_append_len (string, init, len);
212 : :
213 : 46791 : return string;
214 : : }
215 : 18709 : }
216 : :
217 : : /**
218 : : * g_string_copy:
219 : : * @string: a string
220 : : *
221 : : * Copies the [struct@GLib.String] instance and its contents.
222 : : *
223 : : * This will preserve the allocation length of the [struct@GLib.String] in the
224 : : * copy.
225 : : *
226 : : * Returns: (transfer full): a copy of @string
227 : : * Since: 2.86
228 : : */
229 : : GString *
230 : 8 : g_string_copy (GString *string)
231 : : {
232 : 8 : GString *copy = NULL;
233 : :
234 : 8 : g_return_val_if_fail (string != NULL, NULL);
235 : :
236 : 8 : copy = g_slice_new (GString);
237 : 8 : copy->allocated_len = string->allocated_len;
238 : 8 : copy->len = string->len;
239 : :
240 : : /* We can’t just strdup(string->str) here because it may contain embedded nuls. */
241 : 8 : copy->str = g_malloc (string->allocated_len);
242 : 8 : if (string->str != NULL && string->len > 0)
243 : 6 : memcpy (copy->str, string->str, string->len);
244 : 8 : copy->str[copy->len] = '\0';
245 : :
246 : 8 : return g_steal_pointer (©);
247 : 4 : }
248 : :
249 : : /**
250 : : * g_string_free:
251 : : * @string: (transfer full): a #GString
252 : : * @free_segment: if %TRUE, the actual character data is freed as well
253 : : *
254 : : * Frees the memory allocated for the #GString.
255 : : * If @free_segment is %TRUE it also frees the character data. If
256 : : * it's %FALSE, the caller gains ownership of the buffer and must
257 : : * free it after use with g_free().
258 : : *
259 : : * Instead of passing %FALSE to this function, consider using
260 : : * g_string_free_and_steal().
261 : : *
262 : : * Similarly, instead of passing `TRUE` to this function,
263 : : * [method@GLib.String.free_deep] can be used. In particular, it can be used
264 : : * with [func@GLib.clear_pointer].
265 : : *
266 : : * Returns: (nullable): the character data of @string
267 : : * (i.e. %NULL if @free_segment is %TRUE)
268 : : */
269 : : gchar *
270 : 1168599 : (g_string_free) (GString *string,
271 : : gboolean free_segment)
272 : : {
273 : : gchar *segment;
274 : :
275 : 1168599 : g_return_val_if_fail (string != NULL, NULL);
276 : :
277 : 1168599 : if (free_segment)
278 : : {
279 : 381683 : g_free (string->str);
280 : 381683 : segment = NULL;
281 : 172859 : }
282 : : else
283 : 786916 : segment = string->str;
284 : :
285 : 1168599 : g_slice_free (GString, string);
286 : :
287 : 1168599 : return segment;
288 : 690138 : }
289 : :
290 : : /**
291 : : * g_string_free_deep:
292 : : * @string: (transfer full): a string
293 : : *
294 : : * Frees the memory allocated for the [struct@GLib.String] together with its
295 : : * character data.
296 : : *
297 : : * This is equivalent to calling `g_string_free (string, TRUE)`, but it can
298 : : * be used with [func@GLib.clear_pointer]:
299 : : *
300 : : * ```c
301 : : * g_clear_pointer (&my_string, g_string_free_deep);
302 : : * ```
303 : : *
304 : : * Since: 2.90
305 : : */
306 : : void
307 : 8 : (g_string_free_deep) (GString *string)
308 : : {
309 : 8 : g_string_free (string, TRUE);
310 : 8 : }
311 : :
312 : : /**
313 : : * g_string_free_and_steal:
314 : : * @string: (transfer full): a #GString
315 : : *
316 : : * Frees the memory allocated for the #GString.
317 : : *
318 : : * The caller gains ownership of the buffer and
319 : : * must free it after use with g_free().
320 : : *
321 : : * Returns: (transfer full): the character data of @string
322 : : *
323 : : * Since: 2.76
324 : : */
325 : : gchar *
326 : 786886 : g_string_free_and_steal (GString *string)
327 : : {
328 : 786886 : return (g_string_free) (string, FALSE);
329 : : }
330 : :
331 : : /**
332 : : * g_string_free_to_bytes:
333 : : * @string: (transfer full): a #GString
334 : : *
335 : : * Transfers ownership of the contents of @string to a newly allocated
336 : : * #GBytes. The #GString structure itself is deallocated, and it is
337 : : * therefore invalid to use @string after invoking this function.
338 : : *
339 : : * Note that while #GString ensures that its buffer always has a
340 : : * trailing nul character (not reflected in its "len"), the returned
341 : : * #GBytes does not include this extra nul; i.e. it has length exactly
342 : : * equal to the "len" member.
343 : : *
344 : : * Returns: (transfer full): A newly allocated #GBytes containing contents of @string; @string itself is freed
345 : : * Since: 2.34
346 : : */
347 : : GBytes*
348 : 2 : g_string_free_to_bytes (GString *string)
349 : : {
350 : : gsize len;
351 : : gchar *buf;
352 : :
353 : 2 : g_return_val_if_fail (string != NULL, NULL);
354 : :
355 : 2 : len = string->len;
356 : :
357 : 2 : buf = g_string_free (string, FALSE);
358 : :
359 : 2 : return g_bytes_new_take (buf, len);
360 : 1 : }
361 : :
362 : : /**
363 : : * g_string_equal:
364 : : * @v: a #GString
365 : : * @v2: another #GString
366 : : *
367 : : * Compares two strings for equality, returning %TRUE if they are equal.
368 : : * For use with #GHashTable.
369 : : *
370 : : * Returns: %TRUE if the strings are the same length and contain the
371 : : * same bytes
372 : : */
373 : : gboolean
374 : 54 : g_string_equal (const GString *v,
375 : : const GString *v2)
376 : : {
377 : : gchar *p, *q;
378 : 54 : GString *string1 = (GString *) v;
379 : 54 : GString *string2 = (GString *) v2;
380 : 54 : gsize i = string1->len;
381 : :
382 : 54 : if (i != string2->len)
383 : 4 : return FALSE;
384 : :
385 : 50 : p = string1->str;
386 : 50 : q = string2->str;
387 : 344 : while (i)
388 : : {
389 : 296 : if (*p != *q)
390 : 2 : return FALSE;
391 : 294 : p++;
392 : 294 : q++;
393 : 294 : i--;
394 : : }
395 : 48 : return TRUE;
396 : 27 : }
397 : :
398 : : /**
399 : : * g_string_hash:
400 : : * @str: a string to hash
401 : : *
402 : : * Creates a hash code for @str; for use with #GHashTable.
403 : : *
404 : : * Returns: hash code for @str
405 : : */
406 : : guint
407 : 80 : g_string_hash (const GString *str)
408 : : {
409 : 80 : const gchar *p = str->str;
410 : 80 : gsize n = str->len;
411 : 80 : guint h = 0;
412 : :
413 : : /* 31 bit hash function */
414 : 560 : while (n--)
415 : : {
416 : 480 : h = (h << 5) - h + *p;
417 : 480 : p++;
418 : : }
419 : :
420 : 80 : return h;
421 : : }
422 : :
423 : : /**
424 : : * g_string_assign:
425 : : * @string: the destination #GString. Its current contents
426 : : * are destroyed.
427 : : * @rval: the string to copy into @string
428 : : *
429 : : * Copies the bytes from a string into a #GString,
430 : : * destroying any previous contents. It is rather like
431 : : * the standard strcpy() function, except that you do not
432 : : * have to worry about having enough space to copy the string.
433 : : *
434 : : * Returns: (transfer none): @string
435 : : */
436 : : GString *
437 : 64 : g_string_assign (GString *string,
438 : : const gchar *rval)
439 : : {
440 : 64 : g_return_val_if_fail (string != NULL, NULL);
441 : 64 : g_return_val_if_fail (rval != NULL, string);
442 : :
443 : : /* Make sure assigning to itself doesn't corrupt the string. */
444 : 64 : if (string->str != rval)
445 : : {
446 : : /* Assigning from substring should be ok, since
447 : : * g_string_truncate() does not reallocate.
448 : : */
449 : 25 : g_string_truncate (string, 0);
450 : 25 : g_string_append (string, rval);
451 : 25 : }
452 : :
453 : 64 : return string;
454 : 26 : }
455 : :
456 : : /**
457 : : * g_string_truncate:
458 : : * @string: a #GString
459 : : * @len: the new size of @string
460 : : *
461 : : * Cuts off the end of the GString, leaving the first @len bytes.
462 : : *
463 : : * Returns: (transfer none): @string
464 : : */
465 : : GString *
466 : 20 : (g_string_truncate) (GString *string,
467 : : gsize len)
468 : : {
469 : 20 : g_return_val_if_fail (string != NULL, NULL);
470 : :
471 : 20 : string->len = MIN (len, string->len);
472 : 20 : string->str[string->len] = 0;
473 : :
474 : 20 : return string;
475 : 10 : }
476 : :
477 : : /**
478 : : * g_string_set_size:
479 : : * @string: a #GString
480 : : * @len: the new length
481 : : *
482 : : * Sets the length of a #GString. If the length is less than
483 : : * the current length, the string will be truncated. If the
484 : : * length is greater than the current length, the contents
485 : : * of the newly added area are undefined. (However, as
486 : : * always, string->str[string->len] will be a nul byte.)
487 : : *
488 : : * Returns: (transfer none): @string
489 : : */
490 : : GString *
491 : 10560 : g_string_set_size (GString *string,
492 : : gsize len)
493 : : {
494 : 10560 : g_return_val_if_fail (string != NULL, NULL);
495 : :
496 : 10560 : if (len >= string->allocated_len)
497 : 0 : g_string_maybe_expand (string, len - string->len);
498 : :
499 : 10560 : string->len = len;
500 : 10560 : string->str[len] = 0;
501 : :
502 : 10560 : return string;
503 : 5067 : }
504 : :
505 : : /**
506 : : * g_string_insert_len:
507 : : * @string: a #GString
508 : : * @pos: position in @string where insertion should
509 : : * happen, or -1 for at the end
510 : : * @val: bytes to insert
511 : : * @len: number of bytes of @val to insert, or -1 for all of @val
512 : : *
513 : : * Inserts @len bytes of @val into @string at @pos.
514 : : *
515 : : * If @len is positive, @val may contain embedded nuls and need
516 : : * not be nul-terminated. It is the caller's responsibility to
517 : : * ensure that @val has at least @len addressable bytes.
518 : : *
519 : : * If @len is negative, @val must be nul-terminated and @len
520 : : * is considered to request the entire string length.
521 : : *
522 : : * If @pos is -1, bytes are inserted at the end of the string.
523 : : *
524 : : * Returns: (transfer none): @string
525 : : */
526 : : GString *
527 : 152588 : g_string_insert_len (GString *string,
528 : : gssize pos,
529 : : const gchar *val,
530 : : gssize len)
531 : : {
532 : : gsize len_unsigned, pos_unsigned;
533 : :
534 : 152588 : g_return_val_if_fail (string != NULL, NULL);
535 : 152508 : g_return_val_if_fail (len == 0 || val != NULL, string);
536 : :
537 : 152388 : if (len == 0)
538 : 20 : return string;
539 : :
540 : 152368 : if (len < 0)
541 : 15939 : len_unsigned = strlen (val);
542 : : else
543 : 136429 : len_unsigned = len;
544 : :
545 : 152368 : if (pos < 0)
546 : 152202 : pos_unsigned = string->len;
547 : : else
548 : : {
549 : 166 : pos_unsigned = pos;
550 : 166 : g_return_val_if_fail (pos_unsigned <= string->len, string);
551 : : }
552 : :
553 : : /* Check whether val represents a substring of string.
554 : : * This test probably violates chapter and verse of the C standards,
555 : : * since ">=" and "<=" are only valid when val really is a substring.
556 : : * In practice, it will work on modern archs.
557 : : */
558 : 152368 : if (G_UNLIKELY (val >= string->str && val <= string->str + string->len))
559 : 1 : {
560 : 2 : gsize offset = val - string->str;
561 : 2 : gsize precount = 0;
562 : :
563 : 2 : g_string_maybe_expand (string, len_unsigned);
564 : 2 : val = string->str + offset;
565 : : /* At this point, val is valid again. */
566 : :
567 : : /* Open up space where we are going to insert. */
568 : 2 : if (pos_unsigned < string->len)
569 : 4 : memmove (string->str + pos_unsigned + len_unsigned,
570 : 3 : string->str + pos_unsigned, string->len - pos_unsigned);
571 : :
572 : : /* Move the source part before the gap, if any. */
573 : 2 : if (offset < pos_unsigned)
574 : : {
575 : 2 : precount = MIN (len_unsigned, pos_unsigned - offset);
576 : 2 : memcpy (string->str + pos_unsigned, val, precount);
577 : 1 : }
578 : :
579 : : /* Move the source part after the gap, if any. */
580 : 2 : if (len_unsigned > precount)
581 : 5 : memcpy (string->str + pos_unsigned + precount,
582 : 2 : val + /* Already moved: */ precount +
583 : 1 : /* Space opened up: */ len_unsigned,
584 : 1 : len_unsigned - precount);
585 : 1 : }
586 : : else
587 : : {
588 : 152366 : g_string_maybe_expand (string, len_unsigned);
589 : :
590 : : /* If we aren't appending at the end, move a hunk
591 : : * of the old string to the end, opening up space
592 : : */
593 : 152366 : if (pos_unsigned < string->len)
594 : 322 : memmove (string->str + pos_unsigned + len_unsigned,
595 : 241 : string->str + pos_unsigned, string->len - pos_unsigned);
596 : :
597 : : /* insert the new string */
598 : 152366 : if (len_unsigned == 1)
599 : 242 : string->str[pos_unsigned] = *val;
600 : : else
601 : 152124 : memcpy (string->str + pos_unsigned, val, len_unsigned);
602 : : }
603 : :
604 : 152368 : string->len += len_unsigned;
605 : :
606 : 152368 : string->str[string->len] = 0;
607 : :
608 : 152368 : return string;
609 : 75685 : }
610 : :
611 : : /**
612 : : * g_string_append_uri_escaped:
613 : : * @string: a #GString
614 : : * @unescaped: a string
615 : : * @reserved_chars_allowed: a string of reserved characters allowed
616 : : * to be used, or %NULL
617 : : * @allow_utf8: set %TRUE if the escaped string may include UTF8 characters
618 : : *
619 : : * Appends @unescaped to @string, escaping any characters that
620 : : * are reserved in URIs using URI-style escape sequences.
621 : : *
622 : : * Returns: (transfer none): @string
623 : : *
624 : : * Since: 2.16
625 : : */
626 : : GString *
627 : 4140 : g_string_append_uri_escaped (GString *string,
628 : : const gchar *unescaped,
629 : : const gchar *reserved_chars_allowed,
630 : : gboolean allow_utf8)
631 : : {
632 : 6164 : _uri_encoder (string, (const guchar *) unescaped, strlen (unescaped),
633 : 2024 : reserved_chars_allowed, allow_utf8);
634 : 4140 : return string;
635 : : }
636 : :
637 : : /**
638 : : * g_string_append:
639 : : * @string: a #GString
640 : : * @val: the string to append onto the end of @string
641 : : *
642 : : * Adds a string onto the end of a #GString, expanding
643 : : * it if necessary.
644 : : *
645 : : * Returns: (transfer none): @string
646 : : */
647 : : GString *
648 : 80 : (g_string_append) (GString *string,
649 : : const gchar *val)
650 : : {
651 : 80 : return g_string_insert_len (string, -1, val, -1);
652 : : }
653 : :
654 : : /**
655 : : * g_string_append_len:
656 : : * @string: a #GString
657 : : * @val: bytes to append
658 : : * @len: number of bytes of @val to use, or -1 for all of @val
659 : : *
660 : : * Appends @len bytes of @val to @string.
661 : : *
662 : : * If @len is positive, @val may contain embedded nuls and need
663 : : * not be nul-terminated. It is the caller's responsibility to
664 : : * ensure that @val has at least @len addressable bytes.
665 : : *
666 : : * If @len is negative, @val must be nul-terminated and @len
667 : : * is considered to request the entire string length. This
668 : : * makes g_string_append_len() equivalent to g_string_append().
669 : : *
670 : : * Returns: (transfer none): @string
671 : : */
672 : : GString *
673 : 220 : (g_string_append_len) (GString *string,
674 : : const gchar *val,
675 : : gssize len)
676 : : {
677 : 220 : return g_string_insert_len (string, -1, val, len);
678 : : }
679 : :
680 : : /**
681 : : * g_string_append_c:
682 : : * @string: a #GString
683 : : * @c: the byte to append onto the end of @string
684 : : *
685 : : * Adds a byte onto the end of a #GString, expanding
686 : : * it if necessary.
687 : : *
688 : : * Returns: (transfer none): @string
689 : : */
690 : : GString *
691 : 10018 : (g_string_append_c) (GString *string,
692 : : gchar c)
693 : : {
694 : 10018 : g_return_val_if_fail (string != NULL, NULL);
695 : :
696 : 10018 : return g_string_insert_c (string, -1, c);
697 : 5009 : }
698 : :
699 : : /**
700 : : * g_string_append_unichar:
701 : : * @string: a #GString
702 : : * @wc: a Unicode character
703 : : *
704 : : * Converts a Unicode character into UTF-8, and appends it
705 : : * to the string.
706 : : *
707 : : * Returns: (transfer none): @string
708 : : */
709 : : GString *
710 : 19919791 : g_string_append_unichar (GString *string,
711 : : gunichar wc)
712 : : {
713 : 19919791 : g_return_val_if_fail (string != NULL, NULL);
714 : :
715 : 19919791 : return g_string_insert_unichar (string, -1, wc);
716 : 12385401 : }
717 : :
718 : : /**
719 : : * g_string_prepend:
720 : : * @string: a #GString
721 : : * @val: the string to prepend on the start of @string
722 : : *
723 : : * Adds a string on to the start of a #GString,
724 : : * expanding it if necessary.
725 : : *
726 : : * Returns: (transfer none): @string
727 : : */
728 : : GString *
729 : 146 : g_string_prepend (GString *string,
730 : : const gchar *val)
731 : : {
732 : 146 : return g_string_insert_len (string, 0, val, -1);
733 : : }
734 : :
735 : : /**
736 : : * g_string_prepend_len:
737 : : * @string: a #GString
738 : : * @val: bytes to prepend
739 : : * @len: number of bytes in @val to prepend, or -1 for all of @val
740 : : *
741 : : * Prepends @len bytes of @val to @string.
742 : : *
743 : : * If @len is positive, @val may contain embedded nuls and need
744 : : * not be nul-terminated. It is the caller's responsibility to
745 : : * ensure that @val has at least @len addressable bytes.
746 : : *
747 : : * If @len is negative, @val must be nul-terminated and @len
748 : : * is considered to request the entire string length. This
749 : : * makes g_string_prepend_len() equivalent to g_string_prepend().
750 : : *
751 : : * Returns: (transfer none): @string
752 : : */
753 : : GString *
754 : 3 : g_string_prepend_len (GString *string,
755 : : const gchar *val,
756 : : gssize len)
757 : : {
758 : 3 : return g_string_insert_len (string, 0, val, len);
759 : : }
760 : :
761 : : /**
762 : : * g_string_prepend_c:
763 : : * @string: a #GString
764 : : * @c: the byte to prepend on the start of the #GString
765 : : *
766 : : * Adds a byte onto the start of a #GString,
767 : : * expanding it if necessary.
768 : : *
769 : : * Returns: (transfer none): @string
770 : : */
771 : : GString *
772 : 20013 : g_string_prepend_c (GString *string,
773 : : gchar c)
774 : : {
775 : 20013 : g_return_val_if_fail (string != NULL, NULL);
776 : :
777 : 20013 : return g_string_insert_c (string, 0, c);
778 : 10000 : }
779 : :
780 : : /**
781 : : * g_string_prepend_unichar:
782 : : * @string: a #GString
783 : : * @wc: a Unicode character
784 : : *
785 : : * Converts a Unicode character into UTF-8, and prepends it
786 : : * to the string.
787 : : *
788 : : * Returns: (transfer none): @string
789 : : */
790 : : GString *
791 : 80 : g_string_prepend_unichar (GString *string,
792 : : gunichar wc)
793 : : {
794 : 80 : g_return_val_if_fail (string != NULL, NULL);
795 : :
796 : 80 : return g_string_insert_unichar (string, 0, wc);
797 : 40 : }
798 : :
799 : : /**
800 : : * g_string_insert:
801 : : * @string: a #GString
802 : : * @pos: the position to insert the copy of the string
803 : : * @val: the string to insert
804 : : *
805 : : * Inserts a copy of a string into a #GString,
806 : : * expanding it if necessary.
807 : : *
808 : : * Returns: (transfer none): @string
809 : : */
810 : : GString *
811 : 11 : g_string_insert (GString *string,
812 : : gssize pos,
813 : : const gchar *val)
814 : : {
815 : 11 : return g_string_insert_len (string, pos, val, -1);
816 : : }
817 : :
818 : : /**
819 : : * g_string_insert_c:
820 : : * @string: a #GString
821 : : * @pos: the position to insert the byte
822 : : * @c: the byte to insert
823 : : *
824 : : * Inserts a byte into a #GString, expanding it if necessary.
825 : : *
826 : : * Returns: (transfer none): @string
827 : : */
828 : : GString *
829 : 34175 : g_string_insert_c (GString *string,
830 : : gssize pos,
831 : : gchar c)
832 : : {
833 : : gsize pos_unsigned;
834 : :
835 : 34175 : g_return_val_if_fail (string != NULL, NULL);
836 : :
837 : 34175 : g_string_maybe_expand (string, 1);
838 : :
839 : 34175 : if (pos < 0)
840 : 14162 : pos_unsigned = string->len;
841 : : else
842 : : {
843 : 20013 : pos_unsigned = pos;
844 : 20013 : g_return_val_if_fail (pos_unsigned <= string->len, string);
845 : : }
846 : :
847 : : /* If not just an append, move the old stuff */
848 : 34175 : if (pos_unsigned < string->len)
849 : 40013 : memmove (string->str + pos_unsigned + 1,
850 : 30013 : string->str + pos_unsigned, string->len - pos_unsigned);
851 : :
852 : 34175 : string->str[pos_unsigned] = c;
853 : :
854 : 34175 : string->len += 1;
855 : :
856 : 34175 : string->str[string->len] = 0;
857 : :
858 : 34175 : return string;
859 : 17077 : }
860 : :
861 : : /**
862 : : * g_string_insert_unichar:
863 : : * @string: a #GString
864 : : * @pos: the position at which to insert character, or -1
865 : : * to append at the end of the string
866 : : * @wc: a Unicode character
867 : : *
868 : : * Converts a Unicode character into UTF-8, and insert it
869 : : * into the string at the given position.
870 : : *
871 : : * Returns: (transfer none): @string
872 : : */
873 : : GString *
874 : 19919891 : g_string_insert_unichar (GString *string,
875 : : gssize pos,
876 : : gunichar wc)
877 : : {
878 : : gsize pos_unsigned;
879 : : gint charlen, first, i;
880 : : gchar *dest;
881 : :
882 : 19919891 : g_return_val_if_fail (string != NULL, NULL);
883 : :
884 : : /* Code copied from g_unichar_to_utf() */
885 : 19919891 : if (wc < 0x80)
886 : : {
887 : 19554632 : first = 0;
888 : 19554632 : charlen = 1;
889 : 12203071 : }
890 : 365259 : else if (wc < 0x800)
891 : : {
892 : 84035 : first = 0xc0;
893 : 84035 : charlen = 2;
894 : 42002 : }
895 : 281224 : else if (wc < 0x10000)
896 : : {
897 : 261056 : first = 0xe0;
898 : 261056 : charlen = 3;
899 : 130294 : }
900 : 20168 : else if (wc < 0x200000)
901 : : {
902 : 20168 : first = 0xf0;
903 : 20168 : charlen = 4;
904 : 10084 : }
905 : 0 : else if (wc < 0x4000000)
906 : : {
907 : 0 : first = 0xf8;
908 : 0 : charlen = 5;
909 : 0 : }
910 : : else
911 : : {
912 : 0 : first = 0xfc;
913 : 0 : charlen = 6;
914 : : }
915 : : /* End of copied code */
916 : :
917 : 19919891 : g_string_maybe_expand (string, charlen);
918 : :
919 : 19919891 : if (pos < 0)
920 : 19919803 : pos_unsigned = string->len;
921 : : else
922 : : {
923 : 88 : pos_unsigned = pos;
924 : 88 : g_return_val_if_fail (pos_unsigned <= string->len, string);
925 : : }
926 : :
927 : : /* If not just an append, move the old stuff */
928 : 19919891 : if (pos_unsigned < string->len)
929 : 88 : memmove (string->str + pos_unsigned + charlen, string->str + pos_unsigned, string->len - pos_unsigned);
930 : :
931 : 19919891 : dest = string->str + pos_unsigned;
932 : : /* Code copied from g_unichar_to_utf() */
933 : 20586542 : for (i = charlen - 1; i > 0; --i)
934 : : {
935 : 666651 : dest[i] = (wc & 0x3f) | 0x80;
936 : 666651 : wc >>= 6;
937 : 332842 : }
938 : 19919891 : dest[0] = wc | first;
939 : : /* End of copied code */
940 : :
941 : 19919891 : string->len += charlen;
942 : :
943 : 19919891 : string->str[string->len] = 0;
944 : :
945 : 19919891 : return string;
946 : 12385451 : }
947 : :
948 : : /**
949 : : * g_string_overwrite:
950 : : * @string: a #GString
951 : : * @pos: the position at which to start overwriting
952 : : * @val: the string that will overwrite the @string starting at @pos
953 : : *
954 : : * Overwrites part of a string, lengthening it if necessary.
955 : : *
956 : : * Returns: (transfer none): @string
957 : : *
958 : : * Since: 2.14
959 : : */
960 : : GString *
961 : 4 : g_string_overwrite (GString *string,
962 : : gsize pos,
963 : : const gchar *val)
964 : : {
965 : 4 : g_return_val_if_fail (val != NULL, string);
966 : 4 : return g_string_overwrite_len (string, pos, val, strlen (val));
967 : 2 : }
968 : :
969 : : /**
970 : : * g_string_overwrite_len:
971 : : * @string: a #GString
972 : : * @pos: the position at which to start overwriting
973 : : * @val: the string that will overwrite the @string starting at @pos
974 : : * @len: the number of bytes to write from @val
975 : : *
976 : : * Overwrites part of a string, lengthening it if necessary.
977 : : * This function will work with embedded nuls.
978 : : *
979 : : * Returns: (transfer none): @string
980 : : *
981 : : * Since: 2.14
982 : : */
983 : : GString *
984 : 157 : g_string_overwrite_len (GString *string,
985 : : gsize pos,
986 : : const gchar *val,
987 : : gssize len)
988 : : {
989 : : gsize len_unsigned;
990 : : gsize end;
991 : :
992 : 157 : g_return_val_if_fail (string != NULL, NULL);
993 : :
994 : 157 : if (!len)
995 : 2 : return string;
996 : :
997 : 155 : g_return_val_if_fail (val != NULL, string);
998 : 155 : g_return_val_if_fail (pos <= string->len, string);
999 : :
1000 : 155 : if (len < 0)
1001 : 2 : len_unsigned = strlen (val);
1002 : : else
1003 : 153 : len_unsigned = len;
1004 : :
1005 : 155 : end = pos + len_unsigned;
1006 : :
1007 : 155 : if (end > string->len)
1008 : 40 : g_string_maybe_expand (string, end - string->len);
1009 : :
1010 : 155 : memcpy (string->str + pos, val, len_unsigned);
1011 : :
1012 : 155 : if (end > string->len)
1013 : : {
1014 : 40 : string->str[end] = '\0';
1015 : 40 : string->len = end;
1016 : 15 : }
1017 : :
1018 : 155 : return string;
1019 : 78 : }
1020 : :
1021 : : /**
1022 : : * g_string_erase:
1023 : : * @string: a #GString
1024 : : * @pos: the position of the content to remove
1025 : : * @len: the number of bytes to remove, or -1 to remove all
1026 : : * following bytes
1027 : : *
1028 : : * Removes @len bytes from a #GString, starting at position @pos.
1029 : : * The rest of the #GString is shifted down to fill the gap.
1030 : : *
1031 : : * Returns: (transfer none): @string
1032 : : */
1033 : : GString *
1034 : 107547 : g_string_erase (GString *string,
1035 : : gssize pos,
1036 : : gssize len)
1037 : : {
1038 : : gsize len_unsigned, pos_unsigned;
1039 : :
1040 : 107547 : g_return_val_if_fail (string != NULL, NULL);
1041 : 107547 : g_return_val_if_fail (pos >= 0, string);
1042 : 107547 : pos_unsigned = pos;
1043 : :
1044 : 107547 : g_return_val_if_fail (pos_unsigned <= string->len, string);
1045 : :
1046 : 107547 : if (len < 0)
1047 : 60251 : len_unsigned = string->len - pos_unsigned;
1048 : : else
1049 : : {
1050 : 47296 : len_unsigned = len;
1051 : 47296 : g_return_val_if_fail (pos_unsigned + len_unsigned <= string->len, string);
1052 : :
1053 : 47296 : if (pos_unsigned + len_unsigned < string->len)
1054 : 102700 : memmove (string->str + pos_unsigned,
1055 : 61626 : string->str + pos_unsigned + len_unsigned,
1056 : 41089 : string->len - (pos_unsigned + len_unsigned));
1057 : : }
1058 : :
1059 : 107547 : string->len -= len_unsigned;
1060 : :
1061 : 107547 : string->str[string->len] = 0;
1062 : :
1063 : 107547 : return string;
1064 : 23622 : }
1065 : :
1066 : : /**
1067 : : * g_string_replace:
1068 : : * @string: a #GString
1069 : : * @find: the string to find in @string
1070 : : * @replace: the string to insert in place of @find
1071 : : * @limit: the maximum instances of @find to replace with @replace, or `0` for
1072 : : * no limit
1073 : : *
1074 : : * Replaces the string @find with the string @replace in a #GString up to
1075 : : * @limit times. If the number of instances of @find in the #GString is
1076 : : * less than @limit, all instances are replaced. If @limit is `0`,
1077 : : * all instances of @find are replaced.
1078 : : *
1079 : : * If @find is the empty string, since versions 2.69.1 and 2.68.4 the
1080 : : * replacement will be inserted no more than once per possible position
1081 : : * (beginning of string, end of string and between characters). This did
1082 : : * not work correctly in earlier versions.
1083 : : *
1084 : : * If @limit is zero and more than `G_MAXUINT` instances of @find are in
1085 : : * the input string, they will all be replaced, but the return value will
1086 : : * be capped at `G_MAXUINT`.
1087 : : *
1088 : : * Returns: the number of find and replace operations performed,
1089 : : * up to `G_MAXUINT`
1090 : : *
1091 : : * Since: 2.68
1092 : : */
1093 : : guint
1094 : 58 : g_string_replace (GString *string,
1095 : : const gchar *find,
1096 : : const gchar *replace,
1097 : : guint limit)
1098 : : {
1099 : 58 : GString *new_string = NULL;
1100 : : gsize f_len, r_len, new_len;
1101 : : gchar *cur, *next, *first, *dst;
1102 : : guint n;
1103 : :
1104 : 58 : g_return_val_if_fail (string != NULL, 0);
1105 : 58 : g_return_val_if_fail (find != NULL, 0);
1106 : 58 : g_return_val_if_fail (replace != NULL, 0);
1107 : :
1108 : 58 : first = strstr (string->str, find);
1109 : :
1110 : 58 : if (first == NULL)
1111 : 18 : return 0;
1112 : :
1113 : 40 : new_len = string->len;
1114 : 40 : f_len = strlen (find);
1115 : 40 : r_len = strlen (replace);
1116 : :
1117 : : /* It removes a lot of branches and possibility for infinite loops if we
1118 : : * handle the case of an empty @find string separately. */
1119 : 40 : if (G_UNLIKELY (f_len == 0))
1120 : : {
1121 : 18 : size_t r_limit = limit;
1122 : :
1123 : 18 : if (r_limit == 0 || r_limit > string->len)
1124 : : {
1125 : 12 : if (string->len > G_MAXSIZE - 1)
1126 : 0 : g_error ("inserting in every position in string would overflow");
1127 : :
1128 : 12 : r_limit = string->len + 1;
1129 : 6 : }
1130 : :
1131 : 26 : if (r_len > 0 &&
1132 : 16 : (r_limit > G_MAXSIZE / r_len ||
1133 : 16 : r_limit * r_len > G_MAXSIZE - string->len))
1134 : 0 : g_error ("inserting in every position in string would overflow");
1135 : :
1136 : 18 : new_len = string->len + r_limit * r_len;
1137 : 18 : new_string = g_string_sized_new (new_len);
1138 : 78 : for (size_t i = 0; i < r_limit; i++)
1139 : : {
1140 : 60 : g_string_append_len (new_string, replace, r_len);
1141 : 60 : if (i < string->len)
1142 : 48 : g_string_append_c (new_string, string->str[i]);
1143 : 30 : }
1144 : 18 : if (r_limit < string->len)
1145 : 4 : g_string_append_len (new_string, string->str + r_limit, string->len - r_limit);
1146 : :
1147 : 18 : g_free (string->str);
1148 : 18 : string->allocated_len = new_string->allocated_len;
1149 : 18 : string->len = new_string->len;
1150 : 18 : string->str = g_string_free_and_steal (g_steal_pointer (&new_string));
1151 : :
1152 : 18 : return r_limit > G_MAXUINT ? G_MAXUINT : (guint) r_limit;
1153 : : }
1154 : :
1155 : : /* Potentially do two passes: the first to calculate the length of the new string,
1156 : : * new_len, if it’s going to be longer than the original string; and the second to
1157 : : * do the replacements. The first pass is skipped if the new string is going to be
1158 : : * no longer than the original.
1159 : : *
1160 : : * The second pass calls various g_string_insert_len() (and similar) methods
1161 : : * which would normally potentially reallocate string->str, and hence
1162 : : * invalidate the cur/next/first/dst pointers. Because we’ve pre-calculated
1163 : : * the new_len and do all the string manipulations on new_string, that
1164 : : * shouldn’t happen. This means we scan `string` while modifying
1165 : : * `new_string`. */
1166 : 9 : do
1167 : : {
1168 : 32 : dst = first;
1169 : 32 : cur = first;
1170 : 32 : n = 0;
1171 : 116 : while ((next = strstr (cur, find)) != NULL)
1172 : : {
1173 : 86 : if (n < G_MAXUINT)
1174 : 86 : n++;
1175 : :
1176 : 86 : if (r_len <= f_len)
1177 : : {
1178 : 30 : memmove (dst, cur, next - cur);
1179 : 30 : dst += next - cur;
1180 : 30 : memcpy (dst, replace, r_len);
1181 : 30 : dst += r_len;
1182 : 14 : }
1183 : : else
1184 : : {
1185 : 56 : if (new_string == NULL)
1186 : : {
1187 : 28 : new_len += r_len - f_len;
1188 : 13 : }
1189 : : else
1190 : : {
1191 : 28 : g_string_append_len (new_string, cur, next - cur);
1192 : 28 : g_string_append_len (new_string, replace, r_len);
1193 : : }
1194 : : }
1195 : 86 : cur = next + f_len;
1196 : :
1197 : 86 : if (n == limit)
1198 : 2 : break;
1199 : : }
1200 : :
1201 : : /* Append the trailing characters from after the final instance of @find
1202 : : * in the input string. */
1203 : 32 : if (r_len <= f_len)
1204 : : {
1205 : : /* First pass skipped. */
1206 : 12 : gchar *end = string->str + string->len;
1207 : 12 : memmove (dst, cur, end - cur);
1208 : 12 : end = dst + (end - cur);
1209 : 12 : *end = 0;
1210 : 12 : string->len = end - string->str;
1211 : 12 : break;
1212 : : }
1213 : : else
1214 : : {
1215 : 20 : if (new_string == NULL)
1216 : : {
1217 : : /* First pass. */
1218 : 10 : new_string = g_string_sized_new (new_len);
1219 : 10 : g_string_append_len (new_string, string->str, first - string->str);
1220 : 4 : }
1221 : : else
1222 : : {
1223 : : /* Second pass. */
1224 : 10 : g_string_append_len (new_string, cur, (string->str + string->len) - cur);
1225 : 10 : g_free (string->str);
1226 : 10 : string->allocated_len = new_string->allocated_len;
1227 : 10 : string->len = new_string->len;
1228 : 10 : string->str = g_string_free_and_steal (g_steal_pointer (&new_string));
1229 : 10 : break;
1230 : : }
1231 : : }
1232 : 4 : }
1233 : : while (1);
1234 : :
1235 : 22 : return n;
1236 : 19 : }
1237 : :
1238 : : /**
1239 : : * g_string_ascii_down:
1240 : : * @string: a GString
1241 : : *
1242 : : * Converts all uppercase ASCII letters to lowercase ASCII letters.
1243 : : *
1244 : : * Returns: (transfer none): passed-in @string pointer, with all the
1245 : : * uppercase characters converted to lowercase in place,
1246 : : * with semantics that exactly match g_ascii_tolower().
1247 : : */
1248 : : GString *
1249 : 2 : g_string_ascii_down (GString *string)
1250 : : {
1251 : : gchar *s;
1252 : : gint n;
1253 : :
1254 : 2 : g_return_val_if_fail (string != NULL, NULL);
1255 : :
1256 : 2 : n = string->len;
1257 : 2 : s = string->str;
1258 : :
1259 : 42 : while (n)
1260 : : {
1261 : 40 : *s = g_ascii_tolower (*s);
1262 : 40 : s++;
1263 : 40 : n--;
1264 : : }
1265 : :
1266 : 2 : return string;
1267 : 1 : }
1268 : :
1269 : : /**
1270 : : * g_string_ascii_up:
1271 : : * @string: a GString
1272 : : *
1273 : : * Converts all lowercase ASCII letters to uppercase ASCII letters.
1274 : : *
1275 : : * Returns: (transfer none): passed-in @string pointer, with all the
1276 : : * lowercase characters converted to uppercase in place,
1277 : : * with semantics that exactly match g_ascii_toupper().
1278 : : */
1279 : : GString *
1280 : 2 : g_string_ascii_up (GString *string)
1281 : : {
1282 : : gchar *s;
1283 : : gint n;
1284 : :
1285 : 2 : g_return_val_if_fail (string != NULL, NULL);
1286 : :
1287 : 2 : n = string->len;
1288 : 2 : s = string->str;
1289 : :
1290 : 42 : while (n)
1291 : : {
1292 : 40 : *s = g_ascii_toupper (*s);
1293 : 40 : s++;
1294 : 40 : n--;
1295 : : }
1296 : :
1297 : 2 : return string;
1298 : 1 : }
1299 : :
1300 : : /**
1301 : : * g_string_down:
1302 : : * @string: a #GString
1303 : : *
1304 : : * Converts a #GString to lowercase.
1305 : : *
1306 : : * Returns: (transfer none): the #GString
1307 : : *
1308 : : * Deprecated:2.2: This function uses the locale-specific
1309 : : * tolower() function, which is almost never the right thing.
1310 : : * Use g_string_ascii_down() or g_utf8_strdown() instead.
1311 : : */
1312 : : GString *
1313 : 2 : g_string_down (GString *string)
1314 : : {
1315 : : guchar *s;
1316 : : glong n;
1317 : :
1318 : 2 : g_return_val_if_fail (string != NULL, NULL);
1319 : :
1320 : 2 : n = string->len;
1321 : 2 : s = (guchar *) string->str;
1322 : :
1323 : 42 : while (n)
1324 : : {
1325 : 40 : if (isupper (*s))
1326 : 6 : *s = tolower (*s);
1327 : 40 : s++;
1328 : 40 : n--;
1329 : : }
1330 : :
1331 : 2 : return string;
1332 : 1 : }
1333 : :
1334 : : /**
1335 : : * g_string_up:
1336 : : * @string: a #GString
1337 : : *
1338 : : * Converts a #GString to uppercase.
1339 : : *
1340 : : * Returns: (transfer none): @string
1341 : : *
1342 : : * Deprecated:2.2: This function uses the locale-specific
1343 : : * toupper() function, which is almost never the right thing.
1344 : : * Use g_string_ascii_up() or g_utf8_strup() instead.
1345 : : */
1346 : : GString *
1347 : 2 : g_string_up (GString *string)
1348 : : {
1349 : : guchar *s;
1350 : : glong n;
1351 : :
1352 : 2 : g_return_val_if_fail (string != NULL, NULL);
1353 : :
1354 : 2 : n = string->len;
1355 : 2 : s = (guchar *) string->str;
1356 : :
1357 : 42 : while (n)
1358 : : {
1359 : 40 : if (islower (*s))
1360 : 24 : *s = toupper (*s);
1361 : 40 : s++;
1362 : 40 : n--;
1363 : : }
1364 : :
1365 : 2 : return string;
1366 : 1 : }
1367 : :
1368 : : /**
1369 : : * g_string_append_vprintf:
1370 : : * @string: a #GString
1371 : : * @format: (not nullable): the string format. See the printf() documentation
1372 : : * @args: the list of arguments to insert in the output
1373 : : *
1374 : : * Appends a formatted string onto the end of a #GString.
1375 : : * This function is similar to g_string_append_printf()
1376 : : * except that the arguments to the format string are passed
1377 : : * as a va_list.
1378 : : *
1379 : : * Since: 2.14
1380 : : */
1381 : : void
1382 : 2388749 : g_string_append_vprintf (GString *string,
1383 : : const gchar *format,
1384 : : va_list args)
1385 : : {
1386 : : gchar *buf;
1387 : : gint len;
1388 : :
1389 : 2388749 : g_return_if_fail (string != NULL);
1390 : 2388749 : g_return_if_fail (format != NULL);
1391 : :
1392 : 2388749 : len = g_vasprintf (&buf, format, args);
1393 : :
1394 : 2388749 : if (len >= 0)
1395 : : {
1396 : 2388747 : g_string_maybe_expand (string, len);
1397 : 2388747 : memcpy (string->str + string->len, buf, (size_t) len + 1);
1398 : 2388747 : string->len += len;
1399 : 2388747 : g_free (buf);
1400 : 1719340 : }
1401 : : else
1402 : : {
1403 : 2 : g_critical ("Failed to append to string: invalid format/args passed to g_vasprintf()");
1404 : : }
1405 : 1719341 : }
1406 : :
1407 : : /**
1408 : : * g_string_vprintf:
1409 : : * @string: a #GString
1410 : : * @format: (not nullable): the string format. See the printf() documentation
1411 : : * @args: the parameters to insert into the format string
1412 : : *
1413 : : * Writes a formatted string into a #GString.
1414 : : * This function is similar to g_string_printf() except that
1415 : : * the arguments to the format string are passed as a va_list.
1416 : : *
1417 : : * Since: 2.14
1418 : : */
1419 : : void
1420 : 2 : g_string_vprintf (GString *string,
1421 : : const gchar *format,
1422 : : va_list args)
1423 : : {
1424 : 1 : g_string_truncate (string, 0);
1425 : 2 : g_string_append_vprintf (string, format, args);
1426 : 2 : }
1427 : :
1428 : : /**
1429 : : * g_string_sprintf:
1430 : : * @string: a #GString
1431 : : * @format: the string format. See the sprintf() documentation
1432 : : * @...: the parameters to insert into the format string
1433 : : *
1434 : : * Writes a formatted string into a #GString.
1435 : : * This is similar to the standard sprintf() function,
1436 : : * except that the #GString buffer automatically expands
1437 : : * to contain the results. The previous contents of the
1438 : : * #GString are destroyed.
1439 : : *
1440 : : * Deprecated: This function has been renamed to g_string_printf().
1441 : : */
1442 : :
1443 : : /**
1444 : : * g_string_printf:
1445 : : * @string: a #GString
1446 : : * @format: the string format. See the printf() documentation
1447 : : * @...: the parameters to insert into the format string
1448 : : *
1449 : : * Writes a formatted string into a #GString.
1450 : : * This is similar to the standard sprintf() function,
1451 : : * except that the #GString buffer automatically expands
1452 : : * to contain the results. The previous contents of the
1453 : : * #GString are destroyed.
1454 : : */
1455 : : void
1456 : 116 : g_string_printf (GString *string,
1457 : : const gchar *format,
1458 : : ...)
1459 : : {
1460 : : va_list args;
1461 : :
1462 : 58 : g_string_truncate (string, 0);
1463 : :
1464 : 116 : va_start (args, format);
1465 : 116 : g_string_append_vprintf (string, format, args);
1466 : 116 : va_end (args);
1467 : 116 : }
1468 : :
1469 : : /**
1470 : : * g_string_sprintfa:
1471 : : * @string: a #GString
1472 : : * @format: the string format. See the sprintf() documentation
1473 : : * @...: the parameters to insert into the format string
1474 : : *
1475 : : * Appends a formatted string onto the end of a #GString.
1476 : : * This function is similar to g_string_sprintf() except that
1477 : : * the text is appended to the #GString.
1478 : : *
1479 : : * Deprecated: This function has been renamed to g_string_append_printf()
1480 : : */
1481 : :
1482 : : /**
1483 : : * g_string_append_printf:
1484 : : * @string: a #GString
1485 : : * @format: the string format. See the printf() documentation
1486 : : * @...: the parameters to insert into the format string
1487 : : *
1488 : : * Appends a formatted string onto the end of a #GString.
1489 : : * This function is similar to g_string_printf() except
1490 : : * that the text is appended to the #GString.
1491 : : */
1492 : : void
1493 : 2388102 : g_string_append_printf (GString *string,
1494 : : const gchar *format,
1495 : : ...)
1496 : : {
1497 : : va_list args;
1498 : :
1499 : 2388102 : va_start (args, format);
1500 : 2388102 : g_string_append_vprintf (string, format, args);
1501 : 2388102 : va_end (args);
1502 : 2388102 : }
|