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