Compare commits

...

86 Commits

Author SHA1 Message Date
Max Bruckner
c083421f40 Release version 1.6.0 2017-10-08 23:36:41 +02:00
Max Bruckner
96c33e5abb ENABLE_LOCALES: Actually disable the include as well 2017-10-08 23:28:49 +02:00
Max Bruckner
f437767fa9 Contributors: Add Simon Ricaldone and Casperinous 2017-10-08 23:13:30 +02:00
Max Bruckner
c51a19be51 CONTRIBUTING.md: Fix '4 tabs' -> '4 spaces' 2017-10-08 22:05:19 +02:00
Max Bruckner
97d7347a6e Merge branch 'develop' 2017-10-08 22:05:02 +02:00
Max Bruckner
28328a0b34 Merge pull request #203 from Casperinous/master
Fix for #202 issue.
2017-10-08 21:48:46 +02:00
casperinous
9b960fa870 Small indentation fix in order to follow the contribution rules. 2017-10-08 22:02:52 +03:00
casperinous
4f9e9dfc30 Fix for issue #202, regarding the lack of implementation of the localeconv method in some SDK's.
A macro named `ENABLE_LOCALES` was added and an option with the same name too in the CMakeLists.txt
2017-10-08 21:55:58 +03:00
Max Bruckner
acf80470f8 Update Unity to version v2.4.2
Merge commit 'b7bfe1e91a0b55d72f849944d5a33b7962d7bf51' into develop
2017-09-12 18:30:07 +02:00
Max Bruckner
b7bfe1e91a Squashed 'tests/unity/' changes from 3b69bea..60b13f0
60b13f0 Bump version in preparation of release.
f278c18 Fix bug #288 - invalid line numbers on partial name matches
bdd4cb1 Merge pull request #294 from jlindgren90/master
fcd4883 Fix compiler warning due to reusing symbol 'exp'.
05daf95 Update to match Ruby style guide
7b2ad10 Merge pull request #285 from dpostorivo/gt_lt_asserts
0547aab Merge pull request #291 from jlindgren90/master
2ae2bdb Make code C89-compliant.
dbdd168 Fix test link error.
0e7eb54 Rewrite UnityPrintFloat to match printf("%.6g").
a868b2e Merge pull request #286 from palaviv/fix-UNITY_OUTPUT_FLUSH
e56378e Add UNITY_OUTPUT_CHAR_HEADER_DECLARATION to fixture tests rakefile_helper.rb
ad37302 Add UNITY_OUTPUT_CHAR_HEADER_DECLARATION to tests rakefile_helper.rb
b3de931 Add UNITY_OUTPUT_CHAR_HEADER_DECLARATION to fixture tests Makefile defines
59182c4 Add UNITY_OUTPUT_CHAR_HEADER_DECLARATION to tests Makefile defines
a07d07c Allow specifying custom header declaration
c1bc32d - Generator will not change names by default - Fixed some style issues.
f2fdf1a Added Greater than and Less than asserts from other PR

git-subtree-dir: tests/unity
git-subtree-split: 60b13f0685246b009810aecbffafe17fb665d970
2017-09-12 18:30:07 +02:00
Max Bruckner
afd5d186b7 Release version 1.5.9 2017-09-08 13:54:24 +02:00
Max Bruckner
7456637793 CONTRIBUTORS.md: Add Robin Mallinson 2017-09-08 13:52:15 +02:00
Max Bruckner
d92754cd30 Add valgrind suppressions for ARMv7 2017-09-08 13:25:14 +02:00
Max Bruckner
e4980b65b9 Merge pull request #200 from rmallins/cJSON_ParseWithOpts_fix_ErrorPtr_behaviour
Fix error pointer behaviour of cJSON_ParseWithOpts()
2017-09-08 12:05:19 +02:00
rmallins
629c354390 Rewrite test for cJSON_ParseWithOpts() to expect non-null error
pointer in error case and change code to match new expectations.
2017-09-08 01:22:10 +01:00
rmallins
1b2236a9a6 Improve existing tests showing behaviour of Parse and ParseWithOpts functions. 2017-09-08 01:20:52 +01:00
Max Bruckner
1925d1bbe5 Release version 1.5.8 2017-08-21 11:06:10 +02:00
Max Bruckner
76b705576f Makefile: Fix 'make test'
make test tried to execute the test for cJSON_Utils, which has been
ported to CUnity tests.
2017-08-21 10:58:49 +02:00
Max Bruckner
469a437e2a Add valgrind suppressions for ARVMv7 ArchlinuxARM 2017-07-15 11:59:47 +02:00
Max Bruckner
7e2781a734 Merge pull request #187 from simon-p-r/appveyor
First commit of appveyor
2017-07-15 10:19:14 +02:00
simon-p-r
f0f3e55d48 fixed appveyor script 2017-07-15 09:06:10 +01:00
simon-p-r
2caa884f6a removed x64 Visual Studio 9 2008 build 2017-07-15 09:03:13 +01:00
Max Bruckner
88d66c5da9 Release version 1.5.7 2017-07-12 23:13:14 +02:00
Max Bruckner
954d61e5e7 Fix #189, ensure returns an invalid pointer
If realloc returns NULL, ensure didn't abort but returned
printbuffer.offset instead. If an attacker can control
printbuffer.offset and also make realloc fail at just the right moment,
this would make cJSON potentially write at an arbitrary memory address.
2017-07-12 23:02:31 +02:00
simon-p-r
c6f7f78cbb added copy to powershell script 2017-07-10 10:50:55 +01:00
simon-p-r
824e1b2a99 patch for Visual Studio 9 2008 x64 failed builds 2017-07-10 10:38:21 +01:00
simon-p-r
dd980008f7 add appveyor 2017-07-09 22:31:21 +01:00
Max Bruckner
ecdff7837c Merge pull request #185 from jwilk-forks/spelling
Fix typos in json.dict
2017-07-08 20:16:33 +02:00
Jakub Wilk
a3c2eba991 Fix typos in json.dict 2017-07-08 09:39:06 +02:00
Max Bruckner
bf0bc22a11 CMake: Add ENABLE_SAFE_STACK option 2017-07-05 10:49:32 +02:00
Max Bruckner
5baa77f86c cJSON_Parse{,WithOpts}: Skip UTF-8 (Byte Order Marks) 2017-07-03 22:28:04 +02:00
Max Bruckner
b26e71f960 Merge pull request #181 from DaveGamble/msvc-fixes
MSVC compiler handling
2017-06-28 17:28:52 +02:00
Max Bruckner
7a2615c231 Fix: Check if __GNUCC__ is defined
This has been detected via MSVC's Warning C4668
2017-06-28 17:28:51 +02:00
Max Bruckner
e174831819 CMake: Add custom compiler flags for MSVC 2017-06-28 17:28:51 +02:00
Max Bruckner
ac368e9dfb MSVC: Fix warning about assignment in condition 2017-06-28 17:28:51 +02:00
Max Bruckner
d1c2e2df4a MSVC: workaround for C2322 2017-06-28 17:28:51 +02:00
Max Bruckner
04e27dc8c5 CMake: New option BUILD_SHARED_AND_STATIC_LIBS 2017-06-28 17:28:50 +02:00
Max Bruckner
0d675cb048 MSVC: Disable warning about single line comments in system headers 2017-06-28 17:28:50 +02:00
Max Bruckner
45e1278acb tests/print_number: Add test with 17 digits of precision 2017-06-28 17:28:50 +02:00
Max Bruckner
217ab02612 cJSON_Utils: Guard gcc pragmas with a check for __GCC__ 2017-06-28 17:28:50 +02:00
Max Bruckner
e872d40223 MSVC: Disable deprecation warnings for C89 functions
C89 sadly doesn't provide safe alternatives for strcpy, sprintf and the
like.
2017-06-28 17:28:50 +02:00
Max Bruckner
21733eb02e tests/print_number: Use proper double literals 2017-06-28 17:28:49 +02:00
Max Bruckner
a9ce4e6bbc Add warning -Wswitch-enum 2017-06-28 17:28:49 +02:00
Max Bruckner
eb8c0baa3b Add warning -Wused-but-marked-unused 2017-06-28 17:28:49 +02:00
Max Bruckner
4e0c119391 Add warning -Wmissing-variable-declarations 2017-06-28 17:28:49 +02:00
Max Bruckner
38b2f40a9a Add warning -Wunused-macro 2017-06-28 17:28:49 +02:00
Max Bruckner
d3bc571a38 Release Version 1.5.6 2017-06-28 17:25:14 +02:00
Max Bruckner
48eaecd172 Merge pull request #183 from FSMaxB/null-pointer-fixes
Null pointer fixes
2017-06-28 16:13:56 +02:00
Max Bruckner
18ad8a8770 misc_utils_tests: call all utils function with NULL pointers 2017-06-28 16:01:20 +02:00
Max Bruckner
93227319f0 handle null pointers: cJSONUtils_GeneratePatchesCaseSensitive 2017-06-28 16:00:59 +02:00
Max Bruckner
f0c1b896ba handle null pointers: cJSONUtils_GeneratePatches 2017-06-28 16:00:41 +02:00
Max Bruckner
2d252ae595 handle null pointer: compose_patch 2017-06-28 16:00:14 +02:00
Max Bruckner
c46c4d1559 handle null pointer: sort_object 2017-06-28 15:59:53 +02:00
Max Bruckner
1af74c8cc1 handle null pointer: get_item_from_pointer 2017-06-28 15:58:58 +02:00
Max Bruckner
9bdf19fde1 handle null pointer: cJSONUtils_FindPointerFromObjectTo 2017-06-28 15:58:22 +02:00
Max Bruckner
bdd5ff7ad6 misc_tests: Call all functions with NULL pointers 2017-06-28 14:22:42 +02:00
Max Bruckner
24ea388dcf handle null pointers: cJSON_Minify 2017-06-28 14:22:36 +02:00
Max Bruckner
39745c9c75 handle null pointers: cJSON_ReplaceItemViaPointer 2017-06-28 14:22:29 +02:00
Max Bruckner
9585c38d5a handle null pointers: cJSON_CreateStringArray 2017-06-28 14:22:22 +02:00
Max Bruckner
c268e77b21 handle null pointers: cJSON_CreateDoubleArray 2017-06-28 14:22:15 +02:00
Max Bruckner
9f745a2251 handle null pointers: cJSON_CreateFloatArray 2017-06-28 14:22:07 +02:00
Max Bruckner
010e31f2f2 handle null pointers: cJSON_CreateIntArray 2017-06-28 14:21:55 +02:00
Max Bruckner
8ea37fce01 handle null pointers: replace_item_in_object 2017-06-28 14:21:48 +02:00
Max Bruckner
b2fe02712d handle null pointers: cJSON_AddItemReferenceToObject 2017-06-28 14:21:42 +02:00
Max Bruckner
c179509b31 handle null pointers: cJSON_AddItemReferenceToArray 2017-06-28 14:21:34 +02:00
Max Bruckner
46c4f55c94 handle null pointers: cJSON_AddItemToObjectCS 2017-06-28 14:21:26 +02:00
Max Bruckner
90ff72c8bb handle null pointers: create_reference
Also fixes a potential memory leak
2017-06-28 14:21:09 +02:00
Max Bruckner
e9d1de24cf handle null pointers: cJSON_GetArraySize 2017-06-28 14:20:58 +02:00
Max Bruckner
56f2bc6f3e handle null pointers: cJSON_PrintPreallocated 2017-06-28 14:20:47 +02:00
Max Bruckner
cdc35ebf88 handle null pointers: cJSON_AddItemToObject 2017-06-28 14:20:34 +02:00
Max Bruckner
90a46eaccd cJSON.h: Move cJSON_ParseWithOpts after cJSON_Parse 2017-06-27 23:10:19 +02:00
Max Bruckner
2a3a313f83 cJSON_PrintBuffered: Fix potential memory leak 2017-06-27 23:10:19 +02:00
Max Bruckner
a2a2411b12 Release version 1.5.5 2017-06-14 18:07:25 +02:00
Max Bruckner
03ba72faec cJSON_Compare: Fix comparison of objects
It did consider two arrays equal if one is a subset of te other one,
which is incorrect.

See #180
2017-06-14 17:48:56 +02:00
Max Bruckner
569aa060c6 cJSON_Compare: Fix comparison of arrays
It did consider two arrays equal if one is a prefix of the other one,
which is incorrect.

See #180
2017-06-14 17:48:56 +02:00
Max Bruckner
b9cc911831 cJSON_Utils: Fix case sensitivity handling when adding to object 2017-06-14 17:48:56 +02:00
Max Bruckner
9abe75e072 cJSON_Utils: Fix get_item_from_pointer
Accessing nested arrays didn't work as intended.
2017-06-14 17:48:55 +02:00
Max Bruckner
9189b3322a Release v1.5.4 2017-06-04 21:31:45 +02:00
Max Bruckner
bfbd8fe0d8 tests/parse_hex4: Fix GCC 7 compiler warning (fixes #179) 2017-06-04 21:29:14 +02:00
Max Bruckner
38b44a298d Squashed 'tests/unity/' changes from f96c055..3b69bea
3b69bea Merge pull request #284 from rmja/patch-1
aef3679 Fixed UNITY_TEST_ASSERT_EACH_EQUAL_*

git-subtree-dir: tests/unity
git-subtree-split: 3b69beaa58efc41bbbef70a32a46893cae02719d
2017-06-04 19:36:46 +02:00
Max Bruckner
82295f9e4f Update Unity 2017-06-04 19:36:46 +02:00
Max Bruckner
00d5e225a6 Release version 1.5.3 2017-05-22 22:59:32 +02:00
Max Bruckner
9ecc96878f fix #174: cJSON_ReplaceItemInObject doesn't copy name 2017-05-22 22:55:05 +02:00
Max Bruckner
3efee9fda8 CONTRIBUTORS: Dōngwén Huáng: Add Tones to Pin Yin 2017-05-11 10:16:08 +02:00
Max Bruckner
71a7b64860 README: Small improvements 2017-05-11 10:11:43 +02:00
Max Bruckner
ddf268b074 cJSON.h: Document cJSON_ArrayForEach for objects 2017-05-10 13:17:38 +02:00
39 changed files with 1664 additions and 383 deletions

View File

@@ -15,7 +15,7 @@ Coding Style
------------
The coding style has been discussed in [#24](https://github.com/DaveGamble/cJSON/issues/24). The basics are:
* Use 4 tabs for indentation
* Use 4 spaces for indentation
* No oneliners (conditions, loops, variable declarations ...)
* Always use parenthesis for control structures
* Don't implicitly rely on operator precedence, use round brackets in expressions. e.g. `(a > b) && (c < d)` instead of `a>b && c<d`

1
.gitignore vendored
View File

@@ -13,3 +13,4 @@ cJSON_test_utils
libcjson.so.*
libcjson_utils.so.*
*.orig
.vscode

View File

@@ -23,6 +23,6 @@ addons:
script:
- mkdir build
- cd build
- cmake .. -DENABLE_CJSON_UTILS=On -DENABLE_VALGRIND="${VALGRIND}" -DENABLE_SANITIZERS="${SANITIZERS}"
- cmake .. -DENABLE_CJSON_UTILS=On -DENABLE_VALGRIND="${VALGRIND}" -DENABLE_SAFE_STACK="${VALGRIND}" -DENABLE_SANITIZERS="${SANITIZERS}"
- make
- make test CTEST_OUTPUT_ON_FAILURE=On

View File

@@ -1,3 +1,63 @@
1.6.0
=====
Features:
---------
* You can now build cJSON as both shared and static library at once with CMake using `-DBUILD_SHARED_AND_STATIC_LIBS=On`, see #178
* UTF-8 byte order marks are now ignored, see #184
* Locales can now be disabled with the option `-DENABLE_LOCALES=Off`, see #202, thanks @Casperinous
* Better support for MSVC and Visual Studio
Other Changes:
--------------
* Add the new warnings `-Wswitch-enum`, `-Wused-but-makred-unused`, `-Wmissing-variable-declarations`, `-Wunused-macro`
* More number printing tests.
* Continuous integration testing with AppVeyor (semi automatic at this point), thanks @simon-p-r
1.5.9
=====
* Set the global error pointer even if `return_parse_end` is passed to `cJSON_ParseWithOpts`. See #200, thanks @rmallins
1.5.8
=====
* Fix `make test` in the Makefile, thanks @YanhaoMo for reporting this (#195)
1.5.7
=====
Fixes:
------
* Fix a bug where realloc failing would return a pointer to an invalid memory address. This is a security issue as it could potentially be used by an attacker to write to arbitrary memory addresses. (see #189), fixed in (954d61e5e7cb9dc6c480fc28ac1cdceca07dd5bd), big thanks @timothyjohncarney for reporting this issue
* Fix a spelling mistake in the AFL fuzzer dictionary (#185), thanks @jwilk
1.5.6
=====
Fixes:
------
* Make cJSON a lot more tolerant about passing NULL pointers to its functions, it should now fail safely instead of dereferencing the pointer. (#183) Thanks @msichal for reporting #182
1.5.5
=====
Fixes:
------
* Fix pointers to nested arrays in cJSON_Utils (9abe75e072050f34732a7169740989a082b65134)
* Fix an error with case sensitivity handling in cJSON_Utils (b9cc911831b0b3e1bb72f142389428e59f882b38)
* Fix cJSON_Compare for arrays that are prefixes of the other and objects that are a subset of the other (03ba72faec115160d1f3aea5582d9b6af5d3e473) See #180, thanks @zhengqb for reporting
1.5.4
=====
Fixes:
------
* Fix build with GCC 7.1.1 and optimization level `-O2` (bfbd8fe0d85f1dd21e508748fc10fc4c27cc51be)
Other Changes:
--------------
* Update [Unity](https://github.com/ThrowTheSwitch/Unity) to 3b69beaa58efc41bbbef70a32a46893cae02719d
1.5.3
=====
Fixes:
------
* Fix `cJSON_ReplaceItemInObject` not keeping the name of an item (#174)
1.5.2
=====
Fixes:

View File

@@ -6,8 +6,8 @@ include(GNUInstallDirs)
project(cJSON C)
set(PROJECT_VERSION_MAJOR 1)
set(PROJECT_VERSION_MINOR 5)
set(PROJECT_VERSION_PATCH 2)
set(PROJECT_VERSION_MINOR 6)
set(PROJECT_VERSION_PATCH 0)
set(CJSON_VERSION_SO 1)
set(CJSON_UTILS_VERSION_SO 1)
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
@@ -16,32 +16,46 @@ set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT
set(custom_compiler_flags)
include(CheckCCompilerFlag)
option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags for Clang and GCC" ON)
option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags" ON)
if (ENABLE_CUSTOM_COMPILER_FLAGS)
list(APPEND custom_compiler_flags
-std=c89
-pedantic
-Wall
-Wextra
-Werror
-Wstrict-prototypes
-Wwrite-strings
-Wshadow
-Winit-self
-Wcast-align
-Wformat=2
-Wmissing-prototypes
-Wstrict-overflow=2
-Wcast-qual
-Wundef
-Wswitch-default
-Wconversion
-Wc++-compat
-fstack-protector-strong
-Wcomma
-Wdouble-promotion
-Wparentheses
if (("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU"))
list(APPEND custom_compiler_flags
-std=c89
-pedantic
-Wall
-Wextra
-Werror
-Wstrict-prototypes
-Wwrite-strings
-Wshadow
-Winit-self
-Wcast-align
-Wformat=2
-Wmissing-prototypes
-Wstrict-overflow=2
-Wcast-qual
-Wundef
-Wswitch-default
-Wconversion
-Wc++-compat
-fstack-protector-strong
-Wcomma
-Wdouble-promotion
-Wparentheses
-Wformat-overflow
-Wunused-macros
-Wmissing-variable-declarations
-Wused-but-marked-unused
-Wswitch-enum
)
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
list(APPEND custom_compiler_flags
/GS
/Za
/sdl
/W4
)
endif()
endif()
option(ENABLE_SANITIZERS "Enables AddressSanitizer and UndefinedBehaviorSanitizer." OFF)
@@ -59,6 +73,16 @@ if (ENABLE_SANITIZERS)
)
endif()
option(ENABLE_SAFE_STACK "Enables the SafeStack instrumentation pass by the Code Pointer Integrity Project" OFF)
if (ENABLE_SAFE_STACK)
if (ENABLE_SANITIZERS)
message(FATAL_ERROR "ENABLE_SAFE_STACK cannot be used in combination with ENABLE_SANITIZERS")
endif()
list(APPEND custom_compiler_flags
-fsanitize=safe-stack
)
endif()
option(ENABLE_PUBLIC_SYMBOLS "Export library symbols." On)
if (ENABLE_PUBLIC_SYMBOLS)
list(APPEND custom_compiler_flags -fvisibility=hidden)
@@ -98,7 +122,17 @@ set(CJSON_LIB cjson)
file(GLOB HEADERS cJSON.h)
set(SOURCES cJSON.c)
add_library("${CJSON_LIB}" "${HEADERS}" "${SOURCES}")
option(BUILD_SHARED_AND_STATIC_LIBS "Build both shared and static libraries" Off)
if (NOT BUILD_SHARED_AND_STATIC_LIBS)
add_library("${CJSON_LIB}" "${HEADERS}" "${SOURCES}")
else()
# See https://cmake.org/Wiki/CMake_FAQ#How_do_I_make_my_shared_and_static_libraries_have_the_same_root_name.2C_but_different_suffixes.3F
add_library("${CJSON_LIB}" SHARED "${HEADERS}" "${SOURCES}")
add_library("${CJSON_LIB}-static" STATIC "${HEADERS}" "${SOURCES}")
set_target_properties("${CJSON_LIB}-static" PROPERTIES OUTPUT_NAME "${CJSON_LIB}")
set_target_properties("${CJSON_LIB}-static" PROPERTIES PREFIX "lib")
endif()
if (NOT WIN32)
target_link_libraries("${CJSON_LIB}" m)
endif()
@@ -109,6 +143,9 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson.pc.in"
install(FILES cJSON.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(TARGETS "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${CJSON_LIB}")
if (BUILD_SHARED_AND_STATIC_LIBS)
install(TARGETS "${CJSON_LIB}-static" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
if(ENABLE_TARGET_EXPORT)
# export library information for CMake projects
install(EXPORT "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cJSON")
@@ -127,13 +164,25 @@ if(ENABLE_CJSON_UTILS)
file(GLOB HEADERS_UTILS cJSON_Utils.h)
set(SOURCES_UTILS cJSON_Utils.c)
add_library("${CJSON_UTILS_LIB}" "${HEADERS_UTILS}" "${SOURCES_UTILS}")
target_link_libraries("${CJSON_UTILS_LIB}" "${CJSON_LIB}")
if (NOT BUILD_SHARED_AND_STATIC_LIBS)
add_library("${CJSON_UTILS_LIB}" "${HEADERS_UTILS}" "${SOURCES_UTILS}")
target_link_libraries("${CJSON_UTILS_LIB}" "${CJSON_LIB}")
else()
add_library("${CJSON_UTILS_LIB}" SHARED "${HEADERS_UTILS}" "${SOURCES_UTILS}")
target_link_libraries("${CJSON_UTILS_LIB}" "${CJSON_LIB}")
add_library("${CJSON_UTILS_LIB}-static" STATIC "${HEADERS_UTILS}" "${SOURCES_UTILS}")
target_link_libraries("${CJSON_UTILS_LIB}-static" "${CJSON_LIB}-static")
set_target_properties("${CJSON_UTILS_LIB}-static" PROPERTIES OUTPUT_NAME "${CJSON_UTILS_LIB}")
set_target_properties("${CJSON_UTILS_LIB}-static" PROPERTIES PREFIX "lib")
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson_utils.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" @ONLY)
install(TARGETS "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${CJSON_UTILS_LIB}")
if (BUILD_SHARED_AND_STATIC_LIBS)
install(TARGETS "${CJSON_UTILS_LIB}-static" DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
install(FILES cJSON_Utils.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
if(ENABLE_TARGET_EXPORT)
@@ -185,5 +234,11 @@ if(ENABLE_CJSON_TEST)
DEPENDS ${TEST_CJSON})
endif()
# Enable the use of locales
option(ENABLE_LOCALES "Enable the use of locales" ON)
if(ENABLE_LOCALES)
add_definitions(-DENABLE_LOCALES)
endif()
add_subdirectory(tests)
add_subdirectory(fuzzing)

View File

@@ -1,27 +1,30 @@
Contributors
============
Original Author: [Dave Gamble](https://github.com/DaveGamble)
Current Maintainer: [Max Bruckner](https://github.com/FSMaxB)
* [Ajay Bhargav](https://github.com/ajaybhargav)
* [Alper Akcan](https://github.com/alperakcan)
* [Anton Sergeev](https://github.com/anton-sergeev)
* [Christian Schulze](https://github.com/ChristianSch)
* [Dave Gamble](https://github.com/DaveGamble)
* [Casperinous](https://github.com/Casperinous)
* [Debora Grosse](https://github.com/DeboraG)
* [dieyushi](https://github.com/dieyushi)
* [Dongwen Huang (黄东文)](https://github.com/DongwenHuang)
* [Dōngwén Huáng (黄东文)](https://github.com/DongwenHuang)
* Eswar Yaganti
* [Evan Todd](https://github.com/etodd)
* [Fabrice Fontaine](https://github.com/ffontaine)
* Ian Mobley
* Irwan Djadjadi
* [IvanVoid](https://github.com/npi3pak)
* [Jakub Wilk](https://github.com/jwilk)
* [Jiri Zouhar](https://github.com/loigu)
* [Jonathan Fether](https://github.com/jfether)
* [Julián Vásquez](https://github.com/juvasquezg)
* [Kevin Branigan](https://github.com/kbranigan)
* [Kyle Chisholm](https://github.com/ChisholmKyle)
* [Linus Wallgren](https://github.com/ecksun)
* [Max Bruckner](https://github.com/FSMaxB)
* Mike Pontillo
* [Mike Jerris](https://github.com/mjerris)
* [Mike Robinson](https://github.com/mhrobinson)
@@ -29,9 +32,11 @@ Contributors
* [Pawel Winogrodzki](https://github.com/PawelWMS)
* [prefetchnta](https://github.com/prefetchnta)
* [Rafael Leal Dias](https://github.com/rafaeldias)
* [Robin Mallinson](https://github.com/rmallins)
* [Rod Vagg](https://github.com/rvagg)
* [Roland Meertens](https://github.com/rmeertens)
* [Romain Porte](https://github.com/MicroJoe)
* [Simon Ricaldone](https://github.com/simon-p-r)
* [Stephan Gatzka](https://github.com/gatzka)
* [Weston Schmidt](https://github.com/schmidtw)

View File

@@ -8,7 +8,7 @@ CJSON_TEST_SRC = cJSON.c test.c
LDLIBS = -lm
LIBVERSION = 1.5.2
LIBVERSION = 1.6.0
CJSON_SOVERSION = 1
UTILS_SOVERSION = 1
@@ -66,11 +66,10 @@ shared: $(CJSON_SHARED) $(UTILS_SHARED)
static: $(CJSON_STATIC) $(UTILS_STATIC)
tests: $(CJSON_TEST) $(UTILS_TEST)
tests: $(CJSON_TEST)
test: tests
./$(CJSON_TEST)
./$(UTILS_TEST)
.c.o:
$(CC) -c $(R_CFLAGS) $<
@@ -150,4 +149,4 @@ clean:
$(RM) $(CJSON_OBJ) $(UTILS_OBJ) #delete object files
$(RM) $(CJSON_SHARED) $(CJSON_SHARED_VERSION) $(CJSON_SHARED_SO) $(CJSON_STATIC) #delete cJSON
$(RM) $(UTILS_SHARED) $(UTILS_SHARED_VERSION) $(UTILS_SHARED_SO) $(UTILS_STATIC) #delete cJSON_Utils
$(RM) $(CJSON_TEST) $(UTILS_TEST) #delete tests
$(RM) $(CJSON_TEST) #delete test

View File

@@ -85,11 +85,14 @@ You can change the build process with a list of different options that you can p
* `-DENABLE_CJSON_TEST=On`: Enable building the tests. (on by default)
* `-DENABLE_CJSON_UTILS=On`: Enable building cJSON_Utils. (off by default)
* `-DENABLE_TARGET_EXPORT=On`: Enable the export of CMake targets. Turn off if it makes problems. (on by default)
* `-DENABLE_CUSTOM_COMPILER_FLAGS=On`: Enable custom compiler flags (currently for Clang and GCC). Turn off if it makes problems. (on by default)
* `-DENABLE_CUSTOM_COMPILER_FLAGS=On`: Enable custom compiler flags (currently for Clang, GCC and MSVC). Turn off if it makes problems. (on by default)
* `-DENABLE_VALGRIND=On`: Run tests with [valgrind](http://valgrind.org). (off by default)
* `-DENABLE_SANITIZERS=On`: Compile cJSON with [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) and [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) enabled (if possible). (off by default)
* `-DENABLE_SAFE_STACK`: Enable the [SafeStack](https://clang.llvm.org/docs/SafeStack.html) instrumentation pass. Currently only works with the Clang compiler. (off by default)
* `-DBUILD_SHARED_LIBS=On`: Build the shared libraries. (on by default)
* `-DBUILD_SHARED_AND_STATIC_LIBS=On`: Build both shared and static libraries. (off by default)
* `-DCMAKE_INSTALL_PREFIX=/usr`: Set a prefix for the installation.
* `-DENABLE_LOCALES=On`: Enable the usage of localeconv method. ( on by default )
If you are packaging cJSON for a distribution of Linux, you would probably take these steps for example:
```
@@ -383,17 +386,17 @@ cJSON doesn't support strings that contain the zero character `'\0'` or `\u0000`
#### Character Encoding
cJSON only supports UTF-8 encoded input and will always produce UTF-8 as output (If the input contained invalid UTF-8, it will most likely propagate it through to the output, thereby making the output non-valid UTF-8).
cJSON only supports UTF-8 encoded input. In most cases it doesn't reject invalid UTF-8 as input though, it just propagates it through as is. As long as the input doesn't contain invalid UTF-8, the output will always be valid UTF-8.
#### C Standard
cJSON is written in ANSI C (or C89, C90). If your compiler or C library doesn't follow this standard, correct behavior is not guaranteed.
NOTE: ANSI C is not C++ therefore it shouldn't be compiled by a C++ compiler. You can compile it with a C compiler and link it with your C++ code however. Although compiling with a C++ compiler might work, correct behavior is not guaranteed.
NOTE: ANSI C is not C++ therefore it shouldn't be compiled with a C++ compiler. You can compile it with a C compiler and link it with your C++ code however. Although compiling with a C++ compiler might work, correct behavior is not guaranteed.
#### Floating Point Numbers
cJSON does not officially support any `double` implementations other than IEE754 double precision floating point numbers. It might still work with other implementations but bugs with these will be considered invalid.
cJSON does not officially support any `double` implementations other than IEEE754 double precision floating point numbers. It might still work with other implementations but bugs with these will be considered invalid.
The maximum length of a floating point literal that cJSON supports is currently 63 characters.
@@ -417,3 +420,4 @@ When cJSON was originally created, it didn't follow the JSON standard and didn't
# Enjoy cJSON!
- Dave Gamble, Aug 2009
- [cJSON contributors](CONTRIBUTORS.md)

86
appveyor.yml Normal file
View File

@@ -0,0 +1,86 @@
os: Visual Studio 2015
# ENABLE_CUSTOM_COMPILER_FLAGS - on by default
# ENABLE_SANITIZERS - off by default
# ENABLE_PUBLIC_SYMBOLS - on by default
# BUILD_SHARED_LIBS - on by default
# ENABLE_TARGET_EXPORT - on by default
# ENABLE_CJSON_UTILS - off by default
# ENABLE_CJSON_TEST -on by default
# ENABLE_VALGRIND - off by default
# ENABLE_FUZZING - off by default
environment:
matrix:
- GENERATOR: "Visual Studio 14 2015"
BUILD_SHARED_LIBS: ON
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 14 2015"
BUILD_SHARED_LIBS: OFF
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 12 2013"
BUILD_SHARED_LIBS: ON
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 12 2013"
BUILD_SHARED_LIBS: OFF
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 11 2012"
BUILD_SHARED_LIBS: ON
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 11 2012"
BUILD_SHARED_LIBS: OFF
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 10 2010"
BUILD_SHARED_LIBS: ON
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 10 2010"
BUILD_SHARED_LIBS: OFF
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 9 2008"
BUILD_SHARED_LIBS: ON
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
- GENERATOR: "Visual Studio 9 2008"
BUILD_SHARED_LIBS: OFF
ENABLE_CJSON_TEST: OFF
ENABLE_CJSON_UTILS: ON
platform:
- x86
- x64
matrix:
exclude:
- platform: x64
GENERATOR: "Visual Studio 9 2008"
configuration:
- Release
build_script:
- ps: if($env:PLATFORM -eq "x64") { $env:CMAKE_GEN_SUFFIX=" Win64" }
- cmake "-G%GENERATOR%%CMAKE_GEN_SUFFIX%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% -DENABLE_CJSON_TEST=%ENABLE_CJSON_TEST% -H. -Bbuild
- cmake --build build --config "%CONFIGURATION%"
on_failure:
- ps: if(Test-Path builds/CMakeFiles/CMakeOutput.log) { cat builds/CMakeFiles/CMakeOutput.log }
- ps: if(Test-Path builds/CMakeFiles/CMakeError.log) { cat builds/CMakeFiles/CMakeError.log }

212
cJSON.c
View File

@@ -23,9 +23,19 @@
/* cJSON */
/* JSON parser in C. */
/* disable warnings about old C89 functions in MSVC */
#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
#define _CRT_SECURE_NO_DEPRECATE
#endif
#ifdef __GNUC__
#pragma GCC visibility push(default)
#endif
#if defined(_MSC_VER)
#pragma warning (push)
/* disable warning about single line comments in system headers */
#pragma warning (disable : 4001)
#endif
#include <string.h>
#include <stdio.h>
@@ -34,8 +44,14 @@
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include <locale.h>
#ifdef ENABLE_LOCALES
#include <locale.h>
#endif
#if defined(_MSC_VER)
#pragma warning (pop)
#endif
#ifdef __GNUC__
#pragma GCC visibility pop
#endif
@@ -58,7 +74,7 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
}
/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 5) || (CJSON_VERSION_PATCH != 2)
#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 6) || (CJSON_VERSION_PATCH != 0)
#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
#endif
@@ -101,7 +117,27 @@ typedef struct internal_hooks
void *(*reallocate)(void *pointer, size_t size);
} internal_hooks;
static internal_hooks global_hooks = { malloc, free, realloc };
#if defined(_MSC_VER)
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
static void *internal_malloc(size_t size)
{
return malloc(size);
}
static void internal_free(void *pointer)
{
free(pointer);
}
static void *internal_realloc(void *pointer, size_t size)
{
return realloc(pointer, size);
}
#else
#define internal_malloc malloc
#define internal_free free
#define internal_realloc realloc
#endif
static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc };
static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks)
{
@@ -114,7 +150,8 @@ static unsigned char* cJSON_strdup(const unsigned char* string, const internal_h
}
length = strlen((const char*)string) + sizeof("");
if (!(copy = (unsigned char*)hooks->allocate(length)))
copy = (unsigned char*)hooks->allocate(length);
if (copy == NULL)
{
return NULL;
}
@@ -193,8 +230,12 @@ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
/* get the decimal point character of the current locale */
static unsigned char get_decimal_point(void)
{
#ifdef ENABLE_LOCALES
struct lconv *lconv = localeconv();
return (unsigned char) lconv->decimal_point[0];
#else
return '.';
#endif
}
typedef struct
@@ -208,7 +249,6 @@ typedef struct
/* check if the given size is left to read in a given parse buffer (starting with 1) */
#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
#define cannot_read(buffer, size) (!can_read(buffer, size))
/* check if the buffer can be accessed at the given index (starting with 0) */
#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
@@ -377,6 +417,14 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
{
/* reallocate with realloc if available */
newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
if (newbuffer == NULL)
{
p->hooks.deallocate(p->buffer);
p->length = 0;
p->buffer = NULL;
return NULL;
}
}
else
{
@@ -925,6 +973,22 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer)
return buffer;
}
/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
{
if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0))
{
return NULL;
}
if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0))
{
buffer->offset += 3;
}
return buffer;
}
/* Parse an object - create a new root, and populate. */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)
{
@@ -951,7 +1015,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return
goto fail;
}
if (!parse_value(item, buffer_skip_whitespace(&buffer)))
if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer))))
{
/* parse failure. ep is set. */
goto fail;
@@ -998,10 +1062,8 @@ fail:
{
*return_parse_end = (const char*)local_error.json + local_error.position;
}
else
{
global_error = local_error;
}
global_error = local_error;
}
return NULL;
@@ -1111,6 +1173,7 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON
if (!print_value(item, &p))
{
global_hooks.deallocate(p.buffer);
return NULL;
}
@@ -1121,7 +1184,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const i
{
printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
if (len < 0)
if ((len < 0) || (buf == NULL))
{
return false;
}
@@ -1188,7 +1251,6 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf
return parse_object(item, input_buffer);
}
return false;
}
@@ -1652,17 +1714,25 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out
/* Get Array size/item / object item. */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
{
cJSON *c = array->child;
size_t i = 0;
while(c)
cJSON *child = NULL;
size_t size = 0;
if (array == NULL)
{
i++;
c = c->next;
return 0;
}
child = array->child;
while(child != NULL)
{
size++;
child = child->next;
}
/* FIXME: Can overflow here. Cannot be fixed without breaking the API */
return (int)i;
return (int)size;
}
static cJSON* get_array_item(const cJSON *array, size_t index)
@@ -1747,16 +1817,23 @@ static void suffix_object(cJSON *prev, cJSON *item)
/* Utility for handling references. */
static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks)
{
cJSON *ref = cJSON_New_Item(hooks);
if (!ref)
cJSON *reference = NULL;
if (item == NULL)
{
return NULL;
}
memcpy(ref, item, sizeof(cJSON));
ref->string = NULL;
ref->type |= cJSON_IsReference;
ref->next = ref->prev = NULL;
return ref;
reference = cJSON_New_Item(hooks);
if (reference == NULL)
{
return NULL;
}
memcpy(reference, item, sizeof(cJSON));
reference->string = NULL;
reference->type |= cJSON_IsReference;
reference->next = reference->prev = NULL;
return reference;
}
/* Add item to array/object. */
@@ -1789,13 +1866,18 @@ CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item)
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
{
if (item == NULL)
{
return;
}
/* call cJSON_AddItemToObjectCS for code reuse */
cJSON_AddItemToObjectCS(object, (char*)cJSON_strdup((const unsigned char*)string, &global_hooks), item);
/* remove cJSON_StringIsConst flag */
item->type &= ~cJSON_StringIsConst;
}
#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
#pragma GCC diagnostic push
#endif
#ifdef __GNUC__
@@ -1805,7 +1887,7 @@ CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSO
/* Add an item to an object with constant string as key */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
{
if (!item)
if ((item == NULL) || (string == NULL))
{
return;
}
@@ -1817,17 +1899,27 @@ CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJ
item->type |= cJSON_StringIsConst;
cJSON_AddItemToArray(object, item);
}
#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
#pragma GCC diagnostic pop
#endif
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
{
if (array == NULL)
{
return;
}
cJSON_AddItemToArray(array, create_reference(item, &global_hooks));
}
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
{
if ((object == NULL) || (string == NULL))
{
return;
}
cJSON_AddItemToObject(object, string, create_reference(item, &global_hooks));
}
@@ -1932,7 +2024,7 @@ CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newit
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
{
if ((parent == NULL) || (replacement == NULL))
if ((parent == NULL) || (replacement == NULL) || (item == NULL))
{
return false;
}
@@ -1975,14 +2067,34 @@ CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newi
cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
}
static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive)
{
if ((replacement == NULL) || (string == NULL))
{
return false;
}
/* replace the name in the replacement */
if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL))
{
cJSON_free(replacement->string);
}
replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
replacement->type &= ~cJSON_StringIsConst;
cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
return true;
}
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
{
cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItem(object, string), newitem);
replace_item_in_object(object, string, newitem, false);
}
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
{
cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItemCaseSensitive(object, string), newitem);
replace_item_in_object(object, string, newitem, true);
}
/* Create basic types: */
@@ -2120,7 +2232,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count)
cJSON *p = NULL;
cJSON *a = NULL;
if (count < 0)
if ((count < 0) || (numbers == NULL))
{
return NULL;
}
@@ -2155,7 +2267,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
cJSON *p = NULL;
cJSON *a = NULL;
if (count < 0)
if ((count < 0) || (numbers == NULL))
{
return NULL;
}
@@ -2191,7 +2303,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
cJSON *p = NULL;
cJSON *a = NULL;
if (count < 0)
if ((count < 0) || (numbers == NULL))
{
return NULL;
}
@@ -2227,7 +2339,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count)
cJSON *p = NULL;
cJSON *a = NULL;
if (count < 0)
if ((count < 0) || (strings == NULL))
{
return NULL;
}
@@ -2339,6 +2451,12 @@ fail:
CJSON_PUBLIC(void) cJSON_Minify(char *json)
{
unsigned char *into = (unsigned char*)json;
if (json == NULL)
{
return;
}
while (*json)
{
if (*json == ' ')
@@ -2574,16 +2692,22 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
b_element = b_element->next;
}
/* one of the arrays is longer than the other */
if (a_element != b_element) {
return false;
}
return true;
}
case cJSON_Object:
{
cJSON *a_element = NULL;
cJSON *b_element = NULL;
cJSON_ArrayForEach(a_element, a)
{
/* TODO This has O(n^2) runtime, which is horrible! */
cJSON *b_element = get_object_item(b, a_element->string, case_sensitive);
b_element = get_object_item(b, a_element->string, case_sensitive);
if (b_element == NULL)
{
return false;
@@ -2595,6 +2719,22 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
}
}
/* doing this twice, once on a and b to prevent true comparison if a subset of b
* TODO: Do this the proper way, this is just a fix for now */
cJSON_ArrayForEach(b_element, b)
{
a_element = get_object_item(a, b_element->string, case_sensitive);
if (a_element == NULL)
{
return false;
}
if (!cJSON_Compare(b_element, a_element, case_sensitive))
{
return false;
}
}
return true;
}

14
cJSON.h
View File

@@ -30,8 +30,8 @@ extern "C"
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 5
#define CJSON_VERSION_PATCH 2
#define CJSON_VERSION_MINOR 6
#define CJSON_VERSION_PATCH 0
#include <stddef.h>
@@ -138,6 +138,10 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
@@ -228,10 +232,6 @@ The item->next and ->prev pointers are always zero on return from Duplicate. */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error. If not, then cJSON_GetErrorPtr() does the job. */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Macros for creating things quickly. */
@@ -249,7 +249,7 @@ CJSON_PUBLIC(void) cJSON_Minify(char *json);
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array */
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */

View File

@@ -20,13 +20,32 @@
THE SOFTWARE.
*/
/* disable warnings about old C89 functions in MSVC */
#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
#define _CRT_SECURE_NO_DEPRECATE
#endif
#ifdef __GNUCC__
#pragma GCC visibility push(default)
#endif
#if defined(_MSC_VER)
#pragma warning (push)
/* disable warning about single line comments in system headers */
#pragma warning (disable : 4001)
#endif
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#if defined(_MSC_VER)
#pragma warning (pop)
#endif
#ifdef __GNUCC__
#pragma GCC visibility pop
#endif
#include "cJSON_Utils.h"
@@ -162,6 +181,11 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje
size_t child_index = 0;
cJSON *current_child = 0;
if ((object == NULL) || (target == NULL))
{
return NULL;
}
if (object == target)
{
/* found */
@@ -257,6 +281,12 @@ static cJSON_bool decode_array_index_from_pointer(const unsigned char * const po
static cJSON *get_item_from_pointer(cJSON * const object, const char * pointer, const cJSON_bool case_sensitive)
{
cJSON *current_element = object;
if (pointer == NULL)
{
return NULL;
}
/* follow path of the pointer */
while ((pointer[0] == '/') && (current_element != NULL))
{
@@ -279,16 +309,17 @@ static cJSON *get_item_from_pointer(cJSON * const object, const char * pointer,
{
current_element = current_element->next;
}
/* skip to the next path token or end of string */
while ((pointer[0] != '\0') && (pointer[0] != '/'))
{
pointer++;
}
}
else
{
return NULL;
}
/* skip to the next path token or end of string */
while ((pointer[0] != '\0') && (pointer[0] != '/'))
{
pointer++;
}
}
return current_element;
@@ -538,6 +569,10 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
static void sort_object(cJSON * const object, const cJSON_bool case_sensitive)
{
if (object == NULL)
{
return;
}
object->child = sort_list(object->child, case_sensitive);
}
@@ -942,7 +977,14 @@ static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_
}
else if (cJSON_IsObject(parent))
{
cJSON_DeleteItemFromObject(parent, (char*)child_pointer);
if (case_sensitive)
{
cJSON_DeleteItemFromObjectCaseSensitive(parent, (char*)child_pointer);
}
else
{
cJSON_DeleteItemFromObject(parent, (char*)child_pointer);
}
cJSON_AddItemToObject(parent, (char*)child_pointer, value);
value = NULL;
}
@@ -1020,7 +1062,14 @@ CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, con
static void compose_patch(cJSON * const patches, const unsigned char * const operation, const unsigned char * const path, const unsigned char *suffix, const cJSON * const value)
{
cJSON *patch = cJSON_CreateObject();
cJSON *patch = NULL;
if ((patches == NULL) || (operation == NULL) || (path == NULL))
{
return;
}
patch = cJSON_CreateObject();
if (patch == NULL)
{
return;
@@ -1198,7 +1247,14 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to)
{
cJSON *patches = cJSON_CreateArray();
cJSON *patches = NULL;
if ((from == NULL) || (to == NULL))
{
return NULL;
}
patches = cJSON_CreateArray();
create_patches(patches, (const unsigned char*)"", from, to, false);
return patches;
@@ -1206,7 +1262,14 @@ CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * con
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to)
{
cJSON *patches = cJSON_CreateArray();
cJSON *patches = NULL;
if ((from == NULL) || (to == NULL))
{
return NULL;
}
patches = cJSON_CreateArray();
create_patches(patches, (const unsigned char*)"", from, to, true);
return patches;

View File

@@ -25,8 +25,8 @@ escape_sequence_r="\\r"
escape_sequence_t="\\t"
escape_sequence_quote="\\\""
escape_sequence_backslash="\\\\"
escapce_sequence_slash="\\/"
escpae_sequence_utf16_base="\\u"
escape_sequence_slash="\\/"
escape_sequence_utf16_base="\\u"
escape_sequence_utf16="\\u12ab"
number_integer="1"

View File

@@ -25,6 +25,14 @@ if(ENABLE_CJSON_TEST)
target_compile_options(unity PRIVATE "-fno-sanitize=float-divide-by-zero")
endif()
endif()
# Disable -Wswitch-enum for Unity
if (FLAG_SUPPORTED_Wswitchenum)
if ("${CMAKE_VERSION}" VERSION_LESS "2.8.12")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-switch-enum")
else()
target_compile_options(unity PRIVATE "-Wno-switch-enum")
endif()
endif()
#copy test files
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/inputs")
@@ -58,7 +66,7 @@ if(ENABLE_CJSON_TEST)
message(WARNING "Valgrind couldn't be found.")
unset(MEMORYCHECK_COMMAND)
else()
set(MEMORYCHECK_COMMAND_OPTIONS --trace-children=yes --leak-check=full --error-exitcode=1)
set(MEMORYCHECK_COMMAND_OPTIONS --trace-children=yes --leak-check=full --error-exitcode=1 --suppressions=${CMAKE_CURRENT_SOURCE_DIR}/../valgrind.supp)
endif()
endif()
@@ -84,7 +92,8 @@ if(ENABLE_CJSON_TEST)
set (cjson_utils_tests
json_patch_tests
old_utils_tests)
old_utils_tests
misc_utils_tests)
foreach (cjson_utils_test ${cjson_utils_tests})
add_executable("${cjson_utils_test}" "${cjson_utils_test}.c")

View File

@@ -148,6 +148,10 @@ static void cjson_compare_should_compare_arrays(void)
TEST_ASSERT_FALSE(compare_from_string("[true,null,42,\"string\",[],{}]", "[false, true, null, 42, \"string\", [], {}]", true));
TEST_ASSERT_FALSE(compare_from_string("[true,null,42,\"string\",[],{}]", "[false, true, null, 42, \"string\", [], {}]", false));
/* Arrays that are a prefix of another array */
TEST_ASSERT_FALSE(compare_from_string("[1,2,3]", "[1,2]", true));
TEST_ASSERT_FALSE(compare_from_string("[1,2,3]", "[1,2]", false));
}
static void cjson_compare_should_compare_objects(void)
@@ -171,6 +175,15 @@ static void cjson_compare_should_compare_objects(void)
"{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
"{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
false));
/* test objects that are a subset of each other */
TEST_ASSERT_FALSE(compare_from_string(
"{\"one\": 1, \"two\": 2}",
"{\"one\": 1, \"two\": 2, \"three\": 3}",
true))
TEST_ASSERT_FALSE(compare_from_string(
"{\"one\": 1, \"two\": 2}",
"{\"one\": 1, \"two\": 2, \"three\": 3}",
false))
}
int main(void)

View File

@@ -119,7 +119,7 @@ static cJSON_bool test_apply_patch(const cJSON * const test)
return successful;
}
static cJSON_bool test_generate_test(cJSON *test __attribute__((unused)))
static cJSON_bool test_generate_test(cJSON *test)
{
cJSON *doc = NULL;
cJSON *patch = NULL;

View File

@@ -304,6 +304,152 @@ static void cjson_replace_item_via_pointer_should_replace_items(void)
cJSON_free(array);
}
static void cjson_replace_item_in_object_should_preserve_name(void)
{
cJSON root[1] = {{ NULL, NULL, NULL, 0, NULL, 0, 0, NULL }};
cJSON *child = NULL;
cJSON *replacement = NULL;
child = cJSON_CreateNumber(1);
TEST_ASSERT_NOT_NULL(child);
replacement = cJSON_CreateNumber(2);
TEST_ASSERT_NOT_NULL(replacement);
cJSON_AddItemToObject(root, "child", child);
cJSON_ReplaceItemInObject(root, "child", replacement);
TEST_ASSERT_TRUE(root->child == replacement);
TEST_ASSERT_EQUAL_STRING("child", replacement->string);
cJSON_Delete(replacement);
}
static void cjson_functions_shouldnt_crash_with_null_pointers(void)
{
char buffer[10];
cJSON *item = cJSON_CreateString("item");
cJSON_InitHooks(NULL);
TEST_ASSERT_NULL(cJSON_Parse(NULL));
TEST_ASSERT_NULL(cJSON_ParseWithOpts(NULL, NULL, true));
TEST_ASSERT_NULL(cJSON_Print(NULL));
TEST_ASSERT_NULL(cJSON_PrintUnformatted(NULL));
TEST_ASSERT_NULL(cJSON_PrintBuffered(NULL, 10, true));
TEST_ASSERT_FALSE(cJSON_PrintPreallocated(NULL, buffer, sizeof(buffer), true));
TEST_ASSERT_FALSE(cJSON_PrintPreallocated(item, NULL, 1, true));
cJSON_Delete(NULL);
cJSON_GetArraySize(NULL);
TEST_ASSERT_NULL(cJSON_GetArrayItem(NULL, 0));
TEST_ASSERT_NULL(cJSON_GetObjectItem(NULL, "item"));
TEST_ASSERT_NULL(cJSON_GetObjectItem(item, NULL));
TEST_ASSERT_NULL(cJSON_GetObjectItemCaseSensitive(NULL, "item"));
TEST_ASSERT_NULL(cJSON_GetObjectItemCaseSensitive(item, NULL));
TEST_ASSERT_FALSE(cJSON_HasObjectItem(NULL, "item"));
TEST_ASSERT_FALSE(cJSON_HasObjectItem(item, NULL));
TEST_ASSERT_FALSE(cJSON_IsInvalid(NULL));
TEST_ASSERT_FALSE(cJSON_IsFalse(NULL));
TEST_ASSERT_FALSE(cJSON_IsTrue(NULL));
TEST_ASSERT_FALSE(cJSON_IsBool(NULL));
TEST_ASSERT_FALSE(cJSON_IsNull(NULL));
TEST_ASSERT_FALSE(cJSON_IsNumber(NULL));
TEST_ASSERT_FALSE(cJSON_IsString(NULL));
TEST_ASSERT_FALSE(cJSON_IsArray(NULL));
TEST_ASSERT_FALSE(cJSON_IsObject(NULL));
TEST_ASSERT_FALSE(cJSON_IsRaw(NULL));
TEST_ASSERT_NULL(cJSON_CreateString(NULL));
TEST_ASSERT_NULL(cJSON_CreateRaw(NULL));
TEST_ASSERT_NULL(cJSON_CreateIntArray(NULL, 10));
TEST_ASSERT_NULL(cJSON_CreateFloatArray(NULL, 10));
TEST_ASSERT_NULL(cJSON_CreateDoubleArray(NULL, 10));
TEST_ASSERT_NULL(cJSON_CreateStringArray(NULL, 10));
cJSON_AddItemToArray(NULL, item);
cJSON_AddItemToArray(item, NULL);
cJSON_AddItemToObject(item, "item", NULL);
cJSON_AddItemToObject(item, NULL, item);
cJSON_AddItemToObject(NULL, "item", item);
cJSON_AddItemToObjectCS(item, "item", NULL);
cJSON_AddItemToObjectCS(item, NULL, item);
cJSON_AddItemToObjectCS(NULL, "item", item);
cJSON_AddItemReferenceToArray(NULL, item);
cJSON_AddItemReferenceToArray(item, NULL);
cJSON_AddItemReferenceToObject(item, "item", NULL);
cJSON_AddItemReferenceToObject(item, NULL, item);
cJSON_AddItemReferenceToObject(NULL, "item", item);
TEST_ASSERT_NULL(cJSON_DetachItemViaPointer(NULL, item));
TEST_ASSERT_NULL(cJSON_DetachItemViaPointer(item, NULL));
TEST_ASSERT_NULL(cJSON_DetachItemFromArray(NULL, 0));
cJSON_DeleteItemFromArray(NULL, 0);
TEST_ASSERT_NULL(cJSON_DetachItemFromObject(NULL, "item"));
TEST_ASSERT_NULL(cJSON_DetachItemFromObject(item, NULL));
TEST_ASSERT_NULL(cJSON_DetachItemFromObjectCaseSensitive(NULL, "item"));
TEST_ASSERT_NULL(cJSON_DetachItemFromObjectCaseSensitive(item, NULL));
cJSON_DeleteItemFromObject(NULL, "item");
cJSON_DeleteItemFromObject(item, NULL);
cJSON_DeleteItemFromObjectCaseSensitive(NULL, "item");
cJSON_DeleteItemFromObjectCaseSensitive(item, NULL);
cJSON_InsertItemInArray(NULL, 0, item);
cJSON_InsertItemInArray(item, 0, NULL);
TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(NULL, item, item));
TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, NULL, item));
TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(item, item, NULL));
cJSON_ReplaceItemInArray(item, 0, NULL);
cJSON_ReplaceItemInArray(NULL, 0, item);
cJSON_ReplaceItemInObject(NULL, "item", item);
cJSON_ReplaceItemInObject(item, NULL, item);
cJSON_ReplaceItemInObject(item, "item", NULL);
cJSON_ReplaceItemInObjectCaseSensitive(NULL, "item", item);
cJSON_ReplaceItemInObjectCaseSensitive(item, NULL, item);
cJSON_ReplaceItemInObjectCaseSensitive(item, "item", NULL);
TEST_ASSERT_NULL(cJSON_Duplicate(NULL, true));
TEST_ASSERT_FALSE(cJSON_Compare(item, NULL, false));
TEST_ASSERT_FALSE(cJSON_Compare(NULL, item, false));
cJSON_Minify(NULL);
/* skipped because it is only used via a macro that checks for NULL */
/* cJSON_SetNumberHelper(NULL, 0); */
cJSON_Delete(item);
}
static void *failing_realloc(void *pointer, size_t size)
{
(void)size;
(void)pointer;
return NULL;
}
static void ensure_should_fail_on_failed_realloc(void)
{
printbuffer buffer = {NULL, 10, 0, 0, false, false, {&malloc, &free, &failing_realloc}};
buffer.buffer = (unsigned char*)malloc(100);
TEST_ASSERT_NOT_NULL(buffer.buffer);
TEST_ASSERT_NULL_MESSAGE(ensure(&buffer, 200), "Ensure didn't fail with failing realloc.");
}
static void skip_utf8_bom_should_skip_bom(void)
{
const unsigned char string[] = "\xEF\xBB\xBF{}";
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
buffer.content = string;
buffer.length = sizeof(string);
buffer.hooks = global_hooks;
TEST_ASSERT_TRUE(skip_utf8_bom(&buffer) == &buffer);
TEST_ASSERT_EQUAL_UINT(3U, (unsigned int)buffer.offset);
}
static void skip_utf8_bom_should_not_skip_bom_if_not_at_beginning(void)
{
const unsigned char string[] = " \xEF\xBB\xBF{}";
parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
buffer.content = string;
buffer.length = sizeof(string);
buffer.hooks = global_hooks;
buffer.offset = 1;
TEST_ASSERT_NULL(skip_utf8_bom(&buffer));
}
int main(void)
{
UNITY_BEGIN();
@@ -317,6 +463,11 @@ int main(void)
RUN_TEST(cjson_set_number_value_should_set_numbers);
RUN_TEST(cjson_detach_item_via_pointer_should_detach_items);
RUN_TEST(cjson_replace_item_via_pointer_should_replace_items);
RUN_TEST(cjson_replace_item_in_object_should_preserve_name);
RUN_TEST(cjson_functions_shouldnt_crash_with_null_pointers);
RUN_TEST(ensure_should_fail_on_failed_realloc);
RUN_TEST(skip_utf8_bom_should_skip_bom);
RUN_TEST(skip_utf8_bom_should_not_skip_bom_if_not_at_beginning);
return UNITY_END();
}

80
tests/misc_utils_tests.c Normal file
View File

@@ -0,0 +1,80 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unity/examples/unity_config.h"
#include "unity/src/unity.h"
#include "common.h"
#include "../cJSON_Utils.h"
static void cjson_utils_functions_shouldnt_crash_with_null_pointers(void)
{
cJSON *item = cJSON_CreateString("item");
TEST_ASSERT_NOT_NULL(item);
TEST_ASSERT_NULL(cJSONUtils_GetPointer(item, NULL));
TEST_ASSERT_NULL(cJSONUtils_GetPointer(NULL, "pointer"));
TEST_ASSERT_NULL(cJSONUtils_GetPointerCaseSensitive(NULL, "pointer"));
TEST_ASSERT_NULL(cJSONUtils_GetPointerCaseSensitive(item, NULL));
TEST_ASSERT_NULL(cJSONUtils_GeneratePatches(item, NULL));
TEST_ASSERT_NULL(cJSONUtils_GeneratePatches(NULL, item));
TEST_ASSERT_NULL(cJSONUtils_GeneratePatchesCaseSensitive(item, NULL));
TEST_ASSERT_NULL(cJSONUtils_GeneratePatchesCaseSensitive(NULL, item));
cJSONUtils_AddPatchToArray(item, "path", "add", NULL);
cJSONUtils_AddPatchToArray(item, "path", NULL, item);
cJSONUtils_AddPatchToArray(item, NULL, "add", item);
cJSONUtils_AddPatchToArray(NULL, "path", "add", item);
cJSONUtils_ApplyPatches(item, NULL);
cJSONUtils_ApplyPatches(NULL, item);
cJSONUtils_ApplyPatchesCaseSensitive(item, NULL);
cJSONUtils_ApplyPatchesCaseSensitive(NULL, item);
TEST_ASSERT_NULL(cJSONUtils_MergePatch(item, NULL));
item = cJSON_CreateString("item");
TEST_ASSERT_NULL(cJSONUtils_MergePatchCaseSensitive(item, NULL));
item = cJSON_CreateString("item");
/* these calls are actually valid */
/* cJSONUtils_MergePatch(NULL, item); */
/* cJSONUtils_MergePatchCaseSensitive(NULL, item);*/
/* cJSONUtils_GenerateMergePatch(item, NULL); */
/* cJSONUtils_GenerateMergePatch(NULL, item); */
/* cJSONUtils_GenerateMergePatchCaseSensitive(item, NULL); */
/* cJSONUtils_GenerateMergePatchCaseSensitive(NULL, item); */
TEST_ASSERT_NULL(cJSONUtils_FindPointerFromObjectTo(item, NULL));
TEST_ASSERT_NULL(cJSONUtils_FindPointerFromObjectTo(NULL, item));
cJSONUtils_SortObject(NULL);
cJSONUtils_SortObjectCaseSensitive(NULL);
cJSON_Delete(item);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(cjson_utils_functions_shouldnt_crash_with_null_pointers);
return UNITY_END();
}

View File

@@ -142,7 +142,7 @@ static void file_test6_should_not_be_parsed(void)
tree = cJSON_Parse(test6);
TEST_ASSERT_NULL_MESSAGE(tree, "Should fail to parse what is not JSON.");
TEST_ASSERT_EQUAL_STRING_MESSAGE(test6, cJSON_GetErrorPtr(), "Error pointer is incorrect.");
TEST_ASSERT_EQUAL_PTR_MESSAGE(test6, cJSON_GetErrorPtr(), "Error pointer is incorrect.");
if (test6 != NULL)
{
@@ -179,6 +179,22 @@ static void file_test11_should_be_parsed_and_printed(void)
do_test("test11");
}
static void test12_should_not_be_parsed(void)
{
const char *test12 = "{ \"name\": ";
cJSON *tree = NULL;
tree = cJSON_Parse(test12);
TEST_ASSERT_NULL_MESSAGE(tree, "Should fail to parse incomplete JSON.");
TEST_ASSERT_EQUAL_PTR_MESSAGE(test12 + strlen(test12), cJSON_GetErrorPtr(), "Error pointer is incorrect.");
if (tree != NULL)
{
cJSON_Delete(tree);
}
}
int main(void)
{
UNITY_BEGIN();
@@ -193,5 +209,6 @@ int main(void)
RUN_TEST(file_test9_should_be_parsed_and_printed);
RUN_TEST(file_test10_should_be_parsed_and_printed);
RUN_TEST(file_test11_should_be_parsed_and_printed);
RUN_TEST(test12_should_not_be_parsed);
return UNITY_END();
}

View File

@@ -31,8 +31,8 @@
static void parse_hex4_should_parse_all_combinations(void)
{
unsigned int number = 0;
unsigned char digits_lower[5];
unsigned char digits_upper[5];
unsigned char digits_lower[6];
unsigned char digits_upper[6];
/* test all combinations */
for (number = 0; number <= 0xFFFF; number++)
{

View File

@@ -40,11 +40,23 @@ static void parse_with_opts_should_handle_empty_strings(void)
{
const char empty_string[] = "";
const char *error_pointer = NULL;
TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, NULL, false));
error_pointer = cJSON_GetErrorPtr();
TEST_ASSERT_EQUAL_INT(0, error_pointer - empty_string);
TEST_ASSERT_EQUAL_PTR(empty_string, cJSON_GetErrorPtr());
TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, &error_pointer, false));
TEST_ASSERT_EQUAL_INT(0, error_pointer - empty_string);
TEST_ASSERT_EQUAL_PTR(empty_string, error_pointer);
TEST_ASSERT_EQUAL_PTR(empty_string, cJSON_GetErrorPtr());
}
static void parse_with_opts_should_handle_incomplete_json(void)
{
const char json[] = "{ \"name\": ";
const char *parse_end = NULL;
TEST_ASSERT_NULL(cJSON_ParseWithOpts(json, &parse_end, false));
TEST_ASSERT_EQUAL_PTR(json + strlen(json), parse_end);
TEST_ASSERT_EQUAL_PTR(json + strlen(json), cJSON_GetErrorPtr());
}
static void parse_with_opts_should_require_null_if_requested(void)
@@ -65,18 +77,36 @@ static void parse_with_opts_should_return_parse_end(void)
cJSON *item = cJSON_ParseWithOpts(json, &parse_end, false);
TEST_ASSERT_NOT_NULL(item);
TEST_ASSERT_EQUAL_INT(2, parse_end - json);
TEST_ASSERT_EQUAL_PTR(json + 2, parse_end);
cJSON_Delete(item);
}
static void parse_with_opts_should_parse_utf8_bom(void)
{
cJSON *with_bom = NULL;
cJSON *without_bom = NULL;
with_bom = cJSON_ParseWithOpts("\xEF\xBB\xBF{}", NULL, true);
TEST_ASSERT_NOT_NULL(with_bom);
without_bom = cJSON_ParseWithOpts("{}", NULL, true);
TEST_ASSERT_NOT_NULL(with_bom);
TEST_ASSERT_TRUE(cJSON_Compare(with_bom, without_bom, true));
cJSON_Delete(with_bom);
cJSON_Delete(without_bom);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(parse_with_opts_should_handle_null);
RUN_TEST(parse_with_opts_should_handle_empty_strings);
RUN_TEST(parse_with_opts_should_handle_incomplete_json);
RUN_TEST(parse_with_opts_should_require_null_if_requested);
RUN_TEST(parse_with_opts_should_return_parse_end);
RUN_TEST(parse_with_opts_should_parse_utf8_bom);
return UNITY_END();
}

View File

@@ -49,16 +49,16 @@ static void print_number_should_print_zero(void)
static void print_number_should_print_negative_integers(void)
{
assert_print_number("-1", -1);
assert_print_number("-32768", -32768);
assert_print_number("-1", -1.0);
assert_print_number("-32768", -32768.0);
assert_print_number("-2147483648", -2147483648.0);
}
static void print_number_should_print_positive_integers(void)
{
assert_print_number("1", 1);
assert_print_number("32767", 32767);
assert_print_number("2147483647", 2147483647);
assert_print_number("1", 1.0);
assert_print_number("32767", 32767.0);
assert_print_number("2147483647", 2147483647.0);
}
static void print_number_should_print_positive_reals(void)
@@ -68,6 +68,7 @@ static void print_number_should_print_positive_reals(void)
assert_print_number("1000000000000", 10e11);
assert_print_number("1.23e+129", 123e+127);
assert_print_number("1.23e-126", 123e-128);
assert_print_number("3.1415926535897931", 3.1415926535897931);
}
static void print_number_should_print_negative_reals(void)

View File

@@ -118,6 +118,17 @@ Another way of calling TEST_ASSERT_EQUAL_INT
Asserts that the actual value is within plus or minus delta of the expected value. This also comes in
size specific variants.
TEST_ASSERT_GREATER_THAN(threshold, actual)
Asserts that the actual value is greater than the threshold. This also comes in size specific variants.
TEST_ASSERT_LESS_THAN(threshold, actual)
Asserts that the actual value is less than the threshold. This also comes in size specific variants.
Arrays
------

View File

@@ -172,7 +172,7 @@ class UnityModuleGenerator
when 'camel' then part1
when 'snake' then part1.downcase
when 'caps' then part1.upcase
else part1.downcase
else part1
end
else
case (@options[:naming])
@@ -180,7 +180,7 @@ class UnityModuleGenerator
when 'camel' then part1 + part2
when 'snake' then part1.downcase + '_' + part2.downcase
when 'caps' then part1.upcase + '_' + part2.upcase
else part1.downcase + '_' + part2.downcase
else part1 + '_' + part2
end
end
end
@@ -290,7 +290,7 @@ if $0 == __FILE__
' -n"camel" sets the file naming convention.',
' bumpy - BumpyCaseFilenames.',
' camel - camelCaseFilenames.',
' snake - snake_case_filenames. (DEFAULT)',
' snake - snake_case_filenames.',
' caps - CAPS_CASE_FILENAMES.',
' -u update subversion too (requires subversion command line)',
' -y"my.yml" selects a different yaml config file for module generation',

View File

@@ -119,7 +119,7 @@ class UnityTestRunnerGenerator
source_index = 0
tests_and_line_numbers.size.times do |i|
source_lines[source_index..-1].each_with_index do |line, index|
next unless line =~ /#{tests_and_line_numbers[i][:test]}/
next unless line =~ /\s+#{tests_and_line_numbers[i][:test]}(?:\s|\()/
source_index += index
tests_and_line_numbers[i][:line_number] = source_index + 1
break

0
tests/unity/auto/stylize_as_junit.rb Normal file → Executable file
View File

View File

@@ -290,6 +290,60 @@ Asserts the specified bit of the `actual` parameter is high.
Asserts the specified bit of the `actual` parameter is low.
### Integer Less Than / Greater Than
These assertions verify that the `actual` parameter is less than or greater
than `threshold` (exclusive). For example, if the threshold value is 0 for the
greater than assertion will fail if it is 0 or less.
##### `TEST_ASSERT_GREATER_THAN (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_INT (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_INT8 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_INT16 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_INT32 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_UINT (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_UINT8 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_UINT16 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_UINT32 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_HEX8 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_HEX16 (threshold, actual)`
##### `TEST_ASSERT_GREATER_THAN_HEX32 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_INT (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_INT8 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_INT16 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_INT32 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_UINT (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_UINT8 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_UINT16 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_UINT32 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_HEX8 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_HEX16 (threshold, actual)`
##### `TEST_ASSERT_LESS_THAN_HEX32 (threshold, actual)`
### Integer Ranges (of all sizes)

View File

@@ -201,10 +201,12 @@
* `stdout` option. You decide to route your test result output to a custom
* serial `RS232_putc()` function you wrote like thus:
*/
/* #define UNITY_OUTPUT_CHAR(a) RS232_putc(a) */
/* #define UNITY_OUTPUT_FLUSH() RS232_flush() */
/* #define UNITY_OUTPUT_START() RS232_config(115200,1,8,0) */
/* #define UNITY_OUTPUT_COMPLETE() RS232_close() */
/* #define UNITY_OUTPUT_CHAR(a) RS232_putc(a) */
/* #define UNITY_OUTPUT_CHAR_HEADER_DECLARATION RS232_putc(int) */
/* #define UNITY_OUTPUT_FLUSH() RS232_flush() */
/* #define UNITY_OUTPUT_FLUSH_HEADER_DECLARATION RS232_flush(void) */
/* #define UNITY_OUTPUT_START() RS232_config(115200,1,8,0) */
/* #define UNITY_OUTPUT_COMPLETE() RS232_close() */
/* For some targets, Unity can make the otherwise required `setUp()` and
* `tearDown()` functions optional. This is a nice convenience for test writers

View File

@@ -53,7 +53,7 @@ module RakefileHelpers
defines = if $cfg['compiler']['defines']['items'].nil?
''
else
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'])
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'] + ['UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar\(int\)'])
end
options = squash('', $cfg['compiler']['options'])
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])

View File

@@ -6,6 +6,7 @@ endif
CFLAGS += -std=c99 -pedantic -Wall -Wextra -Werror
CFLAGS += $(DEBUG)
DEFINES = -D UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar
DEFINES += -D UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar\(int\)
SRC = ../src/unity_fixture.c \
../../../src/unity.c \
unity_fixture_Test.c \

View File

@@ -1,2 +1,2 @@
120
121

View File

@@ -1,2 +1,2 @@
2.4.1
2.4.2

View File

@@ -27,6 +27,8 @@ static const char UnityStrNull[] = "NULL";
static const char UnityStrSpacer[] = ". ";
static const char UnityStrExpected[] = " Expected ";
static const char UnityStrWas[] = " Was ";
static const char UnityStrGt[] = " to be greater than ";
static const char UnityStrLt[] = " to be less than ";
static const char UnityStrElement[] = " Element ";
static const char UnityStrByte[] = " Byte ";
static const char UnityStrMemory[] = " Memory Mismatch.";
@@ -235,95 +237,97 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
/*-----------------------------------------------*/
#ifndef UNITY_EXCLUDE_FLOAT_PRINT
static void UnityPrintDecimalAndNumberWithLeadingZeros(UNITY_INT32 fraction_part, UNITY_INT32 divisor)
{
UNITY_OUTPUT_CHAR('.');
while (divisor > 0)
{
UNITY_OUTPUT_CHAR('0' + fraction_part / divisor);
fraction_part %= divisor;
divisor /= 10;
if (fraction_part == 0) break; /* Truncate trailing 0's */
}
}
#ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO
/* If rounds up && remainder 0.5 && result odd && below cutoff for double precision issues */
#define ROUND_TIES_TO_EVEN(orig, num_int, num) \
if (num_int > (num) && (num) - (num_int-1) <= 0.5 && (num_int & 1) == 1 && orig < 1e22) \
num_int -= 1 /* => a tie to round down to even */
#else
#define ROUND_TIES_TO_EVEN(orig, num_int, num) /* Remove macro */
#endif
/* Printing floating point numbers is hard. Some goals of this implementation: works for embedded
* systems, floats or doubles, and has a reasonable format. The key paper in this area,
* 'How to Print Floating-Point Numbers Accurately' by Steele & White, shows an approximation by
* scaling called Dragon 2. This code uses a similar idea. The other core algorithm uses casts and
* floating subtraction to give exact remainders after the decimal, to be scaled into an integer.
* Extra trailing 0's are excluded. The output defaults to rounding to nearest, ties to even. You
* can enable rounding ties away from zero. Note: UNITY_DOUBLE param can typedef to float or double
* The old version required compiling in snprintf. For reference, with a similar format as now:
* char buf[19];
* if (number > 4294967296.0 || -number > 4294967296.0) snprintf(buf, sizeof buf, "%.8e", number);
* else snprintf(buf, sizeof buf, "%.6f", number);
* UnityPrint(buf);
*/
/* This function prints a floating-point value in a format similar to
* printf("%.6g"). It can work with either single- or double-precision,
* but for simplicity, it prints only 6 significant digits in either case.
* Printing more than 6 digits accurately is hard (at least in the single-
* precision case) and isn't attempted here. */
void UnityPrintFloat(const UNITY_DOUBLE input_number)
{
UNITY_DOUBLE number;
UNITY_DOUBLE number = input_number;
if (input_number < 0)
/* print minus sign (including for negative zero) */
if (number < 0.0f || (number == 0.0f && 1.0f / number < 0.0f))
{
UNITY_OUTPUT_CHAR('-');
number = -input_number;
} else
{
number = input_number;
number = -number;
}
if (isnan(number)) UnityPrint(UnityStrNaN);
else if (isinf(number)) UnityPrintLen(UnityStrInf, 3);
else if (number <= 0.0000005 && number > 0) UnityPrint("0.000000..."); /* Small number */
else if (number < 4294967295.9999995) /* Rounded result fits in 32 bits, "%.6f" format */
/* handle zero, NaN, and +/- infinity */
if (number == 0.0f) UnityPrint("0");
else if (isnan(number)) UnityPrint("nan");
else if (isinf(number)) UnityPrint("inf");
else
{
const UNITY_INT32 divisor = 1000000/10;
UNITY_UINT32 integer_part = (UNITY_UINT32)number;
UNITY_INT32 fraction_part = (UNITY_INT32)((number - (UNITY_DOUBLE)integer_part)*1000000.0 + 0.5);
/* Double precision calculation gives best performance for six rounded decimal places */
ROUND_TIES_TO_EVEN(number, fraction_part, (number - (UNITY_DOUBLE)integer_part)*1000000.0);
int exponent = 0;
int decimals, digits;
UNITY_INT32 n;
char buf[16];
if (fraction_part == 1000000) /* Carry across the decimal point */
/* scale up or down by powers of 10 */
while (number < 100000.0f / 1e6f) { number *= 1e6f; exponent -= 6; }
while (number < 100000.0f) { number *= 10.0f; exponent--; }
while (number > 1000000.0f * 1e6f) { number /= 1e6f; exponent += 6; }
while (number > 1000000.0f) { number /= 10.0f; exponent++; }
/* round to nearest integer */
n = ((UNITY_INT32)(number + number) + 1) / 2;
if (n > 999999)
{
fraction_part = 0;
integer_part += 1;
}
UnityPrintNumberUnsigned(integer_part);
UnityPrintDecimalAndNumberWithLeadingZeros(fraction_part, divisor);
}
else /* Number is larger, use exponential format of 9 digits, "%.8e" */
{
const UNITY_INT32 divisor = 1000000000/10;
UNITY_INT32 integer_part;
UNITY_DOUBLE_TYPE divide = 10.0;
int exponent = 9;
while (number / divide >= 1000000000.0 - 0.5)
{
divide *= 10;
n = 100000;
exponent++;
}
integer_part = (UNITY_INT32)(number / divide + 0.5);
/* Double precision calculation required for float, to produce 9 rounded digits */
ROUND_TIES_TO_EVEN(number, integer_part, number / divide);
UNITY_OUTPUT_CHAR('0' + integer_part / divisor);
UnityPrintDecimalAndNumberWithLeadingZeros(integer_part % divisor, divisor / 10);
UNITY_OUTPUT_CHAR('e');
UNITY_OUTPUT_CHAR('+');
if (exponent < 10) UNITY_OUTPUT_CHAR('0');
UnityPrintNumber(exponent);
/* determine where to place decimal point */
decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5;
exponent += decimals;
/* truncate trailing zeroes after decimal point */
while (decimals > 0 && n % 10 == 0)
{
n /= 10;
decimals--;
}
/* build up buffer in reverse order */
digits = 0;
while (n != 0 || digits < decimals + 1)
{
buf[digits++] = (char)('0' + n % 10);
n /= 10;
}
while (digits > 0)
{
if(digits == decimals) UNITY_OUTPUT_CHAR('.');
UNITY_OUTPUT_CHAR(buf[--digits]);
}
/* print exponent if needed */
if (exponent != 0)
{
UNITY_OUTPUT_CHAR('e');
if(exponent < 0)
{
UNITY_OUTPUT_CHAR('-');
exponent = -exponent;
}
else
{
UNITY_OUTPUT_CHAR('+');
}
digits = 0;
while (exponent != 0 || digits < 2)
{
buf[digits++] = (char)('0' + exponent % 10);
exponent /= 10;
}
while (digits > 0)
{
UNITY_OUTPUT_CHAR(buf[--digits]);
}
}
}
}
#endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */
@@ -526,6 +530,50 @@ void UnityAssertEqualNumber(const UNITY_INT expected,
}
}
/*-----------------------------------------------*/
void UnityAssertGreaterNumber(const UNITY_INT threshold,
const UNITY_INT actual,
const char *msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style)
{
RETURN_IF_FAIL_OR_IGNORE;
if (!(actual > threshold))
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(actual, style);
UnityPrint(UnityStrGt);
UnityPrintNumberByStyle(threshold, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
/*-----------------------------------------------*/
void UnityAssertSmallerNumber(const UNITY_INT threshold,
const UNITY_INT actual,
const char *msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style)
{
RETURN_IF_FAIL_OR_IGNORE;
if (!(actual < threshold))
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(actual, style);
UnityPrint(UnityStrLt);
UnityPrintNumberByStyle(threshold, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
#define UnityPrintPointlessAndBail() \
{ \
UnityTestResultsFailBegin(lineNumber); \
@@ -1025,7 +1073,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
{
UNITY_UINT32 i = 0;
UNITY_UINT32 j = 0;
const char* exp = NULL;
const char* expd = NULL;
const char* act = NULL;
RETURN_IF_FAIL_OR_IGNORE;
@@ -1048,7 +1096,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
if (flags != UNITY_ARRAY_TO_ARRAY)
{
exp = (const char*)expected;
expd = (const char*)expected;
}
do
@@ -1056,15 +1104,15 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
act = actual[j];
if (flags == UNITY_ARRAY_TO_ARRAY)
{
exp = ((const char* const*)expected)[j];
expd = ((const char* const*)expected)[j];
}
/* if both pointers not null compare the strings */
if (exp && act)
if (expd && act)
{
for (i = 0; exp[i] || act[i]; i++)
for (i = 0; expd[i] || act[i]; i++)
{
if (exp[i] != act[i])
if (expd[i] != act[i])
{
Unity.CurrentTestFailed = 1;
break;
@@ -1073,7 +1121,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
}
else
{ /* handle case of one pointers being null (if both null, test should pass) */
if (exp != act)
if (expd != act)
{
Unity.CurrentTestFailed = 1;
}
@@ -1087,7 +1135,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
UnityPrint(UnityStrElement);
UnityPrintNumberUnsigned(j);
}
UnityPrintExpectedAndActualStrings(exp, act);
UnityPrintExpectedAndActualStrings(expd, act);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}

View File

@@ -114,6 +114,35 @@ void tearDown(void);
#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, NULL)
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
/* Integer Ranges (of all sizes) */
#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
@@ -157,6 +186,8 @@ void tearDown(void);
#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL)
/* Arrays Compared To Single Value */
#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL)
@@ -241,6 +272,35 @@ void tearDown(void);
#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message))
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message))
/* Integer Ranges (of all sizes) */
#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message))

View File

@@ -244,8 +244,8 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT;
#define UNITY_OUTPUT_CHAR(a) (void)putchar(a)
#else
/* If defined as something else, make sure we declare it here so it's ready for use */
#ifndef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION
extern void UNITY_OUTPUT_CHAR(int);
#ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATION
extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION;
#endif
#endif
@@ -253,22 +253,22 @@ extern void UNITY_OUTPUT_CHAR(int);
#ifdef UNITY_USE_FLUSH_STDOUT
/* We want to use the stdout flush utility */
#include <stdio.h>
#define UNITY_OUTPUT_FLUSH (void)fflush(stdout)
#define UNITY_OUTPUT_FLUSH() (void)fflush(stdout)
#else
/* We've specified nothing, therefore flush should just be ignored */
#define UNITY_OUTPUT_FLUSH
#define UNITY_OUTPUT_FLUSH()
#endif
#else
/* We've defined flush as something else, so make sure we declare it here so it's ready for use */
#ifndef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION
extern void UNITY_OUTPUT_FLUSH(void);
#ifdef UNITY_OUTPUT_FLUSH_HEADER_DECLARATION
extern void UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION;
#endif
#endif
#ifndef UNITY_OUTPUT_FLUSH
#define UNITY_FLUSH_CALL()
#else
#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH
#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH()
#endif
#ifndef UNITY_PRINT_EOL
@@ -453,6 +453,18 @@ void UnityAssertEqualNumber(const UNITY_INT expected,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style);
void UnityAssertGreaterNumber(const UNITY_INT threshold,
const UNITY_INT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style);
void UnityAssertSmallerNumber(const UNITY_INT threshold,
const UNITY_INT actual,
const char* msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style);
void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
UNITY_INTERNAL_PTR actual,
const UNITY_UINT32 num_elements,
@@ -650,6 +662,34 @@ int UnityTestMatches(void);
#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((UNITY_INT)(mask), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line))
#define UNITY_TEST_ASSERT_GREATER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT8(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT16(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT32(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT8(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT16(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT32(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX8(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX16(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX32(threshold, actual, line, message) UnityAssertSmallerNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
@@ -704,9 +744,9 @@ int UnityTestMatches(void);
#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY)
#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY)
#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY)
#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY)
#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY)
#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY)
#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_VAL)
#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_VAL)
#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)expected, 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_VAL)
#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)

View File

@@ -14,6 +14,7 @@ CFLAGS += -Wbad-function-cast -Wcast-qual -Wold-style-definition -Wshadow -Wstri
#DEBUG = -O0 -g
CFLAGS += $(DEBUG)
DEFINES = -D UNITY_OUTPUT_CHAR=putcharSpy
DEFINES += -D UNITY_OUTPUT_CHAR_HEADER_DECLARATION=putcharSpy\(int\)
DEFINES += -D UNITY_SUPPORT_64 -D UNITY_INCLUDE_DOUBLE
SRC = ../src/unity.c tests/testunity.c build/testunityRunner.c
INC_DIR = -I ../src

View File

@@ -91,7 +91,7 @@ module RakefileHelpers
defines = if $cfg['compiler']['defines']['items'].nil?
''
else
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=putcharSpy'] + inject_defines)
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=putcharSpy'] + ['UNITY_OUTPUT_CHAR_HEADER_DECLARATION=putcharSpy\(int\)'] + inject_defines)
end
options = squash('', $cfg['compiler']['options'])
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])

View File

@@ -764,8 +764,9 @@ void testNotEqualBitsLow(void)
EXPECT_ABORT_BEGIN
TEST_ASSERT_BITS_LOW(v0, v1);
VERIFY_FAILS_END
}
void testEqualShorts(void)
{
short v0, v1;
@@ -1305,6 +1306,415 @@ void testINT8sNotWithinDeltaAndCustomMessage(void)
VERIFY_FAILS_END
}
//-----------------
void testGreaterThan(void)
{
UNITY_INT v0, v1;
UNITY_INT *p0, *p1;
v0 = 0;
v1 = 1;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN(v0, v1);
TEST_ASSERT_GREATER_THAN(*p0, v1);
TEST_ASSERT_GREATER_THAN(v0, *p1);
TEST_ASSERT_GREATER_THAN(*p0, *p1);
}
void testGreaterThanINT(void)
{
UNITY_INT v0, v1;
UNITY_INT *p0, *p1;
v0 = 302;
v1 = 3334;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_INT(v0, v1);
TEST_ASSERT_GREATER_THAN_INT(*p0, v1);
TEST_ASSERT_GREATER_THAN_INT(v0, *p1);
TEST_ASSERT_GREATER_THAN_INT(*p0, *p1);
}
void testGreaterThanINT8(void)
{
UNITY_INT8 v0, v1;
UNITY_INT8 *p0, *p1;
v0 = -128;
v1 = 127;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_INT8(v0, v1);
TEST_ASSERT_GREATER_THAN_INT8(*p0, v1);
TEST_ASSERT_GREATER_THAN_INT8(v0, *p1);
TEST_ASSERT_GREATER_THAN_INT8(*p0, *p1);
}
void testGreaterThanINT16(void)
{
UNITY_INT16 v0, v1;
UNITY_INT16 *p0, *p1;
v0 = -32768;
v1 = 32767;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_INT16(v0, v1);
TEST_ASSERT_GREATER_THAN_INT16(*p0, v1);
TEST_ASSERT_GREATER_THAN_INT16(v0, *p1);
TEST_ASSERT_GREATER_THAN_INT16(*p0, *p1);
}
void testGreaterThanINT32(void)
{
UNITY_INT32 v0, v1;
UNITY_INT32 *p0, *p1;
v0 = -214783648;
v1 = 214783647;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_INT32(v0, v1);
TEST_ASSERT_GREATER_THAN_INT32(*p0, v1);
TEST_ASSERT_GREATER_THAN_INT32(v0, *p1);
TEST_ASSERT_GREATER_THAN_INT32(*p0, *p1);
}
void testGreaterThanUINT(void)
{
UNITY_UINT v0, v1;
UNITY_UINT *p0, *p1;
v0 = 0;
v1 = 1;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_UINT(v0, v1);
TEST_ASSERT_GREATER_THAN_UINT(*p0, v1);
TEST_ASSERT_GREATER_THAN_UINT(v0, *p1);
TEST_ASSERT_GREATER_THAN_UINT(*p0, *p1);
}
void testGreaterThanUINT8(void)
{
UNITY_UINT8 v0, v1;
UNITY_UINT8 *p0, *p1;
v0 = 0;
v1 = 255;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_UINT8(v0, v1);
TEST_ASSERT_GREATER_THAN_UINT8(*p0, v1);
TEST_ASSERT_GREATER_THAN_UINT8(v0, *p1);
TEST_ASSERT_GREATER_THAN_UINT8(*p0, *p1);
}
void testGreaterThanUINT16(void)
{
UNITY_UINT16 v0, v1;
UNITY_UINT16 *p0, *p1;
v0 = 0;
v1 = 65535;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_UINT16(v0, v1);
TEST_ASSERT_GREATER_THAN_UINT16(*p0, v1);
TEST_ASSERT_GREATER_THAN_UINT16(v0, *p1);
TEST_ASSERT_GREATER_THAN_UINT16(*p0, *p1);
}
void testGreaterThanUINT32(void)
{
UNITY_UINT32 v0, v1;
UNITY_UINT32 *p0, *p1;
v0 = 0;
v1 = 4294967295;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_UINT32(v0, v1);
TEST_ASSERT_GREATER_THAN_UINT32(*p0, v1);
TEST_ASSERT_GREATER_THAN_UINT32(v0, *p1);
TEST_ASSERT_GREATER_THAN_UINT32(*p0, *p1);
}
void testGreaterThanHEX8(void)
{
UNITY_UINT8 v0, v1;
UNITY_UINT8 *p0, *p1;
v0 = 0x00;
v1 = 0xFF;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_HEX8(v0, v1);
TEST_ASSERT_GREATER_THAN_HEX8(*p0, v1);
TEST_ASSERT_GREATER_THAN_HEX8(v0, *p1);
TEST_ASSERT_GREATER_THAN_HEX8(*p0, *p1);
}
void testGreaterThanHEX16(void)
{
UNITY_UINT16 v0, v1;
UNITY_UINT16 *p0, *p1;
v0 = 0x0000;
v1 = 0xFFFF;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_HEX16(v0, v1);
TEST_ASSERT_GREATER_THAN_HEX16(*p0, v1);
TEST_ASSERT_GREATER_THAN_HEX16(v0, *p1);
TEST_ASSERT_GREATER_THAN_HEX16(*p0, *p1);
}
void testGreaterThanHEX32(void)
{
UNITY_UINT32 v0, v1;
UNITY_UINT32 *p0, *p1;
v0 = 0x00000000;
v1 = 0xFFFFFFFF;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_GREATER_THAN_HEX32(v0, v1);
TEST_ASSERT_GREATER_THAN_HEX32(*p0, v1);
TEST_ASSERT_GREATER_THAN_HEX32(v0, *p1);
TEST_ASSERT_GREATER_THAN_HEX32(*p0, *p1);
}
void testNotGreaterThan(void)
{
EXPECT_ABORT_BEGIN
TEST_ASSERT_GREATER_THAN(0, -1);
VERIFY_FAILS_END
}
void testLessThan(void)
{
UNITY_INT v0, v1;
UNITY_INT *p0, *p1;
v0 = 0;
v1 = -1;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN(v0, v1);
TEST_ASSERT_LESS_THAN(*p0, v1);
TEST_ASSERT_LESS_THAN(v0, *p1);
TEST_ASSERT_LESS_THAN(*p0, *p1);
}
void testLessThanINT(void)
{
UNITY_INT v0, v1;
UNITY_INT *p0, *p1;
v0 = 3334;
v1 = 302;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_INT(v0, v1);
TEST_ASSERT_LESS_THAN_INT(*p0, v1);
TEST_ASSERT_LESS_THAN_INT(v0, *p1);
TEST_ASSERT_LESS_THAN_INT(*p0, *p1);
}
void testLessThanINT8(void)
{
UNITY_INT8 v0, v1;
UNITY_INT8 *p0, *p1;
v0 = 127;
v1 = -128;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_INT8(v0, v1);
TEST_ASSERT_LESS_THAN_INT8(*p0, v1);
TEST_ASSERT_LESS_THAN_INT8(v0, *p1);
TEST_ASSERT_LESS_THAN_INT8(*p0, *p1);
}
void testLessThanINT16(void)
{
UNITY_INT16 v0, v1;
UNITY_INT16 *p0, *p1;
v0 = 32767;
v1 = -32768;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_INT16(v0, v1);
TEST_ASSERT_LESS_THAN_INT16(*p0, v1);
TEST_ASSERT_LESS_THAN_INT16(v0, *p1);
TEST_ASSERT_LESS_THAN_INT16(*p0, *p1);
}
void testLessThanINT32(void)
{
UNITY_INT32 v0, v1;
UNITY_INT32 *p0, *p1;
v0 = 214783647;
v1 = -214783648;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_INT32(v0, v1);
TEST_ASSERT_LESS_THAN_INT32(*p0, v1);
TEST_ASSERT_LESS_THAN_INT32(v0, *p1);
TEST_ASSERT_LESS_THAN_INT32(*p0, *p1);
}
void testLessThanUINT(void)
{
UNITY_UINT v0, v1;
UNITY_UINT *p0, *p1;
v0 = 1;
v1 = 0;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_UINT(v0, v1);
TEST_ASSERT_LESS_THAN_UINT(*p0, v1);
TEST_ASSERT_LESS_THAN_UINT(v0, *p1);
TEST_ASSERT_LESS_THAN_UINT(*p0, *p1);
}
void testLessThanUINT8(void)
{
UNITY_UINT8 v0, v1;
UNITY_UINT8 *p0, *p1;
v0 = 255;
v1 = 0;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_UINT8(v0, v1);
TEST_ASSERT_LESS_THAN_UINT8(*p0, v1);
TEST_ASSERT_LESS_THAN_UINT8(v0, *p1);
TEST_ASSERT_LESS_THAN_UINT8(*p0, *p1);
}
void testLessThanUINT16(void)
{
UNITY_UINT16 v0, v1;
UNITY_UINT16 *p0, *p1;
v0 = 65535;
v1 = 0;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_UINT16(v0, v1);
TEST_ASSERT_LESS_THAN_UINT16(*p0, v1);
TEST_ASSERT_LESS_THAN_UINT16(v0, *p1);
TEST_ASSERT_LESS_THAN_UINT16(*p0, *p1);
}
void testLessThanUINT32(void)
{
UNITY_UINT32 v0, v1;
UNITY_UINT32 *p0, *p1;
v0 = 4294967295;
v1 = 0;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_UINT32(v0, v1);
TEST_ASSERT_LESS_THAN_UINT32(*p0, v1);
TEST_ASSERT_LESS_THAN_UINT32(v0, *p1);
TEST_ASSERT_LESS_THAN_UINT32(*p0, *p1);
}
void testLessThanHEX8(void)
{
UNITY_UINT8 v0, v1;
UNITY_UINT8 *p0, *p1;
v0 = 0xFF;
v1 = 0x00;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_HEX8(v0, v1);
TEST_ASSERT_LESS_THAN_HEX8(*p0, v1);
TEST_ASSERT_LESS_THAN_HEX8(v0, *p1);
TEST_ASSERT_LESS_THAN_HEX8(*p0, *p1);
}
void testLessThanHEX16(void)
{
UNITY_UINT16 v0, v1;
UNITY_UINT16 *p0, *p1;
v0 = 0xFFFF;
v1 = 0x0000;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_HEX16(v0, v1);
TEST_ASSERT_LESS_THAN_HEX16(*p0, v1);
TEST_ASSERT_LESS_THAN_HEX16(v0, *p1);
TEST_ASSERT_LESS_THAN_HEX16(*p0, *p1);
}
void testLessThanHEX32(void)
{
UNITY_UINT32 v0, v1;
UNITY_UINT32 *p0, *p1;
v0 = 0xFFFFFFFF;
v1 = 0x00000000;
p0 = &v0;
p1 = &v1;
TEST_ASSERT_LESS_THAN_HEX32(v0, v1);
TEST_ASSERT_LESS_THAN_HEX32(*p0, v1);
TEST_ASSERT_LESS_THAN_HEX32(v0, *p1);
TEST_ASSERT_LESS_THAN_HEX32(*p0, *p1);
}
void testNotLessThan(void)
{
EXPECT_ABORT_BEGIN
TEST_ASSERT_LESS_THAN(0, 1);
VERIFY_FAILS_END
}
//-----------------
void testEqualStrings(void)
{
const char *testString = "foo";
@@ -4056,61 +4466,46 @@ void testFloatPrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.0", 0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.000000...", 0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.000001", 0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.100469499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0", 0.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0", 1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7.999999", 7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.000002", 16.000002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.000004", 16.000004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.000006", 16.000006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4294967040.0", 4294967040.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("0", 0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.99e-07", 0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e-07", 0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.100469499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 0.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7.99999", 7.99999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0002", 16.0002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0004", 16.0004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0006", 16.0006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("999999", 999999.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.0", -0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.000000...",-0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.000001", -0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469", -0.100469499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.0", -0.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.0", -1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.999999", -7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.000002", -16.000002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.000004", -16.000004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.000006", -16.000006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4294967040.0",-4294967040.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0", -0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.99e-07", -0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-5e-07", -0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469", -0.100469499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -0.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.99999", -7.99999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0002", -16.0002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0004", -16.0004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0006", -16.0006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-999999", -999999.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967296.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5.0e+09", 5000000000.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8.0e+09", 8.0e+09f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8.3099991e+09", 8309999104.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0e+10", 1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0e+10", 10000000000.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967296.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e+09", 5000000000.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8e+09", 8.0e+09f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8.31e+09", 8309999104.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 10000000000.0f);
/* Some compilers have trouble with inexact float constants, a float cast works generally */
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.00005499e+10", (float)1.000055e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.10000006e+38", (float)1.10000005e+38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.63529943e+10", 1.63529943e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3.40282347e+38", 3.40282346638e38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.00005e+10", (float)1.000054e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.1e+38", (float)1.10000005e+38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.6353e+10", 1.63529943e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3.40282e+38", 3.40282346638e38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.0e+10", -1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-3.40282347e+38",-3.40282346638e38f);
#endif
}
void testFloatPrintingRoundTiesToEven(void)
{
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
#ifdef UNITY_ROUND_TIES_AWAY_FROM_ZERO
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.007813", 0.0078125f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.976563", 0.9765625f);
#else /* Default to Round ties to even */
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.007182", 0.0071825f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.976562", 0.9765625f);
#endif
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1e+10", -1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-3.40282e+38", -3.40282346638e38f);
#endif
}
@@ -4119,105 +4514,69 @@ void testFloatPrintingInfinityAndNaN(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING("Inf", 1.0f / f_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-Inf", -1.0f / f_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("inf", 1.0f / f_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-inf", -1.0f / f_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("NaN", 0.0f / f_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("nan", 0.0f / f_zero);
#endif
}
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
static void AllFloatPrinting_LessThan32Bits(void)
static void printFloatValue(float f)
{
char expected[18];
union { float f_value; int32_t int_value; } u;
/* Float representations are laid out in integer order, walk up the list */
for (u.f_value = 0.00000050000005f; u.f_value <= 4294967040.0f; u.int_value += 1)
char expected_lower[18];
char expected_higher[18];
startPutcharSpy();
UnityPrintFloat(f);
sprintf(expected, "%.6g", f);
/* We print all NaN's as "nan", not "-nan" */
if(strcmp(expected, "-nan") == 0) strcpy(expected, "nan");
/* Allow for rounding differences in last digit */
double lower = (double)f * 0.9999995;
double higher = (double)f * 1.0000005;
if (isfinite(lower)) sprintf(expected_lower, "%.6g", lower); else strcpy(expected_lower, expected);
if (isfinite(higher)) sprintf(expected_higher, "%.6g", higher); else strcpy(expected_higher, expected);
if (strcmp(expected, getBufferPutcharSpy()) != 0 &&
strcmp(expected_lower, getBufferPutcharSpy()) != 0 &&
strcmp(expected_higher, getBufferPutcharSpy()) != 0)
{
startPutcharSpy();
UnityPrintFloat(u.f_value); /*1.5x as fast as sprintf 5e-7f - 0.01f, 20s vs 30s*/
int len = sprintf(expected, "%.6f", u.f_value);
while (expected[len - 1] == '0' && expected[len - 2] != '.') { len--; }
expected[len] = '\0'; /* delete trailing 0's */
if (strcmp(expected, getBufferPutcharSpy()) != 0)
{
double six_digits = ((double)u.f_value - (uint32_t)u.f_value)*1000000.0;
/* Not a tie (remainder != 0.5) => Can't explain the different strings */
if (six_digits - (uint32_t)six_digits != 0.5)
{
/* Fail with diagnostic printing */
TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, u.f_value);
}
}
}
}
/* Compared to perfect, floats are occasionally rounded wrong. It doesn't affect
* correctness, though. Two examples (of 13 total found during testing):
* Printed: 6.19256349e+20, Exact: 619256348499999981568.0f <= Eliminated by ROUND_TIES_TO_EVEN
* Printed: 2.19012272e+35, Exact: 219012271499999993621766990196637696.0f */
static void AllFloatPrinting_Larger(const float start, const float end)
{
unsigned int wrong = 0;
char expected[18];
union { float f_value; int32_t int_value; } u;
for (u.f_value = start; u.f_value <= end; u.int_value += 1)
{
startPutcharSpy();
UnityPrintFloat(u.f_value); /*Twice as fast as sprintf 2**32-1e12, 10s vs 21s*/
sprintf(expected, "%.8e", u.f_value);
int len = 11 - 1; /* 11th char is 'e' in exponential format */
while (expected[len - 1] == '0' && expected[len - 2] != '.') { len --; }
if (expected[14] != '\0') memmove(&expected[12], &expected[13], 3); /* Two char exponent */
memmove(&expected[len], &expected[11 - 1], sizeof "e+09"); /* 5 char length */
if (strcmp(expected, getBufferPutcharSpy()) != 0)
{
wrong++;
/* endPutcharSpy(); UnityPrint("Expected "); UnityPrint(expected);
UnityPrint(" Was "); UnityPrint(getBufferPutcharSpy()); UNITY_OUTPUT_CHAR('\n'); */
if (wrong > 10 || (wrong > 3 && end <= 1e25f))
TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, u.f_value);
/* Empirical values from the current routine, don't be worse when making changes */
}
/* Fail with diagnostic printing */
TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, f);
}
}
#endif
/* Exhaustive testing of all float values we differentiate when printing. Doubles
* are not explored here -- too many. These tests confirm that the routine works
* for all floats > 5e-7, positives only. Off by default due to test time.
* Compares Unity's routine to your sprintf() C lib, tested to pass on 3 platforms.
* Part1 takes a long time, around 3 minutes compiled with -O2
* Runs through all floats from 0.000001 - 2**32, ~300 million values */
void testAllFloatPrintingPart1_LessThan32Bits(void)
void testFloatPrintingRandomSamples(void)
{
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
AllFloatPrinting_LessThan32Bits();
#if !defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
TEST_IGNORE(); /* Ignore one of three */
#endif
}
union { float f_value; uint32_t int_value; } u;
/* Test takes a long time, around 3.5 minutes compiled with -O2, try ~500 million values */
void testAllFloatPrintingPart2_Larger(void)
{
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
AllFloatPrinting_Larger(4294967296.0f, 1e25f);
#endif
}
/* These values are not covered by the MINSTD generator */
u.int_value = 0x00000000; printFloatValue(u.f_value);
u.int_value = 0x80000000; printFloatValue(u.f_value);
u.int_value = 0x7fffffff; printFloatValue(u.f_value);
u.int_value = 0xffffffff; printFloatValue(u.f_value);
/* Test takes a long time, around 3.5 minutes compiled with -O2, try ~500 million values */
void testAllFloatPrintingPart3_LargerStill(void)
{
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
AllFloatPrinting_Larger(1e25f, 3.40282347e+38f);
uint32_t a = 1;
for(int num_tested = 0; num_tested < 1000000; num_tested++)
{
/* MINSTD pseudo-random number generator */
a = (uint32_t)(((uint64_t)a * 48271u) % 2147483647u);
/* MINSTD does not set the highest bit; test both possibilities */
u.int_value = a; printFloatValue(u.f_value);
u.int_value = a | 0x80000000; printFloatValue(u.f_value);
}
#endif
}
@@ -4893,35 +5252,20 @@ void testDoublePrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4294967295.999999", 4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967296.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0e+10", 9999999995.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.00719925e+15", 9007199254740990.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7.0e+100", 7.0e+100);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3.0e+200", 3.0e+200);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.23456789e+300", 9.23456789e+300);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967296.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 9999999995.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.0072e+15", 9007199254740990.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7e+100", 7.0e+100);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3e+200", 3.0e+200);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.23457e+300", 9.23456789e+300);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469", -0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4294967295.999999", -4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.2949673e+09", -4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7.0e+100", -7.0e+100);
#endif
}
void testDoublePrintingRoundTiesToEven(void)
{
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
#ifdef UNITY_ROUND_TIES_AWAY_FROM_ZERO
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.00000001e+10", 10000000050.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.00719925e+15", 9007199245000000.0);
#else /* Default to Round ties to even */
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0e+10", 10000000050.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.00719924e+15", 9007199245000000.0);
#endif
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469", -0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.29497e+09", -4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.29497e+09", -4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7e+100", -7.0e+100);
#endif
}
@@ -4930,10 +5274,10 @@ void testDoublePrintingInfinityAndNaN(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE();
#else
TEST_ASSERT_EQUAL_PRINT_FLOATING("Inf", 1.0 / d_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-Inf", -1.0 / d_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("inf", 1.0 / d_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-inf", -1.0 / d_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("NaN", 0.0 / d_zero);
TEST_ASSERT_EQUAL_PRINT_FLOATING("nan", 0.0 / d_zero);
#endif
}

6
valgrind.supp Normal file
View File

@@ -0,0 +1,6 @@
{
suppress_ld_on_armv7
Memcheck:Cond
...
obj:*/ld-*.so
}