Compare commits

..

7 Commits

Author SHA1 Message Date
Max Bruckner
7aed06e364 WIP: Libfuzzer 2017-06-06 14:43:09 +02:00
Max Bruckner
33865a75a1 tests/print_number: Add test with 17 digits of precision 2017-06-06 14:35:54 +02:00
Max Bruckner
6d3a32122e tests/print_number: Use proper double literals 2017-06-06 14:35:54 +02:00
Max Bruckner
ed549df6e7 Add warning -Wswitch-enum 2017-06-06 14:35:54 +02:00
Max Bruckner
7aa668ee7a Add warning -Wused-but-marked-unused 2017-06-06 14:35:54 +02:00
Max Bruckner
7f8ee7084a Add warning -Wmissing-variable-declarations 2017-06-06 14:35:53 +02:00
Max Bruckner
5f1fdb4c6f Add warning -Wunused-macro 2017-06-06 14:35:50 +02:00
96 changed files with 1443 additions and 5093 deletions

View File

@@ -1,23 +0,0 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[Makefile]
indent_style = tab
indent_size = unset
# ignore external repositories and test inputs
[tests/{unity,json-patch-tests,inputs}/*]
indent_style = unset
indent_size = unset
end_of_line = unset
charset = unset
trim_trailing_whitespace = unset
insert_final_newline = unset

11
.gitattributes vendored
View File

@@ -1,11 +0,0 @@
* text=auto
/tests/inputs/* text eol=lf
.gitattributes export-ignore
.gitignore export-ignore
.github export-ignore
.editorconfig export-ignore
.travis.yml export-ignore
# Linguist incorrectly identified the headers as C++, manually override this.
*.h linguist-language=C

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

View File

@@ -1,102 +0,0 @@
name: CI
on:
push:
branches: [ master ]
paths-ignore:
- '**.md'
- 'LICENSE'
pull_request:
types: [opened, synchronize]
paths-ignore:
- '**.md'
- 'LICENSE'
jobs:
linux:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'ci skip')"
strategy:
fail-fast: false
matrix:
mem_check:
- ENABLE_VALGRIND
- ENABLE_SANITIZERS
- NONE_MEM_CHECK
compiler:
- GCC
- CLANG
steps:
- uses: actions/checkout@v2
- name: install build dependencies
run: |
sudo apt-get update
sudo apt-get install clang-8 valgrind
- name: build and test
shell: bash
run: |
if [ "${{ matrix.mem_check }}" == "ENABLE_VALGRIND" ]; then
EVENT_CMAKE_OPTIONS="-DENABLE_CJSON_UTILS=ON -DENABLE_VALGRIND=ON -DENABLE_SAFE_STACK=ON -DENABLE_SANITIZERS=OFF"
elif [ "${{ matrix.mem_check }}" == "ENABLE_SANITIZERS" ]; then
EVENT_CMAKE_OPTIONS="-DENABLE_CJSON_UTILS=ON -DENABLE_VALGRIND=OFF -DENABLE_SAFE_STACK=OFF -DENABLE_SANITIZERS=ON"
else
EVENT_CMAKE_OPTIONS="-DENABLE_CJSON_UTILS=ON -DENABLE_VALGRIND=OFF -DENABLE_SAFE_STACK=OFF -DENABLE_SANITIZERS=OFF"
fi
if [ "${{ matrix.compiler }}" == "GCC" ]; then
export CC=gcc
else
export CC=clang
fi
#run build and test
JOBS=20
export CTEST_PARALLEL_LEVEL=$JOBS
export CTEST_OUTPUT_ON_FAILURE=1
mkdir -p build
cd build
echo [cmake]: cmake .. $EVENT_CMAKE_OPTIONS
cmake .. $EVENT_CMAKE_OPTIONS || (rm -rf * && cmake .. $EVENT_CMAKE_OPTIONS)
cmake --build .
make
make test
macos:
runs-on: macos-latest
if: "!contains(github.event.head_commit.message, 'ci skip')"
strategy:
fail-fast: false
matrix:
mem_check:
- ENABLE_VALGRIND
- ENABLE_SANITIZERS
- NONE_MEM_CHECK
compiler:
- GCC
- CLANG
steps:
- uses: actions/checkout@v2
- name: build and test
shell: bash
run: |
if [ "${{ matrix.mem_check }}" == "ENABLE_VALGRIND" ]; then
EVENT_CMAKE_OPTIONS="-DENABLE_CJSON_UTILS=ON -DENABLE_VALGRIND=ON -DENABLE_SAFE_STACK=ON -DENABLE_SANITIZERS=OFF"
elif [ "${{ matrix.mem_check }}" == "ENABLE_SANITIZERS" ]; then
EVENT_CMAKE_OPTIONS="-DENABLE_CJSON_UTILS=ON -DENABLE_VALGRIND=OFF -DENABLE_SAFE_STACK=OFF -DENABLE_SANITIZERS=ON"
else
EVENT_CMAKE_OPTIONS="-DENABLE_CJSON_UTILS=ON -DENABLE_VALGRIND=OFF -DENABLE_SAFE_STACK=OFF -DENABLE_SANITIZERS=OFF"
fi
if [ "${{ matrix.compiler }}" == "GCC" ]; then
export CC=gcc
else
export CC=clang
fi
#run build and test
JOBS=20
export CTEST_PARALLEL_LEVEL=$JOBS
export CTEST_OUTPUT_ON_FAILURE=1
mkdir -p build
cd build
echo [cmake]: cmake .. $EVENT_CMAKE_OPTIONS
cmake .. $EVENT_CMAKE_OPTIONS || (rm -rf * && cmake .. $EVENT_CMAKE_OPTIONS)
cmake --build .
make
make test

3
.gitignore vendored
View File

@@ -13,6 +13,3 @@ cJSON_test_utils
libcjson.so.* libcjson.so.*
libcjson_utils.so.* libcjson_utils.so.*
*.orig *.orig
.vscode
.idea
cmake-build-debug

View File

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

View File

@@ -1,233 +1,43 @@
1.7.15 (Aug 25, 2021) 1.5.4
======
Fixes:
------
* Fix potential core dumped for strrchr, see [#546](https://github.com/DaveGamble/cJSON/pull/546)
* Fix null pointer crash in cJSON_CreateXxArray, see [#538](https://github.com/DaveGamble/cJSON/pull/538)
* Fix several null pointer problems on allocation failure, see [#526](https://github.com/DaveGamble/cJSON/pull/526)
* Fix a possible dereference of null pointer, see [#519](https://github.com/DaveGamble/cJSON/pull/519)
* Fix windows build failure about defining nan, see [#518](https://github.com/DaveGamble/cJSON/pull/518)
1.7.14 (Sep 3, 2020)
======
Fixes:
------
* optimize the way to find tail node, see [#503](https://github.com/DaveGamble/cJSON/pull/503)
* Fix WError error on macosx because NAN is a float. Thanks @sappo, see [#484](https://github.com/DaveGamble/cJSON/pull/484)
* Fix some bugs in detach and replace. Thanks @miaoerduo, see [#456](https://github.com/DaveGamble/cJSON/pull/456)
1.7.13 (Apr 2, 2020)
======
Features:
---------
* add new API of cJSON_ParseWithLength without breaking changes. Thanks @caglarivriz, see [#358](https://github.com/DaveGamble/cJSON/pull/358)
* add new API of cJSON_GetNumberValue. Thanks @Intuition, see[#385](https://github.com/DaveGamble/cJSON/pull/385)
* add uninstall target function for CMake. See [#402](https://github.com/DaveGamble/cJSON/pull/402)
* Improve performance of adding item to array. Thanks @xiaomianhehe, see [#430](https://github.com/DaveGamble/cJSON/pull/430), [#448](https://github.com/DaveGamble/cJSON/pull/448)
* add new API of cJSON_SetValuestring, for changing the valuestring safely. See [#451](https://github.com/DaveGamble/cJSON/pull/451)
* add return value for cJSON_AddItemTo... and cJSON_ReplaceItem... (check if the operation successful). See [#453](https://github.com/DaveGamble/cJSON/pull/453)
Fixes:
------
* Fix clang -Wfloat-equal warning. Thanks @paulmalovanyi, see [#368](https://github.com/DaveGamble/cJSON/pull/368)
* Fix make failed in mac os. See [#405](https://github.com/DaveGamble/cJSON/pull/405)
* Fix memory leak in cJSONUtils_FindPointerFromObjectTo. Thanks @andywolk for reporting, see [#414](https://github.com/DaveGamble/cJSON/issues/414)
* Fix bug in encode_string_as_pointer. Thanks @AIChangJiang for reporting, see [#439](https://github.com/DaveGamble/cJSON/issues/439)
1.7.12 (May 17, 2019)
======
Fixes:
------
* Fix infinite loop in `cJSON_Minify` (potential Denial of Service). Thanks @Alanscut for reporting, see [#354](https://github.com/DaveGamble/cJSON/issues/354)
* Fix link error for Visual Studio. Thanks @tan-wei, see [#352](https://github.com/DaveGamble/cJSON/pull/352).
* Undefine `true` and `false` for `cJSON_Utils` before redefining them. Thanks @raiden00pl, see [#347](https://github.com/DaveGamble/cJSON/pull/347).
1.7.11 (Apr 15, 2019)
======
Fixes:
------
* Fix a bug where cJSON_Minify could overflow it's buffer, both reading and writing. This is a security issue, see [#338](https://github.com/DaveGamble/cJSON/issues/338). Big thanks @bigric3 for reporting.
* Unset `true` and `false` macros before setting them if they exist. See [#339](https://github.com/DaveGamble/cJSON/issues/339), thanks @raiden00pl for reporting
1.7.10 (Dec 21, 2018)
======
Fixes:
------
* Fix package config file for `libcjson`. Thanks @shiluotang for reporting [#321](https://github.com/DaveGamble/cJSON/issues/321)
* Correctly split lists in `cJSON_Utils`'s merge sort. Thanks @andysCaplin for the fix [#322](https://github.com/DaveGamble/cJSON/issues/322)
1.7.9 (Dec 16, 2018)
===== =====
Fixes: Fixes:
------ ------
* Fix a bug where `cJSON_GetObjectItemCaseSensitive` would pass a nullpointer to `strcmp` when called on an array, see [#315](https://github.com/DaveGamble/cJSON/issues/315). Thanks @yuweol for reporting. * Fix build with GCC 7.1.1 and optimization level `-O2` (bfbd8fe0d85f1dd21e508748fc10fc4c27cc51be)
* Fix error in `cJSON_Utils` where the case sensitivity was not respected, see [#317](https://github.com/DaveGamble/cJSON/pull/317). Thanks @yuta-oxo for fixing.
* Fix some warnings detected by the Visual Studio Static Analyzer, see [#307](https://github.com/DaveGamble/cJSON/pull/307). Thanks @bnason-nf
1.7.8 (Sep 22, 2018)
======
Fixes:
------
* cJSON now works with the `__stdcall` calling convention on Windows, see [#295](https://github.com/DaveGamble/cJSON/pull/295), thanks @zhindes for contributing
1.7.7 (May 22, 2018)
=====
Fixes:
------
* Fix a memory leak when realloc fails, see [#267](https://github.com/DaveGamble/cJSON/issues/267), thanks @AlfieDeng for reporting
* Fix a typo in the header file, see [#266](https://github.com/DaveGamble/cJSON/pull/266), thanks @zhaozhixu
1.7.6 (Apr 13, 2018)
=====
Fixes:
------
* Add `SONAME` to the ELF files built by the Makefile, see [#252](https://github.com/DaveGamble/cJSON/issues/252), thanks @YanhaoMo for reporting
* Add include guards and `extern "C"` to `cJSON_Utils.h`, see [#256](https://github.com/DaveGamble/cJSON/issues/256), thanks @daschfg for reporting
Other changes:
* Mark the Makefile as deprecated in the README.
1.7.5 (Mar 23, 2018)
=====
Fixes:
------
* Fix a bug in the JSON Patch implementation of `cJSON Utils`, see [#251](https://github.com/DaveGamble/cJSON/pull/251), thanks @bobkocisko.
1.7.4 (Mar 3, 2018)
=====
Fixes:
------
* Fix potential use after free if the `string` parameter to `cJSON_AddItemToObject` is an alias of the `string` property of the object that is added,see [#248](https://github.com/DaveGamble/cJSON/issues/248). Thanks @hhallen for reporting.
1.7.3 (Feb 8, 2018)
=====
Fixes:
------
* Fix potential double free, thanks @projectgus for reporting [#241](https://github.com/DaveGamble/cJSON/issues/241)
1.7.2 (Feb 6, 2018)
=====
Fixes:
------
* Fix the use of GNUInstallDirs variables and the pkgconfig file. Thanks @zeerd for reporting [#240](https://github.com/DaveGamble/cJSON/pull/240)
1.7.1 (Jan 10, 2018)
=====
Fixes:
------
* Fixed an Off-By-One error that could lead to an out of bounds write. Thanks @liuyunbin for reporting [#230](https://github.com/DaveGamble/cJSON/issues/230)
* Fixed two errors with buffered printing. Thanks @liuyunbin for reporting [#230](https://github.com/DaveGamble/cJSON/issues/230)
1.7.0 (Dec 31, 2017)
=====
Features:
---------
* Large rewrite of the documentation, see [#215](https://github.com/DaveGamble/cJSON/pull/215)
* Added the `cJSON_GetStringValue` function
* Added the `cJSON_CreateStringReference` function
* Added the `cJSON_CreateArrayReference` function
* Added the `cJSON_CreateObjectReference` function
* The `cJSON_Add...ToObject` macros are now functions that return a pointer to the added item, see [#226](https://github.com/DaveGamble/cJSON/pull/226)
Fixes:
------
* Fix a problem with `GNUInstallDirs` in the CMakeLists.txt, thanks @yangfl, see [#210](https://github.com/DaveGamble/cJSON/pull/210)
* Fix linking the tests when building as static library, see [#213](https://github.com/DaveGamble/cJSON/issues/213)
* New overrides for the CMake option `BUILD_SHARED_LIBS`, see [#207](https://github.com/DaveGamble/cJSON/issues/207)
Other Changes:
--------------
* Readme: Explain how to include cJSON, see [#211](https://github.com/DaveGamble/cJSON/pull/211)
* Removed some trailing spaces in the code, thanks @yangfl, see [#212](https://github.com/DaveGamble/cJSON/pull/212)
* Updated [Unity](https://github.com/ThrowTheSwitch/Unity) and [json-patch-tests](https://github.com/json-patch/json-patch-tests)
1.6.0 (Oct 9, 2017)
=====
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](https://github.com/DaveGamble/cJSON/issues/178)
* UTF-8 byte order marks are now ignored, see [#184](https://github.com/DaveGamble/cJSON/issues/184)
* Locales can now be disabled with the option `-DENABLE_LOCALES=Off`, see [#202](https://github.com/DaveGamble/cJSON/issues/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 (Sep 8, 2017)
=====
Fixes:
------
* Set the global error pointer even if `return_parse_end` is passed to `cJSON_ParseWithOpts`, see [#200](https://github.com/DaveGamble/cJSON/pull/200), thanks @rmallins
1.5.8 (Aug 21, 2017)
=====
Fixes:
------
* Fix `make test` in the Makefile, thanks @YanhaoMo for reporting this [#195](https://github.com/DaveGamble/cJSON/issues/195)
1.5.7 (Jul 13, 2017)
=====
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](https://github.com/DaveGamble/cJSON/issues/189), fixed in [954d61e](https://github.com/DaveGamble/cJSON/commit/954d61e5e7cb9dc6c480fc28ac1cdceca07dd5bd), big thanks @timothyjohncarney for reporting this issue
* Fix a spelling mistake in the AFL fuzzer dictionary, see [#185](https://github.com/DaveGamble/cJSON/pull/185), thanks @jwilk
1.5.6 (Jun 28, 2017)
=====
Fixes:
------
* Make cJSON a lot more tolerant about passing NULL pointers to its functions, it should now fail safely instead of dereferencing the pointer, see [#183](https://github.com/DaveGamble/cJSON/pull/183). Thanks @msichal for reporting [#182](https://github.com/DaveGamble/cJSON/issues/182)
1.5.5 (Jun 15, 2017)
=====
Fixes:
------
* Fix pointers to nested arrays in cJSON_Utils, see [9abe](https://github.com/DaveGamble/cJSON/commit/9abe75e072050f34732a7169740989a082b65134)
* Fix an error with case sensitivity handling in cJSON_Utils, see [b9cc911](https://github.com/DaveGamble/cJSON/commit/b9cc911831b0b3e1bb72f142389428e59f882b38)
* Fix cJSON_Compare for arrays that are prefixes of the other and objects that are a subset of the other, see [03ba72f](https://github.com/DaveGamble/cJSON/commit/03ba72faec115160d1f3aea5582d9b6af5d3e473) and [#180](https://github.com/DaveGamble/cJSON/issues/180), thanks @zhengqb for reporting
1.5.4 (Jun 5, 2017)
======
Fixes:
------
* Fix build with GCC 7.1.1 and optimization level `-O2`, see [bfbd8fe](https://github.com/DaveGamble/cJSON/commit/bfbd8fe0d85f1dd21e508748fc10fc4c27cc51be)
Other Changes: Other Changes:
-------------- --------------
* Update [Unity](https://github.com/ThrowTheSwitch/Unity) to 3b69beaa58efc41bbbef70a32a46893cae02719d * Update [Unity](https://github.com/ThrowTheSwitch/Unity) to 3b69beaa58efc41bbbef70a32a46893cae02719d
1.5.3 (May 23, 2017) 1.5.3
===== =====
Fixes: Fixes:
------ ------
* Fix `cJSON_ReplaceItemInObject` not keeping the name of an item, see [#174](https://github.com/DaveGamble/cJSON/issues/174) * Fix `cJSON_ReplaceItemInObject` not keeping the name of an item (#174)
1.5.2 (May 10, 2017) 1.5.2
===== =====
Fixes: Fixes:
------ ------
* Fix a reading buffer overflow in `parse_string`, see [a167d9e](https://github.com/DaveGamble/cJSON/commit/a167d9e381e5c84bc03de4e261757b031c0c690d) * Fix a reading buffer overflow in `parse_string` (a167d9e381e5c84bc03de4e261757b031c0c690d)
* Fix compiling with -Wcomma, see [186cce3](https://github.com/DaveGamble/cJSON/commit/186cce3ece6ce6dfcb58ac8b2a63f7846c3493ad) * Fix compiling with -Wcomma (186cce3ece6ce6dfcb58ac8b2a63f7846c3493ad)
* Remove leftover attribute from tests, see [b537ca7](https://github.com/DaveGamble/cJSON/commit/b537ca70a35680db66f1f5b8b437f7114daa699a) * Remove leftover attribute from tests (b537ca70a35680db66f1f5b8b437f7114daa699a)
1.5.1 (May 6, 2017) 1.5.1
===== =====
Fixes: Fixes:
------ ------
* Add gcc version guard to the Makefile, see [#164](https://github.com/DaveGamble/cJSON/pull/164), thanks @juvasquezg * Add gcc version guard to the Makefile (#164), thanks @juvasquezg
* Fix incorrect free in `cJSON_Utils` if custom memory allocator is used, see [#166](https://github.com/DaveGamble/cJSON/pull/166), thanks @prefetchnta * Fix incorrect free in `cJSON_Utils` if custom memory allocator is used (#166), thanks @prefetchnta
1.5.0 (May 2, 2017) 1.5.0
===== =====
Features: Features:
* cJSON finally prints numbers without losing precision, see [#153](https://github.com/DaveGamble/cJSON/pull/153), thanks @DeboraG ---------
* `cJSON_Compare` recursively checks if two cJSON items contain the same values, see [#148](https://github.com/DaveGamble/cJSON/pull/148) * cJSON finally prints numbers without losing precision (#153) thanks @DeboraG
* Provide case sensitive versions of every function where it matters, see [#158](https://github.com/DaveGamble/cJSON/pull/158) and [#159](https://github.com/DaveGamble/cJSON/pull/159) * `cJSON_Compare` recursively checks if two cJSON items contain the same values (#148)
* Provide case sensitive versions of every function where it matters (#158, #159)
* Added `cJSON_ReplaceItemViaPointer` and `cJSON_DetachItemViaPointer` * Added `cJSON_ReplaceItemViaPointer` and `cJSON_DetachItemViaPointer`
* Added `cJSON_free` and `cJSON_malloc` that expose the internal configured memory allocators. see [02a05ee](https://github.com/DaveGamble/cJSON/commit/02a05eea4e6ba41811f130b322660bea8918e1a0) * Added `cJSON_free` and `cJSON_malloc` that expose the internal configured memory allocators. (02a05eea4e6ba41811f130b322660bea8918e1a0)
Enhancements: Enhancements:
@@ -241,7 +51,7 @@ Enhancements:
Fixes: Fixes:
------ ------
* Fix some warnings with the Microsoft compiler, see [#139](https://github.com/DaveGamble/cJSON/pull/139), thanks @PawelWMS * Fix some warnings with the Microsoft compiler (#139) thanks @PawelWMS
* Fix several bugs in cJSON_Utils, mostly found with [json-patch-tests](https://github.com/json-patch/json-patch-tests) * Fix several bugs in cJSON_Utils, mostly found with [json-patch-tests](https://github.com/json-patch/json-patch-tests)
* Prevent a stack overflow by specifying a maximum nesting depth `CJSON_NESTING_LIMIT` * Prevent a stack overflow by specifying a maximum nesting depth `CJSON_NESTING_LIMIT`
@@ -249,180 +59,180 @@ Other Changes:
-------------- --------------
* Move generated files in the `library_config` subdirectory. * Move generated files in the `library_config` subdirectory.
1.4.7 (Apr 19, 2017) 1.4.7
===== =====
Fixes: Fixes:
------ ------
* Fix `cJSONUtils_ApplyPatches`, it was completely broken and apparently nobody noticed (or at least reported it), see [075a06f](https://github.com/DaveGamble/cJSON/commit/075a06f40bdc4f836c7dd7cad690d253a57cfc50) * Fix `cJSONUtils_ApplyPatches`, it was completely broken and apparently nobody noticed (or at least reported it) (075a06f40bdc4f836c7dd7cad690d253a57cfc50)
* Fix inconsistent prototype for `cJSON_GetObjectItemCaseSensitive`, see [51d3df6](https://github.com/DaveGamble/cJSON/commit/51d3df6c9f7b56b860c8fb24abe7bab255cd4fa9), thanks @PawelWMS * Fix inconsistent prototype for `cJSON_GetObjectItemCaseSensitive` (51d3df6c9f7b56b860c8fb24abe7bab255cd4fa9) thanks @PawelWMS
1.4.6 (Apr 9, 2017) 1.4.6
===== =====
Fixes: Fixes:
------ ------
* Several corrections in the README * Several corrections in the README
* Making clear that `valueint` should not be written to * Making clear that `valueint` should not be written to
* Fix overflow detection in `ensure`, see [2683d4d](https://github.com/DaveGamble/cJSON/commit/2683d4d9873df87c4bdccc523903ddd78d1ad250) * Fix overflow detection in `ensure` (2683d4d9873df87c4bdccc523903ddd78d1ad250)
* Fix a potential null pointer dereference in cJSON_Utils, see [795c3ac](https://github.com/DaveGamble/cJSON/commit/795c3acabed25c9672006b2c0f40be8845064827) * Fix a potential null pointer dereference in cJSON_Utils (795c3acabed25c9672006b2c0f40be8845064827)
* Replace incorrect `sizeof('\0')` with `sizeof("")`, see [84237ff](https://github.com/DaveGamble/cJSON/commit/84237ff48e69825c94261c624eb0376d0c328139) * Replace incorrect `sizeof('\0')` with `sizeof("")` (84237ff48e69825c94261c624eb0376d0c328139)
* Add caveats section to the README, see [50b3c30](https://github.com/DaveGamble/cJSON/commit/50b3c30dfa89830f8f477ce33713500740ac3b79) * Add caveats section to the README (50b3c30dfa89830f8f477ce33713500740ac3b79)
* Make cJSON locale independent, see [#146](https://github.com/DaveGamble/cJSON/pull/146), Thanks @peterh for reporting * Make cJSON locale independent (#146) Thanks @peterh for reporting
* Fix compiling without CMake with MSVC, see [#147](https://github.com/DaveGamble/cJSON/pull/147), Thanks @dertuxmalwieder for reporting * Fix compiling without CMake with MSVC (#147) Thanks @dertuxmalwieder for reporting
1.4.5 (Mar 28, 2017) 1.4.5
===== =====
Fixes: Fixes:
------ ------
* Fix bug in `cJSON_SetNumberHelper`, thanks @mmkeeper, see [#138](https://github.com/DaveGamble/cJSON/issues/138) and [ef34500](https://github.com/DaveGamble/cJSON/commit/ef34500693e8c4a2849d41a4bd66fd19c9ec46c2) * Fix bug in `cJSON_SetNumberHelper`, thanks @mmkeeper (#138 ef34500693e8c4a2849d41a4bd66fd19c9ec46c2)
* Workaround for internal compiler error in GCC 5.4.0 and 6.3.1 on x86 (2f65e80a3471d053fdc3f8aed23d01dd1782a5cb [GCC bugreport](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80097)) * Workaround for internal compiler error in GCC 5.4.0 and 6.3.1 on x86 (2f65e80a3471d053fdc3f8aed23d01dd1782a5cb [GCC bugreport](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80097))
1.4.4 (Mar 24, 2017) 1.4.4
===== =====
Fixes: Fixes:
------ --------
* Fix a theoretical integer overflow, (not sure if it is possible on actual hardware), see [e58f7ec](https://github.com/DaveGamble/cJSON/commit/e58f7ec027d00b7cdcbf63e518c1b5268b29b3da) * Fix a theoretical integer overflow, (not sure if it is possible on actual hardware) e58f7ec027d00b7cdcbf63e518c1b5268b29b3da
* Fix an off by one error, see [cc84a44](https://github.com/DaveGamble/cJSON/commit/cc84a446be20cc283bafdc4d94c050ba1111ac02), thanks @gatzka * Fix an off by one error (cc84a446be20cc283bafdc4d94c050ba1111ac02), thanks @gatzka
* Double check the offset of the print buffer in `ensure`, see [1934059](https://github.com/DaveGamble/cJSON/commit/1934059554b9a0971e00f79e96900f422cfdd114) * Double check the offset of the print buffer in `ensure` (1934059554b9a0971e00f79e96900f422cfdd114)
Improvements: Improvements:
* Add a note in the header about required buffer size when using `cJSON_PrintPreallocated`, see [4bfb8800](https://github.com/DaveGamble/cJSON/commit/4bfb88009342fb568295a7f6dc4b7fee74fbf022) -------------
* Add a note in the header about required buffer size when using `cJSON_PrintPreallocated` (4bfb88009342fb568295a7f6dc4b7fee74fbf022)
1.4.3 (Mar 19, 2017) 1.4.3
===== =====
Fixes: Fixes:
------ ------
* Fix compilation of the tests on 32 bit PowerPC and potentially other systems, see [4ec6e76](https://github.com/DaveGamble/cJSON/commit/4ec6e76ea2eec16f54b58e8c95b4c734e59481e4) * Fix compilation of the tests on 32 bit PowerPC and potentially other systems (4ec6e76ea2eec16f54b58e8c95b4c734e59481e4)
* Fix compilation with old GCC compilers (4.3+ were tested), see [227d33](https://github.com/DaveGamble/cJSON/commit/227d3398d6b967879761ebe02c1b63dbd6ea6e0d), [466eb8e](https://github.com/DaveGamble/cJSON/commit/466eb8e3f8a65080f2b3ca4a79ab7b72bd539dba), see also [#126](https://github.com/DaveGamble/cJSON/issues/126) * Fix compilation with old GCC compilers (4.3+ were tested) (227d3398d6b967879761ebe02c1b63dbd6ea6e0d, 466eb8e3f8a65080f2b3ca4a79ab7b72bd539dba), see also #126
1.4.2 (Mar 16, 2017) 1.4.2
===== =====
Fixes: Fixes:
------ ------
* Fix minimum required cmake version, see [30e1e7a](https://github.com/DaveGamble/cJSON/commit/30e1e7af7c63db9b55f5a3cda977a6c032f0b132) * Fix minimum required cmake version (30e1e7af7c63db9b55f5a3cda977a6c032f0b132)
* Fix detection of supported compiler flags, see [76e5296](https://github.com/DaveGamble/cJSON/commit/76e5296d0d05ceb3018a9901639e0e171b44a557) * Fix detection of supported compiler flags (76e5296d0d05ceb3018a9901639e0e171b44a557)
* Run `cJSON_test` and `cJSON_test_utils` along with unity tests, see [c597601](https://github.com/DaveGamble/cJSON/commit/c597601cf151a757dcf800548f18034d4ddfe2cb) * Run `cJSON_test` and `cJSON_test_utils` along with unity tests (c597601cf151a757dcf800548f18034d4ddfe2cb)
1.4.1 (Mar 16, 2017) 1.4.1
===== =====
Fixes: Fix: Make `print_number` abort with a failure in out of memory situations (cf1842dc6f64c49451a022308b4415e4d468be0a)
------
* Make `print_number` abort with a failure in out of memory situations, see [cf1842](https://github.com/DaveGamble/cJSON/commit/cf1842dc6f64c49451a022308b4415e4d468be0a)
1.4.0 (Mar 4, 2017) 1.4.0
===== =====
Features Features
-------- --------
* Functions to check the type of an item, see [#120](https://github.com/DaveGamble/cJSON/pull/120) * Functions to check the type of an item (#120)
* Use dllexport on windows and fvisibility on Unix systems for public functions, see [#116](https://github.com/DaveGamble/cJSON/pull/116), thanks @mjerris * Use dllexport on windows and fvisibility on Unix systems for public functions (#116), thanks @mjerris
* Remove trailing zeroes from printed numbers, see [#123](https://github.com/DaveGamble/cJSON/pull/123) * Remove trailing zeroes from printed numbers (#123)
* Expose the internal boolean type `cJSON_bool` in the header, see [2d3520e](https://github.com/DaveGamble/cJSON/commit/2d3520e0b9d0eb870e8886e8a21c571eeddbb310) * Expose the internal boolean type `cJSON_bool` in the header (2d3520e0b9d0eb870e8886e8a21c571eeddbb310)
Fixes Fixes
* Fix handling of NULL pointers in `cJSON_ArrayForEach`, see [b47d0e3](https://github.com/DaveGamble/cJSON/commit/b47d0e34caaef298edfb7bd09a72cfff21d231ff) -----
* Make it compile with GCC 7 (fix -Wimplicit-fallthrough warning), see [9d07917](https://github.com/DaveGamble/cJSON/commit/9d07917feb1b613544a7513d19233d4c851ad7ad) * Fix handling of NULL pointers in `cJSON_ArrayForEach` (b47d0e34caaef298edfb7bd09a72cfff21d231ff)
* Make it compile with GCC 7 (fix -Wimplicit-fallthrough warning) (9d07917feb1b613544a7513d19233d4c851ad7ad)
Other Improvements Other Improvements
* internally use realloc if available ([#110](https://github.com/DaveGamble/cJSON/pull/110)) ------------------
* builtin support for fuzzing with [afl](http://lcamtuf.coredump.cx/afl/) ([#111](https://github.com/DaveGamble/cJSON/pull/111)) * internally use realloc if available (#110)
* unit tests for the print functions ([#112](https://github.com/DaveGamble/cJSON/pull/112)) * builtin support for fuzzing with [afl](http://lcamtuf.coredump.cx/afl/) (#111)
* Always use buffered printing ([#113](https://github.com/DaveGamble/cJSON/pull/113)) * unit tests for the print functions (#112)
* simplify the print functions ([#114](https://github.com/DaveGamble/cJSON/pull/114)) * Always use buffered printing (#113)
* Add the compiler flags `-Wdouble-conversion`, `-Wparentheses` and `-Wcomma` ([#122](https://github.com/DaveGamble/cJSON/pull/122)) * simplify the print functions (#114)
* Add the compiler flags `-Wdouble-conversion`, `-Wparentheses` and `-Wcomma` (#122)
1.3.2 (Mar 1, 2017) 1.3.2
===== =====
Fixes: Fix:
------ ----
* Don't build the unity library if testing is disabled, see [#121](https://github.com/DaveGamble/cJSON/pull/121). Thanks @ffontaine - Don't build the unity library if testing is disabled ( #121 ). Thanks @ffontaine
1.3.1 (Feb 27, 2017) 1.3.1
===== =====
Fixes: Bugfix release that fixes an out of bounds read #118. This shouldn't have any security implications.
------
* Bugfix release that fixes an out of bounds read, see [#118](https://github.com/DaveGamble/cJSON/pull/118). This shouldn't have any security implications.
1.3.0 (Feb 17, 2017) 1.3.0
===== =====
This release includes a lot of rework in the parser and includes the Cunity unit testing framework, as well as some fixes. I increased the minor version number because there were quite a lot of internal changes. This release includes a lot of rework in the parser and includes the Cunity unit testing framework, as well as some fixes. I increased the minor version number because there were quite a lot of internal changes.
Features: Features:
* New type for cJSON structs: `cJSON_Invalid`, see [#108](https://github.com/DaveGamble/cJSON/pull/108) ---------
- New type for cJSON structs: `cJSON_Invalid` (#108)
Fixes: Fixes:
------ ------
* runtime checks for a lot of potential integer overflows - runtime checks for a lot of potential integer overflows
* fix incorrect return in cJSON_PrintBuffered [cf9d57d](https://github.com/DaveGamble/cJSON/commit/cf9d57d56cac21fc59465b8d26cf29bf6d2a87b3) - fix incorrect return in cJSON_PrintBuffered (cf9d57d56cac21fc59465b8d26cf29bf6d2a87b3)
* fix several potential issues found by [Coverity](https://scan.coverity.com/projects/cjson) - fix several potential issues found by [Coverity](https://scan.coverity.com/projects/cjson)
* fix potentially undefined behavior when assigning big numbers to `valueint` ([41e2837](https://github.com/DaveGamble/cJSON/commit/41e2837df1b1091643aff073f2313f6ff3cc10f4)) - fix potentially undefined behavior when assigning big numbers to `valueint` (41e2837df1b1091643aff073f2313f6ff3cc10f4)
* Numbers exceeding `INT_MAX` or lower than `INT_MIN` will be explicitly assigned to `valueint` as `INT_MAX` and `INT_MIN` respectively (saturation on overflow). - Numbers exceeding `INT_MAX` or lower than `INT_MIN` will be explicitly assigned to `valueint` as `INT_MAX` and `INT_MIN` respectively (saturation on overflow).
* fix the `cJSON_SetNumberValue` macro ([87f7727](https://github.com/DaveGamble/cJSON/commit/87f77274de6b3af00fb9b9a7f3b900ef382296c2)), this slightly changes the behavior, see commit message - fix the `cJSON_SetNumberValue` macro (87f77274de6b3af00fb9b9a7f3b900ef382296c2), this slightly changes the behavior, see commit message
Introduce unit tests Introduce unit tests
-------------------- --------------------
* Started writing unit tests with the [Cunity](https://github.com/ThrowTheSwitch/Unity) testing framework. Currently this covers the parser functions. Started writing unit tests with the [Cunity](https://github.com/ThrowTheSwitch/Unity) testing framework. Currently this covers the parser functions.
Also: Also:
* Support for running the tests with [Valgrind](http://valgrind.org) - Support for running the tests with [Valgrind](http://valgrind.org)
* Support for compiling the tests with [AddressSanitizer](https://github.com/google/sanitizers) and [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html). - Support for compiling the tests with [AddressSanitizer](https://github.com/google/sanitizers) and [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html).
* `travis.yml` file for running unit tests on travis. (not enabled for the repository yet though [#102](https://github.com/DaveGamble/cJSON/issues/102) - `travis.yml` file for running unit tests on travis. (not enabled for the repository yet though #102)
Simplifications Simplifications
--------------- ---------------
After having unit tests for the parser function in place, I started refactoring the parser functions (as well as others) and making them easier to read and maintain. After having unit tests for the parser function in place, I started refactoring the parser functions (as well as others) and making them easier to read and maintain.
* Use `strtod` from the standard library for parsing numbers ([0747669](https://github.com/DaveGamble/cJSON/commit/074766997246481dfc72bfa78f07898a2716473f)) - Use `strtod` from the standard library for parsing numbers (074766997246481dfc72bfa78f07898a2716473f)
* Use goto-fail in several parser functions ([#100](https://github.com/DaveGamble/cJSON/pull/100)) - Use goto-fail in several parser functions (#100)
* Rewrite/restructure all of the parsing functions to be easier to understand and have less code paths doing the same as another. ([#109](https://github.com/DaveGamble/cJSON/pull/109)) - Rewrite/restructure all of the parsing functions to be easier to understand and have less code paths doing the same as another. (#109)
* Simplify the buffer allocation strategy to always doubling the needed amount ([9f6fa94](https://github.com/DaveGamble/cJSON/commit/9f6fa94c91a87b71e4c6868dbf2ce431a48517b0)) - Simplify the buffer allocation strategy to always doubling the needed amount (9f6fa94c91a87b71e4c6868dbf2ce431a48517b0)
* Combined `cJSON_AddItemToObject` and `cJSON_AddItemToObjectCS` to one function ([cf862d](https://github.com/DaveGamble/cJSON/commit/cf862d0fed7f9407e4b046d78d3d8050d2080d12)) - Combined `cJSON_AddItemToObject` and `cJSON_AddItemToObjectCS` to one function (cf862d0fed7f9407e4b046d78d3d8050d2080d12)
Other changes Other changes
------------- -------------
* Prevent the usage of incompatible C and header versions via preprocessor directive ([123bb1](https://github.com/DaveGamble/cJSON/commit/123bb1af7bfae41d805337fef4b41045ef6c7d25)) - Prevent the usage of incompatible C and header versions via preprocessor directive (123bb1af7bfae41d805337fef4b41045ef6c7d25)
* Let CMake automatically detect compiler flags - Let CMake automatically detect compiler flags
* Add new compiler flags (`-Wundef`, `-Wswitch-default`, `-Wconversion`, `-fstack-protector-strong`) ([#98](https://github.com/DaveGamble/cJSON/pull/98)) - Add new compiler flags (`-Wundef`, `-Wswitch-default`, `-Wconversion`, `-fstack-protector-strong`) (#98)
* Change internal sizes from `int` to `size_t` ([ecd5678](https://github.com/DaveGamble/cJSON/commit/ecd5678527a6bc422da694e5be9e9979878fe6a0)) - Change internal sizes from `int` to `size_t` (ecd5678527a6bc422da694e5be9e9979878fe6a0)
* Change internal strings from `char*` to `unsigned char*` ([28b9ba4](https://github.com/DaveGamble/cJSON/commit/28b9ba4334e0f7309e867e874a31f395c0ac2474)) - Change internal strings from `char*` to `unsigned char*` (28b9ba4334e0f7309e867e874a31f395c0ac2474)
* Add `const` in more places - Add `const` in more places
1.2.1 (Jan 31, 2017) 1.2.1
===== =====
Fixes: Fixes:
------ ------
* Fixes a potential null pointer dereference in cJSON_Utils, discovered using clang's static analyzer by @bnason-nf, see [#96](https://github.com/DaveGamble/cJSON/issues/96) - Fixes a potential null pointer dereference in cJSON_Utils, discovered using clang's static analyzer by @bnason-nf (#96)
1.2.0 (Jan 9, 2017) 1.2.0
===== =====
Features: Features:
--------- ---------
* Add a new type of cJSON item for raw JSON and support printing it. Thanks @loigu, see [#65](https://github.com/DaveGamble/cJSON/pull/65), [#90](https://github.com/DaveGamble/cJSON/pull/90) - Add a new type of cJSON item for raw JSON and support printing it. Thanks @loigu (#65, #90)
Fixes: Fixes:
------ ------
* Compiler warning if const is casted away, Thanks @gatzka, see [#83](https://github.com/DaveGamble/cJSON/pull/83) - Compiler warning if const is casted away, Thanks @gatzka (#83)
* Fix compile error with strict-overflow on PowerPC, see [#85](https://github.com/DaveGamble/cJSON/issues/85) - Fix compile error with strict-overflow on PowerPC, (#85)
* Fix typo in the README, thanks @MicroJoe, see [#88](https://github.com/DaveGamble/cJSON/pull/88) - Fix typo in the README, thanks @MicroJoe (#88)
* Add compile flag for compatibility with C++ compilers - Add compile flag for compatibility with C++ compilers
1.1.0 (Dec 6, 2016) 1.1.0
===== =====
* Add a function `cJSON_PrintPreallocated` to print to a preallocated buffer, thanks @ChisholmKyle, see [#72](https://github.com/DaveGamble/cJSON/pull/72) - Add a function `cJSON_PrintPreallocated` to print to a preallocated buffer, thanks @ChisholmKyle (#72)
* More compiler warnings when using Clang or GCC, thanks @gatzka, see [#75](https://github.com/DaveGamble/cJSON/pull/75), [#78](https://github.com/DaveGamble/cJSON/pull/78) - More compiler warnings when using Clang or GCC, thanks @gatzka (#75, #78)
* fixed a memory leak in `cJSON_Duplicate`, thanks @alperakcan, see [#81](https://github.com/DaveGamble/cJSON/pull/81) - fixed a memory leak in `cJSON_Duplicate`, thanks @alperakcan (#81)
* fix the `ENABLE_CUSTOM_COMPILER_FLAGS` cmake option - fix the `ENABLE_CUSTOM_COMPILER_FLAGS` cmake option
1.0.2 (Nov 25, 2016) 1.0.2
===== =====
* Rename internal boolean type, see [#71](https://github.com/DaveGamble/cJSON/issues/71). Rename internal boolean type, see #71.
1.0.1 (Nov 20, 2016) 1.0.1
===== =====
Small bugfix release. Small bugfix release.
* Fixes a bug with the use of the cJSON structs type in cJSON_Utils, see [d47339e](https://github.com/DaveGamble/cJSON/commit/d47339e2740360e6e0994527d5e4752007480f3a) - Fixes a bug with the use of the cJSON structs type in cJSON_Utils, see d47339e2740360e6e0994527d5e4752007480f3a
* improve code readability - improve code readability
* initialize all variables - initialize all variables
1.0.0 (Nov 17, 2016) 1.0.0
===== =====
This is the first official versioned release of cJSON. It provides an API version for the shared library and improved Makefile and CMake build files. This is the first official versioned release of cJSON. It provides an API version for the shared library and improved Makefile and CMake build files.

View File

@@ -1,13 +1,13 @@
set(CMAKE_LEGACY_CYGWIN_WIN32 0) set(CMAKE_LEGACY_CYGWIN_WIN32 0)
cmake_minimum_required(VERSION 2.8.5) cmake_minimum_required(VERSION 2.8.5)
project(cJSON C)
include(GNUInstallDirs) include(GNUInstallDirs)
project(cJSON C)
set(PROJECT_VERSION_MAJOR 1) set(PROJECT_VERSION_MAJOR 1)
set(PROJECT_VERSION_MINOR 7) set(PROJECT_VERSION_MINOR 5)
set(PROJECT_VERSION_PATCH 15) set(PROJECT_VERSION_PATCH 4)
set(CJSON_VERSION_SO 1) set(CJSON_VERSION_SO 1)
set(CJSON_UTILS_VERSION_SO 1) set(CJSON_UTILS_VERSION_SO 1)
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
@@ -16,50 +16,37 @@ set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT
set(custom_compiler_flags) set(custom_compiler_flags)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags" ON) option(ENABLE_CUSTOM_COMPILER_FLAGS "Enables custom compiler flags for Clang and GCC" ON)
if (ENABLE_CUSTOM_COMPILER_FLAGS) if (ENABLE_CUSTOM_COMPILER_FLAGS)
if (("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")) list(APPEND custom_compiler_flags
list(APPEND custom_compiler_flags -std=c89
-std=c89 -pedantic
-pedantic -Wall
-Wall -Wextra
-Wextra -Werror
-Werror -Wstrict-prototypes
-Wstrict-prototypes -Wwrite-strings
-Wwrite-strings -Wshadow
-Wshadow -Winit-self
-Winit-self -Wcast-align
-Wcast-align -Wformat=2
-Wformat=2 -Wmissing-prototypes
-Wmissing-prototypes -Wstrict-overflow=2
-Wstrict-overflow=2 -Wcast-qual
-Wcast-qual -Wundef
-Wundef -Wswitch-default
-Wswitch-default -Wconversion
-Wconversion -Wc++-compat
-Wc++-compat -fstack-protector-strong
-fstack-protector-strong -Wcomma
-Wcomma -Wdouble-promotion
-Wdouble-promotion -Wparentheses
-Wparentheses -Wformat-overflow
-Wformat-overflow -Wunused-macros
-Wunused-macros -Wmissing-variable-declarations
-Wmissing-variable-declarations -Wused-but-marked-unused
-Wused-but-marked-unused -Wswitch-enum
-Wswitch-enum
) )
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
# Disable warning c4001 - nonstandard extension 'single line comment' was used
# Define _CRT_SECURE_NO_WARNINGS to disable deprecation warnings for "insecure" C library functions
list(APPEND custom_compiler_flags
/GS
/Za
/sdl
/W4
/wd4001
/D_CRT_SECURE_NO_WARNINGS
)
endif()
endif() endif()
option(ENABLE_SANITIZERS "Enables AddressSanitizer and UndefinedBehaviorSanitizer." OFF) option(ENABLE_SANITIZERS "Enables AddressSanitizer and UndefinedBehaviorSanitizer." OFF)
@@ -68,6 +55,7 @@ if (ENABLE_SANITIZERS)
-fno-omit-frame-pointer -fno-omit-frame-pointer
-fsanitize=address -fsanitize=address
-fsanitize=undefined -fsanitize=undefined
-fsanitize=float-divide-by-zero
-fsanitize=float-cast-overflow -fsanitize=float-cast-overflow
-fsanitize-address-use-after-scope -fsanitize-address-use-after-scope
-fsanitize=integer -fsanitize=integer
@@ -76,16 +64,6 @@ if (ENABLE_SANITIZERS)
) )
endif() 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) option(ENABLE_PUBLIC_SYMBOLS "Export library symbols." On)
if (ENABLE_PUBLIC_SYMBOLS) if (ENABLE_PUBLIC_SYMBOLS)
list(APPEND custom_compiler_flags -fvisibility=hidden) list(APPEND custom_compiler_flags -fvisibility=hidden)
@@ -110,6 +88,12 @@ endforeach()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${supported_compiler_flags}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${supported_compiler_flags}")
#variables for pkg-config
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(libdir "${CMAKE_INSTALL_LIBDIR}")
set(version "${PROJECT_VERSION}")
set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
option(BUILD_SHARED_LIBS "Build shared libraries" ON) option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(ENABLE_TARGET_EXPORT "Enable exporting of CMake targets. Disable when it causes problems!" ON) option(ENABLE_TARGET_EXPORT "Enable exporting of CMake targets. Disable when it causes problems!" ON)
@@ -119,26 +103,7 @@ set(CJSON_LIB cjson)
file(GLOB HEADERS cJSON.h) file(GLOB HEADERS cJSON.h)
set(SOURCES cJSON.c) set(SOURCES cJSON.c)
option(BUILD_SHARED_AND_STATIC_LIBS "Build both shared and static libraries" Off) add_library("${CJSON_LIB}" "${HEADERS}" "${SOURCES}")
option(CJSON_OVERRIDE_BUILD_SHARED_LIBS "Override BUILD_SHARED_LIBS with CJSON_BUILD_SHARED_LIBS" OFF)
option(CJSON_BUILD_SHARED_LIBS "Overrides BUILD_SHARED_LIBS if CJSON_OVERRIDE_BUILD_SHARED_LIBS is enabled" ON)
if ((CJSON_OVERRIDE_BUILD_SHARED_LIBS AND CJSON_BUILD_SHARED_LIBS) OR ((NOT CJSON_OVERRIDE_BUILD_SHARED_LIBS) AND BUILD_SHARED_LIBS))
set(CJSON_LIBRARY_TYPE SHARED)
else()
set(CJSON_LIBRARY_TYPE STATIC)
endif()
if (NOT BUILD_SHARED_AND_STATIC_LIBS)
add_library("${CJSON_LIB}" "${CJSON_LIBRARY_TYPE}" "${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) if (NOT WIN32)
target_link_libraries("${CJSON_LIB}" m) target_link_libraries("${CJSON_LIB}" m)
endif() endif()
@@ -146,21 +111,12 @@ endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson.pc.in" configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" @ONLY) "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" @ONLY)
install(FILES cJSON.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/cjson") install(FILES cJSON.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig") install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(TARGETS "${CJSON_LIB}" install(TARGETS "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${CJSON_LIB}")
EXPORT "${CJSON_LIB}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}"
)
if (BUILD_SHARED_AND_STATIC_LIBS)
install(TARGETS "${CJSON_LIB}-static" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
endif()
if(ENABLE_TARGET_EXPORT) if(ENABLE_TARGET_EXPORT)
# export library information for CMake projects # export library information for CMake projects
install(EXPORT "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cJSON") install(EXPORT "${CJSON_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cJSON")
endif() endif()
set_target_properties("${CJSON_LIB}" set_target_properties("${CJSON_LIB}"
@@ -176,36 +132,18 @@ if(ENABLE_CJSON_UTILS)
file(GLOB HEADERS_UTILS cJSON_Utils.h) file(GLOB HEADERS_UTILS cJSON_Utils.h)
set(SOURCES_UTILS cJSON_Utils.c) set(SOURCES_UTILS cJSON_Utils.c)
if (NOT BUILD_SHARED_AND_STATIC_LIBS) add_library("${CJSON_UTILS_LIB}" "${HEADERS_UTILS}" "${SOURCES_UTILS}")
add_library("${CJSON_UTILS_LIB}" "${CJSON_LIBRARY_TYPE}" "${HEADERS_UTILS}" "${SOURCES_UTILS}") target_link_libraries("${CJSON_UTILS_LIB}" "${CJSON_LIB}")
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" configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library_config/libcjson_utils.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" @ONLY) "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" @ONLY)
install(TARGETS "${CJSON_UTILS_LIB}" install(TARGETS "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${CJSON_UTILS_LIB}")
EXPORT "${CJSON_UTILS_LIB}" install(FILES cJSON_Utils.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/cjson")
ARCHIVE DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}"
)
if (BUILD_SHARED_AND_STATIC_LIBS)
install(TARGETS "${CJSON_UTILS_LIB}-static" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
endif()
install(FILES cJSON_Utils.h DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/cjson")
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcjson_utils.pc" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig")
if(ENABLE_TARGET_EXPORT) if(ENABLE_TARGET_EXPORT)
# export library information for CMake projects # export library information for CMake projects
install(EXPORT "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cJSON") install(EXPORT "${CJSON_UTILS_LIB}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cJSON")
endif() endif()
set_target_properties("${CJSON_UTILS_LIB}" set_target_properties("${CJSON_UTILS_LIB}"
@@ -222,12 +160,10 @@ configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/library_config/cJSONConfigVersion.cmake.in" "${CMAKE_CURRENT_SOURCE_DIR}/library_config/cJSONConfigVersion.cmake.in"
${PROJECT_BINARY_DIR}/cJSONConfigVersion.cmake @ONLY) ${PROJECT_BINARY_DIR}/cJSONConfigVersion.cmake @ONLY)
if(ENABLE_TARGET_EXPORT) # Install package config files
# Install package config files install(FILES ${PROJECT_BINARY_DIR}/cJSONConfig.cmake
install(FILES ${PROJECT_BINARY_DIR}/cJSONConfig.cmake ${PROJECT_BINARY_DIR}/cJSONConfigVersion.cmake
${PROJECT_BINARY_DIR}/cJSONConfigVersion.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cJSON")
DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cJSON")
endif()
option(ENABLE_CJSON_TEST "Enable building cJSON test" ON) option(ENABLE_CJSON_TEST "Enable building cJSON test" ON)
if(ENABLE_CJSON_TEST) if(ENABLE_CJSON_TEST)
@@ -254,14 +190,5 @@ if(ENABLE_CJSON_TEST)
DEPENDS ${TEST_CJSON}) DEPENDS ${TEST_CJSON})
endif() endif()
#Create the uninstall target
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${PROJECT_SOURCE_DIR}/library_config/uninstall.cmake")
# 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(tests)
add_subdirectory(fuzzing) add_subdirectory(fuzzing)

View File

@@ -1,79 +1,38 @@
Contributors Contributors
============ ============
Original Author:
- [Dave Gamble](https://github.com/DaveGamble)
Current Maintainer:
- [Max Bruckner](https://github.com/FSMaxB)
- [Alan Wang](https://github.com/Alanscut)
Contributors:
* [Ajay Bhargav](https://github.com/ajaybhargav) * [Ajay Bhargav](https://github.com/ajaybhargav)
* [Alper Akcan](https://github.com/alperakcan) * [Alper Akcan](https://github.com/alperakcan)
* [Andrew Tang](https://github.com/singku)
* [Anton Sergeev](https://github.com/anton-sergeev) * [Anton Sergeev](https://github.com/anton-sergeev)
* [Benbuck Nason](https://github.com/bnason-nf)
* [Bernt Johan Damslora](https://github.com/bjda)
* [Bob Kocisko](https://github.com/bobkocisko)
* [Christian Schulze](https://github.com/ChristianSch) * [Christian Schulze](https://github.com/ChristianSch)
* [Casperinous](https://github.com/Casperinous) * [Dave Gamble](https://github.com/DaveGamble)
* [ChenYuan](https://github.com/zjuchenyuan)
* [Debora Grosse](https://github.com/DeboraG) * [Debora Grosse](https://github.com/DeboraG)
* [dieyushi](https://github.com/dieyushi) * [dieyushi](https://github.com/dieyushi)
* [Dōngwén Huáng (黄东文)](https://github.com/DongwenHuang) * [Dōngwén Huáng (黄东文)](https://github.com/DongwenHuang)
* [Donough Liu](https://github.com/ldm0)
* [Erez Oxman](https://github.com/erez-o)
* Eswar Yaganti * Eswar Yaganti
* [Evan Todd](https://github.com/etodd) * [Evan Todd](https://github.com/etodd)
* [Fabrice Fontaine](https://github.com/ffontaine) * [Fabrice Fontaine](https://github.com/ffontaine)
* Ian Mobley * Ian Mobley
* Irwan Djadjadi * Irwan Djadjadi
* [HuKeping](https://github.com/HuKeping)
* [IvanVoid](https://github.com/npi3pak) * [IvanVoid](https://github.com/npi3pak)
* [Jakub Wilk](https://github.com/jwilk)
* [Jiri Zouhar](https://github.com/loigu) * [Jiri Zouhar](https://github.com/loigu)
* [Jonathan Fether](https://github.com/jfether) * [Jonathan Fether](https://github.com/jfether)
* [Julian Ste](https://github.com/julian-st)
* [Julián Vásquez](https://github.com/juvasquezg) * [Julián Vásquez](https://github.com/juvasquezg)
* [Kevin Branigan](https://github.com/kbranigan) * [Kevin Branigan](https://github.com/kbranigan)
* [Kevin Sapper](https://github.com/sappo)
* [Kyle Chisholm](https://github.com/ChisholmKyle) * [Kyle Chisholm](https://github.com/ChisholmKyle)
* [Linus Wallgren](https://github.com/ecksun) * [Linus Wallgren](https://github.com/ecksun)
* [Mateusz Szafoni](https://github.com/raiden00pl) * [Max Bruckner](https://github.com/FSMaxB)
* Mike Pontillo * Mike Pontillo
* [miaoerduo](https://github.com/miaoerduo)
* [Mike Jerris](https://github.com/mjerris) * [Mike Jerris](https://github.com/mjerris)
* [Mike Robinson](https://github.com/mhrobinson) * [Mike Robinson](https://github.com/mhrobinson)
* [Moorthy](https://github.com/moorthy-bs)
* [myd7349](https://github.com/myd7349)
* [NancyLi1013](https://github.com/NancyLi1013)
* Paulo Antonio Alvarez * Paulo Antonio Alvarez
* [Paweł Malowany](https://github.com/PawelMalowany)
* [Pawel Winogrodzki](https://github.com/PawelWMS) * [Pawel Winogrodzki](https://github.com/PawelWMS)
* [prefetchnta](https://github.com/prefetchnta) * [prefetchnta](https://github.com/prefetchnta)
* [Rafael Leal Dias](https://github.com/rafaeldias) * [Rafael Leal Dias](https://github.com/rafaeldias)
* [Randy](https://github.com/randy408)
* [raiden00pl](https://github.com/raiden00pl)
* [Robin Mallinson](https://github.com/rmallins)
* [Rod Vagg](https://github.com/rvagg) * [Rod Vagg](https://github.com/rvagg)
* [Roland Meertens](https://github.com/rmeertens) * [Roland Meertens](https://github.com/rmeertens)
* [Romain Porte](https://github.com/MicroJoe) * [Romain Porte](https://github.com/MicroJoe)
* [SANJEEV BA](https://github.com/basanjeev)
* [Sang-Heon Jeon](https://github.com/lntuition)
* [Simon Sobisch](https://github.com/GitMensch)
* [Simon Ricaldone](https://github.com/simon-p-r)
* [Square789](https://github.com/Square789)
* [Stephan Gatzka](https://github.com/gatzka) * [Stephan Gatzka](https://github.com/gatzka)
* [Vemake](https://github.com/vemakereporter)
* [Wei Tan](https://github.com/tan-wei)
* [Weston Schmidt](https://github.com/schmidtw) * [Weston Schmidt](https://github.com/schmidtw)
* [xiaomianhehe](https://github.com/xiaomianhehe)
* [yangfl](https://github.com/yangfl)
* [yuta-oxo](https://github.com/yuta-oxo)
* [Zach Hindes](https://github.com/zhindes)
* [Zhao Zhixu](https://github.com/zhaozhixu)
And probably more people on [SourceForge](https://sourceforge.net/p/cjson/bugs/search/?q=status%3Aclosed-rejected+or+status%3Aclosed-out-of-date+or+status%3Awont-fix+or+status%3Aclosed-fixed+or+status%3Aclosed&page=0) And probably more people on [SourceForge](https://sourceforge.net/p/cjson/bugs/search/?q=status%3Aclosed-rejected+or+status%3Aclosed-out-of-date+or+status%3Awont-fix+or+status%3Aclosed-fixed+or+status%3Aclosed&page=0)
Also thanks to all the people who reported bugs and suggested new features.

38
LICENSE
View File

@@ -1,20 +1,20 @@
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.

View File

@@ -8,13 +8,10 @@ CJSON_TEST_SRC = cJSON.c test.c
LDLIBS = -lm LDLIBS = -lm
LIBVERSION = 1.7.15 LIBVERSION = 1.5.4
CJSON_SOVERSION = 1 CJSON_SOVERSION = 1
UTILS_SOVERSION = 1 UTILS_SOVERSION = 1
CJSON_SO_LDFLAG=-Wl,-soname=$(CJSON_LIBNAME).so.$(CJSON_SOVERSION)
UTILS_SO_LDFLAG=-Wl,-soname=$(UTILS_LIBNAME).so.$(UTILS_SOVERSION)
PREFIX ?= /usr/local PREFIX ?= /usr/local
INCLUDE_PATH ?= include/cjson INCLUDE_PATH ?= include/cjson
LIBRARY_PATH ?= lib LIBRARY_PATH ?= lib
@@ -24,11 +21,9 @@ INSTALL_LIBRARY_PATH = $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH)
INSTALL ?= cp -a INSTALL ?= cp -a
CC = gcc -std=c89
# validate gcc version for use fstack-protector-strong # validate gcc version for use fstack-protector-strong
MIN_GCC_VERSION = "4.9" MIN_GCC_VERSION = "4.9"
GCC_VERSION := "`$(CC) -dumpversion`" GCC_VERSION := "`gcc -dumpversion`"
IS_GCC_ABOVE_MIN_VERSION := $(shell expr "$(GCC_VERSION)" ">=" "$(MIN_GCC_VERSION)") IS_GCC_ABOVE_MIN_VERSION := $(shell expr "$(GCC_VERSION)" ">=" "$(MIN_GCC_VERSION)")
ifeq "$(IS_GCC_ABOVE_MIN_VERSION)" "1" ifeq "$(IS_GCC_ABOVE_MIN_VERSION)" "1"
CFLAGS += -fstack-protector-strong CFLAGS += -fstack-protector-strong
@@ -36,8 +31,7 @@ else
CFLAGS += -fstack-protector CFLAGS += -fstack-protector
endif endif
PIC_FLAGS = -fPIC R_CFLAGS = -fPIC -std=c89 -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion $(CFLAGS)
R_CFLAGS = $(PIC_FLAGS) -pedantic -Wall -Werror -Wstrict-prototypes -Wwrite-strings -Wshadow -Winit-self -Wcast-align -Wformat=2 -Wmissing-prototypes -Wstrict-overflow=2 -Wcast-qual -Wc++-compat -Wundef -Wswitch-default -Wconversion $(CFLAGS)
uname := $(shell sh -c 'uname -s 2>/dev/null || echo false') uname := $(shell sh -c 'uname -s 2>/dev/null || echo false')
@@ -48,8 +42,6 @@ STATIC = a
## create dynamic (shared) library on Darwin (base OS for MacOSX and IOS) ## create dynamic (shared) library on Darwin (base OS for MacOSX and IOS)
ifeq (Darwin, $(uname)) ifeq (Darwin, $(uname))
SHARED = dylib SHARED = dylib
CJSON_SO_LDFLAG = ""
UTILS_SO_LDFLAG = ""
endif endif
#cJSON library names #cJSON library names
@@ -74,10 +66,11 @@ shared: $(CJSON_SHARED) $(UTILS_SHARED)
static: $(CJSON_STATIC) $(UTILS_STATIC) static: $(CJSON_STATIC) $(UTILS_STATIC)
tests: $(CJSON_TEST) tests: $(CJSON_TEST) $(UTILS_TEST)
test: tests test: tests
./$(CJSON_TEST) ./$(CJSON_TEST)
./$(UTILS_TEST)
.c.o: .c.o:
$(CC) -c $(R_CFLAGS) $< $(CC) -c $(R_CFLAGS) $<
@@ -98,16 +91,16 @@ $(UTILS_STATIC): $(UTILS_OBJ)
#shared libraries .so.1.0.0 #shared libraries .so.1.0.0
#cJSON #cJSON
$(CJSON_SHARED_VERSION): $(CJSON_OBJ) $(CJSON_SHARED_VERSION): $(CJSON_OBJ)
$(CC) -shared -o $@ $< $(CJSON_SO_LDFLAG) $(LDFLAGS) $(CC) -shared -o $@ $< $(LDFLAGS)
#cJSON_Utils #cJSON_Utils
$(UTILS_SHARED_VERSION): $(UTILS_OBJ) $(UTILS_SHARED_VERSION): $(UTILS_OBJ)
$(CC) -shared -o $@ $< $(CJSON_OBJ) $(UTILS_SO_LDFLAG) $(LDFLAGS) $(CC) -shared -o $@ $< $(LDFLAGS)
#objects #objects
#cJSON #cJSON
$(CJSON_OBJ): cJSON.c cJSON.h $(CJSON_OBJ): cJSON.c cJSON.h
#cJSON_Utils #cJSON_Utils
$(UTILS_OBJ): cJSON_Utils.c cJSON_Utils.h cJSON.h $(UTILS_OBJ): cJSON_Utils.c cJSON_Utils.h
#links .so -> .so.1 -> .so.1.0.0 #links .so -> .so.1 -> .so.1.0.0
@@ -141,8 +134,9 @@ uninstall-cjson: uninstall-utils
$(RM) $(INSTALL_LIBRARY_PATH)/$(CJSON_SHARED) $(RM) $(INSTALL_LIBRARY_PATH)/$(CJSON_SHARED)
$(RM) $(INSTALL_LIBRARY_PATH)/$(CJSON_SHARED_VERSION) $(RM) $(INSTALL_LIBRARY_PATH)/$(CJSON_SHARED_VERSION)
$(RM) $(INSTALL_LIBRARY_PATH)/$(CJSON_SHARED_SO) $(RM) $(INSTALL_LIBRARY_PATH)/$(CJSON_SHARED_SO)
rmdir $(INSTALL_LIBRARY_PATH)
$(RM) $(INSTALL_INCLUDE_PATH)/cJSON.h $(RM) $(INSTALL_INCLUDE_PATH)/cJSON.h
rmdir $(INSTALL_INCLUDE_PATH)
#cJSON_Utils #cJSON_Utils
uninstall-utils: uninstall-utils:
$(RM) $(INSTALL_LIBRARY_PATH)/$(UTILS_SHARED) $(RM) $(INSTALL_LIBRARY_PATH)/$(UTILS_SHARED)
@@ -150,14 +144,10 @@ uninstall-utils:
$(RM) $(INSTALL_LIBRARY_PATH)/$(UTILS_SHARED_SO) $(RM) $(INSTALL_LIBRARY_PATH)/$(UTILS_SHARED_SO)
$(RM) $(INSTALL_INCLUDE_PATH)/cJSON_Utils.h $(RM) $(INSTALL_INCLUDE_PATH)/cJSON_Utils.h
remove-dir: uninstall: uninstall-utils uninstall-cjson
$(if $(wildcard $(INSTALL_LIBRARY_PATH)/*.*),,rmdir $(INSTALL_LIBRARY_PATH))
$(if $(wildcard $(INSTALL_INCLUDE_PATH)/*.*),,rmdir $(INSTALL_INCLUDE_PATH))
uninstall: uninstall-utils uninstall-cjson remove-dir
clean: clean:
$(RM) $(CJSON_OBJ) $(UTILS_OBJ) #delete object files $(RM) $(CJSON_OBJ) $(UTILS_OBJ) #delete object files
$(RM) $(CJSON_SHARED) $(CJSON_SHARED_VERSION) $(CJSON_SHARED_SO) $(CJSON_STATIC) #delete cJSON $(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) $(UTILS_SHARED) $(UTILS_SHARED_VERSION) $(UTILS_SHARED_SO) $(UTILS_STATIC) #delete cJSON_Utils
$(RM) $(CJSON_TEST) #delete test $(RM) $(CJSON_TEST) $(UTILS_TEST) #delete tests

591
README.md
View File

@@ -7,30 +7,9 @@ Ultralightweight JSON parser in ANSI C.
* [Usage](#usage) * [Usage](#usage)
* [Welcome to cJSON](#welcome-to-cjson) * [Welcome to cJSON](#welcome-to-cjson)
* [Building](#building) * [Building](#building)
* [Copying the source](#copying-the-source) * [Some JSON](#some-json)
* [CMake](#cmake) * [Here's the structure](#heres-the-structure)
* [Makefile](#makefile)
* [Vcpkg](#Vcpkg)
* [Including cJSON](#including-cjson)
* [Data Structure](#data-structure)
* [Working with the data structure](#working-with-the-data-structure)
* [Basic types](#basic-types)
* [Arrays](#arrays)
* [Objects](#objects)
* [Parsing JSON](#parsing-json)
* [Printing JSON](#printing-json)
* [Example](#example)
* [Printing](#printing)
* [Parsing](#parsing)
* [Caveats](#caveats) * [Caveats](#caveats)
* [Zero Character](#zero-character)
* [Character Encoding](#character-encoding)
* [C Standard](#c-standard)
* [Floating Point Numbers](#floating-point-numbers)
* [Deep Nesting Of Arrays And Objects](#deep-nesting-of-arrays-and-objects)
* [Thread Safety](#thread-safety)
* [Case Sensitivity](#case-sensitivity)
* [Duplicate Object Members](#duplicate-object-members)
* [Enjoy cJSON!](#enjoy-cjson) * [Enjoy cJSON!](#enjoy-cjson)
## License ## License
@@ -81,13 +60,11 @@ philosophy as JSON itself. Simple, dumb, out of the way.
There are several ways to incorporate cJSON into your project. There are several ways to incorporate cJSON into your project.
#### copying the source #### copying the source
Because the entire library is only one C file and one header file, you can just copy `cJSON.h` and `cJSON.c` to your projects source and start using it. Because the entire library is only one C file and one header file, you can just copy `cJSON.h` and `cJSON.c` to your projects source and start using it.
cJSON is written in ANSI C (C89) in order to support as many platforms and compilers as possible. cJSON is written in ANSI C (C89) in order to support as many platforms and compilers as possible.
#### CMake #### CMake
With CMake, cJSON supports a full blown build system. This way you get the most features. CMake with an equal or higher version than 2.8.5 is supported. With CMake it is recommended to do an out of tree build, meaning the compiled files are put in a directory separate from the source files. So in order to build cJSON with CMake on a Unix platform, make a `build` directory and run CMake inside it. With CMake, cJSON supports a full blown build system. This way you get the most features. CMake with an equal or higher version than 2.8.5 is supported. With CMake it is recommended to do an out of tree build, meaning the compiled files are put in a directory separate from the source files. So in order to build cJSON with CMake on a Unix platform, make a `build` directory and run CMake inside it.
``` ```
@@ -105,19 +82,14 @@ make
And install it with `make install` if you want. By default it installs the headers `/usr/local/include/cjson` and the libraries to `/usr/local/lib`. It also installs files for pkg-config to make it easier to detect and use an existing installation of CMake. And it installs CMake config files, that can be used by other CMake based projects to discover the library. And install it with `make install` if you want. By default it installs the headers `/usr/local/include/cjson` and the libraries to `/usr/local/lib`. It also installs files for pkg-config to make it easier to detect and use an existing installation of CMake. And it installs CMake config files, that can be used by other CMake based projects to discover the library.
You can change the build process with a list of different options that you can pass to CMake. Turn them on with `On` and off with `Off`: You can change the build process with a list of different options that you can pass to CMake. Turn them on with `On` and off with `Off`:
* `-DENABLE_CJSON_TEST=On`: Enable building the tests. (on by default) * `-DENABLE_CJSON_TEST=On`: Enable building the tests. (on by default)
* `-DENABLE_CJSON_UTILS=On`: Enable building cJSON_Utils. (off 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_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, GCC and MSVC). 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_VALGRIND=On`: Run tests with [valgrind](http://valgrind.org). (off 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_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_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. * `-DCMAKE_INSTALL_PREFIX=/usr`: Set a prefix for the installation.
* `-DENABLE_LOCALES=On`: Enable the usage of localeconv method. ( on by default )
* `-DCJSON_OVERRIDE_BUILD_SHARED_LIBS=On`: Enable overriding the value of `BUILD_SHARED_LIBS` with `-DCJSON_BUILD_SHARED_LIBS`.
If you are packaging cJSON for a distribution of Linux, you would probably take these steps for example: If you are packaging cJSON for a distribution of Linux, you would probably take these steps for example:
``` ```
@@ -128,397 +100,280 @@ make
make DESTDIR=$pkgdir install make DESTDIR=$pkgdir install
``` ```
On Windows CMake is usually used to create a Visual Studio solution file by running it inside the Developer Command Prompt for Visual Studio, for exact steps follow the official documentation from CMake and Microsoft and use the online search engine of your choice. The descriptions of the the options above still generally apply, although not all of them work on Windows.
#### Makefile #### Makefile
**NOTE:** This Method is deprecated. Use CMake if at all possible. Makefile support is limited to fixing bugs.
If you don't have CMake available, but still have GNU make. You can use the makefile to build cJSON: If you don't have CMake available, but still have GNU make. You can use the makefile to build cJSON:
Run this command in the directory with the source code and it will automatically compile static and shared libraries and a little test program (not the full test suite). Run this command in the directory with the source code and it will automatically compile static and shared libraries and a little test program.
``` ```
make all make all
``` ```
If you want, you can install the compiled library to your system using `make install`. By default it will install the headers in `/usr/local/include/cjson` and the libraries in `/usr/local/lib`. But you can change this behavior by setting the `PREFIX` and `DESTDIR` variables: `make PREFIX=/usr DESTDIR=temp install`. And uninstall them with: `make PREFIX=/usr DESTDIR=temp uninstall`. If you want, you can install the compiled library to your system using `make install`. By default it will install the headers in `/usr/local/include/cjson` and the libraries in `/usr/local/lib`. But you can change this behavior by setting the `PREFIX` and `DESTDIR` variables: `make PREFIX=/usr DESTDIR=temp install`.
#### Vcpkg ### Some JSON:
You can download and install cJSON using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager: ```json
```
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install cjson
```
The cJSON port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
### Including cJSON
If you installed it via CMake or the Makefile, you can include cJSON like this:
```c
#include <cjson/cJSON.h>
```
### Data Structure
cJSON represents JSON data using the `cJSON` struct data type:
```c
/* The cJSON structure: */
typedef struct cJSON
{ {
struct cJSON *next; "name": "Jack (\"Bee\") Nimble",
struct cJSON *prev; "format": {
"type": "rect",
"width": 1920,
"height": 1080,
"interlace": false,
"frame rate": 24
}
}
```
Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
you have a `char *` to it. Everything is a `cJSON` struct.
Get it parsed:
```c
cJSON * root = cJSON_Parse(my_json_string);
```
This is an object. We're in C. We don't have objects. But we do have structs.
What's the framerate?
```c
cJSON *format = cJSON_GetObjectItemCaseSensitive(root, "format");
cJSON *framerate_item = cJSON_GetObjectItemCaseSensitive(format, "frame rate");
double framerate = 0;
if (cJSON_IsNumber(framerate_item))
{
framerate = framerate_item->valuedouble;
}
```
Want to change the framerate?
```c
cJSON *framerate_item = cJSON_GetObjectItemCaseSensitive(format, "frame rate");
cJSON_SetNumberValue(framerate_item, 25);
```
Back to disk?
```c
char *rendered = cJSON_Print(root);
```
Finished? Delete the root (this takes care of everything else).
```c
cJSON_Delete(root);
```
That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
before you dereference them. If you want to see how you'd build this struct in code?
```c
cJSON *root;
cJSON *fmt;
root = cJSON_CreateObject();
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());
cJSON_AddStringToObject(fmt, "type", "rect");
cJSON_AddNumberToObject(fmt, "width", 1920);
cJSON_AddNumberToObject(fmt, "height", 1080);
cJSON_AddFalseToObject (fmt, "interlace");
cJSON_AddNumberToObject(fmt, "frame rate", 24);
```
Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
Look at `test.c` for a bunch of nice examples, mostly all ripped off the [json.org](http://json.org) site, and
a few from elsewhere.
What about manual mode? First up you need some detail.
Let's cover how the `cJSON` objects represent the JSON data.
cJSON doesn't distinguish arrays from objects in handling; just type.
Each `cJSON` has, potentially, a child, siblings, value, a name.
* The `root` object has: *Object* Type and a Child
* The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
* Sibling has type *Object*, name "format", and a child.
* That child has type *String*, name "type", value "rect", and a sibling:
* Sibling has type *Number*, name "width", value 1920, and a sibling:
* Sibling has type *Number*, name "height", value 1080, and a sibling:
* Sibling has type *False*, name "interlace", and a sibling:
* Sibling has type *Number*, name "frame rate", value 24
### Here's the structure:
```c
typedef struct cJSON {
struct cJSON *next,*prev;
struct cJSON *child; struct cJSON *child;
int type; int type;
char *valuestring; char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ int valueint; /* writing to valueint is DEPRECATED, please use cJSON_SetNumberValue instead */
int valueint;
double valuedouble; double valuedouble;
char *string; char *string;
} cJSON; } cJSON;
``` ```
An item of this type represents a JSON value. The type is stored in `type` as a bit-flag (**this means that you cannot find out the type by just comparing the value of `type`**). By default all values are 0 unless set by virtue of being meaningful.
To check the type of an item, use the corresponding `cJSON_Is...` function. It does a `NULL` check followed by a type check and returns a boolean value if the item is of this type. `next`/`prev` is a doubly linked list of siblings. `next` takes you to your sibling,
`prev` takes you back from your sibling to you.
Only objects and arrays have a `child`, and it's the head of the doubly linked list.
A `child` entry will have `prev == 0`, but next potentially points on. The last sibling has `next == 0`.
The type expresses *Null*/*True*/*False*/*Number*/*String*/*Array*/*Object*, all of which are `#defined` in
`cJSON.h`.
The type can be one of the following: A *Number* has `valueint` and `valuedouble`. `valueint` is a relict of the past, so always use `valuedouble`.
* `cJSON_Invalid` (check with `cJSON_IsInvalid`): Represents an invalid item that doesn't contain any value. You automatically have this type if you set the item to all zero bytes. Any entry which is in the linked list which is the child of an object will have a `string`
* `cJSON_False` (check with `cJSON_IsFalse`): Represents a `false` boolean value. You can also check for boolean values in general with `cJSON_IsBool`. which is the "name" of the entry. When I said "name" in the above example, that's `string`.
* `cJSON_True` (check with `cJSON_IsTrue`): Represents a `true` boolean value. You can also check for boolean values in general with `cJSON_IsBool`. `string` is the JSON name for the 'variable name' if you will.
* `cJSON_NULL` (check with `cJSON_IsNull`): Represents a `null` value.
* `cJSON_Number` (check with `cJSON_IsNumber`): Represents a number value. The value is stored as a double in `valuedouble` and also in `valueint`. If the number is outside of the range of an integer, `INT_MAX` or `INT_MIN` are used for `valueint`.
* `cJSON_String` (check with `cJSON_IsString`): Represents a string value. It is stored in the form of a zero terminated string in `valuestring`.
* `cJSON_Array` (check with `cJSON_IsArray`): Represent an array value. This is implemented by pointing `child` to a linked list of `cJSON` items that represent the values in the array. The elements are linked together using `next` and `prev`, where the first element has `prev.next == NULL` and the last element `next == NULL`.
* `cJSON_Object` (check with `cJSON_IsObject`): Represents an object value. Objects are stored same way as an array, the only difference is that the items in the object store their keys in `string`.
* `cJSON_Raw` (check with `cJSON_IsRaw`): Represents any kind of JSON that is stored as a zero terminated array of characters in `valuestring`. This can be used, for example, to avoid printing the same static JSON over and over again to save performance. cJSON will never create this type when parsing. Also note that cJSON doesn't check if it is valid JSON.
Additionally there are the following two flags: Now you can trivially walk the lists, recursively, and parse as you please.
You can invoke `cJSON_Parse` to get cJSON to parse for you, and then you can take
* `cJSON_IsReference`: Specifies that the item that `child` points to and/or `valuestring` is not owned by this item, it is only a reference. So `cJSON_Delete` and other functions will only deallocate this item, not its `child`/`valuestring`. the root object, and traverse the structure (which is, formally, an N-tree),
* `cJSON_StringIsConst`: This means that `string` points to a constant string. This means that `cJSON_Delete` and other functions will not try to deallocate `string`. and tokenise as you please. If you wanted to build a callback style parser, this is how
you'd do it (just an example, since these things are very specific):
### Working with the data structure
For every value type there is a `cJSON_Create...` function that can be used to create an item of that type.
All of these will allocate a `cJSON` struct that can later be deleted with `cJSON_Delete`.
Note that you have to delete them at some point, otherwise you will get a memory leak.
**Important**: If you have added an item to an array or an object already, you **mustn't** delete it with `cJSON_Delete`. Adding it to an array or object transfers its ownership so that when that array or object is deleted,
it gets deleted as well. You also could use `cJSON_SetValuestring` to change a `cJSON_String`'s `valuestring`, and you needn't to free the previous `valuestring` manually.
#### Basic types
* **null** is created with `cJSON_CreateNull`
* **booleans** are created with `cJSON_CreateTrue`, `cJSON_CreateFalse` or `cJSON_CreateBool`
* **numbers** are created with `cJSON_CreateNumber`. This will set both `valuedouble` and `valueint`. If the number is outside of the range of an integer, `INT_MAX` or `INT_MIN` are used for `valueint`
* **strings** are created with `cJSON_CreateString` (copies the string) or with `cJSON_CreateStringReference` (directly points to the string. This means that `valuestring` won't be deleted by `cJSON_Delete` and you are responsible for its lifetime, useful for constants)
#### Arrays
You can create an empty array with `cJSON_CreateArray`. `cJSON_CreateArrayReference` can be used to create an array that doesn't "own" its content, so its content doesn't get deleted by `cJSON_Delete`.
To add items to an array, use `cJSON_AddItemToArray` to append items to the end.
Using `cJSON_AddItemReferenceToArray` an element can be added as a reference to another item, array or string. This means that `cJSON_Delete` will not delete that items `child` or `valuestring` properties, so no double frees are occurring if they are already used elsewhere.
To insert items in the middle, use `cJSON_InsertItemInArray`. It will insert an item at the given 0 based index and shift all the existing items to the right.
If you want to take an item out of an array at a given index and continue using it, use `cJSON_DetachItemFromArray`, it will return the detached item, so be sure to assign it to a pointer, otherwise you will have a memory leak.
Deleting items is done with `cJSON_DeleteItemFromArray`. It works like `cJSON_DetachItemFromArray`, but deletes the detached item via `cJSON_Delete`.
You can also replace an item in an array in place. Either with `cJSON_ReplaceItemInArray` using an index or with `cJSON_ReplaceItemViaPointer` given a pointer to an element. `cJSON_ReplaceItemViaPointer` will return `0` if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place.
To get the size of an array, use `cJSON_GetArraySize`. Use `cJSON_GetArrayItem` to get an element at a given index.
Because an array is stored as a linked list, iterating it via index is inefficient (`O(n²)`), so you can iterate over an array using the `cJSON_ArrayForEach` macro in `O(n)` time complexity.
#### Objects
You can create an empty object with `cJSON_CreateObject`. `cJSON_CreateObjectReference` can be used to create an object that doesn't "own" its content, so its content doesn't get deleted by `cJSON_Delete`.
To add items to an object, use `cJSON_AddItemToObject`. Use `cJSON_AddItemToObjectCS` to add an item to an object with a name that is a constant or reference (key of the item, `string` in the `cJSON` struct), so that it doesn't get freed by `cJSON_Delete`.
Using `cJSON_AddItemReferenceToArray` an element can be added as a reference to another object, array or string. This means that `cJSON_Delete` will not delete that items `child` or `valuestring` properties, so no double frees are occurring if they are already used elsewhere.
If you want to take an item out of an object, use `cJSON_DetachItemFromObjectCaseSensitive`, it will return the detached item, so be sure to assign it to a pointer, otherwise you will have a memory leak.
Deleting items is done with `cJSON_DeleteItemFromObjectCaseSensitive`. It works like `cJSON_DetachItemFromObjectCaseSensitive` followed by `cJSON_Delete`.
You can also replace an item in an object in place. Either with `cJSON_ReplaceItemInObjectCaseSensitive` using a key or with `cJSON_ReplaceItemViaPointer` given a pointer to an element. `cJSON_ReplaceItemViaPointer` will return `0` if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place.
To get the size of an object, you can use `cJSON_GetArraySize`, this works because internally objects are stored as arrays.
If you want to access an item in an object, use `cJSON_GetObjectItemCaseSensitive`.
To iterate over an object, you can use the `cJSON_ArrayForEach` macro the same way as for arrays.
cJSON also provides convenient helper functions for quickly creating a new item and adding it to an object, like `cJSON_AddNullToObject`. They return a pointer to the new item or `NULL` if they failed.
### Parsing JSON
Given some JSON in a zero terminated string, you can parse it with `cJSON_Parse`.
```c ```c
cJSON *json = cJSON_Parse(string); void parse_and_callback(cJSON *item, const char *prefix)
```
Given some JSON in a string (whether zero terminated or not), you can parse it with `cJSON_ParseWithLength`.
```c
cJSON *json = cJSON_ParseWithLength(string, buffer_length);
```
It will parse the JSON and allocate a tree of `cJSON` items that represents it. Once it returns, you are fully responsible for deallocating it after use with `cJSON_Delete`.
The allocator used by `cJSON_Parse` is `malloc` and `free` by default but can be changed (globally) with `cJSON_InitHooks`.
If an error occurs a pointer to the position of the error in the input string can be accessed using `cJSON_GetErrorPtr`. Note though that this can produce race conditions in multithreading scenarios, in that case it is better to use `cJSON_ParseWithOpts` with `return_parse_end`.
By default, characters in the input string that follow the parsed JSON will not be considered as an error.
If you want more options, use `cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)`.
`return_parse_end` returns a pointer to the end of the JSON in the input string or the position that an error occurs at (thereby replacing `cJSON_GetErrorPtr` in a thread safe way). `require_null_terminated`, if set to `1` will make it an error if the input string contains data after the JSON.
If you want more options giving buffer length, use `cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)`.
### Printing JSON
Given a tree of `cJSON` items, you can print them as a string using `cJSON_Print`.
```c
char *string = cJSON_Print(json);
```
It will allocate a string and print a JSON representation of the tree into it. Once it returns, you are fully responsible for deallocating it after use with your allocator. (usually `free`, depends on what has been set with `cJSON_InitHooks`).
`cJSON_Print` will print with whitespace for formatting. If you want to print without formatting, use `cJSON_PrintUnformatted`.
If you have a rough idea of how big your resulting string will be, you can use `cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)`. `fmt` is a boolean to turn formatting with whitespace on and off. `prebuffer` specifies the first buffer size to use for printing. `cJSON_Print` currently uses 256 bytes for its first buffer size. Once printing runs out of space, a new buffer is allocated and the old gets copied over before printing is continued.
These dynamic buffer allocations can be completely avoided by using `cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)`. It takes a buffer to a pointer to print to and its length. If the length is reached, printing will fail and it returns `0`. In case of success, `1` is returned. Note that you should provide 5 bytes more than is actually needed, because cJSON is not 100% accurate in estimating if the provided memory is enough.
### Example
In this example we want to build and parse the following JSON:
```json
{ {
"name": "Awesome 4K", while (item)
"resolutions": [ {
char *newprefix = malloc(strlen(prefix) + strlen(item->string) + 2);
sprintf(newprefix, "%s/%s", prefix, item->string);
int dorecurse = callback(newprefix, item->type, item);
if (item->child && dorecurse)
{ {
"width": 1280, parse_and_callback(item->child, newprefix);
"height": 720
},
{
"width": 1920,
"height": 1080
},
{
"width": 3840,
"height": 2160
} }
] item = item->next;
free(newprefix);
}
} }
``` ```
#### Printing The `prefix` process will build you a separated list, to simplify your callback handling.
The `dorecurse` flag would let the callback decide to handle sub-arrays on it's own, or
Let's build the above JSON and print it to a string: let you invoke it per-item. For the item above, your callback might look like this:
```c ```c
//create a monitor with a list of supported resolutions int callback(const char *name, int type, cJSON *item)
//NOTE: Returns a heap allocated string, you are required to free it after use.
char *create_monitor(void)
{ {
const unsigned int resolution_numbers[3][2] = { if (!strcmp(name, "name"))
{1280, 720},
{1920, 1080},
{3840, 2160}
};
char *string = NULL;
cJSON *name = NULL;
cJSON *resolutions = NULL;
cJSON *resolution = NULL;
cJSON *width = NULL;
cJSON *height = NULL;
size_t index = 0;
cJSON *monitor = cJSON_CreateObject();
if (monitor == NULL)
{ {
goto end; /* populate name */
}
else if (!strcmp(name, "format/type"))
{
/* handle "rect" */ }
else if (!strcmp(name, "format/width"))
{
/* 800 */
}
else if (!strcmp(name, "format/height"))
{
/* 600 */
}
else if (!strcmp(name, "format/interlace"))
{
/* false */
}
else if (!strcmp(name, "format/frame rate"))
{
/* 24 */
} }
name = cJSON_CreateString("Awesome 4K"); return 1;
if (name == NULL)
{
goto end;
}
/* after creation was successful, immediately add it to the monitor,
* thereby transferring ownership of the pointer to it */
cJSON_AddItemToObject(monitor, "name", name);
resolutions = cJSON_CreateArray();
if (resolutions == NULL)
{
goto end;
}
cJSON_AddItemToObject(monitor, "resolutions", resolutions);
for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
{
resolution = cJSON_CreateObject();
if (resolution == NULL)
{
goto end;
}
cJSON_AddItemToArray(resolutions, resolution);
width = cJSON_CreateNumber(resolution_numbers[index][0]);
if (width == NULL)
{
goto end;
}
cJSON_AddItemToObject(resolution, "width", width);
height = cJSON_CreateNumber(resolution_numbers[index][1]);
if (height == NULL)
{
goto end;
}
cJSON_AddItemToObject(resolution, "height", height);
}
string = cJSON_Print(monitor);
if (string == NULL)
{
fprintf(stderr, "Failed to print monitor.\n");
}
end:
cJSON_Delete(monitor);
return string;
} }
``` ```
Alternatively we can use the `cJSON_Add...ToObject` helper functions to make our lifes a little easier: Alternatively, you might like to parse iteratively.
You'd use:
```c ```c
//NOTE: Returns a heap allocated string, you are required to free it after use. void parse_object(cJSON *item)
char *create_monitor_with_helpers(void)
{ {
const unsigned int resolution_numbers[3][2] = { int i;
{1280, 720}, for (i = 0; i < cJSON_GetArraySize(item); i++)
{1920, 1080},
{3840, 2160}
};
char *string = NULL;
cJSON *resolutions = NULL;
size_t index = 0;
cJSON *monitor = cJSON_CreateObject();
if (cJSON_AddStringToObject(monitor, "name", "Awesome 4K") == NULL)
{ {
goto end; cJSON *subitem = cJSON_GetArrayItem(item, i);
// handle subitem
} }
resolutions = cJSON_AddArrayToObject(monitor, "resolutions");
if (resolutions == NULL)
{
goto end;
}
for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
{
cJSON *resolution = cJSON_CreateObject();
if (cJSON_AddNumberToObject(resolution, "width", resolution_numbers[index][0]) == NULL)
{
goto end;
}
if (cJSON_AddNumberToObject(resolution, "height", resolution_numbers[index][1]) == NULL)
{
goto end;
}
cJSON_AddItemToArray(resolutions, resolution);
}
string = cJSON_Print(monitor);
if (string == NULL)
{
fprintf(stderr, "Failed to print monitor.\n");
}
end:
cJSON_Delete(monitor);
return string;
} }
``` ```
#### Parsing Or, for PROPER manual mode:
In this example we will parse a JSON in the above format and check if the monitor supports a Full HD resolution while printing some diagnostic output:
```c ```c
/* return 1 if the monitor supports full hd, 0 otherwise */ void parse_object(cJSON *item)
int supports_full_hd(const char * const monitor)
{ {
const cJSON *resolution = NULL; cJSON *subitem = item->child;
const cJSON *resolutions = NULL; while (subitem)
const cJSON *name = NULL;
int status = 0;
cJSON *monitor_json = cJSON_Parse(monitor);
if (monitor_json == NULL)
{ {
const char *error_ptr = cJSON_GetErrorPtr(); // handle subitem
if (error_ptr != NULL) if (subitem->child)
{ {
fprintf(stderr, "Error before: %s\n", error_ptr); parse_object(subitem->child);
}
status = 0;
goto end;
}
name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name");
if (cJSON_IsString(name) && (name->valuestring != NULL))
{
printf("Checking monitor \"%s\"\n", name->valuestring);
}
resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, "resolutions");
cJSON_ArrayForEach(resolution, resolutions)
{
cJSON *width = cJSON_GetObjectItemCaseSensitive(resolution, "width");
cJSON *height = cJSON_GetObjectItemCaseSensitive(resolution, "height");
if (!cJSON_IsNumber(width) || !cJSON_IsNumber(height))
{
status = 0;
goto end;
} }
if ((width->valuedouble == 1920) && (height->valuedouble == 1080)) subitem = subitem->next;
{
status = 1;
goto end;
}
} }
end:
cJSON_Delete(monitor_json);
return status;
} }
``` ```
Note that there are no NULL checks except for the result of `cJSON_Parse` because `cJSON_GetObjectItemCaseSensitive` checks for `NULL` inputs already, so a `NULL` value is just propagated and `cJSON_IsNumber` and `cJSON_IsString` return `0` if the input is `NULL`. Of course, this should look familiar, since this is just a stripped-down version
of the callback-parser.
This should cover most uses you'll find for parsing. The rest should be possible
to infer.. and if in doubt, read the source! There's not a lot of it! ;)
In terms of constructing JSON data, the example code above is the right way to do it.
You can, of course, hand your sub-objects to other functions to populate.
Also, if you find a use for it, you can manually build the objects.
For instance, suppose you wanted to build an array of objects?
```c
cJSON *objects[24];
cJSON *Create_array_of_anything(cJSON **items, int num)
{
int i;
cJSON *prev;
cJSON *root = cJSON_CreateArray();
for (i = 0; i < 24; i++)
{
if (!i)
{
root->child = objects[i];
}
else
{
prev->next = objects[i];
objects[i]->prev = prev;
}
prev = objects[i];
}
return root;
}
```
and simply: `Create_array_of_anything(objects, 24);`
cJSON doesn't make any assumptions about what order you create things in.
You can attach the objects, as above, and later add children to each
of those objects.
As soon as you call `cJSON_Print`, it renders the structure to text.
The `test.c` code shows how to handle a bunch of typical cases. If you uncomment
the code, it'll load, parse and print a bunch of test files, also from [json.org](http://json.org),
which are more complex than I'd care to try and stash into a `const char array[]`.
### Caveats ### Caveats
@@ -551,7 +406,6 @@ cJSON doesn't support arrays and objects that are nested too deeply because this
In general cJSON is **not thread safe**. In general cJSON is **not thread safe**.
However it is thread safe under the following conditions: However it is thread safe under the following conditions:
* `cJSON_GetErrorPtr` is never used (the `return_parse_end` parameter of `cJSON_ParseWithOpts` can be used instead) * `cJSON_GetErrorPtr` is never used (the `return_parse_end` parameter of `cJSON_ParseWithOpts` can be used instead)
* `cJSON_InitHooks` is only ever called before using cJSON in any threads. * `cJSON_InitHooks` is only ever called before using cJSON in any threads.
* `setlocale` is never called before all calls to cJSON functions have returned. * `setlocale` is never called before all calls to cJSON functions have returned.
@@ -560,12 +414,7 @@ However it is thread safe under the following conditions:
When cJSON was originally created, it didn't follow the JSON standard and didn't make a distinction between uppercase and lowercase letters. If you want the correct, standard compliant, behavior, you need to use the `CaseSensitive` functions where available. When cJSON was originally created, it didn't follow the JSON standard and didn't make a distinction between uppercase and lowercase letters. If you want the correct, standard compliant, behavior, you need to use the `CaseSensitive` functions where available.
#### Duplicate Object Members
cJSON supports parsing and printing JSON that contains objects that have multiple members with the same name. `cJSON_GetObjectItemCaseSensitive` however will always only return the first one.
# Enjoy cJSON! # Enjoy cJSON!
- Dave Gamble (original author) - Dave Gamble, Aug 2009
- Max Bruckner and Alan Wang (current maintainer) - [cJSON contributors](CONTRIBUTORS.md)
- and the other [cJSON contributors](CONTRIBUTORS.md)

View File

@@ -1,86 +0,0 @@
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 }

825
cJSON.c

File diff suppressed because it is too large Load Diff

182
cJSON.h
View File

@@ -28,60 +28,10 @@ extern "C"
{ {
#endif #endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */ /* project version */
#define CJSON_VERSION_MAJOR 1 #define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7 #define CJSON_VERSION_MINOR 5
#define CJSON_VERSION_PATCH 15 #define CJSON_VERSION_PATCH 4
#include <stddef.h> #include <stddef.h>
@@ -124,13 +74,55 @@ typedef struct cJSON
typedef struct cJSON_Hooks typedef struct cJSON_Hooks
{ {
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ void *(*malloc_fn)(size_t sz);
void *(CJSON_CDECL *malloc_fn)(size_t sz); void (*free_fn)(void *ptr);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks; } cJSON_Hooks;
typedef int cJSON_bool; typedef int cJSON_bool;
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type __stdcall
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
#endif
#else /* !WIN32 */
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */ * This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT #ifndef CJSON_NESTING_LIMIT
@@ -146,12 +138,6 @@ 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. */ /* 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. */ /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
/* 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);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */ /* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */ /* Render a cJSON entity to text for transfer/storage without any formatting. */
@@ -162,11 +148,11 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */ /* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */ /* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */ /* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
@@ -175,10 +161,6 @@ CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *st
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check item type and return its value */
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
/* These functions check the type of an item */ /* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
@@ -203,33 +185,24 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so /* These utilities create an Array of count items. */
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/array that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
/* Append item to the specified array/object. */ /* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */ * writing to `item->string` */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detach items from Arrays/Objects. */ /* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
@@ -239,45 +212,42 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */ /* Update array items. */
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */ /* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
* need to be released. With recurse!=0, it will duplicate any children connected to the item. need to be released. With recurse!=0, it will duplicate any children connected to the item.
* The item->next and ->prev pointers are always zero on return from Duplicate. */ The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
* The input pointer json cannot point to a read-only address area, such as a string constant, /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
* but should point to a readable and writable address area. */ /* 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); CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time. /* Macros for creating things quickly. */
* They return the added item or NULL on failure. */ #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); #define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); #define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
/* When assigning an integer value, it needs to be propagated to valuedouble too. */ /* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */ /* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) #define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
/* Macro for iterating over an array or object */ /* 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) #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)

View File

@@ -20,47 +20,18 @@
THE SOFTWARE. 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) #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 <ctype.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
#include <math.h>
#include <float.h>
#include <math.h>
#if defined(_MSC_VER)
#pragma warning (pop)
#endif
#ifdef __GNUCC__
#pragma GCC visibility pop #pragma GCC visibility pop
#endif
#include "cJSON_Utils.h" #include "cJSON_Utils.h"
/* define our own boolean type */ /* define our own boolean type */
#ifdef true
#undef true
#endif
#define true ((cJSON_bool)1) #define true ((cJSON_bool)1)
#ifdef false
#undef false
#endif
#define false ((cJSON_bool)0) #define false ((cJSON_bool)0)
static unsigned char* cJSONUtils_strdup(const unsigned char* const string) static unsigned char* cJSONUtils_strdup(const unsigned char* const string)
@@ -108,14 +79,6 @@ static int compare_strings(const unsigned char *string1, const unsigned char *st
return tolower(*string1) - tolower(*string2); return tolower(*string1) - tolower(*string2);
} }
/* securely comparison of floating-point variables */
static cJSON_bool compare_double(double a, double b)
{
double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
return (fabs(a - b) <= maxVal * DBL_EPSILON);
}
/* Compare the next path element of two JSON pointers, two NULL pointers are considered unequal: */ /* Compare the next path element of two JSON pointers, two NULL pointers are considered unequal: */
static cJSON_bool compare_pointers(const unsigned char *name, const unsigned char *pointer, const cJSON_bool case_sensitive) static cJSON_bool compare_pointers(const unsigned char *name, const unsigned char *pointer, const cJSON_bool case_sensitive)
{ {
@@ -176,14 +139,13 @@ static void encode_string_as_pointer(unsigned char *destination, const unsigned
{ {
if (source[0] == '/') if (source[0] == '/')
{ {
destination[0] = '~';
destination[1] = '1'; destination[1] = '1';
destination++; destination++;
} }
else if (source[0] == '~') else if (source[0] == '~')
{ {
destination[0] = '~'; destination[0] = '~';
destination[1] = '0'; destination[1] = '1';
destination++; destination++;
} }
else else
@@ -200,11 +162,6 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje
size_t child_index = 0; size_t child_index = 0;
cJSON *current_child = 0; cJSON *current_child = 0;
if ((object == NULL) || (target == NULL))
{
return NULL;
}
if (object == target) if (object == target)
{ {
/* found */ /* found */
@@ -228,7 +185,6 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje
if (child_index > ULONG_MAX) if (child_index > ULONG_MAX)
{ {
cJSON_free(target_pointer); cJSON_free(target_pointer);
cJSON_free(full_pointer);
return NULL; return NULL;
} }
sprintf((char*)full_pointer, "/%lu%s", (unsigned long)child_index, target_pointer); /* /<array_index><path> */ sprintf((char*)full_pointer, "/%lu%s", (unsigned long)child_index, target_pointer); /* /<array_index><path> */
@@ -301,12 +257,6 @@ 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) static cJSON *get_item_from_pointer(cJSON * const object, const char * pointer, const cJSON_bool case_sensitive)
{ {
cJSON *current_element = object; cJSON *current_element = object;
if (pointer == NULL)
{
return NULL;
}
/* follow path of the pointer */ /* follow path of the pointer */
while ((pointer[0] == '/') && (current_element != NULL)) while ((pointer[0] == '/') && (current_element != NULL))
{ {
@@ -329,17 +279,16 @@ static cJSON *get_item_from_pointer(cJSON * const object, const char * pointer,
{ {
current_element = current_element->next; current_element = current_element->next;
} }
/* skip to the next path token or end of string */
while ((pointer[0] != '\0') && (pointer[0] != '/'))
{
pointer++;
}
} }
else else
{ {
return NULL; return NULL;
} }
/* skip to the next path token or end of string */
while ((pointer[0] != '\0') && (pointer[0] != '/'))
{
pointer++;
}
} }
return current_element; return current_element;
@@ -403,7 +352,7 @@ static cJSON *detach_item_from_array(cJSON *array, size_t which)
/* item doesn't exist */ /* item doesn't exist */
return NULL; return NULL;
} }
if (c != array->child) if (c->prev)
{ {
/* not the first element */ /* not the first element */
c->prev->next = c->next; c->prev->next = c->next;
@@ -412,14 +361,10 @@ static cJSON *detach_item_from_array(cJSON *array, size_t which)
{ {
c->next->prev = c->prev; c->next->prev = c->prev;
} }
if (c == array->child) if (c==array->child)
{ {
array->child = c->next; array->child = c->next;
} }
else if (c->next == NULL)
{
array->child->prev = c->prev;
}
/* make sure the detached item doesn't point anywhere anymore */ /* make sure the detached item doesn't point anywhere anymore */
c->prev = c->next = NULL; c->prev = c->next = NULL;
@@ -523,7 +468,6 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
{ {
/* Split the lists */ /* Split the lists */
second->prev->next = NULL; second->prev->next = NULL;
second->prev = NULL;
} }
/* Recursively sort the sub-lists. */ /* Recursively sort the sub-lists. */
@@ -535,7 +479,7 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
while ((first != NULL) && (second != NULL)) while ((first != NULL) && (second != NULL))
{ {
cJSON *smaller = NULL; cJSON *smaller = NULL;
if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, case_sensitive) < 0) if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, false) < 0)
{ {
smaller = first; smaller = first;
} }
@@ -594,10 +538,6 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
static void sort_object(cJSON * const object, 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); object->child = sort_list(object->child, case_sensitive);
} }
@@ -612,7 +552,7 @@ static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensiti
{ {
case cJSON_Number: case cJSON_Number:
/* numeric mismatch. */ /* numeric mismatch. */
if ((a->valueint != b->valueint) || (!compare_double(a->valuedouble, b->valuedouble))) if ((a->valueint != b->valueint) || (a->valuedouble != b->valuedouble))
{ {
return false; return false;
} }
@@ -960,9 +900,7 @@ static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_
/* split pointer in parent and child */ /* split pointer in parent and child */
parent_pointer = cJSONUtils_strdup((unsigned char*)path->valuestring); parent_pointer = cJSONUtils_strdup((unsigned char*)path->valuestring);
if (parent_pointer) { child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/');
child_pointer = (unsigned char*)strrchr((char*)parent_pointer, '/');
}
if (child_pointer != NULL) if (child_pointer != NULL)
{ {
child_pointer[0] = '\0'; child_pointer[0] = '\0';
@@ -1004,23 +942,10 @@ static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_
} }
else if (cJSON_IsObject(parent)) else if (cJSON_IsObject(parent))
{ {
if (case_sensitive) cJSON_DeleteItemFromObject(parent, (char*)child_pointer);
{
cJSON_DeleteItemFromObjectCaseSensitive(parent, (char*)child_pointer);
}
else
{
cJSON_DeleteItemFromObject(parent, (char*)child_pointer);
}
cJSON_AddItemToObject(parent, (char*)child_pointer, value); cJSON_AddItemToObject(parent, (char*)child_pointer, value);
value = NULL; value = NULL;
} }
else /* parent is not an object */
{
/* Couldn't find object to add to. */
status = 9;
goto cleanup;
}
cleanup: cleanup:
if (value != NULL) if (value != NULL)
@@ -1095,14 +1020,7 @@ 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) 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 = NULL; cJSON *patch = cJSON_CreateObject();
if ((patches == NULL) || (operation == NULL) || (path == NULL))
{
return;
}
patch = cJSON_CreateObject();
if (patch == NULL) if (patch == NULL)
{ {
return; return;
@@ -1154,7 +1072,7 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa
switch (from->type & 0xFF) switch (from->type & 0xFF)
{ {
case cJSON_Number: case cJSON_Number:
if ((from->valueint != to->valueint) || !compare_double(from->valuedouble, to->valuedouble)) if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble))
{ {
compose_patch(patches, (const unsigned char*)"replace", path, NULL, to); compose_patch(patches, (const unsigned char*)"replace", path, NULL, to);
} }
@@ -1280,14 +1198,7 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to) CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to)
{ {
cJSON *patches = NULL; cJSON *patches = cJSON_CreateArray();
if ((from == NULL) || (to == NULL))
{
return NULL;
}
patches = cJSON_CreateArray();
create_patches(patches, (const unsigned char*)"", from, to, false); create_patches(patches, (const unsigned char*)"", from, to, false);
return patches; return patches;
@@ -1295,14 +1206,7 @@ CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * con
CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to) CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to)
{ {
cJSON *patches = NULL; cJSON *patches = cJSON_CreateArray();
if ((from == NULL) || (to == NULL))
{
return NULL;
}
patches = cJSON_CreateArray();
create_patches(patches, (const unsigned char*)"", from, to, true); create_patches(patches, (const unsigned char*)"", from, to, true);
return patches; return patches;
@@ -1408,10 +1312,6 @@ static cJSON *generate_merge_patch(cJSON * const from, cJSON * const to, const c
from_child = from->child; from_child = from->child;
to_child = to->child; to_child = to->child;
patch = cJSON_CreateObject(); patch = cJSON_CreateObject();
if (patch == NULL)
{
return NULL;
}
while (from_child || to_child) while (from_child || to_child)
{ {
int diff; int diff;

View File

@@ -20,14 +20,6 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#ifndef cJSON_Utils__h
#define cJSON_Utils__h
#ifdef __cplusplus
extern "C"
{
#endif
#include "cJSON.h" #include "cJSON.h"
/* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */ /* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */
@@ -80,9 +72,3 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje
/* Sorts the members of the object into alphabetical order. */ /* Sorts the members of the object into alphabetical order. */
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object); CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object); CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);
#ifdef __cplusplus
}
#endif
#endif

1
fuzzing/.gitignore vendored
View File

@@ -1 +1,2 @@
afl-build afl-build
libfuzzer-build

View File

@@ -5,30 +5,27 @@ if (ENABLE_FUZZING)
message(FATAL_ERROR "Couldn't find afl-fuzz.") message(FATAL_ERROR "Couldn't find afl-fuzz.")
endif() endif()
option(ENABLE_LIBFUZZER "Enable fuzzing with libfuzzer (only works with llvm 5 which hasn't been release at this point)" Off)
if (ENABLE_LIBFUZZER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer")
endif()
add_library(fuzz-target fuzz-target.c)
target_link_libraries(fuzz-target "${CJSON_LIB}")
add_executable(afl-main afl.c) add_executable(afl-main afl.c)
target_link_libraries(afl-main "${CJSON_LIB}") target_link_libraries(afl-main fuzz-target)
if (NOT ENABLE_SANITIZERS) if (NOT ENABLE_SANITIZERS)
message(FATAL_ERROR "Enable sanitizers with -DENABLE_SANITIZERS=On to do fuzzing.") message(FATAL_ERROR "Enable sanitizers with -DENABLE_SANITIZERS=On to do fuzzing.")
endif() endif()
option(ENABLE_FUZZING_PRINT "Fuzz printing functions together with parser." On)
set(fuzz_print_parameter "no")
if (ENABLE_FUZZING_PRINT)
set(fuzz_print_parameter "yes")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error")
add_custom_target(afl add_custom_target(afl
COMMAND "${AFL_FUZZ}" -i "${CMAKE_CURRENT_SOURCE_DIR}/inputs" -o "${CMAKE_CURRENT_BINARY_DIR}/findings" -x "${CMAKE_CURRENT_SOURCE_DIR}/json.dict" -- "${CMAKE_CURRENT_BINARY_DIR}/afl-main" "@@" "${fuzz_print_parameter}" COMMAND "${AFL_FUZZ}" -i "${CMAKE_CURRENT_SOURCE_DIR}/inputs" -o "${CMAKE_CURRENT_BINARY_DIR}/findings" -x "${CMAKE_CURRENT_SOURCE_DIR}/json.dict" -- "${CMAKE_CURRENT_BINARY_DIR}/afl-main" "@@"
DEPENDS afl-main) DEPENDS afl-main)
endif() endif()
if(ENABLE_CJSON_TEST)
ADD_EXECUTABLE(fuzz_main fuzz_main.c cjson_read_fuzzer.c)
TARGET_LINK_LIBRARIES(fuzz_main cjson)
endif()

View File

@@ -24,54 +24,71 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "../cJSON.h" #include "fuzz-target.h"
static char *read_file(const char *filename) static char *read_file(const char *filename, size_t *size)
{ {
FILE *file = NULL; FILE *file = NULL;
long length = 0; long length = 0;
char *content = NULL; char *content = NULL;
size_t read_chars = 0; size_t read_chars = 0;
if (size == NULL)
{
goto fail;
}
/* open in read binary mode */ /* open in read binary mode */
file = fopen(filename, "rb"); file = fopen(filename, "rb");
if (file == NULL) if (file == NULL)
{ {
goto cleanup; goto fail;
} }
/* get the length */ /* get the length */
if (fseek(file, 0, SEEK_END) != 0) if (fseek(file, 0, SEEK_END) != 0)
{ {
goto cleanup; goto fail;
} }
length = ftell(file); length = ftell(file);
if (length < 0) if (length < 0)
{ {
goto cleanup; goto fail;
} }
if (fseek(file, 0, SEEK_SET) != 0) if (fseek(file, 0, SEEK_SET) != 0)
{ {
goto cleanup; goto fail;
} }
/* allocate content buffer */ /* allocate content buffer */
content = (char*)malloc((size_t)length + sizeof("")); content = (char*)malloc((size_t)length + sizeof(""));
if (content == NULL) if (content == NULL)
{ {
goto cleanup; goto fail;
} }
/* read the file into memory */ /* read the file into memory */
read_chars = fread(content, sizeof(char), (size_t)length, file); read_chars = fread(content, sizeof(char), (size_t)length, file);
if ((long)read_chars != length) if ((long)read_chars != length)
{ {
free(content); goto fail;
content = NULL;
goto cleanup;
} }
content[read_chars] = '\0'; content[read_chars] = '\0';
*size = read_chars + sizeof("");
goto cleanup;
fail:
if (size != NULL)
{
*size = 0;
}
if (content != NULL)
{
free(content);
content = NULL;
}
cleanup: cleanup:
if (file != NULL) if (file != NULL)
@@ -85,92 +102,50 @@ cleanup:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
const char *filename = NULL; const char *filename = NULL;
cJSON *item = NULL;
char *json = NULL; char *json = NULL;
int status = EXIT_FAILURE; int status = EXIT_FAILURE;
char *printed_json = NULL; char *printed_json = NULL;
if ((argc < 2) || (argc > 3)) if (argc != 2)
{ {
printf("Usage:\n"); printf("Usage:\n");
printf("%s input_file [enable_printing]\n", argv[0]); printf("%s input_file\n", argv[0]);
printf("\t input_file: file containing the test data\n"); printf("\t input_file: file containing the test data\n");
printf("\t enable_printing: print after parsing, 'yes' or 'no', defaults to 'no'\n");
goto cleanup; goto cleanup;
} }
filename = argv[1]; filename = argv[1];
#if __AFL_HAVE_MANUAL_CONTROL #if defined(__AFL_HAVE_MANUAL_CONTROL) && __AFL_HAVE_MANUAL_CONTROL
while (__AFL_LOOP(1000)) while (__AFL_LOOP(1000))
{ {
#else
{
#endif #endif
status = EXIT_SUCCESS; size_t size = 0;
status = EXIT_SUCCESS;
json = read_file(filename); json = read_file(filename, &size);
if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0')) if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0'))
{
status = EXIT_FAILURE;
goto cleanup;
}
item = cJSON_Parse(json + 2);
if (item == NULL)
{
goto cleanup;
}
if ((argc == 3) && (strncmp(argv[2], "yes", 3) == 0))
{
int do_format = 0;
if (json[1] == 'f')
{
do_format = 1;
}
if (json[0] == 'b')
{
/* buffered printing */
printed_json = cJSON_PrintBuffered(item, 1, do_format);
}
else
{
/* unbuffered printing */
if (do_format)
{
printed_json = cJSON_Print(item);
}
else
{
printed_json = cJSON_PrintUnformatted(item);
}
}
if (printed_json == NULL)
{ {
status = EXIT_FAILURE; status = EXIT_FAILURE;
goto cleanup; goto cleanup;
} }
printf("%s\n", printed_json);
}
cleanup: LLVMFuzzerTestOneInput(json, size);
if (item != NULL)
{ cleanup:
cJSON_Delete(item); if (json != NULL)
item = NULL; {
free(json);
json = NULL;
}
if (printed_json != NULL)
{
free(printed_json);
printed_json = NULL;
}
} }
if (json != NULL)
{
free(json);
json = NULL;
}
if (printed_json != NULL)
{
free(printed_json);
printed_json = NULL;
}
#if __AFL_HAVE_MANUAL_CONTROL
}
#endif
return status; return status;
} }

View File

@@ -1,77 +0,0 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "../cJSON.h"
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); /* required by C89 */
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
cJSON *json;
size_t offset = 4;
unsigned char *copied;
char *printed_json = NULL;
int minify, require_termination, formatted, buffered;
if(size <= offset) return 0;
if(data[size-1] != '\0') return 0;
if(data[0] != '1' && data[0] != '0') return 0;
if(data[1] != '1' && data[1] != '0') return 0;
if(data[2] != '1' && data[2] != '0') return 0;
if(data[3] != '1' && data[3] != '0') return 0;
minify = data[0] == '1' ? 1 : 0;
require_termination = data[1] == '1' ? 1 : 0;
formatted = data[2] == '1' ? 1 : 0;
buffered = data[3] == '1' ? 1 : 0;
json = cJSON_ParseWithOpts((const char*)data + offset, NULL, require_termination);
if(json == NULL) return 0;
if(buffered)
{
printed_json = cJSON_PrintBuffered(json, 1, formatted);
}
else
{
/* unbuffered printing */
if(formatted)
{
printed_json = cJSON_Print(json);
}
else
{
printed_json = cJSON_PrintUnformatted(json);
}
}
if(printed_json != NULL) free(printed_json);
if(minify)
{
copied = (unsigned char*)malloc(size);
if(copied == NULL) return 0;
memcpy(copied, data, size);
cJSON_Minify((char*)copied + offset);
free(copied);
}
cJSON_Delete(json);
return 0;
}
#ifdef __cplusplus
}
#endif

129
fuzzing/fuzz-target.c Normal file
View File

@@ -0,0 +1,129 @@
/*
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 <string.h>
#include <stdio.h>
#include "fuzz-target.h"
#include "../cJSON.h"
static void minify(const unsigned char *data, size_t size)
{
unsigned char *copied_data = (unsigned char*)malloc(size);
if (copied_data == NULL)
{
return;
}
memcpy(copied_data, data, size);
cJSON_Minify((char*)copied_data);
free(copied_data);
return;
}
static void printing(cJSON *json, unsigned char format_setting, unsigned char buffered_setting)
{
unsigned char *printed = NULL;
if (buffered_setting == '1')
{
printed = (unsigned char*)cJSON_PrintBuffered(json, 1, (format_setting == '1'));
}
else
{
if (format_setting == '1')
{
printed = (unsigned char*)cJSON_Print(json);
}
else
{
printed = (unsigned char*)cJSON_PrintUnformatted(json);
}
}
if (printed != NULL)
{
free(printed);
}
}
extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size)
{
unsigned char minify_setting = '\0'; /* minify instead of parsing */
unsigned char require_zero_setting = '\0'; /* zero termination required */
unsigned char format_setting = '\0'; /* formatted printing */
unsigned char buffered_setting = '\0'; /* buffered printing */
const size_t data_offset = 4;
cJSON *json = NULL;
/* don't work with NULL or without mode selector */
if ((data == NULL) || (size < data_offset))
{
return 0;
}
/* get configuration from the beginning of the test case */
minify_setting = data[0];
require_zero_setting = data[1];
format_setting = data[2];
buffered_setting = data[3];
/* check if settings are valid */
if ((minify_setting != '0') && (minify_setting != '1'))
{
return 0;
}
if ((require_zero_setting != '0') && (require_zero_setting != '1'))
{
return 0;
}
if ((format_setting != '0') && (format_setting != '1'))
{
return 0;
}
if ((buffered_setting != '0') && (buffered_setting != '1'))
{
return 0;
}
if (minify_setting == '1')
{
minify(data + data_offset, size);
return 0;
}
json = cJSON_ParseWithOpts((const char*)data + data_offset, NULL, (require_zero_setting == '1'));
if (json == NULL)
{
return 0;
}
printing(json, format_setting, buffered_setting);
free(json);
return 0;
}

30
fuzzing/fuzz-target.h Normal file
View File

@@ -0,0 +1,30 @@
/*
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 <stdlib.h>
#ifndef CJSON_FUZZ_TARGET
#define CJSON_FUZZ_TARGET
extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);
#endif /* CJSON_FUZZ_TARGET */

View File

@@ -1,54 +0,0 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); /* required by C89 */
/* fuzz target entry point, works without libFuzzer */
int main(int argc, char **argv)
{
FILE *f;
char *buf = NULL;
long siz_buf;
if(argc < 2)
{
fprintf(stderr, "no input file\n");
goto err;
}
f = fopen(argv[1], "rb");
if(f == NULL)
{
fprintf(stderr, "error opening input file %s\n", argv[1]);
goto err;
}
fseek(f, 0, SEEK_END);
siz_buf = ftell(f);
rewind(f);
if(siz_buf < 1) goto err;
buf = (char*)malloc((size_t)siz_buf);
if(buf == NULL)
{
fprintf(stderr, "malloc() failed\n");
goto err;
}
if(fread(buf, (size_t)siz_buf, 1, f) != 1)
{
fprintf(stderr, "fread() failed\n");
goto err;
}
(void)LLVMFuzzerTestOneInput((uint8_t*)buf, (size_t)siz_buf);
err:
free(buf);
return 0;
}

View File

@@ -1,4 +1,4 @@
bf{ 0111{
"glossary": { "glossary": {
"title": "example glossary", "title": "example glossary",
"GlossDiv": { "GlossDiv": {

View File

@@ -1 +1 @@
bf["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] 0111["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]

View File

@@ -1,8 +1,8 @@
bf{ 0111{
"name": "Jack (\"Bee\") Nimble", "name": "Jack (\"Bee\") Nimble",
"format": {"type": "rect", "format": {"type": "rect",
"width": 1920, "width": 1920,
"height": 1080, "height": 1080,
"interlace": false,"frame rate": 24 "interlace": false,"frame rate": 24
} }
} }

View File

@@ -1,4 +1,4 @@
bf{"menu": { 0111{"menu": {
"id": "file", "id": "file",
"value": "File", "value": "File",
"popup": { "popup": {

View File

@@ -1,4 +1,4 @@
bf{"widget": { 0111{"widget": {
"debug": "on", "debug": "on",
"window": { "window": {
"title": "Sample Konfabulator Widget", "title": "Sample Konfabulator Widget",
@@ -6,7 +6,7 @@ bf{"widget": {
"width": 500, "width": 500,
"height": 500 "height": 500
}, },
"image": { "image": {
"src": "Images/Sun.png", "src": "Images/Sun.png",
"name": "sun1", "name": "sun1",
"hOffset": 250, "hOffset": 250,
@@ -23,4 +23,4 @@ bf{"widget": {
"alignment": "center", "alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
} }
}} }}

View File

@@ -1,4 +1,4 @@
bu{"widget": { 0101{"widget": {
"debug": "on", "debug": "on",
"window": { "window": {
"title": "Sample Konfabulator Widget", "title": "Sample Konfabulator Widget",
@@ -6,7 +6,7 @@ bu{"widget": {
"width": 500, "width": 500,
"height": 500 "height": 500
}, },
"image": { "image": {
"src": "Images/Sun.png", "src": "Images/Sun.png",
"name": "sun1", "name": "sun1",
"hOffset": 250, "hOffset": 250,
@@ -23,4 +23,4 @@ bu{"widget": {
"alignment": "center", "alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
} }
}} }}

View File

@@ -1,4 +1,4 @@
uf{"widget": { 0110{"widget": {
"debug": "on", "debug": "on",
"window": { "window": {
"title": "Sample Konfabulator Widget", "title": "Sample Konfabulator Widget",
@@ -6,7 +6,7 @@ uf{"widget": {
"width": 500, "width": 500,
"height": 500 "height": 500
}, },
"image": { "image": {
"src": "Images/Sun.png", "src": "Images/Sun.png",
"name": "sun1", "name": "sun1",
"hOffset": 250, "hOffset": 250,
@@ -23,4 +23,4 @@ uf{"widget": {
"alignment": "center", "alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
} }
}} }}

View File

@@ -1,4 +1,4 @@
uu{"widget": { 0100{"widget": {
"debug": "on", "debug": "on",
"window": { "window": {
"title": "Sample Konfabulator Widget", "title": "Sample Konfabulator Widget",
@@ -6,7 +6,7 @@ uu{"widget": {
"width": 500, "width": 500,
"height": 500 "height": 500
}, },
"image": { "image": {
"src": "Images/Sun.png", "src": "Images/Sun.png",
"name": "sun1", "name": "sun1",
"hOffset": 250, "hOffset": 250,
@@ -23,4 +23,4 @@ uu{"widget": {
"alignment": "center", "alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
} }
}} }}

View File

@@ -1,5 +1,5 @@
bf{"web-app": { 0111{"web-app": {
"servlet": [ "servlet": [
{ {
"servlet-name": "cofaxCDS", "servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet", "servlet-class": "org.cofax.cds.CDSServlet",
@@ -55,7 +55,7 @@ bf{"web-app": {
{ {
"servlet-name": "cofaxAdmin", "servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"}, "servlet-class": "org.cofax.cds.AdminServlet"},
{ {
"servlet-name": "fileServlet", "servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"}, "servlet-class": "org.cofax.cds.FileServlet"},
@@ -82,7 +82,7 @@ bf{"web-app": {
"cofaxAdmin": "/admin/*", "cofaxAdmin": "/admin/*",
"fileServlet": "/static/*", "fileServlet": "/static/*",
"cofaxTools": "/tools/*"}, "cofaxTools": "/tools/*"},
"taglib": { "taglib": {
"taglib-uri": "cofax.tld", "taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}} "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}

View File

@@ -1,4 +1,4 @@
bf{"menu": { 0111{"menu": {
"header": "SVG Viewer", "header": "SVG Viewer",
"items": [ "items": [
{"id": "Open"}, {"id": "Open"},

View File

@@ -1,4 +1,4 @@
bf<!DOCTYPE html> 0111<!DOCTYPE html>
<html> <html>
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">

View File

@@ -1,4 +1,4 @@
bf[ 0111[
{ {
"precision": "zip", "precision": "zip",
"Latitude": 37.7668, "Latitude": 37.7668,

View File

@@ -1,4 +1,4 @@
bf{ 0111{
"Image": { "Image": {
"Width": 800, "Width": 800,
"Height": 600, "Height": 600,

View File

@@ -1,4 +1,4 @@
bf[ 0111[
[0, -1, 0], [0, -1, 0],
[1, 0, 0], [1, 0, 0],
[0, 0, 1] [0, 0, 1]

View File

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

9
fuzzing/libfuzzer.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
mkdir -p libfuzzer-build || exit 1
cd libfuzzer-build || exit 1
#cleanup
rm -r -- *
CC=clang cmake ../.. -DENABLE_FUZZING=On -DENABLE_SANITIZERS=On -DBUILD_SHARED_LIBS=Off -DCMAKE_BUILD_TYPE=Debug -DENABLE_LIBFUZZER=On
make fuzz-target

View File

@@ -1,18 +0,0 @@
#!/bin/bash -eu
# This script is meant to be run by
# https://github.com/google/oss-fuzz/blob/master/projects/cjson/Dockerfile
mkdir build
cd build
cmake -DBUILD_SHARED_LIBS=OFF -DENABLE_CJSON_TEST=OFF ..
make -j$(nproc)
$CXX $CXXFLAGS $SRC/cjson/fuzzing/cjson_read_fuzzer.c -I. \
-o $OUT/cjson_read_fuzzer \
$LIB_FUZZING_ENGINE $SRC/cjson/build/libcjson.a
find $SRC/cjson/fuzzing/inputs -name "*" | \
xargs zip $OUT/cjson_read_fuzzer_seed_corpus.zip
cp $SRC/cjson/fuzzing/json.dict $OUT/cjson_read_fuzzer.dict

View File

@@ -2,8 +2,8 @@
set(CJSON_UTILS_FOUND @ENABLE_CJSON_UTILS@) set(CJSON_UTILS_FOUND @ENABLE_CJSON_UTILS@)
# The include directories used by cJSON # The include directories used by cJSON
set(CJSON_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@") set(CJSON_INCLUDE_DIRS "@prefix@/@includedir@")
set(CJSON_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@") set(CJSON_INCLUDE_DIR "@prefix@/@includedir@")
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)

View File

@@ -1,10 +1,11 @@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@ prefix=@prefix@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ libdir=${prefix}/@libdir@
includedir=${prefix}/@includedir@
Name: libcjson Name: libcjson
Version: @PROJECT_VERSION@ Version: @version@
Description: Ultralightweight JSON parser in ANSI C Description: Ultralightweight JSON parser in ANSI C
URL: https://github.com/DaveGamble/cJSON URL: https://github.com/DaveGamble/cJSON
Libs: -L${libdir} -lcjson Libs: -L${libdir} -lcjson
Libs.private: -lm Libs.Private: -lm
Cflags: -I${includedir} -I${includedir}/cjson Cflags: -I${includedir}

View File

@@ -1,10 +1,11 @@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@ prefix=@prefix@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ libdir=${prefix}/@libdir@
includedir=${prefix}/@includedir@
Name: libcjson_utils Name: libcjson_utils
Version: @PROJECT_VERSION@ Version: @version@
Description: An implementation of JSON Pointer, Patch and Merge Patch based on cJSON. Description: An implementation of JSON Pointer, Patch and Merge Patch based on cJSON.
URL: https://github.com/DaveGamble/cJSON URL: https://github.com/DaveGamble/cJSON
Libs: -L${libdir} -lcjson_utils Libs: -L${libdir} -lcjson_utils
Cflags: -I${includedir} -I${includedir}/cjson Cflags: -I${includedir}
Requires: libcjson Requires: libcjson

View File

@@ -1,27 +0,0 @@
cmake_minimum_required(VERSION 2.8.5)
set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt")
if(NOT EXISTS ${MANIFEST})
message(FATAL_ERROR "Cannot find install mainfest: ${MANIFEST}")
endif()
file(STRINGS ${MANIFEST} files)
foreach(file ${files})
if(EXISTS ${file} OR IS_SYMLINK ${file})
message(STATUS "Removing: ${file}")
execute_process(COMMAND rm -f ${file}
RESULT_VARIABLE result
OUTPUT_QUIET
ERROR_VARIABLE stderr
ERROR_STRIP_TRAILING_WHITESPACE
)
if(NOT ${result} EQUAL 0)
message(FATAL_ERROR "${stderr}")
endif()
else()
message(STATUS "Does-not-exist: ${file}")
endif()
endforeach(file)

2
test.c
View File

@@ -256,7 +256,7 @@ static void create_objects(void)
cJSON_Delete(root); cJSON_Delete(root);
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* print the version */ /* print the version */
printf("Version: %s\n", cJSON_Version()); printf("Version: %s\n", cJSON_Version());

View File

@@ -1,5 +1,5 @@
if(ENABLE_CJSON_TEST) if(ENABLE_CJSON_TEST)
add_library(unity STATIC unity/src/unity.c) add_library(unity unity/src/unity.c)
# Disable -Werror for Unity # Disable -Werror for Unity
if (FLAG_SUPPORTED_Werror) if (FLAG_SUPPORTED_Werror)
@@ -55,11 +55,10 @@ if(ENABLE_CJSON_TEST)
misc_tests misc_tests
parse_with_opts parse_with_opts
compare_tests compare_tests
cjson_add
readme_examples
minify_tests
) )
add_library(test-common common.c)
option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.") option(ENABLE_VALGRIND OFF "Enable the valgrind memory checker for the tests.")
if (ENABLE_VALGRIND) if (ENABLE_VALGRIND)
find_program(MEMORYCHECK_COMMAND valgrind) find_program(MEMORYCHECK_COMMAND valgrind)
@@ -67,16 +66,13 @@ if(ENABLE_CJSON_TEST)
message(WARNING "Valgrind couldn't be found.") message(WARNING "Valgrind couldn't be found.")
unset(MEMORYCHECK_COMMAND) unset(MEMORYCHECK_COMMAND)
else() else()
set(MEMORYCHECK_COMMAND_OPTIONS --trace-children=yes --leak-check=full --error-exitcode=1 --suppressions=${CMAKE_CURRENT_SOURCE_DIR}/../valgrind.supp) set(MEMORYCHECK_COMMAND_OPTIONS --trace-children=yes --leak-check=full --error-exitcode=1)
endif() endif()
endif() endif()
foreach(unity_test ${unity_tests}) foreach(unity_test ${unity_tests})
add_executable("${unity_test}" "${unity_test}.c") add_executable("${unity_test}" "${unity_test}.c")
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") target_link_libraries("${unity_test}" "${CJSON_LIB}" unity test-common)
target_sources(${unity_test} PRIVATE unity_setup.c)
endif()
target_link_libraries("${unity_test}" "${CJSON_LIB}" unity)
if(MEMORYCHECK_COMMAND) if(MEMORYCHECK_COMMAND)
add_test(NAME "${unity_test}" add_test(NAME "${unity_test}"
COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${unity_test}") COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${unity_test}")
@@ -96,15 +92,11 @@ if(ENABLE_CJSON_TEST)
set (cjson_utils_tests set (cjson_utils_tests
json_patch_tests json_patch_tests
old_utils_tests old_utils_tests)
misc_utils_tests)
foreach (cjson_utils_test ${cjson_utils_tests}) foreach (cjson_utils_test ${cjson_utils_tests})
add_executable("${cjson_utils_test}" "${cjson_utils_test}.c") add_executable("${cjson_utils_test}" "${cjson_utils_test}.c")
target_link_libraries("${cjson_utils_test}" "${CJSON_LIB}" "${CJSON_UTILS_LIB}" unity) target_link_libraries("${cjson_utils_test}" "${CJSON_LIB}" "${CJSON_UTILS_LIB}" unity test-common)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
target_sources(${cjson_utils_test} PRIVATE unity_setup.c)
endif()
if(MEMORYCHECK_COMMAND) if(MEMORYCHECK_COMMAND)
add_test(NAME "${cjson_utils_test}" add_test(NAME "${cjson_utils_test}"
COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${cjson_utils_test}") COMMAND "${MEMORYCHECK_COMMAND}" ${MEMORYCHECK_COMMAND_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${cjson_utils_test}")

View File

@@ -1,471 +0,0 @@
/*
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"
static void * CJSON_CDECL failing_malloc(size_t size)
{
(void)size;
return NULL;
}
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
static void CJSON_CDECL normal_free(void *pointer)
{
free(pointer);
}
static cJSON_Hooks failing_hooks = {
failing_malloc,
normal_free
};
static void cjson_add_null_should_add_null(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *null = NULL;
cJSON_AddNullToObject(root, "null");
TEST_ASSERT_NOT_NULL(null = cJSON_GetObjectItemCaseSensitive(root, "null"));
TEST_ASSERT_EQUAL_INT(null->type, cJSON_NULL);
cJSON_Delete(root);
}
static void cjson_add_null_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddNullToObject(NULL, "null"));
TEST_ASSERT_NULL(cJSON_AddNullToObject(root, NULL));
cJSON_Delete(root);
}
static void cjson_add_null_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddNullToObject(root, "null"));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cjson_add_true_should_add_true(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *true_item = NULL;
cJSON_AddTrueToObject(root, "true");
TEST_ASSERT_NOT_NULL(true_item = cJSON_GetObjectItemCaseSensitive(root, "true"));
TEST_ASSERT_EQUAL_INT(true_item->type, cJSON_True);
cJSON_Delete(root);
}
static void cjson_add_true_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddTrueToObject(NULL, "true"));
TEST_ASSERT_NULL(cJSON_AddTrueToObject(root, NULL));
cJSON_Delete(root);
}
static void cjson_add_true_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddTrueToObject(root, "true"));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cjson_create_int_array_should_fail_on_allocation_failure(void)
{
int numbers[] = {1, 2, 3};
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_CreateIntArray(numbers, 3));
cJSON_InitHooks(NULL);
}
static void cjson_create_float_array_should_fail_on_allocation_failure(void)
{
float numbers[] = {1.0f, 2.0f, 3.0f};
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_CreateFloatArray(numbers, 3));
cJSON_InitHooks(NULL);
}
static void cjson_create_double_array_should_fail_on_allocation_failure(void)
{
double numbers[] = {1.0, 2.0, 3.0};
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_CreateDoubleArray(numbers, 3));
cJSON_InitHooks(NULL);
}
static void cjson_create_string_array_should_fail_on_allocation_failure(void)
{
const char* strings[] = {"1", "2", "3"};
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_CreateStringArray(strings, 3));
cJSON_InitHooks(NULL);
}
static void cjson_add_false_should_add_false(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *false_item = NULL;
cJSON_AddFalseToObject(root, "false");
TEST_ASSERT_NOT_NULL(false_item = cJSON_GetObjectItemCaseSensitive(root, "false"));
TEST_ASSERT_EQUAL_INT(false_item->type, cJSON_False);
cJSON_Delete(root);
}
static void cjson_add_false_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddFalseToObject(NULL, "false"));
TEST_ASSERT_NULL(cJSON_AddFalseToObject(root, NULL));
cJSON_Delete(root);
}
static void cjson_add_false_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddFalseToObject(root, "false"));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cjson_add_bool_should_add_bool(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *true_item = NULL;
cJSON *false_item = NULL;
/* true */
cJSON_AddBoolToObject(root, "true", true);
TEST_ASSERT_NOT_NULL(true_item = cJSON_GetObjectItemCaseSensitive(root, "true"));
TEST_ASSERT_EQUAL_INT(true_item->type, cJSON_True);
/* false */
cJSON_AddBoolToObject(root, "false", false);
TEST_ASSERT_NOT_NULL(false_item = cJSON_GetObjectItemCaseSensitive(root, "false"));
TEST_ASSERT_EQUAL_INT(false_item->type, cJSON_False);
cJSON_Delete(root);
}
static void cjson_add_bool_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddBoolToObject(NULL, "false", false));
TEST_ASSERT_NULL(cJSON_AddBoolToObject(root, NULL, false));
cJSON_Delete(root);
}
static void cjson_add_bool_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddBoolToObject(root, "false", false));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cjson_add_number_should_add_number(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *number = NULL;
cJSON_AddNumberToObject(root, "number", 42);
TEST_ASSERT_NOT_NULL(number = cJSON_GetObjectItemCaseSensitive(root, "number"));
TEST_ASSERT_EQUAL_INT(number->type, cJSON_Number);
TEST_ASSERT_EQUAL_DOUBLE(number->valuedouble, 42);
TEST_ASSERT_EQUAL_INT(number->valueint, 42);
cJSON_Delete(root);
}
static void cjson_add_number_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddNumberToObject(NULL, "number", 42));
TEST_ASSERT_NULL(cJSON_AddNumberToObject(root, NULL, 42));
cJSON_Delete(root);
}
static void cjson_add_number_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddNumberToObject(root, "number", 42));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cjson_add_string_should_add_string(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *string = NULL;
cJSON_AddStringToObject(root, "string", "Hello World!");
TEST_ASSERT_NOT_NULL(string = cJSON_GetObjectItemCaseSensitive(root, "string"));
TEST_ASSERT_EQUAL_INT(string->type, cJSON_String);
TEST_ASSERT_EQUAL_STRING(string->valuestring, "Hello World!");
cJSON_Delete(root);
}
static void cjson_add_string_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddStringToObject(NULL, "string", "string"));
TEST_ASSERT_NULL(cJSON_AddStringToObject(root, NULL, "string"));
cJSON_Delete(root);
}
static void cjson_add_string_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddStringToObject(root, "string", "string"));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cjson_add_raw_should_add_raw(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *raw = NULL;
cJSON_AddRawToObject(root, "raw", "{}");
TEST_ASSERT_NOT_NULL(raw = cJSON_GetObjectItemCaseSensitive(root, "raw"));
TEST_ASSERT_EQUAL_INT(raw->type, cJSON_Raw);
TEST_ASSERT_EQUAL_STRING(raw->valuestring, "{}");
cJSON_Delete(root);
}
static void cjson_add_raw_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddRawToObject(NULL, "raw", "{}"));
TEST_ASSERT_NULL(cJSON_AddRawToObject(root, NULL, "{}"));
cJSON_Delete(root);
}
static void cjson_add_raw_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddRawToObject(root, "raw", "{}"));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cJSON_add_object_should_add_object(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *object = NULL;
cJSON_AddObjectToObject(root, "object");
TEST_ASSERT_NOT_NULL(object = cJSON_GetObjectItemCaseSensitive(root, "object"));
TEST_ASSERT_EQUAL_INT(object->type, cJSON_Object);
cJSON_Delete(root);
}
static void cjson_add_object_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddObjectToObject(NULL, "object"));
TEST_ASSERT_NULL(cJSON_AddObjectToObject(root, NULL));
cJSON_Delete(root);
}
static void cjson_add_object_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddObjectToObject(root, "object"));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
static void cJSON_add_array_should_add_array(void)
{
cJSON *root = cJSON_CreateObject();
cJSON *array = NULL;
cJSON_AddArrayToObject(root, "array");
TEST_ASSERT_NOT_NULL(array = cJSON_GetObjectItemCaseSensitive(root, "array"));
TEST_ASSERT_EQUAL_INT(array->type, cJSON_Array);
cJSON_Delete(root);
}
static void cjson_add_array_should_fail_with_null_pointers(void)
{
cJSON *root = cJSON_CreateObject();
TEST_ASSERT_NULL(cJSON_AddArrayToObject(NULL, "array"));
TEST_ASSERT_NULL(cJSON_AddArrayToObject(root, NULL));
cJSON_Delete(root);
}
static void cjson_add_array_should_fail_on_allocation_failure(void)
{
cJSON *root = cJSON_CreateObject();
cJSON_InitHooks(&failing_hooks);
TEST_ASSERT_NULL(cJSON_AddArrayToObject(root, "array"));
cJSON_InitHooks(NULL);
cJSON_Delete(root);
}
int CJSON_CDECL main(void)
{
UNITY_BEGIN();
RUN_TEST(cjson_add_null_should_add_null);
RUN_TEST(cjson_add_null_should_fail_with_null_pointers);
RUN_TEST(cjson_add_null_should_fail_on_allocation_failure);
RUN_TEST(cjson_add_true_should_add_true);
RUN_TEST(cjson_add_true_should_fail_with_null_pointers);
RUN_TEST(cjson_add_true_should_fail_on_allocation_failure);
RUN_TEST(cjson_create_int_array_should_fail_on_allocation_failure);
RUN_TEST(cjson_create_float_array_should_fail_on_allocation_failure);
RUN_TEST(cjson_create_double_array_should_fail_on_allocation_failure);
RUN_TEST(cjson_create_string_array_should_fail_on_allocation_failure);
RUN_TEST(cjson_add_false_should_add_false);
RUN_TEST(cjson_add_false_should_fail_with_null_pointers);
RUN_TEST(cjson_add_false_should_fail_on_allocation_failure);
RUN_TEST(cjson_add_bool_should_add_bool);
RUN_TEST(cjson_add_bool_should_fail_with_null_pointers);
RUN_TEST(cjson_add_bool_should_fail_on_allocation_failure);
RUN_TEST(cjson_add_number_should_add_number);
RUN_TEST(cjson_add_number_should_fail_with_null_pointers);
RUN_TEST(cjson_add_number_should_fail_on_allocation_failure);
RUN_TEST(cjson_add_string_should_add_string);
RUN_TEST(cjson_add_string_should_fail_with_null_pointers);
RUN_TEST(cjson_add_string_should_fail_on_allocation_failure);
RUN_TEST(cjson_add_raw_should_add_raw);
RUN_TEST(cjson_add_raw_should_fail_with_null_pointers);
RUN_TEST(cjson_add_raw_should_fail_on_allocation_failure);
RUN_TEST(cJSON_add_object_should_add_object);
RUN_TEST(cjson_add_object_should_fail_with_null_pointers);
RUN_TEST(cjson_add_object_should_fail_on_allocation_failure);
RUN_TEST(cJSON_add_array_should_add_array);
RUN_TEST(cjson_add_array_should_fail_with_null_pointers);
RUN_TEST(cjson_add_array_should_fail_on_allocation_failure);
return UNITY_END();
}

97
tests/common.c Normal file
View File

@@ -0,0 +1,97 @@
/*
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 "common.h"
CJSON_PUBLIC(void) reset(cJSON *item)
{
if ((item != NULL) && (item->child != NULL))
{
cJSON_Delete(item->child);
}
if ((item->valuestring != NULL) && !(item->type & cJSON_IsReference))
{
global_hooks.deallocate(item->valuestring);
}
if ((item->string != NULL) && !(item->type & cJSON_StringIsConst))
{
global_hooks.deallocate(item->string);
}
memset(item, 0, sizeof(cJSON));
}
CJSON_PUBLIC(char*) read_file(const char *filename)
{
FILE *file = NULL;
long length = 0;
char *content = NULL;
size_t read_chars = 0;
/* open in read binary mode */
file = fopen(filename, "rb");
if (file == NULL)
{
goto cleanup;
}
/* get the length */
if (fseek(file, 0, SEEK_END) != 0)
{
goto cleanup;
}
length = ftell(file);
if (length < 0)
{
goto cleanup;
}
if (fseek(file, 0, SEEK_SET) != 0)
{
goto cleanup;
}
/* allocate content buffer */
content = (char*)malloc((size_t)length + sizeof(""));
if (content == NULL)
{
goto cleanup;
}
/* read the file into memory */
read_chars = fread(content, sizeof(char), (size_t)length, file);
if ((long)read_chars != length)
{
free(content);
content = NULL;
goto cleanup;
}
content[read_chars] = '\0';
cleanup:
if (file != NULL)
{
fclose(file);
}
return content;
}

View File

@@ -25,79 +25,8 @@
#include "../cJSON.c" #include "../cJSON.c"
void reset(cJSON *item); CJSON_PUBLIC(void) reset(cJSON *item);
void reset(cJSON *item) { CJSON_PUBLIC(char*) read_file(const char *filename);
if ((item != NULL) && (item->child != NULL))
{
cJSON_Delete(item->child);
}
if ((item->valuestring != NULL) && !(item->type & cJSON_IsReference))
{
global_hooks.deallocate(item->valuestring);
}
if ((item->string != NULL) && !(item->type & cJSON_StringIsConst))
{
global_hooks.deallocate(item->string);
}
memset(item, 0, sizeof(cJSON));
}
char* read_file(const char *filename);
char* read_file(const char *filename) {
FILE *file = NULL;
long length = 0;
char *content = NULL;
size_t read_chars = 0;
/* open in read binary mode */
file = fopen(filename, "rb");
if (file == NULL)
{
goto cleanup;
}
/* get the length */
if (fseek(file, 0, SEEK_END) != 0)
{
goto cleanup;
}
length = ftell(file);
if (length < 0)
{
goto cleanup;
}
if (fseek(file, 0, SEEK_SET) != 0)
{
goto cleanup;
}
/* allocate content buffer */
content = (char*)malloc((size_t)length + sizeof(""));
if (content == NULL)
{
goto cleanup;
}
/* read the file into memory */
read_chars = fread(content, sizeof(char), (size_t)length, file);
if ((long)read_chars != length)
{
free(content);
content = NULL;
goto cleanup;
}
content[read_chars] = '\0';
cleanup:
if (file != NULL)
{
fclose(file);
}
return content;
}
/* assertion helper macros */ /* assertion helper macros */
#define assert_has_type(item, item_type) TEST_ASSERT_BITS_MESSAGE(0xFF, item_type, item->type, "Item doesn't have expected type.") #define assert_has_type(item, item_type) TEST_ASSERT_BITS_MESSAGE(0xFF, item_type, item->type, "Item doesn't have expected type.")

View File

@@ -64,9 +64,6 @@ static void cjson_compare_should_compare_numbers(void)
TEST_ASSERT_TRUE(compare_from_string("1", "1", false)); TEST_ASSERT_TRUE(compare_from_string("1", "1", false));
TEST_ASSERT_TRUE(compare_from_string("0.0001", "0.0001", true)); TEST_ASSERT_TRUE(compare_from_string("0.0001", "0.0001", true));
TEST_ASSERT_TRUE(compare_from_string("0.0001", "0.0001", false)); TEST_ASSERT_TRUE(compare_from_string("0.0001", "0.0001", false));
TEST_ASSERT_TRUE(compare_from_string("1E100", "10E99", false));
TEST_ASSERT_FALSE(compare_from_string("0.5E-100", "0.5E-101", false));
TEST_ASSERT_FALSE(compare_from_string("1", "2", true)); TEST_ASSERT_FALSE(compare_from_string("1", "2", true));
TEST_ASSERT_FALSE(compare_from_string("1", "2", false)); TEST_ASSERT_FALSE(compare_from_string("1", "2", false));
@@ -151,10 +148,6 @@ 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\", [], {}]", true));
TEST_ASSERT_FALSE(compare_from_string("[true,null,42,\"string\",[],{}]", "[false, true, null, 42, \"string\", [], {}]", false)); 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) static void cjson_compare_should_compare_objects(void)
@@ -178,18 +171,9 @@ static void cjson_compare_should_compare_objects(void)
"{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}", "{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
"{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}", "{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
false)); 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 CJSON_CDECL main(void) int main(void)
{ {
UNITY_BEGIN(); UNITY_BEGIN();

View File

@@ -1,8 +1,8 @@
{ {
"name": "Jack (\"Bee\") Nimble", "name": "Jack (\"Bee\") Nimble",
"format": {"type": "rect", "format": {"type": "rect",
"width": 1920, "width": 1920,
"height": 1080, "height": 1080,
"interlace": false,"frame rate": 24 "interlace": false,"frame rate": 24
} }
} }

View File

@@ -6,7 +6,7 @@
"width": 500, "width": 500,
"height": 500 "height": 500
}, },
"image": { "image": {
"src": "Images/Sun.png", "src": "Images/Sun.png",
"name": "sun1", "name": "sun1",
"hOffset": 250, "hOffset": 250,
@@ -23,4 +23,4 @@
"alignment": "center", "alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
} }
}} }}

View File

@@ -1,5 +1,5 @@
{"web-app": { {"web-app": {
"servlet": [ "servlet": [
{ {
"servlet-name": "cofaxCDS", "servlet-name": "cofaxCDS",
"servlet-class": "org.cofax.cds.CDSServlet", "servlet-class": "org.cofax.cds.CDSServlet",
@@ -55,7 +55,7 @@
{ {
"servlet-name": "cofaxAdmin", "servlet-name": "cofaxAdmin",
"servlet-class": "org.cofax.cds.AdminServlet"}, "servlet-class": "org.cofax.cds.AdminServlet"},
{ {
"servlet-name": "fileServlet", "servlet-name": "fileServlet",
"servlet-class": "org.cofax.cds.FileServlet"}, "servlet-class": "org.cofax.cds.FileServlet"},
@@ -82,7 +82,7 @@
"cofaxAdmin": "/admin/*", "cofaxAdmin": "/admin/*",
"fileServlet": "/static/*", "fileServlet": "/static/*",
"cofaxTools": "/tools/*"}, "cofaxTools": "/tools/*"},
"taglib": { "taglib": {
"taglib-uri": "cofax.tld", "taglib-uri": "cofax.tld",
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}} "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}

View File

@@ -80,12 +80,5 @@
"doc": { "foo": ["bar"] }, "doc": { "foo": ["bar"] },
"patch": [ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] }], "patch": [ { "op": "add", "path": "/foo/-", "value": ["abc", "def"] }],
"expected": {"foo": ["bar", ["abc", "def"]] } "expected": {"foo": ["bar", ["abc", "def"]] }
}, }
{
"comment": "15",
"doc": {"foo": {"bar": 1}},
"patch": [{"op": "add", "path": "/foo/bar/baz", "value": "5"}],
"error": "attempting to add to subfield of non-object"
}
] ]

View File

@@ -202,11 +202,6 @@
"patch": [{"op": "replace", "path": "", "value": {"baz": "qux"}}], "patch": [{"op": "replace", "path": "", "value": {"baz": "qux"}}],
"expected": {"baz": "qux"} }, "expected": {"baz": "qux"} },
{ "comment": "test replace with missing parent key should fail",
"doc": {"bar": "baz"},
"patch": [{"op": "replace", "path": "/foo/bar", "value": false}],
"error": "replace op should fail with missing parent key" },
{ "comment": "spurious patch properties", { "comment": "spurious patch properties",
"doc": {"foo": 1}, "doc": {"foo": 1},
"patch": [{"op": "test", "path": "/foo", "value": 1, "spurious": 1}], "patch": [{"op": "test", "path": "/foo", "value": 1, "spurious": 1}],
@@ -214,7 +209,6 @@
{ "doc": {"foo": null}, { "doc": {"foo": null},
"patch": [{"op": "test", "path": "/foo", "value": null}], "patch": [{"op": "test", "path": "/foo", "value": null}],
"expected": {"foo": null},
"comment": "null value should be valid obj property" }, "comment": "null value should be valid obj property" },
{ "doc": {"foo": null}, { "doc": {"foo": null},
@@ -244,17 +238,14 @@
{ "doc": {"foo": {"foo": 1, "bar": 2}}, { "doc": {"foo": {"foo": 1, "bar": 2}},
"patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}], "patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}],
"expected": {"foo": {"foo": 1, "bar": 2}},
"comment": "test should pass despite rearrangement" }, "comment": "test should pass despite rearrangement" },
{ "doc": {"foo": [{"foo": 1, "bar": 2}]}, { "doc": {"foo": [{"foo": 1, "bar": 2}]},
"patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}], "patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}],
"expected": {"foo": [{"foo": 1, "bar": 2}]},
"comment": "test should pass despite (nested) rearrangement" }, "comment": "test should pass despite (nested) rearrangement" },
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}}, { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
"patch": [{"op": "test", "path": "/foo", "value": {"bar": [1, 2, 5, 4]}}], "patch": [{"op": "test", "path": "/foo", "value": {"bar": [1, 2, 5, 4]}}],
"expected": {"foo": {"bar": [1, 2, 5, 4]}},
"comment": "test should pass - no error" }, "comment": "test should pass - no error" },
{ "doc": {"foo": {"bar": [1, 2, 5, 4]}}, { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
@@ -268,8 +259,7 @@
{ "comment": "Empty-string element", { "comment": "Empty-string element",
"doc": { "": 1 }, "doc": { "": 1 },
"patch": [{"op": "test", "path": "/", "value": 1}], "patch": [{"op": "test", "path": "/", "value": 1}] },
"expected": { "": 1 } },
{ "doc": { { "doc": {
"foo": ["bar", "baz"], "foo": ["bar", "baz"],
@@ -293,23 +283,8 @@
{"op": "test", "path": "/i\\j", "value": 5}, {"op": "test", "path": "/i\\j", "value": 5},
{"op": "test", "path": "/k\"l", "value": 6}, {"op": "test", "path": "/k\"l", "value": 6},
{"op": "test", "path": "/ ", "value": 7}, {"op": "test", "path": "/ ", "value": 7},
{"op": "test", "path": "/m~0n", "value": 8}], {"op": "test", "path": "/m~0n", "value": 8}] },
"expected": {
"": 0,
" ": 7,
"a/b": 1,
"c%d": 2,
"e^f": 3,
"foo": [
"bar",
"baz"
],
"g|h": 4,
"i\\j": 5,
"k\"l": 6,
"m~n": 8
}
},
{ "comment": "Move to same location has no effect", { "comment": "Move to same location has no effect",
"doc": {"foo": 1}, "doc": {"foo": 1},
"patch": [{"op": "move", "from": "/foo", "path": "/foo"}], "patch": [{"op": "move", "from": "/foo", "path": "/foo"}],
@@ -408,21 +383,11 @@
"patch": [ { "op": "copy", "path": "/-" } ], "patch": [ { "op": "copy", "path": "/-" } ],
"error": "missing 'from' parameter" }, "error": "missing 'from' parameter" },
{ "comment": "missing from location to copy",
"doc": { "foo": 1 },
"patch": [ { "op": "copy", "from": "/bar", "path": "/foo" } ],
"error": "missing 'from' location" },
{ "comment": "missing from parameter to move", { "comment": "missing from parameter to move",
"doc": { "foo": 1 }, "doc": { "foo": 1 },
"patch": [ { "op": "move", "path": "" } ], "patch": [ { "op": "move", "path": "" } ],
"error": "missing 'from' parameter" }, "error": "missing 'from' parameter" },
{ "comment": "missing from location to move",
"doc": { "foo": 1 },
"patch": [ { "op": "move", "from": "/bar", "path": "/foo" } ],
"error": "missing 'from' location" },
{ "comment": "duplicate ops", { "comment": "duplicate ops",
"doc": { "foo": "bar" }, "doc": { "foo": "bar" },
"patch": [ { "op": "add", "path": "/baz", "value": "qux", "patch": [ { "op": "add", "path": "/baz", "value": "qux",

View File

@@ -66,7 +66,7 @@ static cJSON_bool test_apply_patch(const cJSON * const test)
} }
else else
{ {
printf("Testing unknown\n"); printf("Testing unkown\n");
} }
disabled = cJSON_GetObjectItemCaseSensitive(test, "disabled"); disabled = cJSON_GetObjectItemCaseSensitive(test, "disabled");

View File

@@ -1,174 +0,0 @@
/*
Copyright (c) 2009-2019 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"
static void cjson_minify_should_not_overflow_buffer(void)
{
char unclosed_multiline_comment[] = "/* bla";
char pending_escape[] = "\"\\";
cJSON_Minify(unclosed_multiline_comment);
TEST_ASSERT_EQUAL_STRING("", unclosed_multiline_comment);
cJSON_Minify(pending_escape);
TEST_ASSERT_EQUAL_STRING("\"\\", pending_escape);
}
static void cjson_minify_should_remove_single_line_comments(void)
{
const char to_minify[] = "{// this is {} \"some kind\" of [] comment /*, don't you see\n}";
char* minified = (char*) malloc(sizeof(to_minify));
TEST_ASSERT_NOT_NULL(minified);
strcpy(minified, to_minify);
cJSON_Minify(minified);
TEST_ASSERT_EQUAL_STRING("{}", minified);
free(minified);
}
static void cjson_minify_should_remove_spaces(void)
{
const char to_minify[] = "{ \"key\":\ttrue\r\n }";
char* minified = (char*) malloc(sizeof(to_minify));
TEST_ASSERT_NOT_NULL(minified);
strcpy(minified, to_minify);
cJSON_Minify(minified);
TEST_ASSERT_EQUAL_STRING("{\"key\":true}", minified);
free(minified);
}
static void cjson_minify_should_remove_multiline_comments(void)
{
const char to_minify[] = "{/* this is\n a /* multi\n //line \n {comment \"\\\" */}";
char* minified = (char*) malloc(sizeof(to_minify));
TEST_ASSERT_NOT_NULL(minified);
strcpy(minified, to_minify);
cJSON_Minify(minified);
TEST_ASSERT_EQUAL_STRING("{}", minified);
free(minified);
}
static void cjson_minify_should_not_modify_strings(void)
{
const char to_minify[] = "\"this is a string \\\" \\t bla\"";
char* minified = (char*) malloc(sizeof(to_minify));
TEST_ASSERT_NOT_NULL(minified);
strcpy(minified, to_minify);
cJSON_Minify(minified);
TEST_ASSERT_EQUAL_STRING(to_minify, minified);
free(minified);
}
static void cjson_minify_should_minify_json(void) {
const char to_minify[] =
"{\n"
" \"glossary\": { // comment\n"
" \"title\": \"example glossary\",\n"
" /* multi\n"
" line */\n"
" \"GlossDiv\": {\n"
" \"title\": \"S\",\n"
" \"GlossList\": {\n"
" \"GlossEntry\": {\n"
" \"ID\": \"SGML\",\n"
" \"SortAs\": \"SGML\",\n"
" \"Acronym\": \"SGML\",\n"
" \"Abbrev\": \"ISO 8879:1986\",\n"
" \"GlossDef\": {\n"
" \"GlossSeeAlso\": [\"GML\", \"XML\"]\n"
" },\n"
" \"GlossSee\": \"markup\"\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}";
const char* minified =
"{"
"\"glossary\":{"
"\"title\":\"example glossary\","
"\"GlossDiv\":{"
"\"title\":\"S\","
"\"GlossList\":{"
"\"GlossEntry\":{"
"\"ID\":\"SGML\","
"\"SortAs\":\"SGML\","
"\"Acronym\":\"SGML\","
"\"Abbrev\":\"ISO 8879:1986\","
"\"GlossDef\":{"
"\"GlossSeeAlso\":[\"GML\",\"XML\"]"
"},"
"\"GlossSee\":\"markup\""
"}"
"}"
"}"
"}"
"}";
char *buffer = (char*) malloc(sizeof(to_minify));
strcpy(buffer, to_minify);
cJSON_Minify(buffer);
TEST_ASSERT_EQUAL_STRING(minified, buffer);
free(buffer);
}
static void cjson_minify_should_not_loop_infinitely(void) {
char string[] = { '8', ' ', '/', ' ', '5', '\n', '\0' };
/* this should not be an infinite loop */
cJSON_Minify(string);
}
int CJSON_CDECL main(void)
{
UNITY_BEGIN();
RUN_TEST(cjson_minify_should_not_overflow_buffer);
RUN_TEST(cjson_minify_should_minify_json);
RUN_TEST(cjson_minify_should_remove_single_line_comments);
RUN_TEST(cjson_minify_should_remove_multiline_comments);
RUN_TEST(cjson_minify_should_remove_spaces);
RUN_TEST(cjson_minify_should_not_modify_strings);
RUN_TEST(cjson_minify_should_not_loop_infinitely);
return UNITY_END();
}

View File

@@ -127,28 +127,6 @@ static void cjson_get_object_item_case_sensitive_should_get_object_items(void)
cJSON_Delete(item); cJSON_Delete(item);
} }
static void cjson_get_object_item_should_not_crash_with_array(void) {
cJSON *array = NULL;
cJSON *found = NULL;
array = cJSON_Parse("[1]");
found = cJSON_GetObjectItem(array, "name");
TEST_ASSERT_NULL(found);
cJSON_Delete(array);
}
static void cjson_get_object_item_case_sensitive_should_not_crash_with_array(void) {
cJSON *array = NULL;
cJSON *found = NULL;
array = cJSON_Parse("[1]");
found = cJSON_GetObjectItemCaseSensitive(array, "name");
TEST_ASSERT_NULL(found);
cJSON_Delete(array);
}
static void typecheck_functions_should_check_type(void) static void typecheck_functions_should_check_type(void)
{ {
cJSON invalid[1]; cJSON invalid[1];
@@ -255,7 +233,6 @@ static void cjson_detach_item_via_pointer_should_detach_items(void)
list[3].prev = &(list[2]); list[3].prev = &(list[2]);
list[2].prev = &(list[1]); list[2].prev = &(list[1]);
list[1].prev = &(list[0]); list[1].prev = &(list[0]);
list[0].prev = &(list[3]);
parent->child = &list[0]; parent->child = &list[0];
@@ -267,7 +244,7 @@ static void cjson_detach_item_via_pointer_should_detach_items(void)
/* detach beginning (list[0]) */ /* detach beginning (list[0]) */
TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[0])) == &(list[0]), "Failed to detach beginning."); TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[0])) == &(list[0]), "Failed to detach beginning.");
TEST_ASSERT_TRUE_MESSAGE((list[0].prev == NULL) && (list[0].next == NULL), "Didn't set pointers of detached item to NULL."); TEST_ASSERT_TRUE_MESSAGE((list[0].prev == NULL) && (list[0].next == NULL), "Didn't set pointers of detached item to NULL.");
TEST_ASSERT_TRUE_MESSAGE((list[2].prev == &(list[3])) && (parent->child == &(list[2])), "Didn't set the new beginning."); TEST_ASSERT_TRUE_MESSAGE((list[2].prev == NULL) && (parent->child == &(list[2])), "Didn't set the new beginning.");
/* detach end (list[3])*/ /* detach end (list[3])*/
TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[3])) == &(list[3]), "Failed to detach end."); TEST_ASSERT_TRUE_MESSAGE(cJSON_DetachItemViaPointer(parent, &(list[3])) == &(list[3]), "Failed to detach end.");
@@ -307,7 +284,7 @@ static void cjson_replace_item_via_pointer_should_replace_items(void)
/* replace beginning */ /* replace beginning */
TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, beginning, &(replacements[0]))); TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, beginning, &(replacements[0])));
TEST_ASSERT_TRUE(replacements[0].prev == end); TEST_ASSERT_NULL(replacements[0].prev);
TEST_ASSERT_TRUE(replacements[0].next == middle); TEST_ASSERT_TRUE(replacements[0].next == middle);
TEST_ASSERT_TRUE(middle->prev == &(replacements[0])); TEST_ASSERT_TRUE(middle->prev == &(replacements[0]));
TEST_ASSERT_TRUE(array->child == &(replacements[0])); TEST_ASSERT_TRUE(array->child == &(replacements[0]));
@@ -332,15 +309,13 @@ static void cjson_replace_item_in_object_should_preserve_name(void)
cJSON root[1] = {{ NULL, NULL, NULL, 0, NULL, 0, 0, NULL }}; cJSON root[1] = {{ NULL, NULL, NULL, 0, NULL, 0, 0, NULL }};
cJSON *child = NULL; cJSON *child = NULL;
cJSON *replacement = NULL; cJSON *replacement = NULL;
cJSON_bool flag = false;
child = cJSON_CreateNumber(1); child = cJSON_CreateNumber(1);
TEST_ASSERT_NOT_NULL(child); TEST_ASSERT_NOT_NULL(child);
replacement = cJSON_CreateNumber(2); replacement = cJSON_CreateNumber(2);
TEST_ASSERT_NOT_NULL(replacement); TEST_ASSERT_NOT_NULL(replacement);
flag = cJSON_AddItemToObject(root, "child", child); cJSON_AddItemToObject(root, "child", child);
TEST_ASSERT_TRUE_MESSAGE(flag, "add item to object failed");
cJSON_ReplaceItemInObject(root, "child", replacement); cJSON_ReplaceItemInObject(root, "child", replacement);
TEST_ASSERT_TRUE(root->child == replacement); TEST_ASSERT_TRUE(root->child == replacement);
@@ -349,308 +324,7 @@ static void cjson_replace_item_in_object_should_preserve_name(void)
cJSON_Delete(replacement); cJSON_Delete(replacement);
} }
static void cjson_functions_should_not_crash_with_null_pointers(void) int main(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);
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(NULL, 0, item));
TEST_ASSERT_FALSE(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));
TEST_ASSERT_FALSE(cJSON_ReplaceItemInArray(item, 0, NULL));
TEST_ASSERT_FALSE(cJSON_ReplaceItemInArray(NULL, 0, item));
TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(NULL, "item", item));
TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(item, NULL, item));
TEST_ASSERT_FALSE(cJSON_ReplaceItemInObject(item, "item", NULL));
TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(NULL, "item", item));
TEST_ASSERT_FALSE(cJSON_ReplaceItemInObjectCaseSensitive(item, NULL, item));
TEST_ASSERT_FALSE(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 * CJSON_CDECL 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));
}
static void cjson_get_string_value_should_get_a_string(void)
{
cJSON *string = cJSON_CreateString("test");
cJSON *number = cJSON_CreateNumber(1);
TEST_ASSERT_TRUE(cJSON_GetStringValue(string) == string->valuestring);
TEST_ASSERT_NULL(cJSON_GetStringValue(number));
TEST_ASSERT_NULL(cJSON_GetStringValue(NULL));
cJSON_Delete(number);
cJSON_Delete(string);
}
static void cjson_get_number_value_should_get_a_number(void)
{
cJSON *string = cJSON_CreateString("test");
cJSON *number = cJSON_CreateNumber(1);
TEST_ASSERT_EQUAL_DOUBLE(cJSON_GetNumberValue(number), number->valuedouble);
TEST_ASSERT_DOUBLE_IS_NAN(cJSON_GetNumberValue(string));
TEST_ASSERT_DOUBLE_IS_NAN(cJSON_GetNumberValue(NULL));
cJSON_Delete(number);
cJSON_Delete(string);
}
static void cjson_create_string_reference_should_create_a_string_reference(void) {
const char *string = "I am a string!";
cJSON *string_reference = cJSON_CreateStringReference(string);
TEST_ASSERT_TRUE(string_reference->valuestring == string);
TEST_ASSERT_EQUAL_INT(cJSON_IsReference | cJSON_String, string_reference->type);
cJSON_Delete(string_reference);
}
static void cjson_create_object_reference_should_create_an_object_reference(void) {
cJSON *number_reference = NULL;
cJSON *number_object = cJSON_CreateObject();
cJSON *number = cJSON_CreateNumber(42);
const char key[] = "number";
TEST_ASSERT_TRUE(cJSON_IsNumber(number));
TEST_ASSERT_TRUE(cJSON_IsObject(number_object));
cJSON_AddItemToObjectCS(number_object, key, number);
number_reference = cJSON_CreateObjectReference(number);
TEST_ASSERT_TRUE(number_reference->child == number);
TEST_ASSERT_EQUAL_INT(cJSON_Object | cJSON_IsReference, number_reference->type);
cJSON_Delete(number_object);
cJSON_Delete(number_reference);
}
static void cjson_create_array_reference_should_create_an_array_reference(void) {
cJSON *number_reference = NULL;
cJSON *number_array = cJSON_CreateArray();
cJSON *number = cJSON_CreateNumber(42);
TEST_ASSERT_TRUE(cJSON_IsNumber(number));
TEST_ASSERT_TRUE(cJSON_IsArray(number_array));
cJSON_AddItemToArray(number_array, number);
number_reference = cJSON_CreateArrayReference(number);
TEST_ASSERT_TRUE(number_reference->child == number);
TEST_ASSERT_EQUAL_INT(cJSON_Array | cJSON_IsReference, number_reference->type);
cJSON_Delete(number_array);
cJSON_Delete(number_reference);
}
static void cjson_add_item_to_object_or_array_should_not_add_itself(void)
{
cJSON *object = cJSON_CreateObject();
cJSON *array = cJSON_CreateArray();
cJSON_bool flag = false;
flag = cJSON_AddItemToObject(object, "key", object);
TEST_ASSERT_FALSE_MESSAGE(flag, "add an object to itself should fail");
flag = cJSON_AddItemToArray(array, array);
TEST_ASSERT_FALSE_MESSAGE(flag, "add an array to itself should fail");
cJSON_Delete(object);
cJSON_Delete(array);
}
static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased(void)
{
cJSON *object = cJSON_CreateObject();
cJSON *number = cJSON_CreateNumber(42);
char *name = (char*)cJSON_strdup((const unsigned char*)"number", &global_hooks);
TEST_ASSERT_NOT_NULL(object);
TEST_ASSERT_NOT_NULL(number);
TEST_ASSERT_NOT_NULL(name);
number->string = name;
/* The following should not have a use after free
* that would show up in valgrind or with AddressSanitizer */
cJSON_AddItemToObject(object, number->string, number);
cJSON_Delete(object);
}
static void cjson_delete_item_from_array_should_not_broken_list_structure(void)
{
const char expected_json1[] = "{\"rd\":[{\"a\":\"123\"}]}";
const char expected_json2[] = "{\"rd\":[{\"a\":\"123\"},{\"b\":\"456\"}]}";
const char expected_json3[] = "{\"rd\":[{\"b\":\"456\"}]}";
char *str1 = NULL;
char *str2 = NULL;
char *str3 = NULL;
cJSON *root = cJSON_Parse("{}");
cJSON *array = cJSON_AddArrayToObject(root, "rd");
cJSON *item1 = cJSON_Parse("{\"a\":\"123\"}");
cJSON *item2 = cJSON_Parse("{\"b\":\"456\"}");
cJSON_AddItemToArray(array, item1);
str1 = cJSON_PrintUnformatted(root);
TEST_ASSERT_EQUAL_STRING(expected_json1, str1);
free(str1);
cJSON_AddItemToArray(array, item2);
str2 = cJSON_PrintUnformatted(root);
TEST_ASSERT_EQUAL_STRING(expected_json2, str2);
free(str2);
/* this should not broken list structure */
cJSON_DeleteItemFromArray(array, 0);
str3 = cJSON_PrintUnformatted(root);
TEST_ASSERT_EQUAL_STRING(expected_json3, str3);
free(str3);
cJSON_Delete(root);
}
static void cjson_set_valuestring_to_object_should_not_leak_memory(void)
{
cJSON *root = cJSON_Parse("{}");
const char *stringvalue = "valuestring could be changed safely";
const char *reference_valuestring = "reference item should be freed by yourself";
const char *short_valuestring = "shorter valuestring";
const char *long_valuestring = "new valuestring which much longer than previous should be changed safely";
cJSON *item1 = cJSON_CreateString(stringvalue);
cJSON *item2 = cJSON_CreateStringReference(reference_valuestring);
char *ptr1 = NULL;
char *return_value = NULL;
cJSON_AddItemToObject(root, "one", item1);
cJSON_AddItemToObject(root, "two", item2);
ptr1 = item1->valuestring;
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "one"), short_valuestring);
TEST_ASSERT_NOT_NULL(return_value);
TEST_ASSERT_EQUAL_PTR_MESSAGE(ptr1, return_value, "new valuestring shorter than old should not reallocate memory");
TEST_ASSERT_EQUAL_STRING(short_valuestring, cJSON_GetObjectItem(root, "one")->valuestring);
/* we needn't to free the original valuestring manually */
ptr1 = item1->valuestring;
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "one"), long_valuestring);
TEST_ASSERT_NOT_NULL(return_value);
TEST_ASSERT_NOT_EQUAL_MESSAGE(ptr1, return_value, "new valuestring longer than old should reallocate memory")
TEST_ASSERT_EQUAL_STRING(long_valuestring, cJSON_GetObjectItem(root, "one")->valuestring);
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "two"), long_valuestring);
TEST_ASSERT_NULL_MESSAGE(return_value, "valuestring of reference object should not be changed");
TEST_ASSERT_EQUAL_STRING(reference_valuestring, cJSON_GetObjectItem(root, "two")->valuestring);
cJSON_Delete(root);
}
int CJSON_CDECL main(void)
{ {
UNITY_BEGIN(); UNITY_BEGIN();
@@ -658,27 +332,12 @@ int CJSON_CDECL main(void)
RUN_TEST(cjson_array_foreach_should_not_dereference_null_pointer); RUN_TEST(cjson_array_foreach_should_not_dereference_null_pointer);
RUN_TEST(cjson_get_object_item_should_get_object_items); RUN_TEST(cjson_get_object_item_should_get_object_items);
RUN_TEST(cjson_get_object_item_case_sensitive_should_get_object_items); RUN_TEST(cjson_get_object_item_case_sensitive_should_get_object_items);
RUN_TEST(cjson_get_object_item_should_not_crash_with_array);
RUN_TEST(cjson_get_object_item_case_sensitive_should_not_crash_with_array);
RUN_TEST(typecheck_functions_should_check_type); RUN_TEST(typecheck_functions_should_check_type);
RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons); RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
RUN_TEST(cjson_set_number_value_should_set_numbers); RUN_TEST(cjson_set_number_value_should_set_numbers);
RUN_TEST(cjson_detach_item_via_pointer_should_detach_items); 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_via_pointer_should_replace_items);
RUN_TEST(cjson_replace_item_in_object_should_preserve_name); RUN_TEST(cjson_replace_item_in_object_should_preserve_name);
RUN_TEST(cjson_functions_should_not_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);
RUN_TEST(cjson_get_string_value_should_get_a_string);
RUN_TEST(cjson_get_number_value_should_get_a_number);
RUN_TEST(cjson_create_string_reference_should_create_a_string_reference);
RUN_TEST(cjson_create_object_reference_should_create_an_object_reference);
RUN_TEST(cjson_create_array_reference_should_create_an_array_reference);
RUN_TEST(cjson_add_item_to_object_or_array_should_not_add_itself);
RUN_TEST(cjson_add_item_to_object_should_not_use_after_free_when_string_is_aliased);
RUN_TEST(cjson_delete_item_from_array_should_not_broken_list_structure);
RUN_TEST(cjson_set_valuestring_to_object_should_not_leak_memory);
return UNITY_END(); return UNITY_END();
} }

View File

@@ -1,80 +0,0 @@
/*
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

@@ -90,10 +90,6 @@ static void misc_tests(void)
/* Misc tests */ /* Misc tests */
int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
cJSON *object = NULL; cJSON *object = NULL;
cJSON *object1 = NULL;
cJSON *object2 = NULL;
cJSON *object3 = NULL;
cJSON *object4 = NULL;
cJSON *nums = NULL; cJSON *nums = NULL;
cJSON *num6 = NULL; cJSON *num6 = NULL;
char *pointer = NULL; char *pointer = NULL;
@@ -116,23 +112,7 @@ static void misc_tests(void)
TEST_ASSERT_EQUAL_STRING("", pointer); TEST_ASSERT_EQUAL_STRING("", pointer);
free(pointer); free(pointer);
object1 = cJSON_CreateObject();
object2 = cJSON_CreateString("m~n");
cJSON_AddItemToObject(object1, "m~n", object2);
pointer = cJSONUtils_FindPointerFromObjectTo(object1, object2);
TEST_ASSERT_EQUAL_STRING("/m~0n",pointer);
free(pointer);
object3 = cJSON_CreateObject();
object4 = cJSON_CreateString("m/n");
cJSON_AddItemToObject(object3, "m/n", object4);
pointer = cJSONUtils_FindPointerFromObjectTo(object3, object4);
TEST_ASSERT_EQUAL_STRING("/m~1n",pointer);
free(pointer);
cJSON_Delete(object); cJSON_Delete(object);
cJSON_Delete(object1);
cJSON_Delete(object3);
} }
static void sort_tests(void) static void sort_tests(void)

View File

@@ -90,8 +90,7 @@ static void parse_array_should_parse_arrays_with_one_element(void)
assert_parse_array("[[]]"); assert_parse_array("[[]]");
assert_has_child(item); assert_has_child(item);
TEST_ASSERT_NOT_NULL(item->child); assert_is_array(item->child);
assert_has_type(item->child, cJSON_Array);
assert_has_no_child(item->child); assert_has_no_child(item->child);
reset(item); reset(item);
@@ -153,7 +152,7 @@ static void parse_array_should_not_parse_non_arrays(void)
assert_not_array("\"[]hello world!\n\""); assert_not_array("\"[]hello world!\n\"");
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
memset(item, 0, sizeof(cJSON)); memset(item, 0, sizeof(cJSON));

View File

@@ -142,7 +142,7 @@ static void file_test6_should_not_be_parsed(void)
tree = cJSON_Parse(test6); tree = cJSON_Parse(test6);
TEST_ASSERT_NULL_MESSAGE(tree, "Should fail to parse what is not JSON."); TEST_ASSERT_NULL_MESSAGE(tree, "Should fail to parse what is not JSON.");
TEST_ASSERT_EQUAL_PTR_MESSAGE(test6, cJSON_GetErrorPtr(), "Error pointer is incorrect."); TEST_ASSERT_EQUAL_STRING_MESSAGE(test6, cJSON_GetErrorPtr(), "Error pointer is incorrect.");
if (test6 != NULL) if (test6 != NULL)
{ {
@@ -179,78 +179,7 @@ static void file_test11_should_be_parsed_and_printed(void)
do_test("test11"); do_test("test11");
} }
static void test12_should_not_be_parsed(void) int main(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);
}
}
static void test13_should_be_parsed_without_null_termination(void)
{
cJSON *tree = NULL;
const char test_13[] = "{" \
"\"Image\":{" \
"\"Width\":800," \
"\"Height\":600," \
"\"Title\":\"Viewfrom15thFloor\"," \
"\"Thumbnail\":{" \
"\"Url\":\"http:/*www.example.com/image/481989943\"," \
"\"Height\":125," \
"\"Width\":\"100\"" \
"}," \
"\"IDs\":[116,943,234,38793]" \
"}" \
"}";
char test_13_wo_null[sizeof(test_13) - 1];
memcpy(test_13_wo_null, test_13, sizeof(test_13) - 1);
tree = cJSON_ParseWithLength(test_13_wo_null, sizeof(test_13) - 1);
TEST_ASSERT_NOT_NULL_MESSAGE(tree, "Failed to parse valid json.");
if (tree != NULL)
{
cJSON_Delete(tree);
}
}
static void test14_should_not_be_parsed(void)
{
cJSON *tree = NULL;
const char test_14[] = "{" \
"\"Image\":{" \
"\"Width\":800," \
"\"Height\":600," \
"\"Title\":\"Viewfrom15thFloor\"," \
"\"Thumbnail\":{" \
"\"Url\":\"http:/*www.example.com/image/481989943\"," \
"\"Height\":125," \
"\"Width\":\"100\"" \
"}," \
"\"IDs\":[116,943,234,38793]" \
"}" \
"}";
tree = cJSON_ParseWithLength(test_14, sizeof(test_14) - 2);
TEST_ASSERT_NULL_MESSAGE(tree, "Should not continue after buffer_length is reached.");
if (tree != NULL)
{
cJSON_Delete(tree);
}
}
int CJSON_CDECL main(void)
{ {
UNITY_BEGIN(); UNITY_BEGIN();
RUN_TEST(file_test1_should_be_parsed_and_printed); RUN_TEST(file_test1_should_be_parsed_and_printed);
@@ -264,8 +193,5 @@ int CJSON_CDECL main(void)
RUN_TEST(file_test9_should_be_parsed_and_printed); RUN_TEST(file_test9_should_be_parsed_and_printed);
RUN_TEST(file_test10_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(file_test11_should_be_parsed_and_printed);
RUN_TEST(test12_should_not_be_parsed);
RUN_TEST(test13_should_be_parsed_without_null_termination);
RUN_TEST(test14_should_not_be_parsed);
return UNITY_END(); return UNITY_END();
} }

View File

@@ -64,7 +64,7 @@ static void parse_hex4_should_parse_mixed_case(void)
TEST_ASSERT_EQUAL_INT(0xBEEF, parse_hex4((const unsigned char*)"BEEF")); TEST_ASSERT_EQUAL_INT(0xBEEF, parse_hex4((const unsigned char*)"BEEF"));
} }
int CJSON_CDECL main(void) int main(void)
{ {
UNITY_BEGIN(); UNITY_BEGIN();
RUN_TEST(parse_hex4_should_parse_all_combinations); RUN_TEST(parse_hex4_should_parse_all_combinations);

View File

@@ -96,7 +96,7 @@ static void parse_number_should_parse_negative_reals(void)
assert_parse_number("-123e-128", 0, -123e-128); assert_parse_number("-123e-128", 0, -123e-128);
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
memset(item, 0, sizeof(cJSON)); memset(item, 0, sizeof(cJSON));

View File

@@ -162,7 +162,7 @@ static void parse_object_should_not_parse_non_objects(void)
assert_not_object("\"{}hello world!\n\""); assert_not_object("\"{}hello world!\n\"");
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
memset(item, 0, sizeof(cJSON)); memset(item, 0, sizeof(cJSON));

View File

@@ -119,7 +119,7 @@ static void parse_string_should_parse_bug_94(void)
reset(item); reset(item);
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item and error pointer */ /* initialize cJSON item and error pointer */
memset(item, 0, sizeof(cJSON)); memset(item, 0, sizeof(cJSON));

View File

@@ -96,7 +96,7 @@ static void parse_value_should_parse_object(void)
reset(item); reset(item);
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
memset(item, 0, sizeof(cJSON)); memset(item, 0, sizeof(cJSON));

View File

@@ -40,23 +40,11 @@ static void parse_with_opts_should_handle_empty_strings(void)
{ {
const char empty_string[] = ""; const char empty_string[] = "";
const char *error_pointer = NULL; const char *error_pointer = NULL;
TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, NULL, false)); TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, NULL, false));
TEST_ASSERT_EQUAL_PTR(empty_string, cJSON_GetErrorPtr()); error_pointer = cJSON_GetErrorPtr();
TEST_ASSERT_EQUAL_INT(0, error_pointer - empty_string);
TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, &error_pointer, false)); TEST_ASSERT_NULL(cJSON_ParseWithOpts(empty_string, &error_pointer, false));
TEST_ASSERT_EQUAL_PTR(empty_string, error_pointer); TEST_ASSERT_EQUAL_INT(0, error_pointer - empty_string);
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) static void parse_with_opts_should_require_null_if_requested(void)
@@ -77,36 +65,18 @@ static void parse_with_opts_should_return_parse_end(void)
cJSON *item = cJSON_ParseWithOpts(json, &parse_end, false); cJSON *item = cJSON_ParseWithOpts(json, &parse_end, false);
TEST_ASSERT_NOT_NULL(item); TEST_ASSERT_NOT_NULL(item);
TEST_ASSERT_EQUAL_PTR(json + 2, parse_end); TEST_ASSERT_EQUAL_INT(2, parse_end - json);
cJSON_Delete(item); cJSON_Delete(item);
} }
static void parse_with_opts_should_parse_utf8_bom(void) int main(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 CJSON_CDECL main(void)
{ {
UNITY_BEGIN(); UNITY_BEGIN();
RUN_TEST(parse_with_opts_should_handle_null); RUN_TEST(parse_with_opts_should_handle_null);
RUN_TEST(parse_with_opts_should_handle_empty_strings); 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_require_null_if_requested);
RUN_TEST(parse_with_opts_should_return_parse_end); RUN_TEST(parse_with_opts_should_return_parse_end);
RUN_TEST(parse_with_opts_should_parse_utf8_bom);
return UNITY_END(); return UNITY_END();
} }

View File

@@ -87,7 +87,7 @@ static void print_array_should_print_arrays_with_multiple_elements(void)
assert_print_array("[1, null, true, false, [], \"hello\", {\n\t}]", "[1,null,true,false,[],\"hello\",{}]"); assert_print_array("[1, null, true, false, [], \"hello\", {\n\t}]", "[1,null,true,false,[],\"hello\",{}]");
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
UNITY_BEGIN(); UNITY_BEGIN();

View File

@@ -27,8 +27,6 @@
static void assert_print_number(const char *expected, double input) static void assert_print_number(const char *expected, double input)
{ {
unsigned char printed[1024]; unsigned char printed[1024];
unsigned char new_buffer[26];
unsigned int i = 0;
cJSON item[1]; cJSON item[1];
printbuffer buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; printbuffer buffer = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } };
buffer.buffer = printed; buffer.buffer = printed;
@@ -36,29 +34,11 @@ static void assert_print_number(const char *expected, double input)
buffer.offset = 0; buffer.offset = 0;
buffer.noalloc = true; buffer.noalloc = true;
buffer.hooks = global_hooks; buffer.hooks = global_hooks;
buffer.buffer = new_buffer;
memset(item, 0, sizeof(item)); memset(item, 0, sizeof(item));
memset(new_buffer, 0, sizeof(new_buffer));
cJSON_SetNumberValue(item, input); cJSON_SetNumberValue(item, input);
TEST_ASSERT_TRUE_MESSAGE(print_number(item, &buffer), "Failed to print number."); TEST_ASSERT_TRUE_MESSAGE(print_number(item, &buffer), "Failed to print number.");
/* In MinGW or visual studio(before 2015),the exponten is represented using three digits,like:"1e-009","1e+017"
* remove extra "0" to output "1e-09" or "1e+17",which makes testcase PASS */
for(i = 0;i <sizeof(new_buffer);i++)
{
if(i >3 && new_buffer[i] =='0')
{
if((new_buffer[i-3] =='e' && new_buffer[i-2] == '-' && new_buffer[i] =='0') ||(new_buffer[i-2] =='e' && new_buffer[i-1] =='+'))
{
while(new_buffer[i] !='\0')
{
new_buffer[i] = new_buffer[i+1];
i++;
}
}
}
}
TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, buffer.buffer, "Printed number is not as expected."); TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, buffer.buffer, "Printed number is not as expected.");
} }
@@ -109,7 +89,7 @@ static void print_number_should_print_non_number(void)
/* assert_print_number("null", -INFTY); */ /* assert_print_number("null", -INFTY); */
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
UNITY_BEGIN(); UNITY_BEGIN();

View File

@@ -88,7 +88,7 @@ static void print_object_should_print_objects_with_multiple_elements(void)
assert_print_object("{\n\t\"one\":\t1,\n\t\"NULL\":\tnull,\n\t\"TRUE\":\ttrue,\n\t\"FALSE\":\tfalse,\n\t\"array\":\t[],\n\t\"world\":\t\"hello\",\n\t\"object\":\t{\n\t}\n}", "{\"one\":1,\"NULL\":null,\"TRUE\":true,\"FALSE\":false,\"array\":[],\"world\":\"hello\",\"object\":{}}"); assert_print_object("{\n\t\"one\":\t1,\n\t\"NULL\":\tnull,\n\t\"TRUE\":\ttrue,\n\t\"FALSE\":\tfalse,\n\t\"array\":\t[],\n\t\"world\":\t\"hello\",\n\t\"object\":\t{\n\t}\n}", "{\"one\":1,\"NULL\":null,\"TRUE\":true,\"FALSE\":false,\"array\":[],\"world\":\"hello\",\"object\":{}}");
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
UNITY_BEGIN(); UNITY_BEGIN();

View File

@@ -65,7 +65,7 @@ static void print_string_should_print_utf8(void)
assert_print_string("\"ü猫慕\"", "ü猫慕"); assert_print_string("\"ü猫慕\"", "ü猫慕");
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
UNITY_BEGIN(); UNITY_BEGIN();

View File

@@ -90,7 +90,7 @@ static void print_value_should_print_object(void)
assert_print_value("{}"); assert_print_value("{}");
} }
int CJSON_CDECL main(void) int main(void)
{ {
/* initialize cJSON item */ /* initialize cJSON item */
UNITY_BEGIN(); UNITY_BEGIN();

View File

@@ -1,258 +0,0 @@
/*
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"
static const char *json = "{\n\
\t\"name\":\t\"Awesome 4K\",\n\
\t\"resolutions\":\t[{\n\
\t\t\t\"width\":\t1280,\n\
\t\t\t\"height\":\t720\n\
\t\t}, {\n\
\t\t\t\"width\":\t1920,\n\
\t\t\t\"height\":\t1080\n\
\t\t}, {\n\
\t\t\t\"width\":\t3840,\n\
\t\t\t\"height\":\t2160\n\
\t\t}]\n\
}";
static char* create_monitor(void)
{
const unsigned int resolution_numbers[3][2] = {
{1280, 720},
{1920, 1080},
{3840, 2160}
};
char *string = NULL;
cJSON *name = NULL;
cJSON *resolutions = NULL;
cJSON *resolution = NULL;
cJSON *width = NULL;
cJSON *height = NULL;
size_t index = 0;
cJSON *monitor = cJSON_CreateObject();
if (monitor == NULL)
{
goto end;
}
name = cJSON_CreateString("Awesome 4K");
if (name == NULL)
{
goto end;
}
/* after creation was successful, immediately add it to the monitor,
* thereby transferring ownership of the pointer to it */
cJSON_AddItemToObject(monitor, "name", name);
resolutions = cJSON_CreateArray();
if (resolutions == NULL)
{
goto end;
}
cJSON_AddItemToObject(monitor, "resolutions", resolutions);
for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
{
resolution = cJSON_CreateObject();
if (resolution == NULL)
{
goto end;
}
cJSON_AddItemToArray(resolutions, resolution);
width = cJSON_CreateNumber(resolution_numbers[index][0]);
if (width == NULL)
{
goto end;
}
cJSON_AddItemToObject(resolution, "width", width);
height = cJSON_CreateNumber(resolution_numbers[index][1]);
if (height == NULL)
{
goto end;
}
cJSON_AddItemToObject(resolution, "height", height);
}
string = cJSON_Print(monitor);
if (string == NULL)
{
fprintf(stderr, "Failed to print monitor.\n");
}
end:
cJSON_Delete(monitor);
return string;
}
static char *create_monitor_with_helpers(void)
{
const unsigned int resolution_numbers[3][2] = {
{1280, 720},
{1920, 1080},
{3840, 2160}
};
char *string = NULL;
cJSON *resolutions = NULL;
size_t index = 0;
cJSON *monitor = cJSON_CreateObject();
if (cJSON_AddStringToObject(monitor, "name", "Awesome 4K") == NULL)
{
goto end;
}
resolutions = cJSON_AddArrayToObject(monitor, "resolutions");
if (resolutions == NULL)
{
goto end;
}
for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
{
cJSON *resolution = cJSON_CreateObject();
if (cJSON_AddNumberToObject(resolution, "width", resolution_numbers[index][0]) == NULL)
{
goto end;
}
if(cJSON_AddNumberToObject(resolution, "height", resolution_numbers[index][1]) == NULL)
{
goto end;
}
cJSON_AddItemToArray(resolutions, resolution);
}
string = cJSON_Print(monitor);
if (string == NULL) {
fprintf(stderr, "Failed to print monitor.\n");
}
end:
cJSON_Delete(monitor);
return string;
}
/* return 1 if the monitor supports full hd, 0 otherwise */
static int supports_full_hd(const char * const monitor)
{
const cJSON *resolution = NULL;
const cJSON *resolutions = NULL;
const cJSON *name = NULL;
int status = 0;
cJSON *monitor_json = cJSON_Parse(monitor);
if (monitor_json == NULL)
{
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL)
{
fprintf(stderr, "Error before: %s\n", error_ptr);
}
status = 0;
goto end;
}
name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name");
if (cJSON_IsString(name) && (name->valuestring != NULL))
{
printf("Checking monitor \"%s\"\n", name->valuestring);
}
resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, "resolutions");
cJSON_ArrayForEach(resolution, resolutions)
{
cJSON *width = cJSON_GetObjectItemCaseSensitive(resolution, "width");
cJSON *height = cJSON_GetObjectItemCaseSensitive(resolution, "height");
if (!cJSON_IsNumber(width) || !cJSON_IsNumber(height))
{
status = 0;
goto end;
}
if (compare_double(width->valuedouble, 1920) && compare_double(height->valuedouble, 1080))
{
status = 1;
goto end;
}
}
end:
cJSON_Delete(monitor_json);
return status;
}
static void create_monitor_should_create_a_monitor(void)
{
char *monitor = create_monitor();
TEST_ASSERT_EQUAL_STRING(monitor, json);
free(monitor);
}
static void create_monitor_with_helpers_should_create_a_monitor(void)
{
char *monitor = create_monitor_with_helpers();
TEST_ASSERT_EQUAL_STRING(json, monitor);
free(monitor);
}
static void supports_full_hd_should_check_for_full_hd_support(void)
{
static const char *monitor_without_hd = "{\n\
\t\t\"name\": \"lame monitor\",\n\
\t\t\"resolutions\":\t[{\n\
\t\t\t\"width\":\t640,\n\
\t\t\t\"height\":\t480\n\
\t\t}]\n\
}";
TEST_ASSERT(supports_full_hd(json));
TEST_ASSERT_FALSE(supports_full_hd(monitor_without_hd));
}
int CJSON_CDECL main(void)
{
UNITY_BEGIN();
RUN_TEST(create_monitor_should_create_a_monitor);
RUN_TEST(create_monitor_with_helpers_should_create_a_monitor);
RUN_TEST(supports_full_hd_should_check_for_full_hd_support);
return UNITY_END();
}

View File

@@ -18,9 +18,7 @@ install:
script: script:
- cd test && rake ci - cd test && rake ci
- make -s - make -s
- make -s DEBUG=-m32 #32-bit architecture with 64-bit support - make -s DEBUG=-m32
- make -s DEBUG=-m32 UNITY_SUPPORT_64= #32-bit build without 64-bit types
- make -s UNITY_INCLUDE_DOUBLE= # without double
- cd ../extras/fixture/test && rake ci - cd ../extras/fixture/test && rake ci
- make -s default noStdlibMalloc - make -s default noStdlibMalloc
- make -s C89 - make -s C89

View File

@@ -118,17 +118,6 @@ 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 Asserts that the actual value is within plus or minus delta of the expected value. This also comes in
size specific variants. 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 Arrays
------ ------

View File

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

View File

@@ -119,7 +119,7 @@ class UnityTestRunnerGenerator
source_index = 0 source_index = 0
tests_and_line_numbers.size.times do |i| tests_and_line_numbers.size.times do |i|
source_lines[source_index..-1].each_with_index do |line, index| source_lines[source_index..-1].each_with_index do |line, index|
next unless line =~ /\s+#{tests_and_line_numbers[i][:test]}(?:\s|\()/ next unless line =~ /#{tests_and_line_numbers[i][:test]}/
source_index += index source_index += index
tests_and_line_numbers[i][:line_number] = source_index + 1 tests_and_line_numbers[i][:line_number] = source_index + 1
break break
@@ -157,9 +157,6 @@ class UnityTestRunnerGenerator
output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */') output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */')
create_runtest(output, mocks) create_runtest(output, mocks)
output.puts("\n/*=======Automagically Detected Files To Include=====*/") output.puts("\n/*=======Automagically Detected Files To Include=====*/")
output.puts('#ifdef __WIN32__')
output.puts('#define UNITY_INCLUDE_SETUP_STUBS')
output.puts('#endif')
output.puts("#include \"#{@options[:framework]}.h\"") output.puts("#include \"#{@options[:framework]}.h\"")
output.puts('#include "cmock.h"') unless mocks.empty? output.puts('#include "cmock.h"') unless mocks.empty?
output.puts('#include <setjmp.h>') output.puts('#include <setjmp.h>')
@@ -238,36 +235,22 @@ class UnityTestRunnerGenerator
end end
def create_suite_setup(output) def create_suite_setup(output)
return if @options[:suite_setup].nil?
output.puts("\n/*=======Suite Setup=====*/") output.puts("\n/*=======Suite Setup=====*/")
output.puts('static void suite_setup(void)') output.puts('static void suite_setup(void)')
output.puts('{') output.puts('{')
if @options[:suite_setup].nil? output.puts(@options[:suite_setup])
# New style, call suiteSetUp() if we can use weak symbols
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
output.puts(' suiteSetUp();')
output.puts('#endif')
else
# Old style, C code embedded in the :suite_setup option
output.puts(@options[:suite_setup])
end
output.puts('}') output.puts('}')
end end
def create_suite_teardown(output) def create_suite_teardown(output)
return if @options[:suite_teardown].nil?
output.puts("\n/*=======Suite Teardown=====*/") output.puts("\n/*=======Suite Teardown=====*/")
output.puts('static int suite_teardown(int num_failures)') output.puts('static int suite_teardown(int num_failures)')
output.puts('{') output.puts('{')
if @options[:suite_teardown].nil? output.puts(@options[:suite_teardown])
# New style, call suiteTearDown() if we can use weak symbols
output.puts('#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA)')
output.puts(' return suiteTearDown(num_failures);')
output.puts('#else')
output.puts(' return num_failures;')
output.puts('#endif')
else
# Old style, C code embedded in the :suite_teardown option
output.puts(@options[:suite_teardown])
end
output.puts('}') output.puts('}')
end end
@@ -359,7 +342,7 @@ class UnityTestRunnerGenerator
output.puts("int #{main_name}(void)") output.puts("int #{main_name}(void)")
output.puts('{') output.puts('{')
end end
output.puts(' suite_setup();') output.puts(' suite_setup();') unless @options[:suite_setup].nil?
output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");") output.puts(" UnityBegin(\"#{filename.gsub(/\\/, '\\\\\\')}\");")
if @options[:use_param_tests] if @options[:use_param_tests]
tests.each do |test| tests.each do |test|
@@ -374,7 +357,7 @@ class UnityTestRunnerGenerator
end end
output.puts output.puts
output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty? output.puts(' CMock_Guts_MemFreeFinal();') unless used_mocks.empty?
output.puts(" return suite_teardown(UnityEnd());") output.puts(" return #{@options[:suite_teardown].nil? ? '' : 'suite_teardown'}(UnityEnd());")
output.puts('}') output.puts('}')
end end

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

View File

@@ -290,60 +290,6 @@ Asserts the specified bit of the `actual` parameter is high.
Asserts the specified bit of the `actual` parameter is low. 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) ### Integer Ranges (of all sizes)

View File

@@ -79,7 +79,18 @@ _Example:_
#define UNITY_EXCLUDE_LIMITS_H #define UNITY_EXCLUDE_LIMITS_H
If you've disabled both of the automatic options above, you're going to have to ##### `UNITY_EXCLUDE_SIZEOF`
The third and final attempt to guess your types is to use the `sizeof()`
operator. Even if the first two options don't work, this one covers most cases.
There _is_ a rare compiler or two out there that doesn't support sizeof() in the
preprocessing stage, though. For these, you have the ability to disable this
feature as well.
_Example:_
#define UNITY_EXCLUDE_SIZEOF
If you've disabled all of the automatic options above, you're going to have to
do the configuration yourself. Don't worry. Even this isn't too bad... there are do the configuration yourself. Don't worry. Even this isn't too bad... there are
just a handful of defines that you are going to specify if you don't like the just a handful of defines that you are going to specify if you don't like the
defaults. defaults.
@@ -116,7 +127,7 @@ _Example:_
#define UNITY_POINTER_WIDTH 64 #define UNITY_POINTER_WIDTH 64
##### `UNITY_SUPPORT_64` ##### `UNITY_INCLUDE_64`
Unity will automatically include 64-bit support if it auto-detects it, or if Unity will automatically include 64-bit support if it auto-detects it, or if
your `int`, `long`, or pointer widths are greater than 32-bits. Define this to your `int`, `long`, or pointer widths are greater than 32-bits. Define this to
@@ -125,7 +136,7 @@ can be a significant size and speed impact to enabling 64-bit support on small
targets, so don't define it if you don't need it. targets, so don't define it if you don't need it.
_Example:_ _Example:_
#define UNITY_SUPPORT_64 #define UNITY_INCLUDE_64
### Floating Point Types ### Floating Point Types
@@ -159,20 +170,24 @@ _Example:_
#define UNITY_INCLUDE_DOUBLE #define UNITY_INCLUDE_DOUBLE
##### `UNITY_EXCLUDE_FLOAT_PRINT` ##### `UNITY_FLOAT_VERBOSE`
##### `UNITY_DOUBLE_VERBOSE`
Unity aims for as small of a footprint as possible and avoids most standard Unity aims for as small of a footprint as possible and avoids most standard
library calls (some embedded platforms dont have a standard library!). Because library calls (some embedded platforms don't have a standard library!). Because
of this, its routines for printing integer values are minimalist and hand-coded. of this, its routines for printing integer values are minimalist and hand-coded.
Therefore, the display of floating point values during a failure are optional. To keep Unity universal, though, we chose to _not_ develop our own floating
By default, Unity will print the actual results of floating point assertion point print routines. Instead, the display of floating point values during a
failure (e.g. ”Expected 4.56 Was 4.68”). To not include this extra support, you failure are optional. By default, Unity will not print the actual results of
can use this define to instead respond to a failed assertion with a message like floating point assertion failure. So a failed assertion will produce a message
Values Not Within Delta. If you would like verbose failure messages for floating like `"Values Not Within Delta"`. If you would like verbose failure messages for
point assertions, use these options to give more explicit failure messages. floating point assertions, use these options to give more explicit failure
messages (e.g. `"Expected 4.56 Was 4.68"`). Note that this feature requires the
use of `sprintf` so might not be desirable in all cases.
_Example:_ _Example:_
#define UNITY_EXCLUDE_FLOAT_PRINT #define UNITY_DOUBLE_VERBOSE
##### `UNITY_FLOAT_TYPE` ##### `UNITY_FLOAT_TYPE`
@@ -262,32 +277,25 @@ will declare an instance of your function by default. If you want to disable
this behavior, add `UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION`. this behavior, add `UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION`.
##### `UNITY_WEAK_ATTRIBUTE` ##### `UNITY_SUPPORT_WEAK`
##### `UNITY_WEAK_PRAGMA` For some targets, Unity can make the otherwise required `setUp()` and
`tearDown()` functions optional. This is a nice convenience for test writers
##### `UNITY_NO_WEAK` since `setUp` and `tearDown` don't often actually _do_ anything. If you're using
gcc or clang, this option is automatically defined for you. Other compilers can
For some targets, Unity can make the otherwise required setUp() and tearDown() also support this behavior, if they support a C feature called weak functions. A
functions optional. This is a nice convenience for test writers since setUp and weak function is a function that is compiled into your executable _unless_ a
tearDown dont often actually do anything. If youre using gcc or clang, this non-weak version of the same function is defined elsewhere. If a non-weak
option is automatically defined for you. Other compilers can also support this version is found, the weak version is ignored as if it never existed. If your
behavior, if they support a C feature called weak functions. A weak function is compiler supports this feature, you can let Unity know by defining
a function that is compiled into your executable unless a non-weak version of `UNITY_SUPPORT_WEAK` as the function attributes that would need to be applied to
the same function is defined elsewhere. If a non-weak version is found, the weak identify a function as weak. If your compiler lacks support for weak functions,
version is ignored as if it never existed. If your compiler supports this feature, you will always need to define `setUp` and `tearDown` functions (though they can
you can let Unity know by defining UNITY_WEAK_ATTRIBUTE or UNITY_WEAK_PRAGMA as be and often will be just empty). The most common options for this feature are:
the function attributes that would need to be applied to identify a function as
weak. If your compiler lacks support for weak functions, you will always need to
define setUp and tearDown functions (though they can be and often will be just
empty). You can also force Unity to NOT use weak functions by defining
UNITY_NO_WEAK. The most common options for this feature are:
_Example:_ _Example:_
#define UNITY_WEAK_ATTRIBUTE weak #define UNITY_SUPPORT_WEAK weak
#define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) #define UNITY_SUPPORT_WEAK __attribute__((weak))
#define UNITY_WEAK_PRAGMA
#define UNITY_NO_WEAK
##### `UNITY_PTR_ATTRIBUTE` ##### `UNITY_PTR_ATTRIBUTE`
@@ -301,51 +309,6 @@ _Example:_
#define UNITY_PTR_ATTRIBUTE near #define UNITY_PTR_ATTRIBUTE near
##### `UNITY_PRINT_EOL`
By default, Unity outputs \n at the end of each line of output. This is easy
to parse by the scripts, by Ceedling, etc, but it might not be ideal for YOUR
system. Feel free to override this and to make it whatever you wish.
_Example:_
#define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\r'); UNITY_OUTPUT_CHAR('\n') }
##### `UNITY_EXCLUDE_DETAILS`
This is an option for if you absolutely must squeeze every byte of memory out of
your system. Unity stores a set of internal scratchpads which are used to pass
extra detail information around. It's used by systems like CMock in order to
report which function or argument flagged an error. If you're not using CMock and
you're not using these details for other things, then you can exclude them.
_Example:_
#define UNITY_EXCLUDE_DETAILS
##### `UNITY_EXCLUDE_SETJMP`
If your embedded system doesn't support the standard library setjmp, you can
exclude Unity's reliance on this by using this define. This dropped dependence
comes at a price, though. You will be unable to use custom helper functions for
your tests, and you will be unable to use tools like CMock. Very likely, if your
compiler doesn't support setjmp, you wouldn't have had the memory space for those
things anyway, though... so this option exists for those situations.
_Example:_
#define UNITY_EXCLUDE_SETJMP
##### `UNITY_OUTPUT_COLOR`
If you want to add color using ANSI escape codes you can use this define.
t
_Example:_
#define UNITY_OUTPUT_COLOR
## Getting Into The Guts ## Getting Into The Guts
There will be cases where the options above aren't quite going to get everything There will be cases where the options above aren't quite going to get everything

View File

@@ -124,7 +124,7 @@ demonstrates using a Ruby hash.
##### `:includes` ##### `:includes`
This option specifies an array of file names to be `#include`'d at the top of This option specifies an array of file names to be ?#include?'d at the top of
your runner C file. You might use it to reference custom types or anything else your runner C file. You might use it to reference custom types or anything else
universally needed in your generated runners. universally needed in your generated runners.
@@ -133,23 +133,11 @@ universally needed in your generated runners.
Define this option with C code to be executed _before any_ test cases are run. Define this option with C code to be executed _before any_ test cases are run.
Alternatively, if your C compiler supports weak symbols, you can leave this
option unset and instead provide a `void suiteSetUp(void)` function in your test
suite. The linker will look for this symbol and fall back to a Unity-provided
stub if it is not found.
##### `:suite_teardown` ##### `:suite_teardown`
Define this option with C code to be executed _after all_ test cases have Define this option with C code to be executed ?after all?test cases have
finished. An integer variable `num_failures` is available for diagnostics. finished.
The code should end with a `return` statement; the value returned will become
the exit code of `main`. You can normally just return `num_failures`.
Alternatively, if your C compiler supports weak symbols, you can leave this
option unset and instead provide a `int suiteTearDown(int num_failures)`
function in your test suite. The linker will look for this symbol and fall
back to a Unity-provided stub if it is not found.
##### `:enforce_strict_ordering` ##### `:enforce_strict_ordering`

View File

@@ -201,12 +201,10 @@
* `stdout` option. You decide to route your test result output to a custom * `stdout` option. You decide to route your test result output to a custom
* serial `RS232_putc()` function you wrote like thus: * serial `RS232_putc()` function you wrote like thus:
*/ */
/* #define UNITY_OUTPUT_CHAR(a) RS232_putc(a) */ /* #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() RS232_flush() */ /* #define UNITY_OUTPUT_START() RS232_config(115200,1,8,0) */
/* #define UNITY_OUTPUT_FLUSH_HEADER_DECLARATION RS232_flush(void) */ /* #define UNITY_OUTPUT_COMPLETE() RS232_close() */
/* #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 /* For some targets, Unity can make the otherwise required `setUp()` and
* `tearDown()` functions optional. This is a nice convenience for test writers * `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? defines = if $cfg['compiler']['defines']['items'].nil?
'' ''
else else
squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'] + ['UNITY_OUTPUT_CHAR_HEADER_DECLARATION=UnityOutputCharSpy_OutputChar\(int\)']) squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items'] + ['UNITY_OUTPUT_CHAR=UnityOutputCharSpy_OutputChar'])
end end
options = squash('', $cfg['compiler']['options']) options = squash('', $cfg['compiler']['options'])
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items']) includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items'])

View File

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

View File

@@ -1,2 +1,2 @@
122 120

View File

@@ -1,2 +1,2 @@
2.4.3 2.4.1

View File

@@ -4,7 +4,6 @@
[Released under MIT License. Please refer to license.txt for details] [Released under MIT License. Please refer to license.txt for details]
============================================================================ */ ============================================================================ */
#define UNITY_INCLUDE_SETUP_STUBS
#include "unity.h" #include "unity.h"
#include <stddef.h> #include <stddef.h>
@@ -20,24 +19,14 @@ void UNITY_OUTPUT_CHAR(int);
struct UNITY_STORAGE_T Unity; struct UNITY_STORAGE_T Unity;
#ifdef UNITY_OUTPUT_COLOR
static const char UnityStrOk[] = "\033[42mOK\033[00m";
static const char UnityStrPass[] = "\033[42mPASS\033[00m";
static const char UnityStrFail[] = "\033[41mFAIL\033[00m";
static const char UnityStrIgnore[] = "\033[43mIGNORE\033[00m";
#else
static const char UnityStrOk[] = "OK"; static const char UnityStrOk[] = "OK";
static const char UnityStrPass[] = "PASS"; static const char UnityStrPass[] = "PASS";
static const char UnityStrFail[] = "FAIL"; static const char UnityStrFail[] = "FAIL";
static const char UnityStrIgnore[] = "IGNORE"; static const char UnityStrIgnore[] = "IGNORE";
#endif
static const char UnityStrNull[] = "NULL"; static const char UnityStrNull[] = "NULL";
static const char UnityStrSpacer[] = ". "; static const char UnityStrSpacer[] = ". ";
static const char UnityStrExpected[] = " Expected "; static const char UnityStrExpected[] = " Expected ";
static const char UnityStrWas[] = " Was "; static const char UnityStrWas[] = " Was ";
static const char UnityStrGt[] = " to be greater than ";
static const char UnityStrLt[] = " to be less than ";
static const char UnityStrOrEqual[] = "or equal to ";
static const char UnityStrElement[] = " Element "; static const char UnityStrElement[] = " Element ";
static const char UnityStrByte[] = " Byte "; static const char UnityStrByte[] = " Byte ";
static const char UnityStrMemory[] = " Memory Mismatch."; static const char UnityStrMemory[] = " Memory Mismatch.";
@@ -92,18 +81,6 @@ void UnityPrint(const char* string)
UNITY_OUTPUT_CHAR('\\'); UNITY_OUTPUT_CHAR('\\');
UNITY_OUTPUT_CHAR('n'); UNITY_OUTPUT_CHAR('n');
} }
#ifdef UNITY_OUTPUT_COLOR
/* print ANSI escape code */
else if (*pch == 27 && *(pch + 1) == '[')
{
while (*pch && *pch != 'm')
{
UNITY_OUTPUT_CHAR(*pch);
pch++;
}
UNITY_OUTPUT_CHAR('m');
}
#endif
/* unprintable characters are shown as codes */ /* unprintable characters are shown as codes */
else else
{ {
@@ -258,97 +235,95 @@ void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number)
/*-----------------------------------------------*/ /*-----------------------------------------------*/
#ifndef UNITY_EXCLUDE_FLOAT_PRINT #ifndef UNITY_EXCLUDE_FLOAT_PRINT
/* This function prints a floating-point value in a format similar to static void UnityPrintDecimalAndNumberWithLeadingZeros(UNITY_INT32 fraction_part, UNITY_INT32 divisor)
* printf("%.6g"). It can work with either single- or double-precision, {
* but for simplicity, it prints only 6 significant digits in either case. UNITY_OUTPUT_CHAR('.');
* Printing more than 6 digits accurately is hard (at least in the single- while (divisor > 0)
* precision case) and isn't attempted here. */ {
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);
*/
void UnityPrintFloat(const UNITY_DOUBLE input_number) void UnityPrintFloat(const UNITY_DOUBLE input_number)
{ {
UNITY_DOUBLE number = input_number; UNITY_DOUBLE number;
/* print minus sign (including for negative zero) */ if (input_number < 0)
if (number < (double)0.0f || (number == (double)0.0f && (double)1.0f / number < (double)0.0f))
{ {
UNITY_OUTPUT_CHAR('-'); UNITY_OUTPUT_CHAR('-');
number = -number; number = -input_number;
} else
{
number = input_number;
} }
/* handle zero, NaN, and +/- infinity */ if (isnan(number)) UnityPrint(UnityStrNaN);
if (number == (double)0.0f) UnityPrint("0"); else if (isinf(number)) UnityPrintLen(UnityStrInf, 3);
else if (isnan(number)) UnityPrint("nan"); else if (number <= 0.0000005 && number > 0) UnityPrint("0.000000..."); /* Small number */
else if (isinf(number)) UnityPrint("inf"); else if (number < 4294967295.9999995) /* Rounded result fits in 32 bits, "%.6f" format */
else
{ {
int exponent = 0; const UNITY_INT32 divisor = 1000000/10;
int decimals, digits; UNITY_UINT32 integer_part = (UNITY_UINT32)number;
UNITY_INT32 n; UNITY_INT32 fraction_part = (UNITY_INT32)((number - (UNITY_DOUBLE)integer_part)*1000000.0 + 0.5);
char buf[16]; /* 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);
/* scale up or down by powers of 10 */ if (fraction_part == 1000000) /* Carry across the decimal point */
while (number < (double)(100000.0f / 1e6f)) { number *= (double)1e6f; exponent -= 6; }
while (number < (double)100000.0f) { number *= (double)10.0f; exponent--; }
while (number > (double)(1000000.0f * 1e6f)) { number /= (double)1e6f; exponent += 6; }
while (number > (double)1000000.0f) { number /= (double)10.0f; exponent++; }
/* round to nearest integer */
n = ((UNITY_INT32)(number + number) + 1) / 2;
if (n > 999999)
{ {
n = 100000; 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;
exponent++; 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);
/* determine where to place decimal point */ UNITY_OUTPUT_CHAR('0' + integer_part / divisor);
decimals = (exponent <= 0 && exponent >= -9) ? -exponent : 5; UnityPrintDecimalAndNumberWithLeadingZeros(integer_part % divisor, divisor / 10);
exponent += decimals; UNITY_OUTPUT_CHAR('e');
UNITY_OUTPUT_CHAR('+');
/* truncate trailing zeroes after decimal point */ if (exponent < 10) UNITY_OUTPUT_CHAR('0');
while (decimals > 0 && n % 10 == 0) UnityPrintNumber(exponent);
{
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 */ #endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */
@@ -551,45 +526,6 @@ void UnityAssertEqualNumber(const UNITY_INT expected,
} }
} }
/*-----------------------------------------------*/
void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold,
const UNITY_INT actual,
const UNITY_COMPARISON_T compare,
const char *msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style)
{
int failed = 0;
RETURN_IF_FAIL_OR_IGNORE;
if (threshold == actual && compare & UNITY_EQUAL_TO) return;
if (threshold == actual) failed = 1;
if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
{
if (actual > threshold && compare & UNITY_SMALLER_THAN) failed = 1;
if (actual < threshold && compare & UNITY_GREATER_THAN) failed = 1;
}
else /* UINT or HEX */
{
if ((UNITY_UINT)actual > (UNITY_UINT)threshold && compare & UNITY_SMALLER_THAN) failed = 1;
if ((UNITY_UINT)actual < (UNITY_UINT)threshold && compare & UNITY_GREATER_THAN) failed = 1;
}
if (failed)
{
UnityTestResultsFailBegin(lineNumber);
UnityPrint(UnityStrExpected);
UnityPrintNumberByStyle(actual, style);
if (compare & UNITY_GREATER_THAN) UnityPrint(UnityStrGt);
if (compare & UNITY_SMALLER_THAN) UnityPrint(UnityStrLt);
if (compare & UNITY_EQUAL_TO) UnityPrint(UnityStrOrEqual);
UnityPrintNumberByStyle(threshold, style);
UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL;
}
}
#define UnityPrintPointlessAndBail() \ #define UnityPrintPointlessAndBail() \
{ \ { \
UnityTestResultsFailBegin(lineNumber); \ UnityTestResultsFailBegin(lineNumber); \
@@ -1089,7 +1025,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
{ {
UNITY_UINT32 i = 0; UNITY_UINT32 i = 0;
UNITY_UINT32 j = 0; UNITY_UINT32 j = 0;
const char* expd = NULL; const char* exp = NULL;
const char* act = NULL; const char* act = NULL;
RETURN_IF_FAIL_OR_IGNORE; RETURN_IF_FAIL_OR_IGNORE;
@@ -1112,7 +1048,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
if (flags != UNITY_ARRAY_TO_ARRAY) if (flags != UNITY_ARRAY_TO_ARRAY)
{ {
expd = (const char*)expected; exp = (const char*)expected;
} }
do do
@@ -1120,15 +1056,15 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
act = actual[j]; act = actual[j];
if (flags == UNITY_ARRAY_TO_ARRAY) if (flags == UNITY_ARRAY_TO_ARRAY)
{ {
expd = ((const char* const*)expected)[j]; exp = ((const char* const*)expected)[j];
} }
/* if both pointers not null compare the strings */ /* if both pointers not null compare the strings */
if (expd && act) if (exp && act)
{ {
for (i = 0; expd[i] || act[i]; i++) for (i = 0; exp[i] || act[i]; i++)
{ {
if (expd[i] != act[i]) if (exp[i] != act[i])
{ {
Unity.CurrentTestFailed = 1; Unity.CurrentTestFailed = 1;
break; break;
@@ -1137,7 +1073,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
} }
else else
{ /* handle case of one pointers being null (if both null, test should pass) */ { /* handle case of one pointers being null (if both null, test should pass) */
if (expd != act) if (exp != act)
{ {
Unity.CurrentTestFailed = 1; Unity.CurrentTestFailed = 1;
} }
@@ -1151,7 +1087,7 @@ void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected,
UnityPrint(UnityStrElement); UnityPrint(UnityStrElement);
UnityPrintNumberUnsigned(j); UnityPrintNumberUnsigned(j);
} }
UnityPrintExpectedAndActualStrings(expd, act); UnityPrintExpectedAndActualStrings(exp, act);
UnityAddMsgIfSpecified(msg); UnityAddMsgIfSpecified(msg);
UNITY_FAIL_AND_BAIL; UNITY_FAIL_AND_BAIL;
} }
@@ -1326,6 +1262,17 @@ void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
UNITY_IGNORE_AND_BAIL; UNITY_IGNORE_AND_BAIL;
} }
/*-----------------------------------------------*/
#if defined(UNITY_WEAK_ATTRIBUTE)
UNITY_WEAK_ATTRIBUTE void setUp(void) { }
UNITY_WEAK_ATTRIBUTE void tearDown(void) { }
#elif defined(UNITY_WEAK_PRAGMA)
#pragma weak setUp
void setUp(void) { }
#pragma weak tearDown
void tearDown(void) { }
#endif
/*-----------------------------------------------*/ /*-----------------------------------------------*/
void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
{ {

View File

@@ -15,43 +15,9 @@ extern "C"
#include "unity_internals.h" #include "unity_internals.h"
/*-------------------------------------------------------
* Test Setup / Teardown
*-------------------------------------------------------*/
/* These functions are intended to be called before and after each test. */
void setUp(void); void setUp(void);
void tearDown(void); void tearDown(void);
/* These functions are intended to be called at the beginning and end of an
* entire test suite. suiteTearDown() is passed the number of tests that
* failed, and its return value becomes the exit code of main(). */
void suiteSetUp(void);
int suiteTearDown(int num_failures);
/* If the compiler supports it, the following block provides stub
* implementations of the above functions as weak symbols. Note that on
* some platforms (MinGW for example), weak function implementations need
* to be in the same translation unit they are called from. This can be
* achieved by defining UNITY_INCLUDE_SETUP_STUBS before including unity.h. */
#ifdef UNITY_INCLUDE_SETUP_STUBS
#ifdef UNITY_WEAK_ATTRIBUTE
UNITY_WEAK_ATTRIBUTE void setUp(void) { }
UNITY_WEAK_ATTRIBUTE void tearDown(void) { }
UNITY_WEAK_ATTRIBUTE void suiteSetUp(void) { }
UNITY_WEAK_ATTRIBUTE int suiteTearDown(int num_failures) { return num_failures; }
#elif defined(UNITY_WEAK_PRAGMA)
#pragma weak setUp
void setUp(void) { }
#pragma weak tearDown
void tearDown(void) { }
#pragma weak suiteSetUp
void suiteSetUp(void) { }
#pragma weak suiteTearDown
int suiteTearDown(int num_failures) { return num_failures; }
#endif
#endif
/*------------------------------------------------------- /*-------------------------------------------------------
* Configuration Options * Configuration Options
*------------------------------------------------------- *-------------------------------------------------------
@@ -148,71 +114,6 @@ int suiteTearDown(int num_failures);
#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_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) #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_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((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_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((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_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((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_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((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_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((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)
#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
/* Integer Ranges (of all sizes) */ /* 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_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) #define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
@@ -340,71 +241,6 @@ int suiteTearDown(int num_failures);
#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_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)) #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_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((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_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((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_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((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_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((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_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((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))
#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message))
/* Integer Ranges (of all sizes) */ /* 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_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)) #define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
@@ -459,7 +295,7 @@ int suiteTearDown(int num_failures);
#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) #define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))

View File

@@ -244,8 +244,8 @@ typedef UNITY_FLOAT_TYPE UNITY_FLOAT;
#define UNITY_OUTPUT_CHAR(a) (void)putchar(a) #define UNITY_OUTPUT_CHAR(a) (void)putchar(a)
#else #else
/* If defined as something else, make sure we declare it here so it's ready for use */ /* If defined as something else, make sure we declare it here so it's ready for use */
#ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATION #ifndef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION
extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION; extern void UNITY_OUTPUT_CHAR(int);
#endif #endif
#endif #endif
@@ -253,22 +253,22 @@ extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION;
#ifdef UNITY_USE_FLUSH_STDOUT #ifdef UNITY_USE_FLUSH_STDOUT
/* We want to use the stdout flush utility */ /* We want to use the stdout flush utility */
#include <stdio.h> #include <stdio.h>
#define UNITY_OUTPUT_FLUSH() (void)fflush(stdout) #define UNITY_OUTPUT_FLUSH (void)fflush(stdout)
#else #else
/* We've specified nothing, therefore flush should just be ignored */ /* We've specified nothing, therefore flush should just be ignored */
#define UNITY_OUTPUT_FLUSH() #define UNITY_OUTPUT_FLUSH
#endif #endif
#else #else
/* We've defined flush as something else, so make sure we declare it here so it's ready for use */ /* We've defined flush as something else, so make sure we declare it here so it's ready for use */
#ifdef UNITY_OUTPUT_FLUSH_HEADER_DECLARATION #ifndef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION
extern void UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION; extern void UNITY_OUTPUT_FLUSH(void);
#endif #endif
#endif #endif
#ifndef UNITY_OUTPUT_FLUSH #ifndef UNITY_OUTPUT_FLUSH
#define UNITY_FLUSH_CALL() #define UNITY_FLUSH_CALL()
#else #else
#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH() #define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH
#endif #endif
#ifndef UNITY_PRINT_EOL #ifndef UNITY_PRINT_EOL
@@ -299,7 +299,7 @@ extern void UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION;
* Language Features Available * Language Features Available
*-------------------------------------------------------*/ *-------------------------------------------------------*/
#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) #if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA)
# if defined(__GNUC__) || defined(__ghs__) /* __GNUC__ includes clang */ # ifdef __GNUC__ /* includes clang */
# if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__) # if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__)
# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) # define UNITY_WEAK_ATTRIBUTE __attribute__((weak))
# endif # endif
@@ -350,15 +350,6 @@ UNITY_DISPLAY_STYLE_UINT = sizeof(unsigned) + UNITY_DISPLAY_RANGE_UINT,
UNITY_DISPLAY_STYLE_UNKNOWN UNITY_DISPLAY_STYLE_UNKNOWN
} UNITY_DISPLAY_STYLE_T; } UNITY_DISPLAY_STYLE_T;
typedef enum
{
UNITY_EQUAL_TO = 1,
UNITY_GREATER_THAN = 2,
UNITY_GREATER_OR_EQUAL = 2 + UNITY_EQUAL_TO,
UNITY_SMALLER_THAN = 4,
UNITY_SMALLER_OR_EQUAL = 4 + UNITY_EQUAL_TO
} UNITY_COMPARISON_T;
#ifndef UNITY_EXCLUDE_FLOAT #ifndef UNITY_EXCLUDE_FLOAT
typedef enum UNITY_FLOAT_TRAIT typedef enum UNITY_FLOAT_TRAIT
{ {
@@ -462,13 +453,6 @@ void UnityAssertEqualNumber(const UNITY_INT expected,
const UNITY_LINE_TYPE lineNumber, const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style); const UNITY_DISPLAY_STYLE_T style);
void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold,
const UNITY_INT actual,
const UNITY_COMPARISON_T compare,
const char *msg,
const UNITY_LINE_TYPE lineNumber,
const UNITY_DISPLAY_STYLE_T style);
void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected,
UNITY_INTERNAL_PTR actual, UNITY_INTERNAL_PTR actual,
const UNITY_UINT32 num_elements, const UNITY_UINT32 num_elements,
@@ -666,54 +650,6 @@ 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_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_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) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (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_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_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) #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)
@@ -774,18 +710,6 @@ int UnityTestMatches(void);
#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_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_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) #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)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64)
#else #else
#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
@@ -796,18 +720,6 @@ int UnityTestMatches(void);
#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) #define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64)
#endif #endif
#ifdef UNITY_EXCLUDE_FLOAT #ifdef UNITY_EXCLUDE_FLOAT

View File

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

View File

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

View File

@@ -764,9 +764,8 @@ void testNotEqualBitsLow(void)
EXPECT_ABORT_BEGIN EXPECT_ABORT_BEGIN
TEST_ASSERT_BITS_LOW(v0, v1); TEST_ASSERT_BITS_LOW(v0, v1);
VERIFY_FAILS_END VERIFY_FAILS_END
} }
void testEqualShorts(void) void testEqualShorts(void)
{ {
short v0, v1; short v0, v1;
@@ -1306,415 +1305,6 @@ void testINT8sNotWithinDeltaAndCustomMessage(void)
VERIFY_FAILS_END 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) void testEqualStrings(void)
{ {
const char *testString = "foo"; const char *testString = "foo";
@@ -4466,46 +4056,61 @@ void testFloatPrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY) #if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE(); TEST_IGNORE();
#else #else
TEST_ASSERT_EQUAL_PRINT_FLOATING("0", 0.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("0.0", 0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.99e-07", 0.000000499f); TEST_ASSERT_EQUAL_PRINT_FLOATING("0.000000...", 0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e-07", 0.00000050000005f); TEST_ASSERT_EQUAL_PRINT_FLOATING("0.000001", 0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.100469499f); 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.0", 0.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("1", 1.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0", 1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.25", 1.25f); 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("7.999999", 7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0002", 16.0002f); TEST_ASSERT_EQUAL_PRINT_FLOATING("16.000002", 16.000002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0004", 16.0004f); TEST_ASSERT_EQUAL_PRINT_FLOATING("16.000004", 16.000004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("16.0006", 16.0006f); TEST_ASSERT_EQUAL_PRINT_FLOATING("16.000006", 16.000006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("999999", 999999.0f); /*Last full print integer*/ 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("0.0", -0.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.99e-07", -0.000000499f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.000000...",-0.000000499f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-5e-07", -0.00000050000005f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.000001", -0.00000050000005f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-0.100469", -0.100469499f); 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.0", -0.9999995f); /*Rounding to int place*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1", -1.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.0", -1.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.25", -1.25f); 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("-7.999999", -7.999999f); /*Not rounding*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0002", -16.0002f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.000002", -16.000002f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0004", -16.0004f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.000004", -16.000004f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.0006", -16.0006f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-16.000006", -16.000006f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-999999", -999999.0f); /*Last full print integer*/ TEST_ASSERT_EQUAL_PRINT_FLOATING("-4294967040.0",-4294967040.0f); /*Last full print integer*/
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967296.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967296.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("5e+09", 5000000000.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("5.0e+09", 5000000000.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8e+09", 8.0e+09f); TEST_ASSERT_EQUAL_PRINT_FLOATING("8.0e+09", 8.0e+09f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("8.31e+09", 8309999104.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("8.3099991e+09", 8309999104.0f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 1.0e+10f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0e+10", 1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 10000000000.0f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0e+10", 10000000000.0f);
/* Some compilers have trouble with inexact float constants, a float cast works generally */ /* Some compilers have trouble with inexact float constants, a float cast works generally */
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.00005e+10", (float)1.000054e+10f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.00005499e+10", (float)1.000055e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.1e+38", (float)1.10000005e+38f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.10000006e+38", (float)1.10000005e+38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1.6353e+10", 1.63529943e+10f); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.63529943e+10", 1.63529943e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3.40282e+38", 3.40282346638e38f); TEST_ASSERT_EQUAL_PRINT_FLOATING("3.40282347e+38", 3.40282346638e38f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-1e+10", -1.0e+10f); TEST_ASSERT_EQUAL_PRINT_FLOATING("-1.0e+10", -1.0e+10f);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-3.40282e+38", -3.40282346638e38f); 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
#endif #endif
} }
@@ -4514,69 +4119,105 @@ void testFloatPrintingInfinityAndNaN(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY) #if defined(UNITY_EXCLUDE_FLOAT_PRINT) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE(); TEST_IGNORE();
#else #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 #endif
} }
#if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY) #if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
static void printFloatValue(float f) static void AllFloatPrinting_LessThan32Bits(void)
{ {
char expected[18]; char expected[18];
char expected_lower[18]; union { float f_value; int32_t int_value; } u;
char expected_higher[18]; /* 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)
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)
{ {
/* Fail with diagnostic printing */ startPutcharSpy();
TEST_ASSERT_EQUAL_PRINT_FLOATING(expected, f);
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 */
}
} }
} }
#endif #endif
void testFloatPrintingRandomSamples(void) /* 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)
{ {
#if !defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) || !defined(USING_OUTPUT_SPY) #if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
TEST_IGNORE(); AllFloatPrinting_LessThan32Bits();
#else #else
union { float f_value; uint32_t int_value; } u; TEST_IGNORE(); /* Ignore one of three */
#endif
}
/* These values are not covered by the MINSTD generator */ /* Test takes a long time, around 3.5 minutes compiled with -O2, try ~500 million values */
u.int_value = 0x00000000; printFloatValue(u.f_value); void testAllFloatPrintingPart2_Larger(void)
u.int_value = 0x80000000; printFloatValue(u.f_value); {
u.int_value = 0x7fffffff; printFloatValue(u.f_value); #if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
u.int_value = 0xffffffff; printFloatValue(u.f_value); AllFloatPrinting_Larger(4294967296.0f, 1e25f);
#endif
}
uint32_t a = 1; /* Test takes a long time, around 3.5 minutes compiled with -O2, try ~500 million values */
for(int num_tested = 0; num_tested < 1000000; num_tested++) void testAllFloatPrintingPart3_LargerStill(void)
{ {
/* MINSTD pseudo-random number generator */ #if defined(UNITY_TEST_ALL_FLOATS_PRINT_OK) && defined(USING_OUTPUT_SPY)
a = (uint32_t)(((uint64_t)a * 48271u) % 2147483647u); AllFloatPrinting_Larger(1e25f, 3.40282347e+38f);
/* 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 #endif
} }
@@ -5252,20 +4893,35 @@ void testDoublePrinting(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY) #if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE(); TEST_IGNORE();
#else #else
TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.10046949999999999); TEST_ASSERT_EQUAL_PRINT_FLOATING("0.100469", 0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967295.999999); TEST_ASSERT_EQUAL_PRINT_FLOATING("4294967295.999999", 4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967295.9999995); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("4.29497e+09", 4294967296.0); TEST_ASSERT_EQUAL_PRINT_FLOATING("4.2949673e+09", 4294967296.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("1e+10", 9999999995.0); TEST_ASSERT_EQUAL_PRINT_FLOATING("1.0e+10", 9999999995.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.0072e+15", 9007199254740990.0); TEST_ASSERT_EQUAL_PRINT_FLOATING("9.00719925e+15", 9007199254740990.0);
TEST_ASSERT_EQUAL_PRINT_FLOATING("7e+100", 7.0e+100); TEST_ASSERT_EQUAL_PRINT_FLOATING("7.0e+100", 7.0e+100);
TEST_ASSERT_EQUAL_PRINT_FLOATING("3e+200", 3.0e+200); TEST_ASSERT_EQUAL_PRINT_FLOATING("3.0e+200", 3.0e+200);
TEST_ASSERT_EQUAL_PRINT_FLOATING("9.23457e+300", 9.23456789e+300); 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("-0.100469", -0.10046949999999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.29497e+09", -4294967295.999999); TEST_ASSERT_EQUAL_PRINT_FLOATING("-4294967295.999999", -4294967295.999999);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.29497e+09", -4294967295.9999995); TEST_ASSERT_EQUAL_PRINT_FLOATING("-4.2949673e+09", -4294967295.9999995);
TEST_ASSERT_EQUAL_PRINT_FLOATING("-7e+100", -7.0e+100); 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
#endif #endif
} }
@@ -5274,10 +4930,10 @@ void testDoublePrintingInfinityAndNaN(void)
#if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY) #if defined(UNITY_EXCLUDE_FLOAT_PRINT) || defined(UNITY_EXCLUDE_DOUBLE) || !defined(USING_OUTPUT_SPY)
TEST_IGNORE(); TEST_IGNORE();
#else #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 #endif
} }

View File

@@ -1,3 +0,0 @@
// msvc doesn't support weak-linking, so we need to define these functions.
void setUp(void) { }
void tearDown(void) { }

View File

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