├── VERSION ├── .tag ├── src ├── tinycbor-export.h.in ├── tinycbor-version.h.in ├── src.pri ├── tags.txt ├── memory.h ├── cborinternalmacros_p.h ├── cborencoder_float.c ├── cborjson.h ├── cborencoder_close_container_checked.c ├── cborparser_float.c ├── utf8_p.h ├── open_memstream.c ├── cborpretty_stdio.c ├── parsetags.pl ├── cborparser_dup_string.c ├── cbor.dox ├── cborerrorstrings.c ├── compilersupport_p.h ├── cborinternal_p.h ├── cborpretty.c └── cborvalidation.c ├── tests ├── cpp │ ├── CMakeLists.txt │ └── tst_cpp.cpp ├── encoder │ ├── CMakeLists.txt │ ├── data.cpp │ └── tst_encoder.cpp ├── parser │ └── CMakeLists.txt ├── tojson │ └── CMakeLists.txt ├── c90 │ ├── CMakeLists.txt │ └── tst_c90.c └── CMakeLists.txt ├── .github ├── dependabot.yml └── workflows │ └── build.yml ├── tools ├── CMakeLists.txt ├── cbordump │ ├── CMakeLists.txt │ └── cbordump.c └── json2cbor │ ├── CMakeLists.txt │ └── json2cbor.c ├── tinycbor.pc.in ├── README ├── SECURITY.md ├── cmake ├── project-config.cmake.in ├── PackageConfig.cmake └── TinyCBORHelpers.cmake ├── TODO ├── LICENSE ├── .appveyor.yml ├── Makefile.configure ├── Makefile.nmake ├── scripts ├── update-docs.sh └── maketag.pl ├── Doxyfile ├── examples └── simplereader.c └── CMakeLists.txt /VERSION: -------------------------------------------------------------------------------- 1 | 0.7.0 2 | -------------------------------------------------------------------------------- /.tag: -------------------------------------------------------------------------------- 1 | 09496c6432adfcfa7a563068e5365849b088f653 2 | -------------------------------------------------------------------------------- /src/tinycbor-export.h.in: -------------------------------------------------------------------------------- 1 | #ifndef CBOR_API 2 | #define CBOR_API 3 | #endif 4 | -------------------------------------------------------------------------------- /tests/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | 4 | tinycbor_add_qtest(tst_cpp tst_cpp.cpp) 5 | -------------------------------------------------------------------------------- /tests/encoder/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | tinycbor_add_qtest(tst_encoder tst_encoder.cpp) 4 | -------------------------------------------------------------------------------- /tests/parser/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | tinycbor_add_qtest(tst_parser tst_parser.cpp) 4 | -------------------------------------------------------------------------------- /tests/tojson/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | tinycbor_add_qtest(tst_tojson tst_tojson.cpp) 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | target-branch: "main" 8 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | include(TinyCBORHelpers) 4 | add_subdirectory(cbordump) 5 | add_subdirectory(json2cbor) 6 | -------------------------------------------------------------------------------- /tools/cbordump/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | if(NOT WIN32) 4 | tinycbor_add_executable(cbordump cbordump.c) 5 | install(TARGETS cbordump) 6 | endif() 7 | -------------------------------------------------------------------------------- /tests/c90/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | tinycbor_add_test(tst_c90 tst_c90.c) 4 | set_target_properties(tst_c90 PROPERTIES 5 | LINKER_LANGUAGE C 6 | C_STANDARD 90 7 | C_STANDARD_REQUIRED ON 8 | ) 9 | -------------------------------------------------------------------------------- /src/tinycbor-version.h.in: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2025 Intel Corporation 2 | * SPDX-License-Identifier: MIT 3 | */ 4 | /* This is a generated file */ 5 | #define TINYCBOR_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ 6 | #define TINYCBOR_VERSION_MINOR @PROJECT_VERSION_MINOR@ 7 | #define TINYCBOR_VERSION_PATCH 0 8 | -------------------------------------------------------------------------------- /tinycbor.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: TinyCBOR 7 | Description: A tiny CBOR encoder and decoder library 8 | Version: @version@ 9 | Libs: -L${libdir} -ltinycbor 10 | Libs.private: -lm 11 | Cflags: -I${includedir}/tinycbor 12 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Concise Binary Object Representation (CBOR) Library 2 | --------------------------------------------------- 3 | 4 | To build TinyCBOR: 5 | 6 | make 7 | 8 | If you want to change the compiler or pass extra compiler flags: 9 | 10 | make CC=clang CFLAGS="-m32 -Oz" LDFLAGS="-m32" 11 | 12 | Documentation: https://intel.github.io/tinycbor/current/ 13 | 14 | -------------------------------------------------------------------------------- /tools/json2cbor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | include(FindPkgConfig) 4 | pkg_check_modules(LIBCJSON libcjson) 5 | if(LIBCJSON_FOUND) 6 | tinycbor_add_executable(json2cbor json2cbor.c) 7 | target_include_directories(json2cbor SYSTEM PUBLIC ${LIBCJSON_INCLUDE_DIRS}) 8 | target_link_libraries(json2cbor ${LIBCJSON_LIBRARIES}) 9 | endif() 10 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 3 | 4 | ## Reporting a Vulnerability 5 | Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). 6 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | include(TinyCBORHelpers) 4 | add_subdirectory(c90) 5 | 6 | if(WITH_FREESTANDING OR NOT WITH_FLOATING_POINT) 7 | return() 8 | endif() 9 | 10 | find_package(Qt6 COMPONENTS Core Test) 11 | if(Qt6_FOUND) 12 | set(CMAKE_CXX_STANDARD 20) 13 | set(CMAKE_AUTOMOC ON) 14 | add_subdirectory(cpp) 15 | add_subdirectory(encoder) 16 | add_subdirectory(parser) 17 | if(WITH_CBOR2JSON) 18 | add_subdirectory(tojson) 19 | endif() 20 | endif() 21 | -------------------------------------------------------------------------------- /cmake/project-config.cmake.in: -------------------------------------------------------------------------------- 1 | # Config file for @PROJECT_NAME_LOWER@ 2 | # 3 | # It defines the following variables: 4 | # 5 | # @PROJECT_NAME_UPPER@_INCLUDE_DIRS - include directory 6 | # @PROJECT_NAME_UPPER@_LIBRARIES - all dynamic libraries 7 | # @PROJECT_NAME_UPPER@_STATIC_LIBRARIES - all static libraries 8 | 9 | @PACKAGE_INIT@ 10 | 11 | include(CMakeFindDependencyMacro) 12 | 13 | # Add optional dependencies here 14 | 15 | include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake") 16 | check_required_components("@PROJECT_NAME@") 17 | -------------------------------------------------------------------------------- /src/src.pri: -------------------------------------------------------------------------------- 1 | SOURCES += \ 2 | $$PWD/cborencoder.c \ 3 | $$PWD/cborencoder_close_container_checked.c \ 4 | $$PWD/cborencoder_float.c \ 5 | $$PWD/cborerrorstrings.c \ 6 | $$PWD/cborparser.c \ 7 | $$PWD/cborparser_dup_string.c \ 8 | $$PWD/cborparser_float.c \ 9 | $$PWD/cborpretty.c \ 10 | $$PWD/cborpretty_stdio.c \ 11 | $$PWD/cbortojson.c \ 12 | $$PWD/cborvalidation.c \ 13 | 14 | HEADERS += \ 15 | $$PWD/cbor.h \ 16 | $$PWD/cborinternal_p.h \ 17 | $$PWD/cborjson.h \ 18 | $$PWD/compilersupport_p.h \ 19 | $$PWD/tinycbor-version.h \ 20 | $$PWD/utf8_p.h \ 21 | 22 | 23 | QMAKE_CFLAGS *= $$QMAKE_CFLAGS_SPLIT_SECTIONS 24 | QMAKE_LFLAGS *= $$QMAKE_LFLAGS_GCSECTIONS 25 | INCLUDEPATH += $$PWD 26 | CONFIG(release, debug|release): DEFINES += NDEBUG 27 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | ==== To Do list for libcbor ==== 2 | === General === 3 | * API review 4 | * Benchmark 5 | * Write examples 6 | ** Simple decoder 7 | ** Decoder to JSON 8 | ** Windowed encoding/decoding (limited memory) 9 | 10 | === Encoder === 11 | * Write API docs 12 | * Add API for creating indeterminate-length arrays and maps 13 | * Add API for creating indeterminate-length strings 14 | * Add API for relaxing doubles to floats and to integers 15 | * Add length-checking of the sub-containers (#ifndef CBOR_ENCODER_NO_USER_CHECK) 16 | * Decide how to indicate number of bytes needed 17 | ** Suggestion: return negative number from the functions 18 | 19 | === Decoder === 20 | * Write functions not yet implemented 21 | * Add API for stream-decoding strings 22 | * Add API for checking known tags and simple types 23 | * (unlikely) Add API for checking the pairing of a tag and the tagged type 24 | * Write tests for error conditions 25 | * Fuzzy-test the decoder 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Intel Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: build-{build} 2 | pull_requests: 3 | do_not_increment_build_number: true 4 | image: 5 | - Visual Studio 2019 6 | - Visual Studio 2022 7 | install: 8 | - cmd: >- 9 | 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.5\msvc2019_64) 10 | 11 | if /i "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2022" (call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat") & (set QTDIR=C:\Qt\6.8\msvc2022_64) 12 | 13 | set path=%PATH%;%QTDIR%\bin 14 | build_script: 15 | - cmd: >- 16 | cmake -S. -Bbuild -GNinja -DWITH_CBOR2JSON=OFF -DBUILD_TESTING=ON -DCMAKE_C_FLAGS="-W3 -Os -MDd" -DCMAKE_CXX_FLAGS="-W3 -O2 -MDd" 17 | 18 | ninja -C build 19 | 20 | test_script: 21 | - cmd: >- 22 | ctest --test-dir build --output-on-failure --output-junit ctest.junitxml 23 | 24 | after_test: 25 | - cmd: >- 26 | curl -F file=@build/ctest.junitxml https://ci.appveyor.com/api/testresults/junit/%APPVEYOR_JOB_ID% 27 | 28 | artifacts: 29 | #- path: build\tinycbor.lib 30 | deploy: off 31 | -------------------------------------------------------------------------------- /cmake/PackageConfig.cmake: -------------------------------------------------------------------------------- 1 | # This cmake code creates the configuration that is found and used by 2 | # find_package() of another cmake project 3 | 4 | # get lower and upper case project name for the configuration files 5 | 6 | # configure and install the configuration files 7 | include(CMakePackageConfigHelpers) 8 | 9 | configure_package_config_file( 10 | "${PROJECT_SOURCE_DIR}/cmake/project-config.cmake.in" 11 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" 12 | INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 13 | #PATH_VARS CMAKE_INSTALL_DIR 14 | ) 15 | 16 | write_basic_package_version_file( 17 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" 18 | VERSION ${PROJECT_VERSION} 19 | COMPATIBILITY SameMinorVersion 20 | ) 21 | 22 | install(FILES 23 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" 24 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" 25 | COMPONENT devel 26 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 27 | ) 28 | 29 | if (PROJECT_LIBRARIES OR PROJECT_STATIC_LIBRARIES) 30 | install( 31 | EXPORT "${TARGETS_EXPORT_NAME}" 32 | FILE ${TARGETS_EXPORT_NAME}.cmake 33 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 34 | ) 35 | endif () 36 | -------------------------------------------------------------------------------- /src/tags.txt: -------------------------------------------------------------------------------- 1 | # Tag number; Tag ID; Applicable types (comma-separated); Semantics 2 | 0;DateTimeString;TextString;Standard date/time string 3 | 1;UnixTime_t;Integer;Epoch-based date/time 4 | 2;PositiveBignum;ByteString;Positive bignum 5 | 3;NegativeBignum;ByteString;Negative bignum 6 | 4;Decimal;Array;Decimal fraction 7 | 5;Bigfloat;Array;Bigfloat 8 | 16;COSE_Encrypt0;Array;COSE Single Recipient Encrypted Data Object (RFC 8152) 9 | 17;COSE_Mac0;Array;COSE Mac w/o Recipients Object (RFC 8152) 10 | 18;COSE_Sign1;Array;COSE Single Signer Data Object (RFC 8162) 11 | 21;ExpectedBase64url;ByteString,Array,Map;Expected conversion to base64url encoding 12 | 22;ExpectedBase64;ByteString,Array,Map;Expected conversion to base64 encoding 13 | 23;ExpectedBase16;ByteString,Array,Map;Expected conversion to base16 encoding 14 | 24;EncodedCbor;ByteString;Encoded CBOR data item 15 | 32;Url;TextString;URI 16 | 33;Base64url;TextString;base64url 17 | 34;Base64;TextString;base64 18 | 35;RegularExpression;TextString;Regular expression 19 | 36;MimeMessage;TextString;MIME message 20 | 96;COSE_Encrypt;Array;COSE Encrypted Data Object (RFC 8152) 21 | 97;COSE_Mac;Array;COSE MACed Data Object (RFC 8152) 22 | 98;COSE_Sign;Array;COSE Signed Data Object (RFC 8152) 23 | 55799;Signature;;Self-describe CBOR 24 | -------------------------------------------------------------------------------- /cmake/TinyCBORHelpers.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Intel Corporation 2 | # SPDX-License-Identifier: MIT 3 | function(tinycbor_add_executable target) 4 | add_executable(${target} ${ARGN}) 5 | target_link_libraries(${target} tinycbor) 6 | target_compile_options(${target} PRIVATE 7 | $<$:-W3> 8 | $<$>:-Wall -Wextra> 9 | ) 10 | endfunction() 11 | 12 | function(tinycbor_add_test target) 13 | tinycbor_add_executable(${target} ${ARGN}) 14 | set(memcheck_command ${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS}) 15 | separate_arguments(memcheck_command) 16 | add_test(NAME ${target} COMMAND ${memcheck_command} $) 17 | endfunction() 18 | 19 | function(tinycbor_add_qtest target) 20 | tinycbor_add_test(${target} ${ARGN}) 21 | target_link_libraries(${target} Qt::Core Qt::Test) 22 | endfunction() 23 | 24 | option(WITH_VALGRIND "Use Valgrind (if found) to run tests" ON) 25 | if(WITH_VALGRIND AND NOT DEFINED CMAKE_MEMORYCHECK_COMMAND) 26 | find_program(VALGRIND "valgrind") 27 | if(VALGRIND) 28 | set(CMAKE_MEMORYCHECK_COMMAND ${VALGRIND} --tool=memcheck) 29 | set(CMAKE_MEMORYCHECK_COMMAND_OPTIONS} 30 | --error-exitcode=255 31 | --errors-for-leak-kinds=definite 32 | --leak-check=yes 33 | --num-callers=20 34 | ) 35 | endif() 36 | else() 37 | set(VALGRIND OFF) 38 | endif() 39 | -------------------------------------------------------------------------------- /tests/c90/tst_c90.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2018 Intel Corporation 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #include "cbor.h" 26 | 27 | int main() 28 | { 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Makefile.configure: -------------------------------------------------------------------------------- 1 | ALLTESTS = open_memstream funopen fopencookie gc_sections \ 2 | system-cjson cjson freestanding 3 | MAKEFILE := $(lastword $(MAKEFILE_LIST)) 4 | OUT := 5 | 6 | PROGRAM-open_memstream = extern int open_memstream(); int main() { return open_memstream(); } 7 | PROGRAM-funopen = extern int funopen(); int main() { return funopen(); } 8 | PROGRAM-fopencookie = extern int fopencookie(); int main() { return fopencookie(); } 9 | PROGRAM-gc_sections = int main() {} 10 | CCFLAGS-gc_sections = -Wl,--gc-sections 11 | PROGRAM-freestanding = \#if !defined(__STDC_HOSTED__) || __STDC_HOSTED__-0 == 1\n 12 | PROGRAM-freestanding += \#error Hosted implementation\n 13 | PROGRAM-freestanding += \#endif\n 14 | PROGRAM-freestanding += int main() {} 15 | CCFLAGS-freestanding = $(CFLAGS) 16 | 17 | PROGRAM-cjson = \#include \n 18 | PROGRAM-cjson += \#include \n 19 | PROGRAM-cjson += \#include \n 20 | PROGRAM-cjson += int main() { double d = NAN; return cJSON_False; } 21 | CCFLAGS-cjson = -I. -I$(dir $(MAKEFILE))src 22 | PROGRAM-system-cjson = $(PROGRAM-cjson) 23 | CCFLAGS-system-cjson = -I. -lcjson 24 | 25 | sink: 26 | @echo >&2 Please run from the top-level Makefile. 27 | 28 | configure: $(foreach it,$(ALLTESTS),check-$(it)) 29 | 30 | check-%: 31 | @echo $(subst check-,,$@)-tested := 1 >>$(OUT) 32 | $(if $(V),,@)if printf "$($(subst check-,PROGRAM-,$@))" | \ 33 | $(CC) -xc $($(subst check-,CCFLAGS-,$@)) -o /dev/null - $(if $(V),,>/dev/null 2>&1); \ 34 | then \ 35 | echo $(subst check-,,$@)-pass := 1 >>$(OUT); \ 36 | fi 37 | -------------------------------------------------------------------------------- /Makefile.nmake: -------------------------------------------------------------------------------- 1 | CFLAGS = -W3 2 | 3 | TINYCBOR_HEADERS = src\cbor.h src\cborjson.h src\tinycbor-export.h 4 | TINYCBOR_SOURCES = \ 5 | src\cborerrorstrings.c \ 6 | src\cborencoder.c \ 7 | src\cborencoder_close_container_checked.c \ 8 | src\cborencoder_float.c \ 9 | src\cborparser.c \ 10 | src\cborparser_dup_string.c \ 11 | src\cborparser_float.c \ 12 | src\cborpretty.c \ 13 | src\cborpretty_stdio.c \ 14 | src\cborvalidation.c 15 | TINYCBOR_OBJS = \ 16 | src\cborerrorstrings.obj \ 17 | src\cborencoder.obj \ 18 | src\cborencoder_close_container_checked.obj \ 19 | src\cborencoder_float.obj \ 20 | src\cborparser.obj \ 21 | src\cborparser_dup_string.obj \ 22 | src\cborparser_float.obj \ 23 | src\cborpretty.obj \ 24 | src\cborpretty_stdio.obj \ 25 | src\cborvalidation.obj 26 | 27 | all: src/tinycbor-export.h lib\tinycbor.lib 28 | check: tests\Makefile lib\tinycbor.lib 29 | cd tests & $(MAKE) check 30 | silentcheck: 31 | cd tests & set TESTARGS=-silent & $(MAKE) -s check 32 | tests\Makefile: tests\tests.pro 33 | qmake -o $@ $** 34 | 35 | src\tinycbor-export.h: src\tinycbor-export.h.in 36 | copy $** $@ 37 | 38 | lib\tinycbor.lib: $(TINYCBOR_OBJS) 39 | -if not exist lib\NUL md lib 40 | lib -nologo /out:$@ $** 41 | 42 | mostlyclean: 43 | -del $(TINYCBOR_OBJS) 44 | -del src\tinycbor-export.h 45 | clean: mostlyclean 46 | -del lib\tinycbor.lib 47 | if exist tests\Makefile (cd tests & $(MAKE) clean) 48 | distclean: clean 49 | if exist tests\Makefile (cd tests & $(MAKE) distclean) 50 | tag: 51 | @perl maketag.pl 52 | 53 | {src\}.c{src\}.obj: 54 | $(CC) -nologo $(CFLAGS) -Isrc -c -Fo$@ $< 55 | 56 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 Intel Corporation 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #if defined(CBOR_CUSTOM_ALLOC_INCLUDE) 26 | # include CBOR_CUSTOM_ALLOC_INCLUDE 27 | #else 28 | # include 29 | # define cbor_malloc malloc 30 | # define cbor_realloc realloc 31 | # define cbor_free free 32 | #endif 33 | -------------------------------------------------------------------------------- /scripts/update-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | tuple="$TRAVIS_BRANCH${TRAVIS_TAG:+tag:$TRAVIS_TAG},$TRAVIS_PULL_REQUEST" 3 | case "$tuple" in 4 | dev,false|main,false|tag:*) 5 | ;; 6 | *) 7 | exit 0 8 | ;; 9 | esac 10 | V=`cut -f1-2 -d. /dev/null; then 18 | git checkout -b gh-pages FETCH_HEAD 19 | if [ -d "$V" ]; then 20 | mv "$V" "old-$V" 21 | fi 22 | mv doc/html "$V" 23 | git add -A "$V" 24 | else 25 | git checkout -b gh-pages FETCH_HEAD 26 | mkdir -p "$V" 27 | fi 28 | 29 | # Update the symlink for the branch name 30 | rm -f "./$TRAVIS_BRANCH" 31 | ln -s "$V" "$TRAVIS_BRANCH" 32 | git add "./$TRAVIS_BRANCH" 33 | 34 | # Update the library sizes file 35 | # (will fail if the release build failed) 36 | mkdir -p "library_sizes/$TRAVIS_BRANCH" 37 | mv sizes "library_sizes/$TRAVIS_BRANCH/$QMAKESPEC" 38 | (cd "library_sizes/$TRAVIS_BRANCH/"; 39 | for f in *; do echo "$f:"; cat "$f" ; done) > "$V/library_sizes.txt" 40 | git add "library_sizes/$TRAVIS_BRANCH" "$V/library_sizes.txt" 41 | git diff --cached -U0 "$V/library_sizes.txt" 42 | 43 | # Commit everything 44 | if git commit -m "Update docs for $V (Travis build $TRAVIS_BUILD_NUMBER) 45 | 46 | Matching commit $TRAVIS_COMMIT: 47 | $TRAVIS_COMMIT_MESSAGE"; then 48 | # We've made a commit, push it 49 | set +x 50 | url=`git config --get remote.origin.url | sed -e s,://github,://$GITHUB_AUTH@github,` 51 | git push "$url" @:gh-pages 52 | fi 53 | -------------------------------------------------------------------------------- /src/cborinternalmacros_p.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2025 Intel Corporation 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #ifndef _BSD_SOURCE 26 | # define _BSD_SOURCE 1 27 | #endif 28 | #ifndef _DEFAULT_SOURCE 29 | # define _DEFAULT_SOURCE 1 30 | #endif 31 | #ifndef __STDC_LIMIT_MACROS 32 | # define __STDC_LIMIT_MACROS 1 33 | #endif 34 | #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ 35 | # define __STDC_WANT_IEC_60559_TYPES_EXT__ 36 | #endif 37 | -------------------------------------------------------------------------------- /Doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = "TinyCBOR $(VERSION) API" 2 | OUTPUT_DIRECTORY = ../doc 3 | ABBREVIATE_BRIEF = 4 | SHORT_NAMES = YES 5 | JAVADOC_AUTOBRIEF = YES 6 | QT_AUTOBRIEF = YES 7 | TAB_SIZE = 8 8 | ALIASES = "value=\arg \c" 9 | OPTIMIZE_OUTPUT_FOR_C = YES 10 | EXTRACT_STATIC = YES 11 | EXTRACT_LOCAL_CLASSES = NO 12 | HIDE_UNDOC_MEMBERS = YES 13 | HIDE_UNDOC_CLASSES = YES 14 | GENERATE_TODOLIST = NO 15 | GENERATE_TESTLIST = NO 16 | GENERATE_BUGLIST = NO 17 | GENERATE_DEPRECATEDLIST= NO 18 | SHOW_USED_FILES = NO 19 | WARN_IF_UNDOCUMENTED = NO 20 | WARN_LOGFILE = doxygen.log 21 | INPUT = . 22 | FILE_PATTERNS = *.h \ 23 | *.c \ 24 | *.dox 25 | EXCLUDE_PATTERNS = *_p.h 26 | STRIP_CODE_COMMENTS = NO 27 | REFERENCED_BY_RELATION = YES 28 | IGNORE_PREFIX = cbor_ \ 29 | Cbor 30 | HTML_TIMESTAMP = NO 31 | GENERATE_HTMLHELP = YES 32 | GENERATE_CHI = YES 33 | BINARY_TOC = YES 34 | TOC_EXPAND = YES 35 | MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest 36 | SEARCHENGINE = NO 37 | GENERATE_LATEX = NO 38 | COMPACT_LATEX = YES 39 | MACRO_EXPANSION = YES 40 | PREDEFINED = DOXYGEN \ 41 | CBOR_INLINE_API= 42 | CLASS_DIAGRAMS = NO 43 | CLASS_GRAPH = NO 44 | COLLABORATION_GRAPH = NO 45 | GROUP_GRAPHS = NO 46 | INCLUDE_GRAPH = NO 47 | INCLUDED_BY_GRAPH = NO 48 | GRAPHICAL_HIERARCHY = NO 49 | DIRECTORY_GRAPH = NO 50 | -------------------------------------------------------------------------------- /src/cborencoder_float.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2019 S.Phirsov 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #include "cborinternalmacros_p.h" 26 | 27 | #include "cbor.h" 28 | 29 | #include "cborinternal_p.h" 30 | 31 | #ifndef CBOR_NO_HALF_FLOAT_TYPE 32 | CborError cbor_encode_float_as_half_float(CborEncoder *encoder, float value) 33 | { 34 | uint16_t v = (uint16_t)encode_half(value); 35 | 36 | return cbor_encode_floating_point(encoder, CborHalfFloatType, &v); 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /tests/cpp/tst_cpp.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Intel Corporation 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #include "../../src/cborencoder.c" 26 | #include "../../src/cborencoder_float.c" 27 | #include "../../src/cborerrorstrings.c" 28 | #include "../../src/cborparser.c" 29 | #include "../../src/cborparser_dup_string.c" 30 | #include "../../src/cborparser_float.c" 31 | #include "../../src/cborvalidation.c" 32 | 33 | #include 34 | 35 | // This is a compilation-only test. 36 | // All it does is verify that the four source files above 37 | // compile as C++ without errors. 38 | class tst_Cpp : public QObject 39 | { 40 | Q_OBJECT 41 | }; 42 | 43 | QTEST_MAIN(tst_Cpp) 44 | #include "tst_cpp.moc" 45 | -------------------------------------------------------------------------------- /src/cborjson.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 Intel Corporation 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #ifndef CBORJSON_H 26 | #define CBORJSON_H 27 | 28 | #include "cbor.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* Conversion to JSON */ 35 | enum CborToJsonFlags 36 | { 37 | CborConvertAddMetadata = 1, 38 | CborConvertTagsToObjects = 2, 39 | CborConvertIgnoreTags = 0, 40 | 41 | CborConvertObeyByteStringTags = 0, 42 | CborConvertByteStringsToBase64Url = 4, 43 | 44 | CborConvertRequireMapStringKeys = 0, 45 | CborConvertStringifyMapKeys = 8, 46 | 47 | CborConvertDefaultFlags = 0 48 | }; 49 | 50 | CBOR_API CborError cbor_value_to_json_advance(FILE *out, CborValue *value, int flags); 51 | CBOR_INLINE_API CborError cbor_value_to_json(FILE *out, const CborValue *value, int flags) 52 | { 53 | CborValue copy = *value; 54 | return cbor_value_to_json_advance(out, ©, flags); 55 | } 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* CBORJSON_H */ 62 | 63 | -------------------------------------------------------------------------------- /src/cborencoder_close_container_checked.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 Intel Corporation 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #include "cborinternalmacros_p.h" 26 | 27 | #include "cbor.h" 28 | 29 | /** 30 | * \addtogroup CborEncoding 31 | * @{ 32 | */ 33 | 34 | /** 35 | * @deprecated 36 | * 37 | * Closes the CBOR container (array or map) provided by \a containerEncoder and 38 | * updates the CBOR stream provided by \a encoder. Both parameters must be the 39 | * same as were passed to cbor_encoder_create_array() or 40 | * cbor_encoder_create_map(). 41 | * 42 | * Prior to version 0.5, cbor_encoder_close_container() did not check the 43 | * number of items added. Since that version, it does and now 44 | * cbor_encoder_close_container_checked() is no longer needed. 45 | * 46 | * \sa cbor_encoder_create_array(), cbor_encoder_create_map() 47 | */ 48 | CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder) 49 | { 50 | return cbor_encoder_close_container(encoder, containerEncoder); 51 | } 52 | 53 | /** @} */ 54 | -------------------------------------------------------------------------------- /src/cborparser_float.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2019 S.Phirsov 4 | ** 5 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 6 | ** of this software and associated documentation files (the "Software"), to deal 7 | ** in the Software without restriction, including without limitation the rights 8 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | ** copies of the Software, and to permit persons to whom the Software is 10 | ** furnished to do so, subject to the following conditions: 11 | ** 12 | ** The above copyright notice and this permission notice shall be included in 13 | ** all copies or substantial portions of the Software. 14 | ** 15 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | ** THE SOFTWARE. 22 | ** 23 | ****************************************************************************/ 24 | 25 | #include "cborinternalmacros_p.h" 26 | 27 | #include "cbor.h" 28 | 29 | #include "cborinternal_p.h" 30 | 31 | #ifndef CBOR_NO_HALF_FLOAT_TYPE 32 | /** 33 | * Retrieves the CBOR half-precision floating point (16-bit) value that \a 34 | * value points to, converts it to the float and store it in \a result. 35 | * If the iterator \a value does not point to a half-precision floating 36 | * point value, the behavior is undefined, so checking with \ref 37 | * cbor_value_get_type or with \ref cbor_value_is_half_float is recommended. 38 | * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_half_float(), cbor_value_get_float() 39 | */ 40 | CborError cbor_value_get_half_float_as_float(const CborValue *value, float *result) 41 | { 42 | uint16_t v; 43 | CborError err = cbor_value_get_half_float(value, &v); 44 | cbor_assert(err == CborNoError); 45 | 46 | *result = (float)decode_half((unsigned short)v); 47 | 48 | return CborNoError; 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /scripts/maketag.pl: -------------------------------------------------------------------------------- 1 | #!perl 2 | use strict; 3 | sub run(@) { 4 | open PROC, "-|", @_ or die("Cannot run $_[0]: $!"); 5 | my @out; 6 | while () { 7 | chomp; 8 | push @out, $_; 9 | } 10 | close PROC; 11 | return @out; 12 | } 13 | 14 | my @tags = run("git", "tag"); 15 | my @v = run("git", "show", "HEAD:VERSION"); 16 | my $v = $v[0]; 17 | 18 | my $tagfile = ".git/TAG_EDITMSG"; 19 | open TAGFILE, ">", $tagfile 20 | or die("Cannot create file for editing tag message: $!"); 21 | select TAGFILE; 22 | print "TinyCBOR release $v\n"; 23 | print "\n"; 24 | print "# Write something nice about this release here\n"; 25 | 26 | # Do we have a commit template? 27 | my @result = run("git", "config", "--get", "commit.template"); 28 | if (scalar @result) { 29 | open TEMPLATE, "<", $result[0]; 30 | map { print $_; }