Compare commits

..
215 changed files with 49554 additions and 45510 deletions
+386 -87
View File
@@ -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
View File
@@ -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
+6
View File
@@ -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
View File
@@ -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)
+4 -4
View File
@@ -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.
+4 -4
View File
@@ -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
View File
@@ -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
+8 -8
View File
@@ -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}")
+6 -6
View File
@@ -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.
-152
View File
@@ -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
-125
View File
@@ -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
-96
View File
@@ -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
-22
View File
@@ -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
-30
View File
@@ -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
-93
View File
@@ -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
-68
View File
@@ -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
-25
View File
@@ -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
-168
View File
@@ -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
+138
View File
@@ -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)
+15 -23
View File
@@ -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)
+48 -55
View 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
-77
View File
@@ -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
-10
View File
@@ -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.
-336
View File
@@ -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 );
}
-110
View File
@@ -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)
+2 -2
View 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)
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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 -4
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+7 -15
View File
@@ -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)
+51 -55
View File
@@ -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}" )
+4
View File
@@ -49,6 +49,10 @@
// $./AP203Minimum
// AP203Minimum outfile.stp
extern void
SchemaInit( class Registry & );
#include <STEPfile.h>
#include <sdai.h>
#include <STEPattribute.h>
+11 -19
View File
@@ -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)
+1 -1
View File
@@ -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;
};
+1 -1
View File
@@ -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;
-127
View File
@@ -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
View File
@@ -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*/
-14
View File
@@ -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 */
+1 -1
View File
@@ -58,7 +58,7 @@ typedef struct Scan_Buffer {
#endif
char * savedPos;
FILE * file;
const char * filename;
char * filename;
bool readEof;
int lineno;
int bol;
-2
View File
@@ -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 ) );
+2 -2
View File
@@ -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 */
-1
View File
@@ -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 */
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+34 -42
View File
@@ -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
-1
View File
@@ -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( ) {
+5
View File
@@ -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;
-32
View File
@@ -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;
}
-15
View File
@@ -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 */
-11
View File
@@ -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
View File
@@ -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)
+88 -2
View File
@@ -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;
}
+15 -1
View File
@@ -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
+94 -2
View File
@@ -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;
}
+22 -1
View File
@@ -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;
+1 -1
View File
@@ -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
+93 -2
View File
@@ -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;
}
/*****************************************************************************/
+19 -1
View File
@@ -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;
+1 -1
View File
@@ -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 ) );
}
+94 -2
View File
@@ -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;
}
+18 -1
View File
@@ -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 *
-153
View File
@@ -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();
}
-46
View File
@@ -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
View File
@@ -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
View File
@@ -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";
}
-7
View File
@@ -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;
-4
View File
@@ -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
View File
@@ -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() {
+30 -56
View File
@@ -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)
+1 -1
View File
@@ -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();
+2 -56
View File
@@ -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;
}
};
+2 -3
View File
@@ -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
View File
@@ -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() );
}
+33 -71
View File
@@ -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
};
+1 -14
View File
@@ -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 );
}
+99
View File
@@ -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
+68
View File
@@ -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
-13
View File
@@ -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;
-29
View File
@@ -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 ) {
-593
View File
@@ -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 );
}
+2 -4
View File
@@ -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;
-2
View File
@@ -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();
+16 -54
View File
@@ -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();
+1 -1
View File
@@ -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 );
+68 -92
View File
@@ -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
View File
@@ -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
View File
@@ -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 );
}
-5
View File
@@ -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
+7 -48
View File
@@ -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 );
}
+8 -25
View File
@@ -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 {
+11 -15
View File
@@ -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;
+5 -3
View File
@@ -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
+1 -8
View File
@@ -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();
}
+16 -53
View File
@@ -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