Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ec8e778a6 | ||
|
|
133f503960 | ||
|
|
89d941d63c | ||
|
|
fe53db9cee | ||
|
|
a9c13f7434 | ||
|
|
77c0b266c4 | ||
|
|
5ef9cc9798 | ||
|
|
3e8050465e | ||
|
|
45ace10eb6 | ||
|
|
a2c83eacf9 | ||
|
|
70f45a9096 |
+386
-87
@@ -32,128 +32,427 @@
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# *******************************************************************
|
||||
# *** STEPcode's CMakeLists.txt ***
|
||||
# *** SC's CMakeLists.txt ***
|
||||
# *******************************************************************
|
||||
|
||||
# This file contains the top level CMakeLists.txt logic for the
|
||||
# STEPcode software package.
|
||||
# SC software package.
|
||||
|
||||
project(SC)
|
||||
PROJECT(SC)
|
||||
|
||||
# SC version
|
||||
set(SC_VERSION_MAJOR 0)
|
||||
set(SC_VERSION_MINOR 7-dev)
|
||||
set(SC_VERSION ${SC_VERSION_MAJOR}.${SC_VERSION_MINOR})
|
||||
SET(SC_VERSION_MAJOR 0)
|
||||
SET(SC_VERSION_MINOR 7-dev)
|
||||
SET(SC_VERSION ${SC_VERSION_MAJOR}.${SC_VERSION_MINOR})
|
||||
|
||||
# SC ABI version. SC_ABI_SOVERSION should be incremented
|
||||
# for each release introducing API incompatibilities
|
||||
set(SC_ABI_SOVERSION 2)
|
||||
set(SC_ABI_VERSION ${SC_ABI_SOVERSION}.0.0)
|
||||
SET(SC_ABI_SOVERSION 2)
|
||||
SET(SC_ABI_VERSION ${SC_ABI_SOVERSION}.0.0)
|
||||
|
||||
# Minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
if(COMMAND CMAKE_POLICY)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
|
||||
IF(COMMAND CMAKE_POLICY)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
if ("${CMAKE_VERSION}" VERSION_GREATER 2.99)
|
||||
CMAKE_POLICY(SET CMP0026 OLD)
|
||||
endif ("${CMAKE_VERSION}" VERSION_GREATER 2.99)
|
||||
endif(COMMAND CMAKE_POLICY)
|
||||
ENDIF(COMMAND CMAKE_POLICY)
|
||||
|
||||
IF( NOT DEFINED INCLUDE_INSTALL_DIR )
|
||||
SET( INCLUDE_INSTALL_DIR include )
|
||||
ENDIF( NOT DEFINED INCLUDE_INSTALL_DIR )
|
||||
|
||||
IF( NOT DEFINED LIB_INSTALL_DIR )
|
||||
SET( LIB_INSTALL_DIR lib )
|
||||
ENDIF( NOT DEFINED LIB_INSTALL_DIR )
|
||||
|
||||
IF( NOT DEFINED BIN_INSTALL_DIR )
|
||||
SET( BIN_INSTALL_DIR bin )
|
||||
ENDIF( NOT DEFINED BIN_INSTALL_DIR )
|
||||
|
||||
IF( NOT DEFINED SC_BUILD_TYPE )
|
||||
SET( SC_BUILD_TYPE "Debug" CACHE STRING "Build type" ) # By default set debug build
|
||||
ENDIF( NOT DEFINED SC_BUILD_TYPE )
|
||||
IF(NOT SC_IS_SUBBUILD)
|
||||
SET(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE} CACHE INTERNAL "Build type, immutable" FORCE )
|
||||
ELSE(NOT SC_IS_SUBBUILD)
|
||||
SET(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE} )
|
||||
ENDIF(NOT SC_IS_SUBBUILD)
|
||||
|
||||
# Define helper macro OPTION_WITH_DEFAULT
|
||||
MACRO( OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT )
|
||||
IF( NOT DEFINED ${OPTION_NAME} )
|
||||
SET( ${OPTION_NAME} ${OPTION_DEFAULT} )
|
||||
ENDIF( NOT DEFINED ${OPTION_NAME} )
|
||||
OPTION( ${OPTION_NAME} "${OPTION_STRING}" ${${OPTION_NAME}} )
|
||||
ENDMACRO( OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT )
|
||||
|
||||
# build shared libs by default
|
||||
OPTION_WITH_DEFAULT(SC_BUILD_SHARED_LIBS "Build shared libs" ON )
|
||||
|
||||
# don't build static libs by default
|
||||
OPTION_WITH_DEFAULT(SC_BUILD_STATIC_LIBS "Build static libs" OFF)
|
||||
|
||||
OPTION_WITH_DEFAULT(SC_PYTHON_GENERATOR "Compile exp2python" ON)
|
||||
OPTION_WITH_DEFAULT(SC_CPP_GENERATOR "Compile exp2cxx" ON)
|
||||
|
||||
OPTION_WITH_DEFAULT(SC_MEMMGR_ENABLE_CHECKS "Enable sc_memmgr's memory leak detection" OFF)
|
||||
OPTION_WITH_DEFAULT(SC_TRACE_FPRINTF "Enable extra comments in generated code so the code's source in exp2cxx may be located" OFF)
|
||||
|
||||
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 )
|
||||
|
||||
if( NOT DEFINED SC_BUILD_SCHEMAS )
|
||||
set( SCHEMAS_WARNING TRUE )
|
||||
#this makes SC_BUILD_SCHEMAS show up in cmake-gui
|
||||
SET(SC_BUILD_SCHEMAS "ALL" CACHE string "Semicolon-separated list of paths to EXPRESS schemas to be built" )
|
||||
endif( NOT DEFINED SC_BUILD_SCHEMAS )
|
||||
|
||||
# CMake derives much of its functionality from modules, typically
|
||||
# stored in one directory - let CMake know where to find them.
|
||||
set(SC_CMAKE_DIR "${SC_SOURCE_DIR}/cmake")
|
||||
SET(SC_CMAKE_DIR "${SC_SOURCE_DIR}/cmake")
|
||||
if(NOT IS_SUBBUILD)
|
||||
set(CMAKE_MODULE_PATH "${SC_CMAKE_DIR};${CMAKE_MODULE_PATH}")
|
||||
SET(CMAKE_MODULE_PATH "${SC_CMAKE_DIR};${CMAKE_MODULE_PATH}")
|
||||
else(NOT IS_SUBBUILD)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${SC_CMAKE_DIR}")
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${SC_CMAKE_DIR}")
|
||||
endif(NOT IS_SUBBUILD)
|
||||
|
||||
# testing and compilation options, build output dirs, install dirs, uninstall, package creation, etc
|
||||
include(${SC_CMAKE_DIR}/SC_Build_opts.cmake)
|
||||
INCLUDE(${SC_CMAKE_DIR}/SC_Utils.cmake)
|
||||
|
||||
# SC_ADDEXEC and SC_ADDLIB macros, dllimport/export, etc
|
||||
include(${SC_CMAKE_DIR}/SC_Targets.cmake)
|
||||
|
||||
# Macros related to paths
|
||||
include(${SC_CMAKE_DIR}/SC_Paths.cmake)
|
||||
|
||||
# locale stuff
|
||||
include(${SC_CMAKE_DIR}/SC_Locale.cmake)
|
||||
|
||||
# logic related to regenerating the lexer and parser source code
|
||||
include(${SC_CMAKE_DIR}/SC_Regenerate.cmake)
|
||||
|
||||
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)
|
||||
|
||||
if(NOT DEFINED SC_BUILD_SCHEMAS)
|
||||
list(APPEND CONFIG_END_MESSAGES
|
||||
"** CMake variable SC_BUILD_SCHEMAS was not set. Defaults to building ALL schemas, which will take a"
|
||||
" while; see http://stepcode.org/mw/index.php?title=STEPcode_CMake_variables#SC_BUILD_SCHEMAS")
|
||||
#this makes SC_BUILD_SCHEMAS show up in cmake-gui
|
||||
set(SC_BUILD_SCHEMAS "ALL" CACHE string "Semicolon-separated list of paths to EXPRESS schemas to be built")
|
||||
endif(NOT DEFINED SC_BUILD_SCHEMAS)
|
||||
|
||||
list(APPEND CONFIG_END_MESSAGES
|
||||
".. Don't worry about any messages above about missing headers or failed tests, as long as"
|
||||
" you see 'Configuring done' below. Headers and features vary by compiler."
|
||||
".. Generating step can take a while if you are building several schemas.")
|
||||
|
||||
# create config headers sc_cf.h and sc_version_string.h
|
||||
include(${SC_CMAKE_DIR}/SC_Config_Headers.cmake)
|
||||
# Save the current LC_ALL, LC_MESSAGES, and LANG environment variables and set them
|
||||
# to "C" so things like date output are as expected
|
||||
SET(_orig_lc_all $ENV{LC_ALL})
|
||||
SET(_orig_lc_messages $ENV{LC_MESSAGES})
|
||||
SET(_orig_lang $ENV{LANG})
|
||||
IF(_orig_lc_all)
|
||||
SET(ENV{LC_ALL} C)
|
||||
ENDIF(_orig_lc_all)
|
||||
IF(_orig_lc_messages)
|
||||
SET(ENV{LC_MESSAGES} C)
|
||||
ENDIF(_orig_lc_messages)
|
||||
IF(_orig_lang)
|
||||
SET(ENV{LANG} C)
|
||||
ENDIF(_orig_lang)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Coverage option
|
||||
OPTION_WITH_DEFAULT( SC_ENABLE_COVERAGE "Enable code coverage test" OFF )
|
||||
IF(SC_ENABLE_COVERAGE)
|
||||
SET(SC_ENABLE_TESTING ON CACHE BOOL "Testing enabled by coverage option" FORCE)
|
||||
# build static libs, better coverage report
|
||||
SET(SC_BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libs" FORCE )
|
||||
SET(SC_BUILD_STATIC_LIBS ON CACHE BOOL "Build static libs" FORCE )
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
|
||||
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-fprofile-arcs -ftest-coverage" CACHE STRING "Extra linker flags required by code coverage" FORCE)
|
||||
SET(SC_BUILD_TYPE "Debug" CACHE STRING "Build type required by testing framework" FORCE)
|
||||
SET( SC_PYTHON_GENERATOR OFF ) #won't build with static libs
|
||||
ENDIF(SC_ENABLE_COVERAGE)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Testing option
|
||||
OPTION_WITH_DEFAULT( SC_ENABLE_TESTING "Enable unittesting framework" OFF )
|
||||
IF(SC_ENABLE_TESTING)
|
||||
if( NOT DEFINED SC_BUILD_SCHEMAS )
|
||||
set( SC_BUILD_SCHEMAS "ALL" ) #test all schemas, unless otherwise specified
|
||||
endif()
|
||||
INCLUDE(CTest)
|
||||
ENABLE_TESTING()
|
||||
ENDIF(SC_ENABLE_TESTING)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# The following logic is what allows binaries to run successfully in
|
||||
# the build directory AND install directory. Thanks to plplot for
|
||||
# identifying the necessity of setting CMAKE_INSTALL_NAME_DIR on OSX.
|
||||
# Documentation of these options is available at
|
||||
# http://www.cmake.org/Wiki/CMake_RPATH_handling
|
||||
|
||||
# use, i.e. don't skip the full RPATH for the build tree
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
|
||||
# when building, don't use the install RPATH already
|
||||
# (but later on when installing)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
|
||||
# the RPATH/INSTALL_NAME_DIR to be used when installing
|
||||
if (NOT APPLE)
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:\$ORIGIN/../lib")
|
||||
endif(NOT APPLE)
|
||||
# On OSX, we need to set INSTALL_NAME_DIR instead of RPATH
|
||||
# http://www.cmake.org/cmake/help/cmake-2-8-docs.html#variable:CMAKE_INSTALL_NAME_DIR
|
||||
set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
|
||||
# add the automatically determined parts of the RPATH which point to
|
||||
# directories outside the build tree to the install RPATH
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Output directories.
|
||||
# When this is a subbuild, assume that the parent project controls these
|
||||
IF( NOT SC_IS_SUBBUILD )
|
||||
IF(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
|
||||
ENDIF(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
IF(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
|
||||
ENDIF(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
|
||||
IF(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
|
||||
ENDIF(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
|
||||
FOREACH(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES})
|
||||
STRING(TOUPPER "${CFG_TYPE}" CFG_TYPE)
|
||||
IF(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
SET("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
|
||||
ENDIF(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
IF(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
SET("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
|
||||
ENDIF(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
IF(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
SET("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
|
||||
ENDIF(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
ENDFOREACH()
|
||||
ENDIF( NOT SC_IS_SUBBUILD )
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure install locations.
|
||||
|
||||
# The location in which to install SC. Need a good Debug location
|
||||
# for Windows. Only do this if CMAKE_INSTALL_PREFIX hasn't been set
|
||||
# already, to try and allow parent builds (if any) some control.
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
IF(NOT WIN32)
|
||||
IF (${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||
SET(SC_INSTALL_PREFIX "${SC_SOURCE_DIR}/../sc-install")
|
||||
ELSE()
|
||||
SET(SC_INSTALL_PREFIX "/usr/local")
|
||||
ENDIF()
|
||||
ENDIF(NOT WIN32)
|
||||
SET( SC_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE
|
||||
PATH "Install prefix prepended to target to create install location" )
|
||||
SET( CMAKE_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE INTERNAL "Prefix prepended to install directories if target destination is not absolute, immutable" FORCE )
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
|
||||
OPTION(SC_BUILD_EXPRESS_ONLY "Only build express parser." OFF)
|
||||
MARK_AS_ADVANCED(SC_BUILD_EXPRESS_ONLY)
|
||||
|
||||
# Take the sc config file template as the starting point for
|
||||
# sc_cf.h.in - scripts may need to append to the template, so
|
||||
# it is read into memory initially.
|
||||
SET(CONFIG_H_FILE ${SC_BINARY_DIR}/include/sc_cf.h.in)
|
||||
set_source_files_properties(${CONFIG_H_FILE} PROPERTIES GENERATED TRUE)
|
||||
set(CMAKE_CURRENT_PROJECT SC)
|
||||
define_property(GLOBAL PROPERTY SC_CONFIG_H_CONTENTS BRIEF_DOCS "config.h.in contents" FULL_DOCS "config.h.in contents for SC project")
|
||||
if(NOT COMMAND CONFIG_H_APPEND)
|
||||
macro(CONFIG_H_APPEND PROJECT_NAME NEW_CONTENTS)
|
||||
if(PROJECT_NAME)
|
||||
get_property(${PROJECT_NAME}_CONFIG_H_CONTENTS GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS)
|
||||
set(${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS "${${PROJECT_NAME}_CONFIG_H_CONTENTS}${NEW_CONTENTS}")
|
||||
set_property(GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS "${${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS}")
|
||||
endif(PROJECT_NAME)
|
||||
endmacro(CONFIG_H_APPEND NEW_CONTENTS)
|
||||
endif(NOT COMMAND CONFIG_H_APPEND)
|
||||
file(READ ${SC_SOURCE_DIR}/include/sc_cf_cmake.h.in CONFIG_H_FILE_CONTENTS)
|
||||
CONFIG_H_APPEND(SC "${CONFIG_H_FILE_CONTENTS}")
|
||||
|
||||
# The Express parser uses the tools Perplex, RE2C and Lemon to generate code
|
||||
# from higher level inputs. Depending on available tools and options, the
|
||||
# SC build can either re-generate code as part of the build, or use cached
|
||||
# files that are ready for compilation.
|
||||
#
|
||||
# SC_GENERATE_LEXER_PARSER is the "high level" control a user sets to determine
|
||||
# how the SC build will interact (or not) with these tools. AUTO (the
|
||||
# default) means it will search for the necessary tools, and use them only if
|
||||
# everything is found. If not, it will fall back to the cached versions. If
|
||||
# this option is set to ON and the necessary tools are not found, the
|
||||
# configure step will fail. If it is set to OFF, SC will not even try to use
|
||||
# the generators and will instead use the cached sources.
|
||||
if(NOT SC_GENERATE_LEXER_PARSER)
|
||||
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
|
||||
else(NOT SC_GENERATE_LEXER_PARSER)
|
||||
string(TOUPPER "${SC_GENERATE_LEXER_PARSER}" SC_GENERATE_LEXER_PARSER)
|
||||
endif(NOT SC_GENERATE_LEXER_PARSER)
|
||||
set_property(CACHE SC_GENERATE_LEXER_PARSER PROPERTY STRINGS AUTO ON OFF)
|
||||
if (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
message(WARNING "Unknown value ${SC_GENERATE_LEXER_PARSER} supplied for BRLCAD_WORD_SIZE - defaulting to AUTO")
|
||||
message(WARNING "Valid options are AUTO, ON and OFF")
|
||||
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
|
||||
endif (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
|
||||
# If the generators have not been turned off, we need to check for them
|
||||
if(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
find_package(LEMON)
|
||||
find_package(RE2C)
|
||||
find_package(PERPLEX)
|
||||
if(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
|
||||
# Templates may be anywhere - make sure we have a stable path if a relative
|
||||
# path was specified at CMake time
|
||||
get_filename_component(lemon_template_fpath "${LEMON_TEMPLATE}" ABSOLUTE)
|
||||
if(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
|
||||
get_filename_component(LEMON_TEMPLATE "${CMAKE_BINARY_DIR}/${LEMON_TEMPLATE}" ABSOLUTE)
|
||||
endif(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
|
||||
get_filename_component(perplex_template_fpath "${PERPLEX_TEMPLATE}" ABSOLUTE)
|
||||
if(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
|
||||
get_filename_component(PERPLEX_TEMPLATE "${CMAKE_BINARY_DIR}/${PERPLEX_TEMPLATE}" ABSOLUTE)
|
||||
endif(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
|
||||
|
||||
if(NOT COMMAND LEMON_TARGET)
|
||||
include(${SC_CMAKE_DIR}/LEMON_Util.cmake)
|
||||
endif(NOT COMMAND LEMON_TARGET)
|
||||
if(NOT COMMAND PERPLEX_TARGET)
|
||||
include(${SC_CMAKE_DIR}/PERPLEX_Util.cmake)
|
||||
endif(NOT COMMAND PERPLEX_TARGET)
|
||||
set(SC_GENERATE_LP_SOURCES 1)
|
||||
else(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
|
||||
if("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
|
||||
message(FATAL_ERROR "\nSC_GENERATE_LEXER_PARSER set to ON, but one or more components of the Perplex/RE2C/Lemon toolchain were not found.\n")
|
||||
else("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
|
||||
set(SC_GENERATE_LP_SOURCES 0)
|
||||
endif("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
|
||||
endif(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
|
||||
else(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
set(SC_GENERATE_LP_SOURCES 0)
|
||||
endif(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
|
||||
INCLUDE(CheckLibraryExists)
|
||||
INCLUDE(CheckIncludeFile)
|
||||
INCLUDE(CheckFunctionExists)
|
||||
INCLUDE(CheckTypeSize)
|
||||
INCLUDE(CMakePushCheckState)
|
||||
INCLUDE(CheckCXXSourceRuns)
|
||||
|
||||
CHECK_INCLUDE_FILE(ndir.h HAVE_NDIR_H)
|
||||
CHECK_INCLUDE_FILE(stdarg.h HAVE_STDARG_H)
|
||||
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
|
||||
CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H)
|
||||
CHECK_INCLUDE_FILE(sysent.h HAVE_SYSENT_H)
|
||||
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
|
||||
CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H)
|
||||
CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)
|
||||
CHECK_INCLUDE_FILE(process.h HAVE_PROCESS_H)
|
||||
CHECK_INCLUDE_FILE(io.h HAVE_IO_H)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(abs HAVE_ABS)
|
||||
CHECK_FUNCTION_EXISTS(memcpy HAVE_MEMCPY)
|
||||
CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE)
|
||||
CHECK_FUNCTION_EXISTS(getopt HAVE_GETOPT)
|
||||
|
||||
CHECK_TYPE_SIZE("ssize_t" SSIZE_T)
|
||||
|
||||
set( TEST_STD_THREAD "
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
void do_work() {
|
||||
std::cout << \"thread\" << std::endl;
|
||||
}
|
||||
int main() {
|
||||
std::thread t(do_work);
|
||||
t.join();
|
||||
}
|
||||
" )
|
||||
cmake_push_check_state()
|
||||
if( UNIX )
|
||||
set( CMAKE_REQUIRED_FLAGS "-pthread -std=c++0x" )
|
||||
else( UNIX )
|
||||
# vars probably need set for MSVC11, embarcadero, etc
|
||||
endif( UNIX )
|
||||
CHECK_CXX_SOURCE_RUNS( "${TEST_STD_THREAD}" HAVE_STD_THREAD ) #quotes are *required*!
|
||||
cmake_pop_check_state()
|
||||
|
||||
# Now that all the tests are done, configure the sc_cf.h file:
|
||||
get_property(CONFIG_H_FILE_CONTENTS GLOBAL PROPERTY SC_CONFIG_H_CONTENTS)
|
||||
file(WRITE ${CONFIG_H_FILE} "${CONFIG_H_FILE_CONTENTS}")
|
||||
configure_file(${CONFIG_H_FILE} ${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_cf.h)
|
||||
|
||||
################ create sc_version_string.h, http://stackoverflow.com/questions/3780667
|
||||
# Using 'ver_string' instead of 'sc_version_string.h' is a trick to force the
|
||||
# command to always execute when the custom target is built. It works because
|
||||
# a file by that name never exists.
|
||||
configure_file(${SC_CMAKE_DIR}/sc_version_string.cmake ${SC_BINARY_DIR}/sc_version_string.cmake @ONLY)
|
||||
add_custom_target(version_string ALL DEPENDS ver_string )
|
||||
# creates sc_version_string.h using cmake script
|
||||
add_custom_command(OUTPUT ver_string ${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
|
||||
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${SC_SOURCE_DIR}
|
||||
-DBINARY_DIR=${SC_BINARY_DIR}
|
||||
-P ${SC_BINARY_DIR}/sc_version_string.cmake)
|
||||
# sc_version_string.h is a generated file
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
|
||||
PROPERTIES GENERATED TRUE
|
||||
HEADER_FILE_ONLY TRUE )
|
||||
################
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D__MSVC__ -D__WIN32__)
|
||||
# add_definitions( -Wall )
|
||||
add_definitions( -D__MSVC__ -D__WIN32__ )
|
||||
# Disable warning for preferred usage of secure functions (example strcpy should be strcpy_s, ...)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
|
||||
add_definitions( -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS )
|
||||
elseif(BORLAND)
|
||||
add_definitions(-D__BORLAND__ -D__WIN32__)
|
||||
add_definitions( -D__BORLAND__ -D__WIN32__ )
|
||||
else()
|
||||
add_definitions(-pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long)
|
||||
add_definitions( -pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long )
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${SC_SOURCE_DIR}/include
|
||||
${SC_BINARY_DIR}/include
|
||||
)
|
||||
)
|
||||
|
||||
add_subdirectory(src/base)
|
||||
add_subdirectory(src/express)
|
||||
add_subdirectory(src/exppp)
|
||||
add_subdirectory(src/exp2cxx)
|
||||
add_subdirectory(src/exp2python)
|
||||
add_subdirectory(src/clstepcore)
|
||||
add_subdirectory(src/cleditor)
|
||||
add_subdirectory(src/cldai)
|
||||
add_subdirectory(src/clutils)
|
||||
if(NOT WIN32) # don't build cllazyfile on windows until export/import macros are in place
|
||||
add_subdirectory(src/cllazyfile)
|
||||
endif(NOT WIN32)
|
||||
add_subdirectory(include)
|
||||
add_subdirectory(data)
|
||||
if(SC_ENABLE_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif(SC_ENABLE_TESTING)
|
||||
add_subdirectory(doc)
|
||||
ADD_SUBDIRECTORY(src/base)
|
||||
ADD_SUBDIRECTORY(src/express)
|
||||
ADD_SUBDIRECTORY(src/exppp)
|
||||
ADD_SUBDIRECTORY(src/exp2cxx)
|
||||
ADD_SUBDIRECTORY(src/exp2python)
|
||||
ADD_SUBDIRECTORY(src/clstepcore)
|
||||
ADD_SUBDIRECTORY(src/cleditor)
|
||||
ADD_SUBDIRECTORY(src/cldai)
|
||||
ADD_SUBDIRECTORY(src/clutils)
|
||||
if( NOT WIN32 ) # don't build cllazyfile on windows until export/import macros are in place
|
||||
ADD_SUBDIRECTORY( src/cllazyfile )
|
||||
endif( NOT WIN32 )
|
||||
ADD_SUBDIRECTORY(include)
|
||||
ADD_SUBDIRECTORY(data)
|
||||
IF(SC_ENABLE_TESTING)
|
||||
ADD_SUBDIRECTORY( test )
|
||||
ENDIF(SC_ENABLE_TESTING)
|
||||
ADD_SUBDIRECTORY(doc)
|
||||
|
||||
# 'make core' builds everything that isn't generated. for devs.
|
||||
add_custom_target(core)
|
||||
add_dependencies(core stepdai check-express stepeditor exp2cxx)
|
||||
if( SCHEMAS_WARNING )
|
||||
message( "** CMake variable SC_BUILD_SCHEMAS was not set. Defaults to building ALL schemas, which will take a")
|
||||
message(" while; see http://stepcode.org/mw/index.php?title=STEPcode_CMake_variables#SC_BUILD_SCHEMAS" )
|
||||
endif( SCHEMAS_WARNING )
|
||||
message( ".. Don't worry about any messages above about missing headers or failed tests, as long as\n you see '-- Configuring done' below. Headers and features vary by compiler." )
|
||||
|
||||
# CONFIG_END_MESSAGES - list of messages to be printed after everything else is done.
|
||||
# THIS MUST BE LAST to ensure that they are visible to the user without scrolling.
|
||||
foreach(_msg ${CONFIG_END_MESSAGES})
|
||||
message("${_msg}")
|
||||
endforeach(_msg ${CONFIG_END_MESSAGES})
|
||||
# this is for testing - 'make core' builds everything that isn't generated
|
||||
add_custom_target( core )
|
||||
add_dependencies( core stepdai check-express stepeditor exp2cxx )
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
###############################################################################
|
||||
# SC Packaging #
|
||||
# $make package #
|
||||
###############################################################################
|
||||
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "STEPcode")
|
||||
SET(CPACK_SET_DESTDIR "ON")
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${SC_VERSION_MAJOR})
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR ${SC_VERSION_MINOR})
|
||||
SET(CPACK_PACKAGE_NAME SC )
|
||||
|
||||
SET(CPACK_PACKAGE_CONTACT "SC Developers <scl-dev@googlegroups.com>")
|
||||
INCLUDE(CPack)
|
||||
|
||||
########################################################################################
|
||||
# Uninstall code #
|
||||
# From http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F #
|
||||
# ######################################################################################
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
|
||||
@@ -8,11 +8,3 @@ set(CTEST_DROP_METHOD "http")
|
||||
set(CTEST_DROP_SITE "my.cdash.org")
|
||||
set(CTEST_DROP_LOCATION "/submit.php?project=StepClassLibrary")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
(from BRL-CAD)
|
||||
|
||||
* rewrite express parser to not require lex/yacc
|
||||
|
||||
* verify/fix step parser generation with newer AP schemas, seems to be
|
||||
outputting invalid syntax.
|
||||
+44
-51
@@ -24,68 +24,61 @@
|
||||
# (To distributed this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
macro(CHECK_C_FILE_RUNS SOURCE VAR)
|
||||
if("${VAR}" MATCHES "^${VAR}$")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
MACRO(CHECK_C_FILE_RUNS SOURCE VAR)
|
||||
IF("${VAR}" MATCHES "^${VAR}$")
|
||||
SET(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
else(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
if(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
else(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
|
||||
endif(CMAKE_REQUIRED_INCLUDES)
|
||||
IF(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
ELSE(CMAKE_REQUIRED_LIBRARIES)
|
||||
SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
|
||||
ENDIF(CMAKE_REQUIRED_LIBRARIES)
|
||||
IF(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
ELSE(CMAKE_REQUIRED_INCLUDES)
|
||||
SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
|
||||
ENDIF(CMAKE_REQUIRED_INCLUDES)
|
||||
|
||||
message(STATUS "Performing Test ${VAR}")
|
||||
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
|
||||
MESSAGE(STATUS "Performing Test ${VAR}")
|
||||
TRY_RUN(${VAR}_EXITCODE ${VAR}_COMPILED
|
||||
${CMAKE_BINARY_DIR}
|
||||
${SOURCE}
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${FILE_RUN_DEFINITIONS}
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${FILE_RUN_DEFINITIONS}
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
|
||||
"${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
|
||||
"${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
|
||||
COMPILE_OUTPUT_VARIABLE OUTPUT)
|
||||
# if it did not compile make the return value fail code of 1
|
||||
if(NOT ${VAR}_COMPILED)
|
||||
set(${VAR}_EXITCODE 1)
|
||||
endif(NOT ${VAR}_COMPILED)
|
||||
IF(NOT ${VAR}_COMPILED)
|
||||
SET(${VAR}_EXITCODE 1)
|
||||
ENDIF(NOT ${VAR}_COMPILED)
|
||||
# if the return value was 0 then it worked
|
||||
if("${${VAR}_EXITCODE}" EQUAL 0)
|
||||
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
|
||||
message(STATUS "Performing Test ${VAR} - Success")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Return value: ${${VAR}}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
else("${${VAR}_EXITCODE}" EQUAL 0)
|
||||
if(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
|
||||
set(${VAR} "${${VAR}_EXITCODE}")
|
||||
else(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
|
||||
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
|
||||
endif(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
|
||||
IF("${${VAR}_EXITCODE}" EQUAL 0)
|
||||
SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
|
||||
MESSAGE(STATUS "Performing Test ${VAR} - Success")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Return value: ${${VAR}}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
ELSE("${${VAR}_EXITCODE}" EQUAL 0)
|
||||
IF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
|
||||
SET(${VAR} "${${VAR}_EXITCODE}")
|
||||
ELSE(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
|
||||
SET(${VAR} "" CACHE INTERNAL "Test ${VAR}")
|
||||
ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
|
||||
|
||||
message(STATUS "Performing Test ${VAR} - Failed")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Return value: ${${VAR}_EXITCODE}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
MESSAGE(STATUS "Performing Test ${VAR} - Failed")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Return value: ${${VAR}_EXITCODE}\n"
|
||||
"Source file was:\n${SOURCE}\n")
|
||||
|
||||
endif("${${VAR}_EXITCODE}" EQUAL 0)
|
||||
endif("${VAR}" MATCHES "^${VAR}$")
|
||||
endmacro(CHECK_C_FILE_RUNS)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
ENDIF("${${VAR}_EXITCODE}" EQUAL 0)
|
||||
ENDIF("${VAR}" MATCHES "^${VAR}$")
|
||||
ENDMACRO(CHECK_C_FILE_RUNS)
|
||||
|
||||
|
||||
@@ -15,18 +15,18 @@
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2006 Tristan Carel
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * The names of the authors may not be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
|
||||
@@ -15,18 +15,18 @@
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2006 Tristan Carel
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * The names of the authors may not be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
|
||||
@@ -8,11 +8,3 @@ mark_as_advanced(RE2C_EXECUTABLE)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(RE2C DEFAULT_MSG RE2C_EXECUTABLE)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
|
||||
@@ -24,18 +24,18 @@
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2006 Tristan Carel
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * The names of the authors may not be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
@@ -106,9 +106,9 @@ macro(LEMON_TARGET Name LemonInput LemonSource LemonHeader)
|
||||
# rename generated outputs
|
||||
if(NOT "${LemonSource}" STREQUAL "${LEMON_GEN_SOURCE}")
|
||||
add_custom_command(
|
||||
OUTPUT ${LemonSource}
|
||||
OUTPUT ${LemonSource}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_SOURCE} ${LemonSource}
|
||||
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_SOURCE}
|
||||
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_SOURCE}
|
||||
)
|
||||
set(LEMON_${Name}_OUTPUTS ${LemonSource} ${LEMON_${Name}_OUTPUTS})
|
||||
endif(NOT "${LemonSource}" STREQUAL "${LEMON_GEN_SOURCE}")
|
||||
@@ -116,7 +116,7 @@ macro(LEMON_TARGET Name LemonInput LemonSource LemonHeader)
|
||||
add_custom_command(
|
||||
OUTPUT ${LemonHeader}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_HEADER} ${LemonHeader}
|
||||
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_HEADER}
|
||||
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_HEADER}
|
||||
)
|
||||
set(LEMON_${Name}_OUTPUTS ${LemonHeader} ${LEMON_${Name}_OUTPUTS})
|
||||
endif(NOT "${LemonHeader}" STREQUAL "${LEMON_GEN_HEADER}")
|
||||
@@ -125,7 +125,7 @@ macro(LEMON_TARGET Name LemonInput LemonSource LemonHeader)
|
||||
|
||||
# make sure we clean up generated output and copied input
|
||||
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS}")
|
||||
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS}")
|
||||
else("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS};${LEMON_BIN_INPUT}")
|
||||
endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Defines two macros - PERPLEX_TARGET, which takes perplex inputs and
|
||||
# runs both perplex and re2c to generate C source code/headers, and
|
||||
# runs both perplex and re2c to generate C source code/headers, and
|
||||
# ADD_PERPLEX_LEMON_DEPENDENCY which is used to set up dependencies between
|
||||
# scanner and parser targets when necessary.
|
||||
#
|
||||
@@ -21,7 +21,7 @@
|
||||
# ${PERPLEX_MyScanner_OUTPUTS}
|
||||
# )
|
||||
# ====================================================================
|
||||
#
|
||||
#
|
||||
#=============================================================================
|
||||
#
|
||||
# Originally based off of FindBISON.cmake from Kitware's CMake distribution
|
||||
@@ -31,18 +31,18 @@
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2006 Tristan Carel
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#
|
||||
# * The names of the authors may not be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
# testing and compilation options, build output dirs, install dirs, etc
|
||||
# included by root CMakeLists
|
||||
|
||||
if(NOT DEFINED INCLUDE_INSTALL_DIR)
|
||||
set(INCLUDE_INSTALL_DIR include)
|
||||
endif(NOT DEFINED INCLUDE_INSTALL_DIR)
|
||||
|
||||
if(NOT DEFINED LIB_INSTALL_DIR)
|
||||
set(LIB_INSTALL_DIR lib)
|
||||
endif(NOT DEFINED LIB_INSTALL_DIR)
|
||||
|
||||
if(NOT DEFINED BIN_INSTALL_DIR)
|
||||
set(BIN_INSTALL_DIR bin)
|
||||
endif(NOT DEFINED BIN_INSTALL_DIR)
|
||||
|
||||
if(NOT DEFINED SC_BUILD_TYPE)
|
||||
set(SC_BUILD_TYPE "Debug" CACHE STRING "Build type") # By default set debug build
|
||||
endif(NOT DEFINED SC_BUILD_TYPE)
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
set(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE} CACHE INTERNAL "Build type, immutable" FORCE)
|
||||
else(NOT SC_IS_SUBBUILD)
|
||||
set(CMAKE_BUILD_TYPE ${SC_BUILD_TYPE})
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
|
||||
# Define helper macro OPTION_WITH_DEFAULT
|
||||
macro(OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT)
|
||||
if(NOT DEFINED ${OPTION_NAME})
|
||||
set(${OPTION_NAME} ${OPTION_DEFAULT})
|
||||
endif(NOT DEFINED ${OPTION_NAME})
|
||||
option(${OPTION_NAME} "${OPTION_STRING}" ${${OPTION_NAME}})
|
||||
endmacro(OPTION_WITH_DEFAULT OPTION_NAME OPTION_STRING OPTION_DEFAULT)
|
||||
|
||||
# build shared libs by default
|
||||
OPTION_WITH_DEFAULT(SC_BUILD_SHARED_LIBS "Build shared libs" ON)
|
||||
|
||||
# don't build static libs by default
|
||||
OPTION_WITH_DEFAULT(SC_BUILD_STATIC_LIBS "Build static libs" OFF)
|
||||
|
||||
OPTION_WITH_DEFAULT(SC_PYTHON_GENERATOR "Compile exp2python" ON)
|
||||
OPTION_WITH_DEFAULT(SC_CPP_GENERATOR "Compile exp2cxx" ON)
|
||||
|
||||
OPTION_WITH_DEFAULT(SC_MEMMGR_ENABLE_CHECKS "Enable sc_memmgr's memory leak detection" OFF)
|
||||
OPTION_WITH_DEFAULT(SC_TRACE_FPRINTF "Enable extra comments in generated code so the code's source in exp2cxx may be located" OFF)
|
||||
|
||||
option(SC_BUILD_EXPRESS_ONLY "Only build express parser." OFF)
|
||||
mark_as_advanced(SC_BUILD_EXPRESS_ONLY)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Coverage option
|
||||
OPTION_WITH_DEFAULT(SC_ENABLE_COVERAGE "Enable code coverage test" OFF)
|
||||
if(SC_ENABLE_COVERAGE)
|
||||
set(SC_ENABLE_TESTING ON CACHE BOOL "Testing enabled by coverage option" FORCE)
|
||||
# build static libs, better coverage report
|
||||
set(SC_BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libs" FORCE)
|
||||
set(SC_BUILD_STATIC_LIBS ON CACHE BOOL "Build static libs" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-fprofile-arcs -ftest-coverage" CACHE STRING "Extra linker flags required by code coverage" FORCE)
|
||||
set(SC_BUILD_TYPE "Debug" CACHE STRING "Build type required by testing framework" FORCE)
|
||||
set(SC_PYTHON_GENERATOR OFF) #won't build with static libs
|
||||
endif(SC_ENABLE_COVERAGE)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Testing option
|
||||
OPTION_WITH_DEFAULT(SC_ENABLE_TESTING "Enable unittesting framework" OFF)
|
||||
if(SC_ENABLE_TESTING)
|
||||
if(NOT DEFINED SC_BUILD_SCHEMAS)
|
||||
set(SC_BUILD_SCHEMAS "ALL") #test all schemas, unless otherwise specified
|
||||
endif()
|
||||
include(CTest)
|
||||
ENABLE_TESTING()
|
||||
endif(SC_ENABLE_TESTING)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# The following logic is what allows binaries to run successfully in
|
||||
# the build directory AND install directory. Thanks to plplot for
|
||||
# identifying the necessity of setting CMAKE_INSTALL_NAME_DIR on OSX.
|
||||
# Documentation of these options is available at
|
||||
# http://www.cmake.org/Wiki/CMake_RPATH_handling
|
||||
|
||||
# use, i.e. don't skip the full RPATH for the build tree
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
|
||||
# when building, don't use the install RPATH already
|
||||
# (but later on when installing)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
|
||||
# the RPATH/INSTALL_NAME_DIR to be used when installing
|
||||
if (NOT APPLE)
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:\$ORIGIN/../lib")
|
||||
endif(NOT APPLE)
|
||||
# On OSX, we need to set INSTALL_NAME_DIR instead of RPATH
|
||||
# http://www.cmake.org/cmake/help/cmake-2-8-docs.html#variable:CMAKE_INSTALL_NAME_DIR
|
||||
set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
|
||||
# add the automatically determined parts of the RPATH which point to
|
||||
# directories outside the build tree to the install RPATH
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
# When this is a subbuild, assume that the parent project controls all of the following
|
||||
#======================================================================================
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
|
||||
# Output directories. In a separate file so it can be used by the schema scanner CMake as well.
|
||||
include(${SC_CMAKE_DIR}/SC_Outdirs.cmake)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure install locations. Only do this if CMAKE_INSTALL_PREFIX hasn't
|
||||
# been set already, to try and allow parent builds (if any) some control.
|
||||
#
|
||||
# Need a good Debug location for Windows.
|
||||
if(NOT WIN32)
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||
set(SC_INSTALL_PREFIX "${SC_SOURCE_DIR}/../sc-install")
|
||||
else()
|
||||
set(SC_INSTALL_PREFIX "/usr/local")
|
||||
endif()
|
||||
endif(NOT WIN32)
|
||||
set(SC_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE
|
||||
PATH "Install prefix prepended to target to create install location")
|
||||
set(CMAKE_INSTALL_PREFIX ${SC_INSTALL_PREFIX} CACHE INTERNAL "Prefix prepended to install directories if target destination is not absolute, immutable" FORCE)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# SC Packaging
|
||||
# $make package
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "STEPcode")
|
||||
set(CPACK_SET_DESTDIR "ON")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${SC_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${SC_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_NAME SC)
|
||||
set(CPACK_PACKAGE_CONTACT "SC Developers <scl-dev@googlegroups.com>")
|
||||
include(CPack)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Uninstall target
|
||||
# From http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
# macros to be used in the CMakeLists generated by the schema scanner
|
||||
|
||||
# uses SC_GENERATE_CXX_ONESHOT - if true, files will only be generated once. this is useful when debugging and modifying code, not otherwise. TODO: print a warning when set
|
||||
if(NOT DEFINED SC_GENERATE_CXX_ONESHOT)
|
||||
set(SC_GENERATE_CXX_ONESHOT FALSE)
|
||||
endif(NOT DEFINED SC_GENERATE_CXX_ONESHOT)
|
||||
|
||||
# find all part 21 files in schema dir, add a test for each one
|
||||
macro(P21_TESTS sfile)
|
||||
get_filename_component(SCHEMA_DIR ${sfile} PATH)
|
||||
file(GLOB_RECURSE P21_FILES ${SCHEMA_DIR}/*.stp ${SCHEMA_DIR}/*.step ${SCHEMA_DIR}/*.p21 ${SCHEMA_DIR}/*.ifc)
|
||||
foreach(TEST_FILE ${P21_FILES})
|
||||
get_filename_component(FNAME ${TEST_FILE} NAME_WE)
|
||||
add_test(NAME read_write_cpp_${PROJECT_NAME}_${FNAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND p21read_${PROJECT_NAME} ${TEST_FILE})
|
||||
set_tests_properties(read_write_cpp_${PROJECT_NAME}_${FNAME} PROPERTIES DEPENDS build_cpp_${PROJECT_NAME} LABELS cpp_schema_rw)
|
||||
if(NOT WIN32)
|
||||
add_test(NAME read_lazy_cpp_${PROJECT_NAME}_${FNAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND lazy_${PROJECT_NAME} ${TEST_FILE})
|
||||
set_tests_properties(read_lazy_cpp_${PROJECT_NAME}_${FNAME} PROPERTIES DEPENDS build_lazy_cpp_${PROJECT_NAME} LABELS cpp_schema_rw)
|
||||
endif(NOT WIN32)
|
||||
endforeach()
|
||||
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)
|
||||
SC_ADDEXEC(p21read_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc" "${PROJECT_NAME};stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
|
||||
#add_dependencies(p21read_${PROJECT_NAME} version_string)
|
||||
if(HAVE_STD_THREAD)
|
||||
set_target_properties(p21read_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
|
||||
endif(HAVE_STD_THREAD)
|
||||
if(NOT WIN32)
|
||||
SC_ADDEXEC(lazy_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc" "${PROJECT_NAME};steplazyfile;stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
|
||||
#add_dependencies(lazy_${PROJECT_NAME} version_string)
|
||||
if(HAVE_STD_THREAD)
|
||||
set_target_properties(lazy_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
|
||||
endif(HAVE_STD_THREAD)
|
||||
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)
|
||||
SC_ADDEXEC(${name}_${PROJECT_NAME} "${src}" "${PROJECT_NAME};stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
|
||||
add_dependencies(${name}_${PROJECT_NAME} version_string)
|
||||
#set_target_properties(${name}_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${${PROJECT_NAME}_COMPILE_FLAGS} -I${path}")
|
||||
endforeach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
|
||||
ENDMACRO(SCHEMA_EXES)
|
||||
|
||||
|
||||
# label the tests and set dependencies
|
||||
macro(SCHEMA_TESTS)
|
||||
add_test(NAME generate_cpp_${PROJECT_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
--target generate_cpp_${PROJECT_NAME}
|
||||
--config $<CONFIGURATION>)
|
||||
set_tests_properties(generate_cpp_${PROJECT_NAME} PROPERTIES LABELS cpp_schema_gen)
|
||||
add_test(NAME build_cpp_${PROJECT_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
--target p21read_${PROJECT_NAME}
|
||||
--config $<CONFIGURATION>)
|
||||
set_tests_properties(build_cpp_${PROJECT_NAME} PROPERTIES DEPENDS generate_cpp_${PROJECT_NAME} LABELS cpp_schema_build)
|
||||
if(NOT WIN32)
|
||||
add_test(NAME build_lazy_cpp_${PROJECT_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
--target lazy_${PROJECT_NAME}
|
||||
--config $<CONFIGURATION>)
|
||||
set_tests_properties(build_lazy_cpp_${PROJECT_NAME} PROPERTIES DEPENDS generate_cpp_${PROJECT_NAME} LABELS cpp_schema_build)
|
||||
endif(NOT WIN32)
|
||||
endmacro(SCHEMA_TESTS)
|
||||
|
||||
# SCHEMA_TARGETS macro -
|
||||
# expFile: path to express file
|
||||
# schemaName: name of the schema
|
||||
# sourceFiles: list of .cc and .h files
|
||||
#
|
||||
# create targets for the schema(s) in expFile
|
||||
# targets include gen_cxx_*, sdai_cxx_*, p21read_*, lazyp21_*, ...
|
||||
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}.")
|
||||
|
||||
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 ${sourceFiles}
|
||||
COMMAND ${CMAKE_COMMAND} -DEXE=\"$<TARGET_FILE:exp2cxx>\" -DEXP=\"${expFile}\"
|
||||
-DONESHOT=\"${SC_GENERATE_CXX_ONESHOT}\" -DSDIR=\"${CMAKE_CURRENT_LIST_DIR}\"
|
||||
-P ${SC_CMAKE_DIR}/SC_Run_exp2cxx.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
COMMENT "[exp2cxx] Generating ${${PROJECT_NAME}_file_count} C++ files for ${PROJECT_NAME}."
|
||||
)
|
||||
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/base
|
||||
${SC_SOURCE_DIR}/src/base/judy/src
|
||||
)
|
||||
# if testing is enabled, "TESTABLE" sets property EXCLUDE_FROM_ALL and prevents installation
|
||||
SC_ADDLIB(${PROJECT_NAME} "${sourceFiles}" "stepdai;stepcore;stepeditor;steputils;base" "TESTABLE")
|
||||
add_dependencies(${PROJECT_NAME} generate_cpp_${PROJECT_NAME})
|
||||
|
||||
if(HAVE_STD_THREAD)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
|
||||
endif(HAVE_STD_THREAD)
|
||||
|
||||
SCHEMA_EXES()
|
||||
SCHEMA_TESTS()
|
||||
P21_TESTS(${expFile})
|
||||
# TODO add test to verify that schema scanner output matches fedex_plus output
|
||||
|
||||
endmacro(SCHEMA_TARGETS expFile schemaName sourceFiles)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
# create sc_cf.h and sc_version_string.h
|
||||
|
||||
# Take the sc config file template as the starting point for
|
||||
# sc_cf.h.in - scripts may need to append to the template, so
|
||||
# it is read into memory initially.
|
||||
set(CONFIG_H_FILE ${SC_BINARY_DIR}/include/sc_cf.h.in)
|
||||
set_source_files_properties(${CONFIG_H_FILE} PROPERTIES GENERATED TRUE)
|
||||
set(CMAKE_CURRENT_PROJECT SC)
|
||||
define_property(GLOBAL PROPERTY SC_CONFIG_H_CONTENTS BRIEF_DOCS "config.h.in contents" FULL_DOCS "config.h.in contents for SC project")
|
||||
if(NOT COMMAND CONFIG_H_APPEND)
|
||||
macro(CONFIG_H_APPEND PROJECT_NAME NEW_CONTENTS)
|
||||
if(PROJECT_NAME)
|
||||
get_property(${PROJECT_NAME}_CONFIG_H_CONTENTS GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS)
|
||||
set(${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS "${${PROJECT_NAME}_CONFIG_H_CONTENTS}${NEW_CONTENTS}")
|
||||
set_property(GLOBAL PROPERTY ${PROJECT_NAME}_CONFIG_H_CONTENTS "${${PROJECT_NAME}_CONFIG_H_FILE_CONTENTS}")
|
||||
endif(PROJECT_NAME)
|
||||
endmacro(CONFIG_H_APPEND NEW_CONTENTS)
|
||||
endif(NOT COMMAND CONFIG_H_APPEND)
|
||||
file(READ ${SC_SOURCE_DIR}/include/sc_cf_cmake.h.in CONFIG_H_FILE_CONTENTS)
|
||||
CONFIG_H_APPEND(SC "${CONFIG_H_FILE_CONTENTS}")
|
||||
|
||||
include(CheckLibraryExists)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckTypeSize)
|
||||
include(CMakePushCheckState)
|
||||
include(CheckCXXSourceRuns)
|
||||
|
||||
CHECK_INCLUDE_FILE(ndir.h HAVE_NDIR_H)
|
||||
CHECK_INCLUDE_FILE(stdarg.h HAVE_STDARG_H)
|
||||
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
|
||||
CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H)
|
||||
CHECK_INCLUDE_FILE(sysent.h HAVE_SYSENT_H)
|
||||
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
|
||||
CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H)
|
||||
CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)
|
||||
CHECK_INCLUDE_FILE(process.h HAVE_PROCESS_H)
|
||||
CHECK_INCLUDE_FILE(io.h HAVE_IO_H)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(abs HAVE_ABS)
|
||||
CHECK_FUNCTION_EXISTS(memcpy HAVE_MEMCPY)
|
||||
CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE)
|
||||
CHECK_FUNCTION_EXISTS(getopt HAVE_GETOPT)
|
||||
|
||||
CHECK_TYPE_SIZE("ssize_t" SSIZE_T)
|
||||
|
||||
set( TEST_STD_THREAD "
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
void do_work() {
|
||||
std::cout << \"thread\" << std::endl;
|
||||
}
|
||||
int main() {
|
||||
std::thread t(do_work);
|
||||
t.join();
|
||||
}
|
||||
" )
|
||||
cmake_push_check_state()
|
||||
if( UNIX )
|
||||
set( CMAKE_REQUIRED_FLAGS "-pthread -std=c++0x" )
|
||||
else( UNIX )
|
||||
# vars probably need set for MSVC11, embarcadero, etc
|
||||
endif( UNIX )
|
||||
CHECK_CXX_SOURCE_RUNS( "${TEST_STD_THREAD}" HAVE_STD_THREAD ) #quotes are *required*!
|
||||
cmake_pop_check_state()
|
||||
|
||||
# Now that all the tests are done, configure the sc_cf.h file:
|
||||
get_property(CONFIG_H_FILE_CONTENTS GLOBAL PROPERTY SC_CONFIG_H_CONTENTS)
|
||||
file(WRITE ${CONFIG_H_FILE} "${CONFIG_H_FILE_CONTENTS}")
|
||||
configure_file(${CONFIG_H_FILE} ${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_cf.h)
|
||||
|
||||
# ------------------------
|
||||
|
||||
# create sc_version_string.h, http://stackoverflow.com/questions/3780667
|
||||
# Using 'ver_string' instead of 'sc_version_string.h' is a trick to force the
|
||||
# command to always execute when the custom target is built. It works because
|
||||
# a file by that name never exists.
|
||||
configure_file(${SC_CMAKE_DIR}/sc_version_string.cmake ${SC_BINARY_DIR}/sc_version_string.cmake @ONLY)
|
||||
add_custom_target(version_string ALL DEPENDS ver_string )
|
||||
# creates sc_version_string.h using cmake script
|
||||
add_custom_command(OUTPUT ver_string ${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
|
||||
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${SC_SOURCE_DIR}
|
||||
-DBINARY_DIR=${SC_BINARY_DIR}
|
||||
-P ${SC_BINARY_DIR}/sc_version_string.cmake)
|
||||
# sc_version_string.h is a generated file
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
|
||||
PROPERTIES GENERATED TRUE
|
||||
HEADER_FILE_ONLY TRUE )
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Save the current LC_ALL, LC_MESSAGES, and LANG environment variables and set them
|
||||
# to "C" so things like date output are as expected
|
||||
set(_orig_lc_all $ENV{LC_ALL})
|
||||
set(_orig_lc_messages $ENV{LC_MESSAGES})
|
||||
set(_orig_lang $ENV{LANG})
|
||||
if(_orig_lc_all)
|
||||
set(ENV{LC_ALL} C)
|
||||
endif(_orig_lc_all)
|
||||
if(_orig_lc_messages)
|
||||
set(ENV{LC_MESSAGES} C)
|
||||
endif(_orig_lc_messages)
|
||||
if(_orig_lang)
|
||||
set(ENV{LANG} C)
|
||||
endif(_orig_lang)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# in its own file so that it can be used by the schema scanner as well
|
||||
if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
|
||||
endif(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
|
||||
endif(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
|
||||
if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
|
||||
endif(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${CFG_TYPE}" CFG_TYPE)
|
||||
if(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
set("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all libraries.")
|
||||
endif(NOT "CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
if(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
set("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/lib CACHE INTERNAL "Single output directory for building all archives.")
|
||||
endif(NOT "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
if(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
set("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}" ${SC_BINARY_DIR}/bin CACHE INTERNAL "Single output directory for building all executables.")
|
||||
endif(NOT "CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE}")
|
||||
endforeach()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
macro(REVERSE_PATH in_path out_path drive_path)
|
||||
set(reversed_path)
|
||||
set(tmp_subpath "${in_path}")
|
||||
while(NOT "${tmp_subpath}" STREQUAL "" AND NOT "${tmp_subpath}" STREQUAL "/")
|
||||
get_filename_component(piece "${tmp_subpath}" NAME)
|
||||
get_filename_component(tmp_subpath "${tmp_subpath}" PATH)
|
||||
if(piece)
|
||||
set(reversed_path "${reversed_path}/${piece}")
|
||||
else(piece)
|
||||
set(${drive_path} ${tmp_subpath})
|
||||
set(tmp_subpath)
|
||||
endif(piece)
|
||||
endwhile(NOT "${tmp_subpath}" STREQUAL "" AND NOT "${tmp_subpath}" STREQUAL "/")
|
||||
set("${out_path}" "${reversed_path}")
|
||||
endmacro(REVERSE_PATH)
|
||||
|
||||
macro(GET_COMMON_ROOT_PATH dir1 dir2 common_subpath)
|
||||
get_filename_component(testpath "${dir1}" REALPATH)
|
||||
set(dir1_rev)
|
||||
set(dir2_rev)
|
||||
REVERSE_PATH("${dir1}" dir1_rev drive_name_1)
|
||||
REVERSE_PATH("${dir2}" dir2_rev drive_name_2)
|
||||
if("${drive_name_1}" STREQUAL "${drive_name_2}")
|
||||
set(component_same 1)
|
||||
set(${common_subpath})
|
||||
while(component_same)
|
||||
get_filename_component(piece1 "${dir1_rev}" NAME)
|
||||
get_filename_component(dir1_rev "${dir1_rev}" PATH)
|
||||
get_filename_component(piece2 "${dir2_rev}" NAME)
|
||||
get_filename_component(dir2_rev "${dir2_rev}" PATH)
|
||||
if("${piece1}" STREQUAL "${piece2}")
|
||||
set(${common_subpath} "${${common_subpath}}/${piece1}")
|
||||
else("${piece1}" STREQUAL "${piece2}")
|
||||
set(component_same 0)
|
||||
endif("${piece1}" STREQUAL "${piece2}")
|
||||
endwhile(component_same)
|
||||
if(drive_name_1)
|
||||
set(${common_subpath} "${drive_name_1}${${common_subpath}}")
|
||||
string(REPLACE "//" "/" ${common_subpath} "${${common_subpath}}")
|
||||
endif(drive_name_1)
|
||||
endif("${drive_name_1}" STREQUAL "${drive_name_2}")
|
||||
endmacro(GET_COMMON_ROOT_PATH)
|
||||
|
||||
|
||||
macro(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
|
||||
set(common_root_path)
|
||||
GET_COMMON_ROOT_PATH("${SC_SOURCE_DIR}" "${current_dir}" common_root_path)
|
||||
string(REPLACE "${common_root_path}" "" subpath "${current_dir}")
|
||||
string(REPLACE "${common_root_path}" "" needed_src_path "${SC_SOURCE_DIR}")
|
||||
string(REGEX REPLACE "^/" "" subpath "${subpath}")
|
||||
string(REGEX REPLACE "^/" "" needed_src_path "${needed_src_path}")
|
||||
string(LENGTH "${subpath}" PATH_LENGTH)
|
||||
if(PATH_LENGTH GREATER 0)
|
||||
set(${rel_path} "..")
|
||||
get_filename_component(subpath "${subpath}" PATH)
|
||||
string(LENGTH "${subpath}" PATH_LENGTH)
|
||||
while(PATH_LENGTH GREATER 0)
|
||||
set(${rel_path} "${${rel_path}}/..")
|
||||
get_filename_component(subpath "${subpath}" PATH)
|
||||
string(LENGTH "${subpath}" PATH_LENGTH)
|
||||
endwhile(PATH_LENGTH GREATER 0)
|
||||
endif(PATH_LENGTH GREATER 0)
|
||||
set(${rel_path} "${${rel_path}}/${needed_src_path}")
|
||||
string(REPLACE "//" "/" ${rel_path} "${${rel_path}}")
|
||||
endmacro(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
|
||||
|
||||
macro(LOCATE_SCHEMA SCHEMA_FILE _res_var)
|
||||
if(EXISTS "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}") #is it a path relative to build dir?
|
||||
set(${_res_var} "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}")
|
||||
elseif(EXISTS "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}") # path relative to STEPcode/data?
|
||||
set(${_res_var} "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}")
|
||||
elseif(EXISTS ${SCHEMA_FILE}) # already an absolute path
|
||||
set(${_res_var} ${SCHEMA_FILE})
|
||||
else()
|
||||
message(FATAL_ERROR "Cannot find ${CMAKE_BINARY_DIR}/${SCHEMA_FILE} or ${SC_SOURCE_DIR}/data/${SCHEMA_FILE}/*.exp or ${SCHEMA_FILE}")
|
||||
endif()
|
||||
|
||||
if(IS_DIRECTORY ${${_res_var}}) #if it is a dir, look for one .exp file inside
|
||||
file(GLOB ${_res_var} ${${_res_var}}/*.exp)
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${${_res_var}})
|
||||
message(FATAL_ERROR "Expected one express file. Found '${${_res_var}}' instead.")
|
||||
endif()
|
||||
endmacro(LOCATE_SCHEMA SCHEMA_FILE _res_var)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
# The Express parser uses the tools Perplex, RE2C and Lemon to generate code
|
||||
# from higher level inputs. Depending on available tools and options, the
|
||||
# SC build can either re-generate code as part of the build, or use cached
|
||||
# files that are ready for compilation.
|
||||
#
|
||||
# SC_GENERATE_LEXER_PARSER is the "high level" control a user sets to determine
|
||||
# how the SC build will interact (or not) with these tools. AUTO (the
|
||||
# default) means it will search for the necessary tools, and use them only if
|
||||
# everything is found. If not, it will fall back to the cached versions. If
|
||||
# this option is set to ON and the necessary tools are not found, the
|
||||
# configure step will fail. If it is set to OFF, SC will not even try to use
|
||||
# the generators and will instead use the cached sources.
|
||||
if(NOT DEFINED SC_GENERATE_LEXER_PARSER)
|
||||
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
|
||||
set(_verbosity "QUIET")
|
||||
else(NOT DEFINED SC_GENERATE_LEXER_PARSER)
|
||||
string(TOUPPER "${SC_GENERATE_LEXER_PARSER}" SC_GENERATE_LEXER_PARSER)
|
||||
endif(NOT DEFINED SC_GENERATE_LEXER_PARSER)
|
||||
set_property(CACHE SC_GENERATE_LEXER_PARSER PROPERTY STRINGS AUTO ON OFF)
|
||||
if (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
message(WARNING "Unknown value ${SC_GENERATE_LEXER_PARSER} supplied for SC_GENERATE_LEXER_PARSER - defaulting to AUTO")
|
||||
message(WARNING "Valid options are AUTO, ON and OFF")
|
||||
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
|
||||
endif (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
|
||||
# If the generators have not been turned off, we need to check for them
|
||||
if(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
find_package(LEMON ${_verbosity})
|
||||
find_package(RE2C ${_verbosity})
|
||||
find_package(PERPLEX ${_verbosity})
|
||||
if(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
|
||||
# Templates may be anywhere - make sure we have a stable path if a relative
|
||||
# path was specified at CMake time
|
||||
get_filename_component(lemon_template_fpath "${LEMON_TEMPLATE}" ABSOLUTE)
|
||||
if(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
|
||||
get_filename_component(LEMON_TEMPLATE "${CMAKE_BINARY_DIR}/${LEMON_TEMPLATE}" ABSOLUTE)
|
||||
endif(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
|
||||
get_filename_component(perplex_template_fpath "${PERPLEX_TEMPLATE}" ABSOLUTE)
|
||||
if(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
|
||||
get_filename_component(PERPLEX_TEMPLATE "${CMAKE_BINARY_DIR}/${PERPLEX_TEMPLATE}" ABSOLUTE)
|
||||
endif(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
|
||||
|
||||
if(NOT COMMAND LEMON_TARGET)
|
||||
include(${SC_CMAKE_DIR}/LEMON_Util.cmake)
|
||||
endif(NOT COMMAND LEMON_TARGET)
|
||||
if(NOT COMMAND PERPLEX_TARGET)
|
||||
include(${SC_CMAKE_DIR}/PERPLEX_Util.cmake)
|
||||
endif(NOT COMMAND PERPLEX_TARGET)
|
||||
set(SC_GENERATE_LP_SOURCES 1)
|
||||
message(".. Found perplex, re2c, and lemon - can regenerate lexer/parser if necessary")
|
||||
else(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
|
||||
if("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
|
||||
message(FATAL_ERROR "\nSC_GENERATE_LEXER_PARSER set to ON, but one or more components of the Perplex/RE2C/Lemon toolchain were not found.\n")
|
||||
else("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
|
||||
set(SC_GENERATE_LP_SOURCES 0)
|
||||
endif("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
|
||||
endif(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
|
||||
else(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
set(SC_GENERATE_LP_SOURCES 0)
|
||||
endif(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
# if oneshot is true, don't run exp2cxx if source files exist. if schema.cc exists, assume others do
|
||||
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()
|
||||
execute_process(COMMAND ${EXE} ${EXP}
|
||||
WORKING_DIRECTORY ${SDIR}
|
||||
RESULT_VARIABLE _res
|
||||
OUTPUT_FILE exp2cxx_stdout.txt
|
||||
ERROR_FILE exp2cxx_stderr.txt
|
||||
)
|
||||
if(NOT "${_res}" STREQUAL "0")
|
||||
message(FATAL_ERROR "${EXE} reported an error for ${EXP}.\nsee exp2cxx_stdout.txt and exp2cxx_stderr.txt in ${SDIR} for details.")
|
||||
endif(NOT "${_res}" STREQUAL "0")
|
||||
# TODO count number of lines in stdout/stderr and tell user?
|
||||
endif()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
|
||||
# set compile definitions for dll exports on windows
|
||||
macro(DEFINE_DLL_EXPORTS libname)
|
||||
if(MSVC OR BORLAND)
|
||||
if(${libname} MATCHES "sdai_.*")
|
||||
set(export "SC_SCHEMA_DLL_EXPORTS")
|
||||
else()
|
||||
string(REGEX REPLACE "lib" "" shortname "${libname}")
|
||||
string(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
|
||||
string(TOUPPER ${LOWERCORE} UPPER_CORE)
|
||||
set(export "SC_${UPPER_CORE}_DLL_EXPORTS")
|
||||
endif()
|
||||
get_target_property(defs ${libname} COMPILE_DEFINITIONS)
|
||||
if(defs) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
|
||||
set(defs "${defs};${export}")
|
||||
else(defs)
|
||||
set(defs "${export}")
|
||||
endif(defs)
|
||||
set_target_properties(${libname} PROPERTIES COMPILE_DEFINITIONS "${defs}")
|
||||
endif(MSVC OR BORLAND)
|
||||
endmacro(DEFINE_DLL_EXPORTS libname)
|
||||
|
||||
# set compile definitions for dll imports on windows
|
||||
macro(DEFINE_DLL_IMPORTS tgt libs)
|
||||
if(MSVC OR BORLAND)
|
||||
get_target_property(defs ${tgt} COMPILE_DEFINITIONS)
|
||||
if(NOT defs) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
|
||||
set(defs "")
|
||||
endif(NOT defs)
|
||||
foreach(lib ${libs})
|
||||
string(REGEX REPLACE "lib" "" shortname "${lib}")
|
||||
string(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
|
||||
string(TOUPPER ${LOWERCORE} UPPER_CORE)
|
||||
list(APPEND defs "SC_${UPPER_CORE}_DLL_IMPORTS")
|
||||
endforeach(lib ${libs})
|
||||
if(DEFINED defs)
|
||||
if(defs)
|
||||
set_target_properties(${tgt} PROPERTIES COMPILE_DEFINITIONS "${defs}")
|
||||
endif(defs)
|
||||
endif(DEFINED defs)
|
||||
endif(MSVC OR BORLAND)
|
||||
endmacro(DEFINE_DLL_IMPORTS tgt libs)
|
||||
|
||||
#EXCLUDE_OR_INSTALL(target destination ARGV3)
|
||||
# installs ${target} in ${destination} unless testing is enabled AND ${arg_3} == "TESTABLE",
|
||||
# in which case the EXCLUDE_FROM_ALL property is set for testing.
|
||||
# EXCLUDE_FROM_ALL cannot be set on targets that are to be installed,
|
||||
# so either test the target or install it - but not both
|
||||
macro(EXCLUDE_OR_INSTALL target dest arg_3)
|
||||
if(NOT ((SC_ENABLE_TESTING) AND ("${arg_3}" STREQUAL "TESTABLE")))
|
||||
INSTALL(TARGETS ${target} DESTINATION ${dest})
|
||||
else(NOT ((SC_ENABLE_TESTING) AND ("${arg_3}" STREQUAL "TESTABLE")))
|
||||
set_target_properties(${target} PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
endif(NOT ((SC_ENABLE_TESTING) AND ("${arg_3}" STREQUAL "TESTABLE")))
|
||||
endmacro(EXCLUDE_OR_INSTALL target dest arg_3)
|
||||
|
||||
#SC_ADDEXEC(execname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
|
||||
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
|
||||
# optional args can also be used by MSVC-specific code, but it looks like these two uses
|
||||
# will not conflict because the MSVC args must contain "STRICT"
|
||||
macro(SC_ADDEXEC execname srcslist libslist)
|
||||
if(SC_BUILD_SHARED_LIBS)
|
||||
add_executable(${execname} ${srcslist})
|
||||
target_link_libraries(${execname} ${libslist})
|
||||
DEFINE_DLL_IMPORTS(${execname} "${libslist}") #add import definitions for all libs that the executable is linked to
|
||||
EXCLUDE_OR_INSTALL(${execname} "bin" "${ARGV3}")
|
||||
# Enable extra compiler flags if local executables and/or global options dictate
|
||||
set(LOCAL_COMPILE_FLAGS "")
|
||||
foreach(extraarg ${ARGN})
|
||||
if(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
set(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
|
||||
endif(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
endforeach(extraarg ${ARGN})
|
||||
if(LOCAL_COMPILE_FLAGS)
|
||||
set_target_properties(${execname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
|
||||
endif(LOCAL_COMPILE_FLAGS)
|
||||
endif(SC_BUILD_SHARED_LIBS)
|
||||
if(SC_BUILD_STATIC_LIBS)
|
||||
if(NOT SC_BUILD_SHARED_LIBS)
|
||||
set(staticexecname "${execname}")
|
||||
else()
|
||||
set(staticexecname "${execname}-static")
|
||||
endif(NOT SC_BUILD_SHARED_LIBS)
|
||||
add_executable(${staticexecname} ${srcslist})
|
||||
target_link_libraries(${staticexecname} ${libslist})
|
||||
EXCLUDE_OR_INSTALL(${staticexecname} "bin" "${ARGV3}")
|
||||
# Enable extra compiler flags if local executables and/or global options dictate
|
||||
set(LOCAL_COMPILE_FLAGS "")
|
||||
foreach(extraarg ${ARGN})
|
||||
if(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
set(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
|
||||
endif(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
endforeach(extraarg ${ARGN})
|
||||
if(LOCAL_COMPILE_FLAGS)
|
||||
set_target_properties(${staticexecname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
|
||||
endif(LOCAL_COMPILE_FLAGS)
|
||||
endif(SC_BUILD_STATIC_LIBS)
|
||||
endmacro(SC_ADDEXEC execname srcslist libslist)
|
||||
|
||||
#SC_ADDLIB(libname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
|
||||
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
|
||||
# optional args can also be used by MSVC-specific code, but it looks like these two uses
|
||||
# will not conflict because the MSVC args must contain "STRICT"
|
||||
macro(SC_ADDLIB libname srcslist libslist)
|
||||
string(REGEX REPLACE "-framework;" "-framework " libslist "${libslist1}")
|
||||
if(SC_BUILD_SHARED_LIBS)
|
||||
add_library(${libname} SHARED ${srcslist})
|
||||
DEFINE_DLL_EXPORTS(${libname})
|
||||
if(NOT "${libs}" MATCHES "NONE")
|
||||
target_link_libraries(${libname} ${libslist})
|
||||
DEFINE_DLL_IMPORTS(${libname} "${libslist}")
|
||||
endif(NOT "${libs}" MATCHES "NONE")
|
||||
set_target_properties(${libname} PROPERTIES VERSION ${SC_ABI_VERSION} SOVERSION ${SC_ABI_SOVERSION})
|
||||
EXCLUDE_OR_INSTALL(${libname} "lib" "${ARGV3}")
|
||||
if(APPLE)
|
||||
set_target_properties(${libname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
|
||||
endif(APPLE)
|
||||
endif(SC_BUILD_SHARED_LIBS)
|
||||
if(SC_BUILD_STATIC_LIBS)
|
||||
if(NOT SC_BUILD_SHARED_LIBS)
|
||||
set(staticlibname "${libname}")
|
||||
else()
|
||||
set(staticlibname "${libname}-static")
|
||||
endif(NOT SC_BUILD_SHARED_LIBS)
|
||||
add_library(${staticlibname} STATIC ${srcslist})
|
||||
DEFINE_DLL_EXPORTS(${staticlibname})
|
||||
if(NOT ${libs} MATCHES "NONE")
|
||||
target_link_libraries(${staticlibname} "${libslist}")
|
||||
DEFINE_DLL_IMPORTS(${staticlibname} ${libslist})
|
||||
endif(NOT ${libs} MATCHES "NONE")
|
||||
if(NOT WIN32)
|
||||
set_target_properties(${staticlibname} PROPERTIES OUTPUT_NAME "${libname}")
|
||||
endif(NOT WIN32)
|
||||
if(WIN32)
|
||||
# We need the lib prefix on win32, so add it even if our add_library
|
||||
# wrapper function has removed it due to the target name - see
|
||||
# http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_make_my_shared_and_static_libraries_have_the_same_root_name.2C_but_different_suffixes.3F
|
||||
set_target_properties(${staticlibname} PROPERTIES PREFIX "lib")
|
||||
endif(WIN32)
|
||||
EXCLUDE_OR_INSTALL(${staticlibname} "lib" "${ARGV3}")
|
||||
if(APPLE)
|
||||
set_target_properties(${staticlibname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
|
||||
endif(APPLE)
|
||||
endif(SC_BUILD_STATIC_LIBS)
|
||||
# Enable extra compiler flags if local libraries and/or global options dictate
|
||||
set(LOCAL_COMPILE_FLAGS "")
|
||||
foreach(extraarg ${ARGN})
|
||||
if(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
set(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
|
||||
endif(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
endforeach(extraarg ${ARGN})
|
||||
if(LOCAL_COMPILE_FLAGS)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${libname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
|
||||
endif(BUILD_SHARED_LIBS)
|
||||
if(BUILD_STATIC_LIBS)
|
||||
set_target_properties(${staticlibname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
|
||||
endif(BUILD_STATIC_LIBS)
|
||||
endif(LOCAL_COMPILE_FLAGS)
|
||||
endmacro(SC_ADDLIB libname srcslist libslist)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
|
||||
# set compile definitions for dll exports on windows
|
||||
MACRO(DEFINE_DLL_EXPORTS libname)
|
||||
IF( MSVC OR BORLAND )
|
||||
if( ${libname} MATCHES "sdai_.*" )
|
||||
set( export "SC_SCHEMA_DLL_EXPORTS" )
|
||||
else()
|
||||
STRING(REGEX REPLACE "lib" "" shortname "${libname}")
|
||||
STRING(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
|
||||
STRING(TOUPPER ${LOWERCORE} UPPER_CORE)
|
||||
set( export "SC_${UPPER_CORE}_DLL_EXPORTS" )
|
||||
endif()
|
||||
get_target_property(defs ${libname} COMPILE_DEFINITIONS )
|
||||
if( defs ) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
|
||||
set( defs "${defs};${export}")
|
||||
else( defs )
|
||||
set( defs "${export}")
|
||||
endif( defs )
|
||||
set_target_properties(${libname} PROPERTIES COMPILE_DEFINITIONS "${defs}" )
|
||||
ENDIF( MSVC OR BORLAND )
|
||||
ENDMACRO(DEFINE_DLL_EXPORTS libname)
|
||||
|
||||
# set compile definitions for dll imports on windows
|
||||
MACRO( DEFINE_DLL_IMPORTS tgt libs )
|
||||
IF( MSVC OR BORLAND )
|
||||
get_target_property(defs ${tgt} COMPILE_DEFINITIONS )
|
||||
if( NOT defs ) #if no properties, ${defs} will be defs-NOTFOUND which CMake interprets as false
|
||||
set( defs "")
|
||||
endif( NOT defs )
|
||||
foreach( lib ${libs} )
|
||||
STRING(REGEX REPLACE "lib" "" shortname "${lib}")
|
||||
STRING(REGEX REPLACE "step" "" LOWERCORE "${shortname}")
|
||||
STRING(TOUPPER ${LOWERCORE} UPPER_CORE)
|
||||
list( APPEND defs "SC_${UPPER_CORE}_DLL_IMPORTS" )
|
||||
endforeach( lib ${libs} )
|
||||
if( DEFINED defs )
|
||||
if( defs )
|
||||
set_target_properties( ${tgt} PROPERTIES COMPILE_DEFINITIONS "${defs}" )
|
||||
endif( defs )
|
||||
endif( DEFINED defs )
|
||||
ENDIF( MSVC OR BORLAND )
|
||||
ENDMACRO( DEFINE_DLL_IMPORTS tgt libs )
|
||||
|
||||
#EXCLUDE_OR_INSTALL(target destination ARGV3)
|
||||
# installs ${target} in ${destination} unless testing is enabled AND ${arg_3} == "TESTABLE",
|
||||
# in which case the EXCLUDE_FROM_ALL property is set for testing.
|
||||
# EXCLUDE_FROM_ALL cannot be set on targets that are to be installed,
|
||||
# so either test the target or install it - but not both
|
||||
MACRO(EXCLUDE_OR_INSTALL target dest arg_3 )
|
||||
if( NOT ( ( SC_ENABLE_TESTING ) AND ( "${arg_3}" STREQUAL "TESTABLE" ) ) )
|
||||
INSTALL(TARGETS ${target} DESTINATION ${dest})
|
||||
else( NOT ( ( SC_ENABLE_TESTING ) AND ( "${arg_3}" STREQUAL "TESTABLE" ) ) )
|
||||
set_target_properties( ${target} PROPERTIES EXCLUDE_FROM_ALL ON )
|
||||
endif( NOT ( ( SC_ENABLE_TESTING ) AND ( "${arg_3}" STREQUAL "TESTABLE" ) ) )
|
||||
ENDMACRO(EXCLUDE_OR_INSTALL target dest arg_3 )
|
||||
|
||||
#SC_ADDEXEC( execname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
|
||||
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
|
||||
# optional args can also be used by MSVC-specific code, but it looks like these two uses
|
||||
# will not conflict because the MSVC args must contain "STRICT"
|
||||
MACRO(SC_ADDEXEC execname srcslist libslist)
|
||||
add_executable(${execname} ${srcslist})
|
||||
target_link_libraries(${execname} ${libslist})
|
||||
DEFINE_DLL_IMPORTS(${execname} "${libslist}") #add import definitions for all libs that the executable is linked to
|
||||
EXCLUDE_OR_INSTALL( ${execname} "bin" "${ARGV3}" )
|
||||
# Enable extra compiler flags if local executables and/or global options dictate
|
||||
SET(LOCAL_COMPILE_FLAGS "")
|
||||
FOREACH(extraarg ${ARGN})
|
||||
IF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
SET(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
|
||||
ENDIF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
ENDFOREACH(extraarg ${ARGN})
|
||||
IF(LOCAL_COMPILE_FLAGS)
|
||||
SET_TARGET_PROPERTIES(${execname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
|
||||
ENDIF(LOCAL_COMPILE_FLAGS)
|
||||
ENDMACRO(SC_ADDEXEC execname srcslist libslist)
|
||||
|
||||
#SC_ADDLIB( libname "source files" "linked libs" ["TESTABLE"] ["MSVC flag" ...])
|
||||
# optional 4th argument of "TESTABLE", passed to EXCLUDE_OR_INSTALL macro
|
||||
# optional args can also be used by MSVC-specific code, but it looks like these two uses
|
||||
# will not conflict because the MSVC args must contain "STRICT"
|
||||
MACRO(SC_ADDLIB libname srcslist libslist)
|
||||
STRING(REGEX REPLACE "-framework;" "-framework " libslist "${libslist1}")
|
||||
IF(SC_BUILD_SHARED_LIBS)
|
||||
add_library(${libname} SHARED ${srcslist})
|
||||
DEFINE_DLL_EXPORTS(${libname})
|
||||
if(NOT "${libs}" MATCHES "NONE")
|
||||
target_link_libraries(${libname} ${libslist})
|
||||
DEFINE_DLL_IMPORTS(${libname} "${libslist}" )
|
||||
endif(NOT "${libs}" MATCHES "NONE")
|
||||
SET_TARGET_PROPERTIES(${libname} PROPERTIES VERSION ${SC_ABI_VERSION} SOVERSION ${SC_ABI_SOVERSION} )
|
||||
EXCLUDE_OR_INSTALL( ${libname} "lib" "${ARGV3}" )
|
||||
if(APPLE)
|
||||
set_target_properties(${libname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
|
||||
endif(APPLE)
|
||||
ENDIF(SC_BUILD_SHARED_LIBS)
|
||||
IF(SC_BUILD_STATIC_LIBS AND NOT MSVC)
|
||||
if( NOT SC_BUILD_SHARED_LIBS )
|
||||
set( staticlibname "${libname}" )
|
||||
else()
|
||||
set( staticlibname "${libname}-static" )
|
||||
endif( NOT SC_BUILD_SHARED_LIBS )
|
||||
add_library(${staticlibname} STATIC ${srcslist})
|
||||
DEFINE_DLL_EXPORTS(${staticlibname})
|
||||
if(NOT ${libs} MATCHES "NONE")
|
||||
target_link_libraries(${staticlibname} "${libslist}")
|
||||
DEFINE_DLL_IMPORTS(${staticlibname} ${libslist} )
|
||||
endif(NOT ${libs} MATCHES "NONE")
|
||||
IF(NOT WIN32)
|
||||
SET_TARGET_PROPERTIES(${staticlibname} PROPERTIES OUTPUT_NAME "${libname}")
|
||||
ENDIF(NOT WIN32)
|
||||
IF(WIN32)
|
||||
# We need the lib prefix on win32, so add it even if our add_library
|
||||
# wrapper function has removed it due to the target name - see
|
||||
# http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_make_my_shared_and_static_libraries_have_the_same_root_name.2C_but_different_suffixes.3F
|
||||
SET_TARGET_PROPERTIES(${staticlibname} PROPERTIES PREFIX "lib")
|
||||
ENDIF(WIN32)
|
||||
EXCLUDE_OR_INSTALL( ${staticlibname} "lib" "${ARGV3}" )
|
||||
if(APPLE)
|
||||
set_target_properties(${staticlibname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress")
|
||||
endif(APPLE)
|
||||
ENDIF(SC_BUILD_STATIC_LIBS AND NOT MSVC)
|
||||
# Enable extra compiler flags if local libraries and/or global options dictate
|
||||
SET(LOCAL_COMPILE_FLAGS "")
|
||||
FOREACH(extraarg ${ARGN})
|
||||
IF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
SET(LOCAL_COMPILE_FLAGS "${LOCAL_COMPILE_FLAGS} ${STRICT_FLAGS}")
|
||||
ENDIF(${extraarg} MATCHES "STRICT" AND SC-ENABLE_STRICT)
|
||||
ENDFOREACH(extraarg ${ARGN})
|
||||
IF(LOCAL_COMPILE_FLAGS)
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
SET_TARGET_PROPERTIES(${libname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
IF(BUILD_STATIC_LIBS AND NOT MSVC)
|
||||
SET_TARGET_PROPERTIES(${staticlibname} PROPERTIES COMPILE_FLAGS ${LOCAL_COMPILE_FLAGS})
|
||||
ENDIF(BUILD_STATIC_LIBS AND NOT MSVC)
|
||||
ENDIF(LOCAL_COMPILE_FLAGS)
|
||||
ENDMACRO(SC_ADDLIB libname srcslist libslist)
|
||||
@@ -1,30 +1,22 @@
|
||||
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
||||
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
list(REVERSE files)
|
||||
foreach (file ${files})
|
||||
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
|
||||
if (EXISTS "$ENV{DESTDIR}${file}")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E remove "$ENV{DESTDIR}${file}"
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RESULT_VARIABLE rm_retval
|
||||
)
|
||||
if(NOT ${rm_retval} EQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
|
||||
endif (NOT ${rm_retval} EQUAL 0)
|
||||
else (EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
|
||||
endif (EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
|
||||
if (EXISTS "$ENV{DESTDIR}${file}")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E remove "$ENV{DESTDIR}${file}"
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RESULT_VARIABLE rm_retval
|
||||
)
|
||||
if(NOT ${rm_retval} EQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
|
||||
endif (NOT ${rm_retval} EQUAL 0)
|
||||
else (EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
|
||||
endif (EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
||||
@@ -4,6 +4,7 @@
|
||||
# http://stackoverflow.com/questions/3780667
|
||||
# http://www.cmake.org/pipermail/cmake/2009-February/027014.html
|
||||
|
||||
|
||||
set(SC_IS_SUBBUILD "@SC_IS_SUBBUILD@")
|
||||
|
||||
#---------- find commit id ------------------
|
||||
@@ -12,76 +13,68 @@ set(SC_IS_SUBBUILD "@SC_IS_SUBBUILD@")
|
||||
#create a tag with 'git tag <name>' and 'git push --tags'
|
||||
#if git can't be found, uses contents of SC_VERSION.txt
|
||||
|
||||
set(VERS_FILE ${SOURCE_DIR}/SC_VERSION.txt)
|
||||
if(EXISTS ${SOURCE_DIR}/.git)
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COMMIT_ID)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
file(READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255)
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
message(WARNING "Git failed (probably no tags in repo). Build will contain revision info from ${VERS_FILE}.")
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
endif()
|
||||
else(GIT_FOUND)
|
||||
file(READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255)
|
||||
set(VERS_FILE ${SOURCE_DIR}/SC_VERSION.txt )
|
||||
if( EXISTS ${SOURCE_DIR}/.git )
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COMMIT_ID )
|
||||
if( NOT ${res_var} EQUAL 0 )
|
||||
file( READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255 )
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
message( WARNING "Git failed (probably no tags in repo). Build will contain revision info from ${VERS_FILE}." )
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
endif()
|
||||
else(GIT_FOUND)
|
||||
file( READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255 )
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
message(WARNING "Git not found. Build will contain revision info from ${VERS_FILE}.")
|
||||
message( WARNING "Git not found. Build will contain revision info from ${VERS_FILE}." )
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
endif(GIT_FOUND)
|
||||
endif(GIT_FOUND)
|
||||
else()
|
||||
file(READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255)
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
message(WARNING "Git failed ('.git' not found). Build will contain revision info from ${VERS_FILE}.")
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
file( READ ${VERS_FILE} GIT_COMMIT_ID LIMIT 255 )
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
message( WARNING "Git failed ('.git' not found). Build will contain revision info from ${VERS_FILE}." )
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
endif()
|
||||
string(REPLACE "\n" "" GIT_COMMIT_ID ${GIT_COMMIT_ID})
|
||||
string( REPLACE "\n" "" GIT_COMMIT_ID ${GIT_COMMIT_ID} )
|
||||
|
||||
#-------------- date and time ---------------
|
||||
#once cmake_minimum_required is >= 2.8.11, we can use TIMESTAMP:
|
||||
#string(TIMESTAMP date_time_string)
|
||||
#string( TIMESTAMP date_time_string )
|
||||
|
||||
if(UNIX)
|
||||
execute_process(COMMAND date "+%d %b %Y %H:%M" OUTPUT_VARIABLE date_time_string OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
elseif(WIN32)
|
||||
execute_process(COMMAND cmd /c date /t OUTPUT_VARIABLE currentDate OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND cmd /c time /t OUTPUT_VARIABLE currentTime OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set (date_time_string "${currentDate} ${currentTime}")
|
||||
if( UNIX )
|
||||
execute_process( COMMAND date "+%d %b %Y %H:%M" OUTPUT_VARIABLE date_time_string OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
elseif( WIN32 )
|
||||
execute_process( COMMAND cmd /c date /t OUTPUT_VARIABLE currentDate OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
execute_process( COMMAND cmd /c time /t OUTPUT_VARIABLE currentTime OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
set ( date_time_string "${currentDate} ${currentTime}" )
|
||||
else()
|
||||
set(date_time_string "\" __DATE__ \" \" __TIME__ \" ")
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
message(STATUS "Unknown platform - using date from preprocessor")
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
set( date_time_string "\" __DATE__ \" \" __TIME__ \" " )
|
||||
if( NOT SC_IS_SUBBUILD )
|
||||
message( STATUS "Unknown platform - using date from preprocessor" )
|
||||
endif( NOT SC_IS_SUBBUILD )
|
||||
endif()
|
||||
|
||||
set(header_string "/* sc_version_string.h - written by cmake. Changes will be lost! */\n"
|
||||
"#ifndef SC_VERSION_STRING\n"
|
||||
"#define SC_VERSION_STRING\n\n"
|
||||
"/*\n** The git commit id looks like \"test-1-g5e1fb47\", where test is the\n"
|
||||
"** name of the last tagged git revision, 1 is the number of commits since that tag,\n"
|
||||
"** 'g' is unknown, and 5e1fb47 is the first 7 chars of the git sha1 commit id.\n"
|
||||
"** timestamp is created from date/time commands on known platforms, and uses\n"
|
||||
"** preprocessor macros elsewhere.\n*/\n\n"
|
||||
"static char sc_version[512] = {\n"
|
||||
" \"git commit id: ${GIT_COMMIT_ID}, build timestamp ${date_time_string}\"\n"
|
||||
"}\;\n\n"
|
||||
"#endif\n"
|
||||
)
|
||||
set( header_string "/* sc_version_string.h - written by cmake. Changes will be lost! */\n"
|
||||
"#ifndef SC_VERSION_STRING\n"
|
||||
"#define SC_VERSION_STRING\n\n"
|
||||
"/*\n** The git commit id looks like \"test-1-g5e1fb47\", where test is the\n"
|
||||
"** name of the last tagged git revision, 1 is the number of commits since that tag,\n"
|
||||
"** 'g' is unknown, and 5e1fb47 is the first 7 chars of the git sha1 commit id.\n"
|
||||
"** timestamp is created from date/time commands on known platforms, and uses\n"
|
||||
"** preprocessor macros elsewhere.\n*/\n\n"
|
||||
"static char sc_version[512] = {\n"
|
||||
" \"git commit id: ${GIT_COMMIT_ID}, build timestamp ${date_time_string}\"\n"
|
||||
"}\;\n\n"
|
||||
"#endif\n"
|
||||
)
|
||||
|
||||
file(WRITE sc_version_string.h.txt ${header_string})
|
||||
file(WRITE sc_version_string.h.txt ${header_string} )
|
||||
# copy the file to the final header only if the version changes
|
||||
# reduces needless rebuilds
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
sc_version_string.h.txt ${BINARY_DIR}/include/sc_version_string.h)
|
||||
sc_version_string.h.txt ${BINARY_DIR}/include/sc_version_string.h)
|
||||
if(NOT SC_IS_SUBBUILD)
|
||||
message("-- sc_version_string.h is up-to-date.")
|
||||
endif(NOT SC_IS_SUBBUILD)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
project(SC_SUBPROJECT_SCHEMA_SCANNER)
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
|
||||
if(NOT ("${CALLED_FROM}" STREQUAL "STEPCODE_CMAKELISTS" AND DEFINED SC_ROOT AND DEFINED SC_BUILDDIR))
|
||||
message(" ${CALLED_FROM} ${SC_ROOT} ${SC_BUILDDIR}")
|
||||
message(FATAL_ERROR "This is not a truly independent project; it should be built during the STEPcode configuration stage.")
|
||||
endif()
|
||||
|
||||
# SC_ROOT: SC root dir
|
||||
# SC_BUILDDIR: SC build dir, so generated headers can be found
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
# set all target location variables so that MSVC will put the executable the same place as other compilers
|
||||
set(SC_BINARY_DIR ${SC_BUILDDIR})
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../SC_Outdirs.cmake)
|
||||
|
||||
set(schema_scanner_src
|
||||
${SC_ROOT}/src/base/sc_mkdir.c
|
||||
${SC_ROOT}/src/exp2cxx/genCxxFilenames.c
|
||||
${SC_ROOT}/src/exp2cxx/class_strings.c
|
||||
${SC_ROOT}/src/express/generated/expparse.c
|
||||
${SC_ROOT}/src/express/generated/expscan.c
|
||||
${SC_ROOT}/src/express/alg.c
|
||||
${SC_ROOT}/src/express/caseitem.c
|
||||
${SC_ROOT}/src/express/dict.c
|
||||
${SC_ROOT}/src/express/entity.c
|
||||
${SC_ROOT}/src/express/error.c
|
||||
${SC_ROOT}/src/express/exp_kw.c
|
||||
${SC_ROOT}/src/express/expr.c
|
||||
${SC_ROOT}/src/express/express.c
|
||||
${SC_ROOT}/src/express/hash.c
|
||||
${SC_ROOT}/src/express/lexact.c
|
||||
${SC_ROOT}/src/express/linklist.c
|
||||
${SC_ROOT}/src/express/memory.c
|
||||
${SC_ROOT}/src/express/object.c
|
||||
${SC_ROOT}/src/express/info.c
|
||||
${SC_ROOT}/src/express/resolve.c
|
||||
${SC_ROOT}/src/express/schema.c
|
||||
${SC_ROOT}/src/express/scope.c
|
||||
${SC_ROOT}/src/express/stmt.c
|
||||
${SC_ROOT}/src/express/symbol.c
|
||||
${SC_ROOT}/src/express/type.c
|
||||
${SC_ROOT}/src/express/variable.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/schemaScanner.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${SC_ROOT}/include/
|
||||
${SC_ROOT}/src/express/
|
||||
${SC_ROOT}/src/express/generated
|
||||
${SC_ROOT}/src/base
|
||||
${SC_ROOT}/src/exp2cxx
|
||||
${SC_BUILDDIR}/include
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D__MSVC__ -D__WIN32__)
|
||||
# Disable warning for preferred usage of secure functions (example strcpy should be strcpy_s, ...)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
|
||||
elseif(BORLAND)
|
||||
add_definitions(-D__BORLAND__ -D__WIN32__)
|
||||
else()
|
||||
add_definitions(-pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long)
|
||||
endif()
|
||||
|
||||
add_definitions(-DSCHEMA_SCANNER)
|
||||
|
||||
add_executable(schema_scanner ${schema_scanner_src})
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
README for STEPcode schema scanner
|
||||
--------------
|
||||
|
||||
The files in this directory are for a schema scanner executable, built by CMake during the configuration stage.
|
||||
|
||||
This scanner is used to determine the file names that exp2cxx will use. In CMake, all file names must be known before
|
||||
configuration finishes - so it is necessary to parse the schemas early.
|
||||
|
||||
This appears to be a standalone project to CMake, but it is intended to be built only as part of STEPcode. It is configured,
|
||||
built, and executed during the configuration stage of STEPcode.
|
||||
@@ -1,336 +0,0 @@
|
||||
|
||||
/** \file schemaScanner.cc
|
||||
* This file, along with part of libexpress, are compiled (at configure time)
|
||||
* into a static executable. This executable is a schema scanner that is used
|
||||
* by CMake to determine what files exp2cxx will create. Otherwise, we'd need
|
||||
* to use a few huge files - there is no other way to tell CMake what the
|
||||
* generated files will be called.
|
||||
*/
|
||||
|
||||
/* WARNING
|
||||
* If you modify this file, you must re-run cmake. It doesn't seem to be possible
|
||||
* to re-run cmake automatically, as CMake's configure_file() gets confused by
|
||||
* the '${' and '}' in writeLists() below.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
# include "expparse.h"
|
||||
# include "expscan.h"
|
||||
# include "express/scope.h"
|
||||
# include "genCxxFilenames.h"
|
||||
# include "sc_mkdir.h"
|
||||
|
||||
# include <string.h>
|
||||
|
||||
# if defined( _WIN32 ) || defined ( __WIN32__ )
|
||||
# include <direct.h>
|
||||
# define getcwd _getcwd
|
||||
# else
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
}
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
int multiple_inheritance = 0;
|
||||
|
||||
using std::string;
|
||||
using std::stringstream;
|
||||
using std::endl;
|
||||
using std::ofstream;
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
|
||||
/** \return true for types that exp2cxx won't generate code for */
|
||||
bool notGenerated( const Type t ) {
|
||||
switch( TYPEget_body( t )->type ) {
|
||||
case integer_:
|
||||
case real_:
|
||||
case string_:
|
||||
case binary_:
|
||||
case boolean_:
|
||||
case number_:
|
||||
case logical_:
|
||||
case aggregate_:
|
||||
case bag_:
|
||||
case set_:
|
||||
case list_:
|
||||
case array_:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* from addRenameTypedefs() in multpass.c - check for renamed
|
||||
* enums and selects - exp2cxx prints typedefs for them */
|
||||
if( ( TYPEis_enumeration( t ) || TYPEis_select( t ) ) && ( TYPEget_head( t ) ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \return a short name for the schema
|
||||
* this name is intended to be unique, but no special care is put into its generation
|
||||
* the official schema name seems most likely to not be unique, but it is generally the longest
|
||||
*
|
||||
* picks the shortest of:
|
||||
* * the name of the dir containing the file (if in sc/data),
|
||||
* * the name of the file containing the schema (minus extension),
|
||||
* * the official name of the schema, passed in arg 'longName'
|
||||
*
|
||||
* TODO: maybe also consider an acronym, such that 'test_array_bounds_expr' becomes 'tabe', 'TABE', 'T_A_B_E', or similar
|
||||
*/
|
||||
string makeShortName( const char * longName ) {
|
||||
//input_filename is path to file. we will extract dir name and file name from it.
|
||||
string dirname = input_filename, filename = input_filename, schname = longName;
|
||||
const char slash = '/';
|
||||
|
||||
//for filename, get rid of dir name(s), if any, as well as the extension
|
||||
size_t sl = filename.rfind( slash );
|
||||
if( sl != string::npos ) {
|
||||
filename.erase( 0, sl + 1 );
|
||||
}
|
||||
size_t dot = filename.rfind( '.' );
|
||||
if( dot != string::npos ) {
|
||||
filename.erase( dot );
|
||||
}
|
||||
|
||||
//for dirname, get rid of the filename and ensure it's in data/
|
||||
sl = dirname.rfind( slash );
|
||||
if( sl != string::npos ) {
|
||||
dirname.erase( sl );
|
||||
}
|
||||
const char * dat = "data";
|
||||
size_t data = dirname.find( dat );
|
||||
if( ( data == string::npos ) || ( dirname[ data + strlen( dat ) ] != slash ) ) {
|
||||
//doesn't contain 'data/'. clear it so it'll be ignored.
|
||||
dirname.clear();
|
||||
} else {
|
||||
//get rid of all but last dir name
|
||||
dirname.erase( 0, dirname.rfind( slash ) + 1 );
|
||||
}
|
||||
|
||||
//use dir name if it's at least 3 chars and shorter than file name
|
||||
//length requirement gets rid of short, undescriptive dir names - including '.' and '..'
|
||||
if( ( dirname.size() > 2 ) && ( dirname.size() < filename.size() ) ) {
|
||||
filename = dirname;
|
||||
}
|
||||
if( strlen( longName ) < filename.size() ) {
|
||||
filename = longName;
|
||||
}
|
||||
filename.insert( 0, "sdai_" );
|
||||
return filename;
|
||||
}
|
||||
|
||||
/** write a CMakeLists.txt file for the schema; print its directory to stdout for CMake's add_subdirectory() command */
|
||||
void writeLists( const char * schemaName, stringstream & eh, stringstream & ei, int ecount,
|
||||
stringstream & th, stringstream & ti, int tcount ) {
|
||||
string shortName = makeShortName( schemaName );
|
||||
if( mkDirIfNone( shortName.c_str() ) < 0 ) {
|
||||
cerr << "Error creating directory " << shortName << " at " << __FILE__ << ":" << __LINE__;
|
||||
perror( 0 );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
size_t nameLen = strlen( schemaName );
|
||||
string schema_upper( nameLen, char() );
|
||||
for( size_t i = 0; i < nameLen; ++i) {
|
||||
schema_upper[i] = toupper(schemaName[i]);
|
||||
}
|
||||
string cmListsPath = shortName;
|
||||
cmListsPath += "/CMakeLists.txt";
|
||||
ofstream cmLists;
|
||||
cmLists.open( cmListsPath.c_str() );
|
||||
if( !cmLists.good() ) {
|
||||
cerr << "error opening file " << cmListsPath << " - exiting." << endl;
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
cmLists << "# ----- GENERATED FILE -----" << endl;
|
||||
cmLists << "# ----- Do not edit! -----" << endl << endl;
|
||||
|
||||
cmLists << "# schema name: " << schemaName << endl;
|
||||
cmLists << "# (short name: " << shortName << ")" << endl;
|
||||
cmLists << "# " << ecount << " entities, " << tcount << " types" << endl << endl;
|
||||
|
||||
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;
|
||||
|
||||
// * 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 << "set(" << shortName << "_entity_hdrs" << endl;
|
||||
cmLists << eh.str();
|
||||
cmLists << " )" << endl << endl;
|
||||
|
||||
cmLists << "set(" << shortName << "_type_hdrs" << endl;
|
||||
cmLists << th.str();
|
||||
cmLists << " )" << endl << endl;
|
||||
|
||||
cmLists << "set(" << shortName << "_misc_hdrs" << endl;
|
||||
cmLists << " Sdaiclasses.h schema.h" << endl;
|
||||
cmLists << " Sdai" << schema_upper << "Names.h" << endl;
|
||||
cmLists << " Sdai" << schema_upper << ".h" << endl;
|
||||
cmLists << " )" << endl << endl;
|
||||
|
||||
cmLists << "# install all headers" << endl;
|
||||
cmLists << "set(all_headers ${" << shortName << "_entity_hdrs} ${" << shortName << "_type_hdrs} ${" << shortName << "_misc_hdrs})" << endl;
|
||||
cmLists << "foreach( header_file ${all_headers} )" << endl;
|
||||
cmLists << " set(curr_dir)" << endl;
|
||||
cmLists << " get_filename_component(curr_dir ${header_file} PATH)" << endl;
|
||||
cmLists << " get_filename_component(curr_name ${header_file} NAME)" << endl;
|
||||
cmLists << " if (curr_dir)" << endl;
|
||||
cmLists << " install( FILES ${header_file} DESTINATION \"include/schemas/" << shortName << "/${curr_dir}\" )" << endl;
|
||||
cmLists << " else (curr_dir)" << endl;
|
||||
cmLists << " install( FILES ${header_file} DESTINATION \"include/schemas/" << shortName << "\" )" << endl;
|
||||
cmLists << " endif (curr_dir)" << endl;
|
||||
cmLists << "endforeach()" << endl;
|
||||
|
||||
cmLists << "# implementation files - 3 lists" << endl << endl;
|
||||
|
||||
cmLists << "# unity build: #include small .cc files to reduce the number" << endl;
|
||||
cmLists << "# of translation units that must be compiled" << 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;
|
||||
|
||||
cmLists << " set(" << shortName << "_type_impls" << endl;
|
||||
cmLists << ti.str();
|
||||
cmLists << " )" << 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 << endl;
|
||||
|
||||
cmLists << "set(schema_target_files ${" << shortName << "_entity_impls} " << "${" << shortName << "_type_impls} " << "${" << shortName << "_misc_impls})" << endl;
|
||||
cmLists << "SCHEMA_TARGETS(\"" << input_filename << "\" \"" << schemaName << "\"" << endl;
|
||||
cmLists << " \"${schema_target_files}\")" << endl;
|
||||
|
||||
cmLists.close();
|
||||
|
||||
char pwd[BUFSIZ] = {0};
|
||||
if( getcwd( pwd, BUFSIZ ) ) {
|
||||
cout << pwd << "/" << shortName << endl;
|
||||
} else {
|
||||
cerr << "Error encountered by getcwd() for " << shortName << " - exiting. Error was ";
|
||||
perror( 0 );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
void printSchemaFilenames( Schema sch ){
|
||||
const int numColumns = 2;
|
||||
const int colWidth = 75;
|
||||
const char * tab = " ";
|
||||
|
||||
stringstream typeHeaders, typeImpls, entityHeaders, entityImpls;
|
||||
typeHeaders << tab;
|
||||
typeImpls << tab;
|
||||
entityHeaders << tab;
|
||||
entityImpls << tab;
|
||||
|
||||
int ecount = 0, tcount = 0;
|
||||
|
||||
DictionaryEntry de;
|
||||
Generic x;
|
||||
filenames_t fn;
|
||||
DICTdo_init( sch->symbol_table, &de );
|
||||
while( 0 != ( x = DICTdo( &de ) ) ) {
|
||||
switch( DICT_type ) {
|
||||
case OBJ_ENTITY:
|
||||
fn = getEntityFilenames( ( Entity ) x );
|
||||
entityHeaders << std::left << std::setw( colWidth ) << fn.header << " ";
|
||||
entityImpls << std::left << std::setw( colWidth ) << fn.impl << " ";
|
||||
++ecount;
|
||||
if( ( ecount % numColumns ) == 0 ) {
|
||||
// columns
|
||||
entityHeaders << endl << tab;
|
||||
entityImpls << endl << tab;
|
||||
}
|
||||
break;
|
||||
case OBJ_TYPE: {
|
||||
Type t = ( Type ) x;
|
||||
if( TYPEis_enumeration( t ) && ( TYPEget_head( t ) ) ) {
|
||||
/* t is a renamed enum type, for which exp2cxx
|
||||
* will print a typedef in an existing file */
|
||||
break;
|
||||
}
|
||||
if( notGenerated( t ) ) {
|
||||
/* skip builtin types */
|
||||
break;
|
||||
}
|
||||
fn = getTypeFilenames( t );
|
||||
typeHeaders << std::left << std::setw( colWidth ) << fn.header << " ";
|
||||
typeImpls << std::left << std::setw( colWidth ) << fn.impl << " ";
|
||||
++tcount;
|
||||
if( ( tcount % numColumns ) == 0 ) {
|
||||
typeHeaders << endl << tab;
|
||||
typeImpls << endl << tab;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* case OBJ_FUNCTION:
|
||||
* case OBJ_PROCEDURE:
|
||||
* case OBJ_RULE: */
|
||||
default:
|
||||
/* ignore everything else */
|
||||
/* TODO: if DEBUG is defined, print the names of these to stderr */
|
||||
break;
|
||||
}
|
||||
}
|
||||
//write the CMakeLists.txt
|
||||
writeLists( sch->symbol.name, entityHeaders, entityImpls, ecount, typeHeaders, typeImpls, tcount );
|
||||
}
|
||||
|
||||
int main( int argc, char ** argv ) {
|
||||
/* TODO init globals! */
|
||||
|
||||
Schema schema;
|
||||
DictionaryEntry de;
|
||||
/* copied from fedex.c */
|
||||
Express model;
|
||||
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];
|
||||
|
||||
EXPRESSinitialize();
|
||||
|
||||
model = EXPRESScreate();
|
||||
EXPRESSparse( model, ( FILE * )0, input_filename );
|
||||
if( ERRORoccurred ) {
|
||||
EXPRESSdestroy( model );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
EXPRESSresolve( model );
|
||||
if( ERRORoccurred ) {
|
||||
int result = EXPRESS_fail( model );
|
||||
EXPRESScleanup();
|
||||
EXPRESSdestroy( model );
|
||||
exit( result );
|
||||
}
|
||||
|
||||
DICTdo_type_init( model->symbol_table, &de, OBJ_SCHEMA );
|
||||
while( 0 != ( schema = ( Schema )DICTdo( &de ) ) ) {
|
||||
printSchemaFilenames( schema );
|
||||
}
|
||||
|
||||
EXPRESSdestroy( model );
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
# this file should be included from data/CMakeLists.txt
|
||||
#
|
||||
# at configure time, this builds a small program
|
||||
# which will parse express schemas to determine
|
||||
# what files exp2cxx will create for that schema.
|
||||
#
|
||||
# The SCHEMA_CMLIST macro is to be used to run this
|
||||
# program. It will set variables for schema name(s),
|
||||
# headers, and implementation files.
|
||||
|
||||
# in a unity build, many small .cc files are #included to create a few large translation units
|
||||
# this makes compilation faster, but sometimes runs into compiler limitations
|
||||
if(NOT DEFINED SC_UNITY_BUILD)
|
||||
if(BORLAND)
|
||||
message(".. Will not do unity build for this compiler.")
|
||||
set(SC_UNITY_BUILD FALSE)
|
||||
else()
|
||||
message(".. Assuming compiler is capable of unity build.")
|
||||
set(SC_UNITY_BUILD TRUE)
|
||||
endif(BORLAND)
|
||||
message(".. Override by setting SC_UNITY_BUILD; TRUE will result in *huge* translation units, higher memory use in compilation, and faster build times.")
|
||||
else(NOT DEFINED SC_UNITY_BUILD)
|
||||
message(".. Respecting user-defined SC_UNITY_BUILD value of ${SC_UNITY_BUILD}.")
|
||||
endif(NOT DEFINED SC_UNITY_BUILD)
|
||||
|
||||
|
||||
# --- variables ---
|
||||
# SC_ROOT: SC root dir
|
||||
# SC_BUILDDIR: SC build dir, so generated headers can be found
|
||||
# SCANNER_SRC_DIR: dir this file is in
|
||||
# SCANNER_OUT_DIR: location of binary, same dir as SC uses
|
||||
# SCANNER_BUILD_DIR: location scanner is built
|
||||
|
||||
set(SCANNER_SRC_DIR ${SC_CMAKE_DIR}/schema_scanner)
|
||||
set(SCANNER_BUILD_DIR ${SC_BINARY_DIR}/schema_scanner CACHE INTERNAL "location for scanner build, config files (copied schemas)")
|
||||
set(SCANNER_OUT_DIR ${SC_BINARY_DIR}/bin CACHE INTERNAL "location for schema_scanner executable")
|
||||
|
||||
#write a cmake file for the cache. the alternative is a very long
|
||||
# command line - and the command line can't have newlines in it
|
||||
set(initial_scanner_cache ${SCANNER_BUILD_DIR}/initial_scanner_cache.cmake)
|
||||
file(WRITE ${initial_scanner_cache} "
|
||||
set(SC_ROOT \"${SC_SOURCE_DIR}\" CACHE STRING \"root dir\")
|
||||
set(SC_BUILDDIR \"${SC_BINARY_DIR}\" CACHE PATH \"build dir\")
|
||||
set(CALLED_FROM \"STEPCODE_CMAKELISTS\" CACHE STRING \"verification\")
|
||||
set(CMAKE_BUILD_TYPE \"Debug\" CACHE STRING \"build type\")
|
||||
set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\" CACHE STRING \"compiler\")
|
||||
set(CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\" CACHE STRING \"compiler\")
|
||||
")
|
||||
|
||||
message("-- Compiling schema scanner...")
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${SC_BINARY_DIR}/schemas)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${SCANNER_BUILD_DIR})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -C ${initial_scanner_cache} ${SCANNER_SRC_DIR} -G ${CMAKE_GENERATOR}
|
||||
WORKING_DIRECTORY ${SCANNER_BUILD_DIR}
|
||||
TIMEOUT 60
|
||||
OUTPUT_VARIABLE _ss_config_out
|
||||
RESULT_VARIABLE _ss_config_stat
|
||||
ERROR_VARIABLE _ss_config_err
|
||||
)
|
||||
if(NOT ${_ss_config_stat} STREQUAL "0")
|
||||
message(FATAL_ERROR "Scanner config status: ${_ss_config_stat}. stdout:\n${_ss_config_out}\nstderr:\n${_ss_config_err}")
|
||||
endif(NOT ${_ss_config_stat} STREQUAL "0")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} --build ${SCANNER_BUILD_DIR} --config Debug --clean-first
|
||||
WORKING_DIRECTORY ${SCANNER_BUILD_DIR}
|
||||
TIMEOUT 120 # should take far less than 2m
|
||||
OUTPUT_VARIABLE _ss_build_out
|
||||
RESULT_VARIABLE _ss_build_stat
|
||||
ERROR_VARIABLE _ss_build_err
|
||||
)
|
||||
if(NOT ${_ss_build_stat} STREQUAL "0")
|
||||
message(FATAL_ERROR "Scanner build status: ${_ss_build_stat}. stdout:\n${_ss_build_out}\nstderr:\n${_ss_build_err}")
|
||||
endif(NOT ${_ss_build_stat} STREQUAL "0")
|
||||
|
||||
message("-- Schema scanner built. Running it...")
|
||||
|
||||
# not sure if it makes sense to install this or not...
|
||||
if(WIN32)
|
||||
install(PROGRAMS ${SCANNER_OUT_DIR}/schema_scanner.exe DESTINATION ${BIN_INSTALL_DIR})
|
||||
else(WIN32)
|
||||
install(PROGRAMS ${SCANNER_OUT_DIR}/schema_scanner DESTINATION ${BIN_INSTALL_DIR})
|
||||
endif(WIN32)
|
||||
|
||||
# macro SCHEMA_CMLIST
|
||||
# runs the schema scanner on one express file, creating a CMakeLists.txt file for each schema found. Those files are added via add_subdirectory().
|
||||
#
|
||||
# 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}
|
||||
WORKING_DIRECTORY ${SC_BINARY_DIR}/schemas
|
||||
RESULT_VARIABLE _ss_stat
|
||||
OUTPUT_VARIABLE _ss_out
|
||||
ERROR_VARIABLE _ss_err
|
||||
)
|
||||
if(NOT "${_ss_stat}" STREQUAL "0")
|
||||
#check size of output, put in file if large?
|
||||
message(FATAL_ERROR "Schema scan for '${SCHEMA_FILE}'\nexited with error code '${_ss_stat}'\nstdout:\n${_ss_out}\nstderr:\n${_ss_err}\n")
|
||||
endif(NOT "${_ss_stat}" STREQUAL "0")
|
||||
# scanner output format: each line contains an absolute path. each path is a dir containing a CMakeLists for one schema
|
||||
# there will usually be a single line of output, but it is not illegal for multiple schemas to exist in one .exp file
|
||||
string(STRIP "${_ss_out}" _ss_stripped)
|
||||
string(REGEX REPLACE "\\\n" ";" _list ${_ss_stripped})
|
||||
foreach(_dir ${_list})
|
||||
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.
|
||||
configure_file(${SCHEMA_FILE} ${SCANNER_BUILD_DIR}/${_schema})
|
||||
endmacro(SCHEMA_CMLIST SCHEMA_FILE)
|
||||
@@ -69,8 +69,8 @@ if(NOT DEBUGGING_GENERATED_SOURCES)
|
||||
endforeach(outf ${output_files})
|
||||
endif(NOT LOCKED_SOURCE_DIR)
|
||||
|
||||
else(NOT DEBUGGING_GENERATED_SOURCES)
|
||||
|
||||
else (NOT DEBUGGING_GENERATED_SOURCES)
|
||||
|
||||
message("\nNote: DEBUGGING_GENERATED_SOURCES is enabled - generated outputs will contain configuration-specific debugging information, so syncing cached output files is not possible. To restore normal behavior, disable DEBUGGING_GENERATED_SOURCES.\n")
|
||||
|
||||
endif(NOT DEBUGGING_GENERATED_SOURCES)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Inherit the parent CMake setting
|
||||
set(DEBUGGING_GENERATED_SOURCES @DEBUGGING_GENERATED_SOURCES@)
|
||||
set(CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
|
||||
set(CURRENT_SOURCE_DIR @CMAKE_CURRENT_SOURCE_DIR@)
|
||||
|
||||
# Include the file the provides the baseline against which
|
||||
# current files will be compared
|
||||
if(NOT DEBUGGING_GENERATED_SOURCES)
|
||||
|
||||
include("@BASELINE_INFORMATION_FILE@")
|
||||
include(@BASELINE_INFORMATION_FILE@)
|
||||
|
||||
# Define a variety of convenience routines
|
||||
include("@PROJECT_CMAKE_DIR@/Generated_Source_Utils.cmake")
|
||||
include(@PROJECT_CMAKE_DIR@/Generated_Source_Utils.cmake)
|
||||
|
||||
# Individually verify all of the files in question.
|
||||
set(filelist "@CACHED_FILELIST@")
|
||||
@@ -20,7 +20,7 @@ if(NOT DEBUGGING_GENERATED_SOURCES)
|
||||
message(FATAL_ERROR "Generated sources have been modified. These files should never be modified directly except when debugging faulty output from the generators - changes to lexer and parser logic should be made to the generator input files. If this is a debugging situation, set the variable DEBUGGING_GENERATED_SOURCES to ON during the CMake configure.")
|
||||
endif(srcs_pass)
|
||||
|
||||
# If we got by that test, see if it looks like these
|
||||
# If we got by that test, see if it looks like these
|
||||
# sources came from the current input files. It's not
|
||||
# a failure condition if they didn't, but warn about it.
|
||||
set(filelist "@INPUT_FILELIST@")
|
||||
|
||||
+10
-18
@@ -1,11 +1,11 @@
|
||||
# run_ctest.cmake
|
||||
# `ctest -S run_ctest.cmake`
|
||||
|
||||
set(CTEST_SOURCE_DIRECTORY .)
|
||||
set(CTEST_BINARY_DIRECTORY build_matrix)
|
||||
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
|
||||
set(CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind)
|
||||
set(CTEST_INITIAL_CACHE "
|
||||
set( CTEST_SOURCE_DIRECTORY . )
|
||||
set( CTEST_BINARY_DIRECTORY build_matrix )
|
||||
set( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
|
||||
set( CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind )
|
||||
set( CTEST_INITIAL_CACHE "
|
||||
SITE:STRING=${CTEST_SITE}
|
||||
BUILDNAME:STRING=${CTEST_BUILD_NAME}
|
||||
SC_ENABLE_TESTING:BOOL=ON
|
||||
@@ -15,19 +15,11 @@ SC_BUILD_TYPE:STRING=Debug
|
||||
|
||||
ctest_start(matrix)
|
||||
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
|
||||
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS -DSC_ENABLE_TESTING=ON)
|
||||
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}")
|
||||
ctest_configure( BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS -DSC_ENABLE_TESTING=ON )
|
||||
ctest_build( BUILD "${CTEST_BINARY_DIRECTORY}" )
|
||||
message("running tests")
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" INCLUDE_LABEL "cpp_schema_....*")
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" INCLUDE_LABEL "cpp_schema_....*" )
|
||||
|
||||
message("running python script")
|
||||
execute_process(COMMAND python ../misc/wiki-scripts/update-matrix.py
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY})
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
execute_process( COMMAND python ../misc/wiki-scripts/update-matrix.py
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} )
|
||||
|
||||
+175
-30
@@ -1,36 +1,181 @@
|
||||
# To build one or more schemas, configure with
|
||||
# 'cmake -DSC_BUILD_SCHEMAS="path/to/schema.exp;path/to/schema2.exp"
|
||||
# you can specify a schema in 3 ways:
|
||||
# * path relative to build dir
|
||||
# * path relative to sc/data (this dir)
|
||||
# * absolute path
|
||||
#
|
||||
# cmake goes through the above options in order until it finds one
|
||||
# that exists. if ${path} is a dir, cmake expects to find a single
|
||||
# .exp file inside, which it uses. otherwise, ${path} is assumed to
|
||||
# be an express file.
|
||||
|
||||
if(NOT "${SC_BUILD_SCHEMAS}" STREQUAL "")
|
||||
include(${SC_CMAKE_DIR}/schema_scanner/schemaScanner.cmake)
|
||||
foreach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
|
||||
get_filename_component(name ${src} NAME_WE)
|
||||
message(STATUS "Additional SDAI executable: ${name}")
|
||||
endforeach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS})
|
||||
MACRO(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
|
||||
string(REPLACE "${SC_SOURCE_DIR}" "" subpath "${current_dir}")
|
||||
string(REGEX REPLACE "^/" "" subpath "${subpath}")
|
||||
string(LENGTH "${subpath}" PATH_LENGTH)
|
||||
if(PATH_LENGTH GREATER 0)
|
||||
set(${rel_path} "..")
|
||||
get_filename_component(subpath "${subpath}" PATH)
|
||||
string(LENGTH "${subpath}" PATH_LENGTH)
|
||||
while(PATH_LENGTH GREATER 0)
|
||||
set(${rel_path} "${${rel_path}}/..")
|
||||
get_filename_component(subpath "${subpath}" PATH)
|
||||
string(LENGTH "${subpath}" PATH_LENGTH)
|
||||
endwhile(PATH_LENGTH GREATER 0)
|
||||
endif(PATH_LENGTH GREATER 0)
|
||||
ENDMACRO(RELATIVE_PATH_TO_TOPLEVEL current_dir rel_path)
|
||||
|
||||
if(SC_BUILD_SCHEMAS STREQUAL "ALL")
|
||||
file(GLOB_RECURSE SC_BUILD_SCHEMAS ${SC_SOURCE_DIR}/data/*.exp)
|
||||
endif()
|
||||
foreach(FILE ${SC_BUILD_SCHEMAS})
|
||||
# figure out an absolute path to the file
|
||||
LOCATE_SCHEMA(${FILE} abspath)
|
||||
SCHEMA_CMLIST(${abspath})
|
||||
endforeach()
|
||||
endif(NOT "${SC_BUILD_SCHEMAS}" STREQUAL "")
|
||||
# This function runs fedex on one express file. The generated source goes in a dir
|
||||
# in the build dir, and it is compiled into a library. A p21read executable is
|
||||
# compiled and linked to the lib. p21read is used to test the lib.
|
||||
FUNCTION(BUILD_A_SCHEMA SCHEMA_FILE)
|
||||
if( EXISTS "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}" ) #is it a path relative to build dir?
|
||||
set( SCHEMA_FILE "${CMAKE_BINARY_DIR}/${SCHEMA_FILE}" )
|
||||
elseif( EXISTS "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}" ) # path relative to STEPcode/data?
|
||||
set( SCHEMA_FILE "${SC_SOURCE_DIR}/data/${SCHEMA_FILE}" )
|
||||
elseif( NOT EXISTS ${SCHEMA_FILE} ) # absolute path
|
||||
message( FATAL_ERROR "Cannot find ${CMAKE_BINARY_DIR}/${SCHEMA_FILE} or ${SC_SOURCE_DIR}/data/${SCHEMA_FILE} or ${SCHEMA_FILE}" )
|
||||
endif()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
if( IS_DIRECTORY ${SCHEMA_FILE} ) #if it is a dir, look for one .exp file inside
|
||||
file(GLOB SCHEMA_FILE ${SCHEMA_FILE}/*.exp )
|
||||
endif()
|
||||
|
||||
if( NOT EXISTS ${SCHEMA_FILE} )
|
||||
message(FATAL_ERROR "Expected one express file. Found '${SCHEMA_FILE}' instead.")
|
||||
endif()
|
||||
|
||||
# read the schema name from a line like 'SCHEMA AUTOMOTIVE_DESIGN;'
|
||||
file(STRINGS ${SCHEMA_FILE} SCHEMA_STATEMENT LIMIT_COUNT 1 REGEX "^SCHEMA .*")
|
||||
string(REGEX REPLACE "^SCHEMA \(.*\)\;$" "\\1" SCHEMA_N ${SCHEMA_STATEMENT} )
|
||||
string(TOUPPER ${SCHEMA_N} SCHEMA_LONG_NAME) #exp2cxx always uses upper case for file names
|
||||
get_filename_component( SCHEMA_SN ${SCHEMA_FILE} NAME )
|
||||
string( REGEX REPLACE "\(.*\).[Ee][Xx][Pp]" "\\1" SCHEMA_SHORT_NAME ${SCHEMA_SN} )
|
||||
|
||||
project( sdai_${SCHEMA_SHORT_NAME} )
|
||||
message( STATUS "Generating code for ${SCHEMA_SHORT_NAME}.")
|
||||
set( SCHEMA_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SCHEMA_SHORT_NAME} )
|
||||
|
||||
#the names of the files that will be generated
|
||||
set( FEDEX_HEADERS ${SCHEMA_OUTPUT_DIR}/Sdaiclasses.h ${SCHEMA_OUTPUT_DIR}/schema.h
|
||||
${SCHEMA_OUTPUT_DIR}/Sdai${SCHEMA_LONG_NAME}.h )
|
||||
set( FEDEX_OUT ${SCHEMA_OUTPUT_DIR}/compstructs.cc ${SCHEMA_OUTPUT_DIR}/schema.cc
|
||||
${SCHEMA_OUTPUT_DIR}/Sdai${SCHEMA_LONG_NAME}.cc ${SCHEMA_OUTPUT_DIR}/SdaiAll.cc
|
||||
${SCHEMA_OUTPUT_DIR}/Sdai${SCHEMA_LONG_NAME}.init.cc ${FEDEX_HEADERS} )
|
||||
|
||||
install( FILES ${FEDEX_HEADERS} DESTINATION include/${SCHEMA_SHORT_NAME} )
|
||||
|
||||
# *cannot* use include_directories() because the includes keep piling up - if building
|
||||
# multiple schemas, each one will use the include dirs from all previous schemas. Since
|
||||
# one header (schema.h) is always named the same, this will not work. only workaround
|
||||
# seems to be set_target_properties( <target> PROPERTIES COMPILE_FLAGS <flags> )
|
||||
set( ${PROJECT_NAME}_COMPILE_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR} -I${SC_SOURCE_DIR}/src/cldai -I${SC_SOURCE_DIR}/src/cleditor -I${SC_SOURCE_DIR}/src/clutils -I${SCHEMA_OUTPUT_DIR} -I${SC_SOURCE_DIR}/src/clstepcore -I${SC_SOURCE_DIR}/src/base" )
|
||||
|
||||
add_custom_command( OUTPUT ${SCHEMA_OUTPUT_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E make_directory ${SCHEMA_OUTPUT_DIR}
|
||||
COMMENT "Creating ${SCHEMA_OUTPUT_DIR} for schema ${SCHEMA_SHORT_NAME}")
|
||||
add_custom_command( OUTPUT ${FEDEX_OUT}
|
||||
COMMAND exp2cxx ARGS ${SCHEMA_FILE}
|
||||
DEPENDS ${SCHEMA_FILE} ${SCHEMA_OUTPUT_DIR}
|
||||
WORKING_DIRECTORY ${SCHEMA_OUTPUT_DIR}
|
||||
COMMENT "Running exp2cxx for ${SCHEMA_SHORT_NAME}..."
|
||||
VERBATIM )
|
||||
add_custom_target( generate_cpp_${SCHEMA_SHORT_NAME} DEPENDS ${FEDEX_OUT} SOURCES ${FEDEX_OUT} )
|
||||
|
||||
if( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
|
||||
# Coverage will always be sparse on schema libs. Compiling the libs with the -fprofile-arcs and
|
||||
# -ftest-coverage is extremely slow. We can avoid that by temporarily changing build type to release.
|
||||
set( PREV_BUILD_TYPE ${CMAKE_BUILD_TYPE} )
|
||||
set( CMAKE_BUILD_TYPE "Release" )
|
||||
endif( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
|
||||
|
||||
# if testing is enabled, "TESTABLE" sets property EXCLUDE_FROM_ALL and prevents installation
|
||||
SC_ADDLIB( ${PROJECT_NAME} "${FEDEX_OUT}" "stepdai;stepcore;stepeditor;steputils;base" "TESTABLE" )
|
||||
add_dependencies( ${PROJECT_NAME} generate_cpp_${SCHEMA_SHORT_NAME} )
|
||||
set_target_properties( ${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
|
||||
${${PROJECT_NAME}_COMPILE_FLAGS} )
|
||||
if( TARGET ${PROJECT_NAME}-static )
|
||||
set_target_properties( ${PROJECT_NAME}-static PROPERTIES COMPILE_FLAGS
|
||||
${${PROJECT_NAME}_COMPILE_FLAGS} )
|
||||
endif( TARGET ${PROJECT_NAME}-static )
|
||||
|
||||
if( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
|
||||
set( CMAKE_BUILD_TYPE ${PREV_BUILD_TYPE} )
|
||||
endif( SC_ENABLE_COVERAGE AND NOT SC_COVER_SCHEMAS )
|
||||
|
||||
add_test( NAME generate_cpp_${SCHEMA_SHORT_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
--target generate_cpp_${SCHEMA_SHORT_NAME}
|
||||
--config $<CONFIGURATION> )
|
||||
add_test( NAME build_cpp_${PROJECT_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
--target p21read_${PROJECT_NAME}
|
||||
--config $<CONFIGURATION> )
|
||||
if(NOT WIN32)
|
||||
add_test( NAME build_lazy_cpp_${PROJECT_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
--target lazy_${PROJECT_NAME}
|
||||
--config $<CONFIGURATION> )
|
||||
endif(NOT WIN32)
|
||||
|
||||
# label the tests and set dependencies
|
||||
set_tests_properties( generate_cpp_${SCHEMA_SHORT_NAME} PROPERTIES LABELS cpp_schema_gen )
|
||||
if(NOT WIN32)
|
||||
set_tests_properties( build_lazy_cpp_${PROJECT_NAME} build_cpp_${PROJECT_NAME} PROPERTIES DEPENDS generate_cpp_${SCHEMA_SHORT_NAME} LABELS cpp_schema_build )
|
||||
endif(NOT WIN32)
|
||||
|
||||
RELATIVE_PATH_TO_TOPLEVEL(${CMAKE_CURRENT_SOURCE_DIR} RELATIVE_PATH_COMPONENT)
|
||||
SC_ADDEXEC( p21read_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc" "${PROJECT_NAME};base" "TESTABLE" )
|
||||
if(NOT WIN32)
|
||||
SC_ADDEXEC( lazy_${PROJECT_NAME} "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc" "${PROJECT_NAME};steplazyfile;stepeditor" "TESTABLE" )
|
||||
endif(NOT WIN32)
|
||||
add_dependencies( p21read_${PROJECT_NAME} version_string )
|
||||
if(NOT WIN32)
|
||||
add_dependencies( lazy_${PROJECT_NAME} version_string )
|
||||
endif(NOT WIN32)
|
||||
set_target_properties( p21read_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
|
||||
${${PROJECT_NAME}_COMPILE_FLAGS} )
|
||||
if(NOT WIN32)
|
||||
set_target_properties( lazy_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${${PROJECT_NAME}_COMPILE_FLAGS} -I${SC_SOURCE_DIR}/src/base/judy/src" )
|
||||
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 )
|
||||
SC_ADDEXEC( ${name}_${PROJECT_NAME} "${src}" "${PROJECT_NAME};base" "TESTABLE" )
|
||||
add_dependencies( ${name}_${PROJECT_NAME} version_string )
|
||||
set_target_properties( ${name}_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
|
||||
"${${PROJECT_NAME}_COMPILE_FLAGS} -I${path}" )
|
||||
endforeach( src ${SC_SDAI_ADDITIONAL_EXES_SRCS} )
|
||||
|
||||
#find all part 21 files in schema dir, add a test for each one
|
||||
get_filename_component( SCHEMA_DIR ${SCHEMA_FILE} PATH )
|
||||
file( GLOB_RECURSE P21_FILES ${SCHEMA_DIR}/*.stp ${SCHEMA_DIR}/*.step ${SCHEMA_DIR}/*.p21 ${SCHEMA_DIR}/*.ifc )
|
||||
foreach( TEST_FILE ${P21_FILES} )
|
||||
get_filename_component( FNAME ${TEST_FILE} NAME_WE )
|
||||
add_test( NAME read_write_cpp_${SCHEMA_SHORT_NAME}_${FNAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND p21read_${PROJECT_NAME} ${TEST_FILE} )
|
||||
set_tests_properties( read_write_cpp_${SCHEMA_SHORT_NAME}_${FNAME} PROPERTIES DEPENDS build_cpp_${PROJECT_NAME} LABELS cpp_schema_rw )
|
||||
if(NOT WIN32)
|
||||
add_test( NAME read_lazy_cpp_${SCHEMA_SHORT_NAME}_${FNAME}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMAND lazy_${PROJECT_NAME} ${TEST_FILE} )
|
||||
set_tests_properties( read_lazy_cpp_${SCHEMA_SHORT_NAME}_${FNAME} PROPERTIES DEPENDS build_lazy_cpp_${PROJECT_NAME} LABELS cpp_schema_rw )
|
||||
endif(NOT WIN32)
|
||||
endforeach()
|
||||
|
||||
ENDFUNCTION(BUILD_A_SCHEMA)
|
||||
|
||||
#----------------------------------------------------------------------------------------------------
|
||||
|
||||
if( DEFINED SC_BUILD_SCHEMAS )
|
||||
foreach( src ${SC_SDAI_ADDITIONAL_EXES_SRCS} )
|
||||
get_filename_component( name ${src} NAME_WE )
|
||||
message( STATUS "Additional SDAI executable: ${name}" )
|
||||
endforeach( src ${SC_SDAI_ADDITIONAL_EXES_SRCS} )
|
||||
|
||||
if( SC_BUILD_SCHEMAS STREQUAL "ALL" )
|
||||
file( GLOB_RECURSE SC_BUILD_SCHEMAS ${SC_SOURCE_DIR}/data/*.exp )
|
||||
endif()
|
||||
foreach( ap ${SC_BUILD_SCHEMAS} )
|
||||
BUILD_A_SCHEMA( ${ap} )
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(* This is a MODIFIED version of AP203 Amd. 1.
|
||||
The change was to remove a useless IF...ELSE...ENDIF statement that always evaluated
|
||||
the same way. Statements in the branch that were never executed caused problems with
|
||||
the same way. Statements in the branch that was never executed caused problems with
|
||||
libexpress, and it was easier to modify the schema than to come up with a generic
|
||||
fix for libexpress. This change does *not* affect the behavior of the schema.
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
SCHEMA config_control_design;
|
||||
|
||||
CONSTANT
|
||||
(* FIXME: gcc error on next statement with c99/POSIX:
|
||||
Syntax error: "(" unexpected
|
||||
*)
|
||||
dummy_gri : geometric_representation_item := representation_item('') ||
|
||||
geometric_representation_item();
|
||||
dummy_tri : topological_representation_item := representation_item('')
|
||||
|
||||
+38581
-33255
File diff suppressed because it is too large
Load Diff
+7
-15
@@ -1,20 +1,12 @@
|
||||
set(sc_MANS
|
||||
man/man1/fedex.1
|
||||
man/man1/exp2cxx.1
|
||||
)
|
||||
SET(sc_MANS
|
||||
man/man1/fedex.1
|
||||
man/man1/exp2cxx.1
|
||||
)
|
||||
|
||||
if(NOT DEFINED MAN_DIR)
|
||||
set(MAN_DIR share/man)
|
||||
endif(NOT DEFINED MAN_DIR)
|
||||
|
||||
if(NOT WIN32)
|
||||
install(FILES ${sc_MANS} DESTINATION ${MAN_DIR}/man1)
|
||||
endif(NOT WIN32)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
IF(NOT WIN32)
|
||||
INSTALL(FILES ${sc_MANS} DESTINATION ${MAN_DIR}/man1)
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
@@ -5,91 +5,87 @@
|
||||
# freely copied in part or in full for any purpose. No acknowledgment is required
|
||||
# for the use of this file.
|
||||
#
|
||||
project(AP203Minimum)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
PROJECT( AP203Minimum )
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
# Set STEPCODE_ROOT_DIR to point to the root of the STEPcode source tree.
|
||||
if(NOT DEFINED STEPCODE_ROOT_DIR)
|
||||
message(FATAL_ERROR "STEPCODE_ROOT_DIR is not defined! Set via cmake-gui or on command line:\n cmake .. -DSTEPCODE_ROOT_DIR=/path/to/sc")
|
||||
endif(NOT DEFINED STEPCODE_ROOT_DIR)
|
||||
if( NOT DEFINED STEPCODE_ROOT_DIR )
|
||||
message( FATAL_ERROR "STEPCODE_ROOT_DIR is not defined! Set via cmake-gui or on command line:\n cmake .. -DSTEPCODE_ROOT_DIR=/path/to/sc" )
|
||||
endif( NOT DEFINED STEPCODE_ROOT_DIR )
|
||||
|
||||
# STEPCODE_ROOT_DIR is relative or absolute path?
|
||||
if(EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
|
||||
set(STEPCODE_ROOT_DIR "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}")
|
||||
message("** STEPCODE_ROOT_DIR is a relative path; converted to absolute path: ${STEPCODE_ROOT_DIR}.")
|
||||
if( EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
|
||||
set( STEPCODE_ROOT_DIR "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}" )
|
||||
message( "** STEPCODE_ROOT_DIR is a relative path; converted to absolute path: ${STEPCODE_ROOT_DIR}." )
|
||||
else()
|
||||
if(NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
|
||||
message(FATAL_ERROR "**** Cannot locate STEPCODE_ROOT_DIR - try an absolute path.")
|
||||
endif(NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
|
||||
endif(EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt")
|
||||
if( NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
|
||||
message( FATAL_ERROR "**** Cannot locate STEPCODE_ROOT_DIR - try an absolute path." )
|
||||
endif( NOT EXISTS "${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
|
||||
endif( EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/SC_VERSION.txt" )
|
||||
|
||||
|
||||
# Use STEPcode as library, but build from this build process.
|
||||
set(SC_IS_SUBBUILD TRUE)
|
||||
set( SC_IS_SUBBUILD TRUE )
|
||||
|
||||
# Build type, DEBUG or RELEASE
|
||||
if(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set(SC_BUILD_TYPE ${CMAKE_BUILD_TYPE})
|
||||
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")
|
||||
set( STEPCODE_BUILD_DIR ${CMAKE_BINARY_DIR}/sc CACHE PATH "STEPcode build subdir" )
|
||||
|
||||
# STEP schema to build and link against.
|
||||
set(SCHEMA ap203)
|
||||
set(SC_BUILD_SCHEMAS ${SCHEMA} CACHE INTERNAL "Schema, internal, immutable" FORCE)
|
||||
set( SCHEMA ap203 )
|
||||
set( SC_BUILD_SCHEMAS ${SCHEMA} CACHE INTERNAL "Schema, internal, immutable" FORCE )
|
||||
|
||||
# Parse out schema name and library.
|
||||
set(SCHEMA_PATH "${STEPCODE_ROOT_DIR}/data/${SCHEMA}/*.exp")
|
||||
file(GLOB SCHEMA_FILE "${SCHEMA_PATH}")
|
||||
set( SCHEMA_PATH "${STEPCODE_ROOT_DIR}/data/${SCHEMA}/*.exp" )
|
||||
file( GLOB SCHEMA_FILE "${SCHEMA_PATH}" )
|
||||
|
||||
if(NOT EXISTS ${SCHEMA_FILE})
|
||||
message(FATAL_ERROR "Cannot find the schema; cannot continue. Looked for ${SCHEMA_PATH} from ${CMAKE_CURRENT_LIST_DIR}")
|
||||
endif(NOT EXISTS ${SCHEMA_FILE})
|
||||
if( NOT EXISTS ${SCHEMA_FILE} )
|
||||
message( FATAL_ERROR "Cannot find the schema; cannot continue. Looked for ${SCHEMA_PATH} from ${CMAKE_CURRENT_LIST_DIR}" )
|
||||
endif( NOT EXISTS ${SCHEMA_FILE} )
|
||||
|
||||
|
||||
get_filename_component(SCHEMA_SN ${SCHEMA_FILE} NAME)
|
||||
string(REGEX REPLACE "\(.*\).[Ee][Xx][Pp]" "sdai_\\1" SCHEMA_LINK_NAME ${SCHEMA_SN})
|
||||
set(STEPCODE_LIBRARIES base stepcore stepeditor stepdai steputils ${SCHEMA_LINK_NAME})
|
||||
get_filename_component( SCHEMA_SN ${SCHEMA_FILE} NAME )
|
||||
string( REGEX REPLACE "\(.*\).[Ee][Xx][Pp]" "\\1" SCHEMA_LINK_NAME ${SCHEMA_SN} )
|
||||
set( STEPCODE_LIBRARIES base stepcore stepeditor stepdai steputils sdai_${SCHEMA_LINK_NAME} )
|
||||
|
||||
# Add STEPCode project to CMake build.
|
||||
add_subdirectory(${STEPCODE_ROOT_DIR} "${CMAKE_CURRENT_BINARY_DIR}/sc" EXCLUDE_FROM_ALL)
|
||||
add_subdirectory( ${STEPCODE_ROOT_DIR} "${CMAKE_CURRENT_BINARY_DIR}/sc" EXCLUDE_FROM_ALL )
|
||||
|
||||
# Set up STEPcode include directories.
|
||||
set(STEPCODE_INCLUDE_DIR
|
||||
${STEPCODE_ROOT_DIR}/src/base
|
||||
${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}
|
||||
${STEPCODE_BUILD_DIR}/schemas/${SCHEMA_LINK_NAME}
|
||||
)
|
||||
set( STEPCODE_INCLUDE_DIR
|
||||
${STEPCODE_ROOT_DIR}/src/base
|
||||
${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}
|
||||
)
|
||||
|
||||
# Reset sane values for build destination. Otherwise, everything ends up in ${CMAKE_BINARY_DIR}/sc
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
|
||||
|
||||
include_directories(
|
||||
${STEPCODE_INCLUDE_DIR}
|
||||
)
|
||||
${STEPCODE_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
# Application sources and headers
|
||||
set(SRCS ap203min.cpp)
|
||||
set( SRCS
|
||||
ap203min.cpp
|
||||
)
|
||||
|
||||
set(HDRS )
|
||||
set( HDRS
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SRCS} ${HDRS})
|
||||
add_executable( ${PROJECT_NAME} ${SRCS} ${HDRS} )
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${STEPCODE_LIBRARIES})
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
target_link_libraries( ${PROJECT_NAME} ${STEPCODE_LIBRARIES} )
|
||||
|
||||
set_target_properties( ${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-I${STEPCODE_BUILD_DIR}/data/${SCHEMA_LINK_NAME}" )
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
// $./AP203Minimum
|
||||
// AP203Minimum outfile.stp
|
||||
|
||||
|
||||
extern void
|
||||
SchemaInit( class Registry & );
|
||||
|
||||
#include <STEPfile.h>
|
||||
#include <sdai.h>
|
||||
#include <STEPattribute.h>
|
||||
|
||||
+11
-19
@@ -1,4 +1,4 @@
|
||||
set(express_HDRS
|
||||
SET(express_HDRS
|
||||
express/alg.h
|
||||
express/basic.h
|
||||
express/caseitem.h
|
||||
@@ -20,29 +20,21 @@ set(express_HDRS
|
||||
express/symbol.h
|
||||
express/type.h
|
||||
express/variable.h
|
||||
)
|
||||
)
|
||||
install(FILES ${express_HDRS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/express)
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/express)
|
||||
|
||||
set(exppp_HDRS
|
||||
SET(exppp_HDRS
|
||||
exppp/exppp.h
|
||||
)
|
||||
)
|
||||
install(FILES ${exppp_HDRS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/exppp)
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/exppp)
|
||||
|
||||
install(FILES ordered_attrs.h
|
||||
sc_export.h
|
||||
sc_stdbool.h
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
|
||||
sc_export.h
|
||||
sc_stdbool.h
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
|
||||
|
||||
install(FILES ${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_cf.h
|
||||
${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
${SC_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode)
|
||||
|
||||
@@ -69,7 +69,7 @@ struct tag {
|
||||
|
||||
/** location of fulltext of algorithm in source file */
|
||||
struct FullText {
|
||||
const char * filename;
|
||||
char * filename;
|
||||
unsigned int start, end;
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ typedef struct Error_Warning_ {
|
||||
/********************/
|
||||
|
||||
extern SC_EXPRESS_EXPORT bool __ERROR_buffer_errors;
|
||||
extern SC_EXPRESS_EXPORT const char * current_filename;
|
||||
extern SC_EXPRESS_EXPORT char * current_filename;
|
||||
|
||||
/* flag to remember whether non-warning errors have occurred */
|
||||
extern SC_EXPRESS_EXPORT bool ERRORoccurred;
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
#ifndef EXP_KW_H
|
||||
#define EXP_KW_H
|
||||
|
||||
#include "sc_export.h"
|
||||
|
||||
extern SC_EXPRESS_EXPORT char * KW_ABS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ABSTRACT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ACOS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_AGGREGATE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ALIAS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_AND;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ANDOR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ARRAY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_AS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ASIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ATAN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BAG;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BEGIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BINARY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BLENGTH;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BOOLEAN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CASE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CONST_E;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CONSTANT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CONTEXT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_COS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_DERIVE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_DIV;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ELSE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_ALIAS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_CASE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_CONSTANT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_CONTEXT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_ENTITY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_FUNCTION;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_IF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_LOCAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_MODEL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_PROCEDURE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_REPEAT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_RULE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_SCHEMA;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_TYPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ENTITY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ENUMERATION;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ESCAPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_EXISTS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_EXP;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FALSE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FIXED;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FOR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FORMAT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FROM;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FUNCTION;
|
||||
extern SC_EXPRESS_EXPORT char * KW_GENERIC;
|
||||
extern SC_EXPRESS_EXPORT char * KW_HIBOUND;
|
||||
extern SC_EXPRESS_EXPORT char * KW_HIINDEX;
|
||||
extern SC_EXPRESS_EXPORT char * KW_IF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_IN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INCLUDE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INSERT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INTEGER;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INVERSE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LENGTH;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LIKE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LIST;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOBOUND;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOCAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOG;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOG10;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOG2;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOGICAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOINDEX;
|
||||
extern SC_EXPRESS_EXPORT char * KW_MOD;
|
||||
extern SC_EXPRESS_EXPORT char * KW_MODEL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_NOT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_NUMBER;
|
||||
extern SC_EXPRESS_EXPORT char * KW_NVL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ODD;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ONEOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OPTIONAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OTHERWISE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_PI;
|
||||
extern SC_EXPRESS_EXPORT char * KW_PROCEDURE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_QUERY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REFERENCE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REMOVE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REPEAT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_RETURN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ROLESOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_RULE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SCHEMA;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SELECT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SELF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SET;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SIZEOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SKIP;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SQRT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_STRING;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SUBTYPE;
|
||||
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_TRUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TYPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TYPEOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_UNIQUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_UNKNOWN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_UNTIL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_USE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_USEDIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VALUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VALUE_IN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VALUE_UNIQUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VAR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_WHERE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_WHILE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_XOR;
|
||||
|
||||
#endif /* EXP_KW_H */
|
||||
+125
-2
@@ -115,6 +115,127 @@ extern SC_EXPRESS_EXPORT Error ERROR_warn_small_real;
|
||||
extern SC_EXPRESS_EXPORT struct Scope_ * FUNC_NVL;
|
||||
extern SC_EXPRESS_EXPORT struct Scope_ * FUNC_USEDIN;
|
||||
|
||||
extern SC_EXPRESS_EXPORT char * KW_ABS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ABSTRACT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ACOS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_AGGREGATE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ALIAS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_AND;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ANDOR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ARRAY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_AS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ASIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ATAN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BAG;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BEGIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BINARY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BLENGTH;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BOOLEAN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_BY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CASE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CONST_E;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CONSTANT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_CONTEXT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_COS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_DERIVE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_DIV;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ELSE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_ALIAS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_CASE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_CONSTANT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_CONTEXT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_ENTITY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_FUNCTION;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_IF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_LOCAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_MODEL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_PROCEDURE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_REPEAT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_RULE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_SCHEMA;
|
||||
extern SC_EXPRESS_EXPORT char * KW_END_TYPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ENTITY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ENUMERATION;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ESCAPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_EXISTS;
|
||||
extern SC_EXPRESS_EXPORT char * KW_EXP;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FALSE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FIXED;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FOR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FORMAT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FROM;
|
||||
extern SC_EXPRESS_EXPORT char * KW_FUNCTION;
|
||||
extern SC_EXPRESS_EXPORT char * KW_GENERIC;
|
||||
extern SC_EXPRESS_EXPORT char * KW_HIBOUND;
|
||||
extern SC_EXPRESS_EXPORT char * KW_HIINDEX;
|
||||
extern SC_EXPRESS_EXPORT char * KW_IF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_IN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INCLUDE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INSERT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INTEGER;
|
||||
extern SC_EXPRESS_EXPORT char * KW_INVERSE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LENGTH;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LIKE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LIST;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOBOUND;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOCAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOG;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOG10;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOG2;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOGICAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_LOINDEX;
|
||||
extern SC_EXPRESS_EXPORT char * KW_MOD;
|
||||
extern SC_EXPRESS_EXPORT char * KW_MODEL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_NOT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_NUMBER;
|
||||
extern SC_EXPRESS_EXPORT char * KW_NVL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ODD;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ONEOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OPTIONAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_OTHERWISE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_PI;
|
||||
extern SC_EXPRESS_EXPORT char * KW_PROCEDURE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_QUERY;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REAL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REFERENCE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REMOVE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_REPEAT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_RETURN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_ROLESOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_RULE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SCHEMA;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SELECT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SELF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SET;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SIZEOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SKIP;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SQRT;
|
||||
extern SC_EXPRESS_EXPORT char * KW_STRING;
|
||||
extern SC_EXPRESS_EXPORT char * KW_SUBTYPE;
|
||||
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_TRUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TYPE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_TYPEOF;
|
||||
extern SC_EXPRESS_EXPORT char * KW_UNIQUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_UNKNOWN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_UNTIL;
|
||||
extern SC_EXPRESS_EXPORT char * KW_USE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_USEDIN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VALUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VALUE_IN;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VALUE_UNIQUE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_VAR;
|
||||
extern SC_EXPRESS_EXPORT char * KW_WHERE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_WHILE;
|
||||
extern SC_EXPRESS_EXPORT char * KW_XOR;
|
||||
|
||||
/******************************/
|
||||
/* macro function definitions */
|
||||
/******************************/
|
||||
@@ -134,9 +255,11 @@ extern SC_EXPRESS_EXPORT void EXPRESSparse PROTO( ( Express, FILE *, ch
|
||||
extern SC_EXPRESS_EXPORT void EXPRESSinitialize PROTO( ( void ) );
|
||||
extern SC_EXPRESS_EXPORT void EXPRESScleanup PROTO( ( void ) );
|
||||
extern SC_EXPRESS_EXPORT void EXPRESSresolve PROTO( ( Express ) );
|
||||
extern SC_EXPRESS_EXPORT int EXPRESS_fail( Express model );
|
||||
extern SC_EXPRESS_EXPORT int EXPRESS_succeed( Express model );
|
||||
extern SC_EXPRESS_EXPORT char * EXPRESSversion PROTO( ( void ) );
|
||||
extern SC_EXPRESS_EXPORT int EXPRESS_fail PROTO( ( Express ) );
|
||||
extern SC_EXPRESS_EXPORT int EXPRESS_succeed PROTO( ( Express ) );
|
||||
extern void EXPRESSinit_init PROTO( ( void ) );
|
||||
extern SC_EXPRESS_EXPORT void EXPRESSusage( int _exit ); /**< exit unless _exit is non-zero */
|
||||
extern SC_EXPRESS_EXPORT void build_complex( Express );
|
||||
|
||||
#endif /*EXPRESS_H*/
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef INFO_H
|
||||
#define INFO_H
|
||||
|
||||
#include "sc_export.h"
|
||||
/** \file info.h
|
||||
* informative functions that were in express.c/express.h
|
||||
*/
|
||||
|
||||
extern SC_EXPRESS_EXPORT char * EXPRESSversion( void );
|
||||
|
||||
/** print usage message, then exit if _exit is non-zero */
|
||||
extern SC_EXPRESS_EXPORT void EXPRESSusage( int _exit );
|
||||
|
||||
#endif /* INFO_H */
|
||||
@@ -58,7 +58,7 @@ typedef struct Scan_Buffer {
|
||||
#endif
|
||||
char * savedPos;
|
||||
FILE * file;
|
||||
const char * filename;
|
||||
char * filename;
|
||||
bool readEof;
|
||||
int lineno;
|
||||
int bol;
|
||||
|
||||
@@ -129,8 +129,6 @@ extern SC_EXPRESS_EXPORT void LISTinitialize PROTO( ( void ) );
|
||||
extern SC_EXPRESS_EXPORT void LISTcleanup PROTO( ( void ) );
|
||||
extern SC_EXPRESS_EXPORT Linked_List LISTcreate PROTO( ( void ) );
|
||||
extern SC_EXPRESS_EXPORT Linked_List LISTcopy PROTO( ( Linked_List ) );
|
||||
extern SC_EXPRESS_EXPORT void LISTsort PROTO( ( Linked_List, int (*comp)(void*, void*) ) );
|
||||
extern SC_EXPRESS_EXPORT void LISTswap PROTO( ( Link, Link ) );
|
||||
extern SC_EXPRESS_EXPORT Generic LISTadd_first PROTO( ( Linked_List, Generic ) );
|
||||
extern SC_EXPRESS_EXPORT Generic LISTadd_last PROTO( ( Linked_List, Generic ) );
|
||||
extern SC_EXPRESS_EXPORT Generic LISTadd_after PROTO( ( Linked_List, Link, Generic ) );
|
||||
|
||||
@@ -59,7 +59,7 @@ typedef struct Symbol_ Symbol;
|
||||
|
||||
struct Symbol_ {
|
||||
char * name;
|
||||
const char * filename;
|
||||
char * filename;
|
||||
int line;
|
||||
char resolved;
|
||||
};
|
||||
@@ -89,6 +89,6 @@ extern SC_EXPRESS_EXPORT struct freelist_head SYMBOL_fl;
|
||||
/***********************/
|
||||
|
||||
extern SC_EXPRESS_EXPORT void SYMBOLinitialize PROTO( ( void ) );
|
||||
SC_EXPRESS_EXPORT Symbol * SYMBOLcreate( char * name, int line, const char * filename );
|
||||
SC_EXPRESS_EXPORT Symbol * SYMBOLcreate( char * name, int line, char * filename );
|
||||
|
||||
#endif /* SYMBOL_H */
|
||||
|
||||
@@ -164,7 +164,6 @@ struct TypeBody_ {
|
||||
* element = expression [ ':' repetition ] .
|
||||
* TODO exp2cxx and exp2py do not use this! Are all use cases handled by libexppp?
|
||||
*/
|
||||
unsigned var : 1; /** denotes variable marked 'VAR' - i.e. one where changes are propagated back to the caller */
|
||||
unsigned encoded : 1; /**< encoded string */
|
||||
} flags;
|
||||
Type base; /**< underlying base type if any can also contain true type if this type is a type reference */
|
||||
|
||||
@@ -79,7 +79,7 @@ struct Variable_ {
|
||||
Expression name; /**< Symbol is inside of 'name' */
|
||||
Type type;
|
||||
Expression initializer; /**< or 'derived' */
|
||||
int offset; /**< used for attr order in Entitys, and for decl order in LOCAL vars. these two uses should never conflict! */
|
||||
int offset;
|
||||
|
||||
struct {
|
||||
unsigned int optional : 1; /**< OPTIONAL keyword */
|
||||
|
||||
+29
-37
@@ -1,15 +1,15 @@
|
||||
# lcov.cmake
|
||||
# `ctest -S lcov.cmake`
|
||||
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
message(FATAL_ERROR "LCOV is Linux-only")
|
||||
endif(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
if( NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
|
||||
message( FATAL_ERROR "LCOV is Linux-only" )
|
||||
endif( NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
|
||||
|
||||
set(CTEST_SOURCE_DIRECTORY .)
|
||||
set(CTEST_BINARY_DIRECTORY build_lcov)
|
||||
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
|
||||
set(CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind)
|
||||
set(CTEST_INITIAL_CACHE "
|
||||
set( CTEST_SOURCE_DIRECTORY . )
|
||||
set( CTEST_BINARY_DIRECTORY build_lcov )
|
||||
set( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
|
||||
set( CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind )
|
||||
set( CTEST_INITIAL_CACHE "
|
||||
SITE:STRING=${CTEST_SITE}
|
||||
BUILDNAME:STRING=${CTEST_BUILD_NAME}
|
||||
SC_ENABLE_TESTING:BOOL=ON
|
||||
@@ -18,50 +18,42 @@ SC_BUILD_SCHEMAS:STRING=ALL
|
||||
SC_BUILD_TYPE:STRING=Debug
|
||||
")
|
||||
|
||||
set(LCOV_OUT "${CTEST_BINARY_DIRECTORY}/lcov_html")
|
||||
set( LCOV_OUT "${CTEST_BINARY_DIRECTORY}/lcov_html" )
|
||||
|
||||
ctest_start(lcov)
|
||||
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
|
||||
message("configuring...")
|
||||
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS "-DSC_BUILD_SCHEMAS=ALL;-DSC_ENABLE_COVERAGE=ON;-SC_PYTHON_GENERATOR=OFF")
|
||||
ctest_configure( BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS "-DSC_BUILD_SCHEMAS=ALL;-DSC_ENABLE_COVERAGE=ON;-SC_PYTHON_GENERATOR=OFF" )
|
||||
message("lcov: resetting counters...")
|
||||
execute_process(COMMAND lcov -z -d .
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET)
|
||||
execute_process( COMMAND lcov -z -d .
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET )
|
||||
|
||||
# copy files so lcov won't complain
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy src/express/expparse.y ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy src/express/expscan.l ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir)
|
||||
execute_process( COMMAND ${CMAKE_COMMAND} -E copy src/express/expparse.y ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir )
|
||||
execute_process( COMMAND ${CMAKE_COMMAND} -E copy src/express/expscan.l ${CTEST_BINARY_DIRECTORY}/src/express/CMakeFiles/express.dir )
|
||||
|
||||
message("building...")
|
||||
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}")
|
||||
ctest_build( BUILD "${CTEST_BINARY_DIRECTORY}" )
|
||||
|
||||
message("running tests...")
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" PARALLEL_LEVEL 1)
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" PARALLEL_LEVEL 1 )
|
||||
|
||||
message("analyzing profiling data using lcov...")
|
||||
execute_process(COMMAND lcov -c -d . -o stepcode.lcov
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET)
|
||||
message( "analyzing profiling data using lcov..." )
|
||||
execute_process( COMMAND lcov -c -d . -o stepcode.lcov
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET )
|
||||
|
||||
message("removing system headers...")
|
||||
execute_process(COMMAND lcov -r stepcode.lcov "/usr/include/*" -o stepcode_no_usr.lcov
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${LCOV_OUT})
|
||||
execute_process( COMMAND lcov -r stepcode.lcov "/usr/include/*" -o stepcode_no_usr.lcov
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY} OUTPUT_QUIET ERROR_QUIET )
|
||||
execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${LCOV_OUT} )
|
||||
|
||||
message("creating html files...")
|
||||
execute_process(COMMAND genhtml ../stepcode_no_usr.lcov
|
||||
WORKING_DIRECTORY ${LCOV_OUT} OUTPUT_QUIET ERROR_QUIET)
|
||||
message( "creating html files..." )
|
||||
execute_process( COMMAND genhtml ../stepcode_no_usr.lcov
|
||||
WORKING_DIRECTORY ${LCOV_OUT} OUTPUT_QUIET ERROR_QUIET )
|
||||
|
||||
message("html files are located in ${LCOV_OUT}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar czf ${LCOV_OUT}.tgz ${LCOV_OUT} WORKING_DIRECTORY ${CTEST_SOURCE_DIRECTORY})
|
||||
message( "html files are located in ${LCOV_OUT}" )
|
||||
execute_process( COMMAND ${CMAKE_COMMAND} -E tar czf ${LCOV_OUT}.tgz ${LCOV_OUT} WORKING_DIRECTORY ${CTEST_SOURCE_DIRECTORY} )
|
||||
|
||||
message("tarball at ${LCOV_OUT}.tgz")
|
||||
|
||||
message("================================================ Success! ================================================")
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
message( "tarball at ${LCOV_OUT}.tgz" )
|
||||
|
||||
message( "================================================ Success! ================================================" )
|
||||
|
||||
+58
-66
@@ -1,11 +1,11 @@
|
||||
# run_ctest.cmake
|
||||
# `ctest -S run_ctest.cmake`
|
||||
|
||||
set(CTEST_SOURCE_DIRECTORY .)
|
||||
set(CTEST_BINARY_DIRECTORY build_ctest)
|
||||
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
|
||||
set(CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind)
|
||||
set(CTEST_INITIAL_CACHE "
|
||||
set( CTEST_SOURCE_DIRECTORY . )
|
||||
set( CTEST_BINARY_DIRECTORY build_ctest )
|
||||
set( CTEST_CMAKE_GENERATOR "Unix Makefiles" )
|
||||
set( CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind )
|
||||
set( CTEST_INITIAL_CACHE "
|
||||
SITE:STRING=${CTEST_SITE}
|
||||
BUILDNAME:STRING=${CTEST_BUILD_NAME}
|
||||
SC_ENABLE_TESTING:BOOL=ON
|
||||
@@ -14,11 +14,11 @@ SC_BUILD_TYPE:STRING=Debug
|
||||
|
||||
|
||||
|
||||
if(EXISTS "../.SC_CTEST_PREFS.cmake")
|
||||
include("../.SC_CTEST_PREFS.cmake")
|
||||
if( EXISTS "../.SC_CTEST_PREFS.cmake" )
|
||||
include( "../.SC_CTEST_PREFS.cmake" )
|
||||
else()
|
||||
message(WARNING "Did not find ../.SC_CTEST_PREFS.cmake, containing config variables - result submission disabled")
|
||||
set(SKIP_SUBMISSION TRUE)
|
||||
message( WARNING "Did not find ../.SC_CTEST_PREFS.cmake, containing config variables - result submission disabled" )
|
||||
set( SKIP_SUBMISSION TRUE )
|
||||
endif()
|
||||
|
||||
######################################################
|
||||
@@ -26,8 +26,8 @@ endif()
|
||||
# use config variables such as these in
|
||||
# ../.SC_CTEST_PREFS.cmake
|
||||
#
|
||||
#set(CTEST_SITE "username")
|
||||
#set(CTEST_BUILD_NAME "build type, os, arch")
|
||||
#set( CTEST_SITE "username")
|
||||
#set( CTEST_BUILD_NAME "build type, os, arch")
|
||||
#
|
||||
#
|
||||
# setting any of these to true causes that set of tests
|
||||
@@ -44,11 +44,11 @@ endif()
|
||||
######################################################
|
||||
|
||||
|
||||
function(SUBMIT_TEST part)
|
||||
if(NOT SKIP_SUBMISSION)
|
||||
ctest_submit(PARTS ${part})
|
||||
endif()
|
||||
endfunction(SUBMIT_TEST part)
|
||||
function( SUBMIT_TEST part )
|
||||
if( NOT SKIP_SUBMISSION )
|
||||
ctest_submit( PARTS ${part} )
|
||||
endif()
|
||||
endfunction( SUBMIT_TEST part )
|
||||
|
||||
######################################################
|
||||
##### To disable reporting of a set of tests, comment
|
||||
@@ -56,73 +56,65 @@ endfunction(SUBMIT_TEST part)
|
||||
##### the set you wish to disable.
|
||||
#####
|
||||
##### To do this for all tests:
|
||||
##### set(SKIP_SUBMISSION TRUE)
|
||||
##### set( SKIP_SUBMISSION TRUE )
|
||||
######################################################
|
||||
|
||||
ctest_start(Experimental)
|
||||
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
|
||||
|
||||
file(WRITE "${CTEST_BINARY_DIRECTORY}/CTestCustom.cmake" "
|
||||
set(CTEST_CUSTOM_ERROR_EXCEPTION \"{standard input}:[0-9][0-9]*: WARNING: \")
|
||||
set( CTEST_CUSTOM_ERROR_EXCEPTION \"{standard input}:[0-9][0-9]*: WARNING: \")
|
||||
")
|
||||
|
||||
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND OPTIONS -DSC_ENABLE_TESTING=ON)
|
||||
SUBMIT_TEST(Configure)
|
||||
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
|
||||
SUBMIT_TEST(Build)
|
||||
# ctest_memcheck(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
|
||||
ctest_configure( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND OPTIONS -DSC_ENABLE_TESTING=ON )
|
||||
SUBMIT_TEST( Configure )
|
||||
ctest_build( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND )
|
||||
SUBMIT_TEST( Build )
|
||||
# ctest_memcheck( BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res )
|
||||
|
||||
if(NOT SKIP_TEST_UNITARY_SCHEMAS)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "unitary_schemas")
|
||||
SUBMIT_TEST(Test)
|
||||
if(NOT SKIP_TEST_UNITARY_SCHEMAS )
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "unitary_schemas" )
|
||||
SUBMIT_TEST( Test )
|
||||
endif()
|
||||
|
||||
if(NOT SKIP_CPP_TEST_SCHEMA_GEN)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_gen")
|
||||
SUBMIT_TEST(Test)
|
||||
if(NOT SKIP_CPP_TEST_SCHEMA_BUILD)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_build")
|
||||
SUBMIT_TEST(Test)
|
||||
if(NOT SKIP_CPP_TEST_SCHEMA_RW)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_rw")
|
||||
SUBMIT_TEST(Test)
|
||||
if(NOT SKIP_CPP_TEST_SCHEMA_GEN )
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_gen" )
|
||||
SUBMIT_TEST( Test )
|
||||
if(NOT SKIP_CPP_TEST_SCHEMA_BUILD )
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_build" )
|
||||
SUBMIT_TEST( Test )
|
||||
if(NOT SKIP_CPP_TEST_SCHEMA_RW )
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_rw" )
|
||||
SUBMIT_TEST( Test )
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT SKIP_TEST_EXCHANGE_FILE)
|
||||
if(SKIP_CPP_TEST_SCHEMA_BUILD)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE "build_cpp_sdai_AP214E3_2010")
|
||||
SUBMIT_TEST(Test)
|
||||
endif()
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "exchange_file")
|
||||
SUBMIT_TEST(Test)
|
||||
if(NOT SKIP_TEST_EXCHANGE_FILE )
|
||||
if( SKIP_CPP_TEST_SCHEMA_BUILD )
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE "build_cpp_sdai_AP214E3_2010" )
|
||||
SUBMIT_TEST( Test )
|
||||
endif()
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "exchange_file" )
|
||||
SUBMIT_TEST( Test )
|
||||
endif()
|
||||
|
||||
if(NOT SKIP_TEST_CPP_SCHEMA_SPECIFIC)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_specific")
|
||||
SUBMIT_TEST(Test)
|
||||
if(NOT SKIP_TEST_CPP_SCHEMA_SPECIFIC )
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_schema_specific" )
|
||||
SUBMIT_TEST( Test )
|
||||
endif()
|
||||
|
||||
if(NOT SKIP_TEST_CPP_UNIT)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_unit_....*")
|
||||
SUBMIT_TEST(Test)
|
||||
if(NOT SKIP_TEST_CPP_UNIT )
|
||||
ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}" APPEND
|
||||
INCLUDE_LABEL "cpp_unit_....*" )
|
||||
SUBMIT_TEST( Test )
|
||||
endif()
|
||||
|
||||
# ctest_coverage()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
# ctest_coverage( )
|
||||
|
||||
+27
-37
@@ -1,55 +1,45 @@
|
||||
|
||||
set(SC_BASE_SOURCES
|
||||
sc_memmgr.cc
|
||||
sc_trace_fprintf.c
|
||||
sc_getopt.cc
|
||||
sc_benchmark.cc
|
||||
sc_mkdir.c
|
||||
)
|
||||
sc_memmgr.cc
|
||||
sc_trace_fprintf.c
|
||||
sc_getopt.cc
|
||||
sc_benchmark.cc
|
||||
)
|
||||
|
||||
set(SC_BASE_HDRS
|
||||
sc_benchmark.h
|
||||
sc_memmgr.h
|
||||
sc_getopt.h
|
||||
sc_trace_fprintf.h
|
||||
sc_stdbool.h
|
||||
sc_mkdir.h
|
||||
)
|
||||
sc_benchmark.h
|
||||
sc_memmgr.h
|
||||
sc_getopt.h
|
||||
sc_trace_fprintf.h
|
||||
sc_stdbool.h
|
||||
)
|
||||
|
||||
if(MINGW OR MSVC OR BORLAND)
|
||||
add_definitions(-DSC_BASE_DLL_EXPORTS)
|
||||
add_definitions( -DSC_BASE_DLL_EXPORTS )
|
||||
endif()
|
||||
|
||||
if (${SC_MEMMGR_ENABLE_CHECKS})
|
||||
add_definitions(-DSC_MEMMGR_ENABLE_CHECKS)
|
||||
add_definitions( -DSC_MEMMGR_ENABLE_CHECKS )
|
||||
endif()
|
||||
|
||||
SC_ADDLIB(base "${SC_BASE_SOURCES}" "")
|
||||
|
||||
if(MINGW OR MSVC OR BORLAND)
|
||||
target_link_libraries(base psapi.lib)
|
||||
target_link_libraries(base psapi.lib)
|
||||
endif()
|
||||
|
||||
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src")
|
||||
message("Judy array source code not found. Downloading (don't sweat, it's public domain)...")
|
||||
file(DOWNLOAD "http://github.com/mpictor/judy-template/archive/master.tar.gz"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz" SHOW_PROGRESS)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
)
|
||||
file(RENAME judy-template-master judy)
|
||||
file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz")
|
||||
message("Judy array source code extracted.")
|
||||
endif(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src")
|
||||
if(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src" )
|
||||
message( "Judy array source code not found. Downloading (don't sweat, it's public domain)..." )
|
||||
file( DOWNLOAD "http://github.com/mpictor/judy-template/archive/master.tar.gz"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz" SHOW_PROGRESS )
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
)
|
||||
file( RENAME judy-template-master judy )
|
||||
file( REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/judy.tar.gz" )
|
||||
message( "Judy array source code extracted." )
|
||||
endif(NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/judy/src" )
|
||||
|
||||
install(FILES ${SC_BASE_HDRS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/base)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/base)
|
||||
|
||||
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8)
|
||||
project( JudyTemplates )
|
||||
|
||||
if( NOT DEFINED CMAKE_BUILD_TYPE )
|
||||
# set( CMAKE_BUILD_TYPE "RelWithDebInfo" ) #optimize, but include debug info
|
||||
set( CMAKE_BUILD_TYPE "Release" )
|
||||
# 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 )
|
||||
@@ -12,29 +12,29 @@ 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" )
|
||||
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 )
|
||||
#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 )
|
||||
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 )
|
||||
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} )
|
||||
@@ -42,37 +42,29 @@ add_library( judy_lib STATIC ${JUDYS_SOURCES} )
|
||||
include_directories( src )
|
||||
|
||||
if( ENABLE_TESTING )
|
||||
include( CTest )
|
||||
include_directories( test )
|
||||
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( 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( 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( 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( 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 )
|
||||
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
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <ios>
|
||||
|
||||
/// mem values in kb, times in ms (granularity may be higher than 1ms)
|
||||
benchVals getMemAndTime( ) {
|
||||
|
||||
@@ -38,6 +38,11 @@ extern "C" {
|
||||
* depends on getMemAndTime() above - may not work on all platforms.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
template class SC_BASE_EXPORT std::allocator<char>;
|
||||
template class SC_BASE_EXPORT std::basic_string<char, std::char_traits<char>, std::allocator<char> >;
|
||||
#endif
|
||||
|
||||
class SC_BASE_EXPORT benchmark {
|
||||
protected:
|
||||
benchVals initialVals, laterVals;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
#include "sc_mkdir.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#ifdef _WIN32
|
||||
# include <direct.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* cross-platform mkdir */
|
||||
int sc_mkdir( const char * path ) {
|
||||
#ifdef _WIN32
|
||||
return mkdir( path );
|
||||
#else
|
||||
return mkdir( path, 0777 );
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
/* return -1 if error, 0 if created, 1 if dir existed already */
|
||||
int mkDirIfNone( const char * path ) {
|
||||
struct stat s;
|
||||
if( stat( path, &s ) != 0 ) {
|
||||
if( errno == ENOENT ) {
|
||||
return sc_mkdir( path );
|
||||
}
|
||||
} else if( s.st_mode & S_IFDIR ) {
|
||||
return 1;
|
||||
}
|
||||
/* either stat returned an error other than ENOENT, or 'path' exists but isn't a dir */
|
||||
return -1;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef SC_MKDIR
|
||||
#define SC_MKDIR
|
||||
|
||||
#include <sc_export.h>
|
||||
|
||||
/** cross-platform mkdir() */
|
||||
SC_BASE_EXPORT int sc_mkdir( const char * path );
|
||||
|
||||
/** create a dir 'path' if 'path' doesn't exist
|
||||
* \return -1 if error, 0 if created, 1 if dir existed already
|
||||
* if it returns -1, check errno
|
||||
*/
|
||||
SC_BASE_EXPORT int mkDirIfNone( const char * path );
|
||||
|
||||
#endif /* SC_MKDIR */
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef SC_STRTOULL_H
|
||||
#define SC_STRTOULL_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# define strtoull _strtoui64
|
||||
# define ULLONG_MAX _UI64_MAX
|
||||
#endif
|
||||
|
||||
#endif /* SC_STRTOULL_H */
|
||||
+30
-44
@@ -1,54 +1,40 @@
|
||||
|
||||
set(LIBSTEPDAI_SRCS
|
||||
sdaiApplication_instance_set.cc
|
||||
sdaiBinary.cc
|
||||
sdaiDaObject.cc
|
||||
sdaiEntity_extent.cc
|
||||
sdaiEntity_extent_set.cc
|
||||
sdaiEnum.cc
|
||||
sdaiModel_contents.cc
|
||||
sdaiModel_contents_list.cc
|
||||
sdaiObject.cc
|
||||
sdaiSession_instance.cc
|
||||
sdaiSet.cc
|
||||
sdaiString.cc
|
||||
)
|
||||
sdaiApplication_instance_set.cc
|
||||
sdaiBinary.cc
|
||||
sdaiDaObject.cc
|
||||
sdaiEntity_extent.cc
|
||||
sdaiEntity_extent_set.cc
|
||||
sdaiEnum.cc
|
||||
sdaiModel_contents.cc
|
||||
sdaiModel_contents_list.cc
|
||||
sdaiObject.cc
|
||||
sdaiSession_instance.cc
|
||||
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
|
||||
sdaiSet.h
|
||||
sdaiString.h
|
||||
)
|
||||
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}
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
|
||||
SC_ADDLIB(stepdai "${LIBSTEPDAI_SRCS}" "steputils;base")
|
||||
if(HAVE_STD_THREAD)
|
||||
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
|
||||
set_target_properties(stepdai PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
|
||||
endif(HAVE_STD_THREAD)
|
||||
|
||||
install(FILES ${SC_CLDAI_HDRS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cldai)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cldai)
|
||||
|
||||
@@ -41,13 +41,99 @@ extern "C"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
SDAI_Application_instance__set::SDAI_Application_instance__set( int defaultSize ) : SDAI__set( defaultSize ) {
|
||||
SDAI_Application_instance__set::SDAI_Application_instance__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new SDAI_Application_instance_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
SDAI_Application_instance__set::~SDAI_Application_instance__set() {
|
||||
delete _buf;
|
||||
}
|
||||
|
||||
void SDAI_Application_instance__set::Check( int index ) {
|
||||
SDAI_Application_instance_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new SDAI_Application_instance_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( SDAI_Application_instance_ptr ) );
|
||||
delete _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void SDAI_Application_instance__set::Insert( SDAI_Application_instance_ptr v, int index ) {
|
||||
SDAI_Application_instance_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Application_instance_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_Application_instance__set::Append( SDAI_Application_instance_ptr v ) {
|
||||
int index = _count;
|
||||
SDAI_Application_instance_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Application_instance_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_Application_instance__set::Remove( int index ) {
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
SDAI_Application_instance_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_Application_instance_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
void SDAI_Application_instance__set::Remove( SDAI_Application_instance_ptr a ) {
|
||||
int index = Index( a );
|
||||
if( !( index < 0 ) ) {
|
||||
Remove( index );
|
||||
}
|
||||
}
|
||||
|
||||
int SDAI_Application_instance__set::Index( SDAI_Application_instance_ptr v ) {
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDAI_Application_instance_ptr & SDAI_Application_instance__set::operator[]( int index ) {
|
||||
return ( SDAI_Application_instance_ptr & )SDAI__set::operator[]( index );
|
||||
Check( index );
|
||||
// _count = max(_count, index+1);
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int
|
||||
SDAI_Application_instance__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void
|
||||
SDAI_Application_instance__set::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,26 @@ class SDAI_Application_instance__set;
|
||||
typedef SDAI_Application_instance__set * SDAI_Application_instance__set_ptr;
|
||||
typedef SDAI_Application_instance__set_ptr SDAI_Application_instance__set_var;
|
||||
|
||||
class SC_DAI_EXPORT SDAI_Application_instance__set : public SDAI__set {
|
||||
class SC_DAI_EXPORT SDAI_Application_instance__set {
|
||||
public:
|
||||
SDAI_Application_instance__set( int = 16 );
|
||||
~SDAI_Application_instance__set();
|
||||
|
||||
SDAI_Application_instance *& operator[]( int index );
|
||||
void Insert( SDAI_Application_instance *, int index );
|
||||
void Append( SDAI_Application_instance * );
|
||||
void Remove( int index );
|
||||
void Remove( SDAI_Application_instance * );
|
||||
int Index( SDAI_Application_instance * );
|
||||
|
||||
int Count();
|
||||
void Clear();
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
SDAI_Application_instance ** _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,10 +78,83 @@ SDAI_DAObject_SDAI::~SDAI_DAObject_SDAI() {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
SDAI_DAObject__set::SDAI_DAObject__set( int defaultSize ) : SDAI__set( defaultSize ){
|
||||
SDAI_DAObject__set::SDAI_DAObject__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new SDAI_DAObject_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
SDAI_DAObject__set::~SDAI_DAObject__set() {
|
||||
delete _buf;
|
||||
}
|
||||
|
||||
void SDAI_DAObject__set::Check( int index ) {
|
||||
|
||||
SDAI_DAObject_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new SDAI_DAObject_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( SDAI_DAObject_ptr ) );
|
||||
delete _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDAI_DAObject__set::Insert( SDAI_DAObject_ptr v, int index ) {
|
||||
|
||||
SDAI_DAObject_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_DAObject_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_DAObject__set::Append( SDAI_DAObject_ptr v ) {
|
||||
|
||||
int index = _count;
|
||||
SDAI_DAObject_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_DAObject_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_DAObject__set::Remove( int index ) {
|
||||
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
SDAI_DAObject_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_DAObject_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int SDAI_DAObject__set::Index( SDAI_DAObject_ptr v ) {
|
||||
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDAI_DAObject_ptr
|
||||
@@ -90,5 +163,24 @@ SDAI_DAObject__set::retrieve( int index ) {
|
||||
}
|
||||
|
||||
SDAI_DAObject_ptr & SDAI_DAObject__set::operator[]( int index ) {
|
||||
return ( SDAI_DAObject_ptr & )SDAI__set::operator[]( index );
|
||||
|
||||
Check( index );
|
||||
// _count = max(_count, index+1);
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int
|
||||
SDAI_DAObject__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
int
|
||||
SDAI_DAObject__set::is_empty() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void
|
||||
SDAI_DAObject__set::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
@@ -489,13 +489,34 @@ class SC_DAI_EXPORT SDAI_DAObject_SDAI : public SDAI_DAObject {
|
||||
typedef SDAI_DAObject_SDAI * SDAI_DAObject_SDAI_ptr;
|
||||
typedef SDAI_DAObject_SDAI_ptr SDAI_DAObject_SDAI_var;
|
||||
|
||||
class SC_DAI_EXPORT SDAI_DAObject__set : public SDAI__set {
|
||||
class SC_DAI_EXPORT SDAI_DAObject__set {
|
||||
public:
|
||||
SDAI_DAObject__set( int = 16 );
|
||||
~SDAI_DAObject__set();
|
||||
|
||||
SDAI_DAObject_ptr retrieve( int index );
|
||||
int is_empty();
|
||||
|
||||
SDAI_DAObject_ptr & operator[]( int index );
|
||||
|
||||
void Insert( SDAI_DAObject_ptr, int index );
|
||||
void Append( SDAI_DAObject_ptr );
|
||||
void Remove( int index );
|
||||
|
||||
int Index( SDAI_DAObject_ptr );
|
||||
|
||||
void Clear();
|
||||
int Count();
|
||||
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
SDAI_DAObject_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
typedef SDAI_DAObject__set * SDAI_DAObject__set_ptr;
|
||||
|
||||
@@ -114,7 +114,7 @@ SDAI_Entity_extent::AddInstance( const SDAI_DAObject_ptr & appInst ) {
|
||||
|
||||
void
|
||||
SDAI_Entity_extent::RemoveInstance( const SDAI_DAObject_ptr & appInst ) {
|
||||
_instances.Remove( appInst );
|
||||
_instances.Remove( _instances.Index( appInst ) );
|
||||
}
|
||||
|
||||
///////// END_ENTITY SDAI_Entity_extent
|
||||
|
||||
@@ -44,10 +44,83 @@ extern "C"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
SDAI_Entity_extent__set::SDAI_Entity_extent__set( int defaultSize ) : SDAI__set( defaultSize ) {
|
||||
SDAI_Entity_extent__set::SDAI_Entity_extent__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new SDAI_Entity_extent_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
SDAI_Entity_extent__set::~SDAI_Entity_extent__set() {
|
||||
delete _buf;
|
||||
}
|
||||
|
||||
void SDAI_Entity_extent__set::Check( int index ) {
|
||||
|
||||
SDAI_Entity_extent_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new SDAI_Entity_extent_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( SDAI_Entity_extent_ptr ) );
|
||||
delete _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDAI_Entity_extent__set::Insert( SDAI_Entity_extent_ptr v, int index ) {
|
||||
|
||||
SDAI_Entity_extent_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Entity_extent_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_Entity_extent__set::Append( SDAI_Entity_extent_ptr v ) {
|
||||
|
||||
int index = _count;
|
||||
SDAI_Entity_extent_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Entity_extent_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_Entity_extent__set::Remove( int index ) {
|
||||
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
SDAI_Entity_extent_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_Entity_extent_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int SDAI_Entity_extent__set::Index( SDAI_Entity_extent_ptr v ) {
|
||||
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDAI_Entity_extent_ptr
|
||||
@@ -56,7 +129,25 @@ SDAI_Entity_extent__set::retrieve( int index ) {
|
||||
}
|
||||
|
||||
SDAI_Entity_extent_ptr & SDAI_Entity_extent__set::operator[]( int index ) {
|
||||
return ( SDAI_Entity_extent_ptr & )SDAI__set::operator[]( index );
|
||||
Check( index );
|
||||
// _count = max(_count, index+1);
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int
|
||||
SDAI_Entity_extent__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
int
|
||||
SDAI_Entity_extent__set::is_empty() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void
|
||||
SDAI_Entity_extent__set::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -37,14 +37,32 @@
|
||||
//#include <EntityExtent.h>
|
||||
*/
|
||||
|
||||
class SC_DAI_EXPORT SDAI_Entity_extent__set : public SDAI__set {
|
||||
class SC_DAI_EXPORT SDAI_Entity_extent__set {
|
||||
public:
|
||||
|
||||
SDAI_Entity_extent__set( int = 16 );
|
||||
~SDAI_Entity_extent__set();
|
||||
|
||||
SDAI_Entity_extent_ptr retrieve( int index );
|
||||
int is_empty();
|
||||
|
||||
SDAI_Entity_extent_ptr & operator[]( int index );
|
||||
|
||||
void Insert( SDAI_Entity_extent_ptr, int index );
|
||||
void Append( SDAI_Entity_extent_ptr );
|
||||
void Remove( int index );
|
||||
int Index( SDAI_Entity_extent_ptr );
|
||||
|
||||
void Clear();
|
||||
int Count();
|
||||
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
SDAI_Entity_extent_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
|
||||
};
|
||||
|
||||
typedef SDAI_Entity_extent__set * SDAI_Entity_extent__set_ptr;
|
||||
|
||||
@@ -73,7 +73,7 @@ void SDAI_Model_contents::AddInstance( const SDAI_DAObject_SDAI_ptr & appInst )
|
||||
}
|
||||
|
||||
void SDAI_Model_contents::RemoveInstance( SDAI_DAObject_SDAI_ptr & appInst ) {
|
||||
_instances.contents_()->Remove( appInst );
|
||||
_instances.contents_()->Remove( _instances.contents_()->Index( appInst ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,10 +36,83 @@ extern "C"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
SDAI_Model_contents__list::SDAI_Model_contents__list( int defaultSize ) : SDAI__set( defaultSize ){
|
||||
SDAI_Model_contents__list::SDAI_Model_contents__list( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new SDAI_Model_contents_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
SDAI_Model_contents__list::~SDAI_Model_contents__list() {
|
||||
delete _buf;
|
||||
}
|
||||
|
||||
void SDAI_Model_contents__list::Check( int index ) {
|
||||
|
||||
SDAI_Model_contents_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new SDAI_Model_contents_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( SDAI_Model_contents_ptr ) );
|
||||
delete _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDAI_Model_contents__list::Insert( SDAI_Model_contents_ptr v, int index ) {
|
||||
|
||||
SDAI_Model_contents_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Model_contents_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_Model_contents__list::Append( SDAI_Model_contents_ptr v ) {
|
||||
|
||||
int index = _count;
|
||||
SDAI_Model_contents_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_Model_contents_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void SDAI_Model_contents__list::Remove( int index ) {
|
||||
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
SDAI_Model_contents_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_Model_contents_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int SDAI_Model_contents__list::Index( SDAI_Model_contents_ptr v ) {
|
||||
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDAI_Model_contents_ptr
|
||||
@@ -49,6 +122,25 @@ SDAI_Model_contents__list::retrieve( int index ) {
|
||||
|
||||
SDAI_Model_contents_ptr &
|
||||
SDAI_Model_contents__list::operator[]( int index ) {
|
||||
return ( SDAI_Model_contents_ptr & )SDAI__set::operator[]( index );
|
||||
|
||||
Check( index );
|
||||
// _count = max(_count, index+1);
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int
|
||||
SDAI_Model_contents__list::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
int
|
||||
SDAI_Model_contents__list::is_empty() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void
|
||||
SDAI_Model_contents__list::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,30 @@
|
||||
|
||||
#include <sc_export.h>
|
||||
|
||||
class SC_DAI_EXPORT SDAI_Model_contents__list : public SDAI__set {
|
||||
class SC_DAI_EXPORT SDAI_Model_contents__list {
|
||||
public:
|
||||
SDAI_Model_contents__list( int = 16 );
|
||||
~SDAI_Model_contents__list();
|
||||
|
||||
SDAI_Model_contents_ptr retrieve( int index );
|
||||
int is_empty();
|
||||
|
||||
SDAI_Model_contents_ptr & operator[]( int index );
|
||||
|
||||
void Insert( SDAI_Model_contents_ptr, int index );
|
||||
void Append( SDAI_Model_contents_ptr );
|
||||
void Remove( int index );
|
||||
int Index( SDAI_Model_contents_ptr );
|
||||
|
||||
void Clear();
|
||||
int Count();
|
||||
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
SDAI_Model_contents_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
typedef SDAI_Model_contents__list *
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <sdai.h>
|
||||
#include "sc_memmgr.h"
|
||||
|
||||
#ifndef HAVE_MEMMOVE
|
||||
extern "C"
|
||||
{
|
||||
void * memmove( void * __s1, const void * __s2, size_t __n );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
SDAI__set::SDAI__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new SDAI_ptr[_bufsize];
|
||||
_count = 0;
|
||||
mtxP = new sc_mutex();
|
||||
}
|
||||
|
||||
SDAI__set::~SDAI__set() {
|
||||
delete _buf;
|
||||
delete mtxP;
|
||||
}
|
||||
|
||||
void SDAI__set::Check( int index ) {
|
||||
// No locking as it is a private function.
|
||||
// i.e. The caller will have to take the responsibilty.
|
||||
|
||||
SDAI_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new SDAI_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( SDAI_ptr ) );
|
||||
delete _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDAI__set::Insert( SDAI_ptr v, int index ) {
|
||||
mtxP->lock();
|
||||
|
||||
SDAI_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
mtxP->unlock();
|
||||
}
|
||||
|
||||
void SDAI__set::Append( SDAI_ptr v ) {
|
||||
mtxP->lock();
|
||||
|
||||
int index = _count;
|
||||
SDAI_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( SDAI_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
mtxP->unlock();
|
||||
}
|
||||
|
||||
void SDAI__set::Remove( int index ) {
|
||||
mtxP->lock();
|
||||
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
SDAI_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( SDAI_ptr ) );
|
||||
}
|
||||
mtxP->unlock();
|
||||
}
|
||||
|
||||
// First find the index of v and then remove v.
|
||||
void SDAI__set::Remove( SDAI_ptr v ) {
|
||||
mtxP->lock();
|
||||
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
--_count;
|
||||
SDAI_ptr * spot = &_buf[i];
|
||||
memmove( spot, spot + 1, ( _count - i )*sizeof( SDAI_ptr ) );
|
||||
}
|
||||
}
|
||||
mtxP->unlock();
|
||||
}
|
||||
|
||||
int SDAI__set::Index( SDAI_ptr v ) {
|
||||
mtxP->lock();
|
||||
int index = -1;
|
||||
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtxP->unlock();
|
||||
return index;
|
||||
}
|
||||
|
||||
SDAI_ptr
|
||||
SDAI__set::retrieve( int index ) {
|
||||
return operator[]( index );
|
||||
}
|
||||
|
||||
SDAI_ptr & SDAI__set::operator[]( int index ) {
|
||||
mtxP->lock();
|
||||
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
SDAI_ptr & sp = _buf[index];
|
||||
mtxP->unlock();
|
||||
return sp;
|
||||
}
|
||||
|
||||
int
|
||||
SDAI__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
int
|
||||
SDAI__set::is_empty() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void
|
||||
SDAI__set::Clear() {
|
||||
mtxP->lock();
|
||||
_count = 0;
|
||||
mtxP->unlock();
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#ifndef SDAISET_H
|
||||
#define SDAISET_H 1
|
||||
|
||||
#include <sc_mutex.h>
|
||||
#include <sc_export.h>
|
||||
|
||||
typedef void * SDAI_ptr;
|
||||
|
||||
class SC_DAI_EXPORT SDAI__set {
|
||||
public:
|
||||
SDAI__set( int = 16 );
|
||||
~SDAI__set();
|
||||
|
||||
SDAI_ptr retrieve( int index );
|
||||
int is_empty();
|
||||
|
||||
SDAI_ptr & operator[]( int index );
|
||||
|
||||
void Insert( SDAI_ptr, int index );
|
||||
void Append( SDAI_ptr );
|
||||
void Remove( int index );
|
||||
void Remove( SDAI_ptr );
|
||||
|
||||
int Index( SDAI_ptr );
|
||||
|
||||
void Clear();
|
||||
int Count();
|
||||
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
SDAI_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
sc_mutex * mtxP;
|
||||
// The above function is declared as a pointer to prevent
|
||||
// 'use of deleted function' compilation error as the
|
||||
// assignment operator '=' is being in the function
|
||||
// 'SDAI_Entity_extent::owned_by_' for a subclass of
|
||||
// SDAI__set: 'SDAI_Model_contents__list'
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
+23
-35
@@ -1,45 +1,33 @@
|
||||
|
||||
set(LIBSTEPEDITOR_SRCS
|
||||
STEPfile.cc
|
||||
STEPfile.inline.cc
|
||||
cmdmgr.cc
|
||||
SdaiHeaderSchema.cc
|
||||
SdaiHeaderSchemaAll.cc
|
||||
SdaiHeaderSchemaInit.cc
|
||||
SdaiSchemaInit.cc
|
||||
)
|
||||
STEPfile.cc
|
||||
STEPfile.inline.cc
|
||||
cmdmgr.cc
|
||||
SdaiHeaderSchema.cc
|
||||
SdaiHeaderSchemaAll.cc
|
||||
SdaiHeaderSchemaInit.cc
|
||||
SdaiSchemaInit.cc
|
||||
)
|
||||
|
||||
SET(SC_CLEDITOR_HDRS
|
||||
STEPfile.h
|
||||
cmdmgr.h
|
||||
editordefines.h
|
||||
SdaiHeaderSchema.h
|
||||
SdaiHeaderSchemaClasses.h
|
||||
SdaiSchemaInit.h
|
||||
seeinfodefault.h
|
||||
)
|
||||
STEPfile.h
|
||||
cmdmgr.h
|
||||
editordefines.h
|
||||
SdaiHeaderSchema.h
|
||||
SdaiHeaderSchemaClasses.h
|
||||
SdaiSchemaInit.h
|
||||
seeinfodefault.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
|
||||
SC_ADDLIB(stepeditor "${LIBSTEPEDITOR_SRCS}" "stepcore;stepdai;steputils;base")
|
||||
if(HAVE_STD_THREAD)
|
||||
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
|
||||
set_target_properties(stepeditor PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
|
||||
endif(HAVE_STD_THREAD)
|
||||
|
||||
install(FILES ${SC_CLEDITOR_HDRS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cleditor)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cleditor)
|
||||
|
||||
+45
-44
@@ -149,7 +149,7 @@ Severity STEPfile::ReadHeader( istream & in ) {
|
||||
}
|
||||
|
||||
//get the entity keyword
|
||||
FillKeyword( in, ";( /\\", _error, keywd );
|
||||
keywd = GetKeyword( in, ";( /\\", _error );
|
||||
ReadTokenSeparator( in, &cmtStr );
|
||||
|
||||
//check for "ENDSEC"
|
||||
@@ -367,9 +367,9 @@ void STEPfile::HeaderMergeInstances( InstMgr * im ) {
|
||||
|
||||
//checking for _headerInstances::FILE_NAME
|
||||
idnum = HeaderId( "File_Name" );
|
||||
se = _headerInstances->GetApplication_instanceFromFileId( idnum );
|
||||
se = _headerInstances->GetApplication_instance( _headerInstances->FindFileId( idnum ) );
|
||||
if( se ) {
|
||||
from = im->GetApplication_instanceFromFileId( idnum );
|
||||
from = im->GetApplication_instance( im->FindFileId( idnum ) );
|
||||
|
||||
// name:
|
||||
// time_stamp: keep the newer time_stamp
|
||||
@@ -379,33 +379,33 @@ void STEPfile::HeaderMergeInstances( InstMgr * im ) {
|
||||
// originating_system:
|
||||
// authorization:
|
||||
} else { // No current File_Name instance
|
||||
from = im->GetApplication_instanceFromFileId( idnum );
|
||||
from = im->GetApplication_instance( im->FindFileId( idnum ) );
|
||||
_headerInstances->Append( from, completeSE );
|
||||
}
|
||||
|
||||
//checking for _headerInstances::FILE_DESCRIPTION
|
||||
idnum = HeaderId( "File_Description" );
|
||||
se = _headerInstances->GetApplication_instanceFromFileId( idnum );
|
||||
se = _headerInstances->GetApplication_instance( _headerInstances->FindFileId( idnum ) );
|
||||
if( se ) {
|
||||
from = im->GetApplication_instanceFromFileId( idnum );
|
||||
from = im->GetApplication_instance( im->FindFileId( idnum ) );
|
||||
|
||||
//description
|
||||
//implementation_level
|
||||
} else {
|
||||
from = im->GetApplication_instanceFromFileId( idnum );
|
||||
from = im->GetApplication_instance( im->FindFileId( idnum ) );
|
||||
_headerInstances->Append( from, completeSE );
|
||||
}
|
||||
|
||||
//checking for _headerInstances::FILE_SCHEMA
|
||||
idnum = HeaderId( "File_Schema" );
|
||||
se = _headerInstances->GetApplication_instanceFromFileId( idnum );
|
||||
se = _headerInstances->GetApplication_instance( _headerInstances->FindFileId( idnum ) );
|
||||
if( se ) {
|
||||
from = im->GetApplication_instanceFromFileId( idnum );
|
||||
from = im->GetApplication_instance( im->FindFileId( idnum ) );
|
||||
|
||||
//description
|
||||
//implementation_level
|
||||
} else {
|
||||
from = im->GetApplication_instanceFromFileId( idnum );
|
||||
from = im->GetApplication_instance( im->FindFileId( idnum ) );
|
||||
_headerInstances->Append( from, completeSE );
|
||||
}
|
||||
|
||||
@@ -913,7 +913,7 @@ Severity STEPfile::CreateScopeInstances( istream & in, SDAI_Application_instance
|
||||
std::vector< SDAI_Application_instance_ptr > inscope;
|
||||
std::string keywd;
|
||||
|
||||
FillKeyword( in, " \n\t/\\#;", _error, keywd );
|
||||
keywd = GetKeyword( in, " \n\t/\\#;", _error );
|
||||
if( strncmp( const_cast<char *>( keywd.c_str() ), "&SCOPE", 6 ) ) {
|
||||
//ERROR: "&SCOPE" expected
|
||||
//TODO: should attempt to recover by reading through ENDSCOPE
|
||||
@@ -955,7 +955,7 @@ Severity STEPfile::CreateScopeInstances( istream & in, SDAI_Application_instance
|
||||
}
|
||||
|
||||
//check for "ENDSCOPE"
|
||||
FillKeyword( in, " \t\n/\\#;", _error, keywd );
|
||||
keywd = GetKeyword( in, " \t\n/\\#;", _error );
|
||||
if( strncmp( const_cast<char *>( keywd.c_str() ), "ENDSCOPE", 8 ) ) {
|
||||
//ERROR: "ENDSCOPE" expected
|
||||
SkipInstance( in, tmpbuf );
|
||||
@@ -1071,7 +1071,7 @@ Severity STEPfile::ReadScopeInstances( istream & in ) {
|
||||
std::string keywd;
|
||||
std::string cmtStr;
|
||||
|
||||
FillKeyword( in, " \n\t/\\#;", _error, keywd );
|
||||
keywd = GetKeyword( in, " \n\t/\\#;", _error );
|
||||
if( strncmp( const_cast<char *>( keywd.c_str() ), "&SCOPE", 6 ) ) {
|
||||
//ERROR: "&SCOPE" expected
|
||||
SkipInstance( in, tmpbuf );
|
||||
@@ -1099,7 +1099,7 @@ Severity STEPfile::ReadScopeInstances( istream & in ) {
|
||||
in.putback( c );
|
||||
|
||||
//check for "ENDSCOPE"
|
||||
FillKeyword( in, " \t\n/\\#;", _error, keywd );
|
||||
keywd = GetKeyword( in, " \t\n/\\#;", _error );
|
||||
if( strncmp( const_cast<char *>( keywd.c_str() ), "ENDSCOPE", 8 ) ) {
|
||||
//ERROR: "ENDSCOPE" expected
|
||||
SkipInstance( in, tmpbuf );
|
||||
@@ -1480,11 +1480,7 @@ int STEPfile::HeaderId( const char * name ) {
|
||||
if( tmp == "FILE_SCHEMA" ) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
_headerIdMtx.lock();
|
||||
int myHeaderId = ++_headerId;
|
||||
_headerIdMtx.unlock();
|
||||
return myHeaderId;
|
||||
return ++_headerId;
|
||||
}
|
||||
|
||||
/***************************
|
||||
@@ -1498,7 +1494,6 @@ void STEPfile::WriteHeader( ostream & out ) {
|
||||
|
||||
// Write the rest of the header instances
|
||||
SDAI_Application_instance * se;
|
||||
_headerInstances->masterMtx.lock();
|
||||
int n = _headerInstances->InstanceCount();
|
||||
for( int i = 0; i < n; ++i ) {
|
||||
se = _headerInstances->GetMgrNode( i ) ->GetApplication_instance();
|
||||
@@ -1510,7 +1505,6 @@ void STEPfile::WriteHeader( ostream & out ) {
|
||||
WriteHeaderInstance(
|
||||
_headerInstances->GetMgrNode( i )->GetApplication_instance(), out );
|
||||
}
|
||||
_headerInstances->masterMtx.unlock();
|
||||
out << "ENDSEC;\n";
|
||||
}
|
||||
|
||||
@@ -1522,8 +1516,6 @@ void STEPfile::WriteHeaderInstance( SDAI_Application_instance * obj, ostream & o
|
||||
out << obj->P21Comment();
|
||||
}
|
||||
out << StrToUpper( obj->EntityName(), tmp ) << "(";
|
||||
obj->mtx.lock();
|
||||
obj->attributes.mtxP->lock();
|
||||
int n = obj->attributes.list_length();
|
||||
for( int i = 0; i < n; ++i ) {
|
||||
( obj->attributes[i] ).STEPwrite( out );
|
||||
@@ -1531,8 +1523,6 @@ void STEPfile::WriteHeaderInstance( SDAI_Application_instance * obj, ostream & o
|
||||
out << ",";
|
||||
}
|
||||
}
|
||||
obj->attributes.mtxP->unlock();
|
||||
obj->mtx.unlock();
|
||||
out << ");\n";
|
||||
}
|
||||
|
||||
@@ -1594,25 +1584,21 @@ void STEPfile::WriteData( ostream & out, int writeComments ) {
|
||||
std::string currSch = schemaName();
|
||||
out << "DATA;\n";
|
||||
|
||||
instances().masterMtx.lock();
|
||||
int n = instances().InstanceCount();
|
||||
for( int i = 0; i < n; ++i ) {
|
||||
instances().GetMgrNode( i )->GetApplication_instance()->STEPwrite( out, currSch.c_str(), writeComments );
|
||||
_oFileInstsWritten++;
|
||||
}
|
||||
instances().masterMtx.unlock();
|
||||
|
||||
out << "ENDSEC;\n";
|
||||
}
|
||||
|
||||
void STEPfile::WriteValuePairsData( ostream & out, int writeComments, int mixedCase ) {
|
||||
std::string currSch = schemaName();
|
||||
instances().masterMtx.lock();
|
||||
int n = instances().InstanceCount();
|
||||
for( int i = 0; i < n; ++i ) {
|
||||
instances().GetMgrNode( i )->GetApplication_instance()->WriteValuePairs( out, currSch.c_str(), writeComments, mixedCase );
|
||||
}
|
||||
instances().masterMtx.unlock();
|
||||
}
|
||||
|
||||
Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
@@ -1623,8 +1609,7 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
int total_insts = 0, valid_insts = 0;
|
||||
|
||||
ReadTokenSeparator( *in );
|
||||
std::string keywd;
|
||||
FillKeyword( *in, "; #", _error, keywd );
|
||||
std::string keywd = GetKeyword( *in, "; #", _error );
|
||||
// get the delimiter off the istream
|
||||
char c;
|
||||
in->get( c );
|
||||
@@ -1687,11 +1672,26 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
cout << errbuf;
|
||||
|
||||
// PASS 2
|
||||
// This would be nicer if you didn't actually have to close the
|
||||
// file but could just reposition the pointer back to the
|
||||
// beginning of the data section. It looks like you can do this
|
||||
// with the GNU File class, but that class doesn't have the
|
||||
// operator >> overloaded which is used to do the rest of the
|
||||
// parsing. SO we are using istreams and this works, but could
|
||||
// be better.
|
||||
|
||||
// reset the error count so you're not counting things twice:
|
||||
_errorCount = 0;
|
||||
in->seekg( 0, std::ifstream::beg );
|
||||
if( !FindDataSection( *in ) ) {
|
||||
istream * in2;
|
||||
if( !( ( in2 = OpenInputFile() ) && ( in2 -> good() ) ) ) {
|
||||
// if the stream is not readable, there's an error
|
||||
_error.AppendToUserMsg( "Cannot open file for 2nd pass -- No data read.\n" );
|
||||
CloseInputFile( in2 );
|
||||
return SEVERITY_INPUT_ERROR;
|
||||
}
|
||||
if( !FindDataSection( *in2 ) ) {
|
||||
_error.AppendToUserMsg( "Error: Unable to find DATA section delimiter in second pass. \nData section not read. Rest of file ignored.\n" );
|
||||
CloseInputFile( in2 );
|
||||
return SEVERITY_INPUT_ERROR;
|
||||
}
|
||||
|
||||
@@ -1699,19 +1699,21 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
case VERSION_CURRENT:
|
||||
case VERSION_UNKNOWN:
|
||||
case WORKING_SESSION:
|
||||
valid_insts = ReadData2( *in, useTechCor );
|
||||
valid_insts = ReadData2( *in2, useTechCor );
|
||||
break;
|
||||
default:
|
||||
_error.AppendToUserMsg( "STEPfile::AppendFile: STEP file version set to unrecognized value.\n" );
|
||||
CloseInputFile( in2 );
|
||||
return SEVERITY_BUG;
|
||||
}
|
||||
|
||||
//check for "ENDSEC;"
|
||||
ReadTokenSeparator( *in );
|
||||
ReadTokenSeparator( *in2 );
|
||||
if( total_insts != valid_insts ) {
|
||||
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 );
|
||||
return _error.GreaterSeverity( SEVERITY_WARNING );
|
||||
}
|
||||
|
||||
@@ -1726,23 +1728,25 @@ Severity STEPfile::AppendFile( istream * in, bool useTechCor ) {
|
||||
|
||||
//check for "ENDSTEP;" || "END-ISO-10303-21;"
|
||||
|
||||
if( in -> good() ) {
|
||||
ReadTokenSeparator( *in );
|
||||
FillKeyword( *in, ";", _error, keywd );
|
||||
if( in2 -> good() ) {
|
||||
ReadTokenSeparator( *in2 );
|
||||
keywd = GetKeyword( *in2, ";", _error );
|
||||
//yank the ";" from the istream
|
||||
//if (';' == in->peek()) in->get();
|
||||
//if (';' == in2->peek()) in2->get();
|
||||
char ch;
|
||||
in->get( ch );
|
||||
in2->get( ch );
|
||||
if( ch != ';' ) {
|
||||
std::cerr << __FILE__ << ":" << __LINE__ << " - Expected ';' at Part 21 EOF, found '" << c << "'." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( !keywd.compare( 0, keywd.size(), END_FILE_DELIM ) ) || !( in -> good() ) ) {
|
||||
if( ( !keywd.compare( 0, keywd.size(), END_FILE_DELIM ) ) || !( in2 -> good() ) ) {
|
||||
_error.AppendToUserMsg( END_FILE_DELIM );
|
||||
_error.AppendToUserMsg( " missing at end of file.\n" );
|
||||
CloseInputFile( in2 );
|
||||
return _error.GreaterSeverity( SEVERITY_WARNING );
|
||||
}
|
||||
CloseInputFile( in2 );
|
||||
cout << "Finished reading file.\n\n";
|
||||
return SEVERITY_NULL;
|
||||
}
|
||||
@@ -1786,8 +1790,6 @@ Severity STEPfile::WriteWorkingFile( const std::string filename, int clearError,
|
||||
void STEPfile::WriteWorkingData( ostream & out, int writeComments ) {
|
||||
std::string currSch = schemaName();
|
||||
out << "DATA;\n";
|
||||
|
||||
instances().masterMtx.lock();
|
||||
int n = instances().InstanceCount();
|
||||
|
||||
for( int i = 0; i < n; ++i ) {
|
||||
@@ -1817,7 +1819,6 @@ void STEPfile::WriteWorkingData( ostream & out, int writeComments ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
instances().masterMtx.unlock();
|
||||
out << "ENDSEC;\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <read_func.h>
|
||||
#include <sc_mutex.h>
|
||||
|
||||
//error reporting level
|
||||
#define READ_COMPLETE 10
|
||||
@@ -37,11 +36,6 @@ enum FileTypeCode {
|
||||
};
|
||||
|
||||
class SC_EDITOR_EXPORT STEPfile {
|
||||
/// hoiji09: As this class is a parser, the locking in this class is dependent upon how it is
|
||||
/// being used in a multithreaded way. Example: The variable llke _fileName restricts
|
||||
/// this class to parse only one file at a time. If we want to parse more then one
|
||||
/// then this will have to change.
|
||||
|
||||
protected:
|
||||
//data members
|
||||
|
||||
@@ -61,7 +55,6 @@ class SC_EDITOR_EXPORT STEPfile {
|
||||
Registry * _headerRegistry;
|
||||
|
||||
int _headerId; ///< STEPfile_id given to SDAI_Application_instance from header section
|
||||
sc_mutex _headerIdMtx; ///< Protects the _headerId
|
||||
|
||||
//file information
|
||||
DirObj * _currentDir;
|
||||
|
||||
@@ -113,9 +113,7 @@ Severity STEPfile::ReadExchangeFile( const std::string filename, bool useTechCor
|
||||
if( _headerInstances ) {
|
||||
_headerInstances->ClearInstances();
|
||||
}
|
||||
_headerIdMtx.lock();
|
||||
_headerId = 5;
|
||||
_headerIdMtx.unlock();
|
||||
Severity rval = AppendFile( in, useTechCor );
|
||||
CloseInputFile( in );
|
||||
return rval;
|
||||
@@ -264,13 +262,11 @@ int STEPfile::IncrementFileId( int fileid ) {
|
||||
|
||||
|
||||
void STEPfile::SetFileIdIncrement() {
|
||||
instances().masterMtx.lock();
|
||||
if( instances().MaxFileId() < 0 ) {
|
||||
_fileIdIncr = 0;
|
||||
} else {
|
||||
_fileIdIncr = ( int )( ( ceil( ( instances().MaxFileId() + 99.0 ) / 1000.0 ) + 1.0 ) * 1000.0 );
|
||||
}
|
||||
instances().masterMtx.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+8
-16
@@ -14,19 +14,15 @@
|
||||
#include "sc_memmgr.h"
|
||||
|
||||
ReplicateLinkNode * ReplicateList::FindNode( MgrNode * mn ) {
|
||||
mtxP->lock(); //mtxP belongs to the superclass SingleLinkList
|
||||
ReplicateLinkNode * rln = ( ReplicateLinkNode * )GetHead();
|
||||
ReplicateLinkNode * retrln = 0;
|
||||
int numEntries = EntryCount();
|
||||
while( numEntries-- ) {
|
||||
if( rln->ReplicateNode() == mn ) {
|
||||
retrln = rln;
|
||||
break;
|
||||
return rln;
|
||||
}
|
||||
rln = ( ReplicateLinkNode * )rln->NextNode();
|
||||
}
|
||||
mtxP->unlock();
|
||||
return retrln;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ReplicateList::IsOnList( MgrNode * mn ) {
|
||||
@@ -37,30 +33,28 @@ bool ReplicateList::IsOnList( MgrNode * mn ) {
|
||||
// returns true if it could delete the node
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool ReplicateList::Remove( ReplicateLinkNode * rln ) {
|
||||
mtxP->lock();
|
||||
bool retval = false;
|
||||
ReplicateLinkNode * rnFollow = ( ReplicateLinkNode * )GetHead();
|
||||
if( rnFollow && rln ) {
|
||||
if( !rnFollow || !rln ) {
|
||||
return false;
|
||||
} else {
|
||||
if( rnFollow == rln ) {
|
||||
head = rln->NextNode();
|
||||
delete rln;
|
||||
retval = true;
|
||||
return true;
|
||||
} else {
|
||||
ReplicateLinkNode * rn = ( ReplicateLinkNode * )rnFollow->NextNode();
|
||||
while( rn ) {
|
||||
if( rn == rln ) {
|
||||
rnFollow->next = ( SingleLinkNode * )rln->NextNode();
|
||||
delete rln;
|
||||
retval = true;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
rnFollow = rn;
|
||||
rn = ( ReplicateLinkNode * )rn->NextNode();
|
||||
} // end while(rn)
|
||||
} // end else
|
||||
} // end else
|
||||
mtxP->unlock();
|
||||
return retval;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReplicateList::Remove( MgrNode * rn ) {
|
||||
@@ -79,11 +73,9 @@ CmdMgr::CmdMgr() {
|
||||
}
|
||||
|
||||
void CmdMgr::ReplicateCmdList( MgrNode * mn ) {
|
||||
replicateList->mtxP->lock(); // To prevent double appending of mn
|
||||
if( !( replicateList->IsOnList( mn ) ) ) {
|
||||
replicateList->AddNode( mn );
|
||||
}
|
||||
replicateList->mtxP->unlock();
|
||||
}
|
||||
|
||||
void CmdMgr::ClearInstances() {
|
||||
|
||||
@@ -1,67 +1,41 @@
|
||||
|
||||
set( clLazyFile_SRCS
|
||||
lazyDataSectionReader.cc
|
||||
lazyFileReader.cc
|
||||
lazyInstMgr.cc
|
||||
p21HeaderSectionReader.cc
|
||||
sectionReader.cc
|
||||
lazyP21DataSectionReader.cc
|
||||
../base/judy/src/judy.c
|
||||
../base/judy/src/judyLArray.h
|
||||
../base/judy/src/judySArray.h
|
||||
)
|
||||
lazyDataSectionReader.cc
|
||||
lazyFileReader.cc
|
||||
lazyInstMgr.cc
|
||||
p21HeaderSectionReader.cc
|
||||
sectionReader.cc
|
||||
lazyP21DataSectionReader.cc
|
||||
../base/judy/src/judy.c
|
||||
../base/judy/src/judyLArray.h
|
||||
../base/judy/src/judySArray.h
|
||||
)
|
||||
|
||||
set( SC_CLLAZYFILE_HDRS
|
||||
headerSectionReader.h
|
||||
lazyFileReader.h
|
||||
lazyP21DataSectionReader.h
|
||||
p21HeaderSectionReader.h
|
||||
lazyDataSectionReader.h
|
||||
lazyInstMgr.h
|
||||
lazyTypes.h
|
||||
sectionReader.h
|
||||
instMgrHelper.h
|
||||
)
|
||||
headerSectionReader.h
|
||||
lazyFileReader.h
|
||||
lazyP21DataSectionReader.h
|
||||
p21HeaderSectionReader.h
|
||||
lazyDataSectionReader.h
|
||||
lazyInstMgr.h
|
||||
lazyTypes.h
|
||||
sectionReader.h
|
||||
instMgrHelper.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SC_SOURCE_DIR}/src/cleditor
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/base/judy/src
|
||||
)
|
||||
|
||||
SC_ADDLIB(steplazyfile "${clLazyFile_SRCS};${clLazyFile_HDRS}" "stepcore;stepdai;steputils;base;")
|
||||
|
||||
if(HAVE_STD_THREAD)
|
||||
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
|
||||
set_target_properties(steplazyfile PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
|
||||
|
||||
#Directory frim which lazy_thread_safety_test will get its schema.h
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}/schemas/sdai_cd209
|
||||
)
|
||||
|
||||
SC_ADDEXEC(lazy_thread_safety_test "lazy_thread_safety_test.cc" "steplazyfile;stepeditor" )
|
||||
set_target_properties(lazy_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD -DNO_REGISTRY")
|
||||
target_link_libraries(lazy_thread_safety_test sdai_cd209 "pthread" ) #sdai_cd209 in causes schema dependency
|
||||
endif(HAVE_STD_THREAD)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SC_SOURCE_DIR}/src/cleditor
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/clstepcore
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/base/judy/src
|
||||
)
|
||||
|
||||
SC_ADDLIB(steplazyfile "${clLazyFile_SRCS};${clLazyFile_HDRS}" "stepcore;stepdai;steputils;base")
|
||||
SC_ADDEXEC(lazy_test "lazy_test.cc" "steplazyfile;stepeditor" )
|
||||
set_target_properties(lazy_test PROPERTIES COMPILE_FLAGS "-DNO_REGISTRY" )
|
||||
if(TARGET lazy_test-static)
|
||||
set_target_properties(lazy_test-static PROPERTIES COMPILE_FLAGS "-DNO_REGISTRY" )
|
||||
endif(TARGET lazy_test-static)
|
||||
|
||||
install(FILES ${SC_CLLAZYFILE_HDRS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cllazyfile)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cllazyfile)
|
||||
|
||||
@@ -27,7 +27,7 @@ class SC_LAZYFILE_EXPORT headerSectionReader: public sectionReader {
|
||||
return _headerInstances;
|
||||
}
|
||||
|
||||
~headerSectionReader() {
|
||||
virtual ~headerSectionReader() {
|
||||
//FIXME delete each instance?! maybe add to clear, since it iterates over everything already
|
||||
//enum clearHow { rawData, deletePointers }
|
||||
_headerInstances->clear();
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
#include <lazyInstMgr.h>
|
||||
#include <instmgr.h>
|
||||
#include <lazyTypes.h>
|
||||
|
||||
#include <sc_mutex.h>
|
||||
#include <sc_thread.h>
|
||||
|
||||
/**
|
||||
* \file instMgrHelper.h helper classes for the lazyInstMgr. Allows use of SDAI_Application_instance class
|
||||
@@ -34,12 +30,6 @@ class mgrNodeHelper: protected MgrNode {
|
||||
// unsigned int c = _lim->countDataSections();
|
||||
return _lim->loadInstance( _id );
|
||||
}
|
||||
|
||||
///Thread safe counterpart of GetSTEPentity()
|
||||
inline SDAI_Application_instance * GetSTEPentitySafely() {
|
||||
return _lim->loadInstanceSafely( _id );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -52,58 +42,14 @@ class mgrNodeHelper: protected MgrNode {
|
||||
|
||||
class instMgrAdapter: public InstMgr {
|
||||
protected:
|
||||
mgrNodeHelper _mn; //Used in single threaded operations
|
||||
|
||||
lazyInstMgr * _lim; //Used in multi threaded operations
|
||||
//map between threadID and the thread's local copy of mgrNodeHelper. Each thread has zero or one copy
|
||||
//of mgrNodeHelper assigned to it. This _map holds the pointer to that mgrNodeHelper.
|
||||
idNodeMap_t _map;
|
||||
sc_mutex _mapMtx;
|
||||
|
||||
mgrNodeHelper _mn;
|
||||
public:
|
||||
instMgrAdapter( lazyInstMgr * lim ): InstMgr( 0 ), _mn( lim ) {
|
||||
_lim = lim;
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
//In case of multiple threads an explicit destructor is needed to free each threads mgrNodeHelper copy
|
||||
~instMgrAdapter() {
|
||||
if( _map.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for( idNodeMap_t::iterator it = _map.begin(); it != _map.end(); it++ ) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
instMgrAdapter( lazyInstMgr * lim ): InstMgr( 0 ), _mn( lim ) {}
|
||||
|
||||
inline mgrNodeHelper * FindFileId( int fileId ) {
|
||||
_mn.setInstance( fileId );
|
||||
return &_mn;
|
||||
}
|
||||
|
||||
///Thread-safe counterpart of FindFileId( fileId ). It protects the state of mgrNodeHelper.
|
||||
inline mgrNodeHelper * FindFileIdSafely( int fileId ) {
|
||||
mgrNodeHelper * _myMN;
|
||||
thread_id_t tid = sc_thread::getthread_id();
|
||||
|
||||
_mapMtx.lock();
|
||||
idNodeMap_t::iterator it = _map.find( tid );
|
||||
|
||||
if( it == _map.end() ) {
|
||||
//thread local copy yet not made. Hence create its copy.
|
||||
_myMN = new mgrNodeHelper( _lim );
|
||||
_map.insert( idNodePair_t( tid, _myMN ) );
|
||||
} else {
|
||||
//reuse the already existing copy.
|
||||
_myMN = it->second;
|
||||
}
|
||||
|
||||
_mapMtx.unlock();
|
||||
|
||||
_myMN->setInstance( fileId );
|
||||
return _myMN;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -11,14 +11,13 @@ void lazyFileReader::initP21() {
|
||||
|
||||
for( ;; ) {
|
||||
lazyDataSectionReader * r;
|
||||
sectionID sid = _parent->reserveDataSection();
|
||||
r = new lazyP21DataSectionReader( this, _file, _file.tellg(), sid );
|
||||
r = new lazyP21DataSectionReader( this, _file, _file.tellg(), _parent->countDataSections() );
|
||||
if( !r->success() ) {
|
||||
delete r; //last read attempt failed
|
||||
std::cerr << "Corrupted data section" << std::endl;
|
||||
break;
|
||||
}
|
||||
_parent->registerDataSection( r, sid );
|
||||
_parent->registerDataSection( r );
|
||||
|
||||
//check for new data section (DATA) or end of file (END-ISO-10303-21;)
|
||||
while( isspace( _file.peek() ) && _file.good() ) {
|
||||
|
||||
+16
-159
@@ -1,16 +1,17 @@
|
||||
#include "lazyTypes.h"
|
||||
#include "lazyInstMgr.h"
|
||||
#include "Registry.h"
|
||||
#include <SubSuperIterators.h>
|
||||
#include "SdaiSchemaInit.h"
|
||||
#include "instMgrHelper.h"
|
||||
|
||||
lazyInstMgr::lazyInstMgr() {
|
||||
_headerRegistry = new Registry( HeaderSchemaInit );
|
||||
_mainRegistry = 0;
|
||||
_instanceTypes = new instanceTypes_t( 255 ); //NOTE arbitrary max of 255 chars for a type name
|
||||
_lazyInstanceCount = 0;
|
||||
_loadedInstanceCount = 0;
|
||||
_longestTypeNameLen = 0;
|
||||
_mainRegistry = 0;
|
||||
_errors = new ErrorDescriptor();
|
||||
_ima = new instMgrAdapter( this );
|
||||
}
|
||||
@@ -22,85 +23,51 @@ lazyInstMgr::~lazyInstMgr() {
|
||||
//loop over files, sections, instances; delete header instances
|
||||
lazyFileReaderVec_t::iterator fit = _files.begin();
|
||||
for( ; fit != _files.end(); ++fit ) {
|
||||
if( *fit ) {
|
||||
delete *fit;
|
||||
}
|
||||
delete *fit;
|
||||
}
|
||||
dataSectionReaderVec_t::iterator sit = _dataSections.begin();
|
||||
for( ; sit != _dataSections.end(); ++sit ) {
|
||||
if( *sit ) {
|
||||
delete *sit;
|
||||
}
|
||||
delete *sit;
|
||||
}
|
||||
_instancesLoaded.clear();
|
||||
_instanceStreamPos.clear();
|
||||
|
||||
void * last = _instanceTypes->end().key;
|
||||
void * current = _instanceTypes->begin().key;
|
||||
std::string str;
|
||||
while( current != last ) {
|
||||
str = (char *)current;
|
||||
str.clear();
|
||||
current = _instanceTypes->next().key;
|
||||
}
|
||||
str.clear();
|
||||
|
||||
delete _instanceTypes;
|
||||
}
|
||||
|
||||
sectionID lazyInstMgr::reserveDataSection() {
|
||||
mtxLock( dataSectionsMtx );
|
||||
sectionID sid = _dataSections.size();
|
||||
_dataSections.push_back( NULL );
|
||||
mtxUnlock( dataSectionsMtx );
|
||||
return sid;
|
||||
}
|
||||
|
||||
void lazyInstMgr::registerDataSection( lazyDataSectionReader * sreader, sectionID sid ) {
|
||||
assert( _dataSections[sid] == NULL );
|
||||
mtxLock( dataSectionsMtx );
|
||||
_dataSections[sid] = sreader;
|
||||
mtxUnlock( dataSectionsMtx );
|
||||
sectionID lazyInstMgr::registerDataSection( lazyDataSectionReader * sreader ) {
|
||||
_dataSections.push_back( sreader );
|
||||
return _dataSections.size() - 1;
|
||||
}
|
||||
|
||||
void lazyInstMgr::addLazyInstance( namedLazyInstance inst ) {
|
||||
assert( inst.loc.begin > 0 && inst.loc.instance > 0 && inst.loc.section >= 0 );
|
||||
|
||||
mtxLock( instanceTypesMtx );
|
||||
_lazyInstanceCount++;
|
||||
assert( inst.loc.begin > 0 && inst.loc.instance > 0 );
|
||||
int len = strlen( inst.name );
|
||||
if( len > _longestTypeNameLen ) {
|
||||
_longestTypeNameLen = len;
|
||||
_longestTypeName = inst.name;
|
||||
}
|
||||
_instanceTypes->insert( inst.name, inst.loc.instance );
|
||||
mtxUnlock( instanceTypesMtx );
|
||||
|
||||
/* store 16 bits of section id and 48 of instance offset into one 64-bit int
|
||||
* TODO: check and warn if anything is lost (in calling code?)
|
||||
* does 32bit need anything special?
|
||||
** TODO: check and warn if anything is lost (in calling code?)
|
||||
** does 32bit need anything special?
|
||||
**
|
||||
** create conversion class?
|
||||
** could then initialize conversion object with number of bits
|
||||
** also a good place to check for data loss
|
||||
*/
|
||||
positionAndSection ps = inst.loc.section;
|
||||
ps <<= 48;
|
||||
ps |= ( inst.loc.begin & 0xFFFFFFFFFFFFULL );
|
||||
|
||||
mtxLock( instanceStreamPosMtx );
|
||||
_instanceStreamPos.insert( inst.loc.instance, ps );
|
||||
mtxUnlock( instanceStreamPosMtx );
|
||||
|
||||
if( inst.refs ) {
|
||||
if( inst.refs->size() > 0 ) {
|
||||
//forward refs
|
||||
mtxLock( fwdRefsMtx );
|
||||
_fwdInstanceRefs.insert( inst.loc.instance, *inst.refs );
|
||||
mtxUnlock( fwdRefsMtx );
|
||||
|
||||
instanceRefs::iterator it = inst.refs->begin();
|
||||
for( ; it != inst.refs->end(); ++it ) {
|
||||
//reverse refs
|
||||
mtxLock( revRefsMtx );
|
||||
_revInstanceRefs.insert( *it, inst.loc.instance );
|
||||
mtxUnlock( revRefsMtx );
|
||||
}
|
||||
} else {
|
||||
delete inst.refs;
|
||||
@@ -129,16 +96,9 @@ void lazyInstMgr::openFile( std::string fname ) {
|
||||
|
||||
SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id ) {
|
||||
assert( _mainRegistry && "Main registry has not been initialized. Do so with initRegistry() or setRegistry()." );
|
||||
SDAI_Application_instance * inst = 0;
|
||||
positionAndSection ps;
|
||||
sectionID sid;
|
||||
|
||||
mtxLock( instanceStreamPosMtx );
|
||||
|
||||
mtxLock( loadInstanceMtx );
|
||||
inst = _instancesLoaded.find( id );
|
||||
mtxUnlock( loadInstanceMtx );
|
||||
|
||||
SDAI_Application_instance * inst = _instancesLoaded.find( id );
|
||||
instanceStreamPos_t::cvector * cv;
|
||||
if( !inst && 0 != ( cv = _instanceStreamPos.find( id ) ) ) {
|
||||
//FIXME _instanceStreamPos.find( id ) can return nonzero for nonexistent key?!
|
||||
@@ -159,117 +119,14 @@ SDAI_Application_instance * lazyInstMgr::loadInstance( instanceID id ) {
|
||||
break;
|
||||
}
|
||||
if( ( inst ) && ( inst != & NilSTEPentity ) ) {
|
||||
mtxLock( loadInstanceMtx );
|
||||
_instancesLoaded.insert( id, inst );
|
||||
_loadedInstanceCount++;
|
||||
mtxUnlock( loadInstanceMtx );
|
||||
} else {
|
||||
std::cerr << "Error loading instance #" << id << "." << std::endl;
|
||||
}
|
||||
} else if( !inst ) {
|
||||
} else {
|
||||
std::cerr << "Instance #" << id << " not found in any section." << std::endl;
|
||||
}
|
||||
|
||||
mtxUnlock( instanceStreamPosMtx );
|
||||
return inst;
|
||||
}
|
||||
|
||||
instanceSet * lazyInstMgr::instanceDependenciesHelper( instanceID id, instanceRefs_t * _fwdRefs ) {
|
||||
instanceSet * checkedDependencies = new instanceSet();
|
||||
instanceRefs dependencies; //Acts as queue for checking duplicated dependency
|
||||
|
||||
instanceRefs_t::cvector * _fwdRefsVec = _fwdRefs->find( id );
|
||||
//Initially populating direct dependencies of id into the queue
|
||||
if( _fwdRefsVec != 0 ) {
|
||||
dependencies.insert( dependencies.end(), _fwdRefsVec->begin(), _fwdRefsVec->end() );
|
||||
}
|
||||
|
||||
size_t curPos = 0;
|
||||
while( curPos < dependencies.size() ) {
|
||||
|
||||
bool isNewElement = ( checkedDependencies->insert( dependencies.at( curPos ) ) ).second;
|
||||
if( isNewElement ) {
|
||||
_fwdRefsVec = _fwdRefs->find( dependencies.at( curPos ) );
|
||||
|
||||
if( _fwdRefsVec != 0 ) {
|
||||
dependencies.insert( dependencies.end(), _fwdRefsVec->begin(), _fwdRefsVec->end() );
|
||||
}
|
||||
}
|
||||
|
||||
curPos++;
|
||||
}
|
||||
|
||||
return checkedDependencies;
|
||||
}
|
||||
|
||||
instanceSet * lazyInstMgr::instanceDependencies( instanceID id ) {
|
||||
return instanceDependenciesHelper( id, getFwdRefs() );
|
||||
}
|
||||
|
||||
void lazyInstMgr::openFileSafely( std::string fname ) {
|
||||
filesMtx.lock();
|
||||
size_t size = _files.size();
|
||||
_files.push_back( NULL ); //place Holder
|
||||
filesMtx.unlock();
|
||||
|
||||
lazyFileReader * fileReader = new lazyFileReader( fname, this, size );
|
||||
|
||||
filesMtx.lock();
|
||||
_files[size] = fileReader;
|
||||
filesMtx.unlock();
|
||||
}
|
||||
|
||||
instanceRefs_t * lazyInstMgr::getFwdRefsSafely() {
|
||||
|
||||
fwdRefsMtx.lock();
|
||||
instanceRefs_t * myFwdRefsCopy = new instanceRefs_t( _fwdInstanceRefs );
|
||||
fwdRefsMtx.unlock();
|
||||
|
||||
return myFwdRefsCopy;
|
||||
}
|
||||
|
||||
instanceRefs_t * lazyInstMgr::getRevRefsSafely() {
|
||||
|
||||
revRefsMtx.lock();
|
||||
instanceRefs_t * myRevRefsCopy = new instanceRefs_t( _revInstanceRefs );
|
||||
revRefsMtx.unlock();
|
||||
|
||||
return myRevRefsCopy;
|
||||
}
|
||||
|
||||
instanceTypes_t::cvector * lazyInstMgr::getInstancesSafely( std::string type ) {
|
||||
|
||||
instanceTypesMtx.lock();
|
||||
instanceTypes_t::cvector * typeInstances = _instanceTypes->find( type.c_str() );
|
||||
instanceTypesMtx.unlock();
|
||||
|
||||
return typeInstances;
|
||||
}
|
||||
|
||||
unsigned int lazyInstMgr::countInstancesSafely( std::string type ) {
|
||||
instanceTypes_t::cvector * v = getInstancesSafely( type );
|
||||
if( !v ) {
|
||||
return 0;
|
||||
}
|
||||
return v->size();
|
||||
}
|
||||
|
||||
SDAI_Application_instance * lazyInstMgr::loadInstanceSafely( instanceID id ) {
|
||||
assert( _mainRegistry && "Main registry has not been initialized. Do so with initRegistry() or setRegistry()." );
|
||||
SDAI_Application_instance * sdaiInst;
|
||||
|
||||
mtxLock( loadInstanceMtx );
|
||||
sdaiInst = _instancesLoaded.find( id );
|
||||
mtxUnlock( loadInstanceMtx );
|
||||
|
||||
if( !sdaiInst ) {
|
||||
sdaiInst = loadInstance( id );
|
||||
}
|
||||
|
||||
return sdaiInst;
|
||||
}
|
||||
|
||||
instanceSet * lazyInstMgr::instanceDependenciesSafely( instanceID id ) {
|
||||
return instanceDependenciesHelper( id, getFwdRefsSafely() );
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "lazyFileReader.h"
|
||||
#include "lazyTypes.h"
|
||||
|
||||
#include "sc_mutex.h"
|
||||
|
||||
#include "Registry.h"
|
||||
#include "sc_memmgr.h"
|
||||
|
||||
@@ -24,11 +22,11 @@ class instMgrAdapter;
|
||||
|
||||
class lazyInstMgr {
|
||||
protected:
|
||||
/** map from instance number to instances that it refers to
|
||||
/** multimap from instance number to instances that it refers to
|
||||
* \sa instanceRefs_pair
|
||||
*/
|
||||
instanceRefs_t _fwdInstanceRefs;
|
||||
/** map from instance number to instances that refer to it
|
||||
/** multimap from instance number to instances that refer to it - the majority of these will not be inverse references!
|
||||
* \sa instanceRefs_pair
|
||||
*/
|
||||
instanceRefs_t _revInstanceRefs;
|
||||
@@ -41,11 +39,15 @@ class lazyInstMgr {
|
||||
|
||||
/** map from instance number to instance pointer (loaded instances only)
|
||||
* \sa instancesLoaded_pair
|
||||
*
|
||||
* TODO should be multimap to allow use of instances in multiple data sections?
|
||||
* a unique instance ID (containing sectionID and instanceID) would also work
|
||||
*/
|
||||
instancesLoaded_t _instancesLoaded;
|
||||
|
||||
/** map from instance number to beginning and end positions and the data section
|
||||
* \sa instanceStreamPos_pair
|
||||
*
|
||||
* FIXME to save memory, modify judyL2Array to not use a vector until there are several
|
||||
* instances with the same instanceID. This will help elsewhere as well.
|
||||
*/
|
||||
@@ -64,13 +66,9 @@ class lazyInstMgr {
|
||||
|
||||
instMgrAdapter * _ima;
|
||||
|
||||
/** mutexes for mutual exclusion */
|
||||
sc_mutex fwdRefsMtx, revRefsMtx, instanceTypesMtx, loadInstanceMtx, instanceStreamPosMtx, dataSectionsMtx, filesMtx;
|
||||
|
||||
public:
|
||||
lazyInstMgr();
|
||||
~lazyInstMgr();
|
||||
void addSchema( void ( *initFn )() ); //?
|
||||
void openFile( std::string fname );
|
||||
|
||||
void addLazyInstance( namedLazyInstance inst );
|
||||
@@ -85,9 +83,14 @@ class lazyInstMgr {
|
||||
instanceRefs_t * getRevRefs() {
|
||||
return & _revInstanceRefs;
|
||||
}
|
||||
|
||||
/// returns two iterators delimiting the instances that match `type`
|
||||
instanceTypes_t::cvector * getInstances( std::string type ) { /*const*/
|
||||
/// returns a vector containing the instances that match `type`
|
||||
instanceTypes_t::cvector * getInstances( std::string type, bool caseSensitive = false ) { /*const*/
|
||||
if( !caseSensitive ) {
|
||||
std::string::iterator it = type.begin();
|
||||
for( ; it != type.end(); ++it ) {
|
||||
*it = toupper( *it );
|
||||
}
|
||||
}
|
||||
return _instanceTypes->find( type.c_str() );
|
||||
}
|
||||
/// get the number of instances of a certain type
|
||||
@@ -98,7 +101,6 @@ class lazyInstMgr {
|
||||
}
|
||||
return v->size();
|
||||
}
|
||||
|
||||
instancesLoaded_t * getHeaderInstances( fileID file ) {
|
||||
return _files[file]->getHeaderInstances();
|
||||
}
|
||||
@@ -146,12 +148,7 @@ class lazyInstMgr {
|
||||
/// get the number of types of instances.
|
||||
unsigned long getNumTypes() const;
|
||||
|
||||
/// reserves a slot in _dataSections vector. Gives the slot a value null, and return the index value.
|
||||
sectionID reserveDataSection();
|
||||
|
||||
/// updates _dataSections vector with the sreader value at the given index.
|
||||
void registerDataSection( lazyDataSectionReader * sreader, sectionID sid );
|
||||
|
||||
sectionID registerDataSection( lazyDataSectionReader * sreader );
|
||||
fileID registerLazyFile( lazyFileReader * freader );
|
||||
|
||||
ErrorDescriptor * getErrorDesc() {
|
||||
@@ -160,61 +157,26 @@ class lazyInstMgr {
|
||||
|
||||
SDAI_Application_instance * loadInstance( instanceID id );
|
||||
|
||||
/// lists all instances that one instance depends on (recursive)
|
||||
instanceSet * instanceDependencies( instanceID id );
|
||||
instanceSet * instanceDependenciesHelper( instanceID id, instanceRefs_t * _fwdRefs );
|
||||
|
||||
/// thread safe counterpart of openFile();
|
||||
void openFileSafely( std::string fname );
|
||||
|
||||
/// thread safe counterpart of getFwdRefs()
|
||||
instanceRefs_t * getFwdRefsSafely();
|
||||
|
||||
/// thread safe counterpart of getRevRefs()
|
||||
instanceRefs_t * getRevRefsSafely();
|
||||
|
||||
/// thread safe counterpart of getInstances()
|
||||
instanceTypes_t::cvector * getInstancesSafely( std::string type );
|
||||
|
||||
/// thread safe counterpart of countInstances()
|
||||
unsigned int countInstancesSafely( std::string type );
|
||||
|
||||
/// Thread safe counterpart of loadInstance( instanceID )
|
||||
SDAI_Application_instance * loadInstanceSafely( instanceID id );
|
||||
|
||||
/// Thread safe counterpart of instanceDependencies( instanceID )
|
||||
instanceSet * instanceDependenciesSafely( instanceID id );
|
||||
|
||||
void mtxLock( sc_mutex &mtx ) {
|
||||
mtx.lock();
|
||||
}
|
||||
|
||||
void mtxUnlock( sc_mutex &mtx ) {
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
/// unloads all instances. (For testing purpose, not thread safe)
|
||||
void unloadAllInstances() {
|
||||
_loadedInstanceCount = 0;
|
||||
_instancesLoaded.clear();
|
||||
}
|
||||
|
||||
/// (For testing purpose, not thread safe)
|
||||
instanceStreamPos_t * getInstanceStreamPos() {
|
||||
return &_instanceStreamPos;
|
||||
}
|
||||
|
||||
// TODO implement these
|
||||
/* * the opposite of instanceDependencies() - all instances that are *not* dependencies of one particular instance
|
||||
same as above, but with list of instances */
|
||||
//std::vector<instanceID> notDependencies(...)
|
||||
|
||||
//renumber instances so that they are numbered 1..N where N is the total number of instances
|
||||
//void normalizeInstanceIds();
|
||||
//find data that is repeated and eliminate, if possible
|
||||
//void eliminateDuplicates();
|
||||
//tell instMgr to use instances from this section
|
||||
//void useDataSection( sectionID id );
|
||||
// add another schema to registry
|
||||
//void addSchema( void ( *initFn )() );
|
||||
|
||||
//list all instances that one instance depends on (recursive)
|
||||
//std::vector<instanceID> instanceDependencies( instanceID id ); //set is faster?
|
||||
|
||||
/* * the opposite of instanceDependencies() - all instances that are *not* dependencies of one particular instance
|
||||
same as above, but with list of instances */
|
||||
//std::vector<instanceID> notDependencies(...)
|
||||
|
||||
//renumber instances so that they are numbered 1..N where N is the total number of instances
|
||||
//void normalizeInstanceIds();
|
||||
|
||||
//find data that is repeated and eliminate, if possible
|
||||
//void eliminateDuplicates();
|
||||
|
||||
//tell instMgr to use instances from this section
|
||||
//void useDataSection( sectionID id );
|
||||
|
||||
// TODO support references from one file to another
|
||||
};
|
||||
|
||||
@@ -11,15 +11,6 @@ lazyP21DataSectionReader::lazyP21DataSectionReader( lazyFileReader * parent, std
|
||||
while( nl = nextInstance(), ( ( nl.loc.begin > 0 ) && ( nl.name != 0 ) ) ) {
|
||||
parent->getInstMgr()->addLazyInstance( nl );
|
||||
}
|
||||
|
||||
if( sectionReader::_error->severity() <= SEVERITY_WARNING ) {
|
||||
sectionReader::_error->PrintContents( std::cerr );
|
||||
if( sectionReader::_error->severity() <= SEVERITY_INPUT_ERROR ) {
|
||||
_error = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( !_file.good() ) {
|
||||
_error = true;
|
||||
return;
|
||||
@@ -54,11 +45,7 @@ const namedLazyInstance lazyP21DataSectionReader::nextInstance() {
|
||||
skipWS();
|
||||
i.loc.section = _sectionID;
|
||||
skipWS();
|
||||
|
||||
std::string * keyword = new string();
|
||||
fillDelimitedKeyword( ";( /\\", *keyword );
|
||||
i.name = keyword->c_str();
|
||||
|
||||
i.name = getDelimitedKeyword( ";( /\\" );
|
||||
if( _file.good() ) {
|
||||
end = seekInstanceEnd( & i.refs );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef LAZYREFS_H
|
||||
#define LAZYREFS_H
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "lazyTypes.h"
|
||||
#include "ExpDict.h"
|
||||
#include "sdaiApplication_instance.h"
|
||||
|
||||
|
||||
|
||||
class lazyRefs {
|
||||
public:
|
||||
//typedefs
|
||||
typedef std::set<std::string> * entityTypeSet;
|
||||
typedef std::pair< EntityDescriptor *, const char * > attrPair; //EntityDescriptor and attr name
|
||||
typedef std::vector< STEPattribute * > attrVec;
|
||||
protected:
|
||||
/* don't need this - the default comparator of std::set, std::less, should work
|
||||
///functor to compare std::pair<> of pointers; in this case, those in attrPair
|
||||
struct pairCmp {
|
||||
bool operator()( const attrPair & lhs, const attrPair & rhs ) const {
|
||||
if( lhs.first == rhs.first && lhs.second == rhs.second ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
typedef std::set< attrPair, pairCmp > attrVec; //set of attrPair's, and comparison functor
|
||||
*/
|
||||
|
||||
///find any inverse attributes, put in `attrs`
|
||||
/// attrs not necessarily in order!
|
||||
void getInverseAttrs( attrVec & attrs, EntityDescriptor * ed ) {
|
||||
attrs.clear();
|
||||
supertypesIterator supersIter( ed );
|
||||
InverseAItr invAttrIter;
|
||||
Inverse_attribute * invAttr;
|
||||
for( ; !supersIter.empty(); ++supersIter ) {
|
||||
//look at attrs of *si
|
||||
invAttrIter( *supersIter );
|
||||
while( 0 != ( invAttr = invAttrIter.NextInverse_attribute() ) ) {
|
||||
attrs.push_back( invAttr );
|
||||
}
|
||||
}
|
||||
// look at our own attrs
|
||||
invAttrIter( *ed );
|
||||
while( 0 != ( invAttr = invAttrIter.NextInverse_attribute() ) ) {
|
||||
attrs.push_back( invAttr );
|
||||
}
|
||||
}
|
||||
|
||||
void loadPossibleInverseRefs( instanceID id ) {
|
||||
EntityDescriptor * eDesc = getEntityDescriptor( id );
|
||||
//it would be nice to be able to check the type of each potential reference and only load those for which there is an inverse attr
|
||||
//however, that would require that we build a list of all types with inverse reference *and* all of their children
|
||||
//that requires looking up each type in the registry and iterating over its supertypes
|
||||
//slow? faster if results are cached, perhaps in std::set<std::string>
|
||||
|
||||
/*
|
||||
* need to look for hits in _revInstanceRefs, then check the type of each
|
||||
* however, we must also check their supertypes - use checkIfEntityTypeMatch() (**** faster to compare entities with a subtype list instead? ****)
|
||||
* also, we must check which entity type actually declares the attr, and use that as the type name to match
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//for each inverse attr, add that type and its subtypes to a set
|
||||
attrVec invAttrs;
|
||||
getInverseAttrs( invAttrs, eDesc );
|
||||
attrVec::iterator iAiter = invAttrs.begin();
|
||||
for( ; iAiter != invAttrs.end(); ++iAiter ) {
|
||||
// const char * _inverted_attr_id;
|
||||
// const char * _inverted_entity_id;
|
||||
|
||||
iAiter->_inverted_attr_id;
|
||||
iAiter->_inverted_entity_id;
|
||||
iAiter->Owner();
|
||||
}
|
||||
|
||||
//find possible referring instances and loop over them, checking each, loading instances of types that may have matching refs
|
||||
instanceRefs_t::cvector * possRefs = _revInstanceRefs.find( id );
|
||||
const instanceRefs_t::cvector::iterator it = possRefs->cbegin();
|
||||
for( ; it != possRefs->cend; ++it ) {
|
||||
//1. get inst type
|
||||
//2. compare its type to types that may reference this inst
|
||||
//3. if there is a match, load it and check whether this instance is reference by the correct attr
|
||||
//4. if so, link the two
|
||||
//5. repeat
|
||||
}
|
||||
}
|
||||
public:
|
||||
void loadInverseRefs( instanceID id ) {}
|
||||
};
|
||||
|
||||
#endif //LAZYREFS_H
|
||||
@@ -0,0 +1,68 @@
|
||||
for inverse attrs, we have the attr name and the type of the instance
|
||||
|
||||
--load instance, find inverse attr(s)
|
||||
--for each inverse attr:
|
||||
--find all instance types that inherit from the inverted attr's owner (list A)
|
||||
--look up instances that reference the one in question (list B) - use memoization
|
||||
--find instances that match both lists, put in list C
|
||||
--load instances in list C
|
||||
--for list C, check that the relevant attr references the original instance - if not, unload (?)
|
||||
--
|
||||
|
||||
--when done with this inverse attr, cache list A
|
||||
|
||||
|
||||
|
||||
|
||||
EXAMPLE
|
||||
*******
|
||||
|
||||
information model
|
||||
-----------------
|
||||
ENTITY Object;
|
||||
ObjectType : OPTIONAL STRING;
|
||||
INVERSE
|
||||
IsDefinedBy : SET [0:?] OF RelDefinesByType FOR RelatedObjects;
|
||||
END_ENTITY;
|
||||
|
||||
ENTITY RelDefinesByType;
|
||||
RelatedObjects : SET [1:?] OF Object;
|
||||
END_ENTITY;
|
||||
|
||||
ENTITY Window
|
||||
SUBTYPE OF (Object);
|
||||
Description : OPTIONAL string;
|
||||
END_ENTITY;
|
||||
|
||||
data file
|
||||
---------
|
||||
#1=OBJECT('one');
|
||||
#2=RELDEFINESBYTYPE((#1));
|
||||
#3=RELDEFINESBYTYPE((#4));
|
||||
#4=WINDOW('two','blah');
|
||||
|
||||
#1 and #4 have an inverse attr, but this is not visible in the data file
|
||||
#2 and #3 have #1 and #4, respectively, in an aggregate (thus the parenthesis around the instance); in this case, a SET called RelatedObjects
|
||||
RelatedObjects is the inverted attr that the inverse attr IsDefinedBy links to
|
||||
|
||||
looking at the entity descriptor for WINDOW, it is not apparent that there is an inverse attr; its parents must be examined
|
||||
|
||||
|
||||
given inverted attr ia:
|
||||
attr method value
|
||||
----------- -----
|
||||
ia->Name() isdefinedby
|
||||
ia->inverted_attr_id_() relatedobjects
|
||||
ia->inverted_entity_id_() reldefinesbytype
|
||||
|
||||
1. for the instance in question, find inverse attrs with recursion
|
||||
2. for each ia,
|
||||
a. entity name is returned by ia->inverted_entity_id_()
|
||||
b. add this entity and its children to a list (list A)
|
||||
c. look up references to the current instance (list B)
|
||||
d. for each item in B, look up its type; if its type is present in A, remember the instance number (list C)
|
||||
e. load each instance in C
|
||||
f. (optional) check if the relevant inverted attr of instances loaded from list C reference the instance in step 1; if not, unload **IF** the instance hadn't been loaded
|
||||
--> if it was loaded, this implies that it is used elsewhere
|
||||
g. cache list A, since it may be useful in the future
|
||||
-- best to store such that the most recently (frequently?) used lists are retained and others are discarded
|
||||
@@ -3,12 +3,8 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
|
||||
# include <sc_thread.h>
|
||||
|
||||
#include "judyLArray.h"
|
||||
#include "judySArray.h"
|
||||
#include "judyL2Array.h"
|
||||
@@ -17,7 +13,6 @@
|
||||
class SDAI_Application_instance;
|
||||
class lazyDataSectionReader;
|
||||
class lazyFileReader;
|
||||
class mgrNodeHelper;
|
||||
|
||||
enum fileTypeEnum { Part21, Part28 };
|
||||
// enum loadingEnum { immediate, lazy };
|
||||
@@ -40,8 +35,6 @@ typedef uint64_t positionAndSection;
|
||||
|
||||
typedef std::vector< instanceID > instanceRefs;
|
||||
|
||||
typedef std::set< instanceID > instanceSet;
|
||||
|
||||
//TODO: create a "unique instance id" from the sectionID and instanceID, and use it everywhere?
|
||||
|
||||
/** This struct contains all the information necessary to locate an instance. It is primarily
|
||||
@@ -83,12 +76,6 @@ typedef std::vector< lazyDataSectionReader * > dataSectionReaderVec_t;
|
||||
// files
|
||||
typedef std::vector< lazyFileReader * > lazyFileReaderVec_t;
|
||||
|
||||
//map thread id to mgrNodeHelper. Each thread will have only one mgrNodeHelper value.
|
||||
typedef std::map< thread_id_t, mgrNodeHelper * > idNodeMap_t;
|
||||
|
||||
//thread id - mgrNodeHelper pointer pair to be used while using the above map
|
||||
typedef std::pair< thread_id_t, mgrNodeHelper * > idNodePair_t;
|
||||
|
||||
// type for performing actions on multiple instances
|
||||
// NOTE not useful? typedef std::vector< lazyInstance > lazyInstanceVec_t;
|
||||
|
||||
|
||||
@@ -71,34 +71,6 @@ instanceID printRefs( lazyInstMgr & mgr ) {
|
||||
return id;
|
||||
}
|
||||
|
||||
/// prints dependencies of an instance
|
||||
void printDeps( lazyInstMgr & mgr ) {
|
||||
const unsigned int displayInstances = 10;
|
||||
instanceRefs_t * refs = mgr.getFwdRefs();
|
||||
instanceRefs_t::cpair p = refs->end();
|
||||
|
||||
instanceID id = p.key;
|
||||
instanceSet * dependencies = mgr.instanceDependencies( id );
|
||||
|
||||
std::cout << std::endl <<"Dependencies" << std::endl << "==============" << std::endl;
|
||||
instanceSet::const_iterator it( dependencies->begin() ), end( dependencies->end() );
|
||||
|
||||
std::cout << "Example: Instance #" << id << " is recursively dependent on " << dependencies->size() << " instances: ";
|
||||
unsigned int i;
|
||||
for(i = 0; it != end && i < displayInstances; it++, i++ ) {
|
||||
std::cout << *it << " ";
|
||||
}
|
||||
|
||||
if( dependencies->size() > displayInstances ) {
|
||||
std::cout << ".... (Displaying only " << displayInstances << " instances) ";
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
delete dependencies;
|
||||
}
|
||||
|
||||
///prints info about a complex instance
|
||||
void dumpComplexInst( STEPcomplex * c, unsigned int depth ) {
|
||||
if( c ) {
|
||||
@@ -155,7 +127,6 @@ int main( int argc, char ** argv ) {
|
||||
// std::cout << "Total types: " << mgr->getNumTypes() << std::endl;
|
||||
|
||||
instWithRef = printRefs( *mgr );
|
||||
printDeps( *mgr );
|
||||
|
||||
#ifndef NO_REGISTRY
|
||||
if( instWithRef ) {
|
||||
|
||||
@@ -1,593 +0,0 @@
|
||||
#include "lazyTypes.h"
|
||||
#include "lazyInstMgr.h"
|
||||
#include "SdaiSchemaInit.h"
|
||||
#include "instMgrHelper.h"
|
||||
|
||||
// Registry will be needed for checkLazyLoadingSafety & checkLazyLoadingSafetyWithAdapter checks.
|
||||
#ifndef NO_REGISTRY
|
||||
# include "schema.h"
|
||||
#endif //NO_REGISTRY
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef HAVE_STD_THREAD
|
||||
# include <thread>
|
||||
#else
|
||||
# error Need std::thread for this test!
|
||||
#endif
|
||||
|
||||
/// It copies the keys of the _refs judy structure provided to it into the vector realRefs
|
||||
void prepareRealRefs ( instanceRefs_t * _refs, instanceRefs &realRefs ) {
|
||||
|
||||
instanceID last = _refs->end().key;
|
||||
instanceID current = _refs->begin().key;
|
||||
|
||||
while( current != last ) {
|
||||
realRefs.push_back( current );
|
||||
current = _refs->next().key;
|
||||
}
|
||||
|
||||
realRefs.push_back( last );
|
||||
}
|
||||
|
||||
/// It copies the keys of the _refs judy structure provided to it into the vector realRefs
|
||||
void prepareRealRefsFromStreamPos ( instanceStreamPos_t * _spos, instanceRefs &realRefs ) {
|
||||
|
||||
instanceID last = _spos->end().key;
|
||||
instanceID current = _spos->begin().key;
|
||||
|
||||
while( current != last ) {
|
||||
realRefs.push_back( current );
|
||||
current = _spos->next().key;
|
||||
}
|
||||
|
||||
realRefs.push_back( last );
|
||||
}
|
||||
|
||||
|
||||
/// Used by an individual thread to iterate over the keys of the _fwdRefs / _revRefs multiple times. For each iteration it expects the order of the keys to be the same as dictated by realRefs.
|
||||
void iterateOverRefs ( lazyInstMgr *mgr, instanceRefs * realRefs, bool forward, bool * success ) {
|
||||
const int iterations = 1000;
|
||||
int i, k, instances = realRefs->size();
|
||||
instanceID current;
|
||||
instanceRefs_t * _refs;
|
||||
|
||||
for( k = 0; k < iterations; k++ ) {
|
||||
_refs = forward ? mgr->getFwdRefsSafely() : mgr->getRevRefsSafely();
|
||||
|
||||
current = _refs->begin().key;
|
||||
for( i = 0; i < instances; i++ ) {
|
||||
|
||||
if( current != (*realRefs)[i] ) {
|
||||
break;
|
||||
}
|
||||
|
||||
current = _refs->next().key;
|
||||
}
|
||||
|
||||
*success = *success && ( i == instances );
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks the thread safety of _fwdRefs (_revRefs) when the forward value provided to it is true (false).
|
||||
bool checkRefsSafety( char * fileName, bool forward ) {
|
||||
instanceRefs realRefs;
|
||||
lazyInstMgr * mgr = new lazyInstMgr;
|
||||
mgr->openFile( fileName );
|
||||
|
||||
if( forward ) {
|
||||
std::cout << "Checking thread safety while iterating over forward references..." ;
|
||||
prepareRealRefs( mgr->getFwdRefs(), realRefs );
|
||||
} else {
|
||||
std::cout << "Checking thread safety while iterating over backward references..." ;
|
||||
prepareRealRefs( mgr->getRevRefs(), realRefs );
|
||||
}
|
||||
|
||||
bool success[2] = { true, true };
|
||||
std::thread first( iterateOverRefs, mgr, &realRefs, forward, &success[0] );
|
||||
std::thread second( iterateOverRefs, mgr, &realRefs, forward, &success[1] );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool pass = ( success[0] && success[1] );
|
||||
if( pass ) {
|
||||
std::cout << "..PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
|
||||
if( !success[0] ) {
|
||||
std::cout << "\tThread 0 could not iterate properly" << std::endl;
|
||||
}
|
||||
|
||||
if( !success[1] ) {
|
||||
std::cout << "\tThread 1 could not iterate properly" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
delete mgr;
|
||||
return pass;
|
||||
}
|
||||
|
||||
/// Checks thread safety of getFwdRefs();
|
||||
bool checkFwdRefsSafety( char * fileName ) {
|
||||
return checkRefsSafety( fileName, true );
|
||||
}
|
||||
|
||||
/// Checks thread safety of getFwdRefs();
|
||||
bool checkRevRefsSafety( char * fileName ) {
|
||||
return checkRefsSafety( fileName, false );
|
||||
}
|
||||
|
||||
/// A vector of some common types which are present in most step files. The types persent in this vector are used to check for thread safety.
|
||||
const std::vector< std::string > commonTypes { "PRODUCT_DEFINITION", "CARTESIAN_POINT", "NODE", "CLASSIFICATION_ROLE" };
|
||||
|
||||
/// Prepares a vector containing pointers to list of instances of the above types.
|
||||
void prepareSameTypeInstances( lazyInstMgr *mgr, std::vector< const instanceRefs * > &sameTypeInstances ) {
|
||||
|
||||
for( int i = 0; i < ( int )commonTypes.size(); i++ ) {
|
||||
sameTypeInstances.push_back( mgr->getInstances( commonTypes[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/// compares the list of both vectors. Returns true when the lists are same.
|
||||
bool compareTypeLists( const instanceRefs * v1, const instanceRefs * v2 ) {
|
||||
|
||||
if( v1 == NULL || v1->empty() ) {
|
||||
//return true if both lists are NULL or EMPTY. false if only one is NULL or EMPTY
|
||||
return ( v2 == NULL || v2->empty() );
|
||||
} else {
|
||||
//An O(1) operation since if the first element is same so will be the rest. (std::vectors are concurrent read safe)
|
||||
return ( v1->at( 0 ) == v2->at( 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/// compares the original instances lists with the thread's own view of instances list.
|
||||
void iterateTypeLists( lazyInstMgr * mgr, std::vector< const instanceRefs * > * sameTypeInstances, bool * success ) {
|
||||
const int iterations = 100000;
|
||||
const instanceRefs * refs;
|
||||
int i, k, instances = commonTypes.size();
|
||||
for( k = 0; k < iterations; k++ ) {
|
||||
|
||||
for( i = 0; i < instances; i++ ) {
|
||||
|
||||
refs = mgr->getInstancesSafely( commonTypes[i] );
|
||||
|
||||
if( !compareTypeLists( refs, (*sameTypeInstances)[i] ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*success = *success && ( i == instances );
|
||||
}
|
||||
}
|
||||
|
||||
/// checks the thread safety of getInstances();
|
||||
bool checkTypeInstancesSafety( char * fileName ) {
|
||||
lazyInstMgr * mgr = new lazyInstMgr;
|
||||
mgr->openFile( fileName );
|
||||
|
||||
std::cout << "Checking thread safety while getting insances of a common types..." ;
|
||||
|
||||
std::vector< const instanceRefs * > sameTypeInstances;
|
||||
prepareSameTypeInstances( mgr, sameTypeInstances );
|
||||
|
||||
bool success[2] = { true, true };
|
||||
std::thread first( iterateTypeLists, mgr, &sameTypeInstances, &success[0] );
|
||||
std::thread second( iterateTypeLists, mgr, &sameTypeInstances, &success[1] );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool pass = ( success[0] && success[1] );
|
||||
if( pass ) {
|
||||
std::cout << "..PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
|
||||
if( !success[0] ) {
|
||||
std::cout << "\tThread 0 could not get insances properly" << std::endl;
|
||||
}
|
||||
|
||||
if( !success[1] ) {
|
||||
std::cout << "\tThread 1 could not get insances properly" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\t\tNumber of instances of different types: ";
|
||||
for( int i = 0; i < ( int )commonTypes.size(); i++ ) {
|
||||
std::cout << ( sameTypeInstances[i] == NULL ? 0 : sameTypeInstances[i]->size() ) << " ";
|
||||
}
|
||||
|
||||
std::cout << std::endl << std::endl;
|
||||
delete mgr;
|
||||
return pass;
|
||||
}
|
||||
|
||||
/// load instances found in _refs into the instancesLoaded. After doing this once, it iterates over the _refs and reports any changes in loaded value.
|
||||
/// Either directly calls loadInstance or uses an adapter, (determined by the value of useAdapter)
|
||||
void loadInstancesFromList( lazyInstMgr * mgr, instanceRefs * _refs, instancesLoaded_t * myInstances, bool useAdapter, bool * success) {
|
||||
const int instances = _refs->size();
|
||||
SDAI_Application_instance * sdaiInstance;
|
||||
int i;
|
||||
// Initial insertion into myInstances
|
||||
for( i = 0; i < instances; i++ ) {
|
||||
if( useAdapter ) {
|
||||
sdaiInstance = mgr->getAdapter()->FindFileIdSafely( _refs->at( i ) )->GetSTEPentitySafely();
|
||||
} else {
|
||||
sdaiInstance = mgr->loadInstanceSafely( _refs->at( i ) );
|
||||
}
|
||||
|
||||
myInstances->insert( _refs->at( i ), sdaiInstance );
|
||||
}
|
||||
|
||||
// For each instance comparing the new pointer with the original pointer
|
||||
for( i = 0; i < instances; i++ ) {
|
||||
if( useAdapter ) {
|
||||
sdaiInstance = mgr->getAdapter()->FindFileIdSafely( _refs->at( i ) )->GetSTEPentitySafely();
|
||||
} else {
|
||||
sdaiInstance = mgr->loadInstanceSafely( _refs->at( i ) );
|
||||
}
|
||||
|
||||
if( myInstances->find( _refs->at( i ) ) != sdaiInstance ) {
|
||||
//the old value has been overwritten. An object lazy-loaded twice. Not Good!!!
|
||||
*success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//compares the instances present in loadedOnT1 and loadedOnT2. If both have an instance belonging to a particular instanceID then the instances should be same
|
||||
bool compareLoadedInstances( instanceRefs * toBeLoadedOnT1, instancesLoaded_t * loadedOnT1, instanceRefs * toBeLoadedOnT2, instancesLoaded_t * loadedOnT2 ) {
|
||||
SDAI_Application_instance * sdaiInstance;
|
||||
|
||||
//Iterate over instanceID's in toBeLoadedOnT1
|
||||
int i, instances = toBeLoadedOnT1->size();
|
||||
for( i = 0; i < instances; i++ ) {
|
||||
sdaiInstance = loadedOnT2->find( toBeLoadedOnT1->at( i ) );
|
||||
if( sdaiInstance != NULL ) {
|
||||
if( sdaiInstance != loadedOnT1->find( toBeLoadedOnT1->at( i ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Iterate over instanceID's in toBeLoadedOnT2
|
||||
instances = toBeLoadedOnT2->size();
|
||||
for( i = 0; i < instances; i++ ) {
|
||||
sdaiInstance = loadedOnT1->find( toBeLoadedOnT2->at( i ) );
|
||||
if( sdaiInstance != NULL ) {
|
||||
if( sdaiInstance != loadedOnT2->find( toBeLoadedOnT2->at( i ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NO_REGISTRY
|
||||
//checks thread safety of loadInstance. (Also of instMgrAdapter if useAdapter is TRUE)
|
||||
bool checkLazyLoadingSafety( char * fileName, bool useAdapter=false ) {
|
||||
|
||||
instanceRefs instancesToBeLoadedFwd, instancesToBeLoadedRev;
|
||||
instanceRefs * toBeLoadedOnT1, * toBeLoadedOnT2;
|
||||
instancesLoaded_t loadedOnT1, loadedOnT2;
|
||||
|
||||
lazyInstMgr * mgr = new lazyInstMgr;
|
||||
mgr->initRegistry( SchemaInit );
|
||||
mgr->openFile( fileName );
|
||||
|
||||
std::cout << "Checking thread safety in Lazy Loading ("<< ( useAdapter ? "with" : "without" ) << " Adapter)...";
|
||||
|
||||
prepareRealRefs( mgr->getFwdRefs(), instancesToBeLoadedFwd );
|
||||
prepareRealRefs( mgr->getRevRefs(), instancesToBeLoadedRev );
|
||||
|
||||
bool intraThreadSuccess[2] = { true, true };
|
||||
bool interThreadSuccess = true;
|
||||
const int iterations = 50;
|
||||
for( int i = 0; i < 2 * iterations; i++ ) {
|
||||
// First set iterations both threads will try to load from same list.
|
||||
toBeLoadedOnT1 = &instancesToBeLoadedFwd;
|
||||
toBeLoadedOnT2 = i < iterations ? &instancesToBeLoadedFwd : &instancesToBeLoadedRev;
|
||||
|
||||
std::thread first( loadInstancesFromList, mgr, toBeLoadedOnT1, &loadedOnT1, useAdapter, &intraThreadSuccess[0] );
|
||||
std::thread second( loadInstancesFromList, mgr, toBeLoadedOnT2, &loadedOnT2, useAdapter, &intraThreadSuccess[1] );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
interThreadSuccess &= compareLoadedInstances( toBeLoadedOnT1, &loadedOnT1, toBeLoadedOnT2, &loadedOnT2 );
|
||||
mgr->unloadAllInstances();
|
||||
|
||||
loadedOnT1.clear();
|
||||
loadedOnT2.clear();
|
||||
}
|
||||
|
||||
bool pass = ( intraThreadSuccess[0] && intraThreadSuccess[1] && interThreadSuccess );
|
||||
if( pass ) {
|
||||
std::cout << "..PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
|
||||
if( !intraThreadSuccess[0] ) {
|
||||
std::cout << "\tThread 0: Difference in instances loaded within 1st and 2nd iterations" << std::endl;
|
||||
}
|
||||
|
||||
if( !intraThreadSuccess[1] ) {
|
||||
std::cout << "\tThread 1: Difference in instances loaded within 1st and 2nd iterations" << std::endl;
|
||||
}
|
||||
|
||||
if( !interThreadSuccess ) {
|
||||
std::cout << "\tDifference in instances loaded by the 2 threads" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
delete mgr;
|
||||
return pass;
|
||||
}
|
||||
|
||||
//checks thread safety of lazyloading along with that of instMgrAdapter
|
||||
bool checkLazyLoadingSafetyWithAdapter( char * fileName ) {
|
||||
return checkLazyLoadingSafety( fileName, true );
|
||||
}
|
||||
#endif //NO_REGISTRY
|
||||
|
||||
/// enum elements represent the status used checking thread safety of openFile
|
||||
enum lazyInstMgrStatus {
|
||||
FWD_REFS,
|
||||
REV_REFS,
|
||||
TYPES,
|
||||
TOTAL_COUNT,
|
||||
COUNT_DATA_SECTIONS,
|
||||
LONGEST_TYPE,
|
||||
STREAM_POS,
|
||||
OK
|
||||
};
|
||||
|
||||
std::string getLazyInstMgrStatusString( lazyInstMgrStatus lIMStatus ) {
|
||||
switch( lIMStatus ) {
|
||||
case FWD_REFS: return "FWD_REFS";
|
||||
case REV_REFS: return "REV_REFS";
|
||||
case TYPES: return "TYPES";
|
||||
case TOTAL_COUNT: return "TOTAL_COUNT";
|
||||
case COUNT_DATA_SECTIONS: return "COUNT_DATA_SECTIONS";
|
||||
case LONGEST_TYPE: return "LONGEST_TYPE";
|
||||
case STREAM_POS: return "STREAM_POS";
|
||||
case OK: return "OK";
|
||||
default: return "Unknown Type";
|
||||
}
|
||||
}
|
||||
|
||||
/// compares the given instanceRefs_t.
|
||||
bool compareRefs( instanceRefs_t * _refs1, instanceRefs_t * _refs2 ) {
|
||||
instanceRefs refs1, refs2;
|
||||
prepareRealRefs( _refs1, refs1 );
|
||||
prepareRealRefs( _refs2, refs2 );
|
||||
|
||||
//both vectors should have same number of elements
|
||||
if( refs1.size() != refs2.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < refs1.size(); i++ ) {
|
||||
const instanceRefs * deps1 = _refs1->find( refs1[i] );
|
||||
const instanceRefs * deps2 = _refs2->find( refs1[i] );
|
||||
|
||||
//Just compare the size of both (value) vectors is sufficient
|
||||
if( deps2 == NULL || deps1->size() != deps2->size() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// compares the given instance vectors. Returns true if both have same elements (irrespective of their order)
|
||||
bool compareInstanceRefs( const instanceRefs * refs1, const instanceRefs * refs2 ) {
|
||||
if( refs1 == NULL ) {
|
||||
return ( refs2 == NULL ) || ( refs2->size() == 0 );
|
||||
}
|
||||
|
||||
if( refs2 == NULL ) {
|
||||
return ( refs1 == NULL ) || ( refs1->size() == 0 );
|
||||
}
|
||||
|
||||
if( refs1->size() != refs2->size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < refs1->size(); i++ )
|
||||
{
|
||||
if( std::find( refs2->begin(), refs2->end(), refs1->at( i ) ) == refs2->end() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// compares _instanceTypes data structure of both managers.
|
||||
bool compareTypes( lazyInstMgr * mgr1, lazyInstMgr * mgr2 ) {
|
||||
int i, types = commonTypes.size();
|
||||
for( i = 0; i < types; i++ ) {
|
||||
const instanceRefs * refs1 = mgr1->getInstances( commonTypes[i] );
|
||||
const instanceRefs * refs2 = mgr2->getInstances( commonTypes[i] );
|
||||
if( !compareInstanceRefs( refs1, refs2 ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// compares the given positionAndSection vectors. Returns true if both have same elements (irrespective of their order)
|
||||
bool comparePosVectors( const std::vector< positionAndSection > * pos1, const std::vector< positionAndSection > * pos2 ) {
|
||||
if( pos1->size() != pos2->size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned i, j;
|
||||
for( i = 0; i < pos1->size(); i++ ) {
|
||||
bool result = false;
|
||||
for( j = 0; j < pos2->size(); j++ ) {
|
||||
positionAndSection ps1, ps2;
|
||||
ps1 = pos1->at( i );
|
||||
ps2 = pos2->at( j );
|
||||
|
||||
//only checking the offset as the sectionID may be different
|
||||
if( ( ps1 & 0xFFFFFFFFFFFF ) == ( ps2 & 0xFFFFFFFFFFFF ) ) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !result ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// For every instance compares its corresponding stream position vector in both lazyInstMgr. Returns false in case of any disprenency
|
||||
bool compareStreamPos( lazyInstMgr * mgr1, lazyInstMgr * mgr2 ) {
|
||||
|
||||
instanceRefs refs1, refs2;
|
||||
instanceStreamPos_t * _pos1 = mgr1->getInstanceStreamPos();
|
||||
instanceStreamPos_t * _pos2 = mgr2->getInstanceStreamPos();
|
||||
|
||||
prepareRealRefsFromStreamPos( _pos1, refs1 );
|
||||
prepareRealRefsFromStreamPos( _pos2, refs2 );
|
||||
|
||||
// number of instances in both managers must be equal
|
||||
if( refs1.size() != refs2.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::vector< positionAndSection > * pos1, * pos2;
|
||||
|
||||
unsigned int i;
|
||||
for( i = 0; i < refs1.size(); i++ ) {
|
||||
pos1 = _pos1->find( refs1[i] );
|
||||
pos2 = _pos2->find( refs1[i] );
|
||||
//checking pos1 and pos2 for similarity
|
||||
if( !comparePosVectors( pos1, pos2 ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// compares various data structures of both lazyInstMgr's and returns OK if both are similar, else returns the point of difference.
|
||||
lazyInstMgrStatus compareLazyInstMgr( lazyInstMgr * mgr1, lazyInstMgr * mgr2 ) {
|
||||
|
||||
if( !compareRefs( mgr1->getFwdRefs(), mgr2->getFwdRefs() ) ) {
|
||||
return FWD_REFS;
|
||||
}
|
||||
|
||||
if( !compareRefs( mgr1->getRevRefs(), mgr2->getRevRefs() ) ) {
|
||||
return REV_REFS;
|
||||
}
|
||||
|
||||
// compares getType and getNumTypes
|
||||
if( !compareTypes( mgr1, mgr2 ) ) {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
if( mgr1->totalInstanceCount() != mgr2->totalInstanceCount() ) {
|
||||
return TOTAL_COUNT;
|
||||
}
|
||||
|
||||
if( mgr1->countDataSections() != mgr2->countDataSections() ) {
|
||||
return COUNT_DATA_SECTIONS;
|
||||
}
|
||||
|
||||
if( mgr1->getLongestTypeName().length() != mgr2->getLongestTypeName().length() ) {
|
||||
return LONGEST_TYPE;
|
||||
}
|
||||
|
||||
if( !compareStreamPos( mgr1, mgr2 ) ) {
|
||||
return STREAM_POS;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// used by different threads to open a step file
|
||||
void openFile( lazyInstMgr * mgr, char * fileName ) {
|
||||
mgr->openFileSafely( fileName );
|
||||
}
|
||||
|
||||
/// checks the thread safety by opening multiple files in parallel
|
||||
bool checkOpenFileSafety( char * file1, char * file2 ) {
|
||||
lazyInstMgr * e_mgr = new lazyInstMgr; //expected lazyInstMgr
|
||||
|
||||
std::cout << "Checking thread safety while opening multiple files in parallel...";
|
||||
|
||||
e_mgr->openFile( file1 );
|
||||
e_mgr->openFile( file2 );
|
||||
|
||||
lazyInstMgrStatus compareResult = OK;
|
||||
const int iterations = 100;
|
||||
for( int i = 0; i < iterations; i++ ) {
|
||||
lazyInstMgr * a_mgr = new lazyInstMgr; //actual lazyInstMgr
|
||||
|
||||
std::thread first( openFile, a_mgr, file1 );
|
||||
std::thread second( openFile, a_mgr, file2 );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
compareResult = compareLazyInstMgr( e_mgr, a_mgr );
|
||||
|
||||
delete a_mgr;
|
||||
|
||||
if( compareResult != OK ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pass = ( compareResult == OK );
|
||||
if( pass ) {
|
||||
std::cout << "..PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
std::cout << "\tDisperency in " << getLazyInstMgrStatusString( compareResult ) << " structure" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
delete e_mgr;
|
||||
return pass;
|
||||
}
|
||||
|
||||
|
||||
/// These tests were run on stepcode/data/cd209/ATS1-out.stp && stepcode/data/cd209/ATS10-out.stp (Bigger files may take a longer time)
|
||||
int main( int argc, char ** argv ) {
|
||||
if( argc != 3 ) {
|
||||
std::cerr << "Expected two argument, given " << argc - 1 << ". Exiting." << std::endl;
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
bool pass = true;
|
||||
|
||||
pass &= checkFwdRefsSafety( argv[1] );
|
||||
pass &= checkRevRefsSafety( argv[1] );
|
||||
|
||||
pass &= checkTypeInstancesSafety( argv[1] );
|
||||
|
||||
#ifndef NO_REGISTRY
|
||||
pass &= checkLazyLoadingSafety( argv[1] );
|
||||
pass &= checkLazyLoadingSafetyWithAdapter( argv[1] );
|
||||
#endif //NO_REGISTRY
|
||||
|
||||
pass &= checkOpenFileSafety( argv[1], argv[2] );
|
||||
|
||||
if( pass ) {
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ p21HeaderSectionReader::p21HeaderSectionReader( lazyFileReader * parent, std::if
|
||||
findSectionEnd();
|
||||
_file.seekg( _sectionStart );
|
||||
namedLazyInstance nl;
|
||||
nextFreeInstance = 4; // 1-3 are reserved per 10303-21
|
||||
while( nl = nextInstance(), ( nl.loc.begin > 0 ) ) {
|
||||
std::streampos pos = _file.tellg();
|
||||
_headerInstances->insert( nl.loc.instance, getRealInstance( _lazyFile->getInstMgr()->getHeaderRegistry(), nl.loc.begin, nl.loc.instance, nl.name, "", true ) );
|
||||
@@ -32,6 +31,7 @@ p21HeaderSectionReader::p21HeaderSectionReader( lazyFileReader * parent, std::if
|
||||
// part of readdata1
|
||||
const namedLazyInstance p21HeaderSectionReader::nextInstance() {
|
||||
namedLazyInstance i;
|
||||
static instanceID nextFreeInstance = 4; // 1-3 are reserved per 10303-21
|
||||
|
||||
i.loc.begin = _file.tellg();
|
||||
i.loc.section = _sectionID;
|
||||
@@ -39,9 +39,7 @@ const namedLazyInstance p21HeaderSectionReader::nextInstance() {
|
||||
if( i.loc.begin <= 0 ) {
|
||||
i.name = 0;
|
||||
} else {
|
||||
std::string * keyword = new string();
|
||||
fillDelimitedKeyword( ";( /\\", *keyword );
|
||||
i.name = keyword->c_str();
|
||||
i.name = getDelimitedKeyword( ";( /\\" );
|
||||
|
||||
if( 0 == strcmp( "FILE_DESCRIPTION", i.name ) ) {
|
||||
i.loc.instance = 1;
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "sc_export.h"
|
||||
|
||||
class SC_LAZYFILE_EXPORT p21HeaderSectionReader: public headerSectionReader {
|
||||
protected:
|
||||
instanceID nextFreeInstance;
|
||||
public:
|
||||
p21HeaderSectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid );
|
||||
void findSectionStart();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "Registry.h"
|
||||
#include "sc_strtoull.h"
|
||||
#include "sdaiApplication_instance.h"
|
||||
#include "read_func.h"
|
||||
#include "SdaiSchemaInit.h"
|
||||
@@ -24,7 +23,6 @@
|
||||
sectionReader::sectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid ):
|
||||
_lazyFile( parent ), _file( file ), _sectionStart( start ), _sectionID( sid ) {
|
||||
_fileID = _lazyFile->ID();
|
||||
_error = new ErrorDescriptor();
|
||||
}
|
||||
|
||||
|
||||
@@ -81,9 +79,10 @@ std::streampos sectionReader::findNormalString( const std::string & str, bool se
|
||||
}
|
||||
|
||||
|
||||
//NOTE different behavior than const char * FillKeyword( istream & in, const char * delims, ErrorDescriptor & err, std::string & str ) in read_func.cc
|
||||
void sectionReader::fillDelimitedKeyword( const char * delimiters, std::string &str ) {
|
||||
char c, firstSpaceDelimeter;
|
||||
//NOTE different behavior than const char * GetKeyword( istream & in, const char * delims, ErrorDescriptor & err ) in read_func.cc
|
||||
const char * sectionReader::getDelimitedKeyword( const char * delimiters ) {
|
||||
static std::string str;
|
||||
char c;
|
||||
str.clear();
|
||||
str.reserve( 100 );
|
||||
skipWS();
|
||||
@@ -96,22 +95,17 @@ void sectionReader::fillDelimitedKeyword( const char * delimiters, std::string &
|
||||
findNormalString( "*/" );
|
||||
skipWS();
|
||||
continue;
|
||||
} else if( isspace( c ) ) {
|
||||
//firstSpaceDelimeter is used for comparision later to handle the case where the first whitespace was a delimeter itself
|
||||
firstSpaceDelimeter = c;
|
||||
skipWS();//skip the remaining whitespaces
|
||||
break;
|
||||
} else {
|
||||
_file.putback( c );
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = _file.peek();
|
||||
if( !strchr( delimiters, c ) && !strchr( delimiters, firstSpaceDelimeter ) ) {
|
||||
// current c is not a delimiter, the first white space encountered is also not a delimeter
|
||||
if( !strchr( delimiters, c ) ) {
|
||||
std::cerr << SC_CURRENT_FUNCTION << ": missing delimiter. Found " << c << ", expected one of " << delimiters << " at end of keyword " << str << ". File offset: " << _file.tellg() << std::endl;
|
||||
abort();
|
||||
}
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
/// search forward in the file for the end of the instance. Start position should
|
||||
@@ -180,8 +174,9 @@ void sectionReader::locateAllInstances() {
|
||||
}
|
||||
|
||||
instanceID sectionReader::readInstanceNumber() {
|
||||
std::streampos start, end;
|
||||
char c;
|
||||
size_t digits = 0;
|
||||
int digits = 0;
|
||||
instanceID id = 0;
|
||||
|
||||
//find instance number ("# nnnn ="), where ' ' is any whitespace found by isspace()
|
||||
@@ -198,55 +193,25 @@ instanceID sectionReader::readInstanceNumber() {
|
||||
return 0;
|
||||
}
|
||||
skipWS();
|
||||
|
||||
// The largest instance ID yet supported is the maximum value of unsigned long long int
|
||||
assert( std::numeric_limits<instanceID>::max() <= std::numeric_limits<unsigned long long int>::max() );
|
||||
|
||||
size_t instanceIDLength = std::numeric_limits<instanceID>::digits10 + 1;
|
||||
char * buffer = new char( instanceIDLength + 1 ); // +1 for the terminating character
|
||||
|
||||
std::stringstream errorMsg;
|
||||
|
||||
start = _file.tellg();
|
||||
do {
|
||||
c = _file.get();
|
||||
if( isdigit( c ) ) {
|
||||
buffer[ digits ] = c; //copy the charcter into the buffer
|
||||
digits++;
|
||||
|
||||
} else {
|
||||
_file.unget();
|
||||
break;
|
||||
}
|
||||
|
||||
if( digits > instanceIDLength ) {
|
||||
errorMsg << "A very large instance ID of string length greater then " << instanceIDLength << " found. Skipping data section " << _sectionID << ".";
|
||||
|
||||
_error->GreaterSeverity( SEVERITY_INPUT_ERROR );
|
||||
_error->UserMsg( "A very large instance ID encountered" );
|
||||
_error->DetailMsg( errorMsg.str() );
|
||||
|
||||
delete buffer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} while( _file.good() );
|
||||
buffer[ digits ] = '\0'; //Append the terminating character
|
||||
skipWS();
|
||||
|
||||
if( _file.good() && ( digits > 0 ) && ( _file.get() == '=' ) ) {
|
||||
id = strtoull( buffer, NULL, 10);
|
||||
if( id == std::numeric_limits<instanceID>::max() ) {
|
||||
//Handling those cases where although the number of digits is equal, but the id value is greater then equal to the maximum allowed value.
|
||||
errorMsg << "A very large instance ID caused an overflow. Skipping data section " << _sectionID << ".";
|
||||
|
||||
_error->GreaterSeverity( SEVERITY_INPUT_ERROR );
|
||||
_error->UserMsg( "A very large instance ID encountered" );
|
||||
_error->DetailMsg( errorMsg.str() );
|
||||
}
|
||||
|
||||
end = _file.tellg();
|
||||
_file.seekg( start );
|
||||
_file >> id;
|
||||
_file.seekg( end );
|
||||
assert( id > 0 );
|
||||
}
|
||||
delete buffer;
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -255,7 +220,7 @@ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg
|
||||
const std::string & typeName, const std::string & schName, bool header ) {
|
||||
char c;
|
||||
const char * tName = 0, * sName = 0; //these are necessary since typeName and schName are const
|
||||
std::string comment, keyword;
|
||||
std::string comment;
|
||||
Severity sev;
|
||||
SDAI_Application_instance * inst = 0;
|
||||
|
||||
@@ -299,8 +264,7 @@ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg
|
||||
break;
|
||||
default:
|
||||
if( ( !header ) && ( typeName.size() == 0 ) ) {
|
||||
fillDelimitedKeyword( ";( /\\", keyword );
|
||||
tName = keyword.c_str();
|
||||
tName = getDelimitedKeyword( ";( /\\" );
|
||||
}
|
||||
inst = reg->ObjCreate( tName, sName );
|
||||
break;
|
||||
@@ -326,9 +290,7 @@ STEPcomplex * sectionReader::CreateSubSuperInstance( const Registry * reg, insta
|
||||
std::vector<std::string *> typeNames;
|
||||
_file.get(); //move past the first '('
|
||||
while( _file.good() && ( _file.peek() != ')' ) ) {
|
||||
std::string keyword;
|
||||
fillDelimitedKeyword( ";( /\\", keyword );
|
||||
typeNames.push_back( new std::string( keyword ) );
|
||||
typeNames.push_back( new std::string( getDelimitedKeyword( ";( /\\" ) ) );
|
||||
if( typeNames.back()->empty() ) {
|
||||
delete typeNames.back();
|
||||
typeNames.pop_back();
|
||||
|
||||
@@ -41,7 +41,7 @@ class SC_LAZYFILE_EXPORT sectionReader {
|
||||
|
||||
/** Get a keyword ending with one of delimiters.
|
||||
*/
|
||||
void fillDelimitedKeyword( const char * delimiters, std::string &keyword );
|
||||
const char * getDelimitedKeyword( const char * delimiters );
|
||||
|
||||
/** Seek to the end of the current instance */
|
||||
std::streampos seekInstanceEnd( instanceRefs ** refs );
|
||||
|
||||
@@ -1,102 +1,78 @@
|
||||
|
||||
set(LIBSTEPCORE_SRCS
|
||||
sdaiApplication_instance.cc
|
||||
STEPcomplex.cc
|
||||
STEPattribute.cc
|
||||
STEPattribute.inline.cc
|
||||
sdai.cc
|
||||
sdaiSelect.cc
|
||||
STEPaggregate.cc
|
||||
STEPundefined.cc
|
||||
STEPattributeList.cc
|
||||
SingleLinkList.cc
|
||||
SingleLinkList.inline.cc
|
||||
Registry.inline.cc
|
||||
ExpDict.cc
|
||||
ExpDict.inline.cc
|
||||
read_func.cc
|
||||
collect.cc
|
||||
complexlist.cc
|
||||
entlist.cc
|
||||
multlist.cc
|
||||
orlist.cc
|
||||
entnode.cc
|
||||
non-ors.cc
|
||||
match-ors.cc
|
||||
trynext.cc
|
||||
print.cc
|
||||
instmgr.cc
|
||||
mgrnode.cc
|
||||
mgrnodearray.cc
|
||||
mgrnodelist.cc
|
||||
dispnode.cc
|
||||
dispnodelist.cc
|
||||
needFunc.cc
|
||||
)
|
||||
sdaiApplication_instance.cc
|
||||
STEPcomplex.cc
|
||||
STEPattribute.cc
|
||||
STEPattribute.inline.cc
|
||||
sdai.cc
|
||||
sdaiSelect.cc
|
||||
STEPaggregate.cc
|
||||
STEPundefined.cc
|
||||
STEPattributeList.cc
|
||||
SingleLinkList.cc
|
||||
SingleLinkList.inline.cc
|
||||
Registry.inline.cc
|
||||
ExpDict.cc
|
||||
ExpDict.inline.cc
|
||||
read_func.cc
|
||||
collect.cc
|
||||
complexlist.cc
|
||||
entlist.cc
|
||||
multlist.cc
|
||||
orlist.cc
|
||||
entnode.cc
|
||||
non-ors.cc
|
||||
match-ors.cc
|
||||
trynext.cc
|
||||
print.cc
|
||||
instmgr.cc
|
||||
mgrnode.cc
|
||||
mgrnodearray.cc
|
||||
mgrnodelist.cc
|
||||
dispnode.cc
|
||||
dispnodelist.cc
|
||||
needFunc.cc
|
||||
)
|
||||
|
||||
set(SC_CLSTEPCORE_HDRS
|
||||
baseType.h
|
||||
complexSupport.h
|
||||
dictdefs.h
|
||||
ExpDict.h
|
||||
read_func.h
|
||||
Registry.h
|
||||
sdaiApplication_instance.h
|
||||
sdai.h
|
||||
sdaiSelect.h
|
||||
SingleLinkList.h
|
||||
STEPaggregate.h
|
||||
STEPattribute.h
|
||||
STEPattributeList.h
|
||||
STEPcomplex.h
|
||||
STEPundefined.h
|
||||
instmgr.h
|
||||
mgrnode.h
|
||||
mgrnodearray.h
|
||||
mgrnodelist.h
|
||||
dispnode.h
|
||||
dispnodelist.h
|
||||
needFunc.h
|
||||
SubSuperIterators.h
|
||||
)
|
||||
SET(SC_CLSTEPCORE_HDRS
|
||||
baseType.h
|
||||
complexSupport.h
|
||||
dictdefs.h
|
||||
ExpDict.h
|
||||
read_func.h
|
||||
Registry.h
|
||||
sdaiApplication_instance.h
|
||||
sdai.h
|
||||
sdaiSelect.h
|
||||
SingleLinkList.h
|
||||
STEPaggregate.h
|
||||
STEPattribute.h
|
||||
STEPattributeList.h
|
||||
STEPcomplex.h
|
||||
STEPundefined.h
|
||||
instmgr.h
|
||||
mgrnode.h
|
||||
mgrnodearray.h
|
||||
mgrnodelist.h
|
||||
dispnode.h
|
||||
dispnodelist.h
|
||||
needFunc.h
|
||||
SubSuperIterators.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/cleditor
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${SC_SOURCE_DIR}/src/base
|
||||
${SC_SOURCE_DIR}/src/cldai
|
||||
${SC_SOURCE_DIR}/src/cleditor
|
||||
${SC_SOURCE_DIR}/src/clutils
|
||||
)
|
||||
|
||||
SC_ADDLIB(stepcore "${LIBSTEPCORE_SRCS}" "steputils;stepdai;base")
|
||||
if(HAVE_STD_THREAD)
|
||||
list(APPEND CMAKE_CXX_FLAGS "-pthread -std=c++0x")
|
||||
set_target_properties(stepcore PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD" )
|
||||
|
||||
SC_ADDEXEC(InstMgr_thread_safety_test "InstMgr_thread_safety_test.cc" "stepcore" )
|
||||
set_target_properties(InstMgr_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
|
||||
target_link_libraries(InstMgr_thread_safety_test "pthread" )
|
||||
|
||||
SC_ADDEXEC(Registry_thread_safety_test "Registry_thread_safety_test.cc" "stepcore" )
|
||||
set_target_properties(Registry_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
|
||||
target_link_libraries(Registry_thread_safety_test "pthread" )
|
||||
|
||||
SC_ADDEXEC(sdaiApplication_instance_thread_safety_test "sdaiApplication_instance_thread_safety_test.cc" "stepcore" )
|
||||
set_target_properties(sdaiApplication_instance_thread_safety_test PROPERTIES COMPILE_FLAGS "-pthread -std=c++0x -DHAVE_STD_THREAD")
|
||||
target_link_libraries(sdaiApplication_instance_thread_safety_test "pthread" )
|
||||
endif(HAVE_STD_THREAD)
|
||||
|
||||
install(FILES ${SC_CLSTEPCORE_HDRS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/clstepcore)
|
||||
|
||||
if(SC_ENABLE_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif(SC_ENABLE_TESTING)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/clstepcore)
|
||||
|
||||
IF(SC_ENABLE_TESTING)
|
||||
ADD_SUBDIRECTORY( test )
|
||||
ENDIF(SC_ENABLE_TESTING)
|
||||
|
||||
+479
-191
@@ -21,143 +21,269 @@
|
||||
#include "sc_memmgr.h"
|
||||
|
||||
|
||||
Dictionary_instance__set::Dictionary_instance__set( int defaultSize ) {
|
||||
Explicit_item_id__set::Explicit_item_id__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new Dictionary_instance_ptr[_bufsize];
|
||||
_buf = new Explicit_item_id_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
Dictionary_instance__set::~Dictionary_instance__set() {
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
void Dictionary_instance__set::Check( int index ) {
|
||||
Dictionary_instance_ptr * newbuf;
|
||||
|
||||
mtx.lock();
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new Dictionary_instance_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( Dictionary_instance_ptr ) );
|
||||
delete[] _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
void Dictionary_instance__set::Insert( Dictionary_instance_ptr v, int index ) {
|
||||
Dictionary_instance_ptr * spot;
|
||||
|
||||
mtx.lock();
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Dictionary_instance_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
void Dictionary_instance__set::Append( Dictionary_instance_ptr v ) {
|
||||
Dictionary_instance_ptr * spot;
|
||||
|
||||
mtx.lock();
|
||||
int index = _count;
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Dictionary_instance_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
void Dictionary_instance__set::Remove( int index ) {
|
||||
mtx.lock();
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
Dictionary_instance_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( Dictionary_instance_ptr ) );
|
||||
}
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
int Dictionary_instance__set::Index( Dictionary_instance_ptr v ) {
|
||||
int index = -1;
|
||||
mtx.lock();
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtx.unlock();
|
||||
return index;
|
||||
}
|
||||
|
||||
Dictionary_instance_ptr & Dictionary_instance__set::operator[]( int index ) {
|
||||
mtx.lock();
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
Dictionary_instance_ptr & dip = _buf[index];
|
||||
mtx.unlock();
|
||||
return dip;
|
||||
}
|
||||
|
||||
int Dictionary_instance__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Dictionary_instance__set::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Explicit_item_id__set::Explicit_item_id__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
|
||||
}
|
||||
|
||||
Explicit_item_id__set::~Explicit_item_id__set() {
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
void Explicit_item_id__set::Check( int index ) {
|
||||
Explicit_item_id_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new Explicit_item_id_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( Explicit_item_id_ptr ) );
|
||||
delete[] _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void Explicit_item_id__set::Insert( Explicit_item_id_ptr v, int index ) {
|
||||
Explicit_item_id_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Explicit_item_id_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Explicit_item_id__set::Append( Explicit_item_id_ptr v ) {
|
||||
int index = _count;
|
||||
Explicit_item_id_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Explicit_item_id_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Explicit_item_id__set::Remove( int index ) {
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
Explicit_item_id_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( Explicit_item_id_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int Explicit_item_id__set::Index( Explicit_item_id_ptr v ) {
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Explicit_item_id_ptr & Explicit_item_id__set::operator[]( int index ) {
|
||||
return ( Explicit_item_id_ptr & )Dictionary_instance__set::operator[]( index );
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int Explicit_item_id__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Explicit_item_id__set::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Implicit_item_id__set::Implicit_item_id__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
|
||||
Implicit_item_id__set::Implicit_item_id__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new Implicit_item_id_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
|
||||
Implicit_item_id__set::~Implicit_item_id__set() {
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
void Implicit_item_id__set::Check( int index ) {
|
||||
Implicit_item_id_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new Implicit_item_id_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( Implicit_item_id_ptr ) );
|
||||
delete[]_buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void Implicit_item_id__set::Insert( Implicit_item_id_ptr v, int index ) {
|
||||
Implicit_item_id_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Implicit_item_id_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Implicit_item_id__set::Append( Implicit_item_id_ptr v ) {
|
||||
int index = _count;
|
||||
Implicit_item_id_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Implicit_item_id_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Implicit_item_id__set::Remove( int index ) {
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
Implicit_item_id_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( Implicit_item_id_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int Implicit_item_id__set::Index( Implicit_item_id_ptr v ) {
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Implicit_item_id_ptr & Implicit_item_id__set::operator[]( int index ) {
|
||||
return ( Implicit_item_id_ptr & )Dictionary_instance__set::operator[]( index );
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int Implicit_item_id__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Implicit_item_id__set::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Interface_spec__set::Interface_spec__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
|
||||
Interface_spec__set::Interface_spec__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new Interface_spec_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
Interface_spec__set::~Interface_spec__set() {
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
void Interface_spec__set::Check( int index ) {
|
||||
Interface_spec_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new Interface_spec_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( Interface_spec_ptr ) );
|
||||
delete[] _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void Interface_spec__set::Insert( Interface_spec_ptr v, int index ) {
|
||||
Interface_spec_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Interface_spec_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Interface_spec__set::Append( Interface_spec_ptr v ) {
|
||||
int index = _count;
|
||||
Interface_spec_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Interface_spec_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Interface_spec__set::Remove( int index ) {
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
Interface_spec_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( Interface_spec_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int Interface_spec__set::Index( Interface_spec_ptr v ) {
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Interface_spec_ptr & Interface_spec__set::operator[]( int index ) {
|
||||
return ( Interface_spec_ptr & )Dictionary_instance__set::operator[]( index );
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int Interface_spec__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Interface_spec__set::Clear() {
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -196,24 +322,18 @@ Interface_spec::~Interface_spec() {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void Schema::AddFunction( const std::string & f ) {
|
||||
_function_list_mtx.lock();
|
||||
_function_list.push_back( f );
|
||||
_function_list_mtx.unlock();
|
||||
}
|
||||
|
||||
void Schema::AddGlobal_rule( Global_rule_ptr gr ) {
|
||||
// locking here is required to prevent _global_rules from initializing twice
|
||||
_global_rules_mtx.lock();
|
||||
if( _global_rules == 0 ) {
|
||||
_global_rules = new Global_rule__set;
|
||||
}
|
||||
_global_rules->Append( gr );
|
||||
_global_rules_mtx.unlock();
|
||||
}
|
||||
|
||||
/// hope I did this right (MP) - was "not implemented"
|
||||
void Schema::global_rules_( Global_rule__set_var & grs ) {
|
||||
_global_rules_mtx.lock();
|
||||
if( _global_rules ) {
|
||||
if( _global_rules->Count() > 0 ) {
|
||||
std::cerr << "In " << __FILE__ << ", Schema::global_rules_(): overwriting non-empty global rule set!" << std::endl;
|
||||
@@ -221,13 +341,10 @@ void Schema::global_rules_( Global_rule__set_var & grs ) {
|
||||
delete _global_rules;
|
||||
}
|
||||
_global_rules = grs;
|
||||
_global_rules_mtx.unlock();
|
||||
}
|
||||
|
||||
void Schema::AddProcedure( const std::string & p ) {
|
||||
_procedure_list_mtx.lock();
|
||||
_procedure_list.push_back( p );
|
||||
_procedure_list_mtx.unlock();
|
||||
}
|
||||
|
||||
/// the whole schema
|
||||
@@ -361,7 +478,6 @@ void Schema::GenerateUseRefExpress( ostream & out ) const {
|
||||
|
||||
/// TYPE definitions
|
||||
void Schema::GenerateTypesExpress( ostream & out ) const {
|
||||
_typeList.mtxP->lock();
|
||||
TypeDescItr tdi( _typeList );
|
||||
tdi.ResetItr();
|
||||
std::string tmp;
|
||||
@@ -371,12 +487,10 @@ void Schema::GenerateTypesExpress( ostream & out ) const {
|
||||
out << endl << td->GenerateExpress( tmp );
|
||||
td = tdi.NextTypeDesc();
|
||||
}
|
||||
_typeList.mtxP->unlock();
|
||||
}
|
||||
|
||||
/// Entity definitions
|
||||
void Schema::GenerateEntitiesExpress( ostream & out ) const {
|
||||
_entList.mtxP->lock();
|
||||
EntityDescItr edi( _entList );
|
||||
edi.ResetItr();
|
||||
std::string tmp;
|
||||
@@ -386,7 +500,6 @@ void Schema::GenerateEntitiesExpress( ostream & out ) const {
|
||||
out << endl << ed->GenerateExpress( tmp );
|
||||
ed = edi.NextEntityDesc();
|
||||
}
|
||||
_entList.mtxP->unlock();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -644,7 +757,6 @@ const char * EnumTypeDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
///////////////
|
||||
// count is # of WHERE rules
|
||||
if( _where_rules != 0 ) {
|
||||
_where_rules->mtx.lock();
|
||||
int all_comments = 1;
|
||||
int count = _where_rules->Count();
|
||||
for( int i = 0; i < count; i++ ) { // print out each UNIQUE rule
|
||||
@@ -669,7 +781,6 @@ const char * EnumTypeDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
buf.append( ( *( _where_rules ) )[i]->label_() );
|
||||
}
|
||||
}
|
||||
_where_rules->mtx.unlock();
|
||||
}
|
||||
|
||||
buf.append( "END_TYPE;\n" );
|
||||
@@ -716,7 +827,6 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
|
||||
const EntityDescriptor * ed = 0;
|
||||
|
||||
_supertypes.mtxP->lock();
|
||||
EntityDescItr edi_super( _supertypes );
|
||||
edi_super.ResetItr();
|
||||
ed = edi_super.NextEntityDesc();
|
||||
@@ -735,11 +845,9 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
if( supertypes ) {
|
||||
buf.append( ")" );
|
||||
}
|
||||
_supertypes.mtxP->unlock();
|
||||
|
||||
buf.append( ";\n" );
|
||||
|
||||
_explicitAttr.mtxP->lock();
|
||||
AttrDescItr adi( _explicitAttr );
|
||||
|
||||
adi.ResetItr();
|
||||
@@ -768,10 +876,8 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
}
|
||||
ad = adi.NextAttrDesc();
|
||||
}
|
||||
_explicitAttr.mtxP->unlock();
|
||||
/////////
|
||||
|
||||
_inverseAttr.mtxP->lock();
|
||||
InverseAItr iai( _inverseAttr );
|
||||
|
||||
iai.ResetItr();
|
||||
@@ -786,11 +892,9 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
buf.append( ia->GenerateExpress( sstr ) );
|
||||
ia = iai.NextInverse_attribute();
|
||||
}
|
||||
_inverseAttr.mtxP->unlock();
|
||||
///////////////
|
||||
// count is # of UNIQUE rules
|
||||
if( _uniqueness_rules != 0 ) {
|
||||
_uniqueness_rules->mtx.lock();
|
||||
count = _uniqueness_rules->Count();
|
||||
for( i = 0; i < count; i++ ) { // print out each UNIQUE rule
|
||||
if( !( *( _uniqueness_rules ) )[i]->_label.size() ) {
|
||||
@@ -815,13 +919,11 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
buf.append( "\n" );
|
||||
}
|
||||
}
|
||||
_uniqueness_rules->mtx.unlock();
|
||||
}
|
||||
|
||||
///////////////
|
||||
// count is # of WHERE rules
|
||||
if( _where_rules != 0 ) {
|
||||
_where_rules->mtx.lock();
|
||||
all_comments = 1;
|
||||
count = _where_rules->Count();
|
||||
for( i = 0; i < count; i++ ) { // print out each UNIQUE rule
|
||||
@@ -847,7 +949,6 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
buf.append( "\n" );
|
||||
}
|
||||
}
|
||||
_where_rules->mtx.unlock();
|
||||
}
|
||||
|
||||
buf.append( "END_ENTITY;\n" );
|
||||
@@ -857,7 +958,6 @@ const char * EntityDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
|
||||
const char * EntityDescriptor::QualifiedName( std::string & s ) const {
|
||||
s.clear();
|
||||
_supertypes.mtxP->lock();
|
||||
EntityDescItr edi( _supertypes );
|
||||
|
||||
int count = 1;
|
||||
@@ -870,8 +970,6 @@ const char * EntityDescriptor::QualifiedName( std::string & s ) const {
|
||||
count++;
|
||||
ed = edi.NextEntityDesc();
|
||||
}
|
||||
_supertypes.mtxP->unlock();
|
||||
|
||||
if( count > 1 ) {
|
||||
s.append( "&" );
|
||||
}
|
||||
@@ -889,18 +987,16 @@ const TypeDescriptor * EntityDescriptor::IsA( const TypeDescriptor * td ) const
|
||||
|
||||
const EntityDescriptor * EntityDescriptor::IsA( const EntityDescriptor * other ) const {
|
||||
const EntityDescriptor * found = 0;
|
||||
_supertypes.mtxP->lock();
|
||||
const EntityDescLinkNode * link = ( const EntityDescLinkNode * )( _supertypes.GetHead() );
|
||||
const EntityDescLinkNode * link = ( const EntityDescLinkNode * )( GetSupertypes().GetHead() );
|
||||
|
||||
if( this == other ) {
|
||||
found = other;
|
||||
return other;
|
||||
} else {
|
||||
while( link && ! found ) {
|
||||
found = link -> EntityDesc() -> IsA( other );
|
||||
link = ( EntityDescLinkNode * ) link -> NextNode();
|
||||
}
|
||||
}
|
||||
_supertypes.mtxP->unlock();
|
||||
return found;
|
||||
}
|
||||
|
||||
@@ -929,24 +1025,96 @@ Where_rule::~Where_rule() {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Where_rule__list::Where_rule__list( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
|
||||
Where_rule__list::Where_rule__list( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new Where_rule_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
Where_rule__list::~Where_rule__list() {
|
||||
Clear();
|
||||
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
void Where_rule__list::Check( int index ) {
|
||||
Where_rule_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new Where_rule_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( Where_rule_ptr ) );
|
||||
delete[] _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void Where_rule__list::Insert( Where_rule_ptr v, int index ) {
|
||||
Where_rule_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Where_rule_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Where_rule__list::Append( Where_rule_ptr v ) {
|
||||
int index = _count;
|
||||
Where_rule_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Where_rule_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Where_rule__list::Remove( int index ) {
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
Where_rule_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( Where_rule_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int Where_rule__list::Index( Where_rule_ptr v ) {
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Where_rule_ptr & Where_rule__list::operator[]( int index ) {
|
||||
return ( Where_rule_ptr & )Dictionary_instance__set::operator[]( index );
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int Where_rule__list::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Where_rule__list::Clear() {
|
||||
mtx.lock();
|
||||
for( int i = 0; i < _count ; i ++ ) {
|
||||
delete ( Where_rule_ptr )_buf[i];
|
||||
delete _buf[i];
|
||||
}
|
||||
_count = 0;
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -966,24 +1134,96 @@ Uniqueness_rule::~Uniqueness_rule() {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Uniqueness_rule__set::Uniqueness_rule__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
|
||||
Uniqueness_rule__set::Uniqueness_rule__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new Uniqueness_rule_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
Uniqueness_rule__set::~Uniqueness_rule__set() {
|
||||
Clear();
|
||||
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
void Uniqueness_rule__set::Check( int index ) {
|
||||
Uniqueness_rule_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new Uniqueness_rule_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( Uniqueness_rule_ptr ) );
|
||||
delete[] _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void Uniqueness_rule__set::Insert( Uniqueness_rule_ptr v, int index ) {
|
||||
Uniqueness_rule_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Uniqueness_rule_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Uniqueness_rule__set::Append( Uniqueness_rule_ptr v ) {
|
||||
int index = _count;
|
||||
Uniqueness_rule_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Uniqueness_rule_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Uniqueness_rule__set::Remove( int index ) {
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
Uniqueness_rule_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( Uniqueness_rule_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int Uniqueness_rule__set::Index( Uniqueness_rule_ptr v ) {
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Uniqueness_rule_ptr & Uniqueness_rule__set::operator[]( int index ) {
|
||||
return ( Uniqueness_rule_ptr & )Dictionary_instance__set::operator[]( index );
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int Uniqueness_rule__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Uniqueness_rule__set::Clear() {
|
||||
mtx.lock();
|
||||
for( int i = 0; i < _count; i ++ ) {
|
||||
delete ( Uniqueness_rule_ptr )_buf[i];
|
||||
delete _buf[i];
|
||||
}
|
||||
_count = 0;
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1009,8 +1249,6 @@ Global_rule::~Global_rule() {
|
||||
}
|
||||
|
||||
void Global_rule::entities_( const Entity__set_var & e ) {
|
||||
// required to prevent potential double deletion
|
||||
mtx.lock();
|
||||
if( _entities ) {
|
||||
if( _entities->EntryCount() > 0 ) {
|
||||
std::cerr << "In " << __FILE__ << ", Global_rule::entities_(): overwriting non-empty entity set!" << std::endl;
|
||||
@@ -1018,11 +1256,9 @@ void Global_rule::entities_( const Entity__set_var & e ) {
|
||||
delete _entities;
|
||||
}
|
||||
_entities = e;
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
void Global_rule::where_rules_( const Where_rule__list_var & wrl ) {
|
||||
mtx.lock();
|
||||
if( _where_rules ) {
|
||||
if( _where_rules->Count() > 0 ) {
|
||||
std::cerr << "In " << __FILE__ << ", Global_rule::where_rules_(): overwriting non-empty rule set!" << std::endl;
|
||||
@@ -1030,29 +1266,99 @@ void Global_rule::where_rules_( const Where_rule__list_var & wrl ) {
|
||||
delete _where_rules;
|
||||
}
|
||||
_where_rules = wrl;
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Global_rule__set::Global_rule__set( int defaultSize ) : Dictionary_instance__set( defaultSize ) {
|
||||
Global_rule__set::Global_rule__set( int defaultSize ) {
|
||||
_bufsize = defaultSize;
|
||||
_buf = new Global_rule_ptr[_bufsize];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
Global_rule__set::~Global_rule__set() {
|
||||
Clear();
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
void Global_rule__set::Check( int index ) {
|
||||
Global_rule_ptr * newbuf;
|
||||
|
||||
if( index >= _bufsize ) {
|
||||
_bufsize = ( index + 1 ) * 2;
|
||||
newbuf = new Global_rule_ptr[_bufsize];
|
||||
memmove( newbuf, _buf, _count * sizeof( Global_rule_ptr ) );
|
||||
delete[] _buf;
|
||||
_buf = newbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void Global_rule__set::Insert( Global_rule_ptr v, int index ) {
|
||||
Global_rule_ptr * spot;
|
||||
index = ( index < 0 ) ? _count : index;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Global_rule_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Global_rule__set::Append( Global_rule_ptr v ) {
|
||||
int index = _count;
|
||||
Global_rule_ptr * spot;
|
||||
|
||||
if( index < _count ) {
|
||||
Check( _count + 1 );
|
||||
spot = &_buf[index];
|
||||
memmove( spot + 1, spot, ( _count - index )*sizeof( Global_rule_ptr ) );
|
||||
|
||||
} else {
|
||||
Check( index );
|
||||
spot = &_buf[index];
|
||||
}
|
||||
*spot = v;
|
||||
++_count;
|
||||
}
|
||||
|
||||
void Global_rule__set::Remove( int index ) {
|
||||
if( 0 <= index && index < _count ) {
|
||||
--_count;
|
||||
Global_rule_ptr * spot = &_buf[index];
|
||||
memmove( spot, spot + 1, ( _count - index )*sizeof( Global_rule_ptr ) );
|
||||
}
|
||||
}
|
||||
|
||||
int Global_rule__set::Index( Global_rule_ptr v ) {
|
||||
for( int i = 0; i < _count; ++i ) {
|
||||
if( _buf[i] == v ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Global_rule_ptr & Global_rule__set::operator[]( int index ) {
|
||||
return ( Global_rule_ptr & )Dictionary_instance__set::operator[]( index );
|
||||
Check( index );
|
||||
_count = ( ( _count > index + 1 ) ? _count : ( index + 1 ) );
|
||||
return _buf[index];
|
||||
}
|
||||
|
||||
int Global_rule__set::Count() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Global_rule__set::Clear() {
|
||||
mtx.lock();
|
||||
for( int i = 0; i < _count; i ++ ) {
|
||||
delete ( Global_rule_ptr )_buf[i];
|
||||
delete _buf[i];
|
||||
}
|
||||
_count = 0;
|
||||
mtx.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -1090,7 +1396,6 @@ const char * TypeDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
///////////////
|
||||
// count is # of WHERE rules
|
||||
if( _where_rules != 0 ) {
|
||||
_where_rules->mtx.lock();
|
||||
int all_comments = 1;
|
||||
int count = _where_rules->Count();
|
||||
for( int i = 0; i < count; i++ ) { // print out each UNIQUE rule
|
||||
@@ -1115,7 +1420,6 @@ const char * TypeDescriptor::GenerateExpress( std::string & buf ) const {
|
||||
buf.append( ( *( _where_rules ) )[i]->label_() );
|
||||
}
|
||||
}
|
||||
_where_rules->mtx.unlock();
|
||||
}
|
||||
|
||||
buf.append( "END_TYPE;\n" );
|
||||
@@ -1400,20 +1704,15 @@ const TypeDescriptor * SelectTypeDescriptor::CanBe( const TypeDescriptor * other
|
||||
return other;
|
||||
}
|
||||
|
||||
const TypeDescriptor * rettd = 0;
|
||||
const TypeDescriptorList & tl = GetElements();
|
||||
tl.mtxP->lock();
|
||||
TypeDescItr elements( tl ) ;
|
||||
TypeDescItr elements( GetElements() ) ;
|
||||
const TypeDescriptor * td = elements.NextTypeDesc();
|
||||
while( td ) {
|
||||
if( td -> CanBe( other ) ) {
|
||||
rettd = td;
|
||||
break;
|
||||
return td;
|
||||
}
|
||||
td = elements.NextTypeDesc();
|
||||
}
|
||||
tl.mtxP->unlock();
|
||||
return rettd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1422,26 +1721,21 @@ const TypeDescriptor * SelectTypeDescriptor::CanBe( const TypeDescriptor * other
|
||||
* type may be an element of a td for a select that is returned.
|
||||
*/
|
||||
const TypeDescriptor * SelectTypeDescriptor::CanBe( const char * other ) const {
|
||||
TypeDescItr elements( GetElements() ) ;
|
||||
const TypeDescriptor * td = 0;
|
||||
|
||||
// see if other is the select
|
||||
if( !StrCmpIns( _name, other ) ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const TypeDescriptor * td = 0;
|
||||
const TypeDescriptor * rettd = 0;
|
||||
const TypeDescriptorList & tl = GetElements();
|
||||
tl.mtxP->lock();
|
||||
|
||||
TypeDescItr elements( tl ) ;
|
||||
// see if other is one of the elements
|
||||
while( ( td = elements.NextTypeDesc() ) ) {
|
||||
if( td -> CanBe( other ) ) {
|
||||
rettd = td;
|
||||
break;
|
||||
return td;
|
||||
}
|
||||
}
|
||||
tl.mtxP->unlock();
|
||||
return rettd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1464,27 +1758,21 @@ const TypeDescriptor * SelectTypeDescriptor::CanBe( const char * other ) const {
|
||||
* from XX (A as B)").
|
||||
*/
|
||||
const TypeDescriptor * SelectTypeDescriptor::CanBeSet( const char * other, const char * schNm ) const {
|
||||
const TypeDescriptorList & tl = GetElements();
|
||||
tl.mtxP->lock();
|
||||
TypeDescItr elements( tl ) ;
|
||||
TypeDescItr elements( GetElements() ) ;
|
||||
const TypeDescriptor * td = elements.NextTypeDesc();
|
||||
const TypeDescriptor * rettd = 0;
|
||||
|
||||
while( td ) {
|
||||
if( td->Type() == REFERENCE_TYPE && td->NonRefType() == sdaiSELECT ) {
|
||||
// Just look at this level, don't look at my items (see intro).
|
||||
if( td->CurrName( other, schNm ) ) {
|
||||
rettd = td;
|
||||
break;
|
||||
return td;
|
||||
}
|
||||
} else if( td->CanBeSet( other, schNm ) ) {
|
||||
rettd = td;
|
||||
break;
|
||||
return td;
|
||||
}
|
||||
td = elements.NextTypeDesc();
|
||||
}
|
||||
tl.mtxP->unlock();
|
||||
return rettd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+78
-41
@@ -40,7 +40,6 @@ enum AggrBoundTypeEnum {
|
||||
#include <baseType.h>
|
||||
#include <dictdefs.h>
|
||||
#include <Str.h>
|
||||
#include <sc_mutex.h>
|
||||
|
||||
// defined and created in Registry.inline.cc
|
||||
extern SC_CORE_EXPORT const TypeDescriptor * t_sdaiINTEGER;
|
||||
@@ -64,33 +63,6 @@ class SC_CORE_EXPORT Dictionary_instance {
|
||||
virtual ~Dictionary_instance();
|
||||
};
|
||||
|
||||
|
||||
typedef Dictionary_instance * Dictionary_instance_ptr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SC_CORE_EXPORT Dictionary_instance__set {
|
||||
public:
|
||||
Dictionary_instance__set( int = 16 );
|
||||
~Dictionary_instance__set();
|
||||
|
||||
Dictionary_instance_ptr & operator[]( int index );
|
||||
virtual void Insert( Dictionary_instance_ptr, int index );
|
||||
virtual void Append( Dictionary_instance_ptr );
|
||||
virtual void Remove( int index );
|
||||
virtual int Index( Dictionary_instance_ptr );
|
||||
|
||||
virtual int Count();
|
||||
virtual void Clear();
|
||||
sc_recursive_mutex mtx;
|
||||
private:
|
||||
virtual void Check( int index );
|
||||
protected:
|
||||
Dictionary_instance_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SC_CORE_EXPORT TypeDescLinkNode : public SingleLinkNode {
|
||||
@@ -314,12 +286,25 @@ class SC_CORE_EXPORT Referenced_item : public Explicit_item_id {
|
||||
|
||||
typedef Referenced_item * Referenced_item_ptr;
|
||||
|
||||
class SC_CORE_EXPORT Explicit_item_id__set : public Dictionary_instance__set {
|
||||
class SC_CORE_EXPORT Explicit_item_id__set {
|
||||
public:
|
||||
Explicit_item_id__set( int = 16 );
|
||||
~Explicit_item_id__set();
|
||||
|
||||
Explicit_item_id_ptr & operator[]( int index );
|
||||
void Insert( Explicit_item_id_ptr, int index );
|
||||
void Append( Explicit_item_id_ptr );
|
||||
void Remove( int index );
|
||||
int Index( Explicit_item_id_ptr );
|
||||
|
||||
int Count();
|
||||
void Clear();
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
Explicit_item_id_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
typedef Explicit_item_id__set * Explicit_item_id__set_ptr;
|
||||
@@ -353,12 +338,25 @@ typedef Implicit_item_id * Implicit_item_id_ptr;
|
||||
// Implicit_item_id__set
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SC_CORE_EXPORT Implicit_item_id__set : public Dictionary_instance__set {
|
||||
class SC_CORE_EXPORT Implicit_item_id__set {
|
||||
public:
|
||||
Implicit_item_id__set( int = 16 );
|
||||
~Implicit_item_id__set();
|
||||
|
||||
Implicit_item_id_ptr & operator[]( int index );
|
||||
void Insert( Implicit_item_id_ptr, int index );
|
||||
void Append( Implicit_item_id_ptr );
|
||||
void Remove( int index );
|
||||
int Index( Implicit_item_id_ptr );
|
||||
|
||||
int Count();
|
||||
void Clear();
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
Implicit_item_id_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
typedef Implicit_item_id__set * Implicit_item_id__set_ptr;
|
||||
@@ -425,12 +423,25 @@ class SC_CORE_EXPORT Interface_spec : public Dictionary_instance {
|
||||
|
||||
typedef Interface_spec * Interface_spec_ptr;
|
||||
|
||||
class SC_CORE_EXPORT Interface_spec__set : public Dictionary_instance__set {
|
||||
class SC_CORE_EXPORT Interface_spec__set {
|
||||
public:
|
||||
Interface_spec__set( int = 16 );
|
||||
~Interface_spec__set();
|
||||
|
||||
Interface_spec_ptr & operator[]( int index );
|
||||
void Insert( Interface_spec_ptr, int index );
|
||||
void Append( Interface_spec_ptr );
|
||||
void Remove( int index );
|
||||
int Index( Interface_spec_ptr );
|
||||
|
||||
int Count();
|
||||
void Clear();
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
Interface_spec_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
typedef Interface_spec__set * Interface_spec__set_ptr;
|
||||
@@ -486,23 +497,31 @@ class SC_CORE_EXPORT Where_rule : public Dictionary_instance {
|
||||
|
||||
typedef Where_rule * Where_rule_ptr;
|
||||
|
||||
class SC_CORE_EXPORT Where_rule__list : public Dictionary_instance__set {
|
||||
class SC_CORE_EXPORT Where_rule__list {
|
||||
public:
|
||||
Where_rule__list( int = 16 );
|
||||
~Where_rule__list();
|
||||
|
||||
Where_rule_ptr & operator[]( int index );
|
||||
void Insert( Where_rule_ptr, int index );
|
||||
void Append( Where_rule_ptr );
|
||||
void Remove( int index );
|
||||
int Index( Where_rule_ptr );
|
||||
|
||||
int Count();
|
||||
void Clear();
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
Where_rule_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
typedef Where_rule__list * Where_rule__list_ptr;
|
||||
typedef Where_rule__list_ptr Where_rule__list_var;
|
||||
|
||||
class SC_CORE_EXPORT Global_rule : public Dictionary_instance {
|
||||
protected:
|
||||
sc_mutex mtx;
|
||||
|
||||
public:
|
||||
Express_id _name;
|
||||
Entity__set_var _entities; // not implemented
|
||||
@@ -547,14 +566,25 @@ class SC_CORE_EXPORT Global_rule : public Dictionary_instance {
|
||||
|
||||
typedef Global_rule * Global_rule_ptr;
|
||||
|
||||
class SC_CORE_EXPORT Global_rule__set : public Dictionary_instance__set {
|
||||
class SC_CORE_EXPORT Global_rule__set {
|
||||
public:
|
||||
Global_rule__set( int = 16 );
|
||||
~Global_rule__set();
|
||||
|
||||
Global_rule_ptr & operator[]( int index );
|
||||
void Insert( Global_rule_ptr, int index );
|
||||
void Append( Global_rule_ptr );
|
||||
void Remove( int index );
|
||||
int Index( Global_rule_ptr );
|
||||
|
||||
int Count();
|
||||
void Clear();
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
Global_rule_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
typedef Global_rule__set * Global_rule__set_ptr;
|
||||
@@ -600,14 +630,25 @@ class SC_CORE_EXPORT Uniqueness_rule : public Dictionary_instance {
|
||||
|
||||
typedef Uniqueness_rule * Uniqueness_rule_ptr;
|
||||
|
||||
class SC_CORE_EXPORT Uniqueness_rule__set : public Dictionary_instance__set {
|
||||
class SC_CORE_EXPORT Uniqueness_rule__set {
|
||||
public:
|
||||
Uniqueness_rule__set( int = 16 );
|
||||
~Uniqueness_rule__set();
|
||||
|
||||
Uniqueness_rule_ptr & operator[]( int index );
|
||||
void Insert( Uniqueness_rule_ptr, int index );
|
||||
void Append( Uniqueness_rule_ptr );
|
||||
void Remove( int index );
|
||||
int Index( Uniqueness_rule_ptr );
|
||||
|
||||
int Count();
|
||||
void Clear();
|
||||
private:
|
||||
void Check( int index );
|
||||
private:
|
||||
Uniqueness_rule_ptr * _buf;
|
||||
int _bufsize;
|
||||
int _count;
|
||||
};
|
||||
|
||||
typedef Uniqueness_rule__set * Uniqueness_rule__set_ptr;
|
||||
@@ -635,10 +676,6 @@ class SC_CORE_EXPORT Schema : public Dictionary_instance {
|
||||
|
||||
Global_rule__set_var _global_rules;
|
||||
|
||||
sc_mutex _function_list_mtx; // required as _function_list is a vector
|
||||
sc_mutex _procedure_list_mtx; // required as _procedure_list is a vector
|
||||
sc_mutex _global_rules_mtx; // required in AddGlobal_rule function
|
||||
|
||||
public:
|
||||
ModelContentsCreator CreateNewModelContents;
|
||||
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
#include "instmgr.h"
|
||||
#include "ExpDict.h"
|
||||
#include "sdaiApplication_instance.h"
|
||||
#include <baseType.h>
|
||||
|
||||
#ifdef HAVE_STD_THREAD
|
||||
# include <thread>
|
||||
#else
|
||||
# error Need std::thread for this test!
|
||||
#endif
|
||||
|
||||
const std::vector< std::string > dummyEDescNames { "A", "B", "C", "A", "B", "C", "D", "B", "A", "E", "C", "D", "B", "A", "E", "F", "F", "B", "C", "E", "F", "G", "C", "A", "G", "H", "I", "B", "A", "E", "F", "F", "C", "C", "E", "F" };
|
||||
|
||||
typedef std::vector< SDAI_Application_instance * > sdaiVec_t;
|
||||
|
||||
/// Deletes non-null elements of sdaiVec
|
||||
void deleteSdaiVec( sdaiVec_t &sdaiVec ) {
|
||||
int i, size = sdaiVec.size();
|
||||
for( i = 0; i < size; i++ ) {
|
||||
if( !sdaiVec[i]) {
|
||||
delete sdaiVec[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void appendInstances( InstMgr * im, sdaiVec_t * sdaiVec, int offset, int stride, int limit ) {
|
||||
SDAI_Application_instance * sai;
|
||||
for( int i = offset; i < limit; i+=stride ) {
|
||||
sai = new SDAI_Application_instance( i+1 );
|
||||
sai->eDesc = new EntityDescriptor( dummyEDescNames[i].c_str(), ( Schema * ) NULL, LTrue, LFalse );
|
||||
(*sdaiVec)[i] = sai;
|
||||
im->Append( sai, completeSE );
|
||||
}
|
||||
}
|
||||
|
||||
void deleteInstances( InstMgr * im, sdaiVec_t * sdaiVec, int offset, int stride, int limit ) {
|
||||
for( int i = offset; i < limit; i+=stride ) {
|
||||
im->Delete( (*sdaiVec)[i] );
|
||||
(*sdaiVec)[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool compareKeywordCount ( InstMgr * mgr1, InstMgr * mgr2 ) {
|
||||
int i, size = dummyEDescNames.size();
|
||||
for( i = 0; i < size; i++ ) {
|
||||
//some comparisions may be repeated.
|
||||
const char * str = dummyEDescNames[i].c_str();
|
||||
if( mgr1->EntityKeywordCount( str ) != mgr2->EntityKeywordCount( str ) ) {
|
||||
std::cout << std::endl << "\tEntityKeywordCount mistmatch for " << str << ": " << mgr1->EntityKeywordCount( str ) << " and " << mgr2->EntityKeywordCount( str ) << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Checks for similarity in the two InstMgr
|
||||
bool compareInstMgr( InstMgr * mgr1, InstMgr * mgr2 ) {
|
||||
if( mgr1->MaxFileId() != mgr2->MaxFileId() ) {
|
||||
std::cout << std::endl << "\tMaxFileId not same: " << mgr1->MaxFileId() << " and " << mgr2->MaxFileId() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( mgr1->InstanceCount() != mgr2->InstanceCount() ) {
|
||||
std::cout << std::endl << "\tInstance count not same: " << mgr1->InstanceCount() << " and " << mgr2->InstanceCount() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !compareKeywordCount( mgr1, mgr2 ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Performs addition of different instances to the same InstMgr simultaneosly.
|
||||
bool checkInstMgrAppendOnlyThreadSafety() {
|
||||
InstMgr * imExpected = new InstMgr( 0 );
|
||||
int size = dummyEDescNames.size();
|
||||
|
||||
//simulate the work done by two threads
|
||||
sdaiVec_t sdaiVecOld( size );
|
||||
appendInstances( imExpected, &sdaiVecOld, 0, 2, size );
|
||||
appendInstances( imExpected, &sdaiVecOld, 1, 2, size );
|
||||
std::cout << "Checking thread safety of InstMgr in Append Operation..." ;
|
||||
|
||||
int i, iterations = 1000;
|
||||
for( i = 0 ; i < iterations; i++ ) {
|
||||
InstMgr * imActual = new InstMgr( 0 );
|
||||
sdaiVec_t sdaiVecNew( size );
|
||||
|
||||
std::thread first( appendInstances, imActual, &sdaiVecNew, 0, 2, size );
|
||||
std::thread second( appendInstances, imActual, &sdaiVecNew, 1, 2, size );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool success = compareInstMgr( imExpected, imActual );
|
||||
delete imActual;
|
||||
deleteSdaiVec( sdaiVecNew );
|
||||
|
||||
if( !success ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pass = ( i = iterations );
|
||||
if( pass ) {
|
||||
std::cout << "...PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
delete imExpected;
|
||||
deleteSdaiVec( sdaiVecOld );
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
/// Performs deletion of different instances to the same InstMgr simultaneosly.
|
||||
bool checkInstMgrDeleteOnlyThreadSafety() {
|
||||
InstMgr * imExpected = new InstMgr( 0 );
|
||||
int size = dummyEDescNames.size();
|
||||
//simulate the work done by two threads
|
||||
|
||||
sdaiVec_t sdaiVecOld( size );
|
||||
appendInstances( imExpected, &sdaiVecOld, 0, 1, size );
|
||||
deleteInstances( imExpected, &sdaiVecOld, 0, 2, size );
|
||||
deleteInstances( imExpected, &sdaiVecOld, 1, 2, size );
|
||||
std::cout << "Checking thread safety of InstMgr in Delete Operation..." ;
|
||||
|
||||
int i, iterations = 1000;
|
||||
for( i = 0 ; i < iterations; i++ ) {
|
||||
InstMgr * imActual = new InstMgr( 0 );
|
||||
sdaiVec_t sdaiVecNew( size );
|
||||
|
||||
appendInstances( imActual, &sdaiVecNew, 0, 1, size ); //Preparetion
|
||||
std::thread first( deleteInstances, imActual, &sdaiVecNew, 0, 2, size );
|
||||
std::thread second( deleteInstances, imActual, &sdaiVecNew, 1, 2, size );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool success = compareInstMgr( imExpected, imActual );
|
||||
delete imActual;
|
||||
deleteSdaiVec( sdaiVecNew );
|
||||
|
||||
if( !success ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pass = ( i = iterations );
|
||||
if( pass ) {
|
||||
std::cout << "...PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
delete imExpected;
|
||||
deleteSdaiVec( sdaiVecOld );
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
/// Performs addition and deletion of different instances to the same InstMgr simultaneosly.
|
||||
bool checkInstMgrAppendDeleteThreadSafety() {
|
||||
InstMgr * imExpected = new InstMgr( 0 );
|
||||
int size = dummyEDescNames.size();
|
||||
//simulate the work done by two threads
|
||||
|
||||
sdaiVec_t sdaiVecOld( size );
|
||||
appendInstances( imExpected, &sdaiVecOld, 0, 2, size );
|
||||
appendInstances( imExpected, &sdaiVecOld, 1, 2, size );
|
||||
deleteInstances( imExpected, &sdaiVecOld, 0, 2, size );
|
||||
std::cout << "Checking thread safety of InstMgr in Append-Delete Operation..." ;
|
||||
|
||||
int i, iterations = 1000;
|
||||
for( i = 0 ; i < iterations; i++ ) {
|
||||
InstMgr * imActual = new InstMgr( 0 );
|
||||
sdaiVec_t sdaiVecNew( size );
|
||||
|
||||
appendInstances( imActual, &sdaiVecNew, 0, 2, size ); //Preparation
|
||||
std::thread first( appendInstances, imActual, &sdaiVecNew, 1, 2, size );
|
||||
std::thread second( deleteInstances, imActual, &sdaiVecNew, 0, 2, size );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool success = compareInstMgr( imExpected, imActual );
|
||||
delete imActual;
|
||||
deleteSdaiVec( sdaiVecNew );
|
||||
|
||||
if( !success ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pass = ( i == iterations );
|
||||
if( pass ) {
|
||||
std::cout << "...PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
delete imExpected;
|
||||
deleteSdaiVec( sdaiVecOld );
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
int main( int , char ** ) {
|
||||
bool pass = true;
|
||||
|
||||
assert( dummyEDescNames.size() % 4 == 0 && "dummyEDescNames should be a multiple of 4 ");
|
||||
|
||||
pass &= checkInstMgrAppendOnlyThreadSafety();
|
||||
pass &= checkInstMgrDeleteOnlyThreadSafety();
|
||||
pass &= checkInstMgrAppendDeleteThreadSafety();
|
||||
|
||||
if( pass ) {
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <sc_hash.h>
|
||||
#include <Str.h>
|
||||
#include <complexSupport.h>
|
||||
#include <sc_mutex.h>
|
||||
|
||||
typedef struct Hash_Table * HashTable;
|
||||
|
||||
@@ -38,10 +37,6 @@ class SC_CORE_EXPORT Registry {
|
||||
HashEntry cur_schema;
|
||||
HashEntry cur_type;
|
||||
|
||||
mutable sc_recursive_mutex entityMtx; // will protect primodialSwamp, entity_cnt and all_ents_cnt
|
||||
mutable sc_recursive_mutex schemaMtx; // will protect active_schemas
|
||||
mutable sc_recursive_mutex typeMtx; // will protect active_types
|
||||
|
||||
// used by AddEntity() and RemoveEntity() to deal with renamings of an
|
||||
// entity done in a USE or REFERENCE clause - see header comments in
|
||||
// file Registry.inline.cc
|
||||
|
||||
@@ -113,28 +113,22 @@ Registry::~Registry() {
|
||||
|
||||
void Registry::DeleteContents() {
|
||||
// entities first
|
||||
entityMtx.lock();
|
||||
SC_HASHlistinit( primordialSwamp, &cur_entity );
|
||||
while( SC_HASHlist( &cur_entity ) ) {
|
||||
delete( EntityDescriptor * ) cur_entity.e->data;
|
||||
}
|
||||
entityMtx.unlock();
|
||||
|
||||
// schemas
|
||||
schemaMtx.lock();
|
||||
SC_HASHlistinit( active_schemas, &cur_schema );
|
||||
while( SC_HASHlist( &cur_schema ) ) {
|
||||
delete( Schema * ) cur_schema.e->data;
|
||||
}
|
||||
schemaMtx.unlock();
|
||||
|
||||
// types
|
||||
typeMtx.lock();
|
||||
SC_HASHlistinit( active_types, &cur_type );
|
||||
while( SC_HASHlist( &cur_type ) ) {
|
||||
delete( TypeDescriptor * ) cur_type.e->data;
|
||||
}
|
||||
typeMtx.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,14 +145,12 @@ const EntityDescriptor * Registry::FindEntity( const char * e, const char * schN
|
||||
const SchRename * altlist;
|
||||
char schformat[BUFSIZ], altName[BUFSIZ];
|
||||
|
||||
entityMtx.lock();
|
||||
if( check_case ) {
|
||||
entd = ( EntityDescriptor * )SC_HASHfind( primordialSwamp, ( char * )e );
|
||||
} else {
|
||||
entd = ( EntityDescriptor * )SC_HASHfind( primordialSwamp,
|
||||
( char * )PrettyTmpName( e ) );
|
||||
}
|
||||
entityMtx.unlock();
|
||||
if( entd && schNm ) {
|
||||
// We've now found an entity. If schNm has a value, we must ensure we
|
||||
// have a valid name.
|
||||
@@ -189,35 +181,24 @@ const EntityDescriptor * Registry::FindEntity( const char * e, const char * schN
|
||||
}
|
||||
|
||||
const Schema * Registry::FindSchema( const char * n, int check_case ) const {
|
||||
const Schema * sc;
|
||||
schemaMtx.lock();
|
||||
if( check_case ) {
|
||||
sc = ( const Schema * ) SC_HASHfind( active_schemas, ( char * ) n );
|
||||
} else {
|
||||
sc = ( const Schema * ) SC_HASHfind( active_schemas,
|
||||
( char * )PrettyTmpName( n ) );
|
||||
return ( const Schema * ) SC_HASHfind( active_schemas, ( char * ) n );
|
||||
}
|
||||
schemaMtx.unlock();
|
||||
return sc;
|
||||
|
||||
return ( const Schema * ) SC_HASHfind( active_schemas,
|
||||
( char * )PrettyTmpName( n ) );
|
||||
}
|
||||
|
||||
const TypeDescriptor * Registry::FindType( const char * n, int check_case ) const {
|
||||
const TypeDescriptor * td;
|
||||
typeMtx.lock();
|
||||
if( check_case ) {
|
||||
td = ( const TypeDescriptor * ) SC_HASHfind( active_types, ( char * ) n );
|
||||
} else {
|
||||
td = ( const TypeDescriptor * ) SC_HASHfind( active_types,
|
||||
( char * )PrettyTmpName( n ) );
|
||||
return ( const TypeDescriptor * ) SC_HASHfind( active_types, ( char * ) n );
|
||||
}
|
||||
typeMtx.unlock();
|
||||
return td;
|
||||
return ( const TypeDescriptor * ) SC_HASHfind( active_types,
|
||||
( char * )PrettyTmpName( n ) );
|
||||
}
|
||||
|
||||
void Registry::ResetTypes() {
|
||||
typeMtx.lock();
|
||||
SC_HASHlistinit( active_types, &cur_type );
|
||||
typeMtx.unlock();
|
||||
}
|
||||
|
||||
const TypeDescriptor * Registry::NextType() {
|
||||
@@ -228,25 +209,19 @@ const TypeDescriptor * Registry::NextType() {
|
||||
}
|
||||
|
||||
void Registry::AddEntity( const EntityDescriptor & e ) {
|
||||
entityMtx.lock();
|
||||
SC_HASHinsert( primordialSwamp, ( char * ) e.Name(), ( EntityDescriptor * ) &e );
|
||||
++entity_cnt;
|
||||
++all_ents_cnt;
|
||||
AddClones( e );
|
||||
entityMtx.unlock();
|
||||
}
|
||||
|
||||
|
||||
void Registry::AddSchema( const Schema & d ) {
|
||||
schemaMtx.lock();
|
||||
SC_HASHinsert( active_schemas, ( char * ) d.Name(), ( Schema * ) &d );
|
||||
schemaMtx.unlock();
|
||||
}
|
||||
|
||||
void Registry::AddType( const TypeDescriptor & d ) {
|
||||
typeMtx.lock();
|
||||
SC_HASHinsert( active_types, ( char * ) d.Name(), ( TypeDescriptor * ) &d );
|
||||
typeMtx.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,14 +234,12 @@ void Registry::AddType( const TypeDescriptor & d ) {
|
||||
void Registry::AddClones( const EntityDescriptor & e ) {
|
||||
const SchRename * alts = e.AltNameList();
|
||||
|
||||
entityMtx.lock();
|
||||
while( alts ) {
|
||||
SC_HASHinsert( primordialSwamp, ( char * )alts->objName(),
|
||||
( EntityDescriptor * )&e );
|
||||
alts = alts->next;
|
||||
}
|
||||
all_ents_cnt += uniqueNames( e.Name(), e.AltNameList() );
|
||||
entityMtx.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,7 +271,6 @@ static int uniqueNames( const char * entnm, const SchRename * altlist ) {
|
||||
}
|
||||
|
||||
void Registry::RemoveEntity( const char * n ) {
|
||||
entityMtx.lock();
|
||||
const EntityDescriptor * e = FindEntity( n );
|
||||
struct Element tmp;
|
||||
|
||||
@@ -307,24 +279,19 @@ void Registry::RemoveEntity( const char * n ) {
|
||||
}
|
||||
tmp.key = ( char * ) n;
|
||||
SC_HASHsearch( primordialSwamp, &tmp, HASH_DELETE ) ? --entity_cnt : 0;
|
||||
entityMtx.unlock();
|
||||
|
||||
}
|
||||
|
||||
void Registry::RemoveSchema( const char * n ) {
|
||||
struct Element tmp;
|
||||
tmp.key = ( char * ) n;
|
||||
schemaMtx.lock();
|
||||
SC_HASHsearch( active_schemas, &tmp, HASH_DELETE );
|
||||
schemaMtx.unlock();
|
||||
}
|
||||
|
||||
void Registry::RemoveType( const char * n ) {
|
||||
struct Element tmp;
|
||||
tmp.key = ( char * ) n;
|
||||
typeMtx.lock();
|
||||
SC_HASHsearch( active_types, &tmp, HASH_DELETE );
|
||||
typeMtx.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,21 +301,17 @@ void Registry::RemoveClones( const EntityDescriptor & e ) {
|
||||
const SchRename * alts = e.AltNameList();
|
||||
struct Element * tmp;
|
||||
|
||||
entityMtx.lock();
|
||||
while( alts ) {
|
||||
tmp = new Element;
|
||||
tmp->key = ( char * ) alts->objName();
|
||||
SC_HASHsearch( primordialSwamp, tmp, HASH_DELETE );
|
||||
alts = alts->next;
|
||||
}
|
||||
entityMtx.unlock();
|
||||
}
|
||||
|
||||
|
||||
SDAI_Application_instance * Registry::ObjCreate( const char * nm, const char * schnm, int check_case ) const {
|
||||
entityMtx.lock();
|
||||
const EntityDescriptor * entd = FindEntity( nm, schnm, check_case );
|
||||
entityMtx.unlock();
|
||||
if( entd ) {
|
||||
SDAI_Application_instance * se =
|
||||
( ( EntityDescriptor * )entd ) -> NewSTEPentity();
|
||||
@@ -374,9 +337,7 @@ int Registry::GetEntityCnt() {
|
||||
}
|
||||
|
||||
void Registry::ResetEntities() {
|
||||
entityMtx.lock();
|
||||
SC_HASHlistinit( primordialSwamp, &cur_entity );
|
||||
entityMtx.unlock();
|
||||
|
||||
}
|
||||
|
||||
@@ -388,9 +349,7 @@ const EntityDescriptor * Registry::NextEntity() {
|
||||
}
|
||||
|
||||
void Registry::ResetSchemas() {
|
||||
schemaMtx.lock();
|
||||
SC_HASHlistinit( active_schemas, &cur_schema );
|
||||
schemaMtx.unlock();
|
||||
}
|
||||
|
||||
const Schema * Registry::NextSchema() {
|
||||
|
||||
@@ -1,338 +0,0 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_STD_THREAD
|
||||
# include <thread>
|
||||
#else
|
||||
# error Need std::thread for this test!
|
||||
#endif
|
||||
|
||||
#include "ExpDict.h"
|
||||
#include "baseType.h"
|
||||
#include "Registry.h"
|
||||
|
||||
enum Mode {
|
||||
ENTITY = 0,
|
||||
SCHEMA = 1,
|
||||
TYPE = 2
|
||||
};
|
||||
const std::vector< std::string > modeNames { "ENTITY", "SCHEMA", "TYPE" };
|
||||
|
||||
/// Will be populated in the main function
|
||||
std::vector< std::string > names;
|
||||
|
||||
/// Needed for constructing a Registry
|
||||
void dummyInit( Registry & reg ) {
|
||||
( void )reg;
|
||||
}
|
||||
|
||||
/// Adds the elements at the specified indexes from the Registry
|
||||
void addElements( Registry * reg, Mode mode, int llimit, int ulimit, int stride ) {
|
||||
int i;
|
||||
for( i = llimit; i < ulimit; i+=stride ) {
|
||||
switch( mode ) {
|
||||
case ENTITY:
|
||||
reg->AddEntity( *( new EntityDescriptor( names[i].c_str(), ( Schema * ) NULL, LTrue, LFalse ) ) );
|
||||
break;
|
||||
|
||||
case SCHEMA:
|
||||
reg->AddSchema( *( new Schema( names[i].c_str() ) ) );
|
||||
break;
|
||||
|
||||
case TYPE:
|
||||
reg->AddType( *( new TypeDescriptor( names[i].c_str(), UNKNOWN_TYPE, ( Schema * )0, ( char * )0 ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes the elements at the specified indexes from the Registry
|
||||
void removeElements( Registry * reg, Mode mode, int llimit, int ulimit, int stride ) {
|
||||
int i;
|
||||
for( i = llimit; i < ulimit; i+=stride ) {
|
||||
switch( mode ) {
|
||||
case ENTITY:
|
||||
reg->RemoveEntity( names[i].c_str() );
|
||||
break;
|
||||
|
||||
case SCHEMA:
|
||||
reg->RemoveSchema( names[i].c_str() );
|
||||
break;
|
||||
|
||||
case TYPE:
|
||||
reg->RemoveType( names[i].c_str() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// compares the elements of the two registry. i.e. either an element should be in both the registries or none of them
|
||||
bool haveSameElements( Registry * reg1, Registry * reg2 ) {
|
||||
int i, size = names.size();
|
||||
for( i = 0; i < size; i++ ) {
|
||||
if( ( reg1->FindEntity( names[i].c_str() ) != NULL ) &&
|
||||
( reg2->FindEntity( names[i].c_str() ) == NULL ) ) {
|
||||
std::cout << std::endl << modeNames[ENTITY] << " " << names[i] << " expected but not present" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if( ( reg1->FindEntity( names[i].c_str() ) == NULL ) &&
|
||||
( reg2->FindEntity( names[i].c_str() ) != NULL ) ) {
|
||||
std::cout << std::endl << modeNames[ENTITY] << " " << names[i] << " not expected but present" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ( reg1->FindSchema( names[i].c_str() ) != NULL ) &&
|
||||
( reg2->FindSchema( names[i].c_str() ) == NULL ) ) {
|
||||
std::cout << std::endl << modeNames[SCHEMA] << " " << names[i] << " expected but not present" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if( ( reg1->FindSchema( names[i].c_str() ) == NULL ) &&
|
||||
( reg2->FindSchema( names[i].c_str() ) != NULL ) ) {
|
||||
std::cout << std::endl << modeNames[SCHEMA] << " " << names[i] << " not expected but present" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ( reg1->FindType( names[i].c_str() ) != NULL ) &&
|
||||
( reg2->FindType( names[i].c_str() ) == NULL ) ) {
|
||||
std::cout << std::endl << modeNames[TYPE] << " " << names[i] << " expected but not present" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if( ( reg1->FindType( names[i].c_str() ) == NULL ) &&
|
||||
( reg2->FindType( names[i].c_str() ) != NULL ) ) {
|
||||
std::cout << std::endl << modeNames[TYPE] << " " << names[i] << " not expected but present" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// compares the given registries and reports any disparity
|
||||
bool compareRegistry( Registry * reg1, Registry * reg2 ) {
|
||||
if( reg1->GetEntityCnt() != reg2->GetEntityCnt() ) {
|
||||
std::cout << std::endl << "\tentityCnt not same: " << reg1->GetEntityCnt() << " and " << reg2->GetEntityCnt() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( reg1->GetFullEntCnt() != reg2->GetFullEntCnt() ) {
|
||||
std::cout << std::endl << "\tall_ents_Cnt not same: " << reg1->GetFullEntCnt() << " and " << reg2->GetFullEntCnt() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !haveSameElements( reg1, reg2 ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// For a particular mode adds elements to one Registry serially and to another Registry parallely.
|
||||
/// It then compares the two Registry and reports any disparity.
|
||||
bool checkRegistryAddOnlyThreadSafety( Mode mode ) {
|
||||
int size = names.size();
|
||||
|
||||
Registry * regExpected = new Registry( dummyInit );
|
||||
addElements( regExpected, mode, 0, size, 2 ); // Add even indexed elements
|
||||
addElements( regExpected, mode, 1, size, 2 ); // Add odd indexed elements
|
||||
|
||||
std::cout << "Checking thread safety of Registry " << modeNames[( int )mode] << " Add Operations..." ;
|
||||
|
||||
int i, iterations = 10;
|
||||
for( i = 0 ; i < iterations; i++ ) {
|
||||
Registry * regActual = new Registry( dummyInit );
|
||||
|
||||
std::thread first( addElements, regActual, mode, 0, size, 2 );
|
||||
std::thread second( addElements, regActual, mode, 1, size, 2 );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool success = compareRegistry( regExpected, regActual );
|
||||
delete regActual;
|
||||
|
||||
if( !success ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pass = ( i == iterations );
|
||||
if( pass ) {
|
||||
std::cout << "...PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
delete regExpected;
|
||||
return pass;
|
||||
}
|
||||
|
||||
/// For a particular mode removes elements to one Registry serially and to another Registry parallely.
|
||||
/// It then compares the two Registry and reports any disparity.
|
||||
bool checkRegistryRemoveOnlyThreadSafety( Mode mode ) {
|
||||
int size = names.size();
|
||||
|
||||
Registry * regExpected = new Registry( dummyInit );
|
||||
addElements( regExpected, mode, 0, size, 1 ); // Add all elements
|
||||
removeElements( regExpected, mode, 0, size, 3 ); // remove one-third elements
|
||||
removeElements( regExpected, mode, 1, size, 3 ); // remove another third elements
|
||||
|
||||
std::cout << "Checking thread safety of Registry " << modeNames[( int )mode] << " Remove Operations..." ;
|
||||
|
||||
int i, iterations = 10;
|
||||
for( i = 0 ; i < iterations; i++ ) {
|
||||
Registry * regActual = new Registry( dummyInit );
|
||||
|
||||
addElements( regActual, mode, 0, size, 1 );
|
||||
std::thread first( removeElements, regActual, mode, 0, size, 3 );
|
||||
std::thread second( removeElements, regActual, mode, 1, size, 3 );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool success = compareRegistry( regExpected, regActual );
|
||||
delete regActual;
|
||||
|
||||
if( !success ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pass = ( i == iterations );
|
||||
if( pass ) {
|
||||
std::cout << "...PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
delete regExpected;
|
||||
return pass;
|
||||
}
|
||||
|
||||
/// For a particular mode adds and removes elements to one Registry serially and to ther Registry parallely.
|
||||
/// It then compares the two Registry and reports any disparity.
|
||||
bool checkRegistryAddRemoveThreadSafety( Mode mode ) {
|
||||
int size = names.size();
|
||||
|
||||
Registry * regExpected = new Registry( dummyInit );
|
||||
addElements( regExpected, mode, 0, size, 2 ); // Add even indexed elements
|
||||
addElements( regExpected, mode, 1, size, 2 ); // Add odd indexed elements
|
||||
removeElements( regExpected, mode, 0, size, 2 ); // remove even indexed elements
|
||||
|
||||
std::cout << "Checking thread safety of Registry " << modeNames[( int )mode] << " Add-Remove Operations..." ;
|
||||
|
||||
int i, iterations = 10;
|
||||
for( i = 0 ; i < iterations; i++ ) {
|
||||
Registry * regActual = new Registry( dummyInit );
|
||||
|
||||
addElements( regActual, mode, 0, size, 2 );
|
||||
std::thread first( addElements, regActual, mode, 1, size, 2 );
|
||||
std::thread second( removeElements, regActual, mode, 0, size, 2 );
|
||||
|
||||
first.join();
|
||||
second.join();
|
||||
|
||||
bool success = compareRegistry( regExpected, regActual );
|
||||
delete regActual;
|
||||
|
||||
if( !success ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool pass = ( i == iterations );
|
||||
if( pass ) {
|
||||
std::cout << "...PASS!" << std::endl;
|
||||
} else {
|
||||
std::cout << "...FAIL!" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
delete regExpected;
|
||||
return pass;
|
||||
}
|
||||
|
||||
bool checkRegistryEntityAddOnlyThreadSafety() {
|
||||
return checkRegistryAddOnlyThreadSafety( ENTITY );
|
||||
}
|
||||
|
||||
bool checkRegistrySchemaAddOnlyThreadSafety() {
|
||||
return checkRegistryAddOnlyThreadSafety( SCHEMA );
|
||||
}
|
||||
|
||||
bool checkRegistryTypeAddOnlyThreadSafety() {
|
||||
return checkRegistryAddOnlyThreadSafety( TYPE );
|
||||
}
|
||||
|
||||
bool checkRegistryEntityRemoveOnlyThreadSafety() {
|
||||
return checkRegistryRemoveOnlyThreadSafety( ENTITY );
|
||||
}
|
||||
|
||||
bool checkRegistrySchemaRemoveOnlyThreadSafety() {
|
||||
return checkRegistryRemoveOnlyThreadSafety( SCHEMA );
|
||||
}
|
||||
|
||||
bool checkRegistryTypeRemoveOnlyThreadSafety() {
|
||||
return checkRegistryRemoveOnlyThreadSafety( TYPE );
|
||||
}
|
||||
|
||||
bool checkRegistryEntityAddRemoveThreadSafety() {
|
||||
return checkRegistryAddRemoveThreadSafety( ENTITY );
|
||||
}
|
||||
|
||||
bool checkRegistrySchemaAddRemoveThreadSafety() {
|
||||
return checkRegistryAddRemoveThreadSafety( SCHEMA );
|
||||
}
|
||||
|
||||
bool checkRegistryTypeAddRemoveThreadSafety() {
|
||||
return checkRegistryAddRemoveThreadSafety( TYPE );
|
||||
}
|
||||
|
||||
// populates the vector names[] with string of the form [A-Z]/[a-z]/[a-z]
|
||||
void populateNamesVector() {
|
||||
char ch[3];
|
||||
ch[0] = 'A';
|
||||
while( ch[0] <= 'Z')
|
||||
{
|
||||
ch[1] = 'a';
|
||||
while( ch[1] <= 'z')
|
||||
{
|
||||
ch[2] = '0';
|
||||
while( ch[2] <= '9')
|
||||
{
|
||||
string str( ch );
|
||||
names.push_back( str );
|
||||
ch[2]++;
|
||||
}
|
||||
ch[1]++;
|
||||
}
|
||||
ch[0]++;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int , char ** ) {
|
||||
populateNamesVector();
|
||||
|
||||
bool pass = true;
|
||||
pass &= checkRegistryEntityAddOnlyThreadSafety();
|
||||
pass &= checkRegistryEntityRemoveOnlyThreadSafety();
|
||||
pass &= checkRegistryEntityAddRemoveThreadSafety();
|
||||
|
||||
pass &= checkRegistrySchemaAddOnlyThreadSafety();
|
||||
pass &= checkRegistrySchemaRemoveOnlyThreadSafety();
|
||||
pass &= checkRegistrySchemaAddRemoveThreadSafety();
|
||||
|
||||
pass &= checkRegistryTypeAddOnlyThreadSafety();
|
||||
pass &= checkRegistryTypeRemoveOnlyThreadSafety();
|
||||
pass &= checkRegistryTypeAddRemoveThreadSafety();
|
||||
|
||||
if( pass ) {
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
@@ -38,7 +38,14 @@ STEPaggregate::STEPaggregate() {
|
||||
}
|
||||
|
||||
STEPaggregate::~STEPaggregate() {
|
||||
// Left to the superclass
|
||||
STEPnode * node;
|
||||
|
||||
node = ( STEPnode * ) head;
|
||||
while( node ) {
|
||||
head = node->NextNode();
|
||||
delete node;
|
||||
node = ( STEPnode * ) head;
|
||||
}
|
||||
}
|
||||
|
||||
STEPaggregate & STEPaggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
@@ -384,7 +391,6 @@ SingleLinkNode * GenericAggregate::NewNode() {
|
||||
STEPaggregate & GenericAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
Empty();
|
||||
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
SingleLinkNode * next = a.GetHead();
|
||||
SingleLinkNode * copy;
|
||||
|
||||
@@ -393,8 +399,6 @@ STEPaggregate & GenericAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
AddNode( copy );
|
||||
next = next->NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
@@ -575,14 +579,11 @@ Severity EntityAggregate::ReadValue( istream & in, ErrorDescriptor * err,
|
||||
|
||||
|
||||
STEPaggregate & EntityAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
const EntityNode * tmp = ( const EntityNode * ) a.GetHead();
|
||||
while( tmp ) {
|
||||
AddNode( new EntityNode( tmp -> node ) );
|
||||
tmp = ( const EntityNode * ) tmp -> NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
@@ -816,15 +817,12 @@ Severity SelectAggregate::ReadValue( istream & in, ErrorDescriptor * err,
|
||||
|
||||
|
||||
STEPaggregate & SelectAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
const SelectNode * tmp = ( const SelectNode * ) a.GetHead();
|
||||
while( tmp ) {
|
||||
AddNode( new SelectNode( tmp -> node ) );
|
||||
|
||||
tmp = ( const SelectNode * ) tmp -> NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
@@ -939,7 +937,6 @@ StringAggregate::~StringAggregate() {
|
||||
STEPaggregate & StringAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
Empty();
|
||||
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
SingleLinkNode * next = a.GetHead();
|
||||
SingleLinkNode * copy;
|
||||
|
||||
@@ -948,8 +945,6 @@ STEPaggregate & StringAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
AddNode( copy );
|
||||
next = next->NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
@@ -1047,7 +1042,6 @@ BinaryAggregate::~BinaryAggregate() {
|
||||
STEPaggregate & BinaryAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
Empty();
|
||||
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
SingleLinkNode * next = a.GetHead();
|
||||
SingleLinkNode * copy;
|
||||
|
||||
@@ -1056,8 +1050,6 @@ STEPaggregate & BinaryAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
AddNode( copy );
|
||||
next = next->NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
@@ -1150,7 +1142,6 @@ void BinaryNode::STEPwrite( ostream & out ) {
|
||||
|
||||
/// COPY
|
||||
STEPaggregate & EnumAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
const EnumNode * tmp = ( const EnumNode * ) a.GetHead();
|
||||
EnumNode * to;
|
||||
|
||||
@@ -1160,8 +1151,6 @@ STEPaggregate & EnumAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
AddNode( to );
|
||||
tmp = ( const EnumNode * ) tmp -> NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
@@ -1317,7 +1306,6 @@ SingleLinkNode * RealAggregate::NewNode() {
|
||||
|
||||
// COPY
|
||||
STEPaggregate & RealAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
const RealNode * tmp = ( const RealNode * ) a.GetHead();
|
||||
RealNode * to;
|
||||
|
||||
@@ -1327,8 +1315,6 @@ STEPaggregate & RealAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
AddNode( to );
|
||||
tmp = ( const RealNode * ) tmp -> NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
@@ -1353,7 +1339,6 @@ SingleLinkNode * IntAggregate::NewNode() {
|
||||
|
||||
/// COPY
|
||||
STEPaggregate & IntAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
a.mtxP->lock(); // required since we are iterating on 'SingleLinkList a'
|
||||
const IntNode * tmp = ( const IntNode * ) a.GetHead();
|
||||
IntNode * to;
|
||||
|
||||
@@ -1363,8 +1348,6 @@ STEPaggregate & IntAggregate::ShallowCopy( const STEPaggregate & a ) {
|
||||
AddNode( to );
|
||||
tmp = ( const IntNode * ) tmp -> NextNode();
|
||||
}
|
||||
a.mtxP->unlock();
|
||||
|
||||
if( head ) {
|
||||
_null = 0;
|
||||
} else {
|
||||
|
||||
@@ -606,7 +606,7 @@ void STEPattribute::ShallowCopy( const STEPattribute * sa ) {
|
||||
_derive = sa->_derive;
|
||||
_redefAttr = sa->_redefAttr;
|
||||
if( _redefAttr ) {
|
||||
ShallowCopy( _redefAttr );
|
||||
_redefAttr->ShallowCopy( sa );
|
||||
}
|
||||
//Should we just use memcpy()? That would be a true shallowCopy
|
||||
switch( sa->NonRefType() ) {
|
||||
@@ -750,18 +750,22 @@ Severity STEPattribute::set_null() {
|
||||
|
||||
case REFERENCE_TYPE:
|
||||
case GENERIC_TYPE:
|
||||
cerr << "Internal error: " << __FILE__ << ":" << __LINE__ << "\n" << _POC_ "\n";
|
||||
cerr << "Internal error: " << __FILE__ << __LINE__
|
||||
<< "\n" << _POC_ "\n";
|
||||
return SEVERITY_BUG;
|
||||
|
||||
case UNKNOWN_TYPE:
|
||||
default:
|
||||
default: {
|
||||
ptr.u -> set_null();
|
||||
std::stringstream err;
|
||||
err << " Warning: attribute '" << Name() << " : " << TypeName() << " : ";
|
||||
err << Type() << "' - " << "Don't know how to make attribute NULL" << std::endl;
|
||||
_error.AppendToDetailMsg( err.str() );
|
||||
char errStr[BUFSIZ];
|
||||
errStr[0] = '\0';
|
||||
sprintf( errStr, " Warning: attribute '%s : %s : %d' - %s.\n",
|
||||
Name(), TypeName(), Type(),
|
||||
"Don't know how to make attribute NULL" );
|
||||
_error.AppendToDetailMsg( errStr );
|
||||
_error.GreaterSeverity( SEVERITY_WARNING );
|
||||
return SEVERITY_WARNING;
|
||||
}
|
||||
}
|
||||
if( Nullable() ) {
|
||||
return SEVERITY_NULL;
|
||||
@@ -1048,14 +1052,6 @@ bool operator == ( const STEPattribute & a1, const STEPattribute & a2 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** evaluate the equality of two attributes
|
||||
* ignores _error and refCount, since those are ancillary
|
||||
* \return true if not equal
|
||||
*/
|
||||
bool operator != ( const STEPattribute & a1, const STEPattribute & a2 ) {
|
||||
return !( a1 == a2 );
|
||||
}
|
||||
|
||||
/// return true if the attr descriptor is identical
|
||||
bool sameADesc( const STEPattribute & a1, const STEPattribute & a2 ) {
|
||||
return a1.aDesc == a2.aDesc;
|
||||
|
||||
@@ -262,11 +262,13 @@ class SC_CORE_EXPORT STEPattribute {
|
||||
STEPattribute( const class AttrDescriptor & d, SCLundefined * p );
|
||||
|
||||
/// return true if attr types and values match
|
||||
SC_CORE_EXPORT friend bool operator == ( const STEPattribute & a1, const STEPattribute & a2 );
|
||||
SC_CORE_EXPORT friend bool operator != ( const STEPattribute & a1, const STEPattribute & a2 );
|
||||
friend bool operator == ( const STEPattribute & a1, const STEPattribute & a2 );
|
||||
friend bool operator != ( const STEPattribute & a1, const STEPattribute & a2 ) {
|
||||
return !( a1 == a2 );
|
||||
}
|
||||
|
||||
/// return true if aDesc's match (behavior of old operator==)
|
||||
SC_CORE_EXPORT friend bool sameADesc ( const STEPattribute & a1, const STEPattribute & a2 );
|
||||
friend bool sameADesc ( const STEPattribute & a1, const STEPattribute & a2 );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,6 @@ STEPattributeList::~STEPattributeList() {
|
||||
|
||||
STEPattribute & STEPattributeList::operator []( int n ) {
|
||||
int x = 0;
|
||||
mtxP->lock();
|
||||
AttrListNode * a = ( AttrListNode * )head;
|
||||
int cnt = EntryCount();
|
||||
if( n < cnt ) {
|
||||
@@ -40,15 +39,12 @@ STEPattribute & STEPattributeList::operator []( int n ) {
|
||||
}
|
||||
}
|
||||
if( a ) {
|
||||
STEPattribute * attr = a->attr;
|
||||
mtxP->unlock();
|
||||
return *( attr );
|
||||
return *( a->attr );
|
||||
}
|
||||
|
||||
// else
|
||||
cerr << "\nERROR in STEP Core library: " << __FILE__ << ":"
|
||||
<< __LINE__ << "\n" << _POC_ << "\n\n";
|
||||
mtxP->unlock();
|
||||
return *( STEPattribute * ) 0;
|
||||
}
|
||||
|
||||
@@ -57,13 +53,11 @@ int STEPattributeList::list_length() {
|
||||
}
|
||||
|
||||
void STEPattributeList::push( STEPattribute * a ) {
|
||||
mtxP->lock();
|
||||
AttrListNode * a2 = ( AttrListNode * )head;
|
||||
|
||||
// if the attribute already exists in the list, don't push it
|
||||
while( a2 ) {
|
||||
if( *a == *( a2 -> attr ) ) {
|
||||
mtxP->unlock();
|
||||
return;
|
||||
}
|
||||
a2 = ( AttrListNode * )( a2->next );
|
||||
@@ -71,5 +65,4 @@ void STEPattributeList::push( STEPattribute * a ) {
|
||||
a->incrRefCount();
|
||||
AttrListNode * saln = new AttrListNode( a );
|
||||
AppendNode( saln );
|
||||
mtxP->unlock();
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
|
||||
bool invalid = false, outOfOrder = false;
|
||||
|
||||
// Splice out the invalid names from our list:
|
||||
ents->sharedMtxP->lock();
|
||||
while( eptr ) {
|
||||
enext = eptr->next;
|
||||
enDesc = _registry->FindEntity( *eptr, schnm );
|
||||
@@ -96,13 +95,10 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
|
||||
}
|
||||
eptr->next = NULL;
|
||||
// must set eptr->next to NULL or next line would del entire list
|
||||
eptr->sharedMtxP = NULL;
|
||||
// must set eptr->sharedMtxP to NULL or the sharedMtxP for the EntNode link-list will get deleted
|
||||
delete eptr;
|
||||
}
|
||||
eptr = enext;
|
||||
}
|
||||
ents->sharedMtxP->unlock();
|
||||
|
||||
// If we changed the name of any of the entities, resort:
|
||||
if( outOfOrder ) {
|
||||
@@ -133,25 +129,20 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
|
||||
"Entity combination does not represent a legal complex entity" );
|
||||
cerr << "ERROR: Could not create instance of the following complex"
|
||||
<< " entity:" << endl;
|
||||
|
||||
ents->sharedMtxP->lock();
|
||||
eptr = ents;
|
||||
while( eptr ) {
|
||||
cerr << *eptr << endl;
|
||||
eptr = eptr->next;
|
||||
}
|
||||
cerr << endl;
|
||||
ents->sharedMtxP->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, build what we can:
|
||||
ents->sharedMtxP->lock();
|
||||
BuildAttrs( *ents );
|
||||
for( eptr = ents->next; eptr; eptr = eptr->next ) {
|
||||
AddEntityPart( *eptr );
|
||||
}
|
||||
ents->sharedMtxP->unlock();
|
||||
AssignDerives();
|
||||
delete ents;
|
||||
}
|
||||
@@ -179,13 +170,9 @@ void STEPcomplex::AssignDerives() {
|
||||
AttrDescLinkNode * attrPtr;
|
||||
const AttrDescriptor * ad;
|
||||
|
||||
// Even though the following is an interation on sc, we dont
|
||||
// use the STEPcomplex mutex since we are assuming that no node
|
||||
// can be removed or inserted between two
|
||||
while( scomp1 && scomp1->eDesc ) {
|
||||
a = 0;
|
||||
attrList = &( scomp1->eDesc->ExplicitAttr() );
|
||||
attrList->mtxP->lock();
|
||||
attrPtr = ( AttrDescLinkNode * )attrList->GetHead();
|
||||
|
||||
// assign nm to be derived attr
|
||||
@@ -201,19 +188,18 @@ void STEPcomplex::AssignDerives() {
|
||||
} else {
|
||||
attrNm = nm;
|
||||
}
|
||||
scomp2 = head; //locked earlier
|
||||
// If we had used the generic hand-over-hand fine grain
|
||||
// locking, the following loop could have caused a deadlock.
|
||||
while( scomp2 && !a && ( scomp1 != scomp2 ) ) {
|
||||
scomp2->MakeDerived( attrNm );
|
||||
a = scomp2->GetSTEPattribute( attrNm );
|
||||
scomp2 = head;
|
||||
while( scomp2 && !a ) {
|
||||
if( scomp1 != scomp2 ) {
|
||||
scomp2->MakeDerived( attrNm );
|
||||
a = scomp2->GetSTEPattribute( attrNm );
|
||||
}
|
||||
scomp2 = scomp2->sc;
|
||||
}
|
||||
}
|
||||
// increment attr
|
||||
attrPtr = ( AttrDescLinkNode * )attrPtr->NextNode();
|
||||
}
|
||||
attrList->mtxP->unlock();
|
||||
scomp1 = scomp1->sc;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +215,7 @@ void STEPcomplex::AddEntityPart( const char * name ) {
|
||||
scomplex = new STEPcomplex( _registry, STEPfile_id );
|
||||
scomplex->BuildAttrs( name );
|
||||
if( scomplex->eDesc ) {
|
||||
scomplex->head = this; // no locking here as the only the current thread will have the copy
|
||||
scomplex->head = this;
|
||||
AppendEntity( scomplex );
|
||||
} else {
|
||||
cout << scomplex->_error.DetailMsg() << endl;
|
||||
@@ -240,16 +226,14 @@ void STEPcomplex::AddEntityPart( const char * name ) {
|
||||
|
||||
STEPcomplex * STEPcomplex::EntityPart( const char * name, const char * currSch ) {
|
||||
STEPcomplex * scomp = head;
|
||||
// No locking in this loop as remove insert operaations are not allowed
|
||||
while( scomp ) {
|
||||
if( scomp->eDesc ) {
|
||||
if( scomp->eDesc->CurrName( name, currSch ) ) {
|
||||
return scomp;
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
cout << "Bug in STEPcomplex::EntityPart(): entity part has "
|
||||
<< "no EntityDescriptor\n";
|
||||
}
|
||||
scomp = scomp->sc;
|
||||
}
|
||||
return 0;
|
||||
@@ -284,19 +268,11 @@ Severity STEPcomplex::ValidLevel( ErrorDescriptor * error, InstMgr * im,
|
||||
}
|
||||
|
||||
void STEPcomplex::AppendEntity( STEPcomplex * stepc ) {
|
||||
// We use the assumption that no remove / insert operation is there.
|
||||
// Hence is locking is required only at the last node.
|
||||
if( !sc ) {
|
||||
// We use the double checking. This safaly eliminates the locking of internal nodes
|
||||
mtx.lock();
|
||||
if( !sc ) {
|
||||
sc = stepc;
|
||||
mtx.unlock();
|
||||
return;
|
||||
} // else another node has just appended a new node
|
||||
mtx.unlock();
|
||||
if( sc ) {
|
||||
sc->AppendEntity( stepc );
|
||||
} else {
|
||||
sc = stepc;
|
||||
}
|
||||
sc->AppendEntity( stepc );
|
||||
}
|
||||
|
||||
// READ
|
||||
@@ -472,13 +448,13 @@ void STEPcomplex::BuildAttrs( const char * s ) {
|
||||
//////////////////////////////////////////////
|
||||
|
||||
STEPattribute * a = 0;
|
||||
attrList->mtxP->lock();
|
||||
|
||||
AttrDescLinkNode * attrPtr = ( AttrDescLinkNode * )attrList->GetHead();
|
||||
while( attrPtr != 0 ) {
|
||||
const AttrDescriptor * ad = attrPtr->AttrDesc();
|
||||
|
||||
if( ( ad->Derived() ) != LTrue ) {
|
||||
mtx.lock(); // To protect _attr_data_list and attributes
|
||||
|
||||
switch( ad->NonRefType() ) {
|
||||
case INTEGER_TYPE:
|
||||
integer_data = new SDAI_Integer;
|
||||
@@ -559,14 +535,10 @@ void STEPcomplex::BuildAttrs( const char * s ) {
|
||||
}
|
||||
|
||||
a -> set_null();
|
||||
attributes.mtxP->lock();
|
||||
attributes.push( a );
|
||||
attributes.mtxP->unlock();
|
||||
mtx.unlock();
|
||||
}
|
||||
attrPtr = ( AttrDescLinkNode * )attrPtr->NextNode();
|
||||
}
|
||||
attrList->mtxP->unlock();
|
||||
} else {
|
||||
_error.AppendToDetailMsg( "Entity does not exist.\n" );
|
||||
_error.GreaterSeverity( SEVERITY_INPUT_ERROR );
|
||||
@@ -620,19 +592,14 @@ void STEPcomplex::WriteExtMapEntities( ostream & out, const char * currSch ) {
|
||||
std::string tmp;
|
||||
out << StrToUpper( EntityName( currSch ), tmp );
|
||||
out << "(";
|
||||
|
||||
mtx.lock(); // Protects attributes
|
||||
attributes.mtxP->lock();
|
||||
int n = attributes.list_length();
|
||||
|
||||
for( int i = 0 ; i < n; i++ ) {
|
||||
( attributes[i] ).STEPwrite( out, currSch );
|
||||
if( i < n - 1 ) {
|
||||
out << ",";
|
||||
}
|
||||
}
|
||||
attributes.mtxP->unlock();
|
||||
mtx.unlock();
|
||||
|
||||
out << ")\n";
|
||||
if( sc ) {
|
||||
sc->WriteExtMapEntities( out, currSch );
|
||||
@@ -647,18 +614,14 @@ const char * STEPcomplex::WriteExtMapEntities( std::string & buf, const char * c
|
||||
buf.append( tmp );
|
||||
buf.append( "i" );
|
||||
|
||||
mtx.lock();
|
||||
attributes.mtxP->lock();
|
||||
int n = attributes.list_length();
|
||||
|
||||
for( int i = 0 ; i < n; i++ ) {
|
||||
buf.append( attributes[i].asStr( currSch ) );
|
||||
if( i < n - 1 ) {
|
||||
buf.append( "," );
|
||||
}
|
||||
}
|
||||
attributes.mtxP->unlock();
|
||||
mtx.unlock();
|
||||
|
||||
buf.append( ")\n" );
|
||||
|
||||
if( sc ) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user