Merge pull request #295 from zhindes/master

Support default __stdcall calling convention (/Gz) on Windows
This commit is contained in:
Max Bruckner 2018-09-21 19:23:31 +02:00 committed by GitHub
commit 3550a5553d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 99 additions and 73 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
* text=auto
/tests/inputs/* text eol=lf

View File

@ -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()

12
cJSON.c
View File

@ -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);
}

98
cJSON.h
View File

@ -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

2
test.c
View File

@ -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());

View File

@ -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}"

View File

@ -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();

View File

@ -186,7 +186,7 @@ static void cjson_compare_should_compare_objects(void)
false))
}
int main(void)
int CJSON_CDECL main(void)
{
UNITY_BEGIN();

View File

@ -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();

View File

@ -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));

View File

@ -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);

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"));
}
int main(void)
int CJSON_CDECL main(void)
{
UNITY_BEGIN();
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);
}
int main(void)
int CJSON_CDECL main(void)
{
/* initialize cJSON item */
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\"");
}
int main(void)
int CJSON_CDECL main(void)
{
/* initialize cJSON item */
memset(item, 0, sizeof(cJSON));

View File

@ -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));

View File

@ -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));

View File

@ -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();

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\",{}]");
}
int main(void)
int CJSON_CDECL main(void)
{
/* initialize cJSON item */
UNITY_BEGIN();

View File

@ -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();

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\":{}}");
}
int main(void)
int CJSON_CDECL main(void)
{
/* initialize cJSON item */
UNITY_BEGIN();

View File

@ -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();

View File

@ -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();

View File

@ -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();

3
tests/unity_setup.c Normal file
View File

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