X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=eglib%2Fsrc%2Fgstr.c;h=3e976c5a2edfe3019a294daad9f45d355f7da250;hb=ba3384aa88a389c308d8258e4ae66caaa2856221;hp=3990eadc1da8d4e7de6fefc7ba71b0da1924c88e;hpb=74db08912cbfea72d3d117858ad019e825cdf5f8;p=mono.git diff --git a/eglib/src/gstr.c b/eglib/src/gstr.c index 3990eadc1da..3e976c5a2ed 100644 --- a/eglib/src/gstr.c +++ b/eglib/src/gstr.c @@ -32,6 +32,8 @@ #include #include +#include "vasprintf.h" + /* This is not a macro, because I dont want to put _GNU_SOURCE in the glib.h header */ gchar * g_strndup (const gchar *str, gsize n) @@ -40,7 +42,7 @@ g_strndup (const gchar *str, gsize n) return strndup (str, n); #else if (str) { - char *retval = malloc(n+1); + char *retval = g_malloc(n+1); if (retval) { strncpy(retval, str, n)[n] = 0; } @@ -63,6 +65,25 @@ g_strfreev (gchar **str_array) g_free (orig); } +gchar ** +g_strdupv (gchar **str_array) +{ + guint length; + gchar **ret; + guint i; + + if (!str_array) + return NULL; + + length = g_strv_length(str_array); + ret = g_new0(gchar *, length + 1); + for (i = 0; str_array[i]; i++) { + ret[i] = g_strdup(str_array[i]); + } + ret[length] = NULL; + return ret; +} + guint g_strv_length(gchar **str_array) { @@ -171,89 +192,186 @@ g_strconcat (const gchar *first, ...) return ret; } +static void +add_to_vector (gchar ***vector, int size, gchar *token) +{ + *vector = *vector == NULL ? + (gchar **)g_malloc(2 * sizeof(*vector)) : + (gchar **)g_realloc(*vector, (size + 1) * sizeof(*vector)); + + (*vector)[size - 1] = token; +} + gchar ** g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens) { - gchar *string_c; - gchar *strtok_save, **vector; - gchar *token, *token_c; + const gchar *c; + gchar *token, **vector; gint size = 1; - size_t token_length; - - g_return_val_if_fail(string != NULL, NULL); - g_return_val_if_fail(delimiter != NULL, NULL); - g_return_val_if_fail(delimiter[0] != 0, NULL); - token_length = strlen(string); - string_c = (gchar *)g_malloc(token_length + 1); - memcpy(string_c, string, token_length); - string_c[token_length] = 0; + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiter != NULL, NULL); + g_return_val_if_fail (delimiter[0] != 0, NULL); + + if (strncmp (string, delimiter, strlen (delimiter)) == 0) { + vector = (gchar **)g_malloc (2 * sizeof(vector)); + vector[0] = g_strdup (""); + size++; + string += strlen (delimiter); + } else { + vector = NULL; + } + + while (*string && !(max_tokens > 0 && size >= max_tokens)) { + c = string; + if (strncmp (string, delimiter, strlen (delimiter)) == 0) { + token = g_strdup (""); + string += strlen (delimiter); + } else { + while (*string && strncmp (string, delimiter, strlen (delimiter)) != 0) { + string++; + } + + if (*string) { + gsize toklen = (string - c); + token = g_strndup (c, toklen); + + /* Need to leave a trailing empty + * token if the delimiter is the last + * part of the string + */ + if (strcmp (string, delimiter) != 0) { + string += strlen (delimiter); + } + } else { + token = g_strdup (c); + } + } + + add_to_vector (&vector, size, token); + size++; + } - if (strncmp (string_c, delimiter, strlen (delimiter)) == 0){ + if (*string) { + if (strcmp (string, delimiter) == 0) + add_to_vector (&vector, size, g_strdup ("")); + else { + /* Add the rest of the string as the last element */ + add_to_vector (&vector, size, g_strdup (string)); + } + size++; + } + + if (vector == NULL) { vector = (gchar **) g_malloc (2 * sizeof (vector)); - vector [0] = g_strdup (""); + vector [0] = NULL; + } else if (size > 0) { + vector[size - 1] = NULL; + } + + return vector; +} + +static gboolean +charcmp (gchar testchar, const gchar *compare) +{ + while(*compare) { + if (*compare == testchar) { + return TRUE; + } + compare++; + } + + return FALSE; +} + +gchar ** +g_strsplit_set (const gchar *string, const gchar *delimiter, gint max_tokens) +{ + const gchar *c; + gchar *token, **vector; + gint size = 1; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiter != NULL, NULL); + g_return_val_if_fail (delimiter[0] != 0, NULL); + + if (charcmp (*string, delimiter)) { + vector = (gchar **)g_malloc (2 * sizeof(vector)); + vector[0] = g_strdup (""); size++; - } else + string++; + } else { vector = NULL; - token = (gchar *)strtok_r(string_c, delimiter, &strtok_save); - - if (!(max_tokens > 0 && size >= max_tokens)){ - while(token != NULL) { - token_length = strlen(token); - token_c = (gchar *)g_malloc(token_length + 1); - memcpy(token_c, token, token_length); - token_c[token_length] = 0; + } + + c = string; + while (*string && !(max_tokens > 0 && size >= max_tokens)) { + if (charcmp (*string, delimiter)) { + gsize toklen = (string - c); + if (toklen == 0) { + token = g_strdup (""); + } else { + token = g_strndup (c, toklen); + } - vector = vector == NULL ? - (gchar **)g_malloc(2 * sizeof(vector)) : - (gchar **)g_realloc(vector, (size + 1) * sizeof(vector)); + c = string + 1; - vector[size - 1] = token_c; + add_to_vector (&vector, size, token); + size++; + } + + string++; + } + + if (max_tokens > 0 && size >= max_tokens) { + if (*string) { + /* Add the rest of the string as the last element */ + add_to_vector (&vector, size, g_strdup (string)); + size++; + } + } else { + if (*c) { + /* Fill in the trailing last token */ + add_to_vector (&vector, size, g_strdup (c)); + size++; + } else { + /* Need to leave a trailing empty token if the + * delimiter is the last part of the string + */ + add_to_vector (&vector, size, g_strdup ("")); size++; - - if(max_tokens > 0 && size >= max_tokens) { - if(size > max_tokens) { - break; - } - - token = *strtok_save ? strtok_save : NULL; - } else { - token = (gchar *)strtok_r(NULL, delimiter, &strtok_save); - } } } - if (vector == NULL){ + if (vector == NULL) { vector = (gchar **) g_malloc (2 * sizeof (vector)); vector [0] = NULL; - } else if (size > 0){ + } else if (size > 0) { vector[size - 1] = NULL; } - g_free(string_c); - string_c = NULL; - return vector; } gchar * g_strreverse (gchar *str) { - size_t len, half; - size_t i; + size_t i, j; gchar c; if (str == NULL) return NULL; - len = strlen (str); - half = len / 2; - len--; - for (i = 0; i < half; i++, len--) { + if (*str == 0) + return str; + + for (i = 0, j = strlen (str) - 1; i < j; i++, j--) { c = str [i]; - str [i] = str [len]; - str [len] = c; + str [i] = str [j]; + str [j] = c; } + return str; } @@ -261,13 +379,14 @@ gchar * g_strjoin (const gchar *separator, ...) { va_list args; - char *res, *s; + char *res, *s, *r; size_t len, slen; if (separator != NULL) slen = strlen (separator); else slen = 0; + len = 0; va_start (args, separator); for (s = va_arg (args, char *); s != NULL; s = va_arg (args, char *)){ @@ -275,21 +394,22 @@ g_strjoin (const gchar *separator, ...) len += slen; } va_end (args); + if (len == 0) return g_strdup (""); /* Remove the last separator */ if (slen > 0 && len > 0) len -= slen; - len++; - res = g_malloc (len); + + res = g_malloc (len + 1); va_start (args, separator); s = va_arg (args, char *); - strcpy (res, s); + r = g_stpcpy (res, s); for (s = va_arg (args, char *); s != NULL; s = va_arg (args, char *)){ if (separator != NULL) - strcat (res, separator); - strcat (res, s); + r = g_stpcpy (r, separator); + r = g_stpcpy (r, s); } va_end (args); @@ -299,7 +419,7 @@ g_strjoin (const gchar *separator, ...) gchar * g_strjoinv (const gchar *separator, gchar **str_array) { - char *res; + char *res, *r; size_t slen, len, i; if (separator != NULL) @@ -312,18 +432,21 @@ g_strjoinv (const gchar *separator, gchar **str_array) len += strlen (str_array [i]); len += slen; } + if (len == 0) return g_strdup (""); + if (slen > 0 && len > 0) len -= slen; - len++; - res = g_malloc (len); - strcpy (res, str_array [0]); + + res = g_malloc (len + 1); + r = g_stpcpy (res, str_array [0]); for (i = 1; str_array [i] != NULL; i++){ if (separator != NULL) - strcat (res, separator); - strcat (res, str_array [i]); + r = g_stpcpy (r, separator); + r = g_stpcpy (r, str_array [i]); } + return res; } @@ -434,29 +557,46 @@ g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error) size_t n; char *ret, *rp; const char *p; +#ifdef G_OS_WIN32 + const char *uriPrefix = "file:///"; +#else + const char *uriPrefix = "file://"; +#endif g_return_val_if_fail (filename != NULL, NULL); if (hostname != NULL) g_warning ("%s", "eglib: g_filename_to_uri: hostname not handled"); - if (*filename != '/'){ + if (!g_path_is_absolute (filename)){ if (error != NULL) *error = g_error_new (NULL, 2, "Not an absolute filename"); return NULL; } - n = strlen ("file://") + 1; + n = strlen (uriPrefix) + 1; for (p = filename; *p; p++){ +#ifdef G_OS_WIN32 + if (*p == '\\') { + n++; + continue; + } +#endif if (char_needs_encoding (*p)) n += 3; else n++; } ret = g_malloc (n); - strcpy (ret, "file://"); + strcpy (ret, uriPrefix); for (p = filename, rp = ret + strlen (ret); *p; p++){ +#ifdef G_OS_WIN32 + if (*p == '\\') { + *rp++ = '/'; + continue; + } +#endif if (char_needs_encoding (*p)){ *rp++ = '%'; *rp++ = hx [((unsigned char)(*p)) >> 4]; @@ -511,13 +651,21 @@ g_filename_from_uri (const gchar *uri, gchar **hostname, GError **error) } flen++; } +#ifndef G_OS_WIN32 flen++; - +#endif + result = g_malloc (flen + 1); - *result = '/'; result [flen] = 0; - for (p = uri + 8, r = result + 1; *p; p++){ +#ifndef G_OS_WIN32 + *result = '/'; + r = result + 1; +#else + r = result; +#endif + + for (p = uri + 8; *p; p++){ if (*p == '%'){ *r++ = (char)((decode (p [1]) << 4) | decode (p [2])); p += 2; @@ -539,6 +687,12 @@ g_strdown (gchar *string) } } +gchar +g_ascii_tolower (gchar c) +{ + return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; +} + gchar * g_ascii_strdown (const gchar *str, gssize len) { @@ -551,12 +705,33 @@ g_ascii_strdown (const gchar *str, gssize len) len = strlen (str); ret = g_malloc (len + 1); - for (i = 0; i < len; i++){ - guchar c = (guchar) str [i]; - if (c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - ret [i] = c; - } + for (i = 0; i < len; i++) + ret [i] = (guchar) g_ascii_tolower (str [i]); + ret [i] = 0; + + return ret; +} + +gchar +g_ascii_toupper (gchar c) +{ + return c >= 'a' && c <= 'z' ? c + ('A' - 'a') : c; +} + +gchar * +g_ascii_strup (const gchar *str, gssize len) +{ + char *ret; + int i; + + g_return_val_if_fail (str != NULL, NULL); + + if (len == -1) + len = strlen (str); + + ret = g_malloc (len + 1); + for (i = 0; i < len; i++) + ret [i] = (guchar) g_ascii_toupper (str [i]); ret [i] = 0; return ret; @@ -570,22 +745,37 @@ g_ascii_strncasecmp (const gchar *s1, const gchar *s2, gsize n) g_return_val_if_fail (s1 != NULL, 0); g_return_val_if_fail (s2 != NULL, 0); - for (i = 0; i < n; i++){ - gchar c1 = *s1++; - gchar c2 = *s2++; + for (i = 0; i < n; i++) { + gchar c1 = g_ascii_tolower (*s1++); + gchar c2 = g_ascii_tolower (*s2++); - if (c1 == c2) - continue; - - if (c1 == 0) - return -1; - if (c2 == 0) - return 1; - return c1-c2; + if (c1 != c2) + return c1 - c2; } + return 0; } +gint +g_ascii_strcasecmp (const gchar *s1, const gchar *s2) +{ + const char *sp1 = s1; + const char *sp2 = s2; + + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + while (*sp1 != '\0') { + char c1 = g_ascii_tolower (*sp1++); + char c2 = g_ascii_tolower (*sp2++); + + if (c1 != c2) + return c1 - c2; + } + + return (*sp1) - (*sp2); +} + gchar * g_strdelimit (gchar *string, const gchar *delimiters, gchar new_delimiter) { @@ -639,6 +829,24 @@ g_strlcpy (gchar *dest, const gchar *src, gsize dest_size) #endif } +gchar * +g_stpcpy (gchar *dest, const char *src) +{ + g_return_val_if_fail (dest != NULL, dest); + g_return_val_if_fail (src != NULL, dest); + +#if HAVE_STPCPY + return stpcpy (dest, src); +#else + while (*src) + *dest++ = *src++; + + *dest = '\0'; + + return dest; +#endif +} + static const gchar escaped_dflt [256] = { 1, 1, 1, 1, 1, 1, 1, 1, 'b', 't', 'n', 1, 'f', 'r', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -697,15 +905,6 @@ g_strescape (const gchar *source, const gchar *exceptions) return result; } -gchar * -g_strdup (const gchar *str) -{ - if (str == NULL) - return NULL; - - return strdup (str); -} - gint g_ascii_xdigit_value (gchar c) { @@ -715,5 +914,12 @@ g_ascii_xdigit_value (gchar c) (c - 'A' + 10)))); } +gchar * +g_strnfill (gsize length, gchar fill_char) +{ + gchar *ret = g_new (gchar, length + 1); - + memset (ret, fill_char, length); + ret [length] = 0; + return ret; +}