Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65cec8d9df | ||
|
|
c4704f4b06 | ||
|
|
cad07e6e16 | ||
|
|
82f0ac4fbd |
+56
-65
@@ -44,11 +44,11 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build && ctest --verbose -j1 .
|
||||
cd build && ctest -j1 .
|
||||
|
||||
linux:
|
||||
name: Ubuntu Latest GCC
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
@@ -86,11 +86,11 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build && ctest --verbose -j1 . -C Release
|
||||
cd build && ctest -j1 . -C Release
|
||||
|
||||
linux_clang:
|
||||
name: Ubuntu Latest Clang
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
@@ -128,7 +128,7 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build && ctest --verbose -j1 . -C Release
|
||||
cd build && ctest -j1 . -C Release
|
||||
|
||||
|
||||
osx:
|
||||
@@ -160,68 +160,62 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build && ctest --verbose -j1 . -C Release
|
||||
cd build && ctest -j1 . -C Release
|
||||
|
||||
brlcad_linux:
|
||||
name: BRL-CAD Linux step-g Test
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Setup - Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@master
|
||||
|
||||
- name: Setup - System
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install re2c astyle xsltproc libxml2-utils
|
||||
sudo apt-get install xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
|
||||
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev
|
||||
# Install dev tools
|
||||
sudo apt-get install re2c lemon
|
||||
sudo apt-get clean
|
||||
|
||||
- name: Clone bext
|
||||
run: |
|
||||
git clone https://github.com/BRL-CAD/bext.git
|
||||
cd bext/stepcode
|
||||
cmake -E rm -r stepcode
|
||||
git clone --depth 1 https://github.com/stepcode/stepcode.git -b develop
|
||||
cd ../..
|
||||
|
||||
- name: Build bext
|
||||
run: |
|
||||
cmake -E make_directory bext_build
|
||||
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DUSE_GDAL=OFF -DUSE_TCL=OFF -DUSE_QT=OFF -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}\bext_output
|
||||
cmake --build bext_build --config Release -j2
|
||||
# We only need the build ouputs (bext_output) after this point, so
|
||||
# clean up to save space for the main BRL-CAD build.
|
||||
cmake -E rm -rf bext
|
||||
cmake -E rm -rf bext_build
|
||||
|
||||
|
||||
- name: Checkout
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/BRL-CAD/brlcad.git -b main
|
||||
cd brlcad/src/other/ext && rm -rf stepcode
|
||||
git clone --depth 1 https://github.com/stepcode/stepcode.git -b develop
|
||||
# Ordinarily BRL-CAD keeps track of what files are supposed to be
|
||||
# present in the repository. In this case we're not interested in
|
||||
# updating the list to the working stepcode filelist, so use an empty
|
||||
# list instead
|
||||
echo "set(stepcode_ignore_files)" > stepcode.dist
|
||||
cd ../../../../
|
||||
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -E make_directory brlcad_build
|
||||
cd brlcad_build
|
||||
cmake -S ../brlcad -DBRLCAD_EXT_DIR=${{ github.workspace }}\bext_output -DBRLCAD_ENABLE_GDAL=OFF -DBRLCAD_ENABLE_TCL=OFF -DBRLCAD_ENABLE_QT=OFF -G Ninja
|
||||
export PATH=$ENV{GITHUB_WORKSPACE}:$PATH
|
||||
cd brlcad
|
||||
cmake -S . -G Ninja -B build -DENABLE_ALL=ON -DCMAKE_BUILD_TYPE=Release -DEXT_BUILD_VERBOSE=ON
|
||||
cd ..
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd brlcad_build
|
||||
cmake --build . --target step-g
|
||||
export PATH=$ENV{GITHUB_WORKSPACE}:$PATH
|
||||
cd brlcad
|
||||
cmake --build build --config Release --target step-g
|
||||
cd ..
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd brlcad_build
|
||||
./bin/step-g ../brlcad/db/nist/NIST_MBE_PMI_3.stp -o nist3.g
|
||||
cd ..
|
||||
export PATH=$ENV{GITHUB_WORKSPACE}:$PATH
|
||||
cd brlcad/build
|
||||
./bin/step-g ../db/nist/NIST_MBE_PMI_3.stp -o nist3.g
|
||||
cd ../..
|
||||
|
||||
|
||||
brlcad_windows:
|
||||
@@ -233,6 +227,9 @@ jobs:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Setup - Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@master
|
||||
|
||||
- name: Add github workspace to path
|
||||
# https://github.community/t/deprecated-add-path/136621
|
||||
run: echo "$ENV{GITHUB_WORKSPACE}" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
|
||||
@@ -243,44 +240,38 @@ jobs:
|
||||
- name: Add cl.exe to PATH
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: Clone bext
|
||||
run: |
|
||||
git clone https://github.com/BRL-CAD/bext.git
|
||||
cd bext/stepcode
|
||||
cmake -E rm -r stepcode
|
||||
git clone --depth 1 https://github.com/stepcode/stepcode.git -b develop
|
||||
cd ../..
|
||||
|
||||
- name: Build bext
|
||||
shell: powershell
|
||||
run: |
|
||||
cmake -E make_directory bext_build
|
||||
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DUSE_GDAL=OFF -DUSE_TCL=OFF -DUSE_QT=OFF -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}\bext_output
|
||||
cmake --build bext_build --config Release -j2
|
||||
# We only need the build ouputs (bext_output) after this point, so
|
||||
# clean up to save space for the main BRL-CAD build.
|
||||
cmake -E rm -rf bext
|
||||
cmake -E rm -rf bext_build
|
||||
|
||||
|
||||
- name: Checkout
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/BRL-CAD/brlcad.git -b main
|
||||
cd brlcad/src/other/ext
|
||||
cmake -E rm -r stepcode
|
||||
git clone --depth 1 https://github.com/stepcode/stepcode.git -b develop
|
||||
# Ordinarily BRL-CAD keeps track of what files are supposed to be
|
||||
# present in the repository. In this case we're not interested in
|
||||
# updating the list to the working stepcode filelist, so use an empty
|
||||
# list instead
|
||||
echo "set(stepcode_ignore_files)" > stepcode.dist
|
||||
cd ../../../../
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -E make_directory brlcad_build
|
||||
cmake -S brlcad -B brlcad_build -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}\bext_output -DBRLCAD_ENABLE_GDAL=OFF -DBRLCAD_ENABLE_TCL=OFF -DBRLCAD_ENABLE_QT=OFF -G Ninja -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_COMPILER="cl.exe"
|
||||
cd brlcad && cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_COMPILER="cl.exe" -DSC_ENABLE_TESTING=ON
|
||||
cd ..
|
||||
# We do the following in order to help ensure files are "flushed"
|
||||
# to disk before compilation is attempted
|
||||
# https://superuser.com/a/1553374/1286142
|
||||
powershell Write-VolumeCache C
|
||||
powershell Write-VolumeCache D
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd brlcad_build
|
||||
cmake --build . --config Release --target step-g
|
||||
cd ..
|
||||
cd brlcad/build
|
||||
ninja -j1 -v step-g
|
||||
cd ../..
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd brlcad_build
|
||||
./bin/step-g.exe ../brlcad/db/nist/NIST_MBE_PMI_3.stp -o nist3.g
|
||||
cd ..
|
||||
cd brlcad/build
|
||||
./bin/step-g.exe ../db/nist/NIST_MBE_PMI_3.stp -o nist3.g
|
||||
cd ../..
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Common build directories used in the source tree
|
||||
/build
|
||||
/build-*
|
||||
/.build
|
||||
|
||||
# Temporary files
|
||||
@@ -20,6 +19,3 @@
|
||||
# Tool specific patterns
|
||||
*.kdev4
|
||||
.kdev_include_paths
|
||||
|
||||
# Parser generator intermediate files
|
||||
*.out
|
||||
|
||||
+1
-117
@@ -129,18 +129,6 @@ if (SC_ENABLE_COVERAGE AND ${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-fprofile-arcs -ftest-coverage" CACHE STRING "Extra linker flags required by code coverage" FORCE)
|
||||
endif (SC_ENABLE_COVERAGE AND ${CMAKE_C_COMPILER_ID} STREQUAL "GNU")
|
||||
|
||||
option(SC_ENABLE_ADDRESS_SANITIZER "Enable AddressSanitizer instrumentation" OFF)
|
||||
option(SC_ENABLE_UNDEFINED_SANITIZER "Enable UndefinedBehaviorSanitizer instrumentation" OFF)
|
||||
option(SC_ENABLE_THREAD_SANITIZER "Enable ThreadSanitizer instrumentation" OFF)
|
||||
|
||||
if(SC_ENABLE_THREAD_SANITIZER AND
|
||||
(SC_ENABLE_ADDRESS_SANITIZER OR SC_ENABLE_UNDEFINED_SANITIZER))
|
||||
message(FATAL_ERROR
|
||||
"SC_ENABLE_THREAD_SANITIZER must use a separate build from "
|
||||
"AddressSanitizer and UndefinedBehaviorSanitizer"
|
||||
)
|
||||
endif()
|
||||
|
||||
option(SC_BUILD_EXPRESS_ONLY "Only build express parser." OFF)
|
||||
mark_as_advanced(SC_BUILD_EXPRESS_ONLY)
|
||||
|
||||
@@ -167,111 +155,6 @@ include(SC_Regenerate)
|
||||
# create config.h header
|
||||
include(SC_Config_Headers)
|
||||
|
||||
# Apply sanitizer instrumentation after configure-time feature tests so their
|
||||
# try-compile executables do not depend on sanitizer runtime behavior. Keep
|
||||
# link flags explicit for CMake 3.12 compatibility (add_link_options was added
|
||||
# in CMake 3.13).
|
||||
if(SC_ENABLE_ADDRESS_SANITIZER OR
|
||||
SC_ENABLE_UNDEFINED_SANITIZER OR
|
||||
SC_ENABLE_THREAD_SANITIZER)
|
||||
if(MSVC)
|
||||
message(FATAL_ERROR "STEPcode sanitizer builds are not yet supported with MSVC")
|
||||
endif()
|
||||
|
||||
include(CMakePushCheckState)
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
set(_sc_sanitizer_compile_options)
|
||||
set(_sc_sanitizer_link_options)
|
||||
|
||||
function(sc_require_sanitizer FLAG RESULT_PREFIX)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS "${FLAG}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${FLAG}")
|
||||
check_c_source_compiles("int main(void) { return 0; }" ${RESULT_PREFIX}_C_SUPPORTED)
|
||||
check_cxx_source_compiles("int main() { return 0; }" ${RESULT_PREFIX}_CXX_SUPPORTED)
|
||||
cmake_pop_check_state()
|
||||
if(NOT ${RESULT_PREFIX}_C_SUPPORTED OR NOT ${RESULT_PREFIX}_CXX_SUPPORTED)
|
||||
message(FATAL_ERROR
|
||||
"STEPcode sanitizer mode was requested, but the C/C++ compiler and "
|
||||
"linker do not support ${FLAG}"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(SC_ENABLE_ADDRESS_SANITIZER)
|
||||
sc_require_sanitizer("-fsanitize=address" SC_ASAN)
|
||||
list(APPEND _sc_sanitizer_compile_options -fsanitize=address)
|
||||
list(APPEND _sc_sanitizer_link_options -fsanitize=address)
|
||||
# exp2cxx is executed during the build to generate schema bindings. It
|
||||
# remains address-instrumented, but leak checking a short-lived build
|
||||
# tool is both outside the test scope and unsupported under common build
|
||||
# tracers/sandboxes. Limit this environment to schema generation; CTest
|
||||
# and installed tools retain the user's normal ASan settings.
|
||||
set(SC_SCHEMA_GENERATOR_ENVIRONMENT "ASAN_OPTIONS=detect_leaks=0")
|
||||
endif()
|
||||
|
||||
if(SC_ENABLE_UNDEFINED_SANITIZER)
|
||||
sc_require_sanitizer("-fsanitize=undefined" SC_UBSAN)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS "-fsanitize=undefined")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "-fsanitize=undefined")
|
||||
check_c_compiler_flag(
|
||||
"-fno-sanitize-recover=undefined"
|
||||
SC_UBSAN_C_NO_RECOVER_SUPPORTED
|
||||
)
|
||||
check_cxx_compiler_flag(
|
||||
"-fno-sanitize-recover=undefined"
|
||||
SC_UBSAN_CXX_NO_RECOVER_SUPPORTED
|
||||
)
|
||||
cmake_pop_check_state()
|
||||
if(NOT SC_UBSAN_C_NO_RECOVER_SUPPORTED OR
|
||||
NOT SC_UBSAN_CXX_NO_RECOVER_SUPPORTED)
|
||||
message(FATAL_ERROR
|
||||
"STEPcode's fail-fast UndefinedBehaviorSanitizer mode was requested, "
|
||||
"but the C/C++ compiler does not support "
|
||||
"-fno-sanitize-recover=undefined"
|
||||
)
|
||||
endif()
|
||||
list(APPEND _sc_sanitizer_compile_options
|
||||
-fsanitize=undefined
|
||||
-fno-sanitize-recover=undefined
|
||||
)
|
||||
list(APPEND _sc_sanitizer_link_options -fsanitize=undefined)
|
||||
endif()
|
||||
|
||||
if(SC_ENABLE_THREAD_SANITIZER)
|
||||
sc_require_sanitizer("-fsanitize=thread" SC_TSAN)
|
||||
list(APPEND _sc_sanitizer_compile_options -fsanitize=thread)
|
||||
list(APPEND _sc_sanitizer_link_options -fsanitize=thread)
|
||||
endif()
|
||||
|
||||
check_c_compiler_flag("-fno-omit-frame-pointer" SC_SANITIZER_C_FRAME_POINTER_SUPPORTED)
|
||||
check_cxx_compiler_flag("-fno-omit-frame-pointer" SC_SANITIZER_CXX_FRAME_POINTER_SUPPORTED)
|
||||
if(SC_SANITIZER_C_FRAME_POINTER_SUPPORTED)
|
||||
list(APPEND _sc_sanitizer_compile_options
|
||||
$<$<COMPILE_LANGUAGE:C>:-fno-omit-frame-pointer>
|
||||
)
|
||||
endif()
|
||||
if(SC_SANITIZER_CXX_FRAME_POINTER_SUPPORTED)
|
||||
list(APPEND _sc_sanitizer_compile_options
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-omit-frame-pointer>
|
||||
)
|
||||
endif()
|
||||
|
||||
add_compile_options(${_sc_sanitizer_compile_options})
|
||||
string(JOIN " " _sc_sanitizer_link_flags ${_sc_sanitizer_link_options})
|
||||
foreach(_sc_link_type EXE SHARED MODULE)
|
||||
set(
|
||||
CMAKE_${_sc_link_type}_LINKER_FLAGS
|
||||
"${CMAKE_${_sc_link_type}_LINKER_FLAGS} ${_sc_sanitizer_link_flags}"
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED SC_SDAI_ADDITIONAL_EXES_SRCS)
|
||||
set(SC_SDAI_ADDITIONAL_EXES_SRCS "" CACHE STRING "Source files for additional executables to be linked with SDAI libs")
|
||||
endif(NOT DEFINED SC_SDAI_ADDITIONAL_EXES_SRCS)
|
||||
@@ -347,3 +230,4 @@ endforeach(_msg ${CONFIG_END_MESSAGES})
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ This repo was moved and renamed in May 2012. Previously, it was at
|
||||
http://github.com/mpictor/StepClassLibrary
|
||||
|
||||
Some are duplicates of changes recorded in the BRL-CAD repo:
|
||||
https://github.com/BRL-CAD/brlcad/tree/158beae4556d94821938368951546384cba53107/src/other/ext/stepcode
|
||||
http://brlcad.svn.sourceforge.net/viewvc/brlcad/brlcad/trunk/src/other/step/?view=log
|
||||
|
||||
Pre-BRL-CAD changes:
|
||||
************************************************************************
|
||||
|
||||
@@ -51,13 +51,7 @@ Installation
|
||||
-DSC_BUILD_SCHEMAS=ALL
|
||||
- Added to make use of ctest easier. If SC_BUILD_SCHEMAS == ALL,
|
||||
then CMake adds each *.exp file found in data/.
|
||||
-DSC_EXP2CXX_API_VERSION=2
|
||||
- opts in to compact descriptor-driven SELECTs and dependency-bounded
|
||||
entity headers in the generated C++ API.
|
||||
- clients include the entity headers they use (for example,
|
||||
entity/SdaiProduct.h); schema.h no longer expands every entity class.
|
||||
- version 1 remains the default for source compatibility.
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DSC_BUILD_TYPE=Release
|
||||
- this causes binaries to be built without debugging information
|
||||
- without this, cmake defaults to a Debug build
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ if (LEMON_EXECUTABLE)
|
||||
|
||||
# execute lemon
|
||||
add_custom_command(
|
||||
OUTPUT ${_out_src_file} ${_basename}.h
|
||||
OUTPUT ${_out_src_file}
|
||||
COMMAND ${LEMON_EXECUTABLE} -T${LEMON_TEMPLATE} ${LEMON_EXECUTABLE_opts} ${_in_y_file}
|
||||
DEPENDS ${Name}_input_cpy
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
@@ -152,7 +152,7 @@ if (LEMON_EXECUTABLE)
|
||||
add_custom_command(
|
||||
OUTPUT ${_out_hdr_file}
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E rename ${_basename}.h ${_out_hdr_file}
|
||||
DEPENDS ${_out_src_file} ${_basename}.h
|
||||
DEPENDS ${_out_src_file}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
|
||||
@@ -27,29 +27,17 @@ endmacro(P21_TESTS sfile)
|
||||
# create p21read_sdai_*, lazy_sdai_*, any exes listed in SC_SDAI_ADDITIONAL_EXES_SRCS
|
||||
macro(SCHEMA_EXES)
|
||||
RELATIVE_PATH_TO_TOPLEVEL(${CMAKE_CURRENT_SOURCE_DIR} RELATIVE_PATH_COMPONENT)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
SC_ADDEXEC(p21read_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc;${RELATIVE_PATH_COMPONENT}/src/test/p21read/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME} stepdai stepcore stepeditor steputils TESTABLE)
|
||||
elseif(BUILD_STATIC_LIBS)
|
||||
SC_ADDEXEC(p21read_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc;${RELATIVE_PATH_COMPONENT}/src/test/p21read/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME}-static stepeditor-static stepcore-static stepdai-static steputils-static TESTABLE)
|
||||
endif()
|
||||
SC_ADDEXEC(p21read_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc;${RELATIVE_PATH_COMPONENT}/src/test/p21read/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME} stepdai stepcore stepeditor steputils TESTABLE)
|
||||
if(NOT WIN32)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
SC_ADDEXEC(lazy_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc;${RELATIVE_PATH_COMPONENT}/src/cllazyfile/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME} steplazyfile stepdai stepcore stepeditor steputils TESTABLE)
|
||||
elseif(BUILD_STATIC_LIBS)
|
||||
SC_ADDEXEC(lazy_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc;${RELATIVE_PATH_COMPONENT}/src/cllazyfile/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME}-static steplazyfile-static stepeditor-static stepcore-static stepdai-static steputils-static TESTABLE)
|
||||
endif()
|
||||
SC_ADDEXEC(lazy_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc;${RELATIVE_PATH_COMPONENT}/src/cllazyfile/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME} steplazyfile stepdai stepcore stepeditor steputils TESTABLE)
|
||||
endif(NOT WIN32)
|
||||
|
||||
#add user-defined executables
|
||||
foreach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
|
||||
get_filename_component(name ${src} NAME_WE)
|
||||
get_filename_component(path ${src} ABSOLUTE)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
SC_ADDEXEC(${name}_${PROJECT_NAME} SOURCES ${src} LINK_LIBRARIES ${PROJECT_NAME} stepdai stepcore stepeditor steputils TESTABLE)
|
||||
elseif(BUILD_STATIC_LIBS)
|
||||
SC_ADDEXEC(${name}_${PROJECT_NAME} SOURCES ${src} LINK_LIBRARIES ${PROJECT_NAME}-static stepcore-static stepdai-static stepeditor-static steputils-static TESTABLE)
|
||||
SC_ADDEXEC(${name}_${PROJECT_NAME} SOURCES ${src} LINK_LIBRARIES ${PROJECT_NAME} stepdai stepcore stepeditor steputils TESTABLE)
|
||||
#set_target_properties(${name}_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${${PROJECT_NAME}_COMPILE_FLAGS} -I${path}")
|
||||
endif()
|
||||
endforeach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
|
||||
ENDMACRO(SCHEMA_EXES)
|
||||
|
||||
@@ -89,40 +77,25 @@ macro(SCHEMA_TARGETS expFile schemaName sourceFiles)
|
||||
# schema scanner comes up with a short schema name for PROJECT() (which sets ${PROJECT_NAME})
|
||||
message(STATUS "Will generate ${${PROJECT_NAME}_file_count} C++ files for ${PROJECT_NAME}.")
|
||||
|
||||
set(_schema_generated_files)
|
||||
foreach(_schema_source ${sourceFiles})
|
||||
list(APPEND _schema_generated_files "${CMAKE_CURRENT_SOURCE_DIR}/${_schema_source}")
|
||||
endforeach()
|
||||
add_custom_target(generate_cpp_${PROJECT_NAME} DEPENDS exp2cxx ${expFile} ${_schema_generated_files} SOURCES ${_schema_generated_files})
|
||||
add_custom_target(generate_cpp_${PROJECT_NAME} DEPENDS exp2cxx ${expFile} ${sourceFiles} SOURCES ${sourceFiles})
|
||||
# this calls a cmake script because it doesn't seem to be possible
|
||||
# to divert stdout, stderr in cmake except via execute_process
|
||||
add_custom_command(OUTPUT ${_schema_generated_files}
|
||||
add_custom_command(OUTPUT ${sourceFiles}
|
||||
COMMAND ${CMAKE_COMMAND} -DEXE=\"$<TARGET_FILE:exp2cxx>\" -DEXP=\"${expFile}\"
|
||||
-DONESHOT=\"${SC_GENERATE_CXX_ONESHOT}\" -DSDIR=\"${CMAKE_CURRENT_LIST_DIR}\"
|
||||
-DCHUNK_SIZE=\"${SC_EXP2CXX_CHUNK_SIZE}\"
|
||||
-DAPI_VERSION=\"${SC_EXP2CXX_API_VERSION}\"
|
||||
-DLATE_BOUND=\"${SC_EXP2CXX_LATE_BOUND}\"
|
||||
-DCOMPAT_NAMES=\"${SC_EXP2CXX_COMPAT_NAMES}\"
|
||||
-DMETADATA_PROFILE=\"${SC_EXP2CXX_METADATA}\"
|
||||
-DGENERATOR_ENVIRONMENT=\"${SC_SCHEMA_GENERATOR_ENVIRONMENT}\"
|
||||
-P ${SC_CMAKE_DIR}/SC_Run_exp2cxx.cmake
|
||||
DEPENDS exp2cxx ${expFile}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
COMMENT "[exp2cxx] Generating ${${PROJECT_NAME}_file_count} C++ files for ${PROJECT_NAME}."
|
||||
)
|
||||
set(_schema_include_dirs
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR} ${SC_SOURCE_DIR}/src/cldai ${SC_SOURCE_DIR}/src/cleditor
|
||||
${SC_SOURCE_DIR}/src/clutils ${SC_SOURCE_DIR}/src/clstepcore ${SC_SOURCE_DIR}/src/cllazyfile
|
||||
${SC_SOURCE_DIR}/src/cllazyfile/judy/src
|
||||
)
|
||||
# Schema libraries should be installed by default
|
||||
# if testing is enabled, "TESTABLE" sets property EXCLUDE_FROM_ALL and prevents installation
|
||||
if(BUILD_SHARED_LIBS)
|
||||
SC_ADDLIB(${PROJECT_NAME} SHARED SOURCES ${_schema_generated_files} LINK_LIBRARIES stepdai stepcore stepeditor steputils)
|
||||
SC_ADDLIB(${PROJECT_NAME} SHARED SOURCES ${sourceFiles} LINK_LIBRARIES stepdai stepcore stepeditor steputils TESTABLE)
|
||||
add_dependencies(${PROJECT_NAME} generate_cpp_${PROJECT_NAME})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${_schema_include_dirs})
|
||||
if(${PROJECT_NAME}_unity_build)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE SC_SDAI_UNITY_BUILD)
|
||||
endif()
|
||||
if(WIN32)
|
||||
target_compile_definitions("${PROJECT_NAME}" PRIVATE SC_SCHEMA_DLL_EXPORTS)
|
||||
if(MSVC)
|
||||
@@ -137,14 +110,10 @@ macro(SCHEMA_TARGETS expFile schemaName sourceFiles)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_STATIC_LIBS)
|
||||
SC_ADDLIB(${PROJECT_NAME}-static STATIC SOURCES ${_schema_generated_files} LINK_LIBRARIES stepcore-static stepdai-static stepeditor-static steputils-static)
|
||||
if($CACHE{SC_BUILD_STATIC_LIBS})
|
||||
SC_ADDLIB(${PROJECT_NAME}-static STATIC SOURCES ${sourceFiles} LINK_LIBRARIES stepdai-static stepcore-static stepeditor-static steputils-static TESTABLE)
|
||||
add_dependencies(${PROJECT_NAME}-static generate_cpp_${PROJECT_NAME})
|
||||
target_include_directories(${PROJECT_NAME}-static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${_schema_include_dirs})
|
||||
target_compile_definitions("${PROJECT_NAME}-static" PRIVATE SC_STATIC)
|
||||
if(${PROJECT_NAME}_unity_build)
|
||||
target_compile_definitions(${PROJECT_NAME}-static PRIVATE SC_SDAI_UNITY_BUILD)
|
||||
endif()
|
||||
if(MSVC)
|
||||
target_compile_options("${PROJECT_NAME}-static" PRIVATE "/bigobj")
|
||||
endif()
|
||||
@@ -164,3 +133,4 @@ endmacro(SCHEMA_TARGETS expFile schemaName sourceFiles)
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
|
||||
@@ -1,26 +1,10 @@
|
||||
|
||||
# if oneshot is true, don't run exp2cxx if source files exist. if schema.cc exists, assume others do
|
||||
if(NOT DEFINED API_VERSION OR "${API_VERSION}" STREQUAL "")
|
||||
set(API_VERSION 1)
|
||||
endif()
|
||||
if(NOT DEFINED METADATA_PROFILE OR "${METADATA_PROFILE}" STREQUAL "")
|
||||
set(METADATA_PROFILE full)
|
||||
endif()
|
||||
|
||||
if(ONESHOT AND EXISTS "${SDIR}/schema.cc")
|
||||
message("WARNING: SC_GENERATE_CXX_ONESHOT is enabled. If generated code has been modified, it will NOT be rewritten!")
|
||||
message("This is ONLY for debugging STEPcode internals!")
|
||||
else()
|
||||
set(_exp2cxx_mode_args)
|
||||
if(LATE_BOUND)
|
||||
list(APPEND _exp2cxx_mode_args --late-bound)
|
||||
endif()
|
||||
if(COMPAT_NAMES)
|
||||
list(APPEND _exp2cxx_mode_args --compat-names)
|
||||
endif()
|
||||
list(APPEND _exp2cxx_mode_args --metadata ${METADATA_PROFILE})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E env ${GENERATOR_ENVIRONMENT}
|
||||
${EXE} -k ${CHUNK_SIZE} -V ${API_VERSION} ${_exp2cxx_mode_args} ${EXP}
|
||||
execute_process(COMMAND ${EXE} ${EXP}
|
||||
WORKING_DIRECTORY ${SDIR}
|
||||
RESULT_VARIABLE _res
|
||||
OUTPUT_FILE exp2cxx_stdout.txt
|
||||
@@ -38,3 +22,4 @@ endif()
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
|
||||
+9
-21
@@ -10,23 +10,15 @@ macro(SC_ADDEXEC execname)
|
||||
|
||||
add_executable(${execname} ${${_arg_prefix}_SOURCES})
|
||||
|
||||
if(BUILD_STATIC_LIBS)
|
||||
target_compile_definitions(${execname} PRIVATE SC_STATIC)
|
||||
endif()
|
||||
|
||||
if(DEFINED "${_arg_prefix}_LINK_LIBRARIES")
|
||||
foreach(_lib ${${_arg_prefix}_LINK_LIBRARIES})
|
||||
if($CACHE{SC_STATIC_UTILS})
|
||||
get_property(_lib_type TARGET ${_lib} PROPERTY TYPE)
|
||||
if(NOT _lib_type STREQUAL "STATIC_LIBRARY")
|
||||
if(NOT $<TARGET_PROPERTY:${_lib},TYPE> STREQUAL "STATIC_LIBRARY")
|
||||
message(SEND_ERROR "SC_ADDEXEC usage error - expected STATIC LINK_LIBRARIES targets (${_lib})")
|
||||
endif()
|
||||
endif()
|
||||
# Executables consume their dependencies but do not publish an
|
||||
# interface to downstream targets.
|
||||
target_link_libraries(${execname} PRIVATE ${_lib})
|
||||
target_link_libraries(${execname} ${_lib})
|
||||
endforeach()
|
||||
target_link_libraries(${execname} PRIVATE ${${_arg_prefix}_LINK_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(NOT ${_arg_prefix}_NO_INSTALL AND NOT ${_arg_prefix}_TESTABLE)
|
||||
@@ -45,7 +37,7 @@ endmacro()
|
||||
macro(SC_ADDLIB _addlib_target)
|
||||
set(_addlib_opts SHARED STATIC NO_INSTALL TESTABLE)
|
||||
set(_addlib_multikw SOURCES LINK_LIBRARIES)
|
||||
string(TOUPPER "SC_ADDLIB_${_addlib_target}_ARG" _arg_prefix)
|
||||
string(TOUPPER "SC_ADDLIB_${libname}_ARG" _arg_prefix)
|
||||
cmake_parse_arguments(${_arg_prefix} "${_addlib_opts}" "" "${_addlib_multikw}" ${ARGN})
|
||||
|
||||
if(NOT DEFINED ${_arg_prefix}_SOURCES)
|
||||
@@ -72,25 +64,20 @@ macro(SC_ADDLIB _addlib_target)
|
||||
if(DEFINED ${_arg_prefix}_LINK_LIBRARIES)
|
||||
foreach(_lib ${${_arg_prefix}_LINK_LIBRARIES})
|
||||
if(${_arg_prefix}_STATIC AND TARGET ${_lib})
|
||||
get_property(_libtype TARGET ${_lib} PROPERTY TYPE)
|
||||
if(NOT ${_libtype} STREQUAL "STATIC_LIBRARY")
|
||||
message(SEND_ERROR "SC_ADDLIB usage error - expected (static) LINK_LIBRARIES targets (${_lib})")
|
||||
get_property(_libtype TARGET ${_lib} PROPERTY TYPE)
|
||||
if(NOT ${_libtype} STREQUAL "STATIC_LIBRARY")
|
||||
message(SEND_ERROR "SC_ADDLIB usage error - expected (static) LINK_LIBRARIES targets (${_lib})")
|
||||
endif()
|
||||
endif()
|
||||
# Schema libraries are consumed directly by generated test programs.
|
||||
# Publish their link requirements explicitly; the legacy unscoped
|
||||
# signature does not reliably provide a transitive interface with
|
||||
# current CMake versions.
|
||||
target_link_libraries(${_addlib_target} PUBLIC ${_lib})
|
||||
target_link_libraries(${_addlib_target} ${_lib})
|
||||
endforeach()
|
||||
target_link_libraries(${_addlib_target} ${_lib})
|
||||
endif()
|
||||
|
||||
if(NOT ${_arg_prefix}_NO_INSTALL AND NOT ${_arg_prefix}_TESTABLE)
|
||||
install(TARGETS ${_addlib_target}
|
||||
RUNTIME DESTINATION ${BIN_DIR}
|
||||
LIBRARY DESTINATION ${LIB_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_DIR}
|
||||
)
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -101,3 +88,4 @@ endmacro()
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ extern "C" {
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@@ -51,35 +50,6 @@ using std::ofstream;
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
|
||||
static unsigned long entityChunkSize = 256;
|
||||
static unsigned long typeChunkSize = 256;
|
||||
|
||||
static bool
|
||||
parseChunkSizes( const char * value )
|
||||
{
|
||||
if( !value || !value[0] ) {
|
||||
return false;
|
||||
}
|
||||
char * end = 0;
|
||||
const unsigned long entities = strtoul( value, &end, 10 );
|
||||
if( !end || entities == 0 ) {
|
||||
return false;
|
||||
}
|
||||
unsigned long types = entities;
|
||||
if( *end == ':' ) {
|
||||
char * typeEnd = 0;
|
||||
types = strtoul( end + 1, &typeEnd, 10 );
|
||||
if( !end[1] || !typeEnd || *typeEnd || types == 0 ) {
|
||||
return false;
|
||||
}
|
||||
} else if( *end ) {
|
||||
return false;
|
||||
}
|
||||
entityChunkSize = entities;
|
||||
typeChunkSize = types;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \return true for types that exp2cxx won't generate code for */
|
||||
bool notGenerated( const Type t ) {
|
||||
switch( TYPEget_body( t )->type ) {
|
||||
@@ -216,34 +186,20 @@ void writeLists( const char * schemaName, stringstream & eh, stringstream & ei,
|
||||
cmLists << "# targets, logic, etc are within a set of macros shared by all schemas" << endl;
|
||||
cmLists << "include(${SC_CMAKE_DIR}/SC_CXX_schema_macros.cmake)" << endl;
|
||||
|
||||
const int entityChunks = std::max( 1, ( ecount + static_cast<int>( entityChunkSize ) - 1 ) / static_cast<int>( entityChunkSize ) );
|
||||
const int typeChunks = std::max( 1, ( tcount + static_cast<int>( typeChunkSize ) - 1 ) / static_cast<int>( typeChunkSize ) );
|
||||
cmLists << "if(SC_EXP2CXX_LATE_BOUND)" << endl;
|
||||
cmLists << " set(" << shortName << "_file_count 10)" << endl;
|
||||
cmLists << "else()" << endl;
|
||||
cmLists << " set(" << shortName << "_file_count " <<
|
||||
( ecount + tcount ) * 2 + entityChunks + typeChunks + 14 << ")" << endl;
|
||||
cmLists << "endif()" << endl << endl;
|
||||
// * 2 for headers, + 10 other files
|
||||
cmLists << "set(" << shortName << "_file_count " << ( ( ecount + tcount ) * 2 ) + 10 << ")" << endl << endl;
|
||||
|
||||
|
||||
cmLists << "PROJECT(" << shortName << ")" << endl;
|
||||
cmLists << "# list headers so they can be installed - entity, type, misc" << endl;
|
||||
|
||||
cmLists << "if(SC_EXP2CXX_LATE_BOUND)" << endl;
|
||||
cmLists << " set(" << shortName << "_entity_hdrs)" << endl;
|
||||
cmLists << "else()" << endl;
|
||||
cmLists << " set(" << shortName << "_entity_hdrs" << endl;
|
||||
cmLists << "set(" << shortName << "_entity_hdrs" << endl;
|
||||
cmLists << eh.str();
|
||||
cmLists << " )" << endl;
|
||||
cmLists << "endif()" << endl << endl;
|
||||
cmLists << " )" << endl << endl;
|
||||
|
||||
cmLists << "if(SC_EXP2CXX_LATE_BOUND)" << endl;
|
||||
cmLists << " set(" << shortName << "_type_hdrs)" << endl;
|
||||
cmLists << "else()" << endl;
|
||||
cmLists << " set(" << shortName << "_type_hdrs" << endl;
|
||||
cmLists << "set(" << shortName << "_type_hdrs" << endl;
|
||||
cmLists << th.str();
|
||||
cmLists << " )" << endl;
|
||||
cmLists << "endif()" << endl << endl;
|
||||
cmLists << " )" << endl << endl;
|
||||
|
||||
cmLists << "set(" << shortName << "_misc_hdrs" << endl;
|
||||
cmLists << " Sdaiclasses.h schema.h" << endl;
|
||||
@@ -268,26 +224,11 @@ void writeLists( const char * schemaName, stringstream & eh, stringstream & ei,
|
||||
|
||||
cmLists << "# unity build: #include small .cc files to reduce the number" << endl;
|
||||
cmLists << "# of translation units that must be compiled" << endl;
|
||||
cmLists << "if(SC_EXP2CXX_LATE_BOUND)" << endl;
|
||||
cmLists << " set(" << shortName << "_unity_build FALSE)" << endl;
|
||||
cmLists << " set(" << shortName << "_entity_impls)" << endl;
|
||||
cmLists << " set(" << shortName << "_type_impls)" << endl;
|
||||
cmLists << "elseif(SC_UNITY_BUILD)" << endl;
|
||||
cmLists << " # bounded compact chunks; definitions are target-local" << endl;
|
||||
cmLists << " set(" << shortName << "_unity_build TRUE)" << endl;
|
||||
cmLists << " set(" << shortName << "_entity_impls" << endl;
|
||||
for( int chunk = 1; chunk <= entityChunks; ++chunk ) {
|
||||
cmLists << " Sdai" << schema_upper << "_unity_entities_" <<
|
||||
std::setfill( '0' ) << std::setw( 4 ) << chunk << ".cc" << endl;
|
||||
}
|
||||
cmLists << " )" << endl;
|
||||
cmLists << " set(" << shortName << "_type_impls" << endl;
|
||||
for( int chunk = 1; chunk <= typeChunks; ++chunk ) {
|
||||
cmLists << " Sdai" << schema_upper << "_unity_types_" <<
|
||||
std::setfill( '0' ) << std::setw( 4 ) << chunk << ".cc" << endl;
|
||||
}
|
||||
cmLists << " )" << endl;
|
||||
cmLists << "else()" << endl;
|
||||
cmLists << "if(SC_UNITY_BUILD)" << endl << " # turns off include statements within type and entity .cc's - the unity T.U.'s include a unity header" << endl;
|
||||
cmLists << " add_definitions( -DSC_SDAI_UNITY_BUILD)" << endl;
|
||||
cmLists << " set(" << shortName << "_entity_impls Sdai" << schema_upper << "_unity_entities.cc)" << endl;
|
||||
cmLists << " set(" << shortName << "_type_impls Sdai" << schema_upper << "_unity_types.cc)" << endl;
|
||||
cmLists << "else(SC_UNITY_BUILD)" << endl;
|
||||
cmLists << " set(" << shortName << "_entity_impls" << endl;
|
||||
cmLists << ei.str();
|
||||
cmLists << " )" << endl << endl;
|
||||
@@ -295,13 +236,12 @@ void writeLists( const char * schemaName, stringstream & eh, stringstream & ei,
|
||||
cmLists << " set(" << shortName << "_type_impls" << endl;
|
||||
cmLists << ti.str();
|
||||
cmLists << " )" << endl;
|
||||
cmLists << "endif()" << endl << endl;
|
||||
cmLists << "endif(SC_UNITY_BUILD)" << endl << endl;
|
||||
|
||||
cmLists << "set( " << shortName << "_misc_impls" << endl;
|
||||
cmLists << " SdaiAll.cc compstructs.cc schema.cc" << endl;
|
||||
cmLists << " Sdai" << schema_upper << ".cc" << endl;
|
||||
cmLists << " Sdai" << schema_upper << ".init.cc" << endl;
|
||||
cmLists << " Sdai" << schema_upper << ".sources.cmake )" << endl << endl;
|
||||
cmLists << " Sdai" << schema_upper << ".init.cc )" << endl << endl;
|
||||
|
||||
cmLists << "set(schema_target_files ${" << shortName << "_entity_impls} " << "${" << shortName << "_type_impls} " << "${" << shortName << "_misc_impls})" << endl;
|
||||
cmLists << "SCHEMA_TARGETS(\"" << input_filename << "\" \"" << schemaName << "\"" << endl;
|
||||
@@ -390,18 +330,14 @@ int main( int argc, char ** argv ) {
|
||||
DictionaryEntry de;
|
||||
/* copied from fedex.c */
|
||||
Express model;
|
||||
if( ( argc != 2 && argc != 3 ) || ( strlen( argv[1] ) < 1 ) ) {
|
||||
fprintf( stderr, "\nUsage: %s file.exp [entity-chunk-size[:type-chunk-size]]\nOutput: a CMakeLists.txt to build the schema,", argv[0] );
|
||||
if( ( argc != 2 ) || ( strlen( argv[1] ) < 1 ) ) {
|
||||
fprintf( stderr, "\nUsage: %s file.exp\nOutput: a CMakeLists.txt to build the schema,", argv[0] );
|
||||
fprintf( stderr, " containing file names for entities, types, etc\n" );
|
||||
fprintf( stderr, "also prints (to stdout) the absolute path to the directory CMakeLists.txt was created in\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
EXPRESSprogram_name = argv[0];
|
||||
input_filename = argv[1];
|
||||
if( argc == 3 && !parseChunkSizes( argv[2] ) ) {
|
||||
fprintf( stderr, "chunk sizes must be positive integers in N or N:N form\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
EXPRESSinitialize();
|
||||
|
||||
|
||||
@@ -18,44 +18,6 @@ else(NOT DEFINED SC_UNITY_BUILD)
|
||||
message( STATUS "Respecting user-defined SC_UNITY_BUILD value of ${SC_UNITY_BUILD}.")
|
||||
endif(NOT DEFINED SC_UNITY_BUILD)
|
||||
|
||||
if(NOT DEFINED SC_EXP2CXX_CHUNK_SIZE)
|
||||
set(SC_EXP2CXX_CHUNK_SIZE "64:8" CACHE STRING "Maximum entity:type objects in generated unity translation units")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED SC_EXP2CXX_API_VERSION)
|
||||
set(SC_EXP2CXX_API_VERSION "1")
|
||||
endif()
|
||||
set(SC_EXP2CXX_API_VERSION "${SC_EXP2CXX_API_VERSION}" CACHE STRING "Generated C++ API version (1 or 2)")
|
||||
set_property(CACHE SC_EXP2CXX_API_VERSION PROPERTY STRINGS 1 2)
|
||||
if(NOT SC_EXP2CXX_API_VERSION MATCHES "^[12]$")
|
||||
message(FATAL_ERROR "SC_EXP2CXX_API_VERSION must be 1 or 2")
|
||||
endif()
|
||||
|
||||
option(SC_EXP2CXX_LATE_BOUND "Generate descriptor-backed entities without early-bound C++ entity classes" OFF)
|
||||
if(SC_EXP2CXX_LATE_BOUND AND NOT SC_EXP2CXX_API_VERSION STREQUAL "2")
|
||||
message(FATAL_ERROR "SC_EXP2CXX_LATE_BOUND requires SC_EXP2CXX_API_VERSION=2")
|
||||
endif()
|
||||
|
||||
option(SC_EXP2CXX_COMPAT_NAMES "Retain generated entity aliases in late-bound output" OFF)
|
||||
if(SC_EXP2CXX_COMPAT_NAMES AND NOT SC_EXP2CXX_LATE_BOUND)
|
||||
message(FATAL_ERROR "SC_EXP2CXX_COMPAT_NAMES requires SC_EXP2CXX_LATE_BOUND=ON")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED SC_EXP2CXX_METADATA)
|
||||
set(SC_EXP2CXX_METADATA "full")
|
||||
endif()
|
||||
set(SC_EXP2CXX_METADATA "${SC_EXP2CXX_METADATA}" CACHE STRING
|
||||
"Generated schema metadata profile (full or structural)")
|
||||
set_property(CACHE SC_EXP2CXX_METADATA PROPERTY STRINGS full structural)
|
||||
if(NOT SC_EXP2CXX_METADATA MATCHES "^(full|structural)$")
|
||||
message(FATAL_ERROR "SC_EXP2CXX_METADATA must be full or structural")
|
||||
endif()
|
||||
if(SC_EXP2CXX_METADATA STREQUAL "structural" AND
|
||||
NOT SC_EXP2CXX_LATE_BOUND)
|
||||
message(FATAL_ERROR
|
||||
"SC_EXP2CXX_METADATA=structural requires SC_EXP2CXX_LATE_BOUND=ON")
|
||||
endif()
|
||||
|
||||
|
||||
# --- variables ---
|
||||
# SC_ROOT: SC root dir
|
||||
@@ -120,7 +82,7 @@ endif(WIN32)
|
||||
# SCHEMA_FILE - path to the schema
|
||||
# TODO should we have a result variable to return schema name(s) found?
|
||||
macro(SCHEMA_CMLIST SCHEMA_FILE)
|
||||
execute_process(COMMAND ${SCANNER_OUT_DIR}/schema_scanner ${SCHEMA_FILE} ${SC_EXP2CXX_CHUNK_SIZE}
|
||||
execute_process(COMMAND ${SCANNER_OUT_DIR}/schema_scanner ${SCHEMA_FILE}
|
||||
WORKING_DIRECTORY ${SC_BINARY_DIR}/schemas
|
||||
RESULT_VARIABLE _ss_stat
|
||||
OUTPUT_VARIABLE _ss_out
|
||||
@@ -135,16 +97,7 @@ macro(SCHEMA_CMLIST SCHEMA_FILE)
|
||||
string(STRIP "${_ss_out}" _ss_stripped)
|
||||
string(REGEX REPLACE "\\\n" ";" _list ${_ss_stripped})
|
||||
foreach(_dir ${_list})
|
||||
get_property(_already_added GLOBAL PROPERTY _SC_SCHEMA_DIRS)
|
||||
list(FIND _already_added "${_dir}" _idx)
|
||||
if(${_idx} EQUAL -1)
|
||||
set_property(GLOBAL APPEND PROPERTY _SC_SCHEMA_DIRS "${_dir}")
|
||||
# Keep generated targets under the top-level binary tree. Passing the
|
||||
# absolute generated-source path as both arguments creates absolute
|
||||
# make target names with newer CMake.
|
||||
get_filename_component(_schema_dir_name "${_dir}" NAME)
|
||||
add_subdirectory("${_dir}" "${SC_BINARY_DIR}/schema-targets/${_schema_dir_name}")
|
||||
endif()
|
||||
add_subdirectory(${_dir} ${_dir}) #specify source and binary dirs as the same
|
||||
endforeach(_dir ${_ss_out})
|
||||
# configure_file forces cmake to run again if the schema has been modified
|
||||
#if multiple schemas in one file, _schema is the last one printed.
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ set(CTEST_INITIAL_CACHE "
|
||||
SITE:STRING=${CTEST_SITE}
|
||||
BUILDNAME:STRING=${CTEST_BUILD_NAME}
|
||||
SC_ENABLE_TESTING:BOOL=ON
|
||||
CMAKE_BUILD_TYPE:STRING=Debug
|
||||
SC_BUILD_TYPE:STRING=Debug
|
||||
")
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
||||
# AP242 TREAT Schema File
|
||||
|
||||
This directory contains an altered version of the AP242 (ISO 10303-242) schema.
|
||||
|
||||
It is corrected to avoid the non-standard parsing requirement of the original
|
||||
by using explicit TREAT expression for type narrowing
|
||||
|
||||
## The Difference
|
||||
|
||||
Both files are identical except for a single line at line 34149 in the `styled_item` entity WHERE rule WR3:
|
||||
|
||||
**Original (242_mim_lf.exp)**:
|
||||
```express
|
||||
QUERY(it <* item | ...)
|
||||
```
|
||||
|
||||
**TREAT version (242_mim_lf_treat.exp)**:
|
||||
```express
|
||||
QUERY(it <* TREAT(item AS set_representation_item) | ...)
|
||||
```
|
||||
|
||||
### Historical Context
|
||||
The original AP242 schema contains a WHERE rule that:
|
||||
1. Checks if `item` (a SELECT type) is a `SET_REPRESENTATION_ITEM`
|
||||
2. Then tries to iterate over `item` in a QUERY expression
|
||||
|
||||
This pattern requires implicit type narrowing, which is not part of the ISO 10303-11 standard.
|
||||
|
||||
### STEPcode's Solution
|
||||
STEPcode implements **flow-sensitive type narrowing** as an extension:
|
||||
- Recognizes TYPEOF guard patterns like `'Type' IN TYPEOF(var)` in AND expressions
|
||||
- Automatically narrows the type for subsequent uses
|
||||
- Makes the original schema parse successfully
|
||||
|
||||
### Standards-Compliant Alternative
|
||||
The TREAT version uses the ISO 10303-11 TREAT expression:
|
||||
- `TREAT(item AS set_representation_item)` explicitly narrows the type
|
||||
- No implicit narrowing needed
|
||||
- Works in any compliant EXPRESS parser
|
||||
|
||||
## Testing
|
||||
|
||||
Both versions parse successfully and produce identical output:
|
||||
|
||||
```bash
|
||||
# Run comparison test
|
||||
./test/compare_ap242_versions.sh
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
✓ Both versions parse successfully
|
||||
✓ Both versions generate the same number of files
|
||||
```
|
||||
|
||||
For detailed comparison, see `doc/ap242-comparison.md`.
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- `doc/ap242-comparison.md` - Detailed comparison and analysis
|
||||
- `doc/express-type-unwrapping.md` - TREAT and narrowing documentation
|
||||
- `src/express/test/README_AP242_BASELINE.md` - Historical PE056 error info
|
||||
@@ -1,165 +0,0 @@
|
||||
# AP242 Schema Comparison: Flow-Sensitive Narrowing vs TREAT Expression
|
||||
|
||||
## Overview
|
||||
|
||||
This document compares two versions of the AP242 schema to demonstrate the difference between STEPcode's non-standard flow-sensitive narrowing extension and the ISO 10303-11 compliant TREAT expression.
|
||||
|
||||
## Schema Versions
|
||||
|
||||
### 1. Original Version (`242_mim_lf.exp`)
|
||||
- **Status**: Uses implicit flow-sensitive narrowing (non-standard extension)
|
||||
- **Location**: `data/ap242/242_mim_lf.exp`
|
||||
- **Size**: 54,756 lines
|
||||
- **Problematic code**: Line 34149 in `styled_item` entity, WR3 WHERE rule
|
||||
|
||||
### 2. TREAT Version (`242_mim_lf_treat.exp`)
|
||||
- **Status**: Standards-compliant using TREAT expression
|
||||
- **Location**: `data/ap242/242_mim_lf_treat.exp`
|
||||
- **Size**: 54,756 lines
|
||||
- **Fix applied**: Line 34149 - explicit TREAT expression
|
||||
|
||||
## The Problem
|
||||
|
||||
In the `styled_item` entity at line ~34148, the WHERE rule WR3 contains:
|
||||
|
||||
```express
|
||||
WR3: ('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.MAPPED_ITEM' IN TYPEOF(item)) OR
|
||||
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN TYPEOF(item)) OR
|
||||
(('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.SET_REPRESENTATION_ITEM' IN TYPEOF(item)) AND
|
||||
(SIZEOF(QUERY(it <* item | ...)) = 0));
|
||||
```
|
||||
|
||||
### Issue
|
||||
- `item` is of type `styled_item_target`, which is a SELECT type
|
||||
- The SELECT contains `set_representation_item` (which is an aggregate type)
|
||||
- The code checks `'SET_REPRESENTATION_ITEM' IN TYPEOF(item)` (a TYPEOF guard)
|
||||
- Then tries to iterate over `item` in a QUERY: `QUERY(it <* item | ...)`
|
||||
|
||||
### Why This Was Problematic
|
||||
According to strict ISO 10303-11 standards, you cannot iterate over a SELECT type directly in a QUERY expression, even if there's a preceding TYPEOF guard. The guard and the QUERY are separate expressions in an AND clause.
|
||||
|
||||
## The Solutions
|
||||
|
||||
### Solution 1: Flow-Sensitive Narrowing (Non-Standard Extension)
|
||||
|
||||
STEPcode implements a **flow-sensitive type narrowing** extension that:
|
||||
1. Recognizes the pattern `'TypeName' IN TYPEOF(var)` in AND expressions
|
||||
2. Automatically narrows the type of `var` to `TypeName` for subsequent expressions in the AND
|
||||
3. Allows `QUERY(it <* item | ...)` to work because `item` is implicitly narrowed to `set_representation_item`
|
||||
|
||||
**Code (original, line 34149)**:
|
||||
```express
|
||||
QUERY(it <* item | ...)
|
||||
```
|
||||
|
||||
**How it works**:
|
||||
- The AND expression LHS has the guard: `'SET_REPRESENTATION_ITEM' IN TYPEOF(item)`
|
||||
- The RHS has the QUERY: `SIZEOF(QUERY(it <* item | ...)) = 0`
|
||||
- STEPcode's narrowing recognizes the pattern and narrows `item` to `set_representation_item`
|
||||
- The QUERY can now iterate over the narrowed type
|
||||
|
||||
### Solution 2: TREAT Expression (Standards-Compliant)
|
||||
|
||||
The ISO 10303-11 standard provides the TREAT expression for explicit type narrowing:
|
||||
|
||||
**Code (TREAT version, line 34149)**:
|
||||
```express
|
||||
QUERY(it <* TREAT(item AS set_representation_item) | ...)
|
||||
```
|
||||
|
||||
**How it works**:
|
||||
- `TREAT(item AS set_representation_item)` explicitly narrows the SELECT type to the member type
|
||||
- The QUERY can iterate over the result of TREAT, which is guaranteed to be `set_representation_item`
|
||||
- No implicit narrowing needed - the intent is explicit in the code
|
||||
|
||||
## The Exact Difference
|
||||
|
||||
```diff
|
||||
--- data/ap242/242_mim_lf.exp
|
||||
+++ data/ap242/242_mim_lf_treat.exp
|
||||
@@ -34146,7 +34146,7 @@
|
||||
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN TYPEOF(item)) OR
|
||||
(('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.SET_REPRESENTATION_ITEM' IN TYPEOF(item)) AND
|
||||
(SIZEOF(QUERY(it
|
||||
- <* item
|
||||
+ <* TREAT(item AS set_representation_item)
|
||||
| NOT (('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.MAPPED_ITEM' IN TYPEOF(it)) OR
|
||||
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN
|
||||
TYPEOF(it))))) =
|
||||
```
|
||||
|
||||
**Change**: Single line change from `<* item` to `<* TREAT(item AS set_representation_item)`
|
||||
|
||||
## Testing Results
|
||||
|
||||
### Original Version (with Flow-Sensitive Narrowing)
|
||||
```bash
|
||||
./build/bin/exp2cxx data/ap242/242_mim_lf.exp /tmp/ap242_original_test
|
||||
```
|
||||
**Result**: ✅ Parses successfully, generates 5,626 C++ files
|
||||
|
||||
### TREAT Version (Standards-Compliant)
|
||||
```bash
|
||||
./build/bin/exp2cxx data/ap242/242_mim_lf_treat.exp /tmp/ap242_treat_test
|
||||
```
|
||||
**Result**: ✅ Parses successfully, generates 5,626 C++ files
|
||||
|
||||
### Output Comparison
|
||||
Both versions generate identical output:
|
||||
- Same number of entities
|
||||
- Same entity relationships
|
||||
- Same multiple inheritance warnings
|
||||
- Identical "Finished writing files" status
|
||||
|
||||
## Verification
|
||||
|
||||
To verify both versions produce consistent output:
|
||||
|
||||
```bash
|
||||
# Parse original version
|
||||
mkdir -p /tmp/ap242_original
|
||||
./build/bin/exp2cxx data/ap242/242_mim_lf.exp /tmp/ap242_original
|
||||
|
||||
# Parse TREAT version
|
||||
mkdir -p /tmp/ap242_treat
|
||||
./build/bin/exp2cxx data/ap242/242_mim_lf_treat.exp /tmp/ap242_treat
|
||||
|
||||
# Compare generated headers (should be identical except for file references)
|
||||
diff /tmp/ap242_original/SdaiAP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.h \
|
||||
/tmp/ap242_treat/SdaiAP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.h
|
||||
```
|
||||
|
||||
## Implications
|
||||
|
||||
### For STEPcode Users
|
||||
- **Current**: Both versions work due to flow-sensitive narrowing extension
|
||||
- **Future**: TREAT version is more portable if other EXPRESS parsers are used
|
||||
- **Recommended**: Use TREAT for new schemas to ensure standards compliance
|
||||
|
||||
### For STEPcode Development
|
||||
- Flow-sensitive narrowing is a valuable usability extension
|
||||
- TREAT expression provides standards-compliant alternative
|
||||
- Both should continue to be supported for compatibility
|
||||
|
||||
### For Standards Compliance
|
||||
- Original AP242 schema uses pattern that requires extension
|
||||
- TREAT version is fully ISO 10303-11 compliant
|
||||
- TREAT makes intent explicit and improves code clarity
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- `doc/express-type-unwrapping.md` - Full documentation of TREAT and narrowing features
|
||||
- `src/express/test/README_AP242_BASELINE.md` - Historical PE056 error documentation
|
||||
- Test schemas:
|
||||
- `test/unitary_schemas/flow_narrowing_test.exp` - Flow-sensitive narrowing examples
|
||||
- `test/unitary_schemas/minimal_treat_test.exp` - TREAT expression examples
|
||||
|
||||
## Conclusion
|
||||
|
||||
This comparison demonstrates:
|
||||
1. ✅ STEPcode's flow-sensitive narrowing successfully handles the original AP242 schema
|
||||
2. ✅ TREAT expression provides the standards-compliant alternative
|
||||
3. ✅ Both approaches produce identical, correct output
|
||||
4. ✅ The single-line change makes the code more explicit and portable
|
||||
|
||||
The availability of both approaches gives users flexibility while maintaining standards compliance when needed.
|
||||
@@ -1,251 +0,0 @@
|
||||
# AP242 API v2 Output Benchmarks
|
||||
|
||||
This file records comparable measurements for the staged API v2 output
|
||||
work. It is intended to make changes in generated output cost visible in
|
||||
the commits which introduce them.
|
||||
|
||||
## Method
|
||||
|
||||
The measurements were made on 2026-08-02 with GCC 13.3.0 and C++11.
|
||||
|
||||
The schema under test was BRL-CAD's `ap242e4.exp` conversion schema.
|
||||
The real exchange-file workload was the NIST STC 09 ASME AP242 edition
|
||||
4 sample, `nist_stc_09_asme1_ap242-e4.stp`.
|
||||
|
||||
The generator used `--late-bound`, the default 64-entity and 8-type chunk
|
||||
limits, and a release STEPcode build. Compilation used `-O2 -fPIC` and two
|
||||
concurrent compiler processes. Generated-output counts include `.cc`, `.h`,
|
||||
and `.cmake` files through directory depth two. The baseline is commit
|
||||
`fa2758c5` before recommendations 1--4.
|
||||
|
||||
## Results
|
||||
|
||||
| Measurement | Baseline | Recommendations 1--4 | Change |
|
||||
|---|---:|---:|---:|
|
||||
| Generated files | 5,719 | 905 | -84.2% |
|
||||
| Generated lines | 254,220 | 123,552 | -51.4% |
|
||||
| Generated bytes | 13,942,523 | 9,804,680 | -29.7% |
|
||||
| Entity leaf files | 4,814 | 0 | -100.0% |
|
||||
| Generation wall time | 2.74 s | 0.56 s | -79.6% |
|
||||
| Generation peak RSS | 109,024 KiB | 109,280 KiB | +0.2% |
|
||||
| Compile/link wall time | 157.68 s | 37.02 s | -76.5% |
|
||||
| Compile/link user time | 277.75 s | 66.32 s | -76.1% |
|
||||
| Compile/link peak RSS | 593,320 KiB | 199,156 KiB | -66.4% |
|
||||
| Schema shared library | 9,956,640 B | 7,716,096 B | -22.5% |
|
||||
| ELF relocations | 28,843 | 39,719 | +37.7% |
|
||||
| Function symbols | 15,641 | 13,542 | -13.4% |
|
||||
| Read/write wall time | 0.26 s | 0.25 s | -3.8% |
|
||||
| Read/write peak RSS | 88,732 KiB | 85,040 KiB | -4.2% |
|
||||
|
||||
The relocation increase is caused by the stable module-ID tables referring
|
||||
to descriptor slots. It is recorded here because the packed schema image
|
||||
stage is expected to remove most of that cost.
|
||||
|
||||
## Recommendations 1--4
|
||||
|
||||
This stage adds stable entity, type, and attribute IDs through `SchemaModule`,
|
||||
makes compatibility entity names opt-in for late-bound output, moves schema
|
||||
rules and complex-entity support to runtime-consumed tables, and writes late
|
||||
entity metadata directly to bounded chunks instead of creating 4,814 leaf
|
||||
files.
|
||||
|
||||
The real AP242 exchange-file check created and validated 10,609 instances
|
||||
with zero errors and zero warnings. Its 949,685-byte rewritten Part 21 file
|
||||
matched the baseline apart from the expected `FILE_NAME` timestamp.
|
||||
|
||||
## Recommendation 5
|
||||
|
||||
This stage resolves each late-bound entity's flattened attribute layout once
|
||||
after schema initialization. Instance construction then follows descriptor
|
||||
and index records directly instead of recursively walking supertypes and
|
||||
repeating attribute-name searches. The cache is external to
|
||||
`EntityDescriptor`, so its object layout and the API v1 ABI are unchanged.
|
||||
|
||||
The construction benchmark uses the 1,531 `DIRECTION` instances in the real
|
||||
exchange file and repeats that population 1,000 times. This isolates the
|
||||
work changed by this stage while retaining a type and frequency from the
|
||||
AP242 workload. Results are the median of three runs.
|
||||
|
||||
| Measurement | Recommendations 1--4 | Recommendation 5 | Change |
|
||||
|---|---:|---:|---:|
|
||||
| 1,531,000 entity constructions | 0.84 s | 0.63 s | -25.0% |
|
||||
| Construction user time | 0.82 s | 0.61 s | -25.6% |
|
||||
| Construction peak RSS | 68,956 KiB | 69,600 KiB | +0.9% |
|
||||
| 20 full read/write runs | 4.90 s | 4.91 s | no measurable change |
|
||||
| Full read/write peak RSS | 85,164 KiB | 85,732 KiB | +0.7% |
|
||||
| `libstepcore` size | 640,936 B | 651,312 B | +1.6% |
|
||||
|
||||
The complete exchange-file check still created and validated 10,609
|
||||
instances with zero errors and zero warnings. Its rewritten file remained
|
||||
949,685 bytes and differed from the previous stage only in the expected
|
||||
`FILE_NAME` timestamp. Generated schema file counts, source size, and the
|
||||
schema shared library are unchanged because this is a shared-runtime change.
|
||||
|
||||
## Recommendation 6
|
||||
|
||||
This stage replaces the generated `SchemaModuleSlot` pointer arrays with a
|
||||
16-byte, relocation-free `SchemaModuleImage`. Shared initialization helpers
|
||||
capture descriptor pointers in stable generated-ID order and transfer those
|
||||
vectors to `SchemaModule` after initialization. The older slot-based entry
|
||||
point remains available for existing generated API v2 code.
|
||||
|
||||
Source and binary measurements compare recommendation 5 with the packed
|
||||
image. Compile times use matching clean CMake builds with two compiler
|
||||
processes. Read/write times are medians from paired 20-run batches.
|
||||
|
||||
| Measurement | Recommendation 5 | Recommendation 6 | Change |
|
||||
|---|---:|---:|---:|
|
||||
| Generated files | 905 | 905 | unchanged |
|
||||
| Generated lines | 123,552 | 117,046 | -5.3% |
|
||||
| Generated bytes | 9,804,680 | 9,060,249 | -7.6% |
|
||||
| Schema module source | 808,907 B | 64,367 B | -92.0% |
|
||||
| Schema module source lines | 7,280 | 773 | -89.4% |
|
||||
| Compile/link wall time | 41.38 s | 41.49 s | no measurable change |
|
||||
| Compile/link peak RSS | 208,312 KiB | 208,188 KiB | -0.1% |
|
||||
| Schema shared library | 7,728,384 B | 7,470,304 B | -3.3% |
|
||||
| ELF relocations | 39,719 | 33,221 | -16.4% |
|
||||
| 20 full read/write runs | 5.10 s | 5.07 s | -0.6% |
|
||||
| Full read/write peak RSS | 85,736 KiB | 85,572 KiB | -0.2% |
|
||||
| `libstepcore` size | 651,312 B | 661,088 B | +1.5% |
|
||||
|
||||
The image removes 6,498 per-descriptor pointer relocations. The shared
|
||||
runtime grows by 9,776 bytes once, while each AP242 schema library is 258,080
|
||||
bytes smaller. Generated API v1 output and the conventional public entity
|
||||
classes remain unchanged.
|
||||
|
||||
The complete exchange-file check again created and validated 10,609
|
||||
instances with zero errors and zero warnings. Its 949,685-byte rewrite
|
||||
differed from recommendation 5 only in the expected `FILE_NAME` timestamp.
|
||||
|
||||
## Recommendation 7
|
||||
|
||||
This stage replaces the remaining generated descriptor procedures with one
|
||||
bounded, offset-based schema image. The shared loader validates every array,
|
||||
string, range, descriptor reference, schema binding, and complex-entity tree
|
||||
before it changes the registry. It then constructs the descriptor graph with
|
||||
an explicit per-load context; the process-global capture path remains only for
|
||||
older generated API v2 code. Complex-entity metadata uses the same packed
|
||||
representation and validation model.
|
||||
|
||||
Source and binary measurements compare recommendation 6 with the complete
|
||||
descriptor image. Compile times use clean CMake builds with two compiler
|
||||
processes. Read/write times use matching 20-run batches.
|
||||
|
||||
| Measurement | Recommendation 6 | Recommendation 7 | Change |
|
||||
|---|---:|---:|---:|
|
||||
| Generated files | 905 | 865 | -4.4% |
|
||||
| Generated lines | 117,046 | 86,400 | -26.2% |
|
||||
| Generated bytes | 9,060,249 | 4,865,657 | -46.3% |
|
||||
| Entity initialization chunks | 38 | 0 | -100.0% |
|
||||
| Compile/link wall time | 41.49 s | 18.71 s | -54.9% |
|
||||
| Compile/link peak RSS | 208,188 KiB | 208,528 KiB | +0.2% |
|
||||
| Schema shared library | 7,470,304 B | 3,503,352 B | -53.1% |
|
||||
| ELF relocations | 33,221 | 9,620 | -71.0% |
|
||||
| 20 full read/write runs | 5.07 s | 4.97 s | -2.0% |
|
||||
| Full read/write peak RSS | 85,572 KiB | 82,916 KiB | -3.1% |
|
||||
|
||||
The image removes the 2,407 generated entity initialization functions and
|
||||
23,601 additional relocations. The generated schema library is 3,966,952
|
||||
bytes smaller, while its existing typed SELECT and enumeration factories
|
||||
remain available for this transitional stage.
|
||||
|
||||
The complete exchange-file check created and validated 10,609 instances with
|
||||
zero errors and zero warnings. Its 949,685-byte rewrite retained the same
|
||||
semantic result as recommendation 6.
|
||||
|
||||
## Recommendations 8 and 9
|
||||
|
||||
This stage makes the compact late-bound output independent of generated type
|
||||
classes. Shared descriptor-driven implementations now construct SELECT,
|
||||
enumeration, and aggregate values, including nested values and BOOLEAN or
|
||||
LOGICAL aliases. Enumeration elements and renamed USE or REFERENCE items are
|
||||
retained in the packed image. The conventional early-bound API v1 and API v2
|
||||
paths still emit their schema-specific type classes.
|
||||
|
||||
The generated schema header is now a dependency-bounded consumer interface.
|
||||
It contains stable entity, type, and attribute IDs plus `SchemaModule` lookup
|
||||
functions, and includes only `schemaModule.h`. Runtime and model-construction
|
||||
declarations remain in the internal `schema.h` umbrella.
|
||||
|
||||
| Measurement | Recommendation 7 | Recommendations 8--9 | Change |
|
||||
|---|---:|---:|---:|
|
||||
| Generated files | 865 | 10 | -98.8% |
|
||||
| Generated lines | 86,400 | 54,839 | -36.5% |
|
||||
| Generated bytes | 4,865,657 | 3,303,993 | -32.1% |
|
||||
| Type leaf files | 802 | 0 | -100.0% |
|
||||
| Type initialization chunks | 51 | 0 | -100.0% |
|
||||
| Compile/link wall time | 18.71 s | 1.21 s | -93.5% |
|
||||
| Compile/link peak RSS | 208,528 KiB | 126,580 KiB | -39.3% |
|
||||
| Schema shared library | 3,503,352 B | 2,178,296 B | -37.8% |
|
||||
| ELF relocations | 9,620 | 49 | -99.5% |
|
||||
| Exported function symbols | 4,647 | 8 | -99.8% |
|
||||
| Public header preprocessed bytes | 2,384,191 | 635,945 | -73.3% |
|
||||
| 20 full read/write runs | 4.97 s | 4.91 s | -1.2% |
|
||||
| Full read/write peak RSS | 82,916 KiB | 82,304 KiB | -0.7% |
|
||||
|
||||
The complete exchange-file check again created and validated 10,609
|
||||
instances with zero errors and zero warnings, and wrote the same 949,685-byte
|
||||
semantic result. Runtime unit coverage separately exercises generic SELECT,
|
||||
enumeration, aggregate, malformed-image, and packed rename behavior.
|
||||
|
||||
## Recommendation 10
|
||||
|
||||
This stage adds an opt-in `structural` metadata profile for late-bound API
|
||||
version 2. The default `full` profile is unchanged. Structural images keep
|
||||
the descriptor graph needed to construct, read, write, and inspect entity,
|
||||
attribute, type, aggregate, enumeration, SELECT, inverse, and renamed values.
|
||||
They omit EXPRESS descriptions, WHERE and UNIQUE rules, schema rule and
|
||||
algorithm text, supertype statements, derived expressions, and symbolic
|
||||
aggregate-bound text.
|
||||
|
||||
The source and library measurements below compare matching fresh output from
|
||||
the two profiles. Compile times use clean CMake builds with one compiler
|
||||
process; read/write times use matching 20-run batches.
|
||||
|
||||
| Measurement | Full metadata | Structural metadata | Change |
|
||||
|---|---:|---:|---:|
|
||||
| Generated files | 10 | 10 | unchanged |
|
||||
| Generated lines | 54,839 | 29,993 | -45.3% |
|
||||
| Generated bytes | 3,304,007 | 1,525,897 | -53.8% |
|
||||
| Packed schema source | 2,612,413 B | 834,303 B | -68.1% |
|
||||
| Generation wall time | 0.48 s | 0.41 s | -14.6% |
|
||||
| Compile/link wall time | 2.08 s | 2.03 s | -2.4% |
|
||||
| Compile/link peak RSS | 126,784 KiB | 118,220 KiB | -6.8% |
|
||||
| Schema shared library | 2,178,296 B | 720,120 B | -66.9% |
|
||||
| ELF relocations | 49 | 49 | unchanged |
|
||||
| 20 full read/write runs | 4.76 s | 4.71 s | -1.1% |
|
||||
| Full read/write peak RSS | 82,276 KiB | 78,900 KiB | -4.1% |
|
||||
|
||||
The structural profile created and validated all 10,609 instances in the
|
||||
real exchange file with zero errors and zero warnings. It wrote the same
|
||||
949,685-byte semantic result as the full profile.
|
||||
|
||||
## Recommendation 11
|
||||
|
||||
This stage writes each generated file to a sibling temporary file and replaces
|
||||
the destination only when its content changes. A compact generated-file
|
||||
manifest supports safe cleanup when an option change makes old entity, type,
|
||||
or unity files obsolete; files not named by the previous manifest are left
|
||||
alone. The manifest itself is also content-stable.
|
||||
|
||||
The deterministic-output audit also found that nonliteral aggregate bounds
|
||||
were being read through the integer member of the expression union. Packed
|
||||
images now emit those bounds as expression records, eliminating process-address
|
||||
values from generated AP242 source as well as correcting the metadata kind.
|
||||
|
||||
| Measurement after identical AP242 generation | Rewrite all | Stable output | Change |
|
||||
|---|---:|---:|---:|
|
||||
| Changed schema source/header timestamps | 10 of 10 | 0 of 10 | -100.0% |
|
||||
| Changed manifest timestamps | n/a | 0 of 1 | stable |
|
||||
| Generation wall time | 0.41 s | 0.40 s | no overhead |
|
||||
| Following CMake build wall time | 2.01 s | 0.06 s | -97.0% |
|
||||
| Following build peak RSS | 118,108 KiB | 18,432 KiB | -84.4% |
|
||||
|
||||
The AP242 manifest is 390 bytes. Switching the focused regression schema
|
||||
from early-bound API version 2 to compact late-bound output removes all stale
|
||||
entity, type, and unity files and their empty directories while preserving an
|
||||
unrelated file in the output directory.
|
||||
|
||||
The real exchange-file check still created and validated all 10,609 instances
|
||||
with zero errors and zero warnings. Its rewritten result remained 949,685
|
||||
bytes.
|
||||
@@ -1,367 +0,0 @@
|
||||
# EXPRESS Type Unwrapping and Narrowing
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the type unwrapping and narrowing features implemented in STEPcode's EXPRESS compiler. These features enable proper type checking and semantic analysis for aggregate types and SELECT type narrowing.
|
||||
|
||||
**Note:** Some features described here are extensions beyond the ISO 10303-11 standard and are explicitly marked as such.
|
||||
|
||||
## Deep Aggregate Unwrapping
|
||||
|
||||
### Background
|
||||
|
||||
In EXPRESS, aggregate types (ARRAY, LIST, SET, BAG) can be nested and wrapped in type definitions. For semantic analysis and type checking, the compiler often needs to "unwrap" these layers to access the underlying element type.
|
||||
|
||||
### Shallow vs Deep Type Checking
|
||||
|
||||
#### Shallow Aggregate Check: `TYPEis_aggregate`
|
||||
|
||||
The macro `TYPEis_aggregate(t)` performs a **shallow** check by testing if `t->u.type->body->base` is non-NULL. This indicates the type has a base type, which is characteristic of aggregate types.
|
||||
|
||||
```c
|
||||
#define TYPEis_aggregate(t) ((t)->u.type->body->base)
|
||||
```
|
||||
|
||||
**Important:** This is a shallow check and does not follow type definition chains. It returns true if the immediate type structure has a base type.
|
||||
|
||||
**Use when:**
|
||||
- You need a quick check if a type is directly an aggregate
|
||||
- You're working with the immediate type structure
|
||||
- Performance is critical and deep unwrapping isn't needed
|
||||
|
||||
#### Deep Aggregate Unwrapping: `TYPEget_nonaggregate_base_type`
|
||||
|
||||
The function `TYPEget_nonaggregate_base_type(Type t)` performs **deep unwrapping** by iteratively following the chain of aggregate base types until reaching a non-aggregate type.
|
||||
|
||||
```express
|
||||
TYPE int_list = LIST OF INTEGER;
|
||||
TYPE named_int_list = int_list; -- typedef chain
|
||||
TYPE set_of_lists = SET OF named_int_list;
|
||||
```
|
||||
|
||||
For `set_of_lists`:
|
||||
- `TYPEis_aggregate()` → true (immediate check)
|
||||
- `TYPEget_nonaggregate_base_type()` → INTEGER (unwraps through SET → LIST → INTEGER)
|
||||
|
||||
**Use when:**
|
||||
- Comparing element types across different aggregate wrappers
|
||||
- Type resolution requires the ultimate element type
|
||||
- Semantic checking needs to validate deep type compatibility
|
||||
|
||||
### Deep Unwrapping Implementation
|
||||
|
||||
```c
|
||||
Type TYPEget_nonaggregate_base_type( Type t ) {
|
||||
while( TYPEis_aggregate( t ) ) {
|
||||
t = t->u.type->body->base;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
```
|
||||
|
||||
This function safely handles:
|
||||
- Nested aggregates (SET OF LIST OF ...)
|
||||
- Type definition chains
|
||||
- Mixed aggregate types
|
||||
|
||||
### Aggregate Type Comparison: `TYPE_retrieve_aggregate`
|
||||
|
||||
For SELECT types containing multiple aggregate members, `TYPE_retrieve_aggregate()` validates that all aggregate members share the same element type.
|
||||
|
||||
```express
|
||||
TYPE item_a = SET OF INTEGER;
|
||||
TYPE item_b = LIST OF INTEGER;
|
||||
TYPE my_select = SELECT(item_a, item_b); -- Valid: both have INTEGER elements
|
||||
```
|
||||
|
||||
The function:
|
||||
1. Iterates through SELECT members
|
||||
2. Identifies which are aggregates
|
||||
3. Unwraps typedef chains to find element types
|
||||
4. Returns common element type or NULL if incompatible
|
||||
|
||||
## TREAT Expression Semantics
|
||||
|
||||
### ISO 10303-11 Standard Syntax
|
||||
|
||||
The TREAT expression is defined in ISO 10303-11 as:
|
||||
|
||||
```express
|
||||
TREAT(expression AS type_identifier)
|
||||
```
|
||||
|
||||
**Purpose:** Explicitly narrow a SELECT type to one of its member types.
|
||||
|
||||
### STEPcode Implementation
|
||||
|
||||
STEPcode implements TREAT as specified in ISO 10303-11 with the following semantics:
|
||||
|
||||
#### Type Resolution
|
||||
|
||||
1. **Operand Resolution:** The expression being narrowed is resolved first
|
||||
```c
|
||||
EXPresolve( e->e.op1, s, Type_Dont_Care );
|
||||
operand_type = e->e.op1->return_type;
|
||||
```
|
||||
|
||||
2. **Target Type Lookup:** The target type identifier is resolved via scope lookup
|
||||
```c
|
||||
target_type = (Type)SCOPEfind( s, e->symbol.name, SCOPE_FIND_TYPE );
|
||||
```
|
||||
|
||||
3. **Type Compatibility:** The implementation validates that narrowing is semantically valid
|
||||
- For SELECT operands: Verifies target is a member type
|
||||
- For other types: Allows permissively (may emit warnings)
|
||||
|
||||
4. **Return Type:** The expression's return type becomes the target type
|
||||
```c
|
||||
return target_type; /* Not Type_Generic */
|
||||
```
|
||||
|
||||
#### Error Handling
|
||||
|
||||
**Clear errors with location information:**
|
||||
|
||||
- **Missing operand:** `SYNTAX` error - "TREAT expression missing operand"
|
||||
- **Missing target type:** `SYNTAX` error - "TREAT expression missing target type"
|
||||
- **Undefined type:** `UNDEFINED_TYPE` error with the type name
|
||||
- **Type mismatch:** Currently permissive (no error, future: may warn)
|
||||
|
||||
All errors use `ERRORreport_with_symbol()` which provides:
|
||||
- File name and line number
|
||||
- Symbol context
|
||||
- Descriptive error message
|
||||
|
||||
#### Example Usage
|
||||
|
||||
```express
|
||||
TYPE attachment = SELECT(nail, screw);
|
||||
END_TYPE;
|
||||
|
||||
FUNCTION get_length(item : attachment) : REAL;
|
||||
LOCAL
|
||||
n : nail;
|
||||
END_LOCAL;
|
||||
|
||||
IF ('EXAMPLE.NAIL' IN TYPEOF(item)) THEN
|
||||
n := TREAT(item AS nail); -- Narrows SELECT to nail
|
||||
RETURN n.length;
|
||||
END_IF;
|
||||
|
||||
RETURN 0.0;
|
||||
END_FUNCTION;
|
||||
```
|
||||
|
||||
### Grammar Integration
|
||||
|
||||
The TREAT syntax is integrated into the EXPRESS parser grammar as a unary expression:
|
||||
|
||||
```yacc
|
||||
unary_expression ::= TOK_TREAT TOK_LEFT_PAREN expression TOK_AS
|
||||
TOK_IDENTIFIER TOK_RIGHT_PAREN
|
||||
```
|
||||
|
||||
Key points:
|
||||
- `TOK_TREAT`: Recognized as a keyword
|
||||
- Creates unary expression with `OP_TREAT` operator
|
||||
- Operand stored in `op1`
|
||||
- Target type name stored in `symbol` field
|
||||
|
||||
## Flow-Sensitive SELECT Narrowing
|
||||
|
||||
**Extension Status:** This is a **non-standard extension** that enhances type safety for SELECT types.
|
||||
|
||||
### Background
|
||||
|
||||
EXPRESS WHERE clauses often use TYPEOF guards to check SELECT types before accessing member-specific attributes. Flow-sensitive narrowing automatically narrows SELECT types within the scope of such guards.
|
||||
|
||||
### Pattern Recognition
|
||||
|
||||
The narrowing system recognizes this pattern:
|
||||
|
||||
```express
|
||||
'TypeName' IN TYPEOF(variable)
|
||||
```
|
||||
|
||||
When this pattern appears in an AND conjunction, the variable is narrowed to `TypeName` for subsequent expressions in the conjunction.
|
||||
|
||||
### Implementation Architecture
|
||||
|
||||
#### Refinement Context
|
||||
|
||||
A **refinement context** tracks active type narrowings during expression resolution:
|
||||
|
||||
```c
|
||||
typedef struct RefinementContext_ {
|
||||
Refinement refinements; /* Linked list of variable → type mappings */
|
||||
struct RefinementContext_ *previous; /* Stack of contexts */
|
||||
} *RefinementContext;
|
||||
|
||||
RefinementContext active_refinements = NULL; /* Thread-local global */
|
||||
```
|
||||
|
||||
#### Pattern Matching
|
||||
|
||||
The function `match_typeof_guard()` identifies guard patterns:
|
||||
|
||||
1. Expression is `IN` operator
|
||||
2. Left operand is string literal (type name)
|
||||
3. Right operand is `TYPEOF(identifier)`
|
||||
4. Identifier resolves to a variable
|
||||
|
||||
#### Refinement Collection
|
||||
|
||||
The function `collect_refinements_from_conjunction()` recursively walks AND expressions:
|
||||
|
||||
1. Recursively descends into AND nodes
|
||||
2. Matches TYPEOF guard patterns at leaves
|
||||
3. Validates narrowing is semantically correct:
|
||||
- Variable must have SELECT type
|
||||
- Target type must be SELECT member (validated via `is_select_member()`)
|
||||
4. Returns linked list of valid refinements
|
||||
|
||||
#### Application
|
||||
|
||||
In `EXPresolve_op_and()`:
|
||||
|
||||
```c
|
||||
Type EXPresolve_op_and(Expression e, Scope s) {
|
||||
EXPresolve(e->e.op1, s, Type_Dont_Care); /* Resolve LHS normally */
|
||||
|
||||
Refinement refs = collect_refinements_from_conjunction(e->e.op1, s);
|
||||
|
||||
if (refs) {
|
||||
/* Create temporary context */
|
||||
struct RefinementContext_ ctx;
|
||||
ctx.refinements = refs;
|
||||
ctx.previous = active_refinements;
|
||||
active_refinements = &ctx;
|
||||
|
||||
EXPresolve(e->e.op2, s, Type_Dont_Care); /* Resolve RHS with narrowing */
|
||||
|
||||
/* Restore previous context */
|
||||
active_refinements = ctx.previous;
|
||||
free_refinements(refs);
|
||||
} else {
|
||||
EXPresolve(e->e.op2, s, Type_Dont_Care);
|
||||
}
|
||||
|
||||
return Type_Logical;
|
||||
}
|
||||
```
|
||||
|
||||
### Behavior Scope
|
||||
|
||||
**What is narrowed:**
|
||||
- Variables with SELECT type
|
||||
- Within RHS of AND expressions
|
||||
- Where LHS contains TYPEOF guard
|
||||
|
||||
**What is NOT narrowed:**
|
||||
- OR expressions (conservative - doesn't extract from disjunction)
|
||||
- NOT expressions (conservative - doesn't extract from negation)
|
||||
- Other boolean operators
|
||||
- Variables not guarded by TYPEOF
|
||||
|
||||
**Rationale:** Conservative approach prevents false narrowing in cases where the guard may not hold.
|
||||
|
||||
### Limitations
|
||||
|
||||
1. **Single-level context:** Only immediate AND RHS is narrowed, not deeply nested scopes
|
||||
2. **No cross-statement narrowing:** Limited to expression-level scope
|
||||
3. **AND-only:** Does not propagate through OR/NOT (conservative)
|
||||
4. **Pattern-based:** Only recognizes exact `'Type' IN TYPEOF(var)` pattern
|
||||
|
||||
### Example
|
||||
|
||||
```express
|
||||
ENTITY test_entity;
|
||||
item : target; -- target is SELECT(set_representation_item, simple_int)
|
||||
WHERE
|
||||
wr1: ('SCHEMA.SET_REPRESENTATION_ITEM' IN TYPEOF(item)) AND
|
||||
(SIZEOF(item) > 0); -- item narrowed to set_representation_item
|
||||
END_ENTITY;
|
||||
```
|
||||
|
||||
Without narrowing, `SIZEOF(item)` would fail (can't take SIZEOF of SELECT). With narrowing, `item` is known to be an aggregate, so `SIZEOF` is valid.
|
||||
|
||||
## Memory Management
|
||||
|
||||
### Refinement Lifecycle
|
||||
|
||||
1. **Collection:** `collect_refinements_from_conjunction()` allocates refinement nodes
|
||||
2. **Usage:** Active during RHS expression resolution only
|
||||
3. **Cleanup:** `free_refinements()` called after RHS resolution completes
|
||||
|
||||
### Context Stack Model
|
||||
|
||||
The implementation uses a **stack-based context model** rather than deep copying:
|
||||
|
||||
- `RefinementContext` has `previous` pointer forming a stack
|
||||
- New contexts pushed onto stack with `active_refinements = &ctx`
|
||||
- Restored with `active_refinements = ctx.previous`
|
||||
- No deep copying of refinement data
|
||||
|
||||
**Memory safety:**
|
||||
- Refinement nodes allocated individually
|
||||
- Freed immediately after use
|
||||
- No dangling pointers (stack-local contexts)
|
||||
- No memory leaks (verified by code inspection)
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Coverage
|
||||
|
||||
**TREAT expression tests:**
|
||||
- `test/unitary_schemas/minimal_treat_test.exp` - Basic TREAT usage
|
||||
- `test/unitary_schemas/test_treat_real.exp` - Nested SELECT types
|
||||
- `test/unitary_schemas/treat_expression.exp` - TREAT in WHERE clauses
|
||||
|
||||
**Flow-sensitive narrowing tests:**
|
||||
- `test/unitary_schemas/flow_narrowing_test.exp` - AND-based narrowing
|
||||
- `test/unitary_schemas/select_aggregate_test.exp` - SELECT of aggregates
|
||||
|
||||
**Production schema comparison:**
|
||||
- `data/ap242/242_mim_lf.exp` - Original AP242 with flow-sensitive narrowing
|
||||
- `data/ap242/242_mim_lf_treat.exp` - TREAT-based standards-compliant version
|
||||
- `test/compare_ap242_versions.sh` - Automated comparison script
|
||||
|
||||
See `doc/ap242-comparison.md` for detailed analysis of the AP242 schema comparison.
|
||||
|
||||
### AP242 Compatibility
|
||||
|
||||
The implementation is validated against the AP242 schema, ensuring:
|
||||
- Large-scale schema parsing succeeds
|
||||
- Complex type hierarchies handled correctly
|
||||
- Production schema compatibility
|
||||
|
||||
**AP242 Schema Versions:**
|
||||
- `data/ap242/242_mim_lf.exp` - Original schema using flow-sensitive narrowing extension
|
||||
- `data/ap242/242_mim_lf_treat.exp` - Standards-compliant version using TREAT expression
|
||||
|
||||
Both versions parse successfully and produce identical output. See `doc/ap242-comparison.md` for detailed analysis.
|
||||
|
||||
## Standards Compliance Notes
|
||||
|
||||
### ISO 10303-11 Compliance
|
||||
|
||||
**Fully compliant:**
|
||||
- TREAT expression syntax and semantics
|
||||
- Aggregate type definitions
|
||||
- SELECT type definitions
|
||||
- Standard type resolution rules
|
||||
|
||||
**Extensions (non-standard):**
|
||||
- Flow-sensitive type narrowing in AND expressions
|
||||
- Permissive TREAT type checking (warns vs errors)
|
||||
|
||||
### Extension Philosophy
|
||||
|
||||
STEPcode's extensions follow these principles:
|
||||
|
||||
1. **Conservative:** Only apply when semantically safe
|
||||
2. **Permissive:** Prefer warnings over errors where reasonable
|
||||
3. **Explicit:** Document extensions clearly
|
||||
4. **Compatible:** Don't break standard-compliant schemas
|
||||
|
||||
Extensions are designed to enhance usability while maintaining backward compatibility with ISO 10303-11 compliant EXPRESS schemas.
|
||||
+1
-33
@@ -45,11 +45,6 @@ EXPRESS code into C++ source code. The C++ source code is generated
|
||||
in files in the directory in which exp2cxx was run. The files are
|
||||
named according to the schema names in the input EXPRESS file.
|
||||
|
||||
Generated files are replaced only when their content changes. exp2cxx records
|
||||
the files it owns in `.exp2cxx-manifest`; a later run removes obsolete files
|
||||
from that manifest while leaving unrelated files in the output directory
|
||||
untouched.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -s|S
|
||||
@@ -62,34 +57,6 @@ Generates C++ classes for use with CORBA (Orbix).
|
||||
.B -l|L
|
||||
Prints logging code in the generated C++ classes.
|
||||
.TP
|
||||
.B -k entity-chunk-size[:type-chunk-size]
|
||||
Limits the number of generated schema objects in each deterministic unity
|
||||
translation unit. A single value applies to both entity and type chunks.
|
||||
.TP
|
||||
.B -V 1|2, --api-version 1|2
|
||||
Selects the generated C++ API. Version 1 is the source-compatible default.
|
||||
Version 2 emits compact SELECT classes, table-driven schema initialization, and
|
||||
dependency-bounded entity headers backed by shared runtime code. Version 2
|
||||
clients include the individual entity headers they use; schema.h does not
|
||||
include every entity class definition.
|
||||
.TP
|
||||
.B -T, --late-bound
|
||||
Selects API version 2 and omits generated early-bound C++ entity classes.
|
||||
Entity instances are constructed at runtime from schema descriptors. This mode
|
||||
is intended for conversion and inspection applications which do not require the
|
||||
conventional generated entity API.
|
||||
.TP
|
||||
.B --compat-names
|
||||
Retains the generated entity-name aliases in late-bound output. Normal
|
||||
late-bound API v2 output uses schema module IDs instead and omits these aliases.
|
||||
.TP
|
||||
.B --metadata full|structural
|
||||
Selects the generated schema metadata profile. Full is the default and
|
||||
retains EXPRESS descriptions, constraints, and executable schema text.
|
||||
Structural is available with late-bound API version 2; it retains the entity,
|
||||
attribute, type, aggregate, enumeration, SELECT, inverse, and rename graph
|
||||
needed by conversion tools while omitting descriptive and constraint text.
|
||||
.TP
|
||||
.B -v
|
||||
Produces a version description.
|
||||
.TP
|
||||
@@ -194,3 +161,4 @@ appropriate file to download).
|
||||
|
||||
.SH BUGS
|
||||
See fedex(1).
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ set(SC_IS_SUBBUILD TRUE)
|
||||
if(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set(SC_BUILD_TYPE ${CMAKE_BUILD_TYPE})
|
||||
|
||||
# Path to STEPcode
|
||||
set(STEPCODE_BUILD_DIR ${CMAKE_BINARY_DIR}/sc CACHE PATH "STEPcode build subdir")
|
||||
@@ -57,6 +58,10 @@ add_subdirectory(${STEPCODE_ROOT_DIR} "${CMAKE_CURRENT_BINARY_DIR}/sc" EXCLUDE_F
|
||||
|
||||
# Set up STEPcode include directories.
|
||||
set(STEPCODE_INCLUDE_DIR
|
||||
${STEPCODE_ROOT_DIR}/src/clstepcore
|
||||
${STEPCODE_ROOT_DIR}/src/cldai
|
||||
${STEPCODE_ROOT_DIR}/src/clutils
|
||||
${STEPCODE_ROOT_DIR}/src/cleditor
|
||||
${STEPCODE_BUILD_DIR}/include
|
||||
${STEPCODE_ROOT_DIR}/include
|
||||
${CMAKE_BINARY_DIR}
|
||||
|
||||
@@ -4,9 +4,9 @@ ExternalProject_Add( STEPCODE
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
||||
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DSC_BUILD_TYPE=Debug
|
||||
-DSC_BUILD_SCHEMAS=ap203/ap203.exp
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
-DSC_BUILD_STATIC_LIBS=ON
|
||||
-DSC_PYTHON_GENERATOR=OFF
|
||||
-DSC_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
)
|
||||
|
||||
@@ -49,15 +49,15 @@
|
||||
// $./AP203Minimum
|
||||
// AP203Minimum outfile.stp
|
||||
|
||||
#include <cleditor/STEPfile.h>
|
||||
#include <clstepcore/sdai.h>
|
||||
#include <clstepcore/STEPattribute.h>
|
||||
#include <clstepcore/ExpDict.h>
|
||||
#include <clstepcore/Registry.h>
|
||||
#include <clutils/errordesc.h>
|
||||
#include <STEPfile.h>
|
||||
#include <sdai.h>
|
||||
#include <STEPattribute.h>
|
||||
#include <ExpDict.h>
|
||||
#include <Registry.h>
|
||||
#include <errordesc.h>
|
||||
|
||||
#include <clstepcore/STEPcomplex.h>
|
||||
#include <cleditor/SdaiHeaderSchema.h>
|
||||
#include <STEPcomplex.h>
|
||||
#include <SdaiHeaderSchema.h>
|
||||
|
||||
#include "schema.h"
|
||||
|
||||
|
||||
@@ -37,12 +37,6 @@ install(FILES ordered_attrs.h
|
||||
install(FILES ${SC_BINARY_DIR}/${INCLUDE_DIR}/config.h
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode)
|
||||
|
||||
add_subdirectory(cldai)
|
||||
add_subdirectory(cleditor)
|
||||
add_subdirectory(cllazyfile)
|
||||
add_subdirectory(clstepcore)
|
||||
add_subdirectory(clutils)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
set(DAI_HDRS
|
||||
sdaiApplication_instance_set.h
|
||||
sdaiBinary.h
|
||||
sdaiDaObject.h
|
||||
sdaiEntity_extent.h
|
||||
sdaiEntity_extent_set.h
|
||||
sdaiEnum.h
|
||||
sdaiModel_contents.h
|
||||
sdaiModel_contents_list.h
|
||||
sdaiObject.h
|
||||
sdaiSession_instance.h
|
||||
sdaiString.h
|
||||
)
|
||||
|
||||
install(FILES ${DAI_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/cldai)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
set(EDITOR_HDRS
|
||||
STEPfile.h
|
||||
cmdmgr.h
|
||||
editordefines.h
|
||||
SdaiHeaderSchema.h
|
||||
SdaiHeaderSchemaClasses.h
|
||||
SdaiSchemaInit.h
|
||||
seeinfodefault.h
|
||||
)
|
||||
|
||||
install(FILES ${EDITOR_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/cleditor)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
set(LAZY_HDRS
|
||||
headerSectionReader.h
|
||||
lazyFileReader.h
|
||||
lazyP21DataSectionReader.h
|
||||
p21HeaderSectionReader.h
|
||||
lazyDataSectionReader.h
|
||||
lazyInstMgr.h
|
||||
lazySupport.h
|
||||
lazyTypes.h
|
||||
sectionReader.h
|
||||
instMgrHelper.h
|
||||
judy.h
|
||||
judyL2Array.h
|
||||
judyLArray.h
|
||||
judyS2Array.h
|
||||
judySArray.h
|
||||
)
|
||||
|
||||
install(FILES ${LAZY_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/cllazyfile)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
@@ -1,131 +0,0 @@
|
||||
#ifndef LAZYSUPPORT_H
|
||||
#define LAZYSUPPORT_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cllazyfile/lazyTypes.h"
|
||||
#include "sc_export.h"
|
||||
|
||||
class lazyInstMgr;
|
||||
class SDAI_Application_instance;
|
||||
|
||||
enum LazyDiagnosticSeverity {
|
||||
LAZY_DIAGNOSTIC_INFO,
|
||||
LAZY_DIAGNOSTIC_WARNING,
|
||||
LAZY_DIAGNOSTIC_ERROR,
|
||||
LAZY_DIAGNOSTIC_FATAL
|
||||
};
|
||||
|
||||
struct SC_LAZYFILE_EXPORT LazyDiagnostic {
|
||||
LazyDiagnosticSeverity severity;
|
||||
instanceID entity;
|
||||
std::string type;
|
||||
lazyFileOffset offset;
|
||||
uint64_t line;
|
||||
std::string attribute;
|
||||
std::string message;
|
||||
uint64_t occurrences;
|
||||
|
||||
LazyDiagnostic(): severity( LAZY_DIAGNOSTIC_INFO ), entity( 0 ), offset( 0 ),
|
||||
line( 0 ), occurrences( 1 ) {}
|
||||
};
|
||||
|
||||
struct SC_LAZYFILE_EXPORT LazyScanProgress {
|
||||
fileID file;
|
||||
lazyFileOffset offset;
|
||||
lazyFileOffset fileSize;
|
||||
uint64_t instancesScanned;
|
||||
|
||||
LazyScanProgress(): file( 0 ), offset( 0 ), fileSize( 0 ), instancesScanned( 0 ) {}
|
||||
};
|
||||
|
||||
struct SC_LAZYFILE_EXPORT LazyCacheStatistics {
|
||||
uint64_t instancesScanned;
|
||||
uint64_t instancesLoaded;
|
||||
uint64_t instancesPinned;
|
||||
uint64_t cacheHighWater;
|
||||
uint64_t cacheHits;
|
||||
uint64_t cacheMisses;
|
||||
uint64_t materializations;
|
||||
uint64_t evictions;
|
||||
uint64_t activeBatches;
|
||||
uint64_t dataSections;
|
||||
uint64_t residentSourceBytes;
|
||||
uint64_t sourceBytesHighWater;
|
||||
bool cancelled;
|
||||
|
||||
LazyCacheStatistics(): instancesScanned( 0 ), instancesLoaded( 0 ), instancesPinned( 0 ),
|
||||
cacheHighWater( 0 ), cacheHits( 0 ), cacheMisses( 0 ), materializations( 0 ),
|
||||
evictions( 0 ), activeBatches( 0 ), dataSections( 0 ), residentSourceBytes( 0 ),
|
||||
sourceBytesHighWater( 0 ), cancelled( false ) {}
|
||||
};
|
||||
|
||||
typedef std::function<void ( const LazyScanProgress & )> LazyProgressCallback;
|
||||
typedef std::function<bool ()> LazyCancellationCallback;
|
||||
typedef std::function<void ( const LazyDiagnostic & )> LazyDiagnosticCallback;
|
||||
|
||||
/** A non-owning, zero-copy view of an indexed instance-ID vector.
|
||||
* The view remains valid until another file is scanned by the manager.
|
||||
*/
|
||||
class SC_LAZYFILE_EXPORT LazyInstanceIdView {
|
||||
public:
|
||||
typedef instanceRefs::const_iterator const_iterator;
|
||||
|
||||
LazyInstanceIdView(): _ids( 0 ) {}
|
||||
explicit LazyInstanceIdView( const instanceRefs * ids ): _ids( ids ) {}
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
size_t size() const;
|
||||
bool empty() const;
|
||||
instanceID operator[]( size_t index ) const;
|
||||
|
||||
private:
|
||||
const instanceRefs * _ids;
|
||||
};
|
||||
|
||||
/** A dependency closure materialized and pinned for a bounded operation.
|
||||
* STEPcode parsing remains single-threaded. Detach immutable conversion data
|
||||
* before releasing the batch or passing work to another thread.
|
||||
*/
|
||||
class SC_LAZYFILE_EXPORT LazyInstanceBatch {
|
||||
public:
|
||||
LazyInstanceBatch();
|
||||
~LazyInstanceBatch();
|
||||
LazyInstanceBatch( LazyInstanceBatch && other );
|
||||
LazyInstanceBatch & operator=( LazyInstanceBatch && other );
|
||||
|
||||
LazyInstanceBatch( const LazyInstanceBatch & ) = delete;
|
||||
LazyInstanceBatch & operator=( const LazyInstanceBatch & ) = delete;
|
||||
|
||||
bool valid() const;
|
||||
void release();
|
||||
const std::vector<instanceID> & roots() const;
|
||||
const std::vector<instanceID> & instances() const;
|
||||
SDAI_Application_instance * get( instanceID id ) const;
|
||||
|
||||
private:
|
||||
friend class lazyInstMgr;
|
||||
LazyInstanceBatch( lazyInstMgr * manager, const std::vector<instanceID> & roots,
|
||||
const std::vector<instanceID> & instances );
|
||||
|
||||
lazyInstMgr * _manager;
|
||||
std::vector<instanceID> _roots;
|
||||
std::vector<instanceID> _instances;
|
||||
};
|
||||
|
||||
/** Adapter preserving a stream-oriented diagnostic presentation. */
|
||||
class SC_LAZYFILE_EXPORT LazyTextDiagnosticAdapter {
|
||||
public:
|
||||
explicit LazyTextDiagnosticAdapter( std::ostream & stream );
|
||||
void operator()( const LazyDiagnostic & diagnostic ) const;
|
||||
|
||||
private:
|
||||
std::ostream * _stream;
|
||||
};
|
||||
|
||||
#endif // LAZYSUPPORT_H
|
||||
@@ -1,72 +0,0 @@
|
||||
set(CORE_HDRS
|
||||
aggrTypeDescriptor.h
|
||||
attrDescriptor.h
|
||||
attrDescriptorList.h
|
||||
baseType.h
|
||||
complexSupport.h
|
||||
create_Aggr.h
|
||||
derivedAttribute.h
|
||||
dictSchema.h
|
||||
dictdefs.h
|
||||
dictionaryInstance.h
|
||||
dispnode.h
|
||||
dispnodelist.h
|
||||
entityDescriptor.h
|
||||
entityDescriptorList.h
|
||||
enumTypeDescriptor.h
|
||||
ExpDict.h
|
||||
explicitItemId.h
|
||||
globalRule.h
|
||||
implicitItemId.h
|
||||
instmgr.h
|
||||
interfaceSpec.h
|
||||
interfacedItem.h
|
||||
inverseAttribute.h
|
||||
inverseAttributeList.h
|
||||
mgrnode.h
|
||||
mgrnodearray.h
|
||||
mgrnodelist.h
|
||||
needFunc.h
|
||||
read_func.h
|
||||
realTypeDescriptor.h
|
||||
Registry.h
|
||||
schRename.h
|
||||
schemaInit.h
|
||||
schemaModule.h
|
||||
sdai.h
|
||||
sdaiApplication_instance.h
|
||||
sdaiSelect.h
|
||||
selectTypeDescriptor.h
|
||||
SingleLinkList.h
|
||||
STEPaggregate.h
|
||||
STEPaggrBinary.h
|
||||
STEPaggrEntity.h
|
||||
STEPaggrEnum.h
|
||||
STEPaggrGeneric.h
|
||||
STEPaggrInt.h
|
||||
STEPaggrReal.h
|
||||
STEPaggrSelect.h
|
||||
STEPaggrString.h
|
||||
STEPattribute.h
|
||||
STEPattributeList.h
|
||||
STEPcomplex.h
|
||||
STEPinvAttrList.h
|
||||
STEPundefined.h
|
||||
stringTypeDescriptor.h
|
||||
SubSuperIterators.h
|
||||
typeDescriptor.h
|
||||
typeDescriptorList.h
|
||||
typeOrRuleVar.h
|
||||
uniquenessRule.h
|
||||
whereRule.h
|
||||
)
|
||||
|
||||
install(FILES ${CORE_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/clstepcore)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
@@ -1,362 +0,0 @@
|
||||
#ifndef SCHEMAINIT_H
|
||||
#define SCHEMAINIT_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sc_export.h"
|
||||
#include "clstepcore/attrDescriptor.h"
|
||||
#include "clstepcore/aggrTypeDescriptor.h"
|
||||
#include "clstepcore/dictSchema.h"
|
||||
#include "clstepcore/entityDescriptor.h"
|
||||
#include "clstepcore/enumTypeDescriptor.h"
|
||||
#include "clstepcore/selectTypeDescriptor.h"
|
||||
#include "clstepcore/schemaModule.h"
|
||||
|
||||
class Derived_attribute;
|
||||
class Inverse_attribute;
|
||||
class ComplexCollect;
|
||||
class Registry;
|
||||
|
||||
/** Compact records used by API v2 generated schema initialization. */
|
||||
struct SC_CORE_EXPORT SchemaInitRecord {
|
||||
Schema ** slot;
|
||||
const char * name;
|
||||
ModelContentsCreator modelContentsCreator;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT EntityDescriptorInitRecord {
|
||||
EntityDescriptor ** slot;
|
||||
const char * name;
|
||||
Schema ** schemaSlot;
|
||||
Logical abstractEntity;
|
||||
Logical externalMapping;
|
||||
Creator creator;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT EntitySupertypeInitRecord {
|
||||
EntityDescriptor * supertype;
|
||||
};
|
||||
|
||||
enum TypeDescriptorInitKind {
|
||||
TypeDescriptorInit_Base,
|
||||
TypeDescriptorInit_Enum,
|
||||
TypeDescriptorInit_Select,
|
||||
TypeDescriptorInit_Aggregate,
|
||||
TypeDescriptorInit_Array,
|
||||
TypeDescriptorInit_List,
|
||||
TypeDescriptorInit_Set,
|
||||
TypeDescriptorInit_Bag
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT TypeDescriptorInitRecord {
|
||||
void * slot;
|
||||
TypeDescriptorInitKind kind;
|
||||
const char * name;
|
||||
PrimitiveType fundamentalType;
|
||||
Schema ** schemaSlot;
|
||||
const char * description;
|
||||
int uniqueElements;
|
||||
SelectCreator selectCreator;
|
||||
EnumCreator enumCreator;
|
||||
AggregateCreator aggregateCreator;
|
||||
|
||||
TypeDescriptorInitRecord( TypeDescriptor ** descriptorSlot,
|
||||
const char * typeName, PrimitiveType type,
|
||||
Schema ** schema, const char * typeDescription );
|
||||
TypeDescriptorInitRecord( EnumTypeDescriptor ** descriptorSlot,
|
||||
const char * typeName, PrimitiveType type,
|
||||
Schema ** schema, const char * typeDescription,
|
||||
EnumCreator creator );
|
||||
TypeDescriptorInitRecord( SelectTypeDescriptor ** descriptorSlot,
|
||||
int unique, const char * typeName,
|
||||
PrimitiveType type, Schema ** schema,
|
||||
const char * typeDescription,
|
||||
SelectCreator creator );
|
||||
TypeDescriptorInitRecord( AggrTypeDescriptor ** descriptorSlot,
|
||||
const char * typeName, PrimitiveType type,
|
||||
Schema ** schema, const char * typeDescription,
|
||||
AggregateCreator creator );
|
||||
TypeDescriptorInitRecord( ArrayTypeDescriptor ** descriptorSlot,
|
||||
const char * typeName, PrimitiveType type,
|
||||
Schema ** schema, const char * typeDescription,
|
||||
AggregateCreator creator );
|
||||
TypeDescriptorInitRecord( ListTypeDescriptor ** descriptorSlot,
|
||||
const char * typeName, PrimitiveType type,
|
||||
Schema ** schema, const char * typeDescription,
|
||||
AggregateCreator creator );
|
||||
TypeDescriptorInitRecord( SetTypeDescriptor ** descriptorSlot,
|
||||
const char * typeName, PrimitiveType type,
|
||||
Schema ** schema, const char * typeDescription,
|
||||
AggregateCreator creator );
|
||||
TypeDescriptorInitRecord( BagTypeDescriptor ** descriptorSlot,
|
||||
const char * typeName, PrimitiveType type,
|
||||
Schema ** schema, const char * typeDescription,
|
||||
AggregateCreator creator );
|
||||
};
|
||||
|
||||
/**
|
||||
* Attribute descriptor record. The overloaded constructors preserve the
|
||||
* concrete type of generated descriptor slots without templates or casts in
|
||||
* generated translation units.
|
||||
*/
|
||||
struct SC_CORE_EXPORT AttributeInitRecord {
|
||||
AttrDescriptor ** attributeSlot;
|
||||
Derived_attribute ** derivedSlot;
|
||||
Inverse_attribute ** inverseSlot;
|
||||
const char * name;
|
||||
const TypeDescriptor * domain;
|
||||
Logical optional;
|
||||
Logical unique;
|
||||
AttrType_Enum attrType;
|
||||
const char * initializer;
|
||||
const char * invertedAttribute;
|
||||
const char * invertedEntity;
|
||||
|
||||
AttributeInitRecord( AttrDescriptor ** slot, const char * attrName,
|
||||
const TypeDescriptor * domainType, Logical isOptional,
|
||||
Logical isUnique, AttrType_Enum type,
|
||||
const char * init = 0 );
|
||||
AttributeInitRecord( Derived_attribute ** slot, const char * attrName,
|
||||
const TypeDescriptor * domainType, Logical isOptional,
|
||||
Logical isUnique, AttrType_Enum type,
|
||||
const char * init = 0 );
|
||||
AttributeInitRecord( Inverse_attribute ** slot, const char * attrName,
|
||||
const TypeDescriptor * domainType, Logical isOptional,
|
||||
Logical isUnique, const char * invertedAttr,
|
||||
const char * invertedEnt );
|
||||
};
|
||||
|
||||
enum ComplexNodeInitKind {
|
||||
ComplexNodeInit_Simple,
|
||||
ComplexNodeInit_And,
|
||||
ComplexNodeInit_Or,
|
||||
ComplexNodeInit_AndOr
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT ComplexNodeInitRecord {
|
||||
ComplexNodeInitKind kind;
|
||||
const char * name;
|
||||
size_t firstChild;
|
||||
size_t nextSibling;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT ComplexListInitRecord {
|
||||
size_t rootNode;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT GlobalRuleInitRecord {
|
||||
const char * name;
|
||||
const char * text;
|
||||
};
|
||||
|
||||
enum SchemaImageDescriptorRefKind {
|
||||
SchemaImageRef_None,
|
||||
SchemaImageRef_Entity,
|
||||
SchemaImageRef_Type,
|
||||
SchemaImageRef_Builtin,
|
||||
SchemaImageRef_Aggregate
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageDescriptorRef {
|
||||
uint32_t kind;
|
||||
uint32_t schema;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageSchemaRecord {
|
||||
uint32_t name;
|
||||
uint32_t firstEntity;
|
||||
uint32_t entityCount;
|
||||
uint32_t firstType;
|
||||
uint32_t typeCount;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageEntityRecord {
|
||||
uint32_t schema;
|
||||
uint32_t name;
|
||||
uint32_t flags;
|
||||
uint32_t supertypeStatement;
|
||||
uint32_t firstSupertype;
|
||||
uint32_t supertypeCount;
|
||||
uint32_t firstAttribute;
|
||||
uint32_t attributeCount;
|
||||
uint32_t firstWhereRule;
|
||||
uint32_t whereRuleCount;
|
||||
uint32_t firstUniqueRule;
|
||||
uint32_t uniqueRuleCount;
|
||||
};
|
||||
|
||||
enum SchemaImageEntityFlags {
|
||||
SchemaImageEntity_Abstract = 1u << 0,
|
||||
SchemaImageEntity_ExternalMapping = 1u << 1
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageTypeRecord {
|
||||
uint32_t schema;
|
||||
uint32_t name;
|
||||
uint32_t description;
|
||||
uint32_t fundamentalType;
|
||||
uint32_t descriptorKind;
|
||||
int32_t uniqueElements;
|
||||
SchemaImageDescriptorRef referent;
|
||||
uint32_t aggregate;
|
||||
uint32_t firstSelectElement;
|
||||
uint32_t selectElementCount;
|
||||
uint32_t firstWhereRule;
|
||||
uint32_t whereRuleCount;
|
||||
uint32_t firstEnumElement;
|
||||
uint32_t enumElementCount;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageAttributeRecord {
|
||||
uint32_t name;
|
||||
SchemaImageDescriptorRef domain;
|
||||
uint32_t optional;
|
||||
uint32_t unique;
|
||||
uint32_t attrType;
|
||||
uint32_t initializer;
|
||||
uint32_t invertedAttribute;
|
||||
uint32_t invertedEntity;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageAggregateRecord {
|
||||
uint32_t schema;
|
||||
uint32_t description;
|
||||
uint32_t fundamentalType;
|
||||
SchemaImageDescriptorRef referent;
|
||||
uint32_t bound1Type;
|
||||
int32_t bound1;
|
||||
uint32_t bound1Text;
|
||||
uint32_t bound2Type;
|
||||
int32_t bound2;
|
||||
uint32_t bound2Text;
|
||||
uint32_t optionalElements;
|
||||
uint32_t uniqueElements;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageRuleRecord {
|
||||
uint32_t text;
|
||||
};
|
||||
|
||||
enum SchemaImageSchemaTextKind {
|
||||
SchemaImageText_GlobalRule,
|
||||
SchemaImageText_Function,
|
||||
SchemaImageText_Procedure
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageSchemaTextRecord {
|
||||
uint32_t schema;
|
||||
uint32_t kind;
|
||||
uint32_t name;
|
||||
uint32_t text;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageRenameRecord {
|
||||
SchemaImageDescriptorRef descriptor;
|
||||
uint32_t schema;
|
||||
uint32_t name;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageSchemaBinding {
|
||||
Schema ** schemaSlot;
|
||||
ModelContentsCreator modelContentsCreator;
|
||||
SchemaModule * module;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaImageTypeBinding {
|
||||
void * slot;
|
||||
SelectCreator selectCreator;
|
||||
EnumCreator enumCreator;
|
||||
AggregateCreator aggregateCreator;
|
||||
};
|
||||
|
||||
enum SchemaLoadError {
|
||||
SchemaLoad_Ok,
|
||||
SchemaLoad_UnsupportedVersion,
|
||||
SchemaLoad_TruncatedImage,
|
||||
SchemaLoad_InvalidOffset,
|
||||
SchemaLoad_InvalidString,
|
||||
SchemaLoad_InvalidReference,
|
||||
SchemaLoad_CountMismatch,
|
||||
SchemaLoad_MissingBinding,
|
||||
SchemaLoad_ModuleFailure
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaLoadResult {
|
||||
SchemaLoadError error;
|
||||
uint32_t record;
|
||||
|
||||
bool Succeeded() const {
|
||||
return error == SchemaLoad_Ok;
|
||||
}
|
||||
const char * Message() const;
|
||||
};
|
||||
|
||||
SC_CORE_EXPORT SchemaLoadResult InitializeSchemaFromImage(
|
||||
Registry & registry, const SchemaModuleImage & image,
|
||||
const SchemaImageSchemaBinding * schemaBindings,
|
||||
size_t schemaBindingCount,
|
||||
const SchemaImageTypeBinding * typeBindings,
|
||||
size_t typeBindingCount, SchemaLoadContext & context );
|
||||
|
||||
enum PackedComplexImageVersion {
|
||||
PackedComplexImageVersion_1 = 1
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT PackedComplexImage {
|
||||
uint32_t version;
|
||||
uint32_t byteSize;
|
||||
uint32_t stringOffset;
|
||||
uint32_t stringBytes;
|
||||
uint32_t nodeOffset;
|
||||
uint32_t nodeCount;
|
||||
uint32_t listOffset;
|
||||
uint32_t listCount;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT PackedComplexNode {
|
||||
uint32_t kind;
|
||||
uint32_t name;
|
||||
uint32_t firstChild;
|
||||
uint32_t nextSibling;
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT PackedComplexList {
|
||||
uint32_t rootNode;
|
||||
};
|
||||
|
||||
SC_CORE_EXPORT ComplexCollect * InitializePackedComplexSupport(
|
||||
const PackedComplexImage & image, SchemaLoadResult * result = 0 );
|
||||
|
||||
SC_CORE_EXPORT void InitializeSchemas( Registry & reg,
|
||||
const SchemaInitRecord * records,
|
||||
size_t count );
|
||||
SC_CORE_EXPORT void InitializeSchemaModuleImages(
|
||||
const SchemaInitRecord * records, size_t count );
|
||||
SC_CORE_EXPORT void InitializeEntityDescriptors(
|
||||
const EntityDescriptorInitRecord * records, size_t count );
|
||||
SC_CORE_EXPORT void InitializeTypeDescriptors(
|
||||
const TypeDescriptorInitRecord * records, size_t count );
|
||||
SC_CORE_EXPORT void InitializeTypeMetadata(
|
||||
Registry & reg, Schema & schema, TypeDescriptor & type,
|
||||
const TypeDescriptor * referent,
|
||||
const TypeDescriptor * const * selectElements, size_t selectElementCount );
|
||||
SC_CORE_EXPORT void InitializeEntityMetadata(
|
||||
Registry & reg, EntityDescriptor & entity, Schema & schema,
|
||||
const EntitySupertypeInitRecord * supertypes, size_t supertypeCount,
|
||||
const AttributeInitRecord * attributes, size_t attributeCount );
|
||||
SC_CORE_EXPORT void InitializeWhereRules(
|
||||
TypeDescriptor & owner, const char * const * rules, size_t count );
|
||||
SC_CORE_EXPORT void InitializeUniquenessRules(
|
||||
EntityDescriptor & owner, const char * const * rules, size_t count );
|
||||
SC_CORE_EXPORT void InitializeGlobalRules(
|
||||
Schema & schema, const GlobalRuleInitRecord * rules, size_t count );
|
||||
SC_CORE_EXPORT void InitializeFunctions(
|
||||
Schema & schema, const char * const * functions, size_t count );
|
||||
SC_CORE_EXPORT void InitializeProcedures(
|
||||
Schema & schema, const char * const * procedures, size_t count );
|
||||
SC_CORE_EXPORT ComplexCollect * InitializeComplexSupport(
|
||||
const ComplexNodeInitRecord * nodes, size_t nodeCount,
|
||||
const ComplexListInitRecord * lists, size_t listCount );
|
||||
|
||||
#endif
|
||||
@@ -1,171 +0,0 @@
|
||||
#ifndef SCHEMAMODULE_H
|
||||
#define SCHEMAMODULE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "sc_export.h"
|
||||
|
||||
class AttrDescriptor;
|
||||
class EntityDescriptor;
|
||||
class Schema;
|
||||
class TypeDescriptor;
|
||||
|
||||
enum SchemaModuleSlotKind {
|
||||
SchemaModuleSlot_Entity,
|
||||
SchemaModuleSlot_Type,
|
||||
SchemaModuleSlot_EnumType,
|
||||
SchemaModuleSlot_SelectType,
|
||||
SchemaModuleSlot_AggregateType,
|
||||
SchemaModuleSlot_ArrayType,
|
||||
SchemaModuleSlot_ListType,
|
||||
SchemaModuleSlot_SetType,
|
||||
SchemaModuleSlot_BagType,
|
||||
SchemaModuleSlot_Attribute,
|
||||
SchemaModuleSlot_DerivedAttribute,
|
||||
SchemaModuleSlot_InverseAttribute
|
||||
};
|
||||
|
||||
struct SC_CORE_EXPORT SchemaModuleSlot {
|
||||
const void * slot;
|
||||
SchemaModuleSlotKind kind;
|
||||
};
|
||||
|
||||
enum SchemaModuleImageVersion {
|
||||
SchemaModuleImageVersion_1 = 1,
|
||||
SchemaModuleImageVersion_2 = 2
|
||||
};
|
||||
|
||||
enum SchemaModuleImageFlags {
|
||||
SchemaModuleImage_FullMetadata = 0,
|
||||
SchemaModuleImage_StructuralMetadata = 1u << 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Relocation-free generated header for a schema module image.
|
||||
*
|
||||
* Version 1 records only stable generated-ID counts. Version 2 describes
|
||||
* one bounded block of offset-based schemas, descriptors, metadata, and
|
||||
* strings. Runtime loading validates the complete block before constructing
|
||||
* descriptors or changing a Registry.
|
||||
*/
|
||||
struct SC_CORE_EXPORT SchemaModuleImage {
|
||||
uint32_t version;
|
||||
uint32_t entityCount;
|
||||
uint32_t typeCount;
|
||||
uint32_t attributeCount;
|
||||
|
||||
/* Version 2 fields. Version 1 initializers leave these zero. */
|
||||
uint32_t byteSize;
|
||||
uint32_t flags;
|
||||
uint32_t schemaCount;
|
||||
uint32_t stringBytes;
|
||||
uint32_t schemaOffset;
|
||||
uint32_t entityOffset;
|
||||
uint32_t typeOffset;
|
||||
uint32_t attributeOffset;
|
||||
uint32_t aggregateCount;
|
||||
uint32_t aggregateOffset;
|
||||
uint32_t referenceCount;
|
||||
uint32_t referenceOffset;
|
||||
uint32_t ruleCount;
|
||||
uint32_t ruleOffset;
|
||||
uint32_t schemaTextCount;
|
||||
uint32_t schemaTextOffset;
|
||||
uint32_t enumElementCount;
|
||||
uint32_t enumElementOffset;
|
||||
uint32_t stringOffset;
|
||||
uint32_t reserved;
|
||||
uint64_t fingerprint;
|
||||
uint32_t renameCount;
|
||||
uint32_t renameOffset;
|
||||
};
|
||||
|
||||
class SchemaModule;
|
||||
|
||||
/**
|
||||
* Per-load descriptor collection used by packed API v2 schema images.
|
||||
*
|
||||
* Keeping this state explicit makes independent schema loads reentrant and
|
||||
* avoids the process-global capture map retained for version-1 images.
|
||||
*/
|
||||
class SC_CORE_EXPORT SchemaLoadContext {
|
||||
class Impl;
|
||||
Impl * _impl;
|
||||
|
||||
SchemaLoadContext( const SchemaLoadContext & );
|
||||
SchemaLoadContext & operator=( const SchemaLoadContext & );
|
||||
friend class SchemaModule;
|
||||
|
||||
public:
|
||||
SchemaLoadContext();
|
||||
~SchemaLoadContext();
|
||||
|
||||
void Begin( Schema & schema );
|
||||
void RecordEntity( Schema & schema, const EntityDescriptor * entity );
|
||||
void RecordType( Schema & schema, const TypeDescriptor * type );
|
||||
void RecordAttribute( Schema & schema, const AttrDescriptor * attribute );
|
||||
};
|
||||
|
||||
SC_CORE_EXPORT void RecordSchemaModuleEntity(
|
||||
Schema & schema, const EntityDescriptor * entity );
|
||||
SC_CORE_EXPORT void RecordSchemaModuleType(
|
||||
Schema & schema, const TypeDescriptor * type );
|
||||
SC_CORE_EXPORT void RecordSchemaModuleAttribute(
|
||||
Schema & schema, const AttrDescriptor * attribute );
|
||||
SC_CORE_EXPORT void BeginSchemaModuleImage( Schema & schema );
|
||||
|
||||
/**
|
||||
* Stable API v2 view of a generated schema.
|
||||
*
|
||||
* Generated EntityId, TypeId, and AttributeId enumerations are converted to
|
||||
* indexes before calling this class. Keeping the public lookup API separate
|
||||
* from generated descriptor globals allows the underlying representation to
|
||||
* move from C++ objects to packed schema data without another API break.
|
||||
*/
|
||||
class SC_CORE_EXPORT SchemaModule {
|
||||
Schema * _schema;
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 4251 )
|
||||
#endif
|
||||
std::vector<const EntityDescriptor *> _entities;
|
||||
std::vector<const TypeDescriptor *> _types;
|
||||
std::vector<const AttrDescriptor *> _attributes;
|
||||
uint64_t _fingerprint;
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
public:
|
||||
SchemaModule();
|
||||
~SchemaModule();
|
||||
|
||||
void Initialize(
|
||||
Schema & schema,
|
||||
const EntityDescriptor * const * entities, size_t entityCount,
|
||||
const TypeDescriptor * const * types, size_t typeCount,
|
||||
const AttrDescriptor * const * attributes, size_t attributeCount );
|
||||
void InitializeFromSlots(
|
||||
Schema & schema,
|
||||
const SchemaModuleSlot * entities, size_t entityCount,
|
||||
const SchemaModuleSlot * types, size_t typeCount,
|
||||
const SchemaModuleSlot * attributes, size_t attributeCount );
|
||||
void InitializeFromImage( Schema & schema,
|
||||
const SchemaModuleImage & image );
|
||||
bool InitializeFromContext( Schema & schema, SchemaLoadContext & context,
|
||||
uint64_t fingerprint );
|
||||
|
||||
bool IsInitialized() const;
|
||||
const Schema & GetSchema() const;
|
||||
const EntityDescriptor * Entity( size_t id ) const;
|
||||
const TypeDescriptor * Type( size_t id ) const;
|
||||
const AttrDescriptor * Attribute( size_t id ) const;
|
||||
size_t EntityCount() const;
|
||||
size_t TypeCount() const;
|
||||
size_t AttributeCount() const;
|
||||
uint64_t Fingerprint() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
set(UTILS_HDRS
|
||||
dirobj.h
|
||||
errordesc.h
|
||||
gennodearray.h
|
||||
gennode.h
|
||||
gennodelist.h
|
||||
sc_hash.h
|
||||
Str.h
|
||||
)
|
||||
|
||||
install(FILES ${UTILS_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/clutils)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -58,7 +58,7 @@ struct freelist_head {
|
||||
#endif
|
||||
};
|
||||
|
||||
char * nnew(void);
|
||||
char * nnew();
|
||||
|
||||
#include "error.h"
|
||||
|
||||
|
||||
@@ -93,10 +93,11 @@
|
||||
/* function pointer types */
|
||||
/**************************/
|
||||
|
||||
typedef void ( *voidFuncptr )(void);
|
||||
typedef int ( *intFuncptr )(void);
|
||||
|
||||
typedef void ( *voidFuncptr )();
|
||||
typedef int ( *intFuncptr )();
|
||||
|
||||
/* Option index - can we get rid of this? */
|
||||
extern SC_EXPRESS_EXPORT int sc_optind;
|
||||
|
||||
#endif /* BASIC_H */
|
||||
|
||||
|
||||
@@ -108,7 +108,6 @@ extern SC_EXPRESS_EXPORT char * KW_SUPERTYPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TAN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_THEN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TO;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TREAT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TRUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TYPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TYPEOF;
|
||||
|
||||
@@ -83,7 +83,7 @@ typedef enum {
|
||||
OP_MINUS, OP_MOD, OP_NEGATE,
|
||||
OP_NOT, OP_NOT_EQUAL, OP_OR,
|
||||
OP_PLUS, OP_REAL_DIV, OP_SUBCOMPONENT,
|
||||
OP_TIMES, OP_TREAT, OP_XOR, OP_UNKNOWN,
|
||||
OP_TIMES, OP_XOR, OP_UNKNOWN,
|
||||
OP_LAST /**< must be last - used only to size tables */
|
||||
} Op_Code;
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
#include "sc_export.h"
|
||||
|
||||
SC_EXPRESS_EXPORT void FACTORYinitialize(void);
|
||||
SC_EXPRESS_EXPORT void FACTORYinitialize();
|
||||
|
||||
#endif /* __FACTORY_H_ */
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
#include "sc_export.h"
|
||||
|
||||
SC_EXPRESS_EXPORT void MEMORYinitialize(void);
|
||||
SC_EXPRESS_EXPORT void MEMORYinitialize();
|
||||
|
||||
#endif // __MEMORY_H
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/***************************/
|
||||
|
||||
struct Object {
|
||||
struct Symbol_ * ( *get_symbol )( void * );
|
||||
struct Symbol_ * ( *get_symbol )();
|
||||
char * type; /**< should complete the phrase "X is ..." - i.e., "an entity", "a type", "of unknown type" */
|
||||
int bits; /**< a bitwise selector of a type, i.e. OBJ_XX_BITS */
|
||||
};
|
||||
|
||||
@@ -47,25 +47,6 @@
|
||||
|
||||
extern SC_EXPRESS_EXPORT int print_objects_while_running;
|
||||
|
||||
/*************************/
|
||||
/* Refinement structures */
|
||||
/*************************/
|
||||
|
||||
/* Maximum length for type name lookups */
|
||||
#define MAX_TYPE_NAME_LENGTH 512
|
||||
|
||||
/** Structure to track type refinements from TYPEOF guards in AND expressions */
|
||||
typedef struct Refinement_ {
|
||||
Variable variable; /**< the variable being refined */
|
||||
Type refined_type; /**< the narrowed type */
|
||||
struct Refinement_ *next; /**< next refinement in the chain */
|
||||
} *Refinement;
|
||||
|
||||
/** Context for passing refinements through expression resolution */
|
||||
typedef struct RefinementContext_ {
|
||||
Refinement refinements; /**< linked list of active refinements */
|
||||
} *RefinementContext;
|
||||
|
||||
/* macros */
|
||||
|
||||
/* cheaper doing the check here, then inside the function call. Return */
|
||||
|
||||
@@ -237,9 +237,6 @@ extern SC_EXPRESS_EXPORT struct freelist_head TYPEBODY_fl;
|
||||
#define TYPEis_oneof(t) ((t)->u.type->body->type == oneof_)
|
||||
#define TYPEis_entity(t) ((t)->u.type->body->type == entity_)
|
||||
#define TYPEis_enumeration(t) ((t)->u.type->body->type == enumeration_)
|
||||
/** Shallow aggregate check - returns true if type has a base (characteristic of aggregates).
|
||||
* Does NOT follow type definition chains. For deep unwrapping through typedef chains,
|
||||
* use TYPEget_nonaggregate_base_type() or TYPEget_aggregate_base(). */
|
||||
#define TYPEis_aggregate(t) ((t)->u.type->body->base)
|
||||
#define TYPEis_aggregate_raw(t) ((t)->u.type->body->type == aggregate_)
|
||||
#define TYPEis_array(t) ((t)->u.type->body->type == array_)
|
||||
@@ -306,7 +303,6 @@ extern SC_EXPRESS_EXPORT void TYPEcleanup( void );
|
||||
|
||||
extern SC_EXPRESS_EXPORT bool TYPEinherits_from( Type, enum type_enum );
|
||||
extern SC_EXPRESS_EXPORT Type TYPEget_nonaggregate_base_type( Type );
|
||||
extern SC_EXPRESS_EXPORT Type TYPEget_aggregate_base( Type );
|
||||
|
||||
extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_type( Type, Scope, struct Symbol_ * );
|
||||
extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_tag( Type, Scope, struct Symbol_ * );
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ BUILDNAME:STRING=${CTEST_BUILD_NAME}
|
||||
SC_ENABLE_TESTING:BOOL=ON
|
||||
SC_ENABLE_COVERAGE:BOOL=ON
|
||||
SC_BUILD_SCHEMAS:STRING=ALL
|
||||
CMAKE_BUILD_TYPE:STRING=Debug
|
||||
SC_BUILD_TYPE:STRING=Debug
|
||||
")
|
||||
|
||||
set(LCOV_OUT "${CTEST_BINARY_DIRECTORY}/lcov_html")
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
find . -type f -path "*/cl*" -not -path "*.git/*" -not -path "*/exp*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include \"$1\"/include \"utils\/$1\"/g" {} \;
|
||||
find . -type f -path "*/cl*" -not -path "*.git/*" -not -path "*/exp*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include <$1>/include \"utils\/$1\"/g" {} \;
|
||||
|
||||
find . -type f -path "*/include*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include \"$1\"/include \"utils\/$1\"/g" {} \;
|
||||
find . -type f -path "*/include*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include <$1>/include \"utils\/$1\"/g" {} \;
|
||||
|
||||
find . -type f -path "*/test*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include \"$1\"/include \"utils\/$1\"/g" {} \;
|
||||
find . -type f -path "*/test*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include <$1>/include \"utils\/$1\"/g" {} \;
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ set(CTEST_INITIAL_CACHE "
|
||||
SITE:STRING=${CTEST_SITE}
|
||||
BUILDNAME:STRING=${CTEST_BUILD_NAME}
|
||||
SC_ENABLE_TESTING:BOOL=ON
|
||||
CMAKE_BUILD_TYPE:STRING=Debug
|
||||
SC_BUILD_TYPE:STRING=Debug
|
||||
")
|
||||
|
||||
|
||||
|
||||
+23
-13
@@ -1,4 +1,5 @@
|
||||
set(DAI_SRCS
|
||||
|
||||
set(LIBSTEPDAI_SRCS
|
||||
sdaiApplication_instance_set.cc
|
||||
sdaiBinary.cc
|
||||
sdaiDaObject.cc
|
||||
@@ -12,33 +13,42 @@ set(DAI_SRCS
|
||||
sdaiString.cc
|
||||
)
|
||||
|
||||
SET(SC_CLDAI_HDRS
|
||||
sdaiApplication_instance_set.h
|
||||
sdaiBinary.h
|
||||
sdaiDaObject.h
|
||||
sdaiEntity_extent.h
|
||||
sdaiEntity_extent_set.h
|
||||
sdaiEnum.h
|
||||
sdaiModel_contents.h
|
||||
sdaiModel_contents_list.h
|
||||
sdaiObject.h
|
||||
sdaiSession_instance.h
|
||||
sdaiString.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/include/stepcode
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
|
||||
set(_libdeps steputils)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
SC_ADDLIB(stepdai SHARED SOURCES ${DAI_SRCS} LINK_LIBRARIES ${_libdeps})
|
||||
SC_ADDLIB(stepdai SHARED SOURCES ${LIBSTEPDAI_SRCS} LINK_LIBRARIES ${_libdeps})
|
||||
if(WIN32)
|
||||
target_compile_definitions(stepdai PRIVATE SC_DAI_DLL_EXPORTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_STATIC_LIBS)
|
||||
# Spell the static dependency names out rather than composing them with a
|
||||
# generator expression. Since 0b950dd1 SC_ADDLIB publishes LINK_LIBRARIES as
|
||||
# PUBLIC, so anything given here lands in INTERFACE_LINK_LIBRARIES and is
|
||||
# re-evaluated in each consumer - where a nested $<JOIN:...> comes back out
|
||||
# mangled and reaches the linker verbatim.
|
||||
set(_static_libdeps)
|
||||
foreach(_libdep ${_libdeps})
|
||||
list(APPEND _static_libdeps ${_libdep}-static)
|
||||
endforeach()
|
||||
SC_ADDLIB(stepdai-static STATIC SOURCES ${DAI_SRCS} LINK_LIBRARIES ${_static_libdeps})
|
||||
SC_ADDLIB(stepdai-static STATIC SOURCES ${LIBSTEPDAI_SRCS} LINK_LIBRARIES $<JOIN:${_libdeps},-static >-static)
|
||||
endif()
|
||||
|
||||
install(FILES ${SC_CLDAI_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/cldai)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
* UArray implementation.
|
||||
*/
|
||||
|
||||
//#include "cldai/sdaiApplication_instance_set.h"
|
||||
#include "clstepcore/sdai.h"
|
||||
//#include <sdaiApplication_instance_set.h>
|
||||
#include <sdai.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clstepcore/sdaiApplication_instance.h"
|
||||
#include "sdaiApplication_instance.h"
|
||||
|
||||
// to help ObjectCenter
|
||||
#ifndef HAVE_MEMMOVE
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
SDAI_Binary::SDAI_Binary( const char * str, int max ) {
|
||||
content = std::string( str, max );
|
||||
@@ -121,17 +121,17 @@ Severity SDAI_Binary::ReadBinary( istream & in, ErrorDescriptor * err, int Assig
|
||||
if( !validDelimiters ) {
|
||||
err->GreaterSeverity( SEVERITY_WARNING );
|
||||
if( needDelims )
|
||||
snprintf( messageBuf, sizeof(messageBuf),
|
||||
sprintf( messageBuf,
|
||||
"Binary value missing double quote delimiters.\n" );
|
||||
else
|
||||
snprintf( messageBuf, sizeof(messageBuf),
|
||||
sprintf( messageBuf,
|
||||
"Mismatched double quote delimiters for binary.\n" );
|
||||
err->AppendToDetailMsg( messageBuf );
|
||||
err->AppendToUserMsg( messageBuf );
|
||||
}
|
||||
} else {
|
||||
err->GreaterSeverity( SEVERITY_WARNING );
|
||||
snprintf( messageBuf, sizeof(messageBuf), "Invalid binary value.\n" );
|
||||
sprintf( messageBuf, "Invalid binary value.\n" );
|
||||
err->AppendToDetailMsg( messageBuf );
|
||||
err->AppendToUserMsg( messageBuf );
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
// to help ObjectCenter
|
||||
#ifndef HAVE_MEMMOVE
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef SDAIDAOBJECT_H
|
||||
#define SDAIDAOBJECT_H 1
|
||||
|
||||
#include "cldai/sdaiObject.h"
|
||||
#include "cldai/sdaiString.h"
|
||||
#include "cldai/sdaiEnum.h"
|
||||
#include <sdaiObject.h>
|
||||
#include <sdaiString.h>
|
||||
#include <sdaiEnum.h>
|
||||
|
||||
#include <sc_export.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
//#include <EntityExtent.h>
|
||||
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
SDAI_Entity_extent::SDAI_Entity_extent( )
|
||||
: _definition( 0 ), _definition_name( 0 ), _owned_by( 0 ) {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
/*
|
||||
#include <EntityExtent.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
/*
|
||||
* NIST STEP Core Class Library
|
||||
@@ -211,10 +211,10 @@ Severity SDAI_LOGICAL::ReadEnum( istream & in, ErrorDescriptor * err, int Assign
|
||||
if( !validDelimiters ) {
|
||||
err->GreaterSeverity( SEVERITY_WARNING );
|
||||
if( needDelims )
|
||||
snprintf( messageBuf, sizeof(messageBuf),
|
||||
sprintf( messageBuf,
|
||||
"Enumerated value has invalid period delimiters.\n" );
|
||||
else
|
||||
snprintf( messageBuf, sizeof(messageBuf),
|
||||
sprintf( messageBuf,
|
||||
"Mismatched period delimiters for enumeration.\n" );
|
||||
err->AppendToDetailMsg( messageBuf );
|
||||
err->AppendToUserMsg( messageBuf );
|
||||
@@ -241,7 +241,7 @@ Severity SDAI_LOGICAL::ReadEnum( istream & in, ErrorDescriptor * err, int Assign
|
||||
} else {
|
||||
in.putback( c );
|
||||
err->GreaterSeverity( SEVERITY_WARNING );
|
||||
snprintf( messageBuf, sizeof(messageBuf), "Invalid enumeration value.\n" );
|
||||
sprintf( messageBuf, "Invalid enumeration value.\n" );
|
||||
err->AppendToDetailMsg( messageBuf );
|
||||
err->AppendToUserMsg( messageBuf );
|
||||
}
|
||||
@@ -489,10 +489,10 @@ Severity SDAI_Enum::ReadEnum( istream & in, ErrorDescriptor * err, int AssignVal
|
||||
if( !validDelimiters ) {
|
||||
err->GreaterSeverity( SEVERITY_WARNING );
|
||||
if( needDelims )
|
||||
snprintf( messageBuf, sizeof(messageBuf),
|
||||
sprintf( messageBuf,
|
||||
"Enumerated value has invalid period delimiters.\n" );
|
||||
else
|
||||
snprintf( messageBuf, sizeof(messageBuf),
|
||||
sprintf( messageBuf,
|
||||
"Mismatched period delimiters for enumeration.\n" );
|
||||
err->AppendToDetailMsg( messageBuf );
|
||||
err->AppendToUserMsg( messageBuf );
|
||||
@@ -519,7 +519,7 @@ Severity SDAI_Enum::ReadEnum( istream & in, ErrorDescriptor * err, int AssignVal
|
||||
} else {
|
||||
in.putback( c );
|
||||
err->GreaterSeverity( SEVERITY_WARNING );
|
||||
snprintf( messageBuf, sizeof(messageBuf), "Invalid enumeration value.\n" );
|
||||
sprintf( messageBuf, "Invalid enumeration value.\n" );
|
||||
err->AppendToDetailMsg( messageBuf );
|
||||
err->AppendToUserMsg( messageBuf );
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
///////// SDAI_Model_contents_instances
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/*
|
||||
* UArray implementation.
|
||||
*/
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
// to help ObjectCenter
|
||||
#ifndef HAVE_MEMMOVE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
SDAI_sdaiObject::SDAI_sdaiObject() {
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
|
||||
SDAI_Session_instance::SDAI_Session_instance() {
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define SESSION_INSTANCE_H 1
|
||||
|
||||
#include <sc_export.h>
|
||||
//#include "clstepcore/sdai.h"
|
||||
//#include <sdai.h>
|
||||
|
||||
class SC_DAI_EXPORT SDAI_Session_instance : public SDAI_sdaiObject {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* and is not subject to copyright.
|
||||
*/
|
||||
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
#include <sstream>
|
||||
|
||||
SDAI_String::SDAI_String( const char * str, size_t max ) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
set(EDITOR_SRCS
|
||||
|
||||
set(LIBSTEPEDITOR_SRCS
|
||||
STEPfile.cc
|
||||
STEPfile.inline.cc
|
||||
cmdmgr.cc
|
||||
@@ -8,22 +9,37 @@ set(EDITOR_SRCS
|
||||
SdaiSchemaInit.cc
|
||||
)
|
||||
|
||||
SET(SC_CLEDITOR_HDRS
|
||||
STEPfile.h
|
||||
cmdmgr.h
|
||||
editordefines.h
|
||||
SdaiHeaderSchema.h
|
||||
SdaiHeaderSchemaClasses.h
|
||||
SdaiSchemaInit.h
|
||||
seeinfodefault.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/include/stepcode
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
SC_ADDLIB(stepeditor SHARED SOURCES ${EDITOR_SRCS} LINK_LIBRARIES stepcore stepdai steputils)
|
||||
SC_ADDLIB(stepeditor SHARED SOURCES ${LIBSTEPEDITOR_SRCS} LINK_LIBRARIES stepcore stepdai steputils)
|
||||
if(WIN32)
|
||||
target_compile_definitions(stepeditor PRIVATE SC_EDITOR_DLL_EXPORTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_STATIC_LIBS)
|
||||
SC_ADDLIB(stepeditor-static STATIC SOURCES ${EDITOR_SRCS} LINK_LIBRARIES steputils-static stepdai-static stepcore-static)
|
||||
SC_ADDLIB(stepeditor-static STATIC SOURCES ${LIBSTEPEDITOR_SRCS} LINK_LIBRARIES stepcore-static stepdai-static steputils-static)
|
||||
endif()
|
||||
|
||||
install(FILES ${SC_CLEDITOR_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/cleditor)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
|
||||
+15
-24
@@ -24,15 +24,15 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "cleditor/STEPfile.h"
|
||||
#include "clstepcore/sdai.h"
|
||||
#include "clstepcore/STEPcomplex.h"
|
||||
#include "clstepcore/STEPattribute.h"
|
||||
#include "cleditor/SdaiHeaderSchema.h"
|
||||
#include <STEPfile.h>
|
||||
#include <sdai.h>
|
||||
#include <STEPcomplex.h>
|
||||
#include <STEPattribute.h>
|
||||
#include <SdaiHeaderSchema.h>
|
||||
|
||||
// STEPundefined contains
|
||||
// void PushPastString (istream& in, std::string &s, ErrorDescriptor *err)
|
||||
#include "clstepcore/STEPundefined.h"
|
||||
#include <STEPundefined.h>
|
||||
|
||||
/**
|
||||
* \returns The new file name for the class.
|
||||
@@ -528,7 +528,7 @@ int STEPfile::ReadData1( istream & in ) {
|
||||
} // end while loop
|
||||
|
||||
if( _entsNotCreated ) {
|
||||
snprintf( buf, sizeof(buf),
|
||||
sprintf( buf,
|
||||
"STEPfile Reading File: Unable to create %d instances.\n\tIn first pass through DATA section. Check for invalid entity types.\n",
|
||||
_entsNotCreated );
|
||||
_error.AppendToUserMsg( buf );
|
||||
@@ -647,7 +647,7 @@ int STEPfile::ReadData2( istream & in, bool useTechCor ) {
|
||||
} // end while loop
|
||||
|
||||
if( _entsInvalid ) {
|
||||
snprintf( buf, sizeof(buf),
|
||||
sprintf( buf,
|
||||
"%s \n\tTotal instances: %d \n\tInvalid instances: %d \n\tIncomplete instances (includes invalid instances): %d \n\t%s: %d.\n",
|
||||
"Second pass complete - instance summary:", total_instances,
|
||||
_entsInvalid, _entsIncomplete, "Warnings",
|
||||
@@ -743,15 +743,6 @@ int STEPfile::FindHeaderSection( istream & in ) {
|
||||
return 0;
|
||||
}
|
||||
in.getline( buf, BUFSIZ, ';' ); // reads but does not store the ;
|
||||
if( in.fail() ) {
|
||||
// A file with no ';' in its first BUFSIZ bytes - a binary file that
|
||||
// is not STEP at all, say - sets failbit and leaves buf unchanged.
|
||||
// eof() then never becomes true and the loop above spins forever.
|
||||
_error.AppendToUserMsg(
|
||||
"Error: Unable to find HEADER section. File not read.\n" );
|
||||
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1330,7 +1321,7 @@ SDAI_Application_instance * STEPfile::ReadInstance( istream & in, ostream & out,
|
||||
}
|
||||
} else {
|
||||
if( node->CurrState() == completeSE ) {
|
||||
snprintf( errbuf, sizeof(errbuf), "WARNING in WORKING FILE: changing instance #%d state from completeSE to incompleteSE.\n", fileid );
|
||||
sprintf( errbuf, "WARNING in WORKING FILE: changing instance #%d state from completeSE to incompleteSE.\n", fileid );
|
||||
_error.AppendToUserMsg( errbuf );
|
||||
if( _fileType != WORKING_SESSION ) {
|
||||
node->ChangeState( incompleteSE );
|
||||
@@ -1652,7 +1643,7 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
}
|
||||
SetFileType( WORKING_SESSION );
|
||||
} else {
|
||||
snprintf( errbuf, sizeof(errbuf),
|
||||
sprintf( errbuf,
|
||||
"Faulty input at beginning of file. \"ISO-10303-21;\" or"
|
||||
" \"STEP_WORKING_SESSION;\" expected. File not read: %s\n",
|
||||
( ( FileName().compare( "-" ) == 0 ) ? "standard input" : FileName().c_str() ) );
|
||||
@@ -1667,14 +1658,14 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
rval = ReadHeader( *in );
|
||||
cout << "\nHEADER read:";
|
||||
if( rval < SEVERITY_WARNING ) {
|
||||
snprintf( errbuf, sizeof(errbuf),
|
||||
sprintf( errbuf,
|
||||
"Error: non-recoverable error in reading header section. "
|
||||
"There were %d errors encountered. Rest of file is ignored.\n",
|
||||
_errorCount );
|
||||
_error.AppendToUserMsg( errbuf );
|
||||
return rval;
|
||||
} else if( rval != SEVERITY_NULL ) {
|
||||
snprintf( errbuf, sizeof(errbuf), " %d ERRORS\t %d WARNINGS\n\n",
|
||||
sprintf( errbuf, " %d ERRORS\t %d WARNINGS\n\n",
|
||||
_errorCount, _warningCount );
|
||||
cout << errbuf;
|
||||
} else {
|
||||
@@ -1692,7 +1683,7 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
|
||||
cout << "\nFIRST PASS complete: " << total_insts
|
||||
<< " instances created.\n";
|
||||
snprintf( errbuf, sizeof(errbuf),
|
||||
sprintf( errbuf,
|
||||
" %d ERRORS\t %d WARNINGS\n\n",
|
||||
_errorCount, _warningCount );
|
||||
cout << errbuf;
|
||||
@@ -1736,7 +1727,7 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
//check for "ENDSEC;"
|
||||
ReadTokenSeparator( *in2 );
|
||||
if( total_insts != valid_insts ) {
|
||||
snprintf( errbuf, sizeof(errbuf), "%d invalid instances in file: %s\n",
|
||||
sprintf( errbuf, "%d invalid instances in file: %s\n",
|
||||
total_insts - valid_insts, ( ( FileName().compare( "-" ) == 0 ) ? "standard input" : FileName().c_str() ) );
|
||||
_error.AppendToUserMsg( errbuf );
|
||||
CloseInputFile( in2 );
|
||||
@@ -1745,7 +1736,7 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
|
||||
cout << "\nSECOND PASS complete: " << valid_insts
|
||||
<< " instances valid.\n";
|
||||
snprintf( errbuf, sizeof(errbuf),
|
||||
sprintf( errbuf,
|
||||
" %d ERRORS\t %d WARNINGS\n\n",
|
||||
_errorCount, _warningCount );
|
||||
_error.AppendToUserMsg( errbuf );
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
|
||||
#include <sc_export.h>
|
||||
#include <string>
|
||||
#include "clstepcore/instmgr.h"
|
||||
#include "clstepcore/Registry.h"
|
||||
#include <instmgr.h>
|
||||
#include <Registry.h>
|
||||
#include <fstream>
|
||||
#include "clutils/dirobj.h"
|
||||
#include "clutils/errordesc.h"
|
||||
#include <dirobj.h>
|
||||
#include <errordesc.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "clstepcore/read_func.h"
|
||||
#include <read_func.h>
|
||||
|
||||
//error reporting level
|
||||
#define READ_COMPLETE 10
|
||||
@@ -11,9 +11,9 @@
|
||||
* and is not subject to copyright.
|
||||
*/
|
||||
|
||||
#include "cleditor/STEPfile.h"
|
||||
#include "cleditor/SdaiHeaderSchema.h"
|
||||
#include "clstepcore/STEPaggregate.h"
|
||||
#include <STEPfile.h>
|
||||
#include <SdaiHeaderSchema.h>
|
||||
#include <STEPaggregate.h>
|
||||
#include <cmath>
|
||||
|
||||
#include <cstring>
|
||||
@@ -179,7 +179,7 @@ istream * STEPfile::OpenInputFile( const std::string filename ) {
|
||||
} else {
|
||||
if( SetFileName( filename ).empty() && ( filename.compare( "-" ) != 0 ) ) {
|
||||
char msg[BUFSIZ+1];
|
||||
snprintf( msg, sizeof(msg), "Unable to find file for input: \'%s\'. File not read.\n", filename.c_str() );
|
||||
sprintf( msg, "Unable to find file for input: \'%s\'. File not read.\n", filename.c_str() );
|
||||
_error.AppendToUserMsg( msg );
|
||||
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
|
||||
return( 0 );
|
||||
@@ -196,7 +196,7 @@ istream * STEPfile::OpenInputFile( const std::string filename ) {
|
||||
|
||||
if( !in || !( in -> good() ) ) {
|
||||
char msg[BUFSIZ+1];
|
||||
snprintf( msg, sizeof(msg), "Unable to open file for input: \'%s\'. File not read.\n", filename.c_str() );
|
||||
sprintf( msg, "Unable to open file for input: \'%s\'. File not read.\n", filename.c_str() );
|
||||
_error.AppendToUserMsg( msg );
|
||||
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
|
||||
return ( 0 );
|
||||
@@ -231,7 +231,7 @@ ofstream * STEPfile::OpenOutputFile( std::string filename ) {
|
||||
} else {
|
||||
if( SetFileName( filename ).empty() ) {
|
||||
char msg[BUFSIZ+1];
|
||||
snprintf( msg, sizeof(msg), "can't find file: %s\nFile not written.\n", filename.c_str() );
|
||||
sprintf( msg, "can't find file: %s\nFile not written.\n", filename.c_str() );
|
||||
_error.AppendToUserMsg( msg );
|
||||
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ extern ofstream * logStream;
|
||||
#define SCLLOGFILE "scl.log"
|
||||
#endif
|
||||
|
||||
#include "clstepcore/ExpDict.h"
|
||||
#include "clstepcore/STEPattribute.h"
|
||||
#include "cleditor/SdaiHeaderSchema.h"
|
||||
#include <ExpDict.h>
|
||||
#include <STEPattribute.h>
|
||||
#include <SdaiHeaderSchema.h>
|
||||
|
||||
Schema * s_header_section_schema = 0;
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
// regenerate it.
|
||||
|
||||
#include <sc_export.h>
|
||||
#include "clstepcore/sdai.h"
|
||||
#include "clstepcore/Registry.h"
|
||||
#include "clstepcore/STEPaggregate.h"
|
||||
#include "cleditor/SdaiHeaderSchemaClasses.h"
|
||||
#include "cleditor/SdaiSchemaInit.h"
|
||||
#include <sdai.h>
|
||||
#include <Registry.h>
|
||||
#include <STEPaggregate.h>
|
||||
#include <SdaiHeaderSchemaClasses.h>
|
||||
#include <SdaiSchemaInit.h>
|
||||
|
||||
///////// ENTITY section_language
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// it since your modifications will be lost if exp2cxx is used to
|
||||
// regenerate it.
|
||||
|
||||
#include "cleditor/SdaiHeaderSchema.h"
|
||||
#include <SdaiHeaderSchema.h>
|
||||
|
||||
void HeaderInitSchemasAndEnts( Registry & reg ) {
|
||||
Uniqueness_rule_ptr ur;
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
// it since your modifications will be lost if exp2cxx is used to
|
||||
// regenerate it.
|
||||
|
||||
#include "clstepcore/Registry.h"
|
||||
#include "clstepcore/ExpDict.h"
|
||||
#include "clstepcore/STEPattribute.h"
|
||||
#include "cleditor/SdaiHeaderSchema.h"
|
||||
#include <Registry.h>
|
||||
#include <ExpDict.h>
|
||||
#include <STEPattribute.h>
|
||||
#include <SdaiHeaderSchema.h>
|
||||
|
||||
void SdaiHEADER_SECTION_SCHEMAInit( Registry & reg ) {
|
||||
header_section_schemat_time_stamp_text->ReferentType( t_sdaiSTRING );
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// it since your modifications will be lost if exp2cxx is used to
|
||||
// regenerate it.
|
||||
|
||||
#include "cleditor/SdaiSchemaInit.h"
|
||||
#include <SdaiSchemaInit.h>
|
||||
|
||||
void HeaderSchemaInit( Registry & reg ) {
|
||||
HeaderInitSchemasAndEnts( reg );
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
#endif
|
||||
|
||||
#include <sc_export.h>
|
||||
#include "clstepcore/sdai.h"
|
||||
#include "clstepcore/Registry.h"
|
||||
#include "clstepcore/STEPaggregate.h"
|
||||
#include "clstepcore/STEPundefined.h"
|
||||
#include "clstepcore/ExpDict.h"
|
||||
#include "clstepcore/STEPattribute.h"
|
||||
#include "clstepcore/complexSupport.h"
|
||||
#include <sdai.h>
|
||||
#include <Registry.h>
|
||||
#include <STEPaggregate.h>
|
||||
#include <STEPundefined.h>
|
||||
#include <ExpDict.h>
|
||||
#include <STEPattribute.h>
|
||||
#include <complexSupport.h>
|
||||
|
||||
#include "cleditor/SdaiHeaderSchemaClasses.h"
|
||||
#include "cleditor/SdaiHeaderSchema.h"
|
||||
#include <SdaiHeaderSchemaClasses.h>
|
||||
#include <SdaiHeaderSchema.h>
|
||||
|
||||
SC_EDITOR_EXPORT void HeaderSchemaInit( Registry & );
|
||||
SC_EDITOR_EXPORT void HeaderInitSchemasAndEnts( Registry & );
|
||||
@@ -10,7 +10,7 @@
|
||||
* and is not subject to copyright.
|
||||
*/
|
||||
|
||||
#include "cleditor/cmdmgr.h"
|
||||
#include <cmdmgr.h>
|
||||
|
||||
ReplicateLinkNode * ReplicateList::FindNode( MgrNode * mn ) {
|
||||
ReplicateLinkNode * rln = ( ReplicateLinkNode * )GetHead();
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
*/
|
||||
|
||||
#include <sc_export.h>
|
||||
#include "clutils/gennode.h"
|
||||
#include "clutils/gennodelist.h"
|
||||
#include "clutils/gennodearray.h"
|
||||
#include <gennode.h>
|
||||
#include <gennodelist.h>
|
||||
#include <gennodearray.h>
|
||||
|
||||
#include "cleditor/editordefines.h"
|
||||
#include "clstepcore/mgrnode.h"
|
||||
#include "clstepcore/mgrnodelist.h"
|
||||
#include "clstepcore/dispnode.h"
|
||||
#include "clstepcore/dispnodelist.h"
|
||||
#include "clstepcore/SingleLinkList.h"
|
||||
#include <editordefines.h>
|
||||
#include <mgrnode.h>
|
||||
#include <mgrnodelist.h>
|
||||
#include <dispnode.h>
|
||||
#include <dispnodelist.h>
|
||||
#include <SingleLinkList.h>
|
||||
|
||||
//#define NUM_CMDMGR_CMDS 9
|
||||
// this is the number of columns that contain cmds (as opposed
|
||||
@@ -20,10 +20,10 @@
|
||||
class MgrNode;
|
||||
class DisplayNode;
|
||||
class DisplayNodelist;
|
||||
#include "clstepcore/sdai.h"
|
||||
#include <sdai.h>
|
||||
//class SDAI_Application_instance;
|
||||
|
||||
#include "cleditor/editordefines.h"
|
||||
#include <editordefines.h>
|
||||
|
||||
class SC_EDITOR_EXPORT seeInfo : public DisplayNode {
|
||||
public:
|
||||
@@ -1,40 +1,60 @@
|
||||
set(LAZY_SRCS
|
||||
|
||||
set( clLazyFile_SRCS
|
||||
lazyDataSectionReader.cc
|
||||
lazyFileReader.cc
|
||||
lazyInstMgr.cc
|
||||
lazySupport.cc
|
||||
p21HeaderSectionReader.cc
|
||||
sectionReader.cc
|
||||
lazyP21DataSectionReader.cc
|
||||
judy.c
|
||||
judy/src/judy.c
|
||||
)
|
||||
|
||||
set( SC_CLLAZYFILE_HDRS
|
||||
headerSectionReader.h
|
||||
lazyFileReader.h
|
||||
lazyP21DataSectionReader.h
|
||||
p21HeaderSectionReader.h
|
||||
lazyDataSectionReader.h
|
||||
lazyInstMgr.h
|
||||
lazyTypes.h
|
||||
sectionReader.h
|
||||
sectionReader.h
|
||||
instMgrHelper.h
|
||||
judy/src/judy.h
|
||||
judy/src/judyLArray.h
|
||||
judy/src/judyL2Array.h
|
||||
judy/src/judySArray.h
|
||||
judy/src/judyS2Array.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/include/stepcode
|
||||
${SC_SOURCE_DIR}/src/cleditor
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/judy/src
|
||||
)
|
||||
|
||||
|
||||
set(_libdeps stepcore stepdai steputils stepeditor)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(_libdeps stepcore stepdai steputils stepeditor)
|
||||
SC_ADDLIB(steplazyfile SHARED SOURCES ${LAZY_SRCS} LINK_LIBRARIES ${_libdeps})
|
||||
SC_ADDLIB(steplazyfile SHARED SOURCES ${clLazyFile_SRCS} LINK_LIBRARIES ${_libdeps})
|
||||
if(WIN32)
|
||||
target_compile_definitions(steplazyfile PRIVATE SC_LAZYFILE_DLL_EXPORTS)
|
||||
endif()
|
||||
SC_ADDEXEC(lazy_test SOURCES "lazy_test.cc;sc_benchmark.cc" LINK_LIBRARIES steplazyfile stepeditor ${_libdeps} NO_INSTALL)
|
||||
target_compile_definitions(lazy_test PRIVATE NO_REGISTRY)
|
||||
endif()
|
||||
|
||||
if(BUILD_STATIC_LIBS)
|
||||
set(_libdeps stepcore-static stepdai-static steputils-static stepeditor-static)
|
||||
SC_ADDLIB(steplazyfile-static STATIC SOURCES ${LAZY_SRCS} LINK_LIBRARIES ${_libdeps})
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
SC_ADDEXEC(lazy_test SOURCES "lazy_test.cc;sc_benchmark.cc" LINK_LIBRARIES steplazyfile-static stepeditor-static ${_libdeps} NO_INSTALL)
|
||||
target_compile_definitions(lazy_test PRIVATE NO_REGISTRY)
|
||||
endif()
|
||||
SC_ADDLIB(steplazyfile-static STATIC SOURCES ${clLazyFile_SRCS} LINK_LIBRARIES ${_libdeps})
|
||||
endif()
|
||||
|
||||
SC_ADDEXEC(lazy_test SOURCES "lazy_test.cc;sc_benchmark.cc" LINK_LIBRARIES steplazyfile stepeditor NO_INSTALL)
|
||||
target_compile_definitions(lazy_test PRIVATE NO_REGISTRY)
|
||||
|
||||
install(FILES ${SC_CLLAZYFILE_HDRS}
|
||||
DESTINATION ${INCLUDE_DIR}/stepcode/cllazyfile)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
@@ -43,18 +63,3 @@ endif()
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
if(SC_ENABLE_TESTING)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(_lazy_index_libs steplazyfile stepeditor stepcore stepdai steputils)
|
||||
else()
|
||||
set(_lazy_index_libs steplazyfile-static stepeditor-static
|
||||
stepcore-static stepdai-static steputils-static)
|
||||
endif()
|
||||
SC_ADDEXEC(lazy_index_test SOURCES lazy_index_test.cc
|
||||
LINK_LIBRARIES ${_lazy_index_libs} NO_INSTALL)
|
||||
add_test(NAME lazy_index
|
||||
COMMAND lazy_index_test
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/lazy_index.stp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/lazy_scope.stp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test/lazy_broken_section.stp)
|
||||
endif()
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
#include <fstream>
|
||||
|
||||
#include "judyL2Array.h"
|
||||
#include "cllazyfile/lazyFileReader.h"
|
||||
#include "cllazyfile/sectionReader.h"
|
||||
#include "cllazyfile/lazyTypes.h"
|
||||
#include "lazyFileReader.h"
|
||||
#include "sectionReader.h"
|
||||
#include "lazyTypes.h"
|
||||
|
||||
#include "sc_export.h"
|
||||
|
||||
@@ -27,9 +27,12 @@ class SC_LAZYFILE_EXPORT headerSectionReader: public sectionReader {
|
||||
}
|
||||
|
||||
virtual ~headerSectionReader() {
|
||||
_headerInstances->clear( true );
|
||||
//FIXME delete each instance?! maybe add to clear, since it iterates over everything already
|
||||
//enum clearHow { rawData, deletePointers }
|
||||
_headerInstances->clear();
|
||||
delete _headerInstances;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //HEADERSECTIONREADER_H
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
#include <sc_export.h>
|
||||
|
||||
#include "clstepcore/mgrnode.h"
|
||||
#include "cllazyfile/lazyInstMgr.h"
|
||||
#include "clstepcore/instmgr.h"
|
||||
#include <mgrnode.h>
|
||||
#include <lazyInstMgr.h>
|
||||
#include <instmgr.h>
|
||||
|
||||
/**
|
||||
* \file instMgrHelper.h helper classes for the lazyInstMgr. Allows use of SDAI_Application_instance class
|
||||
@@ -31,9 +31,7 @@ class SC_LAZYFILE_EXPORT mgrNodeHelper: public MgrNodeBase {
|
||||
_id = id;
|
||||
}
|
||||
inline SDAI_Application_instance * GetSTEPentity() {
|
||||
/* Attribute resolution must not convert a batch-owned cache hit
|
||||
* into a process-lifetime retained instance. */
|
||||
return _lim->loadInstance( _id, true, false );
|
||||
return _lim->loadInstance( _id, true );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,3 +58,4 @@ class SC_LAZYFILE_EXPORT instMgrAdapter: public InstMgrBase {
|
||||
|
||||
|
||||
#endif //INSTMGRHELPER_H
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project( JudyTemplates )
|
||||
|
||||
if( NOT DEFINED CMAKE_BUILD_TYPE )
|
||||
# set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) #optimize, but include debug info
|
||||
set( CMAKE_BUILD_TYPE "Release" )
|
||||
endif( NOT DEFINED CMAKE_BUILD_TYPE )
|
||||
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
|
||||
|
||||
if( NOT DEFINED JUDY_OPTIMIZE_FLAGS )
|
||||
if( CMAKE_COMPILER_IS_GNUCC )
|
||||
set( JUDY_OPTIMIZE_FLAGS "-march=native" )
|
||||
|
||||
#test for LTO; this uses an internal variable so it may break
|
||||
if( DEFINED CMAKE_C_COMPILER_VERSION )
|
||||
if( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 )
|
||||
set( JUDY_OPTIMIZE_FLAGS "${JUDY_OPTIMIZE_FLAGS} -flto" )
|
||||
message( " -- GCC version: ${CMAKE_C_COMPILER_VERSION}. Enabling link-time optimization." )
|
||||
endif( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 )
|
||||
endif( DEFINED CMAKE_C_COMPILER_VERSION )
|
||||
#elseif( MSVC )
|
||||
# set( JUDY_OPTIMIZE_FLAGS "..." ) # <--- set MSVC flags here <---
|
||||
else()
|
||||
message( "Unrecognized compiler - no optimization flags set. Edit CMakeLists.txt or set JUDY_OPTIMIZE_FLAGS." )
|
||||
set( JUDY_OPTIMIZE_FLAGS "" )
|
||||
endif( CMAKE_COMPILER_IS_GNUCC )
|
||||
endif( NOT DEFINED JUDY_OPTIMIZE_FLAGS )
|
||||
add_definitions( ${JUDY_OPTIMIZE_FLAGS} )
|
||||
|
||||
set( JUDYS_SOURCES src/judy.c src/judy.h )
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCC )
|
||||
add_definitions( -pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long )
|
||||
endif( CMAKE_COMPILER_IS_GNUCC )
|
||||
|
||||
add_library( judy_lib STATIC ${JUDYS_SOURCES} )
|
||||
|
||||
include_directories( src )
|
||||
|
||||
if( ENABLE_TESTING )
|
||||
include( CTest )
|
||||
include_directories( test )
|
||||
enable_testing()
|
||||
|
||||
add_executable( pennysort test/pennySort.c test/sort.c ${JUDYS_SOURCES} )
|
||||
add_executable( hexsort test/hexSort.c test/sort.c ${JUDYS_SOURCES} )
|
||||
set_target_properties( pennysort hexsort PROPERTIES COMPILE_FLAGS "-DSTANDALONE" )
|
||||
|
||||
|
||||
add_executable( judyLtest test/judyLtest.cc )
|
||||
target_link_libraries( judyLtest judy_lib )
|
||||
add_test( judyLtest judyLtest )
|
||||
|
||||
add_executable( judyL2test test/judyL2test.cc )
|
||||
target_link_libraries( judyL2test judy_lib )
|
||||
add_test( judyL2test judyL2test )
|
||||
|
||||
add_executable( judyStest test/judyStest.cc )
|
||||
target_link_libraries( judyStest judy_lib )
|
||||
add_test( judyStest judyStest )
|
||||
|
||||
add_executable( judyS2test test/judyS2test.cc )
|
||||
target_link_libraries( judyS2test judy_lib )
|
||||
add_test( judyS2test judyS2test )
|
||||
|
||||
endif( ENABLE_TESTING )
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Judy Array Templates
|
||||
The Judy Array is a sparse dynamic array. It is a particular kind of trie that is highly efficient in space and time, and does not require tuning.
|
||||
|
||||
This uses [Karl Malbrain's implementation](http://code.google.com/p/judyarray/) of the Judy Array. Additional information can be found with Doug Baskins' [original implementation](http://judy.sourceforge.net/) on sourceforge, or on [Wikipedia](http://en.wikipedia.org/wiki/Judy_array).
|
||||
## The templates
|
||||
* `judyLArray` - a C++ template wrapper for an int-int Judy Array. JudyKey and JudyValue must be integer types and the same size as a pointer (i.e. 32- or 64-bit)
|
||||
* `judySArray` - Same as judyLArray, but with string-int mapping. The above restrictions on JudyValue apply here as well.
|
||||
* **TODO** - single-key, multi-value versions of the above
|
||||
* **TODO** - single-key, n-value versions of the above *(?)*
|
||||
|
||||
## Comparison between this and the versions Karl and Doug wrote
|
||||
* Doug Baskins' code is licenced under the LGPL. While more permissive than the GPL, it's still not always acceptable. His code is very fast but weighs in at ~20k lines.
|
||||
* Karl Malbrain's code is ~1250 lines, in a single file containing the judy array and the test code; use requires creating a header.
|
||||
* Both of the above are written in C, so they don't fit neatly into object-oriented C++.
|
||||
* Unlike Doug's code, this is ~1250 lines. Unlike Karl's, this is split into several files.
|
||||
|
||||
## Files
|
||||
* `CMakeLists.txt` - CMake build logic. If you don't have CMake, it should be quite easy to write a file for the build system of your choice.
|
||||
* **src/**
|
||||
* `judy.c`, `judy.h` - implementation of the Judy Array
|
||||
* `judyLArray.h` - the judyLArray template
|
||||
* `judySArray.h` - the judySArray template
|
||||
* **test/**
|
||||
* `hexSort.c` - Sorts a file where each line contains 32 hex chars. Compiles to `hexsort`, which is the same executable as compiling Karl's code with `-DHEXSORT -DSTANDALONE`
|
||||
* `pennySort.c` - Sorts strings; compiles to `pennysort`. Same as compiling Karl's code with `-DSTANDALONE`.
|
||||
* `sort.c`, `sort.h` - Karl's sorting functions. Only used by `hexsort` and `pennysort`.
|
||||
* `judyLtest.cc` - an incomplete test of the judyLArray template.
|
||||
* `judyStest.cc` - an incomplete test of the judySArray template.
|
||||
|
||||
|
||||
## Compiling
|
||||
* requires C and C++ compilers, CMake.
|
||||
* from the command line:
|
||||
* `mkdir build; cd build`
|
||||
* `cmake .. -DENABLE_TESTING=TRUE`
|
||||
* `make`
|
||||
|
||||
## License
|
||||
|
||||
Karl Malbrain's judy array code is public domain; what I've added is public domain as well.
|
||||
|
||||
## Contact
|
||||
mpictor -a-t- gmail
|
||||
@@ -0,0 +1,29 @@
|
||||
#astyle config file
|
||||
|
||||
#run astyle on one or a few files: use
|
||||
# astyle --options=misc/astyle.cfg path/to/file
|
||||
|
||||
#run astyle on all files: from the root dir, use
|
||||
# astyle --options=misc/astyle.cfg --recursive "src/*.c" "src/*.h" "test/*.c" "test/*.h"
|
||||
# in the above line, the double quotes *are* necessary
|
||||
|
||||
|
||||
suffix=none #don't create backup files
|
||||
|
||||
style=java #compact bracket style
|
||||
|
||||
indent=spaces=4
|
||||
|
||||
indent-preprocessor
|
||||
indent-classes
|
||||
indent-switches
|
||||
indent-namespaces
|
||||
pad-oper #pad (space) around operators
|
||||
pad-paren-in #pad inside parenthesis
|
||||
unpad-paren #remove parenthesis padding other than requested above
|
||||
|
||||
add-brackets #add brackets on one-line conditionals
|
||||
convert-tabs #convert all tabs to spaces
|
||||
align-pointer=middle #char * foo
|
||||
|
||||
lineend=linux #lines end with LF (linux), not CRLF (windows)
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
#generates a file of hex keys and runs hexsort on it. No verification is done.
|
||||
#hex data comes from /dev/urandom, so it isn't all that random.
|
||||
|
||||
hexdump -v -e '2/8 "%08x"' -e '"\n"' /dev/urandom |head -n 1000000 >ukeys
|
||||
#a.out [in-file] [out-file] [keysize] [recordlen] [keyoffset] [mergerecs]
|
||||
time bin/hexsort ukeys skeys
|
||||
File diff suppressed because it is too large
Load Diff
@@ -60,34 +60,11 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "cllazyfile/judy.h"
|
||||
#include "judy.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Judy keys are byte-packed: adjacent slots may start at an address that is
|
||||
* not suitably aligned for judyvalue. Callers are likewise permitted to
|
||||
* supply byte buffers without judyvalue alignment. Copy through an aligned
|
||||
* local value rather than dereferencing a cast pointer. Zero-filling any
|
||||
* bytes not requested also makes partial loads deterministic.
|
||||
*/
|
||||
static judyvalue
|
||||
judy_load_value( const unsigned char * source, unsigned int size )
|
||||
{
|
||||
judyvalue value = 0;
|
||||
|
||||
memcpy( &value, source, size );
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
judy_store_value( unsigned char * destination, judyvalue value,
|
||||
unsigned int size )
|
||||
{
|
||||
memcpy( destination, &value, size );
|
||||
}
|
||||
|
||||
#if defined(STANDALONE) || defined(ASKITIS)
|
||||
|
||||
extern unsigned int MaxMem;
|
||||
@@ -336,6 +313,7 @@ void judy_free( Judy * judy, void * block, int type ) {
|
||||
// assemble key from current path
|
||||
|
||||
unsigned int judy_key( Judy * judy, unsigned char * buff, unsigned int max ) {
|
||||
judyvalue * dest = ( judyvalue * )buff;
|
||||
unsigned int len = 0, idx = 0, depth;
|
||||
int slot, off, type;
|
||||
judyvalue value;
|
||||
@@ -355,8 +333,7 @@ unsigned int judy_key( Judy * judy, unsigned char * buff, unsigned int max ) {
|
||||
|
||||
if( judy->depth )
|
||||
if( !( len & JUDY_key_mask ) ) {
|
||||
judy_store_value( buff + depth * JUDY_key_size, 0,
|
||||
JUDY_key_size );
|
||||
dest[depth] = 0;
|
||||
}
|
||||
|
||||
switch( type ) {
|
||||
@@ -373,14 +350,9 @@ unsigned int judy_key( Judy * judy, unsigned char * buff, unsigned int max ) {
|
||||
base = ( unsigned char * )( judy->stack[idx].next & JUDY_mask );
|
||||
|
||||
if( judy->depth ) {
|
||||
value = judy_load_value( base + slot * keysize,
|
||||
JUDY_key_size );
|
||||
value = *( judyvalue * )( base + slot * keysize );
|
||||
value &= JudyMask[keysize];
|
||||
value |= judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
judy_store_value( buff + depth * JUDY_key_size, value,
|
||||
JUDY_key_size );
|
||||
depth++;
|
||||
dest[depth++] |= value;
|
||||
len += keysize;
|
||||
|
||||
if( depth < judy->depth ) {
|
||||
@@ -411,13 +383,7 @@ unsigned int judy_key( Judy * judy, unsigned char * buff, unsigned int max ) {
|
||||
|
||||
case JUDY_radix:
|
||||
if( judy->depth ) {
|
||||
value = judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
value |= ( judyvalue )slot <<
|
||||
( ( JUDY_key_size - ++len ) &
|
||||
JUDY_key_mask ) * 8;
|
||||
judy_store_value( buff + depth * JUDY_key_size, value,
|
||||
JUDY_key_size );
|
||||
dest[depth] |= ( judyvalue )slot << ( JUDY_key_size - ( ++len & JUDY_key_mask ) ) * 8;
|
||||
if( !( len & JUDY_key_mask ) ) {
|
||||
depth++;
|
||||
}
|
||||
@@ -453,6 +419,7 @@ unsigned int judy_key( Judy * judy, unsigned char * buff, unsigned int max ) {
|
||||
// find slot & setup cursor
|
||||
|
||||
JudySlot * judy_slot( Judy * judy, const unsigned char * buff, unsigned int max ) {
|
||||
judyvalue * src = ( judyvalue * )buff;
|
||||
int slot, size, keysize, tst, cnt;
|
||||
JudySlot next = *judy->root;
|
||||
judyvalue value, test = 0;
|
||||
@@ -496,9 +463,7 @@ JudySlot * judy_slot( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
value = 0;
|
||||
|
||||
if( judy->depth ) {
|
||||
value = judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
depth++;
|
||||
value = src[depth++];
|
||||
off |= JUDY_key_mask;
|
||||
off++;
|
||||
value &= JudyMask[keysize];
|
||||
@@ -513,8 +478,7 @@ JudySlot * judy_slot( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
// find slot > key
|
||||
|
||||
while( slot-- ) {
|
||||
test = judy_load_value( base + slot * keysize,
|
||||
JUDY_key_size );
|
||||
test = *( judyvalue * )( base + slot * keysize );
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
test >>= 8 * ( JUDY_key_size - keysize );
|
||||
#else
|
||||
@@ -545,9 +509,7 @@ JudySlot * judy_slot( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
table = ( JudySlot * )( next & JUDY_mask ); // outer radix
|
||||
|
||||
if( judy->depth ) {
|
||||
value = judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
slot = ( value >> ( (( JUDY_key_size - ++off) & JUDY_key_mask ) * 8 ) ) & 0xff;
|
||||
slot = ( src[depth] >> ( (( JUDY_key_size - ++off) & JUDY_key_mask ) * 8 ) ) & 0xff;
|
||||
} else if( off < max ) {
|
||||
slot = buff[off++];
|
||||
} else {
|
||||
@@ -1262,9 +1224,10 @@ void judy_splitspan( Judy * judy, JudySlot * next, unsigned char * base ) {
|
||||
// judy_cell: add string to judy array
|
||||
|
||||
JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max ) {
|
||||
judyvalue * src = ( judyvalue * )buff;
|
||||
int size, idx, slot, cnt, tst;
|
||||
JudySlot * next = judy->root;
|
||||
judyvalue test = 0, value;
|
||||
judyvalue test, value;
|
||||
unsigned int off = 0, start;
|
||||
JudySlot * table;
|
||||
JudySlot * node;
|
||||
@@ -1298,9 +1261,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
value = 0;
|
||||
|
||||
if( judy->depth ) {
|
||||
value = judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
depth++;
|
||||
value = src[depth++];
|
||||
off |= JUDY_key_mask;
|
||||
off++;
|
||||
value &= JudyMask[keysize];
|
||||
@@ -1315,8 +1276,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
// find slot > key
|
||||
|
||||
while( slot-- ) {
|
||||
test = judy_load_value( base + slot * keysize,
|
||||
JUDY_key_size );
|
||||
test = *( judyvalue * )( base + slot * keysize );
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
test >>= 8 * ( JUDY_key_size - keysize );
|
||||
#else
|
||||
@@ -1418,9 +1378,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
table = ( JudySlot * )( *next & JUDY_mask ); // outer radix
|
||||
|
||||
if( judy->depth ) {
|
||||
value = judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
slot = ( value >> ( ( (JUDY_key_size - ++off) & JUDY_key_mask ) * 8 ) ) & 0xff;
|
||||
slot = ( src[depth] >> ( ( (JUDY_key_size - ++off) & JUDY_key_mask ) * 8 ) ) & 0xff;
|
||||
} else if( off < max ) {
|
||||
slot = buff[off++];
|
||||
} else {
|
||||
@@ -1506,8 +1464,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
// fill in slot 0 with bytes of key
|
||||
|
||||
if( judy->depth ) {
|
||||
value = judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
value = src[depth];
|
||||
#if BYTE_ORDER != BIG_ENDIAN
|
||||
memcpy( base, &value, keysize ); // copy new key into slot
|
||||
#else
|
||||
@@ -1585,9 +1542,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
|
||||
// fill in slot 0 with bytes of key
|
||||
|
||||
value = judy_load_value( buff + depth * JUDY_key_size,
|
||||
JUDY_key_size );
|
||||
judy_store_value( base, value, JUDY_key_size );
|
||||
*( judyvalue * )base = src[depth];
|
||||
|
||||
if( judy->level < judy->max ) {
|
||||
judy->level++;
|
||||
@@ -1607,3 +1562,4 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max
|
||||
#endif
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ struct judyl2KVpair {
|
||||
/** A judyL2 array maps JudyKey's to multiple JudyValue's, similar to std::multimap.
|
||||
* Internally, this is a judyL array of std::vector< JudyValue >.
|
||||
* The first template parameter must be the same size as a void*
|
||||
* \tparam JudyKey the type of the key, i.e. uint64_t, etc
|
||||
* \tparam JudyValue the type of the value, i.e. int, pointer-to-object, etc. With judyL2Array, the size of this value can vary.
|
||||
* \param JudyKey the type of the key, i.e. uint64_t, etc
|
||||
* \param JudyValue the type of the value, i.e. int, pointer-to-object, etc. With judyL2Array, the size of this value can vary.
|
||||
*/
|
||||
template< typename JudyKey, typename JudyValue >
|
||||
class judyL2Array {
|
||||
@@ -24,8 +24,8 @@ struct judylKVpair {
|
||||
* a JudyValue. Each cell must be set to a non-zero value by the caller.
|
||||
*
|
||||
* Both template parameters must be the same size as a void*
|
||||
* \tparam JudyKey the type of the key, i.e. uint64_t, pointer-to-object, etc
|
||||
* \tparam JudyValue the type of the value
|
||||
* \param JudyKey the type of the key, i.e. uint64_t, pointer-to-object, etc
|
||||
* \param JudyValue the type of the value
|
||||
*/
|
||||
template< typename JudyKey, typename JudyValue >
|
||||
class judyLArray {
|
||||
@@ -159,8 +159,8 @@ class judyLArray {
|
||||
* getLastValue() will return the entry before the one that was deleted
|
||||
* \sa isEmpty()
|
||||
*/
|
||||
bool removeEntry( JudyKey key ) {
|
||||
if( judy_slot( _judyarray, reinterpret_cast<const unsigned char *>( &key ), _depth * JUDY_key_size ) ) {
|
||||
bool removeEntry( JudyKey * key ) {
|
||||
if( judy_slot( _judyarray, key, _depth * JUDY_key_size ) ) {
|
||||
_lastSlot = ( JudyValue * ) judy_del( _judyarray );
|
||||
return true;
|
||||
} else {
|
||||
@@ -25,7 +25,7 @@ struct judys2KVpair {
|
||||
|
||||
/** A judyS2 array maps a set of strings to multiple JudyValue's, similar to std::multimap.
|
||||
* Internally, this is a judyS array of std::vector< JudyValue >.
|
||||
* \tparam JudyValue the type of the value, i.e. int, pointer-to-object, etc.
|
||||
* \param JudyValue the type of the value, i.e. int, pointer-to-object, etc.
|
||||
*/
|
||||
template< typename JudyValue >
|
||||
class judyS2Array {
|
||||
@@ -51,8 +51,8 @@ class judyS2Array {
|
||||
explicit judyS2Array( const judyS2Array< JudyValue > & other ): _maxKeyLen( other._maxKeyLen ), _success( other._success ) {
|
||||
_judyarray = judy_clone( other._judyarray );
|
||||
_buff = new unsigned char[_maxKeyLen];
|
||||
strncpy( reinterpret_cast< char * >( _buff ), reinterpret_cast< const char * >( other._buff ), _maxKeyLen - 1 );
|
||||
_buff[ _maxKeyLen - 1 ] = '\0'; //ensure that _buff is null-terminated
|
||||
strncpy( _buff, other._buff, _maxKeyLen );
|
||||
_buff[ _maxKeyLen ] = '\0'; //ensure that _buff is null-terminated, since strncpy won't necessarily do so
|
||||
find( _buff ); //set _lastSlot
|
||||
}
|
||||
|
||||
@@ -39,8 +39,8 @@ class judySArray {
|
||||
explicit judySArray( const judySArray< JudyValue > & other ): _maxKeyLen( other._maxKeyLen ), _success( other._success ) {
|
||||
_judyarray = judy_clone( other._judyarray );
|
||||
_buff = new unsigned char[_maxKeyLen];
|
||||
strncpy( reinterpret_cast< char * >( _buff ), reinterpret_cast< const char * >( other._buff ), _maxKeyLen - 1 );
|
||||
_buff[ _maxKeyLen - 1 ] = '\0'; //ensure that _buff is null-terminated
|
||||
strncpy( _buff, other._buff, _maxKeyLen );
|
||||
_buff[ _maxKeyLen ] = '\0'; //ensure that _buff is null-terminated, since strncpy won't necessarily do so
|
||||
find( _buff ); //set _lastSlot
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
// Judy arrays 13 DEC 2012 (judy64n.c from http://code.google.com/p/judyarray/ )
|
||||
// This code is public domain.
|
||||
|
||||
// Author Karl Malbrain, malbrain AT yahoo.com
|
||||
// with assistance from Jan Weiss.
|
||||
// modifications (and any bugs) by Mark Pictor, mpictor at gmail
|
||||
|
||||
// Simplified judy arrays for strings and integers
|
||||
// Adapted from the ideas of Douglas Baskins of HP.
|
||||
|
||||
// Map a set of keys to corresponding memory cells (uints).
|
||||
// Each cell must be set to a non-zero value by the caller.
|
||||
|
||||
|
||||
// Integer mappings are denoted by calling judy_open with the
|
||||
// Integer depth of the Judy Trie as the second argument.
|
||||
|
||||
#ifndef STANDALONE
|
||||
# error must define STANDALONE while compiling this file and judy64.c
|
||||
#endif
|
||||
|
||||
#include "judy.h"
|
||||
#include "sort.h"
|
||||
|
||||
unsigned int MaxMem = 0;
|
||||
/**
|
||||
usage:
|
||||
a.out [in-file] [out-file]
|
||||
where all lines of in-file are 32 chars, hexadecimal
|
||||
On linux, a 1M-line file can be created with the following:
|
||||
hexdump -v -e '2/8 "%08x"' -e '"\n"' /dev/urandom |head -n 1000000 >in-file
|
||||
*/
|
||||
int main( int argc, char ** argv ) {
|
||||
unsigned char buff[1024];
|
||||
JudySlot max = 0;
|
||||
JudySlot * cell;
|
||||
FILE * in, *out;
|
||||
void * judy;
|
||||
unsigned int len;
|
||||
unsigned int idx;
|
||||
|
||||
if( argc > 1 ) {
|
||||
in = fopen( argv[1], "rb" );
|
||||
} else {
|
||||
in = stdin;
|
||||
}
|
||||
|
||||
if( argc > 2 ) {
|
||||
out = fopen( argv[2], "wb" );
|
||||
} else {
|
||||
out = stdout;
|
||||
}
|
||||
|
||||
setvbuf( out, NULL, _IOFBF, 4096 * 1024 );
|
||||
|
||||
if( !in ) {
|
||||
fprintf( stderr, "unable to open input file\n" );
|
||||
}
|
||||
|
||||
if( !out ) {
|
||||
fprintf( stderr, "unable to open output file\n" );
|
||||
}
|
||||
|
||||
PennyMerge = ( unsigned long long )PennyLine * PennyRecs;
|
||||
|
||||
judy = judy_open( 1024, 16 / JUDY_key_size );
|
||||
|
||||
while( fgets( ( char * )buff, sizeof( buff ), in ) ) {
|
||||
judyvalue key[16 / JUDY_key_size];
|
||||
if( len = strlen( ( const char * )buff ) ) {
|
||||
buff[--len] = 0; // remove LF
|
||||
}
|
||||
#if JUDY_key_size == 4
|
||||
key[3] = strtoul( buff + 24, NULL, 16 );
|
||||
buff[24] = 0;
|
||||
key[2] = strtoul( buff + 16, NULL, 16 );
|
||||
buff[16] = 0;
|
||||
key[1] = strtoul( buff + 8, NULL, 16 );
|
||||
buff[8] = 0;
|
||||
key[0] = strtoul( buff, NULL, 16 );
|
||||
#else
|
||||
key[1] = strtoull( buff + 16, NULL, 16 );
|
||||
buff[16] = 0;
|
||||
key[0] = strtoull( buff, NULL, 16 );
|
||||
#endif
|
||||
*( judy_cell( judy, ( void * )key, 0 ) ) += 1; // count instances of string
|
||||
max++;
|
||||
}
|
||||
|
||||
fprintf( stderr, "%" PRIuint " memory used\n", MaxMem );
|
||||
|
||||
cell = judy_strt( judy, NULL, 0 );
|
||||
|
||||
if( cell ) do {
|
||||
judyvalue key[16 / JUDY_key_size];
|
||||
len = judy_key( judy, ( void * )key, 0 );
|
||||
for( idx = 0; idx < *cell; idx++ ) { // spit out duplicates
|
||||
#if JUDY_key_size == 4
|
||||
fprintf( out, "%.8X", key[0] );
|
||||
fprintf( out, "%.8X", key[1] );
|
||||
fprintf( out, "%.8X", key[2] );
|
||||
fprintf( out, "%.8X", key[3] );
|
||||
#else
|
||||
fprintf( out, "%.16llX", key[0] );
|
||||
fprintf( out, "%.16llX", key[1] );
|
||||
#endif
|
||||
fputc( '\n', out );
|
||||
}
|
||||
} while( cell = judy_nxt( judy ) );
|
||||
|
||||
#if 0
|
||||
// test deletion all the way to an empty tree
|
||||
|
||||
if( cell = judy_prv( judy ) )
|
||||
do {
|
||||
max -= *cell;
|
||||
} while( cell = judy_del( judy ) );
|
||||
|
||||
assert( max == 0 );
|
||||
#endif
|
||||
judy_close( judy );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "judyL2Array.h"
|
||||
typedef judyL2Array< uint64_t, uint64_t > jl2a;
|
||||
|
||||
bool testFind( jl2a & j, uint64_t key, unsigned int count ) {
|
||||
jl2a::cvector * v = j.find( key );
|
||||
std::cout << "find: key " << key << " ..." << std::endl;
|
||||
if( count > 0 ) {
|
||||
if( !v || !j.success() || ( v->size() != count ) ) {
|
||||
std::cout << " false negative - v: " << v << " success: " << j.success();
|
||||
if( v ) {
|
||||
std::cout << " expected count: " << count << " actual: " << v->size();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return false;
|
||||
} else {
|
||||
// note - this doesn't verify that the right keys are returned, just the right number!
|
||||
jl2a::vector::const_iterator it = v->begin();
|
||||
std::cout << " correct number of values -";
|
||||
for( ; it != v->end(); it++ ) {
|
||||
std::cout << " " << *it;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
} else {
|
||||
if( v || j.success() ) {
|
||||
std::cout << " false positive - v: " << v << " success: " << j.success() << std::endl;
|
||||
return false;
|
||||
} else {
|
||||
std::cout << " not found, as expected." << std::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
bool pass = true;
|
||||
jl2a jl;
|
||||
std::cout.setf( std::ios::boolalpha );
|
||||
// std::cout << "size of judyL2Array: " << sizeof( jl ) << std::endl;
|
||||
jl.insert( 5, 12 );
|
||||
jl.insert( 6, 2 );
|
||||
jl.insert( 7, 312 );
|
||||
jl.insert( 11, 412 );
|
||||
jl.insert( 7, 313 );
|
||||
jl2a::cpair kv = jl.atOrAfter( 4 );
|
||||
std::cout << "atOrAfter test ..." << std::endl;
|
||||
if( kv.value != 0 && jl.success() ) {
|
||||
std::cout << " key " << kv.key << " value " << kv.value->at( 0 ) << std::endl;
|
||||
} else {
|
||||
std::cout << " failed" << std::endl;
|
||||
pass = false;
|
||||
}
|
||||
|
||||
pass &= testFind( jl, 8, 0 );
|
||||
pass &= testFind( jl, 11, 1 );
|
||||
pass &= testFind( jl, 7, 2 );
|
||||
|
||||
jl.clear();
|
||||
|
||||
//TODO test all of judyL2Array
|
||||
if( pass ) {
|
||||
std::cout << "All tests passed." << std::endl;
|
||||
exit( EXIT_SUCCESS );
|
||||
} else {
|
||||
std::cout << "At least one test failed." << std::endl;
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "judyLArray.h"
|
||||
|
||||
int main() {
|
||||
std::cout.setf( std::ios::boolalpha );
|
||||
judyLArray< uint64_t, uint64_t > jl;
|
||||
std::cout << "size of judyLArray: " << sizeof( jl ) << std::endl;
|
||||
jl.insert( 5, 12 );
|
||||
jl.insert( 6, 2 );
|
||||
jl.insert( 7, 312 );
|
||||
jl.insert( 8, 412 );
|
||||
judyLArray< uint64_t, uint64_t >::pair kv = jl.atOrAfter( 4 );
|
||||
std::cout << "k " << kv.key << " v " << kv.value << std::endl;
|
||||
|
||||
long v = jl.find( 11 );
|
||||
if( v != 0 || jl.success() ) {
|
||||
std::cout << "find: false positive - v: " << v << " success: " << jl.success() << std::endl;
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
v = jl.find( 7 );
|
||||
if( v != 312 || !jl.success() ) {
|
||||
std::cout << "find: false negative - v: " << v << " success: " << jl.success() << std::endl;
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
jl.clear();
|
||||
|
||||
//TODO test all of judyLArray
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "judyS2Array.h"
|
||||
|
||||
typedef judyS2Array< uint64_t > js2a;
|
||||
|
||||
bool testFind( js2a & j, const char * key, unsigned int count ) {
|
||||
js2a::cvector * v = j.find( key );
|
||||
std::cout << "find: key " << key << " ..." << std::endl;
|
||||
if( count > 0 ) {
|
||||
if( !v || !j.success() || ( v->size() != count ) ) {
|
||||
std::cout << " false negative - v: " << v << " success: " << j.success();
|
||||
if( v ) {
|
||||
std::cout << " expected count: " << count << " actual: " << v->size();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return false;
|
||||
} else {
|
||||
// note - this doesn't verify that the right keys are returned, just the right number!
|
||||
js2a::vector::const_iterator it = v->begin();
|
||||
std::cout << " correct number of values -";
|
||||
for( ; it != v->end(); it++ ) {
|
||||
std::cout << " " << *it;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
} else {
|
||||
if( v || j.success() ) {
|
||||
std::cout << " false positive - v: " << v << " success: " << j.success() << std::endl;
|
||||
return false;
|
||||
} else {
|
||||
std::cout << " not found, as expected." << std::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
bool pass = true;
|
||||
std::cout.setf( std::ios::boolalpha );
|
||||
|
||||
js2a js( 255 );
|
||||
js.insert( "blah", 1234 );
|
||||
js.insert( "bah", 124 );
|
||||
js.insert( "blh", 123 );
|
||||
js.insert( "blh", 4123 );
|
||||
js.insert( "bla", 134 );
|
||||
js.insert( "bh", 234 );
|
||||
|
||||
js2a::cpair kv = js.atOrAfter( "ab" );
|
||||
std::cout << "atOrAfter test ..." << std::endl;
|
||||
if( kv.value != 0 && js.success() ) {
|
||||
std::cout << " key " << kv.key << " value " << kv.value->at( 0 ) << std::endl;
|
||||
} else {
|
||||
std::cout << " failed" << std::endl;
|
||||
pass = false;
|
||||
}
|
||||
|
||||
pass &= testFind( js, "sdafsd", 0 );
|
||||
pass &= testFind( js, "bah", 1 );
|
||||
pass &= testFind( js, "blh", 2 );
|
||||
|
||||
js.clear();
|
||||
|
||||
//TODO test all of judyS2Array
|
||||
if( pass ) {
|
||||
std::cout << "All tests passed." << std::endl;
|
||||
exit( EXIT_SUCCESS );
|
||||
} else {
|
||||
std::cout << "At least one test failed." << std::endl;
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user