2006-08-17 Aaron Bockover <abockover@novell.com>
[mono.git] / eglib / src / gstr.c
1 /*
2  * gstr.c: String Utility Functions.
3  *
4  * Author:
5  *   Miguel de Icaza (miguel@novell.com)
6  *   Aaron Bockover (abockover@novell.com)
7  *
8  * (C) 2006 Novell, Inc.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining
11  * a copy of this software and associated documentation files (the
12  * "Software"), to deal in the Software without restriction, including
13  * without limitation the rights to use, copy, modify, merge, publish,
14  * distribute, sublicense, and/or sell copies of the Software, and to
15  * permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be
19  * included in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  */
29 #define _GNU_SOURCE
30 #include <stdio.h>
31 #include <string.h>
32 #include <glib.h>
33
34 /* This is not a macro, because I dont want to put _GNU_SOURCE in the glib.h header */
35 gchar *
36 g_strndup (const gchar *str, gsize n)
37 {
38         return strndup (str, n);
39 }
40
41 void
42 g_strfreev (gchar **str_array)
43 {
44         gchar **orig = str_array;
45         if (str_array == NULL)
46                 return;
47         while (*str_array != NULL){
48                 g_free (*str_array);
49                 str_array++;
50         }
51         g_free (orig);
52 }
53
54 gint
55 g_strv_length(gchar **str_array)
56 {
57         gint length = 0;
58         g_return_val_if_fail(str_array != NULL, 0);
59         for(length = 0; str_array[length] != NULL; length++);
60         return length;
61 }
62
63 gboolean
64 g_str_has_suffix(const gchar *str, const gchar *suffix)
65 {
66         gint str_length;
67         gint suffix_length;
68         
69         g_return_val_if_fail(str != NULL, FALSE);
70         g_return_val_if_fail(suffix != NULL, FALSE);
71
72         str_length = strlen(str);
73         suffix_length = strlen(suffix);
74
75         return suffix_length <= str_length ?
76                 strncmp(str + str_length - suffix_length, suffix, suffix_length) == 0 :
77                 FALSE;
78 }
79
80 gboolean
81 g_str_has_prefix(const gchar *str, const gchar *prefix)
82 {
83         gint str_length;
84         gint prefix_length;
85         
86         g_return_val_if_fail(str != NULL, FALSE);
87         g_return_val_if_fail(prefix != NULL, FALSE);
88
89         str_length = strlen(str);
90         prefix_length = strlen(prefix);
91
92         return prefix_length <= str_length ?
93                 strncmp(str, prefix, prefix_length) == 0 :
94                 FALSE;
95 }
96
97 gchar *
98 g_strdup_vprintf (const gchar *format, va_list args)
99 {
100         int n;
101         char *ret;
102         
103         n = vasprintf (&ret, format, args);
104         if (n == -1)
105                 return NULL;
106
107         return ret;
108 }
109
110 gchar *
111 g_strdup_printf (const gchar *format, ...)
112 {
113         gchar *ret;
114         va_list args;
115         int n;
116
117         va_start (args, format);
118         n = vasprintf (&ret, format, args);
119         va_end (args);
120         if (n == -1)
121                 return NULL;
122
123         return ret;
124 }
125
126 const gchar *
127 g_strerror (gint errnum)
128 {
129         return strerror (errnum);
130 }
131
132 gchar *
133 g_strconcat (const gchar *first, ...)
134 {
135         g_return_val_if_fail (first != NULL, NULL);
136         va_list args;
137         int total = 0;
138         char *s, *ret;
139
140         total += strlen (first);
141         va_start (args, first);
142         for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){
143                 total += strlen (s);
144         }
145         va_end (args);
146         
147         ret = g_malloc (total + 1);
148         if (ret == NULL)
149                 return NULL;
150
151         ret [total] = 0;
152         strcpy (ret, first);
153         va_start (args, first);
154         for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){
155                 strcat (ret, s);
156         }
157         va_end (args);
158
159         return ret;
160 }
161
162 gchar ** 
163 g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens)
164 {
165         gchar *string_c;
166         gchar *strtok_save, **vector;
167         gchar *token, *token_c;
168         gint size = 1;
169         gint token_length;
170
171         g_return_val_if_fail(string != NULL, NULL);
172         g_return_val_if_fail(delimiter != NULL, NULL);
173         g_return_val_if_fail(delimiter[0] != '\0', NULL);
174         
175         token_length = strlen(string);
176         string_c = (gchar *)g_malloc(token_length + 1);
177         strncpy(string_c, string, token_length);
178         string_c[token_length] = '\0';
179         
180         vector = NULL;
181         token = (gchar *)strtok_r(string_c, delimiter, &strtok_save);
182         
183         while(token != NULL) {
184                 token_length = strlen(token);
185                 token_c = (gchar *)g_malloc(token_length + 1);
186                 strncpy(token_c, token, token_length);
187                 token_c[token_length] = '\0';
188
189                 vector = vector == NULL ? 
190                         (gchar **)g_malloc(sizeof(vector)) :
191                         (gchar **)g_realloc(vector, (size + 1) * sizeof(vector));
192         
193                 vector[size - 1] = token_c;     
194                 size++;
195
196                 if(max_tokens > 0 && size >= max_tokens) {
197                         if(size > max_tokens) {
198                                 break;
199                         }
200
201                         token = strtok_save;
202                 } else {
203                         token = (gchar *)strtok_r(NULL, delimiter, &strtok_save);
204                 }
205         }
206
207         vector[size - 1] = NULL;
208         g_free(string_c);
209         string_c = NULL;
210
211         return vector;
212 }
213
214 gchar *
215 g_strreverse (gchar *str)
216 {
217         guint len, half;
218         gint i;
219         gchar c;
220
221         if (str == NULL)
222                 return NULL;
223
224         len = strlen (str);
225         half = len / 2;
226         len--;
227         for (i = 0; i < half; i++, len--) {
228                 c = str [i];
229                 str [i] = str [len];
230                 str [len] = c;
231         }
232         return str;
233 }
234