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