Coverage Report

Created: 2025-12-08 06:11

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