1 | /* GLIB - Library of useful routines for C programming |
---|
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
---|
3 | * |
---|
4 | * This library is free software; you can redistribute it and/or |
---|
5 | * modify it under the terms of the GNU Lesser General Public |
---|
6 | * License as published by the Free Software Foundation; either |
---|
7 | * version 2 of the License, or (at your option) any later version. |
---|
8 | * |
---|
9 | * This library is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
12 | * Lesser General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU Lesser General Public |
---|
15 | * License along with this library; if not, write to the |
---|
16 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
17 | * Boston, MA 02111-1307, USA. |
---|
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 | #ifdef HAVE_UNISTD_H |
---|
34 | #include <unistd.h> |
---|
35 | #endif |
---|
36 | #include <stdarg.h> |
---|
37 | #include <stdlib.h> |
---|
38 | #include <stdio.h> |
---|
39 | #include <string.h> |
---|
40 | #include <ctype.h> |
---|
41 | |
---|
42 | #include "glib.h" |
---|
43 | #include "gprintf.h" |
---|
44 | |
---|
45 | |
---|
46 | struct _GStringChunk |
---|
47 | { |
---|
48 | GHashTable *const_table; |
---|
49 | GSList *storage_list; |
---|
50 | gsize storage_next; |
---|
51 | gsize this_size; |
---|
52 | gsize default_size; |
---|
53 | }; |
---|
54 | |
---|
55 | G_LOCK_DEFINE_STATIC (string_mem_chunk); |
---|
56 | static GMemChunk *string_mem_chunk = NULL; |
---|
57 | |
---|
58 | /* Hash Functions. |
---|
59 | */ |
---|
60 | |
---|
61 | gboolean |
---|
62 | g_str_equal (gconstpointer v1, |
---|
63 | gconstpointer v2) |
---|
64 | { |
---|
65 | const gchar *string1 = v1; |
---|
66 | const gchar *string2 = v2; |
---|
67 | |
---|
68 | return strcmp (string1, string2) == 0; |
---|
69 | } |
---|
70 | |
---|
71 | /* 31 bit hash function */ |
---|
72 | guint |
---|
73 | g_str_hash (gconstpointer key) |
---|
74 | { |
---|
75 | const char *p = key; |
---|
76 | guint h = *p; |
---|
77 | |
---|
78 | if (h) |
---|
79 | for (p += 1; *p != '\0'; p++) |
---|
80 | h = (h << 5) - h + *p; |
---|
81 | |
---|
82 | return h; |
---|
83 | } |
---|
84 | |
---|
85 | #define MY_MAXSIZE ((gsize)-1) |
---|
86 | |
---|
87 | static inline gsize |
---|
88 | nearest_power (gsize base, gsize num) |
---|
89 | { |
---|
90 | if (num > MY_MAXSIZE / 2) |
---|
91 | { |
---|
92 | return MY_MAXSIZE; |
---|
93 | } |
---|
94 | else |
---|
95 | { |
---|
96 | gsize n = base; |
---|
97 | |
---|
98 | while (n < num) |
---|
99 | n <<= 1; |
---|
100 | |
---|
101 | return n; |
---|
102 | } |
---|
103 | } |
---|
104 | |
---|
105 | /* String Chunks. |
---|
106 | */ |
---|
107 | |
---|
108 | GStringChunk* |
---|
109 | g_string_chunk_new (gsize default_size) |
---|
110 | { |
---|
111 | GStringChunk *new_chunk = g_new (GStringChunk, 1); |
---|
112 | gsize size = 1; |
---|
113 | |
---|
114 | size = nearest_power (1, default_size); |
---|
115 | |
---|
116 | new_chunk->const_table = NULL; |
---|
117 | new_chunk->storage_list = NULL; |
---|
118 | new_chunk->storage_next = size; |
---|
119 | new_chunk->default_size = size; |
---|
120 | new_chunk->this_size = size; |
---|
121 | |
---|
122 | return new_chunk; |
---|
123 | } |
---|
124 | |
---|
125 | void |
---|
126 | g_string_chunk_free (GStringChunk *chunk) |
---|
127 | { |
---|
128 | GSList *tmp_list; |
---|
129 | |
---|
130 | g_return_if_fail (chunk != NULL); |
---|
131 | |
---|
132 | if (chunk->storage_list) |
---|
133 | { |
---|
134 | for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next) |
---|
135 | g_free (tmp_list->data); |
---|
136 | |
---|
137 | g_slist_free (chunk->storage_list); |
---|
138 | } |
---|
139 | |
---|
140 | if (chunk->const_table) |
---|
141 | g_hash_table_destroy (chunk->const_table); |
---|
142 | |
---|
143 | g_free (chunk); |
---|
144 | } |
---|
145 | |
---|
146 | gchar* |
---|
147 | g_string_chunk_insert (GStringChunk *chunk, |
---|
148 | const gchar *string) |
---|
149 | { |
---|
150 | g_return_val_if_fail (chunk != NULL, NULL); |
---|
151 | |
---|
152 | return g_string_chunk_insert_len (chunk, string, -1); |
---|
153 | } |
---|
154 | |
---|
155 | gchar* |
---|
156 | g_string_chunk_insert_const (GStringChunk *chunk, |
---|
157 | const gchar *string) |
---|
158 | { |
---|
159 | char* lookup; |
---|
160 | |
---|
161 | g_return_val_if_fail (chunk != NULL, NULL); |
---|
162 | |
---|
163 | if (!chunk->const_table) |
---|
164 | chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal); |
---|
165 | |
---|
166 | lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string); |
---|
167 | |
---|
168 | if (!lookup) |
---|
169 | { |
---|
170 | lookup = g_string_chunk_insert (chunk, string); |
---|
171 | g_hash_table_insert (chunk->const_table, lookup, lookup); |
---|
172 | } |
---|
173 | |
---|
174 | return lookup; |
---|
175 | } |
---|
176 | |
---|
177 | /** |
---|
178 | * g_string_chunk_insert_len: |
---|
179 | * @chunk: a #GStringChunk |
---|
180 | * @string: bytes to insert |
---|
181 | * @len: number of bytes of @string to insert, or -1 to insert a |
---|
182 | * nul-terminated string. |
---|
183 | * |
---|
184 | * Adds a copy of the first @len bytes of @string to the #GStringChunk. The |
---|
185 | * copy is nul-terminated. |
---|
186 | * |
---|
187 | * The characters in the string can be changed, if necessary, though you |
---|
188 | * should not change anything after the end of the string. |
---|
189 | * |
---|
190 | * Return value: a pointer to the copy of @string within the #GStringChunk |
---|
191 | * |
---|
192 | * Since: 2.4 |
---|
193 | **/ |
---|
194 | gchar* |
---|
195 | g_string_chunk_insert_len (GStringChunk *chunk, |
---|
196 | const gchar *string, |
---|
197 | gssize len) |
---|
198 | { |
---|
199 | gchar* pos; |
---|
200 | |
---|
201 | g_return_val_if_fail (chunk != NULL, NULL); |
---|
202 | |
---|
203 | if (len < 0) |
---|
204 | len = strlen (string); |
---|
205 | |
---|
206 | if ((chunk->storage_next + len + 1) > chunk->this_size) |
---|
207 | { |
---|
208 | gsize new_size = nearest_power (chunk->default_size, len + 1); |
---|
209 | |
---|
210 | chunk->storage_list = g_slist_prepend (chunk->storage_list, |
---|
211 | g_new (gchar, new_size)); |
---|
212 | |
---|
213 | chunk->this_size = new_size; |
---|
214 | chunk->storage_next = 0; |
---|
215 | } |
---|
216 | |
---|
217 | pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next; |
---|
218 | |
---|
219 | *(pos + len) = '\0'; |
---|
220 | |
---|
221 | strncpy (pos, string, len); |
---|
222 | len = strlen (pos); |
---|
223 | |
---|
224 | chunk->storage_next += len + 1; |
---|
225 | |
---|
226 | return pos; |
---|
227 | } |
---|
228 | |
---|
229 | /* Strings. |
---|
230 | */ |
---|
231 | static void |
---|
232 | g_string_maybe_expand (GString* string, |
---|
233 | gsize len) |
---|
234 | { |
---|
235 | if (string->len + len >= string->allocated_len) |
---|
236 | { |
---|
237 | string->allocated_len = nearest_power (1, string->len + len + 1); |
---|
238 | string->str = g_realloc (string->str, string->allocated_len); |
---|
239 | } |
---|
240 | } |
---|
241 | |
---|
242 | GString* |
---|
243 | g_string_sized_new (gsize dfl_size) |
---|
244 | { |
---|
245 | GString *string; |
---|
246 | |
---|
247 | G_LOCK (string_mem_chunk); |
---|
248 | if (!string_mem_chunk) |
---|
249 | string_mem_chunk = g_mem_chunk_new ("string mem chunk", |
---|
250 | sizeof (GString), |
---|
251 | 1024, G_ALLOC_AND_FREE); |
---|
252 | |
---|
253 | string = g_chunk_new (GString, string_mem_chunk); |
---|
254 | G_UNLOCK (string_mem_chunk); |
---|
255 | |
---|
256 | string->allocated_len = 0; |
---|
257 | string->len = 0; |
---|
258 | string->str = NULL; |
---|
259 | |
---|
260 | g_string_maybe_expand (string, MAX (dfl_size, 2)); |
---|
261 | string->str[0] = 0; |
---|
262 | |
---|
263 | return string; |
---|
264 | } |
---|
265 | |
---|
266 | GString* |
---|
267 | g_string_new (const gchar *init) |
---|
268 | { |
---|
269 | GString *string; |
---|
270 | |
---|
271 | if (init == NULL || *init == '\0') |
---|
272 | string = g_string_sized_new (2); |
---|
273 | else |
---|
274 | { |
---|
275 | gint len; |
---|
276 | |
---|
277 | len = strlen (init); |
---|
278 | string = g_string_sized_new (len + 2); |
---|
279 | |
---|
280 | g_string_append_len (string, init, len); |
---|
281 | } |
---|
282 | |
---|
283 | return string; |
---|
284 | } |
---|
285 | |
---|
286 | GString* |
---|
287 | g_string_new_len (const gchar *init, |
---|
288 | gssize len) |
---|
289 | { |
---|
290 | GString *string; |
---|
291 | |
---|
292 | if (len < 0) |
---|
293 | return g_string_new (init); |
---|
294 | else |
---|
295 | { |
---|
296 | string = g_string_sized_new (len); |
---|
297 | |
---|
298 | if (init) |
---|
299 | g_string_append_len (string, init, len); |
---|
300 | |
---|
301 | return string; |
---|
302 | } |
---|
303 | } |
---|
304 | |
---|
305 | gchar* |
---|
306 | g_string_free (GString *string, |
---|
307 | gboolean free_segment) |
---|
308 | { |
---|
309 | gchar *segment; |
---|
310 | |
---|
311 | g_return_val_if_fail (string != NULL, NULL); |
---|
312 | |
---|
313 | if (free_segment) |
---|
314 | { |
---|
315 | g_free (string->str); |
---|
316 | segment = NULL; |
---|
317 | } |
---|
318 | else |
---|
319 | segment = string->str; |
---|
320 | |
---|
321 | G_LOCK (string_mem_chunk); |
---|
322 | g_mem_chunk_free (string_mem_chunk, string); |
---|
323 | G_UNLOCK (string_mem_chunk); |
---|
324 | |
---|
325 | return segment; |
---|
326 | } |
---|
327 | |
---|
328 | gboolean |
---|
329 | g_string_equal (const GString *v, |
---|
330 | const GString *v2) |
---|
331 | { |
---|
332 | gchar *p, *q; |
---|
333 | GString *string1 = (GString *) v; |
---|
334 | GString *string2 = (GString *) v2; |
---|
335 | gsize i = string1->len; |
---|
336 | |
---|
337 | if (i != string2->len) |
---|
338 | return FALSE; |
---|
339 | |
---|
340 | p = string1->str; |
---|
341 | q = string2->str; |
---|
342 | while (i) |
---|
343 | { |
---|
344 | if (*p != *q) |
---|
345 | return FALSE; |
---|
346 | p++; |
---|
347 | q++; |
---|
348 | i--; |
---|
349 | } |
---|
350 | return TRUE; |
---|
351 | } |
---|
352 | |
---|
353 | /* 31 bit hash function */ |
---|
354 | guint |
---|
355 | g_string_hash (const GString *str) |
---|
356 | { |
---|
357 | const gchar *p = str->str; |
---|
358 | gsize n = str->len; |
---|
359 | guint h = 0; |
---|
360 | |
---|
361 | while (n--) |
---|
362 | { |
---|
363 | h = (h << 5) - h + *p; |
---|
364 | p++; |
---|
365 | } |
---|
366 | |
---|
367 | return h; |
---|
368 | } |
---|
369 | |
---|
370 | GString* |
---|
371 | g_string_assign (GString *string, |
---|
372 | const gchar *rval) |
---|
373 | { |
---|
374 | g_return_val_if_fail (string != NULL, NULL); |
---|
375 | g_return_val_if_fail (rval != NULL, string); |
---|
376 | |
---|
377 | /* Make sure assigning to itself doesn't corrupt the string. */ |
---|
378 | if (string->str != rval) |
---|
379 | { |
---|
380 | /* Assigning from substring should be ok since g_string_truncate |
---|
381 | does not realloc. */ |
---|
382 | g_string_truncate (string, 0); |
---|
383 | g_string_append (string, rval); |
---|
384 | } |
---|
385 | |
---|
386 | return string; |
---|
387 | } |
---|
388 | |
---|
389 | GString* |
---|
390 | g_string_truncate (GString *string, |
---|
391 | gsize len) |
---|
392 | { |
---|
393 | g_return_val_if_fail (string != NULL, NULL); |
---|
394 | |
---|
395 | string->len = MIN (len, string->len); |
---|
396 | string->str[string->len] = 0; |
---|
397 | |
---|
398 | return string; |
---|
399 | } |
---|
400 | |
---|
401 | /** |
---|
402 | * g_string_set_size: |
---|
403 | * @string: a #GString |
---|
404 | * @len: the new length |
---|
405 | * |
---|
406 | * Sets the length of a #GString. If the length is less than |
---|
407 | * the current length, the string will be truncated. If the |
---|
408 | * length is greater than the current length, the contents |
---|
409 | * of the newly added area are undefined. (However, as |
---|
410 | * always, string->str[string->len] will be a nul byte.) |
---|
411 | * |
---|
412 | * Return value: @string |
---|
413 | **/ |
---|
414 | GString* |
---|
415 | g_string_set_size (GString *string, |
---|
416 | gsize len) |
---|
417 | { |
---|
418 | g_return_val_if_fail (string != NULL, NULL); |
---|
419 | |
---|
420 | if (len >= string->allocated_len) |
---|
421 | g_string_maybe_expand (string, len - string->len); |
---|
422 | |
---|
423 | string->len = len; |
---|
424 | string->str[len] = 0; |
---|
425 | |
---|
426 | return string; |
---|
427 | } |
---|
428 | |
---|
429 | GString* |
---|
430 | g_string_insert_len (GString *string, |
---|
431 | gssize pos, |
---|
432 | const gchar *val, |
---|
433 | gssize len) |
---|
434 | { |
---|
435 | g_return_val_if_fail (string != NULL, NULL); |
---|
436 | g_return_val_if_fail (val != NULL, string); |
---|
437 | |
---|
438 | if (len < 0) |
---|
439 | len = strlen (val); |
---|
440 | |
---|
441 | if (pos < 0) |
---|
442 | pos = string->len; |
---|
443 | else |
---|
444 | g_return_val_if_fail (pos <= string->len, string); |
---|
445 | |
---|
446 | /* Check whether val represents a substring of string. This test |
---|
447 | probably violates chapter and verse of the C standards, since |
---|
448 | ">=" and "<=" are only valid when val really is a substring. |
---|
449 | In practice, it will work on modern archs. */ |
---|
450 | if (val >= string->str && val <= string->str + string->len) |
---|
451 | { |
---|
452 | gsize offset = val - string->str; |
---|
453 | gsize precount = 0; |
---|
454 | |
---|
455 | g_string_maybe_expand (string, len); |
---|
456 | val = string->str + offset; |
---|
457 | /* At this point, val is valid again. */ |
---|
458 | |
---|
459 | /* Open up space where we are going to insert. */ |
---|
460 | if (pos < string->len) |
---|
461 | g_memmove (string->str + pos + len, string->str + pos, string->len - pos); |
---|
462 | |
---|
463 | /* Move the source part before the gap, if any. */ |
---|
464 | if (offset < pos) |
---|
465 | { |
---|
466 | precount = MIN (len, pos - offset); |
---|
467 | memcpy (string->str + pos, val, precount); |
---|
468 | } |
---|
469 | |
---|
470 | /* Move the source part after the gap, if any. */ |
---|
471 | if (len > precount) |
---|
472 | memcpy (string->str + pos + precount, |
---|
473 | val + /* Already moved: */ precount + /* Space opened up: */ len, |
---|
474 | len - precount); |
---|
475 | } |
---|
476 | else |
---|
477 | { |
---|
478 | g_string_maybe_expand (string, len); |
---|
479 | |
---|
480 | /* If we aren't appending at the end, move a hunk |
---|
481 | * of the old string to the end, opening up space |
---|
482 | */ |
---|
483 | if (pos < string->len) |
---|
484 | g_memmove (string->str + pos + len, string->str + pos, string->len - pos); |
---|
485 | |
---|
486 | /* insert the new string */ |
---|
487 | memcpy (string->str + pos, val, len); |
---|
488 | } |
---|
489 | |
---|
490 | string->len += len; |
---|
491 | |
---|
492 | string->str[string->len] = 0; |
---|
493 | |
---|
494 | return string; |
---|
495 | } |
---|
496 | |
---|
497 | GString* |
---|
498 | g_string_append (GString *string, |
---|
499 | const gchar *val) |
---|
500 | { |
---|
501 | g_return_val_if_fail (string != NULL, NULL); |
---|
502 | g_return_val_if_fail (val != NULL, string); |
---|
503 | |
---|
504 | return g_string_insert_len (string, -1, val, -1); |
---|
505 | } |
---|
506 | |
---|
507 | GString* |
---|
508 | g_string_append_len (GString *string, |
---|
509 | const gchar *val, |
---|
510 | gssize len) |
---|
511 | { |
---|
512 | g_return_val_if_fail (string != NULL, NULL); |
---|
513 | g_return_val_if_fail (val != NULL, string); |
---|
514 | |
---|
515 | return g_string_insert_len (string, -1, val, len); |
---|
516 | } |
---|
517 | |
---|
518 | #undef g_string_append_c |
---|
519 | GString* |
---|
520 | g_string_append_c (GString *string, |
---|
521 | gchar c) |
---|
522 | { |
---|
523 | g_return_val_if_fail (string != NULL, NULL); |
---|
524 | |
---|
525 | return g_string_insert_c (string, -1, c); |
---|
526 | } |
---|
527 | |
---|
528 | /** |
---|
529 | * g_string_append_unichar: |
---|
530 | * @string: a #GString |
---|
531 | * @wc: a Unicode character |
---|
532 | * |
---|
533 | * Converts a Unicode character into UTF-8, and appends it |
---|
534 | * to the string. |
---|
535 | * |
---|
536 | * Return value: @string |
---|
537 | **/ |
---|
538 | GString* |
---|
539 | g_string_append_unichar (GString *string, |
---|
540 | gunichar wc) |
---|
541 | { |
---|
542 | g_return_val_if_fail (string != NULL, NULL); |
---|
543 | |
---|
544 | return g_string_insert_unichar (string, -1, wc); |
---|
545 | } |
---|
546 | |
---|
547 | GString* |
---|
548 | g_string_prepend (GString *string, |
---|
549 | const gchar *val) |
---|
550 | { |
---|
551 | g_return_val_if_fail (string != NULL, NULL); |
---|
552 | g_return_val_if_fail (val != NULL, string); |
---|
553 | |
---|
554 | return g_string_insert_len (string, 0, val, -1); |
---|
555 | } |
---|
556 | |
---|
557 | GString* |
---|
558 | g_string_prepend_len (GString *string, |
---|
559 | const gchar *val, |
---|
560 | gssize len) |
---|
561 | { |
---|
562 | g_return_val_if_fail (string != NULL, NULL); |
---|
563 | g_return_val_if_fail (val != NULL, string); |
---|
564 | |
---|
565 | return g_string_insert_len (string, 0, val, len); |
---|
566 | } |
---|
567 | |
---|
568 | GString* |
---|
569 | g_string_prepend_c (GString *string, |
---|
570 | gchar c) |
---|
571 | { |
---|
572 | g_return_val_if_fail (string != NULL, NULL); |
---|
573 | |
---|
574 | return g_string_insert_c (string, 0, c); |
---|
575 | } |
---|
576 | |
---|
577 | /** |
---|
578 | * g_string_prepend_unichar: |
---|
579 | * @string: a #GString. |
---|
580 | * @wc: a Unicode character. |
---|
581 | * |
---|
582 | * Converts a Unicode character into UTF-8, and prepends it |
---|
583 | * to the string. |
---|
584 | * |
---|
585 | * Return value: @string. |
---|
586 | **/ |
---|
587 | GString* |
---|
588 | g_string_prepend_unichar (GString *string, |
---|
589 | gunichar wc) |
---|
590 | { |
---|
591 | g_return_val_if_fail (string != NULL, NULL); |
---|
592 | |
---|
593 | return g_string_insert_unichar (string, 0, wc); |
---|
594 | } |
---|
595 | |
---|
596 | GString* |
---|
597 | g_string_insert (GString *string, |
---|
598 | gssize pos, |
---|
599 | const gchar *val) |
---|
600 | { |
---|
601 | g_return_val_if_fail (string != NULL, NULL); |
---|
602 | g_return_val_if_fail (val != NULL, string); |
---|
603 | if (pos >= 0) |
---|
604 | g_return_val_if_fail (pos <= string->len, string); |
---|
605 | |
---|
606 | return g_string_insert_len (string, pos, val, -1); |
---|
607 | } |
---|
608 | |
---|
609 | GString* |
---|
610 | g_string_insert_c (GString *string, |
---|
611 | gssize pos, |
---|
612 | gchar c) |
---|
613 | { |
---|
614 | g_return_val_if_fail (string != NULL, NULL); |
---|
615 | |
---|
616 | g_string_maybe_expand (string, 1); |
---|
617 | |
---|
618 | if (pos < 0) |
---|
619 | pos = string->len; |
---|
620 | else |
---|
621 | g_return_val_if_fail (pos <= string->len, string); |
---|
622 | |
---|
623 | /* If not just an append, move the old stuff */ |
---|
624 | if (pos < string->len) |
---|
625 | g_memmove (string->str + pos + 1, string->str + pos, string->len - pos); |
---|
626 | |
---|
627 | string->str[pos] = c; |
---|
628 | |
---|
629 | string->len += 1; |
---|
630 | |
---|
631 | string->str[string->len] = 0; |
---|
632 | |
---|
633 | return string; |
---|
634 | } |
---|
635 | |
---|
636 | /** |
---|
637 | * g_string_insert_unichar: |
---|
638 | * @string: a #GString |
---|
639 | * @pos: the position at which to insert character, or -1 to |
---|
640 | * append at the end of the string. |
---|
641 | * @wc: a Unicode character |
---|
642 | * |
---|
643 | * Converts a Unicode character into UTF-8, and insert it |
---|
644 | * into the string at the given position. |
---|
645 | * |
---|
646 | * Return value: @string |
---|
647 | **/ |
---|
648 | GString* |
---|
649 | g_string_insert_unichar (GString *string, |
---|
650 | gssize pos, |
---|
651 | gunichar wc) |
---|
652 | { |
---|
653 | gchar buf[6]; |
---|
654 | gint charlen; |
---|
655 | |
---|
656 | /* We could be somewhat more efficient here by computing |
---|
657 | * the length, adding the space, then converting into that |
---|
658 | * space, by cut-and-pasting the internals of g_unichar_to_utf8. |
---|
659 | */ |
---|
660 | g_return_val_if_fail (string != NULL, NULL); |
---|
661 | |
---|
662 | charlen = g_unichar_to_utf8 (wc, buf); |
---|
663 | return g_string_insert_len (string, pos, buf, charlen); |
---|
664 | } |
---|
665 | |
---|
666 | GString* |
---|
667 | g_string_erase (GString *string, |
---|
668 | gssize pos, |
---|
669 | gssize len) |
---|
670 | { |
---|
671 | g_return_val_if_fail (string != NULL, NULL); |
---|
672 | g_return_val_if_fail (pos >= 0, string); |
---|
673 | g_return_val_if_fail (pos <= string->len, string); |
---|
674 | |
---|
675 | if (len < 0) |
---|
676 | len = string->len - pos; |
---|
677 | else |
---|
678 | { |
---|
679 | g_return_val_if_fail (pos + len <= string->len, string); |
---|
680 | |
---|
681 | if (pos + len < string->len) |
---|
682 | g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len)); |
---|
683 | } |
---|
684 | |
---|
685 | string->len -= len; |
---|
686 | |
---|
687 | string->str[string->len] = 0; |
---|
688 | |
---|
689 | return string; |
---|
690 | } |
---|
691 | |
---|
692 | /** |
---|
693 | * g_string_ascii_down: |
---|
694 | * @string: a GString |
---|
695 | * |
---|
696 | * Converts all upper case ASCII letters to lower case ASCII letters. |
---|
697 | * |
---|
698 | * Return value: passed-in @string pointer, with all the upper case |
---|
699 | * characters converted to lower case in place, with |
---|
700 | * semantics that exactly match g_ascii_tolower. |
---|
701 | **/ |
---|
702 | GString* |
---|
703 | g_string_ascii_down (GString *string) |
---|
704 | { |
---|
705 | gchar *s; |
---|
706 | gint n; |
---|
707 | |
---|
708 | g_return_val_if_fail (string != NULL, NULL); |
---|
709 | |
---|
710 | n = string->len; |
---|
711 | s = string->str; |
---|
712 | |
---|
713 | while (n) |
---|
714 | { |
---|
715 | *s = g_ascii_tolower (*s); |
---|
716 | s++; |
---|
717 | n--; |
---|
718 | } |
---|
719 | |
---|
720 | return string; |
---|
721 | } |
---|
722 | |
---|
723 | /** |
---|
724 | * g_string_ascii_up: |
---|
725 | * @string: a GString |
---|
726 | * |
---|
727 | * Converts all lower case ASCII letters to upper case ASCII letters. |
---|
728 | * |
---|
729 | * Return value: passed-in @string pointer, with all the lower case |
---|
730 | * characters converted to upper case in place, with |
---|
731 | * semantics that exactly match g_ascii_toupper. |
---|
732 | **/ |
---|
733 | GString* |
---|
734 | g_string_ascii_up (GString *string) |
---|
735 | { |
---|
736 | gchar *s; |
---|
737 | gint n; |
---|
738 | |
---|
739 | g_return_val_if_fail (string != NULL, NULL); |
---|
740 | |
---|
741 | n = string->len; |
---|
742 | s = string->str; |
---|
743 | |
---|
744 | while (n) |
---|
745 | { |
---|
746 | *s = g_ascii_toupper (*s); |
---|
747 | s++; |
---|
748 | n--; |
---|
749 | } |
---|
750 | |
---|
751 | return string; |
---|
752 | } |
---|
753 | |
---|
754 | /** |
---|
755 | * g_string_down: |
---|
756 | * @string: a #GString |
---|
757 | * |
---|
758 | * Converts a #GString to lowercase. |
---|
759 | * |
---|
760 | * Returns: the #GString. |
---|
761 | * |
---|
762 | * Deprecated: This function uses the locale-specific tolower() function, |
---|
763 | * which is almost never the right thing. Use g_string_ascii_down() or |
---|
764 | * g_utf8_strdown() instead. |
---|
765 | */ |
---|
766 | GString* |
---|
767 | g_string_down (GString *string) |
---|
768 | { |
---|
769 | guchar *s; |
---|
770 | glong n; |
---|
771 | |
---|
772 | g_return_val_if_fail (string != NULL, NULL); |
---|
773 | |
---|
774 | n = string->len; |
---|
775 | s = (guchar *) string->str; |
---|
776 | |
---|
777 | while (n) |
---|
778 | { |
---|
779 | if (isupper (*s)) |
---|
780 | *s = tolower (*s); |
---|
781 | s++; |
---|
782 | n--; |
---|
783 | } |
---|
784 | |
---|
785 | return string; |
---|
786 | } |
---|
787 | |
---|
788 | /** |
---|
789 | * g_string_up: |
---|
790 | * @string: a #GString |
---|
791 | * |
---|
792 | * Converts a #GString to uppercase. |
---|
793 | * |
---|
794 | * Return value: the #GString |
---|
795 | * |
---|
796 | * Deprecated: This function uses the locale-specific toupper() function, |
---|
797 | * which is almost never the right thing. Use g_string_ascii_up() or |
---|
798 | * g_utf8_strup() instead. |
---|
799 | **/ |
---|
800 | GString* |
---|
801 | g_string_up (GString *string) |
---|
802 | { |
---|
803 | guchar *s; |
---|
804 | glong n; |
---|
805 | |
---|
806 | g_return_val_if_fail (string != NULL, NULL); |
---|
807 | |
---|
808 | n = string->len; |
---|
809 | s = (guchar *) string->str; |
---|
810 | |
---|
811 | while (n) |
---|
812 | { |
---|
813 | if (islower (*s)) |
---|
814 | *s = toupper (*s); |
---|
815 | s++; |
---|
816 | n--; |
---|
817 | } |
---|
818 | |
---|
819 | return string; |
---|
820 | } |
---|
821 | |
---|
822 | static void |
---|
823 | g_string_append_printf_internal (GString *string, |
---|
824 | const gchar *fmt, |
---|
825 | va_list args) |
---|
826 | { |
---|
827 | gchar *buffer; |
---|
828 | gint length; |
---|
829 | |
---|
830 | length = g_vasprintf (&buffer, fmt, args); |
---|
831 | g_string_append_len (string, buffer, length); |
---|
832 | g_free (buffer); |
---|
833 | } |
---|
834 | |
---|
835 | void |
---|
836 | g_string_printf (GString *string, |
---|
837 | const gchar *fmt, |
---|
838 | ...) |
---|
839 | { |
---|
840 | va_list args; |
---|
841 | |
---|
842 | g_string_truncate (string, 0); |
---|
843 | |
---|
844 | va_start (args, fmt); |
---|
845 | g_string_append_printf_internal (string, fmt, args); |
---|
846 | va_end (args); |
---|
847 | } |
---|
848 | |
---|
849 | void |
---|
850 | g_string_append_printf (GString *string, |
---|
851 | const gchar *fmt, |
---|
852 | ...) |
---|
853 | { |
---|
854 | va_list args; |
---|
855 | |
---|
856 | va_start (args, fmt); |
---|
857 | g_string_append_printf_internal (string, fmt, args); |
---|
858 | va_end (args); |
---|
859 | } |
---|