/xbmc/lib/libmms/glib-2.20.4/glib/gstrfuncs.c
C | 2612 lines | 1806 code | 208 blank | 598 comment | 298 complexity | f0391b9260d0a10bb6d628350854d556 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-3.0, CC-BY-SA-3.0, 0BSD, LGPL-2.1, GPL-3.0, BSD-3-Clause, CC0-1.0, Unlicense, GPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- /* GLIB - Library of useful routines for C programming
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
- /*
- * Modified by the GLib Team and others 1997-2000. See the AUTHORS
- * file for a list of people on the GLib Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/.
- */
- /*
- * MT safe
- */
- #include "config.h"
- #define _GNU_SOURCE /* For stpcpy */
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <locale.h>
- #include <errno.h>
- #include <ctype.h> /* For tolower() */
- #if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
- #include <signal.h>
- #endif
- #include "glib.h"
- #include "gprintf.h"
- #include "gprintfint.h"
- #include "glibintl.h"
- #include "galias.h"
- #ifdef G_OS_WIN32
- #include <windows.h>
- #endif
- /* do not include <unistd.h> in this place since it
- * interferes with g_strsignal() on some OSes
- */
- static const guint16 ascii_table_data[256] = {
- 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
- 0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004,
- 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
- 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
- 0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
- 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
- 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
- 0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
- 0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
- 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
- 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
- 0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
- 0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
- 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
- 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
- 0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004
- /* the upper 128 are all zeroes */
- };
- const guint16 * const g_ascii_table = ascii_table_data;
- /**
- * g_strdup:
- * @str: the string to duplicate
- *
- * Duplicates a string. If @str is %NULL it returns %NULL.
- * The returned string should be freed with g_free()
- * when no longer needed.
- *
- * Returns: a newly-allocated copy of @str
- */
- gchar*
- g_strdup (const gchar *str)
- {
- gchar *new_str;
- gsize length;
- if (str)
- {
- length = strlen (str) + 1;
- new_str = g_new (char, length);
- memcpy (new_str, str, length);
- }
- else
- new_str = NULL;
- return new_str;
- }
- gpointer
- g_memdup (gconstpointer mem,
- guint byte_size)
- {
- gpointer new_mem;
- if (mem)
- {
- new_mem = g_malloc (byte_size);
- memcpy (new_mem, mem, byte_size);
- }
- else
- new_mem = NULL;
- return new_mem;
- }
- /**
- * g_strndup:
- * @str: the string to duplicate
- * @n: the maximum number of bytes to copy from @str
- *
- * Duplicates the first @n bytes of a string, returning a newly-allocated
- * buffer @n + 1 bytes long which will always be nul-terminated.
- * If @str is less than @n bytes long the buffer is padded with nuls.
- * If @str is %NULL it returns %NULL.
- * The returned value should be freed when no longer needed.
- *
- * <note><para>
- * To copy a number of characters from a UTF-8 encoded string, use
- * g_utf8_strncpy() instead.
- * </para></note>
- *
- * Returns: a newly-allocated buffer containing the first @n bytes
- * of @str, nul-terminated
- */
- gchar*
- g_strndup (const gchar *str,
- gsize n)
- {
- gchar *new_str;
- if (str)
- {
- new_str = g_new (gchar, n + 1);
- strncpy (new_str, str, n);
- new_str[n] = '\0';
- }
- else
- new_str = NULL;
- return new_str;
- }
- /**
- * g_strnfill:
- * @length: the length of the new string
- * @fill_char: the byte to fill the string with
- *
- * Creates a new string @length bytes long filled with @fill_char.
- * The returned string should be freed when no longer needed.
- *
- * Returns: a newly-allocated string filled the @fill_char
- */
- gchar*
- g_strnfill (gsize length,
- gchar fill_char)
- {
- gchar *str;
- str = g_new (gchar, length + 1);
- memset (str, (guchar)fill_char, length);
- str[length] = '\0';
- return str;
- }
- /**
- * g_stpcpy:
- * @dest: destination buffer.
- * @src: source string.
- *
- * Copies a nul-terminated string into the dest buffer, include the
- * trailing nul, and return a pointer to the trailing nul byte.
- * This is useful for concatenating multiple strings together
- * without having to repeatedly scan for the end.
- *
- * Return value: a pointer to trailing nul byte.
- **/
- gchar *
- g_stpcpy (gchar *dest,
- const gchar *src)
- {
- #ifdef HAVE_STPCPY
- g_return_val_if_fail (dest != NULL, NULL);
- g_return_val_if_fail (src != NULL, NULL);
- return stpcpy (dest, src);
- #else
- register gchar *d = dest;
- register const gchar *s = src;
- g_return_val_if_fail (dest != NULL, NULL);
- g_return_val_if_fail (src != NULL, NULL);
- do
- *d++ = *s;
- while (*s++ != '\0');
- return d - 1;
- #endif
- }
- /**
- * g_strdup_vprintf:
- * @format: a standard printf() format string, but notice
- * <link linkend="string-precision">string precision pitfalls</link>
- * @args: the list of parameters to insert into the format string
- *
- * Similar to the standard C vsprintf() function but safer, since it
- * calculates the maximum space required and allocates memory to hold
- * the result. The returned string should be freed with g_free() when
- * no longer needed.
- *
- * See also g_vasprintf(), which offers the same functionality, but
- * additionally returns the length of the allocated string.
- *
- * Returns: a newly-allocated string holding the result
- */
- gchar*
- g_strdup_vprintf (const gchar *format,
- va_list args)
- {
- gchar *string = NULL;
- g_vasprintf (&string, format, args);
- return string;
- }
- /**
- * g_strdup_printf:
- * @format: a standard printf() format string, but notice
- * <link linkend="string-precision">string precision pitfalls</link>
- * @Varargs: the parameters to insert into the format string
- *
- * Similar to the standard C sprintf() function but safer, since it
- * calculates the maximum space required and allocates memory to hold
- * the result. The returned string should be freed with g_free() when no
- * longer needed.
- *
- * Returns: a newly-allocated string holding the result
- */
- gchar*
- g_strdup_printf (const gchar *format,
- ...)
- {
- gchar *buffer;
- va_list args;
- va_start (args, format);
- buffer = g_strdup_vprintf (format, args);
- va_end (args);
- return buffer;
- }
- /**
- * g_strconcat:
- * @string1: the first string to add, which must not be %NULL
- * @Varargs: a %NULL-terminated list of strings to append to the string
- *
- * Concatenates all of the given strings into one long string.
- * The returned string should be freed with g_free() when no longer needed.
- *
- *
- * <warning><para>The variable argument list <emphasis>must</emphasis> end
- * with %NULL. If you forget the %NULL, g_strconcat() will start appending
- * random memory junk to your string.</para></warning>
- *
- * Returns: a newly-allocated string containing all the string arguments
- */
- gchar*
- g_strconcat (const gchar *string1, ...)
- {
- gsize l;
- va_list args;
- gchar *s;
- gchar *concat;
- gchar *ptr;
- if (!string1)
- return NULL;
- l = 1 + strlen (string1);
- va_start (args, string1);
- s = va_arg (args, gchar*);
- while (s)
- {
- l += strlen (s);
- s = va_arg (args, gchar*);
- }
- va_end (args);
- concat = g_new (gchar, l);
- ptr = concat;
- ptr = g_stpcpy (ptr, string1);
- va_start (args, string1);
- s = va_arg (args, gchar*);
- while (s)
- {
- ptr = g_stpcpy (ptr, s);
- s = va_arg (args, gchar*);
- }
- va_end (args);
- return concat;
- }
- /**
- * g_strtod:
- * @nptr: the string to convert to a numeric value.
- * @endptr: if non-%NULL, it returns the character after
- * the last character used in the conversion.
- *
- * Converts a string to a #gdouble value.
- * It calls the standard strtod() function to handle the conversion, but
- * if the string is not completely converted it attempts the conversion
- * again with g_ascii_strtod(), and returns the best match.
- *
- * This function should seldomly be used. The normal situation when reading
- * numbers not for human consumption is to use g_ascii_strtod(). Only when
- * you know that you must expect both locale formatted and C formatted numbers
- * should you use this. Make sure that you don't pass strings such as comma
- * separated lists of values, since the commas may be interpreted as a decimal
- * point in some locales, causing unexpected results.
- *
- * Return value: the #gdouble value.
- **/
- gdouble
- g_strtod (const gchar *nptr,
- gchar **endptr)
- {
- gchar *fail_pos_1;
- gchar *fail_pos_2;
- gdouble val_1;
- gdouble val_2 = 0;
- g_return_val_if_fail (nptr != NULL, 0);
- fail_pos_1 = NULL;
- fail_pos_2 = NULL;
- val_1 = strtod (nptr, &fail_pos_1);
- if (fail_pos_1 && fail_pos_1[0] != 0)
- val_2 = g_ascii_strtod (nptr, &fail_pos_2);
- if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
- {
- if (endptr)
- *endptr = fail_pos_1;
- return val_1;
- }
- else
- {
- if (endptr)
- *endptr = fail_pos_2;
- return val_2;
- }
- }
- /**
- * g_ascii_strtod:
- * @nptr: the string to convert to a numeric value.
- * @endptr: if non-%NULL, it returns the character after
- * the last character used in the conversion.
- *
- * Converts a string to a #gdouble value.
- *
- * This function behaves like the standard strtod() function
- * does in the C locale. It does this without actually changing
- * the current locale, since that would not be thread-safe.
- * A limitation of the implementation is that this function
- * will still accept localized versions of infinities and NANs.
- *
- * This function is typically used when reading configuration
- * files or other non-user input that should be locale independent.
- * To handle input from the user you should normally use the
- * locale-sensitive system strtod() function.
- *
- * To convert from a #gdouble to a string in a locale-insensitive
- * way, use g_ascii_dtostr().
- *
- * If the correct value would cause overflow, plus or minus %HUGE_VAL
- * is returned (according to the sign of the value), and %ERANGE is
- * stored in %errno. If the correct value would cause underflow,
- * zero is returned and %ERANGE is stored in %errno.
- *
- * This function resets %errno before calling strtod() so that
- * you can reliably detect overflow and underflow.
- *
- * Return value: the #gdouble value.
- **/
- gdouble
- g_ascii_strtod (const gchar *nptr,
- gchar **endptr)
- {
- gchar *fail_pos;
- gdouble val;
- struct lconv *locale_data;
- const char *decimal_point;
- int decimal_point_len;
- const char *p, *decimal_point_pos;
- const char *end = NULL; /* Silence gcc */
- int strtod_errno;
- g_return_val_if_fail (nptr != NULL, 0);
- fail_pos = NULL;
- locale_data = localeconv ();
- decimal_point = locale_data->decimal_point;
- decimal_point_len = strlen (decimal_point);
- g_assert (decimal_point_len != 0);
-
- decimal_point_pos = NULL;
- end = NULL;
- if (decimal_point[0] != '.' ||
- decimal_point[1] != 0)
- {
- p = nptr;
- /* Skip leading space */
- while (g_ascii_isspace (*p))
- p++;
-
- /* Skip leading optional sign */
- if (*p == '+' || *p == '-')
- p++;
-
- if (p[0] == '0' &&
- (p[1] == 'x' || p[1] == 'X'))
- {
- p += 2;
- /* HEX - find the (optional) decimal point */
-
- while (g_ascii_isxdigit (*p))
- p++;
-
- if (*p == '.')
- decimal_point_pos = p++;
-
- while (g_ascii_isxdigit (*p))
- p++;
-
- if (*p == 'p' || *p == 'P')
- p++;
- if (*p == '+' || *p == '-')
- p++;
- while (g_ascii_isdigit (*p))
- p++;
- end = p;
- }
- else if (g_ascii_isdigit (*p) || *p == '.')
- {
- while (g_ascii_isdigit (*p))
- p++;
-
- if (*p == '.')
- decimal_point_pos = p++;
-
- while (g_ascii_isdigit (*p))
- p++;
-
- if (*p == 'e' || *p == 'E')
- p++;
- if (*p == '+' || *p == '-')
- p++;
- while (g_ascii_isdigit (*p))
- p++;
- end = p;
- }
- /* For the other cases, we need not convert the decimal point */
- }
- if (decimal_point_pos)
- {
- char *copy, *c;
- /* We need to convert the '.' to the locale specific decimal point */
- copy = g_malloc (end - nptr + 1 + decimal_point_len);
-
- c = copy;
- memcpy (c, nptr, decimal_point_pos - nptr);
- c += decimal_point_pos - nptr;
- memcpy (c, decimal_point, decimal_point_len);
- c += decimal_point_len;
- memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
- c += end - (decimal_point_pos + 1);
- *c = 0;
- errno = 0;
- val = strtod (copy, &fail_pos);
- strtod_errno = errno;
- if (fail_pos)
- {
- if (fail_pos - copy > decimal_point_pos - nptr)
- fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
- else
- fail_pos = (char *)nptr + (fail_pos - copy);
- }
-
- g_free (copy);
-
- }
- else if (end)
- {
- char *copy;
-
- copy = g_malloc (end - (char *)nptr + 1);
- memcpy (copy, nptr, end - nptr);
- *(copy + (end - (char *)nptr)) = 0;
-
- errno = 0;
- val = strtod (copy, &fail_pos);
- strtod_errno = errno;
- if (fail_pos)
- {
- fail_pos = (char *)nptr + (fail_pos - copy);
- }
-
- g_free (copy);
- }
- else
- {
- errno = 0;
- val = strtod (nptr, &fail_pos);
- strtod_errno = errno;
- }
- if (endptr)
- *endptr = fail_pos;
- errno = strtod_errno;
- return val;
- }
- /**
- * g_ascii_dtostr:
- * @buffer: A buffer to place the resulting string in
- * @buf_len: The length of the buffer.
- * @d: The #gdouble to convert
- *
- * Converts a #gdouble to a string, using the '.' as
- * decimal point.
- *
- * This functions generates enough precision that converting
- * the string back using g_ascii_strtod() gives the same machine-number
- * (on machines with IEEE compatible 64bit doubles). It is
- * guaranteed that the size of the resulting string will never
- * be larger than @G_ASCII_DTOSTR_BUF_SIZE bytes.
- *
- * Return value: The pointer to the buffer with the converted string.
- **/
- gchar *
- g_ascii_dtostr (gchar *buffer,
- gint buf_len,
- gdouble d)
- {
- return g_ascii_formatd (buffer, buf_len, "%.17g", d);
- }
- /**
- * g_ascii_formatd:
- * @buffer: A buffer to place the resulting string in
- * @buf_len: The length of the buffer.
- * @format: The printf()-style format to use for the
- * code to use for converting.
- * @d: The #gdouble to convert
- *
- * Converts a #gdouble to a string, using the '.' as
- * decimal point. To format the number you pass in
- * a printf()-style format string. Allowed conversion
- * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'.
- *
- * If you just want to want to serialize the value into a
- * string, use g_ascii_dtostr().
- *
- * Return value: The pointer to the buffer with the converted string.
- */
- gchar *
- g_ascii_formatd (gchar *buffer,
- gint buf_len,
- const gchar *format,
- gdouble d)
- {
- struct lconv *locale_data;
- const char *decimal_point;
- int decimal_point_len;
- gchar *p;
- int rest_len;
- gchar format_char;
- g_return_val_if_fail (buffer != NULL, NULL);
- g_return_val_if_fail (format[0] == '%', NULL);
- g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL);
-
- format_char = format[strlen (format) - 1];
-
- g_return_val_if_fail (format_char == 'e' || format_char == 'E' ||
- format_char == 'f' || format_char == 'F' ||
- format_char == 'g' || format_char == 'G',
- NULL);
- if (format[0] != '%')
- return NULL;
- if (strpbrk (format + 1, "'l%"))
- return NULL;
- if (!(format_char == 'e' || format_char == 'E' ||
- format_char == 'f' || format_char == 'F' ||
- format_char == 'g' || format_char == 'G'))
- return NULL;
-
- _g_snprintf (buffer, buf_len, format, d);
- locale_data = localeconv ();
- decimal_point = locale_data->decimal_point;
- decimal_point_len = strlen (decimal_point);
- g_assert (decimal_point_len != 0);
- if (decimal_point[0] != '.' ||
- decimal_point[1] != 0)
- {
- p = buffer;
- while (g_ascii_isspace (*p))
- p++;
- if (*p == '+' || *p == '-')
- p++;
- while (isdigit ((guchar)*p))
- p++;
- if (strncmp (p, decimal_point, decimal_point_len) == 0)
- {
- *p = '.';
- p++;
- if (decimal_point_len > 1)
- {
- rest_len = strlen (p + (decimal_point_len-1));
- memmove (p, p + (decimal_point_len-1), rest_len);
- p[rest_len] = 0;
- }
- }
- }
-
- return buffer;
- }
- static guint64
- g_parse_long_long (const gchar *nptr,
- const gchar **endptr,
- guint base,
- gboolean *negative)
- {
- /* this code is based on on the strtol(3) code from GNU libc released under
- * the GNU Lesser General Public License.
- *
- * Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02
- * Free Software Foundation, Inc.
- */
- #define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
- (c) == '\r' || (c) == '\t' || (c) == '\v')
- #define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
- #define ISLOWER(c) ((c) >= 'a' && (c) <= 'z')
- #define ISALPHA(c) (ISUPPER (c) || ISLOWER (c))
- #define TOUPPER(c) (ISLOWER (c) ? (c) - 'a' + 'A' : (c))
- #define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
- gboolean overflow;
- guint64 cutoff;
- guint64 cutlim;
- guint64 ui64;
- const gchar *s, *save;
- guchar c;
-
- g_return_val_if_fail (nptr != NULL, 0);
-
- *negative = FALSE;
- if (base == 1 || base > 36)
- {
- errno = EINVAL;
- if (endptr)
- *endptr = nptr;
- return 0;
- }
-
- save = s = nptr;
-
- /* Skip white space. */
- while (ISSPACE (*s))
- ++s;
- if (G_UNLIKELY (!*s))
- goto noconv;
-
- /* Check for a sign. */
- if (*s == '-')
- {
- *negative = TRUE;
- ++s;
- }
- else if (*s == '+')
- ++s;
-
- /* Recognize number prefix and if BASE is zero, figure it out ourselves. */
- if (*s == '0')
- {
- if ((base == 0 || base == 16) && TOUPPER (s[1]) == 'X')
- {
- s += 2;
- base = 16;
- }
- else if (base == 0)
- base = 8;
- }
- else if (base == 0)
- base = 10;
-
- /* Save the pointer so we can check later if anything happened. */
- save = s;
- cutoff = G_MAXUINT64 / base;
- cutlim = G_MAXUINT64 % base;
-
- overflow = FALSE;
- ui64 = 0;
- c = *s;
- for (; c; c = *++s)
- {
- if (c >= '0' && c <= '9')
- c -= '0';
- else if (ISALPHA (c))
- c = TOUPPER (c) - 'A' + 10;
- else
- break;
- if (c >= base)
- break;
- /* Check for overflow. */
- if (ui64 > cutoff || (ui64 == cutoff && c > cutlim))
- overflow = TRUE;
- else
- {
- ui64 *= base;
- ui64 += c;
- }
- }
-
- /* Check if anything actually happened. */
- if (s == save)
- goto noconv;
-
- /* Store in ENDPTR the address of one character
- past the last character we converted. */
- if (endptr)
- *endptr = s;
-
- if (G_UNLIKELY (overflow))
- {
- errno = ERANGE;
- return G_MAXUINT64;
- }
- return ui64;
-
- noconv:
- /* We must handle a special case here: the base is 0 or 16 and the
- first two characters are '0' and 'x', but the rest are no
- hexadecimal digits. This is no error case. We return 0 and
- ENDPTR points to the `x`. */
- if (endptr)
- {
- if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X'
- && save[-2] == '0')
- *endptr = &save[-1];
- else
- /* There was no number to convert. */
- *endptr = nptr;
- }
- return 0;
- }
- /**
- * g_ascii_strtoull:
- * @nptr: the string to convert to a numeric value.
- * @endptr: if non-%NULL, it returns the character after
- * the last character used in the conversion.
- * @base: to be used for the conversion, 2..36 or 0
- *
- * Converts a string to a #guint64 value.
- * This function behaves like the standard strtoull() function
- * does in the C locale. It does this without actually
- * changing the current locale, since that would not be
- * thread-safe.
- *
- * This function is typically used when reading configuration
- * files or other non-user input that should be locale independent.
- * To handle input from the user you should normally use the
- * locale-sensitive system strtoull() function.
- *
- * If the correct value would cause overflow, %G_MAXUINT64
- * is returned, and %ERANGE is stored in %errno. If the base is
- * outside the valid range, zero is returned, and %EINVAL is stored
- * in %errno. If the string conversion fails, zero is returned, and
- * @endptr returns @nptr (if @endptr is non-%NULL).
- *
- * Return value: the #guint64 value or zero on error.
- *
- * Since: 2.2
- */
- guint64
- g_ascii_strtoull (const gchar *nptr,
- gchar **endptr,
- guint base)
- {
- gboolean negative;
- guint64 result;
- result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative);
- /* Return the result of the appropriate sign. */
- return negative ? -result : result;
- }
- /**
- * g_ascii_strtoll:
- * @nptr: the string to convert to a numeric value.
- * @endptr: if non-%NULL, it returns the character after
- * the last character used in the conversion.
- * @base: to be used for the conversion, 2..36 or 0
- *
- * Converts a string to a #gint64 value.
- * This function behaves like the standard strtoll() function
- * does in the C locale. It does this without actually
- * changing the current locale, since that would not be
- * thread-safe.
- *
- * This function is typically used when reading configuration
- * files or other non-user input that should be locale independent.
- * To handle input from the user you should normally use the
- * locale-sensitive system strtoll() function.
- *
- * If the correct value would cause overflow, %G_MAXINT64 or %G_MININT64
- * is returned, and %ERANGE is stored in %errno. If the base is
- * outside the valid range, zero is returned, and %EINVAL is stored
- * in %errno. If the string conversion fails, zero is returned, and
- * @endptr returns @nptr (if @endptr is non-%NULL).
- *
- * Return value: the #gint64 value or zero on error.
- *
- * Since: 2.12
- */
- gint64
- g_ascii_strtoll (const gchar *nptr,
- gchar **endptr,
- guint base)
- {
- gboolean negative;
- guint64 result;
- result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative);
- if (negative && result > (guint64) G_MININT64)
- {
- errno = ERANGE;
- return G_MININT64;
- }
- else if (!negative && result > (guint64) G_MAXINT64)
- {
- errno = ERANGE;
- return G_MAXINT64;
- }
- else if (negative)
- return - (gint64) result;
- else
- return (gint64) result;
- }
- /**
- * g_strerror:
- * @errnum: the system error number. See the standard C %errno
- * documentation
- *
- * Returns a string corresponding to the given error code, e.g.
- * "no such process". You should use this function in preference to
- * strerror(), because it returns a string in UTF-8 encoding, and since
- * not all platforms support the strerror() function.
- *
- * Returns: a UTF-8 string describing the error code. If the error code
- * is unknown, it returns "unknown error (<code>)". The string
- * can only be used until the next call to g_strerror()
- */
- G_CONST_RETURN gchar*
- g_strerror (gint errnum)
- {
- static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
- char *msg;
- int saved_errno = errno;
- #ifdef HAVE_STRERROR
- const char *msg_locale;
- msg_locale = strerror (errnum);
- if (g_get_charset (NULL))
- {
- errno = saved_errno;
- return msg_locale;
- }
- else
- {
- gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
- if (msg_utf8)
- {
- /* Stick in the quark table so that we can return a static result
- */
- GQuark msg_quark = g_quark_from_string (msg_utf8);
- g_free (msg_utf8);
-
- msg_utf8 = (gchar *) g_quark_to_string (msg_quark);
- errno = saved_errno;
- return msg_utf8;
- }
- }
- #elif NO_SYS_ERRLIST
- switch (errnum)
- {
- #ifdef E2BIG
- case E2BIG: return "argument list too long";
- #endif
- #ifdef EACCES
- case EACCES: return "permission denied";
- #endif
- #ifdef EADDRINUSE
- case EADDRINUSE: return "address already in use";
- #endif
- #ifdef EADDRNOTAVAIL
- case EADDRNOTAVAIL: return "can't assign requested address";
- #endif
- #ifdef EADV
- case EADV: return "advertise error";
- #endif
- #ifdef EAFNOSUPPORT
- case EAFNOSUPPORT: return "address family not supported by protocol family";
- #endif
- #ifdef EAGAIN
- case EAGAIN: return "try again";
- #endif
- #ifdef EALIGN
- case EALIGN: return "EALIGN";
- #endif
- #ifdef EALREADY
- case EALREADY: return "operation already in progress";
- #endif
- #ifdef EBADE
- case EBADE: return "bad exchange descriptor";
- #endif
- #ifdef EBADF
- case EBADF: return "bad file number";
- #endif
- #ifdef EBADFD
- case EBADFD: return "file descriptor in bad state";
- #endif
- #ifdef EBADMSG
- case EBADMSG: return "not a data message";
- #endif
- #ifdef EBADR
- case EBADR: return "bad request descriptor";
- #endif
- #ifdef EBADRPC
- case EBADRPC: return "RPC structure is bad";
- #endif
- #ifdef EBADRQC
- case EBADRQC: return "bad request code";
- #endif
- #ifdef EBADSLT
- case EBADSLT: return "invalid slot";
- #endif
- #ifdef EBFONT
- case EBFONT: return "bad font file format";
- #endif
- #ifdef EBUSY
- case EBUSY: return "mount device busy";
- #endif
- #ifdef ECHILD
- case ECHILD: return "no children";
- #endif
- #ifdef ECHRNG
- case ECHRNG: return "channel number out of range";
- #endif
- #ifdef ECOMM
- case ECOMM: return "communication error on send";
- #endif
- #ifdef ECONNABORTED
- case ECONNABORTED: return "software caused connection abort";
- #endif
- #ifdef ECONNREFUSED
- case ECONNREFUSED: return "connection refused";
- #endif
- #ifdef ECONNRESET
- case ECONNRESET: return "connection reset by peer";
- #endif
- #if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
- case EDEADLK: return "resource deadlock avoided";
- #endif
- #ifdef EDEADLOCK
- case EDEADLOCK: return "resource deadlock avoided";
- #endif
- #ifdef EDESTADDRREQ
- case EDESTADDRREQ: return "destination address required";
- #endif
- #ifdef EDIRTY
- case EDIRTY: return "mounting a dirty fs w/o force";
- #endif
- #ifdef EDOM
- case EDOM: return "math argument out of range";
- #endif
- #ifdef EDOTDOT
- case EDOTDOT: return "cross mount point";
- #endif
- #ifdef EDQUOT
- case EDQUOT: return "disk quota exceeded";
- #endif
- #ifdef EDUPPKG
- case EDUPPKG: return "duplicate package name";
- #endif
- #ifdef EEXIST
- case EEXIST: return "file already exists";
- #endif
- #ifdef EFAULT
- case EFAULT: return "bad address in system call argument";
- #endif
- #ifdef EFBIG
- case EFBIG: return "file too large";
- #endif
- #ifdef EHOSTDOWN
- case EHOSTDOWN: return "host is down";
- #endif
- #ifdef EHOSTUNREACH
- case EHOSTUNREACH: return "host is unreachable";
- #endif
- #ifdef EIDRM
- case EIDRM: return "identifier removed";
- #endif
- #ifdef EINIT
- case EINIT: return "initialization error";
- #endif
- #ifdef EINPROGRESS
- case EINPROGRESS: return "operation now in progress";
- #endif
- #ifdef EINTR
- case EINTR: return "interrupted system call";
- #endif
- #ifdef EINVAL
- case EINVAL: return "invalid argument";
- #endif
- #ifdef EIO
- case EIO: return "I/O error";
- #endif
- #ifdef EISCONN
- case EISCONN: return "socket is already connected";
- #endif
- #ifdef EISDIR
- case EISDIR: return "is a directory";
- #endif
- #ifdef EISNAME
- case EISNAM: return "is a name file";
- #endif
- #ifdef ELBIN
- case ELBIN: return "ELBIN";
- #endif
- #ifdef EL2HLT
- case EL2HLT: return "level 2 halted";
- #endif
- #ifdef EL2NSYNC
- case EL2NSYNC: return "level 2 not synchronized";
- #endif
- #ifdef EL3HLT
- case EL3HLT: return "level 3 halted";
- #endif
- #ifdef EL3RST
- case EL3RST: return "level 3 reset";
- #endif
- #ifdef ELIBACC
- case ELIBACC: return "can not access a needed shared library";
- #endif
- #ifdef ELIBBAD
- case ELIBBAD: return "accessing a corrupted shared library";
- #endif
- #ifdef ELIBEXEC
- case ELIBEXEC: return "can not exec a shared library directly";
- #endif
- #ifdef ELIBMAX
- case ELIBMAX: return "attempting to link in more shared libraries than system limit";
- #endif
- #ifdef ELIBSCN
- case ELIBSCN: return ".lib section in a.out corrupted";
- #endif
- #ifdef ELNRNG
- case ELNRNG: return "link number out of range";
- #endif
- #ifdef ELOOP
- case ELOOP: return "too many levels of symbolic links";
- #endif
- #ifdef EMFILE
- case EMFILE: return "too many open files";
- #endif
- #ifdef EMLINK
- case EMLINK: return "too many links";
- #endif
- #ifdef EMSGSIZE
- case EMSGSIZE: return "message too long";
- #endif
- #ifdef EMULTIHOP
- case EMULTIHOP: return "multihop attempted";
- #endif
- #ifdef ENAMETOOLONG
- case ENAMETOOLONG: return "file name too long";
- #endif
- #ifdef ENAVAIL
- case ENAVAIL: return "not available";
- #endif
- #ifdef ENET
- case ENET: return "ENET";
- #endif
- #ifdef ENETDOWN
- case ENETDOWN: return "network is down";
- #endif
- #ifdef ENETRESET
- case ENETRESET: return "network dropped connection on reset";
- #endif
- #ifdef ENETUNREACH
- case ENETUNREACH: return "network is unreachable";
- #endif
- #ifdef ENFILE
- case ENFILE: return "file table overflow";
- #endif
- #ifdef ENOANO
- case ENOANO: return "anode table overflow";
- #endif
- #if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
- case ENOBUFS: return "no buffer space available";
- #endif
- #ifdef ENOCSI
- case ENOCSI: return "no CSI structure available";
- #endif
- #ifdef ENODATA
- case ENODATA: return "no data available";
- #endif
- #ifdef ENODEV
- case ENODEV: return "no such device";
- #endif
- #ifdef ENOENT
- case ENOENT: return "no such file or directory";
- #endif
- #ifdef ENOEXEC
- case ENOEXEC: return "exec format error";
- #endif
- #ifdef ENOLCK
- case ENOLCK: return "no locks available";
- #endif
- #ifdef ENOLINK
- case ENOLINK: return "link has be severed";
- #endif
- #ifdef ENOMEM
- case ENOMEM: return "not enough memory";
- #endif
- #ifdef ENOMSG
- case ENOMSG: return "no message of desired type";
- #endif
- #ifdef ENONET
- case ENONET: return "machine is not on the network";
- #endif
- #ifdef ENOPKG
- case ENOPKG: return "package not installed";
- #endif
- #ifdef ENOPROTOOPT
- case ENOPROTOOPT: return "bad proocol option";
- #endif
- #ifdef ENOSPC
- case ENOSPC: return "no space left on device";
- #endif
- #ifdef ENOSR
- case ENOSR: return "out of stream resources";
- #endif
- #ifdef ENOSTR
- case ENOSTR: return "not a stream device";
- #endif
- #ifdef ENOSYM
- case ENOSYM: return "unresolved symbol name";
- #endif
- #ifdef ENOSYS
- case ENOSYS: return "function not implemented";
- #endif
- #ifdef ENOTBLK
- case ENOTBLK: return "block device required";
- #endif
- #ifdef ENOTCONN
- case ENOTCONN: return "socket is not connected";
- #endif
- #ifdef ENOTDIR
- case ENOTDIR: return "not a directory";
- #endif
- #ifdef ENOTEMPTY
- case ENOTEMPTY: return "directory not empty";
- #endif
- #ifdef ENOTNAM
- case ENOTNAM: return "not a name file";
- #endif
- #ifdef ENOTSOCK
- case ENOTSOCK: return "socket operation on non-socket";
- #endif
- #ifdef ENOTTY
- case ENOTTY: return "inappropriate device for ioctl";
- #endif
- #ifdef ENOTUNIQ
- case ENOTUNIQ: return "name not unique on network";
- #endif
- #ifdef ENXIO
- case ENXIO: return "no such device or address";
- #endif
- #ifdef EOPNOTSUPP
- case EOPNOTSUPP: return "operation not supported on socket";
- #endif
- #ifdef EPERM
- case EPERM: return "not owner";
- #endif
- #ifdef EPFNOSUPPORT
- case EPFNOSUPPORT: return "protocol family not supported";
- #endif
- #ifdef EPIPE
- case EPIPE: return "broken pipe";
- #endif
- #ifdef EPROCLIM
- case EPROCLIM: return "too many processes";
- #endif
- #ifdef EPROCUNAVAIL
- case EPROCUNAVAIL: return "bad procedure for program";
- #endif
- #ifdef EPROGMISMATCH
- case EPROGMISMATCH: return "program version wrong";
- #endif
- #ifdef EPROGUNAVAIL
- case EPROGUNAVAIL: return "RPC program not available";
- #endif
- #ifdef EPROTO
- case EPROTO: return "protocol error";
- #endif
- #ifdef EPROTONOSUPPORT
- case EPROTONOSUPPORT: return "protocol not suppored";
- #endif
- #ifdef EPROTOTYPE
- case EPROTOTYPE: return "protocol wrong type for socket";
- #endif
- #ifdef ERANGE
- case ERANGE: return "math result unrepresentable";
- #endif
- #if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
- case EREFUSED: return "EREFUSED";
- #endif
- #ifdef EREMCHG
- case EREMCHG: return "remote address changed";
- #endif
- #ifdef EREMDEV
- case EREMDEV: return "remote device";
- #endif
- #ifdef EREMOTE
- case EREMOTE: return "pathname hit remote file system";
- #endif
- #ifdef EREMOTEIO
- case EREMOTEIO: return "remote i/o error";
- #endif
- #ifdef EREMOTERELEASE
- case EREMOTERELEASE: return "EREMOTERELEASE";
- #endif
- #ifdef EROFS
- case EROFS: return "read-only file system";
- #endif
- #ifdef ERPCMISMATCH
- case ERPCMISMATCH: return "RPC version is wrong";
- #endif
- #ifdef ERREMOTE
- case ERREMOTE: return "object is remote";
- #endif
- #ifdef ESHUTDOWN
- case ESHUTDOWN: return "can't send afer socket shutdown";
- #endif
- #ifdef ESOCKTNOSUPPORT
- case ESOCKTNOSUPPORT: return "socket type not supported";
- #endif
- #ifdef ESPIPE
- case ESPIPE: return "invalid seek";
- #endif
- #ifdef ESRCH
- case ESRCH: return "no such process";
- #endif
- #ifdef ESRMNT
- case ESRMNT: return "srmount error";
- #endif
- #ifdef ESTALE
- case ESTALE: return "stale remote file handle";
- #endif
- #ifdef ESUCCESS
- case ESUCCESS: return "Error 0";
- #endif
- #ifdef ETIME
- case ETIME: return "timer expired";
- #endif
- #ifdef ETIMEDOUT
- case ETIMEDOUT: return "connection timed out";
- #endif
- #ifdef ETOOMANYREFS
- case ETOOMANYREFS: return "too many references: can't splice";
- #endif
- #ifdef ETXTBSY
- case ETXTBSY: return "text file or pseudo-device busy";
- #endif
- #ifdef EUCLEAN
- case EUCLEAN: return "structure needs cleaning";
- #endif
- #ifdef EUNATCH
- case EUNATCH: return "protocol driver not attached";
- #endif
- #ifdef EUSERS
- case EUSERS: return "too many users";
- #endif
- #ifdef EVERSION
- case EVERSION: return "version mismatch";
- #endif
- #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
- case EWOULDBLOCK: return "operation would block";
- #endif
- #ifdef EXDEV
- case EXDEV: return "cross-domain link";
- #endif
- #ifdef EXFULL
- case EXFULL: return "message tables full";
- #endif
- }
- #else /* NO_SYS_ERRLIST */
- extern int sys_nerr;
- extern char *sys_errlist[];
- if ((errnum > 0) && (errnum <= sys_nerr))
- return sys_errlist [errnum];
- #endif /* NO_SYS_ERRLIST */
- msg = g_static_private_get (&msg_private);
- if (!msg)
- {
- msg = g_new (gchar, 64);
- g_static_private_set (&msg_private, msg, g_free);
- }
- _g_sprintf (msg, "unknown error (%d)", errnum);
- errno = saved_errno;
- return msg;
- }
- /**
- * g_strsignal:
- * @signum: the signal number. See the <literal>signal</literal>
- * documentation
- *
- * Returns a string describing the given signal, e.g. "Segmentation fault".
- * You should use this function in preference to strsignal(), because it
- * returns a string in UTF-8 encoding, and since not all platforms support
- * the strsignal() function.
- *
- * Returns: a UTF-8 string describing the signal. If the signal is unknown,
- * it returns "unknown signal (<signum>)". The string can only be
- * used until the next call to g_strsignal()
- */
- G_CONST_RETURN gchar*
- g_strsignal (gint signum)
- {
- static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
- char *msg;
- #ifdef HAVE_STRSIGNAL
- const char *msg_locale;
-
- #if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN)
- extern const char *strsignal(int);
- #else
- /* this is declared differently (const) in string.h on BeOS */
- extern char *strsignal (int sig);
- #endif /* !G_OS_BEOS && !G_WITH_CYGWIN */
- msg_locale = strsignal (signum);
- if (g_get_charset (NULL))
- return msg_locale;
- else
- {
- gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
- if (msg_utf8)
- {
- /* Stick in the quark table so that we can return a static result
- */
- GQuark msg_quark = g_quark_from_string (msg_utf8);
- g_free (msg_utf8);
-
- return g_quark_to_string (msg_quark);
- }
- }
- #elif NO_SYS_SIGLIST
- switch (signum)
- {
- #ifdef SIGHUP
- case SIGHUP: return "Hangup";
- #endif
- #ifdef SIGINT
- case SIGINT: return "Interrupt";
- #endif
- #ifdef SIGQUIT
- case SIGQUIT: return "Quit";
- #endif
- #ifdef SIGILL
- case SIGILL: return "Illegal instruction";
- #endif
- #ifdef SIGTRAP
- case SIGTRAP: return "Trace/breakpoint trap";
- #endif
- #ifdef SIGABRT
- case SIGABRT: return "IOT trap/Abort";
- #endif
- #ifdef SIGBUS
- case SIGBUS: return "Bus error";
- #endif
- #ifdef SIGFPE
- case SIGFPE: return "Floating point exception";
- #endif
- #ifdef SIGKILL
- case SIGKILL: return "Killed";
- #endif
- #ifdef SIGUSR1
- case SIGUSR1: return "User defined signal 1";
- #endif
- #ifdef SIGSEGV
- case SIGSEGV: return "Segmentation fault";
- #endif
- #ifdef SIGUSR2
- case SIGUSR2: return "User defined signal 2";
- #endif
- #ifdef SIGPIPE
- case SIGPIPE: return "Broken pipe";
- #endif
- #ifdef SIGALRM
- case SIGALRM: return "Alarm clock";
- #endif
- #ifdef SIGTERM
- case SIGTERM: return "Terminated";
- #endif
- #ifdef SIGSTKFLT
- case SIGSTKFLT: return "Stack fault";
- #endif
- #ifdef SIGCHLD
- case SIGCHLD: return "Child exited";
- #endif
- #ifdef SIGCONT
- case SIGCONT: return "Continued";
- #endif
- #ifdef SIGSTOP
- case SIGSTOP: return "Stopped (signal)";
- #endif
- #ifdef SIGTSTP
- case SIGTSTP: return "Stopped";
- #endif
- #ifdef SIGTTIN
- case SIGTTIN: return "Stopped (tty input)";
- #endif
- #ifdef SIGTTOU
- case SIGTTOU: return "Stopped (tty output)";
- #endif
- #ifdef SIGURG
- case SIGURG: return "Urgent condition";
- #endif
- #ifdef SIGXCPU
- case SIGXCPU: return "CPU time limit exceeded";
- #endif
- #ifdef SIGXFSZ
- case SIGXFSZ: return "File size limit exceeded";
- #endif
- #ifdef SIGVTALRM
- case SIGVTALRM: return "Virtual time alarm";
- #endif
- #ifdef SIGPROF
- case SIGPROF: return "Profile signal";
- #endif
- #ifdef SIGWINCH
- case SIGWINCH: return "Window size changed";
- #endif
- #ifdef SIGIO
- case SIGIO: return "Possible I/O";
- #endif
- #ifdef SIGPWR
- case SIGPWR: return "Power failure";
- #endif
- #ifdef SIGUNUSED
- case SIGUNUSED: return "Unused signal";
- #endif
- }
- #else /* NO_SYS_SIGLIST */
- #ifdef NO_SYS_SIGLIST_DECL
- extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
- #endif
- return (char*) /* this function should return const --josh */ sys_siglist [signum];
- #endif /* NO_SYS_SIGLIST */
- msg = g_static_private_get (&msg_private);
- if (!msg)
- {
- msg = g_new (gchar, 64);
- g_static_private_set (&msg_private, msg, g_free);
- }
- _g_sprintf (msg, "unknown signal (%d)", signum);
-
- return msg;
- }
- /* Functions g_strlcpy and g_strlcat were originally developed by
- * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
- * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
- * for more information.
- */
- #ifdef HAVE_STRLCPY
- /* Use the native ones, if available; they might be implemented in assembly */
- gsize
- g_strlcpy (gchar *dest,
- const gchar *src,
- gsize dest_size)
- {
- g_return_val_if_fail (dest != NULL, 0);
- g_return_val_if_fail (src != NULL, 0);
-
- return strlcpy (dest, src, dest_size);
- }
- gsize
- g_strlcat (gchar *dest,
- const gchar *src,
- gsize dest_size)
- {
- g_return_val_if_fail (dest != NULL, 0);
- g_return_val_if_fail (src != NULL, 0);
-
- return strlcat (dest, src, dest_size);
- }
- #else /* ! HAVE_STRLCPY */
- /**
- * g_strlcpy:
- * @dest: destination buffer
- * @src: source buffer
- * @dest_size: length of @dest in bytes
- *
- * Portability wrapper that calls strlcpy() on systems which have it,
- * and emulates strlcpy() otherwise. Copies @src to @dest; @dest is
- * guaranteed to be nul-terminated; @src must be nul-terminated;
- * @dest_size is the buffer size, not the number of chars to copy.
- *
- * At most dest_size - 1 characters will be copied. Always nul-terminates
- * (unless dest_size == 0). This function does <emphasis>not</emphasis>
- * allocate memory. Unlike strncpy(), this function doesn't pad dest (so
- * it's often faster). It returns the size of the attempted result,
- * strlen (src), so if @retval >= @dest_size, truncation occurred.
- *
- * <note><para>Caveat: strlcpy() is supposedly more secure than
- * strcpy() or strncpy(), but if you really want to avoid screwups,
- * g_strdup() is an even better idea.</para></note>
- *
- * Returns: length of @src
- */
- gsize
- g_strlcpy (gchar *dest,
- const gchar *src,
- gsize dest_size)
- {
- register gchar *d = dest;
- register const gchar *s = src;
- register gsize n = dest_size;
-
- g_return_val_if_fail (dest != NULL, 0);
- g_return_val_if_fail (src != NULL, 0);
-
- /* Copy as many bytes as will fit */
- if (n != 0 && --n != 0)
- do
- {
- register gchar c = *s++;
-
- *d++ = c;
- if (c == 0)
- break;
- }
- while (--n != 0);
-
- /* If not enough room in dest, add NUL and traverse rest of src */
- if (n == 0)
- {
- if (dest_size != 0)
- *d = 0;
- while (*s++)
- ;
- }
-
- return s - src - 1; /* count does not include NUL */
- }
- /**
- * g_strlcat:
- * @dest: destination buffer, already containing one nul-terminated string
- * @src: source buffer
- * @dest_size: length of @dest buffer in bytes (not length of existing string
- * inside @dest)
- *
- * Portability wrapper that calls strlcat() on systems which have it,
- * and emulates it otherwise. Appends nul-terminated @src string to @dest,
- * guaranteeing nul-termination for @dest. The total size of @dest won't
- * exceed @dest_size.
- *
- * At most dest_size - 1 characters will be copied.
- * Unlike strncat, dest_size is the full size of dest, not the space left over.
- * This function does NOT allocate memory.
- * This always NUL terminates (unless siz == 0 or there were no NUL characters
- * in the dest_size characters of dest to start with).
- * Returns size of attempted result, which is
- * MIN (dest_size, strlen (original dest)) + strlen (src),
- * so if retval >= dest_size, truncation occurred.
- *
- * <note><para>Caveat: this is supposedly a more secure alternative to
- * strcat() or strncat(), but for real security g_strconcat() is harder
- * to mess up.</para></note>
- *
- */
- gsize
- g_strlcat (gchar *dest,
- const gchar *src,
- gsize dest_size)
- {
- register gchar *d = dest;
- register const gchar *s = src;
- register gsize bytes_left = dest_size;
- gsize dlength; /* Logically, MIN (strlen (d), dest_size) */
-
- g_return_val_if_fail (dest != NULL, 0);
- g_return_val_if_fail (src != NULL, 0);
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (*d != 0 && bytes_left-- != 0)
- d++;
- dlength = d - dest;
- bytes_left = dest_size - dlength;
-
- if (bytes_left == 0)
- return dlength + strlen (s);
-
- while (*s != 0)
- {
- if (bytes_left != 1)
- {
- *d++ = *s;
- bytes_left--;
- }
- s++;
- }
- *d = 0;
-
- return dlength + (s - src); /* count does not include NUL */
- }
- #endif /* ! HAVE_STRLCPY */
- /**
- * g_ascii_strdown:
- * @str: a string.
- * @len: length of @str in bytes, or -1 if @str is nul-terminated.
- *
- * Converts all upper case ASCII letters to lower case ASCII letters.
- *
- * Return value: a newly-allocated string, with all the upper case
- * characters in @str converted to lower case, with
- * semantics that exactly match g_ascii_tolower(). (Note
- * that this is unlike the old g_strdown(), which modified
- * the string in place.)
- **/
- gchar*
- g_ascii_strdown (const gchar *str,
- gssize len)
- {
- gchar *result, *s;
-
- g_return_val_if_fail (str != NULL, NULL);
- if (len < 0)
- len = strlen (str);
- result = g_strndup (str, len);
- for (s = result; *s; s++)
- *s = g_ascii_tolower (*s);
-
- return result;
- }
- /**
- * g_ascii_strup:
- * @str: a string.
- * @len: length of @str in bytes, or -1 if @str is nul-terminated.
- *
- * Converts all lower case ASCII letters to upper case ASCII letters.
- *
- * Return value: a newly allocated string, with all the lower case
- * characters in @str converted to upper case, with
- * semantics that exactly match g_ascii_toupper(). (Note
- * that this is unlike the old g_strup(), which modified
- * the string in place.)
- **/
- gchar*
- g_ascii_strup (const gchar *str,
- gssize len)
- {
- gchar *result, *s;
- g_return_val_if_fail (str != NULL, NULL);
- if (len < 0)
- len = strlen (str);
- result = g_strndup (str, len);
- for (s = result; *s; s++)
- *s = g_ascii_toupper (*s);
- return result;
- }
- /**
- * g_strdown:
- * @string: the string to convert.
- *
- * Converts a string to lower case.
- *
- * Return value: the string
- *
- * Deprecated:2.2: This function is totally broken for the reasons discussed
- * in the g_strncasecmp() docs - use g_ascii_strdown() or g_utf8_strdown()
- * instead.
- **/
- gchar*
- g_strdown (gchar *string)
- {
- register guchar *s;
-
- g_return_val_if_fail (string != NULL, NULL);
-
- s = (guchar *) string;
-
- while (*s)
- {
- if (isupper (*s))
- *s = tolower (*s);
- s++;
- }
-
- return (gchar *) string;
- }
- /**
- * g_strup:
- * @string: the string to convert.
- *
- * Converts a string to upper case.
- *
- * Return value: the string
- *
- * Deprecated:2.2: This function is totally broken for the reasons discussed
- * in the g_strncasecmp() docs - use g_ascii_strup() or g_utf8_strup() instead.
- **/
- gchar*
- g_strup (gchar *string)
- {
- register guchar *s;
- g_return_val_if_fail (string != NULL, NULL);
- s = (guchar *) string;
- while (*s)
- {
- if (islower (*s))
- *s = toupper (*s);
- s++;
- }
- return (gchar *) string;
- }
- /**
- * g_strreverse:
- * @string: the string to reverse
- *
- * Reverses all of the bytes in a string. For example,
- * <literal>g_strreverse ("abcdef")</literal> will result
- * in "fedcba".
- *
- * Note that g_strreverse() doesn't work on UTF-8 strings
- * containing multibyte characters. For that purpose, use
- * g_utf8_strreverse().
- *
- * Returns: the same pointer passed in as @string
- */
- gchar*
- g_strreverse (gchar *string)
- {
- g_return_val_if_fail (string != NULL, NULL);
- if (*string)
- {
- register gchar *h, *t;
- h = string;
- t = string + strlen (string) - 1;
- while (h < t)
- {
- register gchar c;
- c = *h;
- *h = *t;
- h++;
- *t = c;
- t--;
- }
- }
- return string;
- }
- /**
- * g_ascii_tolower:
- * @c: any character.
- *
- * Convert a character to ASCII lower case.
- *
- * Unlike the standard C library tolower() function, this only
- * recognizes standard ASCII letters and ignores the locale, returning
- * all non-ASCII characters unchanged, even if they are lower case
- * letters in a particular character set. Also unlike the standard
- * library function, this takes and returns a char, not an int, so
- * don't call it on %EOF but no need to worry about casting to #guchar
- * before passing a possibly non-ASCII character in.
- *
- * Return value: the result of converting @c to lower case.
- * If @c is not an ASCII upper case letter,
- * @c is returned unchanged.
- **/
- gchar
- g_ascii_tolower (gchar c)
- {
- return g_ascii_isupper (c) ? c - 'A' + 'a' : c;
- }
- /**
- * g_ascii_toupper:
- * @c: any character.
- *
- * Convert a character to ASCII upper case.
- *
- * Unlike the standard C library toupper() function, this only
- * recognizes standard ASCII letters and ignores the locale, returning
- * all non-ASCII characters unchanged, even if they are upper case
- * letters in a particular character set. Also unlike the standard
- * library function, this takes and returns a char, not an int, so
- * don't call it on %EOF but no need to worry about casting to #guchar
- * before passing a possibly non-ASCII character in.
- *
- * Return value: the result of converting @c to upper case.
- * If @c is not an ASCII lower case letter,
- * @c is returned unchanged.
- **/
- gchar
- g_ascii_toupper (gchar c)
- {
- return g_ascii_islower (c) ? c - 'a' + 'A' : c;
- }
- /**
- * g_ascii_digit_value:
- * @c: an ASCII character.
- *
- * Determines the numeric value of a character as a decimal
- * digit. Differs from g_unichar_digit_value() because it takes
- * a char, so there's no worry about sign extension if characters
- * are signed.
- *
- * Return value: If @c is a decimal digit (according to
- * g_ascii_isdigit()), its numeric value. Otherwise, -1.
- **/
- int
- g_ascii_digit_value (gchar c)
- {
- if (g_ascii_isdigit (c))
- return c - '0';
- return -1;
- }
- /**
- * g_ascii_xdigit_value:
- * @c: an ASCII character.
- *
- * Determines the numeric value of a character as a hexidecimal
- * digit. Differs from g_unichar_xdigit_value() because it takes
- * a char, so there's no worry about sign extension if characters
- * are signed.
- *
- * Return value: If @c is a hex digit (according to
- * g_ascii_isxdigit()), its numeric value. Otherwise, -1.
- **/
- int
- g_ascii_xdigit_value (gchar c)
- {
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- return g_ascii_digit_value (c);
- }
- /**
- * g_ascii_strcasecmp:
- * @s1: string to compare with @s2.
- * @s2: string to compare with @s1.
- *
- * Compare two strings, ignoring the case of ASCII characters.
- *
- * Unlike the BSD strcasecmp() function, this only recognizes standard
- * ASCII letters and ignores the locale, treating all non-ASCII
- * bytes as if they ar…
Large files files are truncated, but you can click here to view the full file