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