mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
g_ascii_strtoll
This commit is contained in:
parent
503db3a1fa
commit
49ab402f5a
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
||||
2006-05-16 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* tests/Makefile.am:
|
||||
* tests/strtoll-test.c: Add tests for g_ascii_strtoll()
|
||||
and g_ascii_strtoull().
|
||||
|
||||
* glib/glib.symbols:
|
||||
* glib/gstrfuncs.h:
|
||||
* glib/gstrfuncs.c (g_ascii_strtoll): New function to
|
||||
parse signed 64bit integers like strtoll does.
|
||||
|
||||
* glib/goption.c (parse_int64): Use g_ascii_strtoll(),
|
||||
since strtoll() is C99 and not available on some
|
||||
systems. (#341826, Kazuki Iwamoto)
|
||||
|
||||
2006-05-15 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* configure.in: Bump version
|
||||
|
@ -1,3 +1,18 @@
|
||||
2006-05-16 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* tests/Makefile.am:
|
||||
* tests/strtoll-test.c: Add tests for g_ascii_strtoll()
|
||||
and g_ascii_strtoull().
|
||||
|
||||
* glib/glib.symbols:
|
||||
* glib/gstrfuncs.h:
|
||||
* glib/gstrfuncs.c (g_ascii_strtoll): New function to
|
||||
parse signed 64bit integers like strtoll does.
|
||||
|
||||
* glib/goption.c (parse_int64): Use g_ascii_strtoll(),
|
||||
since strtoll() is C99 and not available on some
|
||||
systems. (#341826, Kazuki Iwamoto)
|
||||
|
||||
2006-05-15 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* configure.in: Bump version
|
||||
|
@ -1,3 +1,7 @@
|
||||
2006-05-16 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/glib-sections.txt: Add g_ascii_strtoll
|
||||
|
||||
2006-05-15 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* === Released 2.11.1 ===
|
||||
|
@ -1119,6 +1119,7 @@ g_strncasecmp
|
||||
g_strreverse
|
||||
|
||||
<SUBSECTION>
|
||||
g_ascii_strtoll
|
||||
g_ascii_strtoull
|
||||
G_ASCII_DTOSTR_BUF_SIZE
|
||||
g_ascii_strtod
|
||||
|
@ -1012,6 +1012,7 @@ g_ascii_formatd
|
||||
g_ascii_strdown G_GNUC_MALLOC
|
||||
g_ascii_strtod
|
||||
g_ascii_strtoull
|
||||
g_ascii_strtoll
|
||||
g_ascii_strup G_GNUC_MALLOC
|
||||
g_ascii_tolower G_GNUC_CONST
|
||||
g_ascii_toupper G_GNUC_CONST
|
||||
|
146
glib/gstrfuncs.c
146
glib/gstrfuncs.c
@ -591,38 +591,11 @@ g_ascii_formatd (gchar *buffer,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
static guint64
|
||||
g_parse_long_long (const gchar *nptr,
|
||||
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.
|
||||
@ -637,7 +610,7 @@ g_ascii_strtoull (const gchar *nptr,
|
||||
#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 negative, overflow;
|
||||
gboolean overflow;
|
||||
guint64 cutoff;
|
||||
guint64 cutlim;
|
||||
guint64 ui64;
|
||||
@ -657,14 +630,15 @@ g_ascii_strtoull (const gchar *nptr,
|
||||
/* Skip white space. */
|
||||
while (ISSPACE (*s))
|
||||
++s;
|
||||
if (!*s)
|
||||
|
||||
if (G_UNLIKELY (!*s))
|
||||
goto noconv;
|
||||
|
||||
/* Check for a sign. */
|
||||
negative = FALSE;
|
||||
*negative = FALSE;
|
||||
if (*s == '-')
|
||||
{
|
||||
negative = TRUE;
|
||||
*negative = TRUE;
|
||||
++s;
|
||||
}
|
||||
else if (*s == '+')
|
||||
@ -721,14 +695,13 @@ g_ascii_strtoull (const gchar *nptr,
|
||||
if (endptr)
|
||||
*endptr = (gchar*) s;
|
||||
|
||||
if (overflow)
|
||||
if (G_UNLIKELY (overflow))
|
||||
{
|
||||
errno = ERANGE;
|
||||
return G_MAXUINT64;
|
||||
}
|
||||
|
||||
/* Return the result of the appropriate sign. */
|
||||
return negative ? -ui64 : ui64;
|
||||
|
||||
return ui64;
|
||||
|
||||
noconv:
|
||||
/* We must handle a special case here: the base is 0 or 16 and the
|
||||
@ -747,6 +720,99 @@ g_ascii_strtoull (const gchar *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, 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, 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
|
||||
return (gint64) result;
|
||||
}
|
||||
|
||||
G_CONST_RETURN gchar*
|
||||
g_strerror (gint errnum)
|
||||
|
@ -130,6 +130,9 @@ gdouble g_ascii_strtod (const gchar *nptr,
|
||||
guint64 g_ascii_strtoull (const gchar *nptr,
|
||||
gchar **endptr,
|
||||
guint base);
|
||||
gint64 g_ascii_strtoll (const gchar *nptr,
|
||||
gchar **endptr,
|
||||
guint base);
|
||||
/* 29 bytes should enough for all possible values that
|
||||
* g_ascii_dtostr can produce.
|
||||
* Then add 10 for good measure */
|
||||
|
@ -100,6 +100,7 @@ test_programs = \
|
||||
strfunc-test \
|
||||
string-test \
|
||||
strtod-test \
|
||||
strtoll-test \
|
||||
thread-test \
|
||||
threadpool-test \
|
||||
tree-test \
|
||||
@ -166,6 +167,7 @@ spawn_test_LDADD = $(progs_ldadd)
|
||||
strfunc_test_LDADD = $(progs_ldadd)
|
||||
string_test_LDADD = $(progs_ldadd)
|
||||
strtod_test_LDADD = $(progs_ldadd) -lm
|
||||
strtoll_test_LDADD = $(progs_ldadd) -lm
|
||||
thread_test_LDADD = $(thread_ldadd)
|
||||
threadpool_test_LDADD = $(thread_ldadd)
|
||||
tree_test_LDADD = $(progs_ldadd)
|
||||
|
67
tests/strtoll-test.c
Normal file
67
tests/strtoll-test.c
Normal file
@ -0,0 +1,67 @@
|
||||
#undef G_DISABLE_ASSERT
|
||||
#undef G_LOG_DOMAIN
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
|
||||
static void
|
||||
test_uint64 (const gchar *str,
|
||||
const gchar *end,
|
||||
gint base,
|
||||
guint64 result,
|
||||
gint error)
|
||||
{
|
||||
guint64 actual;
|
||||
gchar *endptr = NULL;
|
||||
gint err;
|
||||
|
||||
errno = 0;
|
||||
actual = g_ascii_strtoull (str, &endptr, base);
|
||||
err = errno;
|
||||
|
||||
g_assert (actual == result);
|
||||
g_assert (strcmp (end, endptr) == 0);
|
||||
g_assert (err == error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_int64 (const gchar *str,
|
||||
const gchar *end,
|
||||
gint base,
|
||||
gint64 result,
|
||||
gint error)
|
||||
{
|
||||
gint64 actual;
|
||||
gchar *endptr = NULL;
|
||||
gint err;
|
||||
|
||||
errno = 0;
|
||||
actual = g_ascii_strtoll (str, &endptr, base);
|
||||
err = errno;
|
||||
|
||||
g_assert (actual == result);
|
||||
g_assert (strcmp (end, endptr) == 0);
|
||||
g_assert (err == error);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
test_uint64 ("0", "", 10, 0, 0);
|
||||
test_uint64 ("+0", "", 10, 0, 0);
|
||||
test_uint64 ("-0", "", 10, 0, 0);
|
||||
test_uint64 ("18446744073709551615", "", 10, G_MAXUINT64, 0);
|
||||
test_uint64 ("18446744073709551616", "", 10, G_MAXUINT64, ERANGE);
|
||||
test_uint64 ("20xyz", "xyz", 10, 20, 0);
|
||||
test_uint64 ("-1", "", 10, G_MAXUINT64, 0);
|
||||
|
||||
test_int64 ("0", "", 10, 0, 0);
|
||||
test_int64 ("9223372036854775807", "", 10, G_MAXINT64, 0);
|
||||
test_int64 ("9223372036854775808", "", 10, G_MAXINT64, ERANGE);
|
||||
test_int64 ("-9223372036854775808", "", 10, G_MININT64, 0);
|
||||
test_int64 ("-9223372036854775809", "", 10, G_MININT64, ERANGE);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user