#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include <glib.h>
/* This is not a macro, because I dont want to put _GNU_SOURCE in the glib.h header */
g_free (orig);
}
+guint
+g_strv_length(gchar **str_array)
+{
+ gint length = 0;
+ g_return_val_if_fail(str_array != NULL, 0);
+ for(length = 0; str_array[length] != NULL; length++);
+ return length;
+}
+
+gboolean
+g_str_has_suffix(const gchar *str, const gchar *suffix)
+{
+ gint str_length;
+ gint suffix_length;
+
+ g_return_val_if_fail(str != NULL, FALSE);
+ g_return_val_if_fail(suffix != NULL, FALSE);
+
+ str_length = strlen(str);
+ suffix_length = strlen(suffix);
+
+ return suffix_length <= str_length ?
+ strncmp(str + str_length - suffix_length, suffix, suffix_length) == 0 :
+ FALSE;
+}
+
+gboolean
+g_str_has_prefix(const gchar *str, const gchar *prefix)
+{
+ gint str_length;
+ gint prefix_length;
+
+ g_return_val_if_fail(str != NULL, FALSE);
+ g_return_val_if_fail(prefix != NULL, FALSE);
+
+ str_length = strlen(str);
+ prefix_length = strlen(prefix);
+
+ return prefix_length <= str_length ?
+ strncmp(str, prefix, prefix_length) == 0 :
+ FALSE;
+}
+
gchar *
g_strdup_vprintf (const gchar *format, va_list args)
{
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);
+ g_return_val_if_fail(delimiter[0] != 0, NULL);
token_length = strlen(string);
string_c = (gchar *)g_malloc(token_length + 1);
- strncpy(string_c, string, token_length);
- string_c[token_length] = '\0';
+ memcpy(string_c, string, token_length);
+ string_c[token_length] = 0;
vector = NULL;
token = (gchar *)strtok_r(string_c, delimiter, &strtok_save);
-
+
while(token != NULL) {
token_length = strlen(token);
token_c = (gchar *)g_malloc(token_length + 1);
- strncpy(token_c, token, token_length);
- token_c[token_length] = '\0';
+ memcpy(token_c, token, token_length);
+ token_c[token_length] = 0;
vector = vector == NULL ?
- (gchar **)g_malloc(sizeof(vector)) :
+ (gchar **)g_malloc(2 * sizeof(vector)) :
(gchar **)g_realloc(vector, (size + 1) * sizeof(vector));
vector[size - 1] = token_c;
}
}
- vector[size - 1] = NULL;
+ if(vector != NULL && size > 0) {
+ vector[size - 1] = NULL;
+ }
+
g_free(string_c);
string_c = NULL;
return vector;
}
+gchar *
+g_strreverse (gchar *str)
+{
+ guint len, half;
+ gint i;
+ gchar c;
+
+ if (str == NULL)
+ return NULL;
+
+ len = strlen (str);
+ half = len / 2;
+ len--;
+ for (i = 0; i < half; i++, len--) {
+ c = str [i];
+ str [i] = str [len];
+ str [len] = c;
+ }
+ return str;
+}
+
+gchar *
+g_strjoin (const gchar *separator, ...)
+{
+ va_list args;
+ char *res, *s;
+ int 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 *)){
+ len += strlen (s);
+ 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);
+ va_start (args, separator);
+ s = va_arg (args, char *);
+ strcpy (res, s);
+ for (s = va_arg (args, char *); s != NULL; s = va_arg (args, char *)){
+ if (separator != NULL)
+ strcat (res, separator);
+ strcat (res, s);
+ }
+ va_end (args);
+
+ return res;
+}
+
+gchar *
+g_strchug (gchar *str)
+{
+ gint len;
+ gchar *tmp;
+
+ if (str == NULL)
+ return NULL;
+
+ tmp = str;
+ while (*tmp && isspace (*tmp)) tmp++;
+ if (str != tmp) {
+ len = strlen (str) - (tmp - str - 1);
+ memmove (str, tmp, len);
+ }
+ return str;
+}
+
+gchar *
+g_strchomp (gchar *str)
+{
+ gchar *tmp;
+
+ if (str == NULL)
+ return NULL;
+
+ tmp = str + strlen (str) - 1;
+ while (*tmp && isspace (*tmp)) tmp--;
+ *(tmp + 1) = '\0';
+ return str;
+}
+
+gint
+g_printf(gchar const *format, ...)
+{
+ va_list args;
+ gint ret;
+
+ va_start(args, format);
+ ret = vprintf(format, args);
+ va_end(args);
+
+ return ret;
+}
+
+gint
+g_fprintf(FILE *file, gchar const *format, ...)
+{
+ va_list args;
+ gint ret;
+
+ va_start(args, format);
+ ret = vfprintf(file, format, args);
+ va_end(args);
+
+ return ret;
+}
+
+gint
+g_sprintf(gchar *string, gchar const *format, ...)
+{
+ va_list args;
+ gint ret;
+
+ va_start(args, format);
+ ret = vsprintf(string, format, args);
+ va_end(args);
+
+ return ret;
+}
+
+gint
+g_snprintf(gchar *string, gulong n, gchar const *format, ...)
+{
+ va_list args;
+ gint ret;
+
+ va_start(args, format);
+ ret = vsnprintf(string, n, format, args);
+ va_end(args);
+
+ return ret;
+}
+
+static const char const hx [] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+static gboolean
+char_needs_encoding (char c)
+{
+ if (((unsigned char)c) >= 0x80)
+ return TRUE;
+
+ if ((c >= '@' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= '&' && c < 0x3b) ||
+ (c == '!') || (c == '$') || (c == '_') || (c == '=') || (c == '~'))
+ return FALSE;
+ return TRUE;
+}
+
+gchar *
+g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)
+{
+ int n;
+ char *ret, *rp;
+ const char *p;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ if (hostname != NULL)
+ g_warning ("eglib: g_filename_to_uri: hostname not handled");
+
+ if (*filename != '/'){
+ if (error != NULL)
+ *error = g_error_new (NULL, 2, "Not an absolute filename");
+
+ return NULL;
+ }
+
+ n = strlen ("file://") + 1;
+ for (p = filename; *p; p++){
+ if (char_needs_encoding (*p))
+ n += 3;
+ else
+ n++;
+ }
+ ret = g_malloc (n);
+ strcpy (ret, "file://");
+ for (p = filename, rp = ret + strlen (ret); *p; p++){
+ if (char_needs_encoding (*p)){
+ *rp++ = '%';
+ *rp++ = hx [((unsigned char)(*p)) >> 4];
+ *rp++ = hx [((unsigned char)(*p)) & 0xf];
+ } else
+ *rp++ = *p;
+ }
+ *rp = 0;
+ return ret;
+}
+
+static int
+decode (char p)
+{
+ if (p >= '0' && p <= '9')
+ return p - '0';
+ if (p >= 'A' && p <= 'F')
+ return p - 'A';
+ if (p >= 'a' && p <= 'f')
+ return p - 'a';
+ g_assert_not_reached ();
+ return 0;
+}
+
+gchar *
+g_filename_from_uri (const gchar *uri, gchar **hostname, GError **error)
+{
+ const char *p;
+ char *r, *result;
+ int flen = 0;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ if (hostname != NULL)
+ g_warning ("eglib: g_filename_from_uri: hostname not handled");
+
+ if (strncmp (uri, "file:///", 8) != 0){
+ if (error != NULL)
+ *error = g_error_new (NULL, 2, "URI does not start with the file: scheme");
+ return NULL;
+ }
+
+ for (p = uri + 8; *p; p++){
+ if (*p == '%'){
+ if (p [1] && p [2] && isxdigit (p [1]) && isxdigit (p [2])){
+ p += 2;
+ } else {
+ if (error != NULL)
+ *error = g_error_new (NULL, 2, "URI contains an invalid escape sequence");
+ return NULL;
+ }
+ }
+ flen++;
+ }
+ flen++;
+
+ result = g_malloc (flen + 1);
+ *result = '/';
+ result [flen] = 0;
+
+ for (p = uri + 8, r = result + 1; *p; p++){
+ if (*p == '%'){
+ *r++ = (decode (p [1]) << 4) | decode (p [2]);
+ p += 2;
+ } else
+ *r++ = *p;
+ flen++;
+ }
+ return result;
+}