diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 000000000..42e227d67
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,60 @@
+name: CI
+
+on: [push, pull_request]
+
+env:
+ CTEST_OUTPUT_ON_FAILURE: 1
+
+jobs:
+ ubuntu-ninja-clang:
+ name: Ubuntu (ninja, clang)
+ runs-on: ubuntu-22.04
+ steps:
+ - name: Prepare
+ run: |
+ sudo apt update
+ sudo apt install ninja-build
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ env:
+ CC: clang
+ CXX: clang++
+ run: |
+ scripts/test.sh
+
+ ubuntu-make-gcc:
+ name: Ubuntu (make, gcc)
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ env:
+ CC: gcc
+ CXX: g++
+ run: |
+ scripts/initbuild.sh make
+ scripts/test.sh
+
+ macos:
+ name: macOS
+ runs-on: macos-12
+ steps:
+ - name: Prepare
+ run: |
+ brew install cmake ninja
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ scripts/test.sh
+
+ windows:
+ name: Windows
+ runs-on: windows-2022
+ steps:
+ - uses: microsoft/setup-msbuild@v1.1
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ cmake .
+ msbuild FlatCC.sln /m /property:Configuration=Release
+ ctest -VV
diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml
new file mode 100644
index 000000000..ba78294e4
--- /dev/null
+++ b/.github/workflows/weekly.yml
@@ -0,0 +1,193 @@
+name: Weekly
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '0 10 * * 1' # Mon 10.00 UTC
+
+env:
+ CTEST_OUTPUT_ON_FAILURE: 1
+
+jobs:
+ clang:
+ name: Clang ${{ matrix.clang-version }}
+ runs-on: ubuntu-20.04
+ strategy:
+ fail-fast: false
+ matrix:
+ clang-version: [5, 7, 9, 11, 13, 15]
+ steps:
+ - name: Setup Clang
+ uses: aminya/setup-cpp@v1
+ with:
+ llvm: ${{ matrix.clang-version }}
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ scripts/initbuild.sh make-concurrent
+ scripts/test.sh
+
+ clang-32bit:
+ name: Clang 32bit
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Prepare
+ run: |
+ sudo apt update
+ sudo apt install gcc-multilib g++-multilib
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ env:
+ CC: clang
+ CXX: clang++
+ run: |
+ scripts/initbuild.sh make-32bit
+ scripts/test.sh
+
+ gcc-old:
+ name: GCC 4.4
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Setup GCC
+ run: |
+ wget http://launchpadlibrarian.net/336269522/libmpfr4_3.1.6-1_amd64.deb
+ wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/gcc-4.4-base_4.4.7-8ubuntu1_amd64.deb
+ wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/cpp-4.4_4.4.7-8ubuntu1_amd64.deb
+ wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/gcc-4.4_4.4.7-8ubuntu1_amd64.deb
+ wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/libstdc++6-4.4-dev_4.4.7-8ubuntu1_amd64.deb
+ wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/g++-4.4_4.4.7-8ubuntu1_amd64.deb
+ sudo dpkg -i ./libmpfr4_3.1.6-1_amd64.deb
+ sudo dpkg -i ./gcc-4.4-base_4.4.7-8ubuntu1_amd64.deb
+ sudo dpkg -i ./cpp-4.4_4.4.7-8ubuntu1_amd64.deb
+ sudo dpkg -i ./gcc-4.4_4.4.7-8ubuntu1_amd64.deb
+ sudo dpkg -i ./libstdc++6-4.4-dev_4.4.7-8ubuntu1_amd64.deb ./g++-4.4_4.4.7-8ubuntu1_amd64.deb
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ env:
+ CC: gcc-4.4
+ CXX: g++-4.4
+ run: |
+ scripts/initbuild.sh make-concurrent
+ scripts/test.sh
+
+ gcc:
+ name: GCC ${{ matrix.gcc-version }}
+ runs-on: ubuntu-20.04
+ strategy:
+ fail-fast: false
+ matrix:
+ gcc-version: [7, 9, 11]
+ steps:
+ - name: Setup GCC
+ uses: aminya/setup-cpp@v1
+ with:
+ gcc: ${{ matrix.gcc-version }}
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ scripts/initbuild.sh make-concurrent
+ scripts/test.sh
+
+ gcc-32bit:
+ name: GCC 32bit
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Prepare
+ run: |
+ sudo apt update
+ sudo apt install gcc-multilib g++-multilib
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ scripts/initbuild.sh make-32bit
+ scripts/test.sh
+
+ intel:
+ name: Intel ${{ matrix.compiler }}
+ runs-on: ubuntu-20.04
+ strategy:
+ fail-fast: false
+ matrix:
+ compiler: [icc, icx]
+ steps:
+ - name: Prepare
+ run: |
+ wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | \
+ gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
+ echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | \
+ sudo tee /etc/apt/sources.list.d/oneAPI.list
+ sudo apt update
+ sudo apt install intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2021.4.0
+ - name: Setup Intel oneAPI
+ run: |
+ source /opt/intel/oneapi/setvars.sh
+ printenv >> $GITHUB_ENV
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ env:
+ CC: ${{ matrix.compiler }}
+ CXX: ${{ matrix.compiler }}
+ run: |
+ scripts/initbuild.sh make-concurrent
+ scripts/test.sh
+
+ macos-clang:
+ name: macOS Clang
+ runs-on: macos-11
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ scripts/initbuild.sh make-concurrent
+ scripts/test.sh
+
+ macos-gcc:
+ name: macOS GCC ${{ matrix.gcc-version }}
+ runs-on: macos-11
+ strategy:
+ fail-fast: false
+ matrix:
+ gcc-version: [9, 12]
+ steps:
+ - uses: actions/checkout@v3
+ - name: Prepare
+ run: |
+ brew install gcc@${{ matrix.gcc-version }}
+ - name: Build and run tests
+ env:
+ CC: gcc-${{ matrix.gcc-version }}
+ CXX: g++-${{ matrix.gcc-version }}
+ run: |
+ scripts/initbuild.sh make-concurrent
+ scripts/test.sh
+
+ windows:
+ name: Windows Visual Studio ${{ matrix.version }}
+ runs-on: windows-${{ matrix.version }}
+ strategy:
+ fail-fast: false
+ matrix:
+ version: [2019, 2022]
+ steps:
+ - uses: microsoft/setup-msbuild@v1.1
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ cmake .
+ msbuild FlatCC.sln /m /property:Configuration=Release
+ ctest -VV
+
+ cmake-minimum-required:
+ name: CMake 2.8.12 (min. required)
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Setup cmake
+ uses: jwlawson/actions-setup-cmake@v1
+ with:
+ cmake-version: 2.8.12
+ - uses: actions/checkout@v3
+ - name: Build and run tests
+ run: |
+ cmake --version
+ scripts/initbuild.sh make-concurrent
+ scripts/test.sh
diff --git a/.gitignore b/.gitignore
index eba83e37c..2d7483235 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@ bin/*
lib/*
release/*
scripts/build.cfg
+compile_flags.txt
+compile_commands.json
+.cache
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cf39d87ce..552c96006 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,36 @@
# Change Log
-## [0.6.1-pre]
+## [0.6.2-pre]
+
+- CMake: avoid assuming location of build dir during configuration.
+- Use untyped integer constants in place of enums for public interface flags to
+ allow for safe bit masking operations (PR #248).
+- Added experimental support for generating `compile_commands.json` via
+ `CMakeList.txt` for use with clangd.
+- Remove `fallthrough` macro for improved portability (#247, #252).
+- Added `parse_float/double_compare`, `parse_float/double_is_equal` to
+ portable library, and added `parse_float/double_isnan` to mirror isinf.
+ This should help with GCC 32-bit double precision conversion issue.
+- Add Github Actions builds to replace stale Travis CI build. This also
+ includes source code fixes for some build variants. Although
+ Windows build is included it only covers recent 64-bit Windows. More
+ work is need for older Windows variants. (#250).
+- Increase maximum allowed schema file size from 64 KiB to 1 MB (#256).
+- Fix seg fault in json parser while adding null characters to a too
+ short input string for a fixed length char array struct field (#257).
+- Fix regression where empty namespace in schema does not reset root scope
+ correctly in parser (#265).
+- Fix lexer checks that breaks with UTF-8, notably UTF-8 schema comments (#267).
+- Add sanitizer flag for clang debug and related warnings (input from several
+ PRs incl. #237).
+- Fix missing runtime check for building too large tables (#235).
+- Fix alignment of large objects created outside root buffer (#127).
+- Pad top level buffer end to largest object in buffer
+
+## [0.6.1]
- Add `flatcc_builder_alloc` and `flatcc_builder_free` to handle situations
- where stanard allocation has been redefined via macros so `free` is no longer
+ where standard allocation has been redefined via macros so `free` is no longer
safe to use. These are similar to the existing `aligned_alloc/free` functions.
- Fix a potential, but never seen, low level race condition in the builder when
writing a union field because the builder might reallocate between type
@@ -60,6 +87,12 @@
affected because warnigs were disabled more broadly than intended. Also note
that warnings will still be disabled after pop if the compiler does not
support push/pop diagnostics (#205).
+- Fix verifier crash on malicious string length input (#221).
+- Fix potential crash parsing unterminated JSON (#223).
+- Allow 0 (and other unknown values) as schema default value for enums with
+ `bit_flags` attribute.
+- Disable -pedantic flag for GCC >= 8, it just keeps breaking perfectly valid
+ code (#227).
## [0.6.0]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7a201691d..cb6715a9d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,14 @@
# Ubuntu 14.04 (Trusty)
-#cmake_minimum_required (VERSION 2.8.12.2)
+cmake_minimum_required (VERSION 2.8.12.2)
# Centos 7
#cmake_minimum_required (VERSION 2.8.11)
-cmake_minimum_required (VERSION 2.8)
+#cmake_minimum_required (VERSION 2.8)
+
+# Experimental for generating compile_commands.json so editors with
+# clangd language server support can use it. Symlink
+# build/Debug/compile_commands.json to project root where it is
+# gitignored.
+#set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
# Disable build of tests and samples. Due to custom build step
# dependency on flatcc tool, some custom build configurations may
@@ -14,6 +20,10 @@ option(FLATCC_TEST "enable tests" ON)
# project.
option(FLATCC_CXX_TEST "enable C++ tests" ON)
+# Note that linking with flatcc debug libraries may require souce code to also use
+# the sanitize flag.
+option(FLATCC_DEBUG_CLANG_SANITIZE "enable clang sanitize flag for debug build" ON)
+
# Conditionally set project languages based on FLATCC_TEST, as C++ is
# only necessary if building the tests.
if (FLATCC_TEST AND FLATCC_CXX_TEST)
@@ -134,12 +144,8 @@ endif()
if (FLATCC_REFLECTION)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFLATCC_REFLECTION=1")
- file(WRITE ${PROJECT_SOURCE_DIR}/build/reflection_enabled "REFLECTION=1")
- file(REMOVE ${PROJECT_SOURCE_DIR}/build/reflection_disabled)
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFLATCC_REFLECTION=0")
- file(REMOVE ${PROJECT_SOURCE_DIR}/build/reflection_enabled)
- file(WRITE ${PROJECT_SOURCE_DIR}/build/reflection_disabled "REFLECTION=0")
endif()
@@ -169,7 +175,7 @@ message(STATUS "lib install dir ${dist_dir}/${lib_dir}")
# and constants should be turned off - those are plentiful. They are
# silenced for Clang, GCC and MSVC in generated headers.headers.
-if (CMAKE_C_COMPILER_ID MATCHES "Clang")
+if (CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
# Clang or AppleClang
message(STATUS "Setting Clang compiler options")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes")
@@ -179,13 +185,23 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra")
# Fix broken C++ alignas - either will do
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
- #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPORTABLE_PATCH_CPLUSPLUS_STDALIGN")
+ #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPORTABLE_PATCH_CPLUSPLUS_STDALIGN")
if (FLATCC_ALLOW_WERROR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif()
if (FLATCC_IGNORE_CONST_COND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-tautological-constant-out-of-range-compare")
endif()
+ if (FLATCC_DEBUG_CLANG_SANITIZE)
+ if (CMAKE_BUILD_TYPE MATCHES Debug)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
+ endif()
+ endif()
+ # Suppress warning relaxed in clang-6, see https://reviews.llvm.org/D28148
+ if (CMAKE_C_COMPILER_VERSION VERSION_LESS 6)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers")
+ endif()
# To get assembly output
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -save-temps")
@@ -209,8 +225,9 @@ elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU")
endif()
else()
message(STATUS "Setting GNU C compiler options with c11 and Posix")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -pedantic -Wall -Wextra")
- if (NOT (GCC_VERSION VERSION_LESS 8.0))
+ if (GCC_VERSION VERSION_LESS 8.0)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -pedantic -Wall -Wextra")
+ elseif (NOT (GCC_VERSION VERSION_LESS 8.0))
# Disable some GCC checks:
# (warnings exist since 8.0, but are more aggressive in 9.0)
#
@@ -219,9 +236,11 @@ elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU")
# structs, but these are valid as zero-paddded, not zero terminated.
#
# -Wno-format-overflow:
- # GCC 9 warns on mistakenly assumed NULL string when
+ # GCC 9 warns on mistakenly assumed NULL string when
# printing from a required FlatBuffer string field.
#
+ message(STATUS "Disabling -pedantic for GCC >= 8.0")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall -Wextra")
message(STATUS "Disabling GNU C compiler warnings: -Wstringop-truncation -Wno-format-overflow")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-stringop-truncation -Wno-format-overflow")
endif()
diff --git a/README.md b/README.md
index 78aa7e5d3..3d15466a8 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
-OS-X & Ubuntu: [![Build Status](https://travis-ci.org/dvidelabs/flatcc.svg?branch=master)](https://travis-ci.org/dvidelabs/flatcc)
+Ubuntu, macOS and Windows: [![Build Status](https://github.com/dvidelabs/flatcc/actions/workflows/ci.yml/badge.svg)](https://github.com/dvidelabs/flatcc/actions/workflows/ci.yml)
Windows: [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/dvidelabs/flatcc?branch=master&svg=true)](https://ci.appveyor.com/project/dvidelabs/flatcc)
+Weekly: [![Build Status](https://github.com/dvidelabs/flatcc/actions/workflows/weekly.yml/badge.svg)](https://github.com/dvidelabs/flatcc/actions/workflows/weekly.yml)
_The JSON parser may change the interface for parsing union vectors in a
@@ -25,7 +26,7 @@ executable also handle optional json parsing or printing in less than 2 us for a
* [Poll on Meson Build](#poll-on-meson-build)
* [Reporting Bugs](#reporting-bugs)
* [Status](#status)
- * [Main features supported as of 0.6.0](#main-features-supported-as-of-060)
+ * [Main features supported as of 0.6.1](#main-features-supported-as-of-061)
* [Supported platforms (CI tested)](#supported-platforms-ci-tested)
* [Platforms reported to work by users](#platforms-reported-to-work-by-users)
* [Portability](#portability)
@@ -81,6 +82,7 @@ executable also handle optional json parsing or printing in less than 2 us for a
* [Using the Compiler and Builder library](#using-the-compiler-and-builder-library)
* [FlatBuffers Binary Format](#flatbuffers-binary-format)
* [Security Considerations](#security-considerations)
+* [Style Guide](#style-guide)
* [Benchmarks](#benchmarks)
@@ -292,6 +294,30 @@ fi
## Status
+Release 0.6.2 (in development) is primarily a bug fix release, refer
+to CHANGELOG for details. A long standing bug has been fixed where
+where objects created before a call to _create_as_root would not be
+properly aligned, and buffer end is now also padded to largest object
+seen within the buffer.
+Note that for clang debug builds, -fsanitize=undefined has been
+added and this may require dependent source code to also use
+that flag to avoid missing linker symbols. The feature can be disabled
+in CMakeLists.txt.
+
+Release 0.6.1 contains primarily bug fixes and numerous contributions
+from the community to handle platform edge cases. Additionally,
+pendantic GCC warnings are disabled, relying instead on clang, since GCC
+is too aggressive, breaks builds frequently and works against
+portability. An existing C++ test case ensures that C code also works
+with common C++ compilers, but it can break some environments, so there
+is now a flag to disable that test without disabling all tests. Support
+for Optional Scalar Values in the FlatBuffer format has been added.
+There is also improved support for abstracting memory allocation on
+various platforms. `
_identifier` has been deprecated in favor
+`_file_identifier` in generated code due to `identifier` easily
+leading to name conflicts. `file_extension` constant in generated code
+is now without prefixed dot (.).
+
Release 0.6.0 introduces a "primary" attribute to be used together with
a key attribute to chose default key for finding and sorting. If primary
is absent, the key with the lowest id becomes primary. Tables and
@@ -339,7 +365,7 @@ low-level union interface so the terms { type, value } are used
consistently over { type, member } and { types, members }.
-### Main features supported as of 0.6.0
+### Main features supported as of 0.6.1
- generated FlatBuffers reader and builder headers for C
- generated FlatBuffers verifier headers for C
@@ -364,6 +390,7 @@ consistently over { type, member } and { types, members }.
- base64(url) encoded binary data in JSON.
- sort fields by primary key (as of 0.6.0)
- char arrays (as of 0.6.0)
+- optional scalar values (as of 0.6.1)
There are no plans to make frequent updates once the project becomes
stable, but input from the community will always be welcome and included
@@ -373,6 +400,11 @@ different target platforms.
### Supported platforms (CI tested)
+This list is somewhat outdated, more recent compiler versions are added and
+some old ones are removed when CI platforms no longer supported but largely
+the supported targets remain unchanged. MSVC 2010 might become deprecated
+in the future.
+
The ci-more branch tests additional compilers:
- Ubuntu Trusty gcc 4.4, 4.6-4.9, 5, 6, 7 and clang 3.6, 3.8
@@ -1233,6 +1265,25 @@ For advanced debugging the [hexdump.h] file can be used to dump the buffer
contents. It is used in [test_json.c] and also in [monster_test.c].
See also [FlatBuffers Binary Format].
+As of April 2022, Googles flatc tool has implemented an `--annotate` feature.
+This provides an annotated hex dump given a binary buffer and a schema. The
+output can be used to troubleshoot and rule out or confirm suspected encoding
+bugs in the buffer at hand. The eclectic example in the [FlatBuffers Binary
+Format] document contains a hand written annotated example which inspired the
+`--annotate` feature, but it is not the exact same output format. Note also that
+`flatc` generated buffers tend to have vtables before the table it is referenced
+by, while flatcc normally packs all vtables at the end of the buffer for
+better padding and cache efficiency.
+
+See also [flatc --annotate].
+
+Note: There is experimental support for text editor that supports
+clangd language server or similar. You can edit `CMakeList.txt`
+to generate `build/Debug/compile_comands.json`, at least when
+using clang as a compiler, and copy or symlink it from root. Or
+come with a better suggestion. There are `.gitignore` entries for
+`compile_flags.txt` and `compile_commands.json` in project root.
+
## File and Type Identifiers
@@ -2191,8 +2242,15 @@ Optionally switch to a different build tool by choosing one of:
scripts/initbuild.sh make-concurrent
scripts/initbuild.sh ninja
-where `ninja` is the default and `make-concurrent` is `make` with the `-j`
-flag. A custom build configuration `X` can be added by adding a
+where `ninja` is the default and `make-concurrent` is `make` with the `-j` flag.
+
+To enforce a 32-bit build on a 64-bit machine the following configuration
+can be used:
+
+ scripts/initbuild.sh make-32bit
+
+which uses `make` and provides the `-m32` flag to the compiler.
+A custom build configuration `X` can be added by adding a
`scripts/build.cfg.X` file.
`scripts/initbuild.sh` cleans the build if a specific build
@@ -2527,6 +2585,31 @@ Mostly for implementers: [FlatBuffers Binary Format]
See [Security Considerations].
+## Style Guide
+
+FlatCC coding style is largely similar to the [WebKit Style], with the following notable exceptions:
+
+* Syntax requiring C99 or later is avoided, except `` types are made available.
+* If conditions always use curly brackets, or single line statements without linebreak: `if (err) return -1;`.
+* NULL and nullptr are generally just represented as `0`.
+* Comments are old-school C-style (pre C99). Text is generally cased with punctuation: `/* A comment. */`
+* `true` and `false` keywords are not used (pre C99).
+* In code generation there is essentially no formatting to avoid excessive bloat.
+* Struct names and other types is lower case since this is C, not C++.
+* `snake_case` is used over `camelCase`.
+* Header guards are used over `#pragma once` because it is non-standard and not always reliable in filesystems with ambigious paths.
+* Comma is not placed first in multi-line calls (but maybe that would be a good idea for diff stability).
+* `config.h` inclusion might be handled differently in that `flatbuffers.h` includes the config file.
+* `unsigned` is not used without `int` for historical reasons. Generally a type like `uint32_t` is preferred.
+* Use `TODO:` instead of `FIXME:` in comments for historical reasons.
+
+All the main source code in compiler and runtime aim to be C11 compatible and
+uses many C11 constructs. This is made possible through the included portable
+library such that older compilers can also function. Therefore any platform specific adaptations will be provided by updating
+the portable library rather than introducing compile time flags in the main
+source code.
+
+
## Benchmarks
See [Benchmarks]
@@ -2548,3 +2631,5 @@ See [Benchmarks]
[hexdump.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/support/hexdump.h
[readfile.h]: include/flatcc/support/readfile.h
[Security Considerations]: https://github.com/dvidelabs/flatcc/blob/master/doc/security.md
+[flatc --annotate]: https://github.com/google/flatbuffers/tree/master/tests/annotated_binary
+[WebKit Style]: https://webkit.org/code-style-guidelines/
diff --git a/config/config.h b/config/config.h
index 041ec228c..b07fa6cc8 100644
--- a/config/config.h
+++ b/config/config.h
@@ -54,7 +54,7 @@
* is covers the accumulated size of all included files. 0 is unlimited.
*/
#ifndef FLATCC_MAX_SCHEMA_SIZE
-#define FLATCC_MAX_SCHEMA_SIZE 64 * 1024
+#define FLATCC_MAX_SCHEMA_SIZE 1000000
#endif
/*
diff --git a/external/lex/luthor.c b/external/lex/luthor.c
index fc81985f3..5f037d726 100644
--- a/external/lex/luthor.c
+++ b/external/lex/luthor.c
@@ -176,16 +176,16 @@ static const char lex_alnum[256] = {
#endif
#ifndef lex_isdigit
-#define lex_isdigit(c) ((c) >= '0' && (c) <= '9')
+#define lex_isdigit(c) ((unsigned)(c) >= '0' && (unsigned)(c) <= '9')
#endif
#ifndef lex_ishexdigit
-#define lex_ishexdigit(c) (((c) >= '0' && (c) <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'))
+#define lex_ishexdigit(c) (((c) >= '0' && ((unsigned)c) <= '9') || ((unsigned)(c | 0x20) >= 'a' && (unsigned)(c | 0x20) <= 'f'))
#endif
#ifndef lex_isctrl
#include
-#define lex_isctrl(c) ((c) < 0x20 || (c) == 0x7f)
+#define lex_isctrl(c) (((unsigned)c) < 0x20 || (c) == 0x7f)
#endif
#ifndef lex_isblank
diff --git a/include/flatcc/flatcc_builder.h b/include/flatcc/flatcc_builder.h
index 3871b1d07..2e84d2979 100644
--- a/include/flatcc/flatcc_builder.h
+++ b/include/flatcc/flatcc_builder.h
@@ -710,10 +710,13 @@ static inline void flatcc_builder_refmap_reset(flatcc_builder_t *B)
}
-enum flatcc_builder_buffer_flags {
- flatcc_builder_is_nested = 1,
- flatcc_builder_with_size = 2,
-};
+typedef uint16_t flatcc_builder_buffer_flags_t;
+static const flatcc_builder_buffer_flags_t flatcc_builder_is_nested = 1;
+static const flatcc_builder_buffer_flags_t flatcc_builder_with_size = 2;
+
+/* The flag size in the API needs to match the internal size. */
+static_assert(sizeof(flatcc_builder_buffer_flags_t) ==
+ sizeof(((flatcc_builder_t *)0)->buffer_flags), "flag size mismatch");
/**
* An alternative to start buffer, start struct/table ... end buffer.
@@ -776,7 +779,7 @@ enum flatcc_builder_buffer_flags {
flatcc_builder_ref_t flatcc_builder_create_buffer(flatcc_builder_t *B,
const char identifier[FLATBUFFERS_IDENTIFIER_SIZE],
uint16_t block_align,
- flatcc_builder_ref_t ref, uint16_t align, int flags);
+ flatcc_builder_ref_t ref, uint16_t align, flatcc_builder_buffer_flags_t flags);
/**
* Creates a struct within the current buffer without using any
@@ -867,7 +870,7 @@ flatcc_builder_ref_t flatcc_builder_end_struct(flatcc_builder_t *B);
*/
int flatcc_builder_start_buffer(flatcc_builder_t *B,
const char identifier[FLATBUFFERS_IDENTIFIER_SIZE],
- uint16_t block_align, int flags);
+ uint16_t block_align, flatcc_builder_buffer_flags_t flags);
/**
* The root object should be a struct or a table to conform to the
@@ -923,7 +926,7 @@ flatcc_builder_ref_t flatcc_builder_end_buffer(flatcc_builder_t *B, flatcc_build
*/
flatcc_builder_ref_t flatcc_builder_embed_buffer(flatcc_builder_t *B,
uint16_t block_align,
- const void *data, size_t size, uint16_t align, int flags);
+ const void *data, size_t size, uint16_t align, flatcc_builder_buffer_flags_t flags);
/**
* Applies to the innermost open buffer. The identifier may be null or
diff --git a/include/flatcc/flatcc_json_parser.h b/include/flatcc/flatcc_json_parser.h
index 1907fc7fc..f8281295a 100644
--- a/include/flatcc/flatcc_json_parser.h
+++ b/include/flatcc/flatcc_json_parser.h
@@ -22,13 +22,12 @@ extern "C" {
#define PDIAGNOSTIC_IGNORE_UNUSED
#include "flatcc/portable/pdiagnostic_push.h"
-enum flatcc_json_parser_flags {
- flatcc_json_parser_f_skip_unknown = 1,
- flatcc_json_parser_f_force_add = 2,
- flatcc_json_parser_f_with_size = 4,
- flatcc_json_parser_f_skip_array_overflow = 8,
- flatcc_json_parser_f_reject_array_underflow = 16
-};
+typedef uint32_t flatcc_json_parser_flags_t;
+static const flatcc_json_parser_flags_t flatcc_json_parser_f_skip_unknown = 1;
+static const flatcc_json_parser_flags_t flatcc_json_parser_f_force_add = 2;
+static const flatcc_json_parser_flags_t flatcc_json_parser_f_with_size = 4;
+static const flatcc_json_parser_flags_t flatcc_json_parser_f_skip_array_overflow = 8;
+static const flatcc_json_parser_flags_t flatcc_json_parser_f_reject_array_underflow = 16;
#define FLATCC_JSON_PARSE_ERROR_MAP(XX) \
XX(ok, "ok") \
@@ -92,7 +91,7 @@ typedef struct flatcc_json_parser_ctx flatcc_json_parser_t;
struct flatcc_json_parser_ctx {
flatcc_builder_t *ctx;
const char *line_start;
- int flags;
+ flatcc_json_parser_flags_t flags;
#if FLATCC_JSON_PARSE_ALLOW_UNQUOTED
int unquoted;
#endif
@@ -111,7 +110,7 @@ static inline int flatcc_json_parser_get_error(flatcc_json_parser_t *ctx)
return ctx->error;
}
-static inline void flatcc_json_parser_init(flatcc_json_parser_t *ctx, flatcc_builder_t *B, const char *buf, const char *end, int flags)
+static inline void flatcc_json_parser_init(flatcc_json_parser_t *ctx, flatcc_builder_t *B, const char *buf, const char *end, flatcc_json_parser_flags_t flags)
{
memset(ctx, 0, sizeof(*ctx));
ctx->ctx = B;
@@ -243,24 +242,38 @@ static inline uint64_t flatcc_json_parser_symbol_part_ext(const char *buf, const
}
/* This can bloat inlining for a rarely executed case. */
#if 1
- /* Fall through comments needed to silence gcc 7 warnings. */
switch (n) {
- case 8: w |= ((uint64_t)buf[7]) << (0 * 8);
- fallthrough;
- case 7: w |= ((uint64_t)buf[6]) << (1 * 8);
- fallthrough;
- case 6: w |= ((uint64_t)buf[5]) << (2 * 8);
- fallthrough;
- case 5: w |= ((uint64_t)buf[4]) << (3 * 8);
- fallthrough;
- case 4: w |= ((uint64_t)buf[3]) << (4 * 8);
- fallthrough;
- case 3: w |= ((uint64_t)buf[2]) << (5 * 8);
- fallthrough;
- case 2: w |= ((uint64_t)buf[1]) << (6 * 8);
- fallthrough;
- case 1: w |= ((uint64_t)buf[0]) << (7 * 8);
- fallthrough;
+ case 8:
+ w |= ((uint64_t)buf[7]) << (0 * 8);
+ goto lbl_n_7;
+ case 7:
+lbl_n_7:
+ w |= ((uint64_t)buf[6]) << (1 * 8);
+ goto lbl_n_6;
+ case 6:
+lbl_n_6:
+ w |= ((uint64_t)buf[5]) << (2 * 8);
+ goto lbl_n_5;
+ case 5:
+lbl_n_5:
+ w |= ((uint64_t)buf[4]) << (3 * 8);
+ goto lbl_n_4;
+ case 4:
+lbl_n_4:
+ w |= ((uint64_t)buf[3]) << (4 * 8);
+ goto lbl_n_3;
+ case 3:
+lbl_n_3:
+ w |= ((uint64_t)buf[2]) << (5 * 8);
+ goto lbl_n_2;
+ case 2:
+lbl_n_2:
+ w |= ((uint64_t)buf[1]) << (6 * 8);
+ goto lbl_n_1;
+ case 1:
+lbl_n_1:
+ w |= ((uint64_t)buf[0]) << (7 * 8);
+ break;
case 0:
break;
}
@@ -872,10 +885,10 @@ const char *flatcc_json_parser_union_type_vector(flatcc_json_parser_t *ctx,
* `buf`, `bufsiz` may be larger than the parsed json if trailing
* space or zeroes are expected, but they must represent a valid memory buffer.
* `fid` must be null, or a valid file identifier.
- * `flags` default to 0. See also `flatcc_json_parser_flags`.
+ * `flags` default to 0. See also `flatcc_json_parser_f_` constants.
*/
int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx,
- const char *buf, size_t bufsiz, int flags, const char *fid,
+ const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid,
flatcc_json_parser_table_f *parser);
/*
@@ -883,7 +896,7 @@ int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t *
* root.
*/
int flatcc_json_parser_struct_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx,
- const char *buf, size_t bufsiz, int flags, const char *fid,
+ const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid,
flatcc_json_parser_struct_f *parser);
#include "flatcc/portable/pdiagnostic_pop.h"
diff --git a/include/flatcc/flatcc_json_printer.h b/include/flatcc/flatcc_json_printer.h
index 0ce49c146..cab49a1a4 100644
--- a/include/flatcc/flatcc_json_printer.h
+++ b/include/flatcc/flatcc_json_printer.h
@@ -243,14 +243,13 @@ static inline void flatcc_json_printer_set_nonstrict(flatcc_json_printer_t *ctx)
flatcc_json_printer_set_noenum(ctx, 0);
}
-enum flatcc_json_printer_flags {
- flatcc_json_printer_f_unquote = 1,
- flatcc_json_printer_f_noenum = 2,
- flatcc_json_printer_f_skip_default = 4,
- flatcc_json_printer_f_force_default = 8,
- flatcc_json_printer_f_pretty = 16,
- flatcc_json_printer_f_nonstrict = 32,
-};
+typedef uint32_t flatcc_json_printer_flags_t;
+static const flatcc_json_printer_flags_t flatcc_json_printer_f_unquote = 1;
+static const flatcc_json_printer_flags_t flatcc_json_printer_f_noenum = 2;
+static const flatcc_json_printer_flags_t flatcc_json_printer_f_skip_default = 4;
+static const flatcc_json_printer_flags_t flatcc_json_printer_f_force_default = 8;
+static const flatcc_json_printer_flags_t flatcc_json_printer_f_pretty = 16;
+static const flatcc_json_printer_flags_t flatcc_json_printer_f_nonstrict = 32;
/*
* May be called instead of setting operational modes individually.
@@ -268,7 +267,7 @@ enum flatcc_json_printer_flags {
* `pretty` flag sets indentation to 2.
* `nonstrict` implies: `noenum`, `unquote`, `pretty`.
*/
-static inline void flatcc_json_printer_set_flags(flatcc_json_printer_t *ctx, int flags)
+static inline void flatcc_json_printer_set_flags(flatcc_json_printer_t *ctx, flatcc_json_printer_flags_t flags)
{
ctx->unquote = !!(flags & flatcc_json_printer_f_unquote);
ctx->noenum = !!(flags & flatcc_json_printer_f_noenum);
diff --git a/include/flatcc/flatcc_version.h b/include/flatcc/flatcc_version.h
index 87158986b..78bc9c8d3 100644
--- a/include/flatcc/flatcc_version.h
+++ b/include/flatcc/flatcc_version.h
@@ -2,10 +2,10 @@
extern "C" {
#endif
-#define FLATCC_VERSION_TEXT "0.6.1-dev"
+#define FLATCC_VERSION_TEXT "0.6.2"
#define FLATCC_VERSION_MAJOR 0
#define FLATCC_VERSION_MINOR 6
-#define FLATCC_VERSION_PATCH 1
+#define FLATCC_VERSION_PATCH 2
/* 1 or 0 */
#define FLATCC_VERSION_RELEASED 0
diff --git a/include/flatcc/portable/paligned_alloc.h b/include/flatcc/portable/paligned_alloc.h
index 3dcf4efcd..70b00b9ea 100644
--- a/include/flatcc/portable/paligned_alloc.h
+++ b/include/flatcc/portable/paligned_alloc.h
@@ -61,6 +61,8 @@ extern "C" {
#define PORTABLE_C11_ALIGNED_ALLOC 0
#elif defined (__clang__)
#define PORTABLE_C11_ALIGNED_ALLOC 0
+#elif defined (__APPLE__)
+#define PORTABLE_C11_ALIGNED_ALLOC 0
#elif defined(__IBMC__)
#define PORTABLE_C11_ALIGNED_ALLOC 0
#elif (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
diff --git a/include/flatcc/portable/pattributes.h b/include/flatcc/portable/pattributes.h
index 30b3b23d3..9240fa319 100644
--- a/include/flatcc/portable/pattributes.h
+++ b/include/flatcc/portable/pattributes.h
@@ -40,7 +40,7 @@ extern "C" {
#endif
#ifndef PORTABLE_EXPOSE_ATTRIBUTES
-#define PORTABLE_EXPOSE_ATTRIBUTES 1
+#define PORTABLE_EXPOSE_ATTRIBUTES 0
#endif
#ifdef __has_c_attribute
diff --git a/include/flatcc/portable/pparsefp.h b/include/flatcc/portable/pparsefp.h
index 1d2b9da26..7fa1c247d 100644
--- a/include/flatcc/portable/pparsefp.h
+++ b/include/flatcc/portable/pparsefp.h
@@ -5,6 +5,8 @@
extern "C" {
#endif
+#include /* memcpy */
+
/*
* Parses a float or double number and returns the length parsed if
* successful. The length argument is of limited value due to dependency
@@ -34,7 +36,7 @@ extern "C" {
* Other compilers such as xlc may require linking with -lm which may not
* be convienent so a default isinf is provided. If isinf is available
* and there is a noticable performance issue, define
- * `PORTABLE_USE_ISINF`.
+ * `PORTABLE_USE_ISINF`. This flag also affects isnan.
*/
#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) || defined(PORTABLE_USE_ISINF)
#include
@@ -44,12 +46,13 @@ extern "C" {
#define isinf(x) (!_finite(x))
#endif
/*
- * clang-5 through clang-8 but not clang-9 issues incorrect precision
+ * clang-3 through clang-8 but not clang-9 issues incorrect precision
* loss warning with -Wconversion flag when cast is absent.
*/
#if defined(__clang__)
-#if __clang_major__ >= 5 && __clang_major__ <= 8
+#if __clang_major__ >= 3 && __clang_major__ <= 8
#define parse_double_isinf(x) isinf((float)x)
+#define parse_double_isnan(x) isnan((float)x)
#endif
#endif
#if !defined(parse_double_isinf)
@@ -64,19 +67,29 @@ extern "C" {
#endif
/* Avoid linking with libmath but depends on float/double being IEEE754 */
-static inline int parse_double_isinf(double x)
+static inline int parse_double_isinf(const double x)
{
- union { uint64_t u64; double f64; } v;
- v.f64 = x;
- return (v.u64 & 0x7fffffff00000000ULL) == 0x7ff0000000000000ULL;
+ uint64_t u64x;
+
+ memcpy(&u64x, &x, sizeof(u64x));
+ return (u64x & 0x7fffffff00000000ULL) == 0x7ff0000000000000ULL;
}
static inline int parse_float_isinf(float x)
{
- union { uint32_t u32; float f32; } v;
- v.f32 = x;
- return (v.u32 & 0x7fffffff) == 0x7f800000;
+ uint32_t u32x;
+
+ memcpy(&u32x, &x, sizeof(u32x));
+ return (u32x & 0x7fffffff) == 0x7f800000;
}
+
+#endif
+
+#if !defined(parse_double_isnan)
+#define parse_double_isnan isnan
+#endif
+#if !defined(parse_float_isnan)
+#define parse_float_isnan isnan
#endif
/* Returns 0 when in range, 1 on overflow, and -1 on underflow. */
@@ -131,6 +144,79 @@ static inline const char *parse_float(const char *buf, size_t len, float *result
return end;
}
+/* Inspired by https://bitbashing.io/comparing-floats.html */
+
+/* Return signed ULP distance or INT64_MAX if any value is nan. */
+static inline int64_t parse_double_compare(const double x, const double y)
+{
+ int64_t i64x, i64y;
+
+ if (x == y) return 0;
+ if (parse_double_isnan(x)) return INT64_MAX;
+ if (parse_double_isnan(y)) return INT64_MAX;
+ memcpy(&i64x, &x, sizeof(i64x));
+ memcpy(&i64y, &y, sizeof(i64y));
+ if ((i64x < 0) != (i64y < 0)) return INT64_MAX;
+ return i64x - i64y;
+}
+
+/* Same as double, but INT32_MAX if nan. */
+static inline int32_t parse_float_compare(const float x, const float y)
+{
+ int32_t i32x, i32y;
+
+ if (x == y) return 0;
+ if (parse_float_isnan(x)) return INT32_MAX;
+ if (parse_float_isnan(y)) return INT32_MAX;
+ memcpy(&i32x, &x, sizeof(i32x));
+ memcpy(&i32y, &y, sizeof(i32y));
+ if ((i32x < 0) != (i32y < 0)) return INT32_MAX;
+ return i32x - i32y;
+}
+
+/*
+ * Returns the absolute distance in floating point ULP (representational bit difference).
+ * Uses signed return value so that INT64_MAX and INT32_MAX indicates NaN similar to
+ * the compare function.
+ */
+static inline int64_t parse_double_dist(const double x, const double y)
+{
+ uint64_t m64;
+ int64_t i64;
+
+ i64 = parse_double_compare(x, y);
+ /* Absolute integer value of compare. */
+ m64 = (uint64_t)-(i64 < 0);
+ return (int64_t)(((uint64_t)i64 + m64) ^ m64);
+}
+
+/* Same as double, but INT32_MAX if NaN. */
+static inline int32_t parse_float_dist(const float x, const float y)
+{
+ uint32_t m32;
+ int32_t i32;
+
+ i32 = parse_float_compare(x, y);
+ /* Absolute integer value of compare. */
+ m32 = (uint32_t)-(i32 < 0);
+ return (int32_t)(((uint32_t)i32 + m32) ^ m32);
+}
+
+/*
+ * Returns 1 if no value is NaN, and the difference is at most one ULP (1 bit), and the
+ * sign is the same, and 0 otherwise.
+ */
+static inline int parse_double_is_equal(const double x, const double y)
+{
+ return parse_double_dist(x, y) >> 1 == 0;
+}
+
+/* Same as double, but at lower precision. */
+static inline int parse_float_is_equal(const float x, const float y)
+{
+ return parse_float_dist(x, y) >> 1 == 0;
+}
+
#include "pdiagnostic_pop.h"
#ifdef __cplusplus
diff --git a/include/flatcc/reflection/flatbuffers_common_builder.h b/include/flatcc/reflection/flatbuffers_common_builder.h
index b5ce8a5ce..a4be1ce6e 100644
--- a/include/flatcc/reflection/flatbuffers_common_builder.h
+++ b/include/flatcc/reflection/flatbuffers_common_builder.h
@@ -1,7 +1,7 @@
#ifndef FLATBUFFERS_COMMON_BUILDER_H
#define FLATBUFFERS_COMMON_BUILDER_H
-/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */
+/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */
/* Common FlatBuffers build functionality for C. */
diff --git a/include/flatcc/reflection/flatbuffers_common_reader.h b/include/flatcc/reflection/flatbuffers_common_reader.h
index 67971e9af..c57530868 100644
--- a/include/flatcc/reflection/flatbuffers_common_reader.h
+++ b/include/flatcc/reflection/flatbuffers_common_reader.h
@@ -1,7 +1,7 @@
#ifndef FLATBUFFERS_COMMON_READER_H
#define FLATBUFFERS_COMMON_READER_H
-/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */
+/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */
/* Common FlatBuffers read functionality for C. */
diff --git a/include/flatcc/reflection/reflection_builder.h b/include/flatcc/reflection/reflection_builder.h
index 4b05199ee..65aef73e5 100644
--- a/include/flatcc/reflection/reflection_builder.h
+++ b/include/flatcc/reflection/reflection_builder.h
@@ -1,7 +1,7 @@
#ifndef REFLECTION_BUILDER_H
#define REFLECTION_BUILDER_H
-/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */
+/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */
#ifndef REFLECTION_READER_H
#include "reflection_reader.h"
@@ -13,7 +13,7 @@
#undef flatbuffers_identifier
#define flatbuffers_identifier "BFBS"
#undef flatbuffers_extension
-#define flatbuffers_extension ".bfbs"
+#define flatbuffers_extension "bfbs"
#define __reflection_BaseType_formal_args , reflection_BaseType_enum_t v0
#define __reflection_BaseType_call_args , v0
diff --git a/include/flatcc/reflection/reflection_reader.h b/include/flatcc/reflection/reflection_reader.h
index 06b1dfb46..bf6a0e946 100644
--- a/include/flatcc/reflection/reflection_reader.h
+++ b/include/flatcc/reflection/reflection_reader.h
@@ -1,7 +1,7 @@
#ifndef REFLECTION_READER_H
#define REFLECTION_READER_H
-/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */
+/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */
#ifndef FLATBUFFERS_COMMON_READER_H
#include "flatbuffers_common_reader.h"
@@ -14,7 +14,7 @@
#undef flatbuffers_identifier
#define flatbuffers_identifier "BFBS"
#undef flatbuffers_extension
-#define flatbuffers_extension ".bfbs"
+#define flatbuffers_extension "bfbs"
typedef const struct reflection_Type_table *reflection_Type_table_t;
@@ -54,86 +54,113 @@ typedef struct reflection_Schema_table *reflection_Schema_mutable_table_t;
typedef const flatbuffers_uoffset_t *reflection_Schema_vec_t;
typedef flatbuffers_uoffset_t *reflection_Schema_mutable_vec_t;
#ifndef reflection_Type_file_identifier
-#define reflection_Type_file_identifier flatbuffers_identifier
+#define reflection_Type_file_identifier "BFBS"
#endif
/* deprecated, use reflection_Type_file_identifier */
#ifndef reflection_Type_identifier
-#define reflection_Type_identifier flatbuffers_identifier
+#define reflection_Type_identifier "BFBS"
#endif
#define reflection_Type_type_hash ((flatbuffers_thash_t)0x44c8fe5e)
#define reflection_Type_type_identifier "\x5e\xfe\xc8\x44"
+#ifndef reflection_Type_file_extension
+#define reflection_Type_file_extension "bfbs"
+#endif
#ifndef reflection_KeyValue_file_identifier
-#define reflection_KeyValue_file_identifier flatbuffers_identifier
+#define reflection_KeyValue_file_identifier "BFBS"
#endif
/* deprecated, use reflection_KeyValue_file_identifier */
#ifndef reflection_KeyValue_identifier
-#define reflection_KeyValue_identifier flatbuffers_identifier
+#define reflection_KeyValue_identifier "BFBS"
#endif
#define reflection_KeyValue_type_hash ((flatbuffers_thash_t)0x8c761eaa)
#define reflection_KeyValue_type_identifier "\xaa\x1e\x76\x8c"
+#ifndef reflection_KeyValue_file_extension
+#define reflection_KeyValue_file_extension "bfbs"
+#endif
#ifndef reflection_EnumVal_file_identifier
-#define reflection_EnumVal_file_identifier flatbuffers_identifier
+#define reflection_EnumVal_file_identifier "BFBS"
#endif
/* deprecated, use reflection_EnumVal_file_identifier */
#ifndef reflection_EnumVal_identifier
-#define reflection_EnumVal_identifier flatbuffers_identifier
+#define reflection_EnumVal_identifier "BFBS"
#endif
#define reflection_EnumVal_type_hash ((flatbuffers_thash_t)0x9531c946)
#define reflection_EnumVal_type_identifier "\x46\xc9\x31\x95"
+#ifndef reflection_EnumVal_file_extension
+#define reflection_EnumVal_file_extension "bfbs"
+#endif
#ifndef reflection_Enum_file_identifier
-#define reflection_Enum_file_identifier flatbuffers_identifier
+#define reflection_Enum_file_identifier "BFBS"
#endif
/* deprecated, use reflection_Enum_file_identifier */
#ifndef reflection_Enum_identifier
-#define reflection_Enum_identifier flatbuffers_identifier
+#define reflection_Enum_identifier "BFBS"
#endif
#define reflection_Enum_type_hash ((flatbuffers_thash_t)0xacffa90f)
#define reflection_Enum_type_identifier "\x0f\xa9\xff\xac"
+#ifndef reflection_Enum_file_extension
+#define reflection_Enum_file_extension "bfbs"
+#endif
#ifndef reflection_Field_file_identifier
-#define reflection_Field_file_identifier flatbuffers_identifier
+#define reflection_Field_file_identifier "BFBS"
#endif
/* deprecated, use reflection_Field_file_identifier */
#ifndef reflection_Field_identifier
-#define reflection_Field_identifier flatbuffers_identifier
+#define reflection_Field_identifier "BFBS"
#endif
#define reflection_Field_type_hash ((flatbuffers_thash_t)0x9f7e408a)
#define reflection_Field_type_identifier "\x8a\x40\x7e\x9f"
+#ifndef reflection_Field_file_extension
+#define reflection_Field_file_extension "bfbs"
+#endif
#ifndef reflection_Object_file_identifier
-#define reflection_Object_file_identifier flatbuffers_identifier
+#define reflection_Object_file_identifier "BFBS"
#endif
/* deprecated, use reflection_Object_file_identifier */
#ifndef reflection_Object_identifier
-#define reflection_Object_identifier flatbuffers_identifier
+#define reflection_Object_identifier "BFBS"
#endif
#define reflection_Object_type_hash ((flatbuffers_thash_t)0xb09729bd)
#define reflection_Object_type_identifier "\xbd\x29\x97\xb0"
+#ifndef reflection_Object_file_extension
+#define reflection_Object_file_extension "bfbs"
+#endif
#ifndef reflection_RPCCall_file_identifier
-#define reflection_RPCCall_file_identifier flatbuffers_identifier
+#define reflection_RPCCall_file_identifier "BFBS"
#endif
/* deprecated, use reflection_RPCCall_file_identifier */
#ifndef reflection_RPCCall_identifier
-#define reflection_RPCCall_identifier flatbuffers_identifier
+#define reflection_RPCCall_identifier "BFBS"
#endif
#define reflection_RPCCall_type_hash ((flatbuffers_thash_t)0xe2d586f1)
#define reflection_RPCCall_type_identifier "\xf1\x86\xd5\xe2"
+#ifndef reflection_RPCCall_file_extension
+#define reflection_RPCCall_file_extension "bfbs"
+#endif
#ifndef reflection_Service_file_identifier
-#define reflection_Service_file_identifier flatbuffers_identifier
+#define reflection_Service_file_identifier "BFBS"
#endif
/* deprecated, use reflection_Service_file_identifier */
#ifndef reflection_Service_identifier
-#define reflection_Service_identifier flatbuffers_identifier
+#define reflection_Service_identifier "BFBS"
#endif
#define reflection_Service_type_hash ((flatbuffers_thash_t)0xf31a13b5)
#define reflection_Service_type_identifier "\xb5\x13\x1a\xf3"
+#ifndef reflection_Service_file_extension
+#define reflection_Service_file_extension "bfbs"
+#endif
#ifndef reflection_Schema_file_identifier
-#define reflection_Schema_file_identifier flatbuffers_identifier
+#define reflection_Schema_file_identifier "BFBS"
#endif
/* deprecated, use reflection_Schema_file_identifier */
#ifndef reflection_Schema_identifier
-#define reflection_Schema_identifier flatbuffers_identifier
+#define reflection_Schema_identifier "BFBS"
#endif
#define reflection_Schema_type_hash ((flatbuffers_thash_t)0xfaf93779)
#define reflection_Schema_type_identifier "\x79\x37\xf9\xfa"
+#ifndef reflection_Schema_file_extension
+#define reflection_Schema_file_extension "bfbs"
+#endif
typedef int8_t reflection_BaseType_enum_t;
__flatbuffers_define_integer_type(reflection_BaseType, reflection_BaseType_enum_t, 8)
diff --git a/include/flatcc/reflection/reflection_verifier.h b/include/flatcc/reflection/reflection_verifier.h
index 7d04f34df..5b5bd374a 100644
--- a/include/flatcc/reflection/reflection_verifier.h
+++ b/include/flatcc/reflection/reflection_verifier.h
@@ -1,7 +1,7 @@
#ifndef REFLECTION_VERIFIER_H
#define REFLECTION_VERIFIER_H
-/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */
+/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */
#ifndef REFLECTION_READER_H
#include "reflection_reader.h"
diff --git a/scripts/_user_build.in b/scripts/_user_build.in
index dfcc40a62..d235a0e8f 100644
--- a/scripts/_user_build.in
+++ b/scripts/_user_build.in
@@ -15,12 +15,21 @@ mkdir -p generated
cd build
+# we cannot link with debug library unless we use the sanitize flag.
+SANFLAG_DEBUG=""
+compiler_info="$($CC --version 2>&1)"
+echo "using compiler: $compiler_info"
+if echo $compiler_info | grep -q -i "clang"; then
+ SANFLAG_DEBUG="-fsanitize=undefined"
+ echo "debug sanitizer flag: $SANFLAG_DEBUG"
+fi
+
if [[ "$FLATCC_PORTABLE" = "yes" ]]; then
CFLAGS="$CFLAGS -DFLATCC_PORTABLE"
fi
CFLAGS="$CFLAGS -I ${ROOT}/include -I ${ROOT}/generated"
-CFLAGS_DEBUG=${CFLAGS_DEBUG:--g}
+CFLAGS_DEBUG=${CFLAGS_DEBUG:--g $SANFLAG_DEBUG}
CFLAGS_RELEASE=${CFLAGS_RELEASE:--O2 -DNDEBUG}
${ROOT}/bin/flatcc -a -o ${ROOT}/generated ${ROOT}/src/*.fbs
diff --git a/scripts/build.cfg.make b/scripts/build.cfg.make
index 684ecfc81..ae9c33258 100644
--- a/scripts/build.cfg.make
+++ b/scripts/build.cfg.make
@@ -1,2 +1,3 @@
FLATCC_BUILD_GEN="Unix Makefiles"
FLATCC_BUILD_CMD=make
+FLATCC_BUILD_FLAGS=""
diff --git a/scripts/build.cfg.make-32bit b/scripts/build.cfg.make-32bit
new file mode 100644
index 000000000..2299d679e
--- /dev/null
+++ b/scripts/build.cfg.make-32bit
@@ -0,0 +1,3 @@
+FLATCC_BUILD_GEN="Unix Makefiles"
+FLATCC_BUILD_CMD=make
+FLATCC_BUILD_FLAGS="-DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32"
diff --git a/scripts/build.cfg.make-concurrent b/scripts/build.cfg.make-concurrent
index 35d82f0ea..76846426b 100644
--- a/scripts/build.cfg.make-concurrent
+++ b/scripts/build.cfg.make-concurrent
@@ -1,2 +1,3 @@
FLATCC_BUILD_GEN="Unix Makefiles"
FLATCC_BUILD_CMD="make -j"
+FLATCC_BUILD_FLAGS=""
diff --git a/scripts/build.cfg.ninja b/scripts/build.cfg.ninja
index d69bb6d24..07ead7000 100644
--- a/scripts/build.cfg.ninja
+++ b/scripts/build.cfg.ninja
@@ -1,2 +1,3 @@
FLATCC_BUILD_GEN=Ninja
FLATCC_BUILD_CMD=ninja
+FLATCC_BUILD_FLAGS=""
diff --git a/scripts/initbuild.sh b/scripts/initbuild.sh
index 00561fa73..2b18cd257 100755
--- a/scripts/initbuild.sh
+++ b/scripts/initbuild.sh
@@ -36,5 +36,5 @@ mkdir -p ${ROOT}/build/Release
rm -rf ${ROOT}/build/Debug/*
rm -rf ${ROOT}/build/Release/*
-cd ${ROOT}/build/Debug && cmake -G "$FLATCC_BUILD_GEN" ../.. -DCMAKE_BUILD_TYPE=Debug
-cd ${ROOT}/build/Release && cmake -G "$FLATCC_BUILD_GEN" ../.. -DCMAKE_BUILD_TYPE=Release
+cd ${ROOT}/build/Debug && cmake -G "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. -DCMAKE_BUILD_TYPE=Debug
+cd ${ROOT}/build/Release && cmake -G "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. -DCMAKE_BUILD_TYPE=Release
diff --git a/scripts/test.sh b/scripts/test.sh
index 0728e1660..d87924b9e 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -36,7 +36,3 @@ else
echo "DEBUG TEST PASSED"
fi
-if [ ! -e ${ROOT}/build/reflection_enabled ]; then
- echo "(reflection disabled, skipping affected test and example)"
-fi
-
diff --git a/src/compiler/codegen_c_json_parser.c b/src/compiler/codegen_c_json_parser.c
index 29ebc85dd..307ce76f4 100644
--- a/src/compiler/codegen_c_json_parser.c
+++ b/src/compiler/codegen_c_json_parser.c
@@ -8,8 +8,6 @@
#include
#endif
-#include "flatcc/portable/pattributes.h" /* fallthrough */
-
#define PRINTLN_SPMAX 64
static char println_spaces[PRINTLN_SPMAX];
@@ -1424,7 +1422,7 @@ static int gen_struct_parser(fb_output_t *out, fb_compound_type_t *ct)
println(out, "return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_runtime);");
unindent(); println(out, "}");
println(out, "");
- println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, int flags, const char *fid)", snt.text);
+ println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid)", snt.text);
println(out, "{"); indent();
println(out, "return flatcc_json_parser_struct_as_root(B, ctx, buf, bufsiz, flags, fid, %s_parse_json_struct);",
snt.text);
@@ -1527,7 +1525,7 @@ static int gen_table_parser(fb_output_t *out, fb_compound_type_t *ct)
println(out, "return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_runtime);");
unindent(); println(out, "}");
println(out, "");
- println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, int flags, const char *fid)", snt.text);
+ println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid)", snt.text);
println(out, "{"); indent();
println(out, "return flatcc_json_parser_table_as_root(B, ctx, buf, bufsiz, flags, fid, %s_parse_json_table);",
snt.text);
@@ -1661,7 +1659,7 @@ static int gen_root_table_parser(fb_output_t *out, fb_compound_type_t *ct)
println(out, "static int %s_parse_json(flatcc_builder_t *B, flatcc_json_parser_t *ctx,", out->S->basename);
indent(); indent();
- println(out, "const char *buf, size_t bufsiz, int flags)");
+ println(out, "const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags)");
unindent(); unindent();
println(out, "{"); indent();
println(out, "flatcc_json_parser_t parser;");
@@ -1767,10 +1765,10 @@ static int gen_json_parser_prototypes(fb_output_t *out)
println(out, "static int %s_parse_json(flatcc_builder_t *B, flatcc_json_parser_t *ctx,",
out->S->basename);
indent(); indent();
- println(out, "const char *buf, size_t bufsiz, int flags);");
+ println(out, "const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags);");
unindent(); unindent();
println(out, "");
- fallthrough;
+ break;
default:
break;
}
diff --git a/src/compiler/codegen_c_json_printer.c b/src/compiler/codegen_c_json_printer.c
index 2bdaba63d..efc4c3d14 100644
--- a/src/compiler/codegen_c_json_printer.c
+++ b/src/compiler/codegen_c_json_printer.c
@@ -6,8 +6,6 @@
#include
#endif
-#include "flatcc/portable/pattributes.h" /* fallthrough */
-
static int gen_json_printer_pretext(fb_output_t *out)
{
fprintf(out->fp,
@@ -583,7 +581,7 @@ static int gen_json_printer_prototypes(fb_output_t *out)
fprintf(out->fp,
"static int %s_print_json(flatcc_json_printer_t *ctx, const char *buf, size_t bufsiz);\n\n",
out->S->basename);
- fallthrough;
+ break;
default:
break;
}
diff --git a/src/compiler/codegen_c_reader.c b/src/compiler/codegen_c_reader.c
index 67f8055bc..6de0f2166 100644
--- a/src/compiler/codegen_c_reader.c
+++ b/src/compiler/codegen_c_reader.c
@@ -1593,7 +1593,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct)
const char *nsc = out->nsc;
fb_scoped_name_t snt;
fb_scoped_name_t snref;
- uint64_t present_id;
fb_literal_t literal;
int is_optional;
@@ -1629,7 +1628,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct)
for (sym = ct->members; sym; sym = sym->link) {
current_key_processed = 0;
member = (fb_member_t *)sym;
- present_id = member->id;
is_primary_key = ct->primary_key == member;
is_optional = !!(member->flags & fb_fm_optional);
print_doc(out, "", member->doc);
@@ -1807,7 +1805,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct)
}
break;
case fb_is_union:
- present_id--;
fprintf(out->fp,
"__%sdefine_union_field(%s, %"PRIu64", %s, %.*s, %s, %u)\n",
nsc, nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r);
@@ -1833,7 +1830,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct)
break;
}
if (member->type.ct->symbol.kind == fb_is_union) {
- present_id--;
fprintf(out->fp,
"__%sdefine_union_vector_field(%s, %"PRIu64", %s, %.*s, %s, %u)\n",
nsc, nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r);
diff --git a/src/compiler/codegen_schema.c b/src/compiler/codegen_schema.c
index 0313d9ef8..d0c9fde3c 100644
--- a/src/compiler/codegen_schema.c
+++ b/src/compiler/codegen_schema.c
@@ -465,17 +465,15 @@ static void sort_objects(void *buffer)
static FILE *open_file(fb_options_t *opts, fb_schema_t *S)
{
FILE *fp = 0;
- char *path;
+ char *path = 0, *ext = 0;
const char *prefix = opts->outpath ? opts->outpath : "";
size_t len, prefix_len = strlen(prefix);
const char *name;
- const char *ext;
name = S->basename;
len = strlen(name);
- ext = flatbuffers_extension;
-
+ ext = fb_create_path_ext(".", flatbuffers_extension);
/* We generally should not use cgen options here, but in this case it makes sense. */
if (opts->gen_stdout) {
return stdout;
@@ -486,6 +484,7 @@ static FILE *open_file(fb_options_t *opts, fb_schema_t *S)
fprintf(stderr, "error opening file for writing binary schema: %s\n", path);
}
free(path);
+ free(ext);
return fp;
}
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 250d6600d..006bb86f0 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -16,7 +16,6 @@
#include "codegen.h"
#include "fileio.h"
#include "pstrutil.h"
-#include "flatcc/portable/pattributes.h" /* fallthrough */
#include "flatcc/portable/pparseint.h"
void fb_default_error_out(void *err_ctx, const char *buf, size_t len)
@@ -156,8 +155,6 @@ void error_ref_sym(fb_parser_t *P, fb_ref_t *ref, const char *msg, fb_symbol_t *
/* Accept numbers like -0x42 as integer literals. */
#define LEX_HEX_NUMERIC
-#define lex_isblank(c) ((c) == ' ' || (c) == '\t')
-
#include "parser.h"
#ifdef LEX_DEBUG
@@ -920,7 +917,7 @@ static void parse_enum_decl(fb_parser_t *P, fb_compound_type_t *ct)
case tok_kw_float32:
case tok_kw_float64:
error_tok(P, ct->type.t, "integral type expected");
- fallthrough;
+ break;
default:
break;
}
@@ -1070,7 +1067,7 @@ static void parse_namespace(fb_parser_t *P)
if (optional(P, ';') && t) {
/* Revert to global namespace. */
- P->current_scope = 0;
+ P->current_scope = P->root_scope;
return;
}
if (P->token->id != LEX_TOK_ID) {
@@ -1273,7 +1270,6 @@ static void push_token(fb_parser_t *P, long id, const char *first, const char *l
size_t offset;
fb_token_t *t;
- P->te = P->ts + P->tcapacity;
if (P->token == P->te) {
offset = (size_t)(P->token - P->ts);
P->tcapacity = P->tcapacity ? 2 * P->tcapacity : 1024;
@@ -1336,10 +1332,10 @@ static void inject_token(fb_token_t *t, const char *lex, long id)
push_token((fb_parser_t*)context, LEX_TOK_COMMENT_UNTERMINATED, pos, pos)
#define lex_emit_comment_ctrl(pos) \
- if (lex_isblank(*pos)) { \
+ if (lex_isblank(*pos) || !lex_isctrl(*pos)) { \
push_comment((fb_parser_t*)context, pos, pos + 1); \
} else { \
- push_token((fb_parser_t*)context, LEX_TOK_COMMENT_CTRL, \
+ push_token((fb_parser_t*)context, LEX_TOK_CTRL, \
pos, pos + 1); \
}
@@ -1433,11 +1429,14 @@ int fb_init_parser(fb_parser_t *P, fb_options_t *opts, const char *name,
P->schema.name.name.s.s = s;
P->schema.name.name.s.len = (int)n;
checkmem((P->schema.errorname = fb_create_basename(name, name_len, "")));
+ P->schema.prefix.s = "";
+ P->schema.prefix.len = 0;
if (opts->ns) {
P->schema.prefix.s = (char *)opts->ns;
P->schema.prefix.len = (int)strlen(opts->ns);
}
- P->current_scope = fb_add_scope(P, 0);
+ P->root_scope = fb_add_scope(P, 0);
+ P->current_scope = P->root_scope;
assert(P->current_scope == fb_scope_table_find(&P->schema.root_schema->scope_index, 0, 0));
return 0;
}
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index ef2ecc15a..f09337fe2 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -71,6 +71,7 @@ struct fb_parser {
int has_schema;
fb_options_t opts;
fb_schema_t schema;
+ fb_scope_t *root_scope;
fb_scope_t *current_scope;
char *path;
char *referer_path;
diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c
index a2866cf33..d0a766a61 100644
--- a/src/compiler/semantics.c
+++ b/src/compiler/semantics.c
@@ -11,8 +11,6 @@
#include
#endif
-#include "flatcc/portable/pattributes.h" /* fallthrough */
-
/* Same order as enum! */
static const char *fb_known_attribute_names[] = {
"",
@@ -131,10 +129,11 @@ static inline void set_type_hash(fb_compound_type_t *ct)
uint32_t hash;
hash = fb_hash_fnv1a_32_init();
- if (ct->scope)
- for (name = ct->scope->name; name; name = name->link) {
- hash = fb_hash_fnv1a_32_append(hash, name->ident->text, (size_t)name->ident->len);
- hash = fb_hash_fnv1a_32_append(hash, ".", 1);
+ if (ct->scope) {
+ for (name = ct->scope->name; name; name = name->link) {
+ hash = fb_hash_fnv1a_32_append(hash, name->ident->text, (size_t)name->ident->len);
+ hash = fb_hash_fnv1a_32_append(hash, ".", 1);
+ }
}
sym = &ct->symbol;
hash = fb_hash_fnv1a_32_append(hash, sym->ident->text, (size_t)sym->ident->len);
@@ -524,7 +523,6 @@ static int analyze_struct(fb_parser_t *P, fb_compound_type_t *ct)
member = (fb_member_t *)sym;
switch (member->type.type) {
case vt_fixed_array_type:
- /* fall through */
case vt_scalar_type:
t = member->type.t;
member->type.st = map_scalar_token_type(t);
@@ -537,7 +535,6 @@ static int analyze_struct(fb_parser_t *P, fb_compound_type_t *ct)
member->size = size * member->type.len;
break;
case vt_fixed_array_compound_type_ref:
- /* fall through */
case vt_compound_type_ref:
/* Enums might not be valid, but then it would be detected earlier. */
if (member->type.ct->symbol.kind == fb_is_enum) {
@@ -617,7 +614,7 @@ static int analyze_struct(fb_parser_t *P, fb_compound_type_t *ct)
}
ct->symbol.flags |= fb_circular_closed;
- ct->symbol.flags &= ~fb_circular_open;
+ ct->symbol.flags &= (uint16_t)~fb_circular_open;
ct->order = P->schema.ordered_structs;
P->schema.ordered_structs = ct;
return ret;
@@ -701,8 +698,9 @@ static int process_struct(fb_parser_t *P, fb_compound_type_t *ct)
switch (member->type.type) {
case vt_fixed_array_type_ref:
key_ok = 0;
- fallthrough;
+ goto lbl_type_ref;
case vt_type_ref:
+lbl_type_ref:
type_sym = lookup_type_reference(P, ct->scope, member->type.ref);
if (!type_sym) {
error_ref_sym(P, member->type.ref, "unknown type reference used with struct field", sym);
@@ -1146,7 +1144,9 @@ static int process_table(fb_parser_t *P, fb_compound_type_t *ct)
member->type.type = vt_invalid;
continue;
}
- if (P->opts.strict_enum_init && !(member->flags & fb_fm_optional)) {
+ /* Bitflags can have complex combinations of values, and do not nativele have a 0 value. */
+ if (P->opts.strict_enum_init && !(member->type.ct->metadata_flags & fb_f_bit_flags)
+ && !(member->flags & fb_fm_optional)) {
if (!is_in_value_set(&member->type.ct->value_set, &member->value)) {
error_sym(P, sym, "initializer does not match a defined enum value");
member->type.type = vt_invalid;
@@ -1164,6 +1164,7 @@ static int process_table(fb_parser_t *P, fb_compound_type_t *ct)
continue;
}
if (P->opts.strict_enum_init) {
+ /* TODO: consider if this error is necessary for bit_flags - flatc 2.0.0 errors on this. */
if (!is_in_value_set(&member->type.ct->value_set, &member->value)) {
error_sym_2(P, sym,
"enum type requires an explicit initializer because it has no 0 value", type_sym);
@@ -1545,7 +1546,7 @@ static int process_enum(fb_parser_t *P, fb_compound_type_t *ct)
fb_symbol_t *sym, *old, *type_sym;
fb_member_t *member;
fb_metadata_t *knowns[KNOWN_ATTR_COUNT];
- fb_value_t index = { 0 };
+ fb_value_t index = { { { 0 } }, 0, 0 };
fb_value_t old_index;
int first = 1;
int bit_flags = 0;
diff --git a/src/runtime/builder.c b/src/runtime/builder.c
index 9f54d884f..961bd2208 100644
--- a/src/runtime/builder.c
+++ b/src/runtime/builder.c
@@ -177,7 +177,7 @@ int flatcc_builder_default_alloc(void *alloc_context, iovec_t *b, size_t request
return 0;
}
-#define T_ptr(base, pos) ((void *)((uint8_t *)(base) + (uoffset_t)(pos)))
+#define T_ptr(base, pos) ((void *)((size_t)(base) + (size_t)(pos)))
#define ds_ptr(pos) (T_ptr(B->buffers[flatcc_builder_alloc_ds].iov_base, (pos)))
#define vs_ptr(pos) (T_ptr(B->buffers[flatcc_builder_alloc_vs].iov_base, (pos)))
#define pl_ptr(pos) (T_ptr(B->buffers[flatcc_builder_alloc_pl].iov_base, (pos)))
@@ -698,7 +698,8 @@ static inline flatcc_builder_ref_t emit_back(flatcc_builder_t *B, iov_state_t *i
return ref + 1;
}
-static int align_to_block(flatcc_builder_t *B, uint16_t *align, uint16_t block_align, int is_nested)
+/* If nested we cannot pad the end of the buffer without moving the entire buffer, so we don't. */
+static int align_buffer_end(flatcc_builder_t *B, uint16_t *align, uint16_t block_align, int is_nested)
{
size_t end_pad;
iov_state_t iov;
@@ -708,7 +709,7 @@ static int align_to_block(flatcc_builder_t *B, uint16_t *align, uint16_t block_a
get_min_align(align, block_align);
/* Pad end of buffer to multiple. */
if (!is_nested) {
- end_pad = back_pad(B, block_align);
+ end_pad = back_pad(B, *align);
if (end_pad) {
init_iov();
push_iov(_pad, end_pad);
@@ -723,13 +724,13 @@ static int align_to_block(flatcc_builder_t *B, uint16_t *align, uint16_t block_a
flatcc_builder_ref_t flatcc_builder_embed_buffer(flatcc_builder_t *B,
uint16_t block_align,
- const void *data, size_t size, uint16_t align, int flags)
+ const void *data, size_t size, uint16_t align, flatcc_builder_buffer_flags_t flags)
{
uoffset_t size_field, pad;
iov_state_t iov;
- int with_size = flags & flatcc_builder_with_size;
+ int with_size = (flags & flatcc_builder_with_size) != 0;
- if (align_to_block(B, &align, block_align, !is_top_buffer(B))) {
+ if (align_buffer_end(B, &align, block_align, !is_top_buffer(B))) {
return 0;
}
pad = front_pad(B, (uoffset_t)(size + (with_size ? field_size : 0)), align);
@@ -744,7 +745,7 @@ flatcc_builder_ref_t flatcc_builder_embed_buffer(flatcc_builder_t *B,
flatcc_builder_ref_t flatcc_builder_create_buffer(flatcc_builder_t *B,
const char identifier[identifier_size], uint16_t block_align,
- flatcc_builder_ref_t object_ref, uint16_t align, int flags)
+ flatcc_builder_ref_t object_ref, uint16_t align, flatcc_builder_buffer_flags_t flags)
{
flatcc_builder_ref_t buffer_ref;
uoffset_t header_pad, id_size = 0;
@@ -754,7 +755,7 @@ flatcc_builder_ref_t flatcc_builder_create_buffer(flatcc_builder_t *B,
int is_nested = (flags & flatcc_builder_is_nested) != 0;
int with_size = (flags & flatcc_builder_with_size) != 0;
- if (align_to_block(B, &align, block_align, is_nested)) {
+ if (align_buffer_end(B, &align, block_align, is_nested)) {
return 0;
}
set_min_align(B, align);
@@ -808,7 +809,7 @@ flatcc_builder_ref_t flatcc_builder_create_struct(flatcc_builder_t *B, const voi
}
int flatcc_builder_start_buffer(flatcc_builder_t *B,
- const char identifier[identifier_size], uint16_t block_align, int flags)
+ const char identifier[identifier_size], uint16_t block_align, flatcc_builder_buffer_flags_t flags)
{
/*
* This saves the parent `min_align` in the align field since we
@@ -820,7 +821,11 @@ int flatcc_builder_start_buffer(flatcc_builder_t *B,
return -1;
}
/* B->align now has parent min_align, and child frames will save it. */
- B->min_align = 1;
+ /* Since we allow objects to be created before the buffer at top level,
+ we need to respect min_align in that case. */
+ if (!is_top_buffer(B) || B->min_align == 0) {
+ B->min_align = 1;
+ }
/* Save the parent block align, and set proper defaults for this buffer. */
frame(container.buffer.block_align) = B->block_align;
B->block_align = block_align;
@@ -845,9 +850,9 @@ int flatcc_builder_start_buffer(flatcc_builder_t *B,
flatcc_builder_ref_t flatcc_builder_end_buffer(flatcc_builder_t *B, flatcc_builder_ref_t root)
{
flatcc_builder_ref_t buffer_ref;
- int flags;
+ flatcc_builder_buffer_flags_t flags;
- flags = B->buffer_flags & flatcc_builder_with_size;
+ flags = (flatcc_builder_buffer_flags_t)B->buffer_flags & flatcc_builder_with_size;
flags |= is_top_buffer(B) ? 0 : flatcc_builder_is_nested;
check(frame(type) == flatcc_builder_buffer, "expected buffer frame");
set_min_align(B, B->block_align);
@@ -859,6 +864,8 @@ flatcc_builder_ref_t flatcc_builder_end_buffer(flatcc_builder_t *B, flatcc_build
B->nest_id = frame(container.buffer.nest_id);
B->identifier = frame(container.buffer.identifier);
B->buffer_flags = frame(container.buffer.flags);
+ B->block_align = frame(container.buffer.block_align);
+
exit_frame(B);
return buffer_ref;
}
@@ -1327,6 +1334,7 @@ flatcc_builder_ref_t flatcc_builder_end_table(flatcc_builder_t *B)
flatcc_builder_ref_t table_ref, vt_ref;
int pl_count;
voffset_t *pl;
+ size_t tsize;
check(frame(type) == flatcc_builder_table, "expected table frame");
@@ -1341,7 +1349,14 @@ flatcc_builder_ref_t flatcc_builder_end_table(flatcc_builder_t *B)
* initial vtable offset field. Therefore `field_size` is added here
* to the total table size in the vtable.
*/
- vt[1] = (voffset_t)(B->ds_offset + field_size);
+ tsize = (size_t)(B->ds_offset + field_size);
+ /*
+ * Tables are limited to 64K in standard FlatBuffers format due to the voffset
+ * 16 bit size, but we must also be able to store the table size, so the
+ * table payload has to be slightly less than that.
+ */
+ check(tsize <= FLATBUFFERS_VOFFSET_MAX, "table too large");
+ vt[1] = (voffset_t)tsize;
FLATCC_BUILDER_UPDATE_VT_HASH(B->vt_hash, (uint32_t)vt[0], (uint32_t)vt[1]);
/* Find already emitted vtable, or emit a new one. */
if (!(vt_ref = flatcc_builder_create_cached_vtable(B, vt, vt_size, B->vt_hash))) {
diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c
index 313bd8085..4472af2d8 100644
--- a/src/runtime/json_parser.c
+++ b/src/runtime/json_parser.c
@@ -141,11 +141,10 @@ const char *flatcc_json_parser_space_ext(flatcc_json_parser_t *ctx, const char *
++buf;
}
while (buf != end && *buf <= 0x20) {
- /* Fall through comments needed to silence gcc 7 warnings. */
switch (*buf) {
case 0x0d: buf += (end - buf > 1 && buf[1] == 0x0a);
/* Consume following LF or treating CR as LF. */
- fallthrough;
+ ++ctx->line; ctx->line_start = ++buf; continue;
case 0x0a: ++ctx->line; ctx->line_start = ++buf; continue;
case 0x09: ++buf; continue;
case 0x20: goto again; /* Don't consume here, sync with power of 2 spaces. */
@@ -259,7 +258,7 @@ static inline int decode_utf16_surrogate_pair(uint32_t high, uint32_t low, char
}
-/*
+/*
* UTF-8 code points can have up to 4 bytes but JSON can only
* encode up to 3 bytes via the \uXXXX syntax.
* To handle the range U+10000..U+10FFFF two UTF-16 surrogate
@@ -329,7 +328,7 @@ const char *flatcc_json_parser_string_escape(flatcc_json_parser_t *ctx, const ch
return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_invalid_escape);
};
/* If a high UTF-16 surrogate half pair was detected */
- if (u >= 0xd800 && u <= 0xdbff &&
+ if (u >= 0xd800 && u <= 0xdbff &&
/* and there is space for a matching low half pair */
end - buf >= 12 &&
/* and there is a second escape following immediately */
@@ -344,7 +343,7 @@ const char *flatcc_json_parser_string_escape(flatcc_json_parser_t *ctx, const ch
return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_invalid_escape);
}
return buf + 12;
- /*
+ /*
* Otherwise decode unmatched surrogate pairs as is any
* other UTF-8. Some systems might depend on these surviving.
* Leave ignored errors for the next parse step.
@@ -489,7 +488,7 @@ const char *flatcc_json_parser_match_constant(flatcc_json_parser_t *ctx, const c
*more = 0;
return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_invalid_escape);
case '\"':
- buf = flatcc_json_parser_space(ctx, buf + 1, 0);
+ buf = flatcc_json_parser_space(ctx, buf + 1, end);
*more = 0;
return buf;
}
@@ -855,7 +854,7 @@ const char *flatcc_json_parser_char_array(flatcc_json_parser_t *ctx,
if (k > n) {
if (!(ctx->flags & flatcc_json_parser_f_skip_array_overflow)) {
return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_array_overflow);
- }
+ }
k = n; /* Might truncate UTF-8. */
}
memcpy(s, mark, k);
@@ -869,7 +868,7 @@ const char *flatcc_json_parser_char_array(flatcc_json_parser_t *ctx,
if (k > n) {
if (!(ctx->flags & flatcc_json_parser_f_skip_array_overflow)) {
return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_array_overflow);
- }
+ }
k = n; /* Might truncate UTF-8. */
}
memcpy(s, mark, k);
@@ -880,7 +879,7 @@ const char *flatcc_json_parser_char_array(flatcc_json_parser_t *ctx,
if (ctx->flags & flatcc_json_parser_f_reject_array_underflow) {
return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_array_underflow);
}
- memset(s, 0, n - k);
+ memset(s, 0, n);
}
return flatcc_json_parser_string_end(ctx, buf, end);
}
@@ -1258,12 +1257,12 @@ const char *flatcc_json_parser_union_type_vector(flatcc_json_parser_t *ctx,
}
int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx,
- const char *buf, size_t bufsiz, int flags, const char *fid,
+ const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid,
flatcc_json_parser_table_f *parser)
{
flatcc_json_parser_t _ctx;
flatcc_builder_ref_t root;
- int builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0;
+ flatcc_builder_buffer_flags_t builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0;
ctx = ctx ? ctx : &_ctx;
flatcc_json_parser_init(ctx, B, buf, buf + bufsiz, flags);
@@ -1278,12 +1277,12 @@ int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t *
}
int flatcc_json_parser_struct_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx,
- const char *buf, size_t bufsiz, int flags, const char *fid,
+ const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid,
flatcc_json_parser_table_f *parser)
{
flatcc_json_parser_t _ctx;
flatcc_builder_ref_t root;
- int builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0;
+ flatcc_builder_buffer_flags_t builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0;
ctx = ctx ? ctx : &_ctx;
flatcc_json_parser_init(ctx, B, buf, buf + bufsiz, flags);
diff --git a/src/runtime/verifier.c b/src/runtime/verifier.c
index 1831fcf6b..9c43bf613 100644
--- a/src/runtime/verifier.c
+++ b/src/runtime/verifier.c
@@ -265,7 +265,7 @@ static inline int verify_string(const void *buf, uoffset_t end, uoffset_t base,
base += offset;
n = read_uoffset(buf, base);
base += offset_size;
- verify(end - base >= n + 1, flatcc_verify_error_string_out_of_range);
+ verify(end - base > n, flatcc_verify_error_string_out_of_range);
verify(((uint8_t *)buf + base)[n] == 0, flatcc_verify_error_string_not_zero_terminated);
return flatcc_verify_ok;
}
diff --git a/test/cgen_test/cgen_test.c b/test/cgen_test/cgen_test.c
index 94f4bba9b..6d58ed1a9 100644
--- a/test/cgen_test/cgen_test.c
+++ b/test/cgen_test/cgen_test.c
@@ -41,7 +41,7 @@
#include
#include "flatcc/flatcc.h"
-int main()
+int main(void)
{
const char *name = "../xyzzy.fbs";
diff --git a/test/emit_test/emit_test.c b/test/emit_test/emit_test.c
index fa18034ac..a271a3159 100644
--- a/test/emit_test/emit_test.c
+++ b/test/emit_test/emit_test.c
@@ -2,8 +2,13 @@
#include
#include "emit_test_builder.h"
#include "flatcc/support/hexdump.h"
+#include "flatcc/portable/pparsefp.h"
#define test_assert(x) do { if (!(x)) { assert(0); return -1; }} while(0)
+/* Direct floating point comparisons are not always directly comparable,
+ * especially not for GCC 32-bit compilers. */
+#define test_assert_floateq(x, y) test_assert(parse_float_is_equal((x), (y)))
+#define test_assert_doubleeq(x, y) test_assert(parse_double_is_equal((x), (y)))
int dbg_emitter(void *emit_context,
const flatcc_iovec_t *iov, int iov_count,
@@ -61,13 +66,13 @@ int emit_test(void)
"\x04\x00\x00\x00\xd4\xff\xff\xff\x2a\x00\x00\x00\x00\x00\x00\x00"
"\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00"
"\x00\x00\x80\x3f\xcd\xcc\x8c\x3f\x9a\x99\x99\x3f\x66\x66\xa6\x3f"
- "\x0a\x00\x11\x00\x04\x00\x10\x00\x0c\x00";
+ "\x0a\x00\x11\x00\x04\x00\x10\x00\x0c\x00\x00\x00";
#else
"\x00\x00\x00\x04\xff\xff\xff\xd4\x00\x00\x00\x00\x00\x00\x00\x2a"
"\x00\x00\x00\x0c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"
"\x3f\x80\x00\x00\x3f\x8c\xcc\xcd\x3f\x99\x99\x9a\x3f\xa6\x66\x66"
- "\x00\x0a\x00\x11\x00\x04\x00\x10\x00\x0c";
+ "\x00\x0a\x00\x11\x00\x04\x00\x10\x00\x0c\x00\x00";
#endif
size_t size;
@@ -103,7 +108,8 @@ int emit_test(void)
fprintf(stderr, "buffer size: %d\n", (int)size);
hexdump("emit_test", buf, size, stderr);
- test_assert(size == 58);
+ /* 58 without tail padding, 60 with padding to 4 byte alignment. */
+ test_assert(size == 60);
test_assert(sizeof(expect) - 1 == size);
test_assert(0 == memcmp(buf, expect, size));
@@ -112,7 +118,7 @@ int emit_test(void)
test_assert(time == 42);
test_assert(main_device(mt) == 1);
test_assert(flatbuffers_float_vec_len(main_samples(mt)) == 4);
- test_assert(flatbuffers_float_vec_at(main_samples(mt), 2) == 1.2f);
+ test_assert_floateq(flatbuffers_float_vec_at(main_samples(mt), 2), 1.2f);
/* We use get_direct_buffer, so we can't clear the builder until last. */
flatcc_builder_clear(B);
diff --git a/test/json_test/test_basic_parse.c b/test/json_test/test_basic_parse.c
index de27ee775..7b8f4bac9 100644
--- a/test/json_test/test_basic_parse.c
+++ b/test/json_test/test_basic_parse.c
@@ -277,7 +277,7 @@ const char *test(flatcc_builder_t *B, const char *buf, const char *end, int *ret
return buf;
}
-int main()
+int main(void)
{
int ret = -1;
flatcc_builder_t builder;
diff --git a/test/json_test/test_json.c b/test/json_test/test_json.c
index 6d6698b80..aeee13a04 100644
--- a/test/json_test/test_json.c
+++ b/test/json_test/test_json.c
@@ -47,7 +47,7 @@ static const struct test_scope Movie = {
int test_json(const struct test_scope *scope, char *json,
char *expect, int expect_err,
- int parse_flags, int print_flags, int line)
+ flatcc_json_parser_flags_t parse_flags, flatcc_json_printer_flags_t print_flags, int line)
{
int ret = -1;
int err;
@@ -582,7 +582,7 @@ int fixed_array_tests(void)
* covered in the printer and parser tests using the golden data
* set.
*/
-int main()
+int main(void)
{
BEGIN_TEST(Monster);
diff --git a/test/json_test/test_json_parser.c b/test/json_test/test_json_parser.c
index de2b738b2..a985cfab5 100644
--- a/test/json_test/test_json_parser.c
+++ b/test/json_test/test_json_parser.c
@@ -80,7 +80,7 @@ int test_parse(void)
flatcc_builder_t builder;
flatcc_builder_t *B = &builder;
int ret = -1;
- int flags = 0;
+ flatcc_json_parser_flags_t flags = 0;
flatcc_builder_init(B);
diff --git a/test/monster_test/monster_test.c b/test/monster_test/monster_test.c
index 400415c5d..f3150d8e3 100644
--- a/test/monster_test/monster_test.c
+++ b/test/monster_test/monster_test.c
@@ -5,6 +5,7 @@
#include "flatcc/support/hexdump.h"
#include "flatcc/support/elapsed.h"
+#include "flatcc/portable/pparsefp.h"
#include "../../config/config.h"
/*
@@ -162,8 +163,8 @@ int test_type_aliases(flatcc_builder_t *B)
if (ns(TypeAliases_u16(ta)) != UINT16_MAX) goto failed;
if (ns(TypeAliases_u32(ta)) != UINT32_MAX) goto failed;
if (ns(TypeAliases_u64(ta)) != UINT64_MAX) goto failed;
- if (ns(TypeAliases_f32(ta)) != 2.3f) goto failed;
- if (ns(TypeAliases_f64(ta)) != 2.3) goto failed;
+ if (!parse_float_is_equal(ns(TypeAliases_f32(ta)), 2.3f)) goto failed;
+ if (!parse_double_is_equal(ns(TypeAliases_f64(ta)), 2.3)) goto failed;
if (sizeof(ns(TypeAliases_i8(ta))) != 1) goto failed;
if (sizeof(ns(TypeAliases_i16(ta))) != 2) goto failed;
if (sizeof(ns(TypeAliases_i32(ta))) != 4) goto failed;
@@ -371,13 +372,17 @@ int verify_monster(void *buffer)
if ((size_t)vec & 15) {
printf("Force align of Vec3 struct not correct\n");
}
- /* -3.2f is actually -3.20000005 and not -3.2 due to representation loss. */
- if (ns(Vec3_z(vec)) != -3.2f) {
+ /* -3.2f is actually -3.20000005 and not -3.2 due to representation loss.
+ * For 32-bit GCC compilers, -3.2f might be another value, so use lower
+ * precision portable comparison. */
+ if (!parse_float_is_equal(ns(Vec3_z(vec)), -3.2f)) {
printf("Position failing on z coordinate\n");
return -1;
}
if (nsc(is_native_pe())) {
- if (vec->x != 1.0f || vec->y != 2.0f || vec->z != -3.2f) {
+ if (!parse_float_is_equal(vec->x, 1.0f) ||
+ !parse_float_is_equal(vec->y, 2.0f) ||
+ !parse_float_is_equal(vec->z, -3.2f)) {
printf("Position is incorrect\n");
return -1;
}
@@ -396,7 +401,9 @@ int verify_monster(void *buffer)
*/
ns(Vec3_clear(&v)); /* Not strictly needed here. */
ns(Vec3_copy_from_pe(&v, vec));
- if (v.x != 1.0f || v.y != 2.0f || v.z != -3.2f) {
+ if (!parse_float_is_equal(v.x, 1.0f) ||
+ !parse_float_is_equal(v.y, 2.0f) ||
+ !parse_float_is_equal(v.z, -3.2f)) {
printf("Position is incorrect after copy\n");
return -1;
}
@@ -1601,7 +1608,7 @@ int test_clone_slice(flatcc_builder_t *B)
printf("sliced bool has wrong content\n");
goto done;
}
- if (ns(Monster_pos(mon2)->x != -42.3f)) {
+ if (!parse_float_is_equal(ns(Monster_pos(mon2))->x, -42.3f)) {
printf("cloned pos struct failed\n");
goto done;
};
@@ -2561,8 +2568,8 @@ int test_struct_buffer(flatcc_builder_t *B)
/* Convert buffer to native in place - a nop on native platform. */
v = (ns(Vec3_t) *)vec3;
ns(Vec3_from_pe(v));
- if (v->x != 1.0f || v->y != 2.0f || v->z != 3.0f
- || v->test1 != 4.2 || v->test2 != ns(Color_Blue)
+ if (!parse_float_is_equal(v->x, 1.0f) || !parse_float_is_equal(v->y, 2.0f) || !parse_float_is_equal(v->z, 3.0f)
+ || !parse_double_is_equal(v->test1, 4.2) || v->test2 != ns(Color_Blue)
|| v->test3.a != 2730 || v->test3.b != -17
) {
printf("struct buffer not valid\n");
@@ -2626,8 +2633,8 @@ int test_typed_struct_buffer(flatcc_builder_t *B)
/* Convert buffer to native in place - a nop on native platform. */
v = (ns(Vec3_t) *)vec3;
ns(Vec3_from_pe(v));
- if (v->x != 1.0f || v->y != 2.0f || v->z != 3.0f
- || v->test1 != 4.2 || v->test2 != ns(Color_Blue)
+ if (!parse_float_is_equal(v->x, 1.0f) || !parse_float_is_equal(v->y, 2.0f) || !parse_float_is_equal(v->z, 3.0f)
+ || !parse_double_is_equal(v->test1, 4.2) || v->test2 != ns(Color_Blue)
|| v->test3.a != 2730 || v->test3.b != -17
) {
printf("struct buffer not valid\n");
diff --git a/test/test.sh b/test/test.sh
index 40dc31699..d4fae6fc9 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -83,13 +83,13 @@ $CC -O3 -DNDEBUG -DFLATBUFFERS_BENCHMARK -I ${ROOT}/include monster_test.c \
echo "running optimized version of main monster test"
./monster_test
-if [ -e ${ROOT}/build/reflection_enabled ]; then
- echo "running reflection test"
- ${ROOT}/test/reflection_test//reflection_test.sh
+# This may fail if reflection feature is disabled
+echo "running reflection test"
+${ROOT}/test/reflection_test/reflection_test.sh
- echo "running reflection sample"
- ${ROOT}/samples/reflection/build.sh
-fi
+# This may fail if reflection feature is disabled
+echo "running reflection sample"
+${ROOT}/samples/reflection/build.sh
echo "running monster sample"
${ROOT}/samples/monster/build.sh
@@ -101,6 +101,3 @@ echo "running load test with large buffer"
${ROOT}/test/load_test/load_test.sh
echo "TEST PASSED"
-if [ ! -e ${ROOT}/build/reflection_enabled ]; then
- echo "(reflection disabled, skipping affected test and example)"
-fi