cJSON

mirror of Dave's cJSON
git clone git://git.thc420.xyz/cJSON
Log | Files | Refs | README | LICENSE

commit 3550a5553d0298d251583229acf5768a045eb3b1
parent 86234db0959e7c1533948d825335a14e0dfabad5
Author: Max Bruckner <max@maxbruckner.de>
Date:   Fri, 21 Sep 2018 19:23:31 +0200

Merge pull request #295 from zhindes/master

Support default __stdcall calling convention (/Gz) on Windows
Diffstat:
A.gitattributes | 3+++
MCMakeLists.txt | 4++++
McJSON.c | 12++++++------
McJSON.h | 98+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mtest.c | 2+-
Mtests/CMakeLists.txt | 5++++-
Mtests/cjson_add.c | 12+++++++++---
Mtests/compare_tests.c | 2+-
Mtests/misc_tests.c | 4++--
Mtests/parse_array.c | 2+-
Mtests/parse_examples.c | 2+-
Mtests/parse_hex4.c | 2+-
Mtests/parse_number.c | 2+-
Mtests/parse_object.c | 2+-
Mtests/parse_string.c | 2+-
Mtests/parse_value.c | 2+-
Mtests/parse_with_opts.c | 2+-
Mtests/print_array.c | 2+-
Mtests/print_number.c | 2+-
Mtests/print_object.c | 2+-
Mtests/print_string.c | 2+-
Mtests/print_value.c | 2+-
Mtests/readme_examples.c | 2+-
Atests/unity_setup.c | 3+++
24 files changed, 100 insertions(+), 73 deletions(-)

diff --git a/.gitattributes b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto +/tests/inputs/* text eol=lf+ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -49,11 +49,15 @@ if (ENABLE_CUSTOM_COMPILER_FLAGS) -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() diff --git a/cJSON.c b/cJSON.c @@ -119,22 +119,22 @@ static int case_insensitive_strcmp(const unsigned char *string1, const unsigned typedef struct internal_hooks { - void *(*allocate)(size_t size); - void (*deallocate)(void *pointer); - void *(*reallocate)(void *pointer, size_t size); + void *(CJSON_CDECL *allocate)(size_t size); + void (CJSON_CDECL *deallocate)(void *pointer); + void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); } internal_hooks; #if defined(_MSC_VER) /* work around MSVC error C2322: '...' address of dillimport '...' is not static */ -static void *internal_malloc(size_t size) +static void * CJSON_CDECL internal_malloc(size_t size) { return malloc(size); } -static void internal_free(void *pointer) +static void CJSON_CDECL internal_free(void *pointer) { free(pointer); } -static void *internal_realloc(void *pointer, size_t size) +static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) { return realloc(pointer, size); } diff --git a/cJSON.h b/cJSON.h @@ -28,6 +28,56 @@ extern "C" { #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 */ #define CJSON_VERSION_MAJOR 1 #define CJSON_VERSION_MINOR 7 @@ -74,55 +124,13 @@ typedef struct cJSON typedef struct cJSON_Hooks { - void *(*malloc_fn)(size_t sz); - void (*free_fn)(void *ptr); + /* 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 *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); } cJSON_Hooks; 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. * This is to prevent stack overflows. */ #ifndef CJSON_NESTING_LIMIT diff --git a/test.c b/test.c @@ -256,7 +256,7 @@ static void create_objects(void) cJSON_Delete(root); } -int main(void) +int CJSON_CDECL main(void) { /* print the version */ printf("Version: %s\n", cJSON_Version()); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt @@ -1,5 +1,5 @@ if(ENABLE_CJSON_TEST) - add_library(unity "${CJSON_LIBRARY_TYPE}" unity/src/unity.c) + add_library(unity STATIC unity/src/unity.c) # Disable -Werror for Unity if (FLAG_SUPPORTED_Werror) @@ -72,6 +72,9 @@ if(ENABLE_CJSON_TEST) foreach(unity_test ${unity_tests}) add_executable("${unity_test}" "${unity_test}.c") + if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") + target_sources(${unity_test} PRIVATE unity_setup.c) + endif() target_link_libraries("${unity_test}" "${CJSON_LIB}" unity) if(MEMORYCHECK_COMMAND) add_test(NAME "${unity_test}" diff --git a/tests/cjson_add.c b/tests/cjson_add.c @@ -28,15 +28,21 @@ #include "unity/src/unity.h" #include "common.h" -static void *failing_malloc(size_t size) +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, - free + normal_free }; static void cjson_add_null_should_add_null(void) @@ -372,7 +378,7 @@ static void cjson_add_array_should_fail_on_allocation_failure(void) cJSON_Delete(root); } -int main(void) +int CJSON_CDECL main(void) { UNITY_BEGIN(); diff --git a/tests/compare_tests.c b/tests/compare_tests.c @@ -186,7 +186,7 @@ static void cjson_compare_should_compare_objects(void) false)) } -int main(void) +int CJSON_CDECL main(void) { UNITY_BEGIN(); diff --git a/tests/misc_tests.c b/tests/misc_tests.c @@ -410,7 +410,7 @@ static void cjson_functions_shouldnt_crash_with_null_pointers(void) cJSON_Delete(item); } -static void *failing_realloc(void *pointer, size_t size) +static void * CJSON_CDECL failing_realloc(void *pointer, size_t size) { (void)size; (void)pointer; @@ -527,7 +527,7 @@ static void cjson_add_item_to_object_should_not_use_after_free_when_string_is_al cJSON_Delete(object); } -int main(void) +int CJSON_CDECL main(void) { UNITY_BEGIN(); diff --git a/tests/parse_array.c b/tests/parse_array.c @@ -152,7 +152,7 @@ static void parse_array_should_not_parse_non_arrays(void) assert_not_array("\"[]hello world!\n\""); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ memset(item, 0, sizeof(cJSON)); diff --git a/tests/parse_examples.c b/tests/parse_examples.c @@ -195,7 +195,7 @@ static void test12_should_not_be_parsed(void) } } -int main(void) +int CJSON_CDECL main(void) { UNITY_BEGIN(); RUN_TEST(file_test1_should_be_parsed_and_printed); diff --git a/tests/parse_hex4.c b/tests/parse_hex4.c @@ -64,7 +64,7 @@ static void parse_hex4_should_parse_mixed_case(void) TEST_ASSERT_EQUAL_INT(0xBEEF, parse_hex4((const unsigned char*)"BEEF")); } -int main(void) +int CJSON_CDECL main(void) { UNITY_BEGIN(); RUN_TEST(parse_hex4_should_parse_all_combinations); diff --git a/tests/parse_number.c b/tests/parse_number.c @@ -96,7 +96,7 @@ static void parse_number_should_parse_negative_reals(void) assert_parse_number("-123e-128", 0, -123e-128); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ memset(item, 0, sizeof(cJSON)); diff --git a/tests/parse_object.c b/tests/parse_object.c @@ -162,7 +162,7 @@ static void parse_object_should_not_parse_non_objects(void) assert_not_object("\"{}hello world!\n\""); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ memset(item, 0, sizeof(cJSON)); diff --git a/tests/parse_string.c b/tests/parse_string.c @@ -119,7 +119,7 @@ static void parse_string_should_parse_bug_94(void) reset(item); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item and error pointer */ memset(item, 0, sizeof(cJSON)); diff --git a/tests/parse_value.c b/tests/parse_value.c @@ -96,7 +96,7 @@ static void parse_value_should_parse_object(void) reset(item); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ memset(item, 0, sizeof(cJSON)); diff --git a/tests/parse_with_opts.c b/tests/parse_with_opts.c @@ -97,7 +97,7 @@ static void parse_with_opts_should_parse_utf8_bom(void) cJSON_Delete(without_bom); } -int main(void) +int CJSON_CDECL main(void) { UNITY_BEGIN(); diff --git a/tests/print_array.c b/tests/print_array.c @@ -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\",{}]"); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ UNITY_BEGIN(); diff --git a/tests/print_number.c b/tests/print_number.c @@ -89,7 +89,7 @@ static void print_number_should_print_non_number(void) /* assert_print_number("null", -INFTY); */ } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ UNITY_BEGIN(); diff --git a/tests/print_object.c b/tests/print_object.c @@ -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\":{}}"); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ UNITY_BEGIN(); diff --git a/tests/print_string.c b/tests/print_string.c @@ -65,7 +65,7 @@ static void print_string_should_print_utf8(void) assert_print_string("\"ü猫慕\"", "ü猫慕"); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ UNITY_BEGIN(); diff --git a/tests/print_value.c b/tests/print_value.c @@ -90,7 +90,7 @@ static void print_value_should_print_object(void) assert_print_value("{}"); } -int main(void) +int CJSON_CDECL main(void) { /* initialize cJSON item */ UNITY_BEGIN(); diff --git a/tests/readme_examples.c b/tests/readme_examples.c @@ -246,7 +246,7 @@ static void supports_full_hd_should_check_for_full_hd_support(void) TEST_ASSERT_FALSE(supports_full_hd(monitor_without_hd)); } -int main(void) +int CJSON_CDECL main(void) { UNITY_BEGIN(); diff --git a/tests/unity_setup.c b/tests/unity_setup.c @@ -0,0 +1,3 @@ +// msvc doesn't support weak-linking, so we need to define these functions. +void setUp(void) { } +void tearDown(void) { }