This commit is contained in:
Alexandre B 2024-08-16 04:25:06 -04:00
parent ece548252b
commit 9b7cafa1b4
230 changed files with 37222 additions and 261 deletions

View File

@ -1,6 +1,6 @@
{
"C_Cpp.intelliSenseEngine": "default",
"idf.adapterTargetName": "esp32",
"idf.adapterTargetName": "esp32c3",
"idf.customExtraPaths": "c:\\Users\\alex\\.espressif\\tools\\tools\\xtensa-esp-elf-gdb\\14.2_20240403\\xtensa-esp-elf-gdb\\bin;c:\\Users\\alex\\.espressif\\tools\\tools\\riscv32-esp-elf-gdb\\14.2_20240403\\riscv32-esp-elf-gdb\\bin;c:\\Users\\alex\\.espressif\\tools\\tools\\xtensa-esp-elf\\esp-13.2.0_20230928\\xtensa-esp-elf\\bin;c:\\Users\\alex\\.espressif\\tools\\tools\\riscv32-esp-elf\\esp-13.2.0_20230928\\riscv32-esp-elf\\bin;c:\\Users\\alex\\.espressif\\tools\\tools\\esp32ulp-elf\\2.35_20220830\\esp32ulp-elf\\bin;c:\\Users\\alex\\.espressif\\tools\\tools\\cmake\\3.24.0\\bin;c:\\Users\\alex\\.espressif\\tools\\tools\\openocd-esp32\\v0.12.0-esp32-20240318\\openocd-esp32\\bin;c:\\Users\\alex\\.espressif\\tools\\tools\\ninja\\1.11.1;c:\\Users\\alex\\.espressif\\tools\\tools\\idf-exe\\1.0.3;c:\\Users\\alex\\.espressif\\tools\\tools\\ccache\\4.8\\ccache-4.8-windows-x86_64;c:\\Users\\alex\\.espressif\\tools\\tools\\dfu-util\\0.11\\dfu-util-0.11-win64;c:\\Users\\alex\\.espressif\\tools\\tools\\esp-rom-elfs\\20230320",
"idf.customExtraVars": {
"OPENOCD_SCRIPTS": "c:\\Users\\alex\\.espressif\\tools\\tools\\openocd-esp32\\v0.12.0-esp32-20240318/openocd-esp32/share/openocd/scripts",
@ -10,7 +10,7 @@
"idf.espIdfPathWin": "C:\\Users\\alex\\esp\\v5.2.2\\esp-idf",
"idf.espAdfPathWin": "C:\\Users\\alex\\.espressif\\esp-adf",
"idf.openOcdConfigs": [
"board/esp32-wrover-kit-3.3v.cfg"
"board/esp32c3-builtin.cfg"
],
"idf.portWin": "COM27",
"idf.pythonBinPathWin": "c:\\Users\\alex\\.espressif\\tools\\python_env\\idf5.2_py3.11_env\\Scripts\\python.exe",

View File

@ -0,0 +1,20 @@
set(CMAKE_ASM_COMPILER "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc.exe")
set(CMAKE_ASM_COMPILER_ARG1 "")
set(CMAKE_AR "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ar.exe")
set(CMAKE_ASM_COMPILER_AR "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc-ar.exe")
set(CMAKE_RANLIB "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ranlib.exe")
set(CMAKE_ASM_COMPILER_RANLIB "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc-ranlib.exe")
set(CMAKE_LINKER "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ld.exe")
set(CMAKE_MT "")
set(CMAKE_ASM_COMPILER_LOADED 1)
set(CMAKE_ASM_COMPILER_ID "GNU")
set(CMAKE_ASM_COMPILER_VERSION "")
set(CMAKE_ASM_COMPILER_ENV_VAR "ASM")
set(CMAKE_ASM_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_ASM_LINKER_PREFERENCE 0)

View File

@ -1,4 +1,4 @@
set(CMAKE_C_COMPILER "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc.exe")
set(CMAKE_C_COMPILER "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc.exe")
set(CMAKE_C_COMPILER_ARG1 "")
set(CMAKE_C_COMPILER_ID "GNU")
set(CMAKE_C_COMPILER_VERSION "13.2.0")
@ -21,11 +21,11 @@ set(CMAKE_C_SIMULATE_VERSION "")
set(CMAKE_AR "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-ar.exe")
set(CMAKE_C_COMPILER_AR "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc-ar.exe")
set(CMAKE_RANLIB "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-ranlib.exe")
set(CMAKE_C_COMPILER_RANLIB "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc-ranlib.exe")
set(CMAKE_LINKER "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-ld.exe")
set(CMAKE_AR "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ar.exe")
set(CMAKE_C_COMPILER_AR "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc-ar.exe")
set(CMAKE_RANLIB "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ranlib.exe")
set(CMAKE_C_COMPILER_RANLIB "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc-ranlib.exe")
set(CMAKE_LINKER "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ld.exe")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCC 1)
set(CMAKE_C_COMPILER_LOADED 1)
@ -66,7 +66,7 @@ endif()
set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include-fixed;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/sys-include;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include")
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;c;nosys;c;gcc")
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib")
set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include-fixed;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/sys-include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include")
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;c;nosys;c;gcc;gcc;c;nosys")
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib")
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

View File

@ -0,0 +1,83 @@
set(CMAKE_CXX_COMPILER "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-g++.exe")
set(CMAKE_CXX_COMPILER_ARG1 "")
set(CMAKE_CXX_COMPILER_ID "GNU")
set(CMAKE_CXX_COMPILER_VERSION "13.2.0")
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
set(CMAKE_CXX_COMPILER_WRAPPER "")
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "17")
set(CMAKE_CXX_EXTENSIONS_COMPUTED_DEFAULT "ON")
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23")
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
set(CMAKE_CXX23_COMPILE_FEATURES "cxx_std_23")
set(CMAKE_CXX_PLATFORM_ID "")
set(CMAKE_CXX_SIMULATE_ID "")
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "")
set(CMAKE_CXX_SIMULATE_VERSION "")
set(CMAKE_AR "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ar.exe")
set(CMAKE_CXX_COMPILER_AR "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc-ar.exe")
set(CMAKE_RANLIB "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ranlib.exe")
set(CMAKE_CXX_COMPILER_RANLIB "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc-ranlib.exe")
set(CMAKE_LINKER "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-ld.exe")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCXX 1)
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_CXX_ABI_COMPILED TRUE)
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
foreach (lang C OBJC OBJCXX)
if (CMAKE_${lang}_COMPILER_ID_RUN)
foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
endforeach()
endif()
endforeach()
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "4")
set(CMAKE_CXX_COMPILER_ABI "ELF")
set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN")
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")
if(CMAKE_CXX_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_CXX_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
endif()
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "")
endif()
set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0/backward;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include-fixed;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/sys-include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include")
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc;c;nosys;c;gcc;gcc;c;nosys")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

View File

@ -3,7 +3,7 @@ set(CMAKE_HOST_SYSTEM_NAME "Windows")
set(CMAKE_HOST_SYSTEM_VERSION "10.0.22621")
set(CMAKE_HOST_SYSTEM_PROCESSOR "AMD64")
include("C:/Users/alex/esp/v5.2.2/esp-idf/tools/cmake/toolchain-esp32.cmake")
include("C:/Users/alex/esp/v5.2.2/esp-idf/tools/cmake/toolchain-esp32c3.cmake")
set(CMAKE_SYSTEM "Generic")
set(CMAKE_SYSTEM_NAME "Generic")

View File

@ -0,0 +1,826 @@
/* This source file must have a .cpp extension so that all C++ compilers
recognize the extension without flags. Borland does not know .cxx for
example. */
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__COMO__)
# define COMPILER_ID "Comeau"
/* __COMO_VERSION__ = VRR */
# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
#elif defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_CC)
# define COMPILER_ID "SunPro"
# if __SUNPRO_CC >= 0x5100
/* __SUNPRO_CC = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# endif
#elif defined(__HP_aCC)
# define COMPILER_ID "HP"
/* __HP_aCC = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
#elif defined(__DECCXX)
# define COMPILER_ID "Compaq"
/* __DECCXX_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__open_xl__) && defined(__clang__)
# define COMPILER_ID "IBMClang"
# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
# define COMPILER_ID "XL"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
# define COMPILER_ID "LCC"
# define COMPILER_VERSION_MAJOR DEC(1)
# if defined(__LCC__)
# define COMPILER_VERSION_MINOR DEC(__LCC__- 100)
# endif
# if defined(__LCC_MINOR__)
# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
# endif
# if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define SIMULATE_ID "GNU"
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_ID "GNU"
# if defined(__GNUC__)
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# else
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(_ADI_COMPILER)
# define COMPILER_ID "ADSP"
#if defined(__VERSIONNUM__)
/* __VERSIONNUM__ = 0xVVRRPPTT */
# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
# elif defined(_ADI_COMPILER)
# define PLATFORM_ID "ADSP"
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
# elif defined(__ADSPSHARC__)
# define ARCHITECTURE_ID "SHARC"
# elif defined(__ADSPBLACKFIN__)
# define ARCHITECTURE_ID "Blackfin"
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L
# if defined(__INTEL_CXX11_MODE__)
# if defined(__cpp_aggregate_nsdmi)
# define CXX_STD 201402L
# else
# define CXX_STD 201103L
# endif
# else
# define CXX_STD 199711L
# endif
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
# define CXX_STD _MSVC_LANG
#else
# define CXX_STD __cplusplus
#endif
const char* info_language_standard_default = "INFO" ":" "standard_default["
#if CXX_STD > 202002L
"23"
#elif CXX_STD > 201703L
"20"
#elif CXX_STD >= 201703L
"17"
#elif CXX_STD >= 201402L
"14"
#elif CXX_STD >= 201103L
"11"
#else
"98"
#endif
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__)
"ON"
#else
"OFF"
#endif
"]";
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_standard_default[argc];
require += info_language_extensions_default[argc];
(void)argv;
return require;
}

View File

@ -1,12 +1,24 @@
The target system is: Generic - -
The host system is: Windows - 10.0.22621 - AMD64
Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded.
Compiler: C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc.exe
Build flags: -mlongcalls;-Wno-frame-address;;-fno-builtin-memcpy;-fno-builtin-memset;-fno-builtin-bzero;-fno-builtin-stpcpy;-fno-builtin-strncpy
Compiler: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-gcc.exe
Build flags: -march=rv32imc_zicsr_zifencei;
Id flags:
The output was:
0
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-closer.o): in function `_close_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/closer.c:47:(.text+0x14): warning: _close is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-lseekr.o): in function `_lseek_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/lseekr.c:49:(.text+0x18): warning: _lseek is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-readr.o): in function `_read_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/readr.c:49:(.text+0x18): warning: _read is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-writer.o): in function `_write_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/writer.c:49:(.text+0x18): warning: _write is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-fclose.o): in function `fclose':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/stdio/fclose.c:125:(.text+0x118): warning: __getreent is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-findfp.o): in function `__sfp':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/stdio/findfp.c:180:(.text+0x1ee): warning: pthread_setcancelstate is not implemented and will always fail
Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out"
@ -14,12 +26,24 @@ Compilation of the C compiler identification source "CMakeCCompilerId.c" produce
The C compiler identification is GNU, found in "C:/Users/alex/github/ESP-Nodes/ESP32-C3_Table-Lamp/build/CMakeFiles/3.24.0/CompilerIdC/a.out"
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
Compiler: C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-g++.exe
Build flags: -mlongcalls;-Wno-frame-address;;-fno-builtin-memcpy;-fno-builtin-memset;-fno-builtin-bzero;-fno-builtin-stpcpy;-fno-builtin-strncpy
Compiler: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/riscv32-esp-elf-g++.exe
Build flags: -march=rv32imc_zicsr_zifencei;
Id flags:
The output was:
0
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-closer.o): in function `_close_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/closer.c:47:(.text+0x14): warning: _close is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-lseekr.o): in function `_lseek_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/lseekr.c:49:(.text+0x18): warning: _lseek is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-readr.o): in function `_read_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/readr.c:49:(.text+0x18): warning: _read is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-writer.o): in function `_write_r':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/reent/writer.c:49:(.text+0x18): warning: _write is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-fclose.o): in function `fclose':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/stdio/fclose.c:125:(.text+0x118): warning: __getreent is not implemented and will always fail
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32\libc.a(libc_a-findfp.o): in function `__sfp':
/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/newlib/newlib/libc/stdio/findfp.c:180:(.text+0x1ee): warning: pthread_setcancelstate is not implemented and will always fail
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out"
@ -27,7 +51,7 @@ Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" p
The CXX compiler identification is GNU, found in "C:/Users/alex/github/ESP-Nodes/ESP32-C3_Table-Lamp/build/CMakeFiles/3.24.0/CompilerIdCXX/a.out"
Checking whether the ASM compiler is GNU using "--version" matched "(GNU assembler)|(GCC)|(Free Software Foundation)":
xtensa-esp-elf-gcc.exe (crosstool-NG esp-13.2.0_20230928) 13.2.0
riscv32-esp-elf-gcc.exe (crosstool-NG esp-13.2.0_20230928) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@ -35,340 +59,352 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Detecting C compiler ABI info compiled with the following output:
Change Dir: C:/Users/alex/github/ESP-Nodes/ESP32-C3_Table-Lamp/build/CMakeFiles/CMakeTmp
Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_6ab77 && [1/2] Building C object CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj
Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_993dc && [1/2] Building C object CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj
Using built-in specs.
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-gcc.exe
Target: xtensa-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-gcc.exe
Target: riscv32-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928)
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_6ab77.dir/'
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/cc1.exe -quiet -v -imultilib esp32 -iprefix C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCCompilerABI.c -quiet -dumpdir CMakeFiles/cmTC_6ab77.dir/ -dumpbase CMakeCCompilerABI.c.c -dumpbase-ext .c -mdynconfig=xtensa_esp32.so -mlongcalls -Wno-frame-address -version -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy -o C:\Users\alex\AppData\Local\Temp\ccIjC1x2.s
GNU C17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (xtensa-esp-elf)
COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_993dc.dir/'
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/cc1.exe -quiet -v -imultilib rv32imc_zicsr_zifencei/ilp32 -iprefix C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCCompilerABI.c -quiet -dumpdir CMakeFiles/cmTC_993dc.dir/ -dumpbase CMakeCCompilerABI.c.c -dumpbase-ext .c -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -march=rv32imc_zicsr_zifencei -version -o C:\Users\alex\AppData\Local\Temp\ccYhojUf.s
GNU C17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (riscv32-esp-elf)
compiled by GNU C version 6.3.0 20170516, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include"
#include "..." search starts here:
#include <...> search starts here:
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include
End of search list.
Compiler executable checksum: a7185c8b5363aeb8f378896e00d5f636
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_6ab77.dir/'
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/as.exe --traditional-format --longcalls --dynconfig=xtensa_esp32.so -o CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj C:\Users\alex\AppData\Local\Temp\ccIjC1x2.s
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.'
[2/2] Linking C executable cmTC_6ab77
Compiler executable checksum: 96e036bc63b64a7cb69af58289e1d9da
COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_993dc.dir/'
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/as.exe -v --traditional-format -march=rv32imc_zicsr_zifencei -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -o CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj C:\Users\alex\AppData\Local\Temp\ccYhojUf.s
GNU assembler version 2.41 (riscv32-esp-elf) using BFD version (crosstool-NG esp-13.2.0_20230928) 2.41
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/
COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.'
[2/2] Linking C executable cmTC_993dc
Using built-in specs.
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-gcc.exe
COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe
Target: xtensa-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
Reading specs from C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/nosys.specs
rename spec link_gcc_c_sequence to nosys_link_gcc_c_sequence
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-gcc.exe
COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe
Target: riscv32-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928)
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'cmTC_6ab77' '-dumpdir' 'cmTC_6ab77.'
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\ccvykpCb.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc --dynconfig=xtensa_esp32.so -o cmTC_6ab77 C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj -lgcc -lc -lnosys -lc -lgcc C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'cmTC_6ab77' '-dumpdir' 'cmTC_6ab77.'
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/
COLLECT_GCC_OPTIONS='-nostartfiles' '-march=rv32imc_zicsr_zifencei' '-specs=nosys.specs' '-v' '-o' 'cmTC_993dc' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'cmTC_993dc.'
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\ccTiX7Xi.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -melf32lriscv -o cmTC_993dc -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj -lgcc -lc -lnosys -lc -lgcc --start-group -lgcc -lc -lnosys --end-group
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: warning: cannot find entry symbol _start; defaulting to 00010074
COLLECT_GCC_OPTIONS='-nostartfiles' '-march=rv32imc_zicsr_zifencei' '-specs=nosys.specs' '-v' '-o' 'cmTC_993dc' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'cmTC_993dc.'
Parsed C implicit include dir info from above output: rv=done
found start of include info
found start of implicit include info
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include]
end of search list found
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include-fixed]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/sys-include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include]
implicit include dirs: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include-fixed;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/sys-include;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include-fixed]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/sys-include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include]
implicit include dirs: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include-fixed;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/sys-include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include]
Parsed C implicit link information from above output:
link line regex: [^( *|.*[/\])(xtensa-esp32-elf-ld\.exe|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
link line regex: [^( *|.*[/\])(riscv32-esp-elf-ld\.exe|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
ignore line: [Change Dir: C:/Users/alex/github/ESP-Nodes/ESP32-C3_Table-Lamp/build/CMakeFiles/CMakeTmp]
ignore line: []
ignore line: [Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_6ab77 && [1/2] Building C object CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj]
ignore line: [Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_993dc && [1/2] Building C object CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-gcc.exe]
ignore line: [Target: xtensa-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-gcc.exe]
ignore line: [Target: riscv32-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib]
ignore line: [gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928) ]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_6ab77.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/cc1.exe -quiet -v -imultilib esp32 -iprefix C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCCompilerABI.c -quiet -dumpdir CMakeFiles/cmTC_6ab77.dir/ -dumpbase CMakeCCompilerABI.c.c -dumpbase-ext .c -mdynconfig=xtensa_esp32.so -mlongcalls -Wno-frame-address -version -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy -o C:\Users\alex\AppData\Local\Temp\ccIjC1x2.s]
ignore line: [GNU C17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (xtensa-esp-elf)]
ignore line: [COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_993dc.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/cc1.exe -quiet -v -imultilib rv32imc_zicsr_zifencei/ilp32 -iprefix C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCCompilerABI.c -quiet -dumpdir CMakeFiles/cmTC_993dc.dir/ -dumpbase CMakeCCompilerABI.c.c -dumpbase-ext .c -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -march=rv32imc_zicsr_zifencei -version -o C:\Users\alex\AppData\Local\Temp\ccYhojUf.s]
ignore line: [GNU C17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (riscv32-esp-elf)]
ignore line: [ compiled by GNU C version 6.3.0 20170516 GMP version 6.2.1 MPFR version 4.1.0 MPC version 1.2.1 isl version isl-0.24-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include"]
ignore line: [#include "..." search starts here:]
ignore line: [#include <...> search starts here:]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include]
ignore line: [End of search list.]
ignore line: [Compiler executable checksum: a7185c8b5363aeb8f378896e00d5f636]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_6ab77.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/as.exe --traditional-format --longcalls --dynconfig=xtensa_esp32.so -o CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj C:\Users\alex\AppData\Local\Temp\ccIjC1x2.s]
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.']
ignore line: [[2/2] Linking C executable cmTC_6ab77]
ignore line: [Compiler executable checksum: 96e036bc63b64a7cb69af58289e1d9da]
ignore line: [COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_993dc.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/as.exe -v --traditional-format -march=rv32imc_zicsr_zifencei -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -o CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj C:\Users\alex\AppData\Local\Temp\ccYhojUf.s]
ignore line: [GNU assembler version 2.41 (riscv32-esp-elf) using BFD version (crosstool-NG esp-13.2.0_20230928) 2.41]
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.']
ignore line: [[2/2] Linking C executable cmTC_993dc]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-gcc.exe]
ignore line: [COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe]
ignore line: [Target: xtensa-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [Reading specs from C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/nosys.specs]
ignore line: [rename spec link_gcc_c_sequence to nosys_link_gcc_c_sequence]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-gcc.exe]
ignore line: [COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe]
ignore line: [Target: riscv32-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib]
ignore line: [gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928) ]
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'cmTC_6ab77' '-dumpdir' 'cmTC_6ab77.']
link line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\ccvykpCb.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc --dynconfig=xtensa_esp32.so -o cmTC_6ab77 C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj -lgcc -lc -lnosys -lc -lgcc C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/collect2.exe] ==> ignore
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-nostartfiles' '-march=rv32imc_zicsr_zifencei' '-specs=nosys.specs' '-v' '-o' 'cmTC_993dc' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'cmTC_993dc.']
link line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\ccTiX7Xi.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -melf32lriscv -o cmTC_993dc -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj -lgcc -lc -lnosys -lc -lgcc --start-group -lgcc -lc -lnosys --end-group]
arg [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/collect2.exe] ==> ignore
arg [-plugin] ==> ignore
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/liblto_plugin.dll] ==> ignore
arg [-plugin-opt=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe] ==> ignore
arg [-plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\ccvykpCb.res] ==> ignore
arg [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/liblto_plugin.dll] ==> ignore
arg [-plugin-opt=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe] ==> ignore
arg [-plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\ccTiX7Xi.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lnosys] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [--dynconfig=xtensa_esp32.so] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lnosys] ==> ignore
arg [-melf32lriscv] ==> ignore
arg [-o] ==> ignore
arg [cmTC_6ab77] ==> ignore
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib]
arg [CMakeFiles/cmTC_6ab77.dir/CMakeCCompilerABI.c.obj] ==> ignore
arg [cmTC_993dc] ==> ignore
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib]
arg [CMakeFiles/cmTC_993dc.dir/CMakeCCompilerABI.c.obj] ==> ignore
arg [-lgcc] ==> lib [gcc]
arg [-lc] ==> lib [c]
arg [-lnosys] ==> lib [nosys]
arg [-lc] ==> lib [c]
arg [-lgcc] ==> lib [gcc]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32/crt0.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib]
implicit libs: [gcc;c;nosys;c;gcc]
implicit objs: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32/crt0.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o]
implicit dirs: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib]
arg [--start-group] ==> ignore
arg [-lgcc] ==> lib [gcc]
arg [-lc] ==> lib [c]
arg [-lnosys] ==> lib [nosys]
arg [--end-group] ==> ignore
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib]
implicit libs: [gcc;c;nosys;c;gcc;gcc;c;nosys]
implicit objs: []
implicit dirs: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib]
implicit fwks: []
Detecting CXX compiler ABI info compiled with the following output:
Change Dir: C:/Users/alex/github/ESP-Nodes/ESP32-C3_Table-Lamp/build/CMakeFiles/CMakeTmp
Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_14dda && [1/2] Building CXX object CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj
Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_fd978 && [1/2] Building CXX object CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj
Using built-in specs.
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-g++.exe
Target: xtensa-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-g++.exe
Target: riscv32-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928)
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_14dda.dir/'
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/cc1plus.exe -quiet -v -imultilib esp32 -iprefix C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_14dda.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mdynconfig=xtensa_esp32.so -mlongcalls -Wno-frame-address -version -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy -o C:\Users\alex\AppData\Local\Temp\cchZvEVV.s
GNU C++17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (xtensa-esp-elf)
COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_fd978.dir/'
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/cc1plus.exe -quiet -v -imultilib rv32imc_zicsr_zifencei/ilp32 -iprefix C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_fd978.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -march=rv32imc_zicsr_zifencei -version -o C:\Users\alex\AppData\Local\Temp\ccTISOmS.s
GNU C++17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (riscv32-esp-elf)
compiled by GNU C version 6.3.0 20170516, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/backward"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/backward"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include"
ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include"
#include "..." search starts here:
#include <...> search starts here:
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/backward
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/backward
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include
End of search list.
Compiler executable checksum: 7accc3f4dea0b1ef90bd5b8fb39b4353
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_14dda.dir/'
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/as.exe --traditional-format --longcalls --dynconfig=xtensa_esp32.so -o CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj C:\Users\alex\AppData\Local\Temp\cchZvEVV.s
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.'
[2/2] Linking CXX executable cmTC_14dda
Compiler executable checksum: c3899898cbd00b593a05a0e9a2f92cb0
COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_fd978.dir/'
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/as.exe -v --traditional-format -march=rv32imc_zicsr_zifencei -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -o CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj C:\Users\alex\AppData\Local\Temp\ccTISOmS.s
GNU assembler version 2.41 (riscv32-esp-elf) using BFD version (crosstool-NG esp-13.2.0_20230928) 2.41
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/
COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.'
[2/2] Linking CXX executable cmTC_fd978
Using built-in specs.
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-g++.exe
COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe
Target: xtensa-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
Reading specs from C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/nosys.specs
rename spec link_gcc_c_sequence to nosys_link_gcc_c_sequence
COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-g++.exe
COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe
Target: riscv32-esp-elf
Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928)
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'cmTC_14dda' '-dumpdir' 'cmTC_14dda.'
C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\cc1Kp5F4.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc --dynconfig=xtensa_esp32.so -o cmTC_14dda C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj -lstdc++ -lm -lgcc -lc -lnosys -lc -lgcc C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o
COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'cmTC_14dda' '-dumpdir' 'cmTC_14dda.'
COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/
LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/
COLLECT_GCC_OPTIONS='-nostartfiles' '-march=rv32imc_zicsr_zifencei' '-specs=nosys.specs' '-v' '-o' 'cmTC_fd978' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'cmTC_fd978.'
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\cc7DwSaY.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -melf32lriscv -o cmTC_fd978 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj -lstdc++ -lm -lgcc -lc -lnosys -lc -lgcc --start-group -lgcc -lc -lnosys --end-group
C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld.exe: warning: cannot find entry symbol _start; defaulting to 00010074
COLLECT_GCC_OPTIONS='-nostartfiles' '-march=rv32imc_zicsr_zifencei' '-specs=nosys.specs' '-v' '-o' 'cmTC_fd978' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'cmTC_fd978.'
Parsed CXX implicit include dir info from above output: rv=done
found start of include info
found start of implicit include info
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/backward]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include]
add: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/backward]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include]
add: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include]
end of search list found
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/backward] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/backward]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include-fixed]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/sys-include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include]
implicit include dirs: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/backward;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/include-fixed;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/sys-include;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/backward] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0/backward]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include-fixed]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/sys-include]
collapse include dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include]
implicit include dirs: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include/c++/13.2.0/backward;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/include-fixed;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/sys-include;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/include]
Parsed CXX implicit link information from above output:
link line regex: [^( *|.*[/\])(xtensa-esp32-elf-ld\.exe|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
link line regex: [^( *|.*[/\])(riscv32-esp-elf-ld\.exe|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
ignore line: [Change Dir: C:/Users/alex/github/ESP-Nodes/ESP32-C3_Table-Lamp/build/CMakeFiles/CMakeTmp]
ignore line: []
ignore line: [Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_14dda && [1/2] Building CXX object CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj]
ignore line: [Run Build Command(s):C:/Users/alex/.espressif/tools/tools/ninja/1.11.1/ninja.exe cmTC_fd978 && [1/2] Building CXX object CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-g++.exe]
ignore line: [Target: xtensa-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-g++.exe]
ignore line: [Target: riscv32-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib]
ignore line: [gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928) ]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_14dda.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/cc1plus.exe -quiet -v -imultilib esp32 -iprefix C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_14dda.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mdynconfig=xtensa_esp32.so -mlongcalls -Wno-frame-address -version -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy -o C:\Users\alex\AppData\Local\Temp\cchZvEVV.s]
ignore line: [GNU C++17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (xtensa-esp-elf)]
ignore line: [COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_fd978.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/cc1plus.exe -quiet -v -imultilib rv32imc_zicsr_zifencei/ilp32 -iprefix C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/ C:/Users/alex/.espressif/tools/tools/cmake/3.24.0/share/cmake-3.24/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_fd978.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -march=rv32imc_zicsr_zifencei -version -o C:\Users\alex\AppData\Local\Temp\ccTISOmS.s]
ignore line: [GNU C++17 (crosstool-NG esp-13.2.0_20230928) version 13.2.0 (riscv32-esp-elf)]
ignore line: [ compiled by GNU C version 6.3.0 20170516 GMP version 6.2.1 MPFR version 4.1.0 MPC version 1.2.1 isl version isl-0.24-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/backward"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/../../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/backward"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include"]
ignore line: [ignoring duplicate directory "C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/../../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include"]
ignore line: [#include "..." search starts here:]
ignore line: [#include <...> search starts here:]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/xtensa-esp-elf/esp32]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include/c++/13.2.0/backward]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/include-fixed]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/sys-include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/riscv32-esp-elf/rv32imc_zicsr_zifencei/ilp32]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include/c++/13.2.0/backward]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/include-fixed]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/sys-include]
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/include]
ignore line: [End of search list.]
ignore line: [Compiler executable checksum: 7accc3f4dea0b1ef90bd5b8fb39b4353]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_14dda.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/as.exe --traditional-format --longcalls --dynconfig=xtensa_esp32.so -o CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj C:\Users\alex\AppData\Local\Temp\cchZvEVV.s]
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-dumpdir' 'CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.']
ignore line: [[2/2] Linking CXX executable cmTC_14dda]
ignore line: [Compiler executable checksum: c3899898cbd00b593a05a0e9a2f92cb0]
ignore line: [COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_fd978.dir/']
ignore line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/as.exe -v --traditional-format -march=rv32imc_zicsr_zifencei -march=rv32imc_zicsr_zifencei -mabi=ilp32 -misa-spec=20191213 -o CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj C:\Users\alex\AppData\Local\Temp\ccTISOmS.s]
ignore line: [GNU assembler version 2.41 (riscv32-esp-elf) using BFD version (crosstool-NG esp-13.2.0_20230928) 2.41]
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-march=rv32imc_zicsr_zifencei' '-v' '-o' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj' '-c' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.']
ignore line: [[2/2] Linking CXX executable cmTC_fd978]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\xtensa-esp-elf\esp-13.2.0_20230928\xtensa-esp-elf\bin\xtensa-esp-elf-g++.exe]
ignore line: [COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe]
ignore line: [Target: xtensa-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=xtensa-esp-elf --prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/xtensa-esp-elf/xtensa-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [Reading specs from C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/nosys.specs]
ignore line: [rename spec link_gcc_c_sequence to nosys_link_gcc_c_sequence]
ignore line: [COLLECT_GCC=C:\Users\alex\.espressif\tools\tools\riscv32-esp-elf\esp-13.2.0_20230928\riscv32-esp-elf\bin\riscv32-esp-elf-g++.exe]
ignore line: [COLLECT_LTO_WRAPPER=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe]
ignore line: [Target: riscv32-esp-elf]
ignore line: [Configured with: /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-host_w64-mingw32 --target=riscv32-esp-elf --prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --exec_prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf --with-local-prefix=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf --with-headers=/builds/idf/crosstool-NG/builds/riscv32-esp-elf/riscv32-esp-elf/include --with-newlib --enable-threads=no --disable-shared --with-arch=rv32gc --with-abi=ilp32 --with-pkgversion='crosstool-NG esp-13.2.0_20230928' --disable-__cxa_atexit --enable-cxx-flags=-ffunction-sections --disable-libgomp --disable-libmudflap --disable-libmpx --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx-verbose --with-gmp=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpfr=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-mpc=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --with-isl=/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/riscv32-esp-elf/buildtools/complibs-host --enable-lto --enable-target-optspace --without-long-double-128 --disable-nls --enable-multiarch --enable-languages=c,c++ --disable-libstdcxx-verbose --enable-threads=posix --enable-gcov-custom-rtio --enable-libstdcxx-time=yes --with-gnu-ld]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib]
ignore line: [gcc version 13.2.0 (crosstool-NG esp-13.2.0_20230928) ]
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-mdynconfig=xtensa_esp32.so' '-mlongcalls' '-Wno-frame-address' '-fno-builtin-memcpy' '-fno-builtin-memset' '-fno-builtin-bzero' '-fno-builtin-stpcpy' '-fno-builtin-strncpy' '-v' '-o' 'cmTC_14dda' '-dumpdir' 'cmTC_14dda.']
link line: [ C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\cc1Kp5F4.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc --dynconfig=xtensa_esp32.so -o cmTC_14dda C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj -lstdc++ -lm -lgcc -lc -lnosys -lc -lgcc C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o ]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/collect2.exe] ==> ignore
ignore line: [COMPILER_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/]
ignore line: [LIBRARY_PATH=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/]
ignore line: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-nostartfiles' '-march=rv32imc_zicsr_zifencei' '-specs=nosys.specs' '-v' '-o' 'cmTC_fd978' '-mabi=ilp32' '-misa-spec=20191213' '-march=rv32imc_zicsr_zifencei' '-dumpdir' 'cmTC_fd978.']
link line: [ C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/collect2.exe -plugin C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/liblto_plugin.dll -plugin-opt=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\cc7DwSaY.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lnosys -melf32lriscv -o cmTC_fd978 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0 -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc -LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj -lstdc++ -lm -lgcc -lc -lnosys -lc -lgcc --start-group -lgcc -lc -lnosys --end-group]
arg [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/collect2.exe] ==> ignore
arg [-plugin] ==> ignore
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/liblto_plugin.dll] ==> ignore
arg [-plugin-opt=C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/13.2.0/lto-wrapper.exe] ==> ignore
arg [-plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\cc1Kp5F4.res] ==> ignore
arg [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/liblto_plugin.dll] ==> ignore
arg [-plugin-opt=C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../libexec/gcc/riscv32-esp-elf/13.2.0/lto-wrapper.exe] ==> ignore
arg [-plugin-opt=-fresolution=C:\Users\alex\AppData\Local\Temp\cc7DwSaY.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lnosys] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [--dynconfig=xtensa_esp32.so] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lnosys] ==> ignore
arg [-melf32lriscv] ==> ignore
arg [-o] ==> ignore
arg [cmTC_14dda] ==> ignore
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc]
arg [-LC:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib] ==> dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib]
arg [CMakeFiles/cmTC_14dda.dir/CMakeCXXCompilerABI.cpp.obj] ==> ignore
arg [cmTC_fd978] ==> ignore
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc]
arg [-LC:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib] ==> dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib]
arg [CMakeFiles/cmTC_fd978.dir/CMakeCXXCompilerABI.cpp.obj] ==> ignore
arg [-lstdc++] ==> lib [stdc++]
arg [-lm] ==> lib [m]
arg [-lgcc] ==> lib [gcc]
@ -376,21 +412,19 @@ Parsed CXX implicit link information from above output:
arg [-lnosys] ==> lib [nosys]
arg [-lc] ==> lib [c]
arg [-lgcc] ==> lib [gcc]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o]
arg [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o] ==> obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/crt0.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32/crt0.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o]
collapse obj [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/esp32] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc]
collapse library dir [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib] ==> [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib]
implicit libs: [stdc++;m;gcc;c;nosys;c;gcc]
implicit objs: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32/crt0.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crti.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtbegin.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtend.o;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32/crtn.o]
implicit dirs: [C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0/esp32;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib/esp32;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc/xtensa-esp-elf/13.2.0;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/lib/gcc;C:/Users/alex/.espressif/tools/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/lib]
arg [--start-group] ==> ignore
arg [-lgcc] ==> lib [gcc]
arg [-lc] ==> lib [c]
arg [-lnosys] ==> lib [nosys]
arg [--end-group] ==> ignore
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc]
collapse library dir [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/lib] ==> [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib]
implicit libs: [stdc++;m;gcc;c;nosys;c;gcc;gcc;c;nosys]
implicit objs: []
implicit dirs: [C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib/rv32imc_zicsr_zifencei/ilp32;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc/riscv32-esp-elf/13.2.0;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/lib/gcc;C:/Users/alex/.espressif/tools/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/riscv32-esp-elf/lib]
implicit fwks: []

View File

@ -0,0 +1,81 @@
dependencies:
espressif/cbor:
component_hash: 440f4ee4504841cc9b4f3a8ef755776a612ac9dace355514c68b999868f990ff
source:
service_url: https://api.components.espressif.com/
type: service
version: 0.6.0~1
espressif/esp_diag_data_store:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\esp-insights\components\esp_diag_data_store
type: local
version: 1.0.1
espressif/esp_diagnostics:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\esp-insights\components\esp_diagnostics
type: local
version: 1.0.1
espressif/esp_insights:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\esp-insights\components\esp_insights
type: local
version: 1.0.1
espressif/esp_rainmaker:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\esp_rainmaker
type: local
version: 1.0.0
espressif/esp_schedule:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\esp_schedule
type: local
version: 1.1.0
espressif/esp_secure_cert_mgr:
component_hash: a20007d67e65a000670ab77e45d7554c943eb8dcb0abeada0a57dd9adac3a703
source:
service_url: https://api.components.espressif.com/
type: service
version: 2.4.1
espressif/json_generator:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\json_generator
type: local
version: 1.1.1
espressif/json_parser:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\json_parser
type: local
version: 1.0.3
espressif/mdns:
component_hash: 31117d76cae83a6d83ffd7f035f6fdae5bd05b914fc30b641afeb208b84de19a
source:
service_url: https://api.components.espressif.com/
type: service
version: 1.3.2
espressif/rmaker_common:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\esp-insights\components\rmaker_common
type: local
version: 1.4.3
idf:
component_hash: null
source:
type: idf
version: 5.2.2
jsmn:
component_hash: null
source:
path: C:\Users\alex\.espressif\tools\esp-rainmaker\components\jsmn
type: local
version: 1.1.0
manifest_hash: 441db01601b7ff7fea63ef2fed13beeeb802e924d04240d0318baa30336fd9ff
target: esp32c3
version: 1.0.0

View File

@ -0,0 +1 @@
440f4ee4504841cc9b4f3a8ef755776a612ac9dace355514c68b999868f990ff

View File

@ -0,0 +1,22 @@
idf_component_register(SRCS "tinycbor/src/cborencoder_close_container_checked.c"
"tinycbor/src/cborencoder.c"
"tinycbor/src/cborencoder_float.c"
"tinycbor/src/cborerrorstrings.c"
"tinycbor/src/cborparser_dup_string.c"
"tinycbor/src/cborparser.c"
"tinycbor/src/cborparser_float.c"
"tinycbor/src/cborpretty_stdio.c"
"tinycbor/src/cborpretty.c"
"tinycbor/src/cbortojson.c"
"tinycbor/src/cborvalidation.c"
"tinycbor/src/open_memstream.c"
INCLUDE_DIRS "port/include"
PRIV_INCLUDE_DIRS "tinycbor/src")
# for open_memstream.c
set_source_files_properties(tinycbor/src/open_memstream.c PROPERTIES COMPILE_DEFINITIONS "__linux__")
# workaround for the fact that we are passing -ffreestanding to Clang
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
target_compile_options(${COMPONENT_LIB} PRIVATE "-U __STDC_HOSTED__")
endif()

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Intel Corporation
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.

View File

@ -0,0 +1,13 @@
Concise Binary Object Representation (CBOR) Library
---------------------------------------------------
To build TinyCBOR:
make
If you want to change the compiler or pass extra compiler flags:
make CC=clang CFLAGS="-m32 -Oz" LDFLAGS="-m32"
Documentation: https://intel.github.io/tinycbor/current/

View File

@ -0,0 +1,6 @@
dependencies:
idf:
version: '>=4.3'
description: 'CBOR: Concise Binary Object Representation Library'
url: https://github.com/espressif/idf-extra-components/tree/master/cbor
version: 0.6.0~1

View File

@ -0,0 +1,2 @@
#include "../../tinycbor/src/cbor.h"
#include "../../tinycbor/src/cborjson.h"

View File

@ -0,0 +1,28 @@
version: 0.6-build-{build}
pull_requests:
do_not_increment_build_number: true
image:
- Visual Studio 2017
- Visual Studio 2019
install:
- cmd: >-
if /i "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x86) & (set QTDIR=C:\Qt\5.13\msvc2017)
if /i "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" (call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64) & (set QTDIR=C:\Qt\6.1\msvc2019_64)
set path=%PATH%;%QTDIR%\bin
build_script:
- cmd: >-
nmake -f Makefile.nmake -nologo CFLAGS="-W3 -Os -MDd"
cd tests
qmake CONFIG-=release CONFIG+=debug
nmake -nologo -s
test_script:
- cmd: >-
nmake -s -nologo TESTARGS=-silent check
artifacts:
- path: lib\tinycbor.lib
deploy: off

View File

@ -0,0 +1,4 @@
.tag export-subst
.gitignore export-ignore
.gitattributes export-ignore
.appveyor.yml text

View File

@ -0,0 +1,81 @@
# Frequent generated files
callgrind.out.*
pcviewer.cfg
*~
*.a
*.la
*.core
*.d
*.dylib
*.moc
*.o
*.obj
*.orig
*.swp
*.rej
*.so
*.so.*
*.pbxuser
*.mode1
*.mode1v3
*_pch.h.cpp
*_resource.rc
.#*
*.*#
core
.qmake.cache
.qmake.stash
.qmake.vars
.device.vars
tags
.DS_Store
*.debug
Makefile*
*.prl
*.app
*.pro.user*
*.qmlproject.user*
*.gcov
*.gcda
*.gcno
*.flc
.*.swp
tinycbor.pc
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.exe.embed.manifest
*.exe_manifest.rc
*.exe_manifest.res
# MinGW generated files
*.Debug
*.Release
# INTEGRITY generated files
*.gpj
*.int
*.ael
*.dla
*.dnm
*.dep
*.map
bin
doc
lib
src/cjson
src/doxygen.log
!/Makefile
.config

View File

@ -0,0 +1 @@
$Format:%H$

View File

@ -0,0 +1,92 @@
env:
- BUILD_DOCS=false
jobs:
include:
- # only build docs on main
if: branch = main
env: BUILD_DOCS=true
language: cpp
matrix:
include:
- os: linux
dist: xenial
addons:
apt:
sources:
- sourceline: 'ppa:beineri/opt-qt-5.12.1-xenial'
packages:
- qt512base valgrind
- doxygen
env:
- QMAKESPEC=linux-g++
- EVAL="CC=gcc && CXX=g++"
- CFLAGS="-Os"
- LDFLAGS="-Wl,--no-undefined -lm"
- QMAKEFLAGS="-config release"
- QT_NO_CPU_FEATURE=rdrnd
- os: linux
dist: xenial
addons:
apt:
sources:
- sourceline: 'ppa:beineri/opt-qt-5.12.1-xenial'
packages:
- qt512base
env:
- QMAKESPEC=linux-clang
- EVAL="CC=clang && CXX=clang++"
- CFLAGS="-Oz"
- LDFLAGS="-Wl,--no-undefined -lm"
- QMAKEFLAGS="-config release"
- MAKEFLAGS=-s
- TESTARGS=-silent
- os: linux
dist: xenial
env:
- QMAKESPEC=linux-gcc-freestanding
- EVAL="CXX=false"
- CFLAGS="-ffreestanding -Os"
- LDFLAGS="-Wl,--no-undefined -lm"
- os: linux
dist: xenial
env:
- QMAKESPEC=linux-gcc-no-math
- EVAL="CXX=false && touch src/math.h src/float.h"
- CFLAGS="-ffreestanding -DCBOR_NO_FLOATING_POINT -Os"
- LDFLAGS="-Wl,--no-undefined"
- LDLIBS=""
- os: osx
env:
- QMAKESPEC=macx-clang
- CFLAGS="-Oz"
- QMAKEFLAGS="-config debug"
- MAKEFLAGS=-s
- TESTARGS=-silent
- PATH=/usr/local/opt/qt5/bin:$PATH
install:
- if [ "${TRAVIS_OS_NAME}" != "linux" ]; then
brew update;
brew install qt5;
fi
script:
- PATH=`echo /opt/qt*/bin`:$PATH
- eval "$EVAL"
- make -s -f Makefile.configure configure | tee .config
- make -k
CFLAGS="$CFLAGS -march=native -g1 -Wall -Wextra -Werror"
CPPFLAGS="-DNDEBUG -DCBOR_ENCODER_WRITER_CONTROL=-1 -DCBOR_PARSER_READER_CONTROL=-1"
lib/libtinycbor.a
- size lib/libtinycbor.a | tee sizes
- make -s clean
- make -k
CFLAGS="$CFLAGS -O0 -g"
LDFLAGS="$LDFLAGS" ${LDLIBS+LDLIBS="$LDLIBS"}
- grep -q freestanding-pass .config || make
QMAKEFLAGS="$QMAKEFLAGS QMAKE_CXX=$CXX"
tests/Makefile
- grep -q freestanding-pass .config ||
(cd tests && make TESTARGS=-silent check -k
TESTRUNNER=`which valgrind 2>/dev/null`)
- make -s clean
- ! [ $BUILD_DOCS ] || ./scripts/update-docs.sh

View File

@ -0,0 +1,49 @@
PROJECT_NAME = "TinyCBOR $(VERSION) API"
OUTPUT_DIRECTORY = ../doc
ABBREVIATE_BRIEF =
SHORT_NAMES = YES
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = YES
TAB_SIZE = 8
ALIASES = "value=\arg \c"
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = NO
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
GENERATE_TODOLIST = NO
GENERATE_TESTLIST = NO
GENERATE_BUGLIST = NO
GENERATE_DEPRECATEDLIST= NO
SHOW_USED_FILES = NO
WARN_IF_UNDOCUMENTED = NO
WARN_LOGFILE = doxygen.log
INPUT = .
FILE_PATTERNS = *.h \
*.c \
*.dox
EXCLUDE_PATTERNS = *_p.h
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = YES
IGNORE_PREFIX = cbor_ \
Cbor
HTML_TIMESTAMP = NO
GENERATE_HTMLHELP = YES
GENERATE_CHI = YES
BINARY_TOC = YES
TOC_EXPAND = YES
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
SEARCHENGINE = NO
GENERATE_LATEX = NO
COMPACT_LATEX = YES
MACRO_EXPANSION = YES
PREDEFINED = DOXYGEN \
CBOR_INLINE_API=
CLASS_DIAGRAMS = NO
CLASS_GRAPH = NO
COLLABORATION_GRAPH = NO
GROUP_GRAPHS = NO
INCLUDE_GRAPH = NO
INCLUDED_BY_GRAPH = NO
GRAPHICAL_HIERARCHY = NO
DIRECTORY_GRAPH = NO

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Intel Corporation
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.

View File

@ -0,0 +1,250 @@
# Variables:
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
pkgconfigdir = $(libdir)/pkgconfig
CFLAGS = -Wall -Wextra
LDFLAGS_GCSECTIONS = -Wl,--gc-sections
LDFLAGS += $(if $(gc_sections-pass),$(LDFLAGS_GCSECTIONS))
LDLIBS = -lm
GIT_ARCHIVE = git archive --prefix="$(PACKAGE)/" -9
INSTALL = install
INSTALL_DATA = $(INSTALL) -m 644
INSTALL_PROGRAM = $(INSTALL) -m 755
QMAKE = qmake
MKDIR = mkdir -p
RMDIR = rmdir
SED = sed
# Our sources
TINYCBOR_HEADERS = src/cbor.h src/cborjson.h src/tinycbor-version.h
TINYCBOR_FREESTANDING_SOURCES = \
src/cborerrorstrings.c \
src/cborencoder.c \
src/cborencoder_close_container_checked.c \
src/cborencoder_float.c \
src/cborparser.c \
src/cborparser_float.c \
src/cborpretty.c \
#
CBORDUMP_SOURCES = tools/cbordump/cbordump.c
BUILD_SHARED = $(shell file -L /bin/sh 2>/dev/null | grep -q ELF && echo 1)
BUILD_STATIC = 1
ifneq ($(BUILD_STATIC),1)
ifneq ($(BUILD_SHARED),1)
$(error error: BUILD_STATIC and BUILD_SHARED can not be both disabled)
endif
endif
INSTALL_TARGETS += $(bindir)/cbordump
ifeq ($(BUILD_SHARED),1)
BINLIBRARY=lib/libtinycbor.so
INSTALL_TARGETS += $(libdir)/libtinycbor.so.$(VERSION)
endif
ifeq ($(BUILD_STATIC),1)
BINLIBRARY=lib/libtinycbor.a
INSTALL_TARGETS += $(libdir)/libtinycbor.a
endif
INSTALL_TARGETS += $(pkgconfigdir)/tinycbor.pc
INSTALL_TARGETS += $(TINYCBOR_HEADERS:src/%=$(includedir)/tinycbor/%)
# setup VPATH
MAKEFILE := $(lastword $(MAKEFILE_LIST))
SRCDIR := $(dir $(MAKEFILE))
VPATH = $(SRCDIR):$(SRCDIR)/src
# Our version
GIT_DIR := $(strip $(shell git -C $(SRCDIR). rev-parse --git-dir 2> /dev/null))
VERSION = $(shell cat $(SRCDIR)VERSION)
SOVERSION = $(shell cut -f1-2 -d. $(SRCDIR)VERSION)
PACKAGE = tinycbor-$(VERSION)
# Check that QMAKE is Qt 5
ifeq ($(origin QMAKE),file)
check_qmake = $(strip $(shell $(1) -query QT_VERSION 2>/dev/null | cut -b1))
ifneq ($(call check_qmake,$(QMAKE)),5)
QMAKE := qmake -qt5
ifneq ($(call check_qmake,$(QMAKE)),5)
QMAKE := qmake-qt5
ifneq ($(call check_qmake,$(QMAKE)),5)
QMAKE := @echo >&2 $(MAKEFILE): Cannot find a Qt 5 qmake; false
endif
endif
endif
endif
-include .config
ifeq ($(wildcard .config),)
$(info .config file not yet created)
endif
ifeq ($(freestanding-pass),1)
TINYCBOR_SOURCES = $(TINYCBOR_FREESTANDING_SOURCES)
else
TINYCBOR_SOURCES = \
$(TINYCBOR_FREESTANDING_SOURCES) \
src/cborparser_dup_string.c \
src/cborpretty_stdio.c \
src/cbortojson.c \
src/cborvalidation.c \
#
# if open_memstream is unavailable on the system, try to implement our own
# version using funopen or fopencookie
ifeq ($(open_memstream-pass),)
ifeq ($(funopen-pass)$(fopencookie-pass),)
CFLAGS += -DWITHOUT_OPEN_MEMSTREAM
ifeq ($(wildcard .config),.config)
$(warning warning: funopen and fopencookie unavailable, open_memstream can not be implemented and conversion to JSON will not work properly!)
endif
else
TINYCBOR_SOURCES += src/open_memstream.c
endif
endif
endif
# json2cbor depends on an external library (cjson)
ifneq ($(cjson-pass)$(system-cjson-pass),)
JSON2CBOR_SOURCES = tools/json2cbor/json2cbor.c
INSTALL_TARGETS += $(bindir)/json2cbor
ifeq ($(system-cjson-pass),1)
LDFLAGS_CJSON = -lcjson
else
JSON2CBOR_SOURCES += src/cjson/cJSON.c
json2cbor_CCFLAGS = -I$(SRCDIR)src/cjson
endif
endif
# Rules
all: .config \
$(if $(subst 0,,$(BUILD_STATIC)),lib/libtinycbor.a) \
$(if $(subst 0,,$(BUILD_SHARED)),lib/libtinycbor.so) \
$(if $(freestanding-pass),,bin/cbordump) \
tinycbor.pc
all: $(if $(JSON2CBOR_SOURCES),bin/json2cbor)
check: tests/Makefile | $(BINLIBRARY)
$(MAKE) -C tests check
silentcheck: | $(BINLIBRARY)
TESTARGS=-silent $(MAKE) -f $(MAKEFILE) -s check
configure: .config
.config: Makefile.configure
$(MAKE) -f $(SRCDIR)Makefile.configure OUT='>&9' configure 9> $@
lib/libtinycbor-freestanding.a: $(TINYCBOR_FREESTANDING_SOURCES:.c=.o)
@$(MKDIR) -p lib
$(AR) cqs $@ $^
lib/libtinycbor.a: $(TINYCBOR_SOURCES:.c=.o)
@$(MKDIR) -p lib
$(AR) cqs $@ $^
lib/libtinycbor.so: $(TINYCBOR_SOURCES:.c=.pic.o)
@$(MKDIR) -p lib
$(CC) -shared -Wl,-soname,libtinycbor.so.$(SOVERSION) -o lib/libtinycbor.so.$(VERSION) $(LDFLAGS) $^ $(LDLIBS)
cd lib ; ln -sf libtinycbor.so.$(VERSION) libtinycbor.so ; ln -sf libtinycbor.so.$(VERSION) libtinycbor.so.$(SOVERSION)
bin/cbordump: $(CBORDUMP_SOURCES:.c=.o) $(BINLIBRARY)
@$(MKDIR) -p bin
$(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS)
bin/json2cbor: $(JSON2CBOR_SOURCES:.c=.o) $(BINLIBRARY)
@$(MKDIR) -p bin
$(CC) -o $@ $(LDFLAGS) $^ $(LDFLAGS_CJSON) $(LDLIBS)
tinycbor.pc: tinycbor.pc.in
$(SED) > $@ < $< \
-e 's,@prefix@,$(prefix),' \
-e 's,@exec_prefix@,$(exec_prefix),' \
-e 's,@libdir@,$(libdir),' \
-e 's,@includedir@,$(includedir),' \
-e 's,@version@,$(VERSION),'
tests/Makefile: tests/tests.pro
$(QMAKE) $(QMAKEFLAGS) -o $@ $<
$(PACKAGE).tar.gz: | .git
GIT_DIR=$(SRCDIR).git $(GIT_ARCHIVE) --format=tar.gz -o "$(PACKAGE).tar.gz" HEAD
$(PACKAGE).zip: | .git
GIT_DIR=$(SRCDIR).git $(GIT_ARCHIVE) --format=zip -o "$(PACKAGE).zip" HEAD
$(DESTDIR)$(libdir)/%: lib/%
$(INSTALL) -d $(@D)
$(INSTALL_DATA) $< $@
$(DESTDIR)$(bindir)/%: bin/%
$(INSTALL) -d $(@D)
$(INSTALL_PROGRAM) $< $@
$(DESTDIR)$(pkgconfigdir)/%: %
$(INSTALL) -d $(@D)
$(INSTALL_DATA) $< $@
$(DESTDIR)$(includedir)/tinycbor/%: src/%
$(INSTALL) -d $(@D)
$(INSTALL_DATA) $< $@
install-strip:
$(MAKE) -f $(MAKEFILE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
install: $(INSTALL_TARGETS:%=$(DESTDIR)%)
ifeq ($(BUILD_SHARED),1)
ln -sf libtinycbor.so.$(VERSION) $(DESTDIR)$(libdir)/libtinycbor.so
ln -sf libtinycbor.so.$(VERSION) $(DESTDIR)$(libdir)/libtinycbor.so.$(SOVERSION)
endif
uninstall:
$(RM) $(INSTALL_TARGETS:%=$(DESTDIR)%)
$(RM) $(DESTDIR)$(libdir)/libtinycbor.so
$(RM) $(DESTDIR)$(libdir)/libtinycbor.so.$(SOVERSION)
mostlyclean:
$(RM) $(TINYCBOR_SOURCES:.c=.o)
$(RM) $(TINYCBOR_SOURCES:.c=.pic.o)
$(RM) $(CBORDUMP_SOURCES:.c=.o)
clean: mostlyclean
$(RM) bin/cbordump
$(RM) bin/json2cbor
$(RM) lib/libtinycbor.a
$(RM) lib/libtinycbor-freestanding.a
$(RM) tinycbor.pc
$(RM) lib/libtinycbor.so*
test -e tests/Makefile && $(MAKE) -C tests clean || :
distclean: clean
test -e tests/Makefile && $(MAKE) -C tests distclean || :
docs:
cd $(SRCDIR)src && VERSION=$(VERSION) doxygen $(SRCDIR)/../Doxyfile
dist: $(PACKAGE).tar.gz $(PACKAGE).zip
distcheck: .git
-$(RM) -r $${TMPDIR-/tmp}/tinycbor-distcheck
GIT_DIR=$(SRCDIR).git git archive --prefix=tinycbor-distcheck/ --format=tar HEAD | tar -xf - -C $${TMPDIR-/tmp}
cd $${TMPDIR-/tmp}/tinycbor-distcheck && $(MAKE) silentcheck
$(RM) -r $${TMPDIR-/tmp}/tinycbor-distcheck
tag: distcheck
@cd $(SRCDIR). && perl scripts/maketag.pl
.PHONY: all check silentcheck configure install uninstall
.PHONY: mostlyclean clean distclean
.PHONY: docs dist distcheck release
.SECONDARY:
cflags := $(CPPFLAGS) -I$(SRCDIR)src
cflags += -std=gnu99 $(CFLAGS) \
-Werror=incompatible-pointer-types \
-Werror=implicit-function-declaration \
-Werror=int-conversion
%.o: %.c
@test -d $(@D) || $(MKDIR) $(@D)
$(CC) $(cflags) $($(basename $(notdir $@))_CCFLAGS) -c -o $@ $<
%.pic.o: %.c
@test -d $(@D) || $(MKDIR) $(@D)
$(CC) $(cflags) -fPIC $($(basename $(notdir $@))_CCFLAGS) -c -o $@ $<
-include src/*.d

View File

@ -0,0 +1,13 @@
Concise Binary Object Representation (CBOR) Library
---------------------------------------------------
To build TinyCBOR:
make
If you want to change the compiler or pass extra compiler flags:
make CC=clang CFLAGS="-m32 -Oz" LDFLAGS="-m32"
Documentation: https://intel.github.io/tinycbor/current/

View File

@ -0,0 +1,25 @@
==== To Do list for libcbor ====
=== General ===
* API review
* Benchmark
* Write examples
** Simple decoder
** Decoder to JSON
** Windowed encoding/decoding (limited memory)
=== Encoder ===
* Write API docs
* Add API for creating indeterminate-length arrays and maps
* Add API for creating indeterminate-length strings
* Add API for relaxing doubles to floats and to integers
* Add length-checking of the sub-containers (#ifndef CBOR_ENCODER_NO_USER_CHECK)
* Decide how to indicate number of bytes needed
** Suggestion: return negative number from the functions
=== Decoder ===
* Write functions not yet implemented
* Add API for stream-decoding strings
* Add API for checking known tags and simple types
* (unlikely) Add API for checking the pairing of a tag and the tagged type
* Write tests for error conditions
* Fuzzy-test the decoder

View File

@ -0,0 +1,2 @@
TEMPLATE = subdirs
SUBDIRS = simplereader.pro

View File

@ -0,0 +1,185 @@
#include "../src/cbor.h"
#include <sys/stat.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static uint8_t *readfile(const char *fname, size_t *size)
{
struct stat st;
FILE *f = fopen(fname, "rb");
if (!f)
return NULL;
if (fstat(fileno(f), &st) == -1)
return NULL;
uint8_t *buf = malloc(st.st_size);
if (buf == NULL)
return NULL;
*size = fread(buf, st.st_size, 1, f) == 1 ? st.st_size : 0;
fclose(f);
return buf;
}
static void indent(int nestingLevel)
{
while (nestingLevel--)
printf(" ");
}
static void dumpbytes(const uint8_t *buf, size_t len)
{
printf("\"");
while (len--)
printf("\\x%02X", *buf++);
printf("\"");
}
static CborError dumprecursive(CborValue *it, int nestingLevel)
{
while (!cbor_value_at_end(it)) {
CborError err;
CborType type = cbor_value_get_type(it);
indent(nestingLevel);
switch (type) {
case CborArrayType:
case CborMapType: {
// recursive type
CborValue recursed;
assert(cbor_value_is_container(it));
puts(type == CborArrayType ? "Array[" : "Map[");
err = cbor_value_enter_container(it, &recursed);
if (err)
return err; // parse error
err = dumprecursive(&recursed, nestingLevel + 1);
if (err)
return err; // parse error
err = cbor_value_leave_container(it, &recursed);
if (err)
return err; // parse error
indent(nestingLevel);
puts("]");
continue;
}
case CborIntegerType: {
int64_t val;
cbor_value_get_int64(it, &val); // can't fail
printf("%lld\n", (long long)val);
break;
}
case CborByteStringType: {
uint8_t *buf;
size_t n;
err = cbor_value_dup_byte_string(it, &buf, &n, it);
if (err)
return err; // parse error
dumpbytes(buf, n);
puts("");
free(buf);
continue;
}
case CborTextStringType: {
char *buf;
size_t n;
err = cbor_value_dup_text_string(it, &buf, &n, it);
if (err)
return err; // parse error
printf("\"%s\"\n", buf);
free(buf);
continue;
}
case CborTagType: {
CborTag tag;
cbor_value_get_tag(it, &tag); // can't fail
printf("Tag(%lld)\n", (long long)tag);
break;
}
case CborSimpleType: {
uint8_t type;
cbor_value_get_simple_type(it, &type); // can't fail
printf("simple(%u)\n", type);
break;
}
case CborNullType:
puts("null");
break;
case CborUndefinedType:
puts("undefined");
break;
case CborBooleanType: {
bool val;
cbor_value_get_boolean(it, &val); // can't fail
puts(val ? "true" : "false");
break;
}
case CborDoubleType: {
double val;
if (false) {
float f;
case CborFloatType:
cbor_value_get_float(it, &f);
val = f;
} else {
cbor_value_get_double(it, &val);
}
printf("%g\n", val);
break;
}
case CborHalfFloatType: {
uint16_t val;
cbor_value_get_half_float(it, &val);
printf("__f16(%04x)\n", val);
break;
}
case CborInvalidType:
assert(false); // can't happen
break;
}
err = cbor_value_advance_fixed(it);
if (err)
return err;
}
return CborNoError;
}
int main(int argc, char **argv)
{
if (argc != 2) {
puts("simplereader <filename>");
return 1;
}
size_t length;
uint8_t *buf = readfile(argv[1], &length);
if (!buf) {
perror("readfile");
return 1;
}
CborParser parser;
CborValue it;
CborError err = cbor_parser_init(buf, length, 0, &parser, &it);
if (!err)
err = dumprecursive(&it, 0);
free(buf);
if (err) {
fprintf(stderr, "CBOR parsing failure at offset %ld: %s\n",
it.ptr - buf, cbor_error_string(err));
return 1;
}
return 0;
}

View File

@ -0,0 +1,3 @@
CONFIG -= qt
SOURCES = simplereader.c
include(../src/src.pri)

View File

@ -0,0 +1,91 @@
#!perl
use strict;
sub run(@) {
open PROC, "-|", @_ or die("Cannot run $_[0]: $!");
my @out;
while (<PROC>) {
chomp;
push @out, $_;
}
close PROC;
return @out;
}
my @tags = run("git", "tag");
my @v = run("git", "show", "HEAD:VERSION");
my $v = $v[0];
my $tagfile = ".git/TAG_EDITMSG";
open TAGFILE, ">", $tagfile
or die("Cannot create file for editing tag message: $!");
select TAGFILE;
print "TinyCBOR release $v\n";
print "\n";
print "# Write something nice about this release here\n";
# Do we have a commit template?
my @result = run("git", "config", "--get", "commit.template");
if (scalar @result) {
open TEMPLATE, "<", $result[0];
map { print $_; } <TEMPLATE>;
close TEMPLATE;
}
print "\n";
print "# Commit log\n";
open LOG, "-|", "git", "shortlog", "-e", "--no-merges", "--not", @tags;
map { print "# $_"; } <LOG>;
close LOG;
print "# Header diff:\n";
open DIFF, "-|", "git", "diff", "HEAD", "--not", @tags, "--", 'src/*.h', ':!*_p.h';
map { print "# $_"; } <DIFF>;
close DIFF;
select STDOUT;
close TAGFILE;
# Run the editor.
# We use system so that stdin, stdout and stderr are forwarded.
@result = run("git", "var", "GIT_EDITOR");
@result = ($result[0], $tagfile);
system @result;
exit ($? >> 8) if $?;
# Create the tag
# Also using system so that hte user can see the output.
system("git", "tag", "-a", "-F", $tagfile, split(' ', $ENV{GITTAGFLAGS}), "v$v");
exit ($? >> 8) if $?;
# Update the version files for the next patch release
@v = split(/\./, $v);
if (scalar @v < 3) {
push @v, '1';
} else {
++$v[-1];
}
$v = join('.', @v);
open VERSION, ">", "VERSION" or die("Cannot open VERSION file: $!");
print VERSION "$v\n";
close VERSION;
open VERSION, ">", "src/tinycbor-version.h" or die("Cannot open src/tinycbor-version.h: $!");
print VERSION "#define TINYCBOR_VERSION_MAJOR ", $v[0], "\n";
print VERSION "#define TINYCBOR_VERSION_MINOR ", $v[1], "\n";
print VERSION "#define TINYCBOR_VERSION_PATCH ", $v[2], "\n";
close VERSION;
if (open APPVEYORYML, "<", ".appveyor.yml") {
my @contents = map {
s/^version:.*/version: $v[0].$v[1].$v[2]-build-{build}/;
$_;
} <APPVEYORYML>;
close APPVEYORYML;
open APPVEYORYML, ">", ".appveyor.yml";
print APPVEYORYML join('', @contents);
close APPVEYORYML;
}
# Print summary
print "Tag created and next versions updated.\n";
print "Don't forget to create the docs.\n" if $v[2] == 1;

View File

@ -0,0 +1,52 @@
#!/bin/sh -ex
tuple="$TRAVIS_BRANCH${TRAVIS_TAG:+tag:$TRAVIS_TAG},$TRAVIS_PULL_REQUEST"
case "$tuple" in
dev,false|main,false|tag:*)
;;
*)
exit 0
;;
esac
V=`cut -f1-2 -d. <VERSION`
git fetch origin gh-pages
# Fail if the library sizes file isn't present
test -r sizes
# Run doxygen (maybe)
if [ -n "${TRAVIS_TAG-$FORCE_DOCS}" ] && make -s docs 2>/dev/null; then
git checkout -b gh-pages FETCH_HEAD
if [ -d "$V" ]; then
mv "$V" "old-$V"
fi
mv doc/html "$V"
git add -A "$V"
else
git checkout -b gh-pages FETCH_HEAD
mkdir -p "$V"
fi
# Update the symlink for the branch name
rm -f "./$TRAVIS_BRANCH"
ln -s "$V" "$TRAVIS_BRANCH"
git add "./$TRAVIS_BRANCH"
# Update the library sizes file
# (will fail if the release build failed)
mkdir -p "library_sizes/$TRAVIS_BRANCH"
mv sizes "library_sizes/$TRAVIS_BRANCH/$QMAKESPEC"
(cd "library_sizes/$TRAVIS_BRANCH/";
for f in *; do echo "$f:"; cat "$f" ; done) > "$V/library_sizes.txt"
git add "library_sizes/$TRAVIS_BRANCH" "$V/library_sizes.txt"
git diff --cached -U0 "$V/library_sizes.txt"
# Commit everything
if git commit -m "Update docs for $V (Travis build $TRAVIS_BUILD_NUMBER)
Matching commit $TRAVIS_COMMIT:
$TRAVIS_COMMIT_MESSAGE"; then
# We've made a commit, push it
set +x
url=`git config --get remote.origin.url | sed -e s,://github,://$GITHUB_AUTH@github,`
git push "$url" @:gh-pages
fi

View File

@ -0,0 +1,123 @@
/****************************************************************************
**
** Copyright (C) 2016 Intel Corporation
**
** 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.
**
****************************************************************************/
/**
* \mainpage
* The TinyCBOR $(VERSION) library is a small CBOR encoder and decoder library,
* optimized for very fast operation with very small footprint. The main encoder
* and decoder functions do not allocate memory.
*
* TinyCBOR is divided into the following groups of functions and structures:
* - \ref CborGlobals
* - \ref CborEncoding
* - \ref CborParsing
* - \ref CborPretty
* - \ref CborToJson
*/
/**
* \file <cbor.h>
* The <cbor.h> is the main header in TinyCBOR and defines the constants used by most functions
* as well as the structures for encoding (CborEncoder) and decoding (CborValue).
*
* \sa <cborjson.h>
*/
/**
* \file <cborjson.h>
* The <cborjson.h> file contains the routines that are used to convert a CBOR
* data stream into JSON.
*
* \sa <cbor.h>
*/
/**
* \defgroup CborGlobals Global constants
* \brief Constants used by all TinyCBOR function groups.
*/
/**
* \addtogroup CborGlobals
* @{
*/
/**
* \var size_t CborIndefiniteLength
*
* This variable is a constant used to indicate that the length of the map or
* array is not yet determined. It is used in functions
* cbor_encoder_create_map() and cbor_encoder_create_array()
*/
/**
* \enum CborType
* The CborType enum contains the types known to TinyCBOR.
*
* \value CborIntegerType Type is an integer value, positive, negative or zero
* \value CborByteStringType Type is a string of arbitrary raw bytes
* \value CborTextStringType Type is a text string encoded in UTF-8
* \value CborArrayType Type is a CBOR array
* \value CborMapType Type is a CBOR map (an associative container with key and value pairs)
* \value CborTagType Type is a CBOR tag (a 64-bit integer describing the item that follows, see CborKnownTags)
* \value CborSimpleType Type is one of the CBOR Simple Types
* \value CborBooleanType Type is a boolean (true or false)
* \value CborNullType Type encodes a null
* \value CborUndefinedType Type encodes an undefined value
* \value CborHalfFloatType Type is an IEEE 754 half precision (16-bit) floating point type
* \value CborFloatType Type is an IEEE 754 single precision (32-bit) floating point type
* \value CborDoubleType Type is an IEEE 754 double precision (64-bit) floating point type
* \value CborInvalidType Type is not valid (this value is used to indicate error conditions)
*/
/**
* \enum CborKnownTags
* The CborKnownTags enum contains known tags specified in RFC 7049, for use by the application.
* TinyCBOR does not usually interpret the meaning of these tags and does not add them to the
* output stream, unless specifically instructed to do so in functions for that effect.
*
* \value CborDateTimeStringTag Text string contains a date-time encoded in RFC 3339 format, "YYYY-MM-DD hh:mm:ss+zzzz"
* \value CborUnixTime_tTag Number is a Unix time_t quantity, the number of seconds since 1970-01-01 midnight UTC
* \value CborPositiveBignumTag Item is a CBOR byte string encoding a positive integer of arbitrary precision
* \value CborNegativeBignumTag Item is a CBOR byte string encoding a negative integer of arbitrary precision
* \value CborDecimalTag Item is a CBOR array of two integers encoding a fixed-point decimal
* \value CborBigfloatTag Item is a bigfloat
* \value CborExpectedBase64urlTag Item is a CBOR byte string that is expected to be encoded as Base64Url
* \value CborExpectedBase64Tag Item is a CBOR byte string that is expected to be encoded as Base64
* \value CborExpectedBase16Tag Item is a CBOR byte string that is expected to be encoded as Base16 (also known as "hexdump")
* \value CborUriTag Item is a CBOR text string containing a URI (RFC 3986) or IRI (RFC 3987)
* \value CborBase64urlTag Item is a CBOR text string that was encoded as Base64Url
* \value CborBase64Tag Item is a CBOR text string that was encoded as Base64
* \value CborRegularExpressionTag Item is a CBOR text string containing a regular expression
* \value CborMimeMessageTag Item is a CBOR text string containing a MIME message (RFC 2045, 2046, 2047, 2822)
* \value CborSignatureTag Item contains CBOR-encoded data.
* This tag is also used as "file magic," marking a file as containing CBOR
*/
/**
* \typedef CborTag
* This typedef is an unsigned 64-bit integer. Known CBOR tags can be used from the CborKnownTags enum
* but the user application may use other tag values than the ones specified in RFC 7049.
*/
/** @} */

View File

@ -0,0 +1,724 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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.
**
****************************************************************************/
#ifndef CBOR_H
#define CBOR_H
#ifndef assert
#include <assert.h>
#endif
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "tinycbor-version.h"
#define TINYCBOR_VERSION ((TINYCBOR_VERSION_MAJOR << 16) | (TINYCBOR_VERSION_MINOR << 8) | TINYCBOR_VERSION_PATCH)
#ifdef __cplusplus
extern "C" {
#else
#include <stdbool.h>
#endif
#ifndef SIZE_MAX
/* Some systems fail to define SIZE_MAX in <stdint.h>, even though C99 requires it...
* Conversion from signed to unsigned is defined in 6.3.1.3 (Signed and unsigned integers) p2,
* which says: "the value is converted by repeatedly adding or subtracting one more than the
* maximum value that can be represented in the new type until the value is in the range of the
* new type."
* So -1 gets converted to size_t by adding SIZE_MAX + 1, which results in SIZE_MAX.
*/
# define SIZE_MAX ((size_t)-1)
#endif
#ifndef CBOR_API
# define CBOR_API
#endif
#ifndef CBOR_PRIVATE_API
# define CBOR_PRIVATE_API
#endif
#ifndef CBOR_INLINE_API
# if defined(__cplusplus)
# define CBOR_INLINE inline
# define CBOR_INLINE_API inline
# else
# define CBOR_INLINE_API static CBOR_INLINE
# if defined(_MSC_VER)
# define CBOR_INLINE __inline
# elif defined(__GNUC__)
# define CBOR_INLINE __inline__
# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define CBOR_INLINE inline
# else
# define CBOR_INLINE
# endif
# endif
#endif
typedef enum CborType {
CborIntegerType = 0x00,
CborByteStringType = 0x40,
CborTextStringType = 0x60,
CborArrayType = 0x80,
CborMapType = 0xa0,
CborTagType = 0xc0,
CborSimpleType = 0xe0,
CborBooleanType = 0xf5,
CborNullType = 0xf6,
CborUndefinedType = 0xf7,
CborHalfFloatType = 0xf9,
CborFloatType = 0xfa,
CborDoubleType = 0xfb,
CborInvalidType = 0xff /* equivalent to the break byte, so it will never be used */
} CborType;
typedef uint64_t CborTag;
typedef enum CborKnownTags {
CborDateTimeStringTag = 0,
CborUnixTime_tTag = 1,
CborPositiveBignumTag = 2,
CborNegativeBignumTag = 3,
CborDecimalTag = 4,
CborBigfloatTag = 5,
CborCOSE_Encrypt0Tag = 16,
CborCOSE_Mac0Tag = 17,
CborCOSE_Sign1Tag = 18,
CborExpectedBase64urlTag = 21,
CborExpectedBase64Tag = 22,
CborExpectedBase16Tag = 23,
CborEncodedCborTag = 24,
CborUrlTag = 32,
CborBase64urlTag = 33,
CborBase64Tag = 34,
CborRegularExpressionTag = 35,
CborMimeMessageTag = 36,
CborCOSE_EncryptTag = 96,
CborCOSE_MacTag = 97,
CborCOSE_SignTag = 98,
CborSignatureTag = 55799
} CborKnownTags;
/* #define the constants so we can check with #ifdef */
#define CborDateTimeStringTag CborDateTimeStringTag
#define CborUnixTime_tTag CborUnixTime_tTag
#define CborPositiveBignumTag CborPositiveBignumTag
#define CborNegativeBignumTag CborNegativeBignumTag
#define CborDecimalTag CborDecimalTag
#define CborBigfloatTag CborBigfloatTag
#define CborCOSE_Encrypt0Tag CborCOSE_Encrypt0Tag
#define CborCOSE_Mac0Tag CborCOSE_Mac0Tag
#define CborCOSE_Sign1Tag CborCOSE_Sign1Tag
#define CborExpectedBase64urlTag CborExpectedBase64urlTag
#define CborExpectedBase64Tag CborExpectedBase64Tag
#define CborExpectedBase16Tag CborExpectedBase16Tag
#define CborEncodedCborTag CborEncodedCborTag
#define CborUrlTag CborUrlTag
#define CborBase64urlTag CborBase64urlTag
#define CborBase64Tag CborBase64Tag
#define CborRegularExpressionTag CborRegularExpressionTag
#define CborMimeMessageTag CborMimeMessageTag
#define CborCOSE_EncryptTag CborCOSE_EncryptTag
#define CborCOSE_MacTag CborCOSE_MacTag
#define CborCOSE_SignTag CborCOSE_SignTag
#define CborSignatureTag CborSignatureTag
/* Error API */
typedef enum CborError {
CborNoError = 0,
/* errors in all modes */
CborUnknownError,
CborErrorUnknownLength, /* request for length in array, map, or string with indeterminate length */
CborErrorAdvancePastEOF,
CborErrorIO,
/* parser errors streaming errors */
CborErrorGarbageAtEnd = 256,
CborErrorUnexpectedEOF,
CborErrorUnexpectedBreak,
CborErrorUnknownType, /* can only happen in major type 7 */
CborErrorIllegalType, /* type not allowed here */
CborErrorIllegalNumber,
CborErrorIllegalSimpleType, /* types of value less than 32 encoded in two bytes */
CborErrorNoMoreStringChunks,
/* parser errors in strict mode parsing only */
CborErrorUnknownSimpleType = 512,
CborErrorUnknownTag,
CborErrorInappropriateTagForType,
CborErrorDuplicateObjectKeys,
CborErrorInvalidUtf8TextString,
CborErrorExcludedType,
CborErrorExcludedValue,
CborErrorImproperValue,
CborErrorOverlongEncoding,
CborErrorMapKeyNotString,
CborErrorMapNotSorted,
CborErrorMapKeysNotUnique,
/* encoder errors */
CborErrorTooManyItems = 768,
CborErrorTooFewItems,
/* internal implementation errors */
CborErrorDataTooLarge = 1024,
CborErrorNestingTooDeep,
CborErrorUnsupportedType,
CborErrorUnimplementedValidation,
/* errors in converting to JSON */
CborErrorJsonObjectKeyIsAggregate = 1280,
CborErrorJsonObjectKeyNotString,
CborErrorJsonNotImplemented,
CborErrorOutOfMemory = (int) (~0U / 2 + 1),
CborErrorInternalError = (int) (~0U / 2) /* INT_MAX on two's complement machines */
} CborError;
CBOR_API const char *cbor_error_string(CborError error);
/* Encoder API */
typedef enum CborEncoderAppendType
{
CborEncoderAppendCborData = 0,
CborEncoderAppendStringData = 1
} CborEncoderAppendType;
typedef CborError (*CborEncoderWriteFunction)(void *, const void *, size_t, CborEncoderAppendType);
enum CborEncoderFlags
{
CborIteratorFlag_WriterFunction = 0x01,
CborIteratorFlag_ContainerIsMap_ = 0x20
};
struct CborEncoder
{
union {
uint8_t *ptr;
ptrdiff_t bytes_needed;
CborEncoderWriteFunction writer;
} data;
uint8_t *end;
size_t remaining;
int flags;
};
typedef struct CborEncoder CborEncoder;
static const size_t CborIndefiniteLength = SIZE_MAX;
#ifndef CBOR_NO_ENCODER_API
CBOR_API void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags);
CBOR_API void cbor_encoder_init_writer(CborEncoder *encoder, CborEncoderWriteFunction writer, void *);
CBOR_API CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value);
CBOR_API CborError cbor_encode_int(CborEncoder *encoder, int64_t value);
CBOR_API CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value);
CBOR_API CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value);
CBOR_API CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag);
CBOR_API CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length);
CBOR_INLINE_API CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
{ return cbor_encode_text_string(encoder, string, strlen(string)); }
CBOR_API CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length);
CBOR_API CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value);
CBOR_INLINE_API CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
{ return cbor_encode_simple_value(encoder, (int)value - 1 + (CborBooleanType & 0x1f)); }
CBOR_INLINE_API CborError cbor_encode_null(CborEncoder *encoder)
{ return cbor_encode_simple_value(encoder, CborNullType & 0x1f); }
CBOR_INLINE_API CborError cbor_encode_undefined(CborEncoder *encoder)
{ return cbor_encode_simple_value(encoder, CborUndefinedType & 0x1f); }
CBOR_INLINE_API CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
{ return cbor_encode_floating_point(encoder, CborHalfFloatType, value); }
CBOR_API CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value);
CBOR_INLINE_API CborError cbor_encode_float(CborEncoder *encoder, float value)
{ return cbor_encode_floating_point(encoder, CborFloatType, &value); }
CBOR_INLINE_API CborError cbor_encode_double(CborEncoder *encoder, double value)
{ return cbor_encode_floating_point(encoder, CborDoubleType, &value); }
CBOR_API CborError cbor_encoder_create_array(CborEncoder *parentEncoder, CborEncoder *arrayEncoder, size_t length);
CBOR_API CborError cbor_encoder_create_map(CborEncoder *parentEncoder, CborEncoder *mapEncoder, size_t length);
CBOR_API CborError cbor_encoder_close_container(CborEncoder *parentEncoder, const CborEncoder *containerEncoder);
CBOR_API CborError cbor_encoder_close_container_checked(CborEncoder *parentEncoder, const CborEncoder *containerEncoder);
CBOR_INLINE_API uint8_t *_cbor_encoder_get_buffer_pointer(const CborEncoder *encoder)
{
return encoder->data.ptr;
}
CBOR_INLINE_API size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
{
return (size_t)(encoder->data.ptr - buffer);
}
CBOR_INLINE_API size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
{
return encoder->end ? 0 : (size_t)encoder->data.bytes_needed;
}
#endif /* CBOR_NO_ENCODER_API */
/* Parser API */
enum CborParserGlobalFlags
{
CborParserFlag_ExternalSource = 0x01
};
enum CborParserIteratorFlags
{
/* used for all types, but not during string chunk iteration
* (values are static-asserted, don't change) */
CborIteratorFlag_IntegerValueIs64Bit = 0x01,
CborIteratorFlag_IntegerValueTooLarge = 0x02,
/* used only for CborIntegerType */
CborIteratorFlag_NegativeInteger = 0x04,
/* used only during string iteration */
CborIteratorFlag_BeforeFirstStringChunk = 0x04,
CborIteratorFlag_IteratingStringChunks = 0x08,
/* used for arrays, maps and strings, including during chunk iteration */
CborIteratorFlag_UnknownLength = 0x10,
/* used for maps, but must be kept for all types
* (ContainerIsMap value must be CborMapType - CborArrayType) */
CborIteratorFlag_ContainerIsMap = 0x20,
CborIteratorFlag_NextIsMapKey = 0x40
};
struct CborValue;
struct CborParserOperations
{
bool (*can_read_bytes)(void *token, size_t len);
void *(*read_bytes)(void *token, void *dst, size_t offset, size_t len);
void (*advance_bytes)(void *token, size_t len);
CborError (*transfer_string)(void *token, const void **userptr, size_t offset, size_t len);
};
struct CborParser
{
union {
const uint8_t *end;
const struct CborParserOperations *ops;
} source;
enum CborParserGlobalFlags flags;
};
typedef struct CborParser CborParser;
struct CborValue
{
const CborParser *parser;
union {
const uint8_t *ptr;
void *token;
} source;
uint32_t remaining;
uint16_t extra;
uint8_t type;
uint8_t flags;
};
typedef struct CborValue CborValue;
#ifndef CBOR_NO_PARSER_API
CBOR_API CborError cbor_parser_init(const uint8_t *buffer, size_t size, uint32_t flags, CborParser *parser, CborValue *it);
CBOR_API CborError cbor_parser_init_reader(const struct CborParserOperations *ops, CborParser *parser, CborValue *it, void *token);
CBOR_API CborError cbor_value_validate_basic(const CborValue *it);
CBOR_INLINE_API bool cbor_value_at_end(const CborValue *it)
{ return it->remaining == 0; }
CBOR_INLINE_API const uint8_t *cbor_value_get_next_byte(const CborValue *it)
{ return it->source.ptr; }
CBOR_API CborError cbor_value_reparse(CborValue *it);
CBOR_API CborError cbor_value_advance_fixed(CborValue *it);
CBOR_API CborError cbor_value_advance(CborValue *it);
CBOR_INLINE_API bool cbor_value_is_container(const CborValue *it)
{ return it->type == CborArrayType || it->type == CborMapType; }
CBOR_API CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed);
CBOR_API CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed);
CBOR_PRIVATE_API uint64_t _cbor_value_decode_int64_internal(const CborValue *value);
CBOR_INLINE_API uint64_t _cbor_value_extract_int64_helper(const CborValue *value)
{
return value->flags & CborIteratorFlag_IntegerValueTooLarge ?
_cbor_value_decode_int64_internal(value) : value->extra;
}
CBOR_INLINE_API bool cbor_value_is_valid(const CborValue *value)
{ return value && value->type != CborInvalidType; }
CBOR_INLINE_API CborType cbor_value_get_type(const CborValue *value)
{ return (CborType)value->type; }
/* Null & undefined type */
CBOR_INLINE_API bool cbor_value_is_null(const CborValue *value)
{ return value->type == CborNullType; }
CBOR_INLINE_API bool cbor_value_is_undefined(const CborValue *value)
{ return value->type == CborUndefinedType; }
/* Booleans */
CBOR_INLINE_API bool cbor_value_is_boolean(const CborValue *value)
{ return value->type == CborBooleanType; }
CBOR_INLINE_API CborError cbor_value_get_boolean(const CborValue *value, bool *result)
{
assert(cbor_value_is_boolean(value));
*result = !!value->extra;
return CborNoError;
}
/* Simple types */
CBOR_INLINE_API bool cbor_value_is_simple_type(const CborValue *value)
{ return value->type == CborSimpleType; }
CBOR_INLINE_API CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result)
{
assert(cbor_value_is_simple_type(value));
*result = (uint8_t)value->extra;
return CborNoError;
}
/* Integers */
CBOR_INLINE_API bool cbor_value_is_integer(const CborValue *value)
{ return value->type == CborIntegerType; }
CBOR_INLINE_API bool cbor_value_is_unsigned_integer(const CborValue *value)
{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger) == 0; }
CBOR_INLINE_API bool cbor_value_is_negative_integer(const CborValue *value)
{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger); }
CBOR_INLINE_API CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result)
{
assert(cbor_value_is_integer(value));
*result = _cbor_value_extract_int64_helper(value);
return CborNoError;
}
CBOR_INLINE_API CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result)
{
assert(cbor_value_is_unsigned_integer(value));
*result = _cbor_value_extract_int64_helper(value);
return CborNoError;
}
CBOR_INLINE_API CborError cbor_value_get_int64(const CborValue *value, int64_t *result)
{
assert(cbor_value_is_integer(value));
*result = (int64_t) _cbor_value_extract_int64_helper(value);
if (value->flags & CborIteratorFlag_NegativeInteger)
*result = -*result - 1;
return CborNoError;
}
CBOR_INLINE_API CborError cbor_value_get_int(const CborValue *value, int *result)
{
assert(cbor_value_is_integer(value));
*result = (int) _cbor_value_extract_int64_helper(value);
if (value->flags & CborIteratorFlag_NegativeInteger)
*result = -*result - 1;
return CborNoError;
}
CBOR_API CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result);
CBOR_API CborError cbor_value_get_int_checked(const CborValue *value, int *result);
CBOR_INLINE_API bool cbor_value_is_length_known(const CborValue *value)
{ return (value->flags & CborIteratorFlag_UnknownLength) == 0; }
/* Tags */
CBOR_INLINE_API bool cbor_value_is_tag(const CborValue *value)
{ return value->type == CborTagType; }
CBOR_INLINE_API CborError cbor_value_get_tag(const CborValue *value, CborTag *result)
{
assert(cbor_value_is_tag(value));
*result = _cbor_value_extract_int64_helper(value);
return CborNoError;
}
CBOR_API CborError cbor_value_skip_tag(CborValue *it);
/* Strings */
CBOR_INLINE_API bool cbor_value_is_byte_string(const CborValue *value)
{ return value->type == CborByteStringType; }
CBOR_INLINE_API bool cbor_value_is_text_string(const CborValue *value)
{ return value->type == CborTextStringType; }
CBOR_INLINE_API CborError cbor_value_get_string_length(const CborValue *value, size_t *length)
{
uint64_t v;
assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
if (!cbor_value_is_length_known(value))
return CborErrorUnknownLength;
v = _cbor_value_extract_int64_helper(value);
*length = (size_t)v;
if (*length != v)
return CborErrorDataTooLarge;
return CborNoError;
}
CBOR_PRIVATE_API CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
size_t *buflen, CborValue *next);
CBOR_PRIVATE_API CborError _cbor_value_dup_string(const CborValue *value, void **buffer,
size_t *buflen, CborValue *next);
CBOR_API CborError cbor_value_calculate_string_length(const CborValue *value, size_t *length);
CBOR_INLINE_API CborError cbor_value_copy_text_string(const CborValue *value, char *buffer,
size_t *buflen, CborValue *next)
{
assert(cbor_value_is_text_string(value));
return _cbor_value_copy_string(value, buffer, buflen, next);
}
CBOR_INLINE_API CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer,
size_t *buflen, CborValue *next)
{
assert(cbor_value_is_byte_string(value));
return _cbor_value_copy_string(value, buffer, buflen, next);
}
CBOR_INLINE_API CborError cbor_value_dup_text_string(const CborValue *value, char **buffer,
size_t *buflen, CborValue *next)
{
assert(cbor_value_is_text_string(value));
return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
}
CBOR_INLINE_API CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer,
size_t *buflen, CborValue *next)
{
assert(cbor_value_is_byte_string(value));
return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
}
CBOR_PRIVATE_API CborError _cbor_value_get_string_chunk_size(const CborValue *value, size_t *len);
CBOR_INLINE_API CborError cbor_value_get_string_chunk_size(const CborValue *value, size_t *len)
{
assert(value->flags & CborIteratorFlag_IteratingStringChunks);
return _cbor_value_get_string_chunk_size(value, len);
}
CBOR_INLINE_API bool cbor_value_string_iteration_at_end(const CborValue *value)
{
size_t dummy;
return cbor_value_get_string_chunk_size(value, &dummy) == CborErrorNoMoreStringChunks;
}
CBOR_PRIVATE_API CborError _cbor_value_begin_string_iteration(CborValue *value);
CBOR_INLINE_API CborError cbor_value_begin_string_iteration(CborValue *value)
{
assert(cbor_value_is_text_string(value) || cbor_value_is_byte_string(value));
assert(!(value->flags & CborIteratorFlag_IteratingStringChunks));
return _cbor_value_begin_string_iteration(value);
}
CBOR_PRIVATE_API CborError _cbor_value_finish_string_iteration(CborValue *value);
CBOR_INLINE_API CborError cbor_value_finish_string_iteration(CborValue *value)
{
assert(cbor_value_string_iteration_at_end(value));
return _cbor_value_finish_string_iteration(value);
}
CBOR_PRIVATE_API CborError _cbor_value_get_string_chunk(const CborValue *value, const void **bufferptr,
size_t *len, CborValue *next);
CBOR_INLINE_API CborError cbor_value_get_text_string_chunk(const CborValue *value, const char **bufferptr,
size_t *len, CborValue *next)
{
assert(cbor_value_is_text_string(value));
return _cbor_value_get_string_chunk(value, (const void **)bufferptr, len, next);
}
CBOR_INLINE_API CborError cbor_value_get_byte_string_chunk(const CborValue *value, const uint8_t **bufferptr,
size_t *len, CborValue *next)
{
assert(cbor_value_is_byte_string(value));
return _cbor_value_get_string_chunk(value, (const void **)bufferptr, len, next);
}
CBOR_API CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result);
/* Maps and arrays */
CBOR_INLINE_API bool cbor_value_is_array(const CborValue *value)
{ return value->type == CborArrayType; }
CBOR_INLINE_API bool cbor_value_is_map(const CborValue *value)
{ return value->type == CborMapType; }
CBOR_INLINE_API CborError cbor_value_get_array_length(const CborValue *value, size_t *length)
{
uint64_t v;
assert(cbor_value_is_array(value));
if (!cbor_value_is_length_known(value))
return CborErrorUnknownLength;
v = _cbor_value_extract_int64_helper(value);
*length = (size_t)v;
if (*length != v)
return CborErrorDataTooLarge;
return CborNoError;
}
CBOR_INLINE_API CborError cbor_value_get_map_length(const CborValue *value, size_t *length)
{
uint64_t v;
assert(cbor_value_is_map(value));
if (!cbor_value_is_length_known(value))
return CborErrorUnknownLength;
v = _cbor_value_extract_int64_helper(value);
*length = (size_t)v;
if (*length != v)
return CborErrorDataTooLarge;
return CborNoError;
}
CBOR_API CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element);
/* Floating point */
CBOR_INLINE_API bool cbor_value_is_half_float(const CborValue *value)
{ return value->type == CborHalfFloatType; }
CBOR_API CborError cbor_value_get_half_float_as_float(const CborValue *value, float *result);
CBOR_INLINE_API CborError cbor_value_get_half_float(const CborValue *value, void *result)
{
assert(cbor_value_is_half_float(value));
assert((value->flags & CborIteratorFlag_IntegerValueTooLarge) == 0);
/* size has already been computed */
memcpy(result, &value->extra, sizeof(value->extra));
return CborNoError;
}
CBOR_INLINE_API bool cbor_value_is_float(const CborValue *value)
{ return value->type == CborFloatType; }
CBOR_INLINE_API CborError cbor_value_get_float(const CborValue *value, float *result)
{
uint32_t data;
assert(cbor_value_is_float(value));
assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
data = (uint32_t)_cbor_value_decode_int64_internal(value);
memcpy(result, &data, sizeof(*result));
return CborNoError;
}
CBOR_INLINE_API bool cbor_value_is_double(const CborValue *value)
{ return value->type == CborDoubleType; }
CBOR_INLINE_API CborError cbor_value_get_double(const CborValue *value, double *result)
{
uint64_t data;
assert(cbor_value_is_double(value));
assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
data = _cbor_value_decode_int64_internal(value);
memcpy(result, &data, sizeof(*result));
return CborNoError;
}
/* Validation API */
#ifndef CBOR_NO_VALIDATION_API
enum CborValidationFlags {
/* Bit mapping:
* bits 0-7 (8 bits): canonical format
* bits 8-11 (4 bits): canonical format & strict mode
* bits 12-20 (8 bits): strict mode
* bits 21-31 (10 bits): other
*/
CborValidateShortestIntegrals = 0x0001,
CborValidateShortestFloatingPoint = 0x0002,
CborValidateShortestNumbers = CborValidateShortestIntegrals | CborValidateShortestFloatingPoint,
CborValidateNoIndeterminateLength = 0x0100,
CborValidateMapIsSorted = 0x0200 | CborValidateNoIndeterminateLength,
CborValidateCanonicalFormat = 0x0fff,
CborValidateMapKeysAreUnique = 0x1000 | CborValidateMapIsSorted,
CborValidateTagUse = 0x2000,
CborValidateUtf8 = 0x4000,
CborValidateStrictMode = 0xfff00,
CborValidateMapKeysAreString = 0x100000,
CborValidateNoUndefined = 0x200000,
CborValidateNoTags = 0x400000,
CborValidateFiniteFloatingPoint = 0x800000,
/* unused = 0x1000000, */
/* unused = 0x2000000, */
CborValidateNoUnknownSimpleTypesSA = 0x4000000,
CborValidateNoUnknownSimpleTypes = 0x8000000 | CborValidateNoUnknownSimpleTypesSA,
CborValidateNoUnknownTagsSA = 0x10000000,
CborValidateNoUnknownTagsSR = 0x20000000 | CborValidateNoUnknownTagsSA,
CborValidateNoUnknownTags = 0x40000000 | CborValidateNoUnknownTagsSR,
CborValidateCompleteData = (int)0x80000000,
CborValidateStrictest = (int)~0U,
CborValidateBasic = 0
};
CBOR_API CborError cbor_value_validate(const CborValue *it, uint32_t flags);
#endif /* CBOR_NO_VALIDATION_API */
/* Human-readable (dump) API */
#ifndef CBOR_NO_PRETTY_API
enum CborPrettyFlags {
CborPrettyNumericEncodingIndicators = 0x01,
CborPrettyTextualEncodingIndicators = 0,
CborPrettyIndicateIndeterminateLength = 0x02,
CborPrettyIndicateIndetermineLength = CborPrettyIndicateIndeterminateLength, /* deprecated */
CborPrettyIndicateOverlongNumbers = 0x04,
CborPrettyShowStringFragments = 0x100,
CborPrettyMergeStringFragments = 0,
CborPrettyDefaultFlags = CborPrettyIndicateIndeterminateLength
};
typedef CborError (*CborStreamFunction)(void *token, const char *fmt, ...)
#ifdef __GNUC__
__attribute__((__format__(printf, 2, 3)))
#endif
;
CBOR_API CborError cbor_value_to_pretty_stream(CborStreamFunction streamFunction, void *token, CborValue *value, int flags);
/* The following API requires a hosted C implementation (uses FILE*) */
#if !defined(__STDC_HOSTED__) || __STDC_HOSTED__-0 == 1
CBOR_API CborError cbor_value_to_pretty_advance_flags(FILE *out, CborValue *value, int flags);
CBOR_API CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value);
CBOR_INLINE_API CborError cbor_value_to_pretty(FILE *out, const CborValue *value)
{
CborValue copy = *value;
return cbor_value_to_pretty_advance_flags(out, &copy, CborPrettyDefaultFlags);
}
#endif /* __STDC_HOSTED__ check */
#endif /* CBOR_NO_PRETTY_API */
#endif /* CBOR_NO_PARSER_API */
#ifdef __cplusplus
}
#endif
#endif /* CBOR_H */

View File

@ -0,0 +1,689 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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.
**
****************************************************************************/
#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE 1
#endif
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
#include "cborinternal_p.h"
#include "compilersupport_p.h"
#include <stdlib.h>
#include <string.h>
/**
* \defgroup CborEncoding Encoding to CBOR
* \brief Group of functions used to encode data to CBOR.
*
* CborEncoder is used to encode data into a CBOR stream. The outermost
* CborEncoder is initialized by calling cbor_encoder_init(), with the buffer
* where the CBOR stream will be stored. The outermost CborEncoder is usually
* used to encode exactly one item, most often an array or map. It is possible
* to encode more than one item, but care must then be taken on the decoder
* side to ensure the state is reset after each item was decoded.
*
* Nested CborEncoder objects are created using cbor_encoder_create_array() and
* cbor_encoder_create_map(), later closed with cbor_encoder_close_container()
* or cbor_encoder_close_container_checked(). The pairs of creation and closing
* must be exactly matched and their parameters are always the same.
*
* CborEncoder writes directly to the user-supplied buffer, without extra
* buffering. CborEncoder does not allocate memory and CborEncoder objects are
* usually created on the stack of the encoding functions.
*
* The example below initializes a CborEncoder object with a buffer and encodes
* a single integer.
*
* \code
* uint8_t buf[16];
* CborEncoder encoder;
* cbor_encoder_init(&encoder, buf, sizeof(buf), 0);
* cbor_encode_int(&encoder, some_value);
* \endcode
*
* As explained before, usually the outermost CborEncoder object is used to add
* one array or map, which in turn contains multiple elements. The example
* below creates a CBOR map with one element: a key "foo" and a boolean value.
*
* \code
* uint8_t buf[16];
* CborEncoder encoder, mapEncoder;
* cbor_encoder_init(&encoder, buf, sizeof(buf), 0);
* cbor_encoder_create_map(&encoder, &mapEncoder, 1);
* cbor_encode_text_stringz(&mapEncoder, "foo");
* cbor_encode_boolean(&mapEncoder, some_value);
* cbor_encoder_close_container(&encoder, &mapEncoder);
* \endcode
*
* <h3 class="groupheader">Error checking and buffer size</h3>
*
* All functions operating on CborEncoder return a condition of type CborError.
* If the encoding was successful, they return CborNoError. Some functions do
* extra checking on the input provided and may return some other error
* conditions (for example, cbor_encode_simple_value() checks that the type is
* of the correct type).
*
* In addition, all functions check whether the buffer has enough bytes to
* encode the item being appended. If that is not possible, they return
* CborErrorOutOfMemory.
*
* It is possible to continue with the encoding of data past the first function
* that returns CborErrorOutOfMemory. CborEncoder functions will not overrun
* the buffer, but will instead count how many more bytes are needed to
* complete the encoding. At the end, you can obtain that count by calling
* cbor_encoder_get_extra_bytes_needed().
*
* \section1 Finalizing the encoding
*
* Once all items have been appended and the containers have all been properly
* closed, the user-supplied buffer will contain the CBOR stream and may be
* immediately used. To obtain the size of the buffer, call
* cbor_encoder_get_buffer_size() with the original buffer pointer.
*
* The example below illustrates how one can encode an item with error checking
* and then pass on the buffer for network sending.
*
* \code
* uint8_t buf[16];
* CborError err;
* CborEncoder encoder, mapEncoder;
* cbor_encoder_init(&encoder, buf, sizeof(buf), 0);
* err = cbor_encoder_create_map(&encoder, &mapEncoder, 1);
* if (err)
* return err;
* err = cbor_encode_text_stringz(&mapEncoder, "foo");
* if (err)
* return err;
* err = cbor_encode_boolean(&mapEncoder, some_value);
* if (err)
* return err;
* err = cbor_encoder_close_container_checked(&encoder, &mapEncoder);
* if (err)
* return err;
*
* size_t len = cbor_encoder_get_buffer_size(&encoder, buf);
* send_payload(buf, len);
* return CborNoError;
* \endcode
*
* Finally, the example below expands on the one above and also
* deals with dynamically growing the buffer if the initial allocation wasn't
* big enough. Note the two places where the error checking was replaced with
* an cbor_assertion, showing where the author assumes no error can occur.
*
* \code
* uint8_t *encode_string_array(const char **strings, int n, size_t *bufsize)
* {
* CborError err;
* CborEncoder encoder, arrayEncoder;
* size_t size = 256;
* uint8_t *buf = NULL;
*
* while (1) {
* int i;
* size_t more_bytes;
* uint8_t *nbuf = realloc(buf, size);
* if (nbuf == NULL)
* goto error;
* buf = nbuf;
*
* cbor_encoder_init(&encoder, buf, size, 0);
* err = cbor_encoder_create_array(&encoder, &arrayEncoder, n);
* cbor_assert(!err); // can't fail, the buffer is always big enough
*
* for (i = 0; i < n; ++i) {
* err = cbor_encode_text_stringz(&arrayEncoder, strings[i]);
* if (err && err != CborErrorOutOfMemory)
* goto error;
* }
*
* err = cbor_encoder_close_container_checked(&encoder, &arrayEncoder);
* cbor_assert(!err); // shouldn't fail!
*
* more_bytes = cbor_encoder_get_extra_bytes_needed(encoder);
* if (more_size) {
* // buffer wasn't big enough, try again
* size += more_bytes;
* continue;
* }
*
* *bufsize = cbor_encoder_get_buffer_size(encoder, buf);
* return buf;
* }
* error:
* free(buf);
* return NULL;
* }
* \endcode
*/
/**
* \addtogroup CborEncoding
* @{
*/
/**
* \struct CborEncoder
* Structure used to encode to CBOR.
*/
/**
* Initializes a CborEncoder structure \a encoder by pointing it to buffer \a
* buffer of size \a size. The \a flags field is currently unused and must be
* zero.
*/
void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags)
{
encoder->data.ptr = buffer;
encoder->end = buffer + size;
encoder->remaining = 2;
encoder->flags = flags;
}
void cbor_encoder_init_writer(CborEncoder *encoder, CborEncoderWriteFunction writer, void *token)
{
#ifdef CBOR_ENCODER_WRITE_FUNCTION
(void) writer;
#else
encoder->data.writer = writer;
#endif
encoder->end = (uint8_t *)token;
encoder->remaining = 2;
encoder->flags = CborIteratorFlag_WriterFunction;
}
static inline void put16(void *where, uint16_t v)
{
uint16_t v_be = cbor_htons(v);
memcpy(where, &v_be, sizeof(v_be));
}
/* Note: Since this is currently only used in situations where OOM is the only
* valid error, we KNOW this to be true. Thus, this function now returns just 'true',
* but if in the future, any function starts returning a non-OOM error, this will need
* to be changed to the test. At the moment, this is done to prevent more branches
* being created in the tinycbor output */
static inline bool isOomError(CborError err)
{
if (CBOR_ENCODER_WRITER_CONTROL < 0)
return true;
/* CborErrorOutOfMemory is the only negative error code, intentionally
* so we can write the test like this */
return (int)err < 0;
}
static inline void put32(void *where, uint32_t v)
{
uint32_t v_be = cbor_htonl(v);
memcpy(where, &v_be, sizeof(v_be));
}
static inline void put64(void *where, uint64_t v)
{
uint64_t v_be = cbor_htonll(v);
memcpy(where, &v_be, sizeof(v_be));
}
static inline bool would_overflow(CborEncoder *encoder, size_t len)
{
ptrdiff_t remaining = (ptrdiff_t)encoder->end;
remaining -= remaining ? (ptrdiff_t)encoder->data.ptr : encoder->data.bytes_needed;
remaining -= (ptrdiff_t)len;
return unlikely(remaining < 0);
}
static inline void advance_ptr(CborEncoder *encoder, size_t n)
{
if (encoder->end)
encoder->data.ptr += n;
else
encoder->data.bytes_needed += n;
}
static inline CborError append_to_buffer(CborEncoder *encoder, const void *data, size_t len,
CborEncoderAppendType appendType)
{
if (CBOR_ENCODER_WRITER_CONTROL >= 0) {
if (encoder->flags & CborIteratorFlag_WriterFunction || CBOR_ENCODER_WRITER_CONTROL != 0) {
# ifdef CBOR_ENCODER_WRITE_FUNCTION
return CBOR_ENCODER_WRITE_FUNCTION(encoder->end, data, len, appendType);
# else
return encoder->data.writer(encoder->end, data, len, appendType);
# endif
}
}
#if CBOR_ENCODER_WRITER_CONTROL <= 0
if (would_overflow(encoder, len)) {
if (encoder->end != NULL) {
len -= encoder->end - encoder->data.ptr;
encoder->end = NULL;
encoder->data.bytes_needed = 0;
}
advance_ptr(encoder, len);
return CborErrorOutOfMemory;
}
memcpy(encoder->data.ptr, data, len);
encoder->data.ptr += len;
#endif
return CborNoError;
}
static inline CborError append_byte_to_buffer(CborEncoder *encoder, uint8_t byte)
{
return append_to_buffer(encoder, &byte, 1, CborEncoderAppendCborData);
}
static inline CborError encode_number_no_update(CborEncoder *encoder, uint64_t ui, uint8_t shiftedMajorType)
{
/* Little-endian would have been so much more convenient here:
* We could just write at the beginning of buf but append_to_buffer
* only the necessary bytes.
* Since it has to be big endian, do it the other way around:
* write from the end. */
uint64_t buf[2];
uint8_t *const bufend = (uint8_t *)buf + sizeof(buf);
uint8_t *bufstart = bufend - 1;
put64(buf + 1, ui); /* we probably have a bunch of zeros in the beginning */
if (ui < Value8Bit) {
*bufstart += shiftedMajorType;
} else {
uint8_t more = 0;
if (ui > 0xffU)
++more;
if (ui > 0xffffU)
++more;
if (ui > 0xffffffffU)
++more;
bufstart -= (size_t)1 << more;
*bufstart = shiftedMajorType + Value8Bit + more;
}
return append_to_buffer(encoder, bufstart, bufend - bufstart, CborEncoderAppendCborData);
}
static inline void saturated_decrement(CborEncoder *encoder)
{
if (encoder->remaining)
--encoder->remaining;
}
static inline CborError encode_number(CborEncoder *encoder, uint64_t ui, uint8_t shiftedMajorType)
{
saturated_decrement(encoder);
return encode_number_no_update(encoder, ui, shiftedMajorType);
}
/**
* Appends the unsigned 64-bit integer \a value to the CBOR stream provided by
* \a encoder.
*
* \sa cbor_encode_negative_int, cbor_encode_int
*/
CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value)
{
return encode_number(encoder, value, UnsignedIntegerType << MajorTypeShift);
}
/**
* Appends the negative 64-bit integer whose absolute value is \a
* absolute_value to the CBOR stream provided by \a encoder.
*
* If the value \a absolute_value is zero, this function encodes -2^64.
*
* \sa cbor_encode_uint, cbor_encode_int
*/
CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value)
{
return encode_number(encoder, absolute_value - 1, NegativeIntegerType << MajorTypeShift);
}
/**
* Appends the signed 64-bit integer \a value to the CBOR stream provided by
* \a encoder.
*
* \sa cbor_encode_negative_int, cbor_encode_uint
*/
CborError cbor_encode_int(CborEncoder *encoder, int64_t value)
{
/* adapted from code in RFC 7049 appendix C (pseudocode) */
uint64_t ui = value >> 63; /* extend sign to whole length */
uint8_t majorType = ui & 0x20; /* extract major type */
ui ^= value; /* complement negatives */
return encode_number(encoder, ui, majorType);
}
/**
* Appends the CBOR Simple Type of value \a value to the CBOR stream provided by
* \a encoder.
*
* This function may return error CborErrorIllegalSimpleType if the \a value
* variable contains a number that is not a valid simple type.
*/
CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value)
{
#ifndef CBOR_ENCODER_NO_CHECK_USER
/* check if this is a valid simple type */
if (value >= HalfPrecisionFloat && value <= Break)
return CborErrorIllegalSimpleType;
#endif
return encode_number(encoder, value, SimpleTypesType << MajorTypeShift);
}
/**
* Appends the floating-point value of type \a fpType and pointed to by \a
* value to the CBOR stream provided by \a encoder. The value of \a fpType must
* be one of CborHalfFloatType, CborFloatType or CborDoubleType, otherwise the
* behavior of this function is undefined.
*
* This function is useful for code that needs to pass through floating point
* values but does not wish to have the actual floating-point code.
*
* \sa cbor_encode_half_float, cbor_encode_float_as_half_float, cbor_encode_float, cbor_encode_double
*/
CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value)
{
unsigned size;
uint8_t buf[1 + sizeof(uint64_t)];
cbor_assert(fpType == CborHalfFloatType || fpType == CborFloatType || fpType == CborDoubleType);
buf[0] = fpType;
size = 2U << (fpType - CborHalfFloatType);
if (size == 8)
put64(buf + 1, *(const uint64_t*)value);
else if (size == 4)
put32(buf + 1, *(const uint32_t*)value);
else
put16(buf + 1, *(const uint16_t*)value);
saturated_decrement(encoder);
return append_to_buffer(encoder, buf, size + 1, CborEncoderAppendCborData);
}
/**
* Appends the CBOR tag \a tag to the CBOR stream provided by \a encoder.
*
* \sa CborTag
*/
CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag)
{
/* tags don't count towards the number of elements in an array or map */
return encode_number_no_update(encoder, tag, TagType << MajorTypeShift);
}
static CborError encode_string(CborEncoder *encoder, size_t length, uint8_t shiftedMajorType, const void *string)
{
CborError err = encode_number(encoder, length, shiftedMajorType);
if (err && !isOomError(err))
return err;
return append_to_buffer(encoder, string, length, CborEncoderAppendStringData);
}
/**
* \fn CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
*
* Appends the null-terminated text string \a string to the CBOR stream
* provided by \a encoder. CBOR requires that \a string be valid UTF-8, but
* TinyCBOR makes no verification of correctness. The terminating null is not
* included in the stream.
*
* \sa cbor_encode_text_string, cbor_encode_byte_string
*/
/**
* Appends the byte string \a string of length \a length to the CBOR stream
* provided by \a encoder. CBOR byte strings are arbitrary raw data.
*
* \sa cbor_encode_text_stringz, cbor_encode_text_string
*/
CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length)
{
return encode_string(encoder, length, ByteStringType << MajorTypeShift, string);
}
/**
* Appends the text string \a string of length \a length to the CBOR stream
* provided by \a encoder. CBOR requires that \a string be valid UTF-8, but
* TinyCBOR makes no verification of correctness.
*
* \sa CborError cbor_encode_text_stringz, cbor_encode_byte_string
*/
CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length)
{
return encode_string(encoder, length, TextStringType << MajorTypeShift, string);
}
#ifdef __GNUC__
__attribute__((noinline))
#endif
static CborError create_container(CborEncoder *encoder, CborEncoder *container, size_t length, uint8_t shiftedMajorType)
{
CborError err;
container->data.ptr = encoder->data.ptr;
container->end = encoder->end;
saturated_decrement(encoder);
container->remaining = length + 1; /* overflow ok on CborIndefiniteLength */
cbor_static_assert((int)CborIteratorFlag_ContainerIsMap_ == (int)CborIteratorFlag_ContainerIsMap);
cbor_static_assert(((MapType << MajorTypeShift) & CborIteratorFlag_ContainerIsMap) == CborIteratorFlag_ContainerIsMap);
cbor_static_assert(((ArrayType << MajorTypeShift) & CborIteratorFlag_ContainerIsMap) == 0);
container->flags = shiftedMajorType & CborIteratorFlag_ContainerIsMap;
if (CBOR_ENCODER_WRITER_CONTROL == 0)
container->flags |= encoder->flags & CborIteratorFlag_WriterFunction;
if (length == CborIndefiniteLength) {
container->flags |= CborIteratorFlag_UnknownLength;
err = append_byte_to_buffer(container, shiftedMajorType + IndefiniteLength);
} else {
if (shiftedMajorType & CborIteratorFlag_ContainerIsMap)
container->remaining += length;
err = encode_number_no_update(container, length, shiftedMajorType);
}
return err;
}
/**
* Creates a CBOR array in the CBOR stream provided by \a parentEncoder and
* initializes \a arrayEncoder so that items can be added to the array using
* the CborEncoder functions. The array must be terminated by calling either
* cbor_encoder_close_container() or cbor_encoder_close_container_checked()
* with the same \a encoder and \a arrayEncoder parameters.
*
* The number of items inserted into the array must be exactly \a length items,
* otherwise the stream is invalid. If the number of items is not known when
* creating the array, the constant \ref CborIndefiniteLength may be passed as
* length instead, and an indefinite length array is created.
*
* \sa cbor_encoder_create_map
*/
CborError cbor_encoder_create_array(CborEncoder *parentEncoder, CborEncoder *arrayEncoder, size_t length)
{
return create_container(parentEncoder, arrayEncoder, length, ArrayType << MajorTypeShift);
}
/**
* Creates a CBOR map in the CBOR stream provided by \a parentEncoder and
* initializes \a mapEncoder so that items can be added to the map using
* the CborEncoder functions. The map must be terminated by calling either
* cbor_encoder_close_container() or cbor_encoder_close_container_checked()
* with the same \a encoder and \a mapEncoder parameters.
*
* The number of pair of items inserted into the map must be exactly \a length
* items, otherwise the stream is invalid. If the number is not known
* when creating the map, the constant \ref CborIndefiniteLength may be passed as
* length instead, and an indefinite length map is created.
*
* \b{Implementation limitation:} TinyCBOR cannot encode more than SIZE_MAX/2
* key-value pairs in the stream. If the length \a length is larger than this
* value (and is not \ref CborIndefiniteLength), this function returns error
* CborErrorDataTooLarge.
*
* \sa cbor_encoder_create_array
*/
CborError cbor_encoder_create_map(CborEncoder *parentEncoder, CborEncoder *mapEncoder, size_t length)
{
if (length != CborIndefiniteLength && length > SIZE_MAX / 2)
return CborErrorDataTooLarge;
return create_container(parentEncoder, mapEncoder, length, MapType << MajorTypeShift);
}
/**
* Closes the CBOR container (array or map) provided by \a containerEncoder and
* updates the CBOR stream provided by \a encoder. Both parameters must be the
* same as were passed to cbor_encoder_create_array() or
* cbor_encoder_create_map().
*
* Since version 0.5, this function verifies that the number of items (or pairs
* of items, in the case of a map) was correct. It is no longer necessary to call
* cbor_encoder_close_container_checked() instead.
*
* \sa cbor_encoder_create_array(), cbor_encoder_create_map()
*/
CborError cbor_encoder_close_container(CborEncoder *parentEncoder, const CborEncoder *containerEncoder)
{
// synchronise buffer state with that of the container
parentEncoder->end = containerEncoder->end;
parentEncoder->data = containerEncoder->data;
if (containerEncoder->flags & CborIteratorFlag_UnknownLength)
return append_byte_to_buffer(parentEncoder, BreakByte);
if (containerEncoder->remaining != 1)
return containerEncoder->remaining == 0 ? CborErrorTooManyItems : CborErrorTooFewItems;
if (!parentEncoder->end)
return CborErrorOutOfMemory; /* keep the state */
return CborNoError;
}
/**
* \fn CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
*
* Appends the boolean value \a value to the CBOR stream provided by \a encoder.
*/
/**
* \fn CborError cbor_encode_null(CborEncoder *encoder)
*
* Appends the CBOR type representing a null value to the CBOR stream provided
* by \a encoder.
*
* \sa cbor_encode_undefined()
*/
/**
* \fn CborError cbor_encode_undefined(CborEncoder *encoder)
*
* Appends the CBOR type representing an undefined value to the CBOR stream
* provided by \a encoder.
*
* \sa cbor_encode_null()
*/
/**
* \fn CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
*
* Appends the IEEE 754 half-precision (16-bit) floating point value pointed to
* by \a value to the CBOR stream provided by \a encoder.
*
* \sa cbor_encode_floating_point(), cbor_encode_float(), cbor_encode_double()
*/
/**
* \fn CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value)
*
* Convert the IEEE 754 single-precision (32-bit) floating point value \a value
* to the IEEE 754 half-precision (16-bit) floating point value and append it
* to the CBOR stream provided by \a encoder.
* The \a value should be in the range of the IEEE 754 half-precision floating point type,
* INFINITY, -INFINITY, or NAN, otherwise the behavior of this function is undefined.
*
* \sa cbor_encode_floating_point(), cbor_encode_float(), cbor_encode_double()
*/
/**
* \fn CborError cbor_encode_float(CborEncoder *encoder, float value)
*
* Appends the IEEE 754 single-precision (32-bit) floating point value \a value
* to the CBOR stream provided by \a encoder.
*
* \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_float_as_half_float(), cbor_encode_double()
*/
/**
* \fn CborError cbor_encode_double(CborEncoder *encoder, double value)
*
* Appends the IEEE 754 double-precision (64-bit) floating point value \a value
* to the CBOR stream provided by \a encoder.
*
* \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_float_as_half_float(), cbor_encode_float()
*/
/**
* \fn size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
*
* Returns the total size of the buffer starting at \a buffer after the
* encoding finished without errors. The \a encoder and \a buffer arguments
* must be the same as supplied to cbor_encoder_init().
*
* If the encoding process had errors, the return value of this function is
* meaningless. If the only errors were CborErrorOutOfMemory, instead use
* cbor_encoder_get_extra_bytes_needed() to find out by how much to grow the
* buffer before encoding again.
*
* See \ref CborEncoding for an example of using this function.
*
* \sa cbor_encoder_init(), cbor_encoder_get_extra_bytes_needed(), CborEncoding
*/
/**
* \fn size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
*
* Returns how many more bytes the original buffer supplied to
* cbor_encoder_init() needs to be extended by so that no CborErrorOutOfMemory
* condition will happen for the encoding. If the buffer was big enough, this
* function returns 0. The \a encoder must be the original argument as passed
* to cbor_encoder_init().
*
* This function is usually called after an encoding sequence ended with one or
* more CborErrorOutOfMemory errors, but no other error. If any other error
* happened, the return value of this function is meaningless.
*
* See \ref CborEncoding for an example of using this function.
*
* \sa cbor_encoder_init(), cbor_encoder_get_buffer_size(), CborEncoding
*/
/** @} */

View File

@ -0,0 +1,57 @@
/****************************************************************************
**
** Copyright (C) 2015 Intel Corporation
**
** 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.
**
****************************************************************************/
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
/**
* \addtogroup CborEncoding
* @{
*/
/**
* @deprecated
*
* Closes the CBOR container (array or map) provided by \a containerEncoder and
* updates the CBOR stream provided by \a encoder. Both parameters must be the
* same as were passed to cbor_encoder_create_array() or
* cbor_encoder_create_map().
*
* Prior to version 0.5, cbor_encoder_close_container() did not check the
* number of items added. Since that version, it does and now
* cbor_encoder_close_container_checked() is no longer needed.
*
* \sa cbor_encoder_create_array(), cbor_encoder_create_map()
*/
CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder)
{
return cbor_encoder_close_container(encoder, containerEncoder);
}
/** @} */

View File

@ -0,0 +1,42 @@
/****************************************************************************
**
** Copyright (C) 2019 S.Phirsov
**
** 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.
**
****************************************************************************/
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
#include "cborinternal_p.h"
#ifndef CBOR_NO_HALF_FLOAT_TYPE
CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value)
{
uint16_t v = (uint16_t)encode_half(value);
return cbor_encode_floating_point(encoder, CborHalfFloatType, &v);
}
#endif

View File

@ -0,0 +1,188 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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 "cbor.h"
#ifndef _
# define _(msg) msg
#endif
/**
* \enum CborError
* \ingroup CborGlobals
* The CborError enum contains the possible error values used by the CBOR encoder and decoder.
*
* TinyCBOR functions report success by returning CborNoError, or one error
* condition by returning one of the values below. One exception is the
* out-of-memory condition (CborErrorOutOfMemory), which the functions for \ref
* CborEncoding may report in bit-wise OR with other conditions.
*
* This technique allows code to determine whether the only error condition was
* a lack of buffer space, which may not be a fatal condition if the buffer can
* be resized. Additionally, the functions for \ref CborEncoding may continue
* to be used even after CborErrorOutOfMemory is returned, and instead they
* will simply calculate the extra space needed.
*
* \value CborNoError No error occurred
* \omitvalue CborUnknownError
* \value CborErrorUnknownLength Request for the length of an array, map or string whose length is not provided in the CBOR stream
* \value CborErrorAdvancePastEOF Not enough data in the stream to decode item (decoding would advance past end of stream)
* \value CborErrorIO An I/O error occurred, probably due to an out-of-memory situation
* \value CborErrorGarbageAtEnd Bytes exist past the end of the CBOR stream
* \value CborErrorUnexpectedEOF End of stream reached unexpectedly
* \value CborErrorUnexpectedBreak A CBOR break byte was found where not expected
* \value CborErrorUnknownType An unknown type (future extension to CBOR) was found in the stream
* \value CborErrorIllegalType An invalid type was found while parsing a chunked CBOR string
* \value CborErrorIllegalNumber An illegal initial byte (encoding unspecified additional information) was found
* \value CborErrorIllegalSimpleType An illegal encoding of a CBOR Simple Type of value less than 32 was found
* \omitvalue CborErrorUnknownSimpleType
* \omitvalue CborErrorUnknownTag
* \omitvalue CborErrorInappropriateTagForType
* \omitvalue CborErrorDuplicateObjectKeys
* \value CborErrorInvalidUtf8TextString Illegal UTF-8 encoding found while parsing CBOR Text String
* \value CborErrorTooManyItems Too many items were added to CBOR map or array of pre-determined length
* \value CborErrorTooFewItems Too few items were added to CBOR map or array of pre-determined length
* \value CborErrorDataTooLarge Data item size exceeds TinyCBOR's implementation limits
* \value CborErrorNestingTooDeep Data item nesting exceeds TinyCBOR's implementation limits
* \omitvalue CborErrorUnsupportedType
* \value CborErrorJsonObjectKeyIsAggregate Conversion to JSON failed because the key in a map is a CBOR map or array
* \value CborErrorJsonObjectKeyNotString Conversion to JSON failed because the key in a map is not a text string
* \value CborErrorOutOfMemory During CBOR encoding, the buffer provided is insufficient for encoding the data item;
* in other situations, TinyCBOR failed to allocate memory
* \value CborErrorInternalError An internal error occurred in TinyCBOR
*/
/**
* \ingroup CborGlobals
* Returns the error string corresponding to the CBOR error condition \a error.
*/
const char *cbor_error_string(CborError error)
{
switch (error) {
case CborNoError:
return "";
case CborUnknownError:
return _("unknown error");
case CborErrorOutOfMemory:
return _("out of memory/need more memory");
case CborErrorUnknownLength:
return _("unknown length (attempted to get the length of a map/array/string of indeterminate length");
case CborErrorAdvancePastEOF:
return _("attempted to advance past EOF");
case CborErrorIO:
return _("I/O error");
case CborErrorGarbageAtEnd:
return _("garbage after the end of the content");
case CborErrorUnexpectedEOF:
return _("unexpected end of data");
case CborErrorUnexpectedBreak:
return _("unexpected 'break' byte");
case CborErrorUnknownType:
return _("illegal byte (encodes future extension type)");
case CborErrorIllegalType:
return _("mismatched string type in chunked string");
case CborErrorIllegalNumber:
return _("illegal initial byte (encodes unspecified additional information)");
case CborErrorIllegalSimpleType:
return _("illegal encoding of simple type smaller than 32");
case CborErrorNoMoreStringChunks:
return _("no more byte or text strings available");
case CborErrorUnknownSimpleType:
return _("unknown simple type");
case CborErrorUnknownTag:
return _("unknown tag");
case CborErrorInappropriateTagForType:
return _("inappropriate tag for type");
case CborErrorDuplicateObjectKeys:
return _("duplicate keys in object");
case CborErrorInvalidUtf8TextString:
return _("invalid UTF-8 content in string");
case CborErrorExcludedType:
return _("excluded type found");
case CborErrorExcludedValue:
return _("excluded value found");
case CborErrorImproperValue:
case CborErrorOverlongEncoding:
return _("value encoded in non-canonical form");
case CborErrorMapKeyNotString:
case CborErrorJsonObjectKeyNotString:
return _("key in map is not a string");
case CborErrorMapNotSorted:
return _("map is not sorted");
case CborErrorMapKeysNotUnique:
return _("map keys are not unique");
case CborErrorTooManyItems:
return _("too many items added to encoder");
case CborErrorTooFewItems:
return _("too few items added to encoder");
case CborErrorDataTooLarge:
return _("internal error: data too large");
case CborErrorNestingTooDeep:
return _("internal error: too many nested containers found in recursive function");
case CborErrorUnsupportedType:
return _("unsupported type");
case CborErrorUnimplementedValidation:
return _("validation not implemented for the current parser state");
case CborErrorJsonObjectKeyIsAggregate:
return _("conversion to JSON failed: key in object is an array or map");
case CborErrorJsonNotImplemented:
return _("conversion to JSON failed: open_memstream unavailable");
case CborErrorInternalError:
return _("internal error");
}
return cbor_error_string(CborUnknownError);
}

View File

@ -0,0 +1,316 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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.
**
****************************************************************************/
#ifndef CBORINTERNAL_P_H
#define CBORINTERNAL_P_H
#include "compilersupport_p.h"
#ifndef CBOR_NO_FLOATING_POINT
# include <float.h>
# include <math.h>
#else
# ifndef CBOR_NO_HALF_FLOAT_TYPE
# define CBOR_NO_HALF_FLOAT_TYPE 1
# endif
#endif
#ifndef CBOR_NO_HALF_FLOAT_TYPE
# if defined(__F16C__) || defined(__AVX2__)
# include <immintrin.h>
static inline unsigned short encode_half(float val)
{
__m128i m = _mm_cvtps_ph(_mm_set_ss(val), _MM_FROUND_CUR_DIRECTION);
return _mm_extract_epi16(m, 0);
}
static inline float decode_half(unsigned short half)
{
__m128i m = _mm_cvtsi32_si128(half);
return _mm_cvtss_f32(_mm_cvtph_ps(m));
}
# else
/* software implementation of float-to-fp16 conversions */
static inline unsigned short encode_half(double val)
{
uint64_t v;
int sign, exp, mant;
memcpy(&v, &val, sizeof(v));
sign = v >> 63 << 15;
exp = (v >> 52) & 0x7ff;
mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */
exp -= 1023;
if (exp == 1024) {
/* infinity or NaN */
exp = 16;
mant >>= 1;
} else if (exp >= 16) {
/* overflow, as largest number */
exp = 15;
mant = 1023;
} else if (exp >= -14) {
/* regular normal */
} else if (exp >= -24) {
/* subnormal */
mant |= 1024;
mant >>= -(exp + 14);
exp = -15;
} else {
/* underflow, make zero */
return 0;
}
/* safe cast here as bit operations above guarantee not to overflow */
return (unsigned short)(sign | ((exp + 15) << 10) | mant);
}
/* this function was copied & adapted from RFC 7049 Appendix D */
static inline double decode_half(unsigned short half)
{
int exp = (half >> 10) & 0x1f;
int mant = half & 0x3ff;
double val;
if (exp == 0) val = ldexp(mant, -24);
else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
else val = mant == 0 ? INFINITY : NAN;
return half & 0x8000 ? -val : val;
}
# endif
#endif /* CBOR_NO_HALF_FLOAT_TYPE */
#ifndef CBOR_INTERNAL_API
# define CBOR_INTERNAL_API
#endif
#ifndef CBOR_PARSER_MAX_RECURSIONS
# define CBOR_PARSER_MAX_RECURSIONS 1024
#endif
#ifndef CBOR_ENCODER_WRITER_CONTROL
# define CBOR_ENCODER_WRITER_CONTROL 0
#endif
#ifndef CBOR_PARSER_READER_CONTROL
# define CBOR_PARSER_READER_CONTROL 0
#endif
/*
* CBOR Major types
* Encoded in the high 3 bits of the descriptor byte
* See http://tools.ietf.org/html/rfc7049#section-2.1
*/
typedef enum CborMajorTypes {
UnsignedIntegerType = 0U,
NegativeIntegerType = 1U,
ByteStringType = 2U,
TextStringType = 3U,
ArrayType = 4U,
MapType = 5U, /* a.k.a. object */
TagType = 6U,
SimpleTypesType = 7U
} CborMajorTypes;
/*
* CBOR simple and floating point types
* Encoded in the low 8 bits of the descriptor byte when the
* Major Type is 7.
*/
typedef enum CborSimpleTypes {
FalseValue = 20,
TrueValue = 21,
NullValue = 22,
UndefinedValue = 23,
SimpleTypeInNextByte = 24, /* not really a simple type */
HalfPrecisionFloat = 25, /* ditto */
SinglePrecisionFloat = 26, /* ditto */
DoublePrecisionFloat = 27, /* ditto */
Break = 31
} CborSimpleTypes;
enum {
SmallValueBitLength = 5U,
SmallValueMask = (1U << SmallValueBitLength) - 1, /* 31 */
Value8Bit = 24U,
Value16Bit = 25U,
Value32Bit = 26U,
Value64Bit = 27U,
IndefiniteLength = 31U,
MajorTypeShift = SmallValueBitLength,
MajorTypeMask = (int) (~0U << MajorTypeShift),
BreakByte = (unsigned)Break | (SimpleTypesType << MajorTypeShift)
};
static inline void copy_current_position(CborValue *dst, const CborValue *src)
{
/* This "if" is here for pedantry only: the two branches should perform
* the same memory operation. */
if (src->parser->flags & CborParserFlag_ExternalSource)
dst->source.token = src->source.token;
else
dst->source.ptr = src->source.ptr;
}
static inline bool can_read_bytes(const CborValue *it, size_t n)
{
if (CBOR_PARSER_READER_CONTROL >= 0) {
if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
#ifdef CBOR_PARSER_CAN_READ_BYTES_FUNCTION
return CBOR_PARSER_CAN_READ_BYTES_FUNCTION(it->source.token, n);
#else
return it->parser->source.ops->can_read_bytes(it->source.token, n);
#endif
}
}
/* Convert the pointer subtraction to size_t since end >= ptr
* (this prevents issues with (ptrdiff_t)n becoming negative).
*/
return (size_t)(it->parser->source.end - it->source.ptr) >= n;
}
static inline void advance_bytes(CborValue *it, size_t n)
{
if (CBOR_PARSER_READER_CONTROL >= 0) {
if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
#ifdef CBOR_PARSER_ADVANCE_BYTES_FUNCTION
CBOR_PARSER_ADVANCE_BYTES_FUNCTION(it->source.token, n);
#else
it->parser->source.ops->advance_bytes(it->source.token, n);
#endif
return;
}
}
it->source.ptr += n;
}
static inline CborError transfer_string(CborValue *it, const void **ptr, size_t offset, size_t len)
{
if (CBOR_PARSER_READER_CONTROL >= 0) {
if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
#ifdef CBOR_PARSER_TRANSFER_STRING_FUNCTION
return CBOR_PARSER_TRANSFER_STRING_FUNCTION(it->source.token, ptr, offset, len);
#else
return it->parser->source.ops->transfer_string(it->source.token, ptr, offset, len);
#endif
}
}
it->source.ptr += offset;
if (can_read_bytes(it, len)) {
*CONST_CAST(const void **, ptr) = it->source.ptr;
it->source.ptr += len;
return CborNoError;
}
return CborErrorUnexpectedEOF;
}
static inline void *read_bytes_unchecked(const CborValue *it, void *dst, size_t offset, size_t n)
{
if (CBOR_PARSER_READER_CONTROL >= 0) {
if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
#ifdef CBOR_PARSER_READ_BYTES_FUNCTION
return CBOR_PARSER_READ_BYTES_FUNCTION(it->source.token, dst, offset, n);
#else
return it->parser->source.ops->read_bytes(it->source.token, dst, offset, n);
#endif
}
}
return memcpy(dst, it->source.ptr + offset, n);
}
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
static inline void *read_bytes(const CborValue *it, void *dst, size_t offset, size_t n)
{
if (can_read_bytes(it, offset + n))
return read_bytes_unchecked(it, dst, offset, n);
return NULL;
}
static inline uint16_t read_uint8(const CborValue *it, size_t offset)
{
uint8_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return result;
}
static inline uint16_t read_uint16(const CborValue *it, size_t offset)
{
uint16_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return cbor_ntohs(result);
}
static inline uint32_t read_uint32(const CborValue *it, size_t offset)
{
uint32_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return cbor_ntohl(result);
}
static inline uint64_t read_uint64(const CborValue *it, size_t offset)
{
uint64_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return cbor_ntohll(result);
}
static inline CborError extract_number_checked(const CborValue *it, uint64_t *value, size_t *bytesUsed)
{
uint8_t descriptor;
size_t bytesNeeded = 0;
/* We've already verified that there's at least one byte to be read */
read_bytes_unchecked(it, &descriptor, 0, 1);
descriptor &= SmallValueMask;
if (descriptor < Value8Bit) {
*value = descriptor;
} else if (unlikely(descriptor > Value64Bit)) {
return CborErrorIllegalNumber;
} else {
bytesNeeded = (size_t)(1 << (descriptor - Value8Bit));
if (!can_read_bytes(it, 1 + bytesNeeded))
return CborErrorUnexpectedEOF;
if (descriptor <= Value16Bit) {
if (descriptor == Value16Bit)
*value = read_uint16(it, 1);
else
*value = read_uint8(it, 1);
} else {
if (descriptor == Value32Bit)
*value = read_uint32(it, 1);
else
*value = read_uint64(it, 1);
}
}
if (bytesUsed)
*bytesUsed = bytesNeeded;
return CborNoError;
}
#endif /* CBORINTERNAL_P_H */

View File

@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2015 Intel Corporation
**
** 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.
**
****************************************************************************/
#ifndef CBORJSON_H
#define CBORJSON_H
#include "cbor.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Conversion to JSON */
enum CborToJsonFlags
{
CborConvertAddMetadata = 1,
CborConvertTagsToObjects = 2,
CborConvertIgnoreTags = 0,
CborConvertObeyByteStringTags = 0,
CborConvertByteStringsToBase64Url = 4,
CborConvertRequireMapStringKeys = 0,
CborConvertStringifyMapKeys = 8,
CborConvertDefaultFlags = 0
};
CBOR_API CborError cbor_value_to_json_advance(FILE *out, CborValue *value, int flags);
CBOR_INLINE_API CborError cbor_value_to_json(FILE *out, const CborValue *value, int flags)
{
CborValue copy = *value;
return cbor_value_to_json_advance(out, &copy, flags);
}
#ifdef __cplusplus
}
#endif
#endif /* CBORJSON_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,119 @@
/****************************************************************************
**
** Copyright (C) 2016 Intel Corporation
**
** 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.
**
****************************************************************************/
#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE 1
#endif
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
#include "compilersupport_p.h"
#include <stdlib.h>
/**
* \fn CborError cbor_value_dup_text_string(const CborValue *value, char **buffer, size_t *buflen, CborValue *next)
*
* Allocates memory for the string pointed by \a value and copies it into this
* buffer. The pointer to the buffer is stored in \a buffer and the number of
* bytes copied is stored in \a buflen (those variables must not be NULL).
*
* If the iterator \a value does not point to a text string, the behaviour is
* undefined, so checking with \ref cbor_value_get_type or \ref
* cbor_value_is_text_string is recommended.
*
* If \c malloc returns a NULL pointer, this function will return error
* condition \ref CborErrorOutOfMemory.
*
* On success, \c{*buffer} will contain a valid pointer that must be freed by
* calling \c{free()}. This is the case even for zero-length strings.
*
* The \a next pointer, if not null, will be updated to point to the next item
* after this string. If \a value points to the last item, then \a next will be
* invalid.
*
* This function may not run in constant time (it will run in O(n) time on the
* number of chunks). It requires constant memory (O(1)) in addition to the
* malloc'ed block.
*
* \note This function does not perform UTF-8 validation on the incoming text
* string.
*
* \sa cbor_value_get_text_string_chunk(), cbor_value_copy_text_string(), cbor_value_dup_byte_string()
*/
/**
* \fn CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer, size_t *buflen, CborValue *next)
*
* Allocates memory for the string pointed by \a value and copies it into this
* buffer. The pointer to the buffer is stored in \a buffer and the number of
* bytes copied is stored in \a buflen (those variables must not be NULL).
*
* If the iterator \a value does not point to a byte string, the behaviour is
* undefined, so checking with \ref cbor_value_get_type or \ref
* cbor_value_is_byte_string is recommended.
*
* If \c malloc returns a NULL pointer, this function will return error
* condition \ref CborErrorOutOfMemory.
*
* On success, \c{*buffer} will contain a valid pointer that must be freed by
* calling \c{free()}. This is the case even for zero-length strings.
*
* The \a next pointer, if not null, will be updated to point to the next item
* after this string. If \a value points to the last item, then \a next will be
* invalid.
*
* This function may not run in constant time (it will run in O(n) time on the
* number of chunks). It requires constant memory (O(1)) in addition to the
* malloc'ed block.
*
* \sa cbor_value_get_text_string_chunk(), cbor_value_copy_byte_string(), cbor_value_dup_text_string()
*/
CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *buflen, CborValue *next)
{
CborError err;
cbor_assert(buffer);
cbor_assert(buflen);
*buflen = SIZE_MAX;
err = _cbor_value_copy_string(value, NULL, buflen, NULL);
if (err)
return err;
++*buflen;
*buffer = malloc(*buflen);
if (!*buffer) {
/* out of memory */
return CborErrorOutOfMemory;
}
err = _cbor_value_copy_string(value, *buffer, buflen, next);
if (err) {
free(*buffer);
return err;
}
return CborNoError;
}

View File

@ -0,0 +1,54 @@
/****************************************************************************
**
** Copyright (C) 2019 S.Phirsov
**
** 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.
**
****************************************************************************/
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
#include "cborinternal_p.h"
#ifndef CBOR_NO_HALF_FLOAT_TYPE
/**
* Retrieves the CBOR half-precision floating point (16-bit) value that \a
* value points to, converts it to the float and store it in \a result.
* If the iterator \a value does not point to a half-precision floating
* point value, the behavior is undefined, so checking with \ref
* cbor_value_get_type or with \ref cbor_value_is_half_float is recommended.
* \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_half_float(), cbor_value_get_float()
*/
CborError cbor_value_get_half_float_as_float(const CborValue *value, float *result)
{
uint16_t v;
CborError err = cbor_value_get_half_float(value, &v);
cbor_assert(err == CborNoError);
*result = (float)decode_half((unsigned short)v);
return CborNoError;
}
#endif

View File

@ -0,0 +1,579 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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.
**
****************************************************************************/
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
#include "cborinternal_p.h"
#include "compilersupport_p.h"
#include "utf8_p.h"
#include <inttypes.h>
#include <string.h>
/**
* \defgroup CborPretty Converting CBOR to text
* \brief Group of functions used to convert CBOR to text form.
*
* This group contains two functions that can be used to convert a \ref
* CborValue object to a text representation. This module attempts to follow
* the recommendations from RFC 7049 section 6 "Diagnostic Notation", though it
* has a few differences. They are noted below.
*
* TinyCBOR does not provide a way to convert from the text representation back
* to encoded form. To produce a text form meant to be parsed, CborToJson is
* recommended instead.
*
* Either of the functions in this section will attempt to convert exactly one
* CborValue object to text. Those functions may return any error documented
* for the functions for CborParsing. In addition, if the C standard library
* stream functions return with error, the text conversion will return with
* error CborErrorIO.
*
* These functions also perform UTF-8 validation in CBOR text strings. If they
* encounter a sequence of bytes that is not permitted in UTF-8, they will return
* CborErrorInvalidUtf8TextString. That includes encoding of surrogate points
* in UTF-8.
*
* \warning The output type produced by these functions is not guaranteed to
* remain stable. A future update of TinyCBOR may produce different output for
* the same input and parsers may be unable to handle it.
*
* \sa CborParsing, CborToJson, cbor_parser_init()
*/
/**
* \addtogroup CborPretty
* @{
* <h2 class="groupheader">Text format</h2>
*
* As described in RFC 7049 section 6 "Diagnostic Notation", the format is
* largely borrowed from JSON, but modified to suit CBOR's different data
* types. TinyCBOR makes further modifications to distinguish different, but
* similar values.
*
* CBOR values are currently encoded as follows:
* \par Integrals (unsigned and negative)
* Base-10 (decimal) text representation of the value
* \par Byte strings:
* <tt>"h'"</tt> followed by the Base16 (hex) representation of the binary data, followed by an ending quote (')
* \par Text strings:
* C-style escaped string in quotes, with C11/C++11 escaping of Unicode codepoints above U+007F.
* \par Tags:
* Tag value, with the tagged value in parentheses. No special encoding of the tagged value is performed.
* \par Simple types:
* <tt>"simple(nn)"</tt> where \c nn is the simple value
* \par Null:
* \c null
* \par Undefined:
* \c undefined
* \par Booleans:
* \c true or \c false
* \par Floating point:
* If NaN or infinite, the actual words \c NaN or \c infinite.
* Otherwise, the decimal representation with as many digits as necessary to ensure no loss of information.
* By default, float values are suffixed by "f" and half-float values suffixed by "f16" (doubles have no suffix).
* If the CborPrettyNumericEncodingIndicators flag is active, the values instead are encoded following the
* Section 6 recommended encoding indicators: float values are suffixed with "_2" and half-float with "_1".
* A decimal point is always present.
* \par Arrays:
* Comma-separated list of elements, enclosed in square brackets ("[" and "]").
* \par Maps:
* Comma-separated list of key-value pairs, with the key and value separated
* by a colon (":"), enclosed in curly braces ("{" and "}").
*
* The CborPrettyFlags enumerator contains flags to control some aspects of the
* encoding:
* \par String fragmentation
* When the CborPrettyShowStringFragments option is active, text and byte
* strings that are transmitted in fragments are shown instead inside
* parentheses ("(" and ")") with no preceding number and each fragment is
* displayed individually. If a tag precedes the string, then the output
* will contain a double set of parentheses. If the option is not active,
* the fragments are merged together and the display will not show any
* difference from a string transmitted with determinate length.
* \par Encoding indicators
* Numbers and lengths in CBOR can be encoded in multiple representations.
* If the CborPrettyIndicateOverlongNumbers option is active, numbers
* and lengths that are transmitted in a longer encoding than necessary
* will be indicated, by appending an underscore ("_") to either the
* number or the opening bracket or brace, followed by a number
* indicating the CBOR additional information: 0 for 1 byte, 1 for 2
* bytes, 2 for 4 bytes and 3 for 8 bytes.
* If the CborPrettyIndicateIndeterminateLength option is active, maps,
* arrays and strings encoded with indeterminate length will be marked by
* an underscore after the opening bracket or brace or the string (if not
* showing fragments), without a number after it.
*/
/**
* \enum CborPrettyFlags
* The CborPrettyFlags enum contains flags that control the conversion of CBOR to text format.
*
* \value CborPrettyNumericEncodingIndicators Use numeric encoding indicators instead of textual for float and half-float.
* \value CborPrettyTextualEncodingIndicators Use textual encoding indicators for float ("f") and half-float ("f16").
* \value CborPrettyIndicateIndeterminateLength (default) Indicate when a map or array has indeterminate length.
* \value CborPrettyIndicateOverlongNumbers Indicate when a number or length was encoded with more bytes than needed.
* \value CborPrettyShowStringFragments If the byte or text string is transmitted in chunks, show each individually.
* \value CborPrettyMergeStringFragment Merge all chunked byte or text strings and display them in a single entry.
* \value CborPrettyDefaultFlags Default conversion flags.
*/
#ifndef CBOR_NO_FLOATING_POINT
static inline bool convertToUint64(double v, uint64_t *absolute)
{
double supremum;
v = fabs(v);
/* C11 standard section 6.3.1.4 "Real floating and integer" says:
*
* 1 When a finite value of real floating type is converted to an integer
* type other than _Bool, the fractional part is discarded (i.e., the
* value is truncated toward zero). If the value of the integral part
* cannot be represented by the integer type, the behavior is undefined.
*
* So we must perform a range check that v <= UINT64_MAX, but we can't use
* UINT64_MAX + 1.0 because the standard continues:
*
* 2 When a value of integer type is converted to a real floating type, if
* the value being converted can be represented exactly in the new type,
* it is unchanged. If the value being converted is in the range of
* values that can be represented but cannot be represented exactly, the
* result is either the nearest higher or nearest lower representable
* value, chosen in an implementation-defined manner.
*/
supremum = -2.0 * INT64_MIN; /* -2 * (- 2^63) == 2^64 */
if (v >= supremum)
return false;
/* Now we can convert, these two conversions cannot be UB */
*absolute = v;
return *absolute == v;
}
#endif
static void printRecursionLimit(CborStreamFunction stream, void *out)
{
stream(out, "<nesting too deep, recursion stopped>");
}
static CborError hexDump(CborStreamFunction stream, void *out, const void *ptr, size_t n)
{
const uint8_t *buffer = (const uint8_t *)ptr;
CborError err = CborNoError;
while (n-- && !err)
err = stream(out, "%02" PRIx8, *buffer++);
return err;
}
/* This function decodes buffer as UTF-8 and prints as escaped UTF-16.
* On UTF-8 decoding error, it returns CborErrorInvalidUtf8TextString */
static CborError utf8EscapedDump(CborStreamFunction stream, void *out, const void *ptr, size_t n)
{
const uint8_t *buffer = (const uint8_t *)ptr;
const uint8_t * const end = buffer + n;
CborError err = CborNoError;
while (buffer < end && !err) {
uint32_t uc = get_utf8(&buffer, end);
if (uc == ~0U)
return CborErrorInvalidUtf8TextString;
if (uc < 0x80) {
/* single-byte UTF-8 */
unsigned char escaped = (unsigned char)uc;
if (uc < 0x7f && uc >= 0x20 && uc != '\\' && uc != '"') {
err = stream(out, "%c", (char)uc);
continue;
}
/* print as an escape sequence */
switch (uc) {
case '"':
case '\\':
break;
case '\b':
escaped = 'b';
break;
case '\f':
escaped = 'f';
break;
case '\n':
escaped = 'n';
break;
case '\r':
escaped = 'r';
break;
case '\t':
escaped = 't';
break;
default:
goto print_utf16;
}
err = stream(out, "\\%c", escaped);
continue;
}
/* now print the sequence */
if (uc > 0xffffU) {
/* needs surrogate pairs */
err = stream(out, "\\u%04" PRIX32 "\\u%04" PRIX32,
(uc >> 10) + 0xd7c0, /* high surrogate */
(uc % 0x0400) + 0xdc00);
} else {
print_utf16:
/* no surrogate pair needed */
err = stream(out, "\\u%04" PRIX32, uc);
}
}
return err;
}
static const char *resolve_indicator(const CborValue *it, int flags)
{
static const char indicators[8][3] = {
"_0", "_1", "_2", "_3",
"", "", "", /* these are not possible */
"_"
};
const char *no_indicator = indicators[5]; /* empty string */
uint8_t additional_information;
uint8_t expected_information;
uint64_t value;
CborError err;
if (!read_bytes(it, &additional_information, 0, 1))
return NULL; /* CborErrorUnexpectedEOF */
additional_information &= SmallValueMask;
if (additional_information < Value8Bit)
return no_indicator;
/* determine whether to show anything */
if ((flags & CborPrettyIndicateIndeterminateLength) &&
additional_information == IndefiniteLength)
return indicators[IndefiniteLength - Value8Bit];
if ((flags & CborPrettyIndicateOverlongNumbers) == 0)
return no_indicator;
err = extract_number_checked(it, &value, NULL);
if (err)
return NULL; /* CborErrorUnexpectedEOF */
expected_information = Value8Bit - 1;
if (value >= Value8Bit)
++expected_information;
if (value > 0xffU)
++expected_information;
if (value > 0xffffU)
++expected_information;
if (value > 0xffffffffU)
++expected_information;
return expected_information == additional_information ?
no_indicator :
indicators[additional_information - Value8Bit];
}
static const char *get_indicator(const CborValue *it, int flags)
{
return resolve_indicator(it, flags);
}
static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue *it, int flags, int recursionsLeft);
static CborError container_to_pretty(CborStreamFunction stream, void *out, CborValue *it, CborType containerType,
int flags, int recursionsLeft)
{
const char *comma = "";
CborError err = CborNoError;
if (!recursionsLeft) {
printRecursionLimit(stream, out);
return err; /* do allow the dumping to continue */
}
while (!cbor_value_at_end(it) && !err) {
err = stream(out, "%s", comma);
comma = ", ";
if (!err)
err = value_to_pretty(stream, out, it, flags, recursionsLeft);
if (containerType == CborArrayType)
continue;
/* map: that was the key, so get the value */
if (!err)
err = stream(out, ": ");
if (!err)
err = value_to_pretty(stream, out, it, flags, recursionsLeft);
}
return err;
}
static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue *it, int flags, int recursionsLeft)
{
CborError err = CborNoError;
CborType type = cbor_value_get_type(it);
switch (type) {
case CborArrayType:
case CborMapType: {
/* recursive type */
CborValue recursed;
const char *indicator = get_indicator(it, flags);
const char *space = *indicator ? " " : indicator;
err = stream(out, "%c%s%s", type == CborArrayType ? '[' : '{', indicator, space);
if (err)
return err;
err = cbor_value_enter_container(it, &recursed);
if (err) {
copy_current_position(it, &recursed);
return err; /* parse error */
}
err = container_to_pretty(stream, out, &recursed, type, flags, recursionsLeft - 1);
if (err) {
copy_current_position(it, &recursed);
return err; /* parse error */
}
err = cbor_value_leave_container(it, &recursed);
if (err)
return err; /* parse error */
return stream(out, type == CborArrayType ? "]" : "}");
}
case CborIntegerType: {
uint64_t val;
cbor_value_get_raw_integer(it, &val); /* can't fail */
if (cbor_value_is_unsigned_integer(it)) {
err = stream(out, "%" PRIu64, val);
} else {
/* CBOR stores the negative number X as -1 - X
* (that is, -1 is stored as 0, -2 as 1 and so forth) */
if (++val) { /* unsigned overflow may happen */
err = stream(out, "-%" PRIu64, val);
} else {
/* overflown
* 0xffff`ffff`ffff`ffff + 1 =
* 0x1`0000`0000`0000`0000 = 18446744073709551616 (2^64) */
err = stream(out, "-18446744073709551616");
}
}
if (!err)
err = stream(out, "%s", get_indicator(it, flags));
break;
}
case CborByteStringType:
case CborTextStringType: {
size_t n = 0;
const void *ptr;
bool showingFragments = (flags & CborPrettyShowStringFragments) && !cbor_value_is_length_known(it);
const char *separator = "";
char close = '\'';
char open[3] = "h'";
const char *indicator = NULL;
if (type == CborTextStringType) {
close = open[0] = '"';
open[1] = '\0';
}
if (showingFragments)
err = stream(out, "(_ ");
else
err = stream(out, "%s", open);
if (!err)
err = cbor_value_begin_string_iteration(it);
while (!err) {
if (showingFragments || indicator == NULL) {
/* any iteration, except the second for a non-chunked string */
indicator = resolve_indicator(it, flags);
}
err = _cbor_value_get_string_chunk(it, &ptr, &n, it);
if (err == CborErrorNoMoreStringChunks) {
err = cbor_value_finish_string_iteration(it);
break;
}
if (!err && showingFragments)
err = stream(out, "%s%s", separator, open);
if (!err)
err = (type == CborByteStringType ?
hexDump(stream, out, ptr, n) :
utf8EscapedDump(stream, out, ptr, n));
if (!err && showingFragments) {
err = stream(out, "%c%s", close, indicator);
separator = ", ";
}
}
if (!err) {
if (showingFragments)
err = stream(out, ")");
else
err = stream(out, "%c%s", close, indicator);
}
return err;
}
case CborTagType: {
CborTag tag;
cbor_value_get_tag(it, &tag); /* can't fail */
err = stream(out, "%" PRIu64 "%s(", tag, get_indicator(it, flags));
if (!err)
err = cbor_value_advance_fixed(it);
if (!err && recursionsLeft)
err = value_to_pretty(stream, out, it, flags, recursionsLeft - 1);
else if (!err)
printRecursionLimit(stream, out);
if (!err)
err = stream(out, ")");
return err;
}
case CborSimpleType: {
/* simple types can't fail and can't have overlong encoding */
uint8_t simple_type;
cbor_value_get_simple_type(it, &simple_type);
err = stream(out, "simple(%" PRIu8 ")", simple_type);
break;
}
case CborNullType:
err = stream(out, "null");
break;
case CborUndefinedType:
err = stream(out, "undefined");
break;
case CborBooleanType: {
bool val;
cbor_value_get_boolean(it, &val); /* can't fail */
err = stream(out, val ? "true" : "false");
break;
}
#ifndef CBOR_NO_FLOATING_POINT
case CborDoubleType: {
const char *suffix;
double val;
int r;
uint64_t ival;
if (false) {
float f;
case CborFloatType:
cbor_value_get_float(it, &f);
val = f;
suffix = flags & CborPrettyNumericEncodingIndicators ? "_2" : "f";
} else if (false) {
uint16_t f16;
case CborHalfFloatType:
#ifndef CBOR_NO_HALF_FLOAT_TYPE
cbor_value_get_half_float(it, &f16);
val = decode_half(f16);
suffix = flags & CborPrettyNumericEncodingIndicators ? "_1" : "f16";
#else
(void)f16;
err = CborErrorUnsupportedType;
break;
#endif
} else {
cbor_value_get_double(it, &val);
suffix = "";
}
if ((flags & CborPrettyNumericEncodingIndicators) == 0) {
r = fpclassify(val);
if (r == FP_NAN || r == FP_INFINITE)
suffix = "";
}
if (convertToUint64(val, &ival)) {
/* this double value fits in a 64-bit integer, so show it as such
* (followed by a floating point suffix, to disambiguate) */
err = stream(out, "%s%" PRIu64 ".%s", val < 0 ? "-" : "", ival, suffix);
} else {
/* this number is definitely not a 64-bit integer */
err = stream(out, "%." DBL_DECIMAL_DIG_STR "g%s", val, suffix);
}
break;
}
#else
case CborDoubleType:
case CborFloatType:
case CborHalfFloatType:
err = CborErrorUnsupportedType;
break;
#endif /* !CBOR_NO_FLOATING_POINT */
case CborInvalidType:
err = stream(out, "invalid");
if (err)
return err;
return CborErrorUnknownType;
}
if (!err)
err = cbor_value_advance_fixed(it);
return err;
}
/**
* Converts the current CBOR type pointed by \a value to its textual
* representation and writes it to the stream by calling the \a streamFunction.
* If an error occurs, this function returns an error code similar to
* \ref CborParsing.
*
* The textual representation can be controlled by the \a flags parameter (see
* \ref CborPrettyFlags for more information).
*
* If no error ocurred, this function advances \a value to the next element.
* Often, concatenating the text representation of multiple elements can be
* done by appending a comma to the output stream in between calls to this
* function.
*
* The \a streamFunction function will be called with the \a token value as the
* first parameter and a printf-style format string as the second, with a variable
* number of further parameters.
*
* \sa cbor_value_to_pretty(), cbor_value_to_json_advance()
*/
CborError cbor_value_to_pretty_stream(CborStreamFunction streamFunction, void *token, CborValue *value, int flags)
{
return value_to_pretty(streamFunction, token, value, flags, CBOR_PARSER_MAX_RECURSIONS);
}
/** @} */

View File

@ -0,0 +1,87 @@
/****************************************************************************
**
** Copyright (C) 2017 Intel Corporation
**
** 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 "cbor.h"
#include <stdarg.h>
#include <stdio.h>
static CborError cbor_fprintf(void *out, const char *fmt, ...)
{
int n;
va_list list;
va_start(list, fmt);
n = vfprintf((FILE *)out, fmt, list);
va_end(list);
return n < 0 ? CborErrorIO : CborNoError;
}
/**
* \fn CborError cbor_value_to_pretty(FILE *out, const CborValue *value)
*
* Converts the current CBOR type pointed to by \a value to its textual
* representation and writes it to the \a out stream. If an error occurs, this
* function returns an error code similar to CborParsing.
*
* \sa cbor_value_to_pretty_advance(), cbor_value_to_json_advance()
*/
/**
* Converts the current CBOR type pointed to by \a value to its textual
* representation and writes it to the \a out stream. If an error occurs, this
* function returns an error code similar to CborParsing.
*
* If no error ocurred, this function advances \a value to the next element.
* Often, concatenating the text representation of multiple elements can be
* done by appending a comma to the output stream in between calls to this
* function.
*
* \sa cbor_value_to_pretty(), cbor_value_to_pretty_stream(), cbor_value_to_json_advance()
*/
CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value)
{
return cbor_value_to_pretty_stream(cbor_fprintf, out, value, CborPrettyDefaultFlags);
}
/**
* Converts the current CBOR type pointed to by \a value to its textual
* representation and writes it to the \a out stream. If an error occurs, this
* function returns an error code similar to CborParsing.
*
* The textual representation can be controlled by the \a flags parameter (see
* CborPrettyFlags for more information).
*
* If no error ocurred, this function advances \a value to the next element.
* Often, concatenating the text representation of multiple elements can be
* done by appending a comma to the output stream in between calls to this
* function.
*
* \sa cbor_value_to_pretty_stream(), cbor_value_to_pretty(), cbor_value_to_json_advance()
*/
CborError cbor_value_to_pretty_advance_flags(FILE *out, CborValue *value, int flags)
{
return cbor_value_to_pretty_stream(cbor_fprintf, out, value, flags);
}

View File

@ -0,0 +1,709 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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.
**
****************************************************************************/
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#define _GNU_SOURCE 1
#define _POSIX_C_SOURCE 200809L
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
#include "cborjson.h"
#include "cborinternal_p.h"
#include "compilersupport_p.h"
#include "cborinternal_p.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* \defgroup CborToJson Converting CBOR to JSON
* \brief Group of functions used to convert CBOR to JSON.
*
* This group contains two functions that can be used to convert a \ref
* CborValue object to an equivalent JSON representation. This module attempts
* to follow the recommendations from RFC 7049 section 4.1 "Converting from
* CBOR to JSON", though it has a few differences. They are noted below.
*
* These functions produce a "minified" JSON output, with no spacing,
* indentation or line breaks. If those are necessary, they need to be applied
* in a post-processing phase.
*
* Note that JSON cannot support all CBOR types with fidelity, so the
* conversion is usually lossy. For that reason, TinyCBOR supports adding a set
* of metadata JSON values that can be used by a JSON-to-CBOR converter to
* restore the original data types.
*
* The TinyCBOR library does not provide a way to convert from JSON
* representation back to encoded form. However, it provides a tool called
* \c json2cbor which can be used for that purpose. That tool supports the
* metadata format that these functions may produce.
*
* Either of the functions in this section will attempt to convert exactly one
* CborValue object to JSON. Those functions may return any error documented
* for the functions for CborParsing. In addition, if the C standard library
* stream functions return with error, the text conversion will return with
* error CborErrorIO.
*
* These functions also perform UTF-8 validation in CBOR text strings. If they
* encounter a sequence of bytes that is not permitted in UTF-8, they will return
* CborErrorInvalidUtf8TextString. That includes encoding of surrogate points
* in UTF-8.
*
* \warning The metadata produced by these functions is not guaranteed to
* remain stable. A future update of TinyCBOR may produce different output for
* the same input and parsers may be unable to handle it.
*
* \sa CborParsing, CborPretty, cbor_parser_init()
*/
/**
* \addtogroup CborToJson
* @{
* <h2 class="groupheader">Conversion limitations</h2>
*
* When converting from CBOR to JSON, there may be information loss. This
* section lists the possible scenarios.
*
* \par Number precision:
* ALL JSON numbers, due to its JavaScript heritage, are IEEE 754
* double-precision floating point. This means JSON is not capable of
* representing all integers numbers outside the range [-(2<sup>53</sup>)+1,
* 2<sup>53</sup>-1] and is not capable of representing NaN or infinite. If the
* CBOR data contains a number outside the valid range, the conversion will
* lose precision. If the input was NaN or infinite, the result of the
* conversion will be the JSON null value. In addition, the distinction between
* half-, single- and double-precision is lost.
*
* \par
* If enabled, the original value and original type are stored in the metadata.
*
* \par Non-native types:
* CBOR's type system is richer than JSON's, which means some data values
* cannot be represented when converted to JSON. The conversion silently turns
* them into strings: CBOR simple types become "simple(nn)" where \c nn is the
* simple type's value, with the exception of CBOR undefined, which becomes
* "undefined", while CBOR byte strings are converted to an Base16, Base64, or
* Base64url encoding
*
* \par
* If enabled, the original type is stored in the metadata.
*
* \par Presence of tags:
* JSON has no support for tagged values, so by default tags are dropped when
* converting to JSON. However, if the CborConvertObeyByteStringTags option is
* active (default), then certain known tags are honored and are used to format
* the conversion of the tagged byte string to JSON.
*
* \par
* If the CborConvertTagsToObjects option is active, then the tag and the
* tagged value are converted to a JSON object. Otherwise, if enabled, the
* last (innermost) tag is stored in the metadata.
*
* \par Non-string keys in maps:
* JSON requires all Object keys to be strings, while CBOR does not. By
* default, if a non-string key is found, the conversion fails with error
* CborErrorJsonObjectKeyNotString. If the CborConvertStringifyMapKeys option
* is active, then the conversion attempts to create a string representation
* using CborPretty. Note that the \c json2cbor tool is not able to parse this
* back to the original form.
*
* \par Duplicate keys in maps:
* Neither JSON nor CBOR allow duplicated keys, but current TinyCBOR does not
* validate that this is the case. If there are duplicated keys in the input,
* they will be repeated in the output, which many JSON tools may flag as
* invalid. In addition to that, if the CborConvertStringifyMapKeys option is
* active, it is possible that a non-string key in a CBOR map will be converted
* to a string form that is identical to another key.
*
* \par
* When metadata support is active, the conversion will add extra key-value
* pairs to the JSON output so it can store the metadata. It is possible that
* the keys for the metadata clash with existing keys in the JSON map.
*/
extern FILE *open_memstream(char **bufptr, size_t *sizeptr);
enum ConversionStatusFlags {
TypeWasNotNative = 0x100, /* anything but strings, boolean, null, arrays and maps */
TypeWasTagged = 0x200,
NumberPrecisionWasLost = 0x400,
NumberWasNaN = 0x800,
NumberWasInfinite = 0x1000,
NumberWasNegative = 0x2000, /* only used with NumberWasInifite or NumberWasTooBig */
FinalTypeMask = 0xff
};
typedef struct ConversionStatus {
CborTag lastTag;
uint64_t originalNumber;
int flags;
} ConversionStatus;
static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType type, ConversionStatus *status);
static CborError dump_bytestring_base16(char **result, CborValue *it)
{
static const char characters[] = "0123456789abcdef";
size_t i;
size_t n = 0;
uint8_t *buffer;
CborError err = cbor_value_calculate_string_length(it, &n);
if (err)
return err;
/* a Base16 (hex) output is twice as big as our buffer */
buffer = (uint8_t *)malloc(n * 2 + 1);
if (buffer == NULL)
/* out of memory */
return CborErrorOutOfMemory;
*result = (char *)buffer;
/* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */
++n;
err = cbor_value_copy_byte_string(it, buffer + n - 1, &n, it);
cbor_assert(err == CborNoError);
for (i = 0; i < n; ++i) {
uint8_t byte = buffer[n + i];
buffer[2*i] = characters[byte >> 4];
buffer[2*i + 1] = characters[byte & 0xf];
}
return CborNoError;
}
static CborError generic_dump_base64(char **result, CborValue *it, const char alphabet[65])
{
size_t n = 0, i;
uint8_t *buffer, *out, *in;
CborError err = cbor_value_calculate_string_length(it, &n);
if (err)
return err;
/* a Base64 output (untruncated) has 4 bytes for every 3 in the input */
size_t len = (n + 5) / 3 * 4;
buffer = (uint8_t *)malloc(len + 1);
if (buffer == NULL)
/* out of memory */
return CborErrorOutOfMemory;
out = buffer;
*result = (char *)buffer;
/* we read our byte string at the tail end of the buffer
* so we can do an in-place conversion while iterating forwards */
in = buffer + len - n;
/* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */
++n;
err = cbor_value_copy_byte_string(it, in, &n, it);
cbor_assert(err == CborNoError);
uint_least32_t val = 0;
for (i = 0; n - i >= 3; i += 3) {
/* read 3 bytes x 8 bits = 24 bits */
if (false) {
#ifdef __GNUC__
} else if (i) {
__builtin_memcpy(&val, in + i - 1, sizeof(val));
val = cbor_ntohl(val);
#endif
} else {
val = (in[i] << 16) | (in[i + 1] << 8) | in[i + 2];
}
/* write 4 chars x 6 bits = 24 bits */
*out++ = alphabet[(val >> 18) & 0x3f];
*out++ = alphabet[(val >> 12) & 0x3f];
*out++ = alphabet[(val >> 6) & 0x3f];
*out++ = alphabet[val & 0x3f];
}
/* maybe 1 or 2 bytes left */
if (n - i) {
/* we can read in[i + 1] even if it's past the end of the string because
* we know (by construction) that it's a NUL byte */
#ifdef __GNUC__
uint16_t val16;
__builtin_memcpy(&val16, in + i, sizeof(val16));
val = cbor_ntohs(val16);
#else
val = (in[i] << 8) | in[i + 1];
#endif
val <<= 8;
/* the 65th character in the alphabet is our filler: either '=' or '\0' */
out[4] = '\0';
out[3] = alphabet[64];
if (n - i == 2) {
/* write the third char in 3 chars x 6 bits = 18 bits */
out[2] = alphabet[(val >> 6) & 0x3f];
} else {
out[2] = alphabet[64]; /* filler */
}
out[1] = alphabet[(val >> 12) & 0x3f];
out[0] = alphabet[(val >> 18) & 0x3f];
} else {
out[0] = '\0';
}
return CborNoError;
}
static CborError dump_bytestring_base64(char **result, CborValue *it)
{
static const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
"ghijklmn" "opqrstuv" "wxyz0123" "456789+/" "=";
return generic_dump_base64(result, it, alphabet);
}
static CborError dump_bytestring_base64url(char **result, CborValue *it)
{
static const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
"ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
return generic_dump_base64(result, it, alphabet);
}
static CborError add_value_metadata(FILE *out, CborType type, const ConversionStatus *status)
{
int flags = status->flags;
if (flags & TypeWasTagged) {
/* extract the tagged type, which may be JSON native */
type = flags & FinalTypeMask;
flags &= ~(FinalTypeMask | TypeWasTagged);
if (fprintf(out, "\"tag\":\"%" PRIu64 "\"%s", status->lastTag,
flags & ~TypeWasTagged ? "," : "") < 0)
return CborErrorIO;
}
if (!flags)
return CborNoError;
/* print at least the type */
if (fprintf(out, "\"t\":%d", type) < 0)
return CborErrorIO;
if (flags & NumberWasNaN)
if (fprintf(out, ",\"v\":\"nan\"") < 0)
return CborErrorIO;
if (flags & NumberWasInfinite)
if (fprintf(out, ",\"v\":\"%sinf\"", flags & NumberWasNegative ? "-" : "") < 0)
return CborErrorIO;
if (flags & NumberPrecisionWasLost)
if (fprintf(out, ",\"v\":\"%c%" PRIx64 "\"", flags & NumberWasNegative ? '-' : '+',
status->originalNumber) < 0)
return CborErrorIO;
if (type == CborSimpleType)
if (fprintf(out, ",\"v\":%d", (int)status->originalNumber) < 0)
return CborErrorIO;
return CborNoError;
}
static CborError find_tagged_type(CborValue *it, CborTag *tag, CborType *type)
{
CborError err = CborNoError;
*type = cbor_value_get_type(it);
while (*type == CborTagType) {
cbor_value_get_tag(it, tag); /* can't fail */
err = cbor_value_advance_fixed(it);
if (err)
return err;
*type = cbor_value_get_type(it);
}
return err;
}
static CborError tagged_value_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
{
CborTag tag;
CborError err;
if (flags & CborConvertTagsToObjects) {
cbor_value_get_tag(it, &tag); /* can't fail */
err = cbor_value_advance_fixed(it);
if (err)
return err;
if (fprintf(out, "{\"tag%" PRIu64 "\":", tag) < 0)
return CborErrorIO;
CborType type = cbor_value_get_type(it);
err = value_to_json(out, it, flags, type, status);
if (err)
return err;
if (flags & CborConvertAddMetadata && status->flags) {
if (fprintf(out, ",\"tag%" PRIu64 "$cbor\":{", tag) < 0 ||
add_value_metadata(out, type, status) != CborNoError ||
fputc('}', out) < 0)
return CborErrorIO;
}
if (fputc('}', out) < 0)
return CborErrorIO;
status->flags = TypeWasNotNative | CborTagType;
return CborNoError;
}
CborType type;
err = find_tagged_type(it, &status->lastTag, &type);
if (err)
return err;
tag = status->lastTag;
/* special handling of byte strings? */
if (type == CborByteStringType && (flags & CborConvertByteStringsToBase64Url) == 0 &&
(tag == CborNegativeBignumTag || tag == CborExpectedBase16Tag || tag == CborExpectedBase64Tag)) {
char *str;
const char *pre = "";
if (tag == CborNegativeBignumTag) {
pre = "~";
err = dump_bytestring_base64url(&str, it);
} else if (tag == CborExpectedBase64Tag) {
err = dump_bytestring_base64(&str, it);
} else { /* tag == CborExpectedBase16Tag */
err = dump_bytestring_base16(&str, it);
}
if (err)
return err;
err = fprintf(out, "\"%s%s\"", pre, str) < 0 ? CborErrorIO : CborNoError;
free(str);
status->flags = TypeWasNotNative | TypeWasTagged | CborByteStringType;
return err;
}
/* no special handling */
err = value_to_json(out, it, flags, type, status);
status->flags |= TypeWasTagged | type;
return err;
}
static CborError stringify_map_key(char **key, CborValue *it, int flags, CborType type)
{
(void)flags; /* unused */
(void)type; /* unused */
#ifdef WITHOUT_OPEN_MEMSTREAM
(void)key; /* unused */
(void)it; /* unused */
return CborErrorJsonNotImplemented;
#else
size_t size;
FILE *memstream = open_memstream(key, &size);
if (memstream == NULL)
return CborErrorOutOfMemory; /* could also be EMFILE, but it's unlikely */
CborError err = cbor_value_to_pretty_advance(memstream, it);
if (unlikely(fclose(memstream) < 0 || *key == NULL))
return CborErrorInternalError;
return err;
#endif
}
static CborError array_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
{
const char *comma = "";
while (!cbor_value_at_end(it)) {
if (fprintf(out, "%s", comma) < 0)
return CborErrorIO;
comma = ",";
CborError err = value_to_json(out, it, flags, cbor_value_get_type(it), status);
if (err)
return err;
}
return CborNoError;
}
static CborError map_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
{
const char *comma = "";
CborError err;
while (!cbor_value_at_end(it)) {
char *key;
if (fprintf(out, "%s", comma) < 0)
return CborErrorIO;
comma = ",";
CborType keyType = cbor_value_get_type(it);
if (likely(keyType == CborTextStringType)) {
size_t n = 0;
err = cbor_value_dup_text_string(it, &key, &n, it);
} else if (flags & CborConvertStringifyMapKeys) {
err = stringify_map_key(&key, it, flags, keyType);
} else {
return CborErrorJsonObjectKeyNotString;
}
if (err)
return err;
/* first, print the key */
if (fprintf(out, "\"%s\":", key) < 0) {
free(key);
return CborErrorIO;
}
/* then, print the value */
CborType valueType = cbor_value_get_type(it);
err = value_to_json(out, it, flags, valueType, status);
/* finally, print any metadata we may have */
if (flags & CborConvertAddMetadata) {
if (!err && keyType != CborTextStringType) {
if (fprintf(out, ",\"%s$keycbordump\":true", key) < 0)
err = CborErrorIO;
}
if (!err && status->flags) {
if (fprintf(out, ",\"%s$cbor\":{", key) < 0 ||
add_value_metadata(out, valueType, status) != CborNoError ||
fputc('}', out) < 0)
err = CborErrorIO;
}
}
free(key);
if (err)
return err;
}
return CborNoError;
}
static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType type, ConversionStatus *status)
{
CborError err;
status->flags = 0;
switch (type) {
case CborArrayType:
case CborMapType: {
/* recursive type */
CborValue recursed;
err = cbor_value_enter_container(it, &recursed);
if (err) {
copy_current_position(it, &recursed);
return err; /* parse error */
}
if (fputc(type == CborArrayType ? '[' : '{', out) < 0)
return CborErrorIO;
err = (type == CborArrayType) ?
array_to_json(out, &recursed, flags, status) :
map_to_json(out, &recursed, flags, status);
if (err) {
copy_current_position(it, &recursed);
return err; /* parse error */
}
if (fputc(type == CborArrayType ? ']' : '}', out) < 0)
return CborErrorIO;
err = cbor_value_leave_container(it, &recursed);
if (err)
return err; /* parse error */
status->flags = 0; /* reset, there are never conversion errors for us */
return CborNoError;
}
case CborIntegerType: {
double num; /* JS numbers are IEEE double precision */
uint64_t val;
cbor_value_get_raw_integer(it, &val); /* can't fail */
num = (double)val;
if (cbor_value_is_negative_integer(it)) {
num = -num - 1; /* convert to negative */
if ((uint64_t)(-num - 1) != val) {
status->flags = NumberPrecisionWasLost | NumberWasNegative;
status->originalNumber = val;
}
} else {
if ((uint64_t)num != val) {
status->flags = NumberPrecisionWasLost;
status->originalNumber = val;
}
}
if (fprintf(out, "%.0f", num) < 0) /* this number has no fraction, so no decimal points please */
return CborErrorIO;
break;
}
case CborByteStringType:
case CborTextStringType: {
char *str;
if (type == CborByteStringType) {
err = dump_bytestring_base64url(&str, it);
status->flags = TypeWasNotNative;
} else {
size_t n = 0;
err = cbor_value_dup_text_string(it, &str, &n, it);
}
if (err)
return err;
err = (fprintf(out, "\"%s\"", str) < 0) ? CborErrorIO : CborNoError;
free(str);
return err;
}
case CborTagType:
return tagged_value_to_json(out, it, flags, status);
case CborSimpleType: {
uint8_t simple_type;
cbor_value_get_simple_type(it, &simple_type); /* can't fail */
status->flags = TypeWasNotNative;
status->originalNumber = simple_type;
if (fprintf(out, "\"simple(%" PRIu8 ")\"", simple_type) < 0)
return CborErrorIO;
break;
}
case CborNullType:
if (fprintf(out, "null") < 0)
return CborErrorIO;
break;
case CborUndefinedType:
status->flags = TypeWasNotNative;
if (fprintf(out, "\"undefined\"") < 0)
return CborErrorIO;
break;
case CborBooleanType: {
bool val;
cbor_value_get_boolean(it, &val); /* can't fail */
if (fprintf(out, val ? "true" : "false") < 0)
return CborErrorIO;
break;
}
#ifndef CBOR_NO_FLOATING_POINT
case CborDoubleType: {
double val;
if (false) {
float f;
case CborFloatType:
status->flags = TypeWasNotNative;
cbor_value_get_float(it, &f);
val = f;
} else if (false) {
uint16_t f16;
case CborHalfFloatType:
# ifndef CBOR_NO_HALF_FLOAT_TYPE
status->flags = TypeWasNotNative;
cbor_value_get_half_float(it, &f16);
val = decode_half(f16);
# else
(void)f16;
err = CborErrorUnsupportedType;
break;
# endif
} else {
cbor_value_get_double(it, &val);
}
int r = fpclassify(val);
if (r == FP_NAN || r == FP_INFINITE) {
if (fprintf(out, "null") < 0)
return CborErrorIO;
status->flags |= r == FP_NAN ? NumberWasNaN :
NumberWasInfinite | (val < 0 ? NumberWasNegative : 0);
} else {
uint64_t ival = (uint64_t)fabs(val);
if ((double)ival == fabs(val)) {
/* print as integer so we get the full precision */
r = fprintf(out, "%s%" PRIu64, val < 0 ? "-" : "", ival);
status->flags |= TypeWasNotNative; /* mark this integer number as a double */
} else {
/* this number is definitely not a 64-bit integer */
r = fprintf(out, "%." DBL_DECIMAL_DIG_STR "g", val);
}
if (r < 0)
return CborErrorIO;
}
break;
}
#else
case CborDoubleType:
case CborFloatType:
case CborHalfFloatType:
err = CborErrorUnsupportedType;
break;
#endif /* !CBOR_NO_FLOATING_POINT */
case CborInvalidType:
return CborErrorUnknownType;
}
return cbor_value_advance_fixed(it);
}
/**
* \enum CborToJsonFlags
* The CborToJsonFlags enum contains flags that control the conversion of CBOR to JSON.
*
* \value CborConvertAddMetadata Adds metadata to facilitate restoration of the original CBOR data.
* \value CborConvertTagsToObjects Converts CBOR tags to JSON objects
* \value CborConvertIgnoreTags (default) Ignore CBOR tags, except for byte strings
* \value CborConvertObeyByteStringTags (default) Honor formatting of CBOR byte strings if so tagged
* \value CborConvertByteStringsToBase64Url Force the conversion of all CBOR byte strings to Base64url encoding, despite any tags
* \value CborConvertRequireMapStringKeys (default) Require CBOR map keys to be strings, failing the conversion if they are not
* \value CborConvertStringifyMapKeys Convert non-string keys in CBOR maps to a string form
* \value CborConvertDefaultFlags Default conversion flags.
*/
/**
* \fn CborError cbor_value_to_json(FILE *out, const CborValue *value, int flags)
*
* Converts the current CBOR type pointed to by \a value to JSON and writes that
* to the \a out stream. If an error occurs, this function returns an error
* code similar to CborParsing. The \a flags parameter indicates one or more of
* the flags from CborToJsonFlags that control the conversion.
*
* \sa cbor_value_to_json_advance(), cbor_value_to_pretty()
*/
/**
* Converts the current CBOR type pointed to by \a value to JSON and writes that
* to the \a out stream. If an error occurs, this function returns an error
* code similar to CborParsing. The \a flags parameter indicates one or more of
* the flags from CborToJsonFlags that control the conversion.
*
* If no error ocurred, this function advances \a value to the next element.
*
* \sa cbor_value_to_json(), cbor_value_to_pretty_advance()
*/
CborError cbor_value_to_json_advance(FILE *out, CborValue *value, int flags)
{
ConversionStatus status;
return value_to_json(out, value, flags, cbor_value_get_type(value), &status);
}
/** @} */

View File

@ -0,0 +1,657 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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.
**
****************************************************************************/
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS 1
#endif
#include "cbor.h"
#include "cborinternal_p.h"
#include "compilersupport_p.h"
#include "utf8_p.h"
#include <string.h>
#ifndef CBOR_NO_FLOATING_POINT
# include <float.h>
# include <math.h>
#endif
#ifndef CBOR_PARSER_MAX_RECURSIONS
# define CBOR_PARSER_MAX_RECURSIONS 1024
#endif
/**
* \addtogroup CborParsing
* @{
*/
/**
* \enum CborValidationFlags
* The CborValidationFlags enum contains flags that control the validation of a
* CBOR stream.
*
* \value CborValidateBasic Validates only the syntactic correctedness of the stream.
* \value CborValidateCanonical Validates that the stream is in canonical format, according to
* RFC 7049 section 3.9.
* \value CborValidateStrictMode Performs strict validation, according to RFC 7049 section 3.10.
* \value CborValidateStrictest Attempt to perform the strictest validation we know of.
*
* \value CborValidateShortestIntegrals (Canonical) Validate that integral numbers and lengths are
* enconded in their shortest form possible.
* \value CborValidateShortestFloatingPoint (Canonical) Validate that floating-point numbers are encoded
* in their shortest form possible.
* \value CborValidateShortestNumbers (Canonical) Validate both integral and floating-point numbers
* are in their shortest form possible.
* \value CborValidateNoIndeterminateLength (Canonical) Validate that no string, array or map uses
* indeterminate length encoding.
* \value CborValidateMapIsSorted (Canonical & Strict mode) Validate that map keys appear in
* sorted order.
* \value CborValidateMapKeysAreUnique (Strict mode) Validate that map keys are unique.
* \value CborValidateTagUse (Strict mode) Validate that known tags are used with the
* correct types. This does not validate that the content of
* those types is syntactically correct. For example, this
* option validates that tag 1 (DateTimeString) is used with
* a Text String, but it does not validate that the string is
* a valid date/time representation.
* \value CborValidateUtf8 (Strict mode) Validate that text strings are appropriately
* encoded in UTF-8.
* \value CborValidateMapKeysAreString Validate that all map keys are text strings.
* \value CborValidateNoUndefined Validate that no elements of type "undefined" are present.
* \value CborValidateNoTags Validate that no tags are used.
* \value CborValidateFiniteFloatingPoint Validate that all floating point numbers are finite (no NaN or
* infinities are allowed).
* \value CborValidateCompleteData Validate that the stream is complete and there is no more data
* in the buffer.
* \value CborValidateNoUnknownSimpleTypesSA Validate that all Standards Action simple types are registered
* with IANA.
* \value CborValidateNoUnknownSimpleTypes Validate that all simple types used are registered with IANA.
* \value CborValidateNoUnknownTagsSA Validate that all Standard Actions tags are registered with IANA.
* \value CborValidateNoUnknownTagsSR Validate that all Standard Actions and Specification Required tags
* are registered with IANA (see below for limitations).
* \value CborValidateNoUnkonwnTags Validate that all tags are registered with IANA
* (see below for limitations).
*
* \par Simple type registry
* The CBOR specification requires that registration for use of the first 19
* simple types must be done by way of Standards Action. The rest of the simple
* types only require a specification. The official list can be obtained from
* https://www.iana.org/assignments/cbor-simple-values/cbor-simple-values.xhtml.
*
* \par
* There are no registered simple types recognized by this release of TinyCBOR
* (beyond those defined by RFC 7049).
*
* \par Tag registry
* The CBOR specification requires that registration for use of the first 23
* tags must be done by way of Standards Action. The next up to tag 255 only
* require a specification. Finally, all other tags can be registered on a
* first-come-first-serve basis. The official list can be ontained from
* https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml.
*
* \par
* Given the variability of this list, TinyCBOR cannot recognize all tags
* registered with IANA. Instead, the implementation only recognizes tags
* that are backed by an RFC.
*
* \par
* These are the tags known to the current TinyCBOR release:
<table>
<tr>
<th>Tag</th>
<th>Data Item</th>
<th>Semantics</th>
</tr>
<tr>
<td>0</td>
<td>UTF-8 text string</td>
<td>Standard date/time string</td>
</tr>
<tr>
<td>1</td>
<td>integer</td>
<td>Epoch-based date/time</td>
</tr>
<tr>
<td>2</td>
<td>byte string</td>
<td>Positive bignum</td>
</tr>
<tr>
<td>3</td>
<td>byte string</td>
<td>Negative bignum</td>
</tr>
<tr>
<td>4</td>
<td>array</td>
<td>Decimal fraction</td>
</tr>
<tr>
<td>5</td>
<td>array</td>
<td>Bigfloat</td>
</tr>
<tr>
<td>16</td>
<td>array</td>
<td>COSE Single Recipient Encrypted Data Object (RFC 8152)</td>
</tr>
<tr>
<td>17</td>
<td>array</td>
<td>COSE Mac w/o Recipients Object (RFC 8152)</td>
</tr>
<tr>
<td>18</td>
<td>array</td>
<td>COSE Single Signer Data Object (RFC 8162)</td>
</tr>
<tr>
<td>21</td>
<td>byte string, array, map</td>
<td>Expected conversion to base64url encoding</td>
</tr>
<tr>
<td>22</td>
<td>byte string, array, map</td>
<td>Expected conversion to base64 encoding</td>
</tr>
<tr>
<td>23</td>
<td>byte string, array, map</td>
<td>Expected conversion to base16 encoding</td>
</tr>
<tr>
<td>24</td>
<td>byte string</td>
<td>Encoded CBOR data item</td>
</tr>
<tr>
<td>32</td>
<td>UTF-8 text string</td>
<td>URI</td>
</tr>
<tr>
<td>33</td>
<td>UTF-8 text string</td>
<td>base64url</td>
</tr>
<tr>
<td>34</td>
<td>UTF-8 text string</td>
<td>base64</td>
</tr>
<tr>
<td>35</td>
<td>UTF-8 text string</td>
<td>Regular expression</td>
</tr>
<tr>
<td>36</td>
<td>UTF-8 text string</td>
<td>MIME message</td>
</tr>
<tr>
<td>96</td>
<td>array</td>
<td>COSE Encrypted Data Object (RFC 8152)</td>
</tr>
<tr>
<td>97</td>
<td>array</td>
<td>COSE MACed Data Object (RFC 8152)</td>
</tr>
<tr>
<td>98</td>
<td>array</td>
<td>COSE Signed Data Object (RFC 8152)</td>
</tr>
<tr>
<td>55799</td>
<td>any</td>
<td>Self-describe CBOR</td>
</tr>
</table>
*/
struct KnownTagData { uint32_t tag; uint32_t types; };
static const struct KnownTagData knownTagData[] = {
{ 0, (uint32_t)CborTextStringType },
{ 1, (uint32_t)(CborIntegerType+1) },
{ 2, (uint32_t)CborByteStringType },
{ 3, (uint32_t)CborByteStringType },
{ 4, (uint32_t)CborArrayType },
{ 5, (uint32_t)CborArrayType },
{ 16, (uint32_t)CborArrayType },
{ 17, (uint32_t)CborArrayType },
{ 18, (uint32_t)CborArrayType },
{ 21, (uint32_t)CborByteStringType | ((uint32_t)CborArrayType << 8) | ((uint32_t)CborMapType << 16) },
{ 22, (uint32_t)CborByteStringType | ((uint32_t)CborArrayType << 8) | ((uint32_t)CborMapType << 16) },
{ 23, (uint32_t)CborByteStringType | ((uint32_t)CborArrayType << 8) | ((uint32_t)CborMapType << 16) },
{ 24, (uint32_t)CborByteStringType },
{ 32, (uint32_t)CborTextStringType },
{ 33, (uint32_t)CborTextStringType },
{ 34, (uint32_t)CborTextStringType },
{ 35, (uint32_t)CborTextStringType },
{ 36, (uint32_t)CborTextStringType },
{ 96, (uint32_t)CborArrayType },
{ 97, (uint32_t)CborArrayType },
{ 98, (uint32_t)CborArrayType },
{ 55799, 0U }
};
static CborError validate_value(CborValue *it, uint32_t flags, int recursionLeft);
static inline CborError validate_utf8_string(const void *ptr, size_t n)
{
const uint8_t *buffer = (const uint8_t *)ptr;
const uint8_t * const end = buffer + n;
while (buffer < end) {
uint32_t uc = get_utf8(&buffer, end);
if (uc == ~0U)
return CborErrorInvalidUtf8TextString;
}
return CborNoError;
}
static inline CborError validate_simple_type(uint8_t simple_type, uint32_t flags)
{
/* At current time, all known simple types are those from RFC 7049,
* which are parsed by the parser into different CBOR types.
* That means that if we've got here, the type is unknown */
if (simple_type < 32)
return (flags & CborValidateNoUnknownSimpleTypesSA) ? CborErrorUnknownSimpleType : CborNoError;
return (flags & CborValidateNoUnknownSimpleTypes) == CborValidateNoUnknownSimpleTypes ?
CborErrorUnknownSimpleType : CborNoError;
}
static inline CborError validate_number(const CborValue *it, CborType type, uint32_t flags)
{
CborError err = CborNoError;
size_t bytesUsed, bytesNeeded;
uint64_t value;
if ((flags & CborValidateShortestIntegrals) == 0)
return err;
if (type >= CborHalfFloatType && type <= CborDoubleType)
return err; /* checked elsewhere */
err = extract_number_checked(it, &value, &bytesUsed);
if (err)
return err;
bytesNeeded = 0;
if (value >= Value8Bit)
++bytesNeeded;
if (value > 0xffU)
++bytesNeeded;
if (value > 0xffffU)
bytesNeeded += 2;
if (value > 0xffffffffU)
bytesNeeded += 4;
if (bytesNeeded < bytesUsed)
return CborErrorOverlongEncoding;
return CborNoError;
}
static inline CborError validate_tag(CborValue *it, CborTag tag, uint32_t flags, int recursionLeft)
{
CborType type = cbor_value_get_type(it);
const size_t knownTagCount = sizeof(knownTagData) / sizeof(knownTagData[0]);
const struct KnownTagData *tagData = knownTagData;
const struct KnownTagData * const knownTagDataEnd = knownTagData + knownTagCount;
if (!recursionLeft)
return CborErrorNestingTooDeep;
if (flags & CborValidateNoTags)
return CborErrorExcludedType;
/* find the tag data, if any */
for ( ; tagData != knownTagDataEnd; ++tagData) {
if (tagData->tag < tag)
continue;
if (tagData->tag > tag)
tagData = NULL;
break;
}
if (tagData == knownTagDataEnd)
tagData = NULL;
if (flags & CborValidateNoUnknownTags && !tagData) {
/* tag not found */
if (flags & CborValidateNoUnknownTagsSA && tag < 24)
return CborErrorUnknownTag;
if ((flags & CborValidateNoUnknownTagsSR) == CborValidateNoUnknownTagsSR && tag < 256)
return CborErrorUnknownTag;
if ((flags & CborValidateNoUnknownTags) == CborValidateNoUnknownTags)
return CborErrorUnknownTag;
}
if (flags & CborValidateTagUse && tagData && tagData->types) {
uint32_t allowedTypes = tagData->types;
/* correct Integer so it's not zero */
if (type == CborIntegerType)
type = (CborType)(type + 1);
while (allowedTypes) {
if ((uint8_t)(allowedTypes & 0xff) == type)
break;
allowedTypes >>= 8;
}
if (!allowedTypes)
return CborErrorInappropriateTagForType;
}
return validate_value(it, flags, recursionLeft);
}
#ifndef CBOR_NO_FLOATING_POINT
static inline CborError validate_floating_point(CborValue *it, CborType type, uint32_t flags)
{
CborError err;
int r;
double val;
float valf;
uint16_t valf16 = 0x7c01; /* dummy value, an infinity */
if (type != CborDoubleType) {
if (type == CborFloatType) {
err = cbor_value_get_float(it, &valf);
val = valf;
} else {
# ifdef CBOR_NO_HALF_FLOAT_TYPE
(void)valf16;
return CborErrorUnsupportedType;
# else
err = cbor_value_get_half_float(it, &valf16);
val = decode_half(valf16);
# endif
}
} else {
err = cbor_value_get_double(it, &val);
}
cbor_assert(err == CborNoError); /* can't fail */
r = fpclassify(val);
if (r == FP_NAN || r == FP_INFINITE) {
if (flags & CborValidateFiniteFloatingPoint)
return CborErrorExcludedValue;
if (flags & CborValidateShortestFloatingPoint) {
if (type == CborDoubleType)
return CborErrorOverlongEncoding;
# ifndef CBOR_NO_HALF_FLOAT_TYPE
if (type == CborFloatType)
return CborErrorOverlongEncoding;
if (r == FP_NAN && valf16 != 0x7e00)
return CborErrorImproperValue;
if (r == FP_INFINITE && valf16 != 0x7c00 && valf16 != 0xfc00)
return CborErrorImproperValue;
# endif
}
}
if (flags & CborValidateShortestFloatingPoint && type > CborHalfFloatType) {
if (type == CborDoubleType) {
valf = (float)val;
if ((double)valf == val)
return CborErrorOverlongEncoding;
}
# ifndef CBOR_NO_HALF_FLOAT_TYPE
if (type == CborFloatType) {
valf16 = encode_half(valf);
if (valf == decode_half(valf16))
return CborErrorOverlongEncoding;
}
# endif
}
return CborNoError;
}
#endif
static CborError validate_container(CborValue *it, int containerType, uint32_t flags, int recursionLeft)
{
CborError err;
const uint8_t *previous = NULL;
const uint8_t *previous_end = NULL;
if (!recursionLeft)
return CborErrorNestingTooDeep;
while (!cbor_value_at_end(it)) {
const uint8_t *current = cbor_value_get_next_byte(it);
if (containerType == CborMapType) {
if (flags & CborValidateMapKeysAreString) {
CborType type = cbor_value_get_type(it);
if (type == CborTagType) {
/* skip the tags */
CborValue copy = *it;
err = cbor_value_skip_tag(&copy);
if (err)
return err;
type = cbor_value_get_type(&copy);
}
if (type != CborTextStringType)
return CborErrorMapKeyNotString;
}
}
err = validate_value(it, flags, recursionLeft);
if (err)
return err;
if (containerType != CborMapType)
continue;
if (flags & CborValidateMapIsSorted) {
if (it->parser->flags & CborParserFlag_ExternalSource)
return CborErrorUnimplementedValidation;
if (previous) {
size_t bytelen1 = (size_t)(previous_end - previous);
size_t bytelen2 = (size_t)(cbor_value_get_next_byte(it) - current);
int r = memcmp(previous, current, bytelen1 <= bytelen2 ? bytelen1 : bytelen2);
if (r == 0 && bytelen1 != bytelen2)
r = bytelen1 < bytelen2 ? -1 : +1;
if (r > 0)
return CborErrorMapNotSorted;
if (r == 0 && (flags & CborValidateMapKeysAreUnique) == CborValidateMapKeysAreUnique)
return CborErrorMapKeysNotUnique;
}
previous = current;
previous_end = cbor_value_get_next_byte(it);
}
/* map: that was the key, so get the value */
err = validate_value(it, flags, recursionLeft);
if (err)
return err;
}
return CborNoError;
}
static CborError validate_value(CborValue *it, uint32_t flags, int recursionLeft)
{
CborError err;
CborType type = cbor_value_get_type(it);
if (cbor_value_is_length_known(it)) {
err = validate_number(it, type, flags);
if (err)
return err;
} else {
if (flags & CborValidateNoIndeterminateLength)
return CborErrorUnknownLength;
}
switch (type) {
case CborArrayType:
case CborMapType: {
/* recursive type */
CborValue recursed;
err = cbor_value_enter_container(it, &recursed);
if (!err)
err = validate_container(&recursed, type, flags, recursionLeft - 1);
if (err) {
copy_current_position(it, &recursed);
return err;
}
err = cbor_value_leave_container(it, &recursed);
if (err)
return err;
return CborNoError;
}
case CborIntegerType: {
uint64_t val;
err = cbor_value_get_raw_integer(it, &val);
cbor_assert(err == CborNoError); /* can't fail */
break;
}
case CborByteStringType:
case CborTextStringType: {
size_t n = 0;
const void *ptr;
err = cbor_value_begin_string_iteration(it);
if (err)
return err;
while (1) {
CborValue next;
err = _cbor_value_get_string_chunk(it, &ptr, &n, &next);
if (!err) {
err = validate_number(it, type, flags);
if (err)
return err;
}
*it = next;
if (err == CborErrorNoMoreStringChunks)
return cbor_value_finish_string_iteration(it);
if (err)
return err;
if (type == CborTextStringType && flags & CborValidateUtf8) {
err = validate_utf8_string(ptr, n);
if (err)
return err;
}
}
return CborNoError;
}
case CborTagType: {
CborTag tag;
err = cbor_value_get_tag(it, &tag);
cbor_assert(err == CborNoError); /* can't fail */
err = cbor_value_advance_fixed(it);
if (err)
return err;
err = validate_tag(it, tag, flags, recursionLeft - 1);
if (err)
return err;
return CborNoError;
}
case CborSimpleType: {
uint8_t simple_type;
err = cbor_value_get_simple_type(it, &simple_type);
cbor_assert(err == CborNoError); /* can't fail */
err = validate_simple_type(simple_type, flags);
if (err)
return err;
break;
}
case CborNullType:
case CborBooleanType:
break;
case CborUndefinedType:
if (flags & CborValidateNoUndefined)
return CborErrorExcludedType;
break;
case CborHalfFloatType:
case CborFloatType:
case CborDoubleType: {
#ifdef CBOR_NO_FLOATING_POINT
return CborErrorUnsupportedType;
#else
err = validate_floating_point(it, type, flags);
if (err)
return err;
break;
#endif /* !CBOR_NO_FLOATING_POINT */
}
case CborInvalidType:
return CborErrorUnknownType;
}
err = cbor_value_advance_fixed(it);
return err;
}
/**
* Performs a full validation, controlled by the \a flags options, of the CBOR
* stream pointed by \a it and returns the error it found. If no error was
* found, it returns CborNoError and the application can iterate over the items
* with certainty that no errors will appear during parsing.
*
* If \a flags is CborValidateBasic, the result should be the same as
* cbor_value_validate_basic().
*
* This function has the same timing and memory requirements as
* cbor_value_advance() and cbor_value_validate_basic().
*
* \sa CborValidationFlags, cbor_value_validate_basic(), cbor_value_advance()
*/
CborError cbor_value_validate(const CborValue *it, uint32_t flags)
{
CborValue value = *it;
CborError err = validate_value(&value, flags, CBOR_PARSER_MAX_RECURSIONS);
if (err)
return err;
if (flags & CborValidateCompleteData && can_read_bytes(it, 1))
return CborErrorGarbageAtEnd;
return CborNoError;
}
/**
* @}
*/

View File

@ -0,0 +1,205 @@
/****************************************************************************
**
** Copyright (C) 2017 Intel Corporation
**
** 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.
**
****************************************************************************/
#ifndef COMPILERSUPPORT_H
#define COMPILERSUPPORT_H
#include "cbor.h"
#ifndef _BSD_SOURCE
# define _BSD_SOURCE
#endif
#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE
#endif
#ifndef assert
# include <assert.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#ifndef __cplusplus
# include <stdbool.h>
#endif
#if __STDC_VERSION__ >= 201112L || (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(__cpp_static_assert) && __cpp_static_assert >= 200410)
# define cbor_static_assert(x) static_assert(x, #x)
#elif !defined(__cplusplus) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) && (__STDC_VERSION__ > 199901L)
# define cbor_static_assert(x) _Static_assert(x, #x)
#else
# define cbor_static_assert(x) ((void)sizeof(char[2*!!(x) - 1]))
#endif
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
/* inline is a keyword */
#else
/* use the definition from cbor.h */
# define inline CBOR_INLINE
#endif
#ifdef NDEBUG
# define cbor_assert(cond) do { if (!(cond)) unreachable(); } while (0)
#else
# define cbor_assert(cond) assert(cond)
#endif
#ifndef STRINGIFY
#define STRINGIFY(x) STRINGIFY2(x)
#endif
#define STRINGIFY2(x) #x
#if !defined(UINT32_MAX) || !defined(INT64_MAX)
/* C89? We can define UINT32_MAX portably, but not INT64_MAX */
# error "Your system has stdint.h but that doesn't define UINT32_MAX or INT64_MAX"
#endif
#ifndef DBL_DECIMAL_DIG
/* DBL_DECIMAL_DIG is C11 */
# define DBL_DECIMAL_DIG 17
#endif
#define DBL_DECIMAL_DIG_STR STRINGIFY(DBL_DECIMAL_DIG)
#if defined(__GNUC__) && defined(__i386__) && !defined(__iamcu__)
# define CBOR_INTERNAL_API_CC __attribute__((regparm(3)))
#elif defined(_MSC_VER) && defined(_M_IX86)
# define CBOR_INTERNAL_API_CC __fastcall
#else
# define CBOR_INTERNAL_API_CC
#endif
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) || \
(__has_builtin(__builtin_bswap64) && __has_builtin(__builtin_bswap32))
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define cbor_ntohll __builtin_bswap64
# define cbor_htonll __builtin_bswap64
# define cbor_ntohl __builtin_bswap32
# define cbor_htonl __builtin_bswap32
# ifdef __INTEL_COMPILER
# define cbor_ntohs _bswap16
# define cbor_htons _bswap16
# elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16)
# define cbor_ntohs __builtin_bswap16
# define cbor_htons __builtin_bswap16
# else
# define cbor_ntohs(x) (((uint16_t)(x) >> 8) | ((uint16_t)(x) << 8))
# define cbor_htons cbor_ntohs
# endif
# else
# define cbor_ntohll
# define cbor_htonll
# define cbor_ntohl
# define cbor_htonl
# define cbor_ntohs
# define cbor_htons
# endif
#elif defined(__sun)
# include <sys/byteorder.h>
#elif defined(_MSC_VER)
/* MSVC, which implies Windows, which implies little-endian and sizeof(long) == 4 */
# include <stdlib.h>
# define cbor_ntohll _byteswap_uint64
# define cbor_htonll _byteswap_uint64
# define cbor_ntohl _byteswap_ulong
# define cbor_htonl _byteswap_ulong
# define cbor_ntohs _byteswap_ushort
# define cbor_htons _byteswap_ushort
#endif
#ifndef cbor_ntohs
# include <arpa/inet.h>
# define cbor_ntohs ntohs
# define cbor_htons htons
#endif
#ifndef cbor_ntohl
# include <arpa/inet.h>
# define cbor_ntohl ntohl
# define cbor_htonl htonl
#endif
#ifndef cbor_ntohll
# define cbor_ntohll ntohll
# define cbor_htonll htonll
/* ntohll isn't usually defined */
# ifndef ntohll
# if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
(defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \
(defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
(defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \
defined(__ARMEB__) || defined(__MIPSEB__) || defined(__s390__) || defined(__sparc__)
# define ntohll
# define htonll
# elif (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
(defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
(defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && BYTE_ORDER == LITTLE_ENDIAN) || \
defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64)
# define ntohll(x) ((ntohl((uint32_t)(x)) * UINT64_C(0x100000000)) + (ntohl((x) >> 32)))
# define htonll ntohll
# else
# error "Unable to determine byte order!"
# endif
# endif
#endif
#ifdef __cplusplus
# define CONST_CAST(t, v) const_cast<t>(v)
#else
/* C-style const_cast without triggering a warning with -Wcast-qual */
# define CONST_CAST(t, v) (t)(uintptr_t)(v)
#endif
#ifdef __GNUC__
#ifndef likely
# define likely(x) __builtin_expect(!!(x), 1)
#endif
#ifndef unlikely
# define unlikely(x) __builtin_expect(!!(x), 0)
#endif
# define unreachable() __builtin_unreachable()
#elif defined(_MSC_VER)
# define likely(x) (x)
# define unlikely(x) (x)
# define unreachable() __assume(0)
#else
# define likely(x) (x)
# define unlikely(x) (x)
# define unreachable() do {} while (0)
#endif
static inline bool add_check_overflow(size_t v1, size_t v2, size_t *r)
{
#if ((defined(__GNUC__) && (__GNUC__ >= 5)) && !defined(__INTEL_COMPILER)) || __has_builtin(__builtin_add_overflow)
return __builtin_add_overflow(v1, v2, r);
#else
/* unsigned additions are well-defined */
*r = v1 + v2;
return v1 > v1 + v2;
#endif
}
#endif /* COMPILERSUPPORT_H */

View File

@ -0,0 +1,114 @@
/****************************************************************************
**
** Copyright (C) 2015 Intel Corporation
**
** 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.
**
****************************************************************************/
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#define _GNU_SOURCE 1
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__unix__) || defined(__APPLE__)
# include <unistd.h>
#endif
#ifdef __APPLE__
typedef int RetType;
typedef int LenType;
#elif __linux__
typedef ssize_t RetType;
typedef size_t LenType;
#else
# error "Cannot implement open_memstream!"
#endif
#include "compilersupport_p.h"
struct Buffer
{
char **ptr;
size_t *len;
size_t alloc;
};
static RetType write_to_buffer(void *cookie, const char *data, LenType len)
{
struct Buffer *b = (struct Buffer *)cookie;
char *ptr = *b->ptr;
size_t newsize;
errno = EFBIG;
if (unlikely(add_check_overflow(*b->len, len, &newsize)))
return -1;
if (newsize >= b->alloc) { // NB! one extra byte is needed to avoid buffer overflow at close_buffer
// make room
size_t newalloc = newsize + newsize / 2 + 1; // give 50% more room
ptr = realloc(ptr, newalloc);
if (ptr == NULL)
return -1;
b->alloc = newalloc;
*b->ptr = ptr;
}
memcpy(ptr + *b->len, data, len);
*b->len = newsize;
return len;
}
static int close_buffer(void *cookie)
{
struct Buffer *b = (struct Buffer *)cookie;
if (*b->ptr)
(*b->ptr)[*b->len] = '\0';
free(b);
return 0;
}
FILE *open_memstream(char **bufptr, size_t *lenptr)
{
struct Buffer *b = (struct Buffer *)malloc(sizeof(struct Buffer));
if (b == NULL)
return NULL;
b->alloc = 0;
b->len = lenptr;
b->ptr = bufptr;
*bufptr = NULL;
*lenptr = 0;
#ifdef __APPLE__
return funopen(b, NULL, write_to_buffer, NULL, close_buffer);
#elif __linux__
static const cookie_io_functions_t vtable = {
NULL,
write_to_buffer,
NULL,
close_buffer
};
return fopencookie(b, "w", vtable);
#endif
}

View File

@ -0,0 +1,116 @@
#!/usr/bin/perl -l
## Copyright (C) 2017 Intel Corporation
##
## 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.
##
use strict;
my $fname = shift @ARGV
or die("Usage: parsetags.pl tags.txt");
open TAGS, "<", $fname
or die("Cannot open $fname: $!");
my %typedescriptions = (
"Integer" => "integer",
"ByteString" => "byte string",
"TextString" => "UTF-8 text string",
"Array" => "array",
"Map" => "map",
"Tag" => "tag", # shouldn't happen
"Simple" => "any simple type",
"Boolean" => "boolean",
"Null" => "null",
"Undefined" => "undefined",
"HalfFloat" => "IEEE 754 half-precision floating point",
"Float" => "IEEE 754 single-precision floating point",
"Double" => "IEEE 754 double-precision floating point"
);
my %tags;
while (<TAGS>) {
s/\s*#.*$//;
next if /^$/;
chomp;
die("Could not parse line \"$_\"")
unless /^(\d+);(\w+);([\w,]*);(.*)$/;
$tags{$1}{id} = $2;
$tags{$1}{semantic} = $4;
my @types = split(',', $3);
$tags{$1}{types} = \@types;
}
close TAGS or die;
my @tagnumbers = sort { $a <=> $b } keys %tags;
print "==== HTML listing ====";
print "<table>\n <tr>\n <th>Tag</th>\n <th>Data Item</th>\n <th>Semantics</th>\n </tr>";
for my $n (@tagnumbers) {
print " <tr>";
print " <td>$n</td>";
my @types = @{$tags{$n}{types}};
@types = map { $typedescriptions{$_}; } @types;
unshift @types, "any"
if (scalar @types == 0);
printf " <td>%s</td>\n", join(', ', @types);
printf " <td>%s</td>\n", $tags{$n}{semantic};
print " </td>";
}
print "</table>";
print "\n==== enum listing for cbor.h ====\n";
printf "typedef enum CborKnownTags {";
my $comma = "";
for my $n (@tagnumbers) {
printf "%s\n Cbor%sTag%s = %d", $comma,
$tags{$n}{id},
' ' x (23 - length($tags{$n}{id})),
$n;
$comma = ",";
}
print "\n} CborKnownTags;";
print "\n/* #define the constants so we can check with #ifdef */";
for my $n (@tagnumbers) {
printf "#define Cbor%sTag Cbor%sTag\n", $tags{$n}{id}, $tags{$n}{id};
}
print "\n==== search table ====\n";
print "struct KnownTagData { uint32_t tag; uint32_t types; };";
printf "static const struct KnownTagData knownTagData[] = {";
$comma = "";
for my $n (@tagnumbers) {
my @types = @{$tags{$n}{types}};
my $typemask;
my $shift = 0;
for my $type (@types) {
die("Too many match types for tag $n") if $shift == 32;
my $actualtype = "Cbor${type}Type";
$actualtype = "($actualtype+1)" if $type eq "Integer";
$typemask .= " | " if $typemask ne "";
$typemask .= "((uint32_t)$actualtype << $shift)" if $shift;
$typemask .= "(uint32_t)$actualtype" unless $shift;
$shift += 8;
}
$typemask = "0U" if $typemask eq "";
printf "%s\n { %d, %s }", $comma, $n, $typemask;
$comma = ",";
}
print "\n};";

View File

@ -0,0 +1,26 @@
SOURCES += \
$$PWD/cborencoder.c \
$$PWD/cborencoder_close_container_checked.c \
$$PWD/cborencoder_float.c \
$$PWD/cborerrorstrings.c \
$$PWD/cborparser.c \
$$PWD/cborparser_dup_string.c \
$$PWD/cborparser_float.c \
$$PWD/cborpretty.c \
$$PWD/cborpretty_stdio.c \
$$PWD/cbortojson.c \
$$PWD/cborvalidation.c \
HEADERS += \
$$PWD/cbor.h \
$$PWD/cborinternal_p.h \
$$PWD/cborjson.h \
$$PWD/compilersupport_p.h \
$$PWD/tinycbor-version.h \
$$PWD/utf8_p.h \
QMAKE_CFLAGS *= $$QMAKE_CFLAGS_SPLIT_SECTIONS
QMAKE_LFLAGS *= $$QMAKE_LFLAGS_GCSECTIONS
INCLUDEPATH += $$PWD
CONFIG(release, debug|release): DEFINES += NDEBUG

View File

@ -0,0 +1,23 @@
# Tag number; Tag ID; Applicable types (comma-separated); Semantics
0;DateTimeString;TextString;Standard date/time string
1;UnixTime_t;Integer;Epoch-based date/time
2;PositiveBignum;ByteString;Positive bignum
3;NegativeBignum;ByteString;Negative bignum
4;Decimal;Array;Decimal fraction
5;Bigfloat;Array;Bigfloat
16;COSE_Encrypt0;Array;COSE Single Recipient Encrypted Data Object (RFC 8152)
17;COSE_Mac0;Array;COSE Mac w/o Recipients Object (RFC 8152)
18;COSE_Sign1;Array;COSE Single Signer Data Object (RFC 8162)
21;ExpectedBase64url;ByteString,Array,Map;Expected conversion to base64url encoding
22;ExpectedBase64;ByteString,Array,Map;Expected conversion to base64 encoding
23;ExpectedBase16;ByteString,Array,Map;Expected conversion to base16 encoding
24;EncodedCbor;ByteString;Encoded CBOR data item
32;Url;TextString;URI
33;Base64url;TextString;base64url
34;Base64;TextString;base64
35;RegularExpression;TextString;Regular expression
36;MimeMessage;TextString;MIME message
96;COSE_Encrypt;Array;COSE Encrypted Data Object (RFC 8152)
97;COSE_Mac;Array;COSE MACed Data Object (RFC 8152)
98;COSE_Sign;Array;COSE Signed Data Object (RFC 8152)
55799;Signature;;Self-describe CBOR

View File

@ -0,0 +1,3 @@
#define TINYCBOR_VERSION_MAJOR 0
#define TINYCBOR_VERSION_MINOR 6
#define TINYCBOR_VERSION_PATCH 0

View File

@ -0,0 +1,10 @@
TEMPLATE = lib
CONFIG += static warn_on
CONFIG -= qt
DESTDIR = ../lib
!msvc:QMAKE_CFLAGS += \
-Werror=incompatible-pointer-types \
-Werror=implicit-function-declaration \
-Werror=int-conversion
include(src.pri)

View File

@ -0,0 +1,104 @@
/****************************************************************************
**
** Copyright (C) 2017 Intel Corporation
**
** 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.
**
****************************************************************************/
#ifndef CBOR_UTF8_H
#define CBOR_UTF8_H
#include "compilersupport_p.h"
#include <stdint.h>
static inline uint32_t get_utf8(const uint8_t **buffer, const uint8_t *end)
{
int charsNeeded;
uint32_t uc, min_uc;
uint8_t b;
ptrdiff_t n = end - *buffer;
if (n == 0)
return ~0U;
uc = *(*buffer)++;
if (uc < 0x80) {
/* single-byte UTF-8 */
return uc;
}
/* multi-byte UTF-8, decode it */
if (unlikely(uc <= 0xC1))
return ~0U;
if (uc < 0xE0) {
/* two-byte UTF-8 */
charsNeeded = 2;
min_uc = 0x80;
uc &= 0x1f;
} else if (uc < 0xF0) {
/* three-byte UTF-8 */
charsNeeded = 3;
min_uc = 0x800;
uc &= 0x0f;
} else if (uc < 0xF5) {
/* four-byte UTF-8 */
charsNeeded = 4;
min_uc = 0x10000;
uc &= 0x07;
} else {
return ~0U;
}
if (n < charsNeeded)
return ~0U;
/* first continuation character */
b = *(*buffer)++;
if ((b & 0xc0) != 0x80)
return ~0U;
uc <<= 6;
uc |= b & 0x3f;
if (charsNeeded > 2) {
/* second continuation character */
b = *(*buffer)++;
if ((b & 0xc0) != 0x80)
return ~0U;
uc <<= 6;
uc |= b & 0x3f;
if (charsNeeded > 3) {
/* third continuation character */
b = *(*buffer)++;
if ((b & 0xc0) != 0x80)
return ~0U;
uc <<= 6;
uc |= b & 0x3f;
}
}
/* overlong sequence? surrogate pair? out or range? */
if (uc < min_uc || uc - 0xd800U < 2048U || uc > 0x10ffff)
return ~0U;
return uc;
}
#endif /* CBOR_UTF8_H */

View File

@ -0,0 +1,15 @@
Makefile
debug
moc_predefs.h
release
target_wrapper.*
# The executables
cpp/cpp
cpp/cpp.exe
encoder/encoder
encoder/encoder.exe
parser/parser
parser/parser.exe
tojson/tojson
tojson/tojson.exe

View File

@ -0,0 +1,7 @@
CONFIG += testcase parallel_test console
CONFIG -= qt app_bundle
gcc: QMAKE_CFLAGS += -std=c90 -pedantic-errors -Wall -Wextra -Werror
darwin: QMAKE_CFLAGS += -Wno-long-long
SOURCES += tst_c90.c
INCLUDEPATH += ../../src

View File

@ -0,0 +1,30 @@
/****************************************************************************
**
** Copyright (C) 2018 Intel Corporation
**
** 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 "cbor.h"
int main()
{
return 0;
}

View File

@ -0,0 +1,5 @@
CONFIG += testcase parallel_test c++11
QT = core testlib
SOURCES = tst_cpp.cpp
INCLUDEPATH += ../../src

View File

@ -0,0 +1,44 @@
/****************************************************************************
**
** Copyright (C) 2017 Intel Corporation
**
** 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 "../../src/cborencoder.c"
#include "../../src/cborencoder_float.c"
#include "../../src/cborerrorstrings.c"
#include "../../src/cborparser.c"
#include "../../src/cborparser_dup_string.c"
#include "../../src/cborparser_float.c"
#include "../../src/cborvalidation.c"
#include <QtTest>
// This is a compilation-only test.
// All it does is verify that the four source files above
// compile as C++ without errors.
class tst_Cpp : public QObject
{
Q_OBJECT
};
QTEST_MAIN(tst_Cpp)
#include "tst_cpp.moc"

View File

@ -0,0 +1,346 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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 <QtTest>
static float myNaNf()
{
uint32_t v = 0x7fc00000;
float f;
memcpy(&f, &v, sizeof(f));
Q_ASSERT(qIsNaN(f));
return f;
}
static float myInff()
{
uint32_t v = 0x7f800000;
float f;
memcpy(&f, &v, sizeof(f));
Q_ASSERT(qIsInf(f));
return f;
}
static float myNInff()
{
uint32_t v = 0xff800000;
float f;
memcpy(&f, &v, sizeof(f));
Q_ASSERT(qIsInf(f));
return f;
}
static double myNaN()
{
uint64_t v = UINT64_C(0x7ff8000000000000);
double f;
memcpy(&f, &v, sizeof(f));
Q_ASSERT(qIsNaN(f));
return f;
}
static double myInf()
{
uint64_t v = UINT64_C(0x7ff0000000000000);
double f;
memcpy(&f, &v, sizeof(f));
Q_ASSERT(qIsInf(f));
return f;
}
static double myNInf()
{
uint64_t v = UINT64_C(0xfff0000000000000);
double f;
memcpy(&f, &v, sizeof(f));
Q_ASSERT(qIsInf(f));
return f;
}
template <size_t N> QByteArray raw(const char (&data)[N])
{
return QByteArray::fromRawData(data, N - 1);
}
struct NegativeInteger { quint64 abs; };
Q_DECLARE_METATYPE(NegativeInteger)
struct SimpleType { uint8_t type; };
Q_DECLARE_METATYPE(SimpleType)
struct Float16Standin { uint16_t val; };
Q_DECLARE_METATYPE(Float16Standin)
struct Tag { CborTag tag; QVariant tagged; };
Q_DECLARE_METATYPE(Tag)
template <typename... Args>
QVariant make_list(const Args &... args)
{
return QVariantList{args...};
}
typedef QVector<QPair<QVariant, QVariant>> Map;
Q_DECLARE_METATYPE(Map)
QVariant make_map(const std::initializer_list<QPair<QVariant, QVariant>> &list)
{
return QVariant::fromValue(Map(list));
}
struct IndeterminateLengthArray : QVariantList { using QVariantList::QVariantList; };
struct IndeterminateLengthMap : Map { using Map::Map; };
Q_DECLARE_METATYPE(IndeterminateLengthArray)
Q_DECLARE_METATYPE(IndeterminateLengthMap)
QVariant make_ilarray(const std::initializer_list<QVariant> &list)
{
return QVariant::fromValue(IndeterminateLengthArray(list));
}
QVariant make_ilmap(const std::initializer_list<QPair<QVariant, QVariant>> &list)
{
return QVariant::fromValue(IndeterminateLengthMap(list));
}
void addHalfFloat()
{
QTest::addColumn<QByteArray>("output");
QTest::addColumn<unsigned>("rawInput");
QTest::addColumn<double>("floatInput");
QTest::newRow("+0") << raw("\x00\x00") << 0U << 0.0;
QTest::newRow("-0") << raw("\x80\x00") << 0x8000U << 0.0;
QTest::newRow("min.denorm") << raw("\x00\x01") << 1U << ldexp(1.0, -14) * ldexp(1.0, -10);
QTest::newRow("-min.denorm") << raw("\x80\x01") << 0x8001U << ldexp(-1.0, -14) * ldexp(1.0, -10);
QTest::newRow("max.denorm") << raw("\x03\xff") << 0x03ffU << ldexp(1.0, -14) * (1.0 - ldexp(1.0, -10));
QTest::newRow("-max.denorm") << raw("\x83\xff") << 0x83ffU << ldexp(-1.0, -14) * (1.0 - ldexp(1.0, -10));
QTest::newRow("min.norm") << raw("\x04\x00") << 0x0400U << ldexp(1.0, -14);
QTest::newRow("-min.norm") << raw("\x84\x00") << 0x8400U << ldexp(-1.0, -14);
QTest::newRow("1.0") << raw("\x3c\x00") << 0x3c00U << 1.0;
QTest::newRow("-1.0") << raw("\xbc\x00") << 0xbc00U << -1.0;
QTest::newRow("1.5") << raw("\x3e\x00") << 0x3e00U << 1.5;
QTest::newRow("-1.5") << raw("\xbe\x00") << 0xbe00U << -1.5;
QTest::newRow("max") << raw("\x7b\xff") << 0x7bffU << ldexp(1.0, 15) * (2.0 - ldexp(1.0, -10));
QTest::newRow("-max") << raw("\xfb\xff") << 0xfbffU << ldexp(-1.0, 15) * (2.0 - ldexp(1.0, -10));
QTest::newRow("inf") << raw("\x7c\x00") << 0x7c00U << myInf();
QTest::newRow("-inf") << raw("\xfc\x00") << 0xfc00U << myNInf();
QTest::newRow("nan1") << raw("\x7c\x01") << 0x7c01U << myNaN();
QTest::newRow("nan2") << raw("\xfc\x01") << 0xfc01U << myNaN();
QTest::newRow("nan3") << raw("\x7e\x00") << 0x7e00U << myNaN();
QTest::newRow("nan4") << raw("\xfe\x00") << 0xfe00U << myNaN();
}
void addColumns()
{
QTest::addColumn<QByteArray>("output");
QTest::addColumn<QVariant>("input");
}
void addFixedData()
{
// unsigned integers
QTest::newRow("0U") << raw("\x00") << QVariant(0U);
QTest::newRow("1U") << raw("\x01") << QVariant(1U);
QTest::newRow("10U") << raw("\x0a") << QVariant(10U);
QTest::newRow("23U") << raw("\x17") << QVariant(23U);
QTest::newRow("24U") << raw("\x18\x18") << QVariant(24U);
QTest::newRow("255U") << raw("\x18\xff") << QVariant(255U);
QTest::newRow("256U") << raw("\x19\x01\x00") << QVariant(256U);
QTest::newRow("65535U") << raw("\x19\xff\xff") << QVariant(65535U);
QTest::newRow("65536U") << raw("\x1a\0\1\x00\x00") << QVariant(65536U);
QTest::newRow("4294967295U") << raw("\x1a\xff\xff\xff\xff") << QVariant(4294967295U);
QTest::newRow("4294967296U") << raw("\x1b\0\0\0\1\0\0\0\0") << QVariant(Q_UINT64_C(4294967296));
QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
<< QVariant(std::numeric_limits<quint64>::max());
// signed integers containing non-negative numbers
QTest::newRow("0") << raw("\x00") << QVariant(0);
QTest::newRow("1") << raw("\x01") << QVariant(1);
QTest::newRow("10") << raw("\x0a") << QVariant(10);
QTest::newRow("23") << raw("\x17") << QVariant(23);
QTest::newRow("24") << raw("\x18\x18") << QVariant(24);
QTest::newRow("255") << raw("\x18\xff") << QVariant(255);
QTest::newRow("256") << raw("\x19\x01\x00") << QVariant(256);
QTest::newRow("65535") << raw("\x19\xff\xff") << QVariant(65535);
QTest::newRow("65536") << raw("\x1a\0\1\x00\x00") << QVariant(65536);
QTest::newRow("4294967295") << raw("\x1a\xff\xff\xff\xff") << QVariant(Q_INT64_C(4294967295));
QTest::newRow("4294967296") << raw("\x1b\0\0\0\1\0\0\0\0") << QVariant(Q_INT64_C(4294967296));
// signed integers containing negative numbers
QTest::newRow("-1") << raw("\x20") << QVariant(-1);
QTest::newRow("-2") << raw("\x21") << QVariant(-2);
QTest::newRow("-24") << raw("\x37") << QVariant(-24);
QTest::newRow("-25") << raw("\x38\x18") << QVariant(-25);
QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << QVariant(-256);
QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << QVariant(-257);
QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << QVariant(-65536);
QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << QVariant(-65537);
QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << QVariant(Q_INT64_C(-4294967296));
QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << QVariant(Q_INT64_C(-4294967297));
// negative integers
auto neg = [](quint64 v) { return QVariant::fromValue<NegativeInteger>({v}); };
QTest::newRow("negative1") << raw("\x20") << neg(1);
QTest::newRow("negative2") << raw("\x21") << neg(2);
QTest::newRow("negative24") << raw("\x37") << neg(24);
QTest::newRow("negative25") << raw("\x38\x18") << neg(25);
QTest::newRow("negativeUINT8_MAX") << raw("\x38\xff") << neg(256);
QTest::newRow("negativeUINT8_MAX-1") << raw("\x39\x01\x00") << neg(257);
QTest::newRow("negativeUINT16_MAX") << raw("\x39\xff\xff") << neg(65536);
QTest::newRow("negativeUINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << neg(65537);
QTest::newRow("negativeUINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << neg(Q_UINT64_C(4294967296));
QTest::newRow("negativeUINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << neg(Q_UINT64_C(4294967297));
QTest::newRow("negativeUINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
<< neg(std::numeric_limits<quint64>::max());
QTest::newRow("negativeUINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff") << neg(0);
QTest::newRow("simple0") << raw("\xe0") << QVariant::fromValue(SimpleType{0});
QTest::newRow("simple19") << raw("\xf3") << QVariant::fromValue(SimpleType{19});
QTest::newRow("false") << raw("\xf4") << QVariant(false);
QTest::newRow("true") << raw("\xf5") << QVariant(true);
QTest::newRow("null") << raw("\xf6") << QVariant::fromValue<void *>(nullptr);
QTest::newRow("undefined") << raw("\xf7") << QVariant();
QTest::newRow("simple32") << raw("\xf8\x20") << QVariant::fromValue(SimpleType{32});
QTest::newRow("simple255") << raw("\xf8\xff") << QVariant::fromValue(SimpleType{255});
// floating point
#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0)
QTest::newRow("0.f16") << raw("\xf9\0\0") << QVariant::fromValue(Float16Standin{0x0000});
#else
QTest::newRow("0.f16") << raw("\xf9\0\0") << QVariant::fromValue(qfloat16(0));
QTest::newRow("-1.f16") << raw("\xf9\xbc\0") << QVariant::fromValue(qfloat16(-1));
QTest::newRow("1.5f16") << raw("\xf9\x3e\0") << QVariant::fromValue(qfloat16(1.5));
QTest::newRow("nan_f16") << raw("\xf9\x7e\0") << QVariant::fromValue<qfloat16>(myNaNf());
QTest::newRow("-inf_f16") << raw("\xf9\xfc\0") << QVariant::fromValue<qfloat16>(myNInff());
QTest::newRow("+inf_f16") << raw("\xf9\x7c\0") << QVariant::fromValue<qfloat16>(myInff());
#endif
QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << QVariant::fromValue(0.f);
QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << QVariant(0.);
QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << QVariant::fromValue(-1.f);
QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << QVariant(-1.);
QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << QVariant::fromValue(16777215.f);
QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << QVariant::fromValue(16777215.);
QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << QVariant(-16777215.f);
QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << QVariant::fromValue(-16777215.);
QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << QVariant::fromValue<float>(myNaNf());
QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << QVariant(myNaN());
QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << QVariant::fromValue<float>(myNInff());
QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << QVariant(myNInf());
QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << QVariant::fromValue<float>(myInff());
QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << QVariant(myInf());
}
void addStringsData()
{
// byte strings
QTest::newRow("emptybytestring") << raw("\x40") << QVariant(QByteArray(""));
QTest::newRow("bytestring1") << raw("\x41 ") << QVariant(QByteArray(" "));
QTest::newRow("bytestring1-nul") << raw("\x41\0") << QVariant(QByteArray("", 1));
QTest::newRow("bytestring5") << raw("\x45Hello") << QVariant(QByteArray("Hello"));
QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
<< QVariant(QByteArray("123456789012345678901234"));
QTest::newRow("bytestring256") << raw("\x59\1\0") + QByteArray(256, '3')
<< QVariant(QByteArray(256, '3'));
// text strings
QTest::newRow("emptytextstring") << raw("\x60") << QVariant("");
QTest::newRow("textstring1") << raw("\x61 ") << QVariant(" ");
QTest::newRow("textstring1-nul") << raw("\x61\0") << QVariant(QString::fromLatin1("", 1));
QTest::newRow("textstring5") << raw("\x65Hello") << QVariant("Hello");
QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234")
<< QVariant("123456789012345678901234");
QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3')
<< QVariant(QString(256, '3'));
}
void addArraysAndMaps()
{
QTest::newRow("emptyarray") << raw("\x80") << make_list();
QTest::newRow("emptymap") << raw("\xa0") << make_map({});
QTest::newRow("array-0") << raw("\x81\0") << make_list(0);
QTest::newRow("array-{0-0}") << raw("\x82\0\0") << make_list(0, 0);
QTest::newRow("array-Hello") << raw("\x81\x65Hello") << make_list("Hello");
QTest::newRow("array-array-0") << raw("\x81\x81\0") << make_list(make_list(0));
QTest::newRow("array-array-{0-0}") << raw("\x81\x82\0\0") << make_list(make_list(0, 0));
QTest::newRow("array-array-0-0") << raw("\x82\x81\0\0") << make_list(make_list(0),0);
QTest::newRow("array-array-Hello") << raw("\x81\x81\x65Hello") << make_list(make_list("Hello"));
QTest::newRow("map-0:0") << raw("\xa1\0\0") << make_map({{0,0}});
QTest::newRow("map-0:0-1:1") << raw("\xa2\0\0\1\1") << make_map({{0,0}, {1,1}});
QTest::newRow("map-0:{map-0:0-1:1}") << raw("\xa1\0\xa2\0\0\1\1") << make_map({{0, make_map({{0,0}, {1,1}})}});
QTest::newRow("array-map1") << raw("\x81\xa1\0\0") << make_list(make_map({{0,0}}));
QTest::newRow("array-map2") << raw("\x82\xa1\0\0\xa1\1\1") << make_list(make_map({{0,0}}), make_map({{1,1}}));
QTest::newRow("map-array1") << raw("\xa1\x62oc\x81\0") << make_map({{"oc", make_list(0)}});
QTest::newRow("map-array2") << raw("\xa1\x62oc\x84\0\1\2\3") << make_map({{"oc", make_list(0, 1, 2, 3)}});
QTest::newRow("map-array3") << raw("\xa2\x62oc\x82\0\1\2\3") << make_map({{"oc", make_list(0, 1)}, {2, 3}});
// indeterminate length
QTest::newRow("_emptyarray") << raw("\x9f\xff") << QVariant::fromValue(IndeterminateLengthArray{});
QTest::newRow("_emptymap") << raw("\xbf\xff") << make_ilmap({});
QTest::newRow("_array-0") << raw("\x9f\0\xff") << make_ilarray({0});
QTest::newRow("_array-{0-0}") << raw("\x9f\0\0\xff") << make_ilarray({0, 0});
QTest::newRow("_array-Hello") << raw("\x9f\x65Hello\xff") << make_ilarray({"Hello"});
QTest::newRow("_array-array-0") << raw("\x9f\x81\0\xff") << make_ilarray({make_list(0)});
QTest::newRow("_array-_array-0") << raw("\x9f\x9f\0\xff\xff") << make_ilarray({make_ilarray({0})});
QTest::newRow("_array-_array-{0-0}") << raw("\x9f\x9f\0\0\xff\xff") << make_ilarray({make_ilarray({0, 0})});
QTest::newRow("_array-_array-0-0") << raw("\x9f\x9f\0\xff\0\xff") << make_ilarray({make_ilarray({0}),0});
QTest::newRow("_array-_array-Hello") << raw("\x9f\x9f\x65Hello\xff\xff") << make_ilarray({make_ilarray({"Hello"})});
QTest::newRow("_map-0:0") << raw("\xbf\0\0\xff") << make_ilmap({{0,0}});
QTest::newRow("_map-0:0-1:1") << raw("\xbf\0\0\1\1\xff") << make_ilmap({{0,0}, {1,1}});
QTest::newRow("_map-0:{map-0:0-1:1}") << raw("\xbf\0\xa2\0\0\1\1\xff") << make_ilmap({{0, make_map({{0,0}, {1,1}})}});
QTest::newRow("_map-0:{_map-0:0-1:1}") << raw("\xbf\0\xbf\0\0\1\1\xff\xff") << make_ilmap({{0, make_ilmap({{0,0}, {1,1}})}});
QTest::newRow("_array-map1") << raw("\x9f\xa1\0\0\xff") << make_ilarray({make_map({{0,0}})});
QTest::newRow("_array-_map1") << raw("\x9f\xbf\0\0\xff\xff") << make_ilarray({make_ilmap({{0,0}})});
QTest::newRow("_array-map2") << raw("\x9f\xa1\0\0\xa1\1\1\xff") << make_ilarray({make_map({{0,0}}), make_map({{1,1}})});
QTest::newRow("_array-_map2") << raw("\x9f\xbf\0\0\xff\xbf\1\1\xff\xff") << make_ilarray({make_ilmap({{0,0}}), make_ilmap({{1,1}})});
QTest::newRow("_map-array1") << raw("\xbf\x62oc\x81\0\xff") << make_ilmap({{"oc", make_list(0)}});
QTest::newRow("_map-_array1") << raw("\xbf\x62oc\x9f\0\xff\xff") << make_ilmap({{"oc", make_ilarray({0})}});
QTest::newRow("_map-array2") << raw("\xbf\x62oc\x84\0\1\2\3\xff") << make_ilmap({{"oc", make_list(0, 1, 2, 3)}});
QTest::newRow("_map-_array2") << raw("\xbf\x62oc\x9f\0\1\2\3\xff\xff") << make_ilmap({{"oc", make_ilarray({0, 1, 2, 3})}});
QTest::newRow("_map-array3") << raw("\xbf\x62oc\x82\0\1\2\3\xff") << make_ilmap({{"oc", make_list(0, 1)}, {2, 3}});
QTest::newRow("_map-_array3") << raw("\xbf\x62oc\x9f\0\1\xff\2\3\xff") << make_ilmap({{"oc", make_ilarray({0, 1})}, {2, 3}});
// tagged
QTest::newRow("array-1(0)") << raw("\x81\xc1\0") << make_list(QVariant::fromValue(Tag{1, 0}));
QTest::newRow("array-1(map)") << raw("\x81\xc1\xa0") << make_list(QVariant::fromValue(Tag{1, make_map({})}));
QTest::newRow("map-1(2):3(4)") << raw("\xa1\xc1\2\xc3\4") << make_map({{QVariant::fromValue(Tag{1, 2}), QVariant::fromValue(Tag{3, 4})}});
}

View File

@ -0,0 +1,9 @@
SOURCES += tst_encoder.cpp
CONFIG += testcase parallel_test c++11
QT = core testlib
INCLUDEPATH += ../../src
msvc: POST_TARGETDEPS = ../../lib/tinycbor.lib
else: POST_TARGETDEPS += ../../lib/libtinycbor.a
LIBS += $$POST_TARGETDEPS

View File

@ -0,0 +1,609 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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 <QtTest>
#include "cbor.h"
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
#include <qfloat16.h>
#endif
Q_DECLARE_METATYPE(CborError)
namespace QTest {
template<> char *toString<CborError>(const CborError &err)
{
return qstrdup(cbor_error_string(err));
}
}
class tst_Encoder : public QObject
{
Q_OBJECT
private slots:
void floatAsHalfFloat_data();
void floatAsHalfFloat();
void halfFloat_data();
void halfFloat();
void floatAsHalfFloatCloseToZero_data();
void floatAsHalfFloatCloseToZero();
void floatAsHalfFloatNaN();
void fixed_data();
void fixed();
void strings_data();
void strings() { fixed(); }
void arraysAndMaps_data();
void arraysAndMaps() { fixed(); }
void tags_data();
void tags();
void arrays_data() { tags_data(); }
void arrays();
void maps_data() { tags_data(); }
void maps();
void writerApi_data() { tags_data(); }
void writerApi();
void writerApiFail_data() { tags_data(); }
void writerApiFail();
void shortBuffer_data() { tags_data(); }
void shortBuffer();
void tooShortArrays_data() { tags_data(); }
void tooShortArrays();
void tooShortMaps_data() { tags_data(); }
void tooShortMaps();
void tooBigArrays_data() { tags_data(); }
void tooBigArrays();
void tooBigMaps_data() { tags_data(); }
void tooBigMaps();
void illegalSimpleType_data();
void illegalSimpleType();
};
#include "tst_encoder.moc"
#include "data.cpp"
static inline bool isOomError(CborError err)
{
return err == CborErrorOutOfMemory;
}
CborError encodeVariant(CborEncoder *encoder, const QVariant &v)
{
int type = v.userType();
switch (type) {
case QVariant::Int:
case QVariant::LongLong:
return cbor_encode_int(encoder, v.toLongLong());
case QVariant::UInt:
case QVariant::ULongLong:
return cbor_encode_uint(encoder, v.toULongLong());
case QVariant::Bool:
return cbor_encode_boolean(encoder, v.toBool());
case QVariant::Invalid:
return cbor_encode_undefined(encoder);
case QMetaType::VoidStar:
return cbor_encode_null(encoder);
case QVariant::Double:
return cbor_encode_double(encoder, v.toDouble());
case QMetaType::Float:
return cbor_encode_float(encoder, v.toFloat());
case QVariant::String: {
QByteArray string = v.toString().toUtf8();
return cbor_encode_text_string(encoder, string.constData(), string.length());
}
case QVariant::ByteArray: {
QByteArray string = v.toByteArray();
return cbor_encode_byte_string(encoder, reinterpret_cast<const quint8 *>(string.constData()), string.length());
}
default:
if (type == qMetaTypeId<NegativeInteger>())
return cbor_encode_negative_int(encoder, v.value<NegativeInteger>().abs);
if (type == qMetaTypeId<SimpleType>())
return cbor_encode_simple_value(encoder, v.value<SimpleType>().type);
#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0)
if (type == qMetaTypeId<Float16Standin>())
return cbor_encode_half_float(encoder, v.constData());
#else
if (type == qMetaTypeId<qfloat16>())
return cbor_encode_half_float(encoder, v.constData());
#endif
if (type == qMetaTypeId<Tag>()) {
CborError err = cbor_encode_tag(encoder, v.value<Tag>().tag);
if (err && !isOomError(err))
return err;
return static_cast<CborError>(err | encodeVariant(encoder, v.value<Tag>().tagged));
}
if (type == QVariant::List || type == qMetaTypeId<IndeterminateLengthArray>()) {
CborEncoder sub;
QVariantList list = v.toList();
size_t len = list.length();
if (type == qMetaTypeId<IndeterminateLengthArray>()) {
len = CborIndefiniteLength;
list = v.value<IndeterminateLengthArray>();
}
CborError err = cbor_encoder_create_array(encoder, &sub, len);
if (err && !isOomError(err))
return err;
foreach (const QVariant &v2, list) {
err = static_cast<CborError>(err | encodeVariant(&sub, v2));
if (err && !isOomError(err))
return err;
}
return cbor_encoder_close_container_checked(encoder, &sub);
}
if (type == qMetaTypeId<Map>() || type == qMetaTypeId<IndeterminateLengthMap>()) {
CborEncoder sub;
Map map = v.value<Map>();
size_t len = map.length();
if (type == qMetaTypeId<IndeterminateLengthMap>()) {
len = CborIndefiniteLength;
map = v.value<IndeterminateLengthMap>();
}
CborError err = cbor_encoder_create_map(encoder, &sub, len);
if (err && !isOomError(err))
return err;
for (auto pair : map) {
err = static_cast<CborError>(err | encodeVariant(&sub, pair.first));
if (err && !isOomError(err))
return err;
err = static_cast<CborError>(err | encodeVariant(&sub, pair.second));
if (err && !isOomError(err))
return err;
}
return cbor_encoder_close_container_checked(encoder, &sub);
}
}
return CborErrorUnknownType;
}
template <typename Input, typename FnUnderTest>
void encodeOne(Input input, FnUnderTest fn_under_test, QByteArray &buffer, CborError &error)
{
uint8_t *bufptr = reinterpret_cast<quint8 *>(buffer.data());
CborEncoder encoder;
cbor_encoder_init(&encoder, bufptr, buffer.length(), 0);
error = fn_under_test(&encoder, input);
if (error == CborNoError) {
QCOMPARE(encoder.remaining, size_t(1));
QCOMPARE(cbor_encoder_get_extra_bytes_needed(&encoder), size_t(0));
buffer.resize(int(cbor_encoder_get_buffer_size(&encoder, bufptr)));
}
}
template <typename Input, typename FnUnderTest>
void compare(Input input, FnUnderTest fn_under_test, const QByteArray &output)
{
QByteArray buffer(output.length(), Qt::Uninitialized);
CborError error;
encodeOne(input, fn_under_test, buffer, error);
if (QTest::currentTestFailed())
return;
QCOMPARE(error, CborNoError);
QCOMPARE(buffer, output);
}
void compare(const QVariant &input, const QByteArray &output)
{
compare(input, encodeVariant, output);
}
void tst_Encoder::floatAsHalfFloat_data()
{
addHalfFloat();
}
void tst_Encoder::floatAsHalfFloat()
{
QFETCH(unsigned, rawInput);
QFETCH(double, floatInput);
QFETCH(QByteArray, output);
if (rawInput == 0U || rawInput == 0x8000U)
QSKIP("zero values are out of scope of this test case", QTest::SkipSingle);
if (qIsNaN(floatInput))
QSKIP("NaN values are out of scope of this test case", QTest::SkipSingle);
output.prepend('\xf9');
compare((float)floatInput, cbor_encode_float_as_half_float, output);
}
void tst_Encoder::halfFloat_data()
{
addHalfFloat();
}
void tst_Encoder::halfFloat()
{
QFETCH(unsigned, rawInput);
QFETCH(QByteArray, output);
uint16_t v = (uint16_t)rawInput;
output.prepend('\xf9');
compare(&v, cbor_encode_half_float, output);
}
void tst_Encoder::floatAsHalfFloatCloseToZero_data()
{
QTest::addColumn<double>("floatInput");
QTest::newRow("+0") << 0.0;
QTest::newRow("-0") << -0.0;
QTest::newRow("below min.denorm") << ldexp(1.0, -14) * ldexp(1.0, -11);
QTest::newRow("above -min.denorm") << ldexp(-1.0, -14) * ldexp(1.0, -11);
}
void tst_Encoder::floatAsHalfFloatCloseToZero()
{
QFETCH(double, floatInput);
QByteArray buffer(4, Qt::Uninitialized);
CborError error;
encodeOne((float)floatInput, cbor_encode_float_as_half_float, buffer, error);
QCOMPARE(error, CborNoError);
QVERIFY2(
buffer == raw("\xf9\x00\x00") || buffer == raw("\xf9\x80\x00"),
"Got value " + QByteArray::number(floatInput) + " encoded to: " + buffer);
}
void tst_Encoder::floatAsHalfFloatNaN()
{
QByteArray buffer(4, Qt::Uninitialized);
CborError error;
encodeOne(myNaNf(), cbor_encode_float_as_half_float, buffer, error);
QCOMPARE(error, CborNoError);
QCOMPARE(buffer.size(), 3);
uint8_t ini_byte = (uint8_t)buffer[0],
exp = (uint8_t)buffer[1] & 0x7cU,
manth = (uint8_t)buffer[1] & 0x03U,
mantl = (uint8_t)buffer[2];
QCOMPARE((unsigned)ini_byte, 0xf9U);
QCOMPARE((unsigned)exp, 0x7cU);
QVERIFY((manth | mantl) != 0);
}
void tst_Encoder::fixed_data()
{
addColumns();
addFixedData();
}
void tst_Encoder::fixed()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
compare(input, output);
}
void tst_Encoder::strings_data()
{
addColumns();
addStringsData();
}
void tst_Encoder::arraysAndMaps_data()
{
addColumns();
addArraysAndMaps();
}
void tst_Encoder::tags_data()
{
addColumns();
addFixedData();
addStringsData();
addArraysAndMaps();
}
void tst_Encoder::tags()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
compare(QVariant::fromValue(Tag{1, input}), "\xc1" + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{24, input}), "\xd8\x18" + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{255, input}), "\xd8\xff" + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{256, input}), raw("\xd9\1\0") + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{CborSignatureTag, input}), raw("\xd9\xd9\xf7") + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{65535, input}), raw("\xd9\xff\xff") + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{65536, input}), raw("\xda\0\1\0\0") + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{UINT32_MAX, input}), raw("\xda\xff\xff\xff\xff") + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{UINT32_MAX + Q_UINT64_C(1), input}), raw("\xdb\0\0\0\1\0\0\0\0") + output);
if (QTest::currentTestFailed()) return;
compare(QVariant::fromValue(Tag{UINT64_MAX, input}), raw("\xdb\xff\xff\xff\xff\xff\xff\xff\xff") + output);
if (QTest::currentTestFailed()) return;
// nested tags
compare(QVariant::fromValue(Tag{1, QVariant::fromValue(Tag{1, input})}), "\xc1\xc1" + output);
}
void tst_Encoder::arrays()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
compare(make_list(input), "\x81" + output);
if (QTest::currentTestFailed()) return;
compare(make_list(input, input), "\x82" + output + output);
if (QTest::currentTestFailed()) return;
{
QVariantList list{input};
QByteArray longoutput = output;
// make a list with 32 elements (1 << 5)
for (int i = 0; i < 5; ++i) {
list += list;
longoutput += longoutput;
}
compare(list, "\x98\x20" + longoutput);
if (QTest::currentTestFailed()) return;
// now 256 elements (32 << 3)
for (int i = 0; i < 3; ++i) {
list += list;
longoutput += longoutput;
}
compare(list, raw("\x99\1\0") + longoutput);
if (QTest::currentTestFailed()) return;
}
// nested lists
compare(make_list(make_list(input)), "\x81\x81" + output);
if (QTest::currentTestFailed()) return;
compare(make_list(make_list(input, input)), "\x81\x82" + output + output);
if (QTest::currentTestFailed()) return;
compare(make_list(make_list(input), input), "\x82\x81" + output + output);
if (QTest::currentTestFailed()) return;
compare(make_list(make_list(input), make_list(input)), "\x82\x81" + output + "\x81" + output);
}
void tst_Encoder::maps()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
compare(make_map({{1, input}}), "\xa1\1" + output);
if (QTest::currentTestFailed()) return;
compare(make_map({{1, input}, {input, 24}}), "\xa2\1" + output + output + "\x18\x18");
if (QTest::currentTestFailed()) return;
compare(make_map({{input, input}}), "\xa1" + output + output);
if (QTest::currentTestFailed()) return;
{
Map map{{1, input}};
QByteArray longoutput = "\1" + output;
// make a map with 32 elements (1 << 5)
for (int i = 0; i < 5; ++i) {
map += map;
longoutput += longoutput;
}
compare(QVariant::fromValue(map), "\xb8\x20" + longoutput);
if (QTest::currentTestFailed()) return;
// now 256 elements (32 << 3)
for (int i = 0; i < 3; ++i) {
map += map;
longoutput += longoutput;
}
compare(QVariant::fromValue(map), raw("\xb9\1\0") + longoutput);
if (QTest::currentTestFailed()) return;
}
// nested maps
compare(make_map({{1, make_map({{2, input}})}}), "\xa1\1\xa1\2" + output);
if (QTest::currentTestFailed()) return;
compare(make_map({{1, make_map({{2, input}, {input, false}})}}), "\xa1\1\xa2\2" + output + output + "\xf4");
if (QTest::currentTestFailed()) return;
compare(make_map({{1, make_map({{2, input}})}, {input, false}}), "\xa2\1\xa1\2" + output + output + "\xf4");
if (QTest::currentTestFailed()) return;
}
void tst_Encoder::writerApi()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
// instead of writing to a QByteArray like all other tests, write to a QBuffer
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
auto callback = [](void *token, const void *data, size_t len, CborEncoderAppendType) {
auto buffer = static_cast<QBuffer *>(token);
buffer->write(static_cast<const char *>(data), len);
return CborNoError;
};
CborEncoder encoder;
cbor_encoder_init_writer(&encoder, callback, &buffer);
QCOMPARE(encodeVariant(&encoder, input), CborNoError);
buffer.reset();
QCOMPARE(buffer.readAll(), output);
}
void tst_Encoder::writerApiFail()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
// same as above, but we'll produce an error during writing and we expect
// it to be returned
int callCount = 0;
auto callback = [](void *token, const void *, size_t, CborEncoderAppendType) {
++*static_cast<int *>(token);
return CborErrorIO;
};
CborEncoder encoder;
cbor_encoder_init_writer(&encoder, callback, &callCount);
QCOMPARE(encodeVariant(&encoder, input), CborErrorIO);
QCOMPARE(callCount, 1);
}
void tst_Encoder::shortBuffer()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
QByteArray buffer(output.length(), Qt::Uninitialized);
for (int len = 0; len < output.length(); ++len) {
CborEncoder encoder;
cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), len, 0);
QCOMPARE(encodeVariant(&encoder, input), CborErrorOutOfMemory);
QVERIFY(cbor_encoder_get_extra_bytes_needed(&encoder) != 0);
QCOMPARE(len + cbor_encoder_get_extra_bytes_needed(&encoder), size_t(output.length()));
}
}
void tst_Encoder::tooShortArrays()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
QByteArray buffer(output.length() + 1, Qt::Uninitialized);
CborEncoder encoder, container;
cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
QCOMPARE(cbor_encoder_create_array(&encoder, &container, 2), CborNoError);
QCOMPARE(encodeVariant(&container, input), CborNoError);
QCOMPARE(container.remaining, size_t(2));
QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooFewItems);
}
void tst_Encoder::tooShortMaps()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
QByteArray buffer(output.length() + 1, Qt::Uninitialized);
CborEncoder encoder, container;
cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
QCOMPARE(cbor_encoder_create_map(&encoder, &container, 2), CborNoError);
QCOMPARE(encodeVariant(&container, input), CborNoError);
QCOMPARE(container.remaining, size_t(4));
QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooFewItems);
}
void tst_Encoder::tooBigArrays()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
QByteArray buffer(output.length() * 2 + 1, Qt::Uninitialized);
CborEncoder encoder, container;
cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
QCOMPARE(cbor_encoder_create_array(&encoder, &container, 1), CborNoError);
QCOMPARE(encodeVariant(&container, input), CborNoError);
QCOMPARE(encodeVariant(&container, input), CborNoError);
QCOMPARE(container.remaining, size_t(0));
QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooManyItems);
}
void tst_Encoder::tooBigMaps()
{
QFETCH(QVariant, input);
QFETCH(QByteArray, output);
QByteArray buffer(output.length() * 3 + 1, Qt::Uninitialized);
CborEncoder encoder, container;
cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
QCOMPARE(cbor_encoder_create_map(&encoder, &container, 1), CborNoError);
QCOMPARE(encodeVariant(&container, input), CborNoError);
QCOMPARE(encodeVariant(&container, input), CborNoError);
QCOMPARE(encodeVariant(&container, input), CborNoError);
QCOMPARE(container.remaining, size_t(0));
QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooManyItems);
}
void tst_Encoder::illegalSimpleType_data()
{
QTest::addColumn<int>("type");
QTest::newRow("half-float") << 25;
QTest::newRow("float") << 26;
QTest::newRow("double") << 27;
QTest::newRow("28") << 28;
QTest::newRow("29") << 29;
QTest::newRow("30") << 30;
QTest::newRow("31") << 31;
}
void tst_Encoder::illegalSimpleType()
{
QFETCH(int, type);
quint8 buf[2];
CborEncoder encoder;
cbor_encoder_init(&encoder, buf, sizeof(buf), 0);
QCOMPARE(cbor_encode_simple_value(&encoder, type), CborErrorIllegalSimpleType);
}
QTEST_MAIN(tst_Encoder)

View File

@ -0,0 +1,607 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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 <QtTest>
#include <limits>
#include <cbor.h>
Q_DECLARE_METATYPE(CborError)
template <size_t N> QByteArray raw(const char (&data)[N])
{
return QByteArray::fromRawData(data, N - 1);
}
void addIntegers()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<quint64>("expectedRaw");
QTest::addColumn<qint64>("expectedValue");
QTest::addColumn<bool>("isNegative");
QTest::addColumn<bool>("inInt64Range");
// unsigned integers
QTest::newRow("0") << raw("\x00") << Q_UINT64_C(0) << Q_INT64_C(0) << false << true;
QTest::newRow("1") << raw("\x01") << Q_UINT64_C(1) << Q_INT64_C(1) << false << true;
QTest::newRow("10") << raw("\x0a") << Q_UINT64_C(10) << Q_INT64_C(10) << false << true;
QTest::newRow("23") << raw("\x17") << Q_UINT64_C(23) << Q_INT64_C(23) << false << true;
QTest::newRow("24") << raw("\x18\x18") << Q_UINT64_C(24) << Q_INT64_C(24) << false << true;
QTest::newRow("UINT8_MAX") << raw("\x18\xff") << Q_UINT64_C(255) << Q_INT64_C(255) << false << true;
QTest::newRow("UINT8_MAX+1") << raw("\x19\x01\x00") << Q_UINT64_C(256) << Q_INT64_C(256) << false << true;
QTest::newRow("UINT16_MAX") << raw("\x19\xff\xff") << Q_UINT64_C(65535) << Q_INT64_C(65535) << false << true;
QTest::newRow("UINT16_MAX+1") << raw("\x1a\0\1\x00\x00") << Q_UINT64_C(65536) << Q_INT64_C(65536) << false << true;
QTest::newRow("UINT32_MAX") << raw("\x1a\xff\xff\xff\xff") << Q_UINT64_C(4294967295) << Q_INT64_C(4294967295) << false << true;
QTest::newRow("UINT32_MAX+1") << raw("\x1b\0\0\0\1\0\0\0\0") << Q_UINT64_C(4294967296) << Q_INT64_C(4294967296) << false << true;
QTest::newRow("INT64_MAX") << raw("\x1b" "\x7f\xff\xff\xff" "\xff\xff\xff\xff")
<< quint64(std::numeric_limits<qint64>::max())
<< std::numeric_limits<qint64>::max() << false << true;
QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
<< std::numeric_limits<quint64>::max() << qint64(-123456) << false << false;
// negative integers
QTest::newRow("-1") << raw("\x20") << Q_UINT64_C(0) << Q_INT64_C(-1) << true << true;
QTest::newRow("-2") << raw("\x21") << Q_UINT64_C(1) << Q_INT64_C(-2) << true << true;
QTest::newRow("-24") << raw("\x37") << Q_UINT64_C(23) << Q_INT64_C(-24) << true << true;
QTest::newRow("-25") << raw("\x38\x18") << Q_UINT64_C(24) << Q_INT64_C(-25) << true << true;
QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << Q_UINT64_C(255) << Q_INT64_C(-256) << true << true;
QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << Q_UINT64_C(256) << Q_INT64_C(-257) << true << true;
QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << Q_UINT64_C(65535) << Q_INT64_C(-65536) << true << true;
QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << Q_UINT64_C(65536) << Q_INT64_C(-65537) << true << true;
QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << Q_UINT64_C(4294967295) << Q_INT64_C(-4294967296) << true << true;
QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << Q_UINT64_C(4294967296) << Q_INT64_C(-4294967297) << true << true;
QTest::newRow("INT64_MIN+1") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xfe")
<< quint64(std::numeric_limits<qint64>::max() - 1)
<< (std::numeric_limits<qint64>::min() + 1)
<< true << true;
QTest::newRow("INT64_MIN") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
<< quint64(std::numeric_limits<qint64>::max())
<< std::numeric_limits<qint64>::min()
<< true << true;
QTest::newRow("INT64_MIN-1") << raw("\x3b\x80\0\0\0""\0\0\0\0") << Q_UINT64_C(9223372036854775808) << qint64(-123456) << true << false;
QTest::newRow("-UINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
<< (std::numeric_limits<quint64>::max() - 1) << qint64(-123456) << true << false;
QTest::newRow("-UINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
<< std::numeric_limits<quint64>::max() << qint64(-123456) << true << false;
}
void addColumns()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<QString>("expected");
QTest::addColumn<int>("n"); // some aux integer, not added in all columns
}
void addFixedData()
{
// unsigned integers
QTest::newRow("0") << raw("\x00") << "0";
QTest::newRow("1") << raw("\x01") << "1";
QTest::newRow("10") << raw("\x0a") << "10";
QTest::newRow("23") << raw("\x17") << "23";
QTest::newRow("24") << raw("\x18\x18") << "24";
QTest::newRow("UINT8_MAX") << raw("\x18\xff") << "255";
QTest::newRow("UINT8_MAX+1") << raw("\x19\x01\x00") << "256";
QTest::newRow("UINT16_MAX") << raw("\x19\xff\xff") << "65535";
QTest::newRow("UINT16_MAX+1") << raw("\x1a\0\1\x00\x00") << "65536";
QTest::newRow("UINT32_MAX") << raw("\x1a\xff\xff\xff\xff") << "4294967295";
QTest::newRow("UINT32_MAX+1") << raw("\x1b\0\0\0\1\0\0\0\0") << "4294967296";
QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
<< QString::number(std::numeric_limits<uint64_t>::max());
// negative integers
QTest::newRow("-1") << raw("\x20") << "-1";
QTest::newRow("-2") << raw("\x21") << "-2";
QTest::newRow("-24") << raw("\x37") << "-24";
QTest::newRow("-25") << raw("\x38\x18") << "-25";
QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << "-256";
QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << "-257";
QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << "-65536";
QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << "-65537";
QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << "-4294967296";
QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << "-4294967297";
QTest::newRow("INT64_MIN+1") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xfe")
<< QString::number(std::numeric_limits<int64_t>::min() + 1);
QTest::newRow("INT64_MIN") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
<< QString::number(std::numeric_limits<int64_t>::min());
QTest::newRow("INT64_MIN-1") << raw("\x3b\x80\0\0\0""\0\0\0\0") << "-9223372036854775809";
QTest::newRow("-UINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
<< '-' + QString::number(std::numeric_limits<uint64_t>::max());
QTest::newRow("-UINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
<< "-18446744073709551616";
// overlongs
QTest::newRow("0*1") << raw("\x18\x00") << "0_0";
QTest::newRow("0*2") << raw("\x19\x00\x00") << "0_1";
QTest::newRow("0*4") << raw("\x1a\0\0\0\0") << "0_2";
QTest::newRow("0*8") << raw("\x1b\0\0\0\0\0\0\0\0") << "0_3";
QTest::newRow("-1*1") << raw("\x38\x00") << "-1_0";
QTest::newRow("-1*2") << raw("\x39\x00\x00") << "-1_1";
QTest::newRow("-1*4") << raw("\x3a\0\0\0\0") << "-1_2";
QTest::newRow("-1*8") << raw("\x3b\0\0\0\0\0\0\0\0") << "-1_3";
QTest::newRow("simple0") << raw("\xe0") << "simple(0)";
QTest::newRow("simple19") << raw("\xf3") << "simple(19)";
QTest::newRow("false") << raw("\xf4") << "false";
QTest::newRow("true") << raw("\xf5") << "true";
QTest::newRow("null") << raw("\xf6") << "null";
QTest::newRow("undefined") << raw("\xf7") << "undefined";
QTest::newRow("simple32") << raw("\xf8\x20") << "simple(32)";
QTest::newRow("simple255") << raw("\xf8\xff") << "simple(255)";
// floating point
QTest::newRow("0.f16") << raw("\xf9\0\0") << "0.f16";
QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << "0.f";
QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << "0.";
QTest::newRow("-1.f16") << raw("\xf9\xbc\x00") << "-1.f16";
QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << "-1.f";
QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << "-1.";
QTest::newRow("65504.f16") << raw("\xf9\x7b\xff") << "65504.f16";
QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << "16777215.";
QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << "-16777215.f";
QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << "-16777215.";
QTest::newRow("0.5f16") << raw("\xf9\x38\0") << "0.5f16";
QTest::newRow("0.5f") << raw("\xfa\x3f\0\0\0") << "0.5f";
QTest::newRow("0.5") << raw("\xfb\x3f\xe0\0\0\0\0\0\0") << "0.5";
QTest::newRow("2.f16^11-1") << raw("\xf9\x67\xff") << "2047.f16";
QTest::newRow("2.f^24-1") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
QTest::newRow("2.^53-1") << raw("\xfb\x43\x3f\xff\xff""\xff\xff\xff\xff") << "9007199254740991.";
QTest::newRow("2.f^64-epsilon") << raw("\xfa\x5f\x7f\xff\xff") << "18446742974197923840.f";
QTest::newRow("2.^64-epsilon") << raw("\xfb\x43\xef\xff\xff""\xff\xff\xff\xff") << "18446744073709549568.";
QTest::newRow("2.f^64") << raw("\xfa\x5f\x80\0\0") << "1.8446744073709552e+19f";
QTest::newRow("2.^64") << raw("\xfb\x43\xf0\0\0\0\0\0\0") << "1.8446744073709552e+19";
QTest::newRow("nan_f16") << raw("\xf9\x7e\x00") << "nan";
QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << "nan";
QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << "nan";
QTest::newRow("-inf_f16") << raw("\xf9\xfc\x00") << "-inf";
QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << "-inf";
QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << "-inf";
QTest::newRow("+inf_f16") << raw("\xf9\x7c\x00") << "inf";
QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << "inf";
QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << "inf";
}
void addNonChunkedStringsData()
{
// byte strings
QTest::newRow("emptybytestring") << raw("\x40") << "h''";
QTest::newRow("bytestring1") << raw("\x41 ") << "h'20'";
QTest::newRow("bytestring1-nul") << raw("\x41\0") << "h'00'";
QTest::newRow("bytestring5") << raw("\x45Hello") << "h'48656c6c6f'";
QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
<< "h'313233343536373839303132333435363738393031323334'";
QTest::newRow("bytestring256") << raw("\x59\1\0") + QByteArray(256, '3')
<< "h'" + QString(256 * 2, '3') + '\'';
// text strings
QTest::newRow("emptytextstring") << raw("\x60") << "\"\"";
QTest::newRow("textstring1") << raw("\x61 ") << "\" \"";
QTest::newRow("textstring1-nul") << raw("\x61\0") << "\"\\u0000\"";
QTest::newRow("textstring5") << raw("\x65Hello") << "\"Hello\"";
QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234")
<< "\"123456789012345678901234\"";
QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3')
<< '"' + QString(256, '3') + '"';
// some strings with UTF-8 content
// we had a bug in the pretty dumper - see issue #54
QTest::newRow("textstringutf8-2char") << raw("\x62\xc2\xa0") << "\"\\u00A0\"";
QTest::newRow("textstringutf8-2char2") << raw("\x64\xc2\xa0\xc2\xa9") << "\"\\u00A0\\u00A9\"";
QTest::newRow("textstringutf8-3char") << raw("\x63\xe2\x88\x80") << "\"\\u2200\"";
QTest::newRow("textstringutf8-4char") << raw("\x64\xf0\x90\x88\x83") << "\"\\uD800\\uDE03\"";
// strings with overlong length
QTest::newRow("emptybytestring*1") << raw("\x58\x00") << "h''_0";
QTest::newRow("emptytextstring*1") << raw("\x78\x00") << "\"\"_0";
QTest::newRow("emptybytestring*2") << raw("\x59\x00\x00") << "h''_1";
QTest::newRow("emptytextstring*2") << raw("\x79\x00\x00") << "\"\"_1";
QTest::newRow("emptybytestring*4") << raw("\x5a\0\0\0\0") << "h''_2";
QTest::newRow("emptytextstring*4") << raw("\x7a\0\0\0\0") << "\"\"_2";
QTest::newRow("emptybytestring*8") << raw("\x5b\0\0\0\0\0\0\0\0") << "h''_3";
QTest::newRow("emptytextstring*8") << raw("\x7b\0\0\0\0\0\0\0\0") << "\"\"_3";
QTest::newRow("bytestring5*1") << raw("\x58\x05Hello") << "h'48656c6c6f'_0";
QTest::newRow("textstring5*1") << raw("\x78\x05Hello") << "\"Hello\"_0";
QTest::newRow("bytestring5*2") << raw("\x59\0\5Hello") << "h'48656c6c6f'_1";
QTest::newRow("textstring5*2") << raw("\x79\0\x05Hello") << "\"Hello\"_1";
QTest::newRow("bytestring5*4") << raw("\x5a\0\0\0\5Hello") << "h'48656c6c6f'_2";
QTest::newRow("textstring5*4") << raw("\x7a\0\0\0\x05Hello") << "\"Hello\"_2";
QTest::newRow("bytestring5*8") << raw("\x5b\0\0\0\0\0\0\0\5Hello") << "h'48656c6c6f'_3";
QTest::newRow("textstring5*8") << raw("\x7b\0\0\0\0\0\0\0\x05Hello") << "\"Hello\"_3";
}
void addStringsData()
{
addNonChunkedStringsData();
// strings with undefined length
QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "(_ )";
QTest::newRow("_emptytextstring") << raw("\x7f\xff") << "(_ )";
QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << "(_ h'')";
QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << "(_ \"\")";
QTest::newRow("_emptybytestring2*1") << raw("\x5f\x58\x00\xff") << "(_ h''_0)";
QTest::newRow("_emptytextstring2*1") << raw("\x7f\x78\x00\xff") << "(_ \"\"_0)";
QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << "(_ h'', h'')";
QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << "(_ \"\", \"\")";
QTest::newRow("_emptybytestring3*2") << raw("\x5f\x59\x00\x00\x40\xff") << "(_ h''_1, h'')";
QTest::newRow("_emptytextstring3*2") << raw("\x7f\x79\x00\x00\x60\xff") << "(_ \"\"_1, \"\")";
QTest::newRow("_bytestring5x2") << raw("\x5f\x43Hel\x42lo\xff") << "(_ h'48656c', h'6c6f')";
QTest::newRow("_textstring5x2") << raw("\x7f\x63Hel\x62lo\xff") << "(_ \"Hel\", \"lo\")";
QTest::newRow("_bytestring5x2*8*4") << raw("\x5f\x5b\0\0\0\0\0\0\0\3Hel\x5a\0\0\0\2lo\xff") << "(_ h'48656c'_3, h'6c6f'_2)";
QTest::newRow("_textstring5x2*8*4") << raw("\x7f\x7b\0\0\0\0\0\0\0\3Hel\x7a\0\0\0\2lo\xff") << "(_ \"Hel\"_3, \"lo\"_2)";
QTest::newRow("_bytestring5x5") << raw("\x5f\x41H\x41""e\x41l\x41l\x41o\xff") << "(_ h'48', h'65', h'6c', h'6c', h'6f')";
QTest::newRow("_textstring5x5") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "(_ \"H\", \"e\", \"l\", \"l\", \"o\")";
QTest::newRow("_bytestring5x6") << raw("\x5f\x41H\x41""e\x40\x41l\x41l\x41o\xff") << "(_ h'48', h'65', h'', h'6c', h'6c', h'6f')";
QTest::newRow("_textstring5x6") << raw("\x7f\x61H\x61""e\x61l\x60\x61l\x61o\xff") << "(_ \"H\", \"e\", \"l\", \"\", \"l\", \"o\")";
}
void addTagsData()
{
// since parseOne() works recursively for tags, we can't test lone tags
QTest::newRow("tag0") << raw("\xc0\x00") << "0(0)";
QTest::newRow("tag1") << raw("\xc1\x00") << "1(0)";
QTest::newRow("tag24") << raw("\xd8\x18\x00") << "24(0)";
QTest::newRow("tag255") << raw("\xd8\xff\x00") << "255(0)";
QTest::newRow("tag256") << raw("\xd9\1\0\x00") << "256(0)";
QTest::newRow("tag65535") << raw("\xd9\xff\xff\x00") << "65535(0)";
QTest::newRow("tag65536") << raw("\xda\0\1\0\0\x00") << "65536(0)";
QTest::newRow("tagUINT32_MAX-1") << raw("\xda\xff\xff\xff\xff\x00") << "4294967295(0)";
QTest::newRow("tagUINT32_MAX") << raw("\xdb\0\0\0\1\0\0\0\0\x00") << "4294967296(0)";
QTest::newRow("tagUINT64_MAX") << raw("\xdb" "\xff\xff\xff\xff" "\xff\xff\xff\xff" "\x00")
<< QString::number(std::numeric_limits<uint64_t>::max()) + "(0)";
// overlong tags
QTest::newRow("tag0*1") << raw("\xd8\0\x00") << "0_0(0)";
QTest::newRow("tag0*2") << raw("\xd9\0\0\x00") << "0_1(0)";
QTest::newRow("tag0*4") << raw("\xda\0\0\0\0\x00") << "0_2(0)";
QTest::newRow("tag0*8") << raw("\xdb\0\0\0\0\0\0\0\0\x00") << "0_3(0)";
// tag other things
QTest::newRow("unixtime") << raw("\xc1\x1a\x55\x4b\xbf\xd3") << "1(1431027667)";
QTest::newRow("rfc3339date") << raw("\xc0\x78\x19" "2015-05-07 12:41:07-07:00")
<< "0(\"2015-05-07 12:41:07-07:00\")";
QTest::newRow("tag6+false") << raw("\xc6\xf4") << "6(false)";
QTest::newRow("tag25+true") << raw("\xd8\x19\xf5") << "25(true)";
QTest::newRow("tag256+null") << raw("\xd9\1\0\xf6") << "256(null)";
QTest::newRow("tag65536+simple32") << raw("\xda\0\1\0\0\xf8\x20") << "65536(simple(32))";
QTest::newRow("float+unixtime") << raw("\xc1\xfa\x4e\xaa\x97\x80") << "1(1431027712.f)";
QTest::newRow("double+unixtime") << raw("\xc1\xfb" "\x41\xd5\x52\xef" "\xf4\xc7\xce\xfe")
<< "1(1431027667.1220088)";
}
void addEmptyContainersData()
{
QTest::newRow("emptyarray") << raw("\x80") << "[]" << 0;
QTest::newRow("emptymap") << raw("\xa0") << "{}" << 0;
QTest::newRow("_emptyarray") << raw("\x9f\xff") << "[_ ]" << -1;
QTest::newRow("_emptymap") << raw("\xbf\xff") << "{_ }" << -1;
}
void addMapMixedData()
{
QTest::newRow("map-0-24") << raw("\xa1\0\x18\x18") << "{0: 24}" << 1;
QTest::newRow("map-0*1-24") << raw("\xa1\x18\0\x18\x18") << "{0_0: 24}" << 1;
QTest::newRow("map-0*1-24*2") << raw("\xa1\x18\0\x19\0\x18") << "{0_0: 24_1}" << 1;
QTest::newRow("map-0*4-24*2") << raw("\xa1\x1a\0\0\0\0\x19\0\x18") << "{0_2: 24_1}" << 1;
QTest::newRow("map-24-0") << raw("\xa1\x18\x18\0") << "{24: 0}" << 1;
QTest::newRow("map-24-0*1") << raw("\xa1\x18\x18\x18\0") << "{24: 0_0}" << 1;
QTest::newRow("map-255-65535") << raw("\xa1\x18\xff\x19\xff\xff") << "{255: 65535}" << 1;
QTest::newRow("_map-0-24") << raw("\xbf\0\x18\x18\xff") << "{_ 0: 24}" << 1;
QTest::newRow("_map-0*1-24") << raw("\xbf\x18\0\x18\x18\xff") << "{_ 0_0: 24}" << 1;
QTest::newRow("_map-0*1-24*2") << raw("\xbf\x18\0\x19\0\x18\xff") << "{_ 0_0: 24_1}" << 1;
QTest::newRow("_map-0*4-24*2") << raw("\xbf\x1a\0\0\0\0\x19\0\x18\xff") << "{_ 0_2: 24_1}" << 1;
QTest::newRow("_map-24-0") << raw("\xbf\x18\x18\0\xff") << "{_ 24: 0}" << 1;
QTest::newRow("_map-24-0*1") << raw("\xbf\x18\x18\x18\0\xff") << "{_ 24: 0_0}" << 1;
QTest::newRow("_map-255-65535") << raw("\xbf\x18\xff\x19\xff\xff\xff") << "{_ 255: 65535}" << 1;
}
void addChunkedStringData()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<QString>("concatenated");
QTest::addColumn<QStringList>("chunks");
// non-chunked:
QTest::newRow("emptybytestring") << raw("\x40") << "h''" << QStringList{"h''"};
QTest::newRow("bytestring1") << raw("\x41 ") << "h'20'" << QStringList{"h'20'"};
QTest::newRow("emptytextstring") << raw("\x60") << "\"\"" << QStringList{"\"\""};
QTest::newRow("textstring1") << raw("\x61 ") << "\" \"" << QStringList{"\" \""};
// empty chunked:
QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "h''" << QStringList{};
QTest::newRow("_emptytextstring") << raw("\x7f\xff") << "\"\"" << QStringList{};
QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << "h''" << QStringList{"h''"};
QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << "\"\"" << QStringList{"\"\""};
QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << "h''" << QStringList{"h''", "h''"};
QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << "\"\"" << QStringList{"\"\"", "\"\""};
// regular chunks
QTest::newRow("_bytestring1") << raw("\x5f\x41 \xff") << "h'20'" << QStringList{"h'20'"};
QTest::newRow("_bytestring2") << raw("\x5f\x41 \x41z\xff") << "h'207a'" << QStringList{"h'20'", "h'7a'"};
QTest::newRow("_bytestring3") << raw("\x5f\x41 \x58\x18""123456789012345678901234\x41z\xff")
<< "h'203132333435363738393031323334353637383930313233347a'"
<< QStringList{"h'20'", "h'313233343536373839303132333435363738393031323334'", "h'7a'"};
QTest::newRow("_textstring1") << raw("\x7f\x61 \xff") << "\" \"" << QStringList{"\" \""};
QTest::newRow("_textstring2") << raw("\x7f\x61 \x61z\xff") << "\" z\"" << QStringList{"\" \"", "\"z\""};
QTest::newRow("_textstring3") << raw("\x7f\x61 \x78\x18""123456789012345678901234\x61z\xff")
<< "\" 123456789012345678901234z\""
<< QStringList{"\" \"", "\"123456789012345678901234\"", "\"z\""};
}
void addValidationColumns()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<int>("flags"); // future
QTest::addColumn<CborError>("expectedError");
}
void addValidationData(size_t minInvalid = ~size_t(0))
{
// illegal numbers are future extension points
QTest::newRow("illegal-number-in-unsigned-1") << raw("\x81\x1c") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-unsigned-2") << raw("\x81\x1d") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-unsigned-3") << raw("\x81\x1e") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-unsigned-4") << raw("\x81\x1f") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-negative-1") << raw("\x81\x3c") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-negative-2") << raw("\x81\x3d") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-negative-3") << raw("\x81\x3e") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-negative-4") << raw("\x81\x3f") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-bytearray-length-1") << raw("\x81\x5c") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-bytearray-length-2") << raw("\x81\x5d") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-bytearray-length-3") << raw("\x81\x5e") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-string-length-1") << raw("\x81\x7c") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-string-length-2") << raw("\x81\x7d") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-string-length-3") << raw("\x81\x7e") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-array-length-1") << raw("\x81\x9c") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-array-length-2") << raw("\x81\x9d") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-array-length-3") << raw("\x81\x9e") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-map-length-1") << raw("\x81\xbc") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-map-length-2") << raw("\x81\xbd") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-map-length-3") << raw("\x81\xbe") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-tag-1") << raw("\x81\xdc") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-tag-2") << raw("\x81\xdd") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-tag-3") << raw("\x81\xde") << 0 << CborErrorIllegalNumber;
QTest::newRow("illegal-number-in-tag-4") << raw("\x81\xdf") << 0 << CborErrorIllegalNumber;
QTest::newRow("unsigned-too-short-1-0") << raw("\x81\x18") << 0 << CborErrorUnexpectedEOF; // requires 1 byte, 0 given
QTest::newRow("unsigned-too-short-2-0") << raw("\x81\x19") << 0 << CborErrorUnexpectedEOF; // requires 2 bytes, 0 given
QTest::newRow("unsigned-too-short-2-1") << raw("\x81\x19\x01") << 0 << CborErrorUnexpectedEOF; // etc
QTest::newRow("unsigned-too-short-4-0") << raw("\x81\x1a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("unsigned-too-short-4-3") << raw("\x81\x1a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("unsigned-too-short-8-0") << raw("\x81\x1b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("unsigned-too-short-8-7") << raw("\x81\x1b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("negative-length-too-short-1-0") << raw("\x81\x38") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("negative-length-too-short-2-0") << raw("\x81\x39") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("negative-length-too-short-2-1") << raw("\x81\x39\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("negative-length-too-short-4-0") << raw("\x81\x3a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("negative-length-too-short-4-3") << raw("\x81\x3a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("negative-length-too-short-8-0") << raw("\x81\x3b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("negative-length-too-short-8-7") << raw("\x81\x3b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-length-too-short-1-0") << raw("\x81\x58") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-length-too-short-2-0") << raw("\x81\x59") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-length-too-short-2-1") << raw("\x81\x59\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-length-too-short-4-0") << raw("\x81\x5a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-length-too-short-4-3") << raw("\x81\x5a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-length-too-short-8-0") << raw("\x81\x5b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-length-too-short-8-7") << raw("\x81\x5b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-length-too-short-1-0") << raw("\x81\x78") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-length-too-short-2-0") << raw("\x81\x79") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-length-too-short-2-1") << raw("\x81\x79\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-length-too-short-4-0") << raw("\x81\x7a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-length-too-short-4-3") << raw("\x81\x7a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-length-too-short-8-0") << raw("\x81\x7b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-length-too-short-8-7") << raw("\x81\x7b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-length-too-short-1-0") << raw("\x81\x5f\x58") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-length-too-short-2-0") << raw("\x81\x5f\x59") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-length-too-short-2-1") << raw("\x81\x5f\x59\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-length-too-short-4-0") << raw("\x81\x5f\x5a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-length-too-short-4-3") << raw("\x81\x5f\x5a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-length-too-short-8-0") << raw("\x81\x5f\x5b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-length-too-short-8-7") << raw("\x81\x5f\x5b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-length-too-short-1-0") << raw("\x81\x7f\x78") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-length-too-short-2-0") << raw("\x81\x7f\x79") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-length-too-short-2-1") << raw("\x81\x7f\x79\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-length-too-short-4-0") << raw("\x81\x7f\x7a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-length-too-short-4-3") << raw("\x81\x7f\x7a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-length-too-short-8-0") << raw("\x81\x7f\x7b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-length-too-short-8-7") << raw("\x81\x7f\x7b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-2-length-too-short-1-0") << raw("\x81\x5f\x40\x58") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-2-length-too-short-2-0") << raw("\x81\x5f\x40\x59") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-2-length-too-short-2-1") << raw("\x81\x5f\x40\x59\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-2-length-too-short-4-0") << raw("\x81\x5f\x40\x5a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-2-length-too-short-4-3") << raw("\x81\x5f\x40\x5a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-2-length-too-short-8-0") << raw("\x81\x5f\x40\x5b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-2-length-too-short-8-7") << raw("\x81\x5f\x40\x5b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-2-length-too-short-1-0") << raw("\x81\x7f\x60\x78") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-2-length-too-short-2-0") << raw("\x81\x7f\x60\x79") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-2-length-too-short-2-1") << raw("\x81\x7f\x60\x79\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-2-length-too-short-4-0") << raw("\x81\x7f\x60\x7a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-2-length-too-short-4-3") << raw("\x81\x7f\x60\x7a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-2-length-too-short-8-0") << raw("\x81\x7f\x60\x7b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-2-length-too-short-8-7") << raw("\x81\x7f\x60\x7b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-length-too-short-1-0") << raw("\x81\x98") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-length-too-short-2-0") << raw("\x81\x99") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-length-too-short-2-1") << raw("\x81\x99\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-length-too-short-4-0") << raw("\x81\x9a") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-length-too-short-4-3") << raw("\x81\x9a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-length-too-short-8-0") << raw("\x81\x9b") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-length-too-short-8-7") << raw("\x81\x9b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-length-too-short-1-0") << raw("\x81\xb8") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-length-too-short-2-0") << raw("\x81\xb9") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-length-too-short-2-1") << raw("\x81\xb9\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-length-too-short-4-0") << raw("\x81\xba") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-length-too-short-4-3") << raw("\x81\xba\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-length-too-short-8-0") << raw("\x81\xbb") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-length-too-short-8-7") << raw("\x81\xbb\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("tag-too-short-1-0") << raw("\x81\xd8") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("tag-too-short-2-0") << raw("\x81\xd9") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("tag-too-short-2-1") << raw("\x81\xd9\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("tag-too-short-4-0") << raw("\x81\xda") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("tag-too-short-4-3") << raw("\x81\xda\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("tag-too-short-8-0") << raw("\x81\xdb") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("tag-too-short-8-7") << raw("\x81\xdb\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("fp16-too-short1") << raw("\x81\xf9") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("fp16-too-short2") << raw("\x81\xf9\x00") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("float-too-short1") << raw("\x81\xfa") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("float-too-short2") << raw("\x81\xfa\0\0\0") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("double-too-short1") << raw("\x81\xfb") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("double-too-short2") << raw("\x81\xfb\0\0\0\0\0\0\0") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-too-short1") << raw("\x81\x42z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-too-short2") << raw("\x81\x58\x02z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-too-short3") << raw("\x81\x5a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-too-short4") << raw("\x81\x5b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-too-short1") << raw("\x81\x62z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-too-short2") << raw("\x81\x78\x02z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-too-short3") << raw("\x81\x7a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-too-short4") << raw("\x81\x7b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short1") << raw("\x81\x5f\x42z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short2") << raw("\x81\x5f\x58\x02z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short3") << raw("\x81\x5f\x5a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short4") << raw("\x81\x5f\x5b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short1") << raw("\x81\x7f\x62z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short2") << raw("\x81\x7f\x78\x02z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short3") << raw("\x81\x7f\x7a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short4") << raw("\x81\x7f\x7b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short1x2") << raw("\x81\x5f\x40\x42z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short2x2") << raw("\x81\x5f\x40\x58\x02z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short3x2") << raw("\x81\x5f\x40\x5a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunked-too-short4x2") << raw("\x81\x5f\x40\x5b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short1x2") << raw("\x81\x7f\x60\x62z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short2x2") << raw("\x81\x7f\x60\x78\x02z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short3x2") << raw("\x81\x7f\x60\x7a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunked-too-short4x2") << raw("\x81\x7f\x60\x7b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-no-break1") << raw("\x81\x5f") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-no-break2") << raw("\x81\x5f\x40") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-no-break1") << raw("\x81\x7f") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-no-break2") << raw("\x81\x7f\x60") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-no-break1") << raw("\x81\x9f") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("array-no-break2") << raw("\x81\x9f\0") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-no-break1") << raw("\x81\xbf") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-no-break2") << raw("\x81\xbf\0\0") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("map-break-after-key") << raw("\x81\xbf\0\xff") << 0 << CborErrorUnexpectedBreak;
QTest::newRow("map-break-after-second-key") << raw("\x81\xbf\x64xyzw\x04\x00\xff") << 0 << CborErrorUnexpectedBreak;
QTest::newRow("map-break-after-value-tag") << raw("\x81\xbf\0\xc0\xff") << 0 << CborErrorUnexpectedBreak;
QTest::newRow("map-break-after-value-tag2") << raw("\x81\xbf\0\xd8\x20\xff") << 0 << CborErrorUnexpectedBreak;
// check for pointer additions wrapping over the limit of the address space
auto wraparoundError = [minInvalid](uint64_t encodedSize) {
if (encodedSize > minInvalid)
return CborErrorDataTooLarge;
return CborErrorUnexpectedEOF;
};
constexpr uint64_t FourGB = UINT32_MAX + UINT64_C(1);
// on 32-bit systems, this is a -1
QTest::newRow("bytearray-wraparound1") << raw("\x81\x5a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
QTest::newRow("string-wraparound1") << raw("\x81\x7a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
// on 32-bit systems, a 4GB addition could be dropped
QTest::newRow("bytearray-wraparound2") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
QTest::newRow("string-wraparound2") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
// on 64-bit systems, this could be a -1
QTest::newRow("bytearray-wraparound3") << raw("\x81\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);
QTest::newRow("string-wraparound3") << raw("\x81\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);
// ditto on chunks
QTest::newRow("bytearray-chunk-wraparound1") << raw("\x81\x5f\x5a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
QTest::newRow("string-chunk-wraparound1") << raw("\x81\x7f\x7a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
// on 32-bit systems, a 4GB addition could be dropped
QTest::newRow("bytearray-chunk-wraparound2") << raw("\x81\x5f\x5b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
QTest::newRow("string-chunk-wraparound2") << raw("\x81\x7f\x7b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
// on 64-bit systems, this could be a -1
QTest::newRow("bytearray-chunk-wraparound3") << raw("\x81\x5f\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);
QTest::newRow("string-chunk-wraparound3") << raw("\x81\x7f\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);
QTest::newRow("eof-after-array") << raw("\x81") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-array2") << raw("\x81\x78\x20") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-array-element") << raw("\x81\x82\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-object") << raw("\x81\xa1") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-object2") << raw("\x81\xb8\x20") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-object-key") << raw("\x81\xa1\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-object-value") << raw("\x81\xa2\x01\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-tag") << raw("\x81\xc0") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-tag2") << raw("\x81\xd8\x20") << 0 << CborErrorUnexpectedEOF;
// major type 7 has future types
QTest::newRow("future-type-28") << raw("\x81\xfc") << 0 << CborErrorUnknownType;
QTest::newRow("future-type-29") << raw("\x81\xfd") << 0 << CborErrorUnknownType;
QTest::newRow("future-type-30") << raw("\x81\xfe") << 0 << CborErrorUnknownType;
QTest::newRow("unexpected-break") << raw("\x81\xff") << 0 << CborErrorUnexpectedBreak;
QTest::newRow("illegal-simple-0") << raw("\x81\xf8\0") << 0 << CborErrorIllegalSimpleType;
QTest::newRow("illegal-simple-31") << raw("\x81\xf8\x1f") << 0 << CborErrorIllegalSimpleType;
// not only too big (UINT_MAX or UINT_MAX+1 in size), but also incomplete
if (sizeof(size_t) < sizeof(uint64_t)) {
QTest::newRow("bytearray-too-big1") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
QTest::newRow("string-too-big1") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
}
QTest::newRow("array-too-big1") << raw("\x81\x9a\xff\xff\xff\xff\0\0\0\0") << 0 << CborErrorDataTooLarge;
QTest::newRow("array-too-big2") << raw("\x81\x9b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
QTest::newRow("object-too-big1") << raw("\x81\xba\xff\xff\xff\xff\0\0\0\0") << 0 << CborErrorDataTooLarge;
QTest::newRow("object-too-big2") << raw("\x81\xbb\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
QTest::newRow("no-break-for-array0") << raw("\x81\x9f") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("no-break-for-array1") << raw("\x81\x9f\x01") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("no-break-string0") << raw("\x81\x7f") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("no-break-string1") << raw("\x81\x7f\x61Z") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("nested-indefinite-length-bytearrays") << raw("\x81\x5f\x5f\xff\xff") << 0 << CborErrorIllegalNumber;
QTest::newRow("nested-indefinite-length-strings") << raw("\x81\x7f\x7f\xff\xff") << 0 << CborErrorIllegalNumber;
QTest::newRow("string-chunk-unsigned") << raw("\x81\x7f\0\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-negative") << raw("\x81\x7f\x20\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-bytearray") << raw("\x81\x7f\x40\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-array") << raw("\x81\x7f\x80\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-map") << raw("\x81\x7f\xa0\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-tag") << raw("\x81\x7f\xc0\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-tagged-string") << raw("\x81\x7f\xc0\x60\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-simple0") << raw("\x81\x7f\xe0\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-false") << raw("\x81\x7f\xf4\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-true") << raw("\x81\x7f\xf5\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-null") << raw("\x81\x7f\xf6\xff") << 0 << CborErrorIllegalType;
QTest::newRow("string-chunk-undefined") << raw("\x81\x7f\xf7\xff") << 0 << CborErrorIllegalType;
QTest::newRow("bytearray-chunk-string") << raw("\x81\x5f\x60\xff") << 0 << CborErrorIllegalType;
QTest::newRow("bytearray-chunk-tagged-bytearray") << raw("\x81\x7f\xc0\x40\xff") << 0 << CborErrorIllegalType;
// RFC 7049 Section 2.2.2 "Indefinite-Length Byte Strings and Text Strings" says
// Text strings with indefinite lengths act the same as byte strings
// with indefinite lengths, except that all their chunks MUST be
// definite-length text strings. Note that this implies that the bytes
// of a single UTF-8 character cannot be spread between chunks: a new
// chunk can only be started at a character boundary.
// This test technically tests the dumper, not the parser.
QTest::newRow("string-utf8-chunk-split") << raw("\x81\x7f\x61\xc2\x61\xa0\xff") << 0 << CborErrorInvalidUtf8TextString;
}

View File

@ -0,0 +1,10 @@
SOURCES += tst_parser.cpp ../../src/cborparser.c
CONFIG += testcase parallel_test c++11
QT = core testlib
DEFINES += CBOR_PARSER_MAX_RECURSIONS=16
INCLUDEPATH += ../../src
msvc: POST_TARGETDEPS = ../../lib/tinycbor.lib
else: POST_TARGETDEPS += ../../lib/libtinycbor.a
LIBS += $$POST_TARGETDEPS

View File

@ -0,0 +1,3 @@
TEMPLATE = subdirs
SUBDIRS = parser encoder c90 cpp tojson
msvc: SUBDIRS -= tojson

View File

@ -0,0 +1,8 @@
CONFIG += testcase parallel_test c++11
QT = core testlib
SOURCES += tst_tojson.cpp
INCLUDEPATH += ../../src
msvc: POST_TARGETDEPS = ../../lib/tinycbor.lib
else: POST_TARGETDEPS += ../../lib/libtinycbor.a
LIBS += $$POST_TARGETDEPS

View File

@ -0,0 +1,721 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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 <QtTest>
#include "cbor.h"
#include "cborjson.h"
#include <locale.h>
extern "C" FILE *open_memstream(char **bufptr, size_t *sizeptr);
class tst_ToJson : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void fixed_data();
void fixed();
void textstrings_data();
void textstrings() { fixed(); }
void nonjson_data();
void nonjson() { fixed(); }
void bytestrings_data();
void bytestrings() { fixed(); }
void emptyContainers_data();
void emptyContainers() { fixed(); }
void arrays_data();
void arrays();
void nestedArrays_data() { arrays_data(); }
void nestedArrays();
void maps_data() { arrays_data(); }
void maps();
void nestedMaps_data() { maps_data(); }
void nestedMaps();
void nonStringKeyMaps_data();
void nonStringKeyMaps();
void tagsToObjects_data();
void tagsToObjects();
void taggedByteStringsToBase16_data();
void taggedByteStringsToBase16();
void taggedByteStringsToBase64_data() { taggedByteStringsToBase16_data(); }
void taggedByteStringsToBase64();
void taggedByteStringsToBigNum_data() { taggedByteStringsToBase16_data(); }
void taggedByteStringsToBigNum();
void otherTags_data();
void otherTags();
void metaData_data();
void metaData();
void metaDataAndTagsToObjects_data() { tagsToObjects_data(); }
void metaDataAndTagsToObjects();
void metaDataForKeys_data();
void metaDataForKeys();
};
#include "tst_tojson.moc"
template <size_t N> QByteArray raw(const char (&data)[N])
{
return QByteArray::fromRawData(data, N - 1);
}
void addColumns()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<QString>("expected");
}
void addFixedData()
{
// unsigned integers
QTest::newRow("0") << raw("\x00") << "0";
QTest::newRow("1") << raw("\x01") << "1";
QTest::newRow("2^53-1") << raw("\x1b\0\x1f\xff\xff""\xff\xff\xff\xff") << "9007199254740991";
QTest::newRow("2^64-epsilon") << raw("\x1b\xff\xff\xff\xff""\xff\xff\xf8\x00") << "18446744073709549568";
// negative integers
QTest::newRow("-1") << raw("\x20") << "-1";
QTest::newRow("-2") << raw("\x21") << "-2";
QTest::newRow("-2^53+1") << raw("\x3b\0\x1f\xff\xff""\xff\xff\xff\xfe") << "-9007199254740991";
QTest::newRow("-2^64+epsilon") << raw("\x3b\xff\xff\xff\xff""\xff\xff\xf8\x00") << "-18446744073709549568";
QTest::newRow("false") << raw("\xf4") << "false";
QTest::newRow("true") << raw("\xf5") << "true";
QTest::newRow("null") << raw("\xf6") << "null";
QTest::newRow("0.f16") << raw("\xf9\0\0") << "0";
QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << "0";
QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << "0";
QTest::newRow("-1.f16") << raw("\xf9\xbc\x00") << "-1";
QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << "-1";
QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << "-1";
QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << "16777215";
QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << "16777215";
QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << "-16777215";
QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << "-16777215";
QTest::newRow("0.5f16") << raw("\xf9\x38\0") << "0.5";
QTest::newRow("0.5f") << raw("\xfa\x3f\0\0\0") << "0.5";
QTest::newRow("0.5") << raw("\xfb\x3f\xe0\0\0\0\0\0\0") << "0.5";
QTest::newRow("2.f^24-1") << raw("\xfa\x4b\x7f\xff\xff") << "16777215";
QTest::newRow("2.^53-1") << raw("\xfb\x43\x3f\xff\xff""\xff\xff\xff\xff") << "9007199254740991";
QTest::newRow("2.f^64-epsilon") << raw("\xfa\x5f\x7f\xff\xff") << "18446742974197923840";
QTest::newRow("2.^64-epsilon") << raw("\xfb\x43\xef\xff\xff""\xff\xff\xff\xff") << "18446744073709549568";
QTest::newRow("2.f^64") << raw("\xfa\x5f\x80\0\0") << "1.8446744073709552e+19";
QTest::newRow("2.^64") << raw("\xfb\x43\xf0\0\0\0\0\0\0") << "1.8446744073709552e+19";
// infinities and NaN are not supported in JSON, they convert to null
QTest::newRow("nan_f16") << raw("\xf9\x7e\x00") << "null";
QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << "null";
QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << "null";
QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << "null";
QTest::newRow("-inf_f16") << raw("\xf9\xfc\x00") << "null";
QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << "null";
QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << "null";
QTest::newRow("+inf_f16") << raw("\xf9\x7c\x00") << "null";
QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << "null";
}
void addTextStringsData()
{
QTest::newRow("emptytextstring") << raw("\x60") << "\"\"";
QTest::newRow("textstring1") << raw("\x61 ") << "\" \"";
QTest::newRow("textstring5") << raw("\x65Hello") << "\"Hello\"";
QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234")
<< "\"123456789012345678901234\"";
QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3')
<< '"' + QString(256, '3') + '"';
// strings with undefined length
QTest::newRow("_emptytextstring") << raw("\x7f\xff") << "\"\"";
QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << "\"\"";
QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << "\"\"";
QTest::newRow("_textstring5*2") << raw("\x7f\x63Hel\x62lo\xff") << "\"Hello\"";
QTest::newRow("_textstring5*5") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "\"Hello\"";
QTest::newRow("_textstring5*6") << raw("\x7f\x61H\x61""e\x61l\x60\x61l\x61o\xff") << "\"Hello\"";
}
void addNonJsonData()
{
QTest::newRow("undefined") << raw("\xf7") << "\"undefined\"";
QTest::newRow("simple0") << raw("\xe0") << "\"simple(0)\"";
QTest::newRow("simple19") << raw("\xf3") << "\"simple(19)\"";
QTest::newRow("simple32") << raw("\xf8\x20") << "\"simple(32)\"";
QTest::newRow("simple255") << raw("\xf8\xff") << "\"simple(255)\"";
}
void addByteStringsData()
{
QTest::newRow("emptybytestring") << raw("\x40") << "\"\"";
QTest::newRow("bytestring1") << raw("\x41 ") << "\"IA\"";
QTest::newRow("bytestring1-nul") << raw("\x41\0") << "\"AA\"";
QTest::newRow("bytestring2") << raw("\x42Hi") << "\"SGk\"";
QTest::newRow("bytestring3") << raw("\x43Hey") << "\"SGV5\"";
QTest::newRow("bytestring4") << raw("\x44Hola") << "\"SG9sYQ\"";
QTest::newRow("bytestring5") << raw("\x45Hello") << "\"SGVsbG8\"";
QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
<< "\"MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0\"";
// strings with undefined length
QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "\"\"";
QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << "\"\"";
QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << "\"\"";
QTest::newRow("_bytestring5*2") << raw("\x5f\x43Hel\x42lo\xff") << "\"SGVsbG8\"";
QTest::newRow("_bytestring5*5") << raw("\x5f\x41H\x41""e\x41l\x41l\x41o\xff") << "\"SGVsbG8\"";
QTest::newRow("_bytestring5*6") << raw("\x5f\x41H\x41""e\x40\x41l\x41l\x41o\xff") << "\"SGVsbG8\"";
}
void addEmptyContainersData()
{
QTest::newRow("emptyarray") << raw("\x80") << "[]";
QTest::newRow("emptymap") << raw("\xa0") << "{}";
QTest::newRow("_emptyarray") << raw("\x9f\xff") << "[]";
QTest::newRow("_emptymap") << raw("\xbf\xff") << "{}";
}
CborError parseOne(CborValue *it, QString *parsed, int flags)
{
char *buffer;
size_t size;
FILE *f = open_memstream(&buffer, &size);
CborError err = cbor_value_to_json_advance(f, it, flags);
fclose(f);
*parsed = QString::fromLatin1(buffer);
free(buffer);
return err;
}
bool compareFailed = true;
void compareOne_real(const QByteArray &data, const QString &expected, int flags, int line)
{
compareFailed = true;
CborParser parser;
CborValue first;
CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
QString decoded;
err = parseOne(&first, &decoded, flags);
QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) +
"\"; decoded stream:\n" + decoded.toLatin1());
QCOMPARE(decoded, expected);
// check that we consumed everything
QCOMPARE((void*)cbor_value_get_next_byte(&first), (void*)data.constEnd());
compareFailed = false;
}
#define compareOne(data, expected, flags) \
compareOne_real(data, expected, flags, __LINE__); \
if (compareFailed) return
void tst_ToJson::initTestCase()
{
setlocale(LC_ALL, "C");
}
void tst_ToJson::fixed_data()
{
addColumns();
addFixedData();
}
void tst_ToJson::fixed()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
compareOne(data, expected, 0);
}
void tst_ToJson::textstrings_data()
{
addColumns();
addTextStringsData();
}
void tst_ToJson::nonjson_data()
{
addColumns();
addNonJsonData();
}
void tst_ToJson::bytestrings_data()
{
addColumns();
addByteStringsData();
}
void tst_ToJson::emptyContainers_data()
{
addColumns();
addEmptyContainersData();
}
void tst_ToJson::arrays_data()
{
addColumns();
addFixedData();
addTextStringsData();
addNonJsonData();
addByteStringsData();
}
void tst_ToJson::arrays()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
compareOne("\x81" + data, '[' + expected + ']', 0);
compareOne("\x82" + data + data, '[' + expected + ',' + expected + ']', 0);
}
void tst_ToJson::nestedArrays()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
compareOne("\x81\x81" + data, "[[" + expected + "]]", 0);
compareOne("\x81\x81\x81" + data, "[[[" + expected + "]]]", 0);
compareOne("\x81\x82" + data + data, "[[" + expected + ',' + expected + "]]", 0);
compareOne("\x82\x81" + data + data, "[[" + expected + "]," + expected + "]", 0);
compareOne("\x82\x81" + data + '\x81' + data, "[[" + expected + "],[" + expected + "]]", 0);
}
void tst_ToJson::maps()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
compareOne("\xa1\x65" "Hello" + data, "{\"Hello\":" + expected + '}', 0);
}
void tst_ToJson::nestedMaps()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
compareOne("\xa1\x65Hello\xa1\x65World" + data, "{\"Hello\":{\"World\":" + expected + "}}", 0);
// compareOne("\xa1\x63""foo\xa1\63""bar" + data + "\63""baz\xa1\x64quux" + data,
// "{\"foo\":{\"bar\":" + expected + "},\"baz\":{\"quux\":" + expected + "}", 0);
}
void tst_ToJson::nonStringKeyMaps_data()
{
addColumns();
QTest::newRow("0") << raw("\x00") << "0";
QTest::newRow("1") << raw("\x01") << "1";
QTest::newRow("UINT32_MAX") << raw("\x1a\xff\xff\xff\xff") << "4294967295";
QTest::newRow("UINT32_MAX+1") << raw("\x1b\0\0\0\1\0\0\0\0") << "4294967296";
QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
<< QString::number(std::numeric_limits<uint64_t>::max());
QTest::newRow("-1") << raw("\x20") << "-1";
QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << "-4294967296";
QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << "-4294967297";
QTest::newRow("-UINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
<< '-' + QString::number(std::numeric_limits<uint64_t>::max());
QTest::newRow("-UINT64_MAX-1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
<< "-18446744073709551616";
QTest::newRow("simple0") << raw("\xe0") << "simple(0)";
QTest::newRow("simple19") << raw("\xf3") << "simple(19)";
QTest::newRow("false") << raw("\xf4") << "false";
QTest::newRow("true") << raw("\xf5") << "true";
QTest::newRow("null") << raw("\xf6") << "null";
QTest::newRow("undefined") << raw("\xf7") << "undefined";
QTest::newRow("simple32") << raw("\xf8\x20") << "simple(32)";
QTest::newRow("simple255") << raw("\xf8\xff") << "simple(255)";
QTest::newRow("0.f16") << raw("\xf9\0\0") << "0.f16";
QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << "0.f";
QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << "0.";
QTest::newRow("-1.f16") << raw("\xf9\xbc\x00") << "-1.f16";
QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << "-1.f";
QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << "-1.";
QTest::newRow("65504.f16") << raw("\xf9\x7b\xff") << "65504.f16";
QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << "16777215.";
QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << "-16777215.f";
QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << "-16777215.";
QTest::newRow("0.5f16") << raw("\xf9\x38\0") << "0.5f16";
QTest::newRow("0.5f") << raw("\xfa\x3f\0\0\0") << "0.5f";
QTest::newRow("0.5") << raw("\xfb\x3f\xe0\0\0\0\0\0\0") << "0.5";
QTest::newRow("2.f16^11-1") << raw("\xf9\x67\xff") << "2047.f16";
QTest::newRow("2.f^24-1") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
QTest::newRow("2.^53-1") << raw("\xfb\x43\x3f\xff\xff""\xff\xff\xff\xff") << "9007199254740991.";
QTest::newRow("2.f^64-epsilon") << raw("\xfa\x5f\x7f\xff\xff") << "18446742974197923840.f";
QTest::newRow("2.^64-epsilon") << raw("\xfb\x43\xef\xff\xff""\xff\xff\xff\xff") << "18446744073709549568.";
QTest::newRow("2.f^64") << raw("\xfa\x5f\x80\0\0") << "1.8446744073709552e+19f";
QTest::newRow("2.^64") << raw("\xfb\x43\xf0\0\0\0\0\0\0") << "1.8446744073709552e+19";
QTest::newRow("nan_f16") << raw("\xf9\x7e\x00") << "nan";
QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << "nan";
QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << "nan";
QTest::newRow("-inf_f16") << raw("\xf9\xfc\x00") << "-inf";
QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << "-inf";
QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << "-inf";
QTest::newRow("+inf_f16") << raw("\xf9\x7c\x00") << "inf";
QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << "inf";
QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << "inf";
QTest::newRow("emptybytestring") << raw("\x40") << "h''";
QTest::newRow("bytestring1") << raw("\x41 ") << "h'20'";
QTest::newRow("bytestring1-nul") << raw("\x41\0") << "h'00'";
QTest::newRow("bytestring5") << raw("\x45Hello") << "h'48656c6c6f'";
QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
<< "h'313233343536373839303132333435363738393031323334'";
QTest::newRow("tag0") << raw("\xc0\x00") << "0(0)";
QTest::newRow("tag1") << raw("\xc1\x00") << "1(0)";
QTest::newRow("tag24") << raw("\xd8\x18\x00") << "24(0)";
QTest::newRow("tagUINT64_MAX") << raw("\xdb" "\xff\xff\xff\xff" "\xff\xff\xff\xff" "\x00")
<< QString::number(std::numeric_limits<uint64_t>::max()) + "(0)";
QTest::newRow("emptyarray") << raw("\x80") << "[]";
QTest::newRow("emptymap") << raw("\xa0") << "{}";
QTest::newRow("_emptyarray") << raw("\x9f\xff") << "[_ ]";
QTest::newRow("_emptymap") << raw("\xbf\xff") << "{_ }";
QTest::newRow("map-0-24") << raw("\xa1\0\x18\x18") << "{0: 24}";
QTest::newRow("map-24-0") << raw("\xa1\x18\x18\0") << "{24: 0}";
QTest::newRow("_map-0-24") << raw("\xbf\0\x18\x18\xff") << "{_ 0: 24}";
QTest::newRow("_map-24-0") << raw("\xbf\x18\x18\0\xff") << "{_ 24: 0}";
}
void tst_ToJson::nonStringKeyMaps()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
data = "\xa1" + data + "\1";
compareOne(data, "{\"" + expected + "\":1}", CborConvertStringifyMapKeys);
// and verify that they fail if we use CborConvertRequireMapStringKeys
CborParser parser;
CborValue first;
QString decoded;
cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
CborError err = parseOne(&first, &decoded, CborConvertRequireMapStringKeys);
QCOMPARE(err, CborErrorJsonObjectKeyNotString);
}
void tst_ToJson::tagsToObjects_data()
{
addColumns();
QTest::newRow("0(0)") << raw("\xc0\0") << "{\"tag0\":0}";
QTest::newRow("0(-1)") << raw("\xc0\x20") << "{\"tag0\":-1}";
QTest::newRow("0(\"hello\")") << raw("\xc0\x65hello") << "{\"tag0\":\"hello\"}";
QTest::newRow("22(h'48656c6c6f')") << raw("\xd6\x45Hello") << "{\"tag22\":\"SGVsbG8\"}";
QTest::newRow("0([1,2,3])") << raw("\xc0\x83\1\2\3") << "{\"tag0\":[1,2,3]}";
QTest::newRow("0({\"z\":true,\"y\":1})") << raw("\xc0\xa2\x61z\xf5\x61y\1") << "{\"tag0\":{\"z\":true,\"y\":1}}";
// large tags
QTest::newRow("55799(0)") << raw("\xd9\xd9\xf7\0") << "{\"tag55799\":0}";
QTest::newRow("4294967295") << raw("\xda\xff\xff\xff\xff\0") << "{\"tag4294967295\":0}";
QTest::newRow("18446744073709551615(0)") << raw("\xdb\xff\xff\xff\xff""\xff\xff\xff\xff\0")
<< "{\"tag18446744073709551615\":0}";
// nested tags
QTest::newRow("0(1(2))") << raw("\xc0\xc1\2") << "{\"tag0\":{\"tag1\":2}}";
QTest::newRow("0({\"z\":1(2)})") << raw("\xc0\xa1\x61z\xc1\2") << "{\"tag0\":{\"z\":{\"tag1\":2}}}";
}
void tst_ToJson::tagsToObjects()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
compareOne(data, expected, CborConvertTagsToObjects);
}
void tst_ToJson::taggedByteStringsToBase16_data()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<QString>("base64url");
QTest::addColumn<QString>("base64");
QTest::addColumn<QString>("base16");
QTest::newRow("emptybytestring") << raw("\x40") << "" << "" << "";
QTest::newRow("bytestring1") << raw("\x41 ") << "IA" << "IA==" << "20";
QTest::newRow("bytestring1-nul") << raw("\x41\0") << "AA" << "AA==" << "00";
QTest::newRow("bytestring1-ff") << raw("\x41\xff") << "_w" << "/w==" << "ff";
QTest::newRow("bytestring2") << raw("\x42Hi") << "SGk" << "SGk=" << "4869";
QTest::newRow("bytestring3") << raw("\x43Hey") << "SGV5" << "SGV5" << "486579";
QTest::newRow("bytestring4") << raw("\x44Hola") << "SG9sYQ" << "SG9sYQ==" << "486f6c61";
QTest::newRow("bytestring5") << raw("\x45Hello") << "SGVsbG8" << "SGVsbG8=" << "48656c6c6f";
QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
<< "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0"
<< "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0"
<< "313233343536373839303132333435363738393031323334";
// strings with undefined length
QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "" << "" << "";
QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << "" << "" << "";
QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << "" << "" << "";
QTest::newRow("_bytestring5*2") << raw("\x5f\x43Hel\x42lo\xff") << "SGVsbG8" << "SGVsbG8=" << "48656c6c6f";
QTest::newRow("_bytestring5*5") << raw("\x5f\x41H\x41""e\x41l\x41l\x41o\xff")
<< "SGVsbG8" << "SGVsbG8=" << "48656c6c6f";
QTest::newRow("_bytestring5*6") << raw("\x5f\x41H\x41""e\x40\x41l\x41l\x41o\xff")
<< "SGVsbG8" << "SGVsbG8=" << "48656c6c6f";
}
void tst_ToJson::taggedByteStringsToBase16()
{
QFETCH(QByteArray, data);
QFETCH(QString, base16);
compareOne('\xd7' + data, '"' + base16 + '"', 0);
}
void tst_ToJson::taggedByteStringsToBase64()
{
QFETCH(QByteArray, data);
QFETCH(QString, base64);
compareOne('\xd6' + data, '"' + base64 + '"', 0);
}
void tst_ToJson::taggedByteStringsToBigNum()
{
QFETCH(QByteArray, data);
QFETCH(QString, base64url);
compareOne('\xc3' + data, "\"~" + base64url + '"', 0);
}
void tst_ToJson::otherTags_data()
{
addColumns();
addFixedData();
addTextStringsData();
addNonJsonData();
addByteStringsData();
addEmptyContainersData();
}
void tst_ToJson::otherTags()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
// other tags produce no change in output
compareOne("\xc0" + data, expected, 0);
compareOne("\xc1" + data, expected, 0);
compareOne("\xc2" + data, expected, 0);
compareOne("\xc4" + data, expected, 0);
compareOne("\xc5" + data, expected, 0);
compareOne("\xd8\x20" + data, expected, 0);
compareOne("\xd8\x21" + data, expected, 0);
compareOne("\xd8\x22" + data, expected, 0);
compareOne("\xd8\x23" + data, expected, 0);
compareOne("\xd8\x24" + data, expected, 0);
compareOne("\xd9\xd9\xf7" + data, expected, 0);
}
void tst_ToJson::metaData_data()
{
addColumns();
// booleans, null, strings, double precision numbers, regular maps, arrays and integers that
// didn't get rounded don't have metadata
QTest::newRow("0") << raw("\x00") << QString();
QTest::newRow("1") << raw("\x01") << QString();
QTest::newRow("2^53-1") << raw("\x1b\0\x1f\xff\xff""\xff\xff\xff\xff") << QString();
QTest::newRow("2^64-epsilon") << raw("\x1b\xff\xff\xff\xff""\xff\xff\xf8\x00") << QString();
QTest::newRow("-1") << raw("\x20") << QString();
QTest::newRow("-2") << raw("\x21") << QString();
QTest::newRow("-2^53+1") << raw("\x3b\0\x1f\xff\xff""\xff\xff\xff\xfe") << QString();
QTest::newRow("-2^64+epsilon") << raw("\x3b\xff\xff\xff\xff""\xff\xff\xf8\x00") << QString();
QTest::newRow("emptytextstring") << raw("\x60") << QString();
QTest::newRow("textstring1") << raw("\x61 ") << QString();
QTest::newRow("0.5") << raw("\xfb\x3f\xe0\0\0\0\0\0\0") << QString();
QTest::newRow("2.^64") << raw("\xfb\x43\xf0\0\0\0\0\0\0") << QString();
QTest::newRow("false") << raw("\xf4") << QString();
QTest::newRow("true") << raw("\xf5") << QString();
QTest::newRow("null") << raw("\xf6") << QString();
QTest::newRow("emptyarray") << raw("\x80") << QString();
QTest::newRow("emptymap") << raw("\xa0") << QString();
QTest::newRow("array*1") << raw("\x81\xf6") << QString();
QTest::newRow("map*1") << raw("\xa1\x61z\xf4") << QString();
// ---- everything from here on has at least the type ----
QTest::newRow("emptybytestring") << raw("\x40") << "\"t\":64";
QTest::newRow("bytestring1") << raw("\x41 ") << "\"t\":64";
QTest::newRow("undefined") << raw("\xf7") << "\"t\":247";
QTest::newRow("0.f16") << raw("\xf9\0\0") << "\"t\":249";
QTest::newRow("-1.f16") << raw("\xf9\xbc\x00") << "\"t\":249";
QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << "\"t\":250";
QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << "\"t\":250";
QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << "\"t\":250";
QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << "\"t\":250";
QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << "\"t\":251";
QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << "\"t\":251";
QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << "\"t\":251";
QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << "\"t\":251";
QTest::newRow("2.^53-1") << raw("\xfb\x43\x3f\xff\xff""\xff\xff\xff\xff") << "\"t\":251";
QTest::newRow("2.^64-epsilon") << raw("\xfb\x43\xef\xff\xff""\xff\xff\xff\xff") << "\"t\":251";
// integers that are too precise for double
QTest::newRow("2^53+1") << raw("\x1b\0\x20\0\0""\0\0\0\1")
<< "\"t\":0,\"v\":\"+20000000000001\"";
QTest::newRow("INT64_MAX-1") << raw("\x1b\x7f\xff\xff\xff""\xff\xff\xff\xfe")
<< "\"t\":0,\"v\":\"+7ffffffffffffffe\"";
QTest::newRow("INT64_MAX+1") << raw("\x1b\x80\0\0\0""\0\0\0\1")
<< "\"t\":0,\"v\":\"+8000000000000001\"";
QTest::newRow("-2^53-1") << raw("\x3b\0\x20\0\0""\0\0\0\0")
<< "\"t\":0,\"v\":\"-20000000000000\"";
// simple values
QTest::newRow("simple0") << raw("\xe0") << "\"t\":224,\"v\":0";
QTest::newRow("simple19") << raw("\xf3") << "\"t\":224,\"v\":19";
QTest::newRow("simple32") << raw("\xf8\x20") << "\"t\":224,\"v\":32";
QTest::newRow("simple255") << raw("\xf8\xff") << "\"t\":224,\"v\":255";
// infinities and NaN are not supported in JSON, they convert to null
QTest::newRow("nan_f16") << raw("\xf9\x7e\x00") << "\"t\":249,\"v\":\"nan\"";
QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << "\"t\":250,\"v\":\"nan\"";
QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << "\"t\":251,\"v\":\"nan\"";
QTest::newRow("-inf_f16") << raw("\xf9\xfc\x00") << "\"t\":249,\"v\":\"-inf\"";
QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << "\"t\":250,\"v\":\"-inf\"";
QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << "\"t\":251,\"v\":\"-inf\"";
QTest::newRow("+inf_f16") << raw("\xf9\x7c\x00") << "\"t\":249,\"v\":\"inf\"";
QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << "\"t\":250,\"v\":\"inf\"";
QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << "\"t\":251,\"v\":\"inf\"";
// tags on native types
QTest::newRow("tag+0") << raw("\xc0\x00") << "\"tag\":\"0\"";
QTest::newRow("tag+-2") << raw("\xc0\x21") << "\"tag\":\"0\"";
QTest::newRow("tag+0.5") << raw("\xc0\xfb\x3f\xe0\0\0\0\0\0\0") << "\"tag\":\"0\"";
QTest::newRow("tag+emptytextstring") << raw("\xc0\x60") << "\"tag\":\"0\"";
QTest::newRow("tag+textstring1") << raw("\xc0\x61 ") << "\"tag\":\"0\"";
QTest::newRow("tag+false") << raw("\xc0\xf4") << "\"tag\":\"0\"";
QTest::newRow("tag+true") << raw("\xc0\xf5") << "\"tag\":\"0\"";
QTest::newRow("tag+null") << raw("\xc0\xf6") << "\"tag\":\"0\"";
QTest::newRow("tag+emptyarray") << raw("\xc0\x80") << "\"tag\":\"0\"";
QTest::newRow("tag+emptymap") << raw("\xc0\xa0") << "\"tag\":\"0\"";
QTest::newRow("tag+array*1") << raw("\xc0\x81\xf6") << "\"tag\":\"0\"";
QTest::newRow("tag+map*1") << raw("\xc0\xa1\x61z\xf4") << "\"tag\":\"0\"";
// tags on non-native types
QTest::newRow("tag+emptybytestring") << raw("\xc0\x40") << "\"tag\":\"0\",\"t\":64";
QTest::newRow("tag+bytestring1") << raw("\xc0\x41 ") << "\"tag\":\"0\",\"t\":64";
QTest::newRow("tag+undefined") << raw("\xc0\xf7") << "\"tag\":\"0\",\"t\":247";
QTest::newRow("tag+0.f") << raw("\xc0\xfa\0\0\0\0") << "\"tag\":\"0\",\"t\":250";
QTest::newRow("tag+-1.f") << raw("\xc0\xfa\xbf\x80\0\0") << "\"tag\":\"0\",\"t\":250";
QTest::newRow("tag+16777215.f") << raw("\xc0\xfa\x4b\x7f\xff\xff") << "\"tag\":\"0\",\"t\":250";
QTest::newRow("tag+-16777215.f") << raw("\xc0\xfa\xcb\x7f\xff\xff") << "\"tag\":\"0\",\"t\":250";
QTest::newRow("tag+0.") << raw("\xc0\xfb\0\0\0\0\0\0\0\0") << "\"tag\":\"0\",\"t\":251";
QTest::newRow("tag+-1.") << raw("\xc0\xfb\xbf\xf0\0\0\0\0\0\0") << "\"tag\":\"0\",\"t\":251";
QTest::newRow("tag+16777215.") << raw("\xc0\xfb\x41\x6f\xff\xff\xe0\0\0\0") << "\"tag\":\"0\",\"t\":251";
QTest::newRow("tag+-16777215.") << raw("\xc0\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << "\"tag\":\"0\",\"t\":251";
// big tags (don't fit in JS numbers)
QTest::newRow("bigtag1") << raw("\xdb\0\x20\0\0""\0\0\0\1\x60") << "\"tag\":\"9007199254740993\"";
QTest::newRow("bigtag2") << raw("\xdb\xff\xff\xff\xff""\xff\xff\xff\xfe\x60")
<< "\"tag\":\"18446744073709551614\"";
// specially-handled tags
QTest::newRow("negativebignum") << raw("\xc3\x41 ") << "\"tag\":\"3\",\"t\":64";
QTest::newRow("base64") << raw("\xd6\x41 ") << "\"tag\":\"22\",\"t\":64";
QTest::newRow("base16") << raw("\xd7\x41 ") << "\"tag\":\"23\",\"t\":64";
}
void compareMetaData(QByteArray data, const QString &expected, int otherFlags = 0)
{
QString decoded;
// needs to be in one map, with the entry called "v"
data = "\xa1\x61v" + data;
{
CborParser parser;
CborValue first;
CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
QVERIFY2(!err, QByteArrayLiteral(": Got error \"") + cbor_error_string(err) + "\"");
err = parseOne(&first, &decoded, CborConvertAddMetadata | otherFlags);
QVERIFY2(!err, QByteArrayLiteral(": Got error \"") + cbor_error_string(err) +
"\"; decoded stream:\n" + decoded.toLatin1());
// check that we consumed everything
QCOMPARE((void*)cbor_value_get_next_byte(&first), (void*)data.constEnd());
}
QVERIFY(decoded.startsWith("{\"v\":"));
QVERIFY(decoded.endsWith('}'));
// qDebug() << "was" << decoded;
// extract just the metadata
static const char needle[] = "\"v$cbor\":{";
int pos = decoded.indexOf(needle);
QCOMPARE(pos == -1, expected.isEmpty());
if (pos != -1) {
decoded.chop(2);
decoded = std::move(decoded).mid(pos + strlen(needle));
QCOMPARE(decoded, expected);
}
}
void tst_ToJson::metaData()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
compareMetaData(data, expected);
}
void tst_ToJson::metaDataAndTagsToObjects()
{
QFETCH(QByteArray, data);
// when a tag is converted to an object, the object gets metadata indicating it was a tag
compareMetaData(data, "\"t\":192", CborConvertTagsToObjects);
}
void tst_ToJson::metaDataForKeys_data()
{
nonStringKeyMaps_data();
// string keys generate no metadata
QTest::newRow("string") << raw("\x60") << QString();
}
void tst_ToJson::metaDataForKeys()
{
QFETCH(QByteArray, data);
QFETCH(QString, expected);
if (expected.isEmpty())
expected = "{\"\":false}";
else
expected = "{\"" + expected + "\":false,\"" + expected + "$keycbordump\":true}";
compareOne('\xa1' + data + '\xf4', expected,
CborConvertAddMetadata | CborConvertStringifyMapKeys);
}
QTEST_MAIN(tst_ToJson)

View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: TinyCBOR
Description: A tiny CBOR encoder and decoder library
Version: @version@
Libs: -L${libdir} -ltinycbor
Libs.private: -lm
Cflags: -I${includedir}/tinycbor

View File

@ -0,0 +1,164 @@
/****************************************************************************
**
** Copyright (C) 2021 Intel Corporation
**
** 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.
**
****************************************************************************/
#define _POSIX_C_SOURCE 200809L
#include "cbor.h"
#include "cborjson.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void *xrealloc(void *old, size_t size, const char *fname)
{
old = realloc(old, size);
if (old == NULL) {
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
exit(EXIT_FAILURE);
}
return old;
}
void printerror(CborError err, const char *fname)
{
fprintf(stderr, "%s: %s\n", fname, cbor_error_string(err));
exit(EXIT_FAILURE);
}
void dumpFile(FILE *in, const char *fname, bool printJosn, int flags)
{
static const size_t chunklen = 16 * 1024;
static size_t bufsize = 0;
static uint8_t *buffer = NULL;
size_t buflen = 0;
do {
if (bufsize == buflen)
buffer = xrealloc(buffer, bufsize += chunklen, fname);
size_t n = fread(buffer + buflen, 1, bufsize - buflen, in);
buflen += n;
if (n == 0) {
if (!ferror(in))
continue;
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
exit(EXIT_FAILURE);
}
} while (!feof(in));
CborParser parser;
CborValue value;
CborError err = cbor_parser_init(buffer, buflen, 0, &parser, &value);
if (!err) {
if (printJosn)
err = cbor_value_to_json_advance(stdout, &value, flags);
else
err = cbor_value_to_pretty_advance_flags(stdout, &value, flags);
if (!err)
puts("");
}
if (!err && cbor_value_get_next_byte(&value) != buffer + buflen)
err = CborErrorGarbageAtEnd;
if (err)
printerror(err, fname);
}
int main(int argc, char **argv)
{
bool printJson = false;
int json_flags = CborConvertDefaultFlags;
int cbor_flags = CborPrettyDefaultFlags;
int c;
while ((c = getopt(argc, argv, "MOSUcjhfn")) != -1) {
switch (c) {
case 'c':
printJson = false;
break;
case 'j':
printJson = true;
break;
case 'f':
cbor_flags |= CborPrettyShowStringFragments;
break;
case 'n':
cbor_flags |= CborPrettyIndicateIndeterminateLength | CborPrettyNumericEncodingIndicators;
break;
case 'M':
json_flags |= CborConvertAddMetadata;
break;
case 'O':
json_flags |= CborConvertTagsToObjects;
break;
case 'S':
json_flags |= CborConvertStringifyMapKeys;
break;
case 'U':
json_flags |= CborConvertByteStringsToBase64Url;
break;
case '?':
fprintf(stderr, "Unknown option -%c.\n", optopt);
/* fall through */
case 'h':
puts("Usage: cbordump [OPTION]... [FILE]...\n"
"Interprets FILEs as CBOR binary data and dumps the content to stdout.\n"
"\n"
"Options:\n"
" -c Print a CBOR dump (see RFC 7049) (default)\n"
" -j Print a JSON equivalent version\n"
" -h Print this help output and exit\n"
"When JSON output is active, the following options are recognized:\n"
" -M Add metadata so converting back to CBOR is possible\n"
" -O Convert CBOR tags to JSON objects\n"
" -S Stringify non-text string map keys\n"
" -U Convert all CBOR byte strings to Base64url regardless of tags\n"
"When CBOR dump is active, the following options are recognized:\n"
" -f Show text and byte string fragments\n"
" -n Show overlong encoding of CBOR numbers and length"
"");
return c == '?' ? EXIT_FAILURE : EXIT_SUCCESS;
}
}
char **fname = argv + optind;
if (!*fname) {
dumpFile(stdin, "-", printJson, printJson ? json_flags : cbor_flags);
} else {
for ( ; *fname; ++fname) {
FILE *in = fopen(*fname, "rb");
if (!in) {
perror("open");
return EXIT_FAILURE;
}
dumpFile(in, *fname, printJson, printJson ? json_flags : cbor_flags);
fclose(in);
}
}
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,10 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
DESTDIR = ../../bin
CBORDIR = $$PWD/../../src
INCLUDEPATH += $$CBORDIR
SOURCES += cbordump.c
LIBS += ../../lib/libtinycbor.a

View File

@ -0,0 +1,493 @@
/****************************************************************************
**
** Copyright (C) 2015 Intel Corporation
**
** 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.
**
****************************************************************************/
#define _POSIX_C_SOURCE 200809L
#define _GNU_SOURCE
#include "cbor.h"
#include "cborinternal_p.h"
#include "compilersupport_p.h"
#include <cjson/cJSON.h>
#include <errno.h>
#include <math.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static const char meta_data_marker[] = "$cbor";
uint8_t *buffer;
size_t buffersize;
bool usingMetaData = false;
struct MetaData {
CborTag tag;
union {
const char *v;
uint8_t simpleType;
};
CborType t;
bool tagged;
};
uint8_t *decode_base64_generic(const char *string, size_t *len, const int8_t reverse_alphabet[256])
{
*len = ((strlen(string) + 3) & ~3) * 3 / 4;
uint8_t *buffer = malloc(*len);
if (buffer == NULL)
return NULL;
uint8_t *out = buffer;
const uint8_t *in = (const uint8_t *)string;
bool done = false;
while (!done) {
if (reverse_alphabet[in[0]] < 0 || reverse_alphabet[in[1]] < 0) {
if (in[0] == '\0')
done = true;
break;
}
uint32_t val = reverse_alphabet[in[0]] << 18;
val |= reverse_alphabet[in[1]] << 12;
if (in[2] == '=' || in[2] == '\0') {
if (in[2] == '=' && (in[3] != '=' || in[4] != '\0'))
break;
val >>= 12;
done = true;
} else if (in[3] == '=' || in[3] == '\0') {
if (in[3] == '=' && in[4] != '\0')
break;
val >>= 6;
val |= reverse_alphabet[in[2]];
done = true;
} else {
val |= reverse_alphabet[in[2]] << 6;
val |= reverse_alphabet[in[3]];
}
*out++ = val >> 16;
*out++ = val >> 8;
*out++ = val;
in += 4;
}
if (!done) {
free(buffer);
return NULL;
}
*len = out - buffer;
return buffer;
}
uint8_t *decode_base64(const char *string, size_t *len)
{
static const int8_t reverse_alphabet[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
return decode_base64_generic(string, len, reverse_alphabet);
}
uint8_t *decode_base64url(const char *string, size_t *len)
{
static const int8_t reverse_alphabet[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
return decode_base64_generic(string, len, reverse_alphabet);
}
uint8_t *decode_base16(const char *string, size_t *len)
{
size_t i;
*len = strlen(string) / 2;
uint8_t *buffer = malloc(*len);
if (buffer == NULL)
return NULL;
for (i = 0; i < *len; ++i) {
char c = string[i * 2];
if (c >= '0' && c <= '9') {
buffer[i] = (c - '0') << 4;
} else if ((c | 0x20) >= 'a' && (c | 0x20) <= 'f') {
buffer[i] = ((c | 0x20) - 'a' + 10) << 4;
} else {
free(buffer);
return NULL;
}
c = string[i * 2 + 1];
if (c >= '0' && c <= '9') {
buffer[i] |= (c - '0');
} else if ((c | 0x20) >= 'a' && (c | 0x20) <= 'f') {
buffer[i] |= ((c | 0x20) - 'a' + 10);
} else {
free(buffer);
return NULL;
}
}
return buffer;
}
size_t get_cjson_size_limited(cJSON *container)
{
// cJSON_GetArraySize is O(n), so don't go too far
unsigned s = 0;
cJSON *item;
for (item = container->child; item; item = item->next) {
if (++s > 255)
return CborIndefiniteLength;
}
return s;
}
cJSON *get_meta_data(cJSON *object, cJSON *item)
{
cJSON *meta;
char *metadatakey;
if (asprintf(&metadatakey, "%s%s", item->string, meta_data_marker) < 0 || metadatakey == NULL)
return NULL;
meta = cJSON_GetObjectItem(object, metadatakey);
free(metadatakey);
return meta;
}
struct MetaData parse_meta_data(cJSON *md)
{
struct MetaData result = { 0, {NULL}, CborInvalidType, false };
if (md == NULL || md->type != cJSON_Object)
return result;
for (md = md->child; md; md = md->next) {
if (strcmp(md->string, "tag") == 0) {
if (md->type != cJSON_String || sscanf(md->valuestring, "%" PRIu64, &result.tag) < 0)
fprintf(stderr, "json2cbor: could not parse tag: %s\n", md->valuestring);
else
result.tagged = true;
} else if (strcmp(md->string, "t") == 0) {
result.t = md->valueint;
} else if (strcmp(md->string, "v") == 0) {
if (md->type == cJSON_Number)
result.simpleType = md->valueint;
else
result.v = md->valuestring;
}
}
return result;
}
CborError decode_json(cJSON *json, CborEncoder *encoder);
CborError decode_json_with_metadata(cJSON *item, CborEncoder *encoder, struct MetaData md)
{
switch (md.t) {
case CborIntegerType: {
// integer that has more than 53 bits of precision
uint64_t v;
bool positive = *md.v++ == '+';
if (sscanf(md.v, "%" PRIx64, &v) < 0) {
fprintf(stderr, "json2cbor: could not parse number: %s\n", md.v);
break;
}
return positive ? cbor_encode_uint(encoder, v) : cbor_encode_negative_int(encoder, v);
}
case CborByteStringType: {
uint8_t *data;
size_t len;
if (md.tag == CborExpectedBase64Tag)
data = decode_base64(item->valuestring, &len);
else if (md.tag == CborExpectedBase16Tag)
data = decode_base16(item->valuestring, &len);
else if (md.tag == CborNegativeBignumTag)
data = decode_base64url(item->valuestring + 1, &len);
else
data = decode_base64url(item->valuestring, &len);
if (data != NULL) {
CborError err = cbor_encode_byte_string(encoder, data, len);
free(data);
return err;
}
fprintf(stderr, "json2cbor: could not decode encoded byte string: %s\n", item->valuestring);
break;
}
case CborSimpleType:
return cbor_encode_simple_value(encoder, md.simpleType);
case CborUndefinedType:
return cbor_encode_undefined(encoder);
case CborHalfFloatType:
case CborFloatType:
case CborDoubleType: {
unsigned short half;
double v;
if (!md.v) {
v = item->valuedouble;
} else if (strcmp(md.v, "nan") == 0) {
v = NAN;
} else if (strcmp(md.v, "-inf") == 0) {
v = -INFINITY;
} else if (strcmp(md.v, "inf") == 0) {
v = INFINITY;
} else {
fprintf(stderr, "json2cbor: invalid floating-point value: %s\n", md.v);
break;
}
// we can't get an OOM here because the metadata makes up for space
// (the smallest metadata is "$cbor":{"t":250} (17 bytes)
return (md.t == CborDoubleType) ? cbor_encode_double(encoder, v) :
(md.t == CborFloatType) ? cbor_encode_float(encoder, v) :
(half = encode_half(v), cbor_encode_half_float(encoder, &half));
}
default:
fprintf(stderr, "json2cbor: invalid CBOR type: %d\n", md.t);
case CborInvalidType:
break;
}
return decode_json(item, encoder);
}
CborError decode_json(cJSON *json, CborEncoder *encoder)
{
CborEncoder container;
CborError err;
cJSON *item;
switch (json->type) {
case cJSON_False:
case cJSON_True:
return cbor_encode_boolean(encoder, json->type == cJSON_True);
case cJSON_NULL:
return cbor_encode_null(encoder);
case cJSON_Number:
if ((double)json->valueint == json->valuedouble)
return cbor_encode_int(encoder, json->valueint);
encode_double:
// the only exception that JSON is larger: floating point numbers
container = *encoder; // save the state
err = cbor_encode_double(encoder, json->valuedouble);
if (err == CborErrorOutOfMemory) {
buffersize += 1024;
uint8_t *newbuffer = realloc(buffer, buffersize);
if (newbuffer == NULL)
return err;
*encoder = container; // restore state
encoder->data.ptr = newbuffer + (container.data.ptr - buffer);
encoder->end = newbuffer + buffersize;
buffer = newbuffer;
goto encode_double;
}
return err;
case cJSON_String:
return cbor_encode_text_stringz(encoder, json->valuestring);
default:
return CborErrorUnknownType;
case cJSON_Array:
err = cbor_encoder_create_array(encoder, &container, get_cjson_size_limited(json));
if (err)
return err;
for (item = json->child; item; item = item->next) {
err = decode_json(item, &container);
if (err)
return err;
}
return cbor_encoder_close_container_checked(encoder, &container);
case cJSON_Object:
err = cbor_encoder_create_map(encoder, &container,
usingMetaData ? CborIndefiniteLength : get_cjson_size_limited(json));
if (err)
return err;
for (item = json->child ; item; item = item->next) {
if (usingMetaData && strlen(item->string) > strlen(meta_data_marker)
&& strcmp(item->string + strlen(item->string) - strlen(meta_data_marker), meta_data_marker) == 0)
continue;
err = cbor_encode_text_stringz(&container, item->string);
if (err)
return err;
if (usingMetaData) {
cJSON *meta = get_meta_data(json, item);
struct MetaData md = parse_meta_data(meta);
if (md.tagged) {
err = cbor_encode_tag(&container, md.tag);
if (err)
return err;
}
err = decode_json_with_metadata(item, &container, md);
} else {
err = decode_json(item, &container);
}
if (err)
return err;
}
return cbor_encoder_close_container_checked(encoder, &container);
}
}
int main(int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, "M")) != -1) {
switch (c) {
case 'M':
usingMetaData = true;
break;
case '?':
fprintf(stderr, "Unknown option -%c.\n", optopt);
// fall through
case 'h':
puts("Usage: json2cbor [OPTION]... [FILE]...\n"
"Reads JSON content from FILE and converts to CBOR.\n"
"\n"
"Options:\n"
" -M Interpret metadata added by cbordump tool\n"
"");
return c == '?' ? EXIT_FAILURE : EXIT_SUCCESS;
}
}
FILE *in;
const char *fname = argv[optind];
if (fname && strcmp(fname, "-") != 0) {
in = fopen(fname, "r");
if (!in) {
perror("open");
return EXIT_FAILURE;
}
} else {
in = stdin;
fname = "-";
}
/* 1. read the file */
off_t fsize;
if (fseeko(in, 0, SEEK_END) == 0 && (fsize = ftello(in)) >= 0) {
buffersize = fsize + 1;
buffer = malloc(buffersize);
if (buffer == NULL) {
perror("malloc");
return EXIT_FAILURE;
}
rewind(in);
fsize = fread(buffer, 1, fsize, in);
buffer[fsize] = '\0';
} else {
const unsigned chunk = 16384;
buffersize = 0;
buffer = NULL;
do { // it the hard way
buffer = realloc(buffer, buffersize + chunk);
if (buffer == NULL) {
perror("malloc");
return EXIT_FAILURE;
}
buffersize += fread(buffer + buffersize, 1, chunk, in);
} while (!feof(in) && !ferror(in));
buffer[buffersize] = '\0';
}
if (ferror(in)) {
perror("read");
return EXIT_FAILURE;
}
if (in != stdin)
fclose(in);
/* 2. parse as JSON */
cJSON *doc = cJSON_ParseWithOpts((char *)buffer, NULL, true);
if (doc == NULL) {
fprintf(stderr, "json2cbor: %s: could not parse.\n", fname);
return EXIT_FAILURE;
}
/* 3. encode as CBOR */
// We're going to reuse the buffer, as CBOR is usually shorter than the equivalent JSON
CborEncoder encoder;
cbor_encoder_init(&encoder, buffer, buffersize, 0);
CborError err = decode_json(doc, &encoder);
cJSON_Delete(doc);
if (err) {
fprintf(stderr, "json2cbor: %s: error encoding to CBOR: %s\n", fname,
cbor_error_string(err));
return EXIT_FAILURE;
}
fwrite(buffer, 1, encoder.data.ptr - buffer, stdout);
free(buffer);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,20 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
DESTDIR = ../../bin
CBORDIR = $$PWD/../../src
INCLUDEPATH += $$CBORDIR
SOURCES += json2cbor.c
LIBS += ../../lib/libtinycbor.a
CJSONDIR = .
!exists($$CJSONDIR/cJSON.h): CJSONDIR = $$CBORDIR/cjson
exists($$CJSONDIR/cJSON.h) {
INCLUDEPATH += $$CJSONDIR
SOURCES += $$CJSONDIR/cJSON.c
} else {
message("cJSON not found, not building json2cbor.")
TEMPLATE = aux
}

View File

@ -0,0 +1 @@
a20007d67e65a000670ab77e45d7554c943eb8dcb0abeada0a57dd9adac3a703

View File

@ -0,0 +1,2 @@
*.pyc
tools/esp_secure_cert_data/*

View File

@ -0,0 +1,16 @@
# Contains the pre-commit hooks for the repository
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.3.0
hooks:
- id: trailing-whitespace
exclude: '.+\.(md|rst)'
- id: end-of-file-fixer
- id: check-executables-have-shebangs
- id: mixed-line-ending
args: ['-f=lf']
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.4
hooks:
- id: flake8
args: ['--config=.flake8', '--tee', '--benchmark']

View File

@ -0,0 +1,17 @@
set(srcs "srcs/esp_secure_cert_tlv_read.c" "srcs/esp_secure_cert_crypto.c")
if(CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS)
list(APPEND srcs "srcs/esp_secure_cert_read.c")
endif()
set(priv reqs "")
idf_build_get_property(build_components BUILD_COMPONENTS)
if(esp_partition IN_LIST build_components)
list(APPEND priv_reqs esp_partition)
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES spi_flash mbedtls nvs_flash efuse
PRIV_REQUIRES ${priv_reqs})

View File

@ -0,0 +1,85 @@
# This file contains the list of changes across different versions
## v2.4.1
* Added a new API `esp_secure_cert_get_tlv_info` for obtaining TLV information
* Added `esp_secure_cert_free_tlv_info` API for freeing TLV information.
* Added `esp_secure_cert_iterate_to_next_tlv` API for iterating the TLV entries
* Updated the API documentation for available `esp_secure_cert_get_*` APIs
## v2.4.0 (yanked)
* Added support for multiple entries of the same type by adding a new field called subtype.
* Fixed API for obtaining CA cert for the legacy flash formats (9b091ee)
### Yank explanation
This version was later yanked due to following reason.
* The API `esp_secure_cert_tlv_get_addr` which was made public in this version has incorrect documentation and the respective free API was not present.
* The changes in this version also modifiy the behaviour of existing APIs to obtain the TLV entry of latest subtype. While no current users shall be affected, this may cause inconsistency in the available API usage going forward.
Please note that the yanked version does not affect any of existing users. The yanking is done due to future API usage considerations and to avoid any possible inconsistencies.
## v2.3.1
* Make esp_secure_cert_get_key_type API available for DS peripheral case as well.
## v2.3.0
* Added support to obtain the priv key type
* Added support for getting the efuse key id for priv key
## v2.2.0
* tools: Support DER encoded private keys when creating secure cert partition on host
### Breaking changes in v2.2.0
* Updated the order of arguments for esp_pbkdf2_hmac_sha256 API to match it with corresponding mbedTLS API
## v2.1.0
* Added support for HMAC based ECDSA key derivation with PBKDF2-HMAC-SHA256
* Fixed build failure when example is setup through component manager
## v2.0.8
* Fix for supporting IDF v4.3
## v2.0.7
* Updated documentation regarding TLV format
* Fixed priv_key free API when HMAC based encryption scheme is enabled.
## v2.0.6
* Added HMAC based encryption scheme to protect private key data
* Added support for private key validation in the esp_secure_cert_app
* Added support of configurable esp_secure_cert partition offset in for configure_esp_secure_cert.py utility
## v2.0.5
* Fixed targets in Kconfig to reflect DS Peripheral compatibility
## v2.0.4
* Add implementation of `esp_secure_cert_free_*` APIs for TLV configuration.
## v2.0.3
* Added C linkage so that C++ code can find the definitions for secure cert APIs.
* Minor documentation fixes.
## v2.0.2
* Updated reference to the new esp_partition component (IDFv5.0)
## v2.0.1
* Added fixes for build failures with `-Wstrict-prototypes` CFLAG.
* Added fix for build failure with toolchain change in IDFv4.x and IDFv5.x
## v2.0.0
* Added esp-secure-cert-tool to PyPi.
* Restructure esp-secure-cert-tool
### Breaking changes in v2.0.0
* Added the support for TLV format for storing data in esp_secure_cert partition.
* Make the TLV `cust_flash_tlv` as the default flash format.
* Marked all the supported flash formats before TLV as legacy: `cust_flash`, `nvs`.
* esp_secure_cert_app: Updated the partition table for the example
## v1.0.3
* esp_secure_cert API now Dynamically identify the type of partitionand access the data accordingly
* esp_secure_cert_app: Enable support for target esp32
* Added tests based on qemu
* Added priv_key functionality to the configure_esp_secure_cert.py script.
### Breaking changes in v1.0.3
* Removed all the configuration options related to selecting the type of `esp_secure_cert` partition
* Remove `esp_secure_cert_get_*_addr` API, the contents can now be obtained through `esp_secure_cert_get_*` API.
* Remove APIs to obain the contents of the DS contexts e.g. efuse key id, ciphertext, iv etc. The contents can be accesed from inside the DS context which can be obtained through respective API.
* Breaking change in the `esp_secure_cert_get_*` API:
The API now accepts `char **buffer` instead of `char *buffer`. It will allocate the required memory dynamically and directly if necessary and provide the respective pointer.

View File

@ -0,0 +1,22 @@
menu "ESP Secure Cert Manager"
config ESP_SECURE_CERT_DS_PERIPHERAL
bool "Enable DS peripheral support"
default y
depends on !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32C2
help
Enable the DS peripheral support. Not supported on esp32 and esp32c2.
config ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS
bool "Enable support for legacy formats"
default n
help
This option enables support for the legacy formats along with
the current format in the esp_secure_cert component.
The current format is
cust_flash_tlv
The legacy formats are as follows:
cust_flash
nvs
endmenu # ESP Secure Cert Manager

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,51 @@
# ESP Secure Certificate Manager
The *esp_secure_cert_mgr* provides a simplified interface to access the PKI credentials of a device pre-provisioned with the
Espressif Provisioning Service. It provides the set of APIs that are required to access the contents of
the `esp_secure_cert` partition.
A demo example has also been provided with the `esp_secure_cert_mgr`, more details can be found out
in the [example README](https://github.com/espressif/esp_secure_cert_mgr/blob/main/examples/esp_secure_cert_app/README.md)
## Usage Guidelines
### 1) Include `esp_secure_cert_mgr` in your project
There are two ways to include `esp_secure_cert_mgr` in your project:
i) Add `esp_secure_cert_mgr` to your project with help of IDF component manager:
* The component is hosted at https://components.espressif.com/component/espressif/esp_secure_cert_mgr. Please use the same link to obtain the latest available version of the component along with the instructions on how to add it to your project.
* Additional details about using a component through IDF component manager can be found [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html#using-with-a-project)
ii) Add `esp_secure_cert_mgr` as an extra component in your project.
* Download `esp_secure_cert_mgr` with:
```
git clone https://github.com/espressif/esp_secure_cert_mgr.git
```
* Include `esp_secure_cert_mgr` in `ESP-IDF` with setting `EXTRA_COMPONENT_DIRS` in CMakeLists.txt/Makefile of your project.For reference see [Optional Project Variables](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#optional-project-variables)
### 2) Use the public API provided by `esp_secure_cert_mgr` in your project
* The file [esp_secure_cert_read.h](https://github.com/espressif/esp_secure_cert_mgr/blob/main/include/esp_secure_cert_read.h) contains the public APIs provided by the `esp_secure_cert_mgr`. Please include the file in your project to make use of the available APIs. The file also contains more details about the available APIs.
## What is Pre-Provisioning?
With the Espressif Pre-Provisioning Service, the ESP modules are pre-provisioned with an encrypted RSA private key and respective X509 public certificate before they are shipped out to you. The PKI credentials can then be registered with the cloud service to establish a secure TLS channel for communication. With the pre-provisioning taking place in the factory, it provides a hassle-free PKI infrastructure to the Makers. You may use this repository to set up your test modules to validate that your firmware works with the pre-provisioned modules that you ordered through Espressif's pre-provisioning service.
## ESP Secure Cert Partition
When a device is pre-provisioned that means the PKI credentials are generated for the device. The PKI credentials are then stored in a partition named
*esp_secure_cert*.
The `esp_secure_cert` partition can be generated on host with help of [configure_esp_secure_cert.py](https://github.com/espressif/esp_secure_cert_mgr/blob/main/tools/configure_esp_secure_cert.py) utility, more details about the utility can be found in the [tools/README](https://github.com/espressif/esp_secure_cert_mgr/tree/main/tools#readme).
For esp devices that support DS peripheral, the pre-provisioning is done by leveraging the security benefit of the DS peripheral. In that case, all of the data which is present in the *esp_secure_cert* partition is completely secure.
When the device is pre-provisioned with help of the DS peripheral then by default the partition primarily contains the following data:
1) Device certificate: It is the public key/ certificate for the device's private key. It is used in TLS authentication.
2) CA certificate: This is the certificate of the CA which is used to sign the device cert.
3) Ciphertext: This is the encrypted private key of the device. The ciphertext is encrypted using the DS peripheral, thus it is completely safe to store on the flash.
As listed above, the data only contains the public certificates and the encrypted private key and hence it is completely secure in itself. There is no need to further encrypt this data with any additional security algorithm.
### Partition Format
The *esp_secure_cert* partition uses TLV format by default. Please take a look at the [format document](https://github.com/espressif/esp_secure_cert_mgr/tree/main/docs/format.md) for more details.

View File

@ -0,0 +1,90 @@
#!/bin/bash
ESP_SECURE_CERT_APP=$PWD/../examples/esp_secure_cert_app
# This option causes the script to fail if any command fails in the main body of the script
# Note: this does not apply to the internal functions
# We need to check the exit status of each command individually
set -e
clean() {
rm -r sdkconfig 2>&1
rm -r build 2>&1
}
idf_path_verify() {
if [[ -z "$IDF_PATH" ]]; then
echo "IDF_PATH not set. Please set IDF_PATH "
exit 1
else
echo '--------####--------'
echo 'IDF_PATH & Branch'
echo $IDF_PATH;(cd $IDF_PATH;git branch --show-current)
echo '--------####--------'
fi
}
# Build the default config with ds support enabled
# $1 = IDF_TARGET
build_ds_config() {
idf_target=$1
cd $ESP_SECURE_CERT_APP
clean
idf.py set-target $idf_target || exit $?
idf.py build || exit $?
clean
}
# Build the firmware with the config option for legacy flash formats enabled
# $1 = IDF_TARGET
build_ds_config_legacy_flash_format() {
idf_target=$1
cd $ESP_SECURE_CERT_APP
clean
echo "CONFIG_ESP_SECURE_CERT_SUPPORT_LEGACY_FORMATS=y" >> sdkconfig.defaults
idf.py set-target $idf_target || exit $?
idf.py build || exit $?
clean
}
# Build the firmware with ds support disabled
build_no_ds_config() {
idf_target=$1
if [[ $idf_target == "esp32" ]]; then
echo "No ds config is same as default config for esp32"
echo "Exiting"
exit 0
fi
cd $ESP_SECURE_CERT_APP
clean
echo "CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n" >> sdkconfig.defaults
idf.py set-target $idf_target || exit $?
idf.py build || exit $?
clean
}
# $1 = IDF_TARGET
# $2 = CI_PARALLEL_COUNT
# This function assigns tests based on the parallel count value
assign_test() {
idf_target=$1
ci_parallel_count=$2
if [[ $ci_parallel_count == "1" ]]; then
echo "Building the default config"
build_ds_config $idf_target || exit 1
fi
if [[ $ci_parallel_count == "2" ]]; then
echo "Building the legacy flash format config"
build_ds_config_legacy_flash_format $idf_target || exit 1
fi
if [[ $ci_parallel_count == "3" ]]; then
echo "Building with ds support disabled"
build_no_ds_config $idf_target || exit 1
fi
}
IDF_TARGET=$1
CI_PARALLEL_COUNT=$2
echo "Building for target "$IDF_TARGET
echo "CI Parallel count: "$CI_PARALLEL_COUNT
idf_path_verify || exit 1
assign_test $IDF_TARGET $CI_PARALLEL_COUNT

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -0,0 +1,75 @@
# `esp_secure_cert` partition format
## TLV format
The `esp_secure_cert` partition uses TLV format by default. TLV format has been decided based on its simplicity and efficiency. We use customized headers specifically designed for the `esp_secure_cert` partition. The `esp_secure_cert` partition is supposed to be a READ-only partition which can contain the data which is bound to the device and is not usually updated e.g. Device private key, Device certificate, CA certificate. Currently `esp_secure_cert_mgr` component does not support modification of the `esp_secure_cert` partition.
The TLV format used in the esp_secure_cert partition is as follows:
![](_static/tlv_format.png)
* TLV header: It contains the information regarding the data such as the type of the data and the length of the data. For more details about the TLV, please take a look at [tlv_config.h](https://github.com/espressif/esp_secure_cert_mgr/tree/main/private_include/esp_secure_cert_tlv_config.h).
* i) TLV flags field - flags byte that identifies different characteristics for the TLV
* ii) TLV type: Currently the TLV format supports only a list of pre-defined types. The latest list for pre-defined types can be found at [tlv_config.h](https://github.com/espressif/esp_secure_cert_mgr/tree/main/private_include/esp_secure_cert_tlv_config.h). Additional custom types are also provided in order to allow storing custom data in TLV format. The custom data types can be typecasted to appropriate types after reading the TLV.
* iii) TLV length - the length of the data field in the TLV.
* TLV footer: It contains the crc32 of the data and header field.
* TLV format Padding - In TLV format a padding is added automatically between the end offset of data and TLV footer. The padding is added in order to make the data field a multiple of 16 bytes which is the minimum alignment required for flash encrypted writes.
### Partition table entry
* For TLV format the `partitions.csv` file for the project should contain the following line which enables it to identify the `esp_secure_cert` partition:
```
# Name, Type, SubType, Offset, Size, Flags
esp_secure_cert, 0x3F, , 0xD000, 0x2000, encrypted
```
Please note that, TLV format uses compact data representation and hence partition size is kept as 8KiB.
> Note: The TLV read API expects that a padding of appropriate size is added to data to make it size as a multiple of 16 bytes, the partition generation utility i.e. [configure_esp_secure_cert.py](https://github.com/espressif/esp_secure_cert_mgr/blob/main/tools/configure_esp_secure_cert.py) takes care of this internally while generating the partition.
When flash encryption is enabled for the device it is imporatant to encrypt the `esp_secure_cert` partition as well. Adding the encrypted flag in the partition table as done above can ensure that this is done. When flash encryption is not enabled this flag shall be ignored.
## TLV storage algorithms
The `esp_secure_cert_mgr` component also supports following algorithms for TLV. In this case the TLV data is not stored directly but is stored by using one of the following algorithms. The information about the algorithms is a part of the TLV itself.
- HMAC based AES-GCM encryption:
In this case the first key stored on the device with purpose `HMAC_UP` is used to derive an AES key and the salt.
This key is used to encrypt the TLV contents.
This algorithm is suitable where the platform encryption is not enabled.
- HMAC based ECDSA key derivation:
In this case the ECDSA key is derived using following two values
- Salt: This is the salt stored in a different tlv with type `ESP_SECURE_CERT_HMAC_ECDSA_KEY_SALT`
- HMAC key: This is the first key stored on the device with purpose `HMAC_UP`.
Both of these entities are used as input for the pbkdf2 algorithm to generate the ECDSA key.
Please ensure that appropriate TLV flags are enabled to take care of the underlying security configuration for the given TLV entry. On top of these security configuration, if platform flash encryption is enabled then the secure cert partition contents shall be stored in an encrypted manner on the external flash storage
## Legacy formats for `esp_secure_cert` partition
`esp_secure_cert` partition also supports two legacy flash formats.
The support for these can be enabled through following menuconfig option:
* `Component config > ESP Secure Cert Manager -> Enable support for legacy formats`
1) *cust_flash*: In this case, the partition is a custom flash partition. The data is directly stored over the flash.
* In this case the `partitions.csv` file for the project should contain the following line which enables it to identify the `esp_secure_cert` partition.
```
# Name, Type, SubType, Offset, Size, Flags
esp_secure_cert, 0x3F, , 0xD000, 0x6000, encrypted
```
When flash encryption is enabled the behaviour is same as mentioned above for the TLV format.
2) *nvs partition*: In this case, the partition is of the `nvs` type. The `nvs_flash` abstraction layer from the ESP-IDF is used to store and then retreive the contents of the `esp_secure_cert` partition.
* In this case the `partitions.csv` file for the project should contain the following line which enables it to identify the `esp_secure_cert` partition.
```
# Name, Type, SubType, Offset, Size, Flags
esp_secure_cert, data, nvs, 0xD000, 0x6000,
```
Currently the nvs encryption option is not supported for the `esp_secure_cert` partition.

View File

@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp_secure_cert_app)

View File

@ -0,0 +1,61 @@
# ESP Secure Certificate Application
The sample app demonstrates the use of APIs from *esp_secure_cert_mgr* to retrieve the contents of the *esp_secure_cert* partition. The example can also be used to verify the validity of the contents from the *esp_secure_cert* partition.
## Requirements
* The device must be pre-provisioned and have an *esp_secure_cert* partition.
## How to use the example
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
### Configure the project
* The *esp_secure_cert* partition needs to be generated and flashed first with help of [configure_esp_secure_cert.py](https://github.com/espressif/esp_secure_cert_mgr/blob/main/tools/configure_esp_secure_cert.py) script. See [tools/README.md](https://github.com/espressif/esp_secure_cert_mgr/blob/main/tools/README.md) for more details.
* Please ensure that appropriate type of esp_secure_cert partition has been set in your projects `partitions.csv` file. Please refer the "esp_secure_cert partition" section in the [component README](https://github.com/espressif/esp_secure_cert_mgr#readme) for more details.
### Build and Flash
Build the project and flash it to the board, then run the monitor tool to view the serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
### Example Output
```
I (331) sample_app: Device Cert:
Length: 1233
-----BEGIN CERTIFICATE-----
.
.
-----END CERTIFICATE-----
I (441) sample_app: CA Cert:
Length: 1285
-----BEGIN CERTIFICATE-----
.
.
-----END CERTIFICATE-----
I (561) sample_app: Successfuly obtained ciphertext, ciphertext length is 1200
I (571) sample_app: Successfuly obtained initialization vector, iv length is 16
I (571) sample_app: RSA length is 2048
I (581) sample_app: Efuse key id 1
I (581) sample_app: Successfully obtained the ds context
I (831) sample_app: Ciphertext validated succcessfully
```
## Additional configurations for `pre_prov` partition
Few of the modules which were pre-provisioned initially had the name of the pre-provisioning partition as `pre_prov`. For the modules which have pre-provisioning partition of name `esp_secure_cert` this part can be ignored.
* For modules with `pre_prov` partition of type *cust_flash*, please update the line refering to `esp_secure_cert` partition in the partitions.csv with following:
```
pre_prov, 0x3F, , 0xD000, 0x6000,
```
* No change is necessary for `pre_prov` partition of type *nvs*.

View File

@ -0,0 +1,4 @@
idf_component_register(
SRC_DIRS "."
INCLUDE_DIRS "."
)

View File

@ -0,0 +1,257 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ESP Secure Cert App
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <inttypes.h>
#include "esp_log.h"
#include "esp_secure_cert_read.h"
#include "esp_secure_cert_tlv_read.h"
#include "mbedtls/ssl.h"
#include "mbedtls/pk.h"
#include "mbedtls/x509.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
#include "esp_idf_version.h"
#define TAG "esp_secure_cert_app"
#ifdef CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL
static esp_err_t test_ciphertext_validity(esp_ds_data_ctx_t *ds_data, unsigned char *dev_cert, size_t dev_cert_len)
{
mbedtls_x509_crt crt;
mbedtls_x509_crt_init(&crt);
unsigned char *sig = NULL;
if (ds_data == NULL || dev_cert == NULL) {
return ESP_ERR_INVALID_ARG;
}
int ret = mbedtls_x509_crt_parse(&crt, dev_cert, dev_cert_len);
if (ret < 0) {
ESP_LOGE(TAG, "Parsing of device certificate failed, returned %02X", ret);
goto exit;
}
esp_err_t esp_ret = esp_ds_init_data_ctx(ds_data);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialze the DS context");
return esp_ret;
}
const size_t sig_len = 256;
uint32_t hash[8] = {[0 ... 7] = 0xAABBCCDD};
sig = (unsigned char *) calloc(1, 1000 * sizeof(char));
if (sig == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory for signature");
goto exit;
}
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
ret = esp_ds_rsa_sign(NULL, NULL, NULL, 0, MBEDTLS_MD_SHA256, 0, (const unsigned char *) hash, sig);
#else
ret = esp_ds_rsa_sign(NULL, NULL, NULL, MBEDTLS_MD_SHA256, 0, (const unsigned char *) hash, sig);
#endif
if (ret != 0) {
ESP_LOGE(TAG, "Failed to sign the data with rsa key, returned %02X", ret);
goto exit;
}
esp_ds_release_ds_lock();
ret = mbedtls_pk_verify(&crt.pk, MBEDTLS_MD_SHA256, (const unsigned char *) hash, 0, sig, sig_len);
if (ret != 0) {
printf("\nFailed to verify the data\n");
goto exit;
}
free(sig);
return ESP_OK;
exit:
free(sig);
mbedtls_x509_crt_free(&crt);
printf("\nFailed to verify the ciphertext\n");
esp_ds_release_ds_lock();
return ESP_FAIL;
}
#else
static esp_err_t test_priv_key_validity(unsigned char* priv_key, size_t priv_key_len, unsigned char *dev_cert, size_t dev_cert_len)
{
static const char *pers = "Hello";
mbedtls_x509_crt crt;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_pk_context pk;
unsigned char *sig = NULL;
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_x509_crt_init(&crt);
mbedtls_entropy_init(&entropy);
mbedtls_pk_init(&pk);
esp_err_t esp_ret = ESP_FAIL;
if (priv_key == NULL || dev_cert == NULL) {
return ESP_ERR_INVALID_ARG;
}
int ret = mbedtls_x509_crt_parse(&crt, dev_cert, dev_cert_len);
if (ret != 0) {
ESP_LOGE(TAG, "Parsing of device certificate failed, returned %02X", ret);
esp_ret = ESP_FAIL;
goto exit;
} else {
ESP_LOGI(TAG, "Successfully parsed the certificate");
}
ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen(pers));
if (ret != 0) {
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x", -ret );
esp_ret = ESP_FAIL;
goto exit;
}
#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
ret = mbedtls_pk_parse_key(&pk, (const uint8_t *)priv_key, priv_key_len, NULL, 0);
#else
ret = mbedtls_pk_parse_key(&pk, (const uint8_t *)priv_key, priv_key_len, NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg);
#endif
if (ret != 0) {
ESP_LOGE(TAG, "Failed to parse the key");
esp_ret = ESP_FAIL;
goto exit;
} else {
ESP_LOGI(TAG, "Successfully parsed the key");
}
static uint32_t hash[8] = {[0 ... 7] = 0xAABBCCDD};
#define SIG_SIZE 1024
sig = (unsigned char*)calloc(1, SIG_SIZE * sizeof(char));
if (sig == NULL) {
ESP_LOGE(TAG, "Failed to allocate memory");
esp_ret = ESP_FAIL;
goto exit;
}
size_t sig_len = 0;
#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
ret = mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256, (const unsigned char *) hash, 0, sig, &sig_len, mbedtls_ctr_drbg_random, &ctr_drbg);
#else
ret = mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256, (const unsigned char *) hash, 0, sig, SIG_SIZE, &sig_len, mbedtls_ctr_drbg_random, &ctr_drbg);
#endif
if (ret != 0) {
ESP_LOGE(TAG, "Failed to sign the data");
esp_ret = ESP_FAIL;
goto exit;
} else {
ESP_LOGI(TAG, "Successfully signed the data");
}
ret = mbedtls_pk_verify(&crt.pk, MBEDTLS_MD_SHA256, (const unsigned char *) hash, 0, sig, sig_len);
if (ret != 0) {
ESP_LOGE(TAG, "Failed to verify the signed data");
esp_ret = ESP_FAIL;
goto exit;
}
esp_ret = ESP_OK;
exit:
free(sig);
mbedtls_pk_free(&pk);
mbedtls_entropy_free(&entropy);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_x509_crt_free(&crt);
return esp_ret;
}
#endif
void app_main()
{
uint32_t len = 0;
char *addr = NULL;
esp_err_t esp_ret = ESP_FAIL;
esp_ret = esp_secure_cert_get_device_cert(&addr, &len);
if (esp_ret == ESP_OK) {
ESP_LOGI(TAG, "Device Cert: \nLength: %"PRIu32"\n%s", len, (char *)addr);
} else {
ESP_LOGE(TAG, "Failed to obtain flash address of device cert");
}
esp_ret = esp_secure_cert_get_ca_cert(&addr, &len);
if (esp_ret == ESP_OK) {
ESP_LOGI(TAG, "CA Cert: \nLength: %"PRIu32"\n%s", len, (char *)addr);
ESP_LOG_BUFFER_HEX_LEVEL(TAG, addr, len, ESP_LOG_DEBUG);
} else {
ESP_LOGE(TAG, "Failed to obtain flash address of ca_cert");
}
#ifndef CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL
esp_ret = esp_secure_cert_get_priv_key(&addr, &len);
if (esp_ret == ESP_OK) {
ESP_LOGI(TAG, "PEM KEY: \nLength: %"PRIu32"\n%s", len, (char *)addr);
} else {
ESP_LOGE(TAG, "Failed to obtain flash address of private_key");
}
uint32_t dev_cert_len = 0;
char *dev_cert_addr = NULL;
esp_ret = esp_secure_cert_get_device_cert(&dev_cert_addr, &dev_cert_len);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to obtain the dev cert flash address");
}
esp_ret = test_priv_key_validity((unsigned char *)addr, len, (unsigned char *)dev_cert_addr, dev_cert_len);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to validate the private key and device certificate");
}
#else
esp_ds_data_ctx_t *ds_data = NULL;
ds_data = esp_secure_cert_get_ds_ctx();
if (ds_data != NULL) {
ESP_LOGI(TAG, "Successfully obtained the ds context");
ESP_LOG_BUFFER_HEX_LEVEL(TAG, ds_data->esp_ds_data->c, ESP_DS_C_LEN, ESP_LOG_DEBUG);
ESP_LOG_BUFFER_HEX_LEVEL(TAG, ds_data->esp_ds_data->iv, ESP_DS_IV_LEN, ESP_LOG_DEBUG);
ESP_LOGI(TAG, "The value of rsa length is %d", ds_data->rsa_length_bits);
ESP_LOGI(TAG, "The value of efuse key id is %d", ds_data->efuse_key_id);
} else {
ESP_LOGE(TAG, "Failed to obtain the ds context");
}
/* Read the dev_cert addr again */
esp_ret = esp_secure_cert_get_device_cert(&addr, &len);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to obtain the dev cert flash address");
}
esp_ret = test_ciphertext_validity(ds_data, (unsigned char *)addr, len);
if (esp_ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to validate ciphertext");
} else {
ESP_LOGI(TAG, "Ciphertext validated succcessfully");
}
#endif
if (esp_ret == ESP_OK) {
ESP_LOGI(TAG, "Successfully obtained and verified the contents of esp_secure_cert partition");
} else {
ESP_LOGE(TAG, "Failed to obtain and verify the contents of the esp_secure_cert partition");
}
esp_secure_cert_tlv_config_t tlv_config = {};
tlv_config.type = ESP_SECURE_CERT_DEV_CERT_TLV;
tlv_config.subtype = ESP_SECURE_CERT_SUBTYPE_0;
esp_secure_cert_tlv_info_t tlv_info = {};
esp_ret = esp_secure_cert_get_tlv_info(&tlv_config, &tlv_info);
if (esp_ret == ESP_OK) {
ESP_LOGI(TAG, "Device Cert: \nLength: %"PRIu32"\n%s", tlv_info.length, tlv_info.data);
}
ESP_LOGI(TAG, "Printing a list of TLV entries");
esp_secure_cert_list_tlv_entries();
}

View File

@ -0,0 +1,6 @@
version: "1.0.0"
description: ESP Secure Cert Manager Example
dependencies:
espressif/esp_secure_cert_mgr:
version: '^2.0.8'
override_path: '../../../' # three levels up, pointing the directory with the component itself

View File

@ -0,0 +1,4 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
esp_secure_cert, 0x3F, , 0xD000, 0x2000, encrypted
factory, app, factory, 0x20000, 1M,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
3 esp_secure_cert, 0x3F, , 0xD000, 0x2000, encrypted
4 factory, app, factory, 0x20000, 1M,

View File

@ -0,0 +1,40 @@
# ESP Secure cert partition tests
This folder contains the test setup for testing the different flash formats supported by esp_secure_cert partition. The tests are based on the QEMU emulater.
## Requirements
* **QEMU emulator**:
The test is based on qemu and needs the qemu emulator support.
* For Linux Distributions, the executables to be downloaded from [qemu/releases](https://github.com/espressif/qemu/releases)
* For macOS you need to build the binaries for specific release locally on machine. see [Compiling Qemu](https://github.com/espressif/esp-toolchain-docs/blob/main/qemu/esp32/README.md#compiling-qemu) for more details.
* **Pytest**:
Install the pytest environment by executing following command
```pip install -r requirements.txt```
## Testing
The script [`build_qemu_images.sh`](./build_qemu_images.sh) can be used to generate the respective qemu images. These images are then provided to pytest framework for execution.
### Test the TLV support on esp32
The TLV support can be tested with following commands:
* ```./build_qemu_images.sh tlv```
* ``` cd ..```
* ``pytest --target esp32``
### Test the legacy flash format support on esp32
The TLV support can be tested with following commands:
* ```./build_qemu_images.sh legacy```
* ``` cd ..```
* ``pytest --target esp32``

View File

@ -0,0 +1,82 @@
#!/bin/bash
ESP_SECURE_CERT_APP=$PWD/../
if [ -z "$1" ]; then
echo "Usage: build_qemu_image.sh image_type
image type can be tlv, legacy_format"
exit 1
fi
image_type=$1
# This option causes the script to fail if any command fails in the main body of the script
# Note: this does not apply to the internal functions
# We need to check the exit status of each command individually
set -e
save_defaults() {
cp sdkconfig.defaults sdkconfig_defaults_clean
}
restore_defaults() {
mv sdkconfig_defaults_clean sdkconfig.defaults
}
clean() {
rm -rf sdkconfig 2>&1
rm -rf build 2>&1
}
idf_path_verify() {
if [[ -z "$IDF_PATH" ]]; then
echo "IDF_PATH not set. Please set IDF_PATH "
exit 1
else
echo '--------####--------'
echo 'IDF_PATH & Branch'
echo $IDF_PATH;(cd $IDF_PATH;git branch --show-current)
echo '--------####--------'
fi
}
build_tlv_image() {
cd $ESP_SECURE_CERT_APP
save_defaults
clean
cat sdkconfig.ci.tlv >> sdkconfig.defaults
idf.py build
cd qemu_test
rm -rf qemu_test_images
mkdir qemu_test_images
./make-qemu-img.sh cust_flash_tlv/cust_flash_tlv.bin cust_flash_tlv/partition-table.bin ../ esp_secure_cert_app qemu_test_images/cust_flash_tlv_qemu.img
cd $ESP_SECURE_CERT_APP
restore_defaults
}
build_legacy_format_images() {
cd $ESP_SECURE_CERT_APP
save_defaults
clean
cat sdkconfig.ci.legacy >> sdkconfig.defaults
idf.py build
cd qemu_test
rm -rf qemu_test_images
mkdir qemu_test_images
./make-qemu-img.sh cust_flash/cust_flash.bin cust_flash/partition-table.bin ../ esp_secure_cert_app qemu_test_images/cust_flash_qemu.img
./make-qemu-img.sh cust_flash_legacy/cust_flash_legacy.bin cust_flash_legacy/partition-table.bin ../ esp_secure_cert_app qemu_test_images/cust_flash_legacy_qemu.img
./make-qemu-img.sh nvs/nvs.bin nvs/partition-table.bin ../ esp_secure_cert_app qemu_test_images/nvs_qemu.img
./make-qemu-img.sh nvs_legacy/nvs_legacy.bin nvs/partition-table.bin ../ esp_secure_cert_app qemu_test_images/nvs_legacy_qemu.img
./make-qemu-img.sh nvs_legacy/nvs_legacy.bin nvs_legacy/partition-table.bin ../ esp_secure_cert_app qemu_test_images/nvs_legacy_qemu_new_part_name.img
cd $ESP_SECURE_CERT_APP
restore_defaults
}
if [ $1 == "tlv" ]; then
# Build the TLV format image
build_tlv_image
fi
if [ $1 == "legacy_format" ]; then
# Build the TLV format image
build_legacy_format_images
fi

Some files were not shown because too many files have changed in this diff Show More