* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <config.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <glib.h>
+#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)
{
+#ifdef HAVE_STRNDUP
return strndup (str, n);
+#else
+ if (str) {
+ char *retval = g_malloc(n+1);
+ if (retval) {
+ strncpy(retval, str, n)[n] = 0;
+ }
+ return retval;
+ }
+ return NULL;
+#endif
}
void
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)
{
gboolean
g_str_has_suffix(const gchar *str, const gchar *suffix)
{
- gint str_length;
- gint suffix_length;
+ size_t str_length;
+ size_t suffix_length;
g_return_val_if_fail(str != NULL, FALSE);
g_return_val_if_fail(suffix != NULL, FALSE);
gboolean
g_str_has_prefix(const gchar *str, const gchar *prefix)
{
- gint str_length;
- gint prefix_length;
+ size_t str_length;
+ size_t prefix_length;
g_return_val_if_fail(str != NULL, FALSE);
g_return_val_if_fail(prefix != NULL, FALSE);
gchar *
g_strconcat (const gchar *first, ...)
{
- g_return_val_if_fail (first != NULL, NULL);
va_list args;
- int total = 0;
+ size_t total = 0;
char *s, *ret;
+ g_return_val_if_fail (first != NULL, NULL);
total += strlen (first);
va_start (args, 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;
- gint 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)
{
- guint len, half;
- gint 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;
}
g_strjoin (const gchar *separator, ...)
{
va_list args;
- char *res, *s;
- int len, slen;
+ 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 *)){
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);
gchar *
g_strjoinv (const gchar *separator, gchar **str_array)
{
- char *res;
- int slen, len, i;
+ char *res, *r;
+ size_t slen, len, i;
if (separator != NULL)
slen = strlen (separator);
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;
}
gchar *
g_strchug (gchar *str)
{
- gint len;
+ size_t len;
gchar *tmp;
if (str == NULL)
return ret;
}
-static const char const hx [] = { '0', '1', '2', '3', '4', '5', '6', '7',
+static const char hx [] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static gboolean
gchar *
g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)
{
- int n;
+ 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 ("eglib: g_filename_to_uri: hostname not handled");
+ 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];
g_return_val_if_fail (uri != NULL, NULL);
if (hostname != NULL)
- g_warning ("eglib: g_filename_from_uri: hostname not handled");
+ g_warning ("%s", "eglib: g_filename_from_uri: hostname not handled");
if (strncmp (uri, "file:///", 8) != 0){
if (error != NULL)
}
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++ = (decode (p [1]) << 4) | decode (p [2]);
+ *r++ = (char)((decode (p [1]) << 4) | decode (p [2]));
p += 2;
} else
*r++ = *p;
g_return_if_fail (string != NULL);
while (*string){
- *string = tolower (*string);
+ *string = (gchar)tolower (*string);
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)
{
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;
gint
g_ascii_strncasecmp (const gchar *s1, const gchar *s2, gsize n)
{
- int i;
+ gsize i;
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++;
-
- if (c1 == c2)
- continue;
+ for (i = 0; i < n; i++) {
+ gchar c1 = g_ascii_tolower (*s1++);
+ gchar c2 = g_ascii_tolower (*s2++);
- 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)
{
return string;
}
-#ifndef HAVE_STRLCPY
gsize
g_strlcpy (gchar *dest, const gchar *src, gsize dest_size)
{
+#ifdef HAVE_STRLCPY
+ return strlcpy (dest, src, dest_size);
+#else
gchar *d;
const gchar *s;
gchar c;
/* we need to return the length of src here */
while (*s++) ; /* instead of a plain strlen, we use 's' */
return s - src - 1;
+#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,
gchar escaped [256];
const gchar *ptr;
gchar c;
- int op;
+ gchar op;
gchar *result;
gchar *res_ptr;
return result;
}
-gchar *
-g_strdup (const gchar *str)
-{
- if (str == NULL)
- return NULL;
-
- return strdup (str);
-}
-
gint
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;
+}