2006-08-16 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 gchar *
55 g_strdup_printf (const gchar *format, ...)
56 {
57         gchar *ret;
58         va_list args;
59         int n;
60
61         va_start (args, format);
62         n = vasprintf (&ret, format, args);
63         va_end (args);
64         if (n == -1)
65                 return NULL;
66
67         return ret;
68 }
69
70 const gchar *
71 g_strerror (gint errnum)
72 {
73         return strerror (errnum);
74 }
75
76 gchar *
77 g_strconcat (const gchar *first, ...)
78 {
79         g_return_val_if_fail (first != NULL, NULL);
80         va_list args;
81         int total = 0;
82         char *s, *ret;
83
84         total += strlen (first);
85         va_start (args, first);
86         for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){
87                 total += strlen (s);
88         }
89         va_end (args);
90         
91         ret = g_malloc (total + 1);
92         if (ret == NULL)
93                 return NULL;
94
95         ret [total] = 0;
96         strcpy (ret, first);
97         va_start (args, first);
98         for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){
99                 strcat (ret, s);
100         }
101         va_end (args);
102
103         return ret;
104 }
105
106 gchar ** 
107 g_strsplit(const gchar *string, const gchar *delimiter, gint max_tokens)
108 {
109         gchar *string_c;
110         gchar *strtok_save, **vector;
111         gchar *token, *token_c;
112         gint size = 1;
113         gint token_length;
114
115         g_return_val_if_fail(string != NULL, NULL);
116         g_return_val_if_fail(delimiter != NULL, NULL);
117         g_return_val_if_fail(delimiter[0] != '\0', NULL);
118         
119         token_length = strlen(string);
120         string_c = (gchar *)g_malloc(token_length + 1);
121         strncpy(string_c, string, token_length);
122         string_c[token_length] = '\0';
123         
124         vector = NULL;
125         token = (gchar *)strtok_r(string_c, delimiter, &strtok_save);
126         
127         while(token != NULL) {
128                 token_length = strlen(token);
129                 token_c = (gchar *)malloc(token_length + 1);
130                 strncpy(token_c, token, token_length);
131                 token_c[token_length] = '\0';
132
133                 vector = vector == NULL ? 
134                         (gchar **)g_malloc(sizeof(vector)) :
135                         (gchar **)g_realloc(vector, (size + 1) * sizeof(vector));
136         
137                 vector[size - 1] = token_c;     
138                 size++;
139
140                 if(max_tokens > 0 && size >= max_tokens) {
141                         if(size > max_tokens) {
142                                 break;
143                         }
144
145                         token = strtok_save;
146                 } else {
147                         token = (gchar *)strtok_r(NULL, delimiter, &strtok_save);
148                 }
149         }
150
151         vector[size - 1] = NULL;
152         g_free(string_c);
153         string_c = NULL;
154
155         return vector;
156 }
157