From 886b36045ac77245279ce39e3566488428ef12ff Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Wed, 7 Aug 2019 12:42:34 +0200 Subject: [PATCH 1/6] Squashed 'libs/tinycbor/' content from commit d2dd95c git-subtree-dir: libs/tinycbor git-subtree-split: d2dd95cb8841d88d5a801e3ef9c328fd6200e7bd --- .appveyor.yml | 35 + .gitattributes | 4 + .gitignore | 81 + .tag | 1 + .travis.yml | 84 + Doxyfile | 49 + LICENSE | 21 + Makefile | 240 +++ Makefile.configure | 35 + Makefile.nmake | 47 + README | 13 + TODO | 25 + VERSION | 1 + examples/examples.pro | 2 + examples/simplereader.c | 181 ++ examples/simplereader.pro | 3 + scripts/maketag.pl | 91 + scripts/update-docs.sh | 52 + src/cbor.dox | 123 ++ src/cbor.h | 606 ++++++ src/cborencoder.c | 645 ++++++ src/cborencoder_close_container_checked.c | 57 + src/cborerrorstrings.c | 182 ++ src/cborinternal_p.h | 161 ++ src/cborjson.h | 62 + src/cborparser.c | 1430 ++++++++++++++ src/cborparser_dup_string.c | 119 ++ src/cborpretty.c | 580 ++++++ src/cborpretty_stdio.c | 87 + src/cbortojson.c | 699 +++++++ src/cborvalidation.c | 670 +++++++ src/compilersupport_p.h | 205 ++ src/open_memstream.c | 114 ++ src/parsetags.pl | 116 ++ src/src.pri | 16 + src/tags.txt | 23 + src/tinycbor-version.h | 3 + src/tinycbor.pro | 6 + src/utf8_p.h | 104 + tests/.gitignore | 15 + tests/c90/c90.pro | 7 + tests/c90/tst_c90.c | 30 + tests/cpp/cpp.pro | 5 + tests/cpp/tst_cpp.cpp | 42 + tests/encoder/encoder.pro | 9 + tests/encoder/tst_encoder.cpp | 734 +++++++ tests/parser/parser.pro | 10 + tests/parser/tst_parser.cpp | 2182 +++++++++++++++++++++ tests/tests.pro | 3 + tests/tojson/tojson.pro | 8 + tests/tojson/tst_tojson.cpp | 721 +++++++ tinycbor.pc.in | 11 + tools/Makefile | 12 + tools/cbordump/cbordump.c | 164 ++ tools/cbordump/cbordump.pro | 10 + tools/json2cbor/json2cbor.c | 493 +++++ tools/json2cbor/json2cbor.pro | 20 + 57 files changed, 11449 insertions(+) create mode 100644 .appveyor.yml create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .tag create mode 100644 .travis.yml create mode 100644 Doxyfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 Makefile.configure create mode 100644 Makefile.nmake create mode 100644 README create mode 100644 TODO create mode 100644 VERSION create mode 100644 examples/examples.pro create mode 100644 examples/simplereader.c create mode 100644 examples/simplereader.pro create mode 100644 scripts/maketag.pl create mode 100755 scripts/update-docs.sh create mode 100644 src/cbor.dox create mode 100644 src/cbor.h create mode 100644 src/cborencoder.c create mode 100644 src/cborencoder_close_container_checked.c create mode 100644 src/cborerrorstrings.c create mode 100644 src/cborinternal_p.h create mode 100644 src/cborjson.h create mode 100644 src/cborparser.c create mode 100644 src/cborparser_dup_string.c create mode 100644 src/cborpretty.c create mode 100644 src/cborpretty_stdio.c create mode 100644 src/cbortojson.c create mode 100644 src/cborvalidation.c create mode 100644 src/compilersupport_p.h create mode 100644 src/open_memstream.c create mode 100755 src/parsetags.pl create mode 100644 src/src.pri create mode 100644 src/tags.txt create mode 100644 src/tinycbor-version.h create mode 100644 src/tinycbor.pro create mode 100644 src/utf8_p.h create mode 100644 tests/.gitignore create mode 100644 tests/c90/c90.pro create mode 100644 tests/c90/tst_c90.c create mode 100644 tests/cpp/cpp.pro create mode 100644 tests/cpp/tst_cpp.cpp create mode 100644 tests/encoder/encoder.pro create mode 100644 tests/encoder/tst_encoder.cpp create mode 100644 tests/parser/parser.pro create mode 100644 tests/parser/tst_parser.cpp create mode 100644 tests/tests.pro create mode 100644 tests/tojson/tojson.pro create mode 100644 tests/tojson/tst_tojson.cpp create mode 100644 tinycbor.pc.in create mode 100644 tools/Makefile create mode 100644 tools/cbordump/cbordump.c create mode 100644 tools/cbordump/cbordump.pro create mode 100644 tools/json2cbor/json2cbor.c create mode 100644 tools/json2cbor/json2cbor.pro diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..b3abca27 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,35 @@ +version: 0.5.3-build-{build} +pull_requests: + do_not_increment_build_number: true +image: +- Visual Studio 2015 +- Visual Studio 2013 +- Visual Studio 2017 +install: +- cmd: >- + set tests=1 + + if /i "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" (call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64) & (set tests=0) + + if /i "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" (call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86) & (set QTDIR=C:\Qt\5.9\msvc2015) + + if /i "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64) & (set QTDIR=C:\Qt\5.9\msvc2017_64) + + set path=%PATH%;%QTDIR%\bin +build_script: +- cmd: >- + nmake -f Makefile.nmake -nologo CFLAGS="-W3 -Os -MDd" + + cd tests + + if /i "%tests%"=="1" qmake CONFIG-=release CONFIG+=debug + + if /i "%tests%"=="1" nmake -nologo -s +test_script: +- cmd: >- + if /i "%tests%"=="1" nmake -s -nologo TESTARGS=-silent check + + if /i "%tests%"=="0" echo Tests skipped. +artifacts: +- path: lib\tinycbor.lib +deploy: off diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..76ed2567 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +.tag export-subst +.gitignore export-ignore +.gitattributes export-ignore +.appveyor.yml text diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3272de33 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/.tag b/.tag new file mode 100644 index 00000000..6828f88d --- /dev/null +++ b/.tag @@ -0,0 +1 @@ +$Format:%H$ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..7ca287dd --- /dev/null +++ b/.travis.yml @@ -0,0 +1,84 @@ +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" + 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 + - ./scripts/update-docs.sh diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 00000000..a7263c2f --- /dev/null +++ b/Doxyfile @@ -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 diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..4aad977c --- /dev/null +++ b/LICENSE @@ -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. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..239dde8b --- /dev/null +++ b/Makefile @@ -0,0 +1,240 @@ +# 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/cborparser.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 +INSTALL_TARGETS += $(libdir)/libtinycbor.so.$(SOVERSION) +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)%) +uninstall: + $(RM) $(INSTALL_TARGETS:%=$(DESTDIR)%) + +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) +%.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 diff --git a/Makefile.configure b/Makefile.configure new file mode 100644 index 00000000..c2f51eea --- /dev/null +++ b/Makefile.configure @@ -0,0 +1,35 @@ +ALLTESTS = open_memstream funopen fopencookie gc_sections \ + system-cjson cjson freestanding +MAKEFILE := $(lastword $(MAKEFILE_LIST)) +OUT := + +PROGRAM-open_memstream = extern int open_memstream(); int main() { return open_memstream(); } +PROGRAM-funopen = extern int funopen(); int main() { return funopen(); } +PROGRAM-fopencookie = extern int fopencookie(); int main() { return fopencookie(); } +PROGRAM-gc_sections = int main() {} +CCFLAGS-gc_sections = -Wl,--gc-sections +PROGRAM-freestanding = \#if !defined(__STDC_HOSTED__) || __STDC_HOSTED__-0 == 1\n +PROGRAM-freestanding += \#error Hosted implementation\n +PROGRAM-freestanding += \#endif\n +PROGRAM-freestanding += int main() {} +CCFLAGS-freestanding = $(CFLAGS) + +PROGRAM-cjson = \#include \n +PROGRAM-cjson += \#include \n +PROGRAM-cjson += int main() { return cJSON_False; } +CCFLAGS-cjson = -I$(dir $(MAKEFILE))src +PROGRAM-system-cjson = $(PROGRAM-cjson) +CCFLAGS-system-cjson = -lcjson + +sink: + @echo >&2 Please run from the top-level Makefile. + +configure: $(foreach it,$(ALLTESTS),check-$(it)) + +check-%: + @echo $(subst check-,,$@)-tested := 1 $(OUT) + $(if $(V),,@)if printf "$($(subst check-,PROGRAM-,$@))" | \ + $(CC) -xc $($(subst check-,CCFLAGS-,$@)) -o /dev/null - $(if $(V),,>/dev/null 2>&1); \ + then \ + echo $(subst check-,,$@)-pass := 1 $(OUT); \ + fi diff --git a/Makefile.nmake b/Makefile.nmake new file mode 100644 index 00000000..04b58ab4 --- /dev/null +++ b/Makefile.nmake @@ -0,0 +1,47 @@ +CFLAGS = -W3 + +TINYCBOR_HEADERS = src\cbor.h src\cborjson.h +TINYCBOR_SOURCES = \ + src\cborerrorstrings.c \ + src\cborencoder.c \ + src\cborencoder_close_container_checked.c \ + src\cborparser.c \ + src\cborparser_dup_string.c \ + src\cborpretty.c \ + src\cborpretty_stdio.c \ + src\cborvalidation.c +TINYCBOR_OBJS = \ + src\cborerrorstrings.obj \ + src\cborencoder.obj \ + src\cborencoder_close_container_checked.obj \ + src\cborparser.obj \ + src\cborparser_dup_string.obj \ + src\cborpretty.obj \ + src\cborpretty_stdio.obj \ + src\cborvalidation.obj + +all: lib\tinycbor.lib +check: tests\Makefile lib\tinycbor.lib + cd tests & $(MAKE) check +silentcheck: + cd tests & set TESTARGS=-silent & $(MAKE) -s check +tests\Makefile: tests\tests.pro + qmake -o $@ $** + +lib\tinycbor.lib: $(TINYCBOR_OBJS) + -if not exist lib\NUL md lib + lib -nologo /out:$@ $** + +mostlyclean: + -del $(TINYCBOR_OBJS) +clean: mostlyclean + -del lib\tinycbor.lib + if exist tests\Makefile (cd tests & $(MAKE) clean) +distclean: clean + if exist tests\Makefile (cd tests & $(MAKE) distclean) +tag: + @perl maketag.pl + +{src\}.c{src\}.obj: + $(CC) -nologo $(CFLAGS) -Isrc -c -Fo$@ $< + diff --git a/README b/README new file mode 100644 index 00000000..167efa06 --- /dev/null +++ b/README @@ -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/ + diff --git a/TODO b/TODO new file mode 100644 index 00000000..e9103ee6 --- /dev/null +++ b/TODO @@ -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 diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..be14282b --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.5.3 diff --git a/examples/examples.pro b/examples/examples.pro new file mode 100644 index 00000000..22071ac3 --- /dev/null +++ b/examples/examples.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = simplereader.pro diff --git a/examples/simplereader.c b/examples/simplereader.c new file mode 100644 index 00000000..4752c08d --- /dev/null +++ b/examples/simplereader.c @@ -0,0 +1,181 @@ +#include "../src/cbor.h" + +#include +#include +#include +#include +#include + +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); + *size = fread(buf, st.st_size, 1, f) == 1 ? st.st_size : 0; + fclose(f); + return buf; +} + +static void indent(int nestingLevel) +{ + while (nestingLevel--) + puts(" "); +} + +static void dumpbytes(const uint8_t *buf, size_t len) +{ + while (len--) + printf("%02X ", *buf++); +} + +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 + puts(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 == 1) { + puts("simplereader "); + return 0; + } + + 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; +} diff --git a/examples/simplereader.pro b/examples/simplereader.pro new file mode 100644 index 00000000..07fdc6ac --- /dev/null +++ b/examples/simplereader.pro @@ -0,0 +1,3 @@ +CONFIG -= qt +SOURCES = simplereader.c +include(../src/src.pri) diff --git a/scripts/maketag.pl b/scripts/maketag.pl new file mode 100644 index 00000000..5b1a8b79 --- /dev/null +++ b/scripts/maketag.pl @@ -0,0 +1,91 @@ +#!perl +use strict; +sub run(@) { + open PROC, "-|", @_ or die("Cannot run $_[0]: $!"); + my @out; + while () { + 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 $_; }