Browse Source

* Add int64 support. Two new functions json_object_net_int64 and

json_object_get_int64. Binary compatibility preserved.
    Eric Haszlakiewicz, EHASZLA at transunion com
    Rui Miguel Silva Seabra, rms at 1407 dot org



git-svn-id: http://svn.metaparadigm.com/svn/json-c/trunk@56 327403b1-1117-474d-bef2-5cb71233fd97
tags/json-c-0.10-20120530
Michael Clark 15 years ago
parent
commit
c4dceae1c5
23 changed files with 569 additions and 40 deletions
  1. +4
    -0
      ChangeLog
  2. +1
    -1
      Doxyfile
  3. +21
    -11
      Makefile.am
  4. +1
    -5
      config.h.in
  5. +21
    -0
      json_inttypes.h
  6. +66
    -6
      json_object.c
  7. +25
    -3
      json_object.h
  8. +2
    -1
      json_object_private.h
  9. +18
    -6
      json_tokener.c
  10. +65
    -0
      json_util.c
  11. +1
    -0
      json_util.h
  12. +12
    -0
      parse_int64.test
  13. +114
    -0
      test-defs.sh
  14. +1
    -1
      test1.c
  15. +44
    -0
      test1.expected
  16. +12
    -0
      test1.test
  17. +1
    -0
      test2.expected
  18. +12
    -0
      test2.test
  19. +11
    -6
      test4.c
  20. +3
    -0
      test4.expected
  21. +12
    -0
      test4.test
  22. +99
    -0
      test_parse_int64.c
  23. +23
    -0
      test_parse_int64.expected

+ 4
- 0
ChangeLog View File

@@ -1,4 +1,8 @@
0.10
* Add int64 support. Two new functions json_object_net_int64 and
json_object_get_int64. Binary compatibility preserved.
Eric Haszlakiewicz, EHASZLA at transunion com
Rui Miguel Silva Seabra, rms at 1407 dot org
* Fix subtle bug in linkhash where lookup could hang after all slots
were filled then successively freed.
Spotted by Jean-Marc Naud, j dash m at newtraxtech dot com


+ 1
- 1
Doxyfile View File

@@ -23,7 +23,7 @@ PROJECT_NAME = json-c
# This could be handy for archiving the generated documentation or
# if some version control system is used.

PROJECT_NUMBER = 0.2
PROJECT_NUMBER = 0.10

# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.


+ 21
- 11
Makefile.am View File

@@ -9,16 +9,17 @@ pkgconfig_DATA = json.pc

libjsonincludedir = $(includedir)/json
libjsoninclude_HEADERS = \
json.h \
arraylist.h \
bits.h \
debug.h \
linkhash.h \
arraylist.h \
printbuf.h \
json_util.h \
json.h \
json_inttypes.h \
json_object.h \
json_object_private.h \
json_tokener.h
json_object_private.h \
json_tokener.h \
json_util.h \
linkhash.h \
printbuf.h

libjson_la_LDFLAGS = -version-info 0:1:0

@@ -31,7 +32,7 @@ libjson_la_SOURCES = \
linkhash.c \
printbuf.c

check_PROGRAMS = test1 test2 test3 test4
check_PROGRAMS = test1 test2 test4 test_parse_int64

test1_SOURCES = test1.c
test1_LDADD = $(lib_LTLIBRARIES)
@@ -39,8 +40,17 @@ test1_LDADD = $(lib_LTLIBRARIES)
test2_SOURCES = test2.c
test2_LDADD = $(lib_LTLIBRARIES)

test3_SOURCES = test3.c
test3_LDADD = $(lib_LTLIBRARIES)

test4_SOURCES = test4.c
test4_LDADD = $(lib_LTLIBRARIES)

test_parse_int64_SOURCES = test_parse_int64.c
test_parse_int64_LDADD = $(lib_LTLIBRARIES)

TESTS = test1.test test2.test test4.test parse_int64.test
EXTRA_DIST += $(TESTS)
testsubdir=testSubDir
TESTS_ENVIRONMENT = top_builddir=$(top_builddir)

distclean-local:
-rm -rf $(testsubdir)


+ 1
- 5
config.h.in View File

@@ -80,10 +80,6 @@
/* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG

/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR

/* Name of package */
#undef PACKAGE

@@ -117,5 +113,5 @@
/* Define to rpl_realloc if the replacement function should be used. */
#undef realloc

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t

+ 21
- 0
json_inttypes.h View File

@@ -0,0 +1,21 @@

#ifndef _json_inttypes_h_
#define _json_inttypes_h_

#if defined(_MSC_VER) && _MSC_VER < 1600

/* Anything less than Visual Studio C++ 10 is missing stdint.h and inttypes.h */
typedef __int64 int64_t;
#define PRId64 "I64d"
#define SCNd64 "I64d"

#else

#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
/* inttypes.h includes stdint.h */

#endif

#endif

+ 66
- 6
json_object.c View File

@@ -20,8 +20,10 @@
#include "printbuf.h"
#include "linkhash.h"
#include "arraylist.h"
#include "json_inttypes.h"
#include "json_object.h"
#include "json_object_private.h"
#include "json_util.h"

#if !HAVE_STRNDUP
char* strndup(const char* str, size_t n);
@@ -41,6 +43,7 @@ static const char* json_type_name[] = {
"object",
"array",
"string",
"int64",
};
#endif /* REFCOUNT_DEBUG */

@@ -304,6 +307,8 @@ boolean json_object_get_boolean(struct json_object *jso)
return jso->o.c_boolean;
case json_type_int:
return (jso->o.c_int != 0);
case json_type_int64:
return (jso->o.c_int64 != 0);
case json_type_double:
return (jso->o.c_double != 0);
case json_type_string:
@@ -322,7 +327,11 @@ static int json_object_int_to_json_string(struct json_object* jso,
return sprintbuf(pb, "%d", jso->o.c_int);
}

struct json_object* json_object_new_int(int i)
static int json_object_int64_to_json_string(struct json_object* jso, struct printbuf *pb) {
return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
}

struct json_object* json_object_new_int(int32_t i)
{
struct json_object *jso = json_object_new(json_type_int);
if(!jso) return NULL;
@@ -331,20 +340,69 @@ struct json_object* json_object_new_int(int i)
return jso;
}

int json_object_get_int(struct json_object *jso)
int32_t json_object_get_int(struct json_object *jso)
{
int cint;

if(!jso) return 0;

enum json_type o_type = jso->o_type;
int64_t cint64 = jso->o.c_int64;

if (o_type == json_type_string)
{
/*
* Parse strings into 64-bit numbers, then use the
* 64-to-32-bit number handling below.
*/
if (json_parse_int64(jso->o.c_string, &cint64) != 0)
return 0; /* whoops, it didn't work. */
o_type = json_type_int64;
}

switch(jso->o_type) {
case json_type_int:
return jso->o.c_int;
case json_type_int64:
/* Make sure we return the correct values for out of range numbers. */
if (cint64 <= INT32_MIN)
return INT32_MIN;
else if (cint64 >= INT32_MAX)
return INT32_MAX;
else
return (int32_t)cint64;
case json_type_double:
return (int32_t)jso->o.c_double;
case json_type_boolean:
return jso->o.c_boolean;
default:
return 0;
}
}

struct json_object* json_object_new_int64(int64_t i)
{
struct json_object *jso = json_object_new(json_type_int64);
if(!jso) return NULL;
jso->_to_json_string = &json_object_int64_to_json_string;
jso->o.c_int64 = i;
return jso;
}

int64_t json_object_get_int64(struct json_object *jso)
{
int64_t cint;

if(!jso) return 0;
switch(jso->o_type) {
case json_type_int:
return (int64_t)jso->o.c_int;
case json_type_int64:
return jso->o.c_int64;
case json_type_double:
return (int)jso->o.c_double;
return (int64_t)jso->o.c_double;
case json_type_boolean:
return jso->o.c_boolean;
case json_type_string:
if(sscanf(jso->o.c_string, "%d", &cint) == 1) return cint;
if (json_parse_int64(jso->o.c_string, &cint) == 0) return cint;
default:
return 0;
}
@@ -378,6 +436,8 @@ double json_object_get_double(struct json_object *jso)
return jso->o.c_double;
case json_type_int:
return jso->o.c_int;
case json_type_int64:
return jso->o.c_int64;
case json_type_boolean:
return jso->o.c_boolean;
case json_type_string:


+ 25
- 3
json_object.h View File

@@ -46,7 +46,8 @@ typedef enum json_type {
json_type_int,
json_type_object,
json_type_array,
json_type_string
json_type_string,
json_type_int64
} json_type;

/* reference counting functions */
@@ -74,6 +75,7 @@ extern void json_object_put(struct json_object *obj);
json_type_object,
json_type_array,
json_type_string,
json_type_int64,
*/
extern int json_object_is_type(struct json_object *obj, enum json_type type);

@@ -87,6 +89,7 @@ extern int json_object_is_type(struct json_object *obj, enum json_type type);
json_type_object,
json_type_array,
json_type_string,
json_type_int64,
*/
extern enum json_type json_object_get_type(struct json_object *obj);

@@ -252,7 +255,15 @@ extern boolean json_object_get_boolean(struct json_object *obj);
* @param i the integer
* @returns a json_object of type json_type_int
*/
extern struct json_object* json_object_new_int(int i);
extern struct json_object* json_object_new_int(int32_t i);


/** Create a new empty json_object of type json_type_int64
* @param i the integer
* @returns a json_object of type json_type_int64
*/
extern struct json_object* json_object_new_int64(int64_t i);


/** Get the int value of a json_object
*
@@ -263,7 +274,18 @@ extern struct json_object* json_object_new_int(int i);
* @param obj the json_object instance
* @returns an int
*/
extern int json_object_get_int(struct json_object *obj);
extern int32_t json_object_get_int(struct json_object *obj);

/** Get the int value of a json_object
*
* The type is coerced to a int64 if the passed object is not a int64.
* double objects will return their int64 conversion. Strings will be
* parsed as an int64. If no conversion exists then 0 is returned.
*
* @param obj the json_object instance
* @returns an int64
*/
extern int64_t json_object_get_int64(struct json_object *obj);


/* double type methods */


+ 2
- 1
json_object_private.h View File

@@ -30,7 +30,8 @@ struct json_object
union data {
boolean c_boolean;
double c_double;
int c_int;
int32_t c_int;
int64_t c_int64;
struct lh_table *c_object;
struct array_list *c_array;
char *c_string;


+ 18
- 6
json_tokener.c View File

@@ -20,14 +20,16 @@
#include <stddef.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>

#include "bits.h"
#include "debug.h"
#include "printbuf.h"
#include "arraylist.h"
#include "json_inttypes.h"
#include "json_object.h"
#include "json_tokener.h"
#include "json_util.h"

#if !HAVE_STRNCASECMP && defined(_MSC_VER)
/* MSC has the version as _strnicmp */
@@ -542,11 +544,21 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
printbuf_memappend_fast(tok->pb, case_start, case_len);
}
{
int numi;
double numd;
if(!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) {
current = json_object_new_int(numi);
} else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
int64_t num64;
double numd;
if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
// Decode the type based on the value range to keep compatibilty
// with code that checks the type of objects. i.e. this:
// json_object_get_type(o) == json_type_int
// will continue to work.
// The other option would be to eliminate any distinction between
// int and int64 types, but that would change the ABI of
// json_object_get_int().
if (num64 < INT32_MAX && num64 > INT32_MIN)
current = json_object_new_int(num64);
else
current = json_object_new_int64(num64);
} else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
current = json_object_new_double(numd);
} else {
tok->err = json_tokener_error_parse_number;


+ 65
- 0
json_util.c View File

@@ -17,6 +17,7 @@
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>

#if HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -48,6 +49,7 @@
#include "bits.h"
#include "debug.h"
#include "printbuf.h"
#include "json_inttypes.h"
#include "json_object.h"
#include "json_tokener.h"
#include "json_util.h"
@@ -120,3 +122,66 @@ int json_object_to_file(char *filename, struct json_object *obj)
close(fd);
return 0;
}

int json_parse_int64(const char *buf, int64_t *retval)
{
int64_t num64;
if (sscanf(buf, "%" SCNd64, &num64) != 1)
{
printf("Failed to parse, sscanf != 1\n");
return 1;
}
const char *buf_skip_space = buf;
int orig_has_neg = 0;
// Skip leading spaces
while (isspace((int)*buf_skip_space) && *buf_skip_space)
buf_skip_space++;
if (*buf_skip_space == '-')
{
buf_skip_space++;
orig_has_neg = 1;
}
// Skip leading zeros
while (*buf_skip_space == '0' && *buf_skip_space)
buf_skip_space++;
if (errno != ERANGE)
{
char buf_cmp[100];
char *buf_cmp_start = buf_cmp;
int recheck_has_neg = 0;
snprintf(buf_cmp_start, sizeof(buf_cmp), "%" PRId64, num64);
if (*buf_cmp_start == '-')
{
recheck_has_neg = 1;
buf_cmp_start++;
}
// No need to skip leading spaces or zeros here.

int buf_cmp_len = strlen(buf_cmp_start);
/**
* If the sign is different, or
* some of the digits are different, or
* there is another digit present in the original string
* then we NOT successfully parsed the value.
*/
if (orig_has_neg != recheck_has_neg ||
strncmp(buf_skip_space, buf_cmp_start, strlen(buf_cmp_start)) != 0 ||
(strlen(buf_skip_space) != buf_cmp_len &&
isdigit(buf_skip_space[buf_cmp_len])
)
)
{
errno = ERANGE;
}
}
if (errno == ERANGE)
{
if (orig_has_neg)
num64 = INT64_MIN;
else
num64 = INT64_MAX;
}
*retval = num64;
return 0;
}

+ 1
- 0
json_util.h View File

@@ -23,6 +23,7 @@ extern "C" {
/* utility functions */
extern struct json_object* json_object_from_file(const char *filename);
extern int json_object_to_file(char *filename, struct json_object *obj);
extern int json_parse_int64(const char *buf, int64_t *retval);

#ifdef __cplusplus
}


+ 12
- 0
parse_int64.test View File

@@ -0,0 +1,12 @@
#!/bin/sh

# Common definitions
if test -z "$srcdir"; then
srcdir="${0%/*}"
test "$srcdir" = "$0" && srcdir=.
test -z "$srcdir" && srcdir=.
fi
. "$srcdir/test-defs.sh"

run_output_test test_parse_int64
exit $?

+ 114
- 0
test-defs.sh View File

@@ -0,0 +1,114 @@

#! /bin/sh

# Make sure srcdir is an absolute path. Supply the variable
# if it does not exist. We want to be able to run the tests
# stand-alone!!
#
srcdir=${srcdir-.}
if test ! -d $srcdir ; then
echo "test-defs.sh: installation error" 1>&2
exit 1
fi

# Use absolute paths
case "$srcdir" in
/* | [A-Za-z]:\\*) ;;
*) srcdir=`\cd $srcdir && pwd` ;;
esac

case "$top_builddir" in
/* | [A-Za-z]:\\*) ;;
*) top_builddir=`\cd ${top_builddir-..} && pwd` ;;
esac

progname=`echo "$0" | sed 's,^.*/,,'`
testname=`echo "$progname" | sed 's,-.*$,,'`
testsubdir=${testsubdir-testSubDir}

# User can set VERBOSE to cause output redirection
case "$VERBOSE" in
[Nn]|[Nn][Oo]|0|"")
VERBOSE=0
exec > /dev/null 2>&1
;;
[Yy]|[Yy][Ee][Ss])
VERBOSE=1
;;
esac

rm -rf "$testsubdir/$progname" > /dev/null 2>&1
mkdir -p "$testsubdir/$progname"
cd "$testsubdir/$progname" \
|| { echo "Cannot make or change into $testsubdir/$progname"; exit 1; }

echo "=== Running test $progname"

CMP="${CMP-cmp}"

use_valgrind=${USE_VALGRIND-1}
valgrind_path=$(which valgrind 2> /dev/null)
if [ -z "${valgrind_path}" -o ! -x "${valgrind_path}" ] ; then
use_valgrind=0
fi

#
# This is a common function to check the results of a test program
# that is intended to generate consistent output across runs.
#
# ${top_builddir} must be set to the top level build directory.
#
# Output will be written to the current directory.
#
# It must be passed the name of the test command to run, which must be present
# in the ${top_builddir} directory.
#
# It will compare the output of running that against <name of command>.expected
#
run_output_test()
{
TEST_COMMAND="$1"

REDIR_OUTPUT="> \"${TEST_COMMAND}.out\""
if [ $VERBOSE -gt 1 ] ; then
REDIR_OUTPUT="| tee \"${TEST_COMMAND}.out\""
fi

if [ $use_valgrind -eq 1 ] ; then
eval valgrind --tool=memcheck \
--trace-children=yes \
--demangle=yes \
--log-file=vg.out \
--leak-check=full \
--show-reachable=yes \
--run-libc-freeres=yes \
"\"${top_builddir}/${TEST_COMMAND}\"" ${REDIR_OUTPUT}
err=$?

else
eval "\"${top_builddir}/${TEST_COMMAND}"\" ${REDIR_OUTPUT}
err=$?
fi

if [ $err -ne 0 ] ; then
echo "ERROR: ${TEST_COMMAND} exited with non-zero exit status: $err" 1>&2
fi

if [ $use_valgrind -eq 1 ] ; then
if ! tail -1 "vg.out" | grep -q "ERROR SUMMARY: 0 errors" ; then
echo "ERROR: valgrind found errors during execution:" 1>&2
cat vg.out
err=1
fi
fi

if ! "$CMP" -s "${top_builddir}/${TEST_COMMAND}.expected" "${TEST_COMMAND}.out" ; then
echo "ERROR: ${TEST_COMMAND} failed:" 1>&2
diff "${top_builddir}/${TEST_COMMAND}.expected" "${TEST_COMMAND}.out" 1>&2
err=1
fi

return $err
}



+ 1
- 1
test1.c View File

@@ -158,7 +158,7 @@ int main(int argc, char **argv)
json_object_put(my_string);
json_object_put(my_int);
json_object_put(my_object);
//json_object_put(my_array);
json_object_put(my_array);

return 0;
}

+ 44
- 0
test1.expected View File

@@ -0,0 +1,44 @@
my_string=
my_string.to_string()="\t"
my_string=\
my_string.to_string()="\\"
my_string=foo
my_string.to_string()="foo"
my_int=9
my_int.to_string()=9
my_array=
[0]=1
[1]=2
[2]=3
[3]=null
[4]=5
my_array.to_string()=[ 1, 2, 3, null, 5 ]
my_object=
abc: 12
foo: "bar"
bool0: false
bool1: true
my_object.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true }
new_obj.to_string()="\u0003"
new_obj.to_string()="foo"
new_obj.to_string()="foo"
new_obj.to_string()="ABC"
new_obj.to_string()=null
new_obj.to_string()=true
new_obj.to_string()=12
new_obj.to_string()=12.300000
new_obj.to_string()=[ "\n" ]
new_obj.to_string()=[ "\nabc\n" ]
new_obj.to_string()=[ null ]
new_obj.to_string()=[ ]
new_obj.to_string()=[ false ]
new_obj.to_string()=[ "abc", null, "def", 12 ]
new_obj.to_string()={ }
new_obj.to_string()={ "foo": "bar" }
new_obj.to_string()={ "foo": "bar", "baz": null, "bool0": true }
new_obj.to_string()={ "foo": [ null, "foo" ] }
new_obj.to_string()={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] }
got error as expected
got error as expected
got error as expected
new_obj.to_string()={ "foo": { "bar": 13 } }

+ 12
- 0
test1.test View File

@@ -0,0 +1,12 @@
#!/bin/sh

# Common definitions
if test -z "$srcdir"; then
srcdir="${0%/*}"
test "$srcdir" = "$0" && srcdir=.
test -z "$srcdir" && srcdir=.
fi
. "$srcdir/test-defs.sh"

run_output_test test1
exit $?

+ 1
- 0
test2.expected View File

@@ -0,0 +1 @@
new_obj.to_string()={ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": [ { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": [ "GML", "XML", "markup" ] } ] } } }

+ 12
- 0
test2.test View File

@@ -0,0 +1,12 @@
#!/bin/sh

# Common definitions
if test -z "$srcdir"; then
srcdir="${0%/*}"
test "$srcdir" = "$0" && srcdir=.
test -z "$srcdir" && srcdir=.
fi
. "$srcdir/test-defs.sh"

run_output_test test2
exit $?

+ 11
- 6
test4.c View File

@@ -4,11 +4,14 @@

#include <stdio.h>
#include <string.h>
#include <json/json_object.h>
#include <json/json_tokener.h>
#include "config.h"

void print_hex( const unsigned char* s) {
const unsigned char *iter = s;
#include "json_inttypes.h"
#include "json_object.h"
#include "json_tokener.h"

void print_hex( const char* s) {
const char *iter = s;
unsigned char ch;
while ((ch = *iter++) != 0) {
if( ',' != ch)
@@ -28,10 +31,10 @@ int main() {
printf("input: %s\n", input);

int strings_match = !strcmp( expected, unjson);
int retval = 0;
if (strings_match) {
printf("JSON parse result is correct: %s\n", unjson);
printf("PASS\n");
return(0);
} else {
printf("JSON parse result doesn't match expected string\n");
printf("expected string bytes: ");
@@ -39,6 +42,8 @@ int main() {
printf("parsed string bytes: ");
print_hex( unjson);
printf("FAIL\n");
return(1);
retval = 1;
}
json_object_put(parse_result);
return retval;
}

+ 3
- 0
test4.expected View File

@@ -0,0 +1,3 @@
input: "\ud840\udd26,\ud840\udd27,\ud800\udd26,\ud800\udd27"
JSON parse result is correct: 𠄦,𠄧,𐄦,𐄧
PASS

+ 12
- 0
test4.test View File

@@ -0,0 +1,12 @@
#!/bin/sh

# Common definitions
if test -z "$srcdir"; then
srcdir="${0%/*}"
test "$srcdir" = "$0" && srcdir=.
test -z "$srcdir" && srcdir=.
fi
. "$srcdir/test-defs.sh"

run_output_test test4
exit $?

+ 99
- 0
test_parse_int64.c View File

@@ -0,0 +1,99 @@

#include <stdio.h>
#include <string.h>

#include "config.h"

#include "json_inttypes.h"
#include "json_util.h"

void checkit(const char *buf)
{
int64_t cint64 = -666;

int retval = json_parse_int64(buf, &cint64);
printf("buf=%s parseit=%d, value=%" PRId64 " \n", buf, retval, cint64);
}

/**
* This test calls json_parse_int64 with a variety of different strings.
* It's purpose is to ensure that the results are consistent across all
* different environments that it might be executed in.
*
* This always exits with a 0 exit value. The output should be compared
* against previously saved expected output.
*/
int main()
{
char buf[100];

checkit("x");

checkit("1");

strcpy(buf, "2147483647"); // aka INT32_MAX
checkit(buf);

strcpy(buf, "-1");
checkit(buf);

strcpy(buf, " -1");
checkit(buf);

strcpy(buf, "00001234");
checkit(buf);

strcpy(buf, "0001234x");
checkit(buf);

strcpy(buf, "-00001234");
checkit(buf);

strcpy(buf, "-00001234x");
checkit(buf);

strcpy(buf, "4294967295"); // aka UINT32_MAX

sprintf(buf, "4294967296"); // aka UINT32_MAX + 1

strcpy(buf, "21474836470"); // INT32_MAX * 10
checkit(buf);

strcpy(buf, "31474836470"); // INT32_MAX * 10 + a bunch
checkit(buf);

strcpy(buf, "-2147483647"); // INT32_MIN + 1
checkit(buf);

strcpy(buf, "-2147483648"); // INT32_MIN
checkit(buf);

strcpy(buf, "-2147483649"); // INT32_MIN - 1
checkit(buf);

strcpy(buf, "-21474836480"); // INT32_MIN * 10
checkit(buf);

strcpy(buf, "9223372036854775807"); // INT64_MAX
checkit(buf);

strcpy(buf, "9223372036854775808"); // INT64_MAX + 1
checkit(buf);

strcpy(buf, "-9223372036854775808"); // INT64_MIN
checkit(buf);

strcpy(buf, "-9223372036854775809"); // INT64_MIN - 1
checkit(buf);

strcpy(buf, "18446744073709551615"); // UINT64_MAX
checkit(buf);

strcpy(buf, "18446744073709551616"); // UINT64_MAX + 1
checkit(buf);

strcpy(buf, "-18446744073709551616"); // -UINT64_MAX
checkit(buf);

return 0;
}

+ 23
- 0
test_parse_int64.expected View File

@@ -0,0 +1,23 @@
Failed to parse, sscanf != 1
buf=x parseit=1, value=-666
buf=1 parseit=0, value=1
buf=2147483647 parseit=0, value=2147483647
buf=-1 parseit=0, value=-1
buf= -1 parseit=0, value=-1
buf=00001234 parseit=0, value=1234
buf=0001234x parseit=0, value=1234
buf=-00001234 parseit=0, value=-1234
buf=-00001234x parseit=0, value=-1234
buf=21474836470 parseit=0, value=21474836470
buf=31474836470 parseit=0, value=31474836470
buf=-2147483647 parseit=0, value=-2147483647
buf=-2147483648 parseit=0, value=-2147483648
buf=-2147483649 parseit=0, value=-2147483649
buf=-21474836480 parseit=0, value=-21474836480
buf=9223372036854775807 parseit=0, value=9223372036854775807
buf=9223372036854775808 parseit=0, value=9223372036854775807
buf=-9223372036854775808 parseit=0, value=-9223372036854775808
buf=-9223372036854775809 parseit=0, value=-9223372036854775808
buf=18446744073709551615 parseit=0, value=9223372036854775807
buf=18446744073709551616 parseit=0, value=9223372036854775807
buf=-18446744073709551616 parseit=0, value=-9223372036854775808

Loading…
Cancel
Save