diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60832d128..24d4030df 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -343,6 +343,22 @@ jobs: - name: Generate gRPC run: scripts/check-grpc-generated-code.py + build-generator-windows: + name: Check Generated Code on Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v3 + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + - name: cmake + run: cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON . + - name: build + run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64 + - name: Generate + run: python3 scripts/check_generate_code.py --flatc Release\flatc.exe + - name: Generate gRPC + run: python3 scripts/check-grpc-generated-code.py --flatc Release\flatc.exe + build-benchmarks: name: Build Benchmarks (on Linux) runs-on: ubuntu-latest diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h index 74edbce46..6d0cd2c0c 100644 --- a/include/flatbuffers/util.h +++ b/include/flatbuffers/util.h @@ -31,6 +31,7 @@ # include #endif // FLATBUFFERS_PREFER_PRINTF +#include #include #include @@ -313,6 +314,7 @@ inline bool StringToFloatImpl(T *val, const char *const str) { strtoval_impl(val, str, const_cast(&end)); auto done = (end != str) && (*end == '\0'); if (!done) *val = 0; // erase partial result + if (done && std::isnan(*val)) { *val = std::numeric_limits::quiet_NaN(); } return done; } diff --git a/scripts/check-grpc-generated-code.py b/scripts/check-grpc-generated-code.py index c9a43837a..25b4331e2 100755 --- a/scripts/check-grpc-generated-code.py +++ b/scripts/check-grpc-generated-code.py @@ -29,7 +29,7 @@ root_path = script_path.parent.absolute() print("Generating GRPC code...") generate_grpc_examples.GenerateGRPCExamples() -result = subprocess.run(["git", "diff", "--quiet"], cwd=root_path) +result = subprocess.run(["git", "diff", "--quiet", "--ignore-cr-at-eol"], cwd=root_path) if result.returncode != 0: print( diff --git a/scripts/check_generate_code.py b/scripts/check_generate_code.py index 038dc4e53..aa66734c9 100755 --- a/scripts/check_generate_code.py +++ b/scripts/check_generate_code.py @@ -26,7 +26,7 @@ script_path = Path(__file__).parent.resolve() # Get the root path as an absolute path, so all derived paths are absolute. root_path = script_path.parent.absolute() -result = subprocess.run(["git", "diff", "--quiet"], cwd=root_path) +result = subprocess.run(["git", "diff", "--quiet", "--ignore-cr-at-eol"], cwd=root_path) if result.returncode != 0: print( @@ -46,7 +46,7 @@ if platform.system() == "Windows": gen_cmd = ["py"] + gen_cmd subprocess.run(gen_cmd, cwd=root_path) -result = subprocess.run(["git", "diff", "--quiet"], cwd=root_path) +result = subprocess.run(["git", "diff", "--quiet", "--ignore-cr-at-eol"], cwd=root_path) if result.returncode != 0: print( diff --git a/scripts/generate_code.py b/scripts/generate_code.py index 1e29d755f..1a622ab8a 100755 --- a/scripts/generate_code.py +++ b/scripts/generate_code.py @@ -14,73 +14,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -import argparse import filecmp import glob -import platform import shutil import subprocess import generate_grpc_examples from pathlib import Path - -parser = argparse.ArgumentParser() -parser.add_argument( - "--flatc", - help="path of the Flat C compiler relative to the root directory", -) -parser.add_argument("--cpp-0x", action="store_true", help="use --cpp-std c++ox") -parser.add_argument( - "--skip-monster-extra", - action="store_true", - help="skip generating tests involving monster_extra.fbs", -) -parser.add_argument( - "--skip-gen-reflection", - action="store_true", - help="skip generating the reflection.fbs files", -) -args = parser.parse_args() - -# Get the path where this script is located so we can invoke the script from -# any directory and have the paths work correctly. -script_path = Path(__file__).parent.resolve() - -# Get the root path as an absolute path, so all derived paths are absolute. -root_path = script_path.parent.absolute() - -# Get the location of the flatc executable, reading from the first command line -# argument or defaulting to default names. -flatc_exe = Path( - ("flatc" if not platform.system() == "Windows" else "flatc.exe") - if not args.flatc - else args.flatc -) - -# Find and assert flatc compiler is present. -if root_path in flatc_exe.parents: - flatc_exe = flatc_exe.relative_to(root_path) -flatc_path = Path(root_path, flatc_exe) -assert flatc_path.exists(), "Cannot find the flatc compiler " + str(flatc_path) +from util import flatc, root_path, tests_path, args, flatc_path # Specify the other paths that will be referenced -tests_path = Path(root_path, "tests") swift_code_gen = Path(root_path, "tests/swift/tests/CodeGenerationTests") samples_path = Path(root_path, "samples") reflection_path = Path(root_path, "reflection") -# Execute the flatc compiler with the specified parameters -def flatc(options, schema, prefix=None, include=None, data=None, cwd=tests_path): - cmd = [str(flatc_path)] + options - if prefix: - cmd += ["-o"] + [prefix] - if include: - cmd += ["-I"] + [include] - cmd += [schema] if isinstance(schema, str) else schema - if data: - cmd += [data] if isinstance(data, str) else data - result = subprocess.run(cmd, cwd=str(cwd), check=True) - - # Generate the code for flatbuffers reflection schema def flatc_reflection(options, location, target): full_options = ["--no-prefix"] + options @@ -150,7 +96,7 @@ SWIFT_OPTS_CODE_GEN = [ "--swift", "--gen-json-emit", "--bfbs-filenames", - swift_code_gen + str(swift_code_gen) ] JAVA_OPTS = ["--java"] KOTLIN_OPTS = ["--kotlin"] diff --git a/scripts/generate_grpc_examples.py b/scripts/generate_grpc_examples.py index c5dbba51e..2192619d3 100755 --- a/scripts/generate_grpc_examples.py +++ b/scripts/generate_grpc_examples.py @@ -19,7 +19,7 @@ from pathlib import Path grpc_examples_path = Path(root_path, "grpc/examples") -greeter_schema = Path(grpc_examples_path, "greeter.fbs") +greeter_schema = str(Path(grpc_examples_path, "greeter.fbs")) COMMON_ARGS = [ "--grpc", diff --git a/scripts/util.py b/scripts/util.py index 365ba2de9..5df9531cb 100644 --- a/scripts/util.py +++ b/scripts/util.py @@ -12,20 +12,44 @@ # See the License for the specific language governing permissions and # limitations under the License. +import argparse import platform import subprocess from pathlib import Path +parser = argparse.ArgumentParser() +parser.add_argument( + "--flatc", + help="path of the Flat C compiler relative to the root directory", +) +parser.add_argument("--cpp-0x", action="store_true", help="use --cpp-std c++ox") +parser.add_argument( + "--skip-monster-extra", + action="store_true", + help="skip generating tests involving monster_extra.fbs", +) +parser.add_argument( + "--skip-gen-reflection", + action="store_true", + help="skip generating the reflection.fbs files", +) +args = parser.parse_args() + # Get the path where this script is located so we can invoke the script from # any directory and have the paths work correctly. script_path = Path(__file__).parent.resolve() # Get the root path as an absolute path, so all derived paths are absolute. root_path = script_path.parent.absolute() +tests_path = Path(root_path, "tests") # Get the location of the flatc executable, reading from the first command line # argument or defaulting to default names. -flatc_exe = Path("flatc" if not platform.system() == "Windows" else "flatc.exe") +flatc_exe = Path( + ("flatc" if not platform.system() == "Windows" else "flatc.exe") + if not args.flatc + else args.flatc +) # Find and assert flatc compiler is present. if root_path in flatc_exe.parents: @@ -34,18 +58,13 @@ flatc_path = Path(root_path, flatc_exe) assert flatc_path.exists(), "Cannot find the flatc compiler " + str(flatc_path) # Execute the flatc compiler with the specified parameters -def flatc(options, schema, prefix=None, include=None, data=None, cwd=root_path): +def flatc(options, schema, prefix=None, include=None, data=None, cwd=tests_path): cmd = [str(flatc_path)] + options if prefix: cmd += ["-o"] + [prefix] if include: cmd += ["-I"] + [include] - if isinstance(schema, Path): - cmd += [str(schema)] - elif isinstance(schema, str): - cmd += [schema] - else: - cmd += schema + cmd += [schema] if isinstance(schema, str) else schema if data: cmd += [data] if isinstance(data, str) else data - return subprocess.check_call(cmd, cwd=str(cwd)) + result = subprocess.run(cmd, cwd=str(cwd), check=True)