Coverage Report

Created: 2025-09-27 07:14

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